diff options
Diffstat (limited to 'client/components')
-rw-r--r-- | client/components/activities/activities.jade | 56 | ||||
-rw-r--r-- | client/components/activities/activities.js | 39 | ||||
-rw-r--r-- | client/components/boards/boardHeader.jade | 20 | ||||
-rw-r--r-- | client/components/boards/boardsList.js | 6 | ||||
-rw-r--r-- | client/components/cards/cardDetails.jade | 10 | ||||
-rw-r--r-- | client/components/cards/cardDetails.js | 22 | ||||
-rw-r--r-- | client/components/cards/checklists.jade | 18 | ||||
-rw-r--r-- | client/components/cards/checklists.js | 16 | ||||
-rw-r--r-- | client/components/cards/checklists.styl | 16 | ||||
-rw-r--r-- | client/components/cards/minicard.jade | 4 | ||||
-rw-r--r-- | client/components/cards/minicard.styl | 9 | ||||
-rw-r--r-- | client/components/rules/actions/cardActions.jade | 2 | ||||
-rw-r--r-- | client/components/swimlanes/swimlaneHeader.jade | 3 | ||||
-rw-r--r-- | client/components/swimlanes/swimlanes.js | 2 |
14 files changed, 134 insertions, 89 deletions
diff --git a/client/components/activities/activities.jade b/client/components/activities/activities.jade index c86936a0..77acd6a3 100644 --- a/client/components/activities/activities.jade +++ b/client/components/activities/activities.jade @@ -34,38 +34,38 @@ template(name="activity") //- board activity ------------------------------------------------------ if($eq mode 'board') if($eq activity.activityType 'createBoard') - | {{_ 'activity-created' boardLabel}}. + | {{{_ 'activity-created' boardLabelLink}}}. if($eq activity.activityType 'importBoard') - | {{{_ 'activity-imported-board' boardLabel sourceLink}}}. + | {{{_ 'activity-imported-board' boardLabelLink sourceLink}}}. if($eq activity.activityType 'addBoardMember') - | {{{_ 'activity-added' memberLink boardLabel}}}. + | {{{_ 'activity-added' memberLink boardLabelLink}}}. if($eq activity.activityType 'removeBoardMember') - | {{{_ 'activity-excluded' memberLink boardLabel}}}. + | {{{_ 'activity-excluded' memberLink boardLabelLink}}}. //- card activity ------------------------------------------------------- if($eq activity.activityType 'createCard') if($eq mode 'card') - | {{{_ 'activity-added' cardLabel activity.listName}}}. + | {{{_ 'activity-added' cardLabelLink (sanitize activity.listName)}}}. else - | {{{_ 'activity-added' cardLabel boardLabel}}}. + | {{{_ 'activity-added' cardLabelLink boardLabelLink}}}. if($eq activity.activityType 'importCard') - | {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}. + | {{{_ 'activity-imported' cardLink boardLabelLink sourceLink}}}. if($eq activity.activityType 'moveCard') - | {{{_ 'activity-moved' cardLabel activity.oldList.title activity.list.title}}}. + | {{{_ 'activity-moved' cardLabelLink (sanitize activity.oldList.title) (sanitize activity.list.title)}}}. if($eq activity.activityType 'moveCardBoard') - | {{{_ 'activity-moved' cardLink activity.oldBoardName activity.boardName}}}. + | {{{_ 'activity-moved' cardLink (sanitize activity.oldBoardName) (sanitize activity.boardName)}}}. if($eq activity.activityType 'archivedCard') | {{{_ 'activity-archived' cardLink}}}. if($eq activity.activityType 'restoredCard') - | {{{_ 'activity-sent' cardLink boardLabel}}}. + | {{{_ 'activity-sent' cardLink boardLabelLink}}}. //- checklist activity -------------------------------------------------- if($eq activity.activityType 'addChecklist') @@ -83,25 +83,25 @@ template(name="activity") | {{{_ 'activity-checklist-removed' cardLink}}}. if($eq activity.activityType 'completeChecklist') - | {{{_ 'activity-checklist-completed' activity.checklist.title cardLink}}}. + | {{{_ 'activity-checklist-completed' (sanitize activity.checklist.title) cardLink}}}. if($eq activity.activityType 'uncompleteChecklist') - | {{{_ 'activity-checklist-uncompleted' activity.checklist.title cardLink}}}. + | {{{_ 'activity-checklist-uncompleted' (sanitize activity.checklist.title) cardLink}}}. if($eq activity.activityType 'checkedItem') - | {{{_ 'activity-checked-item' checkItem activity.checklist.title cardLink}}}. + | {{{_ 'activity-checked-item' (sanitize checkItem) (sanitize activity.checklist.title) cardLink}}}. if($eq activity.activityType 'uncheckedItem') - | {{{_ 'activity-unchecked-item' checkItem activity.checklist.title cardLink}}}. + | {{{_ 'activity-unchecked-item' (sanitize checkItem) (sanitize activity.checklist.title) cardLink}}}. if($eq activity.activityType 'addChecklistItem') - | {{{_ 'activity-checklist-item-added' activity.checklist.title cardLink}}}. + | {{{_ 'activity-checklist-item-added' (sanitize activity.checklist.title) cardLink}}}. .activity-checklist(href="{{ activity.card.absoluteUrl }}") +viewer = activity.checklistItem.title if($eq activity.activityType 'removedChecklistItem') - | {{{_ 'activity-checklist-item-removed' activity.checklist.title cardLink}}}. + | {{{_ 'activity-checklist-item-removed' (sanitize activity.checklist.title) cardLink}}}. //- comment activity ---------------------------------------------------- if($eq mode 'card') @@ -143,31 +143,31 @@ template(name="activity") | {{_ 'activity-customfield-created' customField}}. if($eq activity.activityType 'setCustomField') - | {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}. + | {{{_ 'activity-set-customfield' (sanitize lastCustomField) (sanitize lastCustomFieldValue) cardLink}}}. if($eq activity.activityType 'unsetCustomField') - | {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}. + | {{{_ 'activity-unset-customfield' (sanitize lastCustomField) cardLink}}}. //- label activity ------------------------------------------------------ if($eq activity.activityType 'addedLabel') - | {{{_ 'activity-added-label' lastLabel cardLink}}}. + | {{{_ 'activity-added-label' (sanitize lastLabel) cardLink}}}. if($eq activity.activityType 'removedLabel') - | {{{_ 'activity-removed-label' lastLabel cardLink}}}. + | {{{_ 'activity-removed-label' (sanitize lastLabel) cardLink}}}. //- list activity ------------------------------------------------------- if($neq mode 'card') if($eq activity.activityType 'createList') - | {{{_ 'activity-added' listLabel boardLabel}}}. + | {{{_ 'activity-added' (sanitize listLabel) boardLabelLink}}}. if($eq activity.activityType 'importList') - | {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}. + | {{{_ 'activity-imported' (sanitize listLabel) boardLabelLink sourceLink}}}. if($eq activity.activityType 'removeList') - | {{{_ 'activity-removed' activity.title boardLabel}}}. + | {{{_ 'activity-removed' (sanitize activity.title) boardLabelLink}}}. if($eq activity.activityType 'archivedList') - | {{_ 'activity-archived' listLabel}}. + | {{_ 'activity-archived' (sanitize listLabel)}}. //- member activity ---------------------------------------------------- if($eq activity.activityType 'joinMember') @@ -185,15 +185,15 @@ template(name="activity") //- swimlane activity -------------------------------------------------- if($neq mode 'card') if($eq activity.activityType 'createSwimlane') - | {{{_ 'activity-added' activity.swimlane.title boardLabel}}}. + | {{_ 'activity-added' (sanitize activity.swimlane.title) boardLabelLink}}. if($eq activity.activityType 'archivedSwimlane') - | {{_ 'activity-archived' activity.swimlane.title}}. + | {{_ 'activity-archived' (sanitize activity.swimlane.title)}}. //- I don't understand this part ---------------------------------------- if(currentData.timeKey) - | {{{_ activity.activityType }}} + | {{_ activity.activityType }} = ' ' i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }} if (currentData.timeOldValue) @@ -203,6 +203,6 @@ template(name="activity") i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }} = ' @' else if(currentData.timeValue) - | {{{_ activity.activityType 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 5d356f6e..83843d1d 100644 --- a/client/components/activities/activities.js +++ b/client/components/activities/activities.js @@ -1,3 +1,5 @@ +import sanitizeXss from 'xss'; + const activitiesPerPage = 20; BlazeComponent.extendComponent({ @@ -5,8 +7,9 @@ BlazeComponent.extendComponent({ // XXX Should we use ReactiveNumber? this.page = new ReactiveVar(1); this.loadNextPageLocked = false; - const sidebar = this.parentComponent(); // XXX for some reason not working - sidebar.callFirstWith(null, 'resetNextPeak'); + // TODO is sidebar always available? E.g. on small screens/mobile devices + const sidebar = Sidebar; + sidebar && sidebar.callFirstWith(null, 'resetNextPeak'); this.autorun(() => { let mode = this.data().mode; const capitalizedMode = Utils.capitalize(mode); @@ -27,6 +30,8 @@ BlazeComponent.extendComponent({ this.subscribe('activities', mode, searchId, limit, hideSystem, () => { this.loadNextPageLocked = false; + // TODO the guard can be removed as soon as the TODO above is resolved + if (!sidebar) return; // If the sibear peak hasn't increased, that mean that there are no more // activities, and we can stop calling new subscriptions. // XXX This is hacky! We need to know excatly and reactively how many @@ -41,23 +46,22 @@ BlazeComponent.extendComponent({ }); }); }, -}).register('activities'); - -BlazeComponent.extendComponent({ loadNextPage() { if (this.loadNextPageLocked === false) { this.page.set(this.page.get() + 1); this.loadNextPageLocked = true; } }, +}).register('activities'); +BlazeComponent.extendComponent({ checkItem() { const checkItemId = this.currentData().activity.checklistItemId; const checkItem = ChecklistItems.findOne({ _id: checkItemId }); return checkItem && checkItem.title; }, - boardLabel() { + boardLabelLink() { const data = this.currentData(); if (data.mode !== 'board') { return createBoardLink(data.activity.board(), data.activity.listName); @@ -65,10 +69,10 @@ BlazeComponent.extendComponent({ return TAPi18n.__('this-board'); }, - cardLabel() { + cardLabelLink() { const data = this.currentData(); if (data.mode !== 'card') { - return createCardLink(this.currentData().activity.card()); + return createCardLink(data.activity.card()); } return TAPi18n.__('this-card'); }, @@ -134,11 +138,11 @@ BlazeComponent.extendComponent({ { href: source.url, }, - source.system, + sanitizeXss(source.system), ), ); } else { - return source.system; + return sanitizeXss(source.system); } } return null; @@ -162,10 +166,10 @@ BlazeComponent.extendComponent({ href: attachment.url({ download: true }), target: '_blank', }, - attachment.name(), + sanitizeXss(attachment.name()), ), )) || - this.currentData().activity.attachmentName + sanitizeXss(this.currentData().activity.attachmentName) ); }, @@ -202,7 +206,14 @@ BlazeComponent.extendComponent({ }, }).register('activity'); +Template.activity.helpers({ + sanitize(value) { + return sanitizeXss(value); + }, +}); + function createCardLink(card) { + if (!card) return ''; return ( card && Blaze.toHTML( @@ -211,7 +222,7 @@ function createCardLink(card) { href: card.absoluteUrl(), class: 'action-card', }, - card.title, + sanitizeXss(card.title), ), ) ); @@ -228,7 +239,7 @@ function createBoardLink(board, list) { href: board.absoluteUrl(), class: 'action-board', }, - text, + sanitizeXss(text), ), ) ); diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 4c0edac4..1daf0618 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -99,13 +99,13 @@ template(name="boardHeaderBar") a.board-header-btn.js-toggle-board-view( title="{{_ 'board-view'}}") i.fa.fa-caret-down - if $eq boardView 'board-view-lists' - i.fa.fa-trello if $eq boardView 'board-view-swimlanes' i.fa.fa-th-large + if $eq boardView 'board-view-lists' + i.fa.fa-trello if $eq boardView 'board-view-cal' i.fa.fa-calendar - span {{#if boardView}}{{_ boardView}}{{else}}{{_ 'board-view-lists'}}{{/if}} + span {{#if boardView}}{{_ boardView}}{{else}}{{_ 'board-view-swimlanes'}}{{/if}} if canModifyBoard a.board-header-btn.js-multiselection-activate( @@ -173,13 +173,6 @@ template(name="boardChangeWatchPopup") template(name="boardChangeViewPopup") ul.pop-over-list li - with "board-view-lists" - a.js-open-lists-view - i.fa.fa-trello.colorful - | {{_ 'board-view-lists'}} - if $eq Utils.boardView "board-view-lists" - i.fa.fa-check - li with "board-view-swimlanes" a.js-open-swimlanes-view i.fa.fa-th-large.colorful @@ -187,6 +180,13 @@ template(name="boardChangeViewPopup") if $eq Utils.boardView "board-view-swimlanes" i.fa.fa-check li + with "board-view-lists" + a.js-open-lists-view + i.fa.fa-trello.colorful + | {{_ 'board-view-lists'}} + if $eq Utils.boardView "board-view-lists" + i.fa.fa-check + li with "board-view-cal" a.js-open-cal-view i.fa.fa-calendar.colorful diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index eee119ea..145f6789 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -25,10 +25,6 @@ BlazeComponent.extendComponent({ }, onRendered() { - function userIsAllowedToMove() { - return Meteor.user(); - } - const itemsSelector = '.js-board:not(.placeholder)'; const $boards = this.$('.js-boards'); @@ -77,8 +73,6 @@ BlazeComponent.extendComponent({ handle: '.board-handle', }); } - - $boards.sortable('option', 'disabled', !userIsAllowedToMove()); }); }, diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 2aa77627..dabee971 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -220,8 +220,14 @@ template(name="cardDetails") +viewer = getVoteQuestion if showVotingButtons - 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'}} + button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") + if voteState + i.fa.fa-thumbs-up + | {{_ 'vote-for-it'}} + button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}") + if $eq voteState false + i.fa.fa-thumbs-down + | {{_ 'vote-against'}} //- XXX We should use "editable" to avoid repetiting ourselves if canModifyCard diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 11e010d4..a91d9b6e 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -38,22 +38,6 @@ 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; - }, isWatching() { const card = this.currentData(); return card.findWatcher(Meteor.userId()); @@ -412,9 +396,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.data().voteState() === null || + (this.data().voteState() === false && forIt) || + (this.data().voteState() === true && !forIt) ) { newState = forIt; } diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index 1b1e088a..25aa11b9 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,7 +1,17 @@ template(name="checklists") - h3 - i.fa.fa-check - | {{_ 'checklists'}} + .checklists-title + h3 + i.fa.fa-check + | {{_ 'checklists'}} + if currentUser.isBoardMember + .material-toggle-switch + span.toggle-switch-title {{_ 'hide-checked-items'}} + if hideCheckedItems + input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton" checked="checked") + else + input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton") + label.toggle-label(for="toggleHideCheckedItemsButton") + if toggleDeleteDialog.get .board-overlay#card-details-overlay +checklistDeleteDialog(checklist = checklistToDelete) @@ -86,7 +96,7 @@ template(name="checklistItems") | {{_ 'add-checklist-item'}}... template(name='checklistItemDetail') - .js-checklist-item.checklist-item + .js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if hideCheckedItems}} invisible{{/if}}{{/if}}") if canModifyCard .check-box-container .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 29573d2b..17faa773 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -193,6 +193,9 @@ BlazeComponent.extendComponent({ } this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get()); }, + 'click #toggleHideCheckedItemsButton'() { + Meteor.call('toggleHideCheckedItems'); + }, }; return [ @@ -211,6 +214,14 @@ BlazeComponent.extendComponent({ }, }).register('checklists'); +Template.checklists.helpers({ + hideCheckedItems() { + const currentUser = Meteor.user(); + if (currentUser) return currentUser.hasHideCheckedItems(); + return false; + }, +}); + Template.checklistDeleteDialog.onCreated(() => { const $cardDetails = this.$('.card-details'); this.scrollState = { @@ -246,6 +257,11 @@ Template.checklistItemDetail.helpers({ !Meteor.user().isWorker() ); }, + hideCheckedItems() { + const user = Meteor.user(); + if (user) return user.hasHideCheckedItems(); + return false; + }, }); BlazeComponent.extendComponent({ diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl index 0a6d688b..e9b0fcd8 100644 --- a/client/components/cards/checklists.styl +++ b/client/components/cards/checklists.styl @@ -16,6 +16,10 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &:hover color: inherit +.checklists-title + display: flex + justify-content: space-between + .checklist-title .checkbox float: left @@ -99,6 +103,17 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item margin-top: 3px display: flex background: darken(white, 3%) + opacity: 1 + transition: height 0ms 400ms, opacity 400ms 0ms + height: auto + overflow: hidden + + &.is-checked.invisible + opacity: 0 + height: 0 + transition: height 0ms 0ms, opacity 600ms 0ms + margin-top: 0 + margin-bottom: 0 &.placeholder background: darken(white, 20%) @@ -128,6 +143,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item &.is-checked color: #8c8c8c font-style: italic + text-decoration: line-through & .viewer p margin-bottom: 2px diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 8afe1976..03511e0a 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -106,9 +106,9 @@ template(name="minicard") 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-up(class="{{#if voteState}}text-green{{/if}}") span.badge-text {{ voteCountPositive }} - span.badge-icon.fa.fa-thumbs-down + span.badge-icon.fa.fa-thumbs-down(class="{{#if $eq voteState false}}text-red{{/if}}") span.badge-text {{ voteCountNegative }} if attachments.count .badge diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index 7d72a588..1f40e883 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -87,7 +87,9 @@ width: 11px height: @width border-radius: 2px - margin-left: 3px + margin-right: 3px + margin-bottom: 3px + .minicard-custom-fields display:block; .minicard-custom-field @@ -299,3 +301,8 @@ minicard-color(background, color...) .minicard-indigo minicard-color(#4b0082, #ffffff) //White text for better visibility + +.text-red + color:red +.text-green + color:green diff --git a/client/components/rules/actions/cardActions.jade b/client/components/rules/actions/cardActions.jade index c10c4b2b..0840283b 100644 --- a/client/components/rules/actions/cardActions.jade +++ b/client/components/rules/actions/cardActions.jade @@ -75,7 +75,7 @@ template(name="cardActions") button.trigger-button.trigger-button-color.js-show-color-palette( id="color-action" class="card-details-{{cardColorButton}}") - | {{{_ cardColorButtonText }}} + | {{_ cardColorButtonText }} div.trigger-button.js-set-color-action.js-goto-rules i.fa.fa-plus diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 72a7f054..9228bf75 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -11,7 +11,8 @@ template(name="swimlaneHeader") template(name="swimlaneFixedHeader") .swimlane-header( class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}") - = title + +viewer + = title .swimlane-header-menu unless currentUser.isCommentOnly a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 753fa88b..1fc97a89 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -23,8 +23,8 @@ function currentCardIsInThisList(listId, swimlaneId) { currentCard.listId === listId && currentCard.swimlaneId === swimlaneId ); - // Default view: board-view-lists else return currentCard && currentCard.listId === listId; + // https://github.com/wekan/wekan/issues/1623 // https://github.com/ChronikEwok/wekan/commit/cad9b20451bb6149bfb527a99b5001873b06c3de // TODO: In public board, if you would like to switch between List/Swimlane view, you could |