From 3753337d60e17e5e72ec071aa4a1b28e36297d15 Mon Sep 17 00:00:00 2001 From: Pouyan Savoli Date: Mon, 18 Sep 2017 00:46:17 +0200 Subject: dropdown items --- client/components/boards/boardHeader.jade | 2 +- client/components/boards/boardHeader.js | 2 +- client/components/cards/cardCustomFields.jade | 29 ++++- client/components/cards/cardCustomFields.js | 62 +++++++--- client/components/forms/forms.styl | 3 + client/components/sidebar/sidebar.js | 2 +- client/components/sidebar/sidebarCustomFields.jade | 23 ++-- client/components/sidebar/sidebarCustomFields.js | 129 +++++++++++++++------ 8 files changed, 185 insertions(+), 67 deletions(-) (limited to 'client') diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 9d16b10a..67acdc9e 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -103,7 +103,7 @@ template(name="boardHeaderBar") template(name="boardMenuPopup") ul.pop-over-list - li: a.js-configure-custom-fields {{_ 'configure-custom-fields'}} + li: a.js-custom-fields {{_ 'custom-fields'}} li: a.js-open-archives {{_ 'archived-items'}} if currentUser.isBoardAdmin li: a.js-change-board-color {{_ 'board-change-color'}} diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 61cdb149..8983c722 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -1,6 +1,6 @@ Template.boardMenuPopup.events({ 'click .js-rename-board': Popup.open('boardChangeTitle'), - 'click .js-configure-custom-fields'() { + 'click .js-custom-fields'() { Sidebar.setView('customFields'); Popup.close(); }, diff --git a/client/components/cards/cardCustomFields.jade b/client/components/cards/cardCustomFields.jade index 6515aa79..9e9f7d84 100644 --- a/client/components/cards/cardCustomFields.jade +++ b/client/components/cards/cardCustomFields.jade @@ -8,11 +8,14 @@ template(name="cardCustomFieldsPopup") if hasCustomField i.fa.fa-check hr - a.quiet-button.full.js-configure-custom-fields + a.quiet-button.full.js-settings i.fa.fa-cog - span {{_ 'configure-custom-fields'}} + span {{_ 'settings'}} -template(name="cardCustomFieldText") +template(name="cardCustomField") + +Template.dynamic(template=getTemplate) + +template(name="cardCustomField-text") if canModifyCard +inlinedForm(classNames="js-card-customfield-text") +editor(autofocus=true) @@ -25,5 +28,25 @@ template(name="cardCustomFieldText") if value +viewer = value + else + | {{_ 'edit'}} + +template(name="cardCustomField-dropdown") + if canModifyCard + +inlinedForm(classNames="js-card-customfield-dropdown") + select.inline + each items + if($eq data.value this._id) + option(value=_id selected="selected") {{name}} + else + option(value=_id) {{name}} + .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 + = selectedItem else | {{_ 'edit'}} \ No newline at end of file diff --git a/client/components/cards/cardCustomFields.js b/client/components/cards/cardCustomFields.js index 7009dede..f9fa760c 100644 --- a/client/components/cards/cardCustomFields.js +++ b/client/components/cards/cardCustomFields.js @@ -13,7 +13,7 @@ Template.cardCustomFieldsPopup.events({ card.toggleCustomField(customFieldId); evt.preventDefault(); }, - 'click .js-configure-custom-fields'(evt) { + 'click .js-settings'(evt) { EscapeActions.executeUpTo('detailsPane'); Sidebar.setView('customFields'); evt.preventDefault(); @@ -21,23 +21,25 @@ Template.cardCustomFieldsPopup.events({ }); const CardCustomField = BlazeComponent.extendComponent({ - template() { - return 'cardCustomFieldText'; + + getTemplate() { + return 'cardCustomField-' + this.data().definition.type; }, onCreated() { const self = this; - self.date = ReactiveVar(); - self.now = ReactiveVar(moment()); }, - value() { - return this.data().value; + canModifyCard() { + return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); }, +}); +CardCustomField.register('cardCustomField'); - showISODate() { - return this.date.get().toISOString(); - }, +(class extends CardCustomField { + + onCreated() { + } events() { return [{ @@ -48,13 +50,39 @@ const CardCustomField = BlazeComponent.extendComponent({ const value = this.currentComponent().getValue(); card.setCustomField(customFieldId,value); }, - 'click .js-edit-date': Popup.open('editCardStartDate'), }]; - }, + } - canModifyCard() { - return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); - }, -}); +}).register('cardCustomField-text'); + +(class extends CardCustomField { + + onCreated() { + this._items = this.data().definition.settings.dropdownItems; + this.items = this._items.slice(0); + this.items.unshift({ + _id: "", + name: TAPi18n.__('custom-field-dropdown-none') + }); + } + + selectedItem() { + const selected = this._items.find((item) => { + return item._id == this.data().value; + }); + return (selected) ? selected.name : TAPi18n.__('custom-field-dropdown-unknown'); + } + + events() { + return [{ + 'submit .js-card-customfield-dropdown'(evt) { + evt.preventDefault(); + const card = Cards.findOne(Session.get('currentCard')); + const customFieldId = this.data()._id; + const value = this.find('select').value; + card.setCustomField(customFieldId,value); + }, + }]; + } -CardCustomField.register('cardCustomField'); \ No newline at end of file +}).register('cardCustomField-dropdown'); \ No newline at end of file diff --git a/client/components/forms/forms.styl b/client/components/forms/forms.styl index 646da657..81780a6f 100644 --- a/client/components/forms/forms.styl +++ b/client/components/forms/forms.styl @@ -85,6 +85,9 @@ select width: 256px margin-bottom: 8px + &.inline + width: 100% + option[disabled] color: #8c8c8c diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 0ff73215..59a2b42c 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -5,7 +5,7 @@ const defaultView = 'home'; const viewTitles = { filter: 'filter-cards', multiselection: 'multi-selection', - customFields: 'configure-custom-fields', + customFields: 'custom-fields', archives: 'archives', }; diff --git a/client/components/sidebar/sidebarCustomFields.jade b/client/components/sidebar/sidebarCustomFields.jade index e17bb75d..def083e9 100644 --- a/client/components/sidebar/sidebarCustomFields.jade +++ b/client/components/sidebar/sidebarCustomFields.jade @@ -19,31 +19,34 @@ template(name="createCustomFieldPopup") label | {{_ 'name'}} unless _id - input.js-field-name(type="text" name="field-name" autofocus) + input.js-field-name(type="text" autofocus) else - input.js-field-name(type="text" name="field-name" value=name) + input.js-field-name(type="text" value=name) label | {{_ 'type'}} - select.js-field-type(name="field-type" disabled="{{#if _id}}disabled{{/if}}") + select.js-field-type(disabled="{{#if _id}}disabled{{/if}}") each types if selected - option(value=type selected="selected") {{name}} + option(value=value selected="selected") {{name}} else - option(value=type) {{name}} + option(value=value) {{name}} + div.js-field-settings.js-field-settings-dropdown(class="{{#if isTypeNotSelected 'dropdown'}}hide{{/if}}") + label + | {{_ 'custom-field-dropdown-options'}} + 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 .materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}") span {{_ 'show-field-on-card'}} - button.primary.wide.left(type="submit") + button.primary.wide.left(type="button") | {{_ 'save'}} if _id - button.negate.wide.right.js-delete-custom-field + button.negate.wide.right.js-delete-custom-field(type="button") | {{_ 'delete'}} -template(name="editCustomFieldPopup") - | {{> createCustomFieldPopup}} - template(name="deleteCustomFieldPopup") p {{_ "custom-field-delete-pop"}} button.js-confirm.negate.full(type="submit") {{_ 'delete'}} \ No newline at end of file diff --git a/client/components/sidebar/sidebarCustomFields.js b/client/components/sidebar/sidebarCustomFields.js index 6ddd466e..139b8a42 100644 --- a/client/components/sidebar/sidebarCustomFields.js +++ b/client/components/sidebar/sidebarCustomFields.js @@ -15,50 +15,111 @@ BlazeComponent.extendComponent({ }).register('customFieldsSidebar'); -Template.createCustomFieldPopup.helpers({ +const CreateCustomFieldPopup = BlazeComponent.extendComponent({ + + _types: ['text', 'number', 'checkbox', 'date', 'dropdown'], + + onCreated() { + this.type = new ReactiveVar((this.data().type) ? this.data().type : this._types[0]); + this.dropdownItems = new ReactiveVar((this.data().settings && this.data().settings.dropdownItems) ? this.data().settings.dropdownItems : []); + }, + types() { - var currentType = this.type; - return ['text', 'number', 'checkbox', 'date', 'dropdown']. - map(type => {return { - type: type, - name: TAPi18n.__('custom-field-' + type), - selected: type == currentType, - }}); + const currentType = this.data().type; + return this._types. + map(type => {return { + value: type, + name: TAPi18n.__('custom-field-' + type), + selected: type == currentType, + }}); + }, + + isTypeNotSelected(type) { + return this.type.get() !== type; + }, + + getDropdownItems() { + var items = this.dropdownItems.get(); + Array.from(this.findAll('.js-field-settings-dropdown input')).forEach((el, index) => { + //console.log('each item!', index, el.value); + if (!items[index]) items[index] = { + _id: Random.id(6), + }; + items[index].name = el.value.trim(); + }); + return items; }, -}); -Template.createCustomFieldPopup.events({ - 'click .js-field-show-on-card'(event) { - let $target = $(event.target); - if(!$target.hasClass('js-field-show-on-card')){ - $target = $target.parent(); + getSettings() { + let settings = {}; + switch (this.type.get()) { + case 'dropdown': + let dropdownItems = this.getDropdownItems().filter(item => !!item.name.trim()); + settings.dropdownItems = dropdownItems; + break; } - $target.find('.materialCheckBox').toggleClass('is-checked'); - $target.toggleClass('is-checked'); + return settings; }, - 'submit'(evt, tpl) { - evt.preventDefault(); - const name = tpl.find('.js-field-name').value.trim(); - const type = tpl.find('.js-field-type').value.trim(); - const showOnCard = tpl.find('.js-field-show-on-card.is-checked') != null; - //console.log('Create',name,type,showOnCard); + events() { + return [{ + 'change .js-field-type'(evt) { + const value = evt.target.value; + this.type.set(value); + }, + 'keydown .js-dropdown-item.last'(evt) { + if (evt.target.value.trim() && evt.keyCode === 13) { + let items = this.getDropdownItems(); + this.dropdownItems.set(items); + evt.target.value = ''; + } + }, + 'click .js-field-show-on-card'(evt) { + let $target = $(evt.target); + if(!$target.hasClass('js-field-show-on-card')){ + $target = $target.parent(); + } + $target.find('.materialCheckBox').toggleClass('is-checked'); + $target.toggleClass('is-checked'); + }, + 'click .primary'(evt) { + evt.preventDefault(); + + const data = { + boardId: Session.get('currentBoard'), + name: this.find('.js-field-name').value.trim(), + type: this.type.get(), + settings: this.getSettings(), + showOnCard: this.find('.js-field-show-on-card.is-checked') != null + } - CustomFields.insert({ - boardId: Session.get('currentBoard'), - name: name, - type: type, - showOnCard: showOnCard - }); + // insert or update + if (!this.data()._id) { + CustomFields.insert(data); + } else { + CustomFields.update(this.data()._id, {$set: data}); + } - Popup.back(); + Popup.back(); + }, + 'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() { + const customFieldId = this._id; + CustomFields.remove(customFieldId); + Popup.close(); + }), + }]; }, - 'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() { - const customFieldId = this._id; - CustomFields.remove(customFieldId); - Popup.close(); - }), + }); +CreateCustomFieldPopup.register('createCustomFieldPopup'); + +(class extends CreateCustomFieldPopup { + + template() { + return 'createCustomFieldPopup'; + } + +}).register('editCustomFieldPopup'); /*Template.deleteCustomFieldPopup.events({ 'submit'(evt) { -- cgit v1.2.3-1-g7c22