summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/components/boards/boardHeader.jade31
-rw-r--r--client/components/boards/boardHeader.js27
-rw-r--r--client/components/boards/boardHeader.styl19
-rw-r--r--client/components/cards/cardDetails.jade6
-rw-r--r--client/components/cards/cardDetails.js8
-rw-r--r--client/components/cards/minicard.jade16
-rw-r--r--i18n/en.i18n.json11
-rw-r--r--models/boards.js16
-rw-r--r--models/cards.js53
-rw-r--r--server/migrations.js14
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);
});