Merge branch 'feuerball11-feature-custom-fields' into devel

This commit is contained in:
Lauri Ojansivu 2018-06-14 19:38:16 +03:00
commit 85e02010d4
7 changed files with 154 additions and 102 deletions

View file

@ -1,3 +1,22 @@
# Upcoming 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).
Thanks to GitHub users feuerball11, oec 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

@ -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;
@ -163,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--;
commands.splice(i, 1);
i--;
continue;
}
default:
{
if (level > 0) {
subcommands.push(commands[i]);
{
level--;
commands.splice(i, 1);
i--;
continue;
}
}
default:
{
if (level > 0) {
subcommands.push(commands[i]);
commands.splice(i, 1);
i--;
continue;
}
}
}
}
}
@ -205,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': str };
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: str } };
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: str } };
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: str } };
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: str } };
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: str } };
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;
}
}
}
@ -300,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;
}
}
}

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

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