diff --git a/client/components/cards/cardCustomFields.jade b/client/components/cards/cardCustomFields.jade index 11f1bc2f6..aef24b696 100644 --- a/client/components/cards/cardCustomFields.jade +++ b/client/components/cards/cardCustomFields.jade @@ -119,3 +119,23 @@ template(name="cardCustomField-dropdown") if value +viewer = selectedItem + +template(name="cardCustomField-stringtemplate") + if canModifyCard + +inlinedForm(classNames="js-card-customfield-stringtemplate") + +editor(autofocus=true) + = data.value + .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 diff --git a/client/components/cards/cardCustomFields.js b/client/components/cards/cardCustomFields.js index 4469e221e..effcc3e91 100644 --- a/client/components/cards/cardCustomFields.js +++ b/client/components/cards/cardCustomFields.js @@ -234,3 +234,33 @@ CardCustomField.register('cardCustomField'); ]; } }.register('cardCustomField-dropdown')); + +// cardCustomField-stringtemplate +(class extends CardCustomField { + onCreated() { + super.onCreated(); + + this.stringtemplateFormat = this.data().definition.settings.stringtemplateFormat; + } + + formattedValue() { + lines = this.data().value.replace(/\r\n|\n\r|\n|\r/g, '\n').split('\n'); + lines = lines.map(line => + this.stringtemplateFormat.replace(/%\{value\}/gi, line) + ); + + return lines.join(' '); + } + + events() { + return [ + { + 'submit .js-card-customfield-stringtemplate'(event) { + event.preventDefault(); + const value = this.currentComponent().getValue(); + this.card.setCustomField(this.customFieldId, value); + }, + }, + ]; + } +}.register('cardCustomField-stringtemplate')); diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 3931bffbc..cc37cd383 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -82,6 +82,9 @@ template(name="minicard") +minicardCustomFieldDate else if $eq definition.type "checkbox" .materialCheckBox(class="{{#if value }}is-checked{{/if}}") + else if $eq definition.type "stringtemplate" + +viewer + = formattedStringtemplateCustomFieldValue(definition) else +viewer = trueValue diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 88348fc48..60996684f 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -21,6 +21,23 @@ BlazeComponent.extendComponent({ }).format(customFieldTrueValue); }, + formattedStringtemplateCustomFieldValue(definition) { + const customField = this.data() + .customFieldsWD() + .find(f => f._id === definition._id); + + if(customField && customField.trueValue) { + lines = customField.trueValue.replace(/\r\n|\n\r|\n|\r/g, '\n').split('\n'); + lines = lines.map(line => + definition.settings.stringtemplateFormat.replace(/%\{value\}/gi, line) + ); + + return lines.join(' '); + } else { + return ''; + } + }, + events() { return [ { diff --git a/client/components/sidebar/sidebarCustomFields.jade b/client/components/sidebar/sidebarCustomFields.jade index 3f7a3e2ee..58f095f12 100644 --- a/client/components/sidebar/sidebarCustomFields.jade +++ b/client/components/sidebar/sidebarCustomFields.jade @@ -50,6 +50,12 @@ 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'}}") + + div.js-field-settings.js-field-settings-paramlink(class="{{#if isTypeNotSelected 'stringtemplate'}}hide{{/if}}") + label + | {{_ 'custom-field-stringtemplate-format'}} + input.js-field-stringtemplate(type="text" value=getStringtemplateFormat) + a.flex.js-field-show-on-card(class="{{#if showOnCard}}is-checked{{/if}}") .materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}") diff --git a/client/components/sidebar/sidebarCustomFields.js b/client/components/sidebar/sidebarCustomFields.js index 24385f72a..5cc1adf10 100644 --- a/client/components/sidebar/sidebarCustomFields.js +++ b/client/components/sidebar/sidebarCustomFields.js @@ -16,7 +16,7 @@ BlazeComponent.extendComponent({ }).register('customFieldsSidebar'); const CreateCustomFieldPopup = BlazeComponent.extendComponent({ - _types: ['text', 'number', 'date', 'dropdown', 'currency', 'checkbox'], + _types: ['text', 'number', 'date', 'dropdown', 'currency', 'checkbox', 'stringtemplate'], _currencyList: [ { @@ -77,6 +77,12 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ ? this.data().settings.dropdownItems : [], ); + + this.stringtemplateFormat = new ReactiveVar( + this.data().settings && this.data().settings.stringtemplateFormat + ? this.data().settings.stringtemplateFormat + : "", + ); }, types() { @@ -121,6 +127,10 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ return items; }, + getStringtemplateFormat() { + return this.stringtemplateFormat.get(); + }, + getSettings() { const settings = {}; switch (this.type.get()) { @@ -136,6 +146,11 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ settings.dropdownItems = dropdownItems; break; } + case 'stringtemplate': { + const stringtemplateFormat = this.stringtemplateFormat.get(); + settings.stringtemplateFormat = stringtemplateFormat; + break; + } } return settings; }, @@ -158,6 +173,10 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({ evt.target.value = ''; } }, + 'input .js-field-stringtemplate'(evt) { + const value = evt.target.value; + this.stringtemplateFormat.set(value); + }, 'click .js-field-show-on-card'(evt) { let $target = $(evt.target); if (!$target.hasClass('js-field-show-on-card')) { diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index e20645c51..c5cb1f8ba 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -988,5 +988,7 @@ "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", "move-swimlane": "Move Swimlane", - "moveSwimlanePopup-title": "Move Swimlane" + "moveSwimlanePopup-title": "Move Swimlane", + "custom-field-stringtemplate": "String Template", + "custom-field-stringtemplate-format": "Format" } diff --git a/models/customFields.js b/models/customFields.js index 5f3150174..4024e234e 100644 --- a/models/customFields.js +++ b/models/customFields.js @@ -29,6 +29,7 @@ CustomFields.attachSchema( 'dropdown', 'checkbox', 'currency', + 'stringtemplate', ], }, settings: { @@ -64,6 +65,10 @@ CustomFields.attachSchema( }, }), }, + 'settings.stringtemplateFormat': { + type: String, + optional: true, + }, showOnCard: { /** * should we show on the cards this custom field