Browse Source

Merge branch 'devel' of https://github.com/wekan/wekan into feature-custom-fields

IgnatzHome 7 years ago
parent
commit
b5e6e6ee10

+ 21 - 0
CHANGELOG.md

@@ -1,3 +1,24 @@
+# v1.05 2018-06-14 Wekan release
+
+This release adds the following new features:
+
+* [Markdown support in Custom Fields, and view on minicard](https://github.com/wekan/wekan/pull/1699);
+* [Fixes to Advanced Filter, you are now able to filter for Dropdown and Numbers,
+   also Dropdown are now correctly displayed on minicard](https://github.com/wekan/wekan/pull/1699).
+
+and fixes the following bugs:
+
+* [Fix data colour changes on cards](https://github.com/wekan/wekan/pull/1698);
+* [Fix for migration error "title is required" and breaking of Standalone and
+   Sandstorm Wekan](https://github.com/wekan/wekan/commit/8d5cbf1e6c2b6d467fe1c0708cd794fd11b98a2e#commitcomment-29362180);
+* [Fix Issue with custom fields shown on card](https://github.com/wekan/wekan/issues/1659);
+* [Fix showing public board in list mode](https://github.com/wekan/wekan/issues/1623);
+* [Fix for not able to remove Custom Field "Show on Card"](https://github.com/wekan/wekan/pull/1699);
+* [Fix minicardReceivedDate typo in 1.04 regression: Socket connection error and boards
+   not loading](https://github.com/wekan/wekan/issues/1694).
+
+Thanks to GitHub users feuerball11, Fran-KTA, oec, rjevnikar and xet7 for their contributions.
+
 # v1.04 2018-06-12 Wekan release
 
 This release adds the following new features:

+ 12 - 8
client/components/cards/cardDate.js

@@ -279,14 +279,18 @@ class CardDueDate extends CardDate {
 
   classes() {
     let classes = 'due-date' + ' ';
-    if ((this.now.get().diff(this.date.get(), 'days') >= 2) &&
+    // if endAt exists & is < dueAt, dueAt doesn't need to be flagged
+    if ((this.data().endAt !== 0) &&
+       (this.data().endAt !== null) &&
+       (this.data().endAt !== '') &&
+       (this.data().endAt !== undefined) &&
        (this.date.get().isBefore(this.data().endAt)))
+      classes += 'current';
+    else if (this.now.get().diff(this.date.get(), 'days') >= 2)
       classes += 'long-overdue';
-    else if ((this.now.get().diff(this.date.get(), 'minute') >= 0) &&
-       (this.date.get().isBefore(this.data().endAt)))
+    else if (this.now.get().diff(this.date.get(), 'minute') >= 0)
       classes += 'due';
-    else if ((this.now.get().diff(this.date.get(), 'days') >= -1) &&
-       (this.date.get().isBefore(this.data().endAt)))
+    else if (this.now.get().diff(this.date.get(), 'days') >= -1)
       classes += 'almost-due';
     return classes;
   }
@@ -316,10 +320,10 @@ class CardEndDate extends CardDate {
     let classes = 'end-date' + ' ';
     if (this.data.dueAt.diff(this.date.get(), 'days') >= 2)
       classes += 'long-overdue';
-    else if (this.data.dueAt.diff(this.date.get(), 'days') >= 0)
+    else if (this.data.dueAt.diff(this.date.get(), 'days') > 0)
       classes += 'due';
-    else if (this.data.dueAt.diff(this.date.get(), 'days') >= -2)
-      classes += 'almost-due';
+    else if (this.data.dueAt.diff(this.date.get(), 'days') <= 0)
+      classes += 'current';
     return classes;
   }
 

+ 1 - 1
client/components/cards/minicard.jade

@@ -15,7 +15,7 @@ template(name="minicard")
           unless dueAt
             unless endAt
               .date
-                +miniCardReceivedDate
+                +minicardReceivedDate
       if startAt
         .date
           +minicardStartDate

+ 98 - 98
client/lib/filter.js

@@ -149,11 +149,11 @@ class AdvancedFilter {
   {
     const found = CustomFields.findOne({ 'name': field });
     if (found.settings.dropdownItems && found.settings.dropdownItems.length > 0)
-      {
+    {
       for (let i = 0; i < found.settings.dropdownItems.length; i++)
-        {
+      {
         if (found.settings.dropdownItems[i].name === value)
-          {
+        {
           return found.settings.dropdownItems[i]._id;
         }
       }
@@ -179,27 +179,27 @@ class AdvancedFilter {
       if (commands[i].cmd) {
         switch (commands[i].cmd) {
         case '(':
-          {
-            level++;
-            if (start === -1) start = i;
-            continue;
-          }
+        {
+          level++;
+          if (start === -1) start = i;
+          continue;
+        }
         case ')':
-          {
-            level--;
+        {
+          level--;
+          commands.splice(i, 1);
+          i--;
+          continue;
+        }
+        default:
+        {
+          if (level > 0) {
+            subcommands.push(commands[i]);
             commands.splice(i, 1);
             i--;
             continue;
           }
-        default:
-          {
-            if (level > 0) {
-              subcommands.push(commands[i]);
-              commands.splice(i, 1);
-              i--;
-              continue;
-            }
-          }
+        }
         }
       }
     }
@@ -221,86 +221,86 @@ class AdvancedFilter {
         case '=':
         case '==':
         case '===':
-          {
-            const field = commands[i - 1].cmd;
-            const str = commands[i + 1].cmd;
-            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const field = commands[i - 1].cmd;
+          const str = commands[i + 1].cmd;
+          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
         case '!=':
         case '!==':
-          {
-            const field = commands[i - 1].cmd;
-            const str = commands[i + 1].cmd;
-            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} } };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const field = commands[i - 1].cmd;
+          const str = commands[i + 1].cmd;
+          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} } };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
         case '>':
         case 'gt':
         case 'Gt':
         case 'GT':
-          {
-            const field = commands[i - 1].cmd;
-            const str = commands[i + 1].cmd;
-            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gt: parseInt(str, 10) } };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const field = commands[i - 1].cmd;
+          const str = commands[i + 1].cmd;
+          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gt: parseInt(str, 10) } };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
         case '>=':
         case '>==':
         case 'gte':
         case 'Gte':
         case 'GTE':
-          {
-            const field = commands[i - 1].cmd;
-            const str = commands[i + 1].cmd;
-            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gte:  parseInt(str, 10) } };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const field = commands[i - 1].cmd;
+          const str = commands[i + 1].cmd;
+          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gte:  parseInt(str, 10) } };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
         case '<':
         case 'lt':
         case 'Lt':
         case 'LT':
-          {
-            const field = commands[i - 1].cmd;
-            const str = commands[i + 1].cmd;
-            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lt:  parseInt(str, 10) } };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const field = commands[i - 1].cmd;
+          const str = commands[i + 1].cmd;
+          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lt:  parseInt(str, 10) } };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
         case '<=':
         case '<==':
         case 'lte':
         case 'Lte':
         case 'LTE':
-          {
-            const field = commands[i - 1].cmd;
-            const str = commands[i + 1].cmd;
-            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lte:  parseInt(str, 10) } };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const field = commands[i - 1].cmd;
+          const str = commands[i + 1].cmd;
+          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lte:  parseInt(str, 10) } };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
 
         }
       }
@@ -316,44 +316,44 @@ class AdvancedFilter {
         case 'OR':
         case '|':
         case '||':
-          {
-            const op1 = commands[i - 1];
-            const op2 = commands[i + 1];
-            commands[i] = { $or: [op1, op2] };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const op1 = commands[i - 1];
+          const op2 = commands[i + 1];
+          commands[i] = { $or: [op1, op2] };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
         case 'and':
         case 'And':
         case 'AND':
         case '&':
         case '&&':
-          {
-            const op1 = commands[i - 1];
-            const op2 = commands[i + 1];
-            commands[i] = { $and: [op1, op2] };
-            commands.splice(i - 1, 1);
-            commands.splice(i, 1);
+        {
+          const op1 = commands[i - 1];
+          const op2 = commands[i + 1];
+          commands[i] = { $and: [op1, op2] };
+          commands.splice(i - 1, 1);
+          commands.splice(i, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
 
         case 'not':
         case 'Not':
         case 'NOT':
         case '!':
-          {
-            const op1 = commands[i + 1];
-            commands[i] = { $not: op1 };
-            commands.splice(i + 1, 1);
+        {
+          const op1 = commands[i + 1];
+          commands[i] = { $not: op1 };
+          commands.splice(i + 1, 1);
           //changed = true;
-            i--;
-            break;
-          }
+          i--;
+          break;
+        }
 
         }
       }

+ 23 - 23
i18n/bg.i18n.json

@@ -45,7 +45,7 @@
     "activity-checklist-item-added": "добави точка към '%s' в/във %s",
     "add": "Добави",
     "add-attachment": "Добави прикачен файл",
-    "add-board": "Добави дъска",
+    "add-board": "Добави Табло",
     "add-card": "Добави карта",
     "add-swimlane": "Добави коридор",
     "add-checklist": "Добави списък със задачи",
@@ -61,23 +61,23 @@
     "admin-announcement": "Съобщение",
     "admin-announcement-active": "Active System-Wide Announcement",
     "admin-announcement-title": "Съобщение от администратора",
-    "all-boards": "Всички дъски",
+    "all-boards": "Всички табла",
     "and-n-other-card": "И __count__ друга карта",
     "and-n-other-card_plural": "И __count__ други карти",
     "apply": "Приложи",
     "app-is-offline": "Wekan зарежда, моля изчакайте! Презареждането на страницата може да доведе до загуба на данни. Ако Wekan не се зареди, моля проверете дали сървъра му работи.",
     "archive": "Премести в Кошчето",
     "archive-all": "Премести всички в Кошчето",
-    "archive-board": "Премести Дъската в Кошчето",
+    "archive-board": "Премести Таблото в Кошчето",
     "archive-card": "Премести Картата в Кошчето",
     "archive-list": "Премести Списъка в Кошчето",
     "archive-swimlane": "Премести Коридора в Кошчето",
     "archive-selection": "Премести избраните в Кошчето",
-    "archiveBoardPopup-title": "Сигурни ли сте, че искате да преместите Дъската в Кошчето?",
+    "archiveBoardPopup-title": "Сигурни ли сте, че искате да преместите Таблото в Кошчето?",
     "archived-items": "Кошче",
-    "archived-boards": "Дъски в Кошчето",
-    "restore-board": "Възстанови Дъската",
-    "no-archived-boards": "Няма Дъски в Кошчето.",
+    "archived-boards": "Табла в Кошчето",
+    "restore-board": "Възстанови Таблото",
+    "no-archived-boards": "Няма Табла в Кошчето.",
     "archives": "Кошче",
     "assign-member": "Възложи на член от екипа",
     "attached": "прикачен",
@@ -85,20 +85,20 @@
     "attachment-delete-pop": "Изтриването на прикачен файл е завинаги. Няма как да бъде възстановен.",
     "attachmentDeletePopup-title": "Желаете ли да изтриете прикачения файл?",
     "attachments": "Прикачени файлове",
-    "auto-watch": "Автоматично наблюдаване на дъските, когато са създадени",
+    "auto-watch": "Автоматично наблюдаване на таблата, когато са създадени",
     "avatar-too-big": "Аватарът е прекалено голям (максимум 70KB)",
     "back": "Назад",
     "board-change-color": "Промени цвета",
     "board-nb-stars": "%s звезди",
-    "board-not-found": "Дъската не е намерена",
+    "board-not-found": "Таблото не е намерено",
     "board-private-info": "This board will be <strong>private</strong>.",
     "board-public-info": "This board will be <strong>public</strong>.",
     "boardChangeColorPopup-title": "Change Board Background",
-    "boardChangeTitlePopup-title": "Промени името на Дъската",
+    "boardChangeTitlePopup-title": "Промени името на Таблото",
     "boardChangeVisibilityPopup-title": "Change Visibility",
     "boardChangeWatchPopup-title": "Промени наблюдаването",
-    "boardMenuPopup-title": "Меню на Дъската",
-    "boards": "Дъски",
+    "boardMenuPopup-title": "Меню на Таблото",
+    "boards": "Табла",
     "board-view": "Board View",
     "board-view-swimlanes": "Коридори",
     "board-view-lists": "Списъци",
@@ -117,7 +117,7 @@
     "card-edit-labels": "Промени етикетите",
     "card-edit-members": "Промени членовете",
     "card-labels-title": "Промени етикетите за картата.",
-    "card-members-title": "Добави или премахни членове на Дъската от тази карта.",
+    "card-members-title": "Добави или премахни членове на Таблото от тази карта.",
     "card-start": "Начало",
     "card-start-on": "Започва на",
     "cardAttachmentsPopup-title": "Прикачи от",
@@ -142,10 +142,10 @@
     "changeSettingsPopup-title": "Промяна на настройките",
     "checklists": "Списъци със задачи",
     "click-to-star": "Click to star this board.",
-    "click-to-unstar": "Натиснете, за да премахнете тази дъска от любими.",
+    "click-to-unstar": "Натиснете, за да премахнете това табло от любими.",
     "clipboard": "Клипборда или с драг & дроп",
     "close": "Затвори",
-    "close-board": "Затвори Дъската",
+    "close-board": "Затвори Таблото",
     "close-board-pop": "You will be able to restore the board by clicking the “Recycle Bin” button from the home header.",
     "color-black": "черно",
     "color-blue": "синьо",
@@ -165,7 +165,7 @@
     "confirm-checklist-delete-dialog": "Сигурни ли сте, че искате да изтриете този чеклист?",
     "copy-card-link-to-clipboard": "Копирай връзката на картата в клипборда",
     "copyCardPopup-title": "Копирай картата",
-    "copyChecklistToManyCardsPopup-title": "Копирай шаблона за чеклисти в много карти",
+    "copyChecklistToManyCardsPopup-title": "Копирай чеклисти в други карти",
     "copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
     "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]",
     "create": "Create",
@@ -244,7 +244,7 @@
     "filter-no-member": "без член",
     "filter-no-custom-fields": "Няма Собствени полета",
     "filter-on": "Има приложени филтри",
-    "filter-on-desc": "В момента филтрирате картите в тази дъска. Моля, натиснете тук, за да промените филтъра.",
+    "filter-on-desc": "В момента филтрирате картите в това табло. Моля, натиснете тук, за да промените филтъра.",
     "filter-to-selection": "Филтрирай избраните",
     "advanced-filter-label": "Advanced Filter",
     "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. Also you can combine multiple conditions. For Example: F1 == V1 || F1 = V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 and ( F2 == V2 || F2 == V3 )",
@@ -297,7 +297,7 @@
     "listMorePopup-title": "Още",
     "link-list": "Връзка към този списък",
     "list-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the list. There is no undo.",
-    "list-delete-suggest-archive": "Можете да преместите списък в Кошчето, за да го премахнете от Дъската и запазите активността.",
+    "list-delete-suggest-archive": "Можете да преместите списък в Кошчето, за да го премахнете от Таблото и запазите активността.",
     "lists": "Списъци",
     "swimlanes": "Коридори",
     "log-out": "Изход",
@@ -315,7 +315,7 @@
     "multi-selection-on": "Множественият избор е приложен",
     "muted": "Muted",
     "muted-info": "You will never be notified of any changes in this board",
-    "my-boards": "Моите дъски",
+    "my-boards": "Моите табла",
     "name": "Име",
     "no-archived-cards": "Няма карти в Кошчето.",
     "no-archived-lists": "Няма списъци в Кошчето.",
@@ -325,7 +325,7 @@
     "normal-desc": "Can view and edit cards. Can't change settings.",
     "not-accepted-yet": "Invitation not accepted yet",
     "notify-participate": "Получавате информация за всички карти, в които сте отбелязани или сте създали",
-    "notify-watch": "Получавате информация за всички дъски, списъци и карти, които наблюдавате",
+    "notify-watch": "Получавате информация за всички табла, списъци и карти, които наблюдавате",
     "optional": "optional",
     "or": "or",
     "page-maybe-private": "This page may be private. You may be able to view it by <a href='%s'>logging in</a>.",
@@ -351,7 +351,7 @@
     "remove-member-pop": "Remove __name__ (__username__) from __boardTitle__? The member will be removed from all cards on this board. They will receive a notification.",
     "removeMemberPopup-title": "Remove Member?",
     "rename": "Rename",
-    "rename-board": "Промени името на Дъската",
+    "rename-board": "Промени името на Таблото",
     "restore": "Възстанови",
     "save": "Запази",
     "search": "Търсене",
@@ -374,8 +374,8 @@
     "sidebar-close": "Close Sidebar",
     "signupPopup-title": "Create an Account",
     "star-board-title": "Click to star this board. It will show up at top of your boards list.",
-    "starred-boards": "Любими дъски",
-    "starred-boards-description": "Любимите дъски се показват в началото на списъка Ви.",
+    "starred-boards": "Любими табла",
+    "starred-boards-description": "Любимите табла се показват в началото на списъка Ви.",
     "subscribe": "Subscribe",
     "team": "Team",
     "this-board": "this board",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "wekan",
-  "version": "1.04.0",
+  "version": "1.05.0",
   "description": "The open-source Trello-like kanban",
   "private": true,
   "scripts": {

+ 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 = 89,
+    appVersion = 90,
     # Increment this for every release.
 
-    appMarketingVersion = (defaultText = "1.04.0~2018-06-12"),
+    appMarketingVersion = (defaultText = "1.05.0~2018-06-14"),
     # Human-readable presentation of the app version.
 
     minUpgradableAppVersion = 0,

+ 1 - 1
server/migrations.js

@@ -140,7 +140,7 @@ Migrations.add('add-sort-checklists', () => {
         noValidate
       );
     }
-    checklist.items.find().forEach((item, index) => {
+    checklist.items.forEach((item, index) => {
       if (!item.hasOwnProperty('sort')) {
         Checklists.direct.update(
           { _id: checklist._id, 'items._id': item._id },