diff --git a/assets/javascripts/discourse/components/wizard-advanced-toggle.js.es6 b/assets/javascripts/discourse/components/wizard-advanced-toggle.js.es6 new file mode 100644 index 00000000..51b9948c --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-advanced-toggle.js.es6 @@ -0,0 +1,19 @@ +import { default as discourseComputed } from 'discourse-common/utils/decorators'; +import Component from '@ember/component'; + +export default Component.extend({ + classNames: 'wizard-advanced-toggle', + + @discourseComputed('showAdvanced') + toggleClass(showAdvanced) { + let classes = 'btn' + if (showAdvanced) classes += ' btn-primary'; + return classes; + }, + + actions: { + toggleAdvanced() { + this.toggleProperty('showAdvanced'); + } + } +}) \ No newline at end of file diff --git a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 index 45182098..ebbfa985 100644 --- a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 @@ -1,11 +1,11 @@ -import { default as discourseComputed, observes } from 'discourse-common/utils/decorators'; -import { equal, not, empty } from "@ember/object/computed"; +import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators'; +import { equal, not, empty, or } from "@ember/object/computed"; import { actionTypes, generateName, generateSelectKitContent, profileFields -} from '../lib/custom-wizard'; +} from '../lib/wizard'; export default Ember.Component.extend({ classNames: 'wizard-custom-action', @@ -19,6 +19,13 @@ export default Ember.Component.extend({ routeTo: equal('action.type', 'route_to'), disableId: not('action.isNew'), groupPropertyTypes: generateSelectKitContent(['id', 'name']), + hasAdvanced: or('basicTopicFields', 'routeTo'), + + @on('didInsertElement') + @observes('action.type') + updateId() { + if (this.action.type) this.set('action.id', generateName(this.action.type)); + }, @discourseComputed('action.type') basicTopicFields(actionType) { diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index 874a02cc..c62f044f 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -1,6 +1,6 @@ import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators'; import { equal, not, or } from "@ember/object/computed"; -import { generateSelectKitContent } from '../lib/custom-wizard'; +import { generateSelectKitContent } from '../lib/wizard'; export default Ember.Component.extend({ classNames: 'wizard-custom-field', @@ -16,6 +16,7 @@ export default Ember.Component.extend({ categoryPropertyTypes: generateSelectKitContent(['id', 'slug']), prefillEnabled: or('isCategory', 'isTag', 'isGroup'), contentEnabled: or('isCategory', 'isTag', 'isGroup'), + hasAdvanced: or('isCategory', 'isTag', 'isGroup'), @discourseComputed('field.type') isInput: (type) => type === 'text' || type === 'textarea' || type === 'url', diff --git a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 b/assets/javascripts/discourse/components/wizard-custom-step.js.es6 index 169c3fdc..cd9ad57c 100644 --- a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-step.js.es6 @@ -1,5 +1,6 @@ import { observes, on, default as discourseComputed } from 'discourse-common/utils/decorators'; import { not } from "@ember/object/computed"; +import EmberObject from "@ember/object"; export default Ember.Component.extend({ classNames: 'wizard-custom-step', @@ -31,7 +32,7 @@ export default Ember.Component.extend({ actions.forEach(a => { if (a.type === 'route_to' && a.code) { content.push( - Ember.Object.create({ + EmberObject.create({ id: a.code, label: "code (Route To)" }) diff --git a/assets/javascripts/discourse/components/wizard-links.js.es6 b/assets/javascripts/discourse/components/wizard-links.js.es6 index 7c676dab..ecfa2bd8 100644 --- a/assets/javascripts/discourse/components/wizard-links.js.es6 +++ b/assets/javascripts/discourse/components/wizard-links.js.es6 @@ -1,6 +1,7 @@ import { default as computed, on, observes } from 'discourse-common/utils/decorators'; import { notEmpty } from "@ember/object/computed"; import { scheduleOnce } from "@ember/runloop"; +import EmberObject from "@ember/object"; export default Ember.Component.extend({ classNameBindings: [':wizard-links', 'type'], @@ -67,7 +68,7 @@ export default Ember.Component.extend({ params['actions'] = Ember.A(); }; - const newItem = Ember.Object.create(params); + const newItem = EmberObject.create(params); items.pushObject(newItem); this.set('current', newItem); }, diff --git a/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 new file mode 100644 index 00000000..7f3eb153 --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 @@ -0,0 +1,13 @@ +import Component from "@ember/component"; +import { lt } from '@ember/object/computed'; +import { computed } from "@ember/object"; + +export default Component.extend({ + classNameBindings: [':mapper-connector', ':mapper-block', 'single'], + single: lt('connectors.length', 2), + connectorLabel: computed(function() { + let key = this.connector; + let path = this.inputTypes ? `input.${key}.name` : `connector.${key}`; + return I18n.t(`admin.wizard.${path}`); + }) +}); \ No newline at end of file diff --git a/assets/javascripts/discourse/components/wizard-mapper-input.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-input.js.es6 index d7c364ab..08b77c10 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-input.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-input.js.es6 @@ -1,6 +1,6 @@ import { computed, set } from "@ember/object"; import { alias, equal } from "@ember/object/computed"; -import { newPair, connectorContent, inputTypesContent } from '../lib/mapper'; +import { newPair, connectorContent, inputTypesContent } from '../lib/wizard-mapper'; export default Ember.Component.extend({ classNameBindings: [':mapper-input', 'type'], diff --git a/assets/javascripts/discourse/components/wizard-mapper-pair.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-pair.js.es6 index 58144445..9de326b9 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-pair.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-pair.js.es6 @@ -1,4 +1,4 @@ -import { connectorContent } from '../lib/mapper'; +import { connectorContent } from '../lib/wizard-mapper'; import { gt, or, alias } from "@ember/object/computed"; import { computed, observes } from "@ember/object"; diff --git a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 index b25d54b1..b5ee771f 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 @@ -2,7 +2,7 @@ import { alias } from "@ember/object/computed"; import { computed } from "@ember/object"; import { default as discourseComputed, observes } from "discourse-common/utils/decorators"; import { getOwner } from 'discourse-common/lib/get-owner'; -import { defaultSelectionType } from '../lib/mapper'; +import { defaultSelectionType } from '../lib/wizard-mapper'; export default Ember.Component.extend({ classNames: 'mapper-selector', diff --git a/assets/javascripts/discourse/components/wizard-mapper.js.es6 b/assets/javascripts/discourse/components/wizard-mapper.js.es6 index fa7db138..b1714a71 100644 --- a/assets/javascripts/discourse/components/wizard-mapper.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper.js.es6 @@ -1,6 +1,6 @@ import { getOwner } from 'discourse-common/lib/get-owner'; import { on } from 'discourse-common/utils/decorators'; -import { newInput } from '../lib/mapper'; +import { newInput } from '../lib/wizard-mapper'; import { default as discourseComputed } from 'discourse-common/utils/decorators'; export default Ember.Component.extend({ diff --git a/assets/javascripts/discourse/components/wizard-text-editor.js.es6 b/assets/javascripts/discourse/components/wizard-text-editor.js.es6 index 7335f75f..4d2a8475 100644 --- a/assets/javascripts/discourse/components/wizard-text-editor.js.es6 +++ b/assets/javascripts/discourse/components/wizard-text-editor.js.es6 @@ -2,7 +2,7 @@ import { default as discourseComputed, on } from 'discourse-common/utils/decorators'; -import { profileFields } from '../lib/custom-wizard'; +import { profileFields } from '../lib/wizard'; import { scheduleOnce } from "@ember/runloop"; export default Ember.Component.extend({ diff --git a/assets/javascripts/discourse/controllers/admin-wizard.js.es6 b/assets/javascripts/discourse/controllers/admin-wizard.js.es6 index d7557798..0c4622f8 100644 --- a/assets/javascripts/discourse/controllers/admin-wizard.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizard.js.es6 @@ -1,13 +1,20 @@ import { default as discourseComputed, observes } from 'discourse-common/utils/decorators'; import { notEmpty } from "@ember/object/computed"; import showModal from 'discourse/lib/show-modal'; -import { generateId } from '../lib/custom-wizard'; -import { buildProperties } from '../lib/json'; +import { generateId } from '../lib/wizard'; +import { buildProperties } from '../lib/wizard-json'; import { dasherize } from "@ember/string"; +import EmberObject from "@ember/object"; +import { scheduleOnce } from "@ember/runloop"; export default Ember.Controller.extend({ hasName: notEmpty('model.name'), + init() { + this._super(); + scheduleOnce('afterRender', () => ($("body").addClass('admin-wizard'))); + }, + @observes('model.name') setId() { if (!this.model.existingId) this.set('model.id', generateId(this.model.name)); @@ -38,7 +45,7 @@ export default Ember.Controller.extend({ steps.forEach((s) => { if (s.fields && s.fields.length > 0) { let stepFields = s.fields.map((f) => { - return Ember.Object.create({ + return EmberObject.create({ id: f.id, label: `${f.id} (${s.id})`, type: f.type @@ -98,5 +105,9 @@ export default Ember.Controller.extend({ controller.setup(); }, + + toggleAdvanced() { + this.toggleProperty('model.showAdvanced'); + } } }); diff --git a/assets/javascripts/discourse/controllers/admin-wizards-api.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-api.js.es6 index 15861b2d..fc7a456f 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-api.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-api.js.es6 @@ -2,7 +2,7 @@ import { ajax } from 'discourse/lib/ajax'; import { popupAjaxError } from 'discourse/lib/ajax-error'; import CustomWizardApi from '../models/custom-wizard-api'; import { default as computed } from 'discourse-common/utils/decorators'; -import { generateSelectKitContent } from '../lib/custom-wizard'; +import { generateSelectKitContent } from '../lib/wizard'; export default Ember.Controller.extend({ queryParams: ['refresh_list'], diff --git a/assets/javascripts/discourse/lib/json.js.es6 b/assets/javascripts/discourse/lib/wizard-json.js.es6 similarity index 68% rename from assets/javascripts/discourse/lib/json.js.es6 rename to assets/javascripts/discourse/lib/wizard-json.js.es6 index e0b90043..c25ebb81 100644 --- a/assets/javascripts/discourse/lib/json.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-json.js.es6 @@ -1,5 +1,4 @@ -import { properties } from '../lib/custom-wizard'; -import { mappedProperties } from '../lib/mapper'; +import { properties, mappedProperties } from '../lib/wizard'; import EmberObject from '@ember/object'; function present(val) { @@ -152,38 +151,36 @@ function buildObject(json, type) { } Object.keys(json).forEach(prop => { - if (mapped(prop, type)) { + if (mapped(prop, type) && present(json[prop])) { let inputs = []; - if (present(json[prop])) { - json[prop].forEach(inputJson => { - let input = {} - - Object.keys(inputJson).forEach(inputKey => { - if (inputKey === 'pairs') { - let pairs = []; - let pairCount = inputJson.pairs.length; + json[prop].forEach(inputJson => { + let input = {} + + Object.keys(inputJson).forEach(inputKey => { + if (inputKey === 'pairs') { + let pairs = []; + let pairCount = inputJson.pairs.length; + + inputJson.pairs.forEach(pairJson => { + let pair = pairJson; + pair.pairCount = pairCount; - inputJson.pairs.forEach(pairJson => { - let pair = pairJson; - pair.pairCount = pairCount; - - pairs.push( - EmberObject.create(pair) - ); - }); - - input.pairs = pairs; - } else { - input[inputKey] = inputJson[inputKey]; - } - }); - - inputs.push( - EmberObject.create(input) - ); + pairs.push( + EmberObject.create(pair) + ); + }); + + input.pairs = pairs; + } else { + input[inputKey] = inputJson[inputKey]; + } }); - } + + inputs.push( + EmberObject.create(input) + ); + }); params[prop] = Ember.A(inputs); } else { @@ -194,6 +191,30 @@ function buildObject(json, type) { return EmberObject.create(params); } +function isAdvancedWizard(property, value) { + if (property === 'save_submissions' && value == false) return true; + if (property === 'restart_on_revisit' && value == true) return true; + return false; +} + +function isAdvancedStep(property, value) { + return mapped(property, 'step') && present(value); +} + +function isAdvancedField(params) { + if (present(params.property)) return true; + if (present(params.prefill)) return true; + if (present(params.content)) return true; + return false; +} + +function isAdvancedAction(params) { + if (present(params.code)) return true; + if (present(params.custom_fields)) return true; + if (present(params.skip_redirect)) return true; + return false; +} + function buildProperties(json) { let steps = Ember.A(); let props = { @@ -206,6 +227,10 @@ function buildProperties(json) { properties.wizard.forEach((p) => { props[p] = json[p]; + + if (isAdvancedWizard(p, json[p])) { + props.showAdvanced = true; + } }); if (present(json.steps)) { @@ -216,15 +241,23 @@ function buildProperties(json) { properties.step.forEach((p) => { stepParams[p] = stepJson[p]; + + if (isAdvancedStep(p, stepJson[p])) { + stepParams.showAdvanced = true; + } }); stepParams.fields = Ember.A(); if (present(stepJson.fields)) { stepJson.fields.forEach((f) => { - stepParams.fields.pushObject( - buildObject(f, 'field') - ); + let params = buildObject(f, 'field'); + + if (isAdvancedField(params)) { + params.showAdvanced = true; + } + + stepParams.fields.pushObject(params); }); } @@ -232,9 +265,13 @@ function buildProperties(json) { if (present(stepJson.actions)) { stepJson.actions.forEach((a) => { - stepParams.actions.pushObject( - buildObject(a, 'action') - ); + let params = buildObject(a, 'action'); + + if (isAdvancedAction(params)) { + params.showAdvanced = true; + } + + stepParams.actions.pushObject(params); }); } diff --git a/assets/javascripts/discourse/lib/mapper.js.es6 b/assets/javascripts/discourse/lib/wizard-mapper.js.es6 similarity index 73% rename from assets/javascripts/discourse/lib/mapper.js.es6 rename to assets/javascripts/discourse/lib/wizard-mapper.js.es6 index 88aa30f5..99677d1c 100644 --- a/assets/javascripts/discourse/lib/mapper.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-mapper.js.es6 @@ -1,27 +1,4 @@ -const mappedProperties = { - wizard: [ - 'permitted' - ], - step: [ - 'required_data', - 'permitted_params' - ], - field: [ - 'choices', - 'prefill', - 'content' - ], - action: [ - 'title', - 'category', - 'tags', - 'custom_fields', - 'required', - 'recipient', - 'profile_updates', - 'group' - ] -} +import EmberObject from "@ember/object"; // Inputs @@ -67,25 +44,28 @@ const connectors = { ] } -function connectorItem(connector) { - return { - id: connector, - name: I18n.t(`admin.wizard.connector.${connector}`) - }; -} - function defaultConnector(connectorType, inputType, opts = {}) { if (opts[`${connectorType}Connector`]) return opts[`${connectorType}Connector`]; - if (inputType === 'assignment') return 'set'; - return connectorType === 'output' ? 'then' : 'equal'; + if (inputType === 'assignment' && connectorType === 'output') return 'set'; + if (inputType === 'conditional' && connectorType === 'output') return 'then'; + if (inputType === 'conditional' && connectorType === 'pair') return 'equal'; + if (inputType === 'pair') return 'equal'; } function connectorContent(connectorType, inputType, opts) { - let connector = opts[`${connectorType}Connector`] || defaultConnector(connectorType, inputType, opts); - if (connector) return [connectorItem(connector)]; + let connector = opts[`${connectorType}Connector`]; - return connectors[connectorType].map(function(connector) { - return connectorItem(connector); + if (!connector && connectorType === 'output') { + connector = defaultConnector(connectorType, inputType, opts); + } + + let content = connector ? [connector] : connectors[connectorType]; + + return content.map(function(item) { + return { + id: item, + name: I18n.t(`admin.wizard.connector.${item}`) + }; }); } @@ -113,6 +93,7 @@ function defaultSelectionType(inputType, options = {}) { if (inputTypes === true || ((typeof inputTypes === 'string') && inputTypes.split(',').indexOf(inputType) > -1)) { + type = t; break; } @@ -134,7 +115,7 @@ function newPair(inputType, options = {}) { connector: defaultConnector('pair', inputType, options) } - return Ember.Object.create(params); + return EmberObject.create(params); } function newInput(options = {}) { @@ -160,11 +141,10 @@ function newInput(options = {}) { params['connector'] = defaultConnector('output', inputType, options); } - return Ember.Object.create(params); + return EmberObject.create(params); } export { - mappedProperties, defaultInputType, defaultSelectionType, connectorContent, diff --git a/assets/javascripts/discourse/lib/custom-wizard.js.es6 b/assets/javascripts/discourse/lib/wizard.js.es6 similarity index 83% rename from assets/javascripts/discourse/lib/custom-wizard.js.es6 rename to assets/javascripts/discourse/lib/wizard.js.es6 index f5c50e4c..b1dcdd4b 100644 --- a/assets/javascripts/discourse/lib/custom-wizard.js.es6 +++ b/assets/javascripts/discourse/lib/wizard.js.es6 @@ -75,6 +75,7 @@ const actionProperties = [ 'type', 'title', 'post', + 'post_builder', 'post_template', 'category', 'tags', @@ -98,6 +99,31 @@ const properties = { action: actionProperties } +const mappedProperties = { + wizard: [ + 'permitted' + ], + step: [ + 'required_data', + 'permitted_params' + ], + field: [ + 'choices', + 'prefill', + 'content' + ], + action: [ + 'title', + 'category', + 'tags', + 'custom_fields', + 'required', + 'recipient', + 'profile_updates', + 'group' + ] +} + const actionTypes = [ 'create_topic', 'update_profile', @@ -116,6 +142,7 @@ export { generateId, properties, wizardProperties, + mappedProperties, profileFields, actionTypes }; \ No newline at end of file diff --git a/assets/javascripts/discourse/models/custom-wizard.js.es6 b/assets/javascripts/discourse/models/custom-wizard.js.es6 index 4f987d9f..309078c6 100644 --- a/assets/javascripts/discourse/models/custom-wizard.js.es6 +++ b/assets/javascripts/discourse/models/custom-wizard.js.es6 @@ -1,6 +1,6 @@ import { ajax } from 'discourse/lib/ajax'; import EmberObject from "@ember/object"; -import { buildStepJson, buildJson, buildProperties } from '../lib/json'; +import { buildStepJson, buildJson, buildProperties } from '../lib/wizard-json'; const CustomWizard = EmberObject.extend({ save() { @@ -34,7 +34,6 @@ const CustomWizard = EmberObject.extend({ wizard: JSON.stringify(wizardJson) } }).then((result) => { - console.log('result: ', result); if (result.error) { reject(result); } else { diff --git a/assets/javascripts/discourse/routes/admin-wizard.js.es6 b/assets/javascripts/discourse/routes/admin-wizard.js.es6 index 7a880ded..a0ce9cdb 100644 --- a/assets/javascripts/discourse/routes/admin-wizard.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizard.js.es6 @@ -4,7 +4,7 @@ import { generateSelectKitContent, profileFields, generateName -} from '../lib/custom-wizard'; +} from '../lib/wizard'; import DiscourseRoute from "discourse/routes/discourse"; export default DiscourseRoute.extend({ @@ -95,6 +95,7 @@ export default DiscourseRoute.extend({ setupController(controller, model) { const newWizard = this.get('newWizard'); const steps = model.get('steps') || []; + controller.setProperties({ newWizard, model, diff --git a/assets/javascripts/discourse/templates/admin-wizard.hbs b/assets/javascripts/discourse/templates/admin-wizard.hbs index c9db1678..3f50c479 100644 --- a/assets/javascripts/discourse/templates/admin-wizard.hbs +++ b/assets/javascripts/discourse/templates/admin-wizard.hbs @@ -48,26 +48,7 @@
-
-
- -
-
- {{input type='checkbox' checked=model.save_submissions}} - {{i18n 'admin.wizard.save_submissions_label'}} -
-
- -
-
- -
-
- {{input type='checkbox' checked=model.multiple_submissions}} - {{i18n 'admin.wizard.multiple_submissions_label'}} -
-
- +
@@ -90,11 +71,11 @@
- +
- {{input type='checkbox' checked=model.restart_on_revisit}} - {{i18n 'admin.wizard.restart_on_revisit_label'}} + {{input type='checkbox' checked=model.multiple_submissions}} + {{i18n 'admin.wizard.multiple_submissions_label'}}
@@ -138,7 +119,36 @@ textSelection='key,value' )}}
+
+ + {{wizard-advanced-toggle showAdvanced=model.showAdvanced}} + + {{#if model.showAdvanced}} +
+ +
+
+ +
+
+ {{input type='checkbox' checked=model.save_submissions}} + {{i18n 'admin.wizard.save_submissions_label'}} +
+
+ +
+
+ +
+
+ {{input type='checkbox' checked=model.restart_on_revisit}} + {{i18n 'admin.wizard.restart_on_revisit_label'}} +
+
+ +
+ {{/if}}
{{wizard-links type="step" current=currentStep items=model.steps}} diff --git a/assets/javascripts/discourse/templates/components/wizard-advanced-toggle.hbs b/assets/javascripts/discourse/templates/components/wizard-advanced-toggle.hbs new file mode 100644 index 00000000..e77e3a31 --- /dev/null +++ b/assets/javascripts/discourse/templates/components/wizard-advanced-toggle.hbs @@ -0,0 +1,4 @@ +{{d-button + action="toggleAdvanced" + label='admin.wizard.advanced' + class=toggleClass}} \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs index 37567a55..bdc39f23 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs @@ -107,59 +107,7 @@ {{/if}} -{{#if newTopicFields}} -
-
- -
- -
- {{input type='checkbox' checked=action.skip_redirect}} - - - {{i18n 'admin.wizard.action.skip_redirect.description' type='topic'}} - -
-
-{{/if}} - -{{#if basicTopicFields}} -
-
- -
- -
- {{wizard-mapper - inputs=action.custom_fields - keyPlaceholder='admin.wizard.action.custom_fields.key' - options=(hash - pairConnector='set' - wizardSelection='value' - userSelection='value' - )}} -
-
-{{/if}} - -{{#if sendMessage}} -
-
- -
- -
- {{wizard-mapper - inputs=action.required - options=(hash - textSelection='value' - wizardSelection=true - userSelection=true - groupSelection=true - )}} -
-
- +{{#if sendMessage}}
@@ -172,7 +120,7 @@ hasOutput=true textSelection='value,output' wizardSelection=true - userSelection=true + userSelection='key,value' groupSelection='key,value' )}}
@@ -279,14 +227,79 @@ {{input value=action.url}}
- -
-
- -
- -
- {{input value=action.code}} -
-
+{{/if}} + +{{#if hasAdvanced}} + {{wizard-advanced-toggle showAdvanced=action.showAdvanced}} + + {{#if action.showAdvanced}} +
+ + {{#if basicTopicFields}} +
+
+ +
+ +
+ {{wizard-mapper + inputs=action.custom_fields + keyPlaceholder='admin.wizard.action.custom_fields.key' + options=(hash + pairConnector='set' + wizardSelection='value' + userSelection='value' + )}} +
+
+ {{/if}} + + {{#if sendMessage}} +
+
+ +
+ +
+ {{wizard-mapper + inputs=action.required + options=(hash + textSelection='value' + wizardSelection=true + userSelection=true + groupSelection=true + )}} +
+
+ {{/if}} + + {{#if newTopicFields}} +
+
+ +
+ +
+ {{input type='checkbox' checked=action.skip_redirect}} + + + {{i18n 'admin.wizard.action.skip_redirect.description' type='topic'}} + +
+
+ {{/if}} + + {{#if routeTo}} +
+
+ +
+ +
+ {{input value=action.code}} +
+
+ {{/if}} +
+ {{/if}} {{/if}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index 10351e1b..5ffe275e 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -125,24 +125,6 @@ {{/if}} -{{#if isCategory}} -
-
- -
- -
- {{combo-box - value=field.property - content=categoryPropertyTypes - onChange=(action (mut field.property)) - options=(hash - none='admin.wizard.select_property' - )}} -
-
-{{/if}} - {{#if isCategoryOrTag}}
@@ -155,26 +137,52 @@
{{/if}} -{{#if prefillEnabled}} -
-
- -
- -
- {{wizard-mapper inputs=field.prefill options=prefillOptions}} -
-
-{{/if}} +{{#if hasAdvanced}} + {{wizard-advanced-toggle showAdvanced=field.showAdvanced}} -{{#if contentEnabled}} -
-
- + {{#if field.showAdvanced}} +
+ {{#if isCategory}} +
+
+ +
+ +
+ {{combo-box + value=field.property + content=categoryPropertyTypes + onChange=(action (mut field.property)) + options=(hash + none='admin.wizard.select_property' + )}} +
+
+ {{/if}} + + {{#if prefillEnabled}} +
+
+ +
+ +
+ {{wizard-mapper inputs=field.prefill options=prefillOptions}} +
+
+ {{/if}} + + {{#if contentEnabled}} +
+
+ +
+ +
+ {{wizard-mapper inputs=field.content options=contentOptions}} +
+
+ {{/if}}
- -
- {{wizard-mapper inputs=field.content options=contentOptions}} -
-
+ {{/if}} {{/if}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs index 6940412a..6c37f368 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs @@ -46,44 +46,51 @@
-
-
- -
-
- {{wizard-mapper - inputs=step.required_data - keyPlaceholder="admin.wizard.submission_key" - options=(hash - pairConnector='equal' - wizardSelection='value' - userSelection='value' - )}} - {{#if step.required_data}} -
-
- {{i18n 'admin.wizard.step.required_data.not_permitted_message'}} -
- {{input value=step.required_data_message}} -
- {{/if}} -
-
+{{wizard-advanced-toggle showAdvanced=step.showAdvanced}} -
-
- +{{#if step.showAdvanced}} +
+ +
+
+ +
+
+ {{wizard-mapper + inputs=step.required_data + keyPlaceholder="admin.wizard.submission_key" + options=(hash + wizardSelection='value' + userSelection='value' + )}} + {{#if step.required_data}} +
+
+ {{i18n 'admin.wizard.step.required_data.not_permitted_message'}} +
+ {{input value=step.required_data_message}} +
+ {{/if}} +
+
+ +
+
+ +
+
+ {{wizard-mapper + inputs=step.permitted_params + keyPlaceholder='admin.wizard.param_key' + valuePlaceholder='admin.wizard.submission_key' + options=(hash + pairConnector='set' + )}} +
+
+
-
- {{wizard-mapper - inputs=step.permitted_params - keyPlaceholder='admin.wizard.param_key' - valuePlaceholder='admin.wizard.submission_key' - options=(hash - pairConnector='set' - )}} -
-
+{{/if}} {{wizard-links type="field" current=currentField items=step.fields}} diff --git a/assets/javascripts/discourse/templates/components/wizard-mapper-connector.hbs b/assets/javascripts/discourse/templates/components/wizard-mapper-connector.hbs new file mode 100644 index 00000000..f5373394 --- /dev/null +++ b/assets/javascripts/discourse/templates/components/wizard-mapper-connector.hbs @@ -0,0 +1,10 @@ +{{#if single}} + + {{connectorLabel}} + +{{else}} + {{combo-box + value=connector + content=connectors + onChange=(action (mut connector))}} +{{/if}} \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs b/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs index 89965d6e..bfd9ea9a 100644 --- a/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs @@ -1,10 +1,8 @@ {{#if hasOutput}} -
- {{combo-box - value=input.type - content=inputTypes - onChange=(action (mut input.type))}} -
+ {{wizard-mapper-connector + connector=input.type + connectors=inputTypes + inputTypes=true}} {{/if}} {{#if hasPairs}} @@ -30,12 +28,9 @@ {{#if hasOutput}} {{#if hasPairs}} -
- {{combo-box - value=input.connector - content=connectors - onChange=(action (mut input.connector))}} -
+ {{wizard-mapper-connector + connector=input.connector + connectors=connectors}} {{/if}}
diff --git a/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs b/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs index 60150707..7aea5a02 100644 --- a/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs @@ -8,12 +8,9 @@ options=options}}
-
- {{combo-box - value=pair.connector - content=connectors - onChange=(action (mut pair.connector))}} -
+{{wizard-mapper-connector + connector=pair.connector + connectors=connectors}}
{{wizard-mapper-selector diff --git a/assets/javascripts/wizard/components/wizard-field-composer.js.es6 b/assets/javascripts/wizard/components/wizard-field-composer.js.es6 index a0bc3c41..7ae281bd 100644 --- a/assets/javascripts/wizard/components/wizard-field-composer.js.es6 +++ b/assets/javascripts/wizard/components/wizard-field-composer.js.es6 @@ -1,4 +1,5 @@ import { default as computed, observes } from 'discourse-common/utils/decorators'; +import EmberObject from "@ember/object"; export default Ember.Component.extend({ showPreview: false, @@ -6,7 +7,7 @@ export default Ember.Component.extend({ classNameBindings: ["showPreview:show-preview:hide-preview"], didInsertElement() { - this.set('composer', Ember.Object.create({ + this.set('composer', EmberObject.create({ loading: false, reply: this.get('field.value') })) diff --git a/assets/javascripts/wizard/models/custom.js.es6 b/assets/javascripts/wizard/models/custom.js.es6 index 5a87dcd0..9477e813 100644 --- a/assets/javascripts/wizard/models/custom.js.es6 +++ b/assets/javascripts/wizard/models/custom.js.es6 @@ -3,15 +3,15 @@ import getUrl from 'discourse-common/lib/get-url'; import WizardField from 'wizard/models/wizard-field'; import { ajax } from 'wizard/lib/ajax'; import Step from 'wizard/models/step'; +import EmberObject from "@ember/object"; -const CustomWizard = Ember.Object.extend({ +const CustomWizard = EmberObject.extend({ @computed('steps.length') totalSteps: length => length, skip() { - if (this.get('required') && (!this.get('completed') && this.get('permitted'))) return; - const id = this.get('id'); - CustomWizard.skip(id); + if (this.required && (!this.completed && this.permitted)) return; + CustomWizard.skip(this.id); }, }); @@ -70,7 +70,7 @@ export function findCustomWizard(wizardId, params = {}) { subcatMap[c.parent_category_id] || []; subcatMap[c.parent_category_id].push(c.id); } - return (categoriesById[c.id] = Ember.Object.create(c)); + return (categoriesById[c.id] = EmberObject.create(c)); }); // Associate the categories with their parents diff --git a/assets/stylesheets/common/wizard-admin.scss b/assets/stylesheets/common/wizard-admin.scss index e75ff7d6..4b414d41 100644 --- a/assets/stylesheets/common/wizard-admin.scss +++ b/assets/stylesheets/common/wizard-admin.scss @@ -4,6 +4,12 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); +body.admin-wizard { + .boxed.white { + background-color: initial; + } +} + .wizard-list { float: left; width: 250px; @@ -12,8 +18,8 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); .wizard-settings-parent { margin-bottom: 30px; - padding: 30px; - background-color: $setting-background; + padding: 20px; + border: 1px solid $primary-medium; } .wizard-settings-group { @@ -32,10 +38,29 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); .wizard-basic-details, .wizard-custom-field, -.wizard-custom-action { +.wizard-custom-action, +.advanced-settings { @extend .wizard-settings-group; } +.wizard-custom-field, +.wizard-custom-action { + position: relative; + background: transparent; + background-color: $setting-background; + padding: 20px; +} + +.wizard-links { + &.action, &.field { + margin-top: 50px; + } +} + +.wizard-settings > .advanced-settings > div.setting { + margin-bottom: 0; +} + .admin-wizard.settings .wizard-basic-details { justify-content: initial; @@ -99,13 +124,18 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); .admin-wizard.settings { margin-top: 10px; margin-left: 30px; - + [class~='setting'] { display: inline-flex; align-items: flex-start; width: 48%; margin-bottom: 30px; padding-bottom: 0; + position: relative; + + &:last-of-type { + margin-bottom: 0; + } .setting-label { width: 80px; @@ -144,6 +174,7 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); input[type="number"] { width: 70px; + margin-bottom: 0; } input.medium { @@ -198,9 +229,8 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); display: flex; align-items: center; - input[type='checkbox'], - span { - margin: 0 10px 0 0; + input { + margin: 0 7px 0 0; } button { @@ -218,6 +248,15 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); } } + .advanced-settings { + width: 100%; + margin-top: 30px; + + [class~='setting']:first-of-type { + border-top: none; + } + } + .wizard-custom-action > [class~='setting']:last-of-type { margin-bottom: 0; } @@ -365,11 +404,11 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); .admin-contents .wizard-submissions { width: 100%; - display: inline-block; + margin-top: 10px; + margin-left: 30px; table { margin-top: 0; - position: absolute; } } @@ -470,3 +509,11 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%); height: unset !important; } +.wizard-advanced-toggle { + width: 100%; +} + +.add-mapper-input .btn, .btn-after-time, .wizard-editor-gutter .btn { + background-color: $secondary; + border: 1px solid $primary-medium; +} diff --git a/assets/stylesheets/common/wizard-mapper.scss b/assets/stylesheets/common/wizard-mapper.scss index 4c68c3fa..aeb33ba3 100644 --- a/assets/stylesheets/common/wizard-mapper.scss +++ b/assets/stylesheets/common/wizard-mapper.scss @@ -52,11 +52,6 @@ .add-mapper-input { display: block; - - .btn { - background-color: $secondary; - border: 1px solid $primary-medium; - } } .mapper-input + .add-mapper-input { @@ -68,23 +63,27 @@ min-width: 40px; .select-kit .select-kit-header { - padding: 0 0.5em; display: flex; justify-content: center; - - .caret-icon { - display: none; - } + } + + &.single { + height: 28px; + background: $secondary; + border: 1px solid $primary-medium; + display: flex; + align-items: center; + justify-content: center; } } .mapper-selector { width: 100%; - max-width: 160px; - min-width: 160px; + max-width: 150px; + min-width: 150px; input, .select-kit { - width: 160px; + width: 150px; } .type-selector { diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index ad47e52d..ac2a5168 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -60,6 +60,7 @@ en: param_key: 'param' group: "Group" permitted: "Permitted" + advanced: "Advanced" editor: show: "Show" diff --git a/lib/custom_wizard/actions.rb b/lib/custom_wizard/actions.rb index 5afb582b..38eeb4e4 100644 --- a/lib/custom_wizard/actions.rb +++ b/lib/custom_wizard/actions.rb @@ -20,144 +20,69 @@ class CustomWizard::Action end def create_topic - if action['custom_title_enabled'] - title = mapper.interpolate(action['custom_title']) - else - title = data[action['title']] - end + params = basic_topic_params - if action['post_builder'] - post = mapper.interpolate(action['post_template']) - else - post = data[action['post']] - end + byebug - if title - params = { - title: title, - raw: post, - skip_validations: true - } - - params[:category] = action_category_id(action, data) - tags = action_tags(action, data) - params[:tags] = tags + if params[:title] && params[:raw] + params[:category] = action_category + params[:tags] = action_tags - if action['add_fields'] - action['add_fields'].each do |field| - value = field['value_custom'].present? ? field['value_custom'] : data[field['value']] - key = field['key'] - - if key && (value.present? || value === false) - if key.include?('custom_fields') - keyArr = key.split('.') - - if keyArr.length === 3 - custom_key = keyArr.last - type = keyArr.first - - if type === 'topic' - params[:topic_opts] ||= {} - params[:topic_opts][:custom_fields] ||= {} - params[:topic_opts][:custom_fields][custom_key] = value - elsif type === 'post' - params[:custom_fields] ||= {} - params[:custom_fields][custom_key.to_sym] = value - end - end - else - value = [*value] + [*tags] if key === 'tags' - params[key.to_sym] = value - end - end - end - end + byebug creator = PostCreator.new(user, params) post = creator.create if creator.errors.present? updater.errors.add(:create_topic, creator.errors.full_messages.join(" ")) - else - - unless action['skip_redirect'] - data['redirect_on_complete'] = post.topic.url - end + elsif action['skip_redirect'].blank? + data['redirect_on_complete'] = post.topic.url end end end def send_message - if action['required'].present? && data[action['required']].blank? - return - end + return if action['required'].present? && data[action['required']].blank? - if action['custom_title_enabled'] - title = mapper.interpolate(action['custom_title']) - else - title = data[action['title']] - end - - if action['post_builder'] - post = mapper.interpolate(action['post_template']) - else - post = data[action['post']] - end - - if title && post - creator = PostCreator.new(user, - title: title, - raw: post, - archetype: Archetype.private_message, - target_usernames: action['username'] - ) - + params = basic_topic_params + params[:target_usernames] = CustomWizard::Mapper.new( + inputs: action['recipient'], + data: data, + user: user, + opts: { + multiple: true + } + ).output + + if params[:title] && params[:raw] + params[:archetype] = Archetype.private_message + + creator = PostCreator.new(user, params) post = creator.create if creator.errors.present? updater.errors.add(:send_message, creator.errors.full_messages.join(" ")) - else - unless action['skip_redirect'] - data['redirect_on_complete'] = post.topic.url - end + elsif action['skip_redirect'].blank? + data['redirect_on_complete'] = post.topic.url end end end def update_profile - return unless action['profile_updates'].length + return unless (profile_updates = action['profile_updates']).length - attributes = {} - custom_fields = {} + attributes = { custom_fields: {} } - action['profile_updates'].each do |pu| - value = pu['value'] - key = pu['key'] + profile_updates.each do |pu| + pair = field['pairs'].first + field = mapper.map_field(pair['key'], pair['key_type']) + value = mapper.map_field(pair['value'], pair['value_type']) - return if data[key].blank? - - if user_field || custom_field - custom_fields[user_field || custom_field] = data[key] + if field.include?("custom_field") + attributes[:custom_fields][field] = value else - updater_key = value - if ['profile_background', 'card_background'].include?(value) - updater_key = "#{value}_upload_url" - end - attributes[updater_key.to_sym] = data[key] if updater_key + attributes[field.to_sym] = value end - - if ['user_avatar'].include?(value) - this_upload_id = data[key][:id] - user.create_user_avatar unless user.user_avatar - user.user_avatar.custom_upload_id = this_upload_id - user.uploaded_avatar_id = this_upload_id - user.save! - user.user_avatar.save! - end - end - - if custom_fields.present? - attributes[:custom_fields] = custom_fields end if attributes.present? @@ -205,7 +130,7 @@ class CustomWizard::Action url += "&body=#{post}" - if category_id = action_category_id + if category_id = action_category if category = Category.find(category_id) url += "&category=#{category.full_slug('/')}" end @@ -249,35 +174,92 @@ class CustomWizard::Action def route_to url = mapper.interpolate(action['url']) + if action['code'] data[action['code']] = SecureRandom.hex(8) url += "&#{action['code']}=#{data[action['code']]}" end + data['route_to'] = URI.encode(url) end - def action_category_id - if action['custom_category_enabled'] - if action['custom_category_wizard_field'] - data[action['category_id']] - elsif action['custom_category_user_field_key'] - if action['custom_category_user_field_key'].include?('custom_fields') - field = action['custom_category_user_field_key'].split('.').last - user.custom_fields[field] - else - user.send(action['custom_category_user_field_key']) - end - end - else - action['category_id'] + private + + def action_category + output = CustomWizard::Mapper.new( + inputs: action['category'], + data: data, + user: user + ).output + + if output.is_a?(Array) + output.first + elsif output.is_a?(Integer) + output + elsif output.is_a?(String) + output.to_i end end def action_tags - if action['custom_tag_enabled'] - data[action['custom_tag_field']] - else - action['tags'] + output = CustomWizard::Mapper.new( + inputs: action['tags'], + data: data, + user: user, + ).output + + if output.is_a?(Array) + output.flatten + elsif output.is_a?(Integer) + [*output] + elsif output.is_a?(String) + [*output.to_i] end end + + def add_custom_fields(params = {}) + if (custom_fields = action['custom_fields']).present? + custom_fields.each do |field| + pair = field['pairs'].first + value = mapper.map_field(pair['key'], pair['key_type']) + key = mapper.map_field(pair['value'], pair['value_type']) + + if key && + value.present? && + (keyArr = key.split('.')).length === 2 + + if keyArr.first === 'topic' + params[:topic_opts] ||= {} + params[:topic_opts][:custom_fields] ||= {} + params[:topic_opts][:custom_fields][keyArr.last] = value + elsif keyArr.first === 'post' + params[:custom_fields] ||= {} + params[:custom_fields][keyArr.last.to_sym] = value + end + end + end + end + + params + end + + def basic_topic_params + params = { + skip_validations: true + } + + params[:title] = CustomWizard::Mapper.new( + inputs: action['title'], + data: data, + user: user + ).output + + params[:raw] = action['post_builder'] ? + mapper.interpolate(action['post_template']) : + data[action['post']] + + params = add_custom_fields(params) + + params + end end \ No newline at end of file