diff options
-rw-r--r-- | client/components/boards/boardHeader.jade | 31 | ||||
-rw-r--r-- | client/components/boards/boardHeader.js | 27 | ||||
-rw-r--r-- | client/components/boards/boardHeader.styl | 19 | ||||
-rw-r--r-- | client/components/cards/cardDetails.jade | 6 | ||||
-rw-r--r-- | client/components/cards/cardDetails.js | 8 | ||||
-rw-r--r-- | client/components/cards/minicard.jade | 16 | ||||
-rw-r--r-- | i18n/en.i18n.json | 11 | ||||
-rw-r--r-- | models/boards.js | 16 | ||||
-rw-r--r-- | models/cards.js | 53 | ||||
-rw-r--r-- | server/migrations.js | 14 |
10 files changed, 193 insertions, 8 deletions
diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 59691a61..a4abfac6 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -199,9 +199,30 @@ template(name="boardChangeColorPopup") template(name="boardSubtaskSettingsPopup") form.board-subtask-settings - a.flex.js-field-has-subtasks(class="{{#if allowsSubtasks}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsSubtasks}}is-checked{{/if}}") - span {{_ 'show-subtasks-field'}} + h3 {{_ 'show-parent-in-minicard'}} + a#prefix-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}") + .materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}") + span {{_ 'prefix-with-full-path'}} + a#prefix-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}") + .materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}") + span {{_ 'prefix-with-parent'}} + a#subtext-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}") + .materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}") + span {{_ 'subtext-with-full-path'}} + a#subtext-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}") + .materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}") + span {{_ 'subtext-with-parent'}} + a#no-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}") + .materialCheckBox(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}") + span {{_ 'no-parent'}} + div + hr + + div.check-div + a.flex.js-field-has-subtasks(class="{{#if allowsSubtasks}}is-checked{{/if}}") + .materialCheckBox(class="{{#if allowsSubtasks}}is-checked{{/if}}") + span {{_ 'show-subtasks-field'}} + label | {{_ 'deposit-subtasks-board'}} select.js-field-deposit-board(disabled="{{#unless allowsSubtasks}}disabled{{/unless}}") @@ -214,7 +235,9 @@ template(name="boardSubtaskSettingsPopup") option(value='null' selected="selected") {{_ 'custom-field-dropdown-none'}} else option(value='null') {{_ 'custom-field-dropdown-none'}} - hr + div + hr + label | {{_ 'deposit-subtasks-list'}} select.js-field-deposit-list(disabled="{{#unless hasLists}}disabled{{/unless}}") diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index bafee9b9..865bb212 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -195,6 +195,14 @@ BlazeComponent.extendComponent({ return this.currentBoard.subtasksDefaultBoardId === this.currentData()._id; }, + presentParentTask() { + let result = this.currentBoard.presentParentTask; + if ((result === null) || (result === undefined)) { + result = 'no-parent'; + } + return result; + }, + events() { return [{ 'click .js-field-has-subtasks'(evt) { @@ -217,6 +225,25 @@ BlazeComponent.extendComponent({ this.currentBoard.setSubtasksDefaultListId(evt.target.value); evt.preventDefault(); }, + 'click .js-field-show-parent-in-minicard'(evt) { + const value = evt.target.id || $(evt.target).parent()[0].id || $(evt.target).parent()[0].parent()[0].id; + const options = [ + 'prefix-with-full-path', + 'prefix-with-parent', + 'subtext-with-full-path', + 'subtext-with-parent', + 'no-parent']; + options.forEach(function(element) { + if (element !== value) { + $(`#${element} .materialCheckBox`).toggleClass('is-checked', false); + $(`#${element}`).toggleClass('is-checked', false); + } + }); + $(`#${value} .materialCheckBox`).toggleClass('is-checked', true); + $(`#${value}`).toggleClass('is-checked', true); + this.currentBoard.setPresentParentTask(value); + evt.preventDefault(); + }, }]; }, }).register('boardSubtaskSettingsPopup'); diff --git a/client/components/boards/boardHeader.styl b/client/components/boards/boardHeader.styl index 0abdb5bd..402b4f1e 100644 --- a/client/components/boards/boardHeader.styl +++ b/client/components/boards/boardHeader.styl @@ -1,3 +1,22 @@ .integration-form padding: 5px border-bottom: 1px solid #ccc + +.flex + display: -webkit-box + display: -moz-box + display: -webkit-flex + display: -moz-flex + display: -ms-flexbox + display: flex + +.option + @extends .flex + -webkit-border-radius: 3px; + border-radius: 3px; + background: #fff; + text-decoration: none; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2); + box-shadow: 0 1px 2px rgba(0,0,0,0.2); + margin-top: 5px; + padding: 5px; diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 789cc4b1..a5b8a2b3 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -13,6 +13,12 @@ template(name="cardDetails") = title if isWatching i.fa.fa-eye.card-details-watch + .card-details-path + each parentList + | > + a.js-parent-card {{title}} + // else + {{_ 'top-level-card'}} if archived p.warning {{_ 'card-archived'}} diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 4731e448..1c85580f 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -70,6 +70,14 @@ BlazeComponent.extendComponent({ } }, + presentParentTask() { + let result = this.currentBoard.presentParentTask; + if ((result === null) || (result === undefined)) { + result = 'no-parent'; + } + return result; + }, + onRendered() { if (!Utils.isMiniScreen()) this.scrollParentContainer(); const $checklistsDom = this.$('.card-checklist-items'); diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 2a8e95ab..9a9b897f 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -8,7 +8,21 @@ template(name="minicard") .minicard-label(class="card-label-{{color}}" title="{{name}}") .minicard-title +viewer - = title + if isTopLevel + = title + else + if $eq 'prefix-with-full-path' currentBoard.presentParentTask + [{{ parentString ' > ' }}] {{ title }} + else + if $eq 'prefix-with-parent' currentBoard.presentParentTask + [{{ parentCardName }}] {{ title }} + else + = title + if $eq 'subtext-with-full-path' currentBoard.presentParentTask + .small {{ parentString ' > ' }} + if $eq 'subtext-with-parent' currentBoard.presentParentTask + .small {{ parentCardName }} + .dates if receivedAt unless startAt diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index e410572f..ed2c45af 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -485,7 +485,14 @@ "queue": "Queue", "subtask-settings": "Subtasks Settings", "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", - "show-subtasks-field": "Cards can have subtasks:", + "show-subtasks-field": "Cards can have subtasks", "deposit-subtasks-board": "Deposit subtasks to this board:", - "deposit-subtasks-list": "Landing list for subtasks deposited here:" + "deposit-subtasks-list": "Landing list for subtasks deposited here:", + "show-parent-in-minicard": "Show parent in minicard:", + "prefix-with-full-path": "Prefix with full path", + "prefix-with-parent": "Prefix with parent", + "subtext-with-full-path": "Subtext with full path", + "subtext-with-parent": "Subtext with full parent", + "no-parent": "Don't show parent" + } diff --git a/models/boards.js b/models/boards.js index b5b0b0fc..2d80a56a 100644 --- a/models/boards.js +++ b/models/boards.js @@ -165,6 +165,18 @@ Boards.attachSchema(new SimpleSchema({ type: Boolean, defaultValue: true, }, + presentParentTask: { + type: String, + allowedValues: [ + 'prefix-with-full-path', + 'prefix-with-parent', + 'subtext-with-full-path', + 'subtext-with-parent', + 'no-parent', + ], + optional: true, + defaultValue: 'no-parent', + }, })); @@ -489,6 +501,10 @@ Boards.mutations({ setSubtasksDefaultListId(subtasksDefaultListId) { return { $set: { subtasksDefaultListId } }; }, + + setPresentParentTask(presentParentTask) { + return { $set: { presentParentTask } }; + }, }); if (Meteor.isServer) { diff --git a/models/cards.js b/models/cards.js index 8d7a93d0..323ec407 100644 --- a/models/cards.js +++ b/models/cards.js @@ -326,6 +326,59 @@ Cards.helpers({ return Cards.findOne(this.parentId); }, + parentCardName() { + if (this.parentId === '') { + return ''; + } + return Cards.findOne(this.parentId).title; + }, + + parentListId() { + const result = []; + let crtParentId = this.parentId; + while (crtParentId !== '') { + const crt = Cards.findOne(crtParentId); + if ((crt === null) || (crt === undefined)) { + // maybe it has been deleted + break; + } + if (crtParentId in result) { + // circular reference + break; + } + result.unshift(crtParentId); + crtParentId = crt.parentId; + } + return result; + }, + + parentList() { + const resultId = []; + const result = []; + let crtParentId = this.parentId; + while (crtParentId !== '') { + const crt = Cards.findOne(crtParentId); + if ((crt === null) || (crt === undefined)) { + // maybe it has been deleted + break; + } + if (crtParentId in resultId) { + // circular reference + break; + } + resultId.unshift(crtParentId); + result.unshift(crt); + crtParentId = crt.parentId; + } + return result; + }, + + parentString(sep) { + return this.parentList().map(function(elem){ + return elem.title; + }).join(sep); + }, + isTopLevel() { return this.parentId === ''; }, diff --git a/server/migrations.js b/server/migrations.js index c3da3221..5194b79f 100644 --- a/server/migrations.js +++ b/server/migrations.js @@ -294,7 +294,19 @@ Migrations.add('add-subtasks-allowed', () => { }, }, { $set: { - allowsSubtasks: -1, + allowsSubtasks: true, + }, + }, noValidateMulti); +}); + +Migrations.add('add-subtasks-allowed', () => { + Boards.update({ + presentParentTask: { + $exists: false, + }, + }, { + $set: { + presentParentTask: 'no-parent', }, }, noValidateMulti); }); |