2
0
Эх сурвалжийг харах

Customize of some card's functions

dollybean 5 жил өмнө
parent
commit
0b00a8095c

+ 1 - 3
CHANGELOG.md

@@ -1,11 +1,9 @@
-# v3.73 2020-01-29 Wekan release
+# Upcoming Wekan release
 
 This release adds the following new features:
 
 - [Login to Wekan with Nextcloud](https://github.com/wekan/wekan/pull/2897).
   Thanks to bogie.
-- [Add rule action to move cards to other boards](https://github.com/wekan/wekan/pull/2899).
-  Thanks to peterverraedt.
 
 and fixes the following bugs:
 

+ 1 - 1
Stackerfile.yml

@@ -1,5 +1,5 @@
 appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
-appVersion: "v3.73.0"
+appVersion: "v3.72.0"
 files:
   userUploads:
     - README.md

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

@@ -30,6 +30,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'),
+  'click .js-Date-settings': Popup.open('boardDateSettings')
 });
 
 Template.boardMenuPopup.helpers({

+ 129 - 114
client/components/cards/cardDetails.jade

@@ -8,10 +8,13 @@ template(name="cardDetails")
           a.fa.fa-times-thin.close-card-details.js-close-card-details
           if currentUser.isBoardMember
             a.fa.fa-navicon.card-details-menu.js-open-card-details-menu
+            input.inline-input(type="text" id="cardURL_copy" value="{{ absoluteUrl }}" autofocus="autofocus")
+            a.fa.fa-link.card-copy-button.js-copy-link
         if isMiniScreen
           a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details
           if currentUser.isBoardMember
             a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu
+            a.fa.fa-link.card-copy-mobile-button
         h2.card-details-title.js-card-title(
           class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
             +viewer
@@ -36,49 +39,41 @@ template(name="cardDetails")
         p.warning {{_ 'card-archived'}}
 
     .card-details-items
-      .card-details-item.card-details-item-received
-        h3
-          i.fa.fa-sign-out
-          card-details-item-title {{_ 'card-received'}}
-        if getReceived
-          +cardReceivedDate
-        else
-          if canModifyCard
-            unless currentUser.isWorker
-              a.js-received-date {{_ 'add'}}
-
-      .card-details-item.card-details-item-start
-        h3
-          i.fa.fa-hourglass-start
-          card-details-item-title {{_ 'card-start'}}
-        if getStart
-          +cardStartDate
-        else
-          if canModifyCard
-            unless currentUser.isWorker
-              a.js-start-date {{_ 'add'}}
-
-      .card-details-item.card-details-item-due
-        h3
-          i.fa.fa-sign-in
-          card-details-item-title {{_ 'card-due'}}
-        if getDue
-          +cardDueDate
-        else
-          if canModifyCard
-            unless currentUser.isWorker
-              a.js-due-date {{_ 'add'}}
-
-      .card-details-item.card-details-item-end
-        h3
-          i.fa.fa-hourglass-end
-          card-details-item-title {{_ 'card-end'}}
-        if getEnd
-          +cardEndDate
-        else
-          if canModifyCard
-            unless currentUser.isWorker
-              a.js-end-date {{_ 'add'}}
+      if currentBoard.allowsReceivedDate
+        .card-details-item.card-details-item-received
+          h3
+            i.fa.fa-sign-out
+            card-details-item-title {{_ 'card-received'}}
+          if getReceived
+            +cardReceivedDate
+          else
+            if canModifyCard
+              unless currentUser.isWorker
+                a.js-received-date {{_ 'add'}}
+
+      if currentBoard.allowsStartDate
+        .card-details-item.card-details-item-start
+          h3
+            i.fa.fa-hourglass-start
+            card-details-item-title {{_ 'card-start'}}
+          if getStart
+            +cardStartDate
+          else
+            if canModifyCard
+              unless currentUser.isWorker
+                a.js-start-date {{_ 'add'}}
+
+      if currentBoard.allowsEndDate
+        .card-details-item.card-details-item-end
+          h3
+            i.fa.fa-hourglass-end
+            card-details-item-title {{_ 'card-end'}}
+          if getEnd
+            +cardEndDate
+          else
+            if canModifyCard
+              unless currentUser.isWorker
+                a.js-end-date {{_ 'add'}}
 
     .card-details-items
       .card-details-item.card-details-item-members
@@ -92,22 +87,34 @@ template(name="cardDetails")
           unless currentUser.isWorker
             a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}")
               i.fa.fa-plus
-
-      .card-details-item.card-details-item-assignees
-        h3
-          i.fa.fa-user
-          card-details-item-title {{_ 'assignee'}}
-        each getAssignees
-          +userAvatarAssignee(userId=this cardId=../_id)
-          | {{! XXX Hack to hide syntaxic coloration /// }}
-        if canModifyCard
-          a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
-            i.fa.fa-plus
-        if currentUser.isWorker
-          unless assigneeSelected
+      if currentBoard.allowsDueDate
+        .card-details-item.card-details-item-due
+          h3
+            i.fa.fa-sign-in
+            card-details-item-title {{_ 'card-due'}}
+          if getDue
+            +cardDueDate
+          else
+            if canModifyCard
+              unless currentUser.isWorker
+                a.card-label.add-label.js-due-date
+                  i.fa.fa-plus
+
+      if assigngeeSelected
+        .card-details-item.card-details-item-assignees
+          h3
+            i.fa.fa-user
+            card-details-item-title {{_ 'assignee'}}
+          each getAssignees
+            +userAvatarAssignee(userId=this cardId=../_id)
+            | {{! XXX Hack to hide syntaxic coloration /// }}
+          if canModifyCard
             a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
               i.fa.fa-plus
-
+          if currentUser.isWorker
+            unless assigneeSelected
+              a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
+                i.fa.fa-plus
 
       .card-details-item.card-details-item-labels
         h3
@@ -143,9 +150,9 @@ template(name="cardDetails")
     //- XXX We should use "editable" to avoid repetiting ourselves
     if canModifyCard
       unless currentUser.isWorker
-        h3
-          i.fa.fa-align-left
-          card-details-item-title {{_ 'description'}}
+        //h3
+          //- i.fa.fa-align-left
+          //- card-details-item-title {{_ 'description'}}
         +inlinedCardDescription(classNames="card-description js-card-description")
           +editor(autofocus=true)
             | {{getUnsavedValue 'cardDescription' _id getDescription}}
@@ -153,16 +160,16 @@ template(name="cardDetails")
             button.primary(type="submit") {{_ 'save'}}
             a.fa.fa-times-thin.js-close-inlined-form
         else
-          a.js-open-inlined-form
+          a.description-item.add-description.js-open-inlined-form
             if getDescription
               +viewer
                 = getDescription
             else
-              | {{_ 'edit'}}
+              | {{_ 'addmore-detail'}}
           if (hasUnsavedValue 'cardDescription' _id)
             p.quiet
               | {{_ 'unsaved-description'}}
-              a.js-open-inlined-form {{_ 'view-it'}}
+              a.description-item.add-description.js-open-inlined-form {{_ 'view-it'}}
               = ' - '
               a.js-close-inlined-form {{_ 'discard'}}
     else if getDescription
@@ -171,57 +178,59 @@ template(name="cardDetails")
         = getDescription
 
     .card-details-items
-      .card-details-item.card-details-item-name
-        h3
-          i.fa.fa-shopping-cart
-          card-details-item-title {{_ 'requested-by'}}
-        if canModifyCard
-          unless currentUser.isWorker
-            +inlinedForm(classNames="js-card-details-requester")
-              +editCardRequesterForm
-            else
-              a.js-open-inlined-form
-                if getRequestedBy
-                  +viewer
-                    = getRequestedBy
-                else
-                  | {{_ 'add'}}
-        else if getRequestedBy
-          +viewer
-            = getRequestedBy
-
-      .card-details-item.card-details-item-name
-        h3
-          i.fa.fa-user-plus
-          card-details-item-title {{_ 'assigned-by'}}
-        if canModifyCard
-          unless currentUser.isWorker
-            +inlinedForm(classNames="js-card-details-assigner")
-              +editCardAssignerForm
-            else
-              a.js-open-inlined-form
-                if getAssignedBy
-                  +viewer
-                    = getAssignedBy
-                else
-                  | {{_ 'add'}}
-        else if getRequestedBy
-          +viewer
-            = getAssignedBy
-
-    hr
-    +checklists(cardId = _id)
-
-    if currentBoard.allowsSubtasks
-      hr
-      +subtasks(cardId = _id)
-
-    hr
-    h3
-      i.fa.fa-paperclip
-      | {{_ 'attachments'}}
+      if requestBySelected
+        .card-details-item.card-details-item-name
+          h3
+            i.fa.fa-shopping-cart
+            card-details-item-title {{_ 'requested-by'}}
+          if canModifyCard
+            unless currentUser.isWorker
+              +inlinedForm(classNames="js-card-details-requester")
+                +editCardRequesterForm
+              else
+                a.js-open-inlined-form
+                  if getRequestedBy
+                    +viewer
+                      = getRequestedBy
+                  else
+                    | {{_ 'add'}}
+          else if getRequestedBy
+            +viewer
+              = getRequestedBy
 
-    +attachmentsGalery
+      if assigneeBySelected
+        .card-details-item.card-details-item-name
+          h3
+            i.fa.fa-user-plus
+            card-details-item-title {{_ 'assigned-by'}}
+          if canModifyCard
+            unless currentUser.isWorker
+              +inlinedForm(classNames="js-card-details-assigner")
+                +editCardAssignerForm
+              else
+                a.js-open-inlined-form
+                  if getAssignedBy
+                    +viewer
+                      = getAssignedBy
+                  else
+                    | {{_ 'add'}}
+          else if getRequestedBy
+            +viewer
+              = getAssignedBy
+
+    .card-checklist-attachmentGalerys
+      .card-checklist-attachmentGalery.card-checklists
+          +checklists(cardId = _id)
+          if currentBoard.allowsSubtasks
+            hr
+            +subtasks(cardId = _id)
+
+          //- hr
+          //- h3
+          //- i.fa.fa-paperclip
+          //- | {{_ 'attachments'}}
+      .card-checklist-attachmentGalery.card-attachmentGalery
+          +attachmentsGalery
 
     hr
     unless currentUser.isNoComments
@@ -239,7 +248,13 @@ template(name="cardDetails")
             label.toggle-label(for="toggleButton")
     if currentUser.isBoardMember
       unless currentUser.isNoComments
-        +commentForm
+        if canModifyCard
+          +inlinedForm(autoclose=false classNames="js-new-comment-form")
+            +commentForm
+          else
+            +userAvatar(userId=currentUser._id)
+            a.comment-item.add-comment.js-open-inlined-form
+              | {{_ 'Write Comment'}}
     unless currentUser.isNoComments
       if isLoaded.get
         if isLinkedCard

+ 87 - 0
client/components/cards/cardDetails.js

@@ -279,6 +279,29 @@ BlazeComponent.extendComponent({
         'click .js-close-card-details'() {
           Utils.goBoardId(this.data().boardId);
         },
+        'click .js-copy-link'() {
+          StringToCopyElement = document.getElementById('cardURL_copy');
+          StringToCopyElement.select();
+          if (document.execCommand('copy')) {
+            StringToCopyElement.blur();
+          } else {
+            document.getElementById('cardURL_copy').selectionStart = 0;
+            document.getElementById('cardURL_copy').selectionEnd = 999;
+            document.execCommand('copy');
+            if (window.getSelection) {
+              if (window.getSelection().empty) {
+                // Chrome
+                window.getSelection().empty();
+              } else if (window.getSelection().removeAllRanges) {
+                // Firefox
+                window.getSelection().removeAllRanges();
+              }
+            } else if (document.selection) {
+              // IE?
+              document.selection.empty();
+            }
+          }
+        },
         'click .js-open-card-details-menu': Popup.open('cardDetailsActions'),
         'submit .js-card-description'(event) {
           event.preventDefault();
@@ -371,6 +394,54 @@ Template.cardDetails.helpers({
     });
   },
 
+  receivedSelected() {
+    if (this.getReceived().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
+  startSelected() {
+    if (this.getstart().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
+  endSelected() {
+    if (this.getEnd().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
+  dueSelected() {
+    if (this.getDue().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
+  memberSelected() {
+    if (this.getMembers().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
+  labelSelected() {
+    if (this.getLabels().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
   assigneeSelected() {
     if (this.getAssignees().length === 0) {
       return false;
@@ -379,6 +450,22 @@ Template.cardDetails.helpers({
     }
   },
 
+  requestBySelected() {
+    if (this.getRequestBy().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
+  assigneeBySelected() {
+    if (this.getAssigneeBy().length === 0) {
+      return false;
+    } else {
+      return true;
+    }
+  },
+
   memberType() {
     const user = Users.findOne(this.userId);
     return user && user.isBoardAdmin() ? 'admin' : 'normal';

+ 4 - 0
client/components/main/editor.js

@@ -120,6 +120,10 @@ Template.editor.onRendered(() => {
     autosize($textarea);
     $textarea.escapeableTextComplete(mentions);
   };
+<<<<<<< HEAD
+=======
+  
+>>>>>>> ac37e360b69b799c12f03e1c158cfc0367d26e55
   if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) {
     const isSmall = Utils.isMiniScreen();
     const toolbar = isSmall

+ 12 - 25
client/components/rules/actions/boardActions.jade

@@ -1,42 +1,29 @@
 template(name="boardActions")
   div.trigger-item
     div.trigger-content
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-move-card-to'}}
       div.trigger-dropdown
         select(id="move-gen-action")
           option(value="top") {{_'r-top-of'}}
           option(value="bottom") {{_'r-bottom-of'}}
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-its-list'}}
     div.trigger-button.js-add-gen-move-action.js-goto-rules
       i.fa.fa-plus
 
   div.trigger-item
     div.trigger-content
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-move-card-to'}}
       div.trigger-dropdown
         select(id="move-spec-action")
           option(value="top") {{_'r-top-of'}}
           option(value="bottom") {{_'r-bottom-of'}}
-      div.trigger-text
-        | {{_'r-the-board'}}
-      div.trigger-dropdown
-        select(id="board-id")
-          each boards
-            if $eq _id currentBoard._id
-              option(value="{{_id}}" selected) {{_ 'current'}}
-            else
-              option(value="{{_id}}") {{title}}
-      div.trigger-text
-        | {{_'r-in-list'}}
+      div.trigger-text 
+        | {{_'r-list'}}
       div.trigger-dropdown
         input(id="listName",type=text,placeholder="{{_'r-name'}}")
-      div.trigger-text
-        | {{_'r-in-swimlane'}}
-      div.trigger-dropdown
-        input(id="swimlaneName",type=text,placeholder="{{_'r-name'}}")
     div.trigger-button.js-add-spec-move-action.js-goto-rules
       i.fa.fa-plus
 
@@ -46,14 +33,14 @@ template(name="boardActions")
         select(id="arch-action")
           option(value="archive") {{_'r-archive'}}
           option(value="unarchive") {{_'r-unarchive'}}
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-card'}}
     div.trigger-button.js-add-arch-action.js-goto-rules
       i.fa.fa-plus
 
   div.trigger-item
     div.trigger-content
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-add-swimlane'}}
       div.trigger-dropdown
         input(id="swimlane-name",type=text,placeholder="{{_'r-name'}}")
@@ -62,15 +49,15 @@ template(name="boardActions")
 
   div.trigger-item
     div.trigger-content
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-create-card'}}
       div.trigger-dropdown
         input(id="card-name",type=text,placeholder="{{_'r-name'}}")
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-in-list'}}
       div.trigger-dropdown
         input(id="list-name",type=text,placeholder="{{_'r-name'}}")
-      div.trigger-text
+      div.trigger-text 
         | {{_'r-in-swimlane'}}
       div.trigger-dropdown
         input(id="swimlane-name2",type=text,placeholder="{{_'r-name'}}")
@@ -78,8 +65,8 @@ template(name="boardActions")
       i.fa.fa-plus
 
 
-
-
+   
+  
 
 
 

+ 5 - 25
client/components/rules/actions/boardActions.js

@@ -1,22 +1,6 @@
 BlazeComponent.extendComponent({
   onCreated() {},
 
-  boards() {
-    const boards = Boards.find(
-      {
-        archived: false,
-        'members.userId': Meteor.userId(),
-        _id: {
-          $ne: Meteor.user().getTemplatesBoardId(),
-        },
-      },
-      {
-        sort: ['title'],
-      },
-    );
-    return boards;
-  },
-
   events() {
     return [
       {
@@ -68,18 +52,15 @@ BlazeComponent.extendComponent({
           const ruleName = this.data().ruleName.get();
           const trigger = this.data().triggerVar.get();
           const actionSelected = this.find('#move-spec-action').value;
-          const swimlaneName = this.find('#swimlaneName').value;
-          const listName = this.find('#listName').value;
+          const listTitle = this.find('#listName').value;
           const boardId = Session.get('currentBoard');
-          const destBoardId = this.find('#board-id').value;
           const desc = Utils.getTriggerActionDesc(event, this);
           if (actionSelected === 'top') {
             const triggerId = Triggers.insert(trigger);
             const actionId = Actions.insert({
               actionType: 'moveCardToTop',
-              listName,
-              swimlaneName,
-              boardId: destBoardId,
+              listTitle,
+              boardId,
               desc,
             });
             Rules.insert({
@@ -93,9 +74,8 @@ BlazeComponent.extendComponent({
             const triggerId = Triggers.insert(trigger);
             const actionId = Actions.insert({
               actionType: 'moveCardToBottom',
-              listName,
-              swimlaneName,
-              boardId: destBoardId,
+              listTitle,
+              boardId,
               desc,
             });
             Rules.insert({

+ 29 - 0
client/components/sidebar/sidebar.jade

@@ -72,6 +72,25 @@ template(name="boardChangeColorPopup")
           if isSelected
             i.fa.fa-check
 
+template(name="boardDateSettingsPopup")
+  form.board-Date-settings
+    div.check-div
+      a.flex.js-field-has-receiveddate(class="{{#if allowsReceivedDate}}is-checked{{/if}}")
+        .materialCheckBox(class="{{#if allowsReceivedDate}}is-checked{{/if}}")
+        span {{_ 'show-receiveddate-field'}}
+    div.check-div
+      a.flex.js-field-has-startdate(class="{{#if allowsStartDate}}is-checked{{/if}}")
+        .materialCheckBox(class="{{#if allowsStartDate}}is-checked{{/if}}")
+        span {{_ 'show-startdate-field'}}
+    div.check-div
+      a.flex.js-field-has-enddate(class="{{#if allowsEndDate}}is-checked{{/if}}")
+        .materialCheckBox(class="{{#if allowsEndDate}}is-checked{{/if}}")
+        span {{_ 'show-enddate-field'}}
+    div.check-div
+      a.flex.js-field-has-duedate(class="{{#if allowsDueDate}}is-checked{{/if}}")
+        .materialCheckBox(class="{{#if allowsDueDate}}is-checked{{/if}}")
+        span {{_ 'show-duedate-field'}}
+
 template(name="boardSubtaskSettingsPopup")
   form.board-subtask-settings
     h3 {{_ 'show-parent-in-minicard'}}
@@ -201,6 +220,10 @@ template(name="boardMenuPopup")
           a.js-subtask-settings
             i.fa.fa-sitemap
             | {{_ 'subtask-settings'}}
+        li
+          a.js-Date-settings
+            i.fa.fa-calendar
+            | {{_ 'Date-settings'}}
       unless currentBoard.isTemplatesBoard
         hr
         ul.pop-over-list
@@ -238,6 +261,12 @@ template(name="boardMenuPopup")
         a.js-subtask-settings
           i.fa.fa-sitemap
           | {{_ 'subtask-settings'}}
+    hr
+    ul.pop-over-list
+      li
+        a.js-Date-settings
+          i.fa.fa-calendar
+          | {{_ 'Date-settings'}}
 
 template(name="labelsWidget")
   .board-widget.board-widget-labels

+ 125 - 0
client/components/sidebar/sidebar.js

@@ -208,6 +208,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'),
+  'click .js-Date-settings': Popup.open('boardDateSettings')
 });
 
 Template.boardMenuPopup.helpers({
@@ -585,6 +586,130 @@ BlazeComponent.extendComponent({
   },
 }).register('boardSubtaskSettingsPopup');
 
+BlazeComponent.extendComponent({
+  onCreated(){
+    this.currentBoard = Boards.findOne(Session.get('currentBoard'));
+  },
+
+  allowsReceivedDate(){
+    return this.currentBoard.allowsReceivedDate;
+  },
+
+  allowsStartDate(){
+    return this.currentBoard.allowsStartDate;
+  },
+
+  allowsEndDate(){
+    return this.currentBoard.allowsEndDate;
+  },
+
+  allowsDueDate(){
+    return this.currentBoard.allowsDueDate;
+  },
+
+  isBoardSelected(){
+    return this.currentBoard.dateSettingsDefaultBoardID
+  },
+
+  isNullBoardSelected() {
+    return (
+      this.currentBoard.dateSettingsDefaultBoardId === null ||
+      this.currentBoard.dateSettingsDefaultBoardId === 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.dateSettingsDefaultBoardId === this.currentData()._id;
+  },
+
+  events() {
+    return [
+      {
+        'click .js-field-has-receiveddate'(evt) {
+          evt.preventDefault();
+          this.currentBoard.allowsReceivedDate = !this.currentBoard.allowsReceivedDate;
+          this.currentBoard.setAllowsReceivedDate(this.currentBoard.allowsReceivedDate);
+          $(`.js-field-has-receiveddate ${MCB}`).toggleClass(
+            CKCLS,
+            this.currentBoard.allowsReceivedDate,
+          );
+          $('.js-field-has-receiveddate').toggleClass(
+            CKCLS,
+            this.currentBoard.allowsReceivedDate,
+          );
+        },
+        'click .js-field-has-startdate'(evt) {
+          evt.preventDefault();
+          this.currentBoard.allowsStartDate = !this.currentBoard.allowsStartDate;
+          this.currentBoard.setAllowsStartDate(this.currentBoard.allowsStartDate);
+          $(`.js-field-has-startdate ${MCB}`).toggleClass(
+            CKCLS,
+            this.currentBoard.allowsStartDate,
+          );
+          $('.js-field-has-startdate').toggleClass(
+            CKCLS,
+            this.currentBoard.allowsStartDate,
+          );
+        },
+        'click .js-field-has-enddate'(evt) {
+          evt.preventDefault();
+          this.currentBoard.allowsEndDate = !this.currentBoard.allowsEndDate;
+          this.currentBoard.setAllowsEndDate(this.currentBoard.allowsEndDate);
+          $(`.js-field-has-enddate ${MCB}`).toggleClass(
+            CKCLS,
+            this.currentBoard.allowsEndDate,
+          );
+          $('.js-field-has-enddate').toggleClass(
+            CKCLS,
+            this.currentBoard.allowsEndDate,
+          );
+        },
+        'click .js-field-has-duedate'(evt) {
+          evt.preventDefault();
+          this.currentBoard.allowsDueDate = !this.currentBoard.allowsDueDate;
+          this.currentBoard.setAllowsDueDate(this.currentBoard.allowsDueDate);
+          $(`.js-field-has-duedate ${MCB}`).toggleClass(
+            CKCLS,
+            this.currentBoard.allowsDueDate,
+          );
+          $('.js-field-has-duedate').toggleClass(
+            CKCLS,
+            this.currentBoard.allowsDueDate,
+          );
+        },
+      },
+    ];
+  },
+}).register('boardDateSettingsPopup');
+
 BlazeComponent.extendComponent({
   onCreated() {
     this.error = new ReactiveVar('');

+ 8 - 1
i18n/en.i18n.json

@@ -583,8 +583,14 @@
   "default": "Default",
   "queue": "Queue",
   "subtask-settings": "Subtasks Settings",
+  "Date-settings": "Dates Settings",
   "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
+  "boardDateSettingsPopup-title": "Board Dates Settings",
   "show-subtasks-field": "Cards can have subtasks",
+  "show-receiveddate-field": "Cards can have Received Date",
+  "show-startdate-field": "Cards can have Start Date",
+  "show-enddate-field": "Cards can have End Date",
+  "show-duedate-field": "Cards can have Due Date",
   "deposit-subtasks-board": "Deposit subtasks to this board:",
   "deposit-subtasks-list": "Landing list for subtasks deposited here:",
   "show-parent-in-minicard": "Show parent in minicard:",
@@ -756,5 +762,6 @@
   "hide-minicard-label-text": "Hide minicard label text",
   "show-desktop-drag-handles": "Show desktop drag handles",
   "assignee": "Assignee",
-  "cardAssigneesPopup-title": "Assignee"
+  "cardAssigneesPopup-title": "Assignee",
+  "addmore-detail": "Add a more detailed description"
 }

+ 10 - 10
i18n/it.i18n.json

@@ -137,7 +137,7 @@
   "board-view": "Visualizza bacheca",
   "board-view-cal": "Calendario",
   "board-view-swimlanes": "Diagramma Swimlane",
-  "board-view-collapse": "Collassa",
+  "board-view-collapse": "Collapse",
   "board-view-lists": "Liste",
   "bucket-example": "Per esempio come \"una lista di cose da fare\"",
   "cancel": "Cancella",
@@ -223,7 +223,7 @@
   "comment-only-desc": "Puoi commentare solo le schede.",
   "no-comments": "Non ci sono commenti.",
   "no-comments-desc": "Impossibile visualizzare commenti o attività.",
-  "worker": "Lavoratore",
+  "worker": "Worker",
   "worker-desc": "Può solo spostare schede, assegnarsi una scheda e commentare.",
   "computer": "Computer",
   "confirm-subtask-delete-dialog": "Sei sicuro di voler eliminare il sotto-compito?",
@@ -309,7 +309,7 @@
   "list-sort-by": "Ordina la lista per:",
   "list-label-modifiedAt": "Orario ultimo accesso",
   "list-label-title": "Nome della lista",
-  "list-label-sort": "Il tuo ordine manuale",
+  "list-label-sort": "Your Manual Order",
   "list-label-short-modifiedAt": "(L)",
   "list-label-short-title": "(N)",
   "list-label-short-sort": "(M)",
@@ -527,11 +527,11 @@
   "webhook-title": "Nome Webhook",
   "webhook-token": "Token (facoltativo per l'autenticazione)",
   "outgoing-webhooks": "Server esterni",
-  "bidirectional-webhooks": "Webhook a due vie",
+  "bidirectional-webhooks": "Two-Way Webhooks",
   "outgoingWebhooksPopup-title": "Server esterni",
   "boardCardTitlePopup-title": "Filtro per Titolo Scheda",
   "disable-webhook": "Disattiva questo Webhook",
-  "global-webhook": "Webhook globali",
+  "global-webhook": "Global Webhooks",
   "new-outgoing-webhook": "Nuovo webhook in uscita",
   "no-name": "(Sconosciuto)",
   "Node_version": "Versione di Node",
@@ -707,7 +707,7 @@
   "r-df-due-at": "scadenza",
   "r-df-end-at": "fine",
   "r-df-received-at": "ricevuta",
-  "r-to-current-datetime": "a data/ora corrente",
+  "r-to-current-datetime": "to current date/time",
   "r-remove-value-from": "Rimuovi valore da",
   "ldap": "LDAP",
   "oauth2": "Oauth2",
@@ -750,8 +750,8 @@
   "act-atUserComment": "You were mentioned in [__board__] __list__/__card__",
   "delete-user-confirm-popup": "Sei sicuro di voler cancellare questo profilo? Non sarà possibile ripristinarlo.",
   "accounts-allowUserDelete": "Permetti agli utenti di cancellare il loro profilo",
-  "hide-minicard-label-text": "Nascondi etichetta minicard",
-  "show-desktop-drag-handles": "Mostra maniglie di trascinamento del desktop",
-  "assignee": "Assegnatario",
-  "cardAssigneesPopup-title": "Assegnatario"
+  "hide-minicard-label-text": "Hide minicard label text",
+  "show-desktop-drag-handles": "Show desktop drag handles",
+  "assignee": "Assignee",
+  "cardAssigneesPopup-title": "Assignee"
 }

+ 21 - 21
i18n/ja.i18n.json

@@ -90,9 +90,9 @@
   "addMemberPopup-title": "メンバー",
   "admin": "管理",
   "admin-desc": "カードの閲覧と編集、メンバーの削除、ボードの設定変更が可能",
-  "admin-announcement": "アナウンス",
-  "admin-announcement-active": "システム全体アナウンスを有効化",
-  "admin-announcement-title": "管理者からのアナウンス",
+  "admin-announcement": "Announcement",
+  "admin-announcement-active": "Active System-Wide Announcement",
+  "admin-announcement-title": "Announcement from Administrator",
   "all-boards": "全てのボード",
   "and-n-other-card": "And __count__ other card",
   "and-n-other-card_plural": "And __count__ other cards",
@@ -109,7 +109,7 @@
   "archived-items": "アーカイブ",
   "archived-boards": "アーカイブ済みボード",
   "restore-board": "ボードをリストア",
-  "no-archived-boards": "アーカイブ済みボードはありません。",
+  "no-archived-boards": "No Boards in Archive.",
   "archives": "アーカイブ",
   "template": "テンプレート",
   "templates": "テンプレート",
@@ -142,7 +142,7 @@
   "bucket-example": "例:バケットリスト",
   "cancel": "キャンセル",
   "card-archived": "This card is moved to Archive.",
-  "board-archived": "このボードをアーカイブしました。",
+  "board-archived": "This board is moved to Archive.",
   "card-comments-title": "%s 件のコメントがあります。",
   "card-delete-notice": "削除は取り消しできません。このカードに関係するすべてのアクションがなくなります。",
   "card-delete-pop": "すべての内容がアクティビティから削除されます。この削除は元に戻すことができません。",
@@ -516,7 +516,7 @@
   "smtp-password": "パスワード",
   "smtp-tls": "TLSサポート",
   "send-from": "送信元",
-  "send-smtp-test": "テストメールを自分に送信",
+  "send-smtp-test": "Send a test email to yourself",
   "invitation-code": "招待コード",
   "email-invite-register-subject": "__inviter__さんがあなたを招待しています",
   "email-invite-register-text": "Dear __user__,\n\n__inviter__ invites you to kanban board for collaborations.\n\nPlease follow the link below:\n__url__\n\nAnd your invitation code is: __icode__\n\nThanks.",
@@ -535,7 +535,7 @@
   "new-outgoing-webhook": "発信Webフックの作成",
   "no-name": "(Unknown)",
   "Node_version": "Nodeバージョン",
-  "Meteor_version": "Meteor バージョン",
+  "Meteor_version": "Meteor version",
   "MongoDB_version": "MongoDB version",
   "MongoDB_storage_engine": "MongoDB storage engine",
   "MongoDB_Oplog_enabled": "MongoDB Oplog enabled",
@@ -559,7 +559,7 @@
   "no": "いいえ",
   "accounts": "アカウント",
   "accounts-allowEmailChange": "メールアドレスの変更を許可",
-  "accounts-allowUserNameChange": "ユーザー名の変更を許可",
+  "accounts-allowUserNameChange": "Allow Username Change",
   "createdAt": "Created at",
   "verified": "Verified",
   "active": "Active",
@@ -579,11 +579,11 @@
   "delete-board-confirm-popup": "すべてのリスト、カード、ラベル、アクティビティは削除され、ボードの内容を元に戻すことができません。",
   "boardDeletePopup-title": "ボードを削除しますか?",
   "delete-board": "ボードを削除",
-  "default-subtasks-board": "__board__ ボードのサブタスク",
+  "default-subtasks-board": "Subtasks for __board__ board",
   "default": "Default",
   "queue": "Queue",
-  "subtask-settings": "サブタスク設定",
-  "boardSubtaskSettingsPopup-title": "ボードのサブタスク設定",
+  "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:",
@@ -596,11 +596,11 @@
   "parent-card": "Parent card",
   "source-board": "Source board",
   "no-parent": "Don't show parent",
-  "activity-added-label": "ラベル '%s' を %s に追加しました",
-  "activity-removed-label": "ラベル '%s' を %s から削除しました",
+  "activity-added-label": "added label '%s' to %s",
+  "activity-removed-label": "removed label '%s' from %s",
   "activity-delete-attach": "deleted an attachment from %s",
-  "activity-added-label-card": "ラベル '%s' を追加しました",
-  "activity-removed-label-card": "ラベル '%s' を削除しました",
+  "activity-added-label-card": "added label '%s'",
+  "activity-removed-label-card": "removed label '%s'",
   "activity-delete-attach-card": "deleted an attachment",
   "activity-set-customfield": "set custom field '%s' to '%s' in %s",
   "activity-unset-customfield": "unset custom field '%s' in %s",
@@ -650,7 +650,7 @@
   "r-card": "card",
   "r-add": "追加",
   "r-remove": "Remove",
-  "r-label": "ラベル",
+  "r-label": "label",
   "r-member": "member",
   "r-remove-all": "Remove all members from the card",
   "r-set-color": "Set color to",
@@ -677,7 +677,7 @@
   "r-d-archive": "Move card to Archive",
   "r-d-unarchive": "Restore card from Archive",
   "r-d-add-label": "Add label",
-  "r-d-remove-label": "ラベルの削除",
+  "r-d-remove-label": "Remove label",
   "r-create-card": "Create new card",
   "r-in-list": "リスト:",
   "r-in-swimlane": "in swimlane",
@@ -714,15 +714,15 @@
   "cas": "CAS",
   "authentication-method": "認証方式",
   "authentication-type": "認証タイプ",
-  "custom-product-name": "カスタム製品名",
+  "custom-product-name": "Custom Product Name",
   "layout": "レイアウト",
   "hide-logo": "ロゴを隠す",
   "add-custom-html-after-body-start": "Add Custom HTML after <body> start",
   "add-custom-html-before-body-end": "Add Custom HTML before </body> end",
   "error-undefined": "Something went wrong",
   "error-ldap-login": "An error occurred while trying to login",
-  "display-authentication-method": "認証方式を表示",
-  "default-authentication-method": "デフォルトの認証方式",
+  "display-authentication-method": "Display Authentication Method",
+  "default-authentication-method": "Default Authentication Method",
   "duplicate-board": "ボードの複製",
   "people-number": "The number of people is:",
   "swimlaneDeletePopup-title": "スイムレーンを削除しますか?",
@@ -750,7 +750,7 @@
   "act-atUserComment": "You were mentioned in [__board__] __list__/__card__",
   "delete-user-confirm-popup": "Are you sure you want to delete this account? There is no undo.",
   "accounts-allowUserDelete": "ユーザー自身のアカウント削除を許可",
-  "hide-minicard-label-text": "ミニカードのラベル名を隠す",
+  "hide-minicard-label-text": "Hide minicard label text",
   "show-desktop-drag-handles": "Show desktop drag handles",
   "assignee": "Assignee",
   "cardAssigneesPopup-title": "Assignee"

+ 117 - 0
models/boards.js

@@ -278,6 +278,7 @@ Boards.attachSchema(
       optional: true,
       defaultValue: null,
     },
+
     subtasksDefaultListId: {
       /**
        * The default List ID assigned to subtasks.
@@ -286,6 +287,19 @@ Boards.attachSchema(
       optional: true,
       defaultValue: null,
     },
+
+    dateSettingsDefaultBoardId: {
+      type: String,
+      optional: true,
+      defaultValue: null,
+    },
+
+    dateSettingsDefaultListId: {
+      type: String,
+      optional: true,
+      defaultValue: null,
+    },
+
     allowsSubtasks: {
       /**
        * Does the board allows subtasks?
@@ -293,6 +307,39 @@ Boards.attachSchema(
       type: Boolean,
       defaultValue: true,
     },
+
+    allowsReceivedDate: {
+      /**
+       * Does the board allows received date?
+       */
+      type: Boolean,
+      defaultValue: true,
+    },
+
+    allowsStartDate: {
+      /**
+       * Does the board allows start date?
+       */
+      type: Boolean,
+      defaultValue: true,
+    },
+
+    allowsEndDate: {
+      /**
+       * Does the board allows end date?
+       */
+      type: Boolean,
+      defaultValue: true,
+    },
+
+    allowsDueDate: {
+      /**
+       * Does the board allows due date?
+       */
+      type: Boolean,
+      defaultValue: true,
+    },
+
     presentParentTask: {
       /**
        * Controls how to present the parent task:
@@ -710,6 +757,39 @@ Boards.helpers({
     return Boards.findOne(this.getDefaultSubtasksBoardId());
   },
 
+//Date Settings option such as received date, start date and so on.
+  getDefaultDateSettingsBoardId() {
+    if (
+      this.dateSettingsDefaultBoardId === null ||
+      this.dateSettingsDefaultBoardId === undefined
+    ) {
+      this.dateSettingsDefaultBoardId = Boards.insert({
+        title: `^${this.title}^`,
+        permission: this.permission,
+        members: this.members,
+        color: this.color,
+        description: TAPi18n.__('default-dates-board', {
+          board: this.title,
+        }),
+      });
+
+      Swimlanes.insert({
+        title: TAPi18n.__('default'),
+        boardId: this.dateSettingsDefaultBoardId,
+      });
+      Boards.update(this._id, {
+        $set: {
+          dateSettingsDefaultBoardId: this.dateSettingsDefaultBoardId,
+        },
+      });
+    }
+    return this.dateSettingsDefaultBoardId;
+  },
+
+  getDefaultDateSettingsBoard() {
+    return Boards.findOne(this.getDefaultDateSettingsBoardId());
+  },
+
   getDefaultSubtasksListId() {
     if (
       this.subtasksDefaultListId === null ||
@@ -728,6 +808,24 @@ Boards.helpers({
     return Lists.findOne(this.getDefaultSubtasksListId());
   },
 
+  getDefaultDateSettingsListId() {
+    if (
+      this.dateSettingsDefaultListId === null ||
+      this.dateSettingsDefaultListId === undefined
+    ) {
+      this.dateSettingsDefaultListId = Lists.insert({
+        title: TAPi18n.__('queue'),
+        boardId: this._id,
+      });
+      this.setDateSettingsDefaultListId(this.dateSettingsDefaultListId);
+    }
+    return this.dateSettingsDefaultListId;
+  },
+
+  getDefaultDateSettingsList() {
+    return Lists.findOne(this.getDefaultDateSettingsListId());
+  },
+
   getDefaultSwimline() {
     let result = Swimlanes.findOne({ boardId: this._id });
     if (result === undefined) {
@@ -925,6 +1023,25 @@ Boards.mutations({
     return { $set: { allowsSubtasks } };
   },
 
+  setAllowsReceivedDate(allowsReceivedDate) {
+    return { $set: { allowsReceivedDate } };
+  },
+
+
+  setAllowsStartDate(allowsStartDate) {
+    return { $set: { allowsStartDate } };
+  },
+
+
+  setAllowsEndDate(allowsEndDate) {
+    return { $set: { allowsEndDate } };
+  },
+
+
+  setAllowsDueDate(allowsDueDate) {
+    return { $set: { allowsDueDate } };
+  },
+
   setSubtasksDefaultBoardId(subtasksDefaultBoardId) {
     return { $set: { subtasksDefaultBoardId } };
   },

+ 1 - 1
package-lock.json

@@ -1,6 +1,6 @@
 {
   "name": "wekan",
-  "version": "v3.73.0",
+  "version": "v3.71.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "wekan",
-  "version": "v3.73.0",
+  "version": "v3.71.0",
   "description": "Open-Source kanban",
   "private": true,
   "scripts": {

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 0
public/api/wekan.html


+ 1 - 1
public/api/wekan.yml

@@ -1,7 +1,7 @@
 swagger: '2.0'
 info:
   title: Wekan REST API
-  version: v3.73
+  version: v3.71
   description: |
     The REST API allows you to control and extend Wekan with ease.
 

+ 3 - 0
rebuild-wekan.bat

@@ -2,7 +2,10 @@
 
 REM NOTE: You can try this to install Meteor on Windows, it works:
 REM       https://github.com/zodern/windows-meteor-installer/
+<<<<<<< HEAD
 
+=======
+>>>>>>> ac37e360b69b799c12f03e1c158cfc0367d26e55
 REM Installing Meteor with Chocolatey does not currently work.
 
 REM NOTE: THIS .BAT DOES NOT WORK !!

+ 2 - 2
sandstorm-pkgdef.capnp

@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
     appTitle = (defaultText = "Wekan"),
     # The name of the app as it is displayed to the user.
 
-    appVersion = 375,
+    appVersion = 374,
     # Increment this for every release.
 
-    appMarketingVersion = (defaultText = "3.73.0~2020-01-29"),
+    appMarketingVersion = (defaultText = "3.72.0~2020-01-19"),
     # Human-readable presentation of the app version.
 
     minUpgradableAppVersion = 0,

+ 22 - 52
server/rulesHelper.js

@@ -42,65 +42,35 @@ RulesHelper = {
   performAction(activity, action) {
     const card = Cards.findOne({ _id: activity.cardId });
     const boardId = activity.boardId;
-    if (
-      action.actionType === 'moveCardToTop' ||
-      action.actionType === 'moveCardToBottom'
-    ) {
-      let list;
+    if (action.actionType === 'moveCardToTop') {
       let listId;
-      if (action.listName === '*') {
+      let list;
+      if (action.listTitle === '*') {
+        listId = card.listId;
         list = card.list();
-        if (boardId !== action.boardId) {
-          list = Lists.findOne({ title: list.title, boardId: action.boardId });
-        }
-      } else {
-        list = Lists.findOne({
-          title: action.listName,
-          boardId: action.boardId,
-        });
-      }
-      if (list === undefined) {
-        listId = '';
       } else {
+        list = Lists.findOne({ title: action.listTitle, boardId });
         listId = list._id;
       }
-
-      let swimlane;
-      let swimlaneId;
-      if (action.swimlaneName === '*') {
-        swimlane = Swimlanes.findOne(card.swimlaneId);
-        if (boardId !== action.boardId) {
-          swimlane = Swimlanes.findOne({
-            title: swimlane.title,
-            boardId: action.boardId,
-          });
-        }
-      } else {
-        swimlane = Swimlanes.findOne({
-          title: action.swimlaneName,
-          boardId: action.boardId,
-        });
-      }
-      if (swimlane === undefined) {
-        swimlaneId = Swimlanes.findOne({
-          title: 'Default',
-          boardId: action.boardId,
-        })._id;
-      } else {
-        swimlaneId = swimlane._id;
-      }
-
-      if (action.actionType === 'moveCardToTop') {
-        const minOrder = _.min(
-          list.cardsUnfiltered(swimlaneId).map(c => c.sort),
-        );
-        card.move(action.boardId, swimlaneId, listId, minOrder - 1);
+      const minOrder = _.min(
+        list.cardsUnfiltered(card.swimlaneId).map(c => c.sort),
+      );
+      card.move(boardId, card.swimlaneId, listId, minOrder - 1);
+    }
+    if (action.actionType === 'moveCardToBottom') {
+      let listId;
+      let list;
+      if (action.listTitle === '*') {
+        listId = card.listId;
+        list = card.list();
       } else {
-        const maxOrder = _.max(
-          list.cardsUnfiltered(swimlaneId).map(c => c.sort),
-        );
-        card.move(action.boardId, swimlaneId, listId, maxOrder + 1);
+        list = Lists.findOne({ title: action.listTitle, boardId });
+        listId = list._id;
       }
+      const maxOrder = _.max(
+        list.cardsUnfiltered(card.swimlaneId).map(c => c.sort),
+      );
+      card.move(boardId, card.swimlaneId, listId, maxOrder + 1);
     }
     if (action.actionType === 'sendEmail') {
       const to = action.emailTo;

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно