فهرست منبع

Board level settings for subtasks

Nicu Tofan 7 سال پیش
والد
کامیت
94a52080cf

+ 31 - 0
client/components/boards/boardHeader.jade

@@ -130,6 +130,10 @@ template(name="boardMenuPopup")
         li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}}
         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
@@ -193,6 +197,33 @@ template(name="boardChangeColorPopup")
           if isSelected
             i.fa.fa-check
 
+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'}}
+    label
+      | {{_ 'deposit-subtasks-board'}}
+      select.js-field-deposit-board(disabled="{{#unless allowsSubtasks}}disabled{{/unless}}")
+          each boards
+            if isBoardSelected
+              option(value=_id selected="selected") {{title}}
+            else
+              option(value=_id) {{title}}
+          if isNullBoardSelected
+            option(value='null' selected="selected") {{_ 'custom-field-dropdown-none'}}
+          else
+            option(value='null') {{_ 'custom-field-dropdown-none'}}
+    hr
+    label
+      | {{_ 'deposit-subtasks-list'}}
+      select.js-field-deposit-list(disabled="{{#unless hasLists}}disabled{{/unless}}")
+          each lists
+            if isListSelected
+              option(value=_id selected="selected") {{title}}
+            else
+              option(value=_id) {{title}}
+
 template(name="createBoard")
   form
     label

+ 70 - 0
client/components/boards/boardHeader.js

@@ -25,6 +25,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'),
 });
 
 Template.boardMenuPopup.helpers({
@@ -151,6 +152,75 @@ BlazeComponent.extendComponent({
   },
 }).register('boardChangeColorPopup');
 
+BlazeComponent.extendComponent({
+  onCreated() {
+    this.currentBoard = Boards.findOne(Session.get('currentBoard'));
+  },
+
+  allowsSubtasks() {
+    return this.currentBoard.allowsSubtasks;
+  },
+
+  isBoardSelected() {
+    return this.currentBoard.subtasksDefaultBoardId === this.currentData()._id;
+  },
+
+  isNullBoardSelected() {
+    return (this.currentBoard.subtasksDefaultBoardId === null) || (this.currentBoard.subtasksDefaultBoardId === 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.subtasksDefaultBoardId === this.currentData()._id;
+  },
+
+  events() {
+    return [{
+      'click .js-field-has-subtasks'(evt) {
+        evt.preventDefault();
+        this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks;
+        this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks);
+        $('.js-field-has-subtasks .materialCheckBox').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
+        $('.js-field-has-subtasks').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
+        $('.js-field-deposit-board').prop('disabled', !this.currentBoard.allowsSubtasks);
+      },
+      'change .js-field-deposit-board'(evt) {
+        let value = evt.target.value;
+        if (value === 'null') {
+          value = null;
+        }
+        this.currentBoard.setSubtasksDefaultBoardId(value);
+        evt.preventDefault();
+      },
+      'change .js-field-deposit-list'(evt) {
+        this.currentBoard.setSubtasksDefaultListId(evt.target.value);
+        evt.preventDefault();
+      },
+    }];
+  },
+}).register('boardSubtaskSettingsPopup');
+
 const CreateBoard = BlazeComponent.extendComponent({
   template() {
     return 'createBoard';

+ 3 - 2
client/components/cards/cardDetails.jade

@@ -144,8 +144,9 @@ template(name="cardDetails")
     hr
     +checklists(cardId = _id)
 
-    hr
-    +subtasks(cardId = _id)
+    if currentBoard.allowsSubtasks
+      hr
+      +subtasks(cardId = _id)
 
     hr
     h3

+ 1 - 0
client/components/cards/subtasks.js

@@ -30,6 +30,7 @@ BlazeComponent.extendComponent({
         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.

+ 6 - 1
i18n/en.i18n.json

@@ -482,5 +482,10 @@
     "delete-board": "Delete Board",
     "default-subtasks-board": "Subtasks for __board__ board",
     "default": "Default",
-    "queue": "Queue"
+    "queue": "Queue",
+    "subtask-settings": "Subtasks Settings",
+    "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
+    "show-subtasks-field": "Cards can have subtasks:",
+    "deposit-subtasks-board": "Deposit subtasks to this board:",
+    "deposit-subtasks-list": "Landing list for subtasks deposited here:"
 }

+ 16 - 0
models/boards.js

@@ -161,6 +161,10 @@ Boards.attachSchema(new SimpleSchema({
     optional: true,
     defaultValue: null,
   },
+  allowsSubtasks: {
+    type: Boolean,
+    defaultValue: true,
+  },
 }));
 
 
@@ -473,6 +477,18 @@ Boards.mutations({
       },
     };
   },
+
+  setAllowsSubtasks(allowsSubtasks) {
+    return { $set: { allowsSubtasks } };
+  },
+
+  setSubtasksDefaultBoardId(subtasksDefaultBoardId) {
+    return { $set: { subtasksDefaultBoardId } };
+  },
+
+  setSubtasksDefaultListId(subtasksDefaultListId) {
+    return { $set: { subtasksDefaultListId } };
+  },
 });
 
 if (Meteor.isServer) {

+ 1 - 1
models/cards.js

@@ -258,7 +258,7 @@ Cards.helpers({
     return finishCount > 0 && this.subtasksCount() === finishCount;
   },
 
-  hasSubtasks() {
+  allowsSubtasks() {
     return this.subtasksCount() !== 0;
   },
 

+ 12 - 0
server/migrations.js

@@ -287,3 +287,15 @@ Migrations.add('add-subtasks-sort', () => {
   }, noValidateMulti);
 });
 
+Migrations.add('add-subtasks-allowed', () => {
+  Boards.update({
+    allowsSubtasks: {
+      $exists: false,
+    },
+  }, {
+    $set: {
+      allowsSubtasks: -1,
+    },
+  }, noValidateMulti);
+});
+