summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicu Tofan <nicu.tofan@gmail.com>2018-06-23 23:22:38 +0300
committerNicu Tofan <nicu.tofan@gmail.com>2018-06-26 14:32:49 +0300
commit5a023e431504f7573723db6e0d2262ecb1fc61c5 (patch)
tree46ac0e238fddc5e797eca27cc2545ad5975f86a9
parentadb7f5b2ca9e8394db314f7ff97d0d0f811c51c0 (diff)
downloadwekan-5a023e431504f7573723db6e0d2262ecb1fc61c5.tar.gz
wekan-5a023e431504f7573723db6e0d2262ecb1fc61c5.tar.bz2
wekan-5a023e431504f7573723db6e0d2262ecb1fc61c5.zip
Can add cards as subtasks
-rw-r--r--client/components/cards/subtasks.js26
-rw-r--r--i18n/en.i18n.json4
-rw-r--r--models/boards.js54
-rw-r--r--server/migrations.js13
4 files changed, 92 insertions, 5 deletions
diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js
index dc6c607f..0df5d21f 100644
--- a/client/components/cards/subtasks.js
+++ b/client/components/cards/subtasks.js
@@ -12,13 +12,31 @@ BlazeComponent.extendComponent({
const title = textarea.value.trim();
const cardId = this.currentData().cardId;
const card = Cards.findOne(cardId);
+ const sortIndex = -1;
+ const crtBoard = Boards.findOne(card.boardId);
+ const targetBoard = crtBoard.getDefaultSubtasksBoard();
+ const listId = targetBoard.getDefaultSubtasksListId();
+ const swimlaneId = Swimlanes.findOne({boardId: targetBoard._id})._id;
if (title) {
- Subtasks.insert({
- cardId,
+ const _id = Cards.insert({
title,
- sort: card.subtasks().count(),
+ parentId: cardId,
+ members: [],
+ labelIds: [],
+ customFields: [],
+ listId,
+ boardId: targetBoard._id,
+ sort: sortIndex,
+ swimlaneId,
});
+ // In case the filter is active we need to add the newly inserted card in
+ // the list of exceptions -- cards that are not filtered. Otherwise the
+ // card will disappear instantly.
+ // See https://github.com/wekan/wekan/issues/80
+ Filter.addException(_id);
+
+
setTimeout(() => {
this.$('.add-subtask-item').last().click();
}, 100);
@@ -34,7 +52,7 @@ BlazeComponent.extendComponent({
deleteSubtask() {
const subtask = this.currentData().subtask;
if (subtask && subtask._id) {
- Subtasks.remove(subtask._id);
+ Cards.remove(subtask._id);
this.toggleDeleteDialog.set(false);
}
},
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index 17d0ff71..3a87179a 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -479,5 +479,7 @@
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
- "delete-board": "Delete Board"
+ "delete-board": "Delete Board",
+ "default-subtasks-board": "Subtasks for __board__ board",
+ "default": "Default"
}
diff --git a/models/boards.js b/models/boards.js
index 911d82a1..6836a320 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -151,6 +151,16 @@ Boards.attachSchema(new SimpleSchema({
type: String,
optional: true,
},
+ subtasksDefaultBoardId: {
+ type: String,
+ optional: true,
+ defaultValue: null,
+ },
+ subtasksDefaultListId: {
+ type: String,
+ optional: true,
+ defaultValue: null,
+ },
}));
@@ -284,8 +294,52 @@ Boards.helpers({
return Cards.find(query, projection);
},
+ // A board alwasy has another board where it deposits subtasks of thasks
+ // that belong to itself.
+ getDefaultSubtasksBoardId() {
+ if (this.subtasksDefaultBoardId === null) {
+ this.subtasksDefaultBoardId = Boards.insert({
+ title: `^${this.title}^`,
+ permission: this.permission,
+ members: this.members,
+ color: this.color,
+ description: TAPi18n.__('default-subtasks-board', {board: this.title}),
+ });
+
+ Swimlanes.insert({
+ title: TAPi18n.__('default'),
+ boardId: this.subtasksDefaultBoardId,
+ });
+ Boards.update(this._id, {$set: {
+ subtasksDefaultBoardId: this.subtasksDefaultBoardId,
+ }});
+ }
+ return this.subtasksDefaultBoardId;
+ },
+
+ getDefaultSubtasksBoard() {
+ return Boards.findOne(this.getDefaultSubtasksBoardId());
+ },
+
+ getDefaultSubtasksListId() {
+ if (this.subtasksDefaultListId === null) {
+ this.subtasksDefaultListId = Lists.insert({
+ title: TAPi18n.__('new'),
+ boardId: this._id,
+ });
+ Boards.update(this._id, {$set: {
+ subtasksDefaultListId: this.subtasksDefaultListId,
+ }});
+ }
+ return this.subtasksDefaultListId;
+ },
+
+ getDefaultSubtasksList() {
+ return Lists.findOne(this.getDefaultSubtasksListId());
+ },
});
+
Boards.mutations({
archive() {
return { $set: { archived: true } };
diff --git a/server/migrations.js b/server/migrations.js
index cfc0d5ab..3ab3070d 100644
--- a/server/migrations.js
+++ b/server/migrations.js
@@ -269,3 +269,16 @@ Migrations.add('add-parent-field-to-cards', () => {
},
}, noValidateMulti);
});
+
+Migrations.add('add-subtasks-boards', () => {
+ Boards.update({
+ subtasksDefaultBoardId: {
+ $exists: false,
+ },
+ }, {
+ $set: {
+ subtasksDefaultBoardId: null,
+ subtasksDefaultListId: null,
+ },
+ }, noValidateMulti);
+});