|
@@ -1,5 +1,85 @@
|
|
|
const { calculateIndex } = Utils;
|
|
|
|
|
|
+function currentCardIsInThisList(listId, swimlaneId) {
|
|
|
+ const currentCard = Cards.findOne(Session.get('currentCard'));
|
|
|
+ const currentBoardId = Session.get('currentBoard');
|
|
|
+ const board = Boards.findOne(currentBoardId);
|
|
|
+ if (board.view === 'board-view-lists')
|
|
|
+ return currentCard && currentCard.listId === listId;
|
|
|
+ else if (board.view === 'board-view-swimlanes')
|
|
|
+ return currentCard && currentCard.listId === listId && currentCard.swimlaneId === swimlaneId;
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+};
|
|
|
+
|
|
|
+function initSortable(boardComponent, $listsDom) {
|
|
|
+ // We want to animate the card details window closing. We rely on CSS
|
|
|
+ // transition for the actual animation.
|
|
|
+ $listsDom._uihooks = {
|
|
|
+ removeElement(node) {
|
|
|
+ const removeNode = _.once(() => {
|
|
|
+ node.parentNode.removeChild(node);
|
|
|
+ });
|
|
|
+ if ($(node).hasClass('js-card-details')) {
|
|
|
+ $(node).css({
|
|
|
+ flexBasis: 0,
|
|
|
+ padding: 0,
|
|
|
+ });
|
|
|
+ $listsDom.one(CSSEvents.transitionend, removeNode);
|
|
|
+ } else {
|
|
|
+ removeNode();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ $listsDom.sortable({
|
|
|
+ tolerance: 'pointer',
|
|
|
+ helper: 'clone',
|
|
|
+ handle: '.js-list-header',
|
|
|
+ items: '.js-list:not(.js-list-composer)',
|
|
|
+ placeholder: 'list placeholder',
|
|
|
+ distance: 7,
|
|
|
+ start(evt, ui) {
|
|
|
+ ui.placeholder.height(ui.helper.height());
|
|
|
+ EscapeActions.executeUpTo('popup-close');
|
|
|
+ boardComponent.setIsDragging(true);
|
|
|
+ },
|
|
|
+ stop(evt, ui) {
|
|
|
+ // To attribute the new index number, we need to get the DOM element
|
|
|
+ // of the previous and the following card -- if any.
|
|
|
+ const prevListDom = ui.item.prev('.js-list').get(0);
|
|
|
+ const nextListDom = ui.item.next('.js-list').get(0);
|
|
|
+ const sortIndex = calculateIndex(prevListDom, nextListDom, 1);
|
|
|
+
|
|
|
+ $listsDom.sortable('cancel');
|
|
|
+ const listDomElement = ui.item.get(0);
|
|
|
+ const list = Blaze.getData(listDomElement);
|
|
|
+
|
|
|
+ Lists.update(list._id, {
|
|
|
+ $set: {
|
|
|
+ sort: sortIndex.base,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ boardComponent.setIsDragging(false);
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ function userIsMember() {
|
|
|
+ return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Disable drag-dropping while in multi-selection mode, or if the current user
|
|
|
+ // is not a board member
|
|
|
+ boardComponent.autorun(() => {
|
|
|
+ const $listDom = $listsDom;
|
|
|
+ if ($listDom.data('sortable')) {
|
|
|
+ $listsDom.sortable('option', 'disabled',
|
|
|
+ MultiSelection.isActive() || !userIsMember());
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
BlazeComponent.extendComponent({
|
|
|
onRendered() {
|
|
|
const boardComponent = this.parentComponent();
|
|
@@ -9,71 +89,7 @@ BlazeComponent.extendComponent({
|
|
|
boardComponent.scrollLeft();
|
|
|
}
|
|
|
|
|
|
- // We want to animate the card details window closing. We rely on CSS
|
|
|
- // transition for the actual animation.
|
|
|
- $listsDom._uihooks = {
|
|
|
- removeElement(node) {
|
|
|
- const removeNode = _.once(() => {
|
|
|
- node.parentNode.removeChild(node);
|
|
|
- });
|
|
|
- if ($(node).hasClass('js-card-details')) {
|
|
|
- $(node).css({
|
|
|
- flexBasis: 0,
|
|
|
- padding: 0,
|
|
|
- });
|
|
|
- $listsDom.one(CSSEvents.transitionend, removeNode);
|
|
|
- } else {
|
|
|
- removeNode();
|
|
|
- }
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- $listsDom.sortable({
|
|
|
- tolerance: 'pointer',
|
|
|
- helper: 'clone',
|
|
|
- handle: '.js-list-header',
|
|
|
- items: '.js-list:not(.js-list-composer)',
|
|
|
- placeholder: 'list placeholder',
|
|
|
- distance: 7,
|
|
|
- start(evt, ui) {
|
|
|
- ui.placeholder.height(ui.helper.height());
|
|
|
- EscapeActions.executeUpTo('popup-close');
|
|
|
- boardComponent.setIsDragging(true);
|
|
|
- },
|
|
|
- stop(evt, ui) {
|
|
|
- // To attribute the new index number, we need to get the DOM element
|
|
|
- // of the previous and the following card -- if any.
|
|
|
- const prevListDom = ui.item.prev('.js-list').get(0);
|
|
|
- const nextListDom = ui.item.next('.js-list').get(0);
|
|
|
- const sortIndex = calculateIndex(prevListDom, nextListDom, 1);
|
|
|
-
|
|
|
- $listsDom.sortable('cancel');
|
|
|
- const listDomElement = ui.item.get(0);
|
|
|
- const list = Blaze.getData(listDomElement);
|
|
|
-
|
|
|
- Lists.update(list._id, {
|
|
|
- $set: {
|
|
|
- sort: sortIndex.base,
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- boardComponent.setIsDragging(false);
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- function userIsMember() {
|
|
|
- return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
|
|
- }
|
|
|
-
|
|
|
- // Disable drag-dropping while in multi-selection mode, or if the current user
|
|
|
- // is not a board member
|
|
|
- boardComponent.autorun(() => {
|
|
|
- const $listDom = $listsDom;
|
|
|
- if ($listDom.data('sortable')) {
|
|
|
- $listsDom.sortable('option', 'disabled',
|
|
|
- MultiSelection.isActive() || !userIsMember());
|
|
|
- }
|
|
|
- });
|
|
|
+ initSortable(boardComponent, $listsDom);
|
|
|
},
|
|
|
onCreated() {
|
|
|
this.draggingActive = new ReactiveVar(false);
|
|
@@ -87,15 +103,7 @@ BlazeComponent.extendComponent({
|
|
|
},
|
|
|
|
|
|
currentCardIsInThisList(listId, swimlaneId) {
|
|
|
- const currentCard = Cards.findOne(Session.get('currentCard'));
|
|
|
- const currentBoardId = Session.get('currentBoard');
|
|
|
- const board = Boards.findOne(currentBoardId);
|
|
|
- if (board.view === 'board-view-lists')
|
|
|
- return currentCard && currentCard.listId === listId;
|
|
|
- else if (board.view === 'board-view-swimlanes')
|
|
|
- return currentCard && currentCard.listId === listId && currentCard.swimlaneId === swimlaneId;
|
|
|
- else
|
|
|
- return false;
|
|
|
+ return currentCardIsInThisList(listId, swimlaneId);
|
|
|
},
|
|
|
|
|
|
events() {
|
|
@@ -210,3 +218,19 @@ Template.swimlane.helpers({
|
|
|
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
|
|
},
|
|
|
});
|
|
|
+
|
|
|
+BlazeComponent.extendComponent({
|
|
|
+ currentCardIsInThisList(listId, swimlaneId) {
|
|
|
+ return currentCardIsInThisList(listId, swimlaneId);
|
|
|
+ },
|
|
|
+ onRendered() {
|
|
|
+ const boardComponent = this.parentComponent();
|
|
|
+ const $listsDom = this.$('.js-lists');
|
|
|
+
|
|
|
+ if (!Session.get('currentCard')) {
|
|
|
+ boardComponent.scrollLeft();
|
|
|
+ }
|
|
|
+
|
|
|
+ initSortable(boardComponent, $listsDom);
|
|
|
+ },
|
|
|
+}).register('listsGroup');
|