diff options
Diffstat (limited to 'client/components/boards')
-rw-r--r-- | client/components/boards/boardBody.jade | 35 | ||||
-rw-r--r-- | client/components/boards/boardBody.js | 158 | ||||
-rw-r--r-- | client/components/boards/boardBody.styl | 10 | ||||
-rw-r--r-- | client/components/boards/boardHeader.jade | 5 | ||||
-rw-r--r-- | client/components/boards/boardHeader.js | 21 |
5 files changed, 47 insertions, 182 deletions
diff --git a/client/components/boards/boardBody.jade b/client/components/boards/boardBody.jade index bb3d2906..30e70b31 100644 --- a/client/components/boards/boardBody.jade +++ b/client/components/boards/boardBody.jade @@ -20,33 +20,8 @@ template(name="boardBody") class="{{#if draggingActive.get}}is-dragging-active{{/if}}") if showOverlay.get .board-overlay - .lists.js-lists - if isMiniScreen - if currentList - +list(currentList) - else - each currentBoard.lists - +miniList(this) - if currentUser.isBoardMember - +addListForm - else - each currentBoard.lists - +list(this) - if currentCardIsInThisList - +cardDetails(currentCard) - if currentUser.isBoardMember - +addListForm - -template(name="addListForm") - .list.js-list.list-composer.js-list-composer - .list-header - +inlinedForm(autoclose=false) - input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}" - autocomplete="off" autofocus) - .edit-controls.clearfix - button.primary.confirm(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form - else - a.open-list-composer.js-open-inlined-form - i.fa.fa-plus - | {{_ 'add-list'}} + if isViewSwimlanes + each currentBoard.swimlanes + +swimlane(this) + if isViewLists + +listsGroup diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index b3880c61..a068dd04 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -29,10 +29,6 @@ BlazeComponent.extendComponent({ this.mouseHasEnterCardDetails = false; }, - openNewListForm() { - this.childComponents('addListForm')[0].open(); - }, - // 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. @@ -47,16 +43,22 @@ BlazeComponent.extendComponent({ }); }, - currentCardIsInThisList() { - const currentCard = Cards.findOne(Session.get('currentCard')); - const listId = this.currentData()._id; - return currentCard && currentCard.listId === listId; - }, - onlyShowCurrentCard() { return Utils.isMiniScreen() && Session.get('currentCard'); }, + isViewSwimlanes() { + const currentBoardId = Session.get('currentBoard'); + const board = Boards.findOne(currentBoardId); + return (board.view === 'board-view-swimlanes'); + }, + + isViewLists() { + const currentBoardId = Session.get('currentBoard'); + const board = Boards.findOne(currentBoardId); + return (board.view === 'board-view-lists'); + }, + events() { return [{ // XXX The board-overlay div should probably be moved to the parent @@ -66,147 +68,11 @@ BlazeComponent.extendComponent({ this.showOverlay.set(false); } }, - - // Click-and-drag action - 'mousedown .board-canvas'(evt) { - // Translating the board canvas using the click-and-drag action can - // conflict with the build-in browser mechanism to select text. We - // define a list of elements in which we disable the dragging because - // the user will legitimately expect to be able to select some text with - // his mouse. - const noDragInside = ['a', 'input', 'textarea', 'p', '.js-list-header']; - if ($(evt.target).closest(noDragInside.join(',')).length === 0 && $('.lists').prop('clientHeight') > evt.offsetY) { - this._isDragging = true; - this._lastDragPositionX = evt.clientX; - } - }, 'mouseup'() { if (this._isDragging) { this._isDragging = false; } }, - 'mousemove'(evt) { - if (this._isDragging) { - // Update the canvas position - this.listsDom.scrollLeft -= evt.clientX - this._lastDragPositionX; - this._lastDragPositionX = evt.clientX; - // Disable browser text selection while dragging - evt.stopPropagation(); - evt.preventDefault(); - // Don't close opened card or inlined form at the end of the - // click-and-drag. - EscapeActions.executeUpTo('popup-close'); - EscapeActions.preventNextClick(); - } - }, }]; }, }).register('board'); - -Template.boardBody.onRendered(function() { - const self = BlazeComponent.getComponentForElement(this.firstNode); - - self.listsDom = this.find('.js-lists'); - - if (!Session.get('currentCard')) { - self.scrollLeft(); - } - - // We want to animate the card details window closing. We rely on CSS - // transition for the actual animation. - self.listsDom._uihooks = { - removeElement(node) { - const removeNode = _.once(() => { - node.parentNode.removeChild(node); - }); - if ($(node).hasClass('js-card-details')) { - $(node).css({ - flexBasis: 0, - padding: 0, - }); - $(self.listsDom).one(CSSEvents.transitionend, removeNode); - } else { - removeNode(); - } - }, - }; - - $(self.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()); - Popup.close(); - }, - stop() { - $(self.listsDom).find('.js-list:not(.js-list-composer)').each( - (i, list) => { - const data = Blaze.getData(list); - Lists.update(data._id, { - $set: { - sort: i, - }, - }); - } - ); - }, - }); - - function userIsMember() { - return Meteor.user() && Meteor.user().isBoardMember(); - } - - // Disable drag-dropping while in multi-selection mode, or if the current user - // is not a board member - self.autorun(() => { - const $listDom = $(self.listsDom); - if ($listDom.data('sortable')) { - $(self.listsDom).sortable('option', 'disabled', - MultiSelection.isActive() || !userIsMember()); - } - }); - - // 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) { - self.openNewListForm(); - } -}); - -BlazeComponent.extendComponent({ - // Proxy - open() { - this.childComponents('inlinedForm')[0].open(); - }, - - events() { - return [{ - submit(evt) { - evt.preventDefault(); - const titleInput = this.find('.list-name-input'); - const title = titleInput.value.trim(); - if (title) { - Lists.insert({ - title, - boardId: Session.get('currentBoard'), - sort: $('.list').length, - }); - - titleInput.value = ''; - titleInput.focus(); - } - }, - }]; - }, -}).register('addListForm'); - -Template.boardBody.helpers({ - canSeeAddList() { - return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); - }, -}); diff --git a/client/components/boards/boardBody.styl b/client/components/boards/boardBody.styl index bb9beb19..f5ecc08e 100644 --- a/client/components/boards/boardBody.styl +++ b/client/components/boards/boardBody.styl @@ -20,15 +20,14 @@ position() &.is-sibling-sidebar-open margin-right: 248px - .lists - align-items: flex-start + .swimlane + border-bottom: 1px solid #CCC display: flex flex-direction: row margin: 0 0 10px padding: 0 40px 5px 0 overflow-x: auto overflow-y: hidden - position: cover .board-overlay position: cover @@ -49,12 +48,11 @@ position() .board-canvas - .lists - align-items: flex-start + .swimlane + border-bottom: 1px solid #CCC display: flex flex-direction: column margin: 0 padding: 0 40px 0px 0 overflow-x: hidden overflow-y: auto - position: cover diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index ffb8eb27..1a65ce27 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -87,6 +87,11 @@ template(name="boardHeaderBar") a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}") i.fa.fa-times-thin + a.board-header-btn.js-toggle-board-view( + title="{{_ 'board-view'}}") + i.fa.fa-th-large + span {{_ currentBoard.view}} + if canModifyBoard a.board-header-btn.js-multiselection-activate( title="{{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}" diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index fe10dab1..67b05446 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -76,6 +76,22 @@ BlazeComponent.extendComponent({ 'click .js-open-archived-board'() { Modal.open('archivedBoards'); }, + 'click .js-toggle-board-view'() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + if (currentBoard.view === 'board-view-swimlanes') { + Boards.update(currentBoard._id, { + $set: { + view: 'board-view-lists', + }, + }); + } else if (currentBoard.view === 'board-view-lists') { + Boards.update(currentBoard._id, { + $set: { + view: 'board-view-swimlanes', + }, + }); + } + }, 'click .js-open-filter-view'() { Sidebar.setView('filter'); }, @@ -164,6 +180,11 @@ const CreateBoard = BlazeComponent.extendComponent({ permission: visibility, })); + Swimlanes.insert({ + title: 'Default', + boardId: this.boardId.get(), + }); + Utils.goBoardId(this.boardId.get()); }, |