diff --git a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 b/assets/javascripts/discourse/components/wizard-custom-action.js.es6
index 75000d8b..4957dbc6 100644
--- a/assets/javascripts/discourse/components/wizard-custom-action.js.es6
+++ b/assets/javascripts/discourse/components/wizard-custom-action.js.es6
@@ -5,6 +5,8 @@ const ACTION_TYPES = [
{ id: 'update_profile', name: 'Update Profile' },
{ id: 'send_message', name: 'Send Message' },
{ id: 'send_to_api', name: 'Send to API' }
+ { id: 'add_to_group', name: 'Add to Group' },
+ { id: 'route_to', name: 'Route To' }
];
const PROFILE_FIELDS = [
@@ -29,33 +31,10 @@ export default Ember.Component.extend({
sendMessage: Ember.computed.equal('action.type', 'send_message'),
sendToApi: Ember.computed.equal('action.type', 'send_to_api'),
apiEmpty: Ember.computed.empty('action.api'),
+ addToGroup: Ember.computed.equal('action.type', 'add_to_group'),
+ routeTo: Ember.computed.equal('action.type', 'route_to'),
disableId: Ember.computed.not('action.isNew'),
- @computed('currentStepId', 'wizard.save_submissions')
- availableFields(currentStepId, saveSubmissions) {
- const allSteps = this.get('wizard.steps');
- let steps = allSteps;
- let fields = [];
-
- if (!saveSubmissions) {
- steps = [allSteps.findBy('id', currentStepId)];
- }
-
- steps.forEach((s) => {
- if (s.fields && s.fields.length > 0) {
- let stepFields = s.fields.map((f) => {
- return Ember.Object.create({
- id: f.id,
- label: `${f.id} (${s.id})`
- });
- });
- fields.push(...stepFields);
- }
- });
-
- return fields;
- },
-
@computed('availableFields')
builderWizardFields(fields) {
return fields.map((f) => ` w{${f.id}}`);
diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6
index bdef2d67..19cc0ba2 100644
--- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6
+++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6
@@ -15,7 +15,13 @@ export default Ember.Component.extend({
@computed()
presetChoices() {
return [
- { id: 'categories', name: I18n.t('admin.wizard.field.choices_preset.categories') }
+ {
+ id: 'categories',
+ name: I18n.t('admin.wizard.field.choices_preset.categories')
+ },{
+ id: 'groups',
+ name: I18n.t('admin.wizard.field.choices_preset.groups')
+ }
];
},
});
diff --git a/assets/javascripts/discourse/components/wizard-custom-input.js.es6 b/assets/javascripts/discourse/components/wizard-custom-input.js.es6
index 7d5a1271..21e27146 100644
--- a/assets/javascripts/discourse/components/wizard-custom-input.js.es6
+++ b/assets/javascripts/discourse/components/wizard-custom-input.js.es6
@@ -5,6 +5,7 @@ export default Ember.Component.extend({
classNames: 'custom-input',
noneKey: 'admin.wizard.select_field',
noneValue: 'admin.wizard.none',
+ connectorNone: 'admin.wizard.none',
inputKey: 'admin.wizard.key',
customDisabled: Ember.computed.alias('input.user_field'),
diff --git a/assets/javascripts/discourse/components/wizard-custom-inputs.js.es6 b/assets/javascripts/discourse/components/wizard-custom-inputs.js.es6
index 21e839f0..6dca9d65 100644
--- a/assets/javascripts/discourse/components/wizard-custom-inputs.js.es6
+++ b/assets/javascripts/discourse/components/wizard-custom-inputs.js.es6
@@ -1,4 +1,5 @@
export default Ember.Component.extend({
+ classNames: 'custom-inputs',
valuePlaceholder: 'admin.wizard.value',
actions: {
diff --git a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 b/assets/javascripts/discourse/components/wizard-custom-step.js.es6
index f0d9c48f..11dac446 100644
--- a/assets/javascripts/discourse/components/wizard-custom-step.js.es6
+++ b/assets/javascripts/discourse/components/wizard-custom-step.js.es6
@@ -1,4 +1,4 @@
-import { observes } from 'ember-addons/ember-computed-decorators';
+import { observes, default as computed } from 'ember-addons/ember-computed-decorators';
export default Ember.Component.extend({
classNames: 'wizard-custom-step',
@@ -14,5 +14,62 @@ export default Ember.Component.extend({
currentField: fields.length ? fields[0] : null,
currentAction: actions.length ? actions[0] : null
});
- }
+ },
+
+ @computed('availableFields', 'wizard.steps')
+ requiredContent(availableFields, steps) {
+ let content = availableFields;
+ let actions = [];
+
+ steps.forEach(s => {
+ actions.push(...s.actions);
+ });
+
+ actions.forEach(a => {
+ if (a.type === 'route_to' && a.code) {
+ content.push(Ember.Object.create({
+ id: a.code,
+ label: "code (Route To)"
+ }));
+ }
+ });
+
+ return content;
+ },
+
+ @computed
+ requiredConnectorContent() {
+ const label = (id) => I18n.t(`admin.wizard.step.required_data.connector.${id}`);
+ return [
+ {
+ id: 'equals',
+ label: label('equals')
+ }
+ ];
+ },
+
+ @computed('step.id', 'wizard.save_submissions')
+ availableFields(currentStepId, saveSubmissions) {
+ const allSteps = this.get('wizard.steps');
+ let steps = allSteps;
+ let fields = [];
+
+ if (!saveSubmissions) {
+ steps = [allSteps.findBy('id', currentStepId)];
+ }
+
+ steps.forEach((s) => {
+ if (s.fields && s.fields.length > 0) {
+ let stepFields = s.fields.map((f) => {
+ return Ember.Object.create({
+ id: f.id,
+ label: `${f.id} (${s.id})`
+ });
+ });
+ fields.push(...stepFields);
+ }
+ });
+
+ return fields;
+ },
});
diff --git a/assets/javascripts/discourse/models/custom-wizard.js.es6 b/assets/javascripts/discourse/models/custom-wizard.js.es6
index 6cb18535..7e8ad927 100644
--- a/assets/javascripts/discourse/models/custom-wizard.js.es6
+++ b/assets/javascripts/discourse/models/custom-wizard.js.es6
@@ -77,6 +77,8 @@ const CustomWizard = Discourse.Model.extend({
if (s.key) step['key'] = s.key;
if (s.banner) step['banner'] = s.banner;
if (s.raw_description) step['raw_description'] = s.raw_description;
+ if (s.required_data) step['required_data'] = s.required_data;
+ if (s.permitted_params) step['permitted_params'] = s.permitted_params;
const fields = s.get('fields');
if (fields.length) {
@@ -242,6 +244,8 @@ CustomWizard.reopenClass({
title: s.title,
raw_description: s.raw_description,
banner: s.banner,
+ required_data: s.required_data,
+ permitted_params: s.permitted_params,
fields,
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 95384f64..59fa22ab 100644
--- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs
+++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs
@@ -242,3 +242,44 @@
{{/if}}
+
+{{#if addToGroup}}
+
+
+
{{i18n "admin.wizard.action.add_to_group.group_selection"}}
+
+
+ {{combo-box value=action.group_id
+ content=availableFields
+ nameProperty="label"
+ none='admin.wizard.select_field'
+ isDisabled=action.custom_group_enabled}}
+
+ {{input type='checkbox' checked=action.custom_group_enabled}}
+ {{i18n 'admin.wizard.action.add_to_group.custom_group'}}
+ {{#if action.custom_group_enabled}}
+ {{input value=action.group_id}}
+ {{/if}}
+
+
+
+{{/if}}
+
+{{#if routeTo}}
+
+
+
{{i18n "admin.wizard.action.route_to.url"}}
+
+
+ {{input value=action.url}}
+
+
+
+
+
{{i18n "admin.wizard.action.route_to.code"}}
+
+
+ {{input value=action.code}}
+
+
+{{/if}}
diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs
index 048f16e3..4e368de7 100644
--- a/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs
+++ b/assets/javascripts/discourse/templates/components/wizard-custom-input.hbs
@@ -6,7 +6,18 @@
{{/if}}
-{{d-icon 'arrow-right'}}
+
+ {{#if connectorContent}}
+ {{combo-box value=input.connector
+ content=connectorContent
+ nameProperty="label"
+ none=connectorNone}}
+ {{/if}}
+
+ {{#if connectorKey}}
+ {{i18n connectorKey}}
+ {{/if}}
+
{{#if valueContent}}
diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-inputs.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-inputs.hbs
index a8cc5805..f41f3d73 100644
--- a/assets/javascripts/discourse/templates/components/wizard-custom-inputs.hbs
+++ b/assets/javascripts/discourse/templates/components/wizard-custom-inputs.hbs
@@ -2,6 +2,8 @@
{{wizard-custom-input input=input
valueContent=valueContent
keyContent=keyContent
+ connectorContent=connectorContent
+ connectorKey=connectorKey
noneValue=noneValue
valuePlaceholder=valuePlaceholder
allowCustomField=allowCustomField
diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs
index 0722cb6d..0d6eb618 100644
--- a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs
+++ b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs
@@ -43,6 +43,30 @@
+
+
+
{{i18n 'admin.wizard.step.required_data.label'}}
+
+
+ {{wizard-custom-inputs inputs=step.required_data
+ inputKey='admin.wizard.step.required_data.key'
+ valueContent=requiredContent
+ connectorContent=requiredConnectorContent}}
+
+
+
+
+
+
{{i18n 'admin.wizard.step.permitted_params.label'}}
+
+
+ {{wizard-custom-inputs inputs=step.permitted_params
+ inputKey='admin.wizard.step.permitted_params.key'
+ valuePlaceholder='admin.wizard.step.permitted_params.value'
+ connectorKey='admin.wizard.step.permitted_params.connector'}}
+
+
+
{{wizard-links type="field" current=currentField items=step.fields}}
{{#if currentField}}
{{wizard-custom-field field=currentField types=wizard.fieldTypes removeField="removeField"}}
@@ -50,7 +74,10 @@
{{wizard-links type="action" current=currentAction items=step.actions}}
{{#if currentAction}}
- {{wizard-custom-action action=currentAction wizard=wizard removeAction="removeAction" currentStepId=step.id}}
+ {{wizard-custom-action action=currentAction
+ wizard=wizard
+ removeAction="removeAction"
+ availableFields=availableFields}}
{{/if}}
diff --git a/assets/javascripts/wizard/components/custom-user-selector.js.es6 b/assets/javascripts/wizard/components/custom-user-selector.js.es6
index c553bd68..10bfba50 100644
--- a/assets/javascripts/wizard/components/custom-user-selector.js.es6
+++ b/assets/javascripts/wizard/components/custom-user-selector.js.es6
@@ -81,8 +81,7 @@ export default Ember.TextField.extend({
includeGroups,
allowedUsers,
includeMentionableGroups,
- includeMessageableGroups,
- group: self.get("group")
+ includeMessageableGroups
});
return results;
diff --git a/assets/javascripts/wizard/components/wizard-no-access.js.es6 b/assets/javascripts/wizard/components/wizard-no-access.js.es6
index 83fcc7da..0b222ec1 100644
--- a/assets/javascripts/wizard/components/wizard-no-access.js.es6
+++ b/assets/javascripts/wizard/components/wizard-no-access.js.es6
@@ -10,4 +10,4 @@ export default Ember.Component.extend({
CustomWizard.skip(this.get('wizardId'));
}
}
-})
+});
diff --git a/assets/javascripts/wizard/controllers/custom-step.js.es6 b/assets/javascripts/wizard/controllers/custom-step.js.es6
index e273ef7b..fcfe2688 100644
--- a/assets/javascripts/wizard/controllers/custom-step.js.es6
+++ b/assets/javascripts/wizard/controllers/custom-step.js.es6
@@ -5,7 +5,9 @@ export default StepController.extend({
actions: {
goNext(response) {
const next = this.get('step.next');
- if (response.refresh_required) {
+ if (response.route_to) {
+ window.location.href = response.route_to;
+ } else if (response.refresh_required) {
const id = this.get('wizard.id');
window.location.href = getUrl(`/w/${id}/steps/${next}`);
} else {
diff --git a/assets/javascripts/wizard/controllers/custom.js.es6 b/assets/javascripts/wizard/controllers/custom.js.es6
index 9e89a0b0..fc2eb947 100644
--- a/assets/javascripts/wizard/controllers/custom.js.es6
+++ b/assets/javascripts/wizard/controllers/custom.js.es6
@@ -1,3 +1,3 @@
export default Ember.Controller.extend({
queryParams: ['reset']
-})
+});
diff --git a/assets/javascripts/wizard/initializers/custom.js.es6 b/assets/javascripts/wizard/initializers/custom.js.es6
index c426514e..225f1f0f 100644
--- a/assets/javascripts/wizard/initializers/custom.js.es6
+++ b/assets/javascripts/wizard/initializers/custom.js.es6
@@ -71,6 +71,10 @@ export default {
return index === 0 && !required;
}.property('step.index', 'wizard.required'),
+ cookedTitle: function() {
+ return cook(this.get('step.title'));
+ }.property('step.title'),
+
cookedDescription: function() {
return cook(this.get('step.description'));
}.property('step.description'),
diff --git a/assets/javascripts/wizard/models/custom.js.es6 b/assets/javascripts/wizard/models/custom.js.es6
index 90bd8985..4d12b169 100644
--- a/assets/javascripts/wizard/models/custom.js.es6
+++ b/assets/javascripts/wizard/models/custom.js.es6
@@ -24,20 +24,33 @@ CustomWizard.reopenClass({
finished(result) {
let url = "/";
- if (result.redirect_to) {
- url = result.redirect_to;
+ if (result.redirect_on_complete) {
+ url = result.redirect_on_complete;
}
window.location.href = getUrl(url);
}
});
-export function findCustomWizard(wizardId, opts = {}) {
+export function findCustomWizard(wizardId, params = {}) {
let url = `/w/${wizardId}`;
- if (opts.reset) url += '?reset=true';
+
+ let paramKeys = Object.keys(params).filter(k => {
+ if (k === 'wizard_id') return false;
+ return !!params[k];
+ });
+
+ if (paramKeys.length) {
+ url += '?';
+ paramKeys.forEach((k,i) => {
+ if (i > 0) {
+ url += '&';
+ }
+ url += `${k}=${params[k]}`;
+ });
+ }
return ajax({ url, cache: false, dataType: 'json' }).then(result => {
const wizard = result.wizard;
-
if (!wizard) return null;
if (!wizard.completed) {
diff --git a/assets/javascripts/wizard/routes/custom-index.js.es6 b/assets/javascripts/wizard/routes/custom-index.js.es6
index 5e7a2914..c857753d 100644
--- a/assets/javascripts/wizard/routes/custom-index.js.es6
+++ b/assets/javascripts/wizard/routes/custom-index.js.es6
@@ -16,8 +16,13 @@ export default Ember.Route.extend({
const permitted = model.get('permitted');
const minTrust = model.get('min_trust');
const wizardId = model.get('id');
+ const user = model.get('user');
+ const name = model.get('name');
controller.setProperties({
+ requiresLogin: !user,
+ user,
+ name,
completed,
notPermitted: !permitted,
minTrust,
diff --git a/assets/javascripts/wizard/routes/custom-step.js.es6 b/assets/javascripts/wizard/routes/custom-step.js.es6
index b72f8184..ae3e2ddf 100644
--- a/assets/javascripts/wizard/routes/custom-step.js.es6
+++ b/assets/javascripts/wizard/routes/custom-step.js.es6
@@ -15,9 +15,19 @@ export default Ember.Route.extend({
return model.set("wizardId", this.modelFor('custom').id);
},
- setupController(controller, step) {
- controller.setProperties({
- step, wizard: this.modelFor('custom')
- });
+ setupController(controller, model) {
+ let props = {
+ step: model,
+ wizard: this.modelFor('custom')
+ };
+
+ if (!model.permitted) {
+ props['stepMessage'] = {
+ state: 'not-permitted',
+ text: "You're not allowed to view this step."
+ };
+ }
+
+ controller.setProperties(props);
}
});
diff --git a/assets/javascripts/wizard/routes/custom.js.es6 b/assets/javascripts/wizard/routes/custom.js.es6
index dcdfbcb7..66c53bc9 100644
--- a/assets/javascripts/wizard/routes/custom.js.es6
+++ b/assets/javascripts/wizard/routes/custom.js.es6
@@ -4,10 +4,12 @@ import { findCustomWizard } from '../models/custom';
import { ajax } from 'wizard/lib/ajax';
export default Ember.Route.extend({
+ beforeModel(transition) {
+ this.set('queryParams', transition.intent.queryParams);
+ },
+
model(params) {
- let opts = {};
- if (params.reset == 'true') opts['reset'] = true;
- return findCustomWizard(params.wizard_id, opts);
+ return findCustomWizard(params.wizard_id, this.get('queryParams'));
},
afterModel() {
diff --git a/assets/javascripts/wizard/templates/components/wizard-step.hbs b/assets/javascripts/wizard/templates/components/wizard-step.hbs
index 41cc336a..ae793060 100644
--- a/assets/javascripts/wizard/templates/components/wizard-step.hbs
+++ b/assets/javascripts/wizard/templates/components/wizard-step.hbs
@@ -1,6 +1,6 @@
{{#if step.title}}
-
{{step.title}}
+
{{cookedTitle}}
{{/if}}
{{#if step.description}}
diff --git a/assets/javascripts/wizard/templates/custom.index.hbs b/assets/javascripts/wizard/templates/custom.index.hbs
index 8c1a48ae..f6ac1df5 100644
--- a/assets/javascripts/wizard/templates/custom.index.hbs
+++ b/assets/javascripts/wizard/templates/custom.index.hbs
@@ -1,10 +1,15 @@
-{{#if completed}}
- {{wizard-no-access text=(i18n 'wizard.completed') wizardId=wizardId}}
+{{#if noWizard}}
+ {{wizard-no-access text=(i18n 'wizard.none') wizardId=wizardId}}
{{else}}
- {{#if notPermitted}}
- {{wizard-no-access text=(i18n 'wizard.not_permitted' level=minTrust) wizardId=wizardId}}
- {{/if}}
- {{#if noWizard}}
- {{wizard-no-access text=(i18n 'wizard.none') wizardId=wizardId}}
+ {{#if requiresLogin}}
+ {{wizard-no-access text=(i18n 'wizard.requires_login' name=name) wizardId=wizardId}}
+ {{else}}
+ {{#if notPermitted}}
+ {{wizard-no-access text=(i18n 'wizard.not_permitted' name=name level=minTrust) wizardId=wizardId}}
+ {{else}}
+ {{#if completed}}
+ {{wizard-no-access text=(i18n 'wizard.completed' name=name) wizardId=wizardId}}
+ {{/if}}
+ {{/if}}
{{/if}}
{{/if}}
diff --git a/assets/javascripts/wizard/templates/custom.step.hbs b/assets/javascripts/wizard/templates/custom.step.hbs
index 1264618f..b0a39637 100644
--- a/assets/javascripts/wizard/templates/custom.step.hbs
+++ b/assets/javascripts/wizard/templates/custom.step.hbs
@@ -1,9 +1,11 @@
{{stepMessage.text}}
-{{wizard-step step=step
- wizard=wizard
- goNext="goNext"
- goBack=(action "goBack")
- finished="finished"
- showMessage="showMessage"}}
+{{#if step.permitted}}
+ {{wizard-step step=step
+ wizard=wizard
+ goNext="goNext"
+ goBack=(action "goBack")
+ finished="finished"
+ showMessage="showMessage"}}
+{{/if}}
diff --git a/assets/stylesheets/wizard/wizard_composer.scss b/assets/stylesheets/wizard/wizard_composer.scss
index 14b115ce..fa8c8a62 100644
--- a/assets/stylesheets/wizard/wizard_composer.scss
+++ b/assets/stylesheets/wizard/wizard_composer.scss
@@ -157,7 +157,12 @@
////
.d-editor {
- max-height: 250px;
+ min-height: 200px;
+
+ .d-editor-input {
+ resize: vertical;
+ flex: initial;
+ }
}
.d-editor-modal.hidden {
diff --git a/assets/stylesheets/wizard/wizard_custom.scss b/assets/stylesheets/wizard/wizard_custom.scss
index 63eca692..b718bf41 100644
--- a/assets/stylesheets/wizard/wizard_custom.scss
+++ b/assets/stylesheets/wizard/wizard_custom.scss
@@ -293,6 +293,13 @@
background-color: #e45735;
color: #ffffff;
}
+
+ &.not-permitted {
+ height: 60px;
+ line-height: 60px;
+ background-color: #e45735;
+ color: #ffffff;
+ }
}
.p-list-box {
diff --git a/assets/stylesheets/wizard_custom_admin.scss b/assets/stylesheets/wizard_custom_admin.scss
index ab078fc4..0cfb4bb7 100644
--- a/assets/stylesheets/wizard_custom_admin.scss
+++ b/assets/stylesheets/wizard_custom_admin.scss
@@ -83,8 +83,13 @@
.setting-value {
width: initial;
- overflow: hidden;
float: none;
+ display: flex;
+
+ .custom-input .remove {
+ margin-left: 10px;
+ margin-top: 0;
+ }
}
}
@@ -186,13 +191,18 @@
.custom-input {
display: flex;
- margin: 5px 0;
+ align-items: center;
+ margin-bottom: 10px;
.d-icon {
margin: 0 auto;
text-align: center;
}
+ input {
+ margin: 0;
+ }
+
input[disabled] {
background-color: $primary-low;
border-color: #ddd;
@@ -206,6 +216,10 @@
margin: 0 auto;
align-self: flex-start;
}
+
+ .connector {
+ margin: 0 10px;
+ }
}
.setting .add-custom-input {
@@ -213,12 +227,12 @@
}
.admin-contents .wizard-submissions {
- padding: 0 20px;
+ width: 100%;
display: inline-block;
- overflow: scroll;
-
table {
margin-top: 0;
+ display: inline-block;
+ overflow-x: scroll;
}
}
@@ -450,3 +464,7 @@
padding: 20px;
margin-bottom: 20px;
}
+
+.wizard-step-contents{
+ height: unset !important;
+}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 86423497..7634dcc5 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -72,6 +72,16 @@ en:
banner: "Banner"
banner_placeholder: "Image url"
description: "Description"
+ required_data:
+ label: "Required Data"
+ key: 'Submission key'
+ connector:
+ equals: "Equals"
+ permitted_params:
+ label: "Permitted Params"
+ key: 'Param'
+ value: 'Submission key'
+ connector: "Save as"
field:
type: "Choose a type"
header: "Fields"
@@ -88,6 +98,7 @@ en:
choices_preset:
label: "Preset"
categories: "Categories"
+ groups: "Groups"
filter: "Preset Filter"
choice:
value: "Value"
@@ -123,6 +134,16 @@ en:
label: "Builder"
user_fields: "User Fields: "
wizard_fields: "Wizard Fields: "
+ placeholder: "Insert wizard fields using the field_id in w{}. Insert user fields using field key in u{}."
+ add_to_group:
+ label: "Add to Group"
+ group: "Group"
+ group_selection: "Group Selection"
+ custom_group: "Custom Group"
+ route_to:
+ label: "Route To"
+ url: "Url"
+ code: "Code"
custom_title: "Custom Title"
custom_category:
label: "Custom Category"
@@ -237,10 +258,11 @@ en:
filter_placeholder: "Search..."
wizard:
- completed: "You have completed this wizard."
- not_permitted: "You need to be trust level {{level}} or higher to access this wizard."
+ completed: "You have completed the {{name}} wizard."
+ not_permitted: "You need to be trust level {{level}} or higher to access the {{name}} wizard."
none: "There is no wizard here."
return_to_site: "Return to {{siteName}}"
+ requires_login: "You need to be logged in to access the {{name}} wizard."
wizard_composer:
show_preview: "Preview Post"
diff --git a/controllers/wizard.rb b/controllers/wizard.rb
index 3235209c..e2d5656f 100644
--- a/controllers/wizard.rb
+++ b/controllers/wizard.rb
@@ -2,7 +2,6 @@ class CustomWizard::WizardController < ::ApplicationController
prepend_view_path(Rails.root.join('plugins', 'discourse-custom-wizard', 'views'))
layout 'wizard'
- requires_login
helper_method :wizard_page_title
helper_method :theme_ids
@@ -22,12 +21,11 @@ class CustomWizard::WizardController < ::ApplicationController
respond_to do |format|
format.json do
builder = CustomWizard::Builder.new(current_user, params[:wizard_id].underscore)
-
builder_opts = {}
builder_opts[:reset] = params[:reset] if params[:reset]
if builder.wizard.present?
- wizard = builder.build(builder_opts)
+ wizard = builder.build(builder_opts, params)
render_serialized(wizard, WizardSerializer)
else
render json: { error: I18n.t('wizard.none') }
@@ -52,19 +50,22 @@ class CustomWizard::WizardController < ::ApplicationController
end
result = success_json
- submission = Array.wrap(PluginStore.get("#{wizard_id}_submissions", user.id)).last
- if submission && submission['redirect_to']
- result.merge!(redirect_to: submission['redirect_to'])
- end
+ if user
+ submission = Array.wrap(PluginStore.get("#{wizard_id}_submissions", user.id)).last
- if submission && !wizard.save_submissions
- PluginStore.remove("#{wizard_id}_submissions", user.id)
- end
+ if submission && submission['redirect_to']
+ result.merge!(redirect_to: submission['redirect_to'])
+ end
- if user.custom_fields['redirect_to_wizard'] === wizard_id
- user.custom_fields.delete('redirect_to_wizard')
- user.save_custom_fields(true)
+ if submission && !wizard.save_submissions
+ PluginStore.remove("#{wizard_id}_submissions", user.id)
+ end
+
+ if user.custom_fields['redirect_to_wizard'] === wizard_id
+ user.custom_fields.delete('redirect_to_wizard')
+ user.save_custom_fields(true)
+ end
end
render json: result
diff --git a/lib/builder.rb b/lib/builder.rb
index c2be9282..8533c4c3 100644
--- a/lib/builder.rb
+++ b/lib/builder.rb
@@ -2,14 +2,16 @@ class CustomWizard::Builder
attr_accessor :wizard, :updater, :submissions
- def initialize(user, wizard_id)
+ def initialize(user=nil, wizard_id)
data = PluginStore.get('custom_wizard', wizard_id)
-
return if data.blank?
@steps = data['steps']
@wizard = CustomWizard::Wizard.new(user, data)
- @submissions = Array.wrap(PluginStore.get("#{wizard_id}_submissions", user.id))
+
+ if user
+ @submissions = Array.wrap(PluginStore.get("#{wizard_id}_submissions", user.id))
+ end
end
def self.sorted_handlers
@@ -49,10 +51,10 @@ class CustomWizard::Builder
result
end
- result.gsub(/w\{(.*?)\}/) { |match| data[$1.to_sym] }
+ result = result.gsub(/w\{(.*?)\}/) { |match| data[$1.to_sym] }
end
- def build(build_opts = {})
+ def build(build_opts = {}, params = {})
unless (@wizard.completed? && !@wizard.multiple_submissions && !@wizard.user.admin) || !@steps || !@wizard.permitted?
reset_submissions if build_opts[:reset]
@@ -63,6 +65,36 @@ class CustomWizard::Builder
step.description = step_template['description'] if step_template['description']
step.banner = step_template['banner'] if step_template['banner']
step.key = step_template['key'] if step_template['key']
+ step.permitted = true
+
+ if permitted_params = step_template['permitted_params']
+ permitted_data = {}
+
+ permitted_params.each do |param|
+ key = param['key'].to_sym
+ permitted_data[key] = params[key] if params[key]
+ end
+
+ if permitted_data.present?
+ current_data = @submissions.last || {}
+ save_submissions(current_data.merge(permitted_data), false)
+ end
+ end
+
+ if required_data = step_template['required_data']
+ if !@submissions.last && required_data.length
+ step.permitted = false
+ next
+ end
+
+ required_data.each do |rd|
+ if rd['connector'] === 'equals'
+ step.permitted = @submissions.last[rd['key']] == @submissions.last[rd['value']]
+ end
+ end
+
+ next if !step.permitted
+ end
if step_template['fields'] && step_template['fields'].length
step_template['fields'].each do |field_template|
@@ -118,8 +150,13 @@ class CustomWizard::Builder
end
if updater.errors.empty?
- redirect_to = data['redirect_to']
- updater.result = { redirect_to: redirect_to } if redirect_to
+ if route_to = data['route_to']
+ updater.result[:route_to] = route_to
+ end
+
+ if redirect_on_complete = data['redirect_on_complete']
+ updater.result[:redirect_on_complete] = redirect_on_complete
+ end
end
end
end
@@ -200,9 +237,14 @@ class CustomWizard::Builder
end
elsif field_template['choices_preset'] && field_template['choices_preset'].length > 0
objects = []
+ site = Site.new(Guardian.new(@wizard.user))
if field_template['choices_preset'] === 'categories'
- objects = Site.new(Guardian.new(@wizard.user)).categories
+ objects = site.categories
+ end
+
+ if field_template['choices_preset'] === 'groups'
+ objects = site.groups
end
if field_template['choices_filters'] && field_template['choices_filters'].length > 0
@@ -227,7 +269,11 @@ class CustomWizard::Builder
def validate_field(field, updater, step_template)
value = updater.fields[field['id']]
- min_length = field['min_length']
+ min_length = false
+
+ if is_text_type(field)
+ min_length = field['min_length']
+ end
if min_length && value.is_a?(String) && value.strip.length < min_length.to_i
label = field['label'] || I18n.t("#{field['key']}.label")
@@ -246,6 +292,10 @@ class CustomWizard::Builder
end
end
+ def is_text_type(field)
+ ['text', 'textarea'].include? field['type']
+ end
+
def standardise_boolean(value)
!!HasCustomFields::Helpers::CUSTOM_FIELD_TRUE.include?(value)
end
@@ -309,6 +359,7 @@ class CustomWizard::Builder
end
end
else
+ value = [value] if key === 'tags'
params[key.to_sym] = value
end
end
@@ -329,7 +380,7 @@ class CustomWizard::Builder
end
unless action['skip_redirect']
- data['redirect_to'] = post.topic.url
+ data['redirect_on_complete'] = post.topic.url
end
end
end
@@ -358,7 +409,7 @@ class CustomWizard::Builder
updater.errors.add(:send_message, creator.errors.full_messages.join(" "))
else
unless action['skip_redirect']
- data['redirect_to'] = post.topic.url
+ data['redirect_on_complete'] = post.topic.url
end
end
end
@@ -394,7 +445,6 @@ class CustomWizard::Builder
end
def send_to_api(user, action, data)
-
api_body = nil
if action['api_body'] != ""
@@ -415,6 +465,23 @@ class CustomWizard::Builder
## add validation callback
end
end
+
+ def add_to_group(user, action, data)
+ if group_id = data[action['group_id']]
+ if group = Group.find(group_id)
+ group.add(user)
+ end
+ end
+ end
+
+ def route_to(user, action, data)
+ url = CustomWizard::Builder.fill_placeholders(action['url'], user, data)
+ if action['code']
+ data[action['code']] = SecureRandom.hex(8)
+ url += "{action['code']}=#{data[action['code']]}"
+ end
+ data['route_to'] = URI.encode(url)
+ end
def save_submissions(data, final_step)
if final_step
diff --git a/lib/step_updater.rb b/lib/step_updater.rb
index f267db9d..c521924c 100644
--- a/lib/step_updater.rb
+++ b/lib/step_updater.rb
@@ -9,6 +9,7 @@ class CustomWizard::StepUpdater
@step = step
@refresh_required = false
@fields = fields
+ @result = {}
end
def update
diff --git a/lib/wizard.rb b/lib/wizard.rb
index e98b933a..b47d68f1 100644
--- a/lib/wizard.rb
+++ b/lib/wizard.rb
@@ -18,7 +18,7 @@ class CustomWizard::Wizard
:required,
:prompt_completion
- def initialize(user, attrs = {})
+ def initialize(user=nil, attrs = {})
@steps = []
@user = user
@first_step = nil
@@ -54,6 +54,8 @@ class CustomWizard::Wizard
end
def start
+ return nil if !@user
+
if unfinished? && last_completed_step = ::UserHistory.where(
acting_user_id: @user.id,
action: ::UserHistory.actions[:custom_wizard_step],
@@ -76,6 +78,8 @@ class CustomWizard::Wizard
end
def unfinished?
+ return nil if !@user
+
most_recent = ::UserHistory.where(
acting_user_id: @user.id,
action: ::UserHistory.actions[:custom_wizard_step],
@@ -94,6 +98,8 @@ class CustomWizard::Wizard
end
def completed?
+ return nil if !@user
+
steps = CustomWizard::Wizard.step_ids(@id)
history = ::UserHistory.where(
@@ -112,7 +118,7 @@ class CustomWizard::Wizard
end
def permitted?
- user.staff? || user.trust_level.to_i >= min_trust.to_i
+ user && (user.staff? || user.trust_level.to_i >= min_trust.to_i)
end
def reset
diff --git a/lib/wizard_edits.rb b/lib/wizard_edits.rb
index 4a24afd3..dfab138a 100644
--- a/lib/wizard_edits.rb
+++ b/lib/wizard_edits.rb
@@ -60,11 +60,11 @@ end
end
class ::Wizard::Step
- attr_accessor :title, :description, :key
+ attr_accessor :title, :description, :key, :permitted
end
::WizardSerializer.class_eval do
- attributes :id, :background, :completed, :required, :min_trust, :permitted
+ attributes :id, :name, :background, :completed, :required, :min_trust, :permitted, :user
def id
object.id
@@ -74,6 +74,10 @@ end
object.respond_to?(:id)
end
+ def name
+ object.name
+ end
+
def background
object.background
end
@@ -123,18 +127,28 @@ end
def include_required?
object.respond_to?(:required)
end
+
+ def user
+ object.user
+ end
end
::WizardStepSerializer.class_eval do
+ attributes :permitted
+
def title
- return object.title if object.title
- I18n.t("#{object.key || i18n_key}.title", default: '')
+ return PrettyText.cook(object.title) if object.title
+ PrettyText.cook(I18n.t("#{object.key || i18n_key}.title", default: ''))
end
def description
return object.description if object.description
PrettyText.cook(I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url))
end
+
+ def permitted
+ object.permitted
+ end
end
::WizardFieldSerializer.class_eval do