diff options
Diffstat (limited to 'client/components/boards')
-rw-r--r-- | client/components/boards/boardArchive.js | 2 | ||||
-rw-r--r-- | client/components/boards/boardBody.js | 10 | ||||
-rw-r--r-- | client/components/boards/boardsList.jade | 6 | ||||
-rw-r--r-- | client/components/boards/boardsList.js | 75 | ||||
-rw-r--r-- | client/components/boards/boardsList.styl | 18 |
5 files changed, 87 insertions, 24 deletions
diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js index d3e65bd8..5a5cf772 100644 --- a/client/components/boards/boardArchive.js +++ b/client/components/boards/boardArchive.js @@ -7,7 +7,7 @@ BlazeComponent.extendComponent({ return Boards.find( { archived: true }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); }, diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index e70a9f67..4e473f18 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -1,7 +1,7 @@ import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); const subManager = new SubsManager(); -const { calculateIndex, enableClickOnTouch } = Utils; +const { calculateIndex } = Utils; const swimlaneWhileSortingHeight = 150; BlazeComponent.extendComponent({ @@ -191,9 +191,6 @@ BlazeComponent.extendComponent({ }, }); - // ugly touch event hotfix - enableClickOnTouch('.js-swimlane:not(.placeholder)'); - this.autorun(() => { let showDesktopDragHandles = false; currentUser = Meteor.user(); @@ -205,7 +202,7 @@ BlazeComponent.extendComponent({ } else { showDesktopDragHandles = false; } - if (!Utils.isMiniScreen() && showDesktopDragHandles) { + if (Utils.isMiniScreen() || showDesktopDragHandles) { $swimlanesDom.sortable({ handle: '.js-swimlane-header-handle', }); @@ -215,9 +212,8 @@ BlazeComponent.extendComponent({ }); } - // Disable drag-dropping if the current user is not a board member or is miniscreen + // Disable drag-dropping if the current user is not a board member $swimlanesDom.sortable('option', 'disabled', !userIsMember()); - $swimlanesDom.sortable('option', 'disabled', Utils.isMiniScreen()); }); function userIsMember() { diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index f1118aa8..bbce1d6f 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -1,10 +1,10 @@ template(name="boardList") .wrapper - ul.board-list.clearfix + ul.board-list.clearfix.js-boards li.js-add-board a.board-list-item.label {{_ 'add-board'}} each boards - li(class="{{#if isStarred}}starred{{/if}}" class=colorClass) + li(class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board if isInvited .board-list-item span.details @@ -39,7 +39,7 @@ template(name="boardList") i.fa.js-archive-board( class="fa-archive" title="{{_ 'archive-board'}}") - else if currentUser.isBoardAdmin + else if isAdministrable i.fa.js-clone-board( class="fa-clone" title="{{_ 'duplicate-board'}}") diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 0ff1c4fb..df319ce0 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,4 +1,5 @@ const subManager = new SubsManager(); +const { calculateIndex } = Utils; Template.boardListHeaderBar.events({ 'click .js-open-archived-board'() { @@ -7,8 +8,8 @@ Template.boardListHeaderBar.events({ }); Template.boardListHeaderBar.helpers({ - title(){ - return FlowRouter.getRouteName() == 'home' ? 'my-boards' :'public'; + title() { + return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public'; }, templatesBoardId() { return Meteor.user() && Meteor.user().getTemplatesBoardId(); @@ -23,25 +24,77 @@ BlazeComponent.extendComponent({ Meteor.subscribe('setting'); }, + onRendered() { + const self = this; + function userIsAllowedToMove() { + return Meteor.user(); + } + + const itemsSelector = '.js-board:not(.placeholder)'; + + const $boards = this.$('.js-boards'); + $boards.sortable({ + connectWith: '.js-boards', + tolerance: 'pointer', + appendTo: '.board-list', + helper: 'clone', + distance: 7, + items: itemsSelector, + placeholder: 'board-wrapper placeholder', + start(evt, ui) { + ui.helper.css('z-index', 1000); + ui.placeholder.height(ui.helper.height()); + EscapeActions.executeUpTo('popup-close'); + }, + 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 prevBoardDom = ui.item.prev('.js-board').get(0); + const nextBoardBom = ui.item.next('.js-board').get(0); + const sortIndex = calculateIndex(prevBoardDom, nextBoardBom, 1); + + const boardDomElement = ui.item.get(0); + const board = Blaze.getData(boardDomElement); + // Normally the jquery-ui sortable library moves the dragged DOM element + // to its new position, which disrupts Blaze reactive updates mechanism + // (especially when we move the last card of a list, or when multiple + // users move some cards at the same time). To prevent these UX glitches + // we ask sortable to gracefully cancel the move, and to put back the + // DOM in its initial state. The card move is then handled reactively by + // Blaze with the below query. + $boards.sortable('cancel'); + + board.move(sortIndex.base); + }, + }); + + // Disable drag-dropping if the current user is not a board member or is comment only + this.autorun(() => { + $boards.sortable('option', 'disabled', !userIsAllowedToMove()); + }); + }, + boards() { let query = { archived: false, type: 'board', - } - if (FlowRouter.getRouteName() == 'home') - query['members.userId'] = Meteor.userId() - else - query.permission = 'public' + }; + if (FlowRouter.getRouteName() === 'home') + query['members.userId'] = Meteor.userId(); + else query.permission = 'public'; - return Boards.find( - query, - { sort: ['title'] }, - ); + return Boards.find(query, { + sort: { sort: 1 /* boards default sorting */ }, + }); }, isStarred() { const user = Meteor.user(); return user && user.hasStarred(this.currentData()._id); }, + isAdministrable() { + const user = Meteor.user(); + return user && user.isBoardAdmin(this.currentData()._id); + }, hasOvertimeCards() { subManager.subscribe('board', this.currentData()._id, false); diff --git a/client/components/boards/boardsList.styl b/client/components/boards/boardsList.styl index ae366e83..d92c9cf3 100644 --- a/client/components/boards/boardsList.styl +++ b/client/components/boards/boardsList.styl @@ -11,6 +11,19 @@ $spaceBetweenTiles = 16px box-sizing: border-box position: relative + &.placeholder:after + content: ''; + display: block; + background: darken(white, 20%) + border-radius: 3px; + height: 106px; + margin: 8px; + + &.ui-sortable-helper + cursor: grabbing + transform: rotate(4deg) + display: block !important + &.starred .fa-star, .fa-star-o @@ -20,7 +33,7 @@ $spaceBetweenTiles = 16px overflow: hidden; background-color: #999 color: #f6f6f6 - height: 90px + height: auto font-size: 16px line-height: 22px border-radius: 3px @@ -31,6 +44,7 @@ $spaceBetweenTiles = 16px margin: ($spaceBetweenTiles/2) position: relative text-decoration: none + word-wrap: break-word &.tile background-size: auto @@ -183,7 +197,7 @@ $spaceBetweenTiles = 16px overflow: scroll li - width: 50% + width: 50% .board-list-item overflow: hidden |