Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-22 09:20:29 +01:00
various
Dieser Commit ist enthalten in:
Ursprung
515f0b3393
Commit
2046648862
18 geänderte Dateien mit 580 neuen und 446 gelöschten Zeilen
|
@ -1,7 +1,5 @@
|
||||||
import {
|
import { default as discourseComputed, observes } from 'discourse-common/utils/decorators';
|
||||||
default as computed,
|
import { equal, not, empty } from "@ember/object/computed";
|
||||||
observes
|
|
||||||
} from 'discourse-common/utils/decorators';
|
|
||||||
import {
|
import {
|
||||||
actionTypes,
|
actionTypes,
|
||||||
generateName,
|
generateName,
|
||||||
|
@ -12,37 +10,37 @@ import {
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: 'wizard-custom-action',
|
classNames: 'wizard-custom-action',
|
||||||
types: actionTypes.map(t => ({ id: t, name: generateName(t) })),
|
types: actionTypes.map(t => ({ id: t, name: generateName(t) })),
|
||||||
createTopic: Ember.computed.equal('action.type', 'create_topic'),
|
createTopic: equal('action.type', 'create_topic'),
|
||||||
updateProfile: Ember.computed.equal('action.type', 'update_profile'),
|
updateProfile: equal('action.type', 'update_profile'),
|
||||||
sendMessage: Ember.computed.equal('action.type', 'send_message'),
|
sendMessage: equal('action.type', 'send_message'),
|
||||||
sendToApi: Ember.computed.equal('action.type', 'send_to_api'),
|
sendToApi: equal('action.type', 'send_to_api'),
|
||||||
apiEmpty: Ember.computed.empty('action.api'),
|
apiEmpty: empty('action.api'),
|
||||||
addToGroup: Ember.computed.equal('action.type', 'add_to_group'),
|
addToGroup: equal('action.type', 'add_to_group'),
|
||||||
routeTo: Ember.computed.equal('action.type', 'route_to'),
|
routeTo: equal('action.type', 'route_to'),
|
||||||
disableId: Ember.computed.not('action.isNew'),
|
disableId: not('action.isNew'),
|
||||||
groupPropertyTypes: generateSelectKitContent(['id', 'name']),
|
groupPropertyTypes: generateSelectKitContent(['id', 'name']),
|
||||||
|
|
||||||
@computed('action.type')
|
@discourseComputed('action.type')
|
||||||
basicTopicFields(actionType) {
|
basicTopicFields(actionType) {
|
||||||
return ['create_topic', 'send_message', 'open_composer'].indexOf(actionType) > -1;
|
return ['create_topic', 'send_message', 'open_composer'].indexOf(actionType) > -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('action.type')
|
@discourseComputed('action.type')
|
||||||
publicTopicFields(actionType) {
|
publicTopicFields(actionType) {
|
||||||
return ['create_topic', 'open_composer'].indexOf(actionType) > -1;
|
return ['create_topic', 'open_composer'].indexOf(actionType) > -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('action.type')
|
@discourseComputed('action.type')
|
||||||
newTopicFields(actionType) {
|
newTopicFields(actionType) {
|
||||||
return ['create_topic', 'send_message'].indexOf(actionType) > -1;
|
return ['create_topic', 'send_message'].indexOf(actionType) > -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('wizardFields')
|
@discourseComputed('wizardFields')
|
||||||
categoryFields(fields) {
|
categoryFields(fields) {
|
||||||
return fields.filter(f => f.type == 'category');
|
return fields.filter(f => f.type == 'category');
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('wizardFields')
|
@discourseComputed('wizardFields')
|
||||||
tagFields(fields) {
|
tagFields(fields) {
|
||||||
return fields.filter(f => f.type == 'tag');
|
return fields.filter(f => f.type == 'tag');
|
||||||
},
|
},
|
||||||
|
@ -59,7 +57,7 @@ export default Ember.Component.extend({
|
||||||
this.set('action.custom_category_wizard_field', false);
|
this.set('action.custom_category_wizard_field', false);
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('wizard.apis')
|
@discourseComputed('wizard.apis')
|
||||||
availableApis(apis) {
|
availableApis(apis) {
|
||||||
return apis.map(a => {
|
return apis.map(a => {
|
||||||
return {
|
return {
|
||||||
|
@ -69,7 +67,7 @@ export default Ember.Component.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('wizard.apis', 'action.api')
|
@discourseComputed('wizard.apis', 'action.api')
|
||||||
availableEndpoints(apis, api) {
|
availableEndpoints(apis, api) {
|
||||||
if (!api) return [];
|
if (!api) return [];
|
||||||
return apis.find(a => a.name === api).endpoints;
|
return apis.find(a => a.name === api).endpoints;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { default as computed, observes, on } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
|
||||||
import { equal, not, or } from "@ember/object/computed";
|
import { equal, not, or } from "@ember/object/computed";
|
||||||
import { generateSelectKitContent } from '../lib/custom-wizard';
|
import { generateSelectKitContent } from '../lib/custom-wizard';
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ export default Ember.Component.extend({
|
||||||
prefillEnabled: or('isCategory', 'isTag', 'isGroup'),
|
prefillEnabled: or('isCategory', 'isTag', 'isGroup'),
|
||||||
contentEnabled: or('isCategory', 'isTag', 'isGroup'),
|
contentEnabled: or('isCategory', 'isTag', 'isGroup'),
|
||||||
|
|
||||||
@computed('field.type')
|
@discourseComputed('field.type')
|
||||||
isInput: (type) => type === 'text' || type === 'textarea' || type === 'url',
|
isInput: (type) => type === 'text' || type === 'textarea' || type === 'url',
|
||||||
|
|
||||||
@computed('field.type')
|
@discourseComputed('field.type')
|
||||||
isCategoryOrTag: (type) => type === 'tag' || type === 'category',
|
isCategoryOrTag: (type) => type === 'tag' || type === 'category',
|
||||||
|
|
||||||
@on('didInsertElement')
|
@on('didInsertElement')
|
||||||
|
@ -31,7 +31,7 @@ export default Ember.Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('field.type')
|
@discourseComputed('field.type')
|
||||||
prefillOptions(fieldType) {
|
prefillOptions(fieldType) {
|
||||||
if (!this.prefillEnabled) return {};
|
if (!this.prefillEnabled) return {};
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ export default Ember.Component.extend({
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('field.type')
|
@discourseComputed('field.type')
|
||||||
contentOptions(fieldType) {
|
contentOptions(fieldType) {
|
||||||
if (!this.contentEnabled) return {};
|
if (!this.contentEnabled) return {};
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,25 @@
|
||||||
import {
|
import { observes, on, default as discourseComputed } from 'discourse-common/utils/decorators';
|
||||||
observes,
|
import { not } from "@ember/object/computed";
|
||||||
on,
|
|
||||||
default as computed
|
|
||||||
} from 'discourse-common/utils/decorators';
|
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: 'wizard-custom-step',
|
classNames: 'wizard-custom-step',
|
||||||
currentField: null,
|
currentField: null,
|
||||||
currentAction: null,
|
currentAction: null,
|
||||||
disableId: Ember.computed.not('step.isNew'),
|
disableId: not('step.isNew'),
|
||||||
|
|
||||||
@on('didInsertElement')
|
@on('didInsertElement')
|
||||||
@observes('step')
|
@observes('step')
|
||||||
resetCurrentObjects() {
|
resetCurrentObjects() {
|
||||||
const fields = this.get('step.fields');
|
const fields = this.step.fields;
|
||||||
const actions = this.get('step.actions');
|
const actions = this.step.actions;
|
||||||
|
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
currentField: fields.length ? fields[0] : null,
|
currentField: fields.length ? fields[0] : null,
|
||||||
currentAction: actions.length ? actions[0] : null
|
currentAction: actions.length ? actions[0] : null
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('wizardFields', 'wizard.steps')
|
@discourseComputed('wizardFields', 'wizard.steps')
|
||||||
requiredContent(wizardFields, steps) {
|
requiredContent(wizardFields, steps) {
|
||||||
let content = wizardFields;
|
let content = wizardFields;
|
||||||
let actions = [];
|
let actions = [];
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import { computed, set } from "@ember/object";
|
import { computed, set } from "@ember/object";
|
||||||
import { alias, equal } from "@ember/object/computed";
|
import { alias, equal } from "@ember/object/computed";
|
||||||
import {
|
import { newPair, connectorContent, inputTypesContent } from '../lib/mapper';
|
||||||
newPair,
|
|
||||||
connectorContent,
|
|
||||||
inputTypesContent
|
|
||||||
} from '../lib/custom-wizard';
|
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNameBindings: [':mapper-input', 'type'],
|
classNameBindings: [':mapper-input', 'type'],
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { connectorContent } from '../lib/custom-wizard';
|
import { connectorContent } from '../lib/mapper';
|
||||||
import { gt, or, alias } from "@ember/object/computed";
|
import { gt, or, alias } from "@ember/object/computed";
|
||||||
import { computed, observes } from "@ember/object";
|
import { computed, observes } from "@ember/object";
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import { alias } from "@ember/object/computed";
|
import { alias } from "@ember/object/computed";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import {
|
import { default as discourseComputed, observes } from "discourse-common/utils/decorators";
|
||||||
default as discourseComputed,
|
|
||||||
observes,
|
|
||||||
} from "discourse-common/utils/decorators";
|
|
||||||
import { defaultSelectionType } from '../lib/custom-wizard';
|
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||||
|
import { defaultSelectionType } from '../lib/mapper';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: 'mapper-selector',
|
classNames: 'mapper-selector',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||||
import { on } from 'discourse-common/utils/decorators';
|
import { on } from 'discourse-common/utils/decorators';
|
||||||
import { newInput } from '../lib/custom-wizard';
|
import { newInput } from '../lib/mapper';
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
|
|
@ -27,6 +27,77 @@ const profileFields = [
|
||||||
'trust_level'
|
'trust_level'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const wizardProperties = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'background',
|
||||||
|
'save_submissions',
|
||||||
|
'multiple_submissions',
|
||||||
|
'after_signup',
|
||||||
|
'after_time',
|
||||||
|
'after_time_scheduled',
|
||||||
|
'required',
|
||||||
|
'prompt_completion',
|
||||||
|
'restart_on_revisit',
|
||||||
|
'theme_id',
|
||||||
|
'permitted'
|
||||||
|
];
|
||||||
|
|
||||||
|
const stepProperties = [
|
||||||
|
'id',
|
||||||
|
'title',
|
||||||
|
'key',
|
||||||
|
'banner',
|
||||||
|
'raw_description',
|
||||||
|
'required_data',
|
||||||
|
'required_data_message',
|
||||||
|
'permitted_params'
|
||||||
|
]
|
||||||
|
|
||||||
|
const fieldProperties = [
|
||||||
|
'id',
|
||||||
|
'label',
|
||||||
|
'key',
|
||||||
|
'image',
|
||||||
|
'description',
|
||||||
|
'type',
|
||||||
|
'required',
|
||||||
|
'min_length',
|
||||||
|
'file_types',
|
||||||
|
'property',
|
||||||
|
'limit',
|
||||||
|
'prefill',
|
||||||
|
'content',
|
||||||
|
]
|
||||||
|
|
||||||
|
const actionProperties = [
|
||||||
|
'id',
|
||||||
|
'type',
|
||||||
|
'title',
|
||||||
|
'post',
|
||||||
|
'post_template',
|
||||||
|
'category',
|
||||||
|
'tags',
|
||||||
|
'skip_redirect',
|
||||||
|
'custom_fields',
|
||||||
|
'required',
|
||||||
|
'recipient',
|
||||||
|
'profile_updates',
|
||||||
|
'group',
|
||||||
|
'url',
|
||||||
|
'code',
|
||||||
|
'api',
|
||||||
|
'api_endpoint',
|
||||||
|
'api_body'
|
||||||
|
]
|
||||||
|
|
||||||
|
const properties = {
|
||||||
|
wizard: wizardProperties,
|
||||||
|
step: stepProperties,
|
||||||
|
field: fieldProperties,
|
||||||
|
action: actionProperties
|
||||||
|
}
|
||||||
|
|
||||||
const actionTypes = [
|
const actionTypes = [
|
||||||
'create_topic',
|
'create_topic',
|
||||||
'update_profile',
|
'update_profile',
|
||||||
|
@ -39,158 +110,12 @@ const actionTypes = [
|
||||||
'open_composer'
|
'open_composer'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Inputs
|
|
||||||
|
|
||||||
const selectableInputTypes = [
|
|
||||||
'conditional',
|
|
||||||
'assignment'
|
|
||||||
]
|
|
||||||
|
|
||||||
function defaultInputType(options = {}) {
|
|
||||||
if (!options.hasOutput) return 'pair';
|
|
||||||
if (!options.inputTypes) return selectableInputTypes[0];
|
|
||||||
return options.inputTypes.split(',')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapInputTypes(types) {
|
|
||||||
return types.map(function(type) {
|
|
||||||
return {
|
|
||||||
id: type,
|
|
||||||
name: I18n.t(`admin.wizard.input.${type}.name`)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function inputTypesContent(options = {}) {
|
|
||||||
return options.inputTypes ?
|
|
||||||
mapInputTypes(options.inputTypes.split(',')) :
|
|
||||||
mapInputTypes(selectableInputTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connectors
|
|
||||||
|
|
||||||
const connectors = {
|
|
||||||
output: [
|
|
||||||
'then',
|
|
||||||
'set',
|
|
||||||
],
|
|
||||||
pair: [
|
|
||||||
'equal',
|
|
||||||
'greater',
|
|
||||||
'less',
|
|
||||||
'greater_or_equal',
|
|
||||||
'less_or_equal'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
|
|
||||||
function connectorContent(connectorType, inputType, opts) {
|
|
||||||
let connector = opts[`${connectorType}Connector`] || defaultConnector(connectorType, inputType, opts);
|
|
||||||
if (connector) return [connectorItem(connector)];
|
|
||||||
|
|
||||||
return connectors[connectorType].map(function(connector) {
|
|
||||||
return connectorItem(connector);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
const selectionTypes = [
|
|
||||||
'text',
|
|
||||||
'wizard',
|
|
||||||
'user',
|
|
||||||
'group',
|
|
||||||
'category',
|
|
||||||
'tag'
|
|
||||||
]
|
|
||||||
|
|
||||||
function defaultSelectionType(inputType, options = {}) {
|
|
||||||
if (options[`${inputType}DefaultSelection`]) {
|
|
||||||
return options[`${inputType}DefaultSelection`];
|
|
||||||
}
|
|
||||||
|
|
||||||
let type = selectionTypes[0];
|
|
||||||
|
|
||||||
for (let t of selectionTypes) {
|
|
||||||
let inputTypes = options[`${t}Selection`];
|
|
||||||
|
|
||||||
if (inputTypes === true ||
|
|
||||||
((typeof inputTypes === 'string') &&
|
|
||||||
inputTypes.split(',').indexOf(inputType) > -1)) {
|
|
||||||
type = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// items
|
|
||||||
|
|
||||||
function newPair(inputType, options = {}) {
|
|
||||||
let params = {
|
|
||||||
index: options.index,
|
|
||||||
pairCount: options.pairCount,
|
|
||||||
key: '',
|
|
||||||
key_type: defaultSelectionType('key', options),
|
|
||||||
value: '',
|
|
||||||
value_type: defaultSelectionType('value', options),
|
|
||||||
connector: defaultConnector('pair', inputType, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ember.Object.create(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
function newInput(options = {}) {
|
|
||||||
const inputType = defaultInputType(options);
|
|
||||||
|
|
||||||
let params = {
|
|
||||||
type: inputType,
|
|
||||||
pairs: Ember.A(
|
|
||||||
[
|
|
||||||
newPair(
|
|
||||||
inputType,
|
|
||||||
Object.assign({},
|
|
||||||
options,
|
|
||||||
{ index: 0, pairCount: 1 }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.hasOutput) {
|
|
||||||
params['output_type'] = defaultSelectionType('output', options);
|
|
||||||
params['connector'] = defaultConnector('output', inputType, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ember.Object.create(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
generateSelectKitContent,
|
generateSelectKitContent,
|
||||||
profileFields,
|
|
||||||
actionTypes,
|
|
||||||
generateName,
|
generateName,
|
||||||
defaultInputType,
|
generateId,
|
||||||
defaultSelectionType,
|
properties,
|
||||||
connectorContent,
|
wizardProperties,
|
||||||
inputTypesContent,
|
profileFields,
|
||||||
newInput,
|
actionTypes
|
||||||
newPair,
|
|
||||||
generateId
|
|
||||||
};
|
};
|
241
assets/javascripts/discourse/lib/json.js.es6
Normale Datei
241
assets/javascripts/discourse/lib/json.js.es6
Normale Datei
|
@ -0,0 +1,241 @@
|
||||||
|
import { properties } from '../lib/custom-wizard';
|
||||||
|
import { mappedProperties } from '../lib/mapper';
|
||||||
|
import { EmberObject } from '@ember/object';
|
||||||
|
|
||||||
|
function present(val) {
|
||||||
|
return val && val.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapped(property, type) {
|
||||||
|
return mappedProperties[type] &&
|
||||||
|
mappedProperties[type].indexOf(property) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildJson(object, type) {
|
||||||
|
let result = {};
|
||||||
|
|
||||||
|
properties[type].forEach((p) => {
|
||||||
|
let value = object.get(p);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
result[p] = mapped(p, type) ? buildMappedJson(value) : value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
function buildMappedJson(inputs) {
|
||||||
|
if (!inputs || !inputs.length) return false;
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
inputs.forEach(inpt => {
|
||||||
|
let input = {
|
||||||
|
type: inpt.type,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (present(inpt.output)) {
|
||||||
|
input.output = inpt.output;
|
||||||
|
input.output_type = inpt.output_type;
|
||||||
|
input.connector = inpt.connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (present(inpt.pairs)) {
|
||||||
|
input.pairs = [];
|
||||||
|
|
||||||
|
inpt.pairs.forEach(pr => {
|
||||||
|
if (present(pr.key) && present(pr.value)) {
|
||||||
|
|
||||||
|
let pairParams = {
|
||||||
|
index: pr.index,
|
||||||
|
key: pr.key,
|
||||||
|
key_type: pr.key_type,
|
||||||
|
value: pr.value,
|
||||||
|
value_type: pr.value_type,
|
||||||
|
connector: pr.connector
|
||||||
|
}
|
||||||
|
|
||||||
|
input.pairs.push(pairParams);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input.type === 'assignment' && present(input.output)) ||
|
||||||
|
(input.type === 'conditional' && present(input.pairs)) ||
|
||||||
|
(input.type === 'pair' && present(input.pairs))) {
|
||||||
|
|
||||||
|
result.push(input);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.length) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildStepJson(object) {
|
||||||
|
let steps = [];
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
object.some((s) => {
|
||||||
|
let step = buildJson(s, 'step');
|
||||||
|
let fields = s.fields;
|
||||||
|
|
||||||
|
if (fields.length) {
|
||||||
|
step.fields = [];
|
||||||
|
|
||||||
|
fields.some((f) => {
|
||||||
|
if (!f.type) {
|
||||||
|
error = 'type_required';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
step.fields.push(
|
||||||
|
buildJson(f, 'field')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let actions = s.actions;
|
||||||
|
|
||||||
|
if (actions.length) {
|
||||||
|
step.actions = [];
|
||||||
|
|
||||||
|
actions.some((a) => {
|
||||||
|
if (a.api_body) {
|
||||||
|
try {
|
||||||
|
JSON.parse(a.api_body);
|
||||||
|
} catch (e) {
|
||||||
|
error = 'invalid_api_body';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step.actions.push(
|
||||||
|
buildJson(a, 'action')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
steps.push(step);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return { error };
|
||||||
|
} else {
|
||||||
|
return { steps };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildObject(json, type) {
|
||||||
|
let params = {
|
||||||
|
isNew: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(json).forEach(prop => {
|
||||||
|
if (mapped(prop, type)) {
|
||||||
|
let inputs = [];
|
||||||
|
|
||||||
|
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;
|
||||||
|
pairs.push(EmberObject.create(pair));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
input[inputKey] = inputJson[inputKey];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
inputs.push(EmberObject.create(input));
|
||||||
|
});
|
||||||
|
|
||||||
|
params[prop] = Ember.A(inputs);
|
||||||
|
} else {
|
||||||
|
params[prop] = json[prop];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
EmberObject.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildWizardProperties(json) {
|
||||||
|
let steps = Ember.A();
|
||||||
|
let props = {
|
||||||
|
steps
|
||||||
|
};
|
||||||
|
|
||||||
|
if (present(json)) {
|
||||||
|
props.id = json.id;
|
||||||
|
props.existingId = true;
|
||||||
|
|
||||||
|
properties.wizard.forEach((p) => {
|
||||||
|
props[p] = json[p];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (present(json.steps)) {
|
||||||
|
json.steps.forEach((s) => {
|
||||||
|
let fields = Ember.A();
|
||||||
|
|
||||||
|
if (present(s.fields)) {
|
||||||
|
s.fields.forEach((f) => {
|
||||||
|
fields.pushObject(buildObject(f, 'field'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let actions = Ember.A();
|
||||||
|
if (s.actions && s.actions.length) {
|
||||||
|
s.actions.forEach((a) => {
|
||||||
|
const actionParams = { isNew: false };
|
||||||
|
const action = EmberObject.create($.extend(a, actionParams));
|
||||||
|
actions.pushObject(action);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
steps.pushObject(EmberObject.create({
|
||||||
|
id: s.id,
|
||||||
|
key: s.key,
|
||||||
|
title: s.title,
|
||||||
|
raw_description: s.raw_description,
|
||||||
|
banner: s.banner,
|
||||||
|
required_data: s.required_data,
|
||||||
|
required_data_message: s.required_data_message,
|
||||||
|
permitted_params: s.permitted_params,
|
||||||
|
fields,
|
||||||
|
actions,
|
||||||
|
isNew: false
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
props['id'] = '';
|
||||||
|
props['name'] = '';
|
||||||
|
props['background'] = '';
|
||||||
|
props['save_submissions'] = true;
|
||||||
|
props['multiple_submissions'] = false;
|
||||||
|
props['after_signup'] = false;
|
||||||
|
props['after_time'] = false;
|
||||||
|
props['required'] = false;
|
||||||
|
props['prompt_completion'] = false;
|
||||||
|
props['restart_on_revisit'] = false;
|
||||||
|
props['permitted'] = null;
|
||||||
|
props['steps'] = Ember.A();
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
174
assets/javascripts/discourse/lib/mapper.js.es6
Normale Datei
174
assets/javascripts/discourse/lib/mapper.js.es6
Normale Datei
|
@ -0,0 +1,174 @@
|
||||||
|
const mappedProperties = {
|
||||||
|
wizard: [
|
||||||
|
'permitted'
|
||||||
|
],
|
||||||
|
step: [
|
||||||
|
'required_data',
|
||||||
|
'permitted_params'
|
||||||
|
],
|
||||||
|
field: [
|
||||||
|
'choices',
|
||||||
|
'prefill',
|
||||||
|
'content'
|
||||||
|
],
|
||||||
|
action: [
|
||||||
|
'title',
|
||||||
|
'category',
|
||||||
|
'tags',
|
||||||
|
'custom_fields',
|
||||||
|
'required',
|
||||||
|
'recipient',
|
||||||
|
'profile_updates',
|
||||||
|
'group'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
|
||||||
|
const selectableInputTypes = [
|
||||||
|
'conditional',
|
||||||
|
'assignment'
|
||||||
|
]
|
||||||
|
|
||||||
|
function defaultInputType(options = {}) {
|
||||||
|
if (!options.hasOutput) return 'pair';
|
||||||
|
if (!options.inputTypes) return selectableInputTypes[0];
|
||||||
|
return options.inputTypes.split(',')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapInputTypes(types) {
|
||||||
|
return types.map(function(type) {
|
||||||
|
return {
|
||||||
|
id: type,
|
||||||
|
name: I18n.t(`admin.wizard.input.${type}.name`)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputTypesContent(options = {}) {
|
||||||
|
return options.inputTypes ?
|
||||||
|
mapInputTypes(options.inputTypes.split(',')) :
|
||||||
|
mapInputTypes(selectableInputTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connectors
|
||||||
|
|
||||||
|
const connectors = {
|
||||||
|
output: [
|
||||||
|
'then',
|
||||||
|
'set',
|
||||||
|
],
|
||||||
|
pair: [
|
||||||
|
'equal',
|
||||||
|
'greater',
|
||||||
|
'less',
|
||||||
|
'greater_or_equal',
|
||||||
|
'less_or_equal'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectorContent(connectorType, inputType, opts) {
|
||||||
|
let connector = opts[`${connectorType}Connector`] || defaultConnector(connectorType, inputType, opts);
|
||||||
|
if (connector) return [connectorItem(connector)];
|
||||||
|
|
||||||
|
return connectors[connectorType].map(function(connector) {
|
||||||
|
return connectorItem(connector);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
const selectionTypes = [
|
||||||
|
'text',
|
||||||
|
'wizard',
|
||||||
|
'user',
|
||||||
|
'group',
|
||||||
|
'category',
|
||||||
|
'tag'
|
||||||
|
]
|
||||||
|
|
||||||
|
function defaultSelectionType(inputType, options = {}) {
|
||||||
|
if (options[`${inputType}DefaultSelection`]) {
|
||||||
|
return options[`${inputType}DefaultSelection`];
|
||||||
|
}
|
||||||
|
|
||||||
|
let type = selectionTypes[0];
|
||||||
|
|
||||||
|
for (let t of selectionTypes) {
|
||||||
|
let inputTypes = options[`${t}Selection`];
|
||||||
|
|
||||||
|
if (inputTypes === true ||
|
||||||
|
((typeof inputTypes === 'string') &&
|
||||||
|
inputTypes.split(',').indexOf(inputType) > -1)) {
|
||||||
|
type = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// items
|
||||||
|
|
||||||
|
function newPair(inputType, options = {}) {
|
||||||
|
let params = {
|
||||||
|
index: options.index,
|
||||||
|
pairCount: options.pairCount,
|
||||||
|
key: '',
|
||||||
|
key_type: defaultSelectionType('key', options),
|
||||||
|
value: '',
|
||||||
|
value_type: defaultSelectionType('value', options),
|
||||||
|
connector: defaultConnector('pair', inputType, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ember.Object.create(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function newInput(options = {}) {
|
||||||
|
const inputType = defaultInputType(options);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
type: inputType,
|
||||||
|
pairs: Ember.A(
|
||||||
|
[
|
||||||
|
newPair(
|
||||||
|
inputType,
|
||||||
|
Object.assign({},
|
||||||
|
options,
|
||||||
|
{ index: 0, pairCount: 1 }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.hasOutput) {
|
||||||
|
params['output_type'] = defaultSelectionType('output', options);
|
||||||
|
params['connector'] = defaultConnector('output', inputType, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ember.Object.create(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
mappedProperties,
|
||||||
|
defaultInputType,
|
||||||
|
defaultSelectionType,
|
||||||
|
connectorContent,
|
||||||
|
inputTypesContent,
|
||||||
|
newInput,
|
||||||
|
newPair,
|
||||||
|
}
|
|
@ -1,57 +1,38 @@
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
import { buildStepJson, buildJson, buildWizardProperties } from '../lib/json';
|
||||||
const wizardProperties = [
|
|
||||||
'name',
|
|
||||||
'background',
|
|
||||||
'save_submissions',
|
|
||||||
'multiple_submissions',
|
|
||||||
'after_signup',
|
|
||||||
'after_time',
|
|
||||||
'after_time_scheduled',
|
|
||||||
'required',
|
|
||||||
'prompt_completion',
|
|
||||||
'restart_on_revisit',
|
|
||||||
'theme_id',
|
|
||||||
'permitted'
|
|
||||||
];
|
|
||||||
|
|
||||||
const CustomWizard = EmberObject.extend({
|
const CustomWizard = EmberObject.extend({
|
||||||
save() {
|
save() {
|
||||||
return new Ember.RSVP.Promise((resolve, reject) => {
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
|
||||||
const id = this.get('id');
|
let wizardJson = buildJson(this, 'wizard');
|
||||||
if (!id || !id.underscore()) return reject({ error: 'id_required' });
|
|
||||||
|
if (wizardJson.after_time && !wizardJson.after_time_scheduled) {
|
||||||
let wizard = { id: id.underscore() };
|
reject({
|
||||||
|
error: 'after_time_need_time'
|
||||||
wizardProperties.forEach((p) => {
|
});
|
||||||
const value = this.get(p);
|
|
||||||
if (value) wizard[p] = value;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (wizard['after_time'] && !wizard['after_time_scheduled']) {
|
|
||||||
return reject({ error: 'after_time_need_time' });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const steps = this.get('steps');
|
if (this.steps.length > 0) {
|
||||||
if (steps.length > 0) {
|
let stepsResult = buildStepJson(this.steps);
|
||||||
const stepsResult = this.buildSteps(steps);
|
|
||||||
if (stepsResult.error) {
|
if (stepsResult.error ||
|
||||||
reject({ error: stepsResult.error });
|
!stepsResult.steps ||
|
||||||
|
stepsResult.steps.length < 1) {
|
||||||
|
|
||||||
|
reject({
|
||||||
|
error: stepsResult.error || 'steps_required'
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
wizard['steps'] = stepsResult.steps;
|
wizardJson.steps = stepsResult.steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (steps.length < 1 || !wizard['steps'] || wizard['steps'].length < 1) {
|
|
||||||
return reject({ error: 'steps_required' });
|
|
||||||
}
|
|
||||||
|
|
||||||
ajax("/admin/wizards/custom/save", {
|
ajax("/admin/wizards/custom/save", {
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
data: {
|
data: {
|
||||||
wizard: JSON.stringify(wizard)
|
wizard: JSON.stringify(wizardJson)
|
||||||
}
|
}
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
|
@ -63,107 +44,6 @@ const CustomWizard = EmberObject.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
buildSteps(stepsObj) {
|
|
||||||
let steps = [];
|
|
||||||
let error = null;
|
|
||||||
|
|
||||||
stepsObj.some((s) => {
|
|
||||||
if (!s.id || !s.id.underscore()) {
|
|
||||||
error = 'id_required';
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let step = { id: s.id.underscore() };
|
|
||||||
|
|
||||||
if (s.title) step['title'] = s.title;
|
|
||||||
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.required_data_message) step['required_data_message'] = s.required_data_message;
|
|
||||||
if (s.permitted_params) step['permitted_params'] = s.permitted_params;
|
|
||||||
|
|
||||||
const fields = s.get('fields');
|
|
||||||
if (fields.length) {
|
|
||||||
step['fields'] = [];
|
|
||||||
|
|
||||||
fields.some((f) => {
|
|
||||||
let id = f.id;
|
|
||||||
|
|
||||||
if (!id || !id.underscore()) {
|
|
||||||
error = 'id_required';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!f.type) {
|
|
||||||
error = 'type_required';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
f.set('id', id.underscore());
|
|
||||||
|
|
||||||
if (f.label === '') delete f.label;
|
|
||||||
if (f.description === '') delete f.description;
|
|
||||||
|
|
||||||
if (f.type === 'dropdown') {
|
|
||||||
const choices = f.choices;
|
|
||||||
if ((!choices || choices.length < 1) && !f.choices_key) {
|
|
||||||
error = 'field.need_choices';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.dropdown_none === '') delete f.dropdown_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete f.isNew;
|
|
||||||
|
|
||||||
step['fields'].push(f);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const actions = s.actions;
|
|
||||||
if (actions.length) {
|
|
||||||
step['actions'] = [];
|
|
||||||
|
|
||||||
actions.some((a) => {
|
|
||||||
let id = a.get('id');
|
|
||||||
if (!id || !id.underscore()) {
|
|
||||||
error = 'id_required';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//check if api_body is valid JSON
|
|
||||||
let api_body = a.get('api_body');
|
|
||||||
if (api_body) {
|
|
||||||
try {
|
|
||||||
JSON.parse(api_body);
|
|
||||||
} catch (e) {
|
|
||||||
error = 'invalid_api_body';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a.set('id', id.underscore());
|
|
||||||
|
|
||||||
delete a.isNew;
|
|
||||||
|
|
||||||
step['actions'].push(a);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
steps.push(step);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return { error };
|
|
||||||
} else {
|
|
||||||
return { steps };
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
return ajax("/admin/wizards/custom/remove", {
|
return ajax("/admin/wizards/custom/remove", {
|
||||||
type: 'DELETE',
|
type: 'DELETE',
|
||||||
|
@ -191,87 +71,11 @@ CustomWizard.reopenClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
create(w) {
|
create(wizardJson = {}) {
|
||||||
const wizard = this._super.apply(this);
|
const wizard = this._super.apply(this);
|
||||||
let steps = Ember.A();
|
|
||||||
let props = { steps };
|
|
||||||
|
|
||||||
if (w) {
|
|
||||||
props['id'] = w.id;
|
wizard.setProperties(buildWizardProperties(wizardJson));
|
||||||
props['existingId'] = true;
|
|
||||||
|
|
||||||
wizardProperties.forEach((p) => {
|
|
||||||
props[p] = w[p];
|
|
||||||
});
|
|
||||||
|
|
||||||
if (w.steps && w.steps.length) {
|
|
||||||
w.steps.forEach((s) => {
|
|
||||||
// clean empty strings
|
|
||||||
Object.keys(s).forEach((key) => (s[key] === '') && delete s[key]);
|
|
||||||
|
|
||||||
let fields = Ember.A();
|
|
||||||
|
|
||||||
if (s.fields && s.fields.length) {
|
|
||||||
s.fields.forEach((f) => {
|
|
||||||
Object.keys(f).forEach((key) => (f[key] === '') && delete f[key]);
|
|
||||||
|
|
||||||
const fieldParams = { isNew: false };
|
|
||||||
let field = Ember.Object.create($.extend(f, fieldParams));
|
|
||||||
|
|
||||||
if (f.choices) {
|
|
||||||
let choices = Ember.A();
|
|
||||||
|
|
||||||
f.choices.forEach((c) => {
|
|
||||||
choices.pushObject(Ember.Object.create(c));
|
|
||||||
});
|
|
||||||
|
|
||||||
field.set('choices', choices);
|
|
||||||
}
|
|
||||||
|
|
||||||
fields.pushObject(field);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let actions = Ember.A();
|
|
||||||
if (s.actions && s.actions.length) {
|
|
||||||
s.actions.forEach((a) => {
|
|
||||||
const actionParams = { isNew: false };
|
|
||||||
const action = Ember.Object.create($.extend(a, actionParams));
|
|
||||||
actions.pushObject(action);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
steps.pushObject(Ember.Object.create({
|
|
||||||
id: s.id,
|
|
||||||
key: s.key,
|
|
||||||
title: s.title,
|
|
||||||
raw_description: s.raw_description,
|
|
||||||
banner: s.banner,
|
|
||||||
required_data: s.required_data,
|
|
||||||
required_data_message: s.required_data_message,
|
|
||||||
permitted_params: s.permitted_params,
|
|
||||||
fields,
|
|
||||||
actions,
|
|
||||||
isNew: false
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
props['id'] = '';
|
|
||||||
props['name'] = '';
|
|
||||||
props['background'] = '';
|
|
||||||
props['save_submissions'] = true;
|
|
||||||
props['multiple_submissions'] = false;
|
|
||||||
props['after_signup'] = false;
|
|
||||||
props['after_time'] = false;
|
|
||||||
props['required'] = false;
|
|
||||||
props['prompt_completion'] = false;
|
|
||||||
props['restart_on_revisit'] = false;
|
|
||||||
props['permitted'] = null;
|
|
||||||
props['steps'] = Ember.A();
|
|
||||||
};
|
|
||||||
|
|
||||||
wizard.setProperties(props);
|
|
||||||
|
|
||||||
return wizard;
|
return wizard;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,9 +80,11 @@
|
||||||
inputs=action.category
|
inputs=action.category
|
||||||
options=(hash
|
options=(hash
|
||||||
hasOutput=true
|
hasOutput=true
|
||||||
categorySelection='output'
|
textSelection='key,value'
|
||||||
wizardSelection=true
|
wizardSelection=true
|
||||||
userSelection='key,value'
|
userSelection='key,value'
|
||||||
|
categorySelection='output'
|
||||||
|
outputDefaultSelection='category'
|
||||||
)}}
|
)}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
<div class="type-selector">
|
<div class="type-selector">
|
||||||
{{#if textEnabled}}
|
{{#if textEnabled}}
|
||||||
{{input-type-toggle
|
{{wizard-mapper-selector-type
|
||||||
activeType=activeType
|
activeType=activeType
|
||||||
type='text'
|
type='text'
|
||||||
toggle=(action 'toggleType')}}
|
toggle=(action 'toggleType')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if wizardEnabled}}
|
{{#if wizardEnabled}}
|
||||||
{{input-type-toggle
|
{{wizard-mapper-selector-type
|
||||||
activeType=activeType
|
activeType=activeType
|
||||||
type='wizard'
|
type='wizard'
|
||||||
toggle=(action 'toggleType')}}
|
toggle=(action 'toggleType')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if userEnabled}}
|
{{#if userEnabled}}
|
||||||
{{input-type-toggle
|
{{wizard-mapper-selector-type
|
||||||
activeType=activeType
|
activeType=activeType
|
||||||
type='user'
|
type='user'
|
||||||
toggle=(action 'toggleType')}}
|
toggle=(action 'toggleType')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if categoryEnabled}}
|
{{#if categoryEnabled}}
|
||||||
{{input-type-toggle
|
{{wizard-mapper-selector-type
|
||||||
activeType=activeType
|
activeType=activeType
|
||||||
type='category'
|
type='category'
|
||||||
toggle=(action 'toggleType')}}
|
toggle=(action 'toggleType')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if tagEnabled}}
|
{{#if tagEnabled}}
|
||||||
{{input-type-toggle
|
{{wizard-mapper-selector-type
|
||||||
activeType=activeType
|
activeType=activeType
|
||||||
type='tag'
|
type='tag'
|
||||||
toggle=(action 'toggleType')}}
|
toggle=(action 'toggleType')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if groupEnabled}}
|
{{#if groupEnabled}}
|
||||||
{{input-type-toggle
|
{{wizard-mapper-selector-type
|
||||||
activeType=activeType
|
activeType=activeType
|
||||||
type='group'
|
type='group'
|
||||||
toggle=(action 'toggleType')}}
|
toggle=(action 'toggleType')}}
|
||||||
|
|
|
@ -24,7 +24,6 @@ export default Ember.Route.extend({
|
||||||
name,
|
name,
|
||||||
completed,
|
completed,
|
||||||
notPermitted: !permitted,
|
notPermitted: !permitted,
|
||||||
minTrust,
|
|
||||||
wizardId
|
wizardId
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,7 +31,7 @@ class CustomWizard::Wizard
|
||||||
@required = false
|
@required = false
|
||||||
@needs_categories = false
|
@needs_categories = false
|
||||||
@needs_groups = false
|
@needs_groups = false
|
||||||
|
|
||||||
attrs.each do |key, value|
|
attrs.each do |key, value|
|
||||||
setter = "#{key}="
|
setter = "#{key}="
|
||||||
send(setter, value) if respond_to?(setter.to_sym, false)
|
send(setter, value) if respond_to?(setter.to_sym, false)
|
||||||
|
@ -150,40 +150,38 @@ class CustomWizard::Wizard
|
||||||
@groups ||= ::Site.new(Guardian.new(@user)).groups
|
@groups ||= ::Site.new(Guardian.new(@user)).groups
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.templates(filter = nil)
|
def self.filter_records(filter)
|
||||||
rows = [*PluginStoreRow.where(plugin_name: 'custom_wizard')]
|
PluginStoreRow.where("
|
||||||
rows = rows.select { |r| r.value[filter] } if filter
|
plugin_name = 'custom_wizard' AND
|
||||||
rows
|
(value::json ->> '#{filter}')::boolean IS TRUE
|
||||||
|
")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.after_signup(user)
|
def self.after_signup(user)
|
||||||
if (temps = templates('after_signup')).any?
|
if (records = filter_records('after_signup')).any?
|
||||||
wizard = nil
|
result = false
|
||||||
|
|
||||||
temps
|
records
|
||||||
.sort_by { |t| template.value['permitted'].present? }
|
.sort_by { |record| record.value['permitted'].present? }
|
||||||
.each do |template|
|
.each do |record|
|
||||||
wizard = CustomWizard::Wizard.new(user, template)
|
wizard = CustomWizard::Wizard.new(user, JSON.parse(record.value))
|
||||||
|
|
||||||
if wizard.permitted?
|
if wizard.permitted?
|
||||||
wizard = wizard
|
result = wizard
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wizard
|
result
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.prompt_completion(user)
|
def self.prompt_completion(user)
|
||||||
if (temps = templates('prompt_completion')).any?
|
if (records = filter_records('prompt_completion')).any?
|
||||||
temps.reduce([]) do |result, w|
|
records.reduce([]) do |result, record|
|
||||||
data = ::JSON.parse(w.value)
|
wizard = CustomWizard::Wizard.new(user, ::JSON.parse(record.value))
|
||||||
id = data['id']
|
|
||||||
name = data['name']
|
|
||||||
wizard = CustomWizard::Wizard.new(user, id: id, name: name)
|
|
||||||
result.push(id: id, name: name) if !wizard.completed?
|
result.push(id: id, name: name) if !wizard.completed?
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
@ -193,8 +191,8 @@ class CustomWizard::Wizard
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.restart_on_revisit
|
def self.restart_on_revisit
|
||||||
if (temps = templates('restart_on_revisit')).any?
|
if (records = filter_records('restart_on_revisit')).any?
|
||||||
temps.first.key
|
records.first.key
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -89,6 +89,8 @@ after_initialize do
|
||||||
if user &&
|
if user &&
|
||||||
user.first_seen_at.blank? &&
|
user.first_seen_at.blank? &&
|
||||||
wizard = CustomWizard::Wizard.after_signup(user)
|
wizard = CustomWizard::Wizard.after_signup(user)
|
||||||
|
|
||||||
|
byebug
|
||||||
|
|
||||||
if !wizard.completed?
|
if !wizard.completed?
|
||||||
custom_redirect = true
|
custom_redirect = true
|
||||||
|
|
Laden …
In neuem Issue referenzieren