summaryrefslogtreecommitdiffstats
path: root/client/components/cards/cardDetails.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/components/cards/cardDetails.js')
-rw-r--r--client/components/cards/cardDetails.js174
1 files changed, 163 insertions, 11 deletions
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index cd8813f5..7bb54223 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -121,11 +121,6 @@ BlazeComponent.extendComponent({
// Send Webhook but not create Activities records ---
const card = this.currentData();
const userId = Meteor.userId();
- //console.log(`userId: ${userId}`);
- //console.log(`cardId: ${card._id}`);
- //console.log(`boardId: ${card.boardId}`);
- //console.log(`listId: ${card.listId}`);
- //console.log(`swimlaneId: ${card.swimlaneId}`);
const params = {
userId,
cardId: card._id,
@@ -134,16 +129,25 @@ BlazeComponent.extendComponent({
user: Meteor.user().username,
url: '',
};
- //console.log('looking for integrations...');
+
const integrations = Integrations.find({
- boardId: card.boardId,
- type: 'outgoing-webhooks',
+ boardId: { $in: [card.boardId, Integrations.Const.GLOBAL_WEBHOOK_ID] },
enabled: true,
activities: { $in: ['CardDetailsRendered', 'all'] },
}).fetch();
- //console.log(`Investigation length: ${integrations.length}`);
+
if (integrations.length > 0) {
- Meteor.call('outgoingWebhooks', integrations, 'CardSelected', params);
+ integrations.forEach(integration => {
+ Meteor.call(
+ 'outgoingWebhooks',
+ integration,
+ 'CardSelected',
+ params,
+ () => {
+ return;
+ },
+ );
+ });
}
//-------------
}
@@ -309,6 +313,8 @@ BlazeComponent.extendComponent({
},
'click .js-member': Popup.open('cardMember'),
'click .js-add-members': Popup.open('cardMembers'),
+ 'click .js-assignee': Popup.open('cardAssignee'),
+ 'click .js-add-assignees': Popup.open('cardAssignees'),
'click .js-add-labels': Popup.open('cardLabels'),
'click .js-received-date': Popup.open('editCardReceivedDate'),
'click .js-start-date': Popup.open('editCardStartDate'),
@@ -321,6 +327,19 @@ BlazeComponent.extendComponent({
parentComponent.showOverlay.set(true);
parentComponent.mouseHasEnterCardDetails = true;
},
+ 'mousedown .js-card-details'() {
+ Session.set('cardDetailsIsDragging', false);
+ Session.set('cardDetailsIsMouseDown', true);
+ },
+ 'mousemove .js-card-details'() {
+ if (Session.get('cardDetailsIsMouseDown')) {
+ Session.set('cardDetailsIsDragging', true);
+ }
+ },
+ 'mouseup .js-card-details'() {
+ Session.set('cardDetailsIsDragging', false);
+ Session.set('cardDetailsIsMouseDown', false);
+ },
'click #toggleButton'() {
Meteor.call('toggleSystemMessages');
},
@@ -329,6 +348,58 @@ BlazeComponent.extendComponent({
},
}).register('cardDetails');
+Template.cardDetails.helpers({
+ userData() {
+ // We need to handle a special case for the search results provided by the
+ // `matteodem:easy-search` package. Since these results gets published in a
+ // separate collection, and not in the standard Meteor.Users collection as
+ // expected, we use a component parameter ("property") to distinguish the
+ // two cases.
+ const userCollection = this.esSearch ? ESSearchResults : Users;
+ return userCollection.findOne(this.userId, {
+ fields: {
+ profile: 1,
+ username: 1,
+ },
+ });
+ },
+
+ assigneeSelected() {
+ if (this.getAssignees().length === 0) {
+ return false;
+ } else {
+ return true;
+ }
+ },
+
+ memberType() {
+ const user = Users.findOne(this.userId);
+ return user && user.isBoardAdmin() ? 'admin' : 'normal';
+ },
+
+ presenceStatusClassName() {
+ const user = Users.findOne(this.userId);
+ const userPresence = presences.findOne({ userId: this.userId });
+ if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
+ else if (!userPresence) return 'disconnected';
+ else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
+ return 'active';
+ else return 'idle';
+ },
+});
+
+Template.userAvatarAssigneeInitials.helpers({
+ initials() {
+ const user = Users.findOne(this.userId);
+ return user && user.getInitials();
+ },
+
+ viewPortWidth() {
+ const user = Users.findOne(this.userId);
+ return ((user && user.getInitials().length) || 1) * 12;
+ },
+});
+
// We extends the normal InlinedForm component to support UnsavedEdits draft
// feature.
(class extends InlinedForm {
@@ -386,6 +457,7 @@ Template.cardDetailsActionsPopup.helpers({
Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
+ 'click .js-assignees': Popup.open('cardAssignees'),
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
'click .js-custom-fields': Popup.open('cardCustomFields'),
@@ -777,7 +849,14 @@ BlazeComponent.extendComponent({
EscapeActions.register(
'detailsPane',
() => {
- Utils.goBoardId(Session.get('currentBoard'));
+ if (Session.get('cardDetailsIsDragging')) {
+ // Reset dragging status as the mouse landed outside the cardDetails template area and this will prevent a mousedown event from firing
+ Session.set('cardDetailsIsDragging', false);
+ Session.set('cardDetailsIsMouseDown', false);
+ } else {
+ // Prevent close card when the user is selecting text and moves the mouse cursor outside the card detail area
+ Utils.goBoardId(Session.get('currentBoard'));
+ }
},
() => {
return !Session.equals('currentCard', null);
@@ -786,3 +865,76 @@ EscapeActions.register(
noClickEscapeOn: '.js-card-details,.board-sidebar,#header',
},
);
+
+Template.cardAssigneesPopup.events({
+ 'click .js-select-assignee'(event) {
+ const card = Cards.findOne(Session.get('currentCard'));
+ const assigneeId = this.userId;
+ card.toggleAssignee(assigneeId);
+ event.preventDefault();
+ },
+});
+
+Template.cardAssigneesPopup.helpers({
+ isCardAssignee() {
+ const card = Template.parentData();
+ const cardAssignees = card.getAssignees();
+
+ return _.contains(cardAssignees, this.userId);
+ },
+
+ user() {
+ return Users.findOne(this.userId);
+ },
+});
+
+Template.cardAssigneePopup.helpers({
+ userData() {
+ // We need to handle a special case for the search results provided by the
+ // `matteodem:easy-search` package. Since these results gets published in a
+ // separate collection, and not in the standard Meteor.Users collection as
+ // expected, we use a component parameter ("property") to distinguish the
+ // two cases.
+ const userCollection = this.esSearch ? ESSearchResults : Users;
+ return userCollection.findOne(this.userId, {
+ fields: {
+ profile: 1,
+ username: 1,
+ },
+ });
+ },
+
+ memberType() {
+ const user = Users.findOne(this.userId);
+ return user && user.isBoardAdmin() ? 'admin' : 'normal';
+ },
+
+ presenceStatusClassName() {
+ const user = Users.findOne(this.userId);
+ const userPresence = presences.findOne({ userId: this.userId });
+ if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
+ else if (!userPresence) return 'disconnected';
+ else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
+ return 'active';
+ else return 'idle';
+ },
+
+ isCardAssignee() {
+ const card = Template.parentData();
+ const cardAssignees = card.getAssignees();
+
+ return _.contains(cardAssignees, this.userId);
+ },
+
+ user() {
+ return Users.findOne(this.userId);
+ },
+});
+
+Template.cardAssigneePopup.events({
+ 'click .js-remove-assignee'() {
+ Cards.findOne(this.cardId).unassignAssignee(this.userId);
+ Popup.close();
+ },
+ 'click .js-edit-profile': Popup.open('editProfile'),
+});