From 5b0f7f8aef115b202aaff6bc25bb514426dc2009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Fri, 16 Mar 2018 22:13:40 -0300 Subject: Fix drag and drop issues when re-enter board --- client/components/boards/boardBody.js | 103 +++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 21 deletions(-) (limited to 'client/components/boards/boardBody.js') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 94f9af39..3632da9b 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -1,12 +1,8 @@ const subManager = new SubsManager(); +const { calculateIndex } = Utils; BlazeComponent.extendComponent({ - openNewListForm() { - this.childComponents('addListForm')[0].open(); - }, onCreated() { - this.draggingActive = new ReactiveVar(false); - this.showOverlay = new ReactiveVar(false); this.isBoardReady = new ReactiveVar(false); // The pattern we use to manually handle data loading is described here: @@ -24,30 +20,70 @@ BlazeComponent.extendComponent({ }); }); }); + }, - this._isDragging = false; - this._lastDragPositionX = 0; + onlyShowCurrentCard() { + return Utils.isMiniScreen() && Session.get('currentCard'); + }, + +}).register('board'); +BlazeComponent.extendComponent({ + onCreated() { + this.showOverlay = new ReactiveVar(false); + this.draggingActive = new ReactiveVar(false); + this._isDragging = false; // Used to set the overlay this.mouseHasEnterCardDetails = false; }, + onRendered() { + const boardComponent = this; + const $swimlanesDom = boardComponent.$('.js-swimlanes'); - // XXX Flow components allow us to avoid creating these two setter methods by - // exposing a public API to modify the component state. We need to investigate - // best practices here. - setIsDragging(bool) { - this.draggingActive.set(bool); - }, + $swimlanesDom.sortable({ + tolerance: 'pointer', + appendTo: '.board-canvas', + helper: 'clone', + handle: '.js-swimlane-header', + items: '.js-swimlane:not(.placeholder)', + placeholder: 'swimlane 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 prevSwimlaneDom = ui.item.prev('.js-swimlane').get(0); + const nextSwimlaneDom = ui.item.next('.js-swimlane').get(0); + const sortIndex = calculateIndex(prevSwimlaneDom, nextSwimlaneDom, 1); - scrollLeft(position = 0) { - const lists = this.$('.js-lists'); - lists && lists.animate({ - scrollLeft: position, + $swimlanesDom.sortable('cancel'); + const swimlaneDomElement = ui.item.get(0); + const swimlane = Blaze.getData(swimlaneDomElement); + + Swimlanes.update(swimlane._id, { + $set: { + sort: sortIndex.base, + }, + }); + + boardComponent.setIsDragging(false); + }, }); - }, - onlyShowCurrentCard() { - return Utils.isMiniScreen() && Session.get('currentCard'); + function userIsMember() { + return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); + } + + // If there is no data in the board (ie, no lists) we autofocus the list + // creation form by clicking on the corresponding element. + const currentBoard = Boards.findOne(Session.get('currentBoard')); + if (userIsMember() && currentBoard.lists().count() === 0) { + boardComponent.openNewListForm(); + } }, isViewSwimlanes() { @@ -62,6 +98,16 @@ BlazeComponent.extendComponent({ return (board.view === 'board-view-lists'); }, + openNewListForm() { + if (this.isViewSwimlanes()) { + this.childComponents('swimlane')[0] + .childComponents('addListAndSwimlaneForm')[0].open(); + } else if (this.isViewLists()) { + this.childComponents('listsGroup')[0] + .childComponents('addListForm')[0].open(); + } + }, + events() { return [{ // XXX The board-overlay div should probably be moved to the parent @@ -78,4 +124,19 @@ BlazeComponent.extendComponent({ }, }]; }, -}).register('board'); + + // XXX Flow components allow us to avoid creating these two setter methods by + // exposing a public API to modify the component state. We need to investigate + // best practices here. + setIsDragging(bool) { + this.draggingActive.set(bool); + }, + + scrollLeft(position = 0) { + const lists = this.$('.js-lists'); + lists && lists.animate({ + scrollLeft: position, + }); + }, + +}).register('boardBody'); -- cgit v1.2.3-1-g7c22