Merge branch 'devel'

This commit is contained in:
Lauri Ojansivu 2018-06-14 20:44:43 +03:00
commit 37817fcaf8
11 changed files with 106 additions and 48 deletions

View file

@ -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:

View file

@ -88,11 +88,13 @@ BlazeComponent.extendComponent({
isViewSwimlanes() {
const currentUser = Meteor.user();
if (!currentUser) return false;
return (currentUser.profile.boardView === 'board-view-swimlanes');
},
isViewLists() {
const currentUser = Meteor.user();
if (!currentUser) return true;
return (currentUser.profile.boardView === 'board-view-lists');
},

View file

@ -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;
}

View file

@ -15,7 +15,7 @@ template(name="minicard")
unless dueAt
unless endAt
.date
+miniCardReceivedDate
+minicardReceivedDate
if startAt
.date
+minicardStartDate
@ -37,7 +37,8 @@ template(name="minicard")
.minicard-custom-field-item
= definition.name
.minicard-custom-field-item
= value
+viewer
= trueValue
if members
.minicard-members.js-minicard-members

View file

@ -37,7 +37,7 @@ template(name="createCustomFieldPopup")
each dropdownItems.get
input.js-dropdown-item(type="text" value=name placeholder="")
input.js-dropdown-item.last(type="text" value="" placeholder="{{_ 'custom-field-dropdown-options-placeholder'}}")
a.flex.js-field-show-on-card
a.flex.js-field-show-on-card(class="{{#if showOnCard}}is-checked{{/if}}")
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
span {{_ 'show-field-on-card'}}
@ -49,4 +49,4 @@ template(name="createCustomFieldPopup")
template(name="deleteCustomFieldPopup")
p {{_ "custom-field-delete-pop"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}

View file

@ -145,6 +145,22 @@ class AdvancedFilter {
return found._id;
}
_fieldValueToId(field, value)
{
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;
}
}
}
return value;
}
_arrayToSelector(commands) {
try {
//let changed = false;
@ -208,7 +224,7 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': str };
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;
@ -220,7 +236,7 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: str } };
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;
@ -234,7 +250,7 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gt: str } };
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gt: parseInt(str, 10) } };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@ -249,7 +265,7 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gte: str } };
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gte: parseInt(str, 10) } };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@ -263,7 +279,7 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lt: str } };
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lt: parseInt(str, 10) } };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@ -278,7 +294,7 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lte: str } };
commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lte: parseInt(str, 10) } };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;

View file

@ -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",

View file

@ -230,12 +230,26 @@ Cards.helpers({
// match right definition to each field
if (!this.customFields) return [];
return this.customFields.map((customField) => {
const definition = definitions.find((definition) => {
return definition._id === customField._id;
});
//search for "True Value" which is for DropDowns other then the Value (which is the id)
let trueValue = customField.value;
if (definition.settings.dropdownItems && definition.settings.dropdownItems.length > 0)
{
for (let i = 0; i < definition.settings.dropdownItems.length; i++)
{
if (definition.settings.dropdownItems[i]._id === customField.value)
{
trueValue = definition.settings.dropdownItems[i].name;
}
}
}
return {
_id: customField._id,
value: customField.value,
definition: definitions.find((definition) => {
return definition._id === customField._id;
}),
trueValue,
definition,
};
});

View file

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

View file

@ -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,

View file

@ -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 },