From 2bf004120d5a43cd3c3c060fc7c0c30d1b01f220 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 3 Jan 2020 06:49:35 +0200 Subject: Add Worker role. Add more Font Awesome icons. Fix browser console errors when editing user profile name etc. Thanks to xet7 ! Closes #2788 --- client/components/cards/attachments.jade | 26 ++- client/components/cards/cardDate.js | 3 +- client/components/cards/cardDetails.jade | 283 ++++++++++++++++-------- client/components/cards/cardDetails.js | 46 +++- client/components/cards/checklists.jade | 4 +- client/components/cards/checklists.js | 9 +- client/components/cards/minicard.js | 16 +- client/components/cards/subtasks.jade | 4 +- client/components/cards/subtasks.js | 9 +- client/components/lists/list.js | 8 +- client/components/lists/listBody.js | 3 +- client/components/lists/listHeader.jade | 47 +++- client/components/lists/listHeader.js | 15 +- client/components/settings/informationBody.jade | 8 +- client/components/settings/peopleBody.jade | 13 +- client/components/settings/peopleBody.styl | 2 +- client/components/settings/settingBody.jade | 25 ++- client/components/settings/settingBody.styl | 5 +- client/components/sidebar/sidebar.jade | 105 ++++++--- client/components/sidebar/sidebar.js | 41 +++- client/components/sidebar/sidebarArchives.jade | 54 +++-- client/components/sidebar/sidebarArchives.js | 9 + client/components/sidebar/sidebarFilters.jade | 15 +- client/components/swimlanes/swimlaneHeader.js | 8 +- client/components/swimlanes/swimlanes.jade | 33 +-- client/components/swimlanes/swimlanes.js | 24 +- client/components/users/userAvatar.jade | 1 + client/components/users/userHeader.jade | 65 ++++-- client/components/users/userHeader.js | 24 +- 29 files changed, 610 insertions(+), 295 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 2a96f4f4..10b767f4 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -38,18 +38,20 @@ template(name="attachmentsGalery") | {{_ 'download'}} if currentUser.isBoardMember unless currentUser.isCommentOnly - if isImage - a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}") - i.fa.fa-thumb-tack - if($eq ../coverId _id) - | {{_ 'remove-cover'}} - else - | {{_ 'add-cover'}} - a.js-confirm-delete - i.fa.fa-close - | {{_ 'delete'}} + unless currentUser.isWorker + if isImage + a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}") + i.fa.fa-thumb-tack + if($eq ../coverId _id) + | {{_ 'remove-cover'}} + else + | {{_ 'add-cover'}} + a.js-confirm-delete + i.fa.fa-close + | {{_ 'delete'}} if currentUser.isBoardMember unless currentUser.isCommentOnly - li.attachment-item.add-attachment - a.js-add-attachment {{_ 'add-attachment' }} + unless currentUser.isWorker + li.attachment-item.add-attachment + a.js-add-attachment {{_ 'add-attachment' }} diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index cb54b033..c4b5c6d8 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -97,7 +97,8 @@ Template.dateBadge.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 2b4f44b9..a7aa64ce 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -1,7 +1,7 @@ template(name="cardDetails") section.card-details.js-card-details.js-perfect-scrollbar: .card-details-canvas .card-details-header(class='{{#if colorClass}}card-details-{{colorClass}}{{/if}}') - +inlinedForm(classNames="js-card-details-title") + +inlinedForm(classNames="{{#if canModifyCardWorker}}js-card-details-title{{/if}}") +editCardTitleForm else unless isMiniScreen @@ -13,11 +13,11 @@ template(name="cardDetails") 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}}") + class="{{#if canModifyCardWorker}}js-open-inlined-form is-editable{{/if}}") +viewer = getTitle - if isWatching - i.fa.fa-eye.card-details-watch + if isWatching + i.card-details-watch.fa.fa-eye .card-details-path each parentList |   >   @@ -37,49 +37,66 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-received - h3.card-details-item-title {{_ 'card-received'}} + h3 + i.fa.fa-sign-out + card-details-item-title {{_ 'card-received'}} if getReceived +cardReceivedDate else if canModifyCard - a.js-received-date {{_ 'add'}} + unless currentUser.isWorker + a.js-received-date {{_ 'add'}} .card-details-item.card-details-item-start - h3.card-details-item-title {{_ 'card-start'}} + h3 + i.fa.fa-hourglass-start + card-details-item-title {{_ 'card-start'}} if getStart +cardStartDate else if canModifyCard - a.js-start-date {{_ 'add'}} + unless currentUser.isWorker + a.js-start-date {{_ 'add'}} .card-details-item.card-details-item-due - h3.card-details-item-title {{_ 'card-due'}} + h3 + i.fa.fa-sign-in + card-details-item-title {{_ 'card-due'}} if getDue +cardDueDate else if canModifyCard - a.js-due-date {{_ 'add'}} + unless currentUser.isWorker + a.js-due-date {{_ 'add'}} .card-details-item.card-details-item-end - h3.card-details-item-title {{_ 'card-end'}} + h3 + i.fa.fa-hourglass-end + card-details-item-title {{_ 'card-end'}} if getEnd +cardEndDate else if canModifyCard - a.js-end-date {{_ 'add'}} + unless currentUser.isWorker + a.js-end-date {{_ 'add'}} .card-details-items .card-details-item.card-details-item-members - h3.card-details-item-title {{_ 'members'}} + h3 + i.fa.fa-users + card-details-item-title {{_ 'members'}} each getMembers +userAvatar(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} if canModifyCard - a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}") - i.fa.fa-plus + unless currentUser.isWorker + 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'}} + h3 + i.fa.fa-user + card-details-item-title {{_ 'assignee'}} each getAssignees +userAvatarAssignee(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} @@ -89,15 +106,18 @@ template(name="cardDetails") i.fa.fa-plus .card-details-item.card-details-item-labels - h3.card-details-item-title {{_ 'labels'}} + h3 + i.fa.fa-tags + card-details-item-title {{_ 'labels'}} a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}") each labels span.card-label(class="card-label-{{color}}" title=name) +viewer = name if canModifyCard - a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") - i.fa.fa-plus + unless currentUser.isWorker + a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") + i.fa.fa-plus .card-details-items each customFieldsWD @@ -118,26 +138,29 @@ template(name="cardDetails") //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard - h3.card-details-item-title {{_ 'description'}} - +inlinedCardDescription(classNames="card-description js-card-description") - +editor(autofocus=true) - | {{getUnsavedValue 'cardDescription' _id getDescription}} - .edit-controls.clearfix - button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form - else - a.js-open-inlined-form - if getDescription - +viewer - = getDescription - else - | {{_ 'edit'}} - if (hasUnsavedValue 'cardDescription' _id) - p.quiet - | {{_ 'unsaved-description'}} - a.js-open-inlined-form {{_ 'view-it'}} - = ' - ' - a.js-close-inlined-form {{_ 'discard'}} + unless currentUser.isWorker + h3 + i.fa.fa-align-left + card-details-item-title {{_ 'description'}} + +inlinedCardDescription(classNames="card-description js-card-description") + +editor(autofocus=true) + | {{getUnsavedValue 'cardDescription' _id getDescription}} + .edit-controls.clearfix + button.primary(type="submit") {{_ 'save'}} + a.fa.fa-times-thin.js-close-inlined-form + else + a.js-open-inlined-form + if getDescription + +viewer + = getDescription + else + | {{_ 'edit'}} + if (hasUnsavedValue 'cardDescription' _id) + p.quiet + | {{_ 'unsaved-description'}} + a.js-open-inlined-form {{_ 'view-it'}} + = ' - ' + a.js-close-inlined-form {{_ 'discard'}} else if getDescription h3.card-details-item-title {{_ 'description'}} +viewer @@ -145,33 +168,39 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-name - h3.card-details-item-title {{_ 'requested-by'}} + h3 + i.fa.fa-shopping-cart + card-details-item-title {{_ 'requested-by'}} if canModifyCard - +inlinedForm(classNames="js-card-details-requester") - +editCardRequesterForm - else - a.js-open-inlined-form - if getRequestedBy - +viewer - = getRequestedBy - else - | {{_ 'add'}} + unless currentUser.isWorker + +inlinedForm(classNames="js-card-details-requester") + +editCardRequesterForm + else + a.js-open-inlined-form + if getRequestedBy + +viewer + = getRequestedBy + else + | {{_ 'add'}} else if getRequestedBy +viewer = getRequestedBy .card-details-item.card-details-item-name - h3.card-details-item-title {{_ 'assigned-by'}} + h3 + i.fa.fa-user-plus + card-details-item-title {{_ 'assigned-by'}} if canModifyCard - +inlinedForm(classNames="js-card-details-assigner") - +editCardAssignerForm - else - a.js-open-inlined-form - if getAssignedBy - +viewer - = getAssignedBy - else - | {{_ 'add'}} + unless currentUser.isWorker + +inlinedForm(classNames="js-card-details-assigner") + +editCardAssignerForm + else + a.js-open-inlined-form + if getAssignedBy + +viewer + = getAssignedBy + else + | {{_ 'add'}} else if getRequestedBy +viewer = getAssignedBy @@ -193,7 +222,9 @@ template(name="cardDetails") hr unless currentUser.isNoComments .activity-title - h3 {{ _ 'activity'}} + h3 + i.fa.fa-history + | {{ _ 'activity'}} if currentUser.isBoardMember .material-toggle-switch span.toggle-switch-title {{_ 'hide-system-messages'}} @@ -235,32 +266,79 @@ template(name="editCardAssignerForm") template(name="cardDetailsActionsPopup") ul.pop-over-list - li: a.js-toggle-watch-card {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}} + li + a.js-toggle-watch-card + if isWatching + i.fa.fa-eye + | {{_ 'unwatch'}} + else + i.fa.fa-eye-slash + | {{_ 'watch'}} if canModifyCard - hr - ul.pop-over-list - //li: a.js-members {{_ 'card-edit-members'}} - //li: a.js-labels {{_ 'card-edit-labels'}} - //li: a.js-attachments {{_ 'card-edit-attachments'}} - li: a.js-custom-fields {{_ 'card-edit-custom-fields'}} - //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} - //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} - //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} - //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} - li: a.js-spent-time {{_ 'editCardSpentTimePopup-title'}} - li: a.js-set-card-color {{_ 'setCardColorPopup-title'}} - hr - ul.pop-over-list - li: a.js-move-card-to-top {{_ 'moveCardToTop-title'}} - li: a.js-move-card-to-bottom {{_ 'moveCardToBottom-title'}} - hr + unless currentUser.isWorker + hr + ul.pop-over-list + //li: a.js-members {{_ 'card-edit-members'}} + //li: a.js-labels {{_ 'card-edit-labels'}} + //li: a.js-attachments {{_ 'card-edit-attachments'}} + li + a.js-custom-fields + i.fa.fa-list-alt + | {{_ 'card-edit-custom-fields'}} + //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} + //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} + //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} + //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} + li + a.js-spent-time + i.fa.fa-clock-o + | {{_ 'editCardSpentTimePopup-title'}} + li + a.js-set-card-color + i.fa.fa-paint-brush + | {{_ 'setCardColorPopup-title'}} + hr ul.pop-over-list - li: a.js-move-card {{_ 'moveCardPopup-title'}} - li: a.js-copy-card {{_ 'copyCardPopup-title'}} - li: a.js-copy-checklist-cards {{_ 'copyChecklistToManyCardsPopup-title'}} + li + a.js-move-card-to-top + i.fa.fa-arrow-up + | {{_ 'moveCardToTop-title'}} + li + a.js-move-card-to-bottom + i.fa.fa-arrow-down + | {{_ 'moveCardToBottom-title'}} + unless currentUser.isWorker + hr + ul.pop-over-list + li + a.js-move-card + i.fa.fa-arrow-right + | {{_ 'moveCardPopup-title'}} + li + a.js-copy-card + i.fa.fa-copy + | {{_ 'copyCardPopup-title'}} + hr + ul.pop-over-list + li + a.js-copy-checklist-cards + i.fa.fa-list + i.fa.fa-copy + | {{_ 'copyChecklistToManyCardsPopup-title'}} unless archived - li: a.js-archive {{_ 'archive-card'}} - li: a.js-more {{_ 'cardMorePopup-title'}} + hr + ul.pop-over-list + li + a.js-archive + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-card'}} + hr + ul.pop-over-list + li + a.js-more + i.fa.fa-link + | {{_ 'cardMorePopup-title'}} template(name="moveCardPopup") +boardsAndLists @@ -312,16 +390,27 @@ template(name="cardMembersPopup") i.fa.fa-check template(name="cardAssigneesPopup") - ul.pop-over-list.js-card-assignee-list - each board.activeMembers - li.item(class="{{#if isCardAssignee}}active{{/if}}") - a.name.js-select-assignee(href="#") - +userAvatar(userId=user._id) - span.full-name - = user.profile.fullname - | ({{ user.username }}) - if isCardAssignee - i.fa.fa-check + unless currentUser.isWorker + ul.pop-over-list.js-card-assignee-list + each board.activeMembers + li.item(class="{{#if isCardAssignee}}active{{/if}}") + a.name.js-select-assignee(href="#") + +userAvatar(userId=user._id) + span.full-name + = user.profile.fullname + | ({{ user.username }}) + if isCardAssignee + i.fa.fa-check + if currentUser.isWorker + ul.pop-over-list.js-card-assignee-list + li.item(class="{{#if currentUser.isCardAssignee}}active{{/if}}") + a.name.js-select-assigneeWorker(href="#") + +userAvatar(userId=currentUser._id) + span.full-name + = currentUser.profile.fullname + | ({{ currentUser.username }}) + if currentUser.isCardAssignee + i.fa.fa-check template(name="userAvatarAssignee") a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})") @@ -349,11 +438,13 @@ template(name="cardAssigneePopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly + unless currentUser.isWorker li: a.js-remove-assignee {{_ 'remove-member-from-card'}} - if $eq currentUser._id user._id - with currentUser - li: a.js-edit-profile {{_ 'edit-profile'}} + unless currentUser.isWorker + 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") diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 67120043..f0317e6a 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -26,6 +26,7 @@ BlazeComponent.extendComponent({ onCreated() { this.currentBoard = Boards.findOne(Session.get('currentBoard')); + this.currentUser = Meteor.user(); this.isLoaded = new ReactiveVar(false); const boardBody = this.parentComponent().parentComponent(); //in Miniview parent is Board, not BoardBody. @@ -55,6 +56,15 @@ BlazeComponent.extendComponent({ ); }, + canModifyCardWorker() { + return ( + Meteor.user() && + Meteor.user().isBoardMember() && + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() + ); + }, + scrollParentContainer() { const cardPanelWidth = 510; const bodyBoardComponent = this.parentComponent().parentComponent(); @@ -322,7 +332,12 @@ BlazeComponent.extendComponent({ '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-received-date'(event) { + event.preventDefault(); + if (!Meteor.user().isWorker) { + Popup.open('editCardReceivedDate'); + } + }, 'click .js-start-date': Popup.open('editCardStartDate'), 'click .js-due-date': Popup.open('editCardDueDate'), 'click .js-end-date': Popup.open('editCardEndDate'), @@ -383,6 +398,13 @@ Template.cardDetails.helpers({ return user && user.isBoardAdmin() ? 'admin' : 'normal'; }, + isWorker() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return ( + !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) + ); + }, + presenceStatusClassName() { const user = Users.findOne(this.userId); const userPresence = presences.findOne({ userId: this.userId }); @@ -459,6 +481,15 @@ Template.cardDetailsActionsPopup.helpers({ !Meteor.user().isCommentOnly() ); }, + + canModifyCardWorker() { + return ( + Meteor.user() && + Meteor.user().isBoardMember() && + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() + ); + }, }); Template.cardDetailsActionsPopup.events({ @@ -467,7 +498,12 @@ Template.cardDetailsActionsPopup.events({ 'click .js-labels': Popup.open('cardLabels'), 'click .js-attachments': Popup.open('cardAttachments'), 'click .js-custom-fields': Popup.open('cardCustomFields'), - 'click .js-received-date': Popup.open('editCardReceivedDate'), + 'click .js-received-date'(event) { + event.preventDefault(); + if (!Meteor.user().isWorker) { + Popup.open('editCardReceivedDate'); + } + }, 'click .js-start-date': Popup.open('editCardStartDate'), 'click .js-due-date': Popup.open('editCardDueDate'), 'click .js-end-date': Popup.open('editCardEndDate'), @@ -879,6 +915,12 @@ Template.cardAssigneesPopup.events({ card.toggleAssignee(assigneeId); event.preventDefault(); }, + 'click .js-select-assigneeWorker'(event) { + const card = Cards.findOne(Session.get('currentCard')); + const assigneeId = currentUser._id; + card.toggleAssignee(assigneeId); + event.preventDefault(); + }, }); Template.cardAssigneesPopup.helpers({ diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 279d3671..391769e9 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,5 +1,7 @@ template(name="checklists") - h3 {{_ 'checklists'}} + h3 + i.fa.fa-check + | {{_ 'checklists'}} if toggleDeleteDialog.get .board-overlay#card-details-overlay +checklistDeleteDialog(checklist = checklistToDelete) diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 57939eb8..27d1b1c9 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -67,7 +67,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }).register('checklistDetail'); @@ -120,7 +121,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, @@ -228,7 +230,8 @@ Template.checklistItemDetail.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 1ea608f5..da36b87f 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -36,24 +36,20 @@ Template.minicard.helpers({ currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + return true; } else { - if (cookies.has('showDesktopDragHandles')) { - return true; - } else { - return false; - } + return false; } }, hiddenMinicardLabelText() { currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).hiddenMinicardLabelText; + } else if (cookies.has('hiddenMinicardLabelText')) { + return true; } else { - if (cookies.has('hiddenMinicardLabelText')) { - return true; - } else { - return false; - } + return false; } }, }); diff --git a/client/components/cards/subtasks.jade b/client/components/cards/subtasks.jade index 7e64e23f..df35bed3 100644 --- a/client/components/cards/subtasks.jade +++ b/client/components/cards/subtasks.jade @@ -1,5 +1,7 @@ template(name="subtasks") - h3 {{_ 'subtasks'}} + h3 + i.fa.fa-sitemap + | {{_ 'subtasks'}} if toggleDeleteDialog.get .board-overlay#card-details-overlay +subtaskDeleteDialog(subtask = subtaskToDelete) diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index fab860bb..34348fe1 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -3,7 +3,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }).register('subtaskDetail'); @@ -55,7 +56,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, @@ -154,7 +156,8 @@ Template.subtaskItemDetail.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 89d51e85..0513f90f 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -176,12 +176,10 @@ Template.list.helpers({ currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + return true; } else { - if (cookies.has('showDesktopDragHandles')) { - return true; - } else { - return false; - } + return false; } }, }); diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index b0974705..89c27ec7 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -189,7 +189,8 @@ BlazeComponent.extendComponent({ !this.reachedWipLimit() && Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 631f68a0..686de845 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -56,25 +56,47 @@ template(name="editListTitleForm") template(name="listActionPopup") ul.pop-over-list - li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}} + li + a.js-toggle-watch-list + if isWatching + i.fa.fa-eye + | {{_ 'unwatch'}} + else + i.fa.fa-eye-slash + | {{_ 'watch'}} unless currentUser.isCommentOnly - hr - ul.pop-over-list - li: a.js-set-color-list {{_ 'set-color-list'}} - hr + unless currentUser.isWorker + ul.pop-over-list + li + a.js-set-color-list + i.fa.fa-paint-brush + | {{_ 'set-color-list'}} ul.pop-over-list if cards.count - li: a.js-select-cards {{_ 'list-select-cards'}} - hr + li + a.js-select-cards + i.fa.fa-check-square + | {{_ 'list-select-cards'}} if currentUser.isBoardAdmin ul.pop-over-list - li: a.js-set-wip-limit {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} + li + a.js-set-wip-limit + i.fa.fa-ban + | {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} + unless currentUser.isWorker hr - ul.pop-over-list - li: a.js-close-list {{_ 'archive-list'}} + ul.pop-over-list + li + a.js-close-list + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-list'}} hr ul.pop-over-list - li: a.js-more {{_ 'listMorePopup-title'}} + li + a.js-more + i.fa.fa-link + | {{_ 'listMorePopup-title'}} template(name="boardLists") ul.pop-over-list @@ -94,7 +116,8 @@ template(name="listMorePopup") input.inline-input(type="text" readonly value="{{ rootUrl }}") | {{_ 'added'}} span.date(title=list.createdAt) {{ moment createdAt 'LLL' }} - a.js-delete {{_ 'delete'}} + unless currentUser.isWorker + a.js-delete {{_ 'delete'}} template(name="listDeletePopup") p {{_ "list-delete-pop"}} diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 570cc30f..46dbd748 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -9,9 +9,10 @@ BlazeComponent.extendComponent({ canSeeAddCard() { const list = Template.currentData(); return ( - !list.getWipLimit('enabled') || - list.getWipLimit('soft') || - !this.reachedWipLimit() + (!list.getWipLimit('enabled') || + list.getWipLimit('soft') || + !this.reachedWipLimit()) && + !Meteor.user().isWorker() ); }, @@ -109,12 +110,10 @@ Template.listHeader.helpers({ currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + return true; } else { - if (cookies.has('showDesktopDragHandles')) { - return true; - } else { - return false; - } + return false; } }, }); diff --git a/client/components/settings/informationBody.jade b/client/components/settings/informationBody.jade index 2c615ffd..0f85dd9c 100644 --- a/client/components/settings/informationBody.jade +++ b/client/components/settings/informationBody.jade @@ -4,12 +4,16 @@ template(name='information') | {{_ 'error-notAuthorized'}} else .content-title - span {{_ 'info'}} + span + i.fa.fa-info-circle + | {{_ 'info'}} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="information-display") {{_ 'info'}} + a.js-setting-menu(data-id="information-display") + i.fa.fa-info-circle + | {{_ 'info'}} .main-body +statistics diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index d8f672b0..b8a94337 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -5,16 +5,22 @@ template(name="people") else .content-title.ext-box .ext-box-left - span {{_ 'people'}} + span + i.fa.fa-users + | {{_ 'people'}} input#searchInput(placeholder="{{_ 'search'}}") - button#searchButton {{_ 'search'}} + button#searchButton + i.fa.fa-search + | {{_ 'search'}} .ext-box-right span {{_ 'people-number'}} #{peopleNumber} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="people-setting") {{_ 'people'}} + a.js-setting-menu(data-id="people-setting") + i.fa.fa-users + | {{_ 'people'}} .main-body if loading.get +spinner @@ -90,6 +96,7 @@ template(name="peopleRow") td {{_ userData.authenticationMethod }} td a.edit-user + i.fa.fa-edit | {{_ 'edit'}} template(name="editUserPopup") diff --git a/client/components/settings/peopleBody.styl b/client/components/settings/peopleBody.styl index 80387611..c223e181 100644 --- a/client/components/settings/peopleBody.styl +++ b/client/components/settings/peopleBody.styl @@ -33,7 +33,7 @@ table padding: 0; button - min-width: 60px; + min-width: 90px; .content-wrapper margin-top: 10px diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 04b635e8..877fe6e2 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -4,22 +4,35 @@ template(name="setting") | {{_ 'error-notAuthorized'}} else .content-title + i.fa.fa-cog span {{_ 'settings'}} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="registration-setting") {{_ 'registration'}} + a.js-setting-menu(data-id="registration-setting") + i.fa.fa-sign-in + | {{_ 'registration'}} li - a.js-setting-menu(data-id="email-setting") {{_ 'email'}} + a.js-setting-menu(data-id="email-setting") + i.fa.fa-envelope + | {{_ 'email'}} li - a.js-setting-menu(data-id="account-setting") {{_ 'accounts'}} + a.js-setting-menu(data-id="account-setting") + i.fa.fa-users + | {{_ 'accounts'}} li - a.js-setting-menu(data-id="announcement-setting") {{_ 'admin-announcement'}} + a.js-setting-menu(data-id="announcement-setting") + i.fa.fa-bullhorn + | {{_ 'admin-announcement'}} li - a.js-setting-menu(data-id="layout-setting") {{_ 'layout'}} + a.js-setting-menu(data-id="layout-setting") + i.fa.fa-object-group + | {{_ 'layout'}} li - a.js-setting-menu(data-id="webhook-setting") {{_ 'global-webhook'}} + a.js-setting-menu(data-id="webhook-setting") + i.fa.fa-globe + | {{_ 'global-webhook'}} .main-body if loading.get +spinner diff --git a/client/components/settings/settingBody.styl b/client/components/settings/settingBody.styl index bcbd2ea1..d6ac32b2 100644 --- a/client/components/settings/settingBody.styl +++ b/client/components/settings/settingBody.styl @@ -41,15 +41,18 @@ &:hover background #fff box-shadow 0 1px 2px rgba(0,0,0,0.15); + a @extends .flex padding: 1rem 0 1rem 1rem width: 100% - 5rem - span font-size: 13px + i + margin-right: 20px + .main-body padding: 0.1em 1em -webkit-user-select: text // Safari 3.1+ diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index ccfadc0c..19e32970 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -37,11 +37,12 @@ template(name='homeSidebar') template(name="membersWidget") .board-widget.board-widget-members h3 - i.fa.fa-user + i.fa.fa-users | {{_ 'members'}} unless currentUser.isCommentOnly - a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right - i.board-header-btn-icon.fa.fa-cog + unless currentUser.isWorker + a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right + i.board-header-btn-icon.fa.fa-cog .board-widget-content each currentBoard.activeMembers @@ -130,7 +131,9 @@ template(name="chooseBoardSource") template(name="archiveBoardPopup") p {{_ 'close-board-pop'}} - button.js-confirm.negate.full(type="submit") {{_ 'archive'}} + button.js-confirm.negate.full(type="submit") + i.fa.fa-archive + | {{_ 'archive'}} template(name="outgoingWebhooksPopup") each integrations @@ -162,38 +165,80 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list - li: a.js-custom-fields {{_ 'custom-fields'}} - li: a.js-open-archives {{_ 'archived-items'}} + if isNotWorker + li: a.js-custom-fields {{_ 'custom-fields'}} + li + a.js-open-archives + i.fa.fa-archive + | {{_ 'archived-items'}} if currentUser.isBoardAdmin - li: a.js-change-board-color {{_ 'board-change-color'}} + li + a.js-change-board-color + i.fa.fa-paint-brush + | {{_ 'board-change-color'}} + //- XXX Language should be handled by sandstorm, but for now display a language selection link in the board menu. This link is normally present in the header bar that is not displayed on sandstorm. if isSandstorm - li: a.js-change-language {{_ 'language'}} + li + a.js-change-language + i.fa.fa-flag + | {{_ 'language'}} unless isSandstorm if currentUser.isBoardAdmin hr ul.pop-over-list - li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} - unless currentBoard.isTemplatesBoard - li: a.js-archive-board {{_ 'archive-board'}} - li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} - hr - ul.pop-over-list - li: a.js-subtask-settings {{_ 'subtask-settings'}} + li + a(href="{{exportUrl}}", download="{{exportFilename}}") + i.fa.fa-share-alt + | {{_ 'export-board'}} + li + a.js-outgoing-webhooks + i.fa.fa-globe + | {{_ 'outgoing-webhooks'}} + li + a.js-subtask-settings + i.fa.fa-sitemap + | {{_ 'subtask-settings'}} + unless currentBoard.isTemplatesBoard + hr + ul.pop-over-list + li + a.js-archive-board + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-board'}} if isSandstorm hr ul.pop-over-list - li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} - li: a.js-import-board {{_ 'import-board-c'}} - li: a.js-archive-board {{_ 'archive-board'}} - li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} + li + a(href="{{exportUrl}}", download="{{exportFilename}}") + i.fa.fa-share-alt + i.fa.fa-sign-out + | {{_ 'export-board'}} + li + a.js-import-board + i.fa.fa-share-alt + i.fa.fa-sign-in + | {{_ 'import-board-c'}} + li + a.js-archive-board + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-board'}} + li + a.js-outgoing-webhooks + i.fa.fa-globe + | {{_ 'outgoing-webhooks'}} hr ul.pop-over-list - li: a.js-subtask-settings {{_ 'subtask-settings'}} + li + a.js-subtask-settings + i.fa.fa-sitemap + | {{_ 'subtask-settings'}} template(name="labelsWidget") .board-widget.board-widget-labels @@ -203,7 +248,7 @@ template(name="labelsWidget") .board-widget-content each currentBoard.labels a.card-label(class="card-label-{{color}}" - class="{{#if currentUser.isNotCommentOnly}}js-label{{/if}}") + class="{{#if currentUser.isNotCommentOnly}}{{#if currentUser.isNotWorker}}js-label{{/if}}{{/if}}") span.card-label-name +viewer = name @@ -232,12 +277,12 @@ template(name="memberPopup") a.js-change-role | {{_ 'change-permissions'}} span.quiet (#{memberType}) - li - if $eq currentUser._id userId - a.js-leave-member {{_ 'leave-board'}} - else if currentUser.isBoardAdmin - a.js-remove-member {{_ 'remove-from-board'}} - + unless currentUser.isWorker + li + if $eq currentUser._id userId + a.js-leave-member {{_ 'leave-board'}} + else if currentUser.isBoardAdmin + a.js-remove-member {{_ 'remove-from-board'}} template(name="removeMemberPopup") p {{_ 'remove-member-pop' name=user.profile.fullname username=user.username boardTitle=board.title}} @@ -301,6 +346,12 @@ template(name="changePermissionsPopup") if isCommentOnly i.fa.fa-check span.sub-name {{_ 'comment-only-desc'}} + li + a(class="{{#if isLastAdmin}}disabled{{else}}js-set-worker{{/if}}") + | {{_ 'worker'}} + if isWorker + i.fa.fa-check + span.sub-name {{_ 'worker-desc'}} if isLastAdmin hr p.quiet.bottom {{_ 'last-admin-desc'}} diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index caf36020..e8f38b8c 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -112,12 +112,10 @@ BlazeComponent.extendComponent({ currentUser = Meteor.user(); if (currentUser) { Meteor.call('toggleMinicardLabelText'); + } else if (cookies.has('hiddenMinicardLabelText')) { + cookies.remove('hiddenMinicardLabelText'); } else { - if (cookies.has('hiddenMinicardLabelText')) { - cookies.remove('hiddenMinicardLabelText'); - } else { - cookies.set('hiddenMinicardLabelText', 'true'); - } + cookies.set('hiddenMinicardLabelText', 'true'); } }, 'click .js-shortcuts'() { @@ -135,12 +133,10 @@ Template.homeSidebar.helpers({ currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).hiddenMinicardLabelText; + } else if (cookies.has('hiddenMinicardLabelText')) { + return true; } else { - if (cookies.has('hiddenMinicardLabelText')) { - return true; - } else { - return false; - } + return false; } }, }); @@ -165,10 +161,13 @@ Template.memberPopup.helpers({ const currentBoard = Boards.findOne(Session.get('currentBoard')); const commentOnly = currentBoard.hasCommentOnly(this.userId); const noComments = currentBoard.hasNoComments(this.userId); + const worker = currentBoard.hasWorker(this.userId); if (commentOnly) { return TAPi18n.__('comment-only').toLowerCase(); } else if (noComments) { return TAPi18n.__('no-comments').toLowerCase(); + } else if (worker) { + return TAPi18n.__('worker').toLowerCase(); } else { return TAPi18n.__(type).toLowerCase(); } @@ -271,6 +270,14 @@ Template.membersWidget.helpers({ const user = Meteor.user(); return user && user.isInvitedTo(Session.get('currentBoard')); }, + isWorker() { + const user = Meteor.user(); + if (user) { + return Meteor.call(Boards.hasWorker(user.memberId)); + } else { + return false; + } + }, }); Template.membersWidget.events({ @@ -648,7 +655,7 @@ BlazeComponent.extendComponent({ }).register('addMemberPopup'); Template.changePermissionsPopup.events({ - 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only'( + 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only, click .js-set-worker'( event, ) { const currentBoard = Boards.findOne(Session.get('currentBoard')); @@ -658,11 +665,13 @@ Template.changePermissionsPopup.events({ 'js-set-comment-only', ); const isNoComments = $(event.currentTarget).hasClass('js-set-no-comments'); + const isWorker = $(event.currentTarget).hasClass('js-set-worker'); currentBoard.setMemberPermission( memberId, isAdmin, isNoComments, isCommentOnly, + isWorker, ); Popup.back(1); }, @@ -679,7 +688,8 @@ Template.changePermissionsPopup.helpers({ return ( !currentBoard.hasAdmin(this.userId) && !currentBoard.hasNoComments(this.userId) && - !currentBoard.hasCommentOnly(this.userId) + !currentBoard.hasCommentOnly(this.userId) && + !currentBoard.hasWorker(this.userId) ); }, @@ -699,6 +709,13 @@ Template.changePermissionsPopup.helpers({ ); }, + isWorker() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return ( + !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) + ); + }, + isLastAdmin() { const currentBoard = Boards.findOne(Session.get('currentBoard')); return ( diff --git a/client/components/sidebar/sidebarArchives.jade b/client/components/sidebar/sidebarArchives.jade index 466d2cb0..56423ad7 100644 --- a/client/components/sidebar/sidebarArchives.jade +++ b/client/components/sidebar/sidebarArchives.jade @@ -2,54 +2,60 @@ template(name="archivesSidebar") if isArchiveReady.get +basicTabs(tabs=tabs) +tabContent(slug="cards") - p.quiet - a.js-restore-all-cards {{_ 'restore-all'}} - | - - a.js-delete-all-cards {{_ 'delete-all'}} + unless isWorker + p.quiet + a.js-restore-all-cards {{_ 'restore-all'}} + | - + a.js-delete-all-cards {{_ 'delete-all'}} each archivedCards .minicard-wrapper.js-minicard +minicard(this) if currentUser.isBoardMember - p.quiet - a.js-restore-card {{_ 'restore'}} - | - - a.js-delete-card {{_ 'delete'}} + unless isWorker + p.quiet + a.js-restore-card {{_ 'restore'}} + | - + a.js-delete-card {{_ 'delete'}} if cardIsInArchivedList p.quiet.small ({{_ 'warn-list-archived'}}) else p.no-items-message {{_ 'no-archived-cards'}} +tabContent(slug="lists") - p.quiet - a.js-restore-all-lists {{_ 'restore-all'}} - | - - a.js-delete-all-lists {{_ 'delete-all'}} + unless isWorker + p.quiet + a.js-restore-all-lists {{_ 'restore-all'}} + | - + a.js-delete-all-lists {{_ 'delete-all'}} ul.archived-lists each archivedLists li.archived-lists-item = title if currentUser.isBoardMember - p.quiet - a.js-restore-list {{_ 'restore'}} - | - - a.js-delete-list {{_ 'delete'}} + unless isWorker + p.quiet + a.js-restore-list {{_ 'restore'}} + | - + a.js-delete-list {{_ 'delete'}} else li.no-items-message {{_ 'no-archived-lists'}} +tabContent(slug="swimlanes") - p.quiet - a.js-restore-all-swimlanes {{_ 'restore-all'}} - | - - a.js-delete-all-swimlanes {{_ 'delete-all'}} + unless isWorker + p.quiet + a.js-restore-all-swimlanes {{_ 'restore-all'}} + | - + a.js-delete-all-swimlanes {{_ 'delete-all'}} ul.archived-lists each archivedSwimlanes li.archived-lists-item = title if currentUser.isBoardMember - p.quiet - a.js-restore-swimlane {{_ 'restore'}} - | - - a.js-delete-swimlane {{_ 'delete'}} + unless isWorker + p.quiet + a.js-restore-swimlane {{_ 'restore'}} + | - + a.js-delete-swimlane {{_ 'delete'}} else li.no-items-message {{_ 'no-archived-swimlanes'}} else diff --git a/client/components/sidebar/sidebarArchives.js b/client/components/sidebar/sidebarArchives.js index a4846561..75b694e9 100644 --- a/client/components/sidebar/sidebarArchives.js +++ b/client/components/sidebar/sidebarArchives.js @@ -139,3 +139,12 @@ BlazeComponent.extendComponent({ ]; }, }).register('archivesSidebar'); + +Template.archivesSidebar.helpers({ + isWorker() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return ( + !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) + ); + }, +}); diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 5f929cb9..7f31dada 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -117,13 +117,14 @@ template(name="multiselectionSidebar") i.fa.fa-check else if someSelectedElementHave 'member' _id i.fa.fa-ellipsis-h - hr - a.sidebar-btn.js-move-selection - i.fa.fa-share - span {{_ 'move-selection'}} - a.sidebar-btn.js-archive-selection - i.fa.fa-archive - span {{_ 'archive-selection'}} + unless currentUser.isWorker + hr + a.sidebar-btn.js-move-selection + i.fa.fa-share + span {{_ 'move-selection'}} + a.sidebar-btn.js-archive-selection + i.fa.fa-archive + span {{_ 'archive-selection'}} template(name="disambiguateMultiLabelPopup") p {{_ 'what-to-do'}} diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index fbc45351..3032966d 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -35,12 +35,10 @@ Template.swimlaneHeader.helpers({ currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + return true; } else { - if (cookies.has('showDesktopDragHandles')) { - return true; - } else { - return false; - } + return false; } }, }); diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 1dc23c59..9b00d9e8 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -43,19 +43,20 @@ template(name="listsGroup") +addListForm template(name="addListForm") - .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'}}" - autocomplete="off" autofocus) - .edit-controls.clearfix - button.primary.confirm(type="submit") {{_ 'save'}} - unless currentBoard.isTemplatesBoard - unless currentBoard.isTemplateBoard - span.quiet - | {{_ 'or'}} - a.js-list-template {{_ 'template'}} - else - a.open-list-composer.js-open-inlined-form - i.fa.fa-plus - | {{_ 'add-list'}} + unless currentUser.isWorker + .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'}}" + autocomplete="off" autofocus) + .edit-controls.clearfix + button.primary.confirm(type="submit") {{_ 'save'}} + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-list-template {{_ 'template'}} + else + a.open-list-composer.js-open-inlined-form + i.fa.fa-plus + | {{_ 'add-list'}} diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index d072a2a2..6568036f 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -104,12 +104,10 @@ function initSortable(boardComponent, $listsDom) { 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) { @@ -182,12 +180,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; } const noDragInside = ['a', 'input', 'textarea', 'p'].concat( @@ -276,12 +272,10 @@ Template.swimlane.helpers({ currentUser = Meteor.user(); if (currentUser) { return (currentUser.profile || {}).showDesktopDragHandles; + } else if (cookies.has('showDesktopDragHandles')) { + return true; } else { - if (cookies.has('showDesktopDragHandles')) { - return true; - } else { - return false; - } + return false; } }, canSeeAddList() { diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index ebfa48ba..7f2067ce 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -73,6 +73,7 @@ template(name="cardMemberPopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly + if currentUser.isNotWorker li: a.js-remove-member {{_ 'remove-member-from-card'}} if $eq currentUser._id user._id diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 50a80396..9306d21d 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -13,21 +13,46 @@ template(name="headerUserBar") template(name="memberMenuPopup") ul.pop-over-list with currentUser - li: a.js-edit-profile {{_ 'edit-profile'}} - li: a.js-change-settings {{_ 'change-settings'}} - li: a.js-change-avatar {{_ 'edit-avatar'}} + li + a.js-edit-profile + i.fa.fa-user + | {{_ 'edit-profile'}} + li + a.js-change-settings + i.fa.fa-cog + | {{_ 'change-settings'}} + li + a.js-change-avatar + i.fa.fa-picture-o + | {{_ 'edit-avatar'}} unless isSandstorm - li: a.js-change-password {{_ 'changePasswordPopup-title'}} - li: a.js-change-language {{_ 'changeLanguagePopup-title'}} + li + a.js-change-password + i.fa.fa-key + | {{_ 'changePasswordPopup-title'}} + li + a.js-change-language + i.fa.fa-flag + | {{_ 'changeLanguagePopup-title'}} if currentUser.isAdmin - li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}} - hr - ul.pop-over-list - li: a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") {{_ 'templates'}} + li + a.js-go-setting(href="{{pathFor 'setting'}}") + i.fa.fa-lock + | {{_ 'admin-panel'}} + unless currentUser.isWorker + hr + ul.pop-over-list + li + a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") + i.fa.fa-clone + | {{_ 'templates'}} unless isSandstorm hr ul.pop-over-list - li: a.js-logout {{_ 'log-out'}} + li + a.js-logout + i.fa.fa-sign-out + | {{_ 'log-out'}} template(name="editProfilePopup") form @@ -75,21 +100,25 @@ template(name="changeSettingsPopup") ul.pop-over-list li a.js-toggle-system-messages + i.fa.fa-comments-o | {{_ 'hide-system-messages'}} if hiddenSystemMessages i.fa.fa-check li a.js-toggle-desktop-drag-handles + i.fa.fa-arrows | {{_ 'show-desktop-drag-handles'}} if showDesktopDragHandles i.fa.fa-check - li - label.bold - | {{_ 'show-cards-minimum-count'}} - input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") - input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") - + unless currentUser.isWorker + li + label.bold + i.fa.fa-sort-numeric-asc + | {{_ 'show-cards-minimum-count'}} + input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") + input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") template(name="userDeletePopup") - p {{_ 'delete-user-confirm-popup'}} - button.js-confirm.negate.full(type="submit") {{_ 'delete'}} + unless currentUser.isWorker + p {{_ 'delete-user-confirm-popup'}} + button.js-confirm.negate.full(type="submit") {{_ 'delete'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 5f36ef54..847d30fb 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -45,13 +45,31 @@ Template.memberMenuPopup.events({ Template.editProfilePopup.helpers({ allowEmailChange() { - return AccountSettings.findOne('accounts-allowEmailChange').booleanValue; + Meteor.call('AccountSettings.allowEmailChange', (_, result) => { + if (result) { + return true; + } else { + return false; + } + }); }, allowUserNameChange() { - return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue; + Meteor.call('AccountSettings.allowUserNameChange', (_, result) => { + if (result) { + return true; + } else { + return false; + } + }); }, allowUserDelete() { - return AccountSettings.findOne('accounts-allowUserDelete').booleanValue; + Meteor.call('AccountSettings.allowUserDelete', (_, result) => { + if (result) { + return true; + } else { + return false; + } + }); }, }); -- cgit v1.2.3-1-g7c22 From 5376bc7b7905c0dd99fae1aeae3f63b4583a3e3f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 3 Jan 2020 13:27:27 +0200 Subject: Fix not being able to edit received date. Thanks to xet7 ! --- client/components/cards/cardDetails.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index f0317e6a..f47b3824 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -332,12 +332,7 @@ BlazeComponent.extendComponent({ 'click .js-assignee': Popup.open('cardAssignee'), 'click .js-add-assignees': Popup.open('cardAssignees'), 'click .js-add-labels': Popup.open('cardLabels'), - 'click .js-received-date'(event) { - event.preventDefault(); - if (!Meteor.user().isWorker) { - Popup.open('editCardReceivedDate'); - } - }, + 'click .js-received-date': Popup.open('editCardReceivedDate'), 'click .js-start-date': Popup.open('editCardStartDate'), 'click .js-due-date': Popup.open('editCardDueDate'), 'click .js-end-date': Popup.open('editCardEndDate'), -- cgit v1.2.3-1-g7c22 From 27943796ade78ca3c503637a1340918bf06a1267 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 3 Jan 2020 16:02:31 +0200 Subject: Revert to Wekan v3.57 version of client and models directories, removing Worker role temporarily, because Worker role changes broke saving card. Thanks to xet7 ! --- client/components/cards/attachments.jade | 26 +-- client/components/cards/cardDate.js | 3 +- client/components/cards/cardDetails.jade | 283 ++++++++---------------- client/components/cards/cardDetails.js | 39 +--- client/components/cards/checklists.jade | 4 +- client/components/cards/checklists.js | 9 +- client/components/cards/subtasks.jade | 4 +- client/components/cards/subtasks.js | 9 +- client/components/lists/listBody.js | 3 +- client/components/lists/listHeader.jade | 47 +--- client/components/lists/listHeader.js | 7 +- client/components/settings/informationBody.jade | 8 +- client/components/settings/peopleBody.jade | 13 +- client/components/settings/peopleBody.styl | 2 +- client/components/settings/settingBody.jade | 25 +-- client/components/settings/settingBody.styl | 5 +- client/components/sidebar/sidebar.jade | 105 +++------ client/components/sidebar/sidebar.js | 25 +-- client/components/sidebar/sidebarArchives.jade | 54 ++--- client/components/sidebar/sidebarArchives.js | 9 - client/components/sidebar/sidebarFilters.jade | 15 +- client/components/swimlanes/swimlanes.jade | 33 ++- client/components/users/userAvatar.jade | 1 - client/components/users/userHeader.jade | 65 ++---- client/components/users/userHeader.js | 24 +- 25 files changed, 244 insertions(+), 574 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 10b767f4..2a96f4f4 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -38,20 +38,18 @@ template(name="attachmentsGalery") | {{_ 'download'}} if currentUser.isBoardMember unless currentUser.isCommentOnly - unless currentUser.isWorker - if isImage - a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}") - i.fa.fa-thumb-tack - if($eq ../coverId _id) - | {{_ 'remove-cover'}} - else - | {{_ 'add-cover'}} - a.js-confirm-delete - i.fa.fa-close - | {{_ 'delete'}} + if isImage + a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}") + i.fa.fa-thumb-tack + if($eq ../coverId _id) + | {{_ 'remove-cover'}} + else + | {{_ 'add-cover'}} + a.js-confirm-delete + i.fa.fa-close + | {{_ 'delete'}} if currentUser.isBoardMember unless currentUser.isCommentOnly - unless currentUser.isWorker - li.attachment-item.add-attachment - a.js-add-attachment {{_ 'add-attachment' }} + li.attachment-item.add-attachment + a.js-add-attachment {{_ 'add-attachment' }} diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index c4b5c6d8..cb54b033 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -97,8 +97,7 @@ Template.dateBadge.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, }); diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index a7aa64ce..2b4f44b9 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -1,7 +1,7 @@ template(name="cardDetails") section.card-details.js-card-details.js-perfect-scrollbar: .card-details-canvas .card-details-header(class='{{#if colorClass}}card-details-{{colorClass}}{{/if}}') - +inlinedForm(classNames="{{#if canModifyCardWorker}}js-card-details-title{{/if}}") + +inlinedForm(classNames="js-card-details-title") +editCardTitleForm else unless isMiniScreen @@ -13,11 +13,11 @@ template(name="cardDetails") 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 canModifyCardWorker}}js-open-inlined-form is-editable{{/if}}") + class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}") +viewer = getTitle - if isWatching - i.card-details-watch.fa.fa-eye + if isWatching + i.fa.fa-eye.card-details-watch .card-details-path each parentList |   >   @@ -37,66 +37,49 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-received - h3 - i.fa.fa-sign-out - card-details-item-title {{_ 'card-received'}} + h3.card-details-item-title {{_ 'card-received'}} if getReceived +cardReceivedDate else if canModifyCard - unless currentUser.isWorker - a.js-received-date {{_ 'add'}} + a.js-received-date {{_ 'add'}} .card-details-item.card-details-item-start - h3 - i.fa.fa-hourglass-start - card-details-item-title {{_ 'card-start'}} + h3.card-details-item-title {{_ 'card-start'}} if getStart +cardStartDate else if canModifyCard - unless currentUser.isWorker - a.js-start-date {{_ 'add'}} + a.js-start-date {{_ 'add'}} .card-details-item.card-details-item-due - h3 - i.fa.fa-sign-in - card-details-item-title {{_ 'card-due'}} + h3.card-details-item-title {{_ 'card-due'}} if getDue +cardDueDate else if canModifyCard - unless currentUser.isWorker - a.js-due-date {{_ 'add'}} + a.js-due-date {{_ 'add'}} .card-details-item.card-details-item-end - h3 - i.fa.fa-hourglass-end - card-details-item-title {{_ 'card-end'}} + h3.card-details-item-title {{_ 'card-end'}} if getEnd +cardEndDate else if canModifyCard - unless currentUser.isWorker - a.js-end-date {{_ 'add'}} + a.js-end-date {{_ 'add'}} .card-details-items .card-details-item.card-details-item-members - h3 - i.fa.fa-users - card-details-item-title {{_ 'members'}} + h3.card-details-item-title {{_ 'members'}} each getMembers +userAvatar(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} if canModifyCard - unless currentUser.isWorker - a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}") - i.fa.fa-plus + 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 - i.fa.fa-user - card-details-item-title {{_ 'assignee'}} + h3.card-details-item-title {{_ 'assignee'}} each getAssignees +userAvatarAssignee(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} @@ -106,18 +89,15 @@ template(name="cardDetails") i.fa.fa-plus .card-details-item.card-details-item-labels - h3 - i.fa.fa-tags - card-details-item-title {{_ 'labels'}} + h3.card-details-item-title {{_ 'labels'}} a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}") each labels span.card-label(class="card-label-{{color}}" title=name) +viewer = name if canModifyCard - unless currentUser.isWorker - a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") - i.fa.fa-plus + a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") + i.fa.fa-plus .card-details-items each customFieldsWD @@ -138,29 +118,26 @@ template(name="cardDetails") //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard - unless currentUser.isWorker - h3 - i.fa.fa-align-left - card-details-item-title {{_ 'description'}} - +inlinedCardDescription(classNames="card-description js-card-description") - +editor(autofocus=true) - | {{getUnsavedValue 'cardDescription' _id getDescription}} - .edit-controls.clearfix - button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form - else - a.js-open-inlined-form - if getDescription - +viewer - = getDescription - else - | {{_ 'edit'}} - if (hasUnsavedValue 'cardDescription' _id) - p.quiet - | {{_ 'unsaved-description'}} - a.js-open-inlined-form {{_ 'view-it'}} - = ' - ' - a.js-close-inlined-form {{_ 'discard'}} + h3.card-details-item-title {{_ 'description'}} + +inlinedCardDescription(classNames="card-description js-card-description") + +editor(autofocus=true) + | {{getUnsavedValue 'cardDescription' _id getDescription}} + .edit-controls.clearfix + button.primary(type="submit") {{_ 'save'}} + a.fa.fa-times-thin.js-close-inlined-form + else + a.js-open-inlined-form + if getDescription + +viewer + = getDescription + else + | {{_ 'edit'}} + if (hasUnsavedValue 'cardDescription' _id) + p.quiet + | {{_ 'unsaved-description'}} + a.js-open-inlined-form {{_ 'view-it'}} + = ' - ' + a.js-close-inlined-form {{_ 'discard'}} else if getDescription h3.card-details-item-title {{_ 'description'}} +viewer @@ -168,39 +145,33 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-name - h3 - i.fa.fa-shopping-cart - card-details-item-title {{_ 'requested-by'}} + h3.card-details-item-title {{_ 'requested-by'}} if canModifyCard - unless currentUser.isWorker - +inlinedForm(classNames="js-card-details-requester") - +editCardRequesterForm - else - a.js-open-inlined-form - if getRequestedBy - +viewer - = getRequestedBy - else - | {{_ 'add'}} + +inlinedForm(classNames="js-card-details-requester") + +editCardRequesterForm + else + a.js-open-inlined-form + if getRequestedBy + +viewer + = getRequestedBy + else + | {{_ 'add'}} else if getRequestedBy +viewer = getRequestedBy .card-details-item.card-details-item-name - h3 - i.fa.fa-user-plus - card-details-item-title {{_ 'assigned-by'}} + h3.card-details-item-title {{_ 'assigned-by'}} if canModifyCard - unless currentUser.isWorker - +inlinedForm(classNames="js-card-details-assigner") - +editCardAssignerForm - else - a.js-open-inlined-form - if getAssignedBy - +viewer - = getAssignedBy - else - | {{_ 'add'}} + +inlinedForm(classNames="js-card-details-assigner") + +editCardAssignerForm + else + a.js-open-inlined-form + if getAssignedBy + +viewer + = getAssignedBy + else + | {{_ 'add'}} else if getRequestedBy +viewer = getAssignedBy @@ -222,9 +193,7 @@ template(name="cardDetails") hr unless currentUser.isNoComments .activity-title - h3 - i.fa.fa-history - | {{ _ 'activity'}} + h3 {{ _ 'activity'}} if currentUser.isBoardMember .material-toggle-switch span.toggle-switch-title {{_ 'hide-system-messages'}} @@ -266,79 +235,32 @@ template(name="editCardAssignerForm") template(name="cardDetailsActionsPopup") ul.pop-over-list - li - a.js-toggle-watch-card - if isWatching - i.fa.fa-eye - | {{_ 'unwatch'}} - else - i.fa.fa-eye-slash - | {{_ 'watch'}} + li: a.js-toggle-watch-card {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}} if canModifyCard - unless currentUser.isWorker - hr - ul.pop-over-list - //li: a.js-members {{_ 'card-edit-members'}} - //li: a.js-labels {{_ 'card-edit-labels'}} - //li: a.js-attachments {{_ 'card-edit-attachments'}} - li - a.js-custom-fields - i.fa.fa-list-alt - | {{_ 'card-edit-custom-fields'}} - //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} - //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} - //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} - //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} - li - a.js-spent-time - i.fa.fa-clock-o - | {{_ 'editCardSpentTimePopup-title'}} - li - a.js-set-card-color - i.fa.fa-paint-brush - | {{_ 'setCardColorPopup-title'}} - hr + hr ul.pop-over-list - li - a.js-move-card-to-top - i.fa.fa-arrow-up - | {{_ 'moveCardToTop-title'}} - li - a.js-move-card-to-bottom - i.fa.fa-arrow-down - | {{_ 'moveCardToBottom-title'}} - unless currentUser.isWorker - hr - ul.pop-over-list - li - a.js-move-card - i.fa.fa-arrow-right - | {{_ 'moveCardPopup-title'}} - li - a.js-copy-card - i.fa.fa-copy - | {{_ 'copyCardPopup-title'}} - hr - ul.pop-over-list - li - a.js-copy-checklist-cards - i.fa.fa-list - i.fa.fa-copy - | {{_ 'copyChecklistToManyCardsPopup-title'}} + //li: a.js-members {{_ 'card-edit-members'}} + //li: a.js-labels {{_ 'card-edit-labels'}} + //li: a.js-attachments {{_ 'card-edit-attachments'}} + li: a.js-custom-fields {{_ 'card-edit-custom-fields'}} + //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} + //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} + //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} + //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} + li: a.js-spent-time {{_ 'editCardSpentTimePopup-title'}} + li: a.js-set-card-color {{_ 'setCardColorPopup-title'}} + hr + ul.pop-over-list + li: a.js-move-card-to-top {{_ 'moveCardToTop-title'}} + li: a.js-move-card-to-bottom {{_ 'moveCardToBottom-title'}} + hr + ul.pop-over-list + li: a.js-move-card {{_ 'moveCardPopup-title'}} + li: a.js-copy-card {{_ 'copyCardPopup-title'}} + li: a.js-copy-checklist-cards {{_ 'copyChecklistToManyCardsPopup-title'}} unless archived - hr - ul.pop-over-list - li - a.js-archive - i.fa.fa-arrow-right - i.fa.fa-archive - | {{_ 'archive-card'}} - hr - ul.pop-over-list - li - a.js-more - i.fa.fa-link - | {{_ 'cardMorePopup-title'}} + li: a.js-archive {{_ 'archive-card'}} + li: a.js-more {{_ 'cardMorePopup-title'}} template(name="moveCardPopup") +boardsAndLists @@ -390,27 +312,16 @@ template(name="cardMembersPopup") i.fa.fa-check template(name="cardAssigneesPopup") - unless currentUser.isWorker - ul.pop-over-list.js-card-assignee-list - each board.activeMembers - li.item(class="{{#if isCardAssignee}}active{{/if}}") - a.name.js-select-assignee(href="#") - +userAvatar(userId=user._id) - span.full-name - = user.profile.fullname - | ({{ user.username }}) - if isCardAssignee - i.fa.fa-check - if currentUser.isWorker - ul.pop-over-list.js-card-assignee-list - li.item(class="{{#if currentUser.isCardAssignee}}active{{/if}}") - a.name.js-select-assigneeWorker(href="#") - +userAvatar(userId=currentUser._id) - span.full-name - = currentUser.profile.fullname - | ({{ currentUser.username }}) - if currentUser.isCardAssignee - i.fa.fa-check + ul.pop-over-list.js-card-assignee-list + each board.activeMembers + li.item(class="{{#if isCardAssignee}}active{{/if}}") + a.name.js-select-assignee(href="#") + +userAvatar(userId=user._id) + span.full-name + = user.profile.fullname + | ({{ user.username }}) + if isCardAssignee + i.fa.fa-check template(name="userAvatarAssignee") a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})") @@ -438,13 +349,11 @@ template(name="cardAssigneePopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly - unless currentUser.isWorker li: a.js-remove-assignee {{_ 'remove-member-from-card'}} - unless currentUser.isWorker - if $eq currentUser._id user._id - with currentUser - li: a.js-edit-profile {{_ 'edit-profile'}} + 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") diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index f47b3824..67120043 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -26,7 +26,6 @@ BlazeComponent.extendComponent({ onCreated() { this.currentBoard = Boards.findOne(Session.get('currentBoard')); - this.currentUser = Meteor.user(); this.isLoaded = new ReactiveVar(false); const boardBody = this.parentComponent().parentComponent(); //in Miniview parent is Board, not BoardBody. @@ -56,15 +55,6 @@ BlazeComponent.extendComponent({ ); }, - canModifyCardWorker() { - return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() - ); - }, - scrollParentContainer() { const cardPanelWidth = 510; const bodyBoardComponent = this.parentComponent().parentComponent(); @@ -393,13 +383,6 @@ Template.cardDetails.helpers({ return user && user.isBoardAdmin() ? 'admin' : 'normal'; }, - isWorker() { - const currentBoard = Boards.findOne(Session.get('currentBoard')); - return ( - !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) - ); - }, - presenceStatusClassName() { const user = Users.findOne(this.userId); const userPresence = presences.findOne({ userId: this.userId }); @@ -476,15 +459,6 @@ Template.cardDetailsActionsPopup.helpers({ !Meteor.user().isCommentOnly() ); }, - - canModifyCardWorker() { - return ( - Meteor.user() && - Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() - ); - }, }); Template.cardDetailsActionsPopup.events({ @@ -493,12 +467,7 @@ Template.cardDetailsActionsPopup.events({ 'click .js-labels': Popup.open('cardLabels'), 'click .js-attachments': Popup.open('cardAttachments'), 'click .js-custom-fields': Popup.open('cardCustomFields'), - 'click .js-received-date'(event) { - event.preventDefault(); - if (!Meteor.user().isWorker) { - Popup.open('editCardReceivedDate'); - } - }, + 'click .js-received-date': Popup.open('editCardReceivedDate'), 'click .js-start-date': Popup.open('editCardStartDate'), 'click .js-due-date': Popup.open('editCardDueDate'), 'click .js-end-date': Popup.open('editCardEndDate'), @@ -910,12 +879,6 @@ Template.cardAssigneesPopup.events({ card.toggleAssignee(assigneeId); event.preventDefault(); }, - 'click .js-select-assigneeWorker'(event) { - const card = Cards.findOne(Session.get('currentCard')); - const assigneeId = currentUser._id; - card.toggleAssignee(assigneeId); - event.preventDefault(); - }, }); Template.cardAssigneesPopup.helpers({ diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 391769e9..279d3671 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,7 +1,5 @@ template(name="checklists") - h3 - i.fa.fa-check - | {{_ 'checklists'}} + h3 {{_ 'checklists'}} if toggleDeleteDialog.get .board-overlay#card-details-overlay +checklistDeleteDialog(checklist = checklistToDelete) diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 27d1b1c9..57939eb8 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -67,8 +67,7 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, }).register('checklistDetail'); @@ -121,8 +120,7 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, @@ -230,8 +228,7 @@ Template.checklistItemDetail.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, }); diff --git a/client/components/cards/subtasks.jade b/client/components/cards/subtasks.jade index df35bed3..7e64e23f 100644 --- a/client/components/cards/subtasks.jade +++ b/client/components/cards/subtasks.jade @@ -1,7 +1,5 @@ template(name="subtasks") - h3 - i.fa.fa-sitemap - | {{_ 'subtasks'}} + h3 {{_ 'subtasks'}} if toggleDeleteDialog.get .board-overlay#card-details-overlay +subtaskDeleteDialog(subtask = subtaskToDelete) diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index 34348fe1..fab860bb 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -3,8 +3,7 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, }).register('subtaskDetail'); @@ -56,8 +55,7 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, @@ -156,8 +154,7 @@ Template.subtaskItemDetail.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, }); diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 89c27ec7..b0974705 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -189,8 +189,7 @@ BlazeComponent.extendComponent({ !this.reachedWipLimit() && Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() && - !Meteor.user().isWorker() + !Meteor.user().isCommentOnly() ); }, diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 686de845..631f68a0 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -56,47 +56,25 @@ template(name="editListTitleForm") template(name="listActionPopup") ul.pop-over-list - li - a.js-toggle-watch-list - if isWatching - i.fa.fa-eye - | {{_ 'unwatch'}} - else - i.fa.fa-eye-slash - | {{_ 'watch'}} + li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}} unless currentUser.isCommentOnly - unless currentUser.isWorker - ul.pop-over-list - li - a.js-set-color-list - i.fa.fa-paint-brush - | {{_ 'set-color-list'}} + hr + ul.pop-over-list + li: a.js-set-color-list {{_ 'set-color-list'}} + hr ul.pop-over-list if cards.count - li - a.js-select-cards - i.fa.fa-check-square - | {{_ 'list-select-cards'}} + li: a.js-select-cards {{_ 'list-select-cards'}} + hr if currentUser.isBoardAdmin ul.pop-over-list - li - a.js-set-wip-limit - i.fa.fa-ban - | {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} - unless currentUser.isWorker + li: a.js-set-wip-limit {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} hr - ul.pop-over-list - li - a.js-close-list - i.fa.fa-arrow-right - i.fa.fa-archive - | {{_ 'archive-list'}} + ul.pop-over-list + li: a.js-close-list {{_ 'archive-list'}} hr ul.pop-over-list - li - a.js-more - i.fa.fa-link - | {{_ 'listMorePopup-title'}} + li: a.js-more {{_ 'listMorePopup-title'}} template(name="boardLists") ul.pop-over-list @@ -116,8 +94,7 @@ template(name="listMorePopup") input.inline-input(type="text" readonly value="{{ rootUrl }}") | {{_ 'added'}} span.date(title=list.createdAt) {{ moment createdAt 'LLL' }} - unless currentUser.isWorker - a.js-delete {{_ 'delete'}} + a.js-delete {{_ 'delete'}} template(name="listDeletePopup") p {{_ "list-delete-pop"}} diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 46dbd748..07edade0 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -9,10 +9,9 @@ BlazeComponent.extendComponent({ canSeeAddCard() { const list = Template.currentData(); return ( - (!list.getWipLimit('enabled') || - list.getWipLimit('soft') || - !this.reachedWipLimit()) && - !Meteor.user().isWorker() + !list.getWipLimit('enabled') || + list.getWipLimit('soft') || + !this.reachedWipLimit() ); }, diff --git a/client/components/settings/informationBody.jade b/client/components/settings/informationBody.jade index 0f85dd9c..2c615ffd 100644 --- a/client/components/settings/informationBody.jade +++ b/client/components/settings/informationBody.jade @@ -4,16 +4,12 @@ template(name='information') | {{_ 'error-notAuthorized'}} else .content-title - span - i.fa.fa-info-circle - | {{_ 'info'}} + span {{_ 'info'}} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="information-display") - i.fa.fa-info-circle - | {{_ 'info'}} + a.js-setting-menu(data-id="information-display") {{_ 'info'}} .main-body +statistics diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index b8a94337..d8f672b0 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -5,22 +5,16 @@ template(name="people") else .content-title.ext-box .ext-box-left - span - i.fa.fa-users - | {{_ 'people'}} + span {{_ 'people'}} input#searchInput(placeholder="{{_ 'search'}}") - button#searchButton - i.fa.fa-search - | {{_ 'search'}} + button#searchButton {{_ 'search'}} .ext-box-right span {{_ 'people-number'}} #{peopleNumber} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="people-setting") - i.fa.fa-users - | {{_ 'people'}} + a.js-setting-menu(data-id="people-setting") {{_ 'people'}} .main-body if loading.get +spinner @@ -96,7 +90,6 @@ template(name="peopleRow") td {{_ userData.authenticationMethod }} td a.edit-user - i.fa.fa-edit | {{_ 'edit'}} template(name="editUserPopup") diff --git a/client/components/settings/peopleBody.styl b/client/components/settings/peopleBody.styl index c223e181..80387611 100644 --- a/client/components/settings/peopleBody.styl +++ b/client/components/settings/peopleBody.styl @@ -33,7 +33,7 @@ table padding: 0; button - min-width: 90px; + min-width: 60px; .content-wrapper margin-top: 10px diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 877fe6e2..04b635e8 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -4,35 +4,22 @@ template(name="setting") | {{_ 'error-notAuthorized'}} else .content-title - i.fa.fa-cog span {{_ 'settings'}} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="registration-setting") - i.fa.fa-sign-in - | {{_ 'registration'}} + a.js-setting-menu(data-id="registration-setting") {{_ 'registration'}} li - a.js-setting-menu(data-id="email-setting") - i.fa.fa-envelope - | {{_ 'email'}} + a.js-setting-menu(data-id="email-setting") {{_ 'email'}} li - a.js-setting-menu(data-id="account-setting") - i.fa.fa-users - | {{_ 'accounts'}} + a.js-setting-menu(data-id="account-setting") {{_ 'accounts'}} li - a.js-setting-menu(data-id="announcement-setting") - i.fa.fa-bullhorn - | {{_ 'admin-announcement'}} + a.js-setting-menu(data-id="announcement-setting") {{_ 'admin-announcement'}} li - a.js-setting-menu(data-id="layout-setting") - i.fa.fa-object-group - | {{_ 'layout'}} + a.js-setting-menu(data-id="layout-setting") {{_ 'layout'}} li - a.js-setting-menu(data-id="webhook-setting") - i.fa.fa-globe - | {{_ 'global-webhook'}} + a.js-setting-menu(data-id="webhook-setting") {{_ 'global-webhook'}} .main-body if loading.get +spinner diff --git a/client/components/settings/settingBody.styl b/client/components/settings/settingBody.styl index d6ac32b2..bcbd2ea1 100644 --- a/client/components/settings/settingBody.styl +++ b/client/components/settings/settingBody.styl @@ -41,18 +41,15 @@ &:hover background #fff box-shadow 0 1px 2px rgba(0,0,0,0.15); - a @extends .flex padding: 1rem 0 1rem 1rem width: 100% - 5rem + span font-size: 13px - i - margin-right: 20px - .main-body padding: 0.1em 1em -webkit-user-select: text // Safari 3.1+ diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 19e32970..ccfadc0c 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -37,12 +37,11 @@ template(name='homeSidebar') template(name="membersWidget") .board-widget.board-widget-members h3 - i.fa.fa-users + i.fa.fa-user | {{_ 'members'}} unless currentUser.isCommentOnly - unless currentUser.isWorker - a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right - i.board-header-btn-icon.fa.fa-cog + a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right + i.board-header-btn-icon.fa.fa-cog .board-widget-content each currentBoard.activeMembers @@ -131,9 +130,7 @@ template(name="chooseBoardSource") template(name="archiveBoardPopup") p {{_ 'close-board-pop'}} - button.js-confirm.negate.full(type="submit") - i.fa.fa-archive - | {{_ 'archive'}} + button.js-confirm.negate.full(type="submit") {{_ 'archive'}} template(name="outgoingWebhooksPopup") each integrations @@ -165,80 +162,38 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list - if isNotWorker - li: a.js-custom-fields {{_ 'custom-fields'}} - li - a.js-open-archives - i.fa.fa-archive - | {{_ 'archived-items'}} + li: a.js-custom-fields {{_ 'custom-fields'}} + li: a.js-open-archives {{_ 'archived-items'}} if currentUser.isBoardAdmin - li - a.js-change-board-color - i.fa.fa-paint-brush - | {{_ 'board-change-color'}} - + li: a.js-change-board-color {{_ 'board-change-color'}} //- XXX Language should be handled by sandstorm, but for now display a language selection link in the board menu. This link is normally present in the header bar that is not displayed on sandstorm. if isSandstorm - li - a.js-change-language - i.fa.fa-flag - | {{_ 'language'}} + li: a.js-change-language {{_ 'language'}} unless isSandstorm if currentUser.isBoardAdmin hr ul.pop-over-list - li - a(href="{{exportUrl}}", download="{{exportFilename}}") - i.fa.fa-share-alt - | {{_ 'export-board'}} - li - a.js-outgoing-webhooks - i.fa.fa-globe - | {{_ 'outgoing-webhooks'}} - li - a.js-subtask-settings - i.fa.fa-sitemap - | {{_ 'subtask-settings'}} - unless currentBoard.isTemplatesBoard - hr - ul.pop-over-list - li - a.js-archive-board - i.fa.fa-arrow-right - i.fa.fa-archive - | {{_ 'archive-board'}} + li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} + unless currentBoard.isTemplatesBoard + li: a.js-archive-board {{_ 'archive-board'}} + li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} + hr + ul.pop-over-list + li: a.js-subtask-settings {{_ 'subtask-settings'}} if isSandstorm hr ul.pop-over-list - li - a(href="{{exportUrl}}", download="{{exportFilename}}") - i.fa.fa-share-alt - i.fa.fa-sign-out - | {{_ 'export-board'}} - li - a.js-import-board - i.fa.fa-share-alt - i.fa.fa-sign-in - | {{_ 'import-board-c'}} - li - a.js-archive-board - i.fa.fa-arrow-right - i.fa.fa-archive - | {{_ 'archive-board'}} - li - a.js-outgoing-webhooks - i.fa.fa-globe - | {{_ 'outgoing-webhooks'}} + li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} + li: a.js-import-board {{_ 'import-board-c'}} + li: a.js-archive-board {{_ 'archive-board'}} + li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} hr ul.pop-over-list - li - a.js-subtask-settings - i.fa.fa-sitemap - | {{_ 'subtask-settings'}} + li: a.js-subtask-settings {{_ 'subtask-settings'}} template(name="labelsWidget") .board-widget.board-widget-labels @@ -248,7 +203,7 @@ template(name="labelsWidget") .board-widget-content each currentBoard.labels a.card-label(class="card-label-{{color}}" - class="{{#if currentUser.isNotCommentOnly}}{{#if currentUser.isNotWorker}}js-label{{/if}}{{/if}}") + class="{{#if currentUser.isNotCommentOnly}}js-label{{/if}}") span.card-label-name +viewer = name @@ -277,12 +232,12 @@ template(name="memberPopup") a.js-change-role | {{_ 'change-permissions'}} span.quiet (#{memberType}) - unless currentUser.isWorker - li - if $eq currentUser._id userId - a.js-leave-member {{_ 'leave-board'}} - else if currentUser.isBoardAdmin - a.js-remove-member {{_ 'remove-from-board'}} + li + if $eq currentUser._id userId + a.js-leave-member {{_ 'leave-board'}} + else if currentUser.isBoardAdmin + a.js-remove-member {{_ 'remove-from-board'}} + template(name="removeMemberPopup") p {{_ 'remove-member-pop' name=user.profile.fullname username=user.username boardTitle=board.title}} @@ -346,12 +301,6 @@ template(name="changePermissionsPopup") if isCommentOnly i.fa.fa-check span.sub-name {{_ 'comment-only-desc'}} - li - a(class="{{#if isLastAdmin}}disabled{{else}}js-set-worker{{/if}}") - | {{_ 'worker'}} - if isWorker - i.fa.fa-check - span.sub-name {{_ 'worker-desc'}} if isLastAdmin hr p.quiet.bottom {{_ 'last-admin-desc'}} diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index e8f38b8c..9d9c597a 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -161,13 +161,10 @@ Template.memberPopup.helpers({ const currentBoard = Boards.findOne(Session.get('currentBoard')); const commentOnly = currentBoard.hasCommentOnly(this.userId); const noComments = currentBoard.hasNoComments(this.userId); - const worker = currentBoard.hasWorker(this.userId); if (commentOnly) { return TAPi18n.__('comment-only').toLowerCase(); } else if (noComments) { return TAPi18n.__('no-comments').toLowerCase(); - } else if (worker) { - return TAPi18n.__('worker').toLowerCase(); } else { return TAPi18n.__(type).toLowerCase(); } @@ -270,14 +267,6 @@ Template.membersWidget.helpers({ const user = Meteor.user(); return user && user.isInvitedTo(Session.get('currentBoard')); }, - isWorker() { - const user = Meteor.user(); - if (user) { - return Meteor.call(Boards.hasWorker(user.memberId)); - } else { - return false; - } - }, }); Template.membersWidget.events({ @@ -655,7 +644,7 @@ BlazeComponent.extendComponent({ }).register('addMemberPopup'); Template.changePermissionsPopup.events({ - 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only, click .js-set-worker'( + 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only'( event, ) { const currentBoard = Boards.findOne(Session.get('currentBoard')); @@ -665,13 +654,11 @@ Template.changePermissionsPopup.events({ 'js-set-comment-only', ); const isNoComments = $(event.currentTarget).hasClass('js-set-no-comments'); - const isWorker = $(event.currentTarget).hasClass('js-set-worker'); currentBoard.setMemberPermission( memberId, isAdmin, isNoComments, isCommentOnly, - isWorker, ); Popup.back(1); }, @@ -688,8 +675,7 @@ Template.changePermissionsPopup.helpers({ return ( !currentBoard.hasAdmin(this.userId) && !currentBoard.hasNoComments(this.userId) && - !currentBoard.hasCommentOnly(this.userId) && - !currentBoard.hasWorker(this.userId) + !currentBoard.hasCommentOnly(this.userId) ); }, @@ -709,13 +695,6 @@ Template.changePermissionsPopup.helpers({ ); }, - isWorker() { - const currentBoard = Boards.findOne(Session.get('currentBoard')); - return ( - !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) - ); - }, - isLastAdmin() { const currentBoard = Boards.findOne(Session.get('currentBoard')); return ( diff --git a/client/components/sidebar/sidebarArchives.jade b/client/components/sidebar/sidebarArchives.jade index 56423ad7..466d2cb0 100644 --- a/client/components/sidebar/sidebarArchives.jade +++ b/client/components/sidebar/sidebarArchives.jade @@ -2,60 +2,54 @@ template(name="archivesSidebar") if isArchiveReady.get +basicTabs(tabs=tabs) +tabContent(slug="cards") - unless isWorker - p.quiet - a.js-restore-all-cards {{_ 'restore-all'}} - | - - a.js-delete-all-cards {{_ 'delete-all'}} + p.quiet + a.js-restore-all-cards {{_ 'restore-all'}} + | - + a.js-delete-all-cards {{_ 'delete-all'}} each archivedCards .minicard-wrapper.js-minicard +minicard(this) if currentUser.isBoardMember - unless isWorker - p.quiet - a.js-restore-card {{_ 'restore'}} - | - - a.js-delete-card {{_ 'delete'}} + p.quiet + a.js-restore-card {{_ 'restore'}} + | - + a.js-delete-card {{_ 'delete'}} if cardIsInArchivedList p.quiet.small ({{_ 'warn-list-archived'}}) else p.no-items-message {{_ 'no-archived-cards'}} +tabContent(slug="lists") - unless isWorker - p.quiet - a.js-restore-all-lists {{_ 'restore-all'}} - | - - a.js-delete-all-lists {{_ 'delete-all'}} + p.quiet + a.js-restore-all-lists {{_ 'restore-all'}} + | - + a.js-delete-all-lists {{_ 'delete-all'}} ul.archived-lists each archivedLists li.archived-lists-item = title if currentUser.isBoardMember - unless isWorker - p.quiet - a.js-restore-list {{_ 'restore'}} - | - - a.js-delete-list {{_ 'delete'}} + p.quiet + a.js-restore-list {{_ 'restore'}} + | - + a.js-delete-list {{_ 'delete'}} else li.no-items-message {{_ 'no-archived-lists'}} +tabContent(slug="swimlanes") - unless isWorker - p.quiet - a.js-restore-all-swimlanes {{_ 'restore-all'}} - | - - a.js-delete-all-swimlanes {{_ 'delete-all'}} + p.quiet + a.js-restore-all-swimlanes {{_ 'restore-all'}} + | - + a.js-delete-all-swimlanes {{_ 'delete-all'}} ul.archived-lists each archivedSwimlanes li.archived-lists-item = title if currentUser.isBoardMember - unless isWorker - p.quiet - a.js-restore-swimlane {{_ 'restore'}} - | - - a.js-delete-swimlane {{_ 'delete'}} + p.quiet + a.js-restore-swimlane {{_ 'restore'}} + | - + a.js-delete-swimlane {{_ 'delete'}} else li.no-items-message {{_ 'no-archived-swimlanes'}} else diff --git a/client/components/sidebar/sidebarArchives.js b/client/components/sidebar/sidebarArchives.js index 75b694e9..a4846561 100644 --- a/client/components/sidebar/sidebarArchives.js +++ b/client/components/sidebar/sidebarArchives.js @@ -139,12 +139,3 @@ BlazeComponent.extendComponent({ ]; }, }).register('archivesSidebar'); - -Template.archivesSidebar.helpers({ - isWorker() { - const currentBoard = Boards.findOne(Session.get('currentBoard')); - return ( - !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) - ); - }, -}); diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 7f31dada..5f929cb9 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -117,14 +117,13 @@ template(name="multiselectionSidebar") i.fa.fa-check else if someSelectedElementHave 'member' _id i.fa.fa-ellipsis-h - unless currentUser.isWorker - hr - a.sidebar-btn.js-move-selection - i.fa.fa-share - span {{_ 'move-selection'}} - a.sidebar-btn.js-archive-selection - i.fa.fa-archive - span {{_ 'archive-selection'}} + hr + a.sidebar-btn.js-move-selection + i.fa.fa-share + span {{_ 'move-selection'}} + a.sidebar-btn.js-archive-selection + i.fa.fa-archive + span {{_ 'archive-selection'}} template(name="disambiguateMultiLabelPopup") p {{_ 'what-to-do'}} diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 9b00d9e8..1dc23c59 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -43,20 +43,19 @@ template(name="listsGroup") +addListForm template(name="addListForm") - unless currentUser.isWorker - .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'}}" - autocomplete="off" autofocus) - .edit-controls.clearfix - button.primary.confirm(type="submit") {{_ 'save'}} - unless currentBoard.isTemplatesBoard - unless currentBoard.isTemplateBoard - span.quiet - | {{_ 'or'}} - a.js-list-template {{_ 'template'}} - else - a.open-list-composer.js-open-inlined-form - i.fa.fa-plus - | {{_ 'add-list'}} + .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'}}" + autocomplete="off" autofocus) + .edit-controls.clearfix + button.primary.confirm(type="submit") {{_ 'save'}} + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-list-template {{_ 'template'}} + else + a.open-list-composer.js-open-inlined-form + i.fa.fa-plus + | {{_ 'add-list'}} diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index 7f2067ce..ebfa48ba 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -73,7 +73,6 @@ template(name="cardMemberPopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly - if currentUser.isNotWorker li: a.js-remove-member {{_ 'remove-member-from-card'}} if $eq currentUser._id user._id diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 9306d21d..50a80396 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -13,46 +13,21 @@ template(name="headerUserBar") template(name="memberMenuPopup") ul.pop-over-list with currentUser - li - a.js-edit-profile - i.fa.fa-user - | {{_ 'edit-profile'}} - li - a.js-change-settings - i.fa.fa-cog - | {{_ 'change-settings'}} - li - a.js-change-avatar - i.fa.fa-picture-o - | {{_ 'edit-avatar'}} + li: a.js-edit-profile {{_ 'edit-profile'}} + li: a.js-change-settings {{_ 'change-settings'}} + li: a.js-change-avatar {{_ 'edit-avatar'}} unless isSandstorm - li - a.js-change-password - i.fa.fa-key - | {{_ 'changePasswordPopup-title'}} - li - a.js-change-language - i.fa.fa-flag - | {{_ 'changeLanguagePopup-title'}} + li: a.js-change-password {{_ 'changePasswordPopup-title'}} + li: a.js-change-language {{_ 'changeLanguagePopup-title'}} if currentUser.isAdmin - li - a.js-go-setting(href="{{pathFor 'setting'}}") - i.fa.fa-lock - | {{_ 'admin-panel'}} - unless currentUser.isWorker - hr - ul.pop-over-list - li - a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") - i.fa.fa-clone - | {{_ 'templates'}} + li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}} + hr + ul.pop-over-list + li: a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") {{_ 'templates'}} unless isSandstorm hr ul.pop-over-list - li - a.js-logout - i.fa.fa-sign-out - | {{_ 'log-out'}} + li: a.js-logout {{_ 'log-out'}} template(name="editProfilePopup") form @@ -100,25 +75,21 @@ template(name="changeSettingsPopup") ul.pop-over-list li a.js-toggle-system-messages - i.fa.fa-comments-o | {{_ 'hide-system-messages'}} if hiddenSystemMessages i.fa.fa-check li a.js-toggle-desktop-drag-handles - i.fa.fa-arrows | {{_ 'show-desktop-drag-handles'}} if showDesktopDragHandles i.fa.fa-check - unless currentUser.isWorker - li - label.bold - i.fa.fa-sort-numeric-asc - | {{_ 'show-cards-minimum-count'}} - input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") - input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") + li + label.bold + | {{_ 'show-cards-minimum-count'}} + input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") + input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") + template(name="userDeletePopup") - unless currentUser.isWorker - p {{_ 'delete-user-confirm-popup'}} - button.js-confirm.negate.full(type="submit") {{_ 'delete'}} + p {{_ 'delete-user-confirm-popup'}} + button.js-confirm.negate.full(type="submit") {{_ 'delete'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 847d30fb..5f36ef54 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -45,31 +45,13 @@ Template.memberMenuPopup.events({ Template.editProfilePopup.helpers({ allowEmailChange() { - Meteor.call('AccountSettings.allowEmailChange', (_, result) => { - if (result) { - return true; - } else { - return false; - } - }); + return AccountSettings.findOne('accounts-allowEmailChange').booleanValue; }, allowUserNameChange() { - Meteor.call('AccountSettings.allowUserNameChange', (_, result) => { - if (result) { - return true; - } else { - return false; - } - }); + return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue; }, allowUserDelete() { - Meteor.call('AccountSettings.allowUserDelete', (_, result) => { - if (result) { - return true; - } else { - return false; - } - }); + return AccountSettings.findOne('accounts-allowUserDelete').booleanValue; }, }); -- cgit v1.2.3-1-g7c22 From cd253522a305523e3e36bb73313e8c4db500a717 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 3 Jan 2020 17:02:27 +0200 Subject: Add more Font Awesome icons. This was originally added at Wekan v3.58, removed at Wekan v3.60, and now added back at Wekan v3.61. Thanks to xet7 ! --- client/components/cards/cardDetails.jade | 117 +++++++++++++++++++----- client/components/cards/checklists.jade | 4 +- client/components/cards/subtasks.jade | 4 +- client/components/lists/listHeader.jade | 40 ++++++-- client/components/settings/informationBody.jade | 8 +- client/components/settings/peopleBody.jade | 13 ++- client/components/settings/peopleBody.styl | 2 +- client/components/settings/settingBody.jade | 25 +++-- client/components/settings/settingBody.styl | 5 +- client/components/sidebar/sidebar.jade | 78 ++++++++++++---- client/components/sidebar/sidebarFilters.jade | 15 +-- client/components/users/userAvatar.jade | 2 +- client/components/users/userHeader.jade | 44 +++++++-- client/components/users/userHeader.js | 24 ++++- 14 files changed, 293 insertions(+), 88 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 2b4f44b9..d7c7ca59 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -16,8 +16,8 @@ template(name="cardDetails") class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}") +viewer = getTitle - if isWatching - i.fa.fa-eye.card-details-watch + if isWatching + i.card-details-watch.fa.fa-eye .card-details-path each parentList |   >   @@ -37,7 +37,9 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-received - h3.card-details-item-title {{_ 'card-received'}} + h3 + i.fa.fa-sign-out + card-details-item-title {{_ 'card-received'}} if getReceived +cardReceivedDate else @@ -45,7 +47,9 @@ template(name="cardDetails") a.js-received-date {{_ 'add'}} .card-details-item.card-details-item-start - h3.card-details-item-title {{_ 'card-start'}} + h3 + i.fa.fa-hourglass-start + card-details-item-title {{_ 'card-start'}} if getStart +cardStartDate else @@ -53,7 +57,9 @@ template(name="cardDetails") a.js-start-date {{_ 'add'}} .card-details-item.card-details-item-due - h3.card-details-item-title {{_ 'card-due'}} + h3 + i.fa.fa-sign-in + card-details-item-title {{_ 'card-due'}} if getDue +cardDueDate else @@ -61,7 +67,9 @@ template(name="cardDetails") a.js-due-date {{_ 'add'}} .card-details-item.card-details-item-end - h3.card-details-item-title {{_ 'card-end'}} + h3 + i.fa.fa-hourglass-end + card-details-item-title {{_ 'card-end'}} if getEnd +cardEndDate else @@ -70,7 +78,9 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-members - h3.card-details-item-title {{_ 'members'}} + h3 + i.fa.fa-users + card-details-item-title {{_ 'members'}} each getMembers +userAvatar(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} @@ -79,7 +89,9 @@ template(name="cardDetails") i.fa.fa-plus .card-details-item.card-details-item-assignees - h3.card-details-item-title {{_ 'assignee'}} + h3 + i.fa.fa-user + card-details-item-title {{_ 'assignee'}} each getAssignees +userAvatarAssignee(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} @@ -89,7 +101,9 @@ template(name="cardDetails") i.fa.fa-plus .card-details-item.card-details-item-labels - h3.card-details-item-title {{_ 'labels'}} + h3 + i.fa.fa-tags + card-details-item-title {{_ 'labels'}} a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}") each labels span.card-label(class="card-label-{{color}}" title=name) @@ -118,7 +132,9 @@ template(name="cardDetails") //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard - h3.card-details-item-title {{_ 'description'}} + h3 + i.fa.fa-align-left + card-details-item-title {{_ 'description'}} +inlinedCardDescription(classNames="card-description js-card-description") +editor(autofocus=true) | {{getUnsavedValue 'cardDescription' _id getDescription}} @@ -145,7 +161,9 @@ template(name="cardDetails") .card-details-items .card-details-item.card-details-item-name - h3.card-details-item-title {{_ 'requested-by'}} + h3 + i.fa.fa-shopping-cart + card-details-item-title {{_ 'requested-by'}} if canModifyCard +inlinedForm(classNames="js-card-details-requester") +editCardRequesterForm @@ -161,7 +179,9 @@ template(name="cardDetails") = getRequestedBy .card-details-item.card-details-item-name - h3.card-details-item-title {{_ 'assigned-by'}} + h3 + i.fa.fa-user-plus + card-details-item-title {{_ 'assigned-by'}} if canModifyCard +inlinedForm(classNames="js-card-details-assigner") +editCardAssignerForm @@ -193,7 +213,9 @@ template(name="cardDetails") hr unless currentUser.isNoComments .activity-title - h3 {{ _ 'activity'}} + h3 + i.fa.fa-history + | {{ _ 'activity'}} if currentUser.isBoardMember .material-toggle-switch span.toggle-switch-title {{_ 'hide-system-messages'}} @@ -235,32 +257,77 @@ template(name="editCardAssignerForm") template(name="cardDetailsActionsPopup") ul.pop-over-list - li: a.js-toggle-watch-card {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}} + li + a.js-toggle-watch-card + if isWatching + i.fa.fa-eye + | {{_ 'unwatch'}} + else + i.fa.fa-eye-slash + | {{_ 'watch'}} if canModifyCard hr ul.pop-over-list //li: a.js-members {{_ 'card-edit-members'}} //li: a.js-labels {{_ 'card-edit-labels'}} //li: a.js-attachments {{_ 'card-edit-attachments'}} - li: a.js-custom-fields {{_ 'card-edit-custom-fields'}} + li + a.js-custom-fields + i.fa.fa-list-alt + | {{_ 'card-edit-custom-fields'}} //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} - li: a.js-spent-time {{_ 'editCardSpentTimePopup-title'}} - li: a.js-set-card-color {{_ 'setCardColorPopup-title'}} + li + a.js-spent-time + i.fa.fa-clock-o + | {{_ 'editCardSpentTimePopup-title'}} + li + a.js-set-card-color + i.fa.fa-paint-brush + | {{_ 'setCardColorPopup-title'}} hr ul.pop-over-list - li: a.js-move-card-to-top {{_ 'moveCardToTop-title'}} - li: a.js-move-card-to-bottom {{_ 'moveCardToBottom-title'}} + li + a.js-move-card-to-top + i.fa.fa-arrow-up + | {{_ 'moveCardToTop-title'}} + li + a.js-move-card-to-bottom + i.fa.fa-arrow-down + | {{_ 'moveCardToBottom-title'}} hr ul.pop-over-list - li: a.js-move-card {{_ 'moveCardPopup-title'}} - li: a.js-copy-card {{_ 'copyCardPopup-title'}} - li: a.js-copy-checklist-cards {{_ 'copyChecklistToManyCardsPopup-title'}} + li + a.js-move-card + i.fa.fa-arrow-right + | {{_ 'moveCardPopup-title'}} + li + a.js-copy-card + i.fa.fa-copy + | {{_ 'copyCardPopup-title'}} + hr + ul.pop-over-list + li + a.js-copy-checklist-cards + i.fa.fa-list + i.fa.fa-copy + | {{_ 'copyChecklistToManyCardsPopup-title'}} unless archived - li: a.js-archive {{_ 'archive-card'}} - li: a.js-more {{_ 'cardMorePopup-title'}} + hr + ul.pop-over-list + li + a.js-archive + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-card'}} + hr + ul.pop-over-list + li + a.js-more + i.fa.fa-link + | {{_ 'cardMorePopup-title'}} template(name="moveCardPopup") +boardsAndLists @@ -349,7 +416,7 @@ template(name="cardAssigneePopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly - li: a.js-remove-assignee {{_ 'remove-member-from-card'}} + li: a.js-remove-assignee {{_ 'remove-member-from-card'}} if $eq currentUser._id user._id with currentUser diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 279d3671..391769e9 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,5 +1,7 @@ template(name="checklists") - h3 {{_ 'checklists'}} + h3 + i.fa.fa-check + | {{_ 'checklists'}} if toggleDeleteDialog.get .board-overlay#card-details-overlay +checklistDeleteDialog(checklist = checklistToDelete) diff --git a/client/components/cards/subtasks.jade b/client/components/cards/subtasks.jade index 7e64e23f..df35bed3 100644 --- a/client/components/cards/subtasks.jade +++ b/client/components/cards/subtasks.jade @@ -1,5 +1,7 @@ template(name="subtasks") - h3 {{_ 'subtasks'}} + h3 + i.fa.fa-sitemap + | {{_ 'subtasks'}} if toggleDeleteDialog.get .board-overlay#card-details-overlay +subtaskDeleteDialog(subtask = subtaskToDelete) diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 631f68a0..6468839d 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -56,25 +56,45 @@ template(name="editListTitleForm") template(name="listActionPopup") ul.pop-over-list - li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}} + li + a.js-toggle-watch-list + if isWatching + i.fa.fa-eye + | {{_ 'unwatch'}} + else + i.fa.fa-eye-slash + | {{_ 'watch'}} unless currentUser.isCommentOnly - hr ul.pop-over-list - li: a.js-set-color-list {{_ 'set-color-list'}} - hr + li + a.js-set-color-list + i.fa.fa-paint-brush + | {{_ 'set-color-list'}} ul.pop-over-list if cards.count - li: a.js-select-cards {{_ 'list-select-cards'}} - hr + li + a.js-select-cards + i.fa.fa-check-square + | {{_ 'list-select-cards'}} if currentUser.isBoardAdmin ul.pop-over-list - li: a.js-set-wip-limit {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} - hr + li + a.js-set-wip-limit + i.fa.fa-ban + | {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} + hr ul.pop-over-list - li: a.js-close-list {{_ 'archive-list'}} + li + a.js-close-list + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-list'}} hr ul.pop-over-list - li: a.js-more {{_ 'listMorePopup-title'}} + li + a.js-more + i.fa.fa-link + | {{_ 'listMorePopup-title'}} template(name="boardLists") ul.pop-over-list diff --git a/client/components/settings/informationBody.jade b/client/components/settings/informationBody.jade index 2c615ffd..0f85dd9c 100644 --- a/client/components/settings/informationBody.jade +++ b/client/components/settings/informationBody.jade @@ -4,12 +4,16 @@ template(name='information') | {{_ 'error-notAuthorized'}} else .content-title - span {{_ 'info'}} + span + i.fa.fa-info-circle + | {{_ 'info'}} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="information-display") {{_ 'info'}} + a.js-setting-menu(data-id="information-display") + i.fa.fa-info-circle + | {{_ 'info'}} .main-body +statistics diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index d8f672b0..b8a94337 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -5,16 +5,22 @@ template(name="people") else .content-title.ext-box .ext-box-left - span {{_ 'people'}} + span + i.fa.fa-users + | {{_ 'people'}} input#searchInput(placeholder="{{_ 'search'}}") - button#searchButton {{_ 'search'}} + button#searchButton + i.fa.fa-search + | {{_ 'search'}} .ext-box-right span {{_ 'people-number'}} #{peopleNumber} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="people-setting") {{_ 'people'}} + a.js-setting-menu(data-id="people-setting") + i.fa.fa-users + | {{_ 'people'}} .main-body if loading.get +spinner @@ -90,6 +96,7 @@ template(name="peopleRow") td {{_ userData.authenticationMethod }} td a.edit-user + i.fa.fa-edit | {{_ 'edit'}} template(name="editUserPopup") diff --git a/client/components/settings/peopleBody.styl b/client/components/settings/peopleBody.styl index 80387611..c223e181 100644 --- a/client/components/settings/peopleBody.styl +++ b/client/components/settings/peopleBody.styl @@ -33,7 +33,7 @@ table padding: 0; button - min-width: 60px; + min-width: 90px; .content-wrapper margin-top: 10px diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 04b635e8..877fe6e2 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -4,22 +4,35 @@ template(name="setting") | {{_ 'error-notAuthorized'}} else .content-title + i.fa.fa-cog span {{_ 'settings'}} .content-body .side-menu ul li.active - a.js-setting-menu(data-id="registration-setting") {{_ 'registration'}} + a.js-setting-menu(data-id="registration-setting") + i.fa.fa-sign-in + | {{_ 'registration'}} li - a.js-setting-menu(data-id="email-setting") {{_ 'email'}} + a.js-setting-menu(data-id="email-setting") + i.fa.fa-envelope + | {{_ 'email'}} li - a.js-setting-menu(data-id="account-setting") {{_ 'accounts'}} + a.js-setting-menu(data-id="account-setting") + i.fa.fa-users + | {{_ 'accounts'}} li - a.js-setting-menu(data-id="announcement-setting") {{_ 'admin-announcement'}} + a.js-setting-menu(data-id="announcement-setting") + i.fa.fa-bullhorn + | {{_ 'admin-announcement'}} li - a.js-setting-menu(data-id="layout-setting") {{_ 'layout'}} + a.js-setting-menu(data-id="layout-setting") + i.fa.fa-object-group + | {{_ 'layout'}} li - a.js-setting-menu(data-id="webhook-setting") {{_ 'global-webhook'}} + a.js-setting-menu(data-id="webhook-setting") + i.fa.fa-globe + | {{_ 'global-webhook'}} .main-body if loading.get +spinner diff --git a/client/components/settings/settingBody.styl b/client/components/settings/settingBody.styl index bcbd2ea1..d6ac32b2 100644 --- a/client/components/settings/settingBody.styl +++ b/client/components/settings/settingBody.styl @@ -41,15 +41,18 @@ &:hover background #fff box-shadow 0 1px 2px rgba(0,0,0,0.15); + a @extends .flex padding: 1rem 0 1rem 1rem width: 100% - 5rem - span font-size: 13px + i + margin-right: 20px + .main-body padding: 0.1em 1em -webkit-user-select: text // Safari 3.1+ diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index ccfadc0c..e5adc0cd 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -37,7 +37,7 @@ template(name='homeSidebar') template(name="membersWidget") .board-widget.board-widget-members h3 - i.fa.fa-user + i.fa.fa-users | {{_ 'members'}} unless currentUser.isCommentOnly a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right @@ -130,7 +130,9 @@ template(name="chooseBoardSource") template(name="archiveBoardPopup") p {{_ 'close-board-pop'}} - button.js-confirm.negate.full(type="submit") {{_ 'archive'}} + button.js-confirm.negate.full(type="submit") + i.fa.fa-archive + | {{_ 'archive'}} template(name="outgoingWebhooksPopup") each integrations @@ -163,37 +165,78 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list li: a.js-custom-fields {{_ 'custom-fields'}} - li: a.js-open-archives {{_ 'archived-items'}} + li + a.js-open-archives + i.fa.fa-archive + | {{_ 'archived-items'}} if currentUser.isBoardAdmin - li: a.js-change-board-color {{_ 'board-change-color'}} + li + a.js-change-board-color + i.fa.fa-paint-brush + | {{_ 'board-change-color'}} + //- XXX Language should be handled by sandstorm, but for now display a language selection link in the board menu. This link is normally present in the header bar that is not displayed on sandstorm. if isSandstorm - li: a.js-change-language {{_ 'language'}} + li + a.js-change-language + i.fa.fa-flag + | {{_ 'language'}} unless isSandstorm if currentUser.isBoardAdmin hr ul.pop-over-list - li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} - unless currentBoard.isTemplatesBoard - li: a.js-archive-board {{_ 'archive-board'}} - li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} - hr - ul.pop-over-list - li: a.js-subtask-settings {{_ 'subtask-settings'}} + li + a(href="{{exportUrl}}", download="{{exportFilename}}") + i.fa.fa-share-alt + | {{_ 'export-board'}} + li + a.js-outgoing-webhooks + i.fa.fa-globe + | {{_ 'outgoing-webhooks'}} + li + a.js-subtask-settings + i.fa.fa-sitemap + | {{_ 'subtask-settings'}} + unless currentBoard.isTemplatesBoard + hr + ul.pop-over-list + li + a.js-archive-board + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-board'}} if isSandstorm hr ul.pop-over-list - li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}} - li: a.js-import-board {{_ 'import-board-c'}} - li: a.js-archive-board {{_ 'archive-board'}} - li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}} + li + a(href="{{exportUrl}}", download="{{exportFilename}}") + i.fa.fa-share-alt + i.fa.fa-sign-out + | {{_ 'export-board'}} + li + a.js-import-board + i.fa.fa-share-alt + i.fa.fa-sign-in + | {{_ 'import-board-c'}} + li + a.js-archive-board + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-board'}} + li + a.js-outgoing-webhooks + i.fa.fa-globe + | {{_ 'outgoing-webhooks'}} hr ul.pop-over-list - li: a.js-subtask-settings {{_ 'subtask-settings'}} + li + a.js-subtask-settings + i.fa.fa-sitemap + | {{_ 'subtask-settings'}} template(name="labelsWidget") .board-widget.board-widget-labels @@ -238,7 +281,6 @@ template(name="memberPopup") else if currentUser.isBoardAdmin a.js-remove-member {{_ 'remove-from-board'}} - template(name="removeMemberPopup") p {{_ 'remove-member-pop' name=user.profile.fullname username=user.username boardTitle=board.title}} button.js-confirm.negate.full(type="submit") {{_ 'remove-member'}} diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 5f929cb9..7f31dada 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -117,13 +117,14 @@ template(name="multiselectionSidebar") i.fa.fa-check else if someSelectedElementHave 'member' _id i.fa.fa-ellipsis-h - hr - a.sidebar-btn.js-move-selection - i.fa.fa-share - span {{_ 'move-selection'}} - a.sidebar-btn.js-archive-selection - i.fa.fa-archive - span {{_ 'archive-selection'}} + unless currentUser.isWorker + hr + a.sidebar-btn.js-move-selection + i.fa.fa-share + span {{_ 'move-selection'}} + a.sidebar-btn.js-archive-selection + i.fa.fa-archive + span {{_ 'archive-selection'}} template(name="disambiguateMultiLabelPopup") p {{_ 'what-to-do'}} diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index ebfa48ba..ff4a1ce6 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -73,7 +73,7 @@ template(name="cardMemberPopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly - li: a.js-remove-member {{_ 'remove-member-from-card'}} + li: a.js-remove-member {{_ 'remove-member-from-card'}} if $eq currentUser._id user._id with currentUser diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 50a80396..aa567e91 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -13,21 +13,45 @@ template(name="headerUserBar") template(name="memberMenuPopup") ul.pop-over-list with currentUser - li: a.js-edit-profile {{_ 'edit-profile'}} - li: a.js-change-settings {{_ 'change-settings'}} - li: a.js-change-avatar {{_ 'edit-avatar'}} + li + a.js-edit-profile + i.fa.fa-user + | {{_ 'edit-profile'}} + li + a.js-change-settings + i.fa.fa-cog + | {{_ 'change-settings'}} + li + a.js-change-avatar + i.fa.fa-picture-o + | {{_ 'edit-avatar'}} unless isSandstorm - li: a.js-change-password {{_ 'changePasswordPopup-title'}} - li: a.js-change-language {{_ 'changeLanguagePopup-title'}} + li + a.js-change-password + i.fa.fa-key + | {{_ 'changePasswordPopup-title'}} + li + a.js-change-language + i.fa.fa-flag + | {{_ 'changeLanguagePopup-title'}} if currentUser.isAdmin - li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}} + li + a.js-go-setting(href="{{pathFor 'setting'}}") + i.fa.fa-lock + | {{_ 'admin-panel'}} hr ul.pop-over-list - li: a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") {{_ 'templates'}} + li + a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") + i.fa.fa-clone + | {{_ 'templates'}} unless isSandstorm hr ul.pop-over-list - li: a.js-logout {{_ 'log-out'}} + li + a.js-logout + i.fa.fa-sign-out + | {{_ 'log-out'}} template(name="editProfilePopup") form @@ -75,21 +99,23 @@ template(name="changeSettingsPopup") ul.pop-over-list li a.js-toggle-system-messages + i.fa.fa-comments-o | {{_ 'hide-system-messages'}} if hiddenSystemMessages i.fa.fa-check li a.js-toggle-desktop-drag-handles + i.fa.fa-arrows | {{_ 'show-desktop-drag-handles'}} if showDesktopDragHandles i.fa.fa-check li label.bold + i.fa.fa-sort-numeric-asc | {{_ 'show-cards-minimum-count'}} input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") - template(name="userDeletePopup") p {{_ 'delete-user-confirm-popup'}} button.js-confirm.negate.full(type="submit") {{_ 'delete'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 5f36ef54..847d30fb 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -45,13 +45,31 @@ Template.memberMenuPopup.events({ Template.editProfilePopup.helpers({ allowEmailChange() { - return AccountSettings.findOne('accounts-allowEmailChange').booleanValue; + Meteor.call('AccountSettings.allowEmailChange', (_, result) => { + if (result) { + return true; + } else { + return false; + } + }); }, allowUserNameChange() { - return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue; + Meteor.call('AccountSettings.allowUserNameChange', (_, result) => { + if (result) { + return true; + } else { + return false; + } + }); }, allowUserDelete() { - return AccountSettings.findOne('accounts-allowUserDelete').booleanValue; + Meteor.call('AccountSettings.allowUserDelete', (_, result) => { + if (result) { + return true; + } else { + return false; + } + }); }, }); -- cgit v1.2.3-1-g7c22 From f6f7705f23ea18d7f1b8f8736b762eb89e00a3cf Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 5 Jan 2020 21:28:14 +0200 Subject: Add Worker role. This was originally added at Wekan v3.58, reverted at Wekan v3.60 because of bugs, and now after fixes added back. Thanks to xet7 ! Closes #2788 --- client/components/cards/attachments.jade | 26 +-- client/components/cards/cardDate.js | 3 +- client/components/cards/cardDetails.jade | 216 ++++++++++++++----------- client/components/cards/cardDetails.js | 3 +- client/components/cards/checklists.js | 9 +- client/components/cards/subtasks.js | 9 +- client/components/lists/listBody.js | 3 +- client/components/lists/listHeader.jade | 31 ++-- client/components/lists/listHeader.js | 7 +- client/components/sidebar/sidebar.jade | 35 ++-- client/components/sidebar/sidebar.js | 25 ++- client/components/sidebar/sidebarArchives.jade | 54 ++++--- client/components/sidebar/sidebarArchives.js | 9 ++ client/components/swimlanes/swimlanes.jade | 33 ++-- client/components/swimlanes/swimlanes.js | 15 +- client/components/users/userAvatar.jade | 3 +- client/components/users/userHeader.jade | 31 ++-- 17 files changed, 308 insertions(+), 204 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 2a96f4f4..10b767f4 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -38,18 +38,20 @@ template(name="attachmentsGalery") | {{_ 'download'}} if currentUser.isBoardMember unless currentUser.isCommentOnly - if isImage - a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}") - i.fa.fa-thumb-tack - if($eq ../coverId _id) - | {{_ 'remove-cover'}} - else - | {{_ 'add-cover'}} - a.js-confirm-delete - i.fa.fa-close - | {{_ 'delete'}} + unless currentUser.isWorker + if isImage + a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}") + i.fa.fa-thumb-tack + if($eq ../coverId _id) + | {{_ 'remove-cover'}} + else + | {{_ 'add-cover'}} + a.js-confirm-delete + i.fa.fa-close + | {{_ 'delete'}} if currentUser.isBoardMember unless currentUser.isCommentOnly - li.attachment-item.add-attachment - a.js-add-attachment {{_ 'add-attachment' }} + unless currentUser.isWorker + li.attachment-item.add-attachment + a.js-add-attachment {{_ 'add-attachment' }} diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index cb54b033..c4b5c6d8 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -97,7 +97,8 @@ Template.dateBadge.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index d7c7ca59..de4e102a 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -44,7 +44,8 @@ template(name="cardDetails") +cardReceivedDate else if canModifyCard - a.js-received-date {{_ 'add'}} + unless currentUser.isWorker + a.js-received-date {{_ 'add'}} .card-details-item.card-details-item-start h3 @@ -54,7 +55,8 @@ template(name="cardDetails") +cardStartDate else if canModifyCard - a.js-start-date {{_ 'add'}} + unless currentUser.isWorker + a.js-start-date {{_ 'add'}} .card-details-item.card-details-item-due h3 @@ -64,7 +66,8 @@ template(name="cardDetails") +cardDueDate else if canModifyCard - a.js-due-date {{_ 'add'}} + unless currentUser.isWorker + a.js-due-date {{_ 'add'}} .card-details-item.card-details-item-end h3 @@ -74,7 +77,8 @@ template(name="cardDetails") +cardEndDate else if canModifyCard - a.js-end-date {{_ 'add'}} + unless currentUser.isWorker + a.js-end-date {{_ 'add'}} .card-details-items .card-details-item.card-details-item-members @@ -85,8 +89,9 @@ template(name="cardDetails") +userAvatar(userId=this cardId=../_id) | {{! XXX Hack to hide syntaxic coloration /// }} if canModifyCard - a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}") - i.fa.fa-plus + unless currentUser.isWorker + 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 @@ -96,10 +101,14 @@ 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 + if currentUser.isWorker 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 i.fa.fa-tags @@ -110,8 +119,9 @@ template(name="cardDetails") +viewer = name if canModifyCard - a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") - i.fa.fa-plus + unless currentUser.isWorker + a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") + i.fa.fa-plus .card-details-items each customFieldsWD @@ -132,28 +142,29 @@ template(name="cardDetails") //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard - h3 - i.fa.fa-align-left - card-details-item-title {{_ 'description'}} - +inlinedCardDescription(classNames="card-description js-card-description") - +editor(autofocus=true) - | {{getUnsavedValue 'cardDescription' _id getDescription}} - .edit-controls.clearfix - button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form - else - a.js-open-inlined-form - if getDescription - +viewer - = getDescription - else - | {{_ 'edit'}} - if (hasUnsavedValue 'cardDescription' _id) - p.quiet - | {{_ 'unsaved-description'}} - a.js-open-inlined-form {{_ 'view-it'}} - = ' - ' - a.js-close-inlined-form {{_ 'discard'}} + unless currentUser.isWorker + h3 + i.fa.fa-align-left + card-details-item-title {{_ 'description'}} + +inlinedCardDescription(classNames="card-description js-card-description") + +editor(autofocus=true) + | {{getUnsavedValue 'cardDescription' _id getDescription}} + .edit-controls.clearfix + button.primary(type="submit") {{_ 'save'}} + a.fa.fa-times-thin.js-close-inlined-form + else + a.js-open-inlined-form + if getDescription + +viewer + = getDescription + else + | {{_ 'edit'}} + if (hasUnsavedValue 'cardDescription' _id) + p.quiet + | {{_ 'unsaved-description'}} + a.js-open-inlined-form {{_ 'view-it'}} + = ' - ' + a.js-close-inlined-form {{_ 'discard'}} else if getDescription h3.card-details-item-title {{_ 'description'}} +viewer @@ -165,15 +176,16 @@ template(name="cardDetails") i.fa.fa-shopping-cart card-details-item-title {{_ 'requested-by'}} if canModifyCard - +inlinedForm(classNames="js-card-details-requester") - +editCardRequesterForm - else - a.js-open-inlined-form - if getRequestedBy - +viewer - = getRequestedBy - else - | {{_ 'add'}} + unless currentUser.isWorker + +inlinedForm(classNames="js-card-details-requester") + +editCardRequesterForm + else + a.js-open-inlined-form + if getRequestedBy + +viewer + = getRequestedBy + else + | {{_ 'add'}} else if getRequestedBy +viewer = getRequestedBy @@ -183,15 +195,16 @@ template(name="cardDetails") i.fa.fa-user-plus card-details-item-title {{_ 'assigned-by'}} if canModifyCard - +inlinedForm(classNames="js-card-details-assigner") - +editCardAssignerForm - else - a.js-open-inlined-form - if getAssignedBy - +viewer - = getAssignedBy - else - | {{_ 'add'}} + unless currentUser.isWorker + +inlinedForm(classNames="js-card-details-assigner") + +editCardAssignerForm + else + a.js-open-inlined-form + if getAssignedBy + +viewer + = getAssignedBy + else + | {{_ 'add'}} else if getRequestedBy +viewer = getAssignedBy @@ -266,28 +279,29 @@ template(name="cardDetailsActionsPopup") i.fa.fa-eye-slash | {{_ 'watch'}} if canModifyCard - hr - ul.pop-over-list - //li: a.js-members {{_ 'card-edit-members'}} - //li: a.js-labels {{_ 'card-edit-labels'}} - //li: a.js-attachments {{_ 'card-edit-attachments'}} - li - a.js-custom-fields - i.fa.fa-list-alt - | {{_ 'card-edit-custom-fields'}} - //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} - //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} - //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} - //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} - li - a.js-spent-time - i.fa.fa-clock-o - | {{_ 'editCardSpentTimePopup-title'}} - li - a.js-set-card-color - i.fa.fa-paint-brush - | {{_ 'setCardColorPopup-title'}} - hr + unless currentUser.isWorker + hr + ul.pop-over-list + //li: a.js-members {{_ 'card-edit-members'}} + //li: a.js-labels {{_ 'card-edit-labels'}} + //li: a.js-attachments {{_ 'card-edit-attachments'}} + li + a.js-custom-fields + i.fa.fa-list-alt + | {{_ 'card-edit-custom-fields'}} + //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} + //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} + //li: a.js-due-date {{_ 'editCardDueDatePopup-title'}} + //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} + li + a.js-spent-time + i.fa.fa-clock-o + | {{_ 'editCardSpentTimePopup-title'}} + li + a.js-set-card-color + i.fa.fa-paint-brush + | {{_ 'setCardColorPopup-title'}} + hr ul.pop-over-list li a.js-move-card-to-top @@ -297,16 +311,17 @@ template(name="cardDetailsActionsPopup") a.js-move-card-to-bottom i.fa.fa-arrow-down | {{_ 'moveCardToBottom-title'}} - hr - ul.pop-over-list - li - a.js-move-card - i.fa.fa-arrow-right - | {{_ 'moveCardPopup-title'}} - li - a.js-copy-card - i.fa.fa-copy - | {{_ 'copyCardPopup-title'}} + unless currentUser.isWorker + hr + ul.pop-over-list + li + a.js-move-card + i.fa.fa-arrow-right + | {{_ 'moveCardPopup-title'}} + li + a.js-copy-card + i.fa.fa-copy + | {{_ 'copyCardPopup-title'}} hr ul.pop-over-list li @@ -379,16 +394,27 @@ template(name="cardMembersPopup") i.fa.fa-check template(name="cardAssigneesPopup") - ul.pop-over-list.js-card-assignee-list - each board.activeMembers - li.item(class="{{#if isCardAssignee}}active{{/if}}") - a.name.js-select-assignee(href="#") - +userAvatar(userId=user._id) - span.full-name - = user.profile.fullname - | ({{ user.username }}) - if isCardAssignee - i.fa.fa-check + unless currentUser.isWorker + ul.pop-over-list.js-card-assignee-list + each board.activeMembers + li.item(class="{{#if isCardAssignee}}active{{/if}}") + a.name.js-select-assignee(href="#") + +userAvatar(userId=user._id) + span.full-name + = user.profile.fullname + | ({{ user.username }}) + if isCardAssignee + i.fa.fa-check + if currentUser.isWorker + ul.pop-over-list.js-card-assignee-list + li.item(class="{{#if currentUser.isCardAssignee}}active{{/if}}") + a.name.js-select-assignee(href="#") + +userAvatar(userId=currentUser._id) + span.full-name + = currentUser.profile.fullname + | ({{ currentUser.username }}) + if currentUser.isCardAssignee + i.fa.fa-check template(name="userAvatarAssignee") a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})") @@ -416,11 +442,13 @@ template(name="cardAssigneePopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly - li: a.js-remove-assignee {{_ 'remove-member-from-card'}} + unless currentUser.isWorker + li: a.js-remove-assignee {{_ 'remove-member-from-card'}} - if $eq currentUser._id user._id - with currentUser - li: a.js-edit-profile {{_ 'edit-profile'}} + unless currentUser.isWorker + 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") diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 67120043..07dcac44 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -51,7 +51,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 57939eb8..27d1b1c9 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -67,7 +67,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }).register('checklistDetail'); @@ -120,7 +121,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, @@ -228,7 +230,8 @@ Template.checklistItemDetail.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index fab860bb..34348fe1 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -3,7 +3,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }).register('subtaskDetail'); @@ -55,7 +56,8 @@ BlazeComponent.extendComponent({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, @@ -154,7 +156,8 @@ Template.subtaskItemDetail.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index b0974705..89c27ec7 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -189,7 +189,8 @@ BlazeComponent.extendComponent({ !this.reachedWipLimit() && Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 6468839d..ec2c556f 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -10,7 +10,7 @@ template(name="listHeader") 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}}") + class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}{{#unless currentUser.isWorker}}js-open-inlined-form is-editable{{/unless}}{{/unless}}{{/if}}") +viewer = title if wipLimit.enabled @@ -65,11 +65,12 @@ template(name="listActionPopup") i.fa.fa-eye-slash | {{_ 'watch'}} unless currentUser.isCommentOnly - ul.pop-over-list - li - a.js-set-color-list - i.fa.fa-paint-brush - | {{_ 'set-color-list'}} + unless currentUser.isWorker + ul.pop-over-list + li + a.js-set-color-list + i.fa.fa-paint-brush + | {{_ 'set-color-list'}} ul.pop-over-list if cards.count li @@ -82,13 +83,14 @@ template(name="listActionPopup") a.js-set-wip-limit i.fa.fa-ban | {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} - hr - ul.pop-over-list - li - a.js-close-list - i.fa.fa-arrow-right - i.fa.fa-archive - | {{_ 'archive-list'}} + unless currentUser.isWorker + hr + ul.pop-over-list + li + a.js-close-list + i.fa.fa-arrow-right + i.fa.fa-archive + | {{_ 'archive-list'}} hr ul.pop-over-list li @@ -114,7 +116,8 @@ template(name="listMorePopup") input.inline-input(type="text" readonly value="{{ rootUrl }}") | {{_ 'added'}} span.date(title=list.createdAt) {{ moment createdAt 'LLL' }} - a.js-delete {{_ 'delete'}} + unless currentUser.isWorker + a.js-delete {{_ 'delete'}} template(name="listDeletePopup") p {{_ "list-delete-pop"}} diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 07edade0..46dbd748 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -9,9 +9,10 @@ BlazeComponent.extendComponent({ canSeeAddCard() { const list = Template.currentData(); return ( - !list.getWipLimit('enabled') || - list.getWipLimit('soft') || - !this.reachedWipLimit() + (!list.getWipLimit('enabled') || + list.getWipLimit('soft') || + !this.reachedWipLimit()) && + !Meteor.user().isWorker() ); }, diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index e5adc0cd..19e32970 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -40,8 +40,9 @@ template(name="membersWidget") i.fa.fa-users | {{_ 'members'}} unless currentUser.isCommentOnly - a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right - i.board-header-btn-icon.fa.fa-cog + unless currentUser.isWorker + a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right + i.board-header-btn-icon.fa.fa-cog .board-widget-content each currentBoard.activeMembers @@ -164,11 +165,12 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list - li: a.js-custom-fields {{_ 'custom-fields'}} - li - a.js-open-archives - i.fa.fa-archive - | {{_ 'archived-items'}} + if isNotWorker + li: a.js-custom-fields {{_ 'custom-fields'}} + li + a.js-open-archives + i.fa.fa-archive + | {{_ 'archived-items'}} if currentUser.isBoardAdmin li a.js-change-board-color @@ -246,7 +248,7 @@ template(name="labelsWidget") .board-widget-content each currentBoard.labels a.card-label(class="card-label-{{color}}" - class="{{#if currentUser.isNotCommentOnly}}js-label{{/if}}") + class="{{#if currentUser.isNotCommentOnly}}{{#if currentUser.isNotWorker}}js-label{{/if}}{{/if}}") span.card-label-name +viewer = name @@ -275,11 +277,12 @@ template(name="memberPopup") a.js-change-role | {{_ 'change-permissions'}} span.quiet (#{memberType}) - li - if $eq currentUser._id userId - a.js-leave-member {{_ 'leave-board'}} - else if currentUser.isBoardAdmin - a.js-remove-member {{_ 'remove-from-board'}} + unless currentUser.isWorker + li + if $eq currentUser._id userId + a.js-leave-member {{_ 'leave-board'}} + else if currentUser.isBoardAdmin + a.js-remove-member {{_ 'remove-from-board'}} template(name="removeMemberPopup") p {{_ 'remove-member-pop' name=user.profile.fullname username=user.username boardTitle=board.title}} @@ -343,6 +346,12 @@ template(name="changePermissionsPopup") if isCommentOnly i.fa.fa-check span.sub-name {{_ 'comment-only-desc'}} + li + a(class="{{#if isLastAdmin}}disabled{{else}}js-set-worker{{/if}}") + | {{_ 'worker'}} + if isWorker + i.fa.fa-check + span.sub-name {{_ 'worker-desc'}} if isLastAdmin hr p.quiet.bottom {{_ 'last-admin-desc'}} diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 9d9c597a..e8f38b8c 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -161,10 +161,13 @@ Template.memberPopup.helpers({ const currentBoard = Boards.findOne(Session.get('currentBoard')); const commentOnly = currentBoard.hasCommentOnly(this.userId); const noComments = currentBoard.hasNoComments(this.userId); + const worker = currentBoard.hasWorker(this.userId); if (commentOnly) { return TAPi18n.__('comment-only').toLowerCase(); } else if (noComments) { return TAPi18n.__('no-comments').toLowerCase(); + } else if (worker) { + return TAPi18n.__('worker').toLowerCase(); } else { return TAPi18n.__(type).toLowerCase(); } @@ -267,6 +270,14 @@ Template.membersWidget.helpers({ const user = Meteor.user(); return user && user.isInvitedTo(Session.get('currentBoard')); }, + isWorker() { + const user = Meteor.user(); + if (user) { + return Meteor.call(Boards.hasWorker(user.memberId)); + } else { + return false; + } + }, }); Template.membersWidget.events({ @@ -644,7 +655,7 @@ BlazeComponent.extendComponent({ }).register('addMemberPopup'); Template.changePermissionsPopup.events({ - 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only'( + 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only, click .js-set-worker'( event, ) { const currentBoard = Boards.findOne(Session.get('currentBoard')); @@ -654,11 +665,13 @@ Template.changePermissionsPopup.events({ 'js-set-comment-only', ); const isNoComments = $(event.currentTarget).hasClass('js-set-no-comments'); + const isWorker = $(event.currentTarget).hasClass('js-set-worker'); currentBoard.setMemberPermission( memberId, isAdmin, isNoComments, isCommentOnly, + isWorker, ); Popup.back(1); }, @@ -675,7 +688,8 @@ Template.changePermissionsPopup.helpers({ return ( !currentBoard.hasAdmin(this.userId) && !currentBoard.hasNoComments(this.userId) && - !currentBoard.hasCommentOnly(this.userId) + !currentBoard.hasCommentOnly(this.userId) && + !currentBoard.hasWorker(this.userId) ); }, @@ -695,6 +709,13 @@ Template.changePermissionsPopup.helpers({ ); }, + isWorker() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return ( + !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) + ); + }, + isLastAdmin() { const currentBoard = Boards.findOne(Session.get('currentBoard')); return ( diff --git a/client/components/sidebar/sidebarArchives.jade b/client/components/sidebar/sidebarArchives.jade index 466d2cb0..56423ad7 100644 --- a/client/components/sidebar/sidebarArchives.jade +++ b/client/components/sidebar/sidebarArchives.jade @@ -2,54 +2,60 @@ template(name="archivesSidebar") if isArchiveReady.get +basicTabs(tabs=tabs) +tabContent(slug="cards") - p.quiet - a.js-restore-all-cards {{_ 'restore-all'}} - | - - a.js-delete-all-cards {{_ 'delete-all'}} + unless isWorker + p.quiet + a.js-restore-all-cards {{_ 'restore-all'}} + | - + a.js-delete-all-cards {{_ 'delete-all'}} each archivedCards .minicard-wrapper.js-minicard +minicard(this) if currentUser.isBoardMember - p.quiet - a.js-restore-card {{_ 'restore'}} - | - - a.js-delete-card {{_ 'delete'}} + unless isWorker + p.quiet + a.js-restore-card {{_ 'restore'}} + | - + a.js-delete-card {{_ 'delete'}} if cardIsInArchivedList p.quiet.small ({{_ 'warn-list-archived'}}) else p.no-items-message {{_ 'no-archived-cards'}} +tabContent(slug="lists") - p.quiet - a.js-restore-all-lists {{_ 'restore-all'}} - | - - a.js-delete-all-lists {{_ 'delete-all'}} + unless isWorker + p.quiet + a.js-restore-all-lists {{_ 'restore-all'}} + | - + a.js-delete-all-lists {{_ 'delete-all'}} ul.archived-lists each archivedLists li.archived-lists-item = title if currentUser.isBoardMember - p.quiet - a.js-restore-list {{_ 'restore'}} - | - - a.js-delete-list {{_ 'delete'}} + unless isWorker + p.quiet + a.js-restore-list {{_ 'restore'}} + | - + a.js-delete-list {{_ 'delete'}} else li.no-items-message {{_ 'no-archived-lists'}} +tabContent(slug="swimlanes") - p.quiet - a.js-restore-all-swimlanes {{_ 'restore-all'}} - | - - a.js-delete-all-swimlanes {{_ 'delete-all'}} + unless isWorker + p.quiet + a.js-restore-all-swimlanes {{_ 'restore-all'}} + | - + a.js-delete-all-swimlanes {{_ 'delete-all'}} ul.archived-lists each archivedSwimlanes li.archived-lists-item = title if currentUser.isBoardMember - p.quiet - a.js-restore-swimlane {{_ 'restore'}} - | - - a.js-delete-swimlane {{_ 'delete'}} + unless isWorker + p.quiet + a.js-restore-swimlane {{_ 'restore'}} + | - + a.js-delete-swimlane {{_ 'delete'}} else li.no-items-message {{_ 'no-archived-swimlanes'}} else diff --git a/client/components/sidebar/sidebarArchives.js b/client/components/sidebar/sidebarArchives.js index a4846561..75b694e9 100644 --- a/client/components/sidebar/sidebarArchives.js +++ b/client/components/sidebar/sidebarArchives.js @@ -139,3 +139,12 @@ BlazeComponent.extendComponent({ ]; }, }).register('archivesSidebar'); + +Template.archivesSidebar.helpers({ + isWorker() { + const currentBoard = Boards.findOne(Session.get('currentBoard')); + return ( + !currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId) + ); + }, +}); diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 1dc23c59..9b00d9e8 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -43,19 +43,20 @@ template(name="listsGroup") +addListForm template(name="addListForm") - .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'}}" - autocomplete="off" autofocus) - .edit-controls.clearfix - button.primary.confirm(type="submit") {{_ 'save'}} - unless currentBoard.isTemplatesBoard - unless currentBoard.isTemplateBoard - span.quiet - | {{_ 'or'}} - a.js-list-template {{_ 'template'}} - else - a.open-list-composer.js-open-inlined-form - i.fa.fa-plus - | {{_ 'add-list'}} + unless currentUser.isWorker + .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'}}" + autocomplete="off" autofocus) + .edit-controls.clearfix + button.primary.confirm(type="submit") {{_ 'save'}} + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-list-template {{_ 'template'}} + else + a.open-list-composer.js-open-inlined-form + i.fa.fa-plus + | {{_ 'add-list'}} diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 6568036f..a379113d 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -94,7 +94,8 @@ function initSortable(boardComponent, $listsDom) { return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); } @@ -131,6 +132,15 @@ function initSortable(boardComponent, $listsDom) { // MultiSelection.isActive() || !userIsMember(), ); } + + $listsDom.sortable( + 'option', + 'disabled', + // Disable drag-dropping when user is not member + Meteor.user().isWorker(), + // Not disable drag-dropping while in multi-selection mode + // MultiSelection.isActive() || !userIsMember(), + ); }); } @@ -282,7 +292,8 @@ Template.swimlane.helpers({ return ( Meteor.user() && Meteor.user().isBoardMember() && - !Meteor.user().isCommentOnly() + !Meteor.user().isCommentOnly() && + !Meteor.user().isWorker() ); }, }); diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index ff4a1ce6..7f2067ce 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -73,7 +73,8 @@ template(name="cardMemberPopup") p.quiet @{{ user.username }} ul.pop-over-list if currentUser.isNotCommentOnly - li: a.js-remove-member {{_ 'remove-member-from-card'}} + if currentUser.isNotWorker + li: a.js-remove-member {{_ 'remove-member-from-card'}} if $eq currentUser._id user._id with currentUser diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index aa567e91..9306d21d 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -39,12 +39,13 @@ template(name="memberMenuPopup") a.js-go-setting(href="{{pathFor 'setting'}}") i.fa.fa-lock | {{_ 'admin-panel'}} - hr - ul.pop-over-list - li - a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") - i.fa.fa-clone - | {{_ 'templates'}} + unless currentUser.isWorker + hr + ul.pop-over-list + li + a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") + i.fa.fa-clone + | {{_ 'templates'}} unless isSandstorm hr ul.pop-over-list @@ -109,13 +110,15 @@ template(name="changeSettingsPopup") | {{_ 'show-desktop-drag-handles'}} if showDesktopDragHandles i.fa.fa-check - li - label.bold - i.fa.fa-sort-numeric-asc - | {{_ 'show-cards-minimum-count'}} - input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") - input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") + unless currentUser.isWorker + li + label.bold + i.fa.fa-sort-numeric-asc + | {{_ 'show-cards-minimum-count'}} + input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") + input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") template(name="userDeletePopup") - p {{_ 'delete-user-confirm-popup'}} - button.js-confirm.negate.full(type="submit") {{_ 'delete'}} + unless currentUser.isWorker + p {{_ 'delete-user-confirm-popup'}} + button.js-confirm.negate.full(type="submit") {{_ 'delete'}} -- cgit v1.2.3-1-g7c22 From 8ce993921718f3e10c2daa5fabb145b939d789dd Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 6 Jan 2020 10:02:37 +0200 Subject: Fix: Unable to find Archive Card/List/Swimlane in board settings. Thanks to neobradley and xet7 ! Closes #2872 --- client/components/sidebar/sidebar.jade | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'client/components') diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 19e32970..8e84cd61 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -165,12 +165,11 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list - if isNotWorker - li: a.js-custom-fields {{_ 'custom-fields'}} - li - a.js-open-archives - i.fa.fa-archive - | {{_ 'archived-items'}} + li: a.js-custom-fields {{_ 'custom-fields'}} + li + a.js-open-archives + i.fa.fa-archive + | {{_ 'archived-items'}} if currentUser.isBoardAdmin li a.js-change-board-color -- cgit v1.2.3-1-g7c22 From ddce0ada094e6450be260b4cda21fdfa09ae0133 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 6 Jan 2020 11:01:38 +0200 Subject: Removed Custom HTML feature that does not work. Thanks to xet7 ! Closes #2218 --- client/components/settings/settingBody.jade | 6 ------ client/components/settings/settingBody.js | 8 -------- 2 files changed, 14 deletions(-) (limited to 'client/components') diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 877fe6e2..835a3b81 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -184,12 +184,6 @@ template(name='layoutSettings') .title {{_ 'custom-product-name'}} .form-group input.wekan-form-control#product-name(type="text", placeholder="" value="{{currentSetting.productName}}") - li.layout-form - .title {{_ 'add-custom-html-after-body-start'}} - textarea#customHTMLafterBodyStart.wekan-form-control= currentSetting.customHTMLafterBodyStart - li.layout-form - .title {{_ 'add-custom-html-before-body-end'}} - textarea#customHTMLbeforeBodyEnd.wekan-form-control= currentSetting.customHTMLbeforeBodyEnd li button.js-save-layout.primary {{_ 'save'}} diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index 4ff5aedd..319c066b 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -171,20 +171,12 @@ BlazeComponent.extendComponent({ const displayAuthenticationMethod = $('input[name=displayAuthenticationMethod]:checked').val() === 'true'; const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val(); - const customHTMLafterBodyStart = $('#customHTMLafterBodyStart') - .val() - .trim(); - const customHTMLbeforeBodyEnd = $('#customHTMLbeforeBodyEnd') - .val() - .trim(); try { Settings.update(Settings.findOne()._id, { $set: { productName, hideLogo: hideLogoChange, - customHTMLafterBodyStart, - customHTMLbeforeBodyEnd, displayAuthenticationMethod, defaultAuthenticationMethod, }, -- cgit v1.2.3-1-g7c22 From 5058233509e44916296e38fb8a6c5dd591c46d8b Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 6 Jan 2020 20:12:35 +0200 Subject: Wider sidebar. Thanks to vjrj ! Closes #2218 --- client/components/sidebar/sidebar.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/sidebar/sidebar.styl b/client/components/sidebar/sidebar.styl index 740186b5..c1047277 100644 --- a/client/components/sidebar/sidebar.styl +++ b/client/components/sidebar/sidebar.styl @@ -109,7 +109,7 @@ color: darken(white, 40%) .board-sidebar - width: 248px + width: 548px right: -@width transition: top .1s, right .1s, width .1s -- cgit v1.2.3-1-g7c22 From 3e2415631ffebeda6905323c3486bb85ce4b8bc7 Mon Sep 17 00:00:00 2001 From: tsia Date: Mon, 20 Jan 2020 11:23:08 +0100 Subject: Update header.styl --- client/components/main/header.styl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'client/components') diff --git a/client/components/main/header.styl b/client/components/main/header.styl index e3c7618d..f77c2aca 100644 --- a/client/components/main/header.styl +++ b/client/components/main/header.styl @@ -218,6 +218,9 @@ padding: 10px margin: -10px 0 -10px -10px +.announcement .viewer + display: inline-block + .announcement, .offline-warning width: 100% -- cgit v1.2.3-1-g7c22 From 4b56bbfe6dd1c16ac8d2cc8da91dc55cff60177e Mon Sep 17 00:00:00 2001 From: Peter Verraedt Date: Wed, 22 Jan 2020 12:09:26 +0100 Subject: Add rule action to move cards to other boards Fixes #1996 --- client/components/rules/actions/boardActions.jade | 37 +++++++++++++++-------- client/components/rules/actions/boardActions.js | 30 +++++++++++++++--- 2 files changed, 50 insertions(+), 17 deletions(-) (limited to 'client/components') diff --git a/client/components/rules/actions/boardActions.jade b/client/components/rules/actions/boardActions.jade index 6034184c..fda15062 100644 --- a/client/components/rules/actions/boardActions.jade +++ b/client/components/rules/actions/boardActions.jade @@ -1,29 +1,42 @@ template(name="boardActions") div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-move-card-to'}} div.trigger-dropdown select(id="move-gen-action") option(value="top") {{_'r-top-of'}} option(value="bottom") {{_'r-bottom-of'}} - div.trigger-text + div.trigger-text | {{_'r-its-list'}} div.trigger-button.js-add-gen-move-action.js-goto-rules i.fa.fa-plus div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-move-card-to'}} div.trigger-dropdown select(id="move-spec-action") option(value="top") {{_'r-top-of'}} option(value="bottom") {{_'r-bottom-of'}} - div.trigger-text - | {{_'r-list'}} + div.trigger-text + | {{_'r-the-board'}} + div.trigger-dropdown + select(id="board-id") + each boards + if $eq _id currentBoard._id + option(value="{{_id}}" selected) {{_ 'current'}} + else + option(value="{{_id}}") {{title}} + div.trigger-text + | {{_'r-in-list'}} div.trigger-dropdown input(id="listName",type=text,placeholder="{{_'r-name'}}") + div.trigger-text + | {{_'r-in-swimlane'}} + div.trigger-dropdown + input(id="swimlaneName",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-spec-move-action.js-goto-rules i.fa.fa-plus @@ -33,14 +46,14 @@ template(name="boardActions") select(id="arch-action") option(value="archive") {{_'r-archive'}} option(value="unarchive") {{_'r-unarchive'}} - div.trigger-text + div.trigger-text | {{_'r-card'}} div.trigger-button.js-add-arch-action.js-goto-rules i.fa.fa-plus div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-add-swimlane'}} div.trigger-dropdown input(id="swimlane-name",type=text,placeholder="{{_'r-name'}}") @@ -49,15 +62,15 @@ template(name="boardActions") div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-create-card'}} div.trigger-dropdown input(id="card-name",type=text,placeholder="{{_'r-name'}}") - div.trigger-text + div.trigger-text | {{_'r-in-list'}} div.trigger-dropdown input(id="list-name",type=text,placeholder="{{_'r-name'}}") - div.trigger-text + div.trigger-text | {{_'r-in-swimlane'}} div.trigger-dropdown input(id="swimlane-name2",type=text,placeholder="{{_'r-name'}}") @@ -65,8 +78,8 @@ template(name="boardActions") i.fa.fa-plus - - + + diff --git a/client/components/rules/actions/boardActions.js b/client/components/rules/actions/boardActions.js index 8568d2bf..c2f2375a 100644 --- a/client/components/rules/actions/boardActions.js +++ b/client/components/rules/actions/boardActions.js @@ -1,6 +1,22 @@ BlazeComponent.extendComponent({ onCreated() {}, + boards() { + const boards = Boards.find( + { + archived: false, + 'members.userId': Meteor.userId(), + _id: { + $ne: Meteor.user().getTemplatesBoardId(), + }, + }, + { + sort: ['title'], + }, + ); + return boards; + }, + events() { return [ { @@ -52,15 +68,18 @@ BlazeComponent.extendComponent({ const ruleName = this.data().ruleName.get(); const trigger = this.data().triggerVar.get(); const actionSelected = this.find('#move-spec-action').value; - const listTitle = this.find('#listName').value; + const swimlaneName = this.find('#swimlaneName').value; + const listName = this.find('#listName').value; const boardId = Session.get('currentBoard'); + const destBoardId = this.find('#board-id').value; const desc = Utils.getTriggerActionDesc(event, this); if (actionSelected === 'top') { const triggerId = Triggers.insert(trigger); const actionId = Actions.insert({ actionType: 'moveCardToTop', - listTitle, - boardId, + listName, + swimlaneName, + boardId: destBoardId, desc, }); Rules.insert({ @@ -74,8 +93,9 @@ BlazeComponent.extendComponent({ const triggerId = Triggers.insert(trigger); const actionId = Actions.insert({ actionType: 'moveCardToBottom', - listTitle, - boardId, + listName, + swimlaneName, + boardId: destBoardId, desc, }); Rules.insert({ -- cgit v1.2.3-1-g7c22 From 0b00a8095ce34c753e5edac86d4b62e8aaa1b1e0 Mon Sep 17 00:00:00 2001 From: dollybean Date: Tue, 4 Feb 2020 02:28:45 -0800 Subject: Customize of some card's functions --- client/components/boards/boardHeader.js | 1 + client/components/cards/cardDetails.jade | 243 ++++++++++++---------- client/components/cards/cardDetails.js | 87 ++++++++ client/components/main/editor.js | 4 + client/components/rules/actions/boardActions.jade | 37 ++-- client/components/rules/actions/boardActions.js | 30 +-- client/components/sidebar/sidebar.jade | 29 +++ client/components/sidebar/sidebar.js | 125 +++++++++++ 8 files changed, 392 insertions(+), 164 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index eea43bd3..8dea0f85 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -30,6 +30,7 @@ Template.boardMenuPopup.events({ 'click .js-outgoing-webhooks': Popup.open('outgoingWebhooks'), 'click .js-import-board': Popup.open('chooseBoardSource'), 'click .js-subtask-settings': Popup.open('boardSubtaskSettings'), + 'click .js-Date-settings': Popup.open('boardDateSettings') }); Template.boardMenuPopup.helpers({ diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index de4e102a..aec95486 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -8,10 +8,13 @@ template(name="cardDetails") 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 + input.inline-input(type="text" id="cardURL_copy" value="{{ absoluteUrl }}" autofocus="autofocus") + a.fa.fa-link.card-copy-button.js-copy-link 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 + a.fa.fa-link.card-copy-mobile-button h2.card-details-title.js-card-title( class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}") +viewer @@ -36,49 +39,41 @@ template(name="cardDetails") p.warning {{_ 'card-archived'}} .card-details-items - .card-details-item.card-details-item-received - h3 - i.fa.fa-sign-out - card-details-item-title {{_ 'card-received'}} - if getReceived - +cardReceivedDate - else - if canModifyCard - unless currentUser.isWorker - a.js-received-date {{_ 'add'}} - - .card-details-item.card-details-item-start - h3 - i.fa.fa-hourglass-start - card-details-item-title {{_ 'card-start'}} - if getStart - +cardStartDate - else - if canModifyCard - unless currentUser.isWorker - a.js-start-date {{_ 'add'}} - - .card-details-item.card-details-item-due - h3 - i.fa.fa-sign-in - card-details-item-title {{_ 'card-due'}} - if getDue - +cardDueDate - else - if canModifyCard - unless currentUser.isWorker - a.js-due-date {{_ 'add'}} - - .card-details-item.card-details-item-end - h3 - i.fa.fa-hourglass-end - card-details-item-title {{_ 'card-end'}} - if getEnd - +cardEndDate - else - if canModifyCard - unless currentUser.isWorker - a.js-end-date {{_ 'add'}} + if currentBoard.allowsReceivedDate + .card-details-item.card-details-item-received + h3 + i.fa.fa-sign-out + card-details-item-title {{_ 'card-received'}} + if getReceived + +cardReceivedDate + else + if canModifyCard + unless currentUser.isWorker + a.js-received-date {{_ 'add'}} + + if currentBoard.allowsStartDate + .card-details-item.card-details-item-start + h3 + i.fa.fa-hourglass-start + card-details-item-title {{_ 'card-start'}} + if getStart + +cardStartDate + else + if canModifyCard + unless currentUser.isWorker + a.js-start-date {{_ 'add'}} + + if currentBoard.allowsEndDate + .card-details-item.card-details-item-end + h3 + i.fa.fa-hourglass-end + card-details-item-title {{_ 'card-end'}} + if getEnd + +cardEndDate + else + if canModifyCard + unless currentUser.isWorker + a.js-end-date {{_ 'add'}} .card-details-items .card-details-item.card-details-item-members @@ -92,22 +87,34 @@ template(name="cardDetails") unless currentUser.isWorker 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 - i.fa.fa-user - card-details-item-title {{_ 'assignee'}} - each getAssignees - +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 - if currentUser.isWorker - unless assigneeSelected + if currentBoard.allowsDueDate + .card-details-item.card-details-item-due + h3 + i.fa.fa-sign-in + card-details-item-title {{_ 'card-due'}} + if getDue + +cardDueDate + else + if canModifyCard + unless currentUser.isWorker + a.card-label.add-label.js-due-date + i.fa.fa-plus + + if assigngeeSelected + .card-details-item.card-details-item-assignees + h3 + i.fa.fa-user + card-details-item-title {{_ 'assignee'}} + each getAssignees + +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 - + if currentUser.isWorker + 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 @@ -143,9 +150,9 @@ template(name="cardDetails") //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard unless currentUser.isWorker - h3 - i.fa.fa-align-left - card-details-item-title {{_ 'description'}} + //h3 + //- i.fa.fa-align-left + //- card-details-item-title {{_ 'description'}} +inlinedCardDescription(classNames="card-description js-card-description") +editor(autofocus=true) | {{getUnsavedValue 'cardDescription' _id getDescription}} @@ -153,16 +160,16 @@ template(name="cardDetails") button.primary(type="submit") {{_ 'save'}} a.fa.fa-times-thin.js-close-inlined-form else - a.js-open-inlined-form + a.description-item.add-description.js-open-inlined-form if getDescription +viewer = getDescription else - | {{_ 'edit'}} + | {{_ 'addmore-detail'}} if (hasUnsavedValue 'cardDescription' _id) p.quiet | {{_ 'unsaved-description'}} - a.js-open-inlined-form {{_ 'view-it'}} + a.description-item.add-description.js-open-inlined-form {{_ 'view-it'}} = ' - ' a.js-close-inlined-form {{_ 'discard'}} else if getDescription @@ -171,57 +178,59 @@ template(name="cardDetails") = getDescription .card-details-items - .card-details-item.card-details-item-name - h3 - i.fa.fa-shopping-cart - card-details-item-title {{_ 'requested-by'}} - if canModifyCard - unless currentUser.isWorker - +inlinedForm(classNames="js-card-details-requester") - +editCardRequesterForm - else - a.js-open-inlined-form - if getRequestedBy - +viewer - = getRequestedBy - else - | {{_ 'add'}} - else if getRequestedBy - +viewer - = getRequestedBy - - .card-details-item.card-details-item-name - h3 - i.fa.fa-user-plus - card-details-item-title {{_ 'assigned-by'}} - if canModifyCard - unless currentUser.isWorker - +inlinedForm(classNames="js-card-details-assigner") - +editCardAssignerForm - else - a.js-open-inlined-form - if getAssignedBy - +viewer - = getAssignedBy - else - | {{_ 'add'}} - else if getRequestedBy - +viewer - = getAssignedBy - - hr - +checklists(cardId = _id) - - if currentBoard.allowsSubtasks - hr - +subtasks(cardId = _id) - - hr - h3 - i.fa.fa-paperclip - | {{_ 'attachments'}} + if requestBySelected + .card-details-item.card-details-item-name + h3 + i.fa.fa-shopping-cart + card-details-item-title {{_ 'requested-by'}} + if canModifyCard + unless currentUser.isWorker + +inlinedForm(classNames="js-card-details-requester") + +editCardRequesterForm + else + a.js-open-inlined-form + if getRequestedBy + +viewer + = getRequestedBy + else + | {{_ 'add'}} + else if getRequestedBy + +viewer + = getRequestedBy - +attachmentsGalery + if assigneeBySelected + .card-details-item.card-details-item-name + h3 + i.fa.fa-user-plus + card-details-item-title {{_ 'assigned-by'}} + if canModifyCard + unless currentUser.isWorker + +inlinedForm(classNames="js-card-details-assigner") + +editCardAssignerForm + else + a.js-open-inlined-form + if getAssignedBy + +viewer + = getAssignedBy + else + | {{_ 'add'}} + else if getRequestedBy + +viewer + = getAssignedBy + + .card-checklist-attachmentGalerys + .card-checklist-attachmentGalery.card-checklists + +checklists(cardId = _id) + if currentBoard.allowsSubtasks + hr + +subtasks(cardId = _id) + + //- hr + //- h3 + //- i.fa.fa-paperclip + //- | {{_ 'attachments'}} + .card-checklist-attachmentGalery.card-attachmentGalery + +attachmentsGalery hr unless currentUser.isNoComments @@ -239,7 +248,13 @@ template(name="cardDetails") label.toggle-label(for="toggleButton") if currentUser.isBoardMember unless currentUser.isNoComments - +commentForm + if canModifyCard + +inlinedForm(autoclose=false classNames="js-new-comment-form") + +commentForm + else + +userAvatar(userId=currentUser._id) + a.comment-item.add-comment.js-open-inlined-form + | {{_ 'Write Comment'}} unless currentUser.isNoComments if isLoaded.get if isLinkedCard diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 07dcac44..231cbb10 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -279,6 +279,29 @@ BlazeComponent.extendComponent({ 'click .js-close-card-details'() { Utils.goBoardId(this.data().boardId); }, + 'click .js-copy-link'() { + StringToCopyElement = document.getElementById('cardURL_copy'); + StringToCopyElement.select(); + if (document.execCommand('copy')) { + StringToCopyElement.blur(); + } else { + document.getElementById('cardURL_copy').selectionStart = 0; + document.getElementById('cardURL_copy').selectionEnd = 999; + document.execCommand('copy'); + if (window.getSelection) { + if (window.getSelection().empty) { + // Chrome + window.getSelection().empty(); + } else if (window.getSelection().removeAllRanges) { + // Firefox + window.getSelection().removeAllRanges(); + } + } else if (document.selection) { + // IE? + document.selection.empty(); + } + } + }, 'click .js-open-card-details-menu': Popup.open('cardDetailsActions'), 'submit .js-card-description'(event) { event.preventDefault(); @@ -371,6 +394,54 @@ Template.cardDetails.helpers({ }); }, + receivedSelected() { + if (this.getReceived().length === 0) { + return false; + } else { + return true; + } + }, + + startSelected() { + if (this.getstart().length === 0) { + return false; + } else { + return true; + } + }, + + endSelected() { + if (this.getEnd().length === 0) { + return false; + } else { + return true; + } + }, + + dueSelected() { + if (this.getDue().length === 0) { + return false; + } else { + return true; + } + }, + + memberSelected() { + if (this.getMembers().length === 0) { + return false; + } else { + return true; + } + }, + + labelSelected() { + if (this.getLabels().length === 0) { + return false; + } else { + return true; + } + }, + assigneeSelected() { if (this.getAssignees().length === 0) { return false; @@ -379,6 +450,22 @@ Template.cardDetails.helpers({ } }, + requestBySelected() { + if (this.getRequestBy().length === 0) { + return false; + } else { + return true; + } + }, + + assigneeBySelected() { + if (this.getAssigneeBy().length === 0) { + return false; + } else { + return true; + } + }, + memberType() { const user = Users.findOne(this.userId); return user && user.isBoardAdmin() ? 'admin' : 'normal'; diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 39c03aa9..6c5b72b7 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -120,6 +120,10 @@ Template.editor.onRendered(() => { autosize($textarea); $textarea.escapeableTextComplete(mentions); }; +<<<<<<< HEAD +======= + +>>>>>>> ac37e360b69b799c12f03e1c158cfc0367d26e55 if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) { const isSmall = Utils.isMiniScreen(); const toolbar = isSmall diff --git a/client/components/rules/actions/boardActions.jade b/client/components/rules/actions/boardActions.jade index fda15062..6034184c 100644 --- a/client/components/rules/actions/boardActions.jade +++ b/client/components/rules/actions/boardActions.jade @@ -1,42 +1,29 @@ template(name="boardActions") div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-move-card-to'}} div.trigger-dropdown select(id="move-gen-action") option(value="top") {{_'r-top-of'}} option(value="bottom") {{_'r-bottom-of'}} - div.trigger-text + div.trigger-text | {{_'r-its-list'}} div.trigger-button.js-add-gen-move-action.js-goto-rules i.fa.fa-plus div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-move-card-to'}} div.trigger-dropdown select(id="move-spec-action") option(value="top") {{_'r-top-of'}} option(value="bottom") {{_'r-bottom-of'}} - div.trigger-text - | {{_'r-the-board'}} - div.trigger-dropdown - select(id="board-id") - each boards - if $eq _id currentBoard._id - option(value="{{_id}}" selected) {{_ 'current'}} - else - option(value="{{_id}}") {{title}} - div.trigger-text - | {{_'r-in-list'}} + div.trigger-text + | {{_'r-list'}} div.trigger-dropdown input(id="listName",type=text,placeholder="{{_'r-name'}}") - div.trigger-text - | {{_'r-in-swimlane'}} - div.trigger-dropdown - input(id="swimlaneName",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-spec-move-action.js-goto-rules i.fa.fa-plus @@ -46,14 +33,14 @@ template(name="boardActions") select(id="arch-action") option(value="archive") {{_'r-archive'}} option(value="unarchive") {{_'r-unarchive'}} - div.trigger-text + div.trigger-text | {{_'r-card'}} div.trigger-button.js-add-arch-action.js-goto-rules i.fa.fa-plus div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-add-swimlane'}} div.trigger-dropdown input(id="swimlane-name",type=text,placeholder="{{_'r-name'}}") @@ -62,15 +49,15 @@ template(name="boardActions") div.trigger-item div.trigger-content - div.trigger-text + div.trigger-text | {{_'r-create-card'}} div.trigger-dropdown input(id="card-name",type=text,placeholder="{{_'r-name'}}") - div.trigger-text + div.trigger-text | {{_'r-in-list'}} div.trigger-dropdown input(id="list-name",type=text,placeholder="{{_'r-name'}}") - div.trigger-text + div.trigger-text | {{_'r-in-swimlane'}} div.trigger-dropdown input(id="swimlane-name2",type=text,placeholder="{{_'r-name'}}") @@ -78,8 +65,8 @@ template(name="boardActions") i.fa.fa-plus - - + + diff --git a/client/components/rules/actions/boardActions.js b/client/components/rules/actions/boardActions.js index c2f2375a..8568d2bf 100644 --- a/client/components/rules/actions/boardActions.js +++ b/client/components/rules/actions/boardActions.js @@ -1,22 +1,6 @@ BlazeComponent.extendComponent({ onCreated() {}, - boards() { - const boards = Boards.find( - { - archived: false, - 'members.userId': Meteor.userId(), - _id: { - $ne: Meteor.user().getTemplatesBoardId(), - }, - }, - { - sort: ['title'], - }, - ); - return boards; - }, - events() { return [ { @@ -68,18 +52,15 @@ BlazeComponent.extendComponent({ const ruleName = this.data().ruleName.get(); const trigger = this.data().triggerVar.get(); const actionSelected = this.find('#move-spec-action').value; - const swimlaneName = this.find('#swimlaneName').value; - const listName = this.find('#listName').value; + const listTitle = this.find('#listName').value; const boardId = Session.get('currentBoard'); - const destBoardId = this.find('#board-id').value; const desc = Utils.getTriggerActionDesc(event, this); if (actionSelected === 'top') { const triggerId = Triggers.insert(trigger); const actionId = Actions.insert({ actionType: 'moveCardToTop', - listName, - swimlaneName, - boardId: destBoardId, + listTitle, + boardId, desc, }); Rules.insert({ @@ -93,9 +74,8 @@ BlazeComponent.extendComponent({ const triggerId = Triggers.insert(trigger); const actionId = Actions.insert({ actionType: 'moveCardToBottom', - listName, - swimlaneName, - boardId: destBoardId, + listTitle, + boardId, desc, }); Rules.insert({ diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 8e84cd61..fc5ff3a6 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -72,6 +72,25 @@ template(name="boardChangeColorPopup") if isSelected i.fa.fa-check +template(name="boardDateSettingsPopup") + form.board-Date-settings + div.check-div + a.flex.js-field-has-receiveddate(class="{{#if allowsReceivedDate}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsReceivedDate}}is-checked{{/if}}") + span {{_ 'show-receiveddate-field'}} + div.check-div + a.flex.js-field-has-startdate(class="{{#if allowsStartDate}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsStartDate}}is-checked{{/if}}") + span {{_ 'show-startdate-field'}} + div.check-div + a.flex.js-field-has-enddate(class="{{#if allowsEndDate}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsEndDate}}is-checked{{/if}}") + span {{_ 'show-enddate-field'}} + div.check-div + a.flex.js-field-has-duedate(class="{{#if allowsDueDate}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsDueDate}}is-checked{{/if}}") + span {{_ 'show-duedate-field'}} + template(name="boardSubtaskSettingsPopup") form.board-subtask-settings h3 {{_ 'show-parent-in-minicard'}} @@ -201,6 +220,10 @@ template(name="boardMenuPopup") a.js-subtask-settings i.fa.fa-sitemap | {{_ 'subtask-settings'}} + li + a.js-Date-settings + i.fa.fa-calendar + | {{_ 'Date-settings'}} unless currentBoard.isTemplatesBoard hr ul.pop-over-list @@ -238,6 +261,12 @@ template(name="boardMenuPopup") a.js-subtask-settings i.fa.fa-sitemap | {{_ 'subtask-settings'}} + hr + ul.pop-over-list + li + a.js-Date-settings + i.fa.fa-calendar + | {{_ 'Date-settings'}} template(name="labelsWidget") .board-widget.board-widget-labels diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index e8f38b8c..d909a8ae 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -208,6 +208,7 @@ Template.boardMenuPopup.events({ 'click .js-outgoing-webhooks': Popup.open('outgoingWebhooks'), 'click .js-import-board': Popup.open('chooseBoardSource'), 'click .js-subtask-settings': Popup.open('boardSubtaskSettings'), + 'click .js-Date-settings': Popup.open('boardDateSettings') }); Template.boardMenuPopup.helpers({ @@ -585,6 +586,130 @@ BlazeComponent.extendComponent({ }, }).register('boardSubtaskSettingsPopup'); +BlazeComponent.extendComponent({ + onCreated(){ + this.currentBoard = Boards.findOne(Session.get('currentBoard')); + }, + + allowsReceivedDate(){ + return this.currentBoard.allowsReceivedDate; + }, + + allowsStartDate(){ + return this.currentBoard.allowsStartDate; + }, + + allowsEndDate(){ + return this.currentBoard.allowsEndDate; + }, + + allowsDueDate(){ + return this.currentBoard.allowsDueDate; + }, + + isBoardSelected(){ + return this.currentBoard.dateSettingsDefaultBoardID + }, + + isNullBoardSelected() { + return ( + this.currentBoard.dateSettingsDefaultBoardId === null || + this.currentBoard.dateSettingsDefaultBoardId === undefined + ); + }, + + boards() { + return Boards.find( + { + archived: false, + 'members.userId': Meteor.userId(), + }, + { + sort: ['title'], + }, + ); + }, + + lists() { + return Lists.find( + { + boardId: this.currentBoard._id, + archived: false, + }, + { + sort: ['title'], + }, + ); + }, + + hasLists() { + return this.lists().count() > 0; + }, + + isListSelected() { + return this.currentBoard.dateSettingsDefaultBoardId === this.currentData()._id; + }, + + events() { + return [ + { + 'click .js-field-has-receiveddate'(evt) { + evt.preventDefault(); + this.currentBoard.allowsReceivedDate = !this.currentBoard.allowsReceivedDate; + this.currentBoard.setAllowsReceivedDate(this.currentBoard.allowsReceivedDate); + $(`.js-field-has-receiveddate ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsReceivedDate, + ); + $('.js-field-has-receiveddate').toggleClass( + CKCLS, + this.currentBoard.allowsReceivedDate, + ); + }, + 'click .js-field-has-startdate'(evt) { + evt.preventDefault(); + this.currentBoard.allowsStartDate = !this.currentBoard.allowsStartDate; + this.currentBoard.setAllowsStartDate(this.currentBoard.allowsStartDate); + $(`.js-field-has-startdate ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsStartDate, + ); + $('.js-field-has-startdate').toggleClass( + CKCLS, + this.currentBoard.allowsStartDate, + ); + }, + 'click .js-field-has-enddate'(evt) { + evt.preventDefault(); + this.currentBoard.allowsEndDate = !this.currentBoard.allowsEndDate; + this.currentBoard.setAllowsEndDate(this.currentBoard.allowsEndDate); + $(`.js-field-has-enddate ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsEndDate, + ); + $('.js-field-has-enddate').toggleClass( + CKCLS, + this.currentBoard.allowsEndDate, + ); + }, + 'click .js-field-has-duedate'(evt) { + evt.preventDefault(); + this.currentBoard.allowsDueDate = !this.currentBoard.allowsDueDate; + this.currentBoard.setAllowsDueDate(this.currentBoard.allowsDueDate); + $(`.js-field-has-duedate ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsDueDate, + ); + $('.js-field-has-duedate').toggleClass( + CKCLS, + this.currentBoard.allowsDueDate, + ); + }, + }, + ]; + }, +}).register('boardDateSettingsPopup'); + BlazeComponent.extendComponent({ onCreated() { this.error = new ReactiveVar(''); -- cgit v1.2.3-1-g7c22 From 13506945388be72b65df630eb71aee9b026c1472 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 5 Feb 2020 01:18:01 +0200 Subject: Add Board Card Settings to Show on Card only some of it's fields. Default WYSIWYG comment editor not enabled, use markdown instead. --- client/components/boards/boardHeader.js | 2 +- client/components/sidebar/sidebar.js | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 8ab117f6..9040ed83 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -30,7 +30,7 @@ Template.boardMenuPopup.events({ 'click .js-outgoing-webhooks': Popup.open('outgoingWebhooks'), 'click .js-import-board': Popup.open('chooseBoardSource'), 'click .js-subtask-settings': Popup.open('boardSubtaskSettings'), - 'click .js-card-settings': Popup.open('boardCardSettings') + 'click .js-card-settings': Popup.open('boardCardSettings'), }); Template.boardMenuPopup.helpers({ diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 678c16d2..4de7aa80 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -794,8 +794,11 @@ BlazeComponent.extendComponent({ }, 'click .js-field-has-assigned-by'(evt) { evt.preventDefault(); - this.currentBoard.allowsAssignedBy = !this.currentBoard.allowsAssignedBy; - this.currentBoard.setAllowsAssignedBy(this.currentBoard.allowsAssignedBy); + this.currentBoard.allowsAssignedBy = !this.currentBoard + .allowsAssignedBy; + this.currentBoard.setAllowsAssignedBy( + this.currentBoard.allowsAssignedBy, + ); $(`.js-field-has-assigned-by ${MCB}`).toggleClass( CKCLS, this.currentBoard.allowsAssignedBy, @@ -807,8 +810,11 @@ BlazeComponent.extendComponent({ }, 'click .js-field-has-requested-by'(evt) { evt.preventDefault(); - this.currentBoard.allowsRequestedBy = !this.currentBoard.allowsRequestedBy; - this.currentBoard.setAllowsRequestedBy(this.currentBoard.allowsRequestedBy); + this.currentBoard.allowsRequestedBy = !this.currentBoard + .allowsRequestedBy; + this.currentBoard.setAllowsRequestedBy( + this.currentBoard.allowsRequestedBy, + ); $(`.js-field-has-requested-by ${MCB}`).toggleClass( CKCLS, this.currentBoard.allowsRequestedBy, -- cgit v1.2.3-1-g7c22 From f22785dbcde42e425c9ead209ec224aef6e11c16 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 5 Feb 2020 19:47:08 +0200 Subject: - Fix adding comments. - Added some working layout changes from https://github.com/wekan/wekan/pull/2920. - Fixed Card Settings not working at Sandstorm. Thanks to 2020product xet7 ! Closes #2918, closes https://github.com/wekan/wekan/pull/2920 --- client/components/activities/activities.styl | 2 +- client/components/activities/comments.styl | 20 ++++++++++++++++++++ client/components/cards/cardDetails.jade | 25 +++++++++++-------------- client/components/sidebar/sidebar.jade | 12 ++++++------ 4 files changed, 38 insertions(+), 21 deletions(-) (limited to 'client/components') diff --git a/client/components/activities/activities.styl b/client/components/activities/activities.styl index 380e7b40..f3b1acdd 100644 --- a/client/components/activities/activities.styl +++ b/client/components/activities/activities.styl @@ -9,7 +9,7 @@ clear: both .activity - margin: 10px 0 + margin: 0.5px 0 display: flex .member diff --git a/client/components/activities/comments.styl b/client/components/activities/comments.styl index 22f9c482..ccf24b72 100644 --- a/client/components/activities/comments.styl +++ b/client/components/activities/comments.styl @@ -46,3 +46,23 @@ &:is-open cursor: auto + +.comment-item + background-color: #fff + border: 0 + box-shadow: 0 1px 2px rgba(0, 0, 0, .23) + color: #8c8c8c + height: 36px + margin: 4px 4px 6px 0 + width: 92% + + &:hover + background: darken(white, 12%) + + &.add-comment + display: flex + margin: 5px + + a + display: block + margin: auto diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 41ab8ca2..7a6ca7cf 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -9,7 +9,10 @@ template(name="cardDetails") if currentUser.isBoardMember a.fa.fa-navicon.card-details-menu.js-open-card-details-menu input.inline-input(type="hidden" id="cardURL_copy" value="{{ absoluteUrl }}") - a.fa.fa-link.card-copy-button.js-copy-link + a.fa.card-copy-button.js-copy-link( + class="fa-link" + title="{{_ 'copy-card-link-to-clipboard'}}" + ) if isMiniScreen a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details if currentUser.isBoardMember @@ -157,9 +160,9 @@ template(name="cardDetails") //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard unless currentUser.isWorker - //h3 - // i.fa.fa-align-left - // card-details-item-title {{_ 'description'}} + h3 + i.fa.fa-align-left + card-details-item-title {{_ 'description'}} +inlinedCardDescription(classNames="card-description js-card-description") +editor(autofocus=true) | {{getUnsavedValue 'cardDescription' _id getDescription}} @@ -167,16 +170,16 @@ template(name="cardDetails") button.primary(type="submit") {{_ 'save'}} a.fa.fa-times-thin.js-close-inlined-form else - a.description-item.add-description.js-open-inlined-form + a.js-open-inlined-form if getDescription +viewer = getDescription else - | {{_ 'addmore-detail'}} + | {{_ 'edit'}} if (hasUnsavedValue 'cardDescription' _id) p.quiet | {{_ 'unsaved-description'}} - a.description-item.add-description.js-open-inlined-form {{_ 'view-it'}} + a.js-open-inlined-form {{_ 'view-it'}} = ' - ' a.js-close-inlined-form {{_ 'discard'}} else if getDescription @@ -257,13 +260,7 @@ template(name="cardDetails") if currentBoard.allowsComments if currentUser.isBoardMember unless currentUser.isNoComments - if canModifyCard - +inlinedForm(autoclose=false classNames="js-new-comment-form") - +commentForm - else - +userAvatar(userId=currentUser._id) - a.comment-item.add-comment.js-open-inlined-form - | {{_ 'Write Comment'}} + +commentForm unless currentUser.isNoComments if isLoaded.get if isLinkedCard diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index fe0810a5..51b09d72 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -321,15 +321,15 @@ template(name="boardMenuPopup") hr ul.pop-over-list li - a.js-subtask-settings - i.fa.fa-sitemap - | {{_ 'subtask-settings'}} + a.js-card-settings + i.fa.fa-id-card-o + | {{_ 'card-settings'}} hr ul.pop-over-list li - a.js-Date-settings - i.fa.fa-calendar - | {{_ 'Date-settings'}} + a.js-subtask-settings + i.fa.fa-sitemap + | {{_ 'subtask-settings'}} template(name="labelsWidget") .board-widget.board-widget-labels -- cgit v1.2.3-1-g7c22 From bf78b093bad7d463ee325ad96e8b485264d4a3be Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 7 Feb 2020 03:16:16 +0200 Subject: Try to disable dragging Swimlanes/Lists/Cards/Checklists/Subtasks on small mobile smartphones webbrowsers, and hide drag handles on mobile web. Thanks to xet7 ! --- client/components/boards/boardBody.js | 10 ++++------ client/components/cards/cardDetails.js | 6 ++++++ client/components/cards/checklists.js | 3 +++ client/components/cards/minicard.jade | 4 ++-- client/components/lists/list.js | 25 +++++++++++++++++++++--- client/components/lists/listHeader.jade | 4 ++-- client/components/swimlanes/swimlanes.js | 33 ++++++++++++++++++++++---------- 7 files changed, 62 insertions(+), 23 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 55b8c0a1..e70a9f67 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -205,21 +205,19 @@ BlazeComponent.extendComponent({ } else { showDesktopDragHandles = false; } - if ( - Utils.isMiniScreen() || - (!Utils.isMiniScreen() && showDesktopDragHandles) - ) { + if (!Utils.isMiniScreen() && showDesktopDragHandles) { $swimlanesDom.sortable({ handle: '.js-swimlane-header-handle', }); - } else { + } else if (!Utils.isMiniScreen() && !showDesktopDragHandles) { $swimlanesDom.sortable({ handle: '.swimlane-header', }); } - // Disable drag-dropping if the current user is not a board member or is comment only + // Disable drag-dropping if the current user is not a board member or is miniscreen $swimlanesDom.sortable('option', 'disabled', !userIsMember()); + $swimlanesDom.sortable('option', 'disabled', Utils.isMiniScreen()); }); function userIsMember() { diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 92edec38..5fdc5579 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -253,6 +253,12 @@ BlazeComponent.extendComponent({ if ($subtasksDom.data('sortable')) { $subtasksDom.sortable('option', 'disabled', !userIsMember()); } + if ($checklistsDom.data('sortable')) { + $checklistsDom.sortable('option', 'disabled', Utils.isMiniScreen()); + } + if ($subtasksDom.data('sortable')) { + $subtasksDom.sortable('option', 'disabled', Utils.isMiniScreen()); + } }); }, diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 27d1b1c9..c88fdd82 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -60,6 +60,9 @@ BlazeComponent.extendComponent({ if ($itemsDom.data('sortable')) { $(self.itemsDom).sortable('option', 'disabled', !userIsMember()); } + if ($itemsDom.data('sortable')) { + $(self.itemsDom).sortable('option', 'disabled', Utils.isMiniScreen()); + } }); }, diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 7dd220ee..a895c0a3 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -4,8 +4,8 @@ template(name="minicard") class="{{#if isLinkedBoard}}linked-board{{/if}}" class="minicard-{{colorClass}}") if isMiniScreen - .handle - .fa.fa-arrows + //.handle + // .fa.fa-arrows unless isMiniScreen if showDesktopDragHandles .handle diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 0513f90f..8574caf7 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -133,14 +133,33 @@ BlazeComponent.extendComponent({ $cards.sortable({ handle: '.handle', }); - } else { + } else if (!Utils.isMiniScreen() && !showDesktopDragHandles) { $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()); + if ($cards.data('sortable')) { + $cards.sortable( + 'option', + 'disabled', + // Disable drag-dropping when user is not member/is miniscreen + !userIsMember(), + // Not disable drag-dropping while in multi-selection mode + // MultiSelection.isActive() || !userIsMember(), + ); + } + + if ($cards.data('sortable')) { + $cards.sortable( + 'option', + 'disabled', + // Disable drag-dropping when user is not member/is miniscreen + Utils.isMiniScreen(), + // Not disable drag-dropping while in multi-selection mode + // MultiSelection.isActive() || !userIsMember(), + ); + } }); // We want to re-run this function any time a card is added. diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index ec2c556f..182fee9e 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-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-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 diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index a379113d..b7a55ce6 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -115,7 +115,7 @@ function initSortable(boardComponent, $listsDom) { $listsDom.sortable({ handle: '.js-list-handle', }); - } else { + } else if (!Utils.isMiniScreen() && !showDesktopDragHandles) { $listsDom.sortable({ handle: '.js-list-header', }); @@ -126,21 +126,34 @@ function initSortable(boardComponent, $listsDom) { $listsDom.sortable( 'option', 'disabled', - // Disable drag-dropping when user is not member + // Disable drag-dropping when user is not member/is worker/is miniscreen !userIsMember(), // Not disable drag-dropping while in multi-selection mode // MultiSelection.isActive() || !userIsMember(), ); } - $listsDom.sortable( - 'option', - 'disabled', - // Disable drag-dropping when user is not member - Meteor.user().isWorker(), - // Not disable drag-dropping while in multi-selection mode - // MultiSelection.isActive() || !userIsMember(), - ); + if ($listDom.data('sortable')) { + $listsDom.sortable( + 'option', + 'disabled', + // Disable drag-dropping when user is not member/is worker/is miniscreen + Meteor.user().isWorker(), + // Not disable drag-dropping while in multi-selection mode + // MultiSelection.isActive() || !userIsMember(), + ); + } + + if ($listDom.data('sortable')) { + $listsDom.sortable( + 'option', + 'disabled', + // Disable drag-dropping when user is not member/is worker/is miniscreen + Utils.isMiniScreen(), + // Not disable drag-dropping while in multi-selection mode + // MultiSelection.isActive() || !userIsMember(), + ); + } }); } -- cgit v1.2.3-1-g7c22 From 2fce02afbced07c6ff2b05786f159701c8b559e9 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 7 Feb 2020 13:58:43 +0200 Subject: Add Feature: Card Settings/Show on card/Activities. Fix: When in Card Settings hiding Comments, only adding new comment is hidden, not old comments. Thanks to xet7 ! Closes #2925 --- client/components/activities/activities.jade | 388 ++++++++++++++------------- client/components/cards/cardDetails.jade | 17 +- client/components/sidebar/sidebar.jade | 6 + client/components/sidebar/sidebar.js | 16 ++ 4 files changed, 226 insertions(+), 201 deletions(-) (limited to 'client/components') diff --git a/client/components/activities/activities.jade b/client/components/activities/activities.jade index deb73072..d7eff885 100644 --- a/client/components/activities/activities.jade +++ b/client/components/activities/activities.jade @@ -8,234 +8,236 @@ template(name="activities") +cardActivities template(name="boardActivities") - each currentBoard.activities - .activity - +userAvatar(userId=user._id) - p.activity-desc - +memberName(user=user) + if currentBoard.allowsActivities + each currentBoard.activities + .activity + +userAvatar(userId=user._id) + p.activity-desc + +memberName(user=user) - if($eq activityType 'deleteAttachment') - | {{{_ 'activity-delete-attach' cardLink}}}. + if($eq activityType 'deleteAttachment') + | {{{_ 'activity-delete-attach' cardLink}}}. - if($eq activityType 'addAttachment') - | {{{_ 'activity-attached' attachmentLink cardLink}}}. + if($eq activityType 'addAttachment') + | {{{_ 'activity-attached' attachmentLink cardLink}}}. - if($eq activityType 'addBoardMember') - | {{{_ 'activity-added' memberLink boardLabel}}}. + if($eq activityType 'addBoardMember') + | {{{_ 'activity-added' memberLink boardLabel}}}. - if($eq activityType 'addComment') - | {{{_ 'activity-on' cardLink}}} - a.activity-comment(href="{{ card.absoluteUrl }}") - +viewer - = comment.text + if($eq activityType 'addComment') + | {{{_ 'activity-on' cardLink}}} + a.activity-comment(href="{{ card.absoluteUrl }}") + +viewer + = comment.text - if($eq activityType 'addChecklist') - | {{{_ 'activity-checklist-added' cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklist.title - if($eq activityType 'removeChecklist') - | {{{_ 'activity-checklist-removed' cardLink}}}. + if($eq activityType 'addChecklist') + | {{{_ 'activity-checklist-added' cardLink}}}. + .activity-checklist(href="{{ card.absoluteUrl }}") + +viewer + = checklist.title + if($eq activityType 'removeChecklist') + | {{{_ 'activity-checklist-removed' cardLink}}}. - if($eq activityType 'checkedItem') - | {{{_ 'activity-checked-item' checkItem checklist.title cardLink}}}. + if($eq activityType 'checkedItem') + | {{{_ 'activity-checked-item' checkItem checklist.title cardLink}}}. - if($eq activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item' checkItem checklist.title cardLink}}}. + if($eq activityType 'uncheckedItem') + | {{{_ 'activity-unchecked-item' checkItem checklist.title cardLink}}}. - if($eq activityType 'checklistCompleted') - | {{{_ 'activity-checklist-completed' checklist.title cardLink}}}. + if($eq activityType 'checklistCompleted') + | {{{_ 'activity-checklist-completed' checklist.title cardLink}}}. - if($eq activityType 'checklistUncompleted') - | {{{_ 'activity-checklist-uncompleted' checklist.title cardLink}}}. + if($eq activityType 'checklistUncompleted') + | {{{_ 'activity-checklist-uncompleted' checklist.title cardLink}}}. - if($eq activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklistItem.title - if($eq activityType 'removedChecklistItem') - | {{{_ 'activity-checklist-item-removed' checklist.title cardLink}}}. + if($eq activityType 'addChecklistItem') + | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. + .activity-checklist(href="{{ card.absoluteUrl }}") + +viewer + = checklistItem.title + if($eq activityType 'removedChecklistItem') + | {{{_ 'activity-checklist-item-removed' checklist.title cardLink}}}. - if($eq activityType 'archivedCard') - | {{{_ 'activity-archived' cardLink}}}. + if($eq activityType 'archivedCard') + | {{{_ 'activity-archived' cardLink}}}. - if($eq activityType 'archivedList') - | {{_ 'activity-archived' list.title}}. + if($eq activityType 'archivedList') + | {{_ 'activity-archived' list.title}}. - if($eq activityType 'archivedSwimlane') - | {{_ 'activity-archived' swimlane.title}}. + if($eq activityType 'archivedSwimlane') + | {{_ 'activity-archived' swimlane.title}}. - if($eq activityType 'createBoard') - | {{_ 'activity-created' boardLabel}}. + if($eq activityType 'createBoard') + | {{_ 'activity-created' boardLabel}}. - if($eq activityType 'createCard') - | {{{_ 'activity-added' cardLink boardLabel}}}. + if($eq activityType 'createCard') + | {{{_ 'activity-added' cardLink boardLabel}}}. - if($eq activityType 'createCustomField') - | {{_ 'activity-customfield-created' customField}}. + if($eq activityType 'createCustomField') + | {{_ 'activity-customfield-created' customField}}. - if($eq activityType 'createList') - | {{_ 'activity-added' list.title boardLabel}}. + if($eq activityType 'createList') + | {{_ 'activity-added' list.title boardLabel}}. - if($eq activityType 'createSwimlane') - | {{_ 'activity-added' swimlane.title boardLabel}}. + if($eq activityType 'createSwimlane') + | {{_ 'activity-added' swimlane.title boardLabel}}. - if($eq activityType 'removeList') - | {{_ 'activity-removed' title boardLabel}}. + if($eq activityType 'removeList') + | {{_ 'activity-removed' title boardLabel}}. - if($eq activityType 'importBoard') - | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. + if($eq activityType 'importBoard') + | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. - if($eq activityType 'importCard') - | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. + if($eq activityType 'importCard') + | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. - if($eq activityType 'importList') - | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. + if($eq activityType 'importList') + | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. - if($eq activityType 'joinMember') - if($eq user._id member._id) - | {{{_ 'activity-joined' cardLink}}}. - else - | {{{_ 'activity-added' memberLink cardLink}}}. + if($eq activityType 'joinMember') + if($eq user._id member._id) + | {{{_ 'activity-joined' cardLink}}}. + else + | {{{_ 'activity-added' memberLink cardLink}}}. - if($eq activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. + if($eq activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. - if($eq activityType 'moveCard') - | {{{_ 'activity-moved' cardLink oldList.title list.title}}}. + if($eq activityType 'moveCard') + | {{{_ 'activity-moved' cardLink oldList.title list.title}}}. - if($eq activityType 'removeBoardMember') - | {{{_ 'activity-excluded' memberLink boardLabel}}}. + if($eq activityType 'removeBoardMember') + | {{{_ 'activity-excluded' memberLink boardLabel}}}. - if($eq activityType 'restoredCard') - | {{{_ 'activity-sent' cardLink boardLabel}}}. + if($eq activityType 'restoredCard') + | {{{_ 'activity-sent' cardLink boardLabel}}}. - if($eq activityType 'addedLabel') - | {{{_ 'activity-added-label' lastLabel cardLink}}}. + if($eq activityType 'addedLabel') + | {{{_ 'activity-added-label' lastLabel cardLink}}}. - if($eq activityType 'removedLabel') - | {{{_ 'activity-removed-label' lastLabel cardLink}}}. + if($eq activityType 'removedLabel') + | {{{_ 'activity-removed-label' lastLabel cardLink}}}. - if($eq activityType 'setCustomField') - | {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}. + if($eq activityType 'setCustomField') + | {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}. - if($eq activityType 'unsetCustomField') - | {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}. + if($eq activityType 'unsetCustomField') + | {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}. - if($eq activityType 'unjoinMember') - if($eq user._id member._id) - | {{{_ 'activity-unjoined' cardLink}}}. - else - | {{{_ 'activity-removed' memberLink cardLink}}}. + if($eq activityType 'unjoinMember') + if($eq user._id member._id) + | {{{_ 'activity-unjoined' cardLink}}}. + else + | {{{_ 'activity-removed' memberLink cardLink}}}. - span(title=createdAt).activity-meta {{ moment createdAt }} + span(title=createdAt).activity-meta {{ moment createdAt }} template(name="cardActivities") - each currentCard.activities - .activity - +userAvatar(userId=user._id) - p.activity-desc - +memberName(user=user) - if($eq activityType 'createCard') - | {{_ 'activity-added' cardLabel listName}}. - if($eq activityType 'importCard') - | {{{_ 'activity-imported' cardLabel list.title sourceLink}}}. - if($eq activityType 'joinMember') - if($eq user._id member._id) - | {{_ 'activity-joined' cardLabel}}. - else - | {{{_ 'activity-added' memberLink cardLabel}}}. - if($eq activityType 'unjoinMember') - if($eq user._id member._id) - | {{_ 'activity-unjoined' cardLabel}}. - else - | {{{_ 'activity-removed' cardLabel memberLink}}}. - if($eq activityType 'archivedCard') - | {{_ 'activity-archived' cardLabel}}. - - if($eq activityType 'addedLabel') - | {{{_ 'activity-added-label-card' lastLabel }}}. - - if($eq activityType 'removedLabel') - | {{{_ 'activity-removed-label-card' lastLabel }}}. - - if($eq activityType 'removeChecklist') - | {{{_ 'activity-checklist-removed' cardLabel}}}. - - if($eq activityType 'checkedItem') - | {{{_ 'activity-checked-item-card' checkItem checklist.title }}}. - - if($eq activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item-card' checkItem checklist.title }}}. - - if($eq activityType 'checklistCompleted') - | {{{_ 'activity-checklist-completed-card' checklist.title }}}. - - if($eq activityType 'checklistUncompleted') - | {{{_ 'activity-checklist-uncompleted-card' checklist.title }}}. - - if($eq activityType 'restoredCard') - | {{_ 'activity-sent' cardLabel boardLabel}}. - if($eq activityType 'moveCard') - | {{_ 'activity-moved' cardLabel oldList.title list.title}}. - - if($eq activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. - - if($eq activityType 'addAttachment') - | {{{_ 'activity-attached' attachmentLink cardLabel}}}. - if attachment.isImage - img.attachment-image-preview(src=attachment.url) - if($eq activityType 'deleteAttachment') - | {{{_ 'activity-delete-attach' cardLabel}}}. - if($eq activityType 'removedChecklist') - | {{{_ 'activity-checklist-removed' cardLabel}}}. - if($eq activityType 'addChecklist') - | {{{_ 'activity-checklist-added' cardLabel}}}. - .activity-checklist - +viewer - = checklist.title - if($eq activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklistItem.title - - if(currentData.timeKey) - | {{{_ activityType }}} - = ' ' - i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} - if (currentData.timeOldValue) - = ' ' - | {{{_ "previous_as" }}} - = ' ' - i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} - = ' @' - else if(currentData.timeValue) - | {{{_ activityType currentData.timeValue}}} - - - if($eq activityType 'deleteComment') - | {{{_ 'activity-deleteComment' currentData.commentId}}}. - if($eq activityType 'editComment') - | {{{_ 'activity-editComment' currentData.commentId}}}. - if($eq activityType 'addComment') - +inlinedForm(classNames='js-edit-comment') - +editor(autofocus=true) - = comment.text - .edit-controls - button.primary(type="submit") {{_ 'edit'}} - else - .activity-comment + if currentBoard.allowsComments + each currentCard.activities + .activity + +userAvatar(userId=user._id) + p.activity-desc + +memberName(user=user) + if($eq activityType 'createCard') + | {{_ 'activity-added' cardLabel listName}}. + if($eq activityType 'importCard') + | {{{_ 'activity-imported' cardLabel list.title sourceLink}}}. + if($eq activityType 'joinMember') + if($eq user._id member._id) + | {{_ 'activity-joined' cardLabel}}. + else + | {{{_ 'activity-added' memberLink cardLabel}}}. + if($eq activityType 'unjoinMember') + if($eq user._id member._id) + | {{_ 'activity-unjoined' cardLabel}}. + else + | {{{_ 'activity-removed' cardLabel memberLink}}}. + if($eq activityType 'archivedCard') + | {{_ 'activity-archived' cardLabel}}. + + if($eq activityType 'addedLabel') + | {{{_ 'activity-added-label-card' lastLabel }}}. + + if($eq activityType 'removedLabel') + | {{{_ 'activity-removed-label-card' lastLabel }}}. + + if($eq activityType 'removeChecklist') + | {{{_ 'activity-checklist-removed' cardLabel}}}. + + if($eq activityType 'checkedItem') + | {{{_ 'activity-checked-item-card' checkItem checklist.title }}}. + + if($eq activityType 'uncheckedItem') + | {{{_ 'activity-unchecked-item-card' checkItem checklist.title }}}. + + if($eq activityType 'checklistCompleted') + | {{{_ 'activity-checklist-completed-card' checklist.title }}}. + + if($eq activityType 'checklistUncompleted') + | {{{_ 'activity-checklist-uncompleted-card' checklist.title }}}. + + if($eq activityType 'restoredCard') + | {{_ 'activity-sent' cardLabel boardLabel}}. + if($eq activityType 'moveCard') + | {{_ 'activity-moved' cardLabel oldList.title list.title}}. + + if($eq activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. + + if($eq activityType 'addAttachment') + | {{{_ 'activity-attached' attachmentLink cardLabel}}}. + if attachment.isImage + img.attachment-image-preview(src=attachment.url) + if($eq activityType 'deleteAttachment') + | {{{_ 'activity-delete-attach' cardLabel}}}. + if($eq activityType 'removedChecklist') + | {{{_ 'activity-checklist-removed' cardLabel}}}. + if($eq activityType 'addChecklist') + | {{{_ 'activity-checklist-added' cardLabel}}}. + .activity-checklist +viewer + = checklist.title + if($eq activityType 'addChecklistItem') + | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. + .activity-checklist(href="{{ card.absoluteUrl }}") + +viewer + = checklistItem.title + + if(currentData.timeKey) + | {{{_ activityType }}} + = ' ' + i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} + if (currentData.timeOldValue) + = ' ' + | {{{_ "previous_as" }}} + = ' ' + i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} + = ' @' + else if(currentData.timeValue) + | {{{_ activityType currentData.timeValue}}} + + + if($eq activityType 'deleteComment') + | {{{_ 'activity-deleteComment' currentData.commentId}}}. + if($eq activityType 'editComment') + | {{{_ 'activity-editComment' currentData.commentId}}}. + if($eq activityType 'addComment') + +inlinedForm(classNames='js-edit-comment') + +editor(autofocus=true) = comment.text - span(title=createdAt).activity-meta {{ moment createdAt }} - if ($eq currentUser._id comment.userId) - = ' - ' - a.js-open-inlined-form {{_ "edit"}} - = ' - ' - a.js-delete-comment {{_ "delete"}} + .edit-controls + button.primary(type="submit") {{_ 'edit'}} + else + .activity-comment + +viewer + = comment.text + span(title=createdAt).activity-meta {{ moment createdAt }} + if ($eq currentUser._id comment.userId) + = ' - ' + a.js-open-inlined-form {{_ "edit"}} + = ' - ' + a.js-delete-comment {{_ "delete"}} - else - span(title=createdAt).activity-meta {{ moment createdAt }} + else + span(title=createdAt).activity-meta {{ moment createdAt }} diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 7a6ca7cf..cb1f375e 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -261,14 +261,15 @@ template(name="cardDetails") if currentUser.isBoardMember unless currentUser.isNoComments +commentForm - unless currentUser.isNoComments - if isLoaded.get - if isLinkedCard - +activities(card=this mode="linkedcard") - else if isLinkedBoard - +activities(card=this mode="linkedboard") - else - +activities(card=this mode="card") + if currentBoard.allowsActivities + unless currentUser.isNoComments + if isLoaded.get + if isLinkedCard + +activities(card=this mode="linkedcard") + else if isLinkedBoard + +activities(card=this mode="linkedboard") + else + +activities(card=this mode="card") template(name="editCardTitleForm") textarea.js-edit-card-title(rows='1' autofocus dir="auto") diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 51b09d72..ae52dc4c 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -153,6 +153,12 @@ template(name="boardCardSettingsPopup") span i.fa.fa-comment-o | {{_ 'comment'}} + div.check-div + a.flex.js-field-has-comments(class="{{#if allowsActivities}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsActivities}}is-checked{{/if}}") + span + i.fa.fa-history + | {{_ 'activities'}} template(name="boardSubtaskSettingsPopup") form.board-subtask-settings diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 4de7aa80..c3c00b08 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -882,6 +882,22 @@ BlazeComponent.extendComponent({ this.currentBoard.allowsComments, ); }, + 'click .js-field-has-activities'(evt) { + evt.preventDefault(); + this.currentBoard.allowsActivities = !this.currentBoard + .allowsActivities; + this.currentBoard.setAllowsActivities( + this.currentBoard.allowsActivities, + ); + $(`.js-field-has-activities ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsActivities, + ); + $('.js-field-has-activities').toggleClass( + CKCLS, + this.currentBoard.allowsActivities, + ); + }, }, ]; }, -- cgit v1.2.3-1-g7c22 From 2a54218f3f68547032bd53a04a968b233be21e15 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 10 Feb 2020 17:25:27 +0200 Subject: Remove hiding comments and activities. --- client/components/activities/activities.jade | 388 +++++++++++++-------------- client/components/cards/cardDetails.jade | 17 +- client/components/sidebar/sidebar.jade | 24 +- 3 files changed, 213 insertions(+), 216 deletions(-) (limited to 'client/components') diff --git a/client/components/activities/activities.jade b/client/components/activities/activities.jade index d7eff885..8ecbdee8 100644 --- a/client/components/activities/activities.jade +++ b/client/components/activities/activities.jade @@ -8,236 +8,234 @@ template(name="activities") +cardActivities template(name="boardActivities") - if currentBoard.allowsActivities - each currentBoard.activities - .activity - +userAvatar(userId=user._id) - p.activity-desc - +memberName(user=user) + each currentBoard.activities + .activity + +userAvatar(userId=user._id) + p.activity-desc + +memberName(user=user) - if($eq activityType 'deleteAttachment') - | {{{_ 'activity-delete-attach' cardLink}}}. + if($eq activityType 'deleteAttachment') + | {{{_ 'activity-delete-attach' cardLink}}}. - if($eq activityType 'addAttachment') - | {{{_ 'activity-attached' attachmentLink cardLink}}}. + if($eq activityType 'addAttachment') + | {{{_ 'activity-attached' attachmentLink cardLink}}}. - if($eq activityType 'addBoardMember') - | {{{_ 'activity-added' memberLink boardLabel}}}. + if($eq activityType 'addBoardMember') + | {{{_ 'activity-added' memberLink boardLabel}}}. - if($eq activityType 'addComment') - | {{{_ 'activity-on' cardLink}}} - a.activity-comment(href="{{ card.absoluteUrl }}") - +viewer - = comment.text + if($eq activityType 'addComment') + | {{{_ 'activity-on' cardLink}}} + a.activity-comment(href="{{ card.absoluteUrl }}") + +viewer + = comment.text - if($eq activityType 'addChecklist') - | {{{_ 'activity-checklist-added' cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklist.title - if($eq activityType 'removeChecklist') - | {{{_ 'activity-checklist-removed' cardLink}}}. + if($eq activityType 'addChecklist') + | {{{_ 'activity-checklist-added' cardLink}}}. + .activity-checklist(href="{{ card.absoluteUrl }}") + +viewer + = checklist.title + if($eq activityType 'removeChecklist') + | {{{_ 'activity-checklist-removed' cardLink}}}. - if($eq activityType 'checkedItem') - | {{{_ 'activity-checked-item' checkItem checklist.title cardLink}}}. + if($eq activityType 'checkedItem') + | {{{_ 'activity-checked-item' checkItem checklist.title cardLink}}}. - if($eq activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item' checkItem checklist.title cardLink}}}. + if($eq activityType 'uncheckedItem') + | {{{_ 'activity-unchecked-item' checkItem checklist.title cardLink}}}. - if($eq activityType 'checklistCompleted') - | {{{_ 'activity-checklist-completed' checklist.title cardLink}}}. + if($eq activityType 'checklistCompleted') + | {{{_ 'activity-checklist-completed' checklist.title cardLink}}}. - if($eq activityType 'checklistUncompleted') - | {{{_ 'activity-checklist-uncompleted' checklist.title cardLink}}}. + if($eq activityType 'checklistUncompleted') + | {{{_ 'activity-checklist-uncompleted' checklist.title cardLink}}}. - if($eq activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklistItem.title - if($eq activityType 'removedChecklistItem') - | {{{_ 'activity-checklist-item-removed' checklist.title cardLink}}}. + if($eq activityType 'addChecklistItem') + | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. + .activity-checklist(href="{{ card.absoluteUrl }}") + +viewer + = checklistItem.title + if($eq activityType 'removedChecklistItem') + | {{{_ 'activity-checklist-item-removed' checklist.title cardLink}}}. - if($eq activityType 'archivedCard') - | {{{_ 'activity-archived' cardLink}}}. + if($eq activityType 'archivedCard') + | {{{_ 'activity-archived' cardLink}}}. - if($eq activityType 'archivedList') - | {{_ 'activity-archived' list.title}}. + if($eq activityType 'archivedList') + | {{_ 'activity-archived' list.title}}. - if($eq activityType 'archivedSwimlane') - | {{_ 'activity-archived' swimlane.title}}. + if($eq activityType 'archivedSwimlane') + | {{_ 'activity-archived' swimlane.title}}. - if($eq activityType 'createBoard') - | {{_ 'activity-created' boardLabel}}. + if($eq activityType 'createBoard') + | {{_ 'activity-created' boardLabel}}. - if($eq activityType 'createCard') - | {{{_ 'activity-added' cardLink boardLabel}}}. + if($eq activityType 'createCard') + | {{{_ 'activity-added' cardLink boardLabel}}}. - if($eq activityType 'createCustomField') - | {{_ 'activity-customfield-created' customField}}. + if($eq activityType 'createCustomField') + | {{_ 'activity-customfield-created' customField}}. - if($eq activityType 'createList') - | {{_ 'activity-added' list.title boardLabel}}. + if($eq activityType 'createList') + | {{_ 'activity-added' list.title boardLabel}}. - if($eq activityType 'createSwimlane') - | {{_ 'activity-added' swimlane.title boardLabel}}. + if($eq activityType 'createSwimlane') + | {{_ 'activity-added' swimlane.title boardLabel}}. - if($eq activityType 'removeList') - | {{_ 'activity-removed' title boardLabel}}. + if($eq activityType 'removeList') + | {{_ 'activity-removed' title boardLabel}}. - if($eq activityType 'importBoard') - | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. + if($eq activityType 'importBoard') + | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. - if($eq activityType 'importCard') - | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. + if($eq activityType 'importCard') + | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. - if($eq activityType 'importList') - | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. + if($eq activityType 'importList') + | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. - if($eq activityType 'joinMember') - if($eq user._id member._id) - | {{{_ 'activity-joined' cardLink}}}. - else - | {{{_ 'activity-added' memberLink cardLink}}}. + if($eq activityType 'joinMember') + if($eq user._id member._id) + | {{{_ 'activity-joined' cardLink}}}. + else + | {{{_ 'activity-added' memberLink cardLink}}}. - if($eq activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. + if($eq activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. - if($eq activityType 'moveCard') - | {{{_ 'activity-moved' cardLink oldList.title list.title}}}. + if($eq activityType 'moveCard') + | {{{_ 'activity-moved' cardLink oldList.title list.title}}}. - if($eq activityType 'removeBoardMember') - | {{{_ 'activity-excluded' memberLink boardLabel}}}. + if($eq activityType 'removeBoardMember') + | {{{_ 'activity-excluded' memberLink boardLabel}}}. - if($eq activityType 'restoredCard') - | {{{_ 'activity-sent' cardLink boardLabel}}}. + if($eq activityType 'restoredCard') + | {{{_ 'activity-sent' cardLink boardLabel}}}. - if($eq activityType 'addedLabel') - | {{{_ 'activity-added-label' lastLabel cardLink}}}. + if($eq activityType 'addedLabel') + | {{{_ 'activity-added-label' lastLabel cardLink}}}. - if($eq activityType 'removedLabel') - | {{{_ 'activity-removed-label' lastLabel cardLink}}}. + if($eq activityType 'removedLabel') + | {{{_ 'activity-removed-label' lastLabel cardLink}}}. - if($eq activityType 'setCustomField') - | {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}. + if($eq activityType 'setCustomField') + | {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}. - if($eq activityType 'unsetCustomField') - | {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}. + if($eq activityType 'unsetCustomField') + | {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}. - if($eq activityType 'unjoinMember') - if($eq user._id member._id) - | {{{_ 'activity-unjoined' cardLink}}}. - else - | {{{_ 'activity-removed' memberLink cardLink}}}. + if($eq activityType 'unjoinMember') + if($eq user._id member._id) + | {{{_ 'activity-unjoined' cardLink}}}. + else + | {{{_ 'activity-removed' memberLink cardLink}}}. - span(title=createdAt).activity-meta {{ moment createdAt }} + span(title=createdAt).activity-meta {{ moment createdAt }} template(name="cardActivities") - if currentBoard.allowsComments - each currentCard.activities - .activity - +userAvatar(userId=user._id) - p.activity-desc - +memberName(user=user) - if($eq activityType 'createCard') - | {{_ 'activity-added' cardLabel listName}}. - if($eq activityType 'importCard') - | {{{_ 'activity-imported' cardLabel list.title sourceLink}}}. - if($eq activityType 'joinMember') - if($eq user._id member._id) - | {{_ 'activity-joined' cardLabel}}. - else - | {{{_ 'activity-added' memberLink cardLabel}}}. - if($eq activityType 'unjoinMember') - if($eq user._id member._id) - | {{_ 'activity-unjoined' cardLabel}}. - else - | {{{_ 'activity-removed' cardLabel memberLink}}}. - if($eq activityType 'archivedCard') - | {{_ 'activity-archived' cardLabel}}. - - if($eq activityType 'addedLabel') - | {{{_ 'activity-added-label-card' lastLabel }}}. - - if($eq activityType 'removedLabel') - | {{{_ 'activity-removed-label-card' lastLabel }}}. - - if($eq activityType 'removeChecklist') - | {{{_ 'activity-checklist-removed' cardLabel}}}. - - if($eq activityType 'checkedItem') - | {{{_ 'activity-checked-item-card' checkItem checklist.title }}}. - - if($eq activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item-card' checkItem checklist.title }}}. - - if($eq activityType 'checklistCompleted') - | {{{_ 'activity-checklist-completed-card' checklist.title }}}. - - if($eq activityType 'checklistUncompleted') - | {{{_ 'activity-checklist-uncompleted-card' checklist.title }}}. - - if($eq activityType 'restoredCard') - | {{_ 'activity-sent' cardLabel boardLabel}}. - if($eq activityType 'moveCard') - | {{_ 'activity-moved' cardLabel oldList.title list.title}}. - - if($eq activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. - - if($eq activityType 'addAttachment') - | {{{_ 'activity-attached' attachmentLink cardLabel}}}. - if attachment.isImage - img.attachment-image-preview(src=attachment.url) - if($eq activityType 'deleteAttachment') - | {{{_ 'activity-delete-attach' cardLabel}}}. - if($eq activityType 'removedChecklist') - | {{{_ 'activity-checklist-removed' cardLabel}}}. - if($eq activityType 'addChecklist') - | {{{_ 'activity-checklist-added' cardLabel}}}. - .activity-checklist - +viewer - = checklist.title - if($eq activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") + each currentCard.activities + .activity + +userAvatar(userId=user._id) + p.activity-desc + +memberName(user=user) + if($eq activityType 'createCard') + | {{_ 'activity-added' cardLabel listName}}. + if($eq activityType 'importCard') + | {{{_ 'activity-imported' cardLabel list.title sourceLink}}}. + if($eq activityType 'joinMember') + if($eq user._id member._id) + | {{_ 'activity-joined' cardLabel}}. + else + | {{{_ 'activity-added' memberLink cardLabel}}}. + if($eq activityType 'unjoinMember') + if($eq user._id member._id) + | {{_ 'activity-unjoined' cardLabel}}. + else + | {{{_ 'activity-removed' cardLabel memberLink}}}. + if($eq activityType 'archivedCard') + | {{_ 'activity-archived' cardLabel}}. + + if($eq activityType 'addedLabel') + | {{{_ 'activity-added-label-card' lastLabel }}}. + + if($eq activityType 'removedLabel') + | {{{_ 'activity-removed-label-card' lastLabel }}}. + + if($eq activityType 'removeChecklist') + | {{{_ 'activity-checklist-removed' cardLabel}}}. + + if($eq activityType 'checkedItem') + | {{{_ 'activity-checked-item-card' checkItem checklist.title }}}. + + if($eq activityType 'uncheckedItem') + | {{{_ 'activity-unchecked-item-card' checkItem checklist.title }}}. + + if($eq activityType 'checklistCompleted') + | {{{_ 'activity-checklist-completed-card' checklist.title }}}. + + if($eq activityType 'checklistUncompleted') + | {{{_ 'activity-checklist-uncompleted-card' checklist.title }}}. + + if($eq activityType 'restoredCard') + | {{_ 'activity-sent' cardLabel boardLabel}}. + if($eq activityType 'moveCard') + | {{_ 'activity-moved' cardLabel oldList.title list.title}}. + + if($eq activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. + + if($eq activityType 'addAttachment') + | {{{_ 'activity-attached' attachmentLink cardLabel}}}. + if attachment.isImage + img.attachment-image-preview(src=attachment.url) + if($eq activityType 'deleteAttachment') + | {{{_ 'activity-delete-attach' cardLabel}}}. + if($eq activityType 'removedChecklist') + | {{{_ 'activity-checklist-removed' cardLabel}}}. + if($eq activityType 'addChecklist') + | {{{_ 'activity-checklist-added' cardLabel}}}. + .activity-checklist + +viewer + = checklist.title + if($eq activityType 'addChecklistItem') + | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. + .activity-checklist(href="{{ card.absoluteUrl }}") + +viewer + = checklistItem.title + + if(currentData.timeKey) + | {{{_ activityType }}} + = ' ' + i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} + if (currentData.timeOldValue) + = ' ' + | {{{_ "previous_as" }}} + = ' ' + i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} + = ' @' + else if(currentData.timeValue) + | {{{_ activityType currentData.timeValue}}} + + + if($eq activityType 'deleteComment') + | {{{_ 'activity-deleteComment' currentData.commentId}}}. + if($eq activityType 'editComment') + | {{{_ 'activity-editComment' currentData.commentId}}}. + if($eq activityType 'addComment') + +inlinedForm(classNames='js-edit-comment') + +editor(autofocus=true) + = comment.text + .edit-controls + button.primary(type="submit") {{_ 'edit'}} + else + .activity-comment +viewer - = checklistItem.title - - if(currentData.timeKey) - | {{{_ activityType }}} - = ' ' - i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} - if (currentData.timeOldValue) - = ' ' - | {{{_ "previous_as" }}} - = ' ' - i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} - = ' @' - else if(currentData.timeValue) - | {{{_ activityType currentData.timeValue}}} - - - if($eq activityType 'deleteComment') - | {{{_ 'activity-deleteComment' currentData.commentId}}}. - if($eq activityType 'editComment') - | {{{_ 'activity-editComment' currentData.commentId}}}. - if($eq activityType 'addComment') - +inlinedForm(classNames='js-edit-comment') - +editor(autofocus=true) = comment.text - .edit-controls - button.primary(type="submit") {{_ 'edit'}} - else - .activity-comment - +viewer - = comment.text - span(title=createdAt).activity-meta {{ moment createdAt }} - if ($eq currentUser._id comment.userId) - = ' - ' - a.js-open-inlined-form {{_ "edit"}} - = ' - ' - a.js-delete-comment {{_ "delete"}} - - else span(title=createdAt).activity-meta {{ moment createdAt }} + if ($eq currentUser._id comment.userId) + = ' - ' + a.js-open-inlined-form {{_ "edit"}} + = ' - ' + a.js-delete-comment {{_ "delete"}} + + else + span(title=createdAt).activity-meta {{ moment createdAt }} diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index cb1f375e..7a6ca7cf 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -261,15 +261,14 @@ template(name="cardDetails") if currentUser.isBoardMember unless currentUser.isNoComments +commentForm - if currentBoard.allowsActivities - unless currentUser.isNoComments - if isLoaded.get - if isLinkedCard - +activities(card=this mode="linkedcard") - else if isLinkedBoard - +activities(card=this mode="linkedboard") - else - +activities(card=this mode="card") + unless currentUser.isNoComments + if isLoaded.get + if isLinkedCard + +activities(card=this mode="linkedcard") + else if isLinkedBoard + +activities(card=this mode="linkedboard") + else + +activities(card=this mode="card") template(name="editCardTitleForm") textarea.js-edit-card-title(rows='1' autofocus dir="auto") diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index ae52dc4c..07da476f 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -147,18 +147,18 @@ template(name="boardCardSettingsPopup") span i.fa.fa-paperclip | {{_ 'attachments'}} - div.check-div - a.flex.js-field-has-comments(class="{{#if allowsComments}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsComments}}is-checked{{/if}}") - span - i.fa.fa-comment-o - | {{_ 'comment'}} - div.check-div - a.flex.js-field-has-comments(class="{{#if allowsActivities}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsActivities}}is-checked{{/if}}") - span - i.fa.fa-history - | {{_ 'activities'}} + //div.check-div + // a.flex.js-field-has-comments(class="{{#if allowsComments}}is-checked{{/if}}") + // .materialCheckBox(class="{{#if allowsComments}}is-checked{{/if}}") + // span + // i.fa.fa-comment-o + // | {{_ 'comment'}} + //div.check-div + // a.flex.js-field-has-activities(class="{{#if allowsActivities}}is-checked{{/if}}") + // .materialCheckBox(class="{{#if allowsActivities}}is-checked{{/if}}") + // span + // i.fa.fa-history + // | {{_ 'activities'}} template(name="boardSubtaskSettingsPopup") form.board-subtask-settings -- cgit v1.2.3-1-g7c22 From 9a21b0a1c933e7f778e4e57a8258e150ccea1620 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 10 Feb 2020 18:47:03 +0200 Subject: Fix Copy Card Link to Clipboard button at card title did not work. Thanks to 2020product and xet7 ! Related https://github.com/wekan/wekan/pull/2922 --- client/components/cards/cardDetails.jade | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 7a6ca7cf..e238823f 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -9,9 +9,10 @@ template(name="cardDetails") if currentUser.isBoardMember a.fa.fa-navicon.card-details-menu.js-open-card-details-menu input.inline-input(type="hidden" id="cardURL_copy" value="{{ absoluteUrl }}") - a.fa.card-copy-button.js-copy-link( + a.fa.fa-link.card-copy-button.js-copy-link( class="fa-link" title="{{_ 'copy-card-link-to-clipboard'}}" + value="{{ absoluteUrl }}" ) if isMiniScreen a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details -- cgit v1.2.3-1-g7c22 From 4467a68b97a3fbf0fbae7f05177d978f2aa80287 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 10 Feb 2020 19:37:25 +0200 Subject: Part 2: Fix Copy Card Link to Clipboard button at card title did not work. Thanks to 2020product and xet7 ! Related https://github.com/wekan/wekan/pull/2922 --- client/components/cards/cardDetails.jade | 2 +- client/components/cards/cardDetails.styl | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index e238823f..e8bb72a4 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -8,7 +8,7 @@ template(name="cardDetails") 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 - input.inline-input(type="hidden" id="cardURL_copy" value="{{ absoluteUrl }}") + input.inline-input(type="text" id="cardURL_copy" value="{{ absoluteUrl }}") a.fa.fa-link.card-copy-button.js-copy-link( class="fa-link" title="{{_ 'copy-card-link-to-clipboard'}}" diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index fd6122eb..80fa87c0 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -4,6 +4,12 @@ avatar-radius = 50% +#cardURL_copy + // Have clipboard text not visible by moving it to far left + position: absolute + left: -2000px + top: 0px + .assignee border-radius: 3px display: block -- cgit v1.2.3-1-g7c22 From e89965f6422fd95b4ad2112ae407b1dde4853510 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 12 Feb 2020 02:08:29 +0200 Subject: Remove card element grouping to create compact card layout. Card Settings / Show on Card: Description Title and Description Text. Thanks to e-stoniauk, 2020product and xet7 ! Fixes https://github.com/wekan/wekan/pull/2922 --- client/components/cards/attachments.jade | 6 ++- client/components/cards/cardDetails.jade | 73 +++++++++++++++++--------------- client/components/sidebar/sidebar.jade | 14 ++++++ client/components/sidebar/sidebar.js | 40 +++++++++++++++++ 4 files changed, 97 insertions(+), 36 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 10b767f4..b695ea41 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -53,5 +53,7 @@ template(name="attachmentsGalery") if currentUser.isBoardMember unless currentUser.isCommentOnly unless currentUser.isWorker - li.attachment-item.add-attachment - a.js-add-attachment {{_ 'add-attachment' }} + //li.attachment-item.add-attachment + a.js-add-attachment + i.fa.fa-paperclip + | {{_ 'add-attachment' }} diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index e8bb72a4..615ae1d5 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -95,7 +95,7 @@ template(name="cardDetails") a.card-label.add-label.js-end-date i.fa.fa-plus - .card-details-items + //.card-details-items if currentBoard.allowsMembers .card-details-item.card-details-item-members h3 @@ -141,7 +141,7 @@ template(name="cardDetails") a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") i.fa.fa-plus - .card-details-items + //.card-details-items each customFieldsWD .card-details-item.card-details-item-customfield h3.card-details-item-title @@ -149,7 +149,7 @@ template(name="cardDetails") = definition.name +cardCustomField - .card-details-items + //.card-details-items if getSpentTime .card-details-item.card-details-item-spent if getIsOvertime @@ -158,37 +158,7 @@ template(name="cardDetails") h3.card-details-item-title {{_ 'spent-time-hours'}} +cardSpentTime - //- XXX We should use "editable" to avoid repetiting ourselves - if canModifyCard - unless currentUser.isWorker - h3 - i.fa.fa-align-left - card-details-item-title {{_ 'description'}} - +inlinedCardDescription(classNames="card-description js-card-description") - +editor(autofocus=true) - | {{getUnsavedValue 'cardDescription' _id getDescription}} - .edit-controls.clearfix - button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form - else - a.js-open-inlined-form - if getDescription - +viewer - = getDescription - else - | {{_ 'edit'}} - if (hasUnsavedValue 'cardDescription' _id) - p.quiet - | {{_ 'unsaved-description'}} - a.js-open-inlined-form {{_ 'view-it'}} - = ' - ' - a.js-close-inlined-form {{_ 'discard'}} - else if getDescription - h3.card-details-item-title {{_ 'description'}} - +viewer - = getDescription - - .card-details-items + //.card-details-items if currentBoard.allowsRequestedBy .card-details-item.card-details-item-name h3 @@ -229,6 +199,41 @@ template(name="cardDetails") +viewer = getAssignedBy + //- XXX We should use "editable" to avoid repetiting ourselves + if canModifyCard + unless currentUser.isWorker + if currentBoard.allowsDescriptionTitle + h3 + i.fa.fa-align-left + card-details-item-title {{_ 'description'}} + if currentBoard.allowsDescriptionText + +inlinedCardDescription(classNames="card-description js-card-description") + +editor(autofocus=true) + | {{getUnsavedValue 'cardDescription' _id getDescription}} + .edit-controls.clearfix + button.primary(type="submit") {{_ 'save'}} + a.fa.fa-times-thin.js-close-inlined-form + else + if currentBoard.allowsDescriptionText + a.js-open-inlined-form + if getDescription + +viewer + = getDescription + else + | {{_ 'edit'}} + if (hasUnsavedValue 'cardDescription' _id) + p.quiet + | {{_ 'unsaved-description'}} + a.js-open-inlined-form {{_ 'view-it'}} + = ' - ' + a.js-close-inlined-form {{_ 'discard'}} + else if getDescription + if currentBoard.allowsDescriptionTitle + h3.card-details-item-title {{_ 'description'}} + if currentBoard.allowsDescriptionText + +viewer + = getDescription + .card-checklist-attachmentGalerys .card-checklist-attachmentGalery.card-checklists if currentBoard.allowsChecklists diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 07da476f..ebcd8486 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -129,6 +129,20 @@ template(name="boardCardSettingsPopup") span i.fa.fa-tags | {{_ 'labels'}} + div.check-div + a.flex.js-field-has-description-title(class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") + span + i.fa.fa-align-left + | {{_ 'description'}} + | {{_ 'title'}} + div.check-div + a.flex.js-field-has-description-text(class="{{#if allowsDescriptionText}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsDescriptionText}}is-checked{{/if}}") + span + i.fa.fa-align-left + | {{_ 'description'}} + | {{_ 'custom-field-text'}} div.check-div a.flex.js-field-has-checklists(class="{{#if allowsChecklists}}is-checked{{/if}}") .materialCheckBox(class="{{#if allowsChecklists}}is-checked{{/if}}") diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index c3c00b08..8e640564 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -647,6 +647,14 @@ BlazeComponent.extendComponent({ return this.currentBoard.allowsComments; }, + allowsDescriptionTitle() { + return this.currentBoard.allowsDescriptionTitle; + }, + + allowsDescriptionText() { + return this.currentBoard.allowsDescriptionText; + }, + isBoardSelected() { return this.currentBoard.dateSettingsDefaultBoardID; }, @@ -837,6 +845,38 @@ BlazeComponent.extendComponent({ this.currentBoard.allowsLabels, ); }, + 'click .js-field-has-description-title'(evt) { + evt.preventDefault(); + this.currentBoard.allowsDescriptionTitle = !this.currentBoard + .allowsDescriptionTitle; + this.currentBoard.setAllowsDescriptionTitle( + this.currentBoard.allowsDescriptionTitle, + ); + $(`.js-field-has-description-title ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsDescriptionTitle, + ); + $('.js-field-has-description-title').toggleClass( + CKCLS, + this.currentBoard.allowsDescriptionTitle, + ); + }, + 'click .js-field-has-description-text'(evt) { + evt.preventDefault(); + this.currentBoard.allowsDescriptionText = !this.currentBoard + .allowsDescriptionText; + this.currentBoard.setAllowsDescriptionText( + this.currentBoard.allowsDescriptionText, + ); + $(`.js-field-has-description-text ${MCB}`).toggleClass( + CKCLS, + this.currentBoard.allowsDescriptionText, + ); + $('.js-field-has-description-text').toggleClass( + CKCLS, + this.currentBoard.allowsDescriptionText, + ); + }, 'click .js-field-has-checklists'(evt) { evt.preventDefault(); this.currentBoard.allowsChecklists = !this.currentBoard -- cgit v1.2.3-1-g7c22 From e0ca960a35cf006880019ba28fc82aa30f289a71 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sat, 22 Feb 2020 02:49:14 +0200 Subject: Create New User in Admin Panel. Works, but does not save fullname yet, so currently it's needed to edit add fullname later. Thanks to xet7 ! Related #802 --- client/components/settings/peopleBody.jade | 52 ++++++++++++++++ client/components/settings/peopleBody.js | 95 ++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) (limited to 'client/components') diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index b8a94337..ca4bc382 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -40,9 +40,15 @@ template(name="peopleGeneral") th {{_ 'active'}} th {{_ 'authentication-method'}} th + +newUserRow each user in peopleList +peopleRow(userId=user._id) +template(name="newUserRow") + a.new-user + i.fa.fa-edit + | {{_ 'new'}} + template(name="peopleRow") tr if userData.loginDisabled @@ -148,3 +154,49 @@ template(name="editUserPopup") // div // input#deleteButton.primary.wide(type="button" value="{{_ 'delete'}}") +template(name="newUserPopup") + form + //label.hide.userId(type="text" value=user._id) + label + | {{_ 'fullname'}} + input.js-profile-fullname(type="text" value="" autofocus) + label + | {{_ 'username'}} + span.error.hide.username-taken + | {{_ 'error-username-taken'}} + //if isLdap + // input.js-profile-username(type="text" value=user.username readonly) + //else + input.js-profile-username(type="text" value="") + label + | {{_ 'email'}} + span.error.hide.email-taken + | {{_ 'error-email-taken'}} + //if isLdap + // input.js-profile-email(type="email" value="{{user.emails.[0].address}}" readonly) + //else + input.js-profile-email(type="email" value="") + label + | {{_ 'admin'}} + select.select-role.js-profile-isadmin + option(value="false" selected="selected") {{_ 'no'}} + option(value="true") {{_ 'yes'}} + label + | {{_ 'active'}} + select.select-active.js-profile-isactive + option(value="false" selected="selected") {{_ 'yes'}} + option(value="true") {{_ 'no'}} + label + | {{_ 'authentication-type'}} + select.select-authenticationMethod.js-authenticationMethod + each authentications + if isSelected value + option(value="{{value}}" selected) {{_ value}} + else + option(value="{{value}}") {{_ value}} + hr + label + | {{_ 'password'}} + input.js-profile-password(type="password") + div.buttonsContainer + input.primary.wide(type="submit" value="{{_ 'save'}}") diff --git a/client/components/settings/peopleBody.js b/client/components/settings/peopleBody.js index 8610034e..186afd58 100644 --- a/client/components/settings/peopleBody.js +++ b/client/components/settings/peopleBody.js @@ -39,6 +39,9 @@ BlazeComponent.extendComponent({ this.filterPeople(); } }, + 'click #newUserButton'() { + Popup.open('newUser'); + }, }, ]; }, @@ -141,6 +144,47 @@ Template.editUserPopup.helpers({ }, }); +Template.newUserPopup.onCreated(function() { + this.authenticationMethods = new ReactiveVar([]); + this.errorMessage = new ReactiveVar(''); + + Meteor.call('getAuthenticationsEnabled', (_, result) => { + if (result) { + // TODO : add a management of different languages + // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')}) + this.authenticationMethods.set([ + { value: 'password' }, + // Gets only the authentication methods availables + ...Object.entries(result) + .filter(e => e[1]) + .map(e => ({ value: e[0] })), + ]); + } + }); +}); + +Template.newUserPopup.helpers({ + //user() { + // return Users.findOne(this.userId); + //}, + authentications() { + return Template.instance().authenticationMethods.get(); + }, + //isSelected(match) { + // const userId = Template.instance().data.userId; + // const selected = Users.findOne(userId).authenticationMethod; + // return selected === match; + //}, + //isLdap() { + // const userId = Template.instance().data.userId; + // const selected = Users.findOne(userId).authenticationMethod; + // return selected === 'ldap'; + //}, + errorMessage() { + return Template.instance().errorMessage.get(); + }, +}); + BlazeComponent.extendComponent({ onCreated() {}, user() { @@ -155,6 +199,16 @@ BlazeComponent.extendComponent({ }, }).register('peopleRow'); +BlazeComponent.extendComponent({ + events() { + return [ + { + 'click a.new-user': Popup.open('newUser'), + }, + ]; + }, +}).register('newUserRow'); + Template.editUserPopup.events({ submit(event, templateInstance) { event.preventDefault(); @@ -248,3 +302,44 @@ Template.editUserPopup.events({ Popup.close(); }), }); + +Template.newUserPopup.events({ + submit(event, templateInstance) { + event.preventDefault(); + const fullname = templateInstance.find('.js-profile-fullname').value.trim(); + const username = templateInstance.find('.js-profile-username').value.trim(); + const password = templateInstance.find('.js-profile-password').value; + const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim(); + const isActive = templateInstance.find('.js-profile-isactive').value.trim(); + const email = templateInstance.find('.js-profile-email').value.trim(); + + Meteor.call( + 'setCreateUser', + fullname, + username, + password, + isAdmin, + isActive, + email.toLowerCase(), + function(error) { + const usernameMessageElement = templateInstance.$('.username-taken'); + const emailMessageElement = templateInstance.$('.email-taken'); + if (error) { + const errorElement = error.error; + if (errorElement === 'username-already-taken') { + usernameMessageElement.show(); + emailMessageElement.hide(); + } else if (errorElement === 'email-already-taken') { + usernameMessageElement.hide(); + emailMessageElement.show(); + } + } else { + usernameMessageElement.hide(); + emailMessageElement.hide(); + Popup.close(); + } + }, + ); + Popup.close(); + }, +}); -- cgit v1.2.3-1-g7c22 From 2b9540ce02de604bf84ea082f2dcb1d01673708c Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sat, 22 Feb 2020 16:32:54 +0200 Subject: Try to fix afterwards loading of cards by adding fallback when requestIdleCallback is not available. Thanks to xet7 ! Closes #2878, closes #2250 --- client/components/lists/listBody.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 89c27ec7..03f88f63 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -743,9 +743,25 @@ BlazeComponent.extendComponent({ }, updateList() { + // Use fallback when requestIdleCallback is not available on iOS and Safari + // https://www.afasterweb.com/2017/11/20/utilizing-idle-moments/ + checkIdleTime = + window.requestIdleCallback || + function(handler) { + const startTime = Date.now(); + return setTimeout(function() { + handler({ + didTimeout: false, + timeRemaining() { + return Math.max(0, 50.0 - (Date.now() - startTime)); + }, + }); + }, 1); + }; + if (this.spinnerInView()) { this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter); - window.requestIdleCallback(() => this.updateList()); + checkIdleTime(() => this.updateList()); } }, -- cgit v1.2.3-1-g7c22 From aac7c380c8c389b0683b2bd64e2cc856993f0e30 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Sun, 1 Mar 2020 20:59:53 +0200 Subject: - Fix critical and moderate security vulnerabilities reported at 2020-02-26 with responsible disclosure by [Dejan Zelic](https://twitter.com/dejandayoff), Justin Benjamin and others at [Offensive Security](https://twitter.com/offsectraining), that follow standard 90 days before public disclosure. Thanks to xet7. - Fix webhook error that prevented some card etc deleting from web UI of board. Thanks to xet7. - Add some more Font Awesome icons. Thanks to xet7. - Remove autofocus from many form input boxes so that they would not cause warnings. Thanks to xet7. --- client/components/settings/peopleBody.jade | 4 ++-- client/components/sidebar/sidebar.jade | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'client/components') diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index ca4bc382..fef1067e 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -110,7 +110,7 @@ template(name="editUserPopup") label.hide.userId(type="text" value=user._id) label | {{_ 'fullname'}} - input.js-profile-fullname(type="text" value=user.profile.fullname autofocus) + input.js-profile-fullname(type="text" value=user.profile.fullname) label | {{_ 'username'}} span.error.hide.username-taken @@ -159,7 +159,7 @@ template(name="newUserPopup") //label.hide.userId(type="text" value=user._id) label | {{_ 'fullname'}} - input.js-profile-fullname(type="text" value="" autofocus) + input.js-profile-fullname(type="text" value="") label | {{_ 'username'}} span.error.hide.username-taken diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index ebcd8486..f0b0e4be 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -245,7 +245,7 @@ template(name="outgoingWebhooksPopup") 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-url(type="text" name="url" value=url) 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 @@ -257,7 +257,7 @@ template(name="outgoingWebhooksPopup") input(type="hidden" value=_id name="id") input.primary.wide(type="submit" value="{{_ 'save'}}") form.integration-form - input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" autofocus) + input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title") 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") @@ -267,7 +267,10 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list - li: a.js-custom-fields {{_ 'custom-fields'}} + li + a.js-custom-fields + i.fa.fa-list-alt + | {{_ 'custom-fields'}} li a.js-open-archives i.fa.fa-archive -- cgit v1.2.3-1-g7c22 From 2b26bbe78a1a2b8b427963a6c44c3853efdb737e Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 6 Mar 2020 03:52:12 +0200 Subject: Fix: img tag did not allow width and height. Removed swipebox from markdown editor img tag and updated marked markdown to newest version. Thanks to hradec and xet7 ! Closes #2956 --- client/components/main/editor.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'client/components') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 39c03aa9..272be197 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -57,6 +57,9 @@ const sanitizeXss = (input, options) => { } } } + /* Don't use swipebox on markdown, so that img tag can now use width + * and height parameters. https://github.com/wekan/wekan/issues/2956 + * Previously this was added at https://github.com/wekan/wekan/pull/2593 } else if (tag === 'img') { if (!options.isClosing) { const src = getAttr('src'); @@ -64,6 +67,7 @@ const sanitizeXss = (input, options) => { return ``; } } + */ } return undefined; }, -- cgit v1.2.3-1-g7c22 From 482682e50079d70c5113169020d6834013b57c11 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 23 Mar 2020 22:29:20 +0200 Subject: SECURITY VULNERABILITY FIX: Fix XSS bug reported today 4 hours ago by Cyb3rjunky. Logged in users could run javascript in input fields. This affects Wekan versions v3.12-v3.84. In [Wekan v3.12](https://github.com/wekan/wekan/blob/master/CHANGELOG.md#v312-2019-08-09-wekan-release) there was [changes for XSS filter to allow inserting images, videos etc on comment WYSIWYG editor](https://github.com/wekan/wekan/pull/2593) so features related to that are now removed. After this fix, Javascript in input fields is not executed. Thanks to Cyb3rjunky and xet7 ! --- client/components/main/editor.js | 215 +++++++++++++-------------------------- 1 file changed, 68 insertions(+), 147 deletions(-) (limited to 'client/components') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 272be197..97a96b8e 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -1,93 +1,7 @@ -import _sanitizeXss from 'xss'; -const ASIS = 'asis'; -const sanitizeXss = (input, options) => { - const defaultAllowedIframeSrc = /^(https:){0,1}\/\/.*?(youtube|vimeo|dailymotion|youku)/i; - const allowedIframeSrcRegex = (function() { - let reg = defaultAllowedIframeSrc; - const SAFE_IFRAME_SRC_PATTERN = - Meteor.settings.public.SAFE_IFRAME_SRC_PATTERN; - try { - if (SAFE_IFRAME_SRC_PATTERN !== undefined) { - reg = new RegExp(SAFE_IFRAME_SRC_PATTERN, 'i'); - } - } catch (e) { - /*eslint no-console: ["error", { allow: ["warn", "error"] }] */ - - console.error('Wrong pattern specified', SAFE_IFRAM_SRC_PATTERN, e); - } - return reg; - })(); - const targetWindow = '_blank'; - const getHtmlDOM = html => { - const i = document.createElement('i'); - i.innerHTML = html; - return i.firstChild; - }; - options = { - onTag(tag, html, options) { - const htmlDOM = getHtmlDOM(html); - const getAttr = attr => { - return htmlDOM && attr && htmlDOM.getAttribute(attr); - }; - if (tag === 'iframe') { - const clipCls = 'note-vide-clip'; - if (!options.isClosing) { - const iframeCls = getAttr('class'); - let safe = iframeCls.indexOf(clipCls) > -1; - const src = getAttr('src'); - if (allowedIframeSrcRegex.exec(src)) { - safe = true; - } - if (safe) - return ``; - } else { - // remove tag - return ''; - } - } else if (tag === 'a') { - if (!options.isClosing) { - if (getAttr(ASIS) === 'true') { - // if has a ASIS attribute, don't do anything, it's a member id - return html; - } else { - const href = getAttr('href'); - if (href.match(/^((http(s){0,1}:){0,1}\/\/|\/)/)) { - // a valid url - return ``; - } - } - } - /* Don't use swipebox on markdown, so that img tag can now use width - * and height parameters. https://github.com/wekan/wekan/issues/2956 - * Previously this was added at https://github.com/wekan/wekan/pull/2593 - } else if (tag === 'img') { - if (!options.isClosing) { - const src = getAttr('src'); - if (src) { - return ``; - } - } - */ - } - return undefined; - }, - onTagAttr(tag, name, value) { - if (tag === 'img' && name === 'src') { - if (value && value.substr(0, 5) === 'data:') { - // allow image with dataURI src - return `${name}='${value}'`; - } - } else if (tag === 'a' && name === 'target') { - return `${name}='${targetWindow}'`; // always change a href target to a new window - } - return undefined; - }, - ...options, - }; - return _sanitizeXss(input, options); -}; Template.editor.onRendered(() => { const textareaSelector = 'textarea'; + const enableRicherEditor = + Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR || true; const mentions = [ // User mentions { @@ -98,13 +12,7 @@ Template.editor.onRendered(() => { currentBoard .activeMembers() .map(member => { - 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; + const username = Users.findOne(member.userId).username; return username.includes(term) ? username : null; }) .filter(Boolean), @@ -124,16 +32,15 @@ Template.editor.onRendered(() => { autosize($textarea); $textarea.escapeableTextComplete(mentions); }; - if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) { + if (enableRicherEditor) { const isSmall = Utils.isMiniScreen(); const toolbar = isSmall ? [ ['view', ['fullscreen']], ['table', ['table']], - ['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 + ['font', ['bold', 'underline']], //['fontsize', ['fontsize']], + ['color', ['color']], ] : [ ['style', ['style']], @@ -143,11 +50,47 @@ Template.editor.onRendered(() => { ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], - ['insert', ['link', 'picture', 'video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled + //['insert', ['link', 'picture', 'video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled //['insert', ['link', 'picture']], // modal popup has issue somehow :( ['view', ['fullscreen', 'help']], ]; - const cleanPastedHTML = sanitizeXss; + const cleanPastedHTML = function(input) { + const badTags = [ + 'style', + 'script', + 'applet', + 'embed', + 'noframes', + 'noscript', + 'meta', + 'link', + 'button', + 'form', + ].join('|'); + const badPatterns = new RegExp( + `(?:${[ + `<(${badTags})s*[^>][\\s\\S]*?<\\/\\1>`, + `<(${badTags})[^>]*?\\/>`, + ].join('|')})`, + 'gi', + ); + let output = input; + // remove bad Tags + output = output.replace(badPatterns, ''); + // remove attributes ' style="..."' + const badAttributes = new RegExp( + `(?:${[ + 'on\\S+=([\'"]?).*?\\1', + 'href=([\'"]?)javascript:.*?\\2', + 'style=([\'"]?).*?\\3', + 'target=\\S+', + ].join('|')})`, + 'gi', + ); + output = output.replace(badAttributes, ''); + output = output.replace(/( { } 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 + $(originalInput).on('input', function() { + // when comment is submitted, the original textarea will be set to '', so shall we if (!this.value) { const sn = getSummernote(this); - sn && sn.summernote('code', ''); + sn && sn.summernote('reset'); + object && object.editingArea.find('.note-placeholder').show(); } }); const jEditor = object && object.editable; const toolbar = object && object.toolbar; - setAutocomplete(jEditor); + if (jEditor !== undefined) { + jEditor.escapeableTextComplete(mentions); + } if (toolbar !== undefined) { const fBtn = toolbar.find('.btn-fullscreen'); fBtn.on('click', function() { @@ -215,6 +138,7 @@ Template.editor.onRendered(() => { }); } }, + onImageUpload(files) { const $summernote = getSummernote(this); if (files && files.length > 0) { @@ -295,7 +219,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('code', ''); //clear original + someNote.summernote('reset'); //clear original someNote.summernote('pasteHTML', cleaned); //this sets the displayed content editor to the cleaned pasted code. }; setTimeout(function() { @@ -335,6 +259,8 @@ Template.editor.onRendered(() => { } }); +import sanitizeXss from 'xss'; + // XXX I believe we should compute a HTML rendered field on the server that // would handle markdown and user mentions. We can simply have two // fields, one source, and one compiled version (in HTML) and send only the @@ -356,12 +282,11 @@ Blaze.Template.registerHelper( } return member; }); - const mentionRegex = /\B@(?:(?:"([\w.\s]*)")|([\w.]+))/gi; // including space in username + const mentionRegex = /\B@([\w.]*)/gi; let currentMention; while ((currentMention = mentionRegex.exec(content)) !== null) { - const [fullMention, quoteduser, simple] = currentMention; - const username = quoteduser || simple; + const [fullMention, username] = currentMention; const knowedUser = _.findWhere(knowedUsers, { username }); if (!knowedUser) { continue; @@ -380,42 +305,38 @@ Blaze.Template.registerHelper( // `userId` to the popup as usual, and we need to store it in the DOM // using a data attribute. 'data-userId': knowedUser.userId, - [ASIS]: 'true', }, linkValue, ); content = content.replace(fullMention, Blaze.toHTML(link)); } + return HTML.Raw(sanitizeXss(content)); }), ); + Template.viewer.events({ // Viewer sometimes have click-able wrapper around them (for instance to edit // the corresponding text). Clicking a link shouldn't fire these actions, stop // we stop these event at the viewer component level. 'click a'(event, templateInstance) { - let prevent = true; + event.stopPropagation(); + + // XXX We hijack the build-in browser action because we currently don't have + // `_blank` attributes in viewer links, and the transformer function is + // handled by a third party package that we can't configure easily. Fix that + // by using directly `_blank` attribute in the rendered HTML. + event.preventDefault(); + const userId = event.currentTarget.dataset.userid; if (userId) { Popup.open('member').call({ userId }, event, templateInstance); } else { const href = event.currentTarget.href; - const child = event.currentTarget.firstElementChild; - if (child && child.tagName === 'IMG') { - prevent = false; - } else if (href) { + if (href) { window.open(href, '_blank'); } } - if (prevent) { - event.stopPropagation(); - - // XXX We hijack the build-in browser action because we currently don't have - // `_blank` attributes in viewer links, and the transformer function is - // handled by a third party package that we can't configure easily. Fix that - // by using directly `_blank` attribute in the rendered HTML. - event.preventDefault(); - } }, }); -- cgit v1.2.3-1-g7c22 From 12ab8fac5db9c5ac8069d0ca2bca340d6004a25b Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 24 Mar 2020 11:04:04 +0200 Subject: Fix Rich editor can not be disabled, regression from changes yesterday at Wekan v3.85. Thanks to uusijani, vjrj and xet7 ! Closes #2967, closes #104 --- client/components/main/editor.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'client/components') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 97a96b8e..18b823a2 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -1,7 +1,5 @@ Template.editor.onRendered(() => { const textareaSelector = 'textarea'; - const enableRicherEditor = - Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR || true; const mentions = [ // User mentions { @@ -32,7 +30,7 @@ Template.editor.onRendered(() => { autosize($textarea); $textarea.escapeableTextComplete(mentions); }; - if (enableRicherEditor) { + if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) { const isSmall = Utils.isMiniScreen(); const toolbar = isSmall ? [ -- cgit v1.2.3-1-g7c22 From b9099a8b7ea6f63c79bdcbb871cb993b2cb7e325 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 24 Mar 2020 20:39:49 +0200 Subject: 1) Fix Pasting text into a card is adding a line before and after (and multiplies by pasting more) by changing paste "p" to "br". 2) Fixes to summernote and markdown comment editors, related to keeping them open when adding comments, having @member mention not close card, and disabling clicking of @member mention. Thanks to xet7 ! Closes #2890 --- client/components/activities/comments.js | 7 +++++ client/components/main/editor.jade | 7 ++++- client/components/main/editor.js | 51 ++++++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 6 deletions(-) (limited to 'client/components') diff --git a/client/components/activities/comments.js b/client/components/activities/comments.js index 50ca019b..e885459e 100644 --- a/client/components/activities/comments.js +++ b/client/components/activities/comments.js @@ -33,6 +33,13 @@ BlazeComponent.extendComponent({ cardId, }); resetCommentInput(input); + // With Richer editor is in use, and comment is submitted, + // clear comment form with JQuery. Id #summernote is defined + // at client/components/main/editor.jade where it previously was + // id=id, now it is id="summernote". + if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR === 'true') { + $('#summernote').summernote('code', ''); + } Tracker.flush(); autosize.update(input); input.trigger('submitted'); diff --git a/client/components/main/editor.jade b/client/components/main/editor.jade index dbd61715..5c5454ee 100644 --- a/client/components/main/editor.jade +++ b/client/components/main/editor.jade @@ -1,8 +1,13 @@ template(name="editor") + // With Richer editor is in use, and comment is submitted, + // clear comment form with JQuery Comment at + // client/components/activities/comments.js . Id #summernote is defined + // here at client/components/main/editor.jade where it previously was + // id=id, now it is id="summernote". textarea.editor( dir="auto" class="{{class}}" - id=id + id="summernote" autofocus=autofocus placeholder="{{_ 'comment-placeholder'}}") +Template.contentBlock diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 18b823a2..3f09d284 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -30,7 +30,7 @@ Template.editor.onRendered(() => { autosize($textarea); $textarea.escapeableTextComplete(mentions); }; - if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) { + if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR === 'true') { const isSmall = Utils.isMiniScreen(); const toolbar = isSmall ? [ @@ -108,10 +108,37 @@ Template.editor.onRendered(() => { } return undefined; }; + // Prevent @member mentions on Add Comment input field + // from closing card, part 1. + let popupShown = false; inputs.each(function(idx, input) { mSummernotes[idx] = $(input).summernote({ placeholder, + // Prevent @member mentions on Add Comment input field + // from closing card, part 2. + onKeydown(e) { + if (popupShown) { + e.preventDefault(); + } + }, + onKeyup(e) { + if (popupShown) { + e.preventDefault(); + } + }, callbacks: { + // Prevent @member mentions on Add Comment input field + // from closing card, part 3. + onKeydown(e) { + if (popupShown) { + e.preventDefault(); + } + }, + onKeyup(e) { + if (popupShown) { + e.preventDefault(); + } + }, onInit(object) { const originalInput = this; $(originalInput).on('input', function() { @@ -136,7 +163,6 @@ Template.editor.onRendered(() => { }); } }, - onImageUpload(files) { const $summernote = getSummernote(this); if (files && files.length > 0) { @@ -215,6 +241,12 @@ Template.editor.onRendered(() => { const thisNote = this; const updatePastedText = function(object) { const someNote = getSummernote(object); + // Fix Pasting text into a card is adding a line before and after + // (and multiplies by pasting more) by changing paste "p" to "br". + // Fixes https://github.com/wekan/wekan/2890 . + // == Fix Start == + someNote.execCommand('defaultParagraphSeparator', false, 'br'); + // == Fix End == 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 @@ -291,11 +323,17 @@ Blaze.Template.registerHelper( } const linkValue = [' ', at, knowedUser.username]; - let linkClass = 'atMention js-open-member'; + //let linkClass = 'atMention js-open-member'; + let linkClass = 'atMention'; if (knowedUser.userId === Meteor.userId()) { linkClass += ' me'; } - const link = HTML.A( + // This @user mention link generation did open same Wekan + // window in new tab, so now A is changed to U so it's + // underlined and there is no link popup. This way also + // text can be selected more easily. + //const link = HTML.A( + const link = HTML.U( { class: linkClass, // XXX Hack. Since we stringify this render function result below with @@ -329,7 +367,10 @@ Template.viewer.events({ const userId = event.currentTarget.dataset.userid; if (userId) { - Popup.open('member').call({ userId }, event, templateInstance); + // Prevent @member mentions on Add Comment input field + // from closing card, part 4. + PopupNoClose.open('member').call({ userId }, event, templateInstance); + event.preventDefault(); } else { const href = event.currentTarget.href; if (href) { -- cgit v1.2.3-1-g7c22 From 5bd0459cc25183ecc779103fb56e14eb6707095d Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 25 Mar 2020 13:35:54 +0200 Subject: Hide duplicate "Hide system messages" at Change Settings/Member Settings, because it's also on card slider. Thanks to notohiro and xet7 ! Closes #2837 --- client/components/users/userHeader.jade | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'client/components') diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 9306d21d..1cd9da6b 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -98,12 +98,12 @@ template(name="changeLanguagePopup") template(name="changeSettingsPopup") ul.pop-over-list - li - a.js-toggle-system-messages - i.fa.fa-comments-o - | {{_ 'hide-system-messages'}} - if hiddenSystemMessages - i.fa.fa-check + //li + // a.js-toggle-system-messages + // i.fa.fa-comments-o + // | {{_ 'hide-system-messages'}} + // if hiddenSystemMessages + // i.fa.fa-check li a.js-toggle-desktop-drag-handles i.fa.fa-arrows -- cgit v1.2.3-1-g7c22 From c41c1e5293ebb81cb767d2476ae6bf5cec0d983d Mon Sep 17 00:00:00 2001 From: Daniel Eder Date: Thu, 26 Mar 2020 10:57:05 +0100 Subject: subtasks now use parent task swimlane by default --- client/components/cards/subtasks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index 34348fe1..fad859e7 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -20,7 +20,7 @@ BlazeComponent.extendComponent({ const crtBoard = Boards.findOne(card.boardId); const targetBoard = crtBoard.getDefaultSubtasksBoard(); const listId = targetBoard.getDefaultSubtasksListId(); - const swimlaneId = targetBoard.getDefaultSwimline()._id; + const swimlaneId = card.swimlaneId; if (title) { const _id = Cards.insert({ -- cgit v1.2.3-1-g7c22 From 9819c9f801128d07374b0703b482bdb83a672297 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Fri, 27 Mar 2020 11:35:03 -0600 Subject: add a notification drawer like trello --- client/components/activities/activities.jade | 347 ++++++++++----------- client/components/activities/activities.js | 111 ++++--- client/components/main/header.jade | 2 + client/components/main/header.styl | 2 +- client/components/notifications/notification.jade | 10 + client/components/notifications/notification.js | 28 ++ client/components/notifications/notification.styl | 57 ++++ .../components/notifications/notificationIcon.jade | 53 ++++ client/components/notifications/notifications.jade | 5 + client/components/notifications/notifications.js | 32 ++ client/components/notifications/notifications.styl | 17 + .../notifications/notificationsDrawer.jade | 16 + .../notifications/notificationsDrawer.js | 38 +++ .../notifications/notificationsDrawer.styl | 57 ++++ 14 files changed, 545 insertions(+), 230 deletions(-) create mode 100644 client/components/notifications/notification.jade create mode 100644 client/components/notifications/notification.js create mode 100644 client/components/notifications/notification.styl create mode 100644 client/components/notifications/notificationIcon.jade create mode 100644 client/components/notifications/notifications.jade create mode 100644 client/components/notifications/notifications.js create mode 100644 client/components/notifications/notifications.styl create mode 100644 client/components/notifications/notificationsDrawer.jade create mode 100644 client/components/notifications/notificationsDrawer.js create mode 100644 client/components/notifications/notificationsDrawer.styl (limited to 'client/components') diff --git a/client/components/activities/activities.jade b/client/components/activities/activities.jade index 8ecbdee8..c86936a0 100644 --- a/client/components/activities/activities.jade +++ b/client/components/activities/activities.jade @@ -8,234 +8,201 @@ template(name="activities") +cardActivities template(name="boardActivities") - each currentBoard.activities - .activity - +userAvatar(userId=user._id) - p.activity-desc - +memberName(user=user) + each activityData in currentBoard.activities + +activity(activity=activityData card=card mode=mode) - if($eq activityType 'deleteAttachment') - | {{{_ 'activity-delete-attach' cardLink}}}. +template(name="cardActivities") + each activityData in currentCard.activities + +activity(activity=activityData card=card mode=mode) + +template(name="activity") + .activity + +userAvatar(userId=activity.user._id) + p.activity-desc + +memberName(user=activity.user) + + //- attachment activity ------------------------------------------------- + if($eq activity.activityType 'deleteAttachment') + | {{{_ 'activity-delete-attach' cardLink}}}. + + if($eq activity.activityType 'addAttachment') + | {{{_ 'activity-attached' attachmentLink cardLink}}}. + if($neq mode 'board') + if activity.attachment.isImage + img.attachment-image-preview(src=activity.attachment.url) + + //- board activity ------------------------------------------------------ + if($eq mode 'board') + if($eq activity.activityType 'createBoard') + | {{_ 'activity-created' boardLabel}}. - if($eq activityType 'addAttachment') - | {{{_ 'activity-attached' attachmentLink cardLink}}}. + if($eq activity.activityType 'importBoard') + | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. - if($eq activityType 'addBoardMember') + if($eq activity.activityType 'addBoardMember') | {{{_ 'activity-added' memberLink boardLabel}}}. - if($eq activityType 'addComment') - | {{{_ 'activity-on' cardLink}}} - a.activity-comment(href="{{ card.absoluteUrl }}") - +viewer - = comment.text - - if($eq activityType 'addChecklist') - | {{{_ 'activity-checklist-added' cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklist.title - if($eq activityType 'removeChecklist') - | {{{_ 'activity-checklist-removed' cardLink}}}. - - if($eq activityType 'checkedItem') - | {{{_ 'activity-checked-item' checkItem checklist.title cardLink}}}. - - if($eq activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item' checkItem checklist.title cardLink}}}. - - if($eq activityType 'checklistCompleted') - | {{{_ 'activity-checklist-completed' checklist.title cardLink}}}. + if($eq activity.activityType 'removeBoardMember') + | {{{_ 'activity-excluded' memberLink boardLabel}}}. - if($eq activityType 'checklistUncompleted') - | {{{_ 'activity-checklist-uncompleted' checklist.title cardLink}}}. + //- card activity ------------------------------------------------------- + if($eq activity.activityType 'createCard') + if($eq mode 'card') + | {{{_ 'activity-added' cardLabel activity.listName}}}. + else + | {{{_ 'activity-added' cardLabel boardLabel}}}. - if($eq activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklistItem.title - if($eq activityType 'removedChecklistItem') - | {{{_ 'activity-checklist-item-removed' checklist.title cardLink}}}. + if($eq activity.activityType 'importCard') + | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. - if($eq activityType 'archivedCard') - | {{{_ 'activity-archived' cardLink}}}. + if($eq activity.activityType 'moveCard') + | {{{_ 'activity-moved' cardLabel activity.oldList.title activity.list.title}}}. - if($eq activityType 'archivedList') - | {{_ 'activity-archived' list.title}}. + if($eq activity.activityType 'moveCardBoard') + | {{{_ 'activity-moved' cardLink activity.oldBoardName activity.boardName}}}. - if($eq activityType 'archivedSwimlane') - | {{_ 'activity-archived' swimlane.title}}. + if($eq activity.activityType 'archivedCard') + | {{{_ 'activity-archived' cardLink}}}. - if($eq activityType 'createBoard') - | {{_ 'activity-created' boardLabel}}. + if($eq activity.activityType 'restoredCard') + | {{{_ 'activity-sent' cardLink boardLabel}}}. - if($eq activityType 'createCard') - | {{{_ 'activity-added' cardLink boardLabel}}}. + //- checklist activity -------------------------------------------------- + if($eq activity.activityType 'addChecklist') + | {{{_ 'activity-checklist-added' cardLink}}}. + if($eq mode 'card') + .activity-checklist + +viewer + = activity.checklist.title + else + a.activity-checklist(href="{{ activity.card.absoluteUrl }}") + +viewer + = activity.checklist.title - if($eq activityType 'createCustomField') - | {{_ 'activity-customfield-created' customField}}. + if($eq activity.activityType 'removedChecklist') + | {{{_ 'activity-checklist-removed' cardLink}}}. - if($eq activityType 'createList') - | {{_ 'activity-added' list.title boardLabel}}. + if($eq activity.activityType 'completeChecklist') + | {{{_ 'activity-checklist-completed' activity.checklist.title cardLink}}}. - if($eq activityType 'createSwimlane') - | {{_ 'activity-added' swimlane.title boardLabel}}. + if($eq activity.activityType 'uncompleteChecklist') + | {{{_ 'activity-checklist-uncompleted' activity.checklist.title cardLink}}}. - if($eq activityType 'removeList') - | {{_ 'activity-removed' title boardLabel}}. + if($eq activity.activityType 'checkedItem') + | {{{_ 'activity-checked-item' checkItem activity.checklist.title cardLink}}}. - if($eq activityType 'importBoard') - | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. + if($eq activity.activityType 'uncheckedItem') + | {{{_ 'activity-unchecked-item' checkItem activity.checklist.title cardLink}}}. - if($eq activityType 'importCard') - | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. + if($eq activity.activityType 'addChecklistItem') + | {{{_ 'activity-checklist-item-added' activity.checklist.title cardLink}}}. + .activity-checklist(href="{{ activity.card.absoluteUrl }}") + +viewer + = activity.checklistItem.title - if($eq activityType 'importList') - | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. + if($eq activity.activityType 'removedChecklistItem') + | {{{_ 'activity-checklist-item-removed' activity.checklist.title cardLink}}}. - if($eq activityType 'joinMember') - if($eq user._id member._id) - | {{{_ 'activity-joined' cardLink}}}. + //- comment activity ---------------------------------------------------- + if($eq mode 'card') + //- if we are in card mode we display the comment in a way that it + //- can be edited by the owner + if($eq activity.activityType 'addComment') + +inlinedForm(classNames='js-edit-comment') + +editor(autofocus=true) + = activity.comment.text + .edit-controls + button.primary(type="submit") {{_ 'edit'}} else - | {{{_ 'activity-added' memberLink cardLink}}}. - - if($eq activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. - - if($eq activityType 'moveCard') - | {{{_ 'activity-moved' cardLink oldList.title list.title}}}. - - if($eq activityType 'removeBoardMember') - | {{{_ 'activity-excluded' memberLink boardLabel}}}. + .activity-comment + +viewer + = activity.comment.text + span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }} + if ($eq currentUser._id activity.comment.userId) + = ' - ' + a.js-open-inlined-form {{_ "edit"}} + = ' - ' + a.js-delete-comment {{_ "delete"}} - if($eq activityType 'restoredCard') - | {{{_ 'activity-sent' cardLink boardLabel}}}. + if($eq activity.activityType 'deleteComment') + | {{{_ 'activity-deleteComment' currentData.commentId}}}. - if($eq activityType 'addedLabel') - | {{{_ 'activity-added-label' lastLabel cardLink}}}. + if($eq activity.activityType 'editComment') + | {{{_ 'activity-editComment' currentData.commentId}}}. + else + //- if we are not in card mode we only display a summary of the comment + if($eq activity.activityType 'addComment') + | {{{_ 'activity-on' cardLink}}} + a.activity-comment(href="{{ activity.card.absoluteUrl }}") + +viewer + = activity.comment.text - if($eq activityType 'removedLabel') - | {{{_ 'activity-removed-label' lastLabel cardLink}}}. + //- customField activity ------------------------------------------------ + if($eq mode 'board') + if($eq activity.activityType 'createCustomField') + | {{_ 'activity-customfield-created' customField}}. - if($eq activityType 'setCustomField') + if($eq activity.activityType 'setCustomField') | {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}. - if($eq activityType 'unsetCustomField') + if($eq activity.activityType 'unsetCustomField') | {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}. - if($eq activityType 'unjoinMember') - if($eq user._id member._id) - | {{{_ 'activity-unjoined' cardLink}}}. - else - | {{{_ 'activity-removed' memberLink cardLink}}}. + //- label activity ------------------------------------------------------ + if($eq activity.activityType 'addedLabel') + | {{{_ 'activity-added-label' lastLabel cardLink}}}. - span(title=createdAt).activity-meta {{ moment createdAt }} + if($eq activity.activityType 'removedLabel') + | {{{_ 'activity-removed-label' lastLabel cardLink}}}. -template(name="cardActivities") - each currentCard.activities - .activity - +userAvatar(userId=user._id) - p.activity-desc - +memberName(user=user) - if($eq activityType 'createCard') - | {{_ 'activity-added' cardLabel listName}}. - if($eq activityType 'importCard') - | {{{_ 'activity-imported' cardLabel list.title sourceLink}}}. - if($eq activityType 'joinMember') - if($eq user._id member._id) - | {{_ 'activity-joined' cardLabel}}. - else - | {{{_ 'activity-added' memberLink cardLabel}}}. - if($eq activityType 'unjoinMember') - if($eq user._id member._id) - | {{_ 'activity-unjoined' cardLabel}}. - else - | {{{_ 'activity-removed' cardLabel memberLink}}}. - if($eq activityType 'archivedCard') - | {{_ 'activity-archived' cardLabel}}. - - if($eq activityType 'addedLabel') - | {{{_ 'activity-added-label-card' lastLabel }}}. + //- list activity ------------------------------------------------------- + if($neq mode 'card') + if($eq activity.activityType 'createList') + | {{{_ 'activity-added' listLabel boardLabel}}}. - if($eq activityType 'removedLabel') - | {{{_ 'activity-removed-label-card' lastLabel }}}. + if($eq activity.activityType 'importList') + | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. - if($eq activityType 'removeChecklist') - | {{{_ 'activity-checklist-removed' cardLabel}}}. + if($eq activity.activityType 'removeList') + | {{{_ 'activity-removed' activity.title boardLabel}}}. - if($eq activityType 'checkedItem') - | {{{_ 'activity-checked-item-card' checkItem checklist.title }}}. + if($eq activity.activityType 'archivedList') + | {{_ 'activity-archived' listLabel}}. - if($eq activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item-card' checkItem checklist.title }}}. + //- member activity ---------------------------------------------------- + if($eq activity.activityType 'joinMember') + if($eq user._id activity.member._id) + | {{{_ 'activity-joined' cardLink}}}. + else + | {{{_ 'activity-added' memberLink cardLink}}}. - if($eq activityType 'checklistCompleted') - | {{{_ 'activity-checklist-completed-card' checklist.title }}}. + if($eq activity.activityType 'unjoinMember') + if($eq user._id activity.member._id) + | {{{_ 'activity-unjoined' cardLink}}}. + else + | {{{_ 'activity-removed' memberLink cardLink}}}. - if($eq activityType 'checklistUncompleted') - | {{{_ 'activity-checklist-uncompleted-card' checklist.title }}}. + //- swimlane activity -------------------------------------------------- + if($neq mode 'card') + if($eq activity.activityType 'createSwimlane') + | {{{_ 'activity-added' activity.swimlane.title boardLabel}}}. - if($eq activityType 'restoredCard') - | {{_ 'activity-sent' cardLabel boardLabel}}. - if($eq activityType 'moveCard') - | {{_ 'activity-moved' cardLabel oldList.title list.title}}. + if($eq activity.activityType 'archivedSwimlane') + | {{_ 'activity-archived' activity.swimlane.title}}. - if($eq activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink oldBoardName boardName}}}. - if($eq activityType 'addAttachment') - | {{{_ 'activity-attached' attachmentLink cardLabel}}}. - if attachment.isImage - img.attachment-image-preview(src=attachment.url) - if($eq activityType 'deleteAttachment') - | {{{_ 'activity-delete-attach' cardLabel}}}. - if($eq activityType 'removedChecklist') - | {{{_ 'activity-checklist-removed' cardLabel}}}. - if($eq activityType 'addChecklist') - | {{{_ 'activity-checklist-added' cardLabel}}}. - .activity-checklist - +viewer - = checklist.title - if($eq activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. - .activity-checklist(href="{{ card.absoluteUrl }}") - +viewer - = checklistItem.title - - if(currentData.timeKey) - | {{{_ activityType }}} + //- I don't understand this part ---------------------------------------- + if(currentData.timeKey) + | {{{_ activity.activityType }}} + = ' ' + i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} + if (currentData.timeOldValue) = ' ' - i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} - if (currentData.timeOldValue) - = ' ' - | {{{_ "previous_as" }}} - = ' ' - i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} - = ' @' - else if(currentData.timeValue) - | {{{_ activityType currentData.timeValue}}} - - - if($eq activityType 'deleteComment') - | {{{_ 'activity-deleteComment' currentData.commentId}}}. - if($eq activityType 'editComment') - | {{{_ 'activity-editComment' currentData.commentId}}}. - if($eq activityType 'addComment') - +inlinedForm(classNames='js-edit-comment') - +editor(autofocus=true) - = comment.text - .edit-controls - button.primary(type="submit") {{_ 'edit'}} - else - .activity-comment - +viewer - = comment.text - span(title=createdAt).activity-meta {{ moment createdAt }} - if ($eq currentUser._id comment.userId) - = ' - ' - a.js-open-inlined-form {{_ "edit"}} - = ' - ' - a.js-delete-comment {{_ "delete"}} - - else - span(title=createdAt).activity-meta {{ moment createdAt }} + | {{{_ "previous_as" }}} + = ' ' + i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} + = ' @' + else if(currentData.timeValue) + | {{{_ activity.activityType currentData.timeValue}}} + + span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }} diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js index b082273a..36214e19 100644 --- a/client/components/activities/activities.js +++ b/client/components/activities/activities.js @@ -41,7 +41,9 @@ BlazeComponent.extendComponent({ }); }); }, +}).register('activities'); +BlazeComponent.extendComponent({ loadNextPage() { if (this.loadNextPageLocked === false) { this.page.set(this.page.get() + 1); @@ -50,41 +52,37 @@ BlazeComponent.extendComponent({ }, checkItem() { - const checkItemId = this.currentData().checklistItemId; + const checkItemId = this.currentData().activity.checklistItemId; const checkItem = ChecklistItems.findOne({ _id: checkItemId }); - return checkItem.title; + return checkItem && checkItem.title; }, boardLabel() { + const data = this.currentData(); + if (data.mode !== 'board') { + return createBoardLink(data.activity.board(), data.activity.listName); + } return TAPi18n.__('this-board'); }, cardLabel() { + const data = this.currentData(); + if (data.mode !== 'card') { + return createCardLink(this.currentData().activity.card()); + } return TAPi18n.__('this-card'); }, cardLink() { - const card = this.currentData().card(); - return ( - card && - Blaze.toHTML( - HTML.A( - { - href: card.absoluteUrl(), - class: 'action-card', - }, - card.title, - ), - ) - ); + return createCardLink(this.currentData().activity.card()); }, lastLabel() { - const lastLabelId = this.currentData().labelId; + const lastLabelId = this.currentData().activity.labelId; if (!lastLabelId) return null; - const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById( - lastLabelId, - ); + const lastLabel = Boards.findOne( + this.currentData().activity.boardId, + ).getLabelById(lastLabelId); if (lastLabel && (lastLabel.name === undefined || lastLabel.name === '')) { return lastLabel.color; } else { @@ -94,7 +92,7 @@ BlazeComponent.extendComponent({ lastCustomField() { const lastCustomField = CustomFields.findOne( - this.currentData().customFieldId, + this.currentData().activity.customFieldId, ); if (!lastCustomField) return null; return lastCustomField.name; @@ -102,10 +100,10 @@ BlazeComponent.extendComponent({ lastCustomFieldValue() { const lastCustomField = CustomFields.findOne( - this.currentData().customFieldId, + this.currentData().activity.customFieldId, ); if (!lastCustomField) return null; - const value = this.currentData().value; + const value = this.currentData().activity.value; if ( lastCustomField.settings.dropdownItems && lastCustomField.settings.dropdownItems.length > 0 @@ -122,11 +120,13 @@ BlazeComponent.extendComponent({ }, listLabel() { - return this.currentData().list().title; + const activity = this.currentData().activity; + const list = activity.list(); + return (list && list.title) || activity.title; }, sourceLink() { - const source = this.currentData().source; + const source = this.currentData().activity.source; if (source) { if (source.url) { return Blaze.toHTML( @@ -146,30 +146,31 @@ BlazeComponent.extendComponent({ memberLink() { return Blaze.toHTMLWithData(Template.memberName, { - user: this.currentData().member(), + user: this.currentData().activity.member(), }); }, attachmentLink() { - const attachment = this.currentData().attachment(); + const attachment = this.currentData().activity.attachment(); // trying to display url before file is stored generates js errors return ( - attachment && - attachment.url({ download: true }) && - Blaze.toHTML( - HTML.A( - { - href: attachment.url({ download: true }), - target: '_blank', - }, - attachment.name(), - ), - ) + (attachment && + attachment.url({ download: true }) && + Blaze.toHTML( + HTML.A( + { + href: attachment.url({ download: true }), + target: '_blank', + }, + attachment.name(), + ), + )) || + this.currentData().activity.attachmentName ); }, customField() { - const customField = this.currentData().customField(); + const customField = this.currentData().activity.customField(); if (!customField) return null; return customField.name; }, @@ -199,4 +200,36 @@ BlazeComponent.extendComponent({ }, ]; }, -}).register('activities'); +}).register('activity'); + +function createCardLink(card) { + return ( + card && + Blaze.toHTML( + HTML.A( + { + href: card.absoluteUrl(), + class: 'action-card', + }, + card.title, + ), + ) + ); +} + +function createBoardLink(board, list) { + let text = board.title; + if (list) text += `: ${list}`; + return ( + board && + Blaze.toHTML( + HTML.A( + { + href: board.absoluteUrl(), + class: 'action-board', + }, + text, + ), + ) + ); +} diff --git a/client/components/main/header.jade b/client/components/main/header.jade index 75e84c0c..9a5a6b9b 100644 --- a/client/components/main/header.jade +++ b/client/components/main/header.jade @@ -35,6 +35,8 @@ template(name="header") a#header-new-board-icon.js-create-board i.fa.fa-plus(title="Create a new board") + +notifications + +headerUserBar #header(class=currentBoard.colorClass) diff --git a/client/components/main/header.styl b/client/components/main/header.styl index f77c2aca..632d1535 100644 --- a/client/components/main/header.styl +++ b/client/components/main/header.styl @@ -99,7 +99,7 @@ height: 28px font-size: 12px display: flex - z-index: 17 + z-index: 21 #header-user-bar, #header-new-board-icon, diff --git a/client/components/notifications/notification.jade b/client/components/notifications/notification.jade new file mode 100644 index 00000000..c98bbdba --- /dev/null +++ b/client/components/notifications/notification.jade @@ -0,0 +1,10 @@ +template(name='notification') + li.notification(class="{{#if read}}read{{/if}}") + .read-status + .materialCheckBox(class="{{#if read}}is-checked{{/if}}") + +notificationIcon(activityData) + .details + +activity(activity=activityData mode='none') + if read + .remove + a.fa.fa-trash diff --git a/client/components/notifications/notification.js b/client/components/notifications/notification.js new file mode 100644 index 00000000..89277520 --- /dev/null +++ b/client/components/notifications/notification.js @@ -0,0 +1,28 @@ +Template.notification.events({ + 'click .read-status .materialCheckBox'() { + const update = {}; + update[`profile.notifications.${this.index}.read`] = this.read + ? null + : Date.now(); + Users.update(Meteor.userId(), { $set: update }); + }, + 'click .remove a'() { + Meteor.user().removeNotification(this.activityData._id); + }, +}); + +Template.notification.helpers({ + mode: 'board', + isOfActivityType(activityId, type) { + const activity = Activities.findOne(activityId); + return activity && activity.activityType === type; + }, + activityType(activityId) { + const activity = Activities.findOne(activityId); + return activity ? activity.activityType : ''; + }, + activityUser(activityId) { + const activity = Activities.findOne(activityId); + return activity && activity.userId; + }, +}); diff --git a/client/components/notifications/notification.styl b/client/components/notifications/notification.styl new file mode 100644 index 00000000..0cf0cfd5 --- /dev/null +++ b/client/components/notifications/notification.styl @@ -0,0 +1,57 @@ +#notifications-drawer + &.show-read .notification.read + display: flex + + .notification + display: flex + float: none + padding: 12px 8px 8px + color: black + border-bottom: 1px solid #dbdbdb + + &.read + display: none + + .read-status + width: 30px + + input + width: 24px + height: 24px + + .activity-type + margin: 16px 0 0 + width: 17px + height: 17px + font-size: 17px + display: block + color: #bbb + + .details + width: calc(100% - 30px) + + .activity + display: flex + + .activity-desc + width: 100%; + + .activity-comment + display: block + width: 100% + border-radius: 3px + background: #fff + text-decoration: none + box-shadow: 0 1px 2px rgba(0,0,0,0.2) + margin-top: 5px + padding: 5px + + .activity-meta + display: block + font-size: 0.8em + color: #999 + font-style: italic + + .remove + a:hover + color #eb4646 !important diff --git a/client/components/notifications/notificationIcon.jade b/client/components/notifications/notificationIcon.jade new file mode 100644 index 00000000..04377606 --- /dev/null +++ b/client/components/notifications/notificationIcon.jade @@ -0,0 +1,53 @@ +template(name='notificationIcon') + if($in activityType 'deleteAttachment' 'addAttachment') + i.fa.fa-paperclip.activity-type(title="attachment") + else if($in activityType 'createBoard' 'importBoard') + i.fa.fa-chalkboard.activity-type(title="board") + + else if($in activityType 'createCard' 'importCard' 'moveCard') + +cardNotificationIcon + else if($in activityType 'moveCardBoard' 'archivedCard' 'restoredCard') + +cardNotificationIcon + //- $in can only handle up to 3 cases so we have to break this case over 2 cases... use a simple template to keep it + //- DRY and consistant + + else if($in activityType 'addChecklist' 'removedChecklist' 'completeChecklist') + +checklistNotificationIcon + else if($in activityType 'uncompleteChecklist') + +checklistNotificationIcon + //- $in can only handle up to 3 cases so we have to break this case over 2 cases... use a simple template to keep it + //- DRY and consistant + + else if($in activityType 'checkedItem' 'uncheckedItem' 'addChecklistItem' 'removedChecklistItem') + i.fa.fa-check-square.activity-type(title="checklist item") + else if($in activityType 'addComment') + i.fa.fa-comment-o.activity-type(title="comment") + else if($in activityType 'createCustomField' 'setCustomField' 'unsetCustomField') + i.fa.fa-code.activity-type(title="custom field") + else if($in activityType 'addedLabel' 'removedLabel') + i.fa.fa-tag.activity-type(title="label") + + else if($in activityType 'createList' 'removeList' 'archivedList') + +listNotificationIcon + else if($in activityType 'importList') + +listNotificationIcon + //- $in can only handle up to 3 cases so we have to break this case over 2 cases... use a simple template to keep it + //- DRY and consistant + + //- elswhere in the app we use fa-trello to indicate lists... + //- i personally like fa-columns a bit better + else if($in activityType 'unjoinMember' 'addBoardMember' 'joinMember' 'removeBoardMember') + i.fa.fa-user.activity-type(title="member") + else if($in activityType 'createSwimlane' 'archivedSwimlane') + i.fa.fa-th-large.activity-type(title="swimlane") + else + i.fa.fa-bug.activity-type(title="can't find icon for #{activityType}") + +template(name='cardNotificationIcon') + i.fa.fa-clone.activity-type(title="card") + +template(name='checklistNotificationIcon') + i.fa.fa-list.activity-type(title="checklist") + +template(name='listNotificationIcon') + i.fa.fa-columns.activity-type(title="list") diff --git a/client/components/notifications/notifications.jade b/client/components/notifications/notifications.jade new file mode 100644 index 00000000..bf8acbbf --- /dev/null +++ b/client/components/notifications/notifications.jade @@ -0,0 +1,5 @@ +template(name='notifications') + #notifications.board-header-btns.right + a.notifications-drawer-toggle.fa.fa-bell(class="{{#if $gt unreadNotifications 0}}alert{{/if}}") + if $.Session.get 'showNotificationsDrawer' + +notificationsDrawer(unreadNotifications=unreadNotifications) diff --git a/client/components/notifications/notifications.js b/client/components/notifications/notifications.js new file mode 100644 index 00000000..c0aa6cb5 --- /dev/null +++ b/client/components/notifications/notifications.js @@ -0,0 +1,32 @@ +// this hides the notifications drawer if anyone clicks off of the panel +Template.body.events({ + click(event) { + if ( + !$(event.target).is('#notifications *') && + Session.get('showNotificationsDrawer') + ) { + toggleNotificationsDrawer(); + } + }, +}); + +Template.notifications.helpers({ + unreadNotifications() { + const notifications = Users.findOne(Meteor.userId()).notifications(); + const unreadNotifications = _.filter(notifications, v => !v.read); + return unreadNotifications.length; + }, +}); + +Template.notifications.events({ + 'click .notifications-drawer-toggle'() { + toggleNotificationsDrawer(); + }, +}); + +export function toggleNotificationsDrawer() { + Session.set( + 'showNotificationsDrawer', + !Session.get('showNotificationsDrawer'), + ); +} diff --git a/client/components/notifications/notifications.styl b/client/components/notifications/notifications.styl new file mode 100644 index 00000000..710cd3f9 --- /dev/null +++ b/client/components/notifications/notifications.styl @@ -0,0 +1,17 @@ +#notifications + position: relative + + .notifications-drawer-toggle + display: block + line-height: 28px + color: #f2f2f2 + margin: 0 10px + width: 28px + height: 28px + text-align: center + border: 0 + padding: 0 + + &.alert + background-color: #eb4646; + diff --git a/client/components/notifications/notificationsDrawer.jade b/client/components/notifications/notificationsDrawer.jade new file mode 100644 index 00000000..67fc6e65 --- /dev/null +++ b/client/components/notifications/notificationsDrawer.jade @@ -0,0 +1,16 @@ +template(name='notificationsDrawer') + section#notifications-drawer(class="{{#if $.Session.get 'showReadNotifications'}}show-read{{/if}}") + .header + if $.Session.get 'showReadNotifications' + a.toggle-read Filter by Unread + else + a.toggle-read View All + h5 Notifications + if($gt unreadNotifications 0) + |(#{unreadNotifications}) + a.fa.fa-times-thin.close + ul.notifications + each transformedProfile.notifications + +notification(activityData=activity index=dbIndex read=read) + if($gt unreadNotifications 0) + a.all-read Mark all as read diff --git a/client/components/notifications/notificationsDrawer.js b/client/components/notifications/notificationsDrawer.js new file mode 100644 index 00000000..98d4750d --- /dev/null +++ b/client/components/notifications/notificationsDrawer.js @@ -0,0 +1,38 @@ +import { toggleNotificationsDrawer } from './notifications.js'; + +Template.notificationsDrawer.onCreated(function() { + Meteor.subscribe('notificationActivities'); + Meteor.subscribe('notificationCards'); + Meteor.subscribe('notificationUsers'); + Meteor.subscribe('notificationsAttachments'); + Meteor.subscribe('notificationChecklistItems'); + Meteor.subscribe('notificationChecklists'); + Meteor.subscribe('notificationComments'); + Meteor.subscribe('notificationLists'); + Meteor.subscribe('notificationSwimlanes'); +}); + +Template.notificationsDrawer.helpers({ + transformedProfile() { + return Users.findOne(Meteor.userId()); + }, +}); + +Template.notificationsDrawer.events({ + 'click .all-read'() { + const notifications = Meteor.user().profile.notifications; + for (const index in notifications) { + if (notifications.hasOwnProperty(index) && !notifications[index].read) { + const update = {}; + update[`profile.notifications.${index}.read`] = Date.now(); + Users.update(Meteor.userId(), { $set: update }); + } + } + }, + 'click .close'() { + toggleNotificationsDrawer(); + }, + 'click .toggle-read'() { + Session.set('showReadNotifications', !Session.get('showReadNotifications')); + }, +}); diff --git a/client/components/notifications/notificationsDrawer.styl b/client/components/notifications/notificationsDrawer.styl new file mode 100644 index 00000000..a26b5e4a --- /dev/null +++ b/client/components/notifications/notificationsDrawer.styl @@ -0,0 +1,57 @@ +belize = #2980b9 + +section#notifications-drawer + position: fixed + top: 28px + right: 0 + width: 400px + background-color: #fafafa + box-shadow: 0 1px 2px rgba(0,0,0,0.15) + border-radius: 2px + max-height: calc(100vh - 28px - 36px) + color: black + padding-top 36px; + overflow: scroll + + a:hover + color: belize !important + + .header + position: fixed + top 28px + right 0 + width calc(400px - 32px) + padding: 8px 16px + background: #ededed + border-bottom: 1px solid #dbdbdb + z-index 2 + + .toggle-read + position absolute + left 16px + top calc(50% - 8px) + color belize + + h5 + text-align: center + margin: 0 + + .close + position: absolute + top: calc(50% - 12px) + right: 12px + font-size: 24px + height: 24px + line-height: 24px + opacity 1 + + .all-read + color belize + background-color: #fafafa + margin 8px 16px 12px + display inline-block + + ul.notifications + display: block + padding: 0px 16px + margin: 0 -- cgit v1.2.3-1-g7c22 From 3546d7aa02bc65cf1183cb493adeb543ba51945d Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 31 Mar 2020 16:56:32 +0300 Subject: Fix Browser always reload the whole page when I change one of the card color. Fixed by making label colors and text again editable. Regression from [Wekan v3.86 2)](https://github.com/wekan/wekan/commit/b9099a8b7ea6f63c79bdcbb871cb993b2cb7e325). Thanks to javen9881 and xet7 ! Closes #2971 --- client/components/activities/comments.js | 7 ------ client/components/main/editor.jade | 7 +----- client/components/main/editor.js | 38 ++++---------------------------- 3 files changed, 5 insertions(+), 47 deletions(-) (limited to 'client/components') diff --git a/client/components/activities/comments.js b/client/components/activities/comments.js index e885459e..50ca019b 100644 --- a/client/components/activities/comments.js +++ b/client/components/activities/comments.js @@ -33,13 +33,6 @@ BlazeComponent.extendComponent({ cardId, }); resetCommentInput(input); - // With Richer editor is in use, and comment is submitted, - // clear comment form with JQuery. Id #summernote is defined - // at client/components/main/editor.jade where it previously was - // id=id, now it is id="summernote". - if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR === 'true') { - $('#summernote').summernote('code', ''); - } Tracker.flush(); autosize.update(input); input.trigger('submitted'); diff --git a/client/components/main/editor.jade b/client/components/main/editor.jade index 5c5454ee..dbd61715 100644 --- a/client/components/main/editor.jade +++ b/client/components/main/editor.jade @@ -1,13 +1,8 @@ template(name="editor") - // With Richer editor is in use, and comment is submitted, - // clear comment form with JQuery Comment at - // client/components/activities/comments.js . Id #summernote is defined - // here at client/components/main/editor.jade where it previously was - // id=id, now it is id="summernote". textarea.editor( dir="auto" class="{{class}}" - id="summernote" + id=id autofocus=autofocus placeholder="{{_ 'comment-placeholder'}}") +Template.contentBlock diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 3f09d284..86c0078f 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -30,7 +30,7 @@ Template.editor.onRendered(() => { autosize($textarea); $textarea.escapeableTextComplete(mentions); }; - if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR === 'true') { + if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) { const isSmall = Utils.isMiniScreen(); const toolbar = isSmall ? [ @@ -108,37 +108,10 @@ Template.editor.onRendered(() => { } return undefined; }; - // Prevent @member mentions on Add Comment input field - // from closing card, part 1. - let popupShown = false; inputs.each(function(idx, input) { mSummernotes[idx] = $(input).summernote({ placeholder, - // Prevent @member mentions on Add Comment input field - // from closing card, part 2. - onKeydown(e) { - if (popupShown) { - e.preventDefault(); - } - }, - onKeyup(e) { - if (popupShown) { - e.preventDefault(); - } - }, callbacks: { - // Prevent @member mentions on Add Comment input field - // from closing card, part 3. - onKeydown(e) { - if (popupShown) { - e.preventDefault(); - } - }, - onKeyup(e) { - if (popupShown) { - e.preventDefault(); - } - }, onInit(object) { const originalInput = this; $(originalInput).on('input', function() { @@ -163,6 +136,7 @@ Template.editor.onRendered(() => { }); } }, + onImageUpload(files) { const $summernote = getSummernote(this); if (files && files.length > 0) { @@ -323,8 +297,7 @@ Blaze.Template.registerHelper( } const linkValue = [' ', at, knowedUser.username]; - //let linkClass = 'atMention js-open-member'; - let linkClass = 'atMention'; + let linkClass = 'atMention js-open-member'; if (knowedUser.userId === Meteor.userId()) { linkClass += ' me'; } @@ -367,10 +340,7 @@ Template.viewer.events({ const userId = event.currentTarget.dataset.userid; if (userId) { - // Prevent @member mentions on Add Comment input field - // from closing card, part 4. - PopupNoClose.open('member').call({ userId }, event, templateInstance); - event.preventDefault(); + Popup.open('member').call({ userId }, event, templateInstance); } else { const href = event.currentTarget.href; if (href) { -- cgit v1.2.3-1-g7c22 From 033d6710470b2ecd7a0ec0b2f0741ff459e68b32 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 31 Mar 2020 23:17:58 +0300 Subject: Fix richer editor submit did not clear edit area. Thanks to xet7 ! --- client/components/main/editor.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'client/components') diff --git a/client/components/main/editor.js b/client/components/main/editor.js index 86c0078f..081c6521 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -114,12 +114,11 @@ Template.editor.onRendered(() => { callbacks: { onInit(object) { const originalInput = this; - $(originalInput).on('input', function() { + $(originalInput).on('submitted', function() { // when comment is submitted, the original textarea will be set to '', so shall we if (!this.value) { const sn = getSummernote(this); - sn && sn.summernote('reset'); - object && object.editingArea.find('.note-placeholder').show(); + sn && sn.summernote('code', ''); } }); const jEditor = object && object.editable; @@ -223,7 +222,7 @@ Template.editor.onRendered(() => { // == Fix End == 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() { @@ -290,7 +289,8 @@ Blaze.Template.registerHelper( 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; @@ -330,14 +330,7 @@ Template.viewer.events({ // the corresponding text). Clicking a link shouldn't fire these actions, stop // we stop these event at the viewer component level. 'click a'(event, templateInstance) { - event.stopPropagation(); - - // XXX We hijack the build-in browser action because we currently don't have - // `_blank` attributes in viewer links, and the transformer function is - // handled by a third party package that we can't configure easily. Fix that - // by using directly `_blank` attribute in the rendered HTML. - event.preventDefault(); - + let prevent = true; const userId = event.currentTarget.dataset.userid; if (userId) { Popup.open('member').call({ userId }, event, templateInstance); @@ -347,5 +340,14 @@ Template.viewer.events({ window.open(href, '_blank'); } } + if (prevent) { + event.stopPropagation(); + + // XXX We hijack the build-in browser action because we currently don't have + // `_blank` attributes in viewer links, and the transformer function is + // handled by a third party package that we can't configure easily. Fix that + // by using directly `_blank` attribute in the rendered HTML. + event.preventDefault(); + } }, }); -- cgit v1.2.3-1-g7c22 From e7d23435934e044c90a1818f84798cb79194169c Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 31 Mar 2020 23:32:32 +0300 Subject: Move "Rules" from "Board View" to "Board Settings". Thanks to helioguardabaxo and xet7 ! Closes #2973 --- client/components/boards/boardHeader.jade | 14 -------------- client/components/boards/boardHeader.js | 4 ---- client/components/sidebar/sidebar.jade | 4 ++++ client/components/sidebar/sidebar.js | 4 ++++ 4 files changed, 8 insertions(+), 18 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 53a74f76..4c0edac4 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -193,20 +193,6 @@ template(name="boardChangeViewPopup") | {{_ '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 diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 9040ed83..dc553134 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -191,10 +191,6 @@ Template.boardChangeViewPopup.events({ Utils.setBoardView('board-view-cal'); Popup.close(); }, - 'click .js-open-rules-view'() { - Modal.openWide('rulesMain'); - Popup.close(); - }, }); const CreateBoard = BlazeComponent.extendComponent({ diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index f0b0e4be..901fe99f 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -267,6 +267,10 @@ template(name="outgoingWebhooksPopup") template(name="boardMenuPopup") ul.pop-over-list + li + a.js-open-rules-view(title="{{_ 'rules'}}") + i.fa.fa-magic + | {{_ 'rules'}} li a.js-custom-fields i.fa.fa-list-alt diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 8e640564..baf57114 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -182,6 +182,10 @@ Template.memberPopup.helpers({ Template.boardMenuPopup.events({ 'click .js-rename-board': Popup.open('boardChangeTitle'), + 'click .js-open-rules-view'() { + Modal.openWide('rulesMain'); + Popup.close(); + }, 'click .js-custom-fields'() { Sidebar.setView('customFields'); Popup.close(); -- cgit v1.2.3-1-g7c22 From 6b902bdb36205d74ac89d08fe4d91cc425c37fb6 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 31 Mar 2020 23:56:37 +0300 Subject: Improvements on card details visualization. Thanks to helioguardabaxo and xet7 ! Closes #2974 --- client/components/cards/attachments.jade | 2 +- client/components/cards/cardDetails.jade | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index b695ea41..61454fa7 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -55,5 +55,5 @@ template(name="attachmentsGalery") unless currentUser.isWorker //li.attachment-item.add-attachment a.js-add-attachment - i.fa.fa-paperclip + i.fa.fa-plus | {{_ 'add-attachment' }} diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 615ae1d5..257ca0a8 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -203,6 +203,7 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker if currentBoard.allowsDescriptionTitle + hr h3 i.fa.fa-align-left card-details-item-title {{_ 'description'}} @@ -229,6 +230,7 @@ template(name="cardDetails") a.js-close-inlined-form {{_ 'discard'}} else if getDescription if currentBoard.allowsDescriptionTitle + hr h3.card-details-item-title {{_ 'description'}} if currentBoard.allowsDescriptionText +viewer @@ -237,15 +239,16 @@ template(name="cardDetails") .card-checklist-attachmentGalerys .card-checklist-attachmentGalery.card-checklists if currentBoard.allowsChecklists + hr +checklists(cardId = _id) if currentBoard.allowsSubtasks hr +subtasks(cardId = _id) if currentBoard.allowsAttachments - //- hr - //- h3 - //- i.fa.fa-paperclip - //- | {{_ 'attachments'}} + hr + h3 + i.fa.fa-paperclip + | {{_ 'attachments'}} .card-checklist-attachmentGalery.card-attachmentGalery +attachmentsGalery -- cgit v1.2.3-1-g7c22 From d0003a334fdb39070e5ad31809c56665476f2f8f Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 1 Apr 2020 19:39:02 +0300 Subject: Minicard labels on the top and title on bottom. Thanks to helioguardabaxo and xet7 ! Closes #2980 --- client/components/cards/minicard.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 8607e118..7d72a588 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -79,7 +79,7 @@ border-radius: top 2px .minicard-labels - float: right + float: none display: flex flex-wrap: wrap -- cgit v1.2.3-1-g7c22 From f4d0791c6c1051c90d268484dab03c0ea5a5a533 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Wed, 1 Apr 2020 14:50:31 -0600 Subject: add correct i18n for notifications menu --- client/components/notifications/notificationsDrawer.jade | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'client/components') diff --git a/client/components/notifications/notificationsDrawer.jade b/client/components/notifications/notificationsDrawer.jade index 67fc6e65..01117009 100644 --- a/client/components/notifications/notificationsDrawer.jade +++ b/client/components/notifications/notificationsDrawer.jade @@ -2,10 +2,10 @@ template(name='notificationsDrawer') section#notifications-drawer(class="{{#if $.Session.get 'showReadNotifications'}}show-read{{/if}}") .header if $.Session.get 'showReadNotifications' - a.toggle-read Filter by Unread + a.toggle-read {{_ 'filter-by-unread'}} else - a.toggle-read View All - h5 Notifications + a.toggle-read {{_ 'view-all'}} + h5 {{_ 'notifications'}} if($gt unreadNotifications 0) |(#{unreadNotifications}) a.fa.fa-times-thin.close @@ -13,4 +13,4 @@ template(name='notificationsDrawer') each transformedProfile.notifications +notification(activityData=activity index=dbIndex read=read) if($gt unreadNotifications 0) - a.all-read Mark all as read + a.all-read {{_ 'mark-all-as-read'}} -- cgit v1.2.3-1-g7c22 From 89fe030fa35ea24195ac366aaf3a1c917b305249 Mon Sep 17 00:00:00 2001 From: Daniel Eder Date: Thu, 2 Apr 2020 07:49:26 +0200 Subject: subtasks now use swimlane with title matching parent lane title As discussed in #1953 this is required to handle two-board scenarios correctly. --- client/components/cards/subtasks.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index fad859e7..cdc227fc 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -20,7 +20,13 @@ BlazeComponent.extendComponent({ const crtBoard = Boards.findOne(card.boardId); const targetBoard = crtBoard.getDefaultSubtasksBoard(); const listId = targetBoard.getDefaultSubtasksListId(); - const swimlaneId = card.swimlaneId; + + //Get the full swimlane data for the parent task. + const parentSwimlane = Swimlanes.findOne({boardId: crtBoard._id, _id: card.swimlaneId}); + //find the swimlane of the same name in the target board. + const targetSwimlane = Swimlanes.findOne({boardId: targetBoard._id, title: parentSwimlane.title}); + //If no swimlane with a matching title exists in the target board, fall back to the default swimlane. + const swimlaneId = targetSwimlane === undefined ? targetBoard.getDefaultSwimline()._id : targetSwimlane._id; if (title) { const _id = Cards.insert({ -- cgit v1.2.3-1-g7c22 From b849d4c2ba088554a68d00b87afc249a1d3fa180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Will=20=E4=BF=9D=E5=93=A5?= Date: Mon, 6 Apr 2020 18:16:17 +0800 Subject: Update layouts.js --- client/components/main/layouts.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'client/components') diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index ec4a35cc..a4768900 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -73,6 +73,8 @@ Template.userFormsLayout.helpers({ name = 'Igbo'; } else if (lang.name === 'oc') { name = 'Occitan'; + } else if (lang.name === 'zh-TW') { + name = '繁體中文(台灣)'; } return { tag, name }; }).sort(function(a, b) { -- cgit v1.2.3-1-g7c22 From e0930c32a609813c154acec9b3015ad0b095d462 Mon Sep 17 00:00:00 2001 From: Will Date: Tue, 7 Apr 2020 09:43:23 +0000 Subject: Correct zh-TW language name (the right way) --- client/components/main/layouts.js | 2 +- client/components/users/userHeader.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index a4768900..e5c86d76 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -73,7 +73,7 @@ Template.userFormsLayout.helpers({ name = 'Igbo'; } else if (lang.name === 'oc') { name = 'Occitan'; - } else if (lang.name === 'zh-TW') { + } else if (lang.name === '繁体中文(台湾)') { name = '繁體中文(台灣)'; } return { tag, name }; diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 847d30fb..cd315bd6 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -166,6 +166,8 @@ Template.changeLanguagePopup.helpers({ name = 'Igbo'; } else if (lang.name === 'oc') { name = 'Occitan'; + } else if (lang.name === '繁体中文(台湾)') { + name = '繁體中文(台灣)'; } return { tag, name }; }).sort(function(a, b) { -- cgit v1.2.3-1-g7c22 From 2bbc312ad0600da06b7d18f57630ad19cd90efd2 Mon Sep 17 00:00:00 2001 From: Nico Date: Tue, 7 Apr 2020 20:43:35 +0200 Subject: Voteing feature --- client/components/cards/cardDetails.jade | 37 +++++++++++++++ client/components/cards/cardDetails.js | 77 +++++++++++++++++++++++++++++--- client/components/cards/cardDetails.styl | 8 ++++ client/components/cards/minicard.jade | 4 ++ 4 files changed, 121 insertions(+), 5 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 257ca0a8..9cd581ea 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -199,6 +199,24 @@ template(name="cardDetails") +viewer = getAssignedBy + if getVoteQuestion + hr + .vote-title + h3 + i.fa.fa-thumbs-up + card-details-item-title {{_ 'vote-question'}} + .vote-result + .card-label.card-label-green + +viewer + = voteCountPositive + .card-label.card-label-red + +viewer + = voteCountNegative + +viewer + = getVoteQuestion + button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") {{_ 'vote-for-it'}} + button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}") {{_ 'vote-against'}} + //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard unless currentUser.isWorker @@ -315,6 +333,16 @@ template(name="cardDetailsActionsPopup") //li: a.js-members {{_ 'card-edit-members'}} //li: a.js-labels {{_ 'card-edit-labels'}} //li: a.js-attachments {{_ 'card-edit-attachments'}} + if getVoteQuestion + li + a.js-cancel-voting + i.fa.fa-thumbs-up + | {{_ 'card-cancel-voting'}} + else + li + a.js-start-voting + i.fa.fa-thumbs-up + | {{_ 'card-start-voting'}} li a.js-custom-fields i.fa.fa-list-alt @@ -538,3 +566,12 @@ template(name="cardDeletePopup") unless archived p {{_ "card-delete-suggest-archive"}} button.js-confirm.negate.full(type="submit") {{_ 'delete'}} + +template(name="cardStartVotingPopup") + form.edit-vote-question + .fields + label(for="vote") {{_ 'vote-question'}} + input.js-vote-field#vote(type="text" name="vote" value="{{card.getVoteQuestion}}" autofocus) + + button.primary.confirm.js-submit {{_ 'save'}} + //- button.js-remove-color.negate.wide.right {{_ 'delete'}} diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 5fdc5579..8492393c 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -38,6 +38,34 @@ BlazeComponent.extendComponent({ Meteor.subscribe('unsaved-edits'); }, + voteState() { + const card = this.currentData(); + const userId = Meteor.userId() + let state + if (card.vote) { + if (card.vote.positive) { + state = _.contains(card.vote.positive, userId); + if (state === true) return true + } + if (card.vote.negative) { + state = _.contains(card.vote.negative, userId); + if (state === true) return false + } + } + return null + }, + voteCountPositive() { + const card = this.currentData(); + if (card.vote && card.vote.positive) + return card.vote.positive.length + return null + }, + voteCountNegative() { + const card = this.currentData(); + if (card.vote && card.vote.negative) + return card.vote.negative.length + return null + }, isWatching() { const card = this.currentData(); return card.findWatcher(Meteor.userId()); @@ -379,6 +407,18 @@ BlazeComponent.extendComponent({ 'click #toggleButton'() { Meteor.call('toggleSystemMessages'); }, + 'click .js-vote'(e) { + const forIt = $(e.target).hasClass('js-vote-positive') + let newState = null + if ( + this.voteState() == null || + this.voteState() == false && forIt || + this.voteState() == true && !forIt + ) { + newState = forIt + } + this.data().setVote(Meteor.userId(), newState) + } }, ]; }, @@ -560,6 +600,7 @@ Template.cardDetailsActionsPopup.events({ 'click .js-assignees': Popup.open('cardAssignees'), 'click .js-labels': Popup.open('cardLabels'), 'click .js-attachments': Popup.open('cardAttachments'), + 'click .js-start-voting': Popup.open('cardStartVoting'), 'click .js-custom-fields': Popup.open('cardCustomFields'), 'click .js-received-date': Popup.open('editCardReceivedDate'), 'click .js-start-date': Popup.open('editCardStartDate'), @@ -570,6 +611,11 @@ Template.cardDetailsActionsPopup.events({ 'click .js-copy-card': Popup.open('copyCard'), 'click .js-copy-checklist-cards': Popup.open('copyChecklistToManyCards'), 'click .js-set-card-color': Popup.open('setCardColor'), + 'click .js-cancel-voting'(event) { + event.preventDefault(); + this.unsetVote() + Popup.close(); + }, 'click .js-move-card-to-top'(event) { event.preventDefault(); const minOrder = _.min( @@ -603,7 +649,7 @@ Template.cardDetailsActionsPopup.events({ }, }); -Template.editCardTitleForm.onRendered(function() { +Template.editCardTitleForm.onRendered(function () { autosize(this.$('.js-edit-card-title')); }); @@ -617,7 +663,7 @@ Template.editCardTitleForm.events({ }, }); -Template.editCardRequesterForm.onRendered(function() { +Template.editCardRequesterForm.onRendered(function () { autosize(this.$('.js-edit-card-requester')); }); @@ -630,7 +676,7 @@ Template.editCardRequesterForm.events({ }, }); -Template.editCardAssignerForm.onRendered(function() { +Template.editCardAssignerForm.onRendered(function () { autosize(this.$('.js-edit-card-assigner')); }); @@ -770,7 +816,7 @@ Template.copyChecklistToManyCardsPopup.events({ // copy subtasks cursor = Cards.find({ parentId: oldId }); - cursor.forEach(function() { + cursor.forEach(function () { 'use strict'; const subtask = arguments[0]; subtask.parentId = _id; @@ -919,7 +965,7 @@ BlazeComponent.extendComponent({ } } }, - 'click .js-delete': Popup.afterConfirm('cardDelete', function() { + 'click .js-delete': Popup.afterConfirm('cardDelete', function () { Popup.close(); Cards.remove(this._id); Utils.goBoardId(this.boardId); @@ -945,6 +991,27 @@ BlazeComponent.extendComponent({ }, }).register('cardMorePopup'); +BlazeComponent.extendComponent({ + onCreated() { + this.currentCard = this.currentData(); + this.voteQuestion = new ReactiveVar(this.currentCard.voteQuestion); + }, + + events() { + return [ + { + 'submit .edit-vote-question'(evt) { + evt.preventDefault(); + const voteQuestion = evt.target.vote.value; + this.currentCard.setVoteQuestion(voteQuestion) + Popup.close(); + + }, + }, + ]; + }, +}).register('cardStartVotingPopup'); + // Close the card details pane by pressing escape EscapeActions.register( 'detailsPane', diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index 80fa87c0..9bbbf075 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -330,3 +330,11 @@ card-details-color(background, color...) .card-details-indigo card-details-color(#4b0082, #ffffff) //White text for better visibility + +.voted + opacity: .7 +.vote-title + display: flex; + justify-content: space-between; +.vote-result + display: flex; diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index a895c0a3..0b881a54 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -100,6 +100,10 @@ template(name="minicard") if getDescription .badge.badge-state-image-only(title=getDescription) span.badge-icon.fa.fa-align-left + if getVoteQuestion + .badge.badge-state-image-only(title=getVoteQuestion) + span.badge-icon.fa.fa-thumbs-up + span.badge-icon.fa.fa-thumbs-down if attachments.count .badge span.badge-icon.fa.fa-paperclip -- cgit v1.2.3-1-g7c22 From fe285c62e12486a8848376531c89d7a4b11b7fa7 Mon Sep 17 00:00:00 2001 From: Daniel Eder Date: Wed, 8 Apr 2020 16:54:11 +0300 Subject: Add filter option for assignee Works exactly like member --- client/components/sidebar/sidebarFilters.jade | 18 ++++++++++++++++++ client/components/sidebar/sidebarFilters.js | 5 +++++ 2 files changed, 23 insertions(+) (limited to 'client/components') diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 7f31dada..6d899b70 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -45,6 +45,24 @@ template(name="filterSidebar") if Filter.members.isSelected _id i.fa.fa-check hr + ul.sidebar-list + li(class="{{#if Filter.assignees.isSelected undefined}}active{{/if}}") + a.name.js-toggle-assignee-filter + span.sidebar-list-item-description + | {{_ 'filter-no-assignee'}} + if Filter.assignees.isSelected undefined + i.fa.fa-check + each currentBoard.activeMembers + with getUser userId + li(class="{{#if Filter.assignees.isSelected _id}}active{{/if}}") + a.name.js-toggle-assignee-filter + +userAvatar(userId=this._id) + span.sidebar-list-item-description + = profile.fullname + | ({{ username }}) + if Filter.assignees.isSelected _id + i.fa.fa-check + hr ul.sidebar-list li(class="{{#if Filter.customFields.isSelected undefined}}active{{/if}}") a.name.js-toggle-custom-fields-filter diff --git a/client/components/sidebar/sidebarFilters.js b/client/components/sidebar/sidebarFilters.js index ee0176b9..0d402ab5 100644 --- a/client/components/sidebar/sidebarFilters.js +++ b/client/components/sidebar/sidebarFilters.js @@ -18,6 +18,11 @@ BlazeComponent.extendComponent({ Filter.members.toggle(this.currentData()._id); Filter.resetExceptions(); }, + 'click .js-toggle-assignee-filter'(evt) { + evt.preventDefault(); + Filter.assignees.toggle(this.currentData()._id); + Filter.resetExceptions(); + }, 'click .js-toggle-archive-filter'(evt) { evt.preventDefault(); Filter.archive.toggle(this.currentData()._id); -- cgit v1.2.3-1-g7c22 From 968ae122b0386876dcfe3b8414e5a5b94b4b28ae Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 8 Apr 2020 19:38:30 +0300 Subject: Fix typos. --- client/components/cards/cardDetails.styl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index 9bbbf075..6b3ca91c 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -100,11 +100,11 @@ avatar-radius = 50% .ps-scrollbar-y-rail pointer-event: all - position: absolute; + position: absolute .card-details-canvas width: 470px - padding-left: 20px; + padding-left: 20px .card-details-header margin: 0 -20px 5px @@ -241,7 +241,7 @@ input[type="submit"].attachment-add-link-submit .card-details-canvas width: 100% - padding-left: 0px; + padding-left: 0px .card-details-header .close-card-details @@ -334,7 +334,7 @@ card-details-color(background, color...) .voted opacity: .7 .vote-title - display: flex; - justify-content: space-between; + display: flex + justify-content: space-between .vote-result - display: flex; + display: flex -- cgit v1.2.3-1-g7c22 From a182dde11ff4f1ab8cd01a04e1e26affda5d8a3b Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Wed, 8 Apr 2020 13:14:29 -0600 Subject: add a "remove all read" button to notification menu --- client/components/notifications/notificationsDrawer.jade | 4 ++++ client/components/notifications/notificationsDrawer.js | 15 +++++++++++++++ client/components/notifications/notificationsDrawer.styl | 13 ++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/notifications/notificationsDrawer.jade b/client/components/notifications/notificationsDrawer.jade index 01117009..fee6aef6 100644 --- a/client/components/notifications/notificationsDrawer.jade +++ b/client/components/notifications/notificationsDrawer.jade @@ -14,3 +14,7 @@ template(name='notificationsDrawer') +notification(activityData=activity index=dbIndex read=read) if($gt unreadNotifications 0) a.all-read {{_ 'mark-all-as-read'}} + if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0)) + a.remove-read + i.fa.fa-trash + | {{_ 'remove-all-read'}} diff --git a/client/components/notifications/notificationsDrawer.js b/client/components/notifications/notificationsDrawer.js index 98d4750d..76abeea7 100644 --- a/client/components/notifications/notificationsDrawer.js +++ b/client/components/notifications/notificationsDrawer.js @@ -16,6 +16,13 @@ Template.notificationsDrawer.helpers({ transformedProfile() { return Users.findOne(Meteor.userId()); }, + readNotifications() { + const readNotifications = _.filter( + Meteor.user().profile.notifications, + v => !!v.read, + ); + return readNotifications.length; + }, }); Template.notificationsDrawer.events({ @@ -35,4 +42,12 @@ Template.notificationsDrawer.events({ 'click .toggle-read'() { Session.set('showReadNotifications', !Session.get('showReadNotifications')); }, + 'click .remove-read'() { + const user = Meteor.user(); + for (const notification of user.profile.notifications) { + if (notification.read) { + user.removeNotification(notification.activity); + } + } + }, }); diff --git a/client/components/notifications/notificationsDrawer.styl b/client/components/notifications/notificationsDrawer.styl index a26b5e4a..b64f13f4 100644 --- a/client/components/notifications/notificationsDrawer.styl +++ b/client/components/notifications/notificationsDrawer.styl @@ -45,12 +45,23 @@ section#notifications-drawer line-height: 24px opacity 1 - .all-read + .all-read, + .remove-read color belize background-color: #fafafa margin 8px 16px 12px display inline-block + .remove-read + float right + + &:hover + color #eb4646 !important + + i.fa + color inherit + + ul.notifications display: block padding: 0px 16px -- cgit v1.2.3-1-g7c22 From 5ebb47cb0ec7272894a37d99579ede872251f55c Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 8 Apr 2020 23:16:48 +0300 Subject: Add setting default NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE=2 to all Wekan platforms https://github.com/wekan/wekan/pull/2998 Thanks to xet7 ! --- client/components/cards/cardDetails.js | 49 ++++++++++++++++------------------ client/components/cards/subtasks.js | 15 ++++++++--- 2 files changed, 35 insertions(+), 29 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 8492393c..84ba21b1 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -40,31 +40,29 @@ BlazeComponent.extendComponent({ voteState() { const card = this.currentData(); - const userId = Meteor.userId() - let state + const userId = Meteor.userId(); + let state; if (card.vote) { if (card.vote.positive) { state = _.contains(card.vote.positive, userId); - if (state === true) return true + if (state === true) return true; } if (card.vote.negative) { state = _.contains(card.vote.negative, userId); - if (state === true) return false + if (state === true) return false; } } - return null + return null; }, voteCountPositive() { const card = this.currentData(); - if (card.vote && card.vote.positive) - return card.vote.positive.length - return null + if (card.vote && card.vote.positive) return card.vote.positive.length; + return null; }, voteCountNegative() { const card = this.currentData(); - if (card.vote && card.vote.negative) - return card.vote.negative.length - return null + if (card.vote && card.vote.negative) return card.vote.negative.length; + return null; }, isWatching() { const card = this.currentData(); @@ -408,17 +406,17 @@ BlazeComponent.extendComponent({ Meteor.call('toggleSystemMessages'); }, 'click .js-vote'(e) { - const forIt = $(e.target).hasClass('js-vote-positive') - let newState = null + const forIt = $(e.target).hasClass('js-vote-positive'); + let newState = null; if ( this.voteState() == null || - this.voteState() == false && forIt || - this.voteState() == true && !forIt + (this.voteState() == false && forIt) || + (this.voteState() == true && !forIt) ) { - newState = forIt + newState = forIt; } - this.data().setVote(Meteor.userId(), newState) - } + this.data().setVote(Meteor.userId(), newState); + }, }, ]; }, @@ -613,7 +611,7 @@ Template.cardDetailsActionsPopup.events({ 'click .js-set-card-color': Popup.open('setCardColor'), 'click .js-cancel-voting'(event) { event.preventDefault(); - this.unsetVote() + this.unsetVote(); Popup.close(); }, 'click .js-move-card-to-top'(event) { @@ -649,7 +647,7 @@ Template.cardDetailsActionsPopup.events({ }, }); -Template.editCardTitleForm.onRendered(function () { +Template.editCardTitleForm.onRendered(function() { autosize(this.$('.js-edit-card-title')); }); @@ -663,7 +661,7 @@ Template.editCardTitleForm.events({ }, }); -Template.editCardRequesterForm.onRendered(function () { +Template.editCardRequesterForm.onRendered(function() { autosize(this.$('.js-edit-card-requester')); }); @@ -676,7 +674,7 @@ Template.editCardRequesterForm.events({ }, }); -Template.editCardAssignerForm.onRendered(function () { +Template.editCardAssignerForm.onRendered(function() { autosize(this.$('.js-edit-card-assigner')); }); @@ -816,7 +814,7 @@ Template.copyChecklistToManyCardsPopup.events({ // copy subtasks cursor = Cards.find({ parentId: oldId }); - cursor.forEach(function () { + cursor.forEach(function() { 'use strict'; const subtask = arguments[0]; subtask.parentId = _id; @@ -965,7 +963,7 @@ BlazeComponent.extendComponent({ } } }, - 'click .js-delete': Popup.afterConfirm('cardDelete', function () { + 'click .js-delete': Popup.afterConfirm('cardDelete', function() { Popup.close(); Cards.remove(this._id); Utils.goBoardId(this.boardId); @@ -1003,9 +1001,8 @@ BlazeComponent.extendComponent({ 'submit .edit-vote-question'(evt) { evt.preventDefault(); const voteQuestion = evt.target.vote.value; - this.currentCard.setVoteQuestion(voteQuestion) + this.currentCard.setVoteQuestion(voteQuestion); Popup.close(); - }, }, ]; diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index cdc227fc..4cd15c11 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -22,11 +22,20 @@ BlazeComponent.extendComponent({ const listId = targetBoard.getDefaultSubtasksListId(); //Get the full swimlane data for the parent task. - const parentSwimlane = Swimlanes.findOne({boardId: crtBoard._id, _id: card.swimlaneId}); + const parentSwimlane = Swimlanes.findOne({ + boardId: crtBoard._id, + _id: card.swimlaneId, + }); //find the swimlane of the same name in the target board. - const targetSwimlane = Swimlanes.findOne({boardId: targetBoard._id, title: parentSwimlane.title}); + const targetSwimlane = Swimlanes.findOne({ + boardId: targetBoard._id, + title: parentSwimlane.title, + }); //If no swimlane with a matching title exists in the target board, fall back to the default swimlane. - const swimlaneId = targetSwimlane === undefined ? targetBoard.getDefaultSwimline()._id : targetSwimlane._id; + const swimlaneId = + targetSwimlane === undefined + ? targetBoard.getDefaultSwimline()._id + : targetSwimlane._id; if (title) { const _id = Cards.insert({ -- cgit v1.2.3-1-g7c22 From f09219cbfd620e04fd48539bd11eced20c81137b Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 9 Apr 2020 01:55:01 +0200 Subject: Remove export button if WITH_API is not enabled #2938 https://github.com/wekan/wekan/issues/2938#issuecomment-589782402 --- client/components/boards/boardHeader.js | 16 ---------------- client/components/sidebar/sidebar.jade | 20 +++++++++++--------- client/components/sidebar/sidebar.js | 19 +++++++++++++++---- 3 files changed, 26 insertions(+), 29 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index dc553134..be0146ec 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -33,22 +33,6 @@ Template.boardMenuPopup.events({ 'click .js-card-settings': Popup.open('boardCardSettings'), }); -Template.boardMenuPopup.helpers({ - exportUrl() { - const params = { - boardId: Session.get('currentBoard'), - }; - const queryParams = { - authToken: Accounts._storedLoginToken(), - }; - return FlowRouter.path('/api/boards/:boardId/export', params, queryParams); - }, - exportFilename() { - const boardId = Session.get('currentBoard'); - return `wekan-export-board-${boardId}.json`; - }, -}); - Template.boardChangeTitlePopup.events({ submit(event, templateInstance) { const newTitle = templateInstance diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 901fe99f..6bfedc9c 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -298,10 +298,11 @@ template(name="boardMenuPopup") if currentUser.isBoardAdmin hr ul.pop-over-list - li - a(href="{{exportUrl}}", download="{{exportFilename}}") - i.fa.fa-share-alt - | {{_ 'export-board'}} + if withApi + li + a(href="{{exportUrl}}", download="{{exportFilename}}") + i.fa.fa-share-alt + | {{_ 'export-board'}} li a.js-outgoing-webhooks i.fa.fa-globe @@ -326,11 +327,12 @@ template(name="boardMenuPopup") if isSandstorm hr ul.pop-over-list - li - a(href="{{exportUrl}}", download="{{exportFilename}}") - i.fa.fa-share-alt - i.fa.fa-sign-out - | {{_ 'export-board'}} + if withApi + li + a(href="{{exportUrl}}", download="{{exportFilename}}") + i.fa.fa-share-alt + i.fa.fa-sign-out + | {{_ 'export-board'}} li a.js-import-board i.fa.fa-share-alt diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index baf57114..78b47a48 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -196,14 +196,14 @@ Template.boardMenuPopup.events({ }, 'click .js-change-board-color': Popup.open('boardChangeColor'), 'click .js-change-language': Popup.open('changeLanguage'), - 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() { + 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function () { const currentBoard = Boards.findOne(Session.get('currentBoard')); currentBoard.archive(); // XXX We should have some kind of notification on top of the page to // confirm that the board was successfully archived. FlowRouter.go('home'); }), - 'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() { + 'click .js-delete-board': Popup.afterConfirm('deleteBoard', function () { const currentBoard = Boards.findOne(Session.get('currentBoard')); Popup.close(); Boards.remove(currentBoard._id); @@ -215,7 +215,18 @@ Template.boardMenuPopup.events({ 'click .js-card-settings': Popup.open('boardCardSettings'), }); + +Template.boardMenuPopup.onCreated(function () { + this.apiEnabled = new ReactiveVar(false); + Meteor.call('_isApiEnabled', (e, result) => { + this.apiEnabled.set(result) + }) +}) + Template.boardMenuPopup.helpers({ + withApi() { + return Template.instance().apiEnabled.get() + }, exportUrl() { const params = { boardId: Session.get('currentBoard'), @@ -237,7 +248,7 @@ Template.memberPopup.events({ Popup.close(); }, 'click .js-change-role': Popup.open('changePermissions'), - 'click .js-remove-member': Popup.afterConfirm('removeMember', function() { + 'click .js-remove-member': Popup.afterConfirm('removeMember', function () { const boardId = Session.get('currentBoard'); const memberId = this.userId; Cards.find({ boardId, members: memberId }).forEach(card => { @@ -578,7 +589,7 @@ BlazeComponent.extendComponent({ 'subtext-with-parent', 'no-parent', ]; - options.forEach(function(element) { + options.forEach(function (element) { if (element !== value) { $(`#${element} ${MCB}`).toggleClass(CKCLS, false); $(`#${element}`).toggleClass(CKCLS, false); -- cgit v1.2.3-1-g7c22 From fe6616941505b82d503899e2e27d5a2e95f39db3 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Thu, 9 Apr 2020 12:46:24 -0600 Subject: fix bug that prevents editing or deleting comments --- client/components/activities/activities.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'client/components') diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js index 36214e19..5d356f6e 100644 --- a/client/components/activities/activities.js +++ b/client/components/activities/activities.js @@ -180,7 +180,7 @@ BlazeComponent.extendComponent({ { // XXX We should use Popup.afterConfirmation here 'click .js-delete-comment'() { - const commentId = this.currentData().commentId; + const commentId = this.currentData().activity.commentId; CardComments.remove(commentId); }, 'submit .js-edit-comment'(evt) { @@ -188,7 +188,7 @@ BlazeComponent.extendComponent({ const commentText = this.currentComponent() .getValue() .trim(); - const commentId = Template.parentData().commentId; + const commentId = Template.parentData().activity.commentId; if (commentText) { CardComments.update(commentId, { $set: { -- cgit v1.2.3-1-g7c22 From 8f28a409c7dd90319f785e3fc4c1b26803f67f31 Mon Sep 17 00:00:00 2001 From: Nico Date: Fri, 10 Apr 2020 01:46:36 +0200 Subject: Public vote --- client/components/cards/cardDetails.jade | 35 ++++++++++++++++++++++++++------ client/components/cards/cardDetails.js | 25 +++++++++++++++++------ client/components/cards/cardDetails.styl | 2 ++ 3 files changed, 50 insertions(+), 12 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 9cd581ea..99606ae4 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -206,12 +206,12 @@ template(name="cardDetails") i.fa.fa-thumbs-up card-details-item-title {{_ 'vote-question'}} .vote-result - .card-label.card-label-green - +viewer - = voteCountPositive - .card-label.card-label-red - +viewer - = voteCountNegative + if votePublic + a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }} + a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }} + else + .card-label.card-label-green {{ voteCountPositive }} + .card-label.card-label-red {{ voteCountNegative }} +viewer = getVoteQuestion button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") {{_ 'vote-for-it'}} @@ -572,6 +572,29 @@ template(name="cardStartVotingPopup") .fields label(for="vote") {{_ 'vote-question'}} input.js-vote-field#vote(type="text" name="vote" value="{{card.getVoteQuestion}}" autofocus) + label(for="vote-public") {{_ 'vote-public'}} + a.js-toggle-vote-public + .materialCheckBox#vote-public(name="vote-public") button.primary.confirm.js-submit {{_ 'save'}} //- button.js-remove-color.negate.wide.right {{_ 'delete'}} + +template(name="positiveVoteMembersPopup") + ul.pop-over-list.js-card-member-list + each m in voteMemberPositive + li.item + a.name + +userAvatar(userId=m._id) + span.full-name + = m.profile.fullname + | ({{ m.username }}) + +template(name="negativeVoteMembersPopup") + ul.pop-over-list.js-card-member-list + each m in voteMemberNegative + li.item + a.name + +userAvatar(userId=m._id) + span.full-name + = m.profile.fullname + | ({{ m.username }}) diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 84ba21b1..6ca5d784 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -54,6 +54,12 @@ BlazeComponent.extendComponent({ } return null; }, + votePublic() { + const card = this.currentData(); + if (card.vote) + return card.vote.public + return null + }, voteCountPositive() { const card = this.currentData(); if (card.vote && card.vote.positive) return card.vote.positive.length; @@ -382,6 +388,8 @@ BlazeComponent.extendComponent({ 'click .js-start-date': Popup.open('editCardStartDate'), 'click .js-due-date': Popup.open('editCardDueDate'), 'click .js-end-date': Popup.open('editCardEndDate'), + 'click .js-show-positive-votes':Popup.open('positiveVoteMembers'), + 'click .js-show-negative-votes': Popup.open('negativeVoteMembers'), 'mouseenter .js-card-details'() { const parentComponent = this.parentComponent().parentComponent(); //on mobile view parent is Board, not BoardBody. @@ -647,7 +655,7 @@ Template.cardDetailsActionsPopup.events({ }, }); -Template.editCardTitleForm.onRendered(function() { +Template.editCardTitleForm.onRendered(function () { autosize(this.$('.js-edit-card-title')); }); @@ -661,7 +669,7 @@ Template.editCardTitleForm.events({ }, }); -Template.editCardRequesterForm.onRendered(function() { +Template.editCardRequesterForm.onRendered(function () { autosize(this.$('.js-edit-card-requester')); }); @@ -674,7 +682,7 @@ Template.editCardRequesterForm.events({ }, }); -Template.editCardAssignerForm.onRendered(function() { +Template.editCardAssignerForm.onRendered(function () { autosize(this.$('.js-edit-card-assigner')); }); @@ -814,7 +822,7 @@ Template.copyChecklistToManyCardsPopup.events({ // copy subtasks cursor = Cards.find({ parentId: oldId }); - cursor.forEach(function() { + cursor.forEach(function () { 'use strict'; const subtask = arguments[0]; subtask.parentId = _id; @@ -963,7 +971,7 @@ BlazeComponent.extendComponent({ } } }, - 'click .js-delete': Popup.afterConfirm('cardDelete', function() { + 'click .js-delete': Popup.afterConfirm('cardDelete', function () { Popup.close(); Cards.remove(this._id); Utils.goBoardId(this.boardId); @@ -1001,9 +1009,14 @@ BlazeComponent.extendComponent({ 'submit .edit-vote-question'(evt) { evt.preventDefault(); const voteQuestion = evt.target.vote.value; - this.currentCard.setVoteQuestion(voteQuestion); + const publicVote = $('#vote-public').hasClass('is-checked'); + this.currentCard.setVoteQuestion(voteQuestion, publicVote); Popup.close(); }, + 'click a.js-toggle-vote-public'(event) { + event.preventDefault(); + $('#vote-public').toggleClass('is-checked'); + }, }, ]; }, diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index 6b3ca91c..199a12da 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -338,3 +338,5 @@ card-details-color(background, color...) justify-content: space-between .vote-result display: flex +.js-show-positive-votes + cursor: pointer -- cgit v1.2.3-1-g7c22 From edf52bc4382823ed8768251954371094a849213e Mon Sep 17 00:00:00 2001 From: Nico Date: Sun, 12 Apr 2020 00:56:35 +0200 Subject: Public boards overview --- client/components/boards/boardsList.jade | 2 +- client/components/boards/boardsList.js | 18 +++++++++++++----- client/components/main/header.jade | 5 +++++ client/components/main/header.styl | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index 79bae502..f1118aa8 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -55,7 +55,7 @@ template(name="boardList") title="{{_ 'archive-board'}}") template(name="boardListHeaderBar") - h1 {{_ 'my-boards'}} + h1 {{_ title }} .board-header-btns.right a.board-header-btn.js-open-archived-board i.fa.fa-archive diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 3918af82..0ff1c4fb 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -7,6 +7,9 @@ Template.boardListHeaderBar.events({ }); Template.boardListHeaderBar.helpers({ + title(){ + return FlowRouter.getRouteName() == 'home' ? 'my-boards' :'public'; + }, templatesBoardId() { return Meteor.user() && Meteor.user().getTemplatesBoardId(); }, @@ -21,12 +24,17 @@ BlazeComponent.extendComponent({ }, boards() { + let query = { + archived: false, + type: 'board', + } + if (FlowRouter.getRouteName() == 'home') + query['members.userId'] = Meteor.userId() + else + query.permission = 'public' + return Boards.find( - { - archived: false, - 'members.userId': Meteor.userId(), - type: 'board', - }, + query, { sort: ['title'] }, ); }, diff --git a/client/components/main/header.jade b/client/components/main/header.jade index 9a5a6b9b..de7ead93 100644 --- a/client/components/main/header.jade +++ b/client/components/main/header.jade @@ -24,6 +24,11 @@ template(name="header") a(href="{{pathFor 'home'}}") span.fa.fa-home | {{_ 'all-boards'}} + li.separator - + li + a(href="{{pathFor 'public'}}") + span.fa.fa-globe + | {{_ 'public'}} each currentUser.starredBoards li.separator - li(class="{{#if $.Session.equals 'currentBoard' _id}}current{{/if}}") diff --git a/client/components/main/header.styl b/client/components/main/header.styl index 632d1535..38ff0560 100644 --- a/client/components/main/header.styl +++ b/client/components/main/header.styl @@ -127,7 +127,7 @@ &.current color: darken(white, 5%) - &:first-child .fa-home + &:first-child .fa-home,&:nth-child(3) .fa-globe margin-right: 5px a.js-create-board -- cgit v1.2.3-1-g7c22 From 9cacaafb8f93b7043b9d88550ca20615bb1d921e Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Sun, 12 Apr 2020 11:47:30 +0200 Subject: Fix styling issue in notifications drawer The header of the notification drawer had a margin to the right side in Google Chrome caused by overflow: scroll on the #notifications-drawer element. --- client/components/notifications/notificationsDrawer.styl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'client/components') diff --git a/client/components/notifications/notificationsDrawer.styl b/client/components/notifications/notificationsDrawer.styl index b64f13f4..f99e1299 100644 --- a/client/components/notifications/notificationsDrawer.styl +++ b/client/components/notifications/notificationsDrawer.styl @@ -10,8 +10,7 @@ section#notifications-drawer border-radius: 2px max-height: calc(100vh - 28px - 36px) color: black - padding-top 36px; - overflow: scroll + padding-top 36px a:hover color: belize !important @@ -66,3 +65,5 @@ section#notifications-drawer display: block padding: 0px 16px margin: 0 + height: calc(100vh - 102px) + overflow-y: scroll -- cgit v1.2.3-1-g7c22 From 35ae07e2a65c5ab5ba6784cdb67631918a41ccc3 Mon Sep 17 00:00:00 2001 From: salleman Date: Mon, 13 Apr 2020 15:46:29 +0200 Subject: debug isBoardAdmin on main page --- client/components/boards/boardsList.jade | 2 +- client/components/boards/boardsList.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index f1118aa8..46086693 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -39,7 +39,7 @@ template(name="boardList") i.fa.js-archive-board( class="fa-archive" title="{{_ 'archive-board'}}") - else if currentUser.isBoardAdmin + else if isAdministrable i.fa.js-clone-board( class="fa-clone" title="{{_ 'duplicate-board'}}") diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 0ff1c4fb..65bed16a 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -42,6 +42,10 @@ BlazeComponent.extendComponent({ const user = Meteor.user(); return user && user.hasStarred(this.currentData()._id); }, + isAdministrable() { + const user = Meteor.user(); + return user && user.isBoardAdmin(this.currentData()._id); + }, hasOvertimeCards() { subManager.subscribe('board', this.currentData()._id, false); -- cgit v1.2.3-1-g7c22 From 3e817257ef6d7a527aaad040cdcdcc642caea3c1 Mon Sep 17 00:00:00 2001 From: salleman Date: Mon, 13 Apr 2020 21:06:27 +0200 Subject: hide password auth with PASSWORD_LOGIN_ENABLED variable --- client/components/main/layouts.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'client/components') diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index e5c86d76..23960a9e 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -31,6 +31,11 @@ Template.userFormsLayout.onCreated(function() { return this.stop(); }, }); + Meteor.call('isPasswordDisabled', (_, result) => { + if (result) { + $('.at-pwd-form').hide(); + } + }); }); Template.userFormsLayout.onRendered(() => { -- cgit v1.2.3-1-g7c22 From c39364af83b9f6e8ff43bcae97a529942b9a8244 Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Mon, 13 Apr 2020 23:47:00 +0200 Subject: Fix margin in card labels --- client/components/cards/labels.styl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'client/components') diff --git a/client/components/cards/labels.styl b/client/components/cards/labels.styl index 9d7c7553..ee946656 100644 --- a/client/components/cards/labels.styl +++ b/client/components/cards/labels.styl @@ -158,6 +158,8 @@ .edit-labels-pop-over margin-bottom: 8px + .card-label .viewer p + margin: 0 .edit-labels-pop-over .shortcut display: inline-block -- cgit v1.2.3-1-g7c22 From 1389ed0fce80c622220104e6c0e693ac52ce2177 Mon Sep 17 00:00:00 2001 From: Allemand <37148072+salleman33@users.noreply.github.com> Date: Tue, 14 Apr 2020 08:48:51 +0200 Subject: Update layouts.js --- client/components/main/layouts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index 23960a9e..83678e73 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -31,7 +31,7 @@ Template.userFormsLayout.onCreated(function() { return this.stop(); }, }); - Meteor.call('isPasswordDisabled', (_, result) => { + Meteor.call('isPasswordLoginDisabled', (_, result) => { if (result) { $('.at-pwd-form').hide(); } -- cgit v1.2.3-1-g7c22 From 9df5c0e2de0d2a1d3a200bb40a7f39dfa1ef4f56 Mon Sep 17 00:00:00 2001 From: Devin McAllester Date: Tue, 14 Apr 2020 17:05:58 -0700 Subject: Allows for use of checklist on mobile --- client/components/cards/checklists.jade | 3 ++- client/components/cards/checklists.js | 2 +- client/components/cards/checklists.styl | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 391769e9..1b1e088a 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -88,7 +88,8 @@ template(name="checklistItems") template(name='checklistItemDetail') .js-checklist-item.checklist-item if canModifyCard - .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") + .check-box-container + .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}") +viewer = item.title diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index c88fdd82..94d8176b 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -250,7 +250,7 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click .js-checklist-item .check-box': this.toggleItem, + 'click .js-checklist-item .check-box-container': this.toggleItem, }, ]; }, diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl index 8ac37a15..0a6d688b 100644 --- a/client/components/cards/checklists.styl +++ b/client/components/cards/checklists.styl @@ -113,6 +113,9 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &:hover background-color: darken(white, 8%) + .check-box-container + padding-right: 1px; + .check-box margin: 0.1em 0 0 0; &.is-checked @@ -121,7 +124,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item .item-title flex: 1 - padding-left: 10px; + margin-left: 10px; &.is-checked color: #8c8c8c font-style: italic -- cgit v1.2.3-1-g7c22 From d7e0350ecf8744de4e77f3a59b37dda220c52c4c Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Fri, 17 Apr 2020 19:47:26 +0200 Subject: Improve card layout on mobile devices --- client/components/cards/cardDetails.styl | 1 + 1 file changed, 1 insertion(+) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl index 199a12da..3e2beadd 100644 --- a/client/components/cards/cardDetails.styl +++ b/client/components/cards/cardDetails.styl @@ -94,6 +94,7 @@ avatar-radius = 50% animation: flexGrowIn 0.1s box-shadow: 0 0 7px 0 darken(white, 30%) transition: flex-basis 0.1s + box-sizing: border-box .mCustomScrollBox padding-left: 0 -- cgit v1.2.3-1-g7c22 From 960fe5163b6a2f7c3dca03b5e31d69611b49f079 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Fri, 17 Apr 2020 21:58:19 +0300 Subject: Remove old warning from Sandstorm import board data loss, because bug has been already fixed. Thanks to aputsiaq and xet7 ! --- client/components/import/import.jade | 3 --- 1 file changed, 3 deletions(-) (limited to 'client/components') diff --git a/client/components/import/import.jade b/client/components/import/import.jade index 5b52f417..1551a7dd 100644 --- a/client/components/import/import.jade +++ b/client/components/import/import.jade @@ -15,9 +15,6 @@ template(name="importTextarea") p: label(for='import-textarea') {{_ instruction}} {{_ 'import-board-instruction-about-errors'}} textarea.js-import-json(placeholder="{{_ 'import-json-placeholder'}}" autofocus) | {{jsonText}} - if isSandstorm - h1.warning {{_ 'import-sandstorm-backup-warning'}} - p.warning {{_ 'import-sandstorm-warning'}} input.primary.wide(type="submit" value="{{_ 'import'}}") template(name="importMapMembers") -- cgit v1.2.3-1-g7c22 From f583645744be50cba72a3e80ba2d916abb84eaba Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Sun, 19 Apr 2020 10:31:40 +0300 Subject: Make linked card clickable --- client/components/cards/cardDetails.jade | 2 +- client/components/cards/cardDetails.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 99606ae4..ae97e0e9 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -32,7 +32,7 @@ template(name="cardDetails") // else {{_ 'top-level-card'}} if isLinkedCard - h3.linked-card-location + a.linked-card-location.js-go-to-linked-card +viewer | {{getBoardTitle}} > {{getTitle}} diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 6ca5d784..9d31fc60 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -379,6 +379,9 @@ BlazeComponent.extendComponent({ this.data().setRequestedBy(''); } }, + 'click .js-go-to-linked-card'() { + Utils.goCardId(this.data().linkedId) + }, 'click .js-member': Popup.open('cardMember'), 'click .js-add-members': Popup.open('cardMembers'), 'click .js-assignee': Popup.open('cardAssignee'), -- cgit v1.2.3-1-g7c22 From 10fcc19b7f9307e71f01b6abca055806d69f7d4e Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Sun, 19 Apr 2020 12:30:21 +0300 Subject: Add sortDefault helper for sorting boards --- client/components/boards/boardArchive.js | 2 +- client/components/boards/boardsList.js | 16 ++++++---------- client/components/cards/cardDetails.js | 6 +++--- client/components/lists/listBody.js | 4 ++-- client/components/rules/actions/boardActions.js | 2 +- client/components/settings/settingBody.js | 2 +- client/components/sidebar/sidebar.js | 6 +++--- 7 files changed, 17 insertions(+), 21 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js index d3e65bd8..9f4d60a1 100644 --- a/client/components/boards/boardArchive.js +++ b/client/components/boards/boardArchive.js @@ -7,7 +7,7 @@ BlazeComponent.extendComponent({ return Boards.find( { archived: true }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ } }, ); }, diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 65bed16a..aabc98e8 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -7,8 +7,8 @@ Template.boardListHeaderBar.events({ }); Template.boardListHeaderBar.helpers({ - title(){ - return FlowRouter.getRouteName() == 'home' ? 'my-boards' :'public'; + title() { + return FlowRouter.getRouteName() == 'home' ? 'my-boards' : 'public'; }, templatesBoardId() { return Meteor.user() && Meteor.user().getTemplatesBoardId(); @@ -27,16 +27,12 @@ BlazeComponent.extendComponent({ let query = { archived: false, type: 'board', - } + }; if (FlowRouter.getRouteName() == 'home') - query['members.userId'] = Meteor.userId() - else - query.permission = 'public' + query['members.userId'] = Meteor.userId(); + else query.permission = 'public'; - return Boards.find( - query, - { sort: ['title'] }, - ); + return Boards.find(query, { sort: { sort: 1 /* boards default sorting */ } }); }, isStarred() { const user = Meteor.user(); diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 9d31fc60..ce504146 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -727,7 +727,7 @@ BlazeComponent.extendComponent({ _id: { $ne: Meteor.user().getTemplatesBoardId() }, }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); return boards; @@ -903,7 +903,7 @@ BlazeComponent.extendComponent({ }, }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); return boards; @@ -974,7 +974,7 @@ BlazeComponent.extendComponent({ } } }, - 'click .js-delete': Popup.afterConfirm('cardDelete', function () { + 'click .js-delete': Popup.afterConfirm('cardDelete', function() { Popup.close(); Cards.remove(this._id); Utils.goBoardId(this.boardId); diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 03f88f63..88f88db0 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -411,7 +411,7 @@ BlazeComponent.extendComponent({ type: 'board', }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); return boards; @@ -597,7 +597,7 @@ BlazeComponent.extendComponent({ type: 'board', }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); return boards; diff --git a/client/components/rules/actions/boardActions.js b/client/components/rules/actions/boardActions.js index c2f2375a..02910cc1 100644 --- a/client/components/rules/actions/boardActions.js +++ b/client/components/rules/actions/boardActions.js @@ -11,7 +11,7 @@ BlazeComponent.extendComponent({ }, }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); return boards; diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index 319c066b..62752084 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -48,7 +48,7 @@ BlazeComponent.extendComponent({ 'members.isAdmin': true, }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); }, diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 78b47a48..11471c2f 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -510,7 +510,7 @@ BlazeComponent.extendComponent({ 'members.userId': Meteor.userId(), }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); }, @@ -589,7 +589,7 @@ BlazeComponent.extendComponent({ 'subtext-with-parent', 'no-parent', ]; - options.forEach(function (element) { + options.forEach(function(element) { if (element !== value) { $(`#${element} ${MCB}`).toggleClass(CKCLS, false); $(`#${element}`).toggleClass(CKCLS, false); @@ -688,7 +688,7 @@ BlazeComponent.extendComponent({ 'members.userId': Meteor.userId(), }, { - sort: ['title'], + sort: { sort: 1 /* boards default sorting */ }, }, ); }, -- cgit v1.2.3-1-g7c22 From ef5f38f431dbedbecc81135702764cdc08797177 Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Sun, 19 Apr 2020 12:45:04 +0300 Subject: Make boards sortable --- client/components/boards/boardsList.jade | 4 +-- client/components/boards/boardsList.js | 54 ++++++++++++++++++++++++++++++++ client/components/boards/boardsList.styl | 15 ++++++++- 3 files changed, 70 insertions(+), 3 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index 46086693..bbce1d6f 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -1,10 +1,10 @@ template(name="boardList") .wrapper - ul.board-list.clearfix + ul.board-list.clearfix.js-boards li.js-add-board a.board-list-item.label {{_ 'add-board'}} each boards - li(class="{{#if isStarred}}starred{{/if}}" class=colorClass) + li(class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board if isInvited .board-list-item span.details diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index aabc98e8..d2d44407 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,4 +1,5 @@ const subManager = new SubsManager(); +const { calculateIndex, enableClickOnTouch } = Utils; Template.boardListHeaderBar.events({ 'click .js-open-archived-board'() { @@ -23,6 +24,59 @@ BlazeComponent.extendComponent({ Meteor.subscribe('setting'); }, + onRendered() { + const self = this; + function userIsAllowedToMove() { + return Meteor.user(); + } + + const itemsSelector = '.js-board:not(.placeholder)'; + + const $boards = this.$('.js-boards'); + $boards.sortable({ + connectWith: '.js-boards', + tolerance: 'pointer', + appendTo: '.board-list', + helper: 'clone', + distance: 7, + items: itemsSelector, + placeholder: 'board-wrapper placeholder', + start(evt, ui) { + ui.helper.css('z-index', 1000); + ui.placeholder.height(ui.helper.height()); + EscapeActions.executeUpTo('popup-close'); + }, + stop(evt, ui) { + // To attribute the new index number, we need to get the DOM element + // of the previous and the following card -- if any. + const prevCardDom = ui.item.prev('.js-board').get(0); + const nextCardDom = ui.item.next('.js-board').get(0); + const sortIndex = calculateIndex(prevCardDom, nextCardDom, 1); + + const boardDomElement = ui.item.get(0); + const board = Blaze.getData(boardDomElement); + // Normally the jquery-ui sortable library moves the dragged DOM element + // to its new position, which disrupts Blaze reactive updates mechanism + // (especially when we move the last card of a list, or when multiple + // users move some cards at the same time). To prevent these UX glitches + // we ask sortable to gracefully cancel the move, and to put back the + // DOM in its initial state. The card move is then handled reactively by + // Blaze with the below query. + $boards.sortable('cancel'); + + board.move(sortIndex.base); + }, + }); + + // ugly touch event hotfix + enableClickOnTouch(itemsSelector); + + // Disable drag-dropping if the current user is not a board member or is comment only + this.autorun(() => { + $boards.sortable('option', 'disabled', !userIsAllowedToMove()); + }); + }, + boards() { let query = { archived: false, diff --git a/client/components/boards/boardsList.styl b/client/components/boards/boardsList.styl index ae366e83..d12a0337 100644 --- a/client/components/boards/boardsList.styl +++ b/client/components/boards/boardsList.styl @@ -11,6 +11,19 @@ $spaceBetweenTiles = 16px box-sizing: border-box position: relative + &.placeholder:after + content: ''; + display: block; + background: darken(white, 20%) + border-radius: 3px; + height: 106px; + margin: 8px; + + &.ui-sortable-helper + cursor: grabbing + transform: rotate(4deg) + display: block !important + &.starred .fa-star, .fa-star-o @@ -183,7 +196,7 @@ $spaceBetweenTiles = 16px overflow: scroll li - width: 50% + width: 50% .board-list-item overflow: hidden -- cgit v1.2.3-1-g7c22 From 1a065ff351b5c37536d73cc3d46b736fe310e32c Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Sun, 19 Apr 2020 15:52:43 +0300 Subject: Refactor variable names --- client/components/boards/boardsList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index d2d44407..c700084f 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -49,9 +49,9 @@ BlazeComponent.extendComponent({ stop(evt, ui) { // To attribute the new index number, we need to get the DOM element // of the previous and the following card -- if any. - const prevCardDom = ui.item.prev('.js-board').get(0); - const nextCardDom = ui.item.next('.js-board').get(0); - const sortIndex = calculateIndex(prevCardDom, nextCardDom, 1); + const prevBoardDom = ui.item.prev('.js-board').get(0); + const nextBoardBom = ui.item.next('.js-board').get(0); + const sortIndex = calculateIndex(prevBoardDom, nextBoardBom, 1); const boardDomElement = ui.item.get(0); const board = Blaze.getData(boardDomElement); -- cgit v1.2.3-1-g7c22 From 9f0273aa4487545cc28712d33a4ee141738b1571 Mon Sep 17 00:00:00 2001 From: boeserwolf Date: Tue, 21 Apr 2020 00:58:15 +0300 Subject: Pre-fill the title of checklists (Trello-style) --- client/components/cards/checklists.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 94d8176b..5acab536 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -1,4 +1,4 @@ -const { calculateIndexData, enableClickOnTouch } = Utils; +const { calculateIndexData, enableClickOnTouch, capitalize } = Utils; function initSorting(items) { items.sortable({ @@ -177,6 +177,16 @@ BlazeComponent.extendComponent({ } }, + focusChecklistItem(event) { + // If a new checklist is created, pre-fill the title and select it. + const checklist = this.currentData().checklist; + if (!checklist) { + const textarea = event.target; + textarea.value = capitalize(TAPi18n.__('r-checklist')); + textarea.select(); + } + }, + events() { const events = { 'click .toggle-delete-checklist-dialog'(event) { @@ -196,6 +206,7 @@ BlazeComponent.extendComponent({ 'submit .js-edit-checklist-item': this.editChecklistItem, 'click .js-delete-checklist-item': this.deleteItem, 'click .confirm-checklist-delete': this.deleteChecklist, + 'focus .js-add-checklist-item': this.focusChecklistItem, keydown: this.pressKey, }, ]; -- cgit v1.2.3-1-g7c22 From b2acc3ba45c48d3bb3b25e84bc31f5b80e7961d4 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Tue, 21 Apr 2020 17:06:39 +0200 Subject: Multiple lint issue fixes Found by using the command `meteor npm run lint:eslint:fix`. --- client/components/boards/boardsList.js | 4 ++-- client/components/cards/cardDetails.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index c700084f..847ea395 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -9,7 +9,7 @@ Template.boardListHeaderBar.events({ Template.boardListHeaderBar.helpers({ title() { - return FlowRouter.getRouteName() == 'home' ? 'my-boards' : 'public'; + return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public'; }, templatesBoardId() { return Meteor.user() && Meteor.user().getTemplatesBoardId(); @@ -82,7 +82,7 @@ BlazeComponent.extendComponent({ archived: false, type: 'board', }; - if (FlowRouter.getRouteName() == 'home') + if (FlowRouter.getRouteName() === 'home') query['members.userId'] = Meteor.userId(); else query.permission = 'public'; diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index ce504146..a578ba7c 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -420,9 +420,9 @@ BlazeComponent.extendComponent({ const forIt = $(e.target).hasClass('js-vote-positive'); let newState = null; if ( - this.voteState() == null || - (this.voteState() == false && forIt) || - (this.voteState() == true && !forIt) + this.voteState() === null || + (this.voteState() === false && forIt) || + (this.voteState() === true && !forIt) ) { newState = forIt; } -- cgit v1.2.3-1-g7c22 From 8e14459cff4da1391f536dfbc6441abb21e9c215 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Wed, 22 Apr 2020 14:44:08 +0200 Subject: Implement option to change the first day of week in user settings Implements #2535. --- client/components/main/popup.styl | 4 ++++ client/components/users/userHeader.jade | 11 ++++++++++ client/components/users/userHeader.js | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) (limited to 'client/components') diff --git a/client/components/main/popup.styl b/client/components/main/popup.styl index 023cba3d..f1db3927 100644 --- a/client/components/main/popup.styl +++ b/client/components/main/popup.styl @@ -135,6 +135,10 @@ $popupWidth = 300px margin-bottom: 8px .pop-over-list + li + display: block + clear: both + li > a clear: both cursor: pointer diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 1cd9da6b..3747d882 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -117,6 +117,17 @@ template(name="changeSettingsPopup") | {{_ 'show-cards-minimum-count'}} input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") + li + label.bold + i.fa.fa-calendar + | {{_ 'start-day-of-week'}} + select#start-day-of-week.inline-input.left + each day in weekDays startDayOfWeek + if day.isSelected + option(selected="true", value="#{day.value}") #{day.name} + else + option(value="#{day.value}") #{day.name} + input.js-apply-start-day-of-week.left(type="submit" value="{{_ 'apply'}}") template(name="userDeletePopup") unless currentUser.isWorker diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index cd315bd6..5298e99a 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -224,6 +224,27 @@ Template.changeSettingsPopup.helpers({ return cookies.get('limitToShowCardsCount'); } }, + weekDays(startDay) { + return [ + TAPi18n.__('sunday'), + TAPi18n.__('monday'), + TAPi18n.__('tuesday'), + TAPi18n.__('wednesday'), + TAPi18n.__('thursday'), + TAPi18n.__('friday'), + TAPi18n.__('saturday'), + ].map(function(day, index) { + return { name: day, value: index, isSelected: index === startDay }; + }); + }, + startDayOfWeek() { + currentUser = Meteor.user(); + if (currentUser) { + return currentUser.getStartDayOfWeek(); + } else { + return cookies.get('startDayOfWeek'); + } + }, }); Template.changeSettingsPopup.events({ @@ -263,4 +284,20 @@ Template.changeSettingsPopup.events({ Popup.back(); } }, + 'click .js-apply-start-day-of-week'(event, templateInstance) { + event.preventDefault(); + const startDay = parseInt( + templateInstance.$('#start-day-of-week').val(), + 10, + ); + if (!isNaN(startDay)) { + currentUser = Meteor.user(); + if (currentUser) { + Meteor.call('changeStartDayOfWeek', startDay); + } else { + cookies.set('startDayOfWeek', startDay); + } + Popup.back(); + } + }, }); -- cgit v1.2.3-1-g7c22 From 9e95c06415e614e587d684ff9660cc53c5f8c8d3 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 22 Apr 2020 21:00:31 +0300 Subject: Fix lint errors in lint error fix. Thanks to xet7 ! --- client/components/boards/boardArchive.js | 2 +- client/components/boards/boardsList.js | 4 +++- client/components/cards/cardDetails.js | 17 ++++++++--------- client/components/sidebar/sidebar.js | 17 ++++++++--------- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js index 9f4d60a1..5a5cf772 100644 --- a/client/components/boards/boardArchive.js +++ b/client/components/boards/boardArchive.js @@ -7,7 +7,7 @@ BlazeComponent.extendComponent({ return Boards.find( { archived: true }, { - sort: { sort: 1 /* boards default sorting */ } + sort: { sort: 1 /* boards default sorting */ }, }, ); }, diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 847ea395..9208fdb2 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -86,7 +86,9 @@ BlazeComponent.extendComponent({ query['members.userId'] = Meteor.userId(); else query.permission = 'public'; - return Boards.find(query, { sort: { sort: 1 /* boards default sorting */ } }); + return Boards.find(query, { + sort: { sort: 1 /* boards default sorting */ }, + }); }, isStarred() { const user = Meteor.user(); diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index a578ba7c..b958d5bf 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -56,9 +56,8 @@ BlazeComponent.extendComponent({ }, votePublic() { const card = this.currentData(); - if (card.vote) - return card.vote.public - return null + if (card.vote) return card.vote.public; + return null; }, voteCountPositive() { const card = this.currentData(); @@ -380,7 +379,7 @@ BlazeComponent.extendComponent({ } }, 'click .js-go-to-linked-card'() { - Utils.goCardId(this.data().linkedId) + Utils.goCardId(this.data().linkedId); }, 'click .js-member': Popup.open('cardMember'), 'click .js-add-members': Popup.open('cardMembers'), @@ -391,7 +390,7 @@ BlazeComponent.extendComponent({ 'click .js-start-date': Popup.open('editCardStartDate'), 'click .js-due-date': Popup.open('editCardDueDate'), 'click .js-end-date': Popup.open('editCardEndDate'), - 'click .js-show-positive-votes':Popup.open('positiveVoteMembers'), + 'click .js-show-positive-votes': Popup.open('positiveVoteMembers'), 'click .js-show-negative-votes': Popup.open('negativeVoteMembers'), 'mouseenter .js-card-details'() { const parentComponent = this.parentComponent().parentComponent(); @@ -658,7 +657,7 @@ Template.cardDetailsActionsPopup.events({ }, }); -Template.editCardTitleForm.onRendered(function () { +Template.editCardTitleForm.onRendered(function() { autosize(this.$('.js-edit-card-title')); }); @@ -672,7 +671,7 @@ Template.editCardTitleForm.events({ }, }); -Template.editCardRequesterForm.onRendered(function () { +Template.editCardRequesterForm.onRendered(function() { autosize(this.$('.js-edit-card-requester')); }); @@ -685,7 +684,7 @@ Template.editCardRequesterForm.events({ }, }); -Template.editCardAssignerForm.onRendered(function () { +Template.editCardAssignerForm.onRendered(function() { autosize(this.$('.js-edit-card-assigner')); }); @@ -825,7 +824,7 @@ Template.copyChecklistToManyCardsPopup.events({ // copy subtasks cursor = Cards.find({ parentId: oldId }); - cursor.forEach(function () { + cursor.forEach(function() { 'use strict'; const subtask = arguments[0]; subtask.parentId = _id; diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 11471c2f..cbe00797 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -196,14 +196,14 @@ Template.boardMenuPopup.events({ }, 'click .js-change-board-color': Popup.open('boardChangeColor'), 'click .js-change-language': Popup.open('changeLanguage'), - 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function () { + 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() { const currentBoard = Boards.findOne(Session.get('currentBoard')); currentBoard.archive(); // XXX We should have some kind of notification on top of the page to // confirm that the board was successfully archived. FlowRouter.go('home'); }), - 'click .js-delete-board': Popup.afterConfirm('deleteBoard', function () { + 'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() { const currentBoard = Boards.findOne(Session.get('currentBoard')); Popup.close(); Boards.remove(currentBoard._id); @@ -215,17 +215,16 @@ Template.boardMenuPopup.events({ 'click .js-card-settings': Popup.open('boardCardSettings'), }); - -Template.boardMenuPopup.onCreated(function () { +Template.boardMenuPopup.onCreated(function() { this.apiEnabled = new ReactiveVar(false); Meteor.call('_isApiEnabled', (e, result) => { - this.apiEnabled.set(result) - }) -}) + this.apiEnabled.set(result); + }); +}); Template.boardMenuPopup.helpers({ withApi() { - return Template.instance().apiEnabled.get() + return Template.instance().apiEnabled.get(); }, exportUrl() { const params = { @@ -248,7 +247,7 @@ Template.memberPopup.events({ Popup.close(); }, 'click .js-change-role': Popup.open('changePermissions'), - 'click .js-remove-member': Popup.afterConfirm('removeMember', function () { + 'click .js-remove-member': Popup.afterConfirm('removeMember', function() { const boardId = Session.get('currentBoard'); const memberId = this.userId; Cards.find({ boardId, members: memberId }).forEach(card => { -- cgit v1.2.3-1-g7c22 From 52f884f2b1bdbf89eeafc355129bb7bfdbe978fc Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Wed, 22 Apr 2020 19:42:10 +0200 Subject: Use only one 'Apply' button for applying the user settings --- client/components/users/userHeader.jade | 8 +++----- client/components/users/userHeader.js | 19 +++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) (limited to 'client/components') diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 3747d882..d0adf29d 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -112,13 +112,11 @@ template(name="changeSettingsPopup") i.fa.fa-check unless currentUser.isWorker li - label.bold + label.bold.clear i.fa.fa-sort-numeric-asc | {{_ 'show-cards-minimum-count'}} input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false") - input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}") - li - label.bold + label.bold.clear i.fa.fa-calendar | {{_ 'start-day-of-week'}} select#start-day-of-week.inline-input.left @@ -127,7 +125,7 @@ template(name="changeSettingsPopup") option(selected="true", value="#{day.value}") #{day.name} else option(value="#{day.value}") #{day.name} - input.js-apply-start-day-of-week.left(type="submit" value="{{_ 'apply'}}") + input.js-apply-user-settings.left(type="submit" value="{{_ 'apply'}}") template(name="userDeletePopup") unless currentUser.isWorker diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 5298e99a..b7bb284e 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -268,36 +268,31 @@ Template.changeSettingsPopup.events({ cookies.set('hasHiddenSystemMessages', 'true'); } }, - 'click .js-apply-show-cards-at'(event, templateInstance) { + 'click .js-apply-user-settings'(event, templateInstance) { event.preventDefault(); const minLimit = parseInt( templateInstance.$('#show-cards-count-at').val(), 10, ); + const startDay = parseInt( + templateInstance.$('#start-day-of-week').val(), + 10, + ); + const currentUser = Meteor.user(); if (!isNaN(minLimit)) { - currentUser = Meteor.user(); if (currentUser) { Meteor.call('changeLimitToShowCardsCount', minLimit); } else { cookies.set('limitToShowCardsCount', minLimit); } - Popup.back(); } - }, - 'click .js-apply-start-day-of-week'(event, templateInstance) { - event.preventDefault(); - const startDay = parseInt( - templateInstance.$('#start-day-of-week').val(), - 10, - ); if (!isNaN(startDay)) { - currentUser = Meteor.user(); if (currentUser) { Meteor.call('changeStartDayOfWeek', startDay); } else { cookies.set('startDayOfWeek', startDay); } - Popup.back(); } + Popup.back(); }, }); -- cgit v1.2.3-1-g7c22 From c1287248a6a4975133790deab6747530e5ece3cb Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Wed, 22 Apr 2020 00:24:32 +0200 Subject: Mobile device layout fix --- client/components/main/popup.styl | 1 + 1 file changed, 1 insertion(+) (limited to 'client/components') diff --git a/client/components/main/popup.styl b/client/components/main/popup.styl index f1db3927..b4815ca6 100644 --- a/client/components/main/popup.styl +++ b/client/components/main/popup.styl @@ -320,6 +320,7 @@ $popupWidth = 300px input[type="file"] margin: 4px 0 12px width: 100% + box-sizing: border-box .pop-over-list li > a -- cgit v1.2.3-1-g7c22 From 981ed546f1cae45ad8b92b393ee29c1a26277f32 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Thu, 23 Apr 2020 00:54:39 +0200 Subject: Newer versions of jQuery sortable use `uiSortable` key Newer versions of jQuery sortable use `uiSortable` as key to store the data. Let's adapt the code. While at it, refactor the code. --- client/components/cards/cardDetails.js | 15 +++++---------- client/components/cards/checklists.js | 7 ++----- client/components/lists/list.js | 15 ++------------- client/components/swimlanes/swimlanes.js | 26 ++------------------------ 4 files changed, 11 insertions(+), 52 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index b958d5bf..8fc3c12a 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -278,17 +278,12 @@ BlazeComponent.extendComponent({ // Disable sorting if the current user is not a board member this.autorun(() => { - if ($checklistsDom.data('sortable')) { - $checklistsDom.sortable('option', 'disabled', !userIsMember()); + const disabled = !userIsMember() || Utils.isMiniScreen(); + if ($checklistsDom.data('uiSortable')) { + $checklistsDom.sortable('option', 'disabled', disabled); } - if ($subtasksDom.data('sortable')) { - $subtasksDom.sortable('option', 'disabled', !userIsMember()); - } - if ($checklistsDom.data('sortable')) { - $checklistsDom.sortable('option', 'disabled', Utils.isMiniScreen()); - } - if ($subtasksDom.data('sortable')) { - $subtasksDom.sortable('option', 'disabled', Utils.isMiniScreen()); + if ($subtasksDom.data('uiSortable')) { + $subtasksDom.sortable('option', 'disabled', disabled); } }); }, diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 5acab536..8daf6ee7 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -57,11 +57,8 @@ BlazeComponent.extendComponent({ // Disable sorting if the current user is not a board member self.autorun(() => { const $itemsDom = $(self.itemsDom); - if ($itemsDom.data('sortable')) { - $(self.itemsDom).sortable('option', 'disabled', !userIsMember()); - } - if ($itemsDom.data('sortable')) { - $(self.itemsDom).sortable('option', 'disabled', Utils.isMiniScreen()); + if ($itemsDom.data('uiSortable')) { + $(self.itemsDom).sortable('option', 'disabled', !userIsMember() || Utils.isMiniScreen()); } }); }, diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 8574caf7..7ce520dc 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -139,23 +139,12 @@ BlazeComponent.extendComponent({ }); } - if ($cards.data('sortable')) { + if ($cards.data('uiSortable')) { $cards.sortable( 'option', 'disabled', // Disable drag-dropping when user is not member/is miniscreen - !userIsMember(), - // Not disable drag-dropping while in multi-selection mode - // MultiSelection.isActive() || !userIsMember(), - ); - } - - if ($cards.data('sortable')) { - $cards.sortable( - 'option', - 'disabled', - // Disable drag-dropping when user is not member/is miniscreen - Utils.isMiniScreen(), + !userIsMember() || Utils.isMiniScreen(), // Not disable drag-dropping while in multi-selection mode // MultiSelection.isActive() || !userIsMember(), ); diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index b7a55ce6..577bf6d2 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -122,34 +122,12 @@ function initSortable(boardComponent, $listsDom) { } const $listDom = $listsDom; - if ($listDom.data('sortable')) { + if ($listDom.data('uiSortable')) { $listsDom.sortable( 'option', 'disabled', // Disable drag-dropping when user is not member/is worker/is miniscreen - !userIsMember(), - // Not disable drag-dropping while in multi-selection mode - // MultiSelection.isActive() || !userIsMember(), - ); - } - - if ($listDom.data('sortable')) { - $listsDom.sortable( - 'option', - 'disabled', - // Disable drag-dropping when user is not member/is worker/is miniscreen - Meteor.user().isWorker(), - // Not disable drag-dropping while in multi-selection mode - // MultiSelection.isActive() || !userIsMember(), - ); - } - - if ($listDom.data('sortable')) { - $listsDom.sortable( - 'option', - 'disabled', - // Disable drag-dropping when user is not member/is worker/is miniscreen - Utils.isMiniScreen(), + !userIsMember() || Meteor.user().isWorker() || Utils.isMiniScreen(), // Not disable drag-dropping while in multi-selection mode // MultiSelection.isActive() || !userIsMember(), ); -- cgit v1.2.3-1-g7c22 From 6476503137fc41cf52e913aa33aed6bb1abaac6a Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Thu, 23 Apr 2020 02:09:01 +0200 Subject: Fix drag-and-drop and scrolling on mobile devices Use drag handles on "miniscreens" whenever useful, this is especially useful on mobile device. This should hopefully fix https://github.com/wekan/wekan/issues/2947. While at it, simplify the condition Utils.isMiniScreen() || (!Utils.isMiniScreen() && showDesktopDragHandles) to Utils.isMiniScreen() || showDesktopDragHandle --- client/components/boards/boardBody.js | 5 ++--- client/components/cards/minicard.jade | 4 ++-- client/components/lists/list.js | 6 +++--- client/components/lists/listHeader.jade | 3 +-- client/components/swimlanes/swimlanes.js | 9 ++++----- 5 files changed, 12 insertions(+), 15 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index e70a9f67..29922fcc 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -205,7 +205,7 @@ BlazeComponent.extendComponent({ } else { showDesktopDragHandles = false; } - if (!Utils.isMiniScreen() && showDesktopDragHandles) { + if (Utils.isMiniScreen() || showDesktopDragHandles) { $swimlanesDom.sortable({ handle: '.js-swimlane-header-handle', }); @@ -215,9 +215,8 @@ BlazeComponent.extendComponent({ }); } - // Disable drag-dropping if the current user is not a board member or is miniscreen + // Disable drag-dropping if the current user is not a board member $swimlanesDom.sortable('option', 'disabled', !userIsMember()); - $swimlanesDom.sortable('option', 'disabled', Utils.isMiniScreen()); }); function userIsMember() { diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 0b881a54..b6ccd4d7 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -4,8 +4,8 @@ template(name="minicard") class="{{#if isLinkedBoard}}linked-board{{/if}}" class="minicard-{{colorClass}}") if isMiniScreen - //.handle - // .fa.fa-arrows + .handle + .fa.fa-arrows unless isMiniScreen if showDesktopDragHandles .handle diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 7ce520dc..a0031b2f 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -129,7 +129,7 @@ BlazeComponent.extendComponent({ showDesktopDragHandles = false; } - if (!Utils.isMiniScreen() && showDesktopDragHandles) { + if (Utils.isMiniScreen() || showDesktopDragHandles) { $cards.sortable({ handle: '.handle', }); @@ -143,8 +143,8 @@ BlazeComponent.extendComponent({ $cards.sortable( 'option', 'disabled', - // Disable drag-dropping when user is not member/is miniscreen - !userIsMember() || Utils.isMiniScreen(), + // Disable drag-dropping when user is not member + !userIsMember(), // Not disable drag-dropping while in multi-selection mode // MultiSelection.isActive() || !userIsMember(), ); diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 182fee9e..fa1faf34 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -30,10 +30,9 @@ 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-handle.handle.fa.fa-arrows.js-list-handle else a.list-header-menu-icon.fa.fa-angle-right.js-select-list - //a.list-header-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 diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 577bf6d2..2d299ddc 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -111,7 +111,7 @@ function initSortable(boardComponent, $listsDom) { showDesktopDragHandles = false; } - if (!Utils.isMiniScreen() && showDesktopDragHandles) { + if (Utils.isMiniScreen() || showDesktopDragHandles) { $listsDom.sortable({ handle: '.js-list-handle', }); @@ -126,8 +126,8 @@ function initSortable(boardComponent, $listsDom) { $listsDom.sortable( 'option', 'disabled', - // Disable drag-dropping when user is not member/is worker/is miniscreen - !userIsMember() || Meteor.user().isWorker() || Utils.isMiniScreen(), + // Disable drag-dropping when user is not member/is worker + !userIsMember() || Meteor.user().isWorker(), // Not disable drag-dropping while in multi-selection mode // MultiSelection.isActive() || !userIsMember(), ); @@ -188,8 +188,7 @@ BlazeComponent.extendComponent({ } const noDragInside = ['a', 'input', 'textarea', 'p'].concat( - Utils.isMiniScreen() || - (!Utils.isMiniScreen() && showDesktopDragHandles) + Utils.isMiniScreen() || showDesktopDragHandles ? ['.js-list-handle', '.js-swimlane-header-handle'] : ['.js-list-header'], ); -- cgit v1.2.3-1-g7c22 From 6d1cdebfe214c7f67f8cc396cf880d1b5a18f013 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Sat, 25 Apr 2020 09:48:56 +0200 Subject: Make it compatible with newer and older versions of jQuery sortable While at it, fix comments and prettify it. --- client/components/cards/cardDetails.js | 4 ++-- client/components/cards/checklists.js | 10 +++++++--- client/components/lists/list.js | 2 +- client/components/swimlanes/swimlanes.js | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 8fc3c12a..90014f7d 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -279,10 +279,10 @@ BlazeComponent.extendComponent({ // Disable sorting if the current user is not a board member this.autorun(() => { const disabled = !userIsMember() || Utils.isMiniScreen(); - if ($checklistsDom.data('uiSortable')) { + if ($checklistsDom.data('uiSortable') || $checklistsDom.data('sortable')) { $checklistsDom.sortable('option', 'disabled', disabled); } - if ($subtasksDom.data('uiSortable')) { + if ($subtasksDom.data('uiSortable') || $subtasksDom.data('sortable')) { $subtasksDom.sortable('option', 'disabled', disabled); } }); diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 8daf6ee7..ca394aa5 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -54,11 +54,15 @@ BlazeComponent.extendComponent({ return Meteor.user() && Meteor.user().isBoardMember(); } - // Disable sorting if the current user is not a board member + // Disable sorting if the current user is not a board member or is a miniscreen self.autorun(() => { const $itemsDom = $(self.itemsDom); - if ($itemsDom.data('uiSortable')) { - $(self.itemsDom).sortable('option', 'disabled', !userIsMember() || Utils.isMiniScreen()); + if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) { + $(self.itemsDom).sortable( + 'option', + 'disabled', + !userIsMember() || Utils.isMiniScreen(), + ); } }); }, diff --git a/client/components/lists/list.js b/client/components/lists/list.js index a0031b2f..1f622b86 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -139,7 +139,7 @@ BlazeComponent.extendComponent({ }); } - if ($cards.data('uiSortable')) { + if ($cards.data('uiSortable') || $cards.data('sortable')) { $cards.sortable( 'option', 'disabled', diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 2d299ddc..ea8aaf1d 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -122,7 +122,7 @@ function initSortable(boardComponent, $listsDom) { } const $listDom = $listsDom; - if ($listDom.data('uiSortable')) { + if ($listDom.data('uiSortable') || $listDom.data('sortable')) { $listsDom.sortable( 'option', 'disabled', -- cgit v1.2.3-1-g7c22 From f1b18d79cdbfd9c9edecf4f93a89e88ee1c6faea Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Fri, 24 Apr 2020 22:41:24 +0200 Subject: Don't interpret dragging an element as a click Remove `enableClickOnTouch` as this behavior is not intuitive. --- client/components/boards/boardBody.js | 5 +---- client/components/boards/boardsList.js | 5 +---- client/components/cards/cardDetails.js | 8 +------- client/components/cards/checklists.js | 5 +---- client/components/lists/list.js | 5 +---- client/components/swimlanes/swimlanes.js | 5 +---- 6 files changed, 6 insertions(+), 27 deletions(-) (limited to 'client/components') diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 29922fcc..4e473f18 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -1,7 +1,7 @@ import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); const subManager = new SubsManager(); -const { calculateIndex, enableClickOnTouch } = Utils; +const { calculateIndex } = Utils; const swimlaneWhileSortingHeight = 150; BlazeComponent.extendComponent({ @@ -191,9 +191,6 @@ BlazeComponent.extendComponent({ }, }); - // ugly touch event hotfix - enableClickOnTouch('.js-swimlane:not(.placeholder)'); - this.autorun(() => { let showDesktopDragHandles = false; currentUser = Meteor.user(); diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 9208fdb2..df319ce0 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,5 +1,5 @@ const subManager = new SubsManager(); -const { calculateIndex, enableClickOnTouch } = Utils; +const { calculateIndex } = Utils; Template.boardListHeaderBar.events({ 'click .js-open-archived-board'() { @@ -68,9 +68,6 @@ 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(() => { $boards.sortable('option', 'disabled', !userIsAllowedToMove()); diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 90014f7d..f31c3890 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -1,5 +1,5 @@ const subManager = new SubsManager(); -const { calculateIndexData, enableClickOnTouch } = Utils; +const { calculateIndexData } = Utils; let cardColors; Meteor.startup(() => { @@ -231,9 +231,6 @@ BlazeComponent.extendComponent({ }, }); - // ugly touch event hotfix - enableClickOnTouch('.card-checklist-items .js-checklist'); - const $subtasksDom = this.$('.card-subtasks-items'); $subtasksDom.sortable({ @@ -269,9 +266,6 @@ BlazeComponent.extendComponent({ }, }); - // ugly touch event hotfix - enableClickOnTouch('.card-subtasks-items .js-subtasks'); - function userIsMember() { return Meteor.user() && Meteor.user().isBoardMember(); } diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index ca394aa5..29573d2b 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -1,4 +1,4 @@ -const { calculateIndexData, enableClickOnTouch, capitalize } = Utils; +const { calculateIndexData, capitalize } = Utils; function initSorting(items) { items.sortable({ @@ -36,9 +36,6 @@ function initSorting(items) { checklistItem.move(checklistId, sortIndex.base); }, }); - - // ugly touch event hotfix - enableClickOnTouch('.js-checklist-item:not(.placeholder)'); } BlazeComponent.extendComponent({ diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 1f622b86..839304f8 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -1,6 +1,6 @@ import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); -const { calculateIndex, enableClickOnTouch } = Utils; +const { calculateIndex } = Utils; BlazeComponent.extendComponent({ // Proxy @@ -114,9 +114,6 @@ BlazeComponent.extendComponent({ }, }); - // ugly touch event hotfix - enableClickOnTouch(itemsSelector); - this.autorun(() => { let showDesktopDragHandles = false; currentUser = Meteor.user(); diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index ea8aaf1d..753fa88b 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -1,6 +1,6 @@ import { Cookies } from 'meteor/ostrio:cookies'; const cookies = new Cookies(); -const { calculateIndex, enableClickOnTouch } = Utils; +const { calculateIndex } = Utils; function currentListIsInThisSwimlane(swimlaneId) { const currentList = Lists.findOne(Session.get('currentList')); @@ -87,9 +87,6 @@ function initSortable(boardComponent, $listsDom) { }, }); - // ugly touch event hotfix - enableClickOnTouch('.js-list:not(.js-list-composer)'); - function userIsMember() { return ( Meteor.user() && -- cgit v1.2.3-1-g7c22 From e63e7b11318502e9f1238fcd7efff3c30590b29c Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Sat, 25 Apr 2020 13:25:21 +0200 Subject: Allow variable height for board list items This fixes https://github.com/wekan/wekan/issues/3041. --- client/components/boards/boardsList.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.styl b/client/components/boards/boardsList.styl index d12a0337..347881d6 100644 --- a/client/components/boards/boardsList.styl +++ b/client/components/boards/boardsList.styl @@ -33,7 +33,7 @@ $spaceBetweenTiles = 16px overflow: hidden; background-color: #999 color: #f6f6f6 - height: 90px + height: auto font-size: 16px line-height: 22px border-radius: 3px -- cgit v1.2.3-1-g7c22 From ed0c64a270031448a9956b40084da6f075f8601a Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Sat, 25 Apr 2020 13:26:21 +0200 Subject: Allow words in title/description to be able to break and wrap onto the next line --- client/components/boards/boardsList.styl | 1 + 1 file changed, 1 insertion(+) (limited to 'client/components') diff --git a/client/components/boards/boardsList.styl b/client/components/boards/boardsList.styl index 347881d6..d92c9cf3 100644 --- a/client/components/boards/boardsList.styl +++ b/client/components/boards/boardsList.styl @@ -44,6 +44,7 @@ $spaceBetweenTiles = 16px margin: ($spaceBetweenTiles/2) position: relative text-decoration: none + word-wrap: break-word &.tile background-size: auto -- cgit v1.2.3-1-g7c22 From fe7398faef9670ff9a1885c37673beec148faed8 Mon Sep 17 00:00:00 2001 From: Nico Date: Sun, 26 Apr 2020 02:37:18 +0200 Subject: Put checkbox and label in same row --- client/components/cards/cardTime.jade | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardTime.jade b/client/components/cards/cardTime.jade index 8af8c414..177b689f 100644 --- a/client/components/cards/cardTime.jade +++ b/client/components/cards/cardTime.jade @@ -4,9 +4,10 @@ template(name="editCardSpentTime") .fields label(for="time") {{_ 'time'}} input.js-time-field#time(type="number" step="0.01" name="time" value="{{card.getSpentTime}}" placeholder=timeFormat autofocus) - label(for="overtime") {{_ 'overtime'}} - a.js-toggle-overtime - .materialCheckBox#overtime(class="{{#if getIsOvertime}}is-checked{{/if}}" name="overtime") + .check-div + a.flex.js-toggle-overtime + .materialCheckBox#overtime(class="{{#if getIsOvertime}}is-checked{{/if}}" name="overtime") + span {{_ 'overtime'}} if error.get .warning {{_ error.get}} -- cgit v1.2.3-1-g7c22 From 7bb0aa74884d026bb6a0192bd2c4d0fb43f2953b Mon Sep 17 00:00:00 2001 From: Nico Date: Sun, 26 Apr 2020 02:41:26 +0200 Subject: Additional vote features --- client/components/cards/cardDetails.jade | 14 ++++++++++++-- client/components/cards/cardDetails.js | 23 +++++++---------------- client/components/cards/minicard.jade | 2 ++ 3 files changed, 21 insertions(+), 18 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index ae97e0e9..85425c59 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -212,6 +212,8 @@ template(name="cardDetails") else .card-label.card-label-green {{ voteCountPositive }} .card-label.card-label-red {{ voteCountNegative }} + unless ($and currentBoard.isPublic voteAllowNonBoardMembers ) + .card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }} +viewer = getVoteQuestion button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") {{_ 'vote-for-it'}} @@ -572,9 +574,17 @@ template(name="cardStartVotingPopup") .fields label(for="vote") {{_ 'vote-question'}} input.js-vote-field#vote(type="text" name="vote" value="{{card.getVoteQuestion}}" autofocus) - label(for="vote-public") {{_ 'vote-public'}} - a.js-toggle-vote-public + .check-div + a.flex.js-toggle-vote-public .materialCheckBox#vote-public(name="vote-public") + span {{_ 'vote-public'}} + .check-div + a.flex.js-toggle-vote-allow-non-members + .materialCheckBox#vote-allow-non-members(name="vote-allow-non-members") + span {{_ 'allowNonBoardMembers'}} + //- label(for="vote-public") {{_ 'vote-public'}} + //- a.js-toggle-vote-public + //- .materialCheckBox#vote-public(name="vote-public") button.primary.confirm.js-submit {{_ 'save'}} //- button.js-remove-color.negate.wide.right {{_ 'delete'}} diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index f31c3890..b8c7fa3f 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -54,21 +54,7 @@ BlazeComponent.extendComponent({ } return null; }, - votePublic() { - const card = this.currentData(); - if (card.vote) return card.vote.public; - return null; - }, - voteCountPositive() { - const card = this.currentData(); - if (card.vote && card.vote.positive) return card.vote.positive.length; - return null; - }, - voteCountNegative() { - const card = this.currentData(); - if (card.vote && card.vote.negative) return card.vote.negative.length; - return null; - }, + isWatching() { const card = this.currentData(); return card.findWatcher(Meteor.userId()); @@ -1001,13 +987,18 @@ BlazeComponent.extendComponent({ evt.preventDefault(); const voteQuestion = evt.target.vote.value; const publicVote = $('#vote-public').hasClass('is-checked'); - this.currentCard.setVoteQuestion(voteQuestion, publicVote); + const allowNonBoardMembers = $('#vote-allow-non-members').hasClass('is-checked'); + this.currentCard.setVoteQuestion(voteQuestion, publicVote,allowNonBoardMembers); Popup.close(); }, 'click a.js-toggle-vote-public'(event) { event.preventDefault(); $('#vote-public').toggleClass('is-checked'); }, + 'click a.js-toggle-vote-allow-non-members'(event) { + event.preventDefault(); + $('#vote-allow-non-members').toggleClass('is-checked'); + }, }, ]; }, diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index b6ccd4d7..79dd9127 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -103,7 +103,9 @@ template(name="minicard") if getVoteQuestion .badge.badge-state-image-only(title=getVoteQuestion) span.badge-icon.fa.fa-thumbs-up + span.badge-text {{ voteCountPositive }} span.badge-icon.fa.fa-thumbs-down + span.badge-text {{ voteCountNegative }} if attachments.count .badge span.badge-icon.fa.fa-paperclip -- cgit v1.2.3-1-g7c22 From de993a079d9f528ae1cfe9d4ba8a3a7541d93941 Mon Sep 17 00:00:00 2001 From: Nico Date: Sun, 26 Apr 2020 02:44:14 +0200 Subject: Remove old code --- client/components/cards/cardDetails.jade | 5 ----- 1 file changed, 5 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 85425c59..b4259ae6 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -582,12 +582,7 @@ template(name="cardStartVotingPopup") a.flex.js-toggle-vote-allow-non-members .materialCheckBox#vote-allow-non-members(name="vote-allow-non-members") span {{_ 'allowNonBoardMembers'}} - //- label(for="vote-public") {{_ 'vote-public'}} - //- a.js-toggle-vote-public - //- .materialCheckBox#vote-public(name="vote-public") - button.primary.confirm.js-submit {{_ 'save'}} - //- button.js-remove-color.negate.wide.right {{_ 'delete'}} template(name="positiveVoteMembersPopup") ul.pop-over-list.js-card-member-list -- cgit v1.2.3-1-g7c22 From eddcb2260bdfba62ecd3e8f8fe6da6e6927ccc47 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Mon, 27 Apr 2020 01:15:10 +0200 Subject: Reactivate the touch event fix for the boards list This fixes https://github.com/wekan/wekan/issues/3049. --- client/components/boards/boardsList.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index df319ce0..9208fdb2 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,5 +1,5 @@ const subManager = new SubsManager(); -const { calculateIndex } = Utils; +const { calculateIndex, enableClickOnTouch } = Utils; Template.boardListHeaderBar.events({ 'click .js-open-archived-board'() { @@ -68,6 +68,9 @@ 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(() => { $boards.sortable('option', 'disabled', !userIsAllowedToMove()); -- cgit v1.2.3-1-g7c22 From ee106d1cb41b8e7b4ae757936f0f46688325f685 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 27 Apr 2020 02:54:40 +0300 Subject: Revert In Progress additional vote features. Translations are not removed. Thanks to xet7 ! Related https://github.com/wekan/wekan/pull/3048 --- client/components/cards/cardDetails.jade | 13 ++++--------- client/components/cards/cardDetails.js | 23 ++++++++++++++++------- client/components/cards/cardTime.jade | 7 +++---- client/components/cards/minicard.jade | 2 -- 4 files changed, 23 insertions(+), 22 deletions(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index b4259ae6..ae97e0e9 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -212,8 +212,6 @@ template(name="cardDetails") else .card-label.card-label-green {{ voteCountPositive }} .card-label.card-label-red {{ voteCountNegative }} - unless ($and currentBoard.isPublic voteAllowNonBoardMembers ) - .card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }} +viewer = getVoteQuestion button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") {{_ 'vote-for-it'}} @@ -574,15 +572,12 @@ template(name="cardStartVotingPopup") .fields label(for="vote") {{_ 'vote-question'}} input.js-vote-field#vote(type="text" name="vote" value="{{card.getVoteQuestion}}" autofocus) - .check-div - a.flex.js-toggle-vote-public + label(for="vote-public") {{_ 'vote-public'}} + a.js-toggle-vote-public .materialCheckBox#vote-public(name="vote-public") - span {{_ 'vote-public'}} - .check-div - a.flex.js-toggle-vote-allow-non-members - .materialCheckBox#vote-allow-non-members(name="vote-allow-non-members") - span {{_ 'allowNonBoardMembers'}} + button.primary.confirm.js-submit {{_ 'save'}} + //- button.js-remove-color.negate.wide.right {{_ 'delete'}} template(name="positiveVoteMembersPopup") ul.pop-over-list.js-card-member-list diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index b8c7fa3f..f31c3890 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -54,7 +54,21 @@ BlazeComponent.extendComponent({ } return null; }, - + votePublic() { + const card = this.currentData(); + if (card.vote) return card.vote.public; + return null; + }, + voteCountPositive() { + const card = this.currentData(); + if (card.vote && card.vote.positive) return card.vote.positive.length; + return null; + }, + voteCountNegative() { + const card = this.currentData(); + if (card.vote && card.vote.negative) return card.vote.negative.length; + return null; + }, isWatching() { const card = this.currentData(); return card.findWatcher(Meteor.userId()); @@ -987,18 +1001,13 @@ BlazeComponent.extendComponent({ evt.preventDefault(); const voteQuestion = evt.target.vote.value; const publicVote = $('#vote-public').hasClass('is-checked'); - const allowNonBoardMembers = $('#vote-allow-non-members').hasClass('is-checked'); - this.currentCard.setVoteQuestion(voteQuestion, publicVote,allowNonBoardMembers); + this.currentCard.setVoteQuestion(voteQuestion, publicVote); Popup.close(); }, 'click a.js-toggle-vote-public'(event) { event.preventDefault(); $('#vote-public').toggleClass('is-checked'); }, - 'click a.js-toggle-vote-allow-non-members'(event) { - event.preventDefault(); - $('#vote-allow-non-members').toggleClass('is-checked'); - }, }, ]; }, diff --git a/client/components/cards/cardTime.jade b/client/components/cards/cardTime.jade index 177b689f..8af8c414 100644 --- a/client/components/cards/cardTime.jade +++ b/client/components/cards/cardTime.jade @@ -4,10 +4,9 @@ template(name="editCardSpentTime") .fields label(for="time") {{_ 'time'}} input.js-time-field#time(type="number" step="0.01" name="time" value="{{card.getSpentTime}}" placeholder=timeFormat autofocus) - .check-div - a.flex.js-toggle-overtime - .materialCheckBox#overtime(class="{{#if getIsOvertime}}is-checked{{/if}}" name="overtime") - span {{_ 'overtime'}} + label(for="overtime") {{_ 'overtime'}} + a.js-toggle-overtime + .materialCheckBox#overtime(class="{{#if getIsOvertime}}is-checked{{/if}}" name="overtime") if error.get .warning {{_ error.get}} diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 79dd9127..b6ccd4d7 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -103,9 +103,7 @@ template(name="minicard") if getVoteQuestion .badge.badge-state-image-only(title=getVoteQuestion) span.badge-icon.fa.fa-thumbs-up - span.badge-text {{ voteCountPositive }} span.badge-icon.fa.fa-thumbs-down - span.badge-text {{ voteCountNegative }} if attachments.count .badge span.badge-icon.fa.fa-paperclip -- cgit v1.2.3-1-g7c22 From 09666585e22a1250416ec95c1ebb2748e2941d4d Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Mon, 27 Apr 2020 02:56:11 +0300 Subject: Revert part 2, related https://github.com/wekan/wekan/pull/3048 --- client/components/cards/cardDetails.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index f31c3890..271fbe2f 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -273,7 +273,10 @@ BlazeComponent.extendComponent({ // Disable sorting if the current user is not a board member this.autorun(() => { const disabled = !userIsMember() || Utils.isMiniScreen(); - if ($checklistsDom.data('uiSortable') || $checklistsDom.data('sortable')) { + if ( + $checklistsDom.data('uiSortable') || + $checklistsDom.data('sortable') + ) { $checklistsDom.sortable('option', 'disabled', disabled); } if ($subtasksDom.data('uiSortable') || $subtasksDom.data('sortable')) { -- cgit v1.2.3-1-g7c22 From f7a0d15db7ffff9cc395859f8b593b4545b87103 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Mon, 27 Apr 2020 02:04:46 +0200 Subject: Make sure that the board header buttons fit into one line ...even for devices with 360px width resolution. --- client/components/main/header.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/main/header.styl b/client/components/main/header.styl index 38ff0560..d8093861 100644 --- a/client/components/main/header.styl +++ b/client/components/main/header.styl @@ -175,7 +175,7 @@ .board-header-btn height: 32px line-height: @height - font-size: 16px + font-size: 15px i.fa line-height: 32px -- cgit v1.2.3-1-g7c22 From 9b9e3c9e0c2533495bfa2eba13d8580be5e48624 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Mon, 27 Apr 2020 14:14:56 +0200 Subject: Fix list header height when cards count is shown --- client/components/lists/list.styl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'client/components') diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 27cf678c..bc7f763f 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -43,9 +43,6 @@ background: white margin: -3px 0 8px -.list-header-card-count - height: 35px - .list-header-add flex: 0 0 auto padding: 20px 12px 4px @@ -60,6 +57,9 @@ background-color: #e4e4e4; border-bottom: 6px solid #e4e4e4; + &.list-header-card-count + min-height: 35px + height: auto &.ui-sortable-handle cursor: grab -- cgit v1.2.3-1-g7c22 From 6afc9259f084717a0cc3ce6d66979fd7c1471939 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 28 Apr 2020 15:14:10 +0300 Subject: Smaller height for Add Board button. Thanks to xet7 ! --- client/components/boards/boardsList.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/components') diff --git a/client/components/boards/boardsList.styl b/client/components/boards/boardsList.styl index d92c9cf3..97d4f195 100644 --- a/client/components/boards/boardsList.styl +++ b/client/components/boards/boardsList.styl @@ -69,7 +69,7 @@ $spaceBetweenTiles = 16px .label font-weight: normal - line-height:90px + line-height: 56px :hover background-color:#939393 -- cgit v1.2.3-1-g7c22 From 8d5adc04645e3e71423f16869f39b8d79969bccd Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Thu, 30 Apr 2020 06:54:48 +0300 Subject: Install Wekan to mobile homescreen icon and use fullscreen PWA. Docs at https://github.com/wekan/wekan/wiki/PWA Thanks to xet7 ! Closes #2879 --- client/components/main/layouts.jade | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'client/components') diff --git a/client/components/main/layouts.jade b/client/components/main/layouts.jade index 9543c5c5..08dfc58c 100644 --- a/client/components/main/layouts.jade +++ b/client/components/main/layouts.jade @@ -6,10 +6,16 @@ head where the application is deployed with a path prefix, but it seems to be difficult to do that cleanly with Blaze -- at least without adding extra packages. - link(rel="shortcut icon" href="/wekan-favicon.png") - link(rel="apple-touch-icon" href="/wekan-favicon.png") - link(rel="mask-icon" href="/wekan-logo-150.svg") - link(rel="manifest" href="/wekan-manifest.json") + link(rel="shortcut icon" type="image/x-icon" href="/favicon.ico") + link(rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png") + link(rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png") + link(rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png") + link(rel="manifest" href="/site.webmanifest") + link(rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5") + meta(name="apple-mobile-web-app-title" content="Wekan") + meta(name="application-name" content="Wekan") + meta(name="msapplication-TileColor" content="#00aba9") + meta(name="theme-color" content="#ffffff") template(name="userFormsLayout") section.auth-layout -- cgit v1.2.3-1-g7c22