mirror of
https://github.com/wekan/wekan.git
synced 2026-02-09 17:54:21 +01:00
Merge branch 'tod31-customfield-stringtemplate'
This commit is contained in:
commit
2fcf85fd61
9 changed files with 194 additions and 3 deletions
|
|
@ -119,3 +119,24 @@ template(name="cardCustomField-dropdown")
|
||||||
if value
|
if value
|
||||||
+viewer
|
+viewer
|
||||||
= selectedItem
|
= selectedItem
|
||||||
|
|
||||||
|
template(name="cardCustomField-stringtemplate")
|
||||||
|
if canModifyCard
|
||||||
|
+inlinedForm(classNames="js-card-customfield-stringtemplate")
|
||||||
|
each item in stringtemplateItems.get
|
||||||
|
input.js-card-customfield-stringtemplate-item(type="text" value=item placeholder="")
|
||||||
|
input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}")
|
||||||
|
.edit-controls.clearfix
|
||||||
|
button.primary(type="submit") {{_ 'save'}}
|
||||||
|
a.fa.fa-times-thin.js-close-inlined-form
|
||||||
|
else
|
||||||
|
a.js-open-inlined-form
|
||||||
|
if value
|
||||||
|
+viewer
|
||||||
|
= formattedValue
|
||||||
|
else
|
||||||
|
| {{_ 'edit'}}
|
||||||
|
else
|
||||||
|
if value
|
||||||
|
+viewer
|
||||||
|
= formattedValue
|
||||||
|
|
|
||||||
|
|
@ -234,3 +234,86 @@ CardCustomField.register('cardCustomField');
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}.register('cardCustomField-dropdown'));
|
}.register('cardCustomField-dropdown'));
|
||||||
|
|
||||||
|
// cardCustomField-stringtemplate
|
||||||
|
(class extends CardCustomField {
|
||||||
|
onCreated() {
|
||||||
|
super.onCreated();
|
||||||
|
|
||||||
|
this.stringtemplateFormat = this.data().definition.settings.stringtemplateFormat;
|
||||||
|
this.stringtemplateSeparator = this.data().definition.settings.stringtemplateSeparator;
|
||||||
|
|
||||||
|
this.stringtemplateItems = new ReactiveVar(this.data().value ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedValue() {
|
||||||
|
return (this.data().value ?? [])
|
||||||
|
.filter(value => !!value.trim())
|
||||||
|
.map(value => this.stringtemplateFormat.replace(/%\{value\}/gi, value))
|
||||||
|
.join(this.stringtemplateSeparator ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
getItems() {
|
||||||
|
return Array.from(this.findAll('input'))
|
||||||
|
.map(input => input.value)
|
||||||
|
.filter(value => !!value.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'submit .js-card-customfield-stringtemplate'(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const items = this.getItems();
|
||||||
|
this.card.setCustomField(this.customFieldId, items);
|
||||||
|
},
|
||||||
|
|
||||||
|
'keydown .js-card-customfield-stringtemplate-item'(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (event.metaKey || event.ctrlKey) {
|
||||||
|
this.find('button[type=submit]').click();
|
||||||
|
} else if (event.target.value.trim()) {
|
||||||
|
const inputLast = this.find('input.last');
|
||||||
|
|
||||||
|
let items = this.getItems();
|
||||||
|
|
||||||
|
if (event.target === inputLast) {
|
||||||
|
inputLast.value = '';
|
||||||
|
} else if (event.target.nextSibling === inputLast) {
|
||||||
|
inputLast.focus();
|
||||||
|
} else {
|
||||||
|
event.target.blur();
|
||||||
|
|
||||||
|
const idx = Array.from(this.findAll('input'))
|
||||||
|
.indexOf(event.target);
|
||||||
|
items.splice(idx + 1, 0, '');
|
||||||
|
|
||||||
|
Tracker.afterFlush(() => {
|
||||||
|
const element = this.findAll('input')[idx + 1];
|
||||||
|
element.focus();
|
||||||
|
element.value = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stringtemplateItems.set(items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'blur .js-card-customfield-stringtemplate-item'(event) {
|
||||||
|
if (!event.target.value.trim() || event.target === this.find('input.last')) {
|
||||||
|
const items = this.getItems();
|
||||||
|
this.stringtemplateItems.set(items);
|
||||||
|
this.find('input.last').value = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'click .js-close-inlined-form'(event) {
|
||||||
|
this.stringtemplateItems.set(this.data().value ?? []);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}.register('cardCustomField-stringtemplate'));
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ template(name="minicard")
|
||||||
+minicardCustomFieldDate
|
+minicardCustomFieldDate
|
||||||
else if $eq definition.type "checkbox"
|
else if $eq definition.type "checkbox"
|
||||||
.materialCheckBox(class="{{#if value }}is-checked{{/if}}")
|
.materialCheckBox(class="{{#if value }}is-checked{{/if}}")
|
||||||
|
else if $eq definition.type "stringtemplate"
|
||||||
|
+viewer
|
||||||
|
= formattedStringtemplateCustomFieldValue(definition)
|
||||||
else
|
else
|
||||||
+viewer
|
+viewer
|
||||||
= trueValue
|
= trueValue
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,20 @@ BlazeComponent.extendComponent({
|
||||||
}).format(customFieldTrueValue);
|
}).format(customFieldTrueValue);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
formattedStringtemplateCustomFieldValue(definition) {
|
||||||
|
const customField = this.data()
|
||||||
|
.customFieldsWD()
|
||||||
|
.find(f => f._id === definition._id);
|
||||||
|
|
||||||
|
const customFieldTrueValue =
|
||||||
|
customField && customField.trueValue ? customField.trueValue : [];
|
||||||
|
|
||||||
|
return customFieldTrueValue
|
||||||
|
.filter(value => !!value.trim())
|
||||||
|
.map(value => definition.settings.stringtemplateFormat.replace(/%\{value\}/gi, value))
|
||||||
|
.join(definition.settings.stringtemplateSeparator ?? '');
|
||||||
|
},
|
||||||
|
|
||||||
events() {
|
events() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,15 @@ template(name="createCustomFieldPopup")
|
||||||
each dropdownItems.get
|
each dropdownItems.get
|
||||||
input.js-dropdown-item(type="text" value=name placeholder="")
|
input.js-dropdown-item(type="text" value=name placeholder="")
|
||||||
input.js-dropdown-item.last(type="text" value="" placeholder="{{_ 'custom-field-dropdown-options-placeholder'}}")
|
input.js-dropdown-item.last(type="text" value="" placeholder="{{_ 'custom-field-dropdown-options-placeholder'}}")
|
||||||
|
|
||||||
|
div.js-field-settings.js-field-settings-stringtemplate(class="{{#if isTypeNotSelected 'stringtemplate'}}hide{{/if}}")
|
||||||
|
label
|
||||||
|
| {{_ 'custom-field-stringtemplate-format'}}
|
||||||
|
input.js-field-stringtemplate-format(type="text" value=getStringtemplateFormat)
|
||||||
|
label
|
||||||
|
| {{_ 'custom-field-stringtemplate-separator'}}
|
||||||
|
input.js-field-stringtemplate-separator(type="text" value=getStringtemplateSeparator)
|
||||||
|
|
||||||
a.flex.js-field-show-on-card(class="{{#if showOnCard}}is-checked{{/if}}")
|
a.flex.js-field-show-on-card(class="{{#if showOnCard}}is-checked{{/if}}")
|
||||||
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
|
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,15 @@ BlazeComponent.extendComponent({
|
||||||
}).register('customFieldsSidebar');
|
}).register('customFieldsSidebar');
|
||||||
|
|
||||||
const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
_types: ['text', 'number', 'date', 'dropdown', 'currency', 'checkbox'],
|
_types: [
|
||||||
|
'text',
|
||||||
|
'number',
|
||||||
|
'date',
|
||||||
|
'dropdown',
|
||||||
|
'currency',
|
||||||
|
'checkbox',
|
||||||
|
'stringtemplate',
|
||||||
|
],
|
||||||
|
|
||||||
_currencyList: [
|
_currencyList: [
|
||||||
{
|
{
|
||||||
|
|
@ -77,6 +85,18 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
? this.data().settings.dropdownItems
|
? this.data().settings.dropdownItems
|
||||||
: [],
|
: [],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.stringtemplateFormat = new ReactiveVar(
|
||||||
|
this.data().settings && this.data().settings.stringtemplateFormat
|
||||||
|
? this.data().settings.stringtemplateFormat
|
||||||
|
: '',
|
||||||
|
);
|
||||||
|
|
||||||
|
this.stringtemplateSeparator = new ReactiveVar(
|
||||||
|
this.data().settings && this.data().settings.stringtemplateSeparator
|
||||||
|
? this.data().settings.stringtemplateSeparator
|
||||||
|
: '',
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
types() {
|
types() {
|
||||||
|
|
@ -121,6 +141,14 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
return items;
|
return items;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getStringtemplateFormat() {
|
||||||
|
return this.stringtemplateFormat.get();
|
||||||
|
},
|
||||||
|
|
||||||
|
getStringtemplateSeparator() {
|
||||||
|
return this.stringtemplateSeparator.get();
|
||||||
|
},
|
||||||
|
|
||||||
getSettings() {
|
getSettings() {
|
||||||
const settings = {};
|
const settings = {};
|
||||||
switch (this.type.get()) {
|
switch (this.type.get()) {
|
||||||
|
|
@ -136,6 +164,14 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
settings.dropdownItems = dropdownItems;
|
settings.dropdownItems = dropdownItems;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'stringtemplate': {
|
||||||
|
const stringtemplateFormat = this.stringtemplateFormat.get();
|
||||||
|
settings.stringtemplateFormat = stringtemplateFormat;
|
||||||
|
|
||||||
|
const stringtemplateSeparator = this.stringtemplateSeparator.get();
|
||||||
|
settings.stringtemplateSeparator = stringtemplateSeparator;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return settings;
|
return settings;
|
||||||
},
|
},
|
||||||
|
|
@ -158,6 +194,14 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
evt.target.value = '';
|
evt.target.value = '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'input .js-field-stringtemplate-format'(evt) {
|
||||||
|
const value = evt.target.value;
|
||||||
|
this.stringtemplateFormat.set(value);
|
||||||
|
},
|
||||||
|
'input .js-field-stringtemplate-separator'(evt) {
|
||||||
|
const value = evt.target.value;
|
||||||
|
this.stringtemplateSeparator.set(value);
|
||||||
|
},
|
||||||
'click .js-field-show-on-card'(evt) {
|
'click .js-field-show-on-card'(evt) {
|
||||||
let $target = $(evt.target);
|
let $target = $(evt.target);
|
||||||
if (!$target.hasClass('js-field-show-on-card')) {
|
if (!$target.hasClass('js-field-show-on-card')) {
|
||||||
|
|
|
||||||
|
|
@ -988,5 +988,9 @@
|
||||||
"hide-system-messages-of-all-users": "Hide system messages of all users",
|
"hide-system-messages-of-all-users": "Hide system messages of all users",
|
||||||
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
|
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
|
||||||
"move-swimlane": "Move Swimlane",
|
"move-swimlane": "Move Swimlane",
|
||||||
"moveSwimlanePopup-title": "Move Swimlane"
|
"moveSwimlanePopup-title": "Move Swimlane",
|
||||||
|
"custom-field-stringtemplate": "String Template",
|
||||||
|
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
|
||||||
|
"custom-field-stringtemplate-separator": "Separator (use   or for a space)",
|
||||||
|
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,10 +155,14 @@ Cards.attachSchema(
|
||||||
/**
|
/**
|
||||||
* value attached to the custom field
|
* value attached to the custom field
|
||||||
*/
|
*/
|
||||||
type: Match.OneOf(String, Number, Boolean, Date),
|
type: Match.OneOf(String, Number, Boolean, Date, [String]),
|
||||||
optional: true,
|
optional: true,
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
},
|
},
|
||||||
|
'value.$': {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
dateLastActivity: {
|
dateLastActivity: {
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ CustomFields.attachSchema(
|
||||||
'dropdown',
|
'dropdown',
|
||||||
'checkbox',
|
'checkbox',
|
||||||
'currency',
|
'currency',
|
||||||
|
'stringtemplate',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
|
|
@ -64,6 +65,14 @@ CustomFields.attachSchema(
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
'settings.stringtemplateFormat': {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
'settings.stringtemplateSeparator': {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
showOnCard: {
|
showOnCard: {
|
||||||
/**
|
/**
|
||||||
* should we show on the cards this custom field
|
* should we show on the cards this custom field
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue