From dc1cbfbfe47be8526f9abdaa30765bd0b31493d7 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 17 Oct 2017 21:17:53 +0800 Subject: [PATCH] Working version --- .../components/wizard-custom-action.js.es6 | 32 ++----- .../components/wizard-custom-field.js.es6 | 39 +-------- .../components/wizard-custom-input.js.es6 | 17 ++++ .../discourse/components/wizard-links.js.es6 | 8 +- .../discourse/models/custom-wizard.js.es6 | 14 ++- .../components/wizard-custom-action.hbs | 29 +++---- .../components/wizard-custom-field.hbs | 20 +---- .../components/wizard-custom-input.hbs | 16 ++++ .../components/wizard-custom-step.hbs | 2 +- .../wizard/controllers/custom-step.js.es6 | 10 ++- .../javascripts/wizard/routes/custom.js.es6 | 9 -- config/locales/client.en.yml | 37 +++++++- lib/builder.rb | 87 ++++++++++++------- 13 files changed, 172 insertions(+), 148 deletions(-) create mode 100644 assets/javascripts/discourse/components/wizard-custom-input.js.es6 create mode 100644 assets/javascripts/discourse/templates/components/wizard-custom-input.hbs diff --git a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 index af027b58..fa900ac9 100644 --- a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 @@ -1,4 +1,4 @@ -import { on, observes, default as computed } from 'ember-addons/ember-computed-decorators'; +import { default as computed } from 'ember-addons/ember-computed-decorators'; const PROFILE_FIELDS = [ 'name', @@ -24,36 +24,20 @@ export default Ember.Component.extend({ createTopic: Ember.computed.equal('action.type', 'create_topic'), updateProfile: Ember.computed.equal('action.type', 'update_profile'), sendMessage: Ember.computed.equal('action.type', 'send_message'), - - @on('init') - @observes('action') - setup() { - if (!this.get('isNew')) this.set('existingId', this.get('action.id')); - }, + disableId: Ember.computed.not('action.isNew'), @computed('steps') wizardFields(steps) { let fields = []; steps.forEach((s) => { - let stepFields = s.fields.map((f) => `${f.id} (${s.id})`); + let stepFields = s.fields.map((f) => { + return Ember.Object.create({ + id: f.id, + label: `${f.id} (${s.id})` + }); + }); fields.push(...stepFields); }); return fields; - }, - - @computed('action.profile_updates.[]') - profileUpdates: fields => fields, - - actions: { - addProfileUpdate() { - if (!this.get('action.profile_updates')) { - this.set('action.profile_updates', Ember.A()); - } - this.get('action.profile_updates').pushObject(Ember.Object.create()); - }, - - removeProfileUpdate(f) { - this.get('action.profile_updates').removeObject(f); - } } }); diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index 90995897..8b73ce4b 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -1,52 +1,17 @@ -import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators'; +import { default as computed } from 'ember-addons/ember-computed-decorators'; export default Ember.Component.extend({ classNames: 'wizard-custom-field', isDropdown: Ember.computed.equal('field.type', 'dropdown'), - - @on('init') - @observes('field') - setup() { - if (!this.get('isNew')) this.set('existingId', this.get('field.id')); - }, + disableId: Ember.computed.not('field.isNew'), @computed('field.type') isInput: (type) => type === 'text' || type === 'textarea', - @computed('field.choices.[]') - dropdownChoices: choices => choices, - - @computed('field.choices_filters.[]') - presetFilters: filters => filters, - @computed() presetChoices() { return [ { id: 'categories', name: I18n.t('admin.wizard.field.choices_preset.categories') } ]; - }, - - actions: { - addFilter() { - if (!this.get('field.choices_filters')) { - this.set('field.choices_filters', Ember.A()); - } - this.get('field.choices_filters').pushObject(Ember.Object.create()); - }, - - removeFilter(f) { - this.get('field.choices_filters').removeObject(f); - }, - - addChoice() { - if (!this.get('field.choices')) { - this.set('field.choices', Ember.A()); - } - this.get('field.choices').pushObject(Ember.Object.create()); - }, - - removeChoice(c) { - this.get('field.choices').removeObject(c); - } } }); diff --git a/assets/javascripts/discourse/components/wizard-custom-input.js.es6 b/assets/javascripts/discourse/components/wizard-custom-input.js.es6 new file mode 100644 index 00000000..c4f89e92 --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-custom-input.js.es6 @@ -0,0 +1,17 @@ +export default Ember.Component.extend({ + noneKey: 'admin.wizard.none', + noneValue: 'admin.wizard.none', + + actions: { + add() { + if (!this.get('inputs')) { + this.set('inputs', Ember.A()); + } + this.get('inputs').pushObject(Ember.Object.create()); + }, + + remove(input) { + this.get('inputs').removeObject(input); + } + } +}); diff --git a/assets/javascripts/discourse/components/wizard-links.js.es6 b/assets/javascripts/discourse/components/wizard-links.js.es6 index ce8dd946..431512d4 100644 --- a/assets/javascripts/discourse/components/wizard-links.js.es6 +++ b/assets/javascripts/discourse/components/wizard-links.js.es6 @@ -34,8 +34,9 @@ export default Ember.Component.extend({ return items.map((item) => { if (item) { const id = item.get('id'); - const label = item.get('label') || item.get('title'); - let link = { id, label: label || id }; + const type = this.get('type'); + const label = type === 'action' ? id : (item.get('label') || item.get('title') || id); + let link = { id, label }; let classes = 'btn'; if (current && item.get('id') === current.get('id')) { @@ -52,8 +53,8 @@ export default Ember.Component.extend({ actions: { add() { const items = this.get('items'); - const newId = `step_${items.length + 1}`; const type = this.get('type'); + const newId = `${type}_${items.length + 1}`; let params = { id: newId, isNew: true }; if (type === 'step') { @@ -64,6 +65,7 @@ export default Ember.Component.extend({ const newItem = Ember.Object.create(params); items.pushObject(newItem); this.set('current', newItem); + this.sendAction('isNew'); }, change(itemId) { diff --git a/assets/javascripts/discourse/models/custom-wizard.js.es6 b/assets/javascripts/discourse/models/custom-wizard.js.es6 index f6262c59..bf13fbc7 100644 --- a/assets/javascripts/discourse/models/custom-wizard.js.es6 +++ b/assets/javascripts/discourse/models/custom-wizard.js.es6 @@ -62,6 +62,8 @@ const CustomWizard = Discourse.Model.extend({ } } + delete f.isNew; + step['fields'].push(f); }); } @@ -76,6 +78,8 @@ const CustomWizard = Discourse.Model.extend({ a.set('id', id.underscore()); + delete a.isNew; + step['actions'].push(a); }); @@ -138,7 +142,8 @@ CustomWizard.reopenClass({ s.fields.forEach((f) => { Object.keys(f).forEach((key) => (f[key] === '') && delete f[key]); - let field = Ember.Object.create(f); + const fieldParams = { isNew: false }; + let field = Ember.Object.create(Object.assign(f, fieldParams)); if (f.choices) { let choices = Ember.A(); @@ -157,7 +162,9 @@ CustomWizard.reopenClass({ let actions = Ember.A(); if (s.actions && s.actions.length) { s.actions.forEach((a) => { - actions.pushObject(Ember.Object.create(a)); + const actionParams = { isNew: false }; + const action = Ember.Object.create(Object.assign(a, actionParams)); + actions.pushObject(action); }); } @@ -168,7 +175,8 @@ CustomWizard.reopenClass({ description: s.description, banner: s.banner, fields, - actions + actions, + isNew: false })); }); }; diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs index 8e8e699d..8e542c93 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs @@ -3,7 +3,7 @@

{{i18n "admin.wizard.id"}}

- {{input value=action.id placeholderKey='admin.wizard.id_placeholder' disabled=existingId}} + {{input value=action.id placeholderKey='admin.wizard.id_placeholder' disabled=disableId}}
@@ -44,13 +44,9 @@ -
-
-

{{i18n "admin.wizard.action.create_topic.featured_link"}}

-
-
- {{combo-box value=action.featured_link content=wizardFields none='admin.wizard.action.none'}} -
+
+ + {{wizard-custom-input inputs=action.add_fields valueContent=wizardFields noneValue='admin.wizard.action.none'}}
{{/if}} @@ -60,7 +56,7 @@

{{i18n "admin.wizard.action.title"}}

- {{combo-box value=action.title content=wizardFields none='admin.wizard.action.none'}} + {{combo-box value=action.title content=wizardFields nameProperty='label' none='admin.wizard.action.none'}}
@@ -69,7 +65,7 @@

{{i18n "admin.wizard.action.post"}}

- {{combo-box value=action.post content=wizardFields none='admin.wizard.action.none'}} + {{combo-box value=action.post content=wizardFields nameProperty='label' none='admin.wizard.action.none'}}
@@ -88,13 +84,10 @@ {{#if updateProfile}}
- {{#each profileUpdates as |pu|}} - - {{combo-box value=pu.wizard_field content=wizardFields none='admin.wizard.action.update_profile.wizard_field'}} - {{combo-box value=pu.profile_field content=profileFields none='admin.wizard.action.update_profile.profile_field'}} - - {{d-button action='removeProfileUpdate' actionParam=f icon='times'}} - {{/each}} -
{{d-button action='addProfileUpdate' label='admin.wizard.add' icon='plus'}}
+ {{wizard-custom-input inputs=action.profile_updates + valueContent=profileFields + keyContent=wizardFields + noneKey='admin.wizard.action.none' + noneValue='admin.wizard.action.none'}}
{{/if}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index 1321b18e..07e6a826 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -3,7 +3,7 @@

{{i18n 'admin.wizard.id'}}

- {{input name="id" value=field.id placeholderKey="admin.wizard.id_placeholder" disabled=existingId}} + {{input name="id" value=field.id placeholderKey="admin.wizard.id_placeholder" disabled=disableId}}
@@ -83,27 +83,13 @@ {{combo-box value=field.choices_preset content=presetChoices none='admin.wizard.field.choices_preset.none'}} - {{#each presetFilters as |f|}} - - {{input type="text" value=f.key placeholder=(i18n 'admin.wizard.field.choices_preset.key')}} - {{input type="text" value=f.value placeholder=(i18n 'admin.wizard.field.choices_preset.value')}} - - {{d-button action='removeFilter' actionParam=f icon='times'}} - {{/each}} -
{{d-button action='addFilter' label='admin.wizard.add' icon='plus'}}
+ {{wizard-custom-input inputs=field.choices_filters}}
{{i18n 'admin.wizard.field.choices_custom'}}
- {{#each dropdownChoices as |c|}} - - {{input type='text' value=c.value placeholder=(i18n 'admin.wizard.field.choice.value')}} - {{input type='text' value=c.label placeholder=(i18n 'admin.wizard.field.choice.label')}} - - {{d-button action='removeChoice' actionParam=c icon='times'}} - {{/each}} -
{{d-button action='addChoice' label='admin.wizard.add' icon='plus'}}
+ {{wizard-custom-input inputs=field.choices}}
{{/if}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs new file mode 100644 index 00000000..5cce6e95 --- /dev/null +++ b/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs @@ -0,0 +1,16 @@ +{{#each inputs as |in|}} + + {{#if keyContent}} + {{combo-box value=in.key content=keyContent nameProperty="label" none=noneKey}} + {{else}} + {{input type="text" value=in.key placeholder=(i18n 'admin.wizard.key')}} + {{/if}} + {{#if valueContent}} + {{combo-box value=in.value content=valueContent nameProperty="label" none=noneValue}} + {{else}} + {{input type="text" value=in.value placeholder=(i18n 'admin.wizard.value')}} + {{/if}} + + {{d-button action='remove' actionParam=in icon='times'}} +{{/each}} +
{{d-button action='add' label='admin.wizard.add' icon='plus'}}
diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs index 42e1ee18..d9041685 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs @@ -43,7 +43,7 @@ -{{wizard-links type="field" current=currentField itesm=step.fields}} +{{wizard-links type="field" current=currentField items=step.fields}} {{#if currentField}} {{wizard-custom-field field=currentField types=fieldTypes removeField="removeField"}} {{/if}} diff --git a/assets/javascripts/wizard/controllers/custom-step.js.es6 b/assets/javascripts/wizard/controllers/custom-step.js.es6 index fec11ef1..9dc4f3ce 100644 --- a/assets/javascripts/wizard/controllers/custom-step.js.es6 +++ b/assets/javascripts/wizard/controllers/custom-step.js.es6 @@ -7,7 +7,7 @@ export default StepController.extend({ const next = this.get('step.next'); if (response.refresh_required) { const id = this.get('wizard.id'); - document.location = getUrl(`/w/${id}/steps/${next}`); + window.location.href = getUrl(`/w/${id}/steps/${next}`); } else { this.transitionToRoute('custom.step', next); } @@ -19,6 +19,14 @@ export default StepController.extend({ showMessage(message) { this.set('stepMessage', message); + }, + + finished(result) { + let url = "/"; + if (result.topic_id) { + url += `t/${result.topic_id}`; + } + window.location.href = getUrl(url); } } }); diff --git a/assets/javascripts/wizard/routes/custom.js.es6 b/assets/javascripts/wizard/routes/custom.js.es6 index 1f627fb3..38490a55 100644 --- a/assets/javascripts/wizard/routes/custom.js.es6 +++ b/assets/javascripts/wizard/routes/custom.js.es6 @@ -1,6 +1,5 @@ import { findCustomWizard } from '../models/custom'; import { ajax } from 'wizard/lib/ajax'; -import { getUrl } from 'discourse-common/lib/get-url'; export default Ember.Route.extend({ model(params) { @@ -25,13 +24,5 @@ export default Ember.Route.extend({ customWizard: true, logoUrl: Wizard.SiteSettings.logo_small_url }); - }, - - actions: { - finished(result) { - let url = "/"; - if (result.topic_id) url += `t/${result.topic_id}`; - document.location.replace(getUrl(url)); - } } }); diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 5803a10d..1be29877 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -20,11 +20,13 @@ en: add: "Add" url: "Url" key: "Key" + value: "Value" id: "Id" id_placeholder: "Underscored. Cannot be changed." key_placeholder: "Translation key" custom_text_placeholder: "Overrides translation" type: "Type" + none: "Make a selection" error: name_required: "Wizards must have a name." steps_required: "Wizards must have at least one step." @@ -47,11 +49,8 @@ en: choices_custom: "Custom" choices_preset: label: "Preset" - none: "Select a data type" categories: "Categories" filter: "Filter" - key: "Key" - value: "Value" choice: value: "Value" label: "Label" @@ -71,7 +70,7 @@ en: create_topic: label: "Create Topic" category: "Category" - featured_link: "Featured Link" + add_fields: "Add Fields" update_profile: label: "Update Profile" wizard_field: "Wizard Field" @@ -80,3 +79,33 @@ en: wizard_js: wizard: completed: "You have completed this wizard." + location: + name: + title: "Name (optional)" + desc: "e.g. P. Sherman Dentist" + street: + title: "Number and Street" + desc: "e.g. 42 Wallaby Way" + postalcode: + title: "Postal Code (Zip)" + desc: "e.g. 2548" + city: + title: "City, Town or Village" + desc: "e.g. Sydney" + country_code: + title: "Country" + placeholder: "Select a Country" + query: + title: "Address" + desc: "e.g. 42 Wallaby Way, Sydney." + geo: + desc: "Locations provided by {{provider}}" + btn: + label: "Find Location" + results: "Locations" + no_results: "No results. Please double check the spelling." + show_map: "Show Map" + validation: + city: "Please enter a city or town." + countrycode: "Please enter a country." + geo_location: "Search and select a result." diff --git a/lib/builder.rb b/lib/builder.rb index a3329b85..28d0849b 100644 --- a/lib/builder.rb +++ b/lib/builder.rb @@ -12,6 +12,7 @@ class CustomWizard::Builder background: data["background"], name: data["name"] ) + @submissions = Array.wrap(PluginStore.get("custom_wizard_submissions", wizard_id)) end def self.sorted_handlers @@ -49,10 +50,9 @@ class CustomWizard::Builder params[:description] = f['description'] if f['description'] params[:key] = f['key'] if f['key'] - submissions = Array.wrap(PluginStore.get("custom_wizard_submissions", @wizard.id)) - if submissions.last && submissions.last['completed'] === false - @submission = submissions.last - params[:value] = @submission[f['id']] if @submission[f['id']] + if @submissions.last && @submissions.last['completed'] === false + submission = @submissions.last + params[:value] = submission[f['id']] if submission[f['id']] end field = step.add_field(params) @@ -94,12 +94,13 @@ class CustomWizard::Builder step.on_update do |updater| @updater = updater - input = updater.fields + submission = @submissions.last || {} + step_input = updater.fields || {} user = @wizard.user if s['fields'] && s['fields'].length s['fields'].each do |f| - value = input[f['id']] + value = step_input[f['id']] min_length = f['min_length'] if min_length && value.is_a?(String) && value.length < min_length.to_i label = f['label'] || I18n.t("#{f['key']}.label") @@ -121,17 +122,43 @@ class CustomWizard::Builder if s['actions'] && s['actions'].length s['actions'].each do |a| if a['type'] === 'create_topic' - title = input[a['title']] - post = input[a['post']] + title = submission[a['title']] + post = submission[a['post']] - if title && post + if title params = { title: title, raw: post, skip_validations: true } params[:category] = a['category_id'] if a['category_id'] - params[:featured_link] = input[a['featured_link']] if input[a['featured_link']] + + topic_custom_fields = {} + + if a['add_fields'] + a['add_fields'].each do |f| + value = submission[f['value']] + key = f['key'] + + if key.include?('custom_fields') + keyArr = key.split('.') + + if keyArr.length === 3 + custom_key = keyArr.last + type = keyArr.first + + if type === 'topic' + topic_custom_fields[custom_key] = value + elsif type === 'post' + params[:custom_fields] ||= {} + params[:custom_fields][custom_key.to_sym] = value + end + end + else + params[key.to_sym] = value + end + end + end creator = PostCreator.new(user, params) post = creator.create @@ -139,14 +166,20 @@ class CustomWizard::Builder if creator.errors.present? updater.errors.add(:create_topic, creator.errors.full_messages.join(" ")) else + if topic_custom_fields.present? + topic_custom_fields.each do |k, v| + post.topic.custom_fields[k] = v + end + post.topic.save_custom_fields(true) + end updater.result = { topic_id: post.topic.id } end end end if a['type'] === 'send_message' - title = input[a['title']] - post = input[a['post']] + title = submission[a['title']] + post = submission[a['post']] if title && post creator = PostCreator.new(user, @@ -160,50 +193,42 @@ class CustomWizard::Builder if creator.errors.present? updater.errors.add(:send_message, creator.errors.full_messages.join(" ")) else - updater.result = { topic_id: post.topic.id } + updater.result = { topic_id: post.topic_id } end end end if a['type'] === 'update_profile' && a['profile_updates'].length - updater = UserUpdater.new(user, user) - attributes = a['profile_updates'].map do |pu| - { pu['profile_field'].to_sym => input[pu['wizard_field']] } + user_updater = UserUpdater.new(user, user) + attributes = {} + a['profile_updates'].each do |pu| + attributes[pu['key'].to_sym] = submission[pu['value']] end - updater.update(attributes) + user_updater.update(attributes) if attributes.present? end end end if @wizard.save_submissions && updater.errors.empty? - store_key = @wizard.id - submissions = Array.wrap(PluginStore.get("custom_wizard_submissions", store_key)) - submission = {} - - if submissions.last && submissions.last['completed'] === false - submission = submissions.last - submissions.pop(1) - end + @submissions.pop(1) if submission && submission['completed'] === false submission['user_id'] = @wizard.user.id submission['completed'] = updater.step.next.nil? - if input - input.each do |key, value| + if step_input + step_input.each do |key, value| submission[key] = value end end - submissions.push(submission) - PluginStore.set('custom_wizard_submissions', store_key, submissions) + @submissions.push(submission) + PluginStore.set('custom_wizard_submissions', @wizard.id, @submissions) end end end end end - puts "BUILDER: #{@wizard.respond_to?(:multiple_submissions)}" - @wizard end end