From 3f0600fed70512f87dc20fe039695d1681a73d39 Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Sat, 17 Aug 2019 19:17:57 -0400 Subject: Add Feature: enable two-way webhooks - stage one --- client/components/settings/settingBody.jade | 8 +++ client/components/settings/settingBody.js | 3 + client/components/sidebar/sidebar.jade | 36 +++++++----- client/components/sidebar/sidebar.js | 86 +++++++++++++++++++---------- client/lib/utils.js | 1 - 5 files changed, 89 insertions(+), 45 deletions(-) (limited to 'client') diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 8eb584dc..04b635e8 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -18,6 +18,8 @@ template(name="setting") a.js-setting-menu(data-id="announcement-setting") {{_ 'admin-announcement'}} li a.js-setting-menu(data-id="layout-setting") {{_ 'layout'}} + li + a.js-setting-menu(data-id="webhook-setting") {{_ 'global-webhook'}} .main-body if loading.get +spinner @@ -31,6 +33,12 @@ template(name="setting") +announcementSettings else if layoutSetting.get +layoutSettings + else if webhookSetting.get + +webhookSettings + +template(name="webhookSettings") + span + +outgoingWebhooksPopup template(name="general") ul#registration-setting.setting-detail diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index f9b5c08d..4ff5aedd 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -7,11 +7,13 @@ BlazeComponent.extendComponent({ this.accountSetting = new ReactiveVar(false); this.announcementSetting = new ReactiveVar(false); this.layoutSetting = new ReactiveVar(false); + this.webhookSetting = new ReactiveVar(false); Meteor.subscribe('setting'); Meteor.subscribe('mailServer'); Meteor.subscribe('accountSettings'); Meteor.subscribe('announcements'); + Meteor.subscribe('globalwebhooks'); }, setError(error) { @@ -83,6 +85,7 @@ BlazeComponent.extendComponent({ this.accountSetting.set('account-setting' === targetID); this.announcementSetting.set('announcement-setting' === targetID); this.layoutSetting.set('layout-setting' === targetID); + this.webhookSetting.set('webhook-setting' === targetID); } }, diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 2dfe41b3..ccfadc0c 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -135,22 +135,30 @@ template(name="archiveBoardPopup") template(name="outgoingWebhooksPopup") each integrations form.integration-form - if title - h4 {{title}} - else - h4 {{_ 'no-name'}} - label - | URL - input.js-outgoing-webhooks-url(type="text" name="url" value=url) - input(type="hidden" value=_id name="id") + a.flex + span {{_ 'disable-webhook'}} + b   + .materialCheckBox(class="{{#unless enabled}}is-checked{{/unless}}") + input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" value=title) + input.js-outgoing-webhooks-url(type="text" name="url" value=url autofocus) + input.js-outgoing-webhooks-token(placeholder="{{_ 'webhook-token' }}" type="text" value=token name="token") + select.js-outgoing-webhooks-type(name="type") + each _type in types + if($eq _type this.type) + option(value=_type selected="selected") {{_ _type}} + else + option(value=_type) {{_ _type}} + input(type="hidden" value=this.type name="_type") + input(type="hidden" value=_id name="id") input.primary.wide(type="submit" value="{{_ 'save'}}") form.integration-form - h4 - | {{_ 'new-outgoing-webhook'}} - label - | URL - input.js-outgoing-webhooks-url(type="text" name="url" autofocus) - input.primary.wide(type="submit" value="{{_ 'save'}}") + input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" autofocus) + input.js-outgoing-webhooks-url(placeholder="{{_ 'URL' }}" type="text" name="url") + input.js-outgoing-webhooks-token(placeholder="{{_ 'webhook-token' }}" type="text" name="token") + select.js-outgoing-webhooks-type(name="type") + each _type in types + option(value=_type) {{_ _type}} + input.primary.wide(type="submit" value="{{_ 'create'}}") template(name="boardMenuPopup") ul.pop-over-list diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index f7efb1e8..f1ccfb1e 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -1,6 +1,8 @@ Sidebar = null; const defaultView = 'home'; +const MCB = '.materialCheckBox'; +const CKCLS = 'is-checked'; const viewTitles = { filter: 'filter-cards', @@ -280,44 +282,71 @@ Template.membersWidget.events({ }); BlazeComponent.extendComponent({ + boardId() { + return Session.get('currentBoard') || Integrations.Const.GLOBAL_WEBHOOK_ID; + }, integrations() { - const boardId = Session.get('currentBoard'); + const boardId = this.boardId(); return Integrations.find({ boardId: `${boardId}` }).fetch(); }, - - integration(id) { - const boardId = Session.get('currentBoard'); - return Integrations.findOne({ _id: id, boardId: `${boardId}` }); + types() { + return Integrations.Const.WEBHOOK_TYPES; + }, + integration(cond) { + const boardId = this.boardId(); + const condition = { boardId, ...cond }; + for (const k in condition) { + if (!condition[k]) delete condition[k]; + } + return Integrations.findOne(condition); + }, + onCreated() { + this.disabled = new ReactiveVar(false); }, - events() { return [ { + 'click a.flex'(evt) { + this.disabled.set(!this.disabled.get()); + $(evt.target).toggleClass(CKCLS, this.disabled.get()); + }, submit(evt) { evt.preventDefault(); const url = evt.target.url.value; - const boardId = Session.get('currentBoard'); + const boardId = this.boardId(); let id = null; let integration = null; + const title = evt.target.title.value; + const token = evt.target.token.value; + const type = evt.target.type.value; + const enabled = !this.disabled.get(); + let remove = false; + const values = { + url, + type, + token, + title, + enabled, + }; if (evt.target.id) { id = evt.target.id.value; - integration = this.integration(id); - if (url) { - Integrations.update(integration._id, { - $set: { - url: `${url}`, - }, - }); - } else { - Integrations.remove(integration._id); - } + integration = this.integration({ _id: id }); + remove = !url; + } else if (url) { + integration = this.integration({ url, token }); + } + if (remove) { + Integrations.remove(integration._id); + } else if (integration && integration._id) { + Integrations.update(integration._id, { + $set: values, + }); } else if (url) { Integrations.insert({ + ...values, userId: Meteor.userId(), enabled: true, - type: 'outgoing-webhooks', - url: `${url}`, - boardId: `${boardId}`, + boardId, activities: ['all'], }); } @@ -474,12 +503,12 @@ BlazeComponent.extendComponent({ evt.preventDefault(); this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks; this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks); - $('.js-field-has-subtasks .materialCheckBox').toggleClass( - 'is-checked', + $(`.js-field-has-subtasks ${MCB}`).toggleClass( + CKCLS, this.currentBoard.allowsSubtasks, ); $('.js-field-has-subtasks').toggleClass( - 'is-checked', + CKCLS, this.currentBoard.allowsSubtasks, ); $('.js-field-deposit-board').prop( @@ -515,15 +544,12 @@ BlazeComponent.extendComponent({ ]; options.forEach(function(element) { if (element !== value) { - $(`#${element} .materialCheckBox`).toggleClass( - 'is-checked', - false, - ); - $(`#${element}`).toggleClass('is-checked', false); + $(`#${element} ${MCB}`).toggleClass(CKCLS, false); + $(`#${element}`).toggleClass(CKCLS, false); } }); - $(`#${value} .materialCheckBox`).toggleClass('is-checked', true); - $(`#${value}`).toggleClass('is-checked', true); + $(`#${value} ${MCB}`).toggleClass(CKCLS, true); + $(`#${value}`).toggleClass(CKCLS, true); this.currentBoard.setPresentParentTask(value); evt.preventDefault(); }, diff --git a/client/lib/utils.js b/client/lib/utils.js index 81835929..cc3526c0 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -23,7 +23,6 @@ Utils = { }) ); }, - MAX_IMAGE_PIXEL: Meteor.settings.public.MAX_IMAGE_PIXEL, COMPRESS_RATIO: Meteor.settings.public.IMAGE_COMPRESS_RATIO, processUploadedAttachment(card, fileObj, callback) { -- cgit v1.2.3-1-g7c22 From 0cf9a7b552a8036158d5b158f875057b9aaf5fc0 Mon Sep 17 00:00:00 2001 From: justinr1234 Date: Mon, 26 Aug 2019 12:16:21 -0500 Subject: Fix last label undefined --- client/components/activities/activities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js index 05149826..b082273a 100644 --- a/client/components/activities/activities.js +++ b/client/components/activities/activities.js @@ -85,7 +85,7 @@ BlazeComponent.extendComponent({ const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById( lastLabelId, ); - if (lastLabel.name === undefined || lastLabel.name === '') { + if (lastLabel && (lastLabel.name === undefined || lastLabel.name === '')) { return lastLabel.color; } else { return lastLabel.name; -- cgit v1.2.3-1-g7c22 From a97360dcfba2bf1dd1be115dd91dd1dde49ded69 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 26 Aug 2019 23:24:13 +0300 Subject: Try to fix lint, and make board loading fix Sandstorm-only where user permissions work differently. Thanks to xet7 ! Related https://github.com/wekan/wekan/pull/2654 --- client/components/lists/listBody.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'client') diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index a1a4c11a..c8e41a0b 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -701,8 +701,23 @@ BlazeComponent.extendComponent({ this.listId = this.parentComponent().data()._id; this.swimlaneId = ''; - let user = Meteor.user(); - if (user) { + const isSandstorm = + Meteor.settings && + Meteor.settings.public && + Meteor.settings.public.sandstorm; + + if (isSandstorm) { + const user = Meteor.user(); + if (user) { + const boardView = (Meteor.user().profile || {}).boardView; + if (boardView === 'board-view-swimlanes') { + this.swimlaneId = this.parentComponent() + .parentComponent() + .parentComponent() + .data()._id; + } + } + } else { const boardView = (Meteor.user().profile || {}).boardView; if (boardView === 'board-view-swimlanes') { this.swimlaneId = this.parentComponent() -- cgit v1.2.3-1-g7c22 From b7c5ba3d1b97bc33c95618cefbd0416d78a4d4dc Mon Sep 17 00:00:00 2001 From: Steffen Date: Thu, 29 Aug 2019 13:53:40 +0200 Subject: add card color to calendar event (#2651) --- client/components/boards/boardBody.js | 1 + client/components/boards/boardBody.styl | 78 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 6cff5ab1..07cd306a 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -326,6 +326,7 @@ BlazeComponent.extendComponent({ slug: currentBoard.slug, cardId: card._id, }), + className: card.color ? `calendar-event-${card.color}` : null, }); }); callback(events); diff --git a/client/components/boards/boardBody.styl b/client/components/boards/boardBody.styl index dfaaa050..32207d82 100644 --- a/client/components/boards/boardBody.styl +++ b/client/components/boards/boardBody.styl @@ -53,3 +53,81 @@ position() padding: 0 0px 0px 0 overflow-x: hidden overflow-y: auto + +calendar-event-color(background, borderColor, color...) + background: background !important + border-color: borderColor + if color + color: color !important //overwrite text for better visibility + +.calendar-event-green + calendar-event-color(#3cb500, #2a8000, #ffffff) //White text for better visibility + +.calendar-event-yellow + calendar-event-color(#fad900, #c7ac00, #000) //Black text for better visibility + +.calendar-event-orange + calendar-event-color(#ff9f19, #cc7c14, #000) //Black text for better visibility + +.calendar-event-red + calendar-event-color(#eb4646, #b83737, #ffffff) //White text for better visibility + +.calendar-event-purple + calendar-event-color(#a632db, #7d26a6, #ffffff) //White text for better visibility + +.calendar-event-blue + calendar-event-color(#0079bf, #005a8a, #ffffff) //White text for better visibility + +.calendar-event-pink + calendar-event-color(#ff78cb, #cc62a3, #000) //Black text for better visibility + +.calendar-event-sky + calendar-event-color(#00c2e0, #0094ab, #ffffff) //White text for better visibility + +.calendar-event-black + calendar-event-color(#4d4d4d, #1a1a1a, #ffffff) //White text for better visibility + +.calendar-event-lime + calendar-event-color(#51e898, #3eb375, #000) //Black text for better visibility + +.calendar-event-silver + calendar-event-color(#c0c0c0, #8c8c8c, #000) //Black text for better visibility + +.calendar-event-peachpuff + calendar-event-color(#ffdab9, #ccaf95, #000) //Black text for better visibility + +.calendar-event-crimson + calendar-event-color(#dc143c, #a8112f, #ffffff) //White text for better visibility + +.calendar-event-plum + calendar-event-color(#dda0dd, #a87ba8, #000) //Black text for better visibility + +.calendar-event-darkgreen + calendar-event-color(#006400, #003000, #ffffff) //White text for better visibility + +.calendar-event-slateblue + calendar-event-color(#6a5acd, #4f4399, #ffffff) //White text for better visibility + +.calendar-event-magenta + calendar-event-color(#ff00ff, #cc00cc, #ffffff) //White text for better visibility + +.calendar-event-gold + calendar-event-color(#ffd700, #ccaa00, #000) //Black text for better visibility + +.calendar-event-navy + calendar-event-color(#000080, #000033, #ffffff) //White text for better visibility + +.calendar-event-gray + calendar-event-color(#808080, #333333, #ffffff) //White text for better visibility + +.calendar-event-saddlebrown + calendar-event-color(#8b4513, #572b0c, #ffffff) //White text for better visibility + +.calendar-event-paleturquoise + calendar-event-color(#afeeee, #8ababa, #000) //Black text for better visibility + +.calendar-event-mistyrose + calendar-event-color(#ffe4e1, #ccb8b6, #000) //Black text for better visibility + +.calendar-event-indigo + calendar-event-color(#4b0082, #2b004d, #ffffff) //White text for better visibility -- cgit v1.2.3-1-g7c22 From 663ba26d4dd0bba8330496a76035b1674031a299 Mon Sep 17 00:00:00 2001 From: guillaume Date: Fri, 30 Aug 2019 17:17:25 +0200 Subject: Patch admin search feature --- client/components/settings/peopleBody.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'client') diff --git a/client/components/settings/peopleBody.js b/client/components/settings/peopleBody.js index a9f2247c..8610034e 100644 --- a/client/components/settings/peopleBody.js +++ b/client/components/settings/peopleBody.js @@ -17,7 +17,7 @@ BlazeComponent.extendComponent({ this.autorun(() => { const limit = this.page.get() * usersPerPage; - this.subscribe('people', limit, () => { + this.subscribe('people', this.findUsersOptions.get(), limit, () => { this.loadNextPageLocked = false; const nextPeakBefore = this.callFirstWith(null, 'getNextPeak'); this.calculateNextPeak(); @@ -85,7 +85,7 @@ BlazeComponent.extendComponent({ const users = Users.find(this.findUsersOptions.get(), { fields: { _id: true }, }); - this.number.set(users.count()); + this.number.set(users.count(false)); return users; }, peopleNumber() { -- cgit v1.2.3-1-g7c22 From 74b5bdf2aa66a2b4ea94d4ecbd7f5f63eaf1f5eb Mon Sep 17 00:00:00 2001 From: Justin Reynolds Date: Fri, 6 Sep 2019 17:18:06 -0500 Subject: Fix #2451 unable to drag select text without closing card details --- client/components/cards/cardDetails.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index cd8813f5..47941560 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -321,6 +321,19 @@ BlazeComponent.extendComponent({ parentComponent.showOverlay.set(true); parentComponent.mouseHasEnterCardDetails = true; }, + 'mousedown .js-card-details'() { + Session.set('cardDetailsIsDragging', false); + Session.set('cardDetailsIsMouseDown', true); + }, + 'mousemove .js-card-details'() { + if (Session.get('cardDetailsIsMouseDown')) { + Session.set('cardDetailsIsDragging', true); + } + }, + 'mouseup .js-card-details'() { + Session.set('cardDetailsIsDragging', false); + Session.set('cardDetailsIsMouseDown', false); + }, 'click #toggleButton'() { Meteor.call('toggleSystemMessages'); }, @@ -777,7 +790,14 @@ BlazeComponent.extendComponent({ EscapeActions.register( 'detailsPane', () => { - Utils.goBoardId(Session.get('currentBoard')); + if (Session.get('cardDetailsIsDragging')) { + // Reset dragging status as the mouse landed outside the cardDetails template area and this will prevent a mousedown event from firing + Session.set('cardDetailsIsDragging', false); + Session.set('cardDetailsIsMouseDown', false); + } else { + // Prevent close card when the user is selecting text and moves the mouse cursor outside the card detail area + Utils.goBoardId(Session.get('currentBoard')); + } }, () => { return !Session.equals('currentCard', null); -- cgit v1.2.3-1-g7c22 From e0046032e865dca408ceb78d0afbdec723cb3e28 Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Wed, 11 Sep 2019 09:05:16 -0400 Subject: Fixing @user in comments doesn't work if it's in a separate line --- client/components/main/layouts.styl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'client') diff --git a/client/components/main/layouts.styl b/client/components/main/layouts.styl index 56c35284..01ce2f16 100644 --- a/client/components/main/layouts.styl +++ b/client/components/main/layouts.styl @@ -381,6 +381,10 @@ a display: block word-wrap: break-word + table + word-wrap: normal + word-break: normal + ol list-style-type: decimal padding-left: 20px -- cgit v1.2.3-1-g7c22 From 03d7fc02ecc90690e1282d417f35b7e4561af066 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 17 Sep 2019 01:39:10 +0300 Subject: Drag handles. In Progress. --- client/components/boards/boardBody.js | 2 +- client/components/cards/minicard.jade | 9 +++- client/components/cards/minicard.js | 3 ++ client/components/cards/minicard.styl | 2 +- client/components/lists/list.js | 14 ++++++- client/components/lists/list.styl | 22 +++++++--- client/components/lists/listHeader.jade | 4 ++ client/components/lists/listHeader.js | 6 +++ client/components/swimlanes/swimlaneHeader.jade | 2 + client/components/swimlanes/swimlaneHeader.js | 6 +++ client/components/swimlanes/swimlanes.js | 56 +++++++++++++++++++++---- client/components/swimlanes/swimlanes.styl | 8 ++++ client/components/users/userHeader.jade | 5 +++ client/components/users/userHeader.js | 6 +++ 14 files changed, 127 insertions(+), 18 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 07cd306a..713b6cbc 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -89,7 +89,7 @@ BlazeComponent.extendComponent({ helper.append(list.clone()); return helper; }, - handle: '.js-swimlane-header', + handle: '.js-swimlane-header-handle', items: '.swimlane:not(.placeholder)', placeholder: 'swimlane placeholder', distance: 7, diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 3806ce41..a3f32304 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -3,6 +3,13 @@ template(name="minicard") class="{{#if isLinkedCard}}linked-card{{/if}}" class="{{#if isLinkedBoard}}linked-board{{/if}}" class="minicard-{{colorClass}}") + if isMiniScreen + .handle + .fa.fa-arrows + unless isMiniScreen + if showDesktopDragHandles + .handle + .fa.fa-arrows if cover .minicard-cover(style="background-image: url('{{cover.url}}');") if labels @@ -15,8 +22,6 @@ template(name="minicard") if hiddenMinicardLabelText .minicard-label(class="card-label-{{color}}" title="{{name}}") .minicard-title - .handle - .fa.fa-arrows if $eq 'prefix-with-full-path' currentBoard.presentParentTask .parent-prefix | {{ parentString ' > ' }} diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 4c25c11d..4c76db46 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -26,6 +26,9 @@ BlazeComponent.extendComponent({ }).register('minicard'); Template.minicard.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, hiddenMinicardLabelText() { return Meteor.user().hasHiddenMinicardLabelText(); }, diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index c4172572..9997fd5f 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -105,7 +105,7 @@ right: 5px; top: 5px; display:none; - @media only screen and (max-width: 1199px) { + @media only screen { display:block; } .fa-arrows diff --git a/client/components/lists/list.js b/client/components/lists/list.js index c2b39be9..b7b8b2e0 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -31,7 +31,13 @@ BlazeComponent.extendComponent({ const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)'; const $cards = this.$('.js-minicards'); - if (window.matchMedia('(max-width: 1199px)').matches) { + if (Utils.isMiniScreen) { + $('.js-minicards').sortable({ + handle: '.handle', + }); + } + + if (!Utils.isMiniScreen && showDesktopDragHandles) { $('.js-minicards').sortable({ handle: '.handle', }); @@ -155,6 +161,12 @@ BlazeComponent.extendComponent({ }, }).register('list'); +Template.list.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + Template.miniList.events({ 'click .js-select-list'() { const listId = this._id; diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 81938c1a..459481ea 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -84,17 +84,16 @@ padding-left: 10px color: #a6a6a6 - .list-header-menu position: absolute padding: 27px 19px margin-top: 1px top: -7px - right: -7px + right: 3px .list-header-plus-icon color: #a6a6a6 - margin-right: 10px + margin-right: 15px .highlight color: #ce1414 @@ -165,7 +164,12 @@ @media screen and (max-width: 800px) .list-header-menu - margin-right: 30px + position: absolute + padding: 27px 19px + margin-top: 1px + top: -7px + margin-right: 50px + right: -3px .mini-list flex: 0 0 60px @@ -221,9 +225,17 @@ padding: 7px top: 50% transform: translateY(-50%) - right: 17px + margin-right: 27px font-size: 20px + .list-header-menu-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + right: 10px + font-size: 24px + .link-board-wrapper display: flex align-items: baseline diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index f930e57a..6a61a66f 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -29,8 +29,10 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu + a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle else a.list-header-menu-icon.fa.fa-angle-right.js-select-list + a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle else if currentUser.isBoardMember if isWatching i.list-header-watch-icon.fa.fa-eye @@ -39,6 +41,8 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu + if showDesktopDragHandles + a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle template(name="editListTitleForm") .list-composer diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index e8a82499..5b7232cd 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -80,6 +80,12 @@ BlazeComponent.extendComponent({ }, }).register('listHeader'); +Template.listHeader.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + Template.listActionPopup.helpers({ isWipLimitEnabled() { return Template.currentData().getWipLimit('enabled'); diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 8c6aa5a3..fb6ef21d 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -16,6 +16,8 @@ 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 + if showDesktopDragHandles + a.swimlane-header-menu-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..6f8029fd 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -28,6 +28,12 @@ BlazeComponent.extendComponent({ }, }).register('swimlaneHeader'); +Template.swimlaneHeader.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + Template.swimlaneActionPopup.events({ 'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'), 'click .js-close-swimlane'(event) { diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index e0857003..33a7991e 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -53,10 +53,21 @@ function initSortable(boardComponent, $listsDom) { }, }; + if (Utils.isMiniScreen) { + $listsDom.sortable({ + handle: '.js-list-handle', + }); + } + + if (!Utils.isMiniScreen && showDesktopDragHandles) { + $listsDom.sortable({ + handle: '.js-list-header', + }); + } + $listsDom.sortable({ tolerance: 'pointer', helper: 'clone', - handle: '.js-list-header', items: '.js-list:not(.js-list-composer)', placeholder: 'list placeholder', distance: 7, @@ -151,13 +162,39 @@ 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', - ]; + + if (Utils.isMiniScreen) { + const noDragInside = [ + 'a', + 'input', + 'textarea', + 'p', + '.js-list-handle', + '.js-swimlane-header-handle', + ]; + } + + if (!Utils.isMiniScreen && !showDesktopDragHandles) { + const noDragInside = [ + 'a', + 'input', + 'textarea', + 'p', + '.js-list-header', + ]; + } + + if (!Utils.isMiniScreen && showDesktopDragHandles) { + const noDragInside = [ + 'a', + 'input', + 'textarea', + 'p', + '.js-list-handle', + '.js-swimlane-header-handle', + ]; + } + if ( $(evt.target).closest(noDragInside.join(',')).length === 0 && this.$('.swimlane').prop('clientHeight') > evt.offsetY @@ -233,6 +270,9 @@ BlazeComponent.extendComponent({ }).register('addListForm'); Template.swimlane.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, canSeeAddList() { return ( Meteor.user() && diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 1056e1e3..503091ee 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -50,6 +50,14 @@ margin-left: 5px margin-right: 10px + .swimlane-header-menu-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 300px + font-size: 18px + .list-group height: 100% diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 946bdab1..50a80396 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -78,6 +78,11 @@ template(name="changeSettingsPopup") | {{_ 'hide-system-messages'}} if hiddenSystemMessages i.fa.fa-check + li + a.js-toggle-desktop-drag-handles + | {{_ 'show-desktop-drag-handles'}} + if showDesktopDragHandles + i.fa.fa-check li label.bold | {{_ 'show-cards-minimum-count'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 36fb2020..194f990f 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -161,6 +161,9 @@ Template.changeLanguagePopup.events({ }); Template.changeSettingsPopup.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, hiddenSystemMessages() { return Meteor.user().hasHiddenSystemMessages(); }, @@ -170,6 +173,9 @@ Template.changeSettingsPopup.helpers({ }); Template.changeSettingsPopup.events({ + 'click .js-toggle-desktop-drag-handles'() { + Meteor.call('toggleDesktopDragHandles'); + }, 'click .js-toggle-system-messages'() { Meteor.call('toggleSystemMessages'); }, -- cgit v1.2.3-1-g7c22 From 194b6ad46e2d711ad5ab5e5df6d97ccea38acea8 Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Tue, 17 Sep 2019 09:27:23 -0400 Subject: BugFix: in richer editor @ autocomplete doesn't really insert the user name into comment properly --- client/components/main/editor.js | 34 ++++++++++++++++++++++++++++------ client/lib/textComplete.js | 1 + 2 files changed, 29 insertions(+), 6 deletions(-) (limited to 'client') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 91403086..2035f62f 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -156,25 +156,47 @@ Template.editor.onRendered(() => { } return undefined; }; + let popupShown = false; inputs.each(function(idx, input) { mSummernotes[idx] = $(input).summernote({ placeholder, callbacks: { + onKeydown(e) { + if (popupShown) { + e.preventDefault(); + } + }, + onKeyup(e) { + if (popupShown) { + e.preventDefault(); + } + }, onInit(object) { const originalInput = this; + const setAutocomplete = function(jEditor) { + if (jEditor !== undefined) { + jEditor.escapeableTextComplete(mentions).on({ + 'textComplete:show'() { + popupShown = true; + }, + 'textComplete:hide'() { + popupShown = false; + }, + }); + } + }; $(originalInput).on('submitted', function() { // resetCommentInput has been called if (!this.value) { const sn = getSummernote(this); - sn && sn.summernote('reset'); - object && object.editingArea.find('.note-placeholder').show(); + sn && sn.summernote('code', ''); + setAutocomplete(jEditor); + //object && object.editingArea.find('.note-placeholder').show(); } }); const jEditor = object && object.editable; const toolbar = object && object.toolbar; - if (jEditor !== undefined) { - jEditor.escapeableTextComplete(mentions); - } + setAutocomplete(jEditor); if (toolbar !== undefined) { const fBtn = toolbar.find('.btn-fullscreen'); fBtn.on('click', function() { @@ -264,7 +286,7 @@ Template.editor.onRendered(() => { const someNote = getSummernote(object); const original = someNote.summernote('code'); const cleaned = cleanPastedHTML(original); //this is where to call whatever clean function you want. I have mine in a different file, called CleanPastedHTML. - someNote.summernote('reset'); //clear original + someNote.summernote('code', ''); //clear original someNote.summernote('pasteHTML', cleaned); //this sets the displayed content editor to the cleaned pasted code. }; setTimeout(function() { diff --git a/client/lib/textComplete.js b/client/lib/textComplete.js index 0261d7f6..8b6dc1f7 100644 --- a/client/lib/textComplete.js +++ b/client/lib/textComplete.js @@ -45,6 +45,7 @@ $.fn.escapeableTextComplete = function(strategies, options, ...otherArgs) { }); }, }); + return this; }; EscapeActions.register('textcomplete', () => {}, () => dropdownMenuIsOpened, { -- cgit v1.2.3-1-g7c22 From f29d7daa1d687df535a7c6ac5c53cc6f067c44cb Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Tue, 17 Sep 2019 09:30:26 -0400 Subject: BugFix: in richer editor @ autocomplete doesn't really insert the user name into comment properly --- client/components/main/editor.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'client') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 2035f62f..b1725227 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -190,8 +190,6 @@ Template.editor.onRendered(() => { if (!this.value) { const sn = getSummernote(this); sn && sn.summernote('code', ''); - setAutocomplete(jEditor); - //object && object.editingArea.find('.note-placeholder').show(); } }); const jEditor = object && object.editable; -- cgit v1.2.3-1-g7c22 From 4ee88e026e86ab26757d46c9dadffa5005a7740f Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Thu, 19 Sep 2019 15:16:48 -0400 Subject: Buxfixed: if username contains space, it will cause @ commment failed to send out email and other --- client/components/main/editor.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'client') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index b1725227..39c03aa9 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -94,7 +94,13 @@ Template.editor.onRendered(() => { currentBoard .activeMembers() .map(member => { - const username = Users.findOne(member.userId).username; + const user = Users.findOne(member.userId); + if (user._id === Meteor.userId()) { + return null; + } + const value = user.username; + const username = + value && value.match(/\s+/) ? `"${value}"` : value; return username.includes(term) ? username : null; }) .filter(Boolean), @@ -120,9 +126,10 @@ Template.editor.onRendered(() => { ? [ ['view', ['fullscreen']], ['table', ['table']], - ['font', ['bold', 'underline']], - //['fontsize', ['fontsize']], + ['font', ['bold']], ['color', ['color']], + ['insert', ['video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled + //['fontsize', ['fontsize']], ] : [ ['style', ['style']], @@ -345,11 +352,12 @@ Blaze.Template.registerHelper( } return member; }); - const mentionRegex = /\B@([\w.]*)/gi; + const mentionRegex = /\B@(?:(?:"([\w.\s]*)")|([\w.]+))/gi; // including space in username let currentMention; while ((currentMention = mentionRegex.exec(content)) !== null) { - const [fullMention, username] = currentMention; + const [fullMention, quoteduser, simple] = currentMention; + const username = quoteduser || simple; const knowedUser = _.findWhere(knowedUsers, { username }); if (!knowedUser) { continue; -- cgit v1.2.3-1-g7c22 From 872ed4b2f934e9df7a3f4acd63bade013af2d1e9 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 25 Sep 2019 20:49:19 +0300 Subject: Drag handles continue. In progress. --- client/components/lists/list.js | 6 ++++++ client/components/swimlanes/swimlanes.js | 1 + 2 files changed, 7 insertions(+) (limited to 'client') diff --git a/client/components/lists/list.js b/client/components/lists/list.js index b7b8b2e0..023ba358 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -43,6 +43,12 @@ BlazeComponent.extendComponent({ }); } + if (!Utils.isMiniScreen && !showDesktopDragHandles) { + $('.js-minicards').sortable({ + handle: 'list-header', + }); + } + $cards.sortable({ connectWith: '.js-minicards:not(.js-list-full)', tolerance: 'pointer', diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 33a7991e..2c916e4d 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -68,6 +68,7 @@ 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, -- cgit v1.2.3-1-g7c22 From 62b72a03c4889377169411c8cdbf372c71cac1af Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Thu, 26 Sep 2019 10:53:40 -0400 Subject: Add feature: Add due timeline into Calendar view --- client/components/boards/boardBody.js | 52 ++++++++++++++++++++++++----------- client/lib/datepicker.js | 10 ++++++- 2 files changed, 45 insertions(+), 17 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 07cd306a..d64636f4 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -309,26 +309,46 @@ BlazeComponent.extendComponent({ events(start, end, timezone, callback) { const currentBoard = Boards.findOne(Session.get('currentBoard')); const events = []; + const pushEvent = function(card, title, start, end, extraCls) { + start = start || card.startAt; + end = end || card.endAt; + title = title || card.title; + const className = + (extraCls ? `${extraCls} ` : '') + + (card.color ? `calendar-event-${card.color}` : ''); + events.push({ + id: card._id, + title, + start, + end: end || card.endAt, + allDay: + Math.abs(end.getTime() - start.getTime()) / 1000 === 24 * 3600, + url: FlowRouter.url('card', { + boardId: currentBoard._id, + slug: currentBoard.slug, + cardId: card._id, + }), + className, + }); + }; currentBoard .cardsInInterval(start.toDate(), end.toDate()) .forEach(function(card) { - events.push({ - id: card._id, - title: card.title, - start: card.startAt, - end: card.endAt, - allDay: - Math.abs(card.endAt.getTime() - card.startAt.getTime()) / - 1000 === - 24 * 3600, - url: FlowRouter.url('card', { - boardId: currentBoard._id, - slug: currentBoard.slug, - cardId: card._id, - }), - className: card.color ? `calendar-event-${card.color}` : null, - }); + pushEvent(card); + }); + currentBoard + .cardsDueInBetween(start.toDate(), end.toDate()) + .forEach(function(card) { + pushEvent( + card, + `${card.title} ${TAPi18n.__('card-due')}`, + card.dueAt, + new Date(card.dueAt.getTime() + 36e5), + ); }); + events.sort(function(first, second) { + return first.id > second.id ? 1 : -1; + }); callback(events); }, eventResize(event, delta, revertFunc) { diff --git a/client/lib/datepicker.js b/client/lib/datepicker.js index eb5b60b8..da44bbc5 100644 --- a/client/lib/datepicker.js +++ b/client/lib/datepicker.js @@ -21,7 +21,15 @@ DatePicker = BlazeComponent.extendComponent({ function(evt) { this.find('#date').value = moment(evt.date).format('L'); this.error.set(''); - this.find('#time').focus(); + const timeInput = this.find('#time'); + timeInput.focus(); + if (!timeInput.value) { + const currentHour = evt.date.getHours(); + const defaultMoment = moment( + currentHour > 0 ? evt.date : '1970-01-01 08:00:00', + ); // default to 8:00 am local time + timeInput.value = defaultMoment.format('LT'); + } }.bind(this), ); -- cgit v1.2.3-1-g7c22 From 98c38fe58f597cbc0389676ae880704a671e480b Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 1 Oct 2019 00:48:36 +0300 Subject: Drag handles continue. In progress. Thanks to xet7 ! --- client/components/cards/cardDetails.js | 3 ++- client/components/cards/checklists.jade | 7 +++++ client/components/cards/checklists.js | 19 ++++++++++---- client/components/cards/checklists.styl | 19 ++++++++++++-- client/components/lists/list.js | 1 + client/components/lists/list.styl | 10 ++++++- client/components/lists/listHeader.jade | 3 ++- client/components/swimlanes/swimlaneHeader.jade | 7 +++-- client/components/swimlanes/swimlanes.js | 35 ++++++++++++++----------- client/components/swimlanes/swimlanes.styl | 8 ++++++ 10 files changed, 84 insertions(+), 28 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 47941560..ad0ee1a6 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -165,7 +165,8 @@ BlazeComponent.extendComponent({ $checklistsDom.sortable({ tolerance: 'pointer', helper: 'clone', - handle: '.checklist-title', + //handle: '.checklist-title', + handle: '.checklist-item-handle', items: '.js-checklist', placeholder: 'checklist placeholder', distance: 7, diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 279d3671..5cc82211 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -31,10 +31,12 @@ template(name="checklistDetail") h2.title.js-open-inlined-form.is-editable +viewer = checklist.title + a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle else h2.title +viewer = checklist.title + a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle +checklistItems(checklist = checklist) template(name="checklistDeleteDialog") @@ -75,6 +77,11 @@ template(name="checklistItems") +editChecklistItemForm(type = 'item' item = item checklist = checklist) else +checklistItemDetail(item = item checklist = checklist) + if isMiniScreen + a.checklist-item-handle.handle.fa.fa-arrows.js-checklist-item-handle + unless isMiniScreen + if showDesktopDragHandles + a.checklist-item-handle.handle.fa.fa-arrows.js-checklist-item-handle if canModifyCard +inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist = checklist) +addChecklistItemForm diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 57939eb8..1a3a3265 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -4,11 +4,11 @@ function initSorting(items) { items.sortable({ tolerance: 'pointer', helper: 'clone', - items: '.js-checklist-item:not(.placeholder)', + items: '.js-checklist-item-handle:not(.placeholder)', connectWith: '.js-checklist-items', appendTo: '.board-canvas', distance: 7, - placeholder: 'checklist-item placeholder', + placeholder: 'checklist-item-handle placeholder', scroll: false, start(evt, ui) { ui.placeholder.height(ui.helper.height()); @@ -17,11 +17,11 @@ function initSorting(items) { stop(evt, ui) { const parent = ui.item.parents('.js-checklist-items'); const checklistId = Blaze.getData(parent.get(0)).checklist._id; - let prevItem = ui.item.prev('.js-checklist-item').get(0); + let prevItem = ui.item.prev('.js-checklist-item-handle').get(0); if (prevItem) { prevItem = Blaze.getData(prevItem).item; } - let nextItem = ui.item.next('.js-checklist-item').get(0); + let nextItem = ui.item.next('.js-checklist-item-handle').get(0); if (nextItem) { nextItem = Blaze.getData(nextItem).item; } @@ -38,7 +38,7 @@ function initSorting(items) { }); // ugly touch event hotfix - enableClickOnTouch('.js-checklist-item:not(.placeholder)'); + enableClickOnTouch('.js-checklist-item-handle:not(.placeholder)'); } BlazeComponent.extendComponent({ @@ -197,6 +197,12 @@ BlazeComponent.extendComponent({ }, }).register('checklists'); +Template.checklists.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + Template.checklistDeleteDialog.onCreated(() => { const $cardDetails = this.$('.card-details'); this.scrollState = { @@ -231,6 +237,9 @@ Template.checklistItemDetail.helpers({ !Meteor.user().isCommentOnly() ); }, + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, }); BlazeComponent.extendComponent({ diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl index 8ac37a15..a383a128 100644 --- a/client/components/cards/checklists.styl +++ b/client/components/cards/checklists.styl @@ -35,6 +35,14 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &.is-finished color: #3cb500 + .checklist-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 100px + font-size: 18px + .js-delete-checklist @extends .delete-text @@ -70,7 +78,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item margin-left: 12% float: left .toggle-delete-checklist-dialog - margin-right: 12% + margin-right: 20% float: right #card-details-overlay @@ -125,12 +133,19 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &.is-checked color: #8c8c8c font-style: italic - & .viewer + &.viewer p margin-bottom: 2px display: block word-wrap: break-word max-width: 420px + .checklist-item-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 200px + font-size: 18px .js-delete-checklist-item margin: 0 0 0.5em 1.33em diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 023ba358..a134a00a 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -52,6 +52,7 @@ BlazeComponent.extendComponent({ $cards.sortable({ connectWith: '.js-minicards:not(.js-list-full)', tolerance: 'pointer', + handle: 'list-header', appendTo: '.board-canvas', helper(evt, item) { const helper = item.clone(); diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 459481ea..53de5bad 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -225,7 +225,7 @@ padding: 7px top: 50% transform: translateY(-50%) - margin-right: 27px + right: 47px font-size: 20px .list-header-menu-handle @@ -236,6 +236,14 @@ right: 10px font-size: 24px + .list-header-menu-handle-miniscreen-angle-left + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + right: 25px + font-size: 24px + .link-board-wrapper display: flex align-items: baseline diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 6a61a66f..78d0801a 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -29,9 +29,10 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu - a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle + a.list-header-menu-handle-miniscreen-angle-left.handle.fa.fa-arrows.js-list-handle else a.list-header-menu-icon.fa.fa-angle-right.js-select-list + |     a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle else if currentUser.isBoardMember if isWatching diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index fb6ef21d..dde8561e 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -16,8 +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 - if showDesktopDragHandles - a.swimlane-header-menu-handle.handle.fa.fa-arrows.js-swimlane-header-handle + if isMiniScreen + a.swimlane-header-menu-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle + unless isMiniScreen + if showDesktopDragHandles + a.swimlane-header-menu-handle.handle.fa.fa-arrows.js-swimlane-header-handle template(name="editSwimlaneTitleForm") .list-composer diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 2c916e4d..8953eb05 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -53,22 +53,9 @@ function initSortable(boardComponent, $listsDom) { }, }; - if (Utils.isMiniScreen) { - $listsDom.sortable({ - handle: '.js-list-handle', - }); - } - - if (!Utils.isMiniScreen && showDesktopDragHandles) { - $listsDom.sortable({ - handle: '.js-list-header', - }); - } - $listsDom.sortable({ tolerance: 'pointer', helper: 'clone', - handle: '.js-list-header', items: '.js-list:not(.js-list-composer)', placeholder: 'list placeholder', distance: 7, @@ -113,6 +100,22 @@ function initSortable(boardComponent, $listsDom) { // is not a board member boardComponent.autorun(() => { const $listDom = $listsDom; + + if (Utils.isMiniScreen) { + $listsDom.sortable({ + handle: '.js-list-handle', + }); + } + + if (!Utils.isMiniScreen && showDesktopDragHandles) { + $listsDom.sortable({ + handle: '.js-list-header', + }); + } + + + + if ($listDom.data('sortable')) { $listsDom.sortable( 'option', @@ -165,7 +168,7 @@ BlazeComponent.extendComponent({ // his mouse. if (Utils.isMiniScreen) { - const noDragInside = [ + noDragInside = [ 'a', 'input', 'textarea', @@ -176,7 +179,7 @@ BlazeComponent.extendComponent({ } if (!Utils.isMiniScreen && !showDesktopDragHandles) { - const noDragInside = [ + noDragInside = [ 'a', 'input', 'textarea', @@ -186,7 +189,7 @@ BlazeComponent.extendComponent({ } if (!Utils.isMiniScreen && showDesktopDragHandles) { - const noDragInside = [ + noDragInside = [ 'a', 'input', 'textarea', diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 503091ee..4fbfce4f 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -58,6 +58,14 @@ left: 300px font-size: 18px + .swimlane-header-menu-miniscreen-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 487px + font-size: 18px + .list-group height: 100% -- cgit v1.2.3-1-g7c22 From 4785086e2f4b1840d3a3059c2646363b10527d4f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 1 Oct 2019 00:58:12 +0300 Subject: Fix lint. --- client/components/swimlanes/swimlanes.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 8953eb05..54bead31 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -105,17 +105,12 @@ function initSortable(boardComponent, $listsDom) { $listsDom.sortable({ handle: '.js-list-handle', }); - } - + }; if (!Utils.isMiniScreen && showDesktopDragHandles) { $listsDom.sortable({ handle: '.js-list-header', }); - } - - - - + }; if ($listDom.data('sortable')) { $listsDom.sortable( 'option', @@ -179,13 +174,7 @@ BlazeComponent.extendComponent({ } if (!Utils.isMiniScreen && !showDesktopDragHandles) { - noDragInside = [ - 'a', - 'input', - 'textarea', - 'p', - '.js-list-header', - ]; + noDragInside = ['a', 'input', 'textarea', 'p', '.js-list-header']; } if (!Utils.isMiniScreen && showDesktopDragHandles) { -- cgit v1.2.3-1-g7c22 From 83f81f45860f79dadd600842c7b43e85fe94f018 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 1 Oct 2019 01:05:02 +0300 Subject: Fix prettier. --- client/components/swimlanes/swimlanes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 54bead31..1f4a882b 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -105,12 +105,12 @@ function initSortable(boardComponent, $listsDom) { $listsDom.sortable({ handle: '.js-list-handle', }); - }; + } if (!Utils.isMiniScreen && showDesktopDragHandles) { $listsDom.sortable({ handle: '.js-list-header', }); - }; + } if ($listDom.data('sortable')) { $listsDom.sortable( 'option', -- cgit v1.2.3-1-g7c22 From e60926f8471c05f50877f46568554e7b2f24815a Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Tue, 1 Oct 2019 10:39:36 -0400 Subject: #2738 adding all pertinent help file for due days, plus modified the .list-header-name when in mobile mode --- client/components/lists/list.styl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'client') diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 459481ea..0d3ccfce 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -171,6 +171,10 @@ margin-right: 50px right: -3px + .list-header + .list-header-name + margin-left: 1.4rem + .mini-list flex: 0 0 60px height: auto -- cgit v1.2.3-1-g7c22 From 5bc355f9a5e78df4c19764fdc4a343a46af4fdf8 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 3 Oct 2019 04:23:33 +0300 Subject: Drag handles. In progress. --- client/components/boards/boardBody.js | 2 +- client/components/cards/cardDetails.js | 3 +- client/components/cards/checklists.jade | 10 +++- client/components/cards/checklists.js | 41 +++++++++++++++-- client/components/cards/checklists.styl | 12 ++--- client/components/cards/minicard.jade | 6 +-- client/components/cards/minicard.styl | 15 +++++- client/components/lists/list.js | 39 ++++++++-------- client/components/swimlanes/swimlanes.js | 78 +++++++++++++++++--------------- 9 files changed, 133 insertions(+), 73 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 47042ae7..d64636f4 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -89,7 +89,7 @@ BlazeComponent.extendComponent({ helper.append(list.clone()); return helper; }, - handle: '.js-swimlane-header-handle', + handle: '.js-swimlane-header', items: '.swimlane:not(.placeholder)', placeholder: 'swimlane placeholder', distance: 7, diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index ad0ee1a6..47941560 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -165,8 +165,7 @@ BlazeComponent.extendComponent({ $checklistsDom.sortable({ tolerance: 'pointer', helper: 'clone', - //handle: '.checklist-title', - handle: '.checklist-item-handle', + handle: '.checklist-title', items: '.js-checklist', placeholder: 'checklist placeholder', distance: 7, diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 5cc82211..635b4092 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -31,12 +31,20 @@ template(name="checklistDetail") h2.title.js-open-inlined-form.is-editable +viewer = checklist.title + if isMiniScreen a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle + unless isMiniScreen + if showDesktopDragHandles + a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle else h2.title +viewer = checklist.title - a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle + if isMiniScreen + a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle + unless isMiniScreen + if showDesktopDragHandles + a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle +checklistItems(checklist = checklist) template(name="checklistDeleteDialog") diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 1a3a3265..2128b67d 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -4,11 +4,11 @@ function initSorting(items) { items.sortable({ tolerance: 'pointer', helper: 'clone', - items: '.js-checklist-item-handle:not(.placeholder)', + items: '.js-checklist-item:not(.placeholder)', connectWith: '.js-checklist-items', appendTo: '.board-canvas', distance: 7, - placeholder: 'checklist-item-handle placeholder', + placeholder: 'checklist-item placeholder', scroll: false, start(evt, ui) { ui.placeholder.height(ui.helper.height()); @@ -17,11 +17,11 @@ function initSorting(items) { stop(evt, ui) { const parent = ui.item.parents('.js-checklist-items'); const checklistId = Blaze.getData(parent.get(0)).checklist._id; - let prevItem = ui.item.prev('.js-checklist-item-handle').get(0); + let prevItem = ui.item.prev('.js-checklist-item').get(0); if (prevItem) { prevItem = Blaze.getData(prevItem).item; } - let nextItem = ui.item.next('.js-checklist-item-handle').get(0); + let nextItem = ui.item.next('.js-checklist-item').get(0); if (nextItem) { nextItem = Blaze.getData(nextItem).item; } @@ -38,7 +38,8 @@ function initSorting(items) { }); // ugly touch event hotfix - enableClickOnTouch('.js-checklist-item-handle:not(.placeholder)'); + enableClickOnTouch('.js-checklist-item:not(.placeholder)'); + } BlazeComponent.extendComponent({ @@ -60,6 +61,30 @@ BlazeComponent.extendComponent({ if ($itemsDom.data('sortable')) { $(self.itemsDom).sortable('option', 'disabled', !userIsMember()); } + if(Utils.isMiniScreen()) { + this.$('.js-checklists').sortable({ + handle: '.checklist-handle', + }); + this.$('.js-checklist-item').sortable({ + handle: '.checklist-item-handle', + }); + } else { + if (Meteor.user().hasShowDesktopDragHandles()) { + this.$('.js-checklists').sortable({ + handle: '.checklist-handle', + }); + this.$('.js-checklist-item').sortable({ + handle: '.checklist-item-handle', + }); + } else { + this.$('.js-checklists').sortable({ + handle: '.checklist-title', + }); + this.$('.js-checklist-item').sortable({ + handle: '.checklist-item', + }); + } + } }); }, @@ -72,6 +97,12 @@ BlazeComponent.extendComponent({ }, }).register('checklistDetail'); +Template.checklistDetail.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + BlazeComponent.extendComponent({ addChecklist(event) { event.preventDefault(); diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl index a383a128..dd3afe04 100644 --- a/client/components/cards/checklists.styl +++ b/client/components/cards/checklists.styl @@ -37,10 +37,10 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item .checklist-handle position: absolute - padding: 7px - top: 50% + float: right + padding-bottom: 30px transform: translateY(-50%) - left: 100px + left: 400px font-size: 18px .js-delete-checklist @@ -141,10 +141,10 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item max-width: 420px .checklist-item-handle position: absolute - padding: 7px - top: 50% + float: right + padding-bottom: 30px transform: translateY(-50%) - left: 200px + left: 400px font-size: 18px .js-delete-checklist-item diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index a3f32304..2bc20622 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -3,13 +3,13 @@ template(name="minicard") class="{{#if isLinkedCard}}linked-card{{/if}}" class="{{#if isLinkedBoard}}linked-board{{/if}}" class="minicard-{{colorClass}}") - if isMiniScreen - .handle - .fa.fa-arrows unless isMiniScreen if showDesktopDragHandles .handle .fa.fa-arrows + if isMiniScreen + .handle + .fa.fa-arrows if cover .minicard-cover(style="background-image: url('{{cover.url}}');") if labels diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 9997fd5f..428a7abe 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -105,12 +105,25 @@ right: 5px; top: 5px; display:none; - @media only screen { + @media only screen and (min-width: 1200px) { display:block; } .fa-arrows font-size:20px; color: #ccc; + //.handle-minicard-desktop + // width: 20px; + // height: 20px; + // position: absolute; + // right: 5px; + // top: 5px; + // display:none; + // @media only screen and (min-width: 1200px) { + // display:block; + // } + // .fa-arrows + // font-size:20px; + // color: #ccc; .minicard-title p:last-child margin-bottom: 0 diff --git a/client/components/lists/list.js b/client/components/lists/list.js index a134a00a..fa70179b 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -31,24 +31,6 @@ BlazeComponent.extendComponent({ const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)'; const $cards = this.$('.js-minicards'); - if (Utils.isMiniScreen) { - $('.js-minicards').sortable({ - handle: '.handle', - }); - } - - if (!Utils.isMiniScreen && showDesktopDragHandles) { - $('.js-minicards').sortable({ - handle: '.handle', - }); - } - - if (!Utils.isMiniScreen && !showDesktopDragHandles) { - $('.js-minicards').sortable({ - handle: 'list-header', - }); - } - $cards.sortable({ connectWith: '.js-minicards:not(.js-list-full)', tolerance: 'pointer', @@ -138,6 +120,21 @@ BlazeComponent.extendComponent({ // Disable drag-dropping if the current user is not a board member or is comment only this.autorun(() => { $cards.sortable('option', 'disabled', !userIsMember()); + if (Utils.isMiniScreen()) { + this.$('.js-minicards').sortable({ + handle: '.handle', + }); + } else { + if (Meteor.user().hasShowDesktopDragHandles()) { + this.$('.js-minicards').sortable({ + handle: '.handle', + }); + } else { + this.$('.js-minicards').sortable({ + handle: '.minicard-title', + }); + } + } }); // We want to re-run this function any time a card is added. @@ -180,3 +177,9 @@ Template.miniList.events({ Session.set('currentList', listId); }, }); + +Template.miniList.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 1f4a882b..ed53b9e9 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -56,6 +56,7 @@ 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, @@ -101,16 +102,7 @@ function initSortable(boardComponent, $listsDom) { boardComponent.autorun(() => { const $listDom = $listsDom; - if (Utils.isMiniScreen) { - $listsDom.sortable({ - handle: '.js-list-handle', - }); - } - if (!Utils.isMiniScreen && showDesktopDragHandles) { - $listsDom.sortable({ - handle: '.js-list-header', - }); - } + if ($listDom.data('sortable')) { $listsDom.sortable( 'option', @@ -118,6 +110,33 @@ function initSortable(boardComponent, $listsDom) { MultiSelection.isActive() || !userIsMember(), ); } + + + if (Utils.isMiniScreen()) { + this.$('.js-lists').sortable({ + handle: '.list-header-menu-handle', + }); + this.$('.js-swimlanes').sortable({ + handle: '.swimlane-header-menu-miniscreen-handle', + }); + } else { + if (Meteor.user().hasShowDesktopDragHandles()) { + this.$('.js-lists').sortable({ + handle: '.list-header-menu-handle', + }); + this.$('.js-swimlanes').sortable({ + handle: '.swimlane-header-menu-handle', + }); + } else { + this.$('.js-lists').sortable({ + handle: '.list-header', + }); + this.$('.js-swimlanes').sortable({ + handle: '.swimlane-header', + }); + } + } + }); } @@ -161,32 +180,13 @@ 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. - - if (Utils.isMiniScreen) { - noDragInside = [ - 'a', - 'input', - 'textarea', - 'p', - '.js-list-handle', - '.js-swimlane-header-handle', - ]; - } - - if (!Utils.isMiniScreen && !showDesktopDragHandles) { - noDragInside = ['a', 'input', 'textarea', 'p', '.js-list-header']; - } - - if (!Utils.isMiniScreen && showDesktopDragHandles) { - noDragInside = [ - 'a', - 'input', - 'textarea', - 'p', - '.js-list-handle', - '.js-swimlane-header-handle', - ]; - } + const noDragInside = [ + 'a', + 'input', + 'textarea', + 'p', + '.js-list-header', + ]; if ( $(evt.target).closest(noDragInside.join(',')).length === 0 && @@ -308,3 +308,9 @@ BlazeComponent.extendComponent({ initSortable(boardComponent, $listsDom); }, }).register('listsGroup'); + +Template.listsGroup.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); -- cgit v1.2.3-1-g7c22 From f3b858ca212bdce571b56325eaa205feda60dca2 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 3 Oct 2019 06:03:11 +0300 Subject: Revert drag handle changes. --- client/components/cards/checklists.jade | 15 ---------- client/components/cards/checklists.js | 40 ------------------------- client/components/cards/checklists.styl | 19 ++---------- client/components/cards/minicard.jade | 9 ++---- client/components/cards/minicard.js | 3 -- client/components/cards/minicard.styl | 16 ++-------- client/components/lists/list.js | 34 ++++----------------- client/components/lists/list.styl | 34 ++++----------------- client/components/lists/listHeader.jade | 5 ---- client/components/lists/listHeader.js | 6 ---- client/components/swimlanes/swimlaneHeader.jade | 5 ---- client/components/swimlanes/swimlaneHeader.js | 6 ---- client/components/swimlanes/swimlanes.js | 39 ------------------------ client/components/swimlanes/swimlanes.styl | 16 ---------- client/components/users/userHeader.jade | 5 ---- client/components/users/userHeader.js | 6 ---- 16 files changed, 17 insertions(+), 241 deletions(-) (limited to 'client') diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 635b4092..279d3671 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -31,20 +31,10 @@ template(name="checklistDetail") h2.title.js-open-inlined-form.is-editable +viewer = checklist.title - if isMiniScreen - a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle - unless isMiniScreen - if showDesktopDragHandles - a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle else h2.title +viewer = checklist.title - if isMiniScreen - a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle - unless isMiniScreen - if showDesktopDragHandles - a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle +checklistItems(checklist = checklist) template(name="checklistDeleteDialog") @@ -85,11 +75,6 @@ template(name="checklistItems") +editChecklistItemForm(type = 'item' item = item checklist = checklist) else +checklistItemDetail(item = item checklist = checklist) - if isMiniScreen - a.checklist-item-handle.handle.fa.fa-arrows.js-checklist-item-handle - unless isMiniScreen - if showDesktopDragHandles - a.checklist-item-handle.handle.fa.fa-arrows.js-checklist-item-handle if canModifyCard +inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist = checklist) +addChecklistItemForm diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 2128b67d..57939eb8 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -39,7 +39,6 @@ function initSorting(items) { // ugly touch event hotfix enableClickOnTouch('.js-checklist-item:not(.placeholder)'); - } BlazeComponent.extendComponent({ @@ -61,30 +60,6 @@ BlazeComponent.extendComponent({ if ($itemsDom.data('sortable')) { $(self.itemsDom).sortable('option', 'disabled', !userIsMember()); } - if(Utils.isMiniScreen()) { - this.$('.js-checklists').sortable({ - handle: '.checklist-handle', - }); - this.$('.js-checklist-item').sortable({ - handle: '.checklist-item-handle', - }); - } else { - if (Meteor.user().hasShowDesktopDragHandles()) { - this.$('.js-checklists').sortable({ - handle: '.checklist-handle', - }); - this.$('.js-checklist-item').sortable({ - handle: '.checklist-item-handle', - }); - } else { - this.$('.js-checklists').sortable({ - handle: '.checklist-title', - }); - this.$('.js-checklist-item').sortable({ - handle: '.checklist-item', - }); - } - } }); }, @@ -97,12 +72,6 @@ BlazeComponent.extendComponent({ }, }).register('checklistDetail'); -Template.checklistDetail.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); - BlazeComponent.extendComponent({ addChecklist(event) { event.preventDefault(); @@ -228,12 +197,6 @@ BlazeComponent.extendComponent({ }, }).register('checklists'); -Template.checklists.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); - Template.checklistDeleteDialog.onCreated(() => { const $cardDetails = this.$('.card-details'); this.scrollState = { @@ -268,9 +231,6 @@ Template.checklistItemDetail.helpers({ !Meteor.user().isCommentOnly() ); }, - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, }); BlazeComponent.extendComponent({ diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl index dd3afe04..8ac37a15 100644 --- a/client/components/cards/checklists.styl +++ b/client/components/cards/checklists.styl @@ -35,14 +35,6 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &.is-finished color: #3cb500 - .checklist-handle - position: absolute - float: right - padding-bottom: 30px - transform: translateY(-50%) - left: 400px - font-size: 18px - .js-delete-checklist @extends .delete-text @@ -78,7 +70,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item margin-left: 12% float: left .toggle-delete-checklist-dialog - margin-right: 20% + margin-right: 12% float: right #card-details-overlay @@ -133,19 +125,12 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &.is-checked color: #8c8c8c font-style: italic - &.viewer + & .viewer p margin-bottom: 2px display: block word-wrap: break-word max-width: 420px - .checklist-item-handle - position: absolute - float: right - padding-bottom: 30px - transform: translateY(-50%) - left: 400px - font-size: 18px .js-delete-checklist-item margin: 0 0 0.5em 1.33em diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 2bc20622..3806ce41 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -3,13 +3,6 @@ template(name="minicard") class="{{#if isLinkedCard}}linked-card{{/if}}" class="{{#if isLinkedBoard}}linked-board{{/if}}" class="minicard-{{colorClass}}") - unless isMiniScreen - if showDesktopDragHandles - .handle - .fa.fa-arrows - if isMiniScreen - .handle - .fa.fa-arrows if cover .minicard-cover(style="background-image: url('{{cover.url}}');") if labels @@ -22,6 +15,8 @@ template(name="minicard") if hiddenMinicardLabelText .minicard-label(class="card-label-{{color}}" title="{{name}}") .minicard-title + .handle + .fa.fa-arrows if $eq 'prefix-with-full-path' currentBoard.presentParentTask .parent-prefix | {{ parentString ' > ' }} diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 4c76db46..4c25c11d 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -26,9 +26,6 @@ BlazeComponent.extendComponent({ }).register('minicard'); Template.minicard.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, hiddenMinicardLabelText() { return Meteor.user().hasHiddenMinicardLabelText(); }, diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 428a7abe..30228063 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -105,25 +105,13 @@ right: 5px; top: 5px; display:none; - @media only screen and (min-width: 1200px) { + // @media only screen and (max-width: 1199px) { + @media only screen and (max-width: 800px) { display:block; } .fa-arrows font-size:20px; color: #ccc; - //.handle-minicard-desktop - // width: 20px; - // height: 20px; - // position: absolute; - // right: 5px; - // top: 5px; - // display:none; - // @media only screen and (min-width: 1200px) { - // display:block; - // } - // .fa-arrows - // font-size:20px; - // color: #ccc; .minicard-title p:last-child margin-bottom: 0 diff --git a/client/components/lists/list.js b/client/components/lists/list.js index fa70179b..bde43520 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -31,10 +31,15 @@ BlazeComponent.extendComponent({ const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)'; const $cards = this.$('.js-minicards'); + if (Utils.isMiniScreen()) { + $('.js-minicards').sortable({ + handle: '.handle', + }); + } + $cards.sortable({ connectWith: '.js-minicards:not(.js-list-full)', tolerance: 'pointer', - handle: 'list-header', appendTo: '.board-canvas', helper(evt, item) { const helper = item.clone(); @@ -120,21 +125,6 @@ BlazeComponent.extendComponent({ // Disable drag-dropping if the current user is not a board member or is comment only this.autorun(() => { $cards.sortable('option', 'disabled', !userIsMember()); - if (Utils.isMiniScreen()) { - this.$('.js-minicards').sortable({ - handle: '.handle', - }); - } else { - if (Meteor.user().hasShowDesktopDragHandles()) { - this.$('.js-minicards').sortable({ - handle: '.handle', - }); - } else { - this.$('.js-minicards').sortable({ - handle: '.minicard-title', - }); - } - } }); // We want to re-run this function any time a card is added. @@ -165,21 +155,9 @@ BlazeComponent.extendComponent({ }, }).register('list'); -Template.list.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); - Template.miniList.events({ 'click .js-select-list'() { const listId = this._id; Session.set('currentList', listId); }, }); - -Template.miniList.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 8523362f..81938c1a 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -84,16 +84,17 @@ padding-left: 10px color: #a6a6a6 + .list-header-menu position: absolute padding: 27px 19px margin-top: 1px top: -7px - right: 3px + right: -7px .list-header-plus-icon color: #a6a6a6 - margin-right: 15px + margin-right: 10px .highlight color: #ce1414 @@ -164,16 +165,7 @@ @media screen and (max-width: 800px) .list-header-menu - position: absolute - padding: 27px 19px - margin-top: 1px - top: -7px - margin-right: 50px - right: -3px - - .list-header - .list-header-name - margin-left: 1.4rem + margin-right: 30px .mini-list flex: 0 0 60px @@ -229,25 +221,9 @@ padding: 7px top: 50% transform: translateY(-50%) - right: 47px + right: 17px font-size: 20px - .list-header-menu-handle - position: absolute - padding: 7px - top: 50% - transform: translateY(-50%) - right: 10px - font-size: 24px - - .list-header-menu-handle-miniscreen-angle-left - position: absolute - padding: 7px - top: 50% - transform: translateY(-50%) - right: 25px - font-size: 24px - .link-board-wrapper display: flex align-items: baseline diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 78d0801a..f930e57a 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -29,11 +29,8 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu - a.list-header-menu-handle-miniscreen-angle-left.handle.fa.fa-arrows.js-list-handle else a.list-header-menu-icon.fa.fa-angle-right.js-select-list - |     - a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle else if currentUser.isBoardMember if isWatching i.list-header-watch-icon.fa.fa-eye @@ -42,8 +39,6 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu - if showDesktopDragHandles - a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle template(name="editListTitleForm") .list-composer diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 5b7232cd..e8a82499 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -80,12 +80,6 @@ BlazeComponent.extendComponent({ }, }).register('listHeader'); -Template.listHeader.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); - Template.listActionPopup.helpers({ isWipLimitEnabled() { return Template.currentData().getWipLimit('enabled'); diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index dde8561e..8c6aa5a3 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -16,11 +16,6 @@ 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 - if isMiniScreen - a.swimlane-header-menu-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle - unless isMiniScreen - if showDesktopDragHandles - a.swimlane-header-menu-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 6f8029fd..ee21d100 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -28,12 +28,6 @@ BlazeComponent.extendComponent({ }, }).register('swimlaneHeader'); -Template.swimlaneHeader.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); - Template.swimlaneActionPopup.events({ 'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'), 'click .js-close-swimlane'(event) { diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index ed53b9e9..e0857003 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -101,8 +101,6 @@ function initSortable(boardComponent, $listsDom) { // is not a board member boardComponent.autorun(() => { const $listDom = $listsDom; - - if ($listDom.data('sortable')) { $listsDom.sortable( 'option', @@ -110,33 +108,6 @@ function initSortable(boardComponent, $listsDom) { MultiSelection.isActive() || !userIsMember(), ); } - - - if (Utils.isMiniScreen()) { - this.$('.js-lists').sortable({ - handle: '.list-header-menu-handle', - }); - this.$('.js-swimlanes').sortable({ - handle: '.swimlane-header-menu-miniscreen-handle', - }); - } else { - if (Meteor.user().hasShowDesktopDragHandles()) { - this.$('.js-lists').sortable({ - handle: '.list-header-menu-handle', - }); - this.$('.js-swimlanes').sortable({ - handle: '.swimlane-header-menu-handle', - }); - } else { - this.$('.js-lists').sortable({ - handle: '.list-header', - }); - this.$('.js-swimlanes').sortable({ - handle: '.swimlane-header', - }); - } - } - }); } @@ -187,7 +158,6 @@ BlazeComponent.extendComponent({ 'p', '.js-list-header', ]; - if ( $(evt.target).closest(noDragInside.join(',')).length === 0 && this.$('.swimlane').prop('clientHeight') > evt.offsetY @@ -263,9 +233,6 @@ BlazeComponent.extendComponent({ }).register('addListForm'); Template.swimlane.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, canSeeAddList() { return ( Meteor.user() && @@ -308,9 +275,3 @@ BlazeComponent.extendComponent({ initSortable(boardComponent, $listsDom); }, }).register('listsGroup'); - -Template.listsGroup.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, -}); diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 4fbfce4f..1056e1e3 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -50,22 +50,6 @@ margin-left: 5px margin-right: 10px - .swimlane-header-menu-handle - position: absolute - padding: 7px - top: 50% - transform: translateY(-50%) - left: 300px - font-size: 18px - - .swimlane-header-menu-miniscreen-handle - position: absolute - padding: 7px - top: 50% - transform: translateY(-50%) - left: 487px - font-size: 18px - .list-group height: 100% diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 50a80396..946bdab1 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -78,11 +78,6 @@ template(name="changeSettingsPopup") | {{_ 'hide-system-messages'}} if hiddenSystemMessages i.fa.fa-check - li - a.js-toggle-desktop-drag-handles - | {{_ 'show-desktop-drag-handles'}} - if showDesktopDragHandles - i.fa.fa-check li label.bold | {{_ 'show-cards-minimum-count'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 194f990f..36fb2020 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -161,9 +161,6 @@ Template.changeLanguagePopup.events({ }); Template.changeSettingsPopup.helpers({ - showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); - }, hiddenSystemMessages() { return Meteor.user().hasHiddenSystemMessages(); }, @@ -173,9 +170,6 @@ Template.changeSettingsPopup.helpers({ }); Template.changeSettingsPopup.events({ - 'click .js-toggle-desktop-drag-handles'() { - Meteor.call('toggleDesktopDragHandles'); - }, 'click .js-toggle-system-messages'() { Meteor.call('toggleSystemMessages'); }, -- cgit v1.2.3-1-g7c22 From 68be12d166b21a41b4e2c4021b0966807e5ed1e6 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sat, 5 Oct 2019 12:52:57 +0300 Subject: More black minicard badges. Thanks to sfahrenholz and xet7 ! Closes #2745 --- client/components/cards/minicard.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 30228063..7c27cba1 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -128,7 +128,7 @@ .badges float: left margin-top: 7px - color: darken(white, 50%) + color: darken(white, 80%) &:empty display: none -- cgit v1.2.3-1-g7c22 From 3064cdd3712d2014b0e340dc04faa1efa34b209d Mon Sep 17 00:00:00 2001 From: benji <38424890+moserben16@users.noreply.github.com> Date: Wed, 9 Oct 2019 14:24:45 +0200 Subject: Update attachments.js added else condition to check if MAX_IMAGE_PIXEL is not set, so that it is possible to upload attachments using drag-and-drop or Ctrl+V without setting the environmental-variable. If this change is not allowed, please document in the wiki, that this is necessary for a fully-running wekan-instance --- client/components/cards/attachments.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'client') diff --git a/client/components/cards/attachments.js b/client/components/cards/attachments.js index 843f1eb7..59f173c9 100644 --- a/client/components/cards/attachments.js +++ b/client/components/cards/attachments.js @@ -131,6 +131,8 @@ Template.previewClipboardImagePopup.onRendered(() => { direct(results); }, }); + } else { + direct(results); } } }; -- cgit v1.2.3-1-g7c22 From 36e006fa4e78fe94e627625d1cc589654668f22a Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 9 Oct 2019 18:09:14 +0300 Subject: Fix prettier. --- client/components/cards/attachments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/cards/attachments.js b/client/components/cards/attachments.js index 59f173c9..e4439155 100644 --- a/client/components/cards/attachments.js +++ b/client/components/cards/attachments.js @@ -131,7 +131,7 @@ Template.previewClipboardImagePopup.onRendered(() => { direct(results); }, }); - } else { + } else { direct(results); } } -- cgit v1.2.3-1-g7c22 From 77f8b76d4e13c35ea3451622176bbb69a4d39a32 Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Thu, 10 Oct 2019 22:57:40 -0400 Subject: Add Features: allowing lists to be sorted by modifiedAt when not in draggable mode --- client/components/cards/minicard.jade | 2 ++ client/components/lists/listHeader.jade | 1 + client/components/swimlanes/swimlanes.jade | 16 ++++++------- client/components/swimlanes/swimlanes.js | 36 +++++------------------------- 4 files changed, 16 insertions(+), 39 deletions(-) (limited to 'client') diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index a3f32304..ba0c5707 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -58,6 +58,8 @@ template(name="minicard") if getDue .date +minicardDueDate + if getEnd + +minicardEndDate if getSpentTime .date +cardSpentTime diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 6a61a66f..23ae6282 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -9,6 +9,7 @@ template(name="listHeader") if currentList a.list-header-left-icon.fa.fa-angle-left.js-unselect-list h2.list-header-name( + title="{{ moment updatedAt 'LLL' }}" class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}js-open-inlined-form is-editable{{/unless}}{{/if}}") +viewer = title diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 3ad43777..8f07a01c 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -12,13 +12,13 @@ template(name="swimlane") unless currentUser.isCommentOnly +addListForm else + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm 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 @@ -26,20 +26,20 @@ template(name="listsGroup") if currentList +list(currentList) else - each lists - +miniList(this) if currentUser.isBoardMember unless currentUser.isCommentOnly +addListForm + each lists + +miniList(this) else + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm each lists if visible this +list(this) if currentCardIsInThisList _id null +cardDetails(currentCard) - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm template(name="addListForm") .list.list-composer.js-list-composer diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 33a7991e..1bfc0f79 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -163,37 +163,11 @@ BlazeComponent.extendComponent({ // the user will legitimately expect to be able to select some text with // his mouse. - if (Utils.isMiniScreen) { - const noDragInside = [ - 'a', - 'input', - 'textarea', - 'p', - '.js-list-handle', - '.js-swimlane-header-handle', - ]; - } - - if (!Utils.isMiniScreen && !showDesktopDragHandles) { - const noDragInside = [ - 'a', - 'input', - 'textarea', - 'p', - '.js-list-header', - ]; - } - - if (!Utils.isMiniScreen && showDesktopDragHandles) { - const noDragInside = [ - 'a', - 'input', - 'textarea', - 'p', - '.js-list-handle', - '.js-swimlane-header-handle', - ]; - } + const noDragInside = ['a', 'input', 'textarea', 'p'].concat( + Util.isMiniScreen || (!Util.isMiniScreen && showDesktopDragHandles) + ? ['.js-list-handle', '.js-swimlane-header-handle'] + : ['.js-list-header'], + ); if ( $(evt.target).closest(noDragInside.join(',')).length === 0 && -- cgit v1.2.3-1-g7c22 From bc2a20f04e32607f8488a9cecd815647fb43e40e Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Fri, 18 Oct 2019 16:44:09 -0400 Subject: Add Feature: allow user to sort Lists in Board by his own preference, boardadmin can star list --- client/components/boards/boardHeader.jade | 18 +++++ client/components/boards/boardHeader.js | 102 +++++++++++++++++++++++++- client/components/lists/listHeader.jade | 4 +- client/components/lists/listHeader.js | 18 +++++ client/components/sidebar/sidebarFilters.jade | 3 + client/components/sidebar/sidebarFilters.js | 4 + client/components/swimlanes/swimlanes.jade | 2 +- client/components/swimlanes/swimlanes.js | 5 ++ client/lib/filter.js | 20 ++++- 9 files changed, 171 insertions(+), 5 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index fe533f95..175cc2c2 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -77,6 +77,10 @@ template(name="boardHeaderBar") i.fa.fa-archive span {{_ 'archives'}} + if showSort + a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}") + i.fa(class="{{directionClass}}") + span {{_ 'sort'}}{{_ listSortShortDesc}} a.board-header-btn.js-open-filter-view( title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}" class="{{#if Filter.isActive}}emphasis{{/if}}") @@ -194,6 +198,20 @@ template(name="createBoard") | / a.js-board-template {{_ 'template'}} +template(name="listsortPopup") + h2 + | {{_ 'list-sort-by'}} + hr + ul.pop-over-list + each value in allowedSortValues + li + a.js-sort-by(name="{{value.name}}") + if $eq sortby value.name + i(class="fa {{Direction}}") + | {{_ value.label }}{{_ value.shortLabel}} + if $eq sortby value.name + i(class="fa fa-check") + template(name="boardChangeTitlePopup") form label diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index cb84c233..e14b1444 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -1,3 +1,5 @@ +const DOWNCLS = 'fa-sort-down'; +const UPCLS = 'fa-sort-up'; Template.boardMenuPopup.events({ 'click .js-rename-board': Popup.open('boardChangeTitle'), 'click .js-custom-fields'() { @@ -80,7 +82,25 @@ BlazeComponent.extendComponent({ const currentBoard = Boards.findOne(Session.get('currentBoard')); return currentBoard && currentBoard.stars >= 2; }, - + showSort() { + return Meteor.user().hasSortBy(); + }, + directionClass() { + return this.currentDirection() === -1 ? DOWNCLS : UPCLS; + }, + changeDirection() { + const direction = 0 - this.currentDirection() === -1 ? '-' : ''; + Meteor.call('setListSortBy', direction + this.currentListSortBy()); + }, + currentDirection() { + return Meteor.user().getListSortByDirection(); + }, + currentListSortBy() { + return Meteor.user().getListSortBy(); + }, + listSortShortDesc() { + return `list-label-short-${this.currentListSortBy()}`; + }, events() { return [ { @@ -118,6 +138,16 @@ BlazeComponent.extendComponent({ 'click .js-open-filter-view'() { Sidebar.setView('filter'); }, + 'click .js-open-sort-view'(evt) { + const target = evt.target; + if (target.tagName === 'I') { + // click on the text, popup choices + this.changeDirection(); + } else { + // change the sort order + Popup.open('listsort')(evt); + } + }, 'click .js-filter-reset'(event) { event.stopPropagation(); Sidebar.setView(); @@ -277,3 +307,73 @@ BlazeComponent.extendComponent({ ]; }, }).register('boardChangeWatchPopup'); + +BlazeComponent.extendComponent({ + onCreated() { + //this.sortBy = new ReactiveVar(); + ////this.sortDirection = new ReactiveVar(); + //this.setSortBy(); + this.downClass = DOWNCLS; + this.upClass = UPCLS; + }, + allowedSortValues() { + const types = []; + const pushed = {}; + Meteor.user() + .getListSortTypes() + .forEach(type => { + const key = type.replace(/^-/, ''); + if (pushed[key] === undefined) { + types.push({ + name: key, + label: `list-label-${key}`, + shortLabel: `list-label-short-${key}`, + }); + pushed[key] = 1; + } + }); + return types; + }, + Direction() { + return Meteor.user().getListSortByDirection() === -1 + ? this.downClass + : this.upClass; + }, + sortby() { + return Meteor.user().getListSortBy(); + }, + + setSortBy(type = null) { + const user = Meteor.user(); + if (type === null) { + type = user._getListSortBy(); + } else { + let value = ''; + if (type.map) { + // is an array + value = (type[1] === -1 ? '-' : '') + type[0]; + } + Meteor.call('setListSortBy', value); + } + //this.sortBy.set(type[0]); + //this.sortDirection.set(type[1]); + }, + + events() { + return [ + { + 'click .js-sort-by'(evt) { + evt.preventDefault(); + const target = evt.target; + const sortby = target.getAttribute('name'); + const down = !!target.querySelector(`.${this.upClass}`); + const direction = down ? -1 : 1; + this.setSortBy([sortby, direction]); + if (Utils.isMiniScreen) { + Popup.close(); + } + }, + }, + ]; + }, +}).register('listsortPopup'); diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 23ae6282..3b3a0242 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -9,7 +9,7 @@ template(name="listHeader") if currentList a.list-header-left-icon.fa.fa-angle-left.js-unselect-list h2.list-header-name( - title="{{ moment updatedAt 'LLL' }}" + title="{{ moment modifiedAt 'LLL' }}" class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}js-open-inlined-form is-editable{{/unless}}{{/if}}") +viewer = title @@ -39,6 +39,8 @@ template(name="listHeader") i.list-header-watch-icon.fa.fa-eye div.list-header-menu unless currentUser.isCommentOnly + if isBoardAdmin + a.fa.js-list-star.list-header-plus-icon(class="fa-star{{#unless starred}}-o{{/unless}}") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 5b7232cd..b524d4e0 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -13,6 +13,20 @@ BlazeComponent.extendComponent({ ); }, + isBoardAdmin() { + return Meteor.user().isBoardAdmin(); + }, + starred(check = undefined) { + const list = Template.currentData(); + const status = list.isStarred(); + if (check === undefined) { + // just check + return status; + } else { + list.star(!status); + return !status; + } + }, editTitle(event) { event.preventDefault(); const newTitle = this.childComponents('inlinedForm')[0] @@ -61,6 +75,10 @@ BlazeComponent.extendComponent({ events() { return [ { + 'click .js-list-star'(event) { + event.preventDefault(); + this.starred(!this.starred()); + }, 'click .js-open-list-menu': Popup.open('listAction'), 'click .js-add-card'(event) { const listDom = $(event.target).parents( diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 55ab213a..0a68719e 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -4,6 +4,9 @@ and #each x in y constructors to fix this. template(name="filterSidebar") + ul.sidebar-list + span {{_ 'list-filter-label'}} + input.js-list-filter(type="text") ul.sidebar-list li(class="{{#if Filter.labelIds.isSelected undefined}}active{{/if}}") a.name.js-toggle-label-filter diff --git a/client/components/sidebar/sidebarFilters.js b/client/components/sidebar/sidebarFilters.js index 3483d00c..ee76ef37 100644 --- a/client/components/sidebar/sidebarFilters.js +++ b/client/components/sidebar/sidebarFilters.js @@ -4,6 +4,10 @@ BlazeComponent.extendComponent({ events() { return [ { + 'change .js-list-filter'(evt) { + evt.preventDefault(); + Filter.lists.set(this.find('.js-list-filter').value.trim()); + }, 'click .js-toggle-label-filter'(evt) { evt.preventDefault(); Filter.labelIds.toggle(this.currentData()._id); diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 8f07a01c..98af6d54 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -42,7 +42,7 @@ template(name="listsGroup") +cardDetails(currentCard) 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 1bfc0f79..8faad870 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -267,6 +267,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/lib/filter.js b/client/lib/filter.js index 1ca3a280..b0695625 100644 --- a/client/lib/filter.js +++ b/client/lib/filter.js @@ -439,6 +439,14 @@ class AdvancedFilter { const commands = this._filterToCommands(); return this._arrayToSelector(commands); } + getRegexSelector() { + // generate a regex for filter list + this._dep.depend(); + return new RegExp( + `^.*${this._filter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}.*$`, + 'i', + ); + } } // The global Filter object. @@ -455,8 +463,16 @@ Filter = { hideEmpty: new SetFilter(), customFields: new SetFilter('_id'), advanced: new AdvancedFilter(), - - _fields: ['labelIds', 'members', 'archive', 'hideEmpty', 'customFields'], + lists: new AdvancedFilter(), // we need the ability to filter list by name as well + + _fields: [ + 'labelIds', + 'members', + 'archive', + 'hideEmpty', + 'customFields', + 'lists', + ], // We don't filter cards that have been added after the last filter change. To // implement this we keep the id of these cards in this `_exceptions` fields -- cgit v1.2.3-1-g7c22 From d2d4840758b0f5aed7feb4f6a459bb2b2d1a3f0b Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Fri, 18 Oct 2019 18:06:34 -0400 Subject: Add Feature: allowing user to filter list in Filter function not just cards --- client/lib/filter.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'client') diff --git a/client/lib/filter.js b/client/lib/filter.js index b0695625..9ddea65c 100644 --- a/client/lib/filter.js +++ b/client/lib/filter.js @@ -465,14 +465,7 @@ Filter = { advanced: new AdvancedFilter(), lists: new AdvancedFilter(), // we need the ability to filter list by name as well - _fields: [ - 'labelIds', - 'members', - 'archive', - 'hideEmpty', - 'customFields', - 'lists', - ], + _fields: ['labelIds', 'members', 'archive', 'hideEmpty', 'customFields'], // We don't filter cards that have been added after the last filter change. To // implement this we keep the id of these cards in this `_exceptions` fields @@ -549,6 +542,7 @@ Filter = { const filter = this[fieldName]; filter.reset(); }); + this.lists.reset(); this.advanced.reset(); this.resetExceptions(); }, -- cgit v1.2.3-1-g7c22 From 32f50e16586696ec7d100ce0438d1030ae1f606e Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Sat, 19 Oct 2019 00:28:49 -0400 Subject: Add Feature: allow user to search Lists in Board --- client/components/sidebar/sidebarFilters.jade | 3 ++- client/components/sidebar/sidebarFilters.js | 4 ++-- client/components/sidebar/sidebarSearches.jade | 4 ++++ client/components/sidebar/sidebarSearches.js | 5 +++++ 4 files changed, 13 insertions(+), 3 deletions(-) (limited to 'client') diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 0a68719e..ff2cd948 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -6,7 +6,8 @@ template(name="filterSidebar") ul.sidebar-list span {{_ 'list-filter-label'}} - input.js-list-filter(type="text") + form.js-list-filter + input(type="text") ul.sidebar-list li(class="{{#if Filter.labelIds.isSelected undefined}}active{{/if}}") a.name.js-toggle-label-filter diff --git a/client/components/sidebar/sidebarFilters.js b/client/components/sidebar/sidebarFilters.js index ee76ef37..ee0176b9 100644 --- a/client/components/sidebar/sidebarFilters.js +++ b/client/components/sidebar/sidebarFilters.js @@ -4,9 +4,9 @@ BlazeComponent.extendComponent({ events() { return [ { - 'change .js-list-filter'(evt) { + 'submit .js-list-filter'(evt) { evt.preventDefault(); - Filter.lists.set(this.find('.js-list-filter').value.trim()); + Filter.lists.set(this.find('.js-list-filter input').value.trim()); }, 'click .js-toggle-label-filter'(evt) { evt.preventDefault(); diff --git a/client/components/sidebar/sidebarSearches.jade b/client/components/sidebar/sidebarSearches.jade index 96877c50..4ee7fc9c 100644 --- a/client/components/sidebar/sidebarSearches.jade +++ b/client/components/sidebar/sidebarSearches.jade @@ -2,6 +2,10 @@ template(name="searchSidebar") form.js-search-term-form input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus dir="auto") .list-body.js-perfect-scrollbar + .minilists.clearfix.js-minilists + each (lists) + a.minilist-wrapper.js-minilist(href=absoluteUrl) + +minilist(this) .minicards.clearfix.js-minicards each (results) a.minicard-wrapper.js-minicard(href=absoluteUrl) diff --git a/client/components/sidebar/sidebarSearches.js b/client/components/sidebar/sidebarSearches.js index 8944c04e..02677260 100644 --- a/client/components/sidebar/sidebarSearches.js +++ b/client/components/sidebar/sidebarSearches.js @@ -8,6 +8,11 @@ BlazeComponent.extendComponent({ return currentBoard.searchCards(this.term.get()); }, + lists() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return currentBoard.searchLists(this.term.get()); + }, + events() { return [ { -- cgit v1.2.3-1-g7c22 From 0fb15888bc7c845f85c3201c024ee35448b8836c Mon Sep 17 00:00:00 2001 From: Thomas Liske Date: Thu, 24 Oct 2019 12:57:07 +0200 Subject: Enhancement: set card times more sensible using the 'Today' button in datepicker --- client/components/cards/cardDate.js | 8 ++++---- client/lib/datepicker.js | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index 91205f1c..7f8f5edb 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -105,7 +105,7 @@ Template.dateBadge.helpers({ // editCardReceivedDatePopup (class extends DatePicker { onCreated() { - super.onCreated(); + super.onCreated(moment().format("YYYY-MM-DD HH:mm")); this.data().getReceived() && this.date.set(moment(this.data().getReceived())); } @@ -122,7 +122,7 @@ Template.dateBadge.helpers({ // editCardStartDatePopup (class extends DatePicker { onCreated() { - super.onCreated(); + super.onCreated(moment().format("YYYY-MM-DD HH:mm")); this.data().getStart() && this.date.set(moment(this.data().getStart())); } @@ -148,7 +148,7 @@ Template.dateBadge.helpers({ // editCardDueDatePopup (class extends DatePicker { onCreated() { - super.onCreated(); + super.onCreated('1970-01-01 17:00:00'); this.data().getDue() && this.date.set(moment(this.data().getDue())); } @@ -171,7 +171,7 @@ Template.dateBadge.helpers({ // editCardEndDatePopup (class extends DatePicker { onCreated() { - super.onCreated(); + super.onCreated(moment().format("YYYY-MM-DD HH:mm")); this.data().getEnd() && this.date.set(moment(this.data().getEnd())); } diff --git a/client/lib/datepicker.js b/client/lib/datepicker.js index da44bbc5..79c1413f 100644 --- a/client/lib/datepicker.js +++ b/client/lib/datepicker.js @@ -3,10 +3,11 @@ DatePicker = BlazeComponent.extendComponent({ return 'datepicker'; }, - onCreated() { + onCreated(defaultTime='1970-01-01 08:00:00') { this.error = new ReactiveVar(''); this.card = this.data(); this.date = new ReactiveVar(moment.invalid()); + this.defaultTime = defaultTime; }, onRendered() { @@ -26,7 +27,7 @@ DatePicker = BlazeComponent.extendComponent({ if (!timeInput.value) { const currentHour = evt.date.getHours(); const defaultMoment = moment( - currentHour > 0 ? evt.date : '1970-01-01 08:00:00', + currentHour > 0 ? evt.date : this.defaultTime, ); // default to 8:00 am local time timeInput.value = defaultMoment.format('LT'); } -- cgit v1.2.3-1-g7c22 From 064c4d7ca7cce65989979480a5f6ff4816895283 Mon Sep 17 00:00:00 2001 From: Thomas Liske Date: Mon, 28 Oct 2019 08:25:55 +0100 Subject: Lintian fixes. --- client/components/cards/cardDate.js | 6 +++--- client/lib/datepicker.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index 7f8f5edb..6634ee1b 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -105,7 +105,7 @@ Template.dateBadge.helpers({ // editCardReceivedDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format("YYYY-MM-DD HH:mm")); + super.onCreated(moment().format('YYYY-MM-DD HH:mm')); this.data().getReceived() && this.date.set(moment(this.data().getReceived())); } @@ -122,7 +122,7 @@ Template.dateBadge.helpers({ // editCardStartDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format("YYYY-MM-DD HH:mm")); + super.onCreated(moment().format('YYYY-MM-DD HH:mm')); this.data().getStart() && this.date.set(moment(this.data().getStart())); } @@ -171,7 +171,7 @@ Template.dateBadge.helpers({ // editCardEndDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format("YYYY-MM-DD HH:mm")); + super.onCreated(moment().format('YYYY-MM-DD HH:mm')); this.data().getEnd() && this.date.set(moment(this.data().getEnd())); } diff --git a/client/lib/datepicker.js b/client/lib/datepicker.js index 79c1413f..8ad66c5f 100644 --- a/client/lib/datepicker.js +++ b/client/lib/datepicker.js @@ -3,7 +3,7 @@ DatePicker = BlazeComponent.extendComponent({ return 'datepicker'; }, - onCreated(defaultTime='1970-01-01 08:00:00') { + onCreated(defaultTime = '1970-01-01 08:00:00') { this.error = new ReactiveVar(''); this.card = this.data(); this.date = new ReactiveVar(moment.invalid()); -- cgit v1.2.3-1-g7c22 From 7d6d3af54a2fc1fb68634725eb754b22f02fd430 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 29 Oct 2019 19:05:44 +0200 Subject: Add Features: allowing lists to be sorted by modifiedAt when not in draggable mode. Bug Fix #2093: the broken should be prior to file attachment feature introduced, and tested export board is working. Thanks to whowillcare ! ( xet7 merged this pull request manually from https://github.com/wekan/wekan/pull/2756 ) Closes #2093 --- client/components/boards/boardBody.js | 2 +- client/components/boards/boardHeader.jade | 18 +++++ client/components/boards/boardHeader.js | 102 +++++++++++++++++++++++- client/components/cards/minicard.jade | 11 ++- client/components/cards/minicard.js | 3 + client/components/cards/minicard.styl | 5 +- client/components/lists/list.js | 14 +++- client/components/lists/list.styl | 26 ++++-- client/components/lists/listHeader.jade | 7 ++ client/components/lists/listHeader.js | 24 ++++++ client/components/sidebar/sidebarFilters.jade | 4 + client/components/sidebar/sidebarFilters.js | 4 + client/components/sidebar/sidebarSearches.jade | 4 + client/components/sidebar/sidebarSearches.js | 5 ++ client/components/swimlanes/swimlaneHeader.jade | 2 + client/components/swimlanes/swimlaneHeader.js | 6 ++ client/components/swimlanes/swimlanes.jade | 18 ++--- client/components/swimlanes/swimlanes.js | 35 ++++++-- client/components/swimlanes/swimlanes.styl | 8 ++ client/components/users/userHeader.jade | 5 ++ client/components/users/userHeader.js | 6 ++ client/lib/filter.js | 10 +++ 22 files changed, 289 insertions(+), 30 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index d64636f4..47042ae7 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -89,7 +89,7 @@ BlazeComponent.extendComponent({ helper.append(list.clone()); return helper; }, - handle: '.js-swimlane-header', + handle: '.js-swimlane-header-handle', items: '.swimlane:not(.placeholder)', placeholder: 'swimlane placeholder', distance: 7, diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index fe533f95..175cc2c2 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -77,6 +77,10 @@ template(name="boardHeaderBar") i.fa.fa-archive span {{_ 'archives'}} + if showSort + a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}") + i.fa(class="{{directionClass}}") + span {{_ 'sort'}}{{_ listSortShortDesc}} a.board-header-btn.js-open-filter-view( title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}" class="{{#if Filter.isActive}}emphasis{{/if}}") @@ -194,6 +198,20 @@ template(name="createBoard") | / a.js-board-template {{_ 'template'}} +template(name="listsortPopup") + h2 + | {{_ 'list-sort-by'}} + hr + ul.pop-over-list + each value in allowedSortValues + li + a.js-sort-by(name="{{value.name}}") + if $eq sortby value.name + i(class="fa {{Direction}}") + | {{_ value.label }}{{_ value.shortLabel}} + if $eq sortby value.name + i(class="fa fa-check") + template(name="boardChangeTitlePopup") form label diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index cb84c233..e14b1444 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -1,3 +1,5 @@ +const DOWNCLS = 'fa-sort-down'; +const UPCLS = 'fa-sort-up'; Template.boardMenuPopup.events({ 'click .js-rename-board': Popup.open('boardChangeTitle'), 'click .js-custom-fields'() { @@ -80,7 +82,25 @@ BlazeComponent.extendComponent({ const currentBoard = Boards.findOne(Session.get('currentBoard')); return currentBoard && currentBoard.stars >= 2; }, - + showSort() { + return Meteor.user().hasSortBy(); + }, + directionClass() { + return this.currentDirection() === -1 ? DOWNCLS : UPCLS; + }, + changeDirection() { + const direction = 0 - this.currentDirection() === -1 ? '-' : ''; + Meteor.call('setListSortBy', direction + this.currentListSortBy()); + }, + currentDirection() { + return Meteor.user().getListSortByDirection(); + }, + currentListSortBy() { + return Meteor.user().getListSortBy(); + }, + listSortShortDesc() { + return `list-label-short-${this.currentListSortBy()}`; + }, events() { return [ { @@ -118,6 +138,16 @@ BlazeComponent.extendComponent({ 'click .js-open-filter-view'() { Sidebar.setView('filter'); }, + 'click .js-open-sort-view'(evt) { + const target = evt.target; + if (target.tagName === 'I') { + // click on the text, popup choices + this.changeDirection(); + } else { + // change the sort order + Popup.open('listsort')(evt); + } + }, 'click .js-filter-reset'(event) { event.stopPropagation(); Sidebar.setView(); @@ -277,3 +307,73 @@ BlazeComponent.extendComponent({ ]; }, }).register('boardChangeWatchPopup'); + +BlazeComponent.extendComponent({ + onCreated() { + //this.sortBy = new ReactiveVar(); + ////this.sortDirection = new ReactiveVar(); + //this.setSortBy(); + this.downClass = DOWNCLS; + this.upClass = UPCLS; + }, + allowedSortValues() { + const types = []; + const pushed = {}; + Meteor.user() + .getListSortTypes() + .forEach(type => { + const key = type.replace(/^-/, ''); + if (pushed[key] === undefined) { + types.push({ + name: key, + label: `list-label-${key}`, + shortLabel: `list-label-short-${key}`, + }); + pushed[key] = 1; + } + }); + return types; + }, + Direction() { + return Meteor.user().getListSortByDirection() === -1 + ? this.downClass + : this.upClass; + }, + sortby() { + return Meteor.user().getListSortBy(); + }, + + setSortBy(type = null) { + const user = Meteor.user(); + if (type === null) { + type = user._getListSortBy(); + } else { + let value = ''; + if (type.map) { + // is an array + value = (type[1] === -1 ? '-' : '') + type[0]; + } + Meteor.call('setListSortBy', value); + } + //this.sortBy.set(type[0]); + //this.sortDirection.set(type[1]); + }, + + events() { + return [ + { + 'click .js-sort-by'(evt) { + evt.preventDefault(); + const target = evt.target; + const sortby = target.getAttribute('name'); + const down = !!target.querySelector(`.${this.upClass}`); + const direction = down ? -1 : 1; + this.setSortBy([sortby, direction]); + if (Utils.isMiniScreen) { + Popup.close(); + } + }, + }, + ]; + }, +}).register('listsortPopup'); diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 3806ce41..ba0c5707 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -3,6 +3,13 @@ template(name="minicard") class="{{#if isLinkedCard}}linked-card{{/if}}" class="{{#if isLinkedBoard}}linked-board{{/if}}" class="minicard-{{colorClass}}") + if isMiniScreen + .handle + .fa.fa-arrows + unless isMiniScreen + if showDesktopDragHandles + .handle + .fa.fa-arrows if cover .minicard-cover(style="background-image: url('{{cover.url}}');") if labels @@ -15,8 +22,6 @@ template(name="minicard") if hiddenMinicardLabelText .minicard-label(class="card-label-{{color}}" title="{{name}}") .minicard-title - .handle - .fa.fa-arrows if $eq 'prefix-with-full-path' currentBoard.presentParentTask .parent-prefix | {{ parentString ' > ' }} @@ -53,6 +58,8 @@ template(name="minicard") if getDue .date +minicardDueDate + if getEnd + +minicardEndDate if getSpentTime .date +cardSpentTime diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 4c25c11d..4c76db46 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -26,6 +26,9 @@ BlazeComponent.extendComponent({ }).register('minicard'); Template.minicard.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, hiddenMinicardLabelText() { return Meteor.user().hasHiddenMinicardLabelText(); }, diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 7c27cba1..9997fd5f 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -105,8 +105,7 @@ right: 5px; top: 5px; display:none; - // @media only screen and (max-width: 1199px) { - @media only screen and (max-width: 800px) { + @media only screen { display:block; } .fa-arrows @@ -128,7 +127,7 @@ .badges float: left margin-top: 7px - color: darken(white, 80%) + color: darken(white, 50%) &:empty display: none diff --git a/client/components/lists/list.js b/client/components/lists/list.js index bde43520..b7b8b2e0 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -31,7 +31,13 @@ BlazeComponent.extendComponent({ const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)'; const $cards = this.$('.js-minicards'); - if (Utils.isMiniScreen()) { + if (Utils.isMiniScreen) { + $('.js-minicards').sortable({ + handle: '.handle', + }); + } + + if (!Utils.isMiniScreen && showDesktopDragHandles) { $('.js-minicards').sortable({ handle: '.handle', }); @@ -155,6 +161,12 @@ BlazeComponent.extendComponent({ }, }).register('list'); +Template.list.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + Template.miniList.events({ 'click .js-select-list'() { const listId = this._id; diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 81938c1a..0d3ccfce 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -84,17 +84,16 @@ padding-left: 10px color: #a6a6a6 - .list-header-menu position: absolute padding: 27px 19px margin-top: 1px top: -7px - right: -7px + right: 3px .list-header-plus-icon color: #a6a6a6 - margin-right: 10px + margin-right: 15px .highlight color: #ce1414 @@ -165,7 +164,16 @@ @media screen and (max-width: 800px) .list-header-menu - margin-right: 30px + position: absolute + padding: 27px 19px + margin-top: 1px + top: -7px + margin-right: 50px + right: -3px + + .list-header + .list-header-name + margin-left: 1.4rem .mini-list flex: 0 0 60px @@ -221,9 +229,17 @@ padding: 7px top: 50% transform: translateY(-50%) - right: 17px + margin-right: 27px font-size: 20px + .list-header-menu-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + right: 10px + font-size: 24px + .link-board-wrapper display: flex align-items: baseline diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index f930e57a..3b3a0242 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -9,6 +9,7 @@ template(name="listHeader") if currentList a.list-header-left-icon.fa.fa-angle-left.js-unselect-list h2.list-header-name( + title="{{ moment modifiedAt 'LLL' }}" class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}js-open-inlined-form is-editable{{/unless}}{{/if}}") +viewer = title @@ -29,16 +30,22 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu + a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle else a.list-header-menu-icon.fa.fa-angle-right.js-select-list + a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle else if currentUser.isBoardMember if isWatching i.list-header-watch-icon.fa.fa-eye div.list-header-menu unless currentUser.isCommentOnly + if isBoardAdmin + a.fa.js-list-star.list-header-plus-icon(class="fa-star{{#unless starred}}-o{{/unless}}") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu + if showDesktopDragHandles + a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle template(name="editListTitleForm") .list-composer diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index e8a82499..b524d4e0 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -13,6 +13,20 @@ BlazeComponent.extendComponent({ ); }, + isBoardAdmin() { + return Meteor.user().isBoardAdmin(); + }, + starred(check = undefined) { + const list = Template.currentData(); + const status = list.isStarred(); + if (check === undefined) { + // just check + return status; + } else { + list.star(!status); + return !status; + } + }, editTitle(event) { event.preventDefault(); const newTitle = this.childComponents('inlinedForm')[0] @@ -61,6 +75,10 @@ BlazeComponent.extendComponent({ events() { return [ { + 'click .js-list-star'(event) { + event.preventDefault(); + this.starred(!this.starred()); + }, 'click .js-open-list-menu': Popup.open('listAction'), 'click .js-add-card'(event) { const listDom = $(event.target).parents( @@ -80,6 +98,12 @@ BlazeComponent.extendComponent({ }, }).register('listHeader'); +Template.listHeader.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + Template.listActionPopup.helpers({ isWipLimitEnabled() { return Template.currentData().getWipLimit('enabled'); diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 55ab213a..5f929cb9 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -4,6 +4,10 @@ and #each x in y constructors to fix this. template(name="filterSidebar") + ul.sidebar-list + span {{_ 'list-filter-label'}} + form.js-list-filter + input(type="text") ul.sidebar-list li(class="{{#if Filter.labelIds.isSelected undefined}}active{{/if}}") a.name.js-toggle-label-filter diff --git a/client/components/sidebar/sidebarFilters.js b/client/components/sidebar/sidebarFilters.js index 3483d00c..ee0176b9 100644 --- a/client/components/sidebar/sidebarFilters.js +++ b/client/components/sidebar/sidebarFilters.js @@ -4,6 +4,10 @@ BlazeComponent.extendComponent({ events() { return [ { + 'submit .js-list-filter'(evt) { + evt.preventDefault(); + Filter.lists.set(this.find('.js-list-filter input').value.trim()); + }, 'click .js-toggle-label-filter'(evt) { evt.preventDefault(); Filter.labelIds.toggle(this.currentData()._id); diff --git a/client/components/sidebar/sidebarSearches.jade b/client/components/sidebar/sidebarSearches.jade index 96877c50..4ee7fc9c 100644 --- a/client/components/sidebar/sidebarSearches.jade +++ b/client/components/sidebar/sidebarSearches.jade @@ -2,6 +2,10 @@ template(name="searchSidebar") form.js-search-term-form input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus dir="auto") .list-body.js-perfect-scrollbar + .minilists.clearfix.js-minilists + each (lists) + a.minilist-wrapper.js-minilist(href=absoluteUrl) + +minilist(this) .minicards.clearfix.js-minicards each (results) a.minicard-wrapper.js-minicard(href=absoluteUrl) diff --git a/client/components/sidebar/sidebarSearches.js b/client/components/sidebar/sidebarSearches.js index 8944c04e..02677260 100644 --- a/client/components/sidebar/sidebarSearches.js +++ b/client/components/sidebar/sidebarSearches.js @@ -8,6 +8,11 @@ BlazeComponent.extendComponent({ return currentBoard.searchCards(this.term.get()); }, + lists() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return currentBoard.searchLists(this.term.get()); + }, + events() { return [ { diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 8c6aa5a3..fb6ef21d 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -16,6 +16,8 @@ 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 + if showDesktopDragHandles + a.swimlane-header-menu-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..6f8029fd 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -28,6 +28,12 @@ BlazeComponent.extendComponent({ }, }).register('swimlaneHeader'); +Template.swimlaneHeader.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, +}); + 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..98af6d54 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -12,13 +12,13 @@ template(name="swimlane") unless currentUser.isCommentOnly +addListForm else + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm 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 @@ -26,23 +26,23 @@ template(name="listsGroup") if currentList +list(currentList) else - each lists - +miniList(this) if currentUser.isBoardMember unless currentUser.isCommentOnly +addListForm + each lists + +miniList(this) else + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm each lists if visible this +list(this) if currentCardIsInThisList _id null +cardDetails(currentCard) - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +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..8faad870 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -53,10 +53,21 @@ function initSortable(boardComponent, $listsDom) { }, }; + if (Utils.isMiniScreen) { + $listsDom.sortable({ + handle: '.js-list-handle', + }); + } + + if (!Utils.isMiniScreen && showDesktopDragHandles) { + $listsDom.sortable({ + handle: '.js-list-header', + }); + } + $listsDom.sortable({ tolerance: 'pointer', helper: 'clone', - handle: '.js-list-header', items: '.js-list:not(.js-list-composer)', placeholder: 'list placeholder', distance: 7, @@ -151,13 +162,13 @@ 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', - ]; + + const noDragInside = ['a', 'input', 'textarea', 'p'].concat( + Util.isMiniScreen || (!Util.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 @@ -233,6 +244,9 @@ BlazeComponent.extendComponent({ }).register('addListForm'); Template.swimlane.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, canSeeAddList() { return ( Meteor.user() && @@ -253,6 +267,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..503091ee 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -50,6 +50,14 @@ margin-left: 5px margin-right: 10px + .swimlane-header-menu-handle + position: absolute + padding: 7px + top: 50% + transform: translateY(-50%) + left: 300px + font-size: 18px + .list-group height: 100% diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 946bdab1..50a80396 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -78,6 +78,11 @@ template(name="changeSettingsPopup") | {{_ 'hide-system-messages'}} if hiddenSystemMessages i.fa.fa-check + li + a.js-toggle-desktop-drag-handles + | {{_ 'show-desktop-drag-handles'}} + if showDesktopDragHandles + i.fa.fa-check li label.bold | {{_ 'show-cards-minimum-count'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 36fb2020..194f990f 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -161,6 +161,9 @@ Template.changeLanguagePopup.events({ }); Template.changeSettingsPopup.helpers({ + showDesktopDragHandles() { + return Meteor.user().hasShowDesktopDragHandles(); + }, hiddenSystemMessages() { return Meteor.user().hasHiddenSystemMessages(); }, @@ -170,6 +173,9 @@ Template.changeSettingsPopup.helpers({ }); Template.changeSettingsPopup.events({ + 'click .js-toggle-desktop-drag-handles'() { + Meteor.call('toggleDesktopDragHandles'); + }, 'click .js-toggle-system-messages'() { Meteor.call('toggleSystemMessages'); }, diff --git a/client/lib/filter.js b/client/lib/filter.js index 1ca3a280..9ddea65c 100644 --- a/client/lib/filter.js +++ b/client/lib/filter.js @@ -439,6 +439,14 @@ class AdvancedFilter { const commands = this._filterToCommands(); return this._arrayToSelector(commands); } + getRegexSelector() { + // generate a regex for filter list + this._dep.depend(); + return new RegExp( + `^.*${this._filter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}.*$`, + 'i', + ); + } } // The global Filter object. @@ -455,6 +463,7 @@ Filter = { hideEmpty: new SetFilter(), customFields: new SetFilter('_id'), advanced: new AdvancedFilter(), + lists: new AdvancedFilter(), // we need the ability to filter list by name as well _fields: ['labelIds', 'members', 'archive', 'hideEmpty', 'customFields'], @@ -533,6 +542,7 @@ Filter = { const filter = this[fieldName]; filter.reset(); }); + this.lists.reset(); this.advanced.reset(); this.resetExceptions(); }, -- cgit v1.2.3-1-g7c22 From b26504f4145e1968f18389982210f60c1f1fa725 Mon Sep 17 00:00:00 2001 From: "Sam X. Chen" Date: Wed, 30 Oct 2019 09:45:50 -0400 Subject: Fix: lists filter didn't get added into filter active checklist --- client/lib/filter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/lib/filter.js b/client/lib/filter.js index 9ddea65c..592eb4ab 100644 --- a/client/lib/filter.js +++ b/client/lib/filter.js @@ -477,7 +477,9 @@ Filter = { return ( _.any(this._fields, fieldName => { return this[fieldName]._isActive(); - }) || this.advanced._isActive() + }) || + this.advanced._isActive() || + this.lists._isActive() ); }, -- cgit v1.2.3-1-g7c22 From 758bbab44115084c351c5581b62607e826604e1c Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 30 Oct 2019 17:33:02 +0200 Subject: Revert New List item moved from right to left. Thanks to derbolle and xet7 ! Closes #2772 --- client/components/swimlanes/swimlanes.jade | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 98af6d54..3ad43777 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -12,13 +12,13 @@ template(name="swimlane") unless currentUser.isCommentOnly +addListForm else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm 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 @@ -26,23 +26,23 @@ template(name="listsGroup") if currentList +list(currentList) else + each lists + +miniList(this) if currentUser.isBoardMember unless currentUser.isCommentOnly +addListForm - each lists - +miniList(this) else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm each lists if visible this +list(this) if currentCardIsInThisList _id null +cardDetails(currentCard) + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm template(name="addListForm") - .list.list-composer.js-list-composer(class="{{#if isMiniScreen}}mini-list{{/if}}") + .list.list-composer.js-list-composer .list-header-add +inlinedForm(autoclose=false) input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}" -- cgit v1.2.3-1-g7c22 From 5bb99ba0962c4549db8e01c75d83443d37c1c484 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 30 Oct 2019 18:09:56 +0200 Subject: Add back miniscreen add list style. --- client/components/swimlanes/swimlanes.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 3ad43777..9eab6054 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -42,7 +42,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'}}" -- cgit v1.2.3-1-g7c22 From 806df30ba3499cef193eaf1b437cdef65282510f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 30 Oct 2019 20:45:30 +0200 Subject: Revert creating new list to left, now creates again to right. Thanks to whowillcare ! Revert New List item moved from right to left. Thanks to derbolle and xet7 ! Closes #2772 --- client/components/swimlanes/swimlanes.jade | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 98af6d54..9eab6054 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -12,13 +12,13 @@ template(name="swimlane") unless currentUser.isCommentOnly +addListForm else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm 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 @@ -26,20 +26,20 @@ template(name="listsGroup") if currentList +list(currentList) else + each lists + +miniList(this) if currentUser.isBoardMember unless currentUser.isCommentOnly +addListForm - each lists - +miniList(this) else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm each lists if visible this +list(this) if currentCardIsInThisList _id null +cardDetails(currentCard) + if currentUser.isBoardMember + unless currentUser.isCommentOnly + +addListForm template(name="addListForm") .list.list-composer.js-list-composer(class="{{#if isMiniScreen}}mini-list{{/if}}") -- cgit v1.2.3-1-g7c22 From 9e1aaf163f3bd0b3c2d2aee8225d111f83b3d421 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 31 Oct 2019 02:21:50 +0200 Subject: Assignee field like Jira #2452 , in progress. Assignee can not be removed yet, it removes member, wrong link in popup. Thanks to xet7 ! --- client/components/cards/cardDetails.jade | 21 +++++++++++++++++++++ client/components/cards/cardDetails.js | 3 +++ client/components/cards/cardDetails.styl | 1 + client/components/users/userAvatar.jade | 32 ++++++++++++++++++++++++++++++++ client/components/users/userAvatar.js | 30 ++++++++++++++++++++++++++++++ client/components/users/userAvatar.styl | 12 ++++++++---- 6 files changed, 95 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 13b6bd13..639c7742 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -73,6 +73,15 @@ template(name="cardDetails") a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}") i.fa.fa-plus + .card-details-item.card-details-item-assignees + h3.card-details-item-title {{_ 'assignee'}} + each getAssignees + +userAvatar(userId=this cardId=../_id) + | {{! XXX Hack to hide syntaxic coloration /// }} + if canModifyCard + a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}") + i.fa.fa-plus + .card-details-item.card-details-item-labels h3.card-details-item-title {{_ 'labels'}} a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}") @@ -296,6 +305,18 @@ template(name="cardMembersPopup") if isCardMember i.fa.fa-check +template(name="cardAssigneesPopup") + ul.pop-over-list.js-card-assignee-list + each board.activeAssignees + li.item(class="{{#if isCardAssignee}}active{{/if}}") + a.name.js-select-assignee(href="#") + +userAvatarAssignee(userId=user._id) + span.full-name + = user.profile.fullname + | ({{ user.username }}) + if isCardAssignee + i.fa.fa-check + template(name="cardMorePopup") p.quiet span.clearfix diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 47941560..6408db74 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -309,6 +309,8 @@ BlazeComponent.extendComponent({ }, 'click .js-member': Popup.open('cardMember'), 'click .js-add-members': Popup.open('cardMembers'), + 'click .js-assignee': Popup.open('cardAssignee'), + 'click .js-add-assignees': Popup.open('cardAssignees'), 'click .js-add-labels': Popup.open('cardLabels'), 'click .js-received-date': Popup.open('editCardReceivedDate'), 'click .js-start-date': Popup.open('editCardStartDate'), @@ -399,6 +401,7 @@ Template.cardDetailsActionsPopup.helpers({ Template.cardDetailsActionsPopup.events({ 'click .js-members': Popup.open('cardMembers'), + 'click .js-assignees': Popup.open('cardAssignees'), 'click .js-labels': Popup.open('cardLabels'), 'click .js-attachments': Popup.open('cardAttachments'), 'click .js-custom-fields': Popup.open('cardCustomFields'), diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index cd475072..825e22e9 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -93,6 +93,7 @@ margin-right: 0 &.card-details-item-labels, &.card-details-item-members, + &.card-details-item-assignees, &.card-details-item-received, &.card-details-item-start, &.card-details-item-due, diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index ebfa48ba..e551cab5 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -15,6 +15,23 @@ template(name="userAvatar") a.edit-avatar.js-change-avatar i.fa.fa-pencil +template(name="userAvatarAssignee") + a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})") + if userData.profile.avatarUrl + img.avatar.avatar-image(src="{{userData.profile.avatarUrl}}") + else + +userAvatarInitials(userId=userData._id) + + if showStatus + span.assignee-presence-status(class=presenceStatusClassName) + span.assignee-type(class=assigneeType) + + unless isSandstorm + if showEdit + if $eq currentUser._id userData._id + a.edit-avatar.js-change-avatar + i.fa.fa-pencil + template(name="userAvatarInitials") svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15") text(x="50%" y="13" text-anchor="middle")= initials @@ -78,3 +95,18 @@ template(name="cardMemberPopup") if $eq currentUser._id user._id with currentUser li: a.js-edit-profile {{_ 'edit-profile'}} + +template(name="cardAssigneePopup") + .board-assignee-menu + .mini-profile-info + +userAvatar(userId=user._id showEdit=true) + .info + h3= user.profile.fullname + p.quiet @{{ user.username }} + ul.pop-over-list + if currentUser.isNotCommentOnly + li: a.js-remove-assignee {{_ 'remove-member-from-card'}} + + if $eq currentUser._id user._id + with currentUser + li: a.js-edit-profile {{_ 'edit-profile'}} diff --git a/client/components/users/userAvatar.js b/client/components/users/userAvatar.js index 262a63af..7a2831b2 100644 --- a/client/components/users/userAvatar.js +++ b/client/components/users/userAvatar.js @@ -139,6 +139,13 @@ Template.cardMembersPopup.helpers({ return _.contains(cardMembers, this.userId); }, + isCardAssignee() { + const card = Template.parentData(); + const cardAssignees = card.getAssignees(); + + return _.contains(cardAssignees, this.userId); + }, + user() { return Users.findOne(this.userId); }, @@ -166,3 +173,26 @@ Template.cardMemberPopup.events({ }, 'click .js-edit-profile': Popup.open('editProfile'), }); + +Template.cardAssigneesPopup.events({ + 'click .js-select-assignee'(event) { + const card = Cards.findOne(Session.get('currentCard')); + const assigneeId = this.userId; + card.toggleAssignee(assigneeId); + event.preventDefault(); + }, +}); + +Template.cardAssigneePopup.helpers({ + user() { + return Users.findOne(this.userId); + }, +}); + +Template.cardAssigneePopup.events({ + 'click .js-remove-assignee'() { + Cards.findOne(this.cardId).unassignAssignee(this.userId); + Popup.close(); + }, + 'click .js-edit-profile': Popup.open('editProfile'), +}); diff --git a/client/components/users/userAvatar.styl b/client/components/users/userAvatar.styl index b962b01c..5fcd9f6c 100644 --- a/client/components/users/userAvatar.styl +++ b/client/components/users/userAvatar.styl @@ -2,7 +2,8 @@ avatar-radius = 50% -.member +.member, +.assignee border-radius: 3px display: block position: relative @@ -32,7 +33,8 @@ avatar-radius = 50% height: 100% width: @height - .member-presence-status + .member-presence-status, + .assignee-presence-status background-color: #b3b3b3 border: 1px solid #fff border-radius: 50% @@ -79,7 +81,8 @@ avatar-radius = 50% color: white - &.add-member + &.add-member, + &.add-assignee display: flex align-items: center justify-content: center @@ -111,7 +114,8 @@ avatar-radius = 50% p padding-top: 0 - .member + .member, + .assignee width: 50px height: @width margin-right: 10px -- cgit v1.2.3-1-g7c22 From 3e8f9ef1a5275a5e9b691c7e74dc73b97a43689a Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sat, 2 Nov 2019 16:12:40 +0200 Subject: Assignee field like Jira #2452 , in progress. Added features: - Assignee can now be added and removed. - Avatar icon is at card and assignee details TODO: - When selecting new assignee (+) icon, list does not yet show avatars and names who to add. There is empty avatar without name. Thanks to xet7 ! --- client/components/cards/cardDetails.jade | 40 ++++++++++- client/components/cards/cardDetails.js | 104 +++++++++++++++++++++++++++ client/components/cards/cardDetails.styl | 120 +++++++++++++++++++++++++++++++ client/components/users/userAvatar.jade | 32 --------- client/components/users/userAvatar.js | 30 -------- client/components/users/userAvatar.styl | 12 ++-- 6 files changed, 266 insertions(+), 72 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 639c7742..ad8010e4 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -76,7 +76,7 @@ template(name="cardDetails") .card-details-item.card-details-item-assignees h3.card-details-item-title {{_ 'assignee'}} each getAssignees - +userAvatar(userId=this cardId=../_id) + +userAvatarAssignee(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} if canModifyCard a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}") @@ -307,7 +307,7 @@ template(name="cardMembersPopup") template(name="cardAssigneesPopup") ul.pop-over-list.js-card-assignee-list - each board.activeAssignees + each board.activeMembers li.item(class="{{#if isCardAssignee}}active{{/if}}") a.name.js-select-assignee(href="#") +userAvatarAssignee(userId=user._id) @@ -317,6 +317,42 @@ template(name="cardAssigneesPopup") if isCardAssignee i.fa.fa-check +template(name="userAvatarAssignee") + a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})") + if userData.profile.avatarUrl + img.avatar.avatar-image(src="{{userData.profile.avatarUrl}}") + else + +userAvatarAssigneeInitials(userId=userData._id) + + if showStatus + span.member-presence-status(class=presenceStatusClassName) + span.member-type(class=memberType) + + unless isSandstorm + if showEdit + if $eq currentUser._id userData._id + a.edit-avatar.js-change-avatar + i.fa.fa-pencil + +template(name="cardAssigneePopup") + .board-assignee-menu + .mini-profile-info + +userAvatar(userId=user._id showEdit=true) + .info + h3= user.profile.fullname + p.quiet @{{ user.username }} + ul.pop-over-list + if currentUser.isNotCommentOnly + li: a.js-remove-assignee {{_ 'remove-member-from-card'}} + + if $eq currentUser._id user._id + with currentUser + li: a.js-edit-profile {{_ 'edit-profile'}} + +template(name="userAvatarAssigneeInitials") + svg.avatar.avatar-assignee-initials(viewBox="0 0 {{viewPortWidth}} 15") + text(x="50%" y="13" text-anchor="middle")= initials + template(name="cardMorePopup") p.quiet span.clearfix diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 6408db74..3b2873a2 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -344,6 +344,50 @@ BlazeComponent.extendComponent({ }, }).register('cardDetails'); +Template.cardDetails.helpers({ + userData() { + // We need to handle a special case for the search results provided by the + // `matteodem:easy-search` package. Since these results gets published in a + // separate collection, and not in the standard Meteor.Users collection as + // expected, we use a component parameter ("property") to distinguish the + // two cases. + const userCollection = this.esSearch ? ESSearchResults : Users; + return userCollection.findOne(this.userId, { + fields: { + profile: 1, + username: 1, + }, + }); + }, + + memberType() { + const user = Users.findOne(this.userId); + return user && user.isBoardAdmin() ? 'admin' : 'normal'; + }, + + presenceStatusClassName() { + const user = Users.findOne(this.userId); + const userPresence = presences.findOne({ userId: this.userId }); + if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending'; + else if (!userPresence) return 'disconnected'; + else if (Session.equals('currentBoard', userPresence.state.currentBoardId)) + return 'active'; + else return 'idle'; + }, +}); + +Template.userAvatarAssigneeInitials.helpers({ + initials() { + const user = Users.findOne(this.userId); + return user && user.getInitials(); + }, + + viewPortWidth() { + const user = Users.findOne(this.userId); + return ((user && user.getInitials().length) || 1) * 12; + }, +}); + // We extends the normal InlinedForm component to support UnsavedEdits draft // feature. (class extends InlinedForm { @@ -809,3 +853,63 @@ EscapeActions.register( noClickEscapeOn: '.js-card-details,.board-sidebar,#header', }, ); + +Template.cardAssigneesPopup.events({ + 'click .js-select-assignee'(event) { + const card = Cards.findOne(Session.get('currentCard')); + const assigneeId = this.userId; + card.toggleAssignee(assigneeId); + event.preventDefault(); + }, +}); + +Template.cardAssigneePopup.helpers({ + userData() { + // We need to handle a special case for the search results provided by the + // `matteodem:easy-search` package. Since these results gets published in a + // separate collection, and not in the standard Meteor.Users collection as + // expected, we use a component parameter ("property") to distinguish the + // two cases. + const userCollection = this.esSearch ? ESSearchResults : Users; + return userCollection.findOne(this.userId, { + fields: { + profile: 1, + username: 1, + }, + }); + }, + + memberType() { + const user = Users.findOne(this.userId); + return user && user.isBoardAdmin() ? 'admin' : 'normal'; + }, + + presenceStatusClassName() { + const user = Users.findOne(this.userId); + const userPresence = presences.findOne({ userId: this.userId }); + if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending'; + else if (!userPresence) return 'disconnected'; + else if (Session.equals('currentBoard', userPresence.state.currentBoardId)) + return 'active'; + else return 'idle'; + }, + + isCardAssignee() { + const card = Template.parentData(); + const cardAssignees = card.getAssignees(); + + return _.contains(cardAssignees, this.userId); + }, + + user() { + return Users.findOne(this.userId); + }, +}); + +Template.cardAssigneePopup.events({ + 'click .js-remove-assignee'() { + Cards.findOne(this.cardId).unassignAssignee(this.userId); + Popup.close(); + }, + 'click .js-edit-profile': Popup.open('editProfile'), +}); diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index 825e22e9..295a659d 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -1,5 +1,125 @@ @import 'nib' +// Assignee, code copied from wekan/client/users/userAvatar.styl + +avatar-radius = 50% + +.assignee + border-radius: 3px + display: block + position: relative + float: left + height: 30px + width: @height + margin: 0 4px 4px 0 + cursor: pointer + user-select: none + z-index: 1 + text-decoration: none + border-radius: avatar-radius + + .avatar + overflow: hidden + border-radius: avatar-radius + + &.avatar-assignee-initials + height: 70% + width: @height + padding: 15% + background-color: #dbdbdb + color: #444444 + position: absolute + + &.avatar-image + height: 100% + width: @height + + .assignee-presence-status + background-color: #b3b3b3 + border: 1px solid #fff + border-radius: 50% + height: 7px + width: @height + position: absolute + right: -1px + bottom: -1px + border: 1px solid white + z-index: 15 + + &.active + background: #64c464 + border-color: #daf1da + + &.idle + background: #e4e467 + border-color: #f7f7d4 + + &.disconnected + background: #bdbdbd + border-color: #ededed + + &.pending + background: #e44242 + border-color: #f1dada + + .edit-avatar + position: absolute + top: 0 + height: 100% + width: 100% + border-radius: avatar-radius + background: black + display: flex + align-items: center + justify-content: center + opacity: 0 + + &:hover + opacity: 0.6 + + i.fa-pencil + color: white + + + &.add-assignee + display: flex + align-items: center + justify-content: center + box-shadow: 0 0 0 2px darken(white, 25%) inset + + &:hover, &.is-active + box-shadow: 0 0 0 2px darken(white, 60%) inset + +.atMention + background: #dbdbdb + border-radius: 3px + padding: 1px 4px + margin: -1px 0 + display: inline-block + + &.me + background: #cfdfe8 + +.mini-profile-info + margin-top: 10px + + .info + padding-top: 5px + + h3, p + margin-bottom: 0 + padding-left: 0 + + p + padding-top: 0 + + .assignee + width: 50px + height: @width + margin-right: 10px + +// Other card details + .card-details padding: 0 flex-shrink: 0 diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index e551cab5..ebfa48ba 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -15,23 +15,6 @@ template(name="userAvatar") a.edit-avatar.js-change-avatar i.fa.fa-pencil -template(name="userAvatarAssignee") - a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})") - if userData.profile.avatarUrl - img.avatar.avatar-image(src="{{userData.profile.avatarUrl}}") - else - +userAvatarInitials(userId=userData._id) - - if showStatus - span.assignee-presence-status(class=presenceStatusClassName) - span.assignee-type(class=assigneeType) - - unless isSandstorm - if showEdit - if $eq currentUser._id userData._id - a.edit-avatar.js-change-avatar - i.fa.fa-pencil - template(name="userAvatarInitials") svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15") text(x="50%" y="13" text-anchor="middle")= initials @@ -95,18 +78,3 @@ template(name="cardMemberPopup") if $eq currentUser._id user._id with currentUser li: a.js-edit-profile {{_ 'edit-profile'}} - -template(name="cardAssigneePopup") - .board-assignee-menu - .mini-profile-info - +userAvatar(userId=user._id showEdit=true) - .info - h3= user.profile.fullname - p.quiet @{{ user.username }} - ul.pop-over-list - if currentUser.isNotCommentOnly - li: a.js-remove-assignee {{_ 'remove-member-from-card'}} - - if $eq currentUser._id user._id - with currentUser - li: a.js-edit-profile {{_ 'edit-profile'}} diff --git a/client/components/users/userAvatar.js b/client/components/users/userAvatar.js index 7a2831b2..262a63af 100644 --- a/client/components/users/userAvatar.js +++ b/client/components/users/userAvatar.js @@ -139,13 +139,6 @@ Template.cardMembersPopup.helpers({ return _.contains(cardMembers, this.userId); }, - isCardAssignee() { - const card = Template.parentData(); - const cardAssignees = card.getAssignees(); - - return _.contains(cardAssignees, this.userId); - }, - user() { return Users.findOne(this.userId); }, @@ -173,26 +166,3 @@ Template.cardMemberPopup.events({ }, 'click .js-edit-profile': Popup.open('editProfile'), }); - -Template.cardAssigneesPopup.events({ - 'click .js-select-assignee'(event) { - const card = Cards.findOne(Session.get('currentCard')); - const assigneeId = this.userId; - card.toggleAssignee(assigneeId); - event.preventDefault(); - }, -}); - -Template.cardAssigneePopup.helpers({ - user() { - return Users.findOne(this.userId); - }, -}); - -Template.cardAssigneePopup.events({ - 'click .js-remove-assignee'() { - Cards.findOne(this.cardId).unassignAssignee(this.userId); - Popup.close(); - }, - 'click .js-edit-profile': Popup.open('editProfile'), -}); diff --git a/client/components/users/userAvatar.styl b/client/components/users/userAvatar.styl index 5fcd9f6c..b962b01c 100644 --- a/client/components/users/userAvatar.styl +++ b/client/components/users/userAvatar.styl @@ -2,8 +2,7 @@ avatar-radius = 50% -.member, -.assignee +.member border-radius: 3px display: block position: relative @@ -33,8 +32,7 @@ avatar-radius = 50% height: 100% width: @height - .member-presence-status, - .assignee-presence-status + .member-presence-status background-color: #b3b3b3 border: 1px solid #fff border-radius: 50% @@ -81,8 +79,7 @@ avatar-radius = 50% color: white - &.add-member, - &.add-assignee + &.add-member display: flex align-items: center justify-content: center @@ -114,8 +111,7 @@ avatar-radius = 50% p padding-top: 0 - .member, - .assignee + .member width: 50px height: @width margin-right: 10px -- cgit v1.2.3-1-g7c22 From 32ce2b51d8bff5e8851732394a8bae3c56f8b0b6 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sat, 2 Nov 2019 16:38:16 +0200 Subject: Assignee field like Jira #2452 , in progress. Added features: - When selecting new assignee (+) icon, list shows names who to add. TODO: - When selecting new assignee (+) icon, list does not yet show avatars who to add. Thanks to xet7 ! --- client/components/cards/cardDetails.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'client') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 3b2873a2..2c74985f 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -863,6 +863,19 @@ Template.cardAssigneesPopup.events({ }, }); +Template.cardAssigneesPopup.helpers({ + isCardAssignee() { + const card = Template.parentData(); + const cardAssignees = card.getAssignees(); + + return _.contains(cardAssignees, this.userId); + }, + + user() { + return Users.findOne(this.userId); + }, +}); + Template.cardAssigneePopup.helpers({ userData() { // We need to handle a special case for the search results provided by the -- cgit v1.2.3-1-g7c22 From d3ca8167626005c33602b600811bc56f8d47ae6a Mon Sep 17 00:00:00 2001 From: Benjamin Andresen Date: Mon, 4 Nov 2019 08:08:51 +0100 Subject: cardDate: fix ReceivedDate startAt coloring --- client/components/cards/cardDate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index 6634ee1b..77b39078 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -237,7 +237,7 @@ class CardReceivedDate extends CardDate { const theDate = this.date.get(); // if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged if ( - (startAt && theDate.isAfter(dueAt)) || + (startAt && theDate.isAfter(startAt)) || (endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)) ) -- cgit v1.2.3-1-g7c22 From 7a5401d5f09fc888c02defb189a6a70f9b2725ab Mon Sep 17 00:00:00 2001 From: Benjamin Andresen Date: Mon, 4 Nov 2019 08:10:11 +0100 Subject: cardDate: endDate coloring change if no due-date timestamp is set => Gray if end-date timestamp is younger than due-date timestamp => Green if end-date timestamp is older than due-date timestamp => Red resolves #2741 --- client/components/cards/cardDate.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index 77b39078..a298fbab 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -344,9 +344,9 @@ class CardEndDate extends CardDate { let classes = 'end-date' + ' '; const dueAt = this.data().getDue(); const theDate = this.date.get(); - if (theDate.diff(dueAt, 'days') >= 2) classes += 'long-overdue'; - else if (theDate.diff(dueAt, 'days') >= 0) classes += 'due'; - else if (theDate.diff(dueAt, 'days') >= -2) classes += 'almost-due'; + if (!dueAt) classes += '' + else if (theDate.isBefore(dueAt)) classes += 'current' + else if (theDate.isAfter(dueAt)) classes += 'due' return classes; } -- cgit v1.2.3-1-g7c22 From b56ddf9df9a3719fd29bd8b777decc37773779b6 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 4 Nov 2019 09:59:40 +0200 Subject: Fix prettier --- client/components/cards/cardDate.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index a298fbab..cb54b033 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -344,9 +344,9 @@ class CardEndDate extends CardDate { let classes = 'end-date' + ' '; const dueAt = this.data().getDue(); const theDate = this.date.get(); - if (!dueAt) classes += '' - else if (theDate.isBefore(dueAt)) classes += 'current' - else if (theDate.isAfter(dueAt)) classes += 'due' + if (!dueAt) classes += ''; + else if (theDate.isBefore(dueAt)) classes += 'current'; + else if (theDate.isAfter(dueAt)) classes += 'due'; return classes; } -- cgit v1.2.3-1-g7c22 From ea823ab68fd5243c8485177e44a074be836836b8 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 4 Nov 2019 10:00:28 +0200 Subject: Assignee field like Jira #2452 , in progress. --- client/components/cards/cardDetails.jade | 2 +- client/components/cards/cardDetails.styl | 45 -------------------------------- client/components/main/popup.styl | 6 +++-- 3 files changed, 5 insertions(+), 48 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index ad8010e4..97c2144f 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -325,7 +325,7 @@ template(name="userAvatarAssignee") +userAvatarAssigneeInitials(userId=userData._id) if showStatus - span.member-presence-status(class=presenceStatusClassName) + span.assignee-presence-status(class=presenceStatusClassName) span.member-type(class=memberType) unless isSandstorm diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index 295a659d..e4549e44 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -62,23 +62,6 @@ avatar-radius = 50% background: #e44242 border-color: #f1dada - .edit-avatar - position: absolute - top: 0 - height: 100% - width: 100% - border-radius: avatar-radius - background: black - display: flex - align-items: center - justify-content: center - opacity: 0 - - &:hover - opacity: 0.6 - - i.fa-pencil - color: white &.add-assignee @@ -90,34 +73,6 @@ avatar-radius = 50% &:hover, &.is-active box-shadow: 0 0 0 2px darken(white, 60%) inset -.atMention - background: #dbdbdb - border-radius: 3px - padding: 1px 4px - margin: -1px 0 - display: inline-block - - &.me - background: #cfdfe8 - -.mini-profile-info - margin-top: 10px - - .info - padding-top: 5px - - h3, p - margin-bottom: 0 - padding-left: 0 - - p - padding-top: 0 - - .assignee - width: 50px - height: @width - margin-right: 10px - // Other card details .card-details diff --git a/client/components/main/popup.styl b/client/components/main/popup.styl index ff00eef3..023cba3d 100644 --- a/client/components/main/popup.styl +++ b/client/components/main/popup.styl @@ -130,7 +130,8 @@ $popupWidth = 300px .popup-container-depth-{depth} transform: translateX(- depth * $popupWidth) -.select-members-list +.select-members-list, +.select-avatars-list margin-bottom: 8px .pop-over-list @@ -230,7 +231,8 @@ $popupWidth = 300px min-height: 56px position: relative - .member + .member, + .avatar position: absolute top: 2px left: 2px -- cgit v1.2.3-1-g7c22 From 6a8960547729148bd3085cb469f9e93d510ed66c Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 4 Nov 2019 10:52:52 +0200 Subject: Some drag handle fixes. Thanks to xet7 ! Related #2081 --- client/components/lists/list.styl | 6 +++--- client/components/lists/listHeader.jade | 6 +++--- client/components/swimlanes/swimlaneHeader.jade | 7 +++++-- client/components/swimlanes/swimlanes.styl | 10 +++++++++- 4 files changed, 20 insertions(+), 9 deletions(-) (limited to 'client') diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 0d3ccfce..27cf678c 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -168,7 +168,7 @@ padding: 27px 19px margin-top: 1px top: -7px - margin-right: 50px + margin-right: 7px right: -3px .list-header @@ -229,10 +229,10 @@ padding: 7px top: 50% transform: translateY(-50%) - margin-right: 27px + right: 47px font-size: 20px - .list-header-menu-handle + .list-header-handle position: absolute padding: 7px top: 50% diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 3b3a0242..064303ee 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -30,10 +30,10 @@ template(name="listHeader") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu - a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle + a.list-header-handle.handle.fa.fa-arrows.js-list-handle else a.list-header-menu-icon.fa.fa-angle-right.js-select-list - a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle + a.list-header-handle.handle.fa.fa-arrows.js-list-handle else if currentUser.isBoardMember if isWatching i.list-header-watch-icon.fa.fa-eye @@ -45,7 +45,7 @@ template(name="listHeader") a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu if showDesktopDragHandles - a.list-header-menu-handle.handle.fa.fa-arrows.js-list-handle + a.list-header-handle.handle.fa.fa-arrows.js-list-handle template(name="editListTitleForm") .list-composer diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index fb6ef21d..72a7f054 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -16,8 +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 - if showDesktopDragHandles - a.swimlane-header-menu-handle.handle.fa.fa-arrows.js-swimlane-header-handle + 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/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 503091ee..5bd6d2d2 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -50,7 +50,7 @@ margin-left: 5px margin-right: 10px - .swimlane-header-menu-handle + .swimlane-header-handle position: absolute padding: 7px top: 50% @@ -58,6 +58,14 @@ left: 300px 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% -- cgit v1.2.3-1-g7c22 From 2ec15602d284122fce1a45bed352d0d4050162e2 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 4 Nov 2019 11:13:10 +0200 Subject: Fix desktop swimlane drag handle position. Thanks to xet7 ! Related #2081 --- client/components/swimlanes/swimlanes.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 5bd6d2d2..164c66d5 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -55,7 +55,7 @@ padding: 7px top: 50% transform: translateY(-50%) - left: 300px + left: 230px font-size: 18px .swimlane-header-miniscreen-handle -- cgit v1.2.3-1-g7c22 From d84ea7d16fc9fa45d17cbe91d63035436f55343a Mon Sep 17 00:00:00 2001 From: jymcheong Date: Tue, 5 Nov 2019 11:04:35 +0800 Subject: fixed #2780 https://github.com/wekan/wekan/issues/2780 --- client/components/cards/cardDetails.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 2c74985f..2944b56c 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -121,11 +121,6 @@ BlazeComponent.extendComponent({ // Send Webhook but not create Activities records --- const card = this.currentData(); const userId = Meteor.userId(); - //console.log(`userId: ${userId}`); - //console.log(`cardId: ${card._id}`); - //console.log(`boardId: ${card.boardId}`); - //console.log(`listId: ${card.listId}`); - //console.log(`swimlaneId: ${card.swimlaneId}`); const params = { userId, cardId: card._id, @@ -134,16 +129,25 @@ BlazeComponent.extendComponent({ user: Meteor.user().username, url: '', }; - //console.log('looking for integrations...'); - const integrations = Integrations.find({ - boardId: card.boardId, - type: 'outgoing-webhooks', + + const integrations = Integrations.find({ + boardId: { $in: [card.boardId, Integrations.Const.GLOBAL_WEBHOOK_ID] }, enabled: true, activities: { $in: ['CardDetailsRendered', 'all'] }, }).fetch(); - //console.log(`Investigation length: ${integrations.length}`); + if (integrations.length > 0) { - Meteor.call('outgoingWebhooks', integrations, 'CardSelected', params); + integrations.forEach(integration => { + Meteor.call( + 'outgoingWebhooks', + integration, + 'CardSelected', + params, + () => { + return; + }, + ); + }); } //------------- } -- cgit v1.2.3-1-g7c22 From ebdb3a0cc3b10e804b30635b5a19dcfbf4a3eadc Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 5 Nov 2019 23:26:07 +0200 Subject: Fix prettier. --- client/components/cards/cardDetails.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 2944b56c..ad500657 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -129,13 +129,13 @@ BlazeComponent.extendComponent({ user: Meteor.user().username, url: '', }; - - const integrations = Integrations.find({ - boardId: { $in: [card.boardId, Integrations.Const.GLOBAL_WEBHOOK_ID] }, + + const integrations = Integrations.find({ + boardId: { $in: [card.boardId, Integrations.Const.GLOBAL_WEBHOOK_ID] }, enabled: true, activities: { $in: ['CardDetailsRendered', 'all'] }, }).fetch(); - + if (integrations.length > 0) { integrations.forEach(integration => { Meteor.call( -- cgit v1.2.3-1-g7c22 From 56efb5c41075151eeb259d99990a7e86695b2b69 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 5 Nov 2019 23:42:22 +0200 Subject: Assignee field like Jira #2452 , in progress. In add assignee popup, avatars are now visible. Thanks to xet7 ! --- client/components/cards/cardDetails.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 97c2144f..02929757 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -310,7 +310,7 @@ template(name="cardAssigneesPopup") each board.activeMembers li.item(class="{{#if isCardAssignee}}active{{/if}}") a.name.js-select-assignee(href="#") - +userAvatarAssignee(userId=user._id) + +userAvatar(userId=user._id) span.full-name = user.profile.fullname | ({{ user.username }}) -- cgit v1.2.3-1-g7c22 From 3cf09efb13438d66db6cf739591c679ea538d812 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 7 Nov 2019 00:14:50 +0200 Subject: Assignee field like Jira #2452 , in progress. When there is one selected assignee on card, don't show + button for adding more assignees, because there can only be one assignee. Thanks to xet7 ! --- client/components/cards/cardDetails.jade | 5 +++-- client/components/cards/cardDetails.js | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 02929757..53a264ec 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -79,8 +79,9 @@ template(name="cardDetails") +userAvatarAssignee(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} if canModifyCard - a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}") - i.fa.fa-plus + unless assigneeSelected + a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}") + i.fa.fa-plus .card-details-item.card-details-item-labels h3.card-details-item-title {{_ 'labels'}} diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index ad500657..7bb54223 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -364,6 +364,14 @@ Template.cardDetails.helpers({ }); }, + assigneeSelected() { + if (this.getAssignees().length === 0) { + return false; + } else { + return true; + } + }, + memberType() { const user = Users.findOne(this.userId); return user && user.isBoardAdmin() ? 'admin' : 'normal'; -- cgit v1.2.3-1-g7c22 From 9fd14f7ecb593d3debf5adff8f6c61adb0c3feca Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 7 Nov 2019 06:04:23 +0200 Subject: Assignee field like Jira #2452 , in progress. Now assignee is visible also at minicard. Thanks to xet7 ! --- client/components/cards/minicard.jade | 6 ++++++ client/components/cards/minicard.styl | 14 +++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'client') diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index ba0c5707..79672f8c 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -76,6 +76,12 @@ template(name="minicard") +viewer = trueValue + if getAssignees + .minicard-assignees.js-minicard-assignees + each getAssignees + +userAvatar(userId=this) + hr + if getMembers .minicard-members.js-minicard-members each getMembers diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 9997fd5f..8607e118 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -160,9 +160,10 @@ padding-left: 0px line-height: 12px - .minicard-members + .minicard-members, + .minicard-assignees float: right - margin: 2px -8px -2px 0 + margin: 2px -8px 12px 0 .member float: right @@ -170,10 +171,17 @@ height: 28px width: @height + .assignee + float: right + border-radius: 50% + height: 28px + width: @height + + .badges margin-top: 10px - .minicard-members:empty + .minicard-members:empty, + .minicard-assignees:empty display: none &.minicard-composer -- cgit v1.2.3-1-g7c22 From 36b5965dd07e3f0fd90069353310739c394c220f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 8 Nov 2019 00:21:04 +0200 Subject: Close card button now visible on mobile. Closes #2261 --- client/components/cards/cardDetails.jade | 11 ++++++++--- client/components/cards/cardDetails.styl | 14 +++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 53a264ec..2b4f44b9 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -4,9 +4,14 @@ template(name="cardDetails") +inlinedForm(classNames="js-card-details-title") +editCardTitleForm else - a.fa.fa-times-thin.close-card-details.js-close-card-details - if currentUser.isBoardMember - a.fa.fa-navicon.card-details-menu.js-open-card-details-menu + unless isMiniScreen + a.fa.fa-times-thin.close-card-details.js-close-card-details + if currentUser.isBoardMember + a.fa.fa-navicon.card-details-menu.js-open-card-details-menu + if isMiniScreen + a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details + if currentUser.isBoardMember + a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu h2.card-details-title.js-card-title( class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}") +viewer diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index e4549e44..3fc4d047 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -107,7 +107,9 @@ avatar-radius = 50% border-bottom: 1px solid darken(white, 14%) .close-card-details, - .card-details-menu + .card-details-menu, + .close-card-details-mobile-web, + .card-details-menu-mobile-web float: right .close-card-details @@ -115,10 +117,20 @@ avatar-radius = 50% padding: 5px margin-right: -8px + .close-card-details-mobile-web + font-size: 24px + padding: 5px + margin-right: 40px + .card-details-menu font-size: 17px padding: 10px + .card-details-menu-mobile-web + font-size: 17px + padding: 10px + margin-right: 30px + .card-details-watch font-size: 17px padding-left: 7px -- cgit v1.2.3-1-g7c22 From 274a997e62b421b034e1eb0b3a486813fe127240 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 13 Nov 2019 19:33:13 +0200 Subject: Fix card, list and swimlane move. Allow moving cards in multiselect mode. Closes #2771, closes #2743, closes #2704, related #2081 --- client/components/boards/boardBody.js | 19 ++++++++++++- client/components/lists/list.js | 27 ++++++++++--------- client/components/swimlanes/swimlaneHeader.jade | 2 ++ client/components/swimlanes/swimlanes.js | 36 ++++++++++++++----------- 4 files changed, 54 insertions(+), 30 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 47042ae7..82f12c40 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -89,7 +89,6 @@ BlazeComponent.extendComponent({ helper.append(list.clone()); return helper; }, - handle: '.js-swimlane-header-handle', items: '.swimlane:not(.placeholder)', placeholder: 'swimlane placeholder', distance: 7, @@ -193,6 +192,24 @@ BlazeComponent.extendComponent({ // ugly touch event hotfix enableClickOnTouch('.js-swimlane:not(.placeholder)'); + this.autorun(() => { + if ( + Utils.isMiniScreen() || + (!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles()) + ) { + $swimlanesDom.sortable({ + handle: '.js-swimlane-header-handle', + }); + } else { + $swimlanesDom.sortable({ + handle: '.swimlane-header', + }); + } + + // Disable drag-dropping if the current user is not a board member or is comment only + $swimlanesDom.sortable('option', 'disabled', !userIsMember()); + }); + function userIsMember() { return ( Meteor.user() && diff --git a/client/components/lists/list.js b/client/components/lists/list.js index b7b8b2e0..6bd8eefe 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -31,18 +31,6 @@ BlazeComponent.extendComponent({ const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)'; const $cards = this.$('.js-minicards'); - if (Utils.isMiniScreen) { - $('.js-minicards').sortable({ - handle: '.handle', - }); - } - - if (!Utils.isMiniScreen && showDesktopDragHandles) { - $('.js-minicards').sortable({ - handle: '.handle', - }); - } - $cards.sortable({ connectWith: '.js-minicards:not(.js-list-full)', tolerance: 'pointer', @@ -128,8 +116,21 @@ BlazeComponent.extendComponent({ // ugly touch event hotfix enableClickOnTouch(itemsSelector); - // Disable drag-dropping if the current user is not a board member or is comment only this.autorun(() => { + if ( + Utils.isMiniScreen() || + (!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles()) + ) { + $cards.sortable({ + handle: '.handle', + }); + } else { + $cards.sortable({ + handle: '.minicard', + }); + } + + // Disable drag-dropping if the current user is not a board member or is comment only $cards.sortable('option', 'disabled', !userIsMember()); }); diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 72a7f054..4b48b0cc 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -17,6 +17,8 @@ template(name="swimlaneFixedHeader") a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon a.fa.fa-navicon.js-open-swimlane-menu unless isMiniScreen + unless showDesktopDragHandles + a.swimlane-header.handle.fa.fa-arrows.js-swimlane-header-handle if showDesktopDragHandles a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle if isMiniScreen diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 8faad870..f2fa882f 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -53,18 +53,6 @@ function initSortable(boardComponent, $listsDom) { }, }; - if (Utils.isMiniScreen) { - $listsDom.sortable({ - handle: '.js-list-handle', - }); - } - - if (!Utils.isMiniScreen && showDesktopDragHandles) { - $listsDom.sortable({ - handle: '.js-list-header', - }); - } - $listsDom.sortable({ tolerance: 'pointer', helper: 'clone', @@ -108,15 +96,29 @@ function initSortable(boardComponent, $listsDom) { ); } - // Disable drag-dropping while in multi-selection mode, or if the current user - // is not a board member boardComponent.autorun(() => { + if ( + Utils.isMiniScreen() || + (!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles()) + ) { + $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(), ); } }); @@ -164,7 +166,9 @@ BlazeComponent.extendComponent({ // his mouse. const noDragInside = ['a', 'input', 'textarea', 'p'].concat( - Util.isMiniScreen || (!Util.isMiniScreen && showDesktopDragHandles) + Utils.isMiniScreen() || + (!Utils.isMiniScreen() && + Meteor.user().hasShowDesktopDragHandles()) ? ['.js-list-handle', '.js-swimlane-header-handle'] : ['.js-list-header'], ); -- cgit v1.2.3-1-g7c22 From a6366114718f0faf0e1c600374ffdd8745a3d9ff Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 17 Nov 2019 00:57:50 +0200 Subject: Remove swimlane handle at desktop non-handle mode. --- client/components/swimlanes/swimlaneHeader.jade | 2 -- 1 file changed, 2 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 4b48b0cc..72a7f054 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -17,8 +17,6 @@ template(name="swimlaneFixedHeader") a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon a.fa.fa-navicon.js-open-swimlane-menu unless isMiniScreen - unless showDesktopDragHandles - a.swimlane-header.handle.fa.fa-arrows.js-swimlane-header-handle if showDesktopDragHandles a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle if isMiniScreen -- cgit v1.2.3-1-g7c22 From 26e0bbce172f89baa380ddae19b7b495519db40f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 17 Nov 2019 01:20:26 +0200 Subject: Swimlanes collapsed by default. TODO: - Add count. - Move list names to top, if possible. I did not get it working yet. - Try to fit collapse+swimlane name etc at same row. Related #2804 --- client/components/swimlanes/swimlanes.jade | 31 ++++++++------- client/components/swimlanes/swimlanes.js | 16 ++++++++ client/components/swimlanes/swimlanes.styl | 60 +++++++++++++++++++++++------- 3 files changed, 80 insertions(+), 27 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 9eab6054..3c70833e 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -1,24 +1,27 @@ template(name="swimlane") .swimlane +swimlaneHeader - .swimlane.js-lists.js-swimlane - if isMiniScreen - if currentListIsInThisSwimlane _id - +list(currentList) - unless currentList + // 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 - +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 template(name="listsGroup") .swimlane.list-group.js-lists diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index f2fa882f..0b94174d 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -134,6 +134,22 @@ BlazeComponent.extendComponent({ } initSortable(boardComponent, $listsDom); + + // Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp + var acc = document.getElementsByClassName("accordion"); + var i; + for (i = 0; i < acc.length; i++) { + acc[i].addEventListener("click", function() { + this.classList.toggle("active"); + var 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); diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 164c66d5..9a89bf07 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -1,5 +1,39 @@ @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 +59,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 -- cgit v1.2.3-1-g7c22 From c93ea33d05bed042a744fc11e4730c9e5ecdb93b Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 17 Nov 2019 01:36:33 +0200 Subject: Fix prettify. --- client/components/swimlanes/swimlanes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 0b94174d..2cba5b56 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -136,16 +136,16 @@ BlazeComponent.extendComponent({ initSortable(boardComponent, $listsDom); // Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp - var acc = document.getElementsByClassName("accordion"); + var acc = document.getElementsByClassName('accordion'); var i; for (i = 0; i < acc.length; i++) { - acc[i].addEventListener("click", function() { - this.classList.toggle("active"); + acc[i].addEventListener('click', function() { + this.classList.toggle('active'); var panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { - panel.style.maxHeight = panel.scrollHeight + "px"; + panel.style.maxHeight = panel.scrollHeight + 'px'; } }); } -- cgit v1.2.3-1-g7c22 From f652b677d0fa9c8bbeef7ca366aebd5f5a149d02 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 17 Nov 2019 01:59:57 +0200 Subject: Fix prettier. --- client/components/swimlanes/swimlanes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 2cba5b56..f4e33ddd 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -136,16 +136,16 @@ BlazeComponent.extendComponent({ initSortable(boardComponent, $listsDom); // Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp - var acc = document.getElementsByClassName('accordion'); - var i; + let acc = document.getElementsByClassName('accordion'); + let i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener('click', function() { this.classList.toggle('active'); - var panel = this.nextElementSibling; + let panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { - panel.style.maxHeight = panel.scrollHeight + 'px'; + panel.style.maxHeight = panel.scrollHeight.toString() + 'px'; } }); } -- cgit v1.2.3-1-g7c22 From 34bfb09c85ead9d0db4fd8b5fb9f923593bcb25a Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 17 Nov 2019 14:03:39 +0200 Subject: Fix prettier. --- client/components/swimlanes/swimlanes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'client') diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index f4e33ddd..56d8fb81 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -136,16 +136,16 @@ BlazeComponent.extendComponent({ initSortable(boardComponent, $listsDom); // Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp - let acc = document.getElementsByClassName('accordion'); + const acc = document.getElementsByClassName('accordion'); let i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener('click', function() { this.classList.toggle('active'); - let panel = this.nextElementSibling; + const panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { - panel.style.maxHeight = panel.scrollHeight.toString() + 'px'; + panel.style.maxHeight = `${panel.scrollHeight}px`; } }); } -- cgit v1.2.3-1-g7c22 From 96abe3c6914ce37d9fb44da8fda375e40ad65c9e Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 18 Nov 2019 22:23:49 +0200 Subject: New feature: Now there is popup selection of Lists/Swimlanes/Calendar/Roles. New feature, not set visible yet, because switching to it does not work properly yet: Collapsible Swimlanes #2804 Fix: Public board now loads correctly. When you select one of Lists/Swimlanes/Calendar view and reload webbrowser page, it can change view. Closes #2311 Fix: List sorting commented out. Closes #2800 Fix: Errors hasHiddenMinicardText, hasShowDragHandles, showSort, hasSortBy, profile, FirefoxAndroid/IE11/Vivaldi/Chromium browsers not working by using cookies instead of database. More details at https://github.com/wekan/wekan/issues/2643#issuecomment-554907955 Note: Cookie changes are not always immediate, if there is no effect, you may need to reload webbrowser page. Closes #2643 . Thanks to xet7 ! --- client/components/boards/boardBody.js | 29 +++++-- client/components/boards/boardHeader.jade | 104 +++++++++++++++++------- client/components/boards/boardHeader.js | 109 +++++++++++++++++++++----- client/components/cards/minicard.js | 24 +++++- client/components/lists/list.js | 25 +++--- client/components/lists/listBody.js | 25 +++--- client/components/lists/listHeader.js | 16 +++- client/components/sidebar/sidebar.js | 16 +++- client/components/swimlanes/swimlaneHeader.js | 8 +- client/components/swimlanes/swimlanes.jade | 26 +++++- client/components/swimlanes/swimlanes.js | 55 +++++++------ client/components/users/userHeader.js | 30 ++++++- client/lib/utils.js | 54 +++++++++++++ 13 files changed, 403 insertions(+), 118 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 82f12c40..8122a0b6 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -192,10 +192,13 @@ BlazeComponent.extendComponent({ // ugly touch event hotfix enableClickOnTouch('.js-swimlane:not(.placeholder)'); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + this.autorun(() => { if ( Utils.isMiniScreen() || - (!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles()) + (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) ) { $swimlanesDom.sortable({ handle: '.js-swimlane-header-handle', @@ -227,20 +230,32 @@ BlazeComponent.extendComponent({ }, isViewSwimlanes() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); const currentUser = Meteor.user(); - if (!currentUser) return false; + if (!currentUser) { + return cookies.get('boardView') === 'board-view-swimlanes'; + } return (currentUser.profile || {}).boardView === 'board-view-swimlanes'; }, isViewLists() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); const currentUser = Meteor.user(); - if (!currentUser) return true; + if (!currentUser) { + return cookies.get('boardView') === 'board-view-lists'; + } return (currentUser.profile || {}).boardView === 'board-view-lists'; }, isViewCalendar() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); const currentUser = Meteor.user(); - if (!currentUser) return false; + if (!currentUser) { + return cookies.get('boardView') === 'board-view-cal'; + } return (currentUser.profile || {}).boardView === 'board-view-cal'; }, @@ -398,8 +413,12 @@ BlazeComponent.extendComponent({ }; }, isViewCalendar() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); const currentUser = Meteor.user(); - if (!currentUser) return false; + if (!currentUser) { + return cookies.get('boardView') === 'board-view-cal'; + } return (currentUser.profile || {}).boardView === 'board-view-cal'; }, }).register('calendarView'); diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 175cc2c2..39221778 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -77,10 +77,11 @@ template(name="boardHeaderBar") i.fa.fa-archive span {{_ 'archives'}} - if showSort - a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}") - i.fa(class="{{directionClass}}") - span {{_ 'sort'}}{{_ listSortShortDesc}} + //if showSort + // a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}") + // i.fa(class="{{directionClass}}") + // span {{_ 'sort'}}{{_ listSortShortDesc}} + a.board-header-btn.js-open-filter-view( title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}" class="{{#if Filter.isActive}}emphasis{{/if}}") @@ -89,15 +90,6 @@ template(name="boardHeaderBar") if Filter.isActive a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}") i.fa.fa-times-thin - - if currentUser.isAdmin - a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}") - i.fa.fa-magic - span {{_ 'rules'}} - else if currentUser.isBoardAdmin - a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}") - i.fa.fa-magic - span {{_ 'rules'}} a.board-header-btn.js-open-search-view(title="{{_ 'search'}}") i.fa.fa-search @@ -106,8 +98,19 @@ template(name="boardHeaderBar") unless currentBoard.isTemplatesBoard a.board-header-btn.js-toggle-board-view( title="{{_ 'board-view'}}") - i.fa.fa-th-large - span {{#if currentUser.profile.boardView}}{{_ currentUser.profile.boardView}}{{else}}{{_ 'board-view-lists'}}{{/if}} + i.fa.fa-caret-down + if $eq boardView 'board-view-lists' + i.fa.fa-trello + if $eq boardView 'board-view-swimlanes' + i.fa.fa-th-large + // unless collapseSwimlane + // i.fa.fa-th-large + // if collapseSwimlane + // i.fa.fa-play + if $eq boardView 'board-view-cal' + i.fa.fa-calendar + span {{#if boardView}}{{_ boardView}}{{else}}{{_ 'board-view-lists'}}{{/if}} + //span {{#if collapseSwimlane}}{{_ 'board-view-collapse'}}{{else}}{{#if boardView}}{{_ boardView}}{{else}}{{_ 'board-view-lists'}}{{/if}}{{/if}} if canModifyBoard a.board-header-btn.js-multiselection-activate( @@ -172,6 +175,51 @@ template(name="boardChangeWatchPopup") i.fa.fa-check span.sub-name {{_ 'muted-info'}} +template(name="boardChangeViewPopup") + ul.pop-over-list + li + with "board-view-lists" + a.js-open-lists-view + i.fa.fa-trello.colorful + | {{_ 'board-view-lists'}} + if $eq Utils.boardView "board-view-lists" + i.fa.fa-check + li + with "board-view-swimlanes" + a.js-open-swimlanes-view + i.fa.fa-th-large.colorful + | {{_ 'board-view-swimlanes'}} + if $eq Utils.boardView "board-view-swimlanes" + i.fa.fa-check + //li + // with "board-view-collapse" + // a.js-open-collapse-view + // i.fa.fa-play.colorful + // | {{_ 'board-view-collapse'}} + // if $eq Utils.boardView "board-view-collapse" + // i.fa.fa-check + li + with "board-view-cal" + a.js-open-cal-view + i.fa.fa-calendar.colorful + | {{_ 'board-view-cal'}} + if $eq Utils.boardView "board-view-cal" + i.fa.fa-check + if currentUser.isAdmin + hr + li + with "board-view-rules" + a.js-open-rules-view(title="{{_ 'rules'}}") + i.fa.fa-magic + | {{_ 'rules'}} + else if currentUser.isBoardAdmin + hr + li + with "board-view-rules" + a.js-open-rules-view(title="{{_ 'rules'}}") + i.fa.fa-magic + | {{_ 'rules'}} + template(name="createBoard") form label @@ -198,19 +246,19 @@ template(name="createBoard") | / a.js-board-template {{_ 'template'}} -template(name="listsortPopup") - h2 - | {{_ 'list-sort-by'}} - hr - ul.pop-over-list - each value in allowedSortValues - li - a.js-sort-by(name="{{value.name}}") - if $eq sortby value.name - i(class="fa {{Direction}}") - | {{_ value.label }}{{_ value.shortLabel}} - if $eq sortby value.name - i(class="fa fa-check") +//template(name="listsortPopup") +// h2 +// | {{_ 'list-sort-by'}} +// hr +// ul.pop-over-list +// each value in allowedSortValues +// li +// a.js-sort-by(name="{{value.name}}") +// if $eq sortby value.name +// i(class="fa {{Direction}}") +// | {{_ value.label }}{{_ value.shortLabel}} +// if $eq sortby value.name +// i(class="fa fa-check") template(name="boardChangeTitlePopup") form diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index e14b1444..1706f8e4 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -1,5 +1,7 @@ +/* const DOWNCLS = 'fa-sort-down'; const UPCLS = 'fa-sort-up'; +*/ Template.boardMenuPopup.events({ 'click .js-rename-board': Popup.open('boardChangeTitle'), 'click .js-custom-fields'() { @@ -82,6 +84,7 @@ BlazeComponent.extendComponent({ const currentBoard = Boards.findOne(Session.get('currentBoard')); return currentBoard && currentBoard.stars >= 2; }, + /* showSort() { return Meteor.user().hasSortBy(); }, @@ -101,6 +104,7 @@ BlazeComponent.extendComponent({ listSortShortDesc() { return `list-label-short-${this.currentListSortBy()}`; }, + */ events() { return [ { @@ -114,30 +118,14 @@ BlazeComponent.extendComponent({ 'click .js-open-archived-board'() { Modal.open('archivedBoards'); }, - 'click .js-toggle-board-view'() { - const currentUser = Meteor.user(); - if ( - (currentUser.profile || {}).boardView === 'board-view-swimlanes' - ) { - currentUser.setBoardView('board-view-cal'); - } else if ( - (currentUser.profile || {}).boardView === 'board-view-lists' - ) { - currentUser.setBoardView('board-view-swimlanes'); - } else if ( - (currentUser.profile || {}).boardView === 'board-view-cal' - ) { - currentUser.setBoardView('board-view-lists'); - } else { - currentUser.setBoardView('board-view-swimlanes'); - } - }, + 'click .js-toggle-board-view': Popup.open('boardChangeView'), 'click .js-toggle-sidebar'() { Sidebar.toggle(); }, 'click .js-open-filter-view'() { Sidebar.setView('filter'); }, + /* 'click .js-open-sort-view'(evt) { const target = evt.target; if (target.tagName === 'I') { @@ -148,6 +136,7 @@ BlazeComponent.extendComponent({ Popup.open('listsort')(evt); } }, + */ 'click .js-filter-reset'(event) { event.stopPropagation(); Sidebar.setView(); @@ -156,9 +145,6 @@ BlazeComponent.extendComponent({ 'click .js-open-search-view'() { Sidebar.setView('search'); }, - 'click .js-open-rules-view'() { - Modal.openWide('rulesMain'); - }, 'click .js-multiselection-activate'() { const currentCard = Session.get('currentCard'); MultiSelection.activate(); @@ -186,6 +172,85 @@ Template.boardHeaderBar.helpers({ !Meteor.user().isCommentOnly() ); }, + boardView() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.get('boardView') === 'board-view-lists') { + return 'board-view-lists'; + } else if (cookies.get('boardView') === 'board-view-swimlanes') { + return 'board-view-swimlanes'; + } else if (cookies.get('boardView') === 'board-view-collapse') { + return 'board-view-collapse'; + } else if (cookies.get('boardView') === 'board-view-cal') { + return 'board-view-cal'; + } else { + return false; + } + }, + collapseSwimlane() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('collapseSwimlane')) { + return true; + } else { + return false; + } + }, +}); + +Template.boardChangeViewPopup.events({ + 'click .js-open-lists-view'() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.get('boardView') !== 'board-view-lists') { + cookies.set('boardView', 'board-view-lists'); + const currentUser = Meteor.user(); + if (currentUser) { + Meteor.user().setBoardView('board-view-lists'); + } + } + Popup.close(); + }, + 'click .js-open-swimlanes-view'() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.get('boardView') !== 'board-view-swimlanes') { + cookies.set('boardView', 'board-view-swimlanes'); + cookies.remove('collapseSwimlane'); + const currentUser = Meteor.user(); + if (currentUser) { + Meteor.user().setBoardView('board-view-swimlanes'); + } + } + Popup.close(); + }, + 'click .js-open-collapse-view'() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.get('boardView') !== 'board-view-swimlanes') { + cookies.set('boardView', 'board-view-swimlanes'); + cookies.set('collapseSwimlane', 'true'); + const currentUser = Meteor.user(); + if (currentUser) { + Meteor.user().setBoardView('board-view-swimlanes'); + } + } + Popup.close(); + }, + 'click .js-open-cal-view'() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + cookies.set('boardView', 'board-view-cal'); + const currentUser = Meteor.user(); + if (currentUser) { + Meteor.user().setBoardView('board-view-cal'); + } + Popup.close(); + }, + 'click .js-open-rules-view'() { + Modal.openWide('rulesMain'); + Popup.close(); + }, }); const CreateBoard = BlazeComponent.extendComponent({ @@ -308,6 +373,7 @@ BlazeComponent.extendComponent({ }, }).register('boardChangeWatchPopup'); +/* BlazeComponent.extendComponent({ onCreated() { //this.sortBy = new ReactiveVar(); @@ -377,3 +443,4 @@ BlazeComponent.extendComponent({ ]; }, }).register('listsortPopup'); +*/ diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 4c76db46..5caea709 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -18,7 +18,13 @@ BlazeComponent.extendComponent({ }, { 'click .js-toggle-minicard-label-text'() { - Meteor.call('toggleMinicardLabelText'); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + cookies.remove('hiddenMinicardLabelText'); //true + } else { + cookies.set('hiddenMinicardLabelText', 'true'); //true + } }, }, ]; @@ -27,9 +33,21 @@ BlazeComponent.extendComponent({ Template.minicard.helpers({ showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } }, hiddenMinicardLabelText() { - return Meteor.user().hasHiddenMinicardLabelText(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + return true; + } else { + return false; + } }, }); diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 6bd8eefe..8433ad90 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -73,16 +73,15 @@ BlazeComponent.extendComponent({ const listId = Blaze.getData(ui.item.parents('.list').get(0))._id; const currentBoard = Boards.findOne(Session.get('currentBoard')); let swimlaneId = ''; - const boardView = (Meteor.user().profile || {}).boardView; if ( - boardView === 'board-view-swimlanes' || + Utils.boardView() === 'board-view-swimlanes' || currentBoard.isTemplatesBoard() ) swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id; else if ( - boardView === 'board-view-lists' || - boardView === 'board-view-cal' || - !boardView + Utils.boardView() === 'board-view-lists' || + Utils.boardView() === 'board-view-cal' || + !Utils.boardView ) swimlaneId = currentBoard.getDefaultSwimline()._id; @@ -116,11 +115,11 @@ BlazeComponent.extendComponent({ // ugly touch event hotfix enableClickOnTouch(itemsSelector); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + this.autorun(() => { - if ( - Utils.isMiniScreen() || - (!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles()) - ) { + if (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) { $cards.sortable({ handle: '.handle', }); @@ -164,7 +163,13 @@ BlazeComponent.extendComponent({ Template.list.helpers({ showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } }, }); diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index c8e41a0b..46d2794e 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -48,7 +48,6 @@ BlazeComponent.extendComponent({ const board = this.data().board(); let linkedId = ''; let swimlaneId = ''; - const boardView = (Meteor.user().profile || {}).boardView; let cardType = 'cardType-card'; if (title) { if (board.isTemplatesBoard()) { @@ -71,14 +70,14 @@ BlazeComponent.extendComponent({ }); cardType = 'cardType-linkedBoard'; } - } else if (boardView === 'board-view-swimlanes') + } else if (Utils.boardView() === 'board-view-swimlanes') swimlaneId = this.parentComponent() .parentComponent() .data()._id; else if ( - boardView === 'board-view-lists' || - boardView === 'board-view-cal' || - !boardView + Utils.boardView() === 'board-view-lists' || + Utils.boardView() === 'board-view-cal' || + !Utils.boardView ) swimlaneId = board.getDefaultSwimline()._id; @@ -157,9 +156,8 @@ BlazeComponent.extendComponent({ }, idOrNull(swimlaneId) { - const currentUser = Meteor.user(); if ( - (currentUser.profile || {}).boardView === 'board-view-swimlanes' || + Utils.boardView() === 'board-view-swimlanes' || this.data() .board() .isTemplatesBoard() @@ -397,10 +395,9 @@ BlazeComponent.extendComponent({ '.js-swimlane', ); this.swimlaneId = ''; - const boardView = (Meteor.user().profile || {}).boardView; - if (boardView === 'board-view-swimlanes') + if (Utils.boardView() === 'board-view-swimlanes') this.swimlaneId = Blaze.getData(swimlane[0])._id; - else if (boardView === 'board-view-lists' || !boardView) + else if (Utils.boardView() === 'board-view-lists' || !Utils.boardView) this.swimlaneId = Swimlanes.findOne({ boardId: this.boardId })._id; }, @@ -580,7 +577,7 @@ BlazeComponent.extendComponent({ const swimlane = $(Popup._getTopStack().openerElement).parents( '.js-swimlane', ); - if ((Meteor.user().profile || {}).boardView === 'board-view-swimlanes') + if (Utils.boardView() === 'board-view-swimlanes') this.swimlaneId = Blaze.getData(swimlane[0])._id; else this.swimlaneId = Swimlanes.findOne({ boardId: this.boardId })._id; // List where to insert card @@ -709,8 +706,7 @@ BlazeComponent.extendComponent({ if (isSandstorm) { const user = Meteor.user(); if (user) { - const boardView = (Meteor.user().profile || {}).boardView; - if (boardView === 'board-view-swimlanes') { + if (Utils.boardView() === 'board-view-swimlanes') { this.swimlaneId = this.parentComponent() .parentComponent() .parentComponent() @@ -718,8 +714,7 @@ BlazeComponent.extendComponent({ } } } else { - const boardView = (Meteor.user().profile || {}).boardView; - if (boardView === 'board-view-swimlanes') { + if (Utils.boardView() === 'board-view-swimlanes') { this.swimlaneId = this.parentComponent() .parentComponent() .parentComponent() diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index b524d4e0..90946610 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -44,14 +44,16 @@ BlazeComponent.extendComponent({ }, limitToShowCardsCount() { - return Meteor.user().getLimitToShowCardsCount(); + const currentUser = Meteor.user(); + if (currentUser) { + return Meteor.user().getLimitToShowCardsCount(); + } }, cardsCount() { const list = Template.currentData(); let swimlaneId = ''; - const boardView = (Meteor.user().profile || {}).boardView; - if (boardView === 'board-view-swimlanes') + if (Utils.boardView() === 'board-view-swimlanes') swimlaneId = this.parentComponent() .parentComponent() .data()._id; @@ -100,7 +102,13 @@ BlazeComponent.extendComponent({ Template.listHeader.helpers({ showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } }, }); diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index f1ccfb1e..4b918d54 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -107,7 +107,13 @@ BlazeComponent.extendComponent({ 'click .js-toggle-sidebar': this.toggle, 'click .js-back-home': this.setView, 'click .js-toggle-minicard-label-text'() { - Meteor.call('toggleMinicardLabelText'); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + cookies.remove('hiddenMinicardLabelText'); //true + } else { + cookies.set('hiddenMinicardLabelText', 'true'); //true + } }, 'click .js-shortcuts'() { FlowRouter.go('shortcuts'); @@ -121,7 +127,13 @@ Blaze.registerHelper('Sidebar', () => Sidebar); Template.homeSidebar.helpers({ hiddenMinicardLabelText() { - return Meteor.user().hasHiddenMinicardLabelText(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + return true; + } else { + return false; + } }, }); diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index 6f8029fd..c8ef4dcb 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -30,7 +30,13 @@ BlazeComponent.extendComponent({ Template.swimlaneHeader.helpers({ showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } }, }); diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 3c70833e..ea9cc913 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -1,9 +1,7 @@ template(name="swimlane") .swimlane +swimlaneHeader - // Minimize swimlanes next 2 lines below https://www.w3schools.com/howto/howto_js_accordion.asp - button(class="accordion") - div(class="panel") + unless collapseSwimlane .swimlane.js-lists.js-swimlane if isMiniScreen if currentListIsInThisSwimlane _id @@ -22,6 +20,28 @@ template(name="swimlane") 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 diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 56d8fb81..1bb522e5 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -14,7 +14,7 @@ function currentCardIsInThisList(listId, swimlaneId) { if ( currentUser && currentUser.profile && - currentUser.profile.boardView === 'board-view-swimlanes' + Utils.boardView() === 'board-view-swimlanes' ) return ( currentCard && @@ -97,10 +97,9 @@ function initSortable(boardComponent, $listsDom) { } boardComponent.autorun(() => { - if ( - Utils.isMiniScreen() || - (!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles()) - ) { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) { $listsDom.sortable({ handle: '.js-list-handle', }); @@ -135,21 +134,25 @@ BlazeComponent.extendComponent({ initSortable(boardComponent, $listsDom); - // 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`; - } - }); + 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 } - // Minimize swimlanes end https://www.w3schools.com/howto/howto_js_accordion.asp }, onCreated() { this.draggingActive = new ReactiveVar(false); @@ -181,10 +184,12 @@ BlazeComponent.extendComponent({ // the user will legitimately expect to be able to select some text with // his mouse. + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + const noDragInside = ['a', 'input', 'textarea', 'p'].concat( Utils.isMiniScreen() || - (!Utils.isMiniScreen() && - Meteor.user().hasShowDesktopDragHandles()) + (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) ? ['.js-list-handle', '.js-swimlane-header-handle'] : ['.js-list-header'], ); @@ -265,7 +270,13 @@ BlazeComponent.extendComponent({ Template.swimlane.helpers({ showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } }, canSeeAddList() { return ( diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 194f990f..3a5bb4e3 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -162,19 +162,41 @@ Template.changeLanguagePopup.events({ Template.changeSettingsPopup.helpers({ showDesktopDragHandles() { - return Meteor.user().hasShowDesktopDragHandles(); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } }, hiddenSystemMessages() { - return Meteor.user().hasHiddenSystemMessages(); + const currentUser = Meteor.user(); + if (currentUser) { + return Meteor.user().hasHiddenSystemMessages(); + } else { + return false; + } }, showCardsCountAt() { - return Meteor.user().getLimitToShowCardsCount(); + const currentUser = Meteor.user(); + if (currentUser) { + return Meteor.user().getLimitToShowCardsCount(); + } else { + return false; + } }, }); Template.changeSettingsPopup.events({ 'click .js-toggle-desktop-drag-handles'() { - Meteor.call('toggleDesktopDragHandles'); + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + cookies.remove('showDesktopDragHandles'); //true + } else { + cookies.set('showDesktopDragHandles', 'true'); //true + } }, 'click .js-toggle-system-messages'() { Meteor.call('toggleSystemMessages'); diff --git a/client/lib/utils.js b/client/lib/utils.js index cc3526c0..7b4990e7 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -1,4 +1,58 @@ Utils = { + setBoardView(view) { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + currentUser = Meteor.user(); + if (view === 'board-view-lists') { + cookies.set('boardView', 'board-view-lists'); //true + if (currentUser) { + Meteor.user().setBoardView('board-view-lists'); + } + } else if (view === 'board-view-swimlanes') { + cookies.set('boardView', 'board-view-swimlanes'); //true + if (currentUser) { + Meteor.user().setBoardView('board-view-swimlanes'); + } + } else if (view === 'board-view-collapse') { + cookies.set('boardView', 'board-view-swimlane'); //true + cookies.set('collapseSwimlane', 'true'); //true + if (currentUser) { + Meteor.user().setBoardView('board-view-swimlane'); + } + } else if (view === 'board-view-cal') { + cookies.set('boardView', 'board-view-cal'); //true + if (currentUser) { + Meteor.user().setBoardView('board-view-cal'); + } + } + }, + + unsetBoardView() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + cookies.remove('boardView'); + cookies.remove('collapseSwimlane'); + }, + + boardView() { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.get('boardView') === 'board-view-lists') { + return 'board-view-lists'; + } else if ( + cookies.get('boardView') === 'board-view-swimlanes' && + !cookies.has('collapseSwimlane') + ) { + return 'board-view-swimlanes'; + } else if (cookies.has('collapseSwimlane')) { + return 'board-view-swimlanes'; + } else if (cookies.get('boardView') === 'board-view-cal') { + return 'board-view-cal'; + } else { + return false; + } + }, + // XXX We should remove these two methods goBoardId(_id) { const board = Boards.findOne(_id); -- cgit v1.2.3-1-g7c22 From 351d4767d7e93c90ac798769d6071da8730d834f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 19 Nov 2019 14:09:36 +0200 Subject: When logged in, use database for setting, so that changes are immediate. Only on public board use cookies. Comment out Collapse CSS that is not in use. Thanks to xet7 ! --- client/components/boards/boardBody.js | 57 +++++++++++------- client/components/cards/minicard.js | 30 ++++++---- client/components/lists/list.js | 29 +++++++-- client/components/lists/listHeader.js | 15 +++-- client/components/sidebar/sidebar.js | 30 ++++++---- client/components/swimlanes/swimlaneHeader.js | 15 +++-- client/components/swimlanes/swimlanes.jade | 44 +++++++------- client/components/swimlanes/swimlanes.js | 46 +++++++++++--- client/components/swimlanes/swimlanes.styl | 2 + client/components/users/userHeader.js | 86 +++++++++++++++++++++------ 10 files changed, 249 insertions(+), 105 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 8122a0b6..f00b8b1d 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -196,9 +196,20 @@ BlazeComponent.extendComponent({ const cookies = new Cookies(); this.autorun(() => { + let showDesktopDragHandles = false; + currentUser = Meteor.user(); + if (currentUser) { + showDesktopDragHandles = (currentUser.profile || {}).showDesktopDragHandles; + } else { + if (cookies.has('showDesktopDragHandles')) { + showDesktopDragHandles = true; + } else { + showDesktopDragHandles = false; + } + } if ( Utils.isMiniScreen() || - (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) + (!Utils.isMiniScreen() && showDesktopDragHandles) ) { $swimlanesDom.sortable({ handle: '.js-swimlane-header-handle', @@ -230,33 +241,36 @@ BlazeComponent.extendComponent({ }, isViewSwimlanes() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - const currentUser = Meteor.user(); - if (!currentUser) { + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).boardView === 'board-view-swimlanes'; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); return cookies.get('boardView') === 'board-view-swimlanes'; } - return (currentUser.profile || {}).boardView === 'board-view-swimlanes'; }, isViewLists() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - const currentUser = Meteor.user(); - if (!currentUser) { + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).boardView === 'board-view-lists'; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); return cookies.get('boardView') === 'board-view-lists'; } - return (currentUser.profile || {}).boardView === 'board-view-lists'; }, isViewCalendar() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - const currentUser = Meteor.user(); - if (!currentUser) { + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).boardView === 'board-view-cal'; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); return cookies.get('boardView') === 'board-view-cal'; } - return (currentUser.profile || {}).boardView === 'board-view-cal'; }, openNewListForm() { @@ -413,12 +427,13 @@ BlazeComponent.extendComponent({ }; }, isViewCalendar() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - const currentUser = Meteor.user(); - if (!currentUser) { + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).boardView === 'board-view-cal'; + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); return cookies.get('boardView') === 'board-view-cal'; } - return (currentUser.profile || {}).boardView === 'board-view-cal'; }, }).register('calendarView'); diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 5caea709..a9f92dec 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -33,21 +33,31 @@ BlazeComponent.extendComponent({ Template.minicard.helpers({ showDesktopDragHandles() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } } }, hiddenMinicardLabelText() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('hiddenMinicardLabelText')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).hiddenMinicardLabelText; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + return true; + } else { + return false; + } } }, }); diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 8433ad90..7a51fc6e 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -119,7 +119,19 @@ BlazeComponent.extendComponent({ const cookies = new Cookies(); this.autorun(() => { - if (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) { + let showDesktopDragHandles = false; + currentUser = Meteor.user(); + if (currentUser) { + showDesktopDragHandles = (currentUser.profile || {}).showDesktopDragHandles; + } else { + if (cookies.has('showDesktopDragHandles')) { + showDesktopDragHandles = true; + } else { + showDesktopDragHandles = false; + } + } + + if (!Utils.isMiniScreen() && showDesktopDragHandles) { $cards.sortable({ handle: '.handle', }); @@ -163,12 +175,17 @@ BlazeComponent.extendComponent({ Template.list.helpers({ showDesktopDragHandles() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } } }, }); diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 90946610..4ef431fb 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -102,12 +102,17 @@ BlazeComponent.extendComponent({ Template.listHeader.helpers({ showDesktopDragHandles() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } } }, }); diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 4b918d54..6bb22f39 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -107,12 +107,17 @@ BlazeComponent.extendComponent({ 'click .js-toggle-sidebar': this.toggle, 'click .js-back-home': this.setView, 'click .js-toggle-minicard-label-text'() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('hiddenMinicardLabelText')) { - cookies.remove('hiddenMinicardLabelText'); //true + currentUser = Meteor.user(); + if (currentUser) { + Meteor.call('toggleMinicardLabelText'); } else { - cookies.set('hiddenMinicardLabelText', 'true'); //true + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + cookies.remove('hiddenMinicardLabelText'); + } else { + cookies.set('hiddenMinicardLabelText', 'true'); + } } }, 'click .js-shortcuts'() { @@ -127,12 +132,17 @@ Blaze.registerHelper('Sidebar', () => Sidebar); Template.homeSidebar.helpers({ hiddenMinicardLabelText() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('hiddenMinicardLabelText')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).hiddenMinicardLabelText; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hiddenMinicardLabelText')) { + return true; + } else { + return false; + } } }, }); diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index c8ef4dcb..69971b05 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -30,12 +30,17 @@ BlazeComponent.extendComponent({ Template.swimlaneHeader.helpers({ showDesktopDragHandles() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } } }, }); diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index ea9cc913..b2e03afe 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -20,28 +20,28 @@ template(name="swimlane") 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 + //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 diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 1bb522e5..cad673aa 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -99,7 +99,21 @@ function initSortable(boardComponent, $listsDom) { boardComponent.autorun(() => { import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); - if (!Utils.isMiniScreen() && cookies.has('showDesktopDragHandles')) { + 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', }); @@ -186,10 +200,23 @@ BlazeComponent.extendComponent({ import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); + 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() && cookies.has('showDesktopDragHandles')) + (!Utils.isMiniScreen() && showDesktopDragHandles) ? ['.js-list-handle', '.js-swimlane-header-handle'] : ['.js-list-header'], ); @@ -270,12 +297,17 @@ BlazeComponent.extendComponent({ Template.swimlane.helpers({ showDesktopDragHandles() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } } }, canSeeAddList() { diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl index 9a89bf07..ca5611cc 100644 --- a/client/components/swimlanes/swimlanes.styl +++ b/client/components/swimlanes/swimlanes.styl @@ -1,5 +1,6 @@ @import 'nib' +/* // Minimize swimlanes start https://www.w3schools.com/howto/howto_js_accordion.asp .accordion @@ -33,6 +34,7 @@ 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 diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 3a5bb4e3..1f0e3ef0 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -5,10 +5,22 @@ Template.headerUserBar.events({ Template.memberMenuPopup.helpers({ templatesBoardId() { - return Meteor.user().getTemplatesBoardId(); + currentUser = Meteor.user(); + if (currentUser) { + return Meteor.user().getTemplatesBoardId(); + } else { + // No need to getTemplatesBoardId on public board + return false; + } }, templatesBoardSlug() { - return Meteor.user().getTemplatesBoardSlug(); + currentUser = Meteor.user(); + if (currentUser) { + return Meteor.user().getTemplatesBoardSlug(); + } else { + // No need to getTemplatesBoardSlug() on public board + return false; + } }, }); @@ -162,44 +174,73 @@ Template.changeLanguagePopup.events({ Template.changeSettingsPopup.helpers({ showDesktopDragHandles() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - return true; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).showDesktopDragHandles; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + return true; + } else { + return false; + } } }, hiddenSystemMessages() { - const currentUser = Meteor.user(); + currentUser = Meteor.user(); if (currentUser) { - return Meteor.user().hasHiddenSystemMessages(); + return (currentUser.profile || {}).hasHiddenSystemMessages; } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hasHiddenSystemMessages')) { + return true; + } else { + return false; + } } }, showCardsCountAt() { - const currentUser = Meteor.user(); + currentUser = Meteor.user(); if (currentUser) { return Meteor.user().getLimitToShowCardsCount(); } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + return cookies.get('limitToShowCardsCount'); } }, }); Template.changeSettingsPopup.events({ 'click .js-toggle-desktop-drag-handles'() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('showDesktopDragHandles')) { - cookies.remove('showDesktopDragHandles'); //true + currentUser = Meteor.user(); + if (currentUser) { + Meteor.call('toggleDesktopDragHandles'); } else { - cookies.set('showDesktopDragHandles', 'true'); //true + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('showDesktopDragHandles')) { + cookies.remove('showDesktopDragHandles'); + } else { + cookies.set('showDesktopDragHandles', 'true'); + } } }, 'click .js-toggle-system-messages'() { - Meteor.call('toggleSystemMessages'); + currentUser = Meteor.user(); + if (currentUser) { + Meteor.call('toggleSystemMessages'); + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.has('hasHiddenSystemMessages')) { + cookies.remove('hasHiddenSystemMessages'); + } else { + cookies.set('hasHiddenSystemMessages', 'true'); + } + } }, 'click .js-apply-show-cards-at'(event, templateInstance) { event.preventDefault(); @@ -208,7 +249,14 @@ Template.changeSettingsPopup.events({ 10, ); if (!isNaN(minLimit)) { - Meteor.call('changeLimitToShowCardsCount', minLimit); + currentUser = Meteor.user(); + if (currentUser) { + Meteor.call('changeLimitToShowCardsCount', minLimit); + } else { + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + cookies.set('limitToShowCardsCount', minLimit); + } Popup.back(); } }, -- cgit v1.2.3-1-g7c22 From 4786b0c18ddeb8f48525216eabebdced7159467d Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 19 Nov 2019 21:42:00 +0200 Subject: Use database when logged in. Continued. Thanks to xet7 ! --- client/components/boards/boardHeader.js | 79 +++++++-------------------------- client/components/lists/listHeader.jade | 4 +- client/lib/utils.js | 65 +++++++++++++-------------- 3 files changed, 50 insertions(+), 98 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 1706f8e4..ffbb9b72 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -173,78 +173,33 @@ Template.boardHeaderBar.helpers({ ); }, boardView() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.get('boardView') === 'board-view-lists') { - return 'board-view-lists'; - } else if (cookies.get('boardView') === 'board-view-swimlanes') { - return 'board-view-swimlanes'; - } else if (cookies.get('boardView') === 'board-view-collapse') { - return 'board-view-collapse'; - } else if (cookies.get('boardView') === 'board-view-cal') { - return 'board-view-cal'; - } else { - return false; - } - }, - collapseSwimlane() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.has('collapseSwimlane')) { - return true; - } else { - return false; - } - }, + return Utils.boardView(); + }, + //collapseSwimlane() { + // import { Cookies } from 'meteor/ostrio:cookies'; + // const cookies = new Cookies(); + // if (cookies.has('collapseSwimlane')) { + // return true; + // } else { + // return false; + // } + //}, }); Template.boardChangeViewPopup.events({ 'click .js-open-lists-view'() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.get('boardView') !== 'board-view-lists') { - cookies.set('boardView', 'board-view-lists'); - const currentUser = Meteor.user(); - if (currentUser) { - Meteor.user().setBoardView('board-view-lists'); - } - } + Utils.setBoardView('board-view-lists'); Popup.close(); }, 'click .js-open-swimlanes-view'() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.get('boardView') !== 'board-view-swimlanes') { - cookies.set('boardView', 'board-view-swimlanes'); - cookies.remove('collapseSwimlane'); - const currentUser = Meteor.user(); - if (currentUser) { - Meteor.user().setBoardView('board-view-swimlanes'); - } - } - Popup.close(); - }, - 'click .js-open-collapse-view'() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.get('boardView') !== 'board-view-swimlanes') { - cookies.set('boardView', 'board-view-swimlanes'); - cookies.set('collapseSwimlane', 'true'); - const currentUser = Meteor.user(); - if (currentUser) { - Meteor.user().setBoardView('board-view-swimlanes'); - } - } + Utils.setBoardView('board-view-swimlanes'); Popup.close(); }, + //'click .js-open-collapse-view'() { + // Utils.setBoardView('board-view-collapse'); + //Popup.close(); 'click .js-open-cal-view'() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - cookies.set('boardView', 'board-view-cal'); - const currentUser = Meteor.user(); - if (currentUser) { - Meteor.user().setBoardView('board-view-cal'); - } + Utils.setBoardView('board-view-cal'); Popup.close(); }, 'click .js-open-rules-view'() { diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 064303ee..631f68a0 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -39,8 +39,8 @@ template(name="listHeader") i.list-header-watch-icon.fa.fa-eye div.list-header-menu unless currentUser.isCommentOnly - if isBoardAdmin - a.fa.js-list-star.list-header-plus-icon(class="fa-star{{#unless starred}}-o{{/unless}}") + //if isBoardAdmin + // a.fa.js-list-star.list-header-plus-icon(class="fa-star{{#unless starred}}-o{{/unless}}") if canSeeAddCard a.js-add-card.fa.fa-plus.list-header-plus-icon a.fa.fa-navicon.js-open-list-menu diff --git a/client/lib/utils.js b/client/lib/utils.js index 7b4990e7..80ec412c 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -3,26 +3,18 @@ Utils = { import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); currentUser = Meteor.user(); - if (view === 'board-view-lists') { - cookies.set('boardView', 'board-view-lists'); //true - if (currentUser) { - Meteor.user().setBoardView('board-view-lists'); - } - } else if (view === 'board-view-swimlanes') { - cookies.set('boardView', 'board-view-swimlanes'); //true - if (currentUser) { - Meteor.user().setBoardView('board-view-swimlanes'); - } - } else if (view === 'board-view-collapse') { - cookies.set('boardView', 'board-view-swimlane'); //true - cookies.set('collapseSwimlane', 'true'); //true - if (currentUser) { - Meteor.user().setBoardView('board-view-swimlane'); - } - } else if (view === 'board-view-cal') { - cookies.set('boardView', 'board-view-cal'); //true - if (currentUser) { - Meteor.user().setBoardView('board-view-cal'); + if (currentUser) { + Meteor.user().setBoardView(view); + } else { + if (view === 'board-view-lists') { + cookies.set('boardView', 'board-view-lists'); //true + } else if (view === 'board-view-swimlanes') { + cookies.set('boardView', 'board-view-swimlanes'); //true + //} else if (view === 'board-view-collapse') { + // cookies.set('boardView', 'board-view-swimlane'); //true + // cookies.set('collapseSwimlane', 'true'); //true + } else if (view === 'board-view-cal') { + cookies.set('boardView', 'board-view-cal'); //true } } }, @@ -35,21 +27,26 @@ Utils = { }, boardView() { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); - if (cookies.get('boardView') === 'board-view-lists') { - return 'board-view-lists'; - } else if ( - cookies.get('boardView') === 'board-view-swimlanes' && - !cookies.has('collapseSwimlane') - ) { - return 'board-view-swimlanes'; - } else if (cookies.has('collapseSwimlane')) { - return 'board-view-swimlanes'; - } else if (cookies.get('boardView') === 'board-view-cal') { - return 'board-view-cal'; + currentUser = Meteor.user(); + if (currentUser) { + return (currentUser.profile || {}).boardView } else { - return false; + import { Cookies } from 'meteor/ostrio:cookies'; + const cookies = new Cookies(); + if (cookies.get('boardView') === 'board-view-lists') { + return 'board-view-lists'; + } else if ( + cookies.get('boardView') === 'board-view-swimlanes' + //&& !cookies.has('collapseSwimlane') + ) { + return 'board-view-swimlanes'; + //} else if (cookies.has('collapseSwimlane')) { + // return 'board-view-swimlanes'; + } else if (cookies.get('boardView') === 'board-view-cal') { + return 'board-view-cal'; + } else { + return false; + } } }, -- cgit v1.2.3-1-g7c22 From 115d23f9293cad8a93f18f75a47a8a65756f71ce Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 19 Nov 2019 21:55:43 +0200 Subject: Use database when logged in. Continued. Thanks to xet7 ! --- client/components/boards/boardBody.js | 3 ++- client/components/lists/list.js | 3 ++- client/components/lists/listBody.js | 12 +++++------- client/components/swimlanes/swimlanes.js | 6 ++++-- client/lib/utils.js | 12 ++++++------ 5 files changed, 19 insertions(+), 17 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index f00b8b1d..b10f55ab 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -199,7 +199,8 @@ BlazeComponent.extendComponent({ let showDesktopDragHandles = false; currentUser = Meteor.user(); if (currentUser) { - showDesktopDragHandles = (currentUser.profile || {}).showDesktopDragHandles; + showDesktopDragHandles = (currentUser.profile || {}) + .showDesktopDragHandles; } else { if (cookies.has('showDesktopDragHandles')) { showDesktopDragHandles = true; diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 7a51fc6e..d97f4404 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -122,7 +122,8 @@ BlazeComponent.extendComponent({ let showDesktopDragHandles = false; currentUser = Meteor.user(); if (currentUser) { - showDesktopDragHandles = (currentUser.profile || {}).showDesktopDragHandles; + showDesktopDragHandles = (currentUser.profile || {}) + .showDesktopDragHandles; } else { if (cookies.has('showDesktopDragHandles')) { showDesktopDragHandles = true; diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 46d2794e..b0974705 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -713,13 +713,11 @@ BlazeComponent.extendComponent({ .data()._id; } } - } else { - if (Utils.boardView() === 'board-view-swimlanes') { - this.swimlaneId = this.parentComponent() - .parentComponent() - .parentComponent() - .data()._id; - } + } else if (Utils.boardView() === 'board-view-swimlanes') { + this.swimlaneId = this.parentComponent() + .parentComponent() + .parentComponent() + .data()._id; } }, diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index cad673aa..8618373c 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -102,7 +102,8 @@ function initSortable(boardComponent, $listsDom) { let showDesktopDragHandles = false; currentUser = Meteor.user(); if (currentUser) { - showDesktopDragHandles = (currentUser.profile || {}).showDesktopDragHandles; + showDesktopDragHandles = (currentUser.profile || {}) + .showDesktopDragHandles; } else { import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); @@ -203,7 +204,8 @@ BlazeComponent.extendComponent({ let showDesktopDragHandles = false; currentUser = Meteor.user(); if (currentUser) { - showDesktopDragHandles = (currentUser.profile || {}).showDesktopDragHandles; + showDesktopDragHandles = (currentUser.profile || {}) + .showDesktopDragHandles; } else { import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); diff --git a/client/lib/utils.js b/client/lib/utils.js index 80ec412c..ab5e3597 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -10,9 +10,9 @@ Utils = { cookies.set('boardView', 'board-view-lists'); //true } else if (view === 'board-view-swimlanes') { cookies.set('boardView', 'board-view-swimlanes'); //true - //} else if (view === 'board-view-collapse') { - // cookies.set('boardView', 'board-view-swimlane'); //true - // cookies.set('collapseSwimlane', 'true'); //true + //} else if (view === 'board-view-collapse') { + // cookies.set('boardView', 'board-view-swimlane'); //true + // cookies.set('collapseSwimlane', 'true'); //true } else if (view === 'board-view-cal') { cookies.set('boardView', 'board-view-cal'); //true } @@ -29,7 +29,7 @@ Utils = { boardView() { currentUser = Meteor.user(); if (currentUser) { - return (currentUser.profile || {}).boardView + return (currentUser.profile || {}).boardView; } else { import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); @@ -40,8 +40,8 @@ Utils = { //&& !cookies.has('collapseSwimlane') ) { return 'board-view-swimlanes'; - //} else if (cookies.has('collapseSwimlane')) { - // return 'board-view-swimlanes'; + //} else if (cookies.has('collapseSwimlane')) { + // return 'board-view-swimlanes'; } else if (cookies.get('boardView') === 'board-view-cal') { return 'board-view-cal'; } else { -- cgit v1.2.3-1-g7c22 From 788dd0a81a06efee165007a92780f9e8c2c754ac Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 20 Nov 2019 21:10:11 +0200 Subject: Fix lint errors. --- client/components/boards/boardBody.js | 30 ++++++++++------------ client/components/lists/list.js | 24 ++++++++--------- client/components/lists/listHeader.js | 20 ++++++++------- client/components/swimlanes/swimlanes.js | 44 +++++++++++++++----------------- client/lib/utils.js | 42 +++++++++++++++--------------- 5 files changed, 76 insertions(+), 84 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index b10f55ab..41b6f4ef 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -201,16 +201,14 @@ BlazeComponent.extendComponent({ if (currentUser) { showDesktopDragHandles = (currentUser.profile || {}) .showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + showDesktopDragHandles = true; } else { - if (cookies.has('showDesktopDragHandles')) { - showDesktopDragHandles = true; - } else { - showDesktopDragHandles = false; - } + showDesktopDragHandles = false; } if ( - Utils.isMiniScreen() || - (!Utils.isMiniScreen() && showDesktopDragHandles) + Utils.isMiniScreen() + || (!Utils.isMiniScreen() && showDesktopDragHandles) ) { $swimlanesDom.sortable({ handle: '.js-swimlane-header-handle', @@ -227,9 +225,9 @@ BlazeComponent.extendComponent({ function userIsMember() { return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + Meteor.user() + && Meteor.user().isBoardMember() + && !Meteor.user().isCommentOnly() ); } @@ -308,16 +306,16 @@ BlazeComponent.extendComponent({ scrollLeft(position = 0) { const swimlanes = this.$('.js-swimlanes'); - swimlanes && - swimlanes.animate({ + swimlanes + && swimlanes.animate({ scrollLeft: position, }); }, scrollTop(position = 0) { const swimlanes = this.$('.js-swimlanes'); - swimlanes && - swimlanes.animate({ + swimlanes + && swimlanes.animate({ scrollTop: position, }); }, @@ -361,8 +359,8 @@ BlazeComponent.extendComponent({ end = end || card.endAt; title = title || card.title; const className = - (extraCls ? `${extraCls} ` : '') + - (card.color ? `calendar-event-${card.color}` : ''); + (extraCls ? `${extraCls} ` : '') + + (card.color ? `calendar-event-${card.color}` : ''); events.push({ id: card._id, title, diff --git a/client/components/lists/list.js b/client/components/lists/list.js index d97f4404..e58ea430 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -22,9 +22,9 @@ BlazeComponent.extendComponent({ function userIsMember() { return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + Meteor.user() + && Meteor.user().isBoardMember() + && !Meteor.user().isCommentOnly() ); } @@ -74,14 +74,14 @@ BlazeComponent.extendComponent({ const currentBoard = Boards.findOne(Session.get('currentBoard')); let swimlaneId = ''; if ( - Utils.boardView() === 'board-view-swimlanes' || - currentBoard.isTemplatesBoard() + Utils.boardView() === 'board-view-swimlanes' + || currentBoard.isTemplatesBoard() ) swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id; else if ( - Utils.boardView() === 'board-view-lists' || - Utils.boardView() === 'board-view-cal' || - !Utils.boardView + Utils.boardView() === 'board-view-lists' + || Utils.boardView() === 'board-view-cal' + || !Utils.boardView ) swimlaneId = currentBoard.getDefaultSwimline()._id; @@ -124,12 +124,10 @@ BlazeComponent.extendComponent({ if (currentUser) { showDesktopDragHandles = (currentUser.profile || {}) .showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + showDesktopDragHandles = true; } else { - if (cookies.has('showDesktopDragHandles')) { - showDesktopDragHandles = true; - } else { - showDesktopDragHandles = false; - } + showDesktopDragHandles = false; } if (!Utils.isMiniScreen() && showDesktopDragHandles) { diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 4ef431fb..34322fa9 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -7,9 +7,9 @@ BlazeComponent.extendComponent({ canSeeAddCard() { const list = Template.currentData(); return ( - !list.getWipLimit('enabled') || - list.getWipLimit('soft') || - !this.reachedWipLimit() + !list.getWipLimit('enabled') + || list.getWipLimit('soft') + || !this.reachedWipLimit() ); }, @@ -47,6 +47,8 @@ BlazeComponent.extendComponent({ const currentUser = Meteor.user(); if (currentUser) { return Meteor.user().getLimitToShowCardsCount(); + } else { + return false; } }, @@ -64,8 +66,8 @@ BlazeComponent.extendComponent({ reachedWipLimit() { const list = Template.currentData(); return ( - list.getWipLimit('enabled') && - list.getWipLimit('value') <= list.cards().count() + list.getWipLimit('enabled') + && list.getWipLimit('value') <= list.cards().count() ); }, @@ -175,8 +177,8 @@ BlazeComponent.extendComponent({ const list = Template.currentData(); if ( - list.getWipLimit('soft') && - list.getWipLimit('value') < list.cards().count() + list.getWipLimit('soft') + && list.getWipLimit('value') < list.cards().count() ) { list.setWipLimit(list.cards().count()); } @@ -187,8 +189,8 @@ BlazeComponent.extendComponent({ const list = Template.currentData(); // Prevent user from using previously stored wipLimit.value if it is less than the current number of cards in the list if ( - !list.getWipLimit('enabled') && - list.getWipLimit('value') < list.cards().count() + !list.getWipLimit('enabled') + && list.getWipLimit('value') < list.cards().count() ) { list.setWipLimit(list.cards().count()); } diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 8618373c..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 && - Utils.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; @@ -90,15 +90,13 @@ function initSortable(boardComponent, $listsDom) { function userIsMember() { return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + Meteor.user() + && Meteor.user().isBoardMember() + && !Meteor.user().isCommentOnly() ); } boardComponent.autorun(() => { - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); let showDesktopDragHandles = false; currentUser = Meteor.user(); if (currentUser) { @@ -199,8 +197,6 @@ BlazeComponent.extendComponent({ // the user will legitimately expect to be able to select some text with // his mouse. - import { Cookies } from 'meteor/ostrio:cookies'; - const cookies = new Cookies(); let showDesktopDragHandles = false; currentUser = Meteor.user(); if (currentUser) { @@ -217,15 +213,15 @@ BlazeComponent.extendComponent({ } const noDragInside = ['a', 'input', 'textarea', 'p'].concat( - Utils.isMiniScreen() || - (!Utils.isMiniScreen() && showDesktopDragHandles) + 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; @@ -259,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(); }, @@ -314,9 +310,9 @@ Template.swimlane.helpers({ }, canSeeAddList() { return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + Meteor.user() + && Meteor.user().isBoardMember() + && !Meteor.user().isCommentOnly() ); }, }); diff --git a/client/lib/utils.js b/client/lib/utils.js index ab5e3597..c90dd749 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -5,17 +5,15 @@ Utils = { currentUser = Meteor.user(); if (currentUser) { Meteor.user().setBoardView(view); - } else { - if (view === 'board-view-lists') { - cookies.set('boardView', 'board-view-lists'); //true - } else if (view === 'board-view-swimlanes') { - cookies.set('boardView', 'board-view-swimlanes'); //true - //} else if (view === 'board-view-collapse') { - // cookies.set('boardView', 'board-view-swimlane'); //true - // cookies.set('collapseSwimlane', 'true'); //true - } else if (view === 'board-view-cal') { - cookies.set('boardView', 'board-view-cal'); //true - } + } else if (view === 'board-view-lists') { + cookies.set('boardView', 'board-view-lists'); //true + } else if (view === 'board-view-swimlanes') { + cookies.set('boardView', 'board-view-swimlanes'); //true + //} else if (view === 'board-view-collapse') { + // cookies.set('boardView', 'board-view-swimlane'); //true + // cookies.set('collapseSwimlane', 'true'); //true + } else if (view === 'board-view-cal') { + cookies.set('boardView', 'board-view-cal'); //true } }, @@ -54,8 +52,8 @@ Utils = { goBoardId(_id) { const board = Boards.findOne(_id); return ( - board && - FlowRouter.go('board', { + board + && FlowRouter.go('board', { id: board._id, slug: board.slug, }) @@ -66,8 +64,8 @@ Utils = { const card = Cards.findOne(_id); const board = Boards.findOne(card.boardId); return ( - board && - FlowRouter.go('card', { + board + && FlowRouter.go('card', { cardId: card._id, boardId: board._id, slug: board.slug, @@ -238,8 +236,8 @@ Utils = { }; if ( - 'ontouchstart' in window || - (window.DocumentTouch && document instanceof window.DocumentTouch) + 'ontouchstart' in window + || (window.DocumentTouch && document instanceof window.DocumentTouch) ) { return true; } @@ -260,8 +258,8 @@ Utils = { calculateTouchDistance(touchA, touchB) { return Math.sqrt( - Math.pow(touchA.screenX - touchB.screenX, 2) + - Math.pow(touchA.screenY - touchB.screenY, 2), + Math.pow(touchA.screenX - touchB.screenX, 2) + + Math.pow(touchA.screenY - touchB.screenY, 2), ); }, @@ -278,9 +276,9 @@ Utils = { }); $(document).on('touchend', selector, function(e) { if ( - touchStart && - lastTouch && - Utils.calculateTouchDistance(touchStart, lastTouch) <= 20 + touchStart + && lastTouch + && Utils.calculateTouchDistance(touchStart, lastTouch) <= 20 ) { e.preventDefault(); const clickEvent = document.createEvent('MouseEvents'); -- cgit v1.2.3-1-g7c22