diff options
author | 蔡仲明 (Romulus Urakagi Tsai) <urakagi@gmail.com> | 2019-11-21 11:25:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-21 11:25:56 +0800 |
commit | 3e0bedd8c7a6dec97352212adb1cbde1ade44190 (patch) | |
tree | 651ff30d25ddb0416444370368d699e597c142d7 /client/components/swimlanes | |
parent | 9bbeb73db1cd0ce1caaaca8dfb14ea92131bbf9d (diff) | |
parent | 4f5de87cc4c2281bd576548693de7c94e6a988c6 (diff) | |
download | wekan-3e0bedd8c7a6dec97352212adb1cbde1ade44190.tar.gz wekan-3e0bedd8c7a6dec97352212adb1cbde1ade44190.tar.bz2 wekan-3e0bedd8c7a6dec97352212adb1cbde1ade44190.zip |
Merge pull request #1 from wekan/master
Update master
Diffstat (limited to 'client/components/swimlanes')
-rw-r--r-- | client/components/swimlanes/swimlaneHeader.jade | 5 | ||||
-rw-r--r-- | client/components/swimlanes/swimlaneHeader.js | 17 | ||||
-rw-r--r-- | client/components/swimlanes/swimlanes.jade | 53 | ||||
-rw-r--r-- | client/components/swimlanes/swimlanes.js | 138 | ||||
-rw-r--r-- | client/components/swimlanes/swimlanes.styl | 78 |
5 files changed, 234 insertions, 57 deletions
diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 8c6aa5a3..72a7f054 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -16,6 +16,11 @@ template(name="swimlaneFixedHeader") unless currentUser.isCommentOnly a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon a.fa.fa-navicon.js-open-swimlane-menu + unless isMiniScreen + if showDesktopDragHandles + a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle + if isMiniScreen + a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle template(name="editSwimlaneTitleForm") .list-composer diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index ee21d100..69971b05 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -28,6 +28,23 @@ BlazeComponent.extendComponent({ }, }).register('swimlaneHeader'); +Template.swimlaneHeader.helpers({ + showDesktopDragHandles() { + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } + } + }, +}); + Template.swimlaneActionPopup.events({ 'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'), 'click .js-close-swimlane'(event) { diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 3ad43777..b2e03afe 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -1,24 +1,47 @@ template(name="swimlane") .swimlane +swimlaneHeader - .swimlane.js-lists.js-swimlane - if isMiniScreen - if currentListIsInThisSwimlane _id - +list(currentList) - unless currentList + unless collapseSwimlane + .swimlane.js-lists.js-swimlane + if isMiniScreen + if currentListIsInThisSwimlane _id + +list(currentList) + unless currentList + each lists + +miniList(this) + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm + else each lists - +miniList(this) + +list(this) + if currentCardIsInThisList _id ../_id + +cardDetails(currentCard) if currentUser.isBoardMember unless currentUser.isCommentOnly +addListForm - else - each lists - +list(this) - if currentCardIsInThisList _id ../_id - +cardDetails(currentCard) - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm + //if collapseSwimlane + // // Minimize swimlanes next 2 lines below https://www.w3schools.com/howto/howto_js_accordion.asp + // button(class="accordion") + // div(class="panel") + // .swimlane.js-lists.js-swimlane + // if isMiniScreen + // if currentListIsInThisSwimlane _id + // +list(currentList) + // unless currentList + // each lists + // +miniList(this) + // if currentUser.isBoardMember + // unless currentUser.isCommentOnly + // +addListForm + // else + // each lists + // +list(this) + // if currentCardIsInThisList _id ../_id + // +cardDetails(currentCard) + // if currentUser.isBoardMember + // unless currentUser.isCommentOnly + // +addListForm template(name="listsGroup") .swimlane.list-group.js-lists @@ -42,7 +65,7 @@ template(name="listsGroup") +addListForm template(name="addListForm") - .list.list-composer.js-list-composer + .list.list-composer.js-list-composer(class="{{#if isMiniScreen}}mini-list{{/if}}") .list-header-add +inlinedForm(autoclose=false) input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}" diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index e0857003..9bc093be 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -3,8 +3,8 @@ const { calculateIndex, enableClickOnTouch } = Utils; function currentListIsInThisSwimlane(swimlaneId) { const currentList = Lists.findOne(Session.get('currentList')); return ( - currentList && - (currentList.swimlaneId === swimlaneId || currentList.swimlaneId === '') + currentList + && (currentList.swimlaneId === swimlaneId || currentList.swimlaneId === '') ); } @@ -12,14 +12,14 @@ function currentCardIsInThisList(listId, swimlaneId) { const currentCard = Cards.findOne(Session.get('currentCard')); const currentUser = Meteor.user(); if ( - currentUser && - currentUser.profile && - currentUser.profile.boardView === 'board-view-swimlanes' + currentUser + && currentUser.profile + && Utils.boardView() === 'board-view-swimlanes' ) return ( - currentCard && - currentCard.listId === listId && - currentCard.swimlaneId === swimlaneId + currentCard + && currentCard.listId === listId + && currentCard.swimlaneId === swimlaneId ); // Default view: board-view-lists else return currentCard && currentCard.listId === listId; @@ -56,7 +56,6 @@ function initSortable(boardComponent, $listsDom) { $listsDom.sortable({ tolerance: 'pointer', helper: 'clone', - handle: '.js-list-header', items: '.js-list:not(.js-list-composer)', placeholder: 'list placeholder', distance: 7, @@ -91,21 +90,47 @@ function initSortable(boardComponent, $listsDom) { function userIsMember() { return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + 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(() => { + let showDesktopDragHandles = false; + currentUser = Meteor.user(); + if (currentUser) { + showDesktopDragHandles = (currentUser.profile || {}) + .showDesktopDragHandles; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + showDesktopDragHandles = true; + } else { + showDesktopDragHandles = false; + } + } + + if (!Utils.isMiniScreen() && showDesktopDragHandles) { + $listsDom.sortable({ + handle: '.js-list-handle', + }); + } else { + $listsDom.sortable({ + handle: '.js-list-header', + }); + } + const $listDom = $listsDom; if ($listDom.data('sortable')) { $listsDom.sortable( 'option', 'disabled', - MultiSelection.isActive() || !userIsMember(), + // Disable drag-dropping when user is not member + !userIsMember(), + // Not disable drag-dropping while in multi-selection mode + // MultiSelection.isActive() || !userIsMember(), ); } }); @@ -121,6 +146,26 @@ BlazeComponent.extendComponent({ } initSortable(boardComponent, $listsDom); + + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('collapseSwimlane')) { + // Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp + const acc = document.getElementsByClassName('accordion'); + let i; + for (i = 0; i < acc.length; i++) { + acc[i].addEventListener('click', function() { + this.classList.toggle('active'); + const panel = this.nextElementSibling; + if (panel.style.maxHeight) { + panel.style.maxHeight = null; + } else { + panel.style.maxHeight = `${panel.scrollHeight}px`; + } + }); + } + // Minimize swimlanes end https://www.w3schools.com/howto/howto_js_accordion.asp + } }, onCreated() { this.draggingActive = new ReactiveVar(false); @@ -151,16 +196,32 @@ BlazeComponent.extendComponent({ // 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', - ]; + + let showDesktopDragHandles = false; + currentUser = Meteor.user(); + if (currentUser) { + showDesktopDragHandles = (currentUser.profile || {}) + .showDesktopDragHandles; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + showDesktopDragHandles = true; + } else { + showDesktopDragHandles = false; + } + } + + const noDragInside = ['a', 'input', 'textarea', 'p'].concat( + Utils.isMiniScreen() + || (!Utils.isMiniScreen() && showDesktopDragHandles) + ? ['.js-list-handle', '.js-swimlane-header-handle'] + : ['.js-list-header'], + ); + if ( - $(evt.target).closest(noDragInside.join(',')).length === 0 && - this.$('.swimlane').prop('clientHeight') > evt.offsetY + $(evt.target).closest(noDragInside.join(',')).length === 0 + && this.$('.swimlane').prop('clientHeight') > evt.offsetY ) { this._isDragging = true; this._lastDragPositionX = evt.clientX; @@ -194,8 +255,8 @@ BlazeComponent.extendComponent({ onCreated() { this.currentBoard = Boards.findOne(Session.get('currentBoard')); this.isListTemplatesSwimlane = - this.currentBoard.isTemplatesBoard() && - this.currentData().isListTemplatesSwimlane(); + this.currentBoard.isTemplatesBoard() + && this.currentData().isListTemplatesSwimlane(); this.currentSwimlane = this.currentData(); }, @@ -233,11 +294,25 @@ BlazeComponent.extendComponent({ }).register('addListForm'); Template.swimlane.helpers({ + showDesktopDragHandles() { + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } + } + }, canSeeAddList() { return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + Meteor.user() + && Meteor.user().isBoardMember() + && !Meteor.user().isCommentOnly() ); }, }); @@ -253,6 +328,11 @@ BlazeComponent.extendComponent({ return false; } } + if (Filter.lists._isActive()) { + if (!list.title.match(Filter.lists.getRegexSelector())) { + return false; + } + } if (Filter.hideEmpty.isSelected()) { const swimlaneId = this.parentComponent() .parentComponent() diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 1056e1e3..ca5611cc 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -1,5 +1,41 @@ @import 'nib' +/* +// Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp + +.accordion + cursor: pointer + width: 30px + height: 20px + border: none + outline: none + font-size: 18px + transition: 0.4s + padding-top: 0px + margin-top: 0px + +.accordion:after + // Unicode triagle right: + content: '\25B6' + color: #777 + font-weight: bold + float: left + +.active:after + // Unicode triangle down: + content: '\25BC' + +.panel + width: 100% + max-height: 0 + overflow: hidden + transition: max-height 0.2s ease-out + margin: 0px + padding: 0px + +// Minimize swimlanes end https://www.w3schools.com/howto/howto_js_accordion.asp +*/ + .swimlane // Even if this background color is the same as the body we can't leave it // transparent, because that won't work during a swimlane drag. @@ -25,22 +61,22 @@ cursor: grabbing .swimlane-header-wrap - display: flex; - flex-direction: row; - flex: 1 0 100%; - background-color: #ccc; + display: flex + flex-direction: row + flex: 1 0 100% + background-color: #ccc .swimlane-header - font-size: 14px; + font-size: 14px padding: 5px 5px - font-weight: bold; - min-height: 9px; - width: 100%; - overflow: hidden; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - word-wrap: break-word; - text-align: center; + font-weight: bold + min-height: 9px + width: 100% + overflow: hidden + -o-text-overflow: ellipsis + text-overflow: ellipsis + word-wrap: break-word + text-align: center .swimlane-header-menu position: absolute @@ -50,6 +86,22 @@ margin-left: 5px margin-right: 10px + .swimlane-header-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 230px + font-size: 18px + + .swimlane-header-miniscreen-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 87vw + font-size: 24px + .list-group height: 100% |