Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-22 17:30:29 +01:00
wip
Dieser Commit ist enthalten in:
Ursprung
04d7fc1c59
Commit
6570e4b74b
21 geänderte Dateien mit 246 neuen und 134 gelöschten Zeilen
|
@ -41,7 +41,8 @@ export default Component.extend({
|
||||||
if (this.isDropdown) {
|
if (this.isDropdown) {
|
||||||
options.wizardFieldSelection = 'key,value';
|
options.wizardFieldSelection = 'key,value';
|
||||||
options.listSelection = 'assignment';
|
options.listSelection = 'assignment';
|
||||||
options.inputTypes = 'pair,assignment';
|
options.inputTypes = 'association,assignment';
|
||||||
|
options.singular = true;
|
||||||
options.pairConnector = 'association';
|
options.pairConnector = 'association';
|
||||||
options.keyPlaceholder = 'admin.wizard.key';
|
options.keyPlaceholder = 'admin.wizard.key';
|
||||||
options.valuePlaceholder = 'admin.wizard.value';
|
options.valuePlaceholder = 'admin.wizard.value';
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { lt } from '@ember/object/computed';
|
import { gt } from '@ember/object/computed';
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':mapper-connector', ':mapper-block', 'single'],
|
classNameBindings: [':mapper-connector', ':mapper-block', 'hasMultiple::single'],
|
||||||
single: lt('connectors.length', 2),
|
hasMultiple: gt('connectors.length', 1),
|
||||||
connectorLabel: computed(function() {
|
connectorLabel: computed(function() {
|
||||||
let key = this.connector;
|
let key = this.connector;
|
||||||
let path = this.inputTypes ? `input.${key}.name` : `connector.${key}`;
|
let path = this.inputTypes ? `input.${key}.name` : `connector.${key}`;
|
||||||
|
|
|
@ -5,13 +5,14 @@ import Component from "@ember/component";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':mapper-input', 'type'],
|
classNameBindings: [':mapper-input', 'inputType'],
|
||||||
inputType: alias('input.type'),
|
inputType: alias('input.type'),
|
||||||
isConditional: equal('inputType', 'conditional'),
|
isConditional: equal('inputType', 'conditional'),
|
||||||
isAssignment: equal('inputType', 'assignment'),
|
isAssignment: equal('inputType', 'assignment'),
|
||||||
isPair: equal('inputType', 'pair'),
|
isAssociation: equal('inputType', 'association'),
|
||||||
|
isValidation: equal('inputType', 'validation'),
|
||||||
hasOutput: or('isConditional', 'isAssignment'),
|
hasOutput: or('isConditional', 'isAssignment'),
|
||||||
hasPairs: or('isConditional', 'isPair'),
|
hasPairs: or('isConditional', 'isAssociation', 'isValidation'),
|
||||||
connectors: computed(function() { return connectorContent('output', this.input.type, this.options) }),
|
connectors: computed(function() { return connectorContent('output', this.input.type, this.options) }),
|
||||||
inputTypes: computed(function() { return inputTypesContent(this.options) }),
|
inputTypes: computed(function() { return inputTypesContent(this.options) }),
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { alias, or, gt } from "@ember/object/computed";
|
import { alias, or, gt } from "@ember/object/computed";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import { default as discourseComputed, observes } from "discourse-common/utils/decorators";
|
import { default as discourseComputed, observes, on } from "discourse-common/utils/decorators";
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||||
import { defaultSelectionType, selectionTypes } from '../lib/wizard-mapper';
|
import { defaultSelectionType, selectionTypes } from '../lib/wizard-mapper';
|
||||||
import { snakeCase, selectKitContent } from '../lib/wizard';
|
import { snakeCase, selectKitContent } from '../lib/wizard';
|
||||||
|
@ -72,7 +72,7 @@ export default Component.extend({
|
||||||
return showTypes ? 'chevron-down' : 'chevron-right';
|
return showTypes ? 'chevron-down' : 'chevron-right';
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('options.@each', 'inputType')
|
@observes('inputType')
|
||||||
resetActiveType() {
|
resetActiveType() {
|
||||||
this.set('activeType', defaultSelectionType(this.selectorType, this.options));
|
this.set('activeType', defaultSelectionType(this.selectorType, this.options));
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||||
import { on } from 'discourse-common/utils/decorators';
|
|
||||||
import { newInput, selectionTypes } from '../lib/wizard-mapper';
|
import { newInput, selectionTypes } from '../lib/wizard-mapper';
|
||||||
import { default as discourseComputed, observes } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
|
||||||
|
import { gt } from "@ember/object/computed";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: 'wizard-mapper',
|
classNames: 'wizard-mapper',
|
||||||
|
hasInput: gt('inputs.length', 0),
|
||||||
|
|
||||||
@discourseComputed('inputs.[]', 'options.singular')
|
@discourseComputed('options.singular', 'hasInput')
|
||||||
canAdd(inputs, singular) {
|
canAdd(singular, hasInput) {
|
||||||
return !singular || !inputs || inputs.length < 1;
|
return !singular || !hasInput;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('options.@each')
|
@discourseComputed('options.@each.inputType')
|
||||||
inputOptions(options) {
|
inputOptions(options) {
|
||||||
let result = {
|
let result = {
|
||||||
inputTypes: options.inputTypes || 'conditional,assignment',
|
inputTypes: options.inputTypes || 'conditional,assignment',
|
||||||
|
inputConnector: options.inputConnector || 'or',
|
||||||
pairConnector: options.pairConnector || null,
|
pairConnector: options.pairConnector || null,
|
||||||
outputConnector: options.outputConnector || null,
|
outputConnector: options.outputConnector || null,
|
||||||
context: options.context || null
|
context: options.context || null
|
||||||
|
@ -45,7 +47,9 @@ export default Component.extend({
|
||||||
this.set('inputs', A());
|
this.set('inputs', A());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.get('inputs').pushObject(newInput(this.inputOptions));
|
this.get('inputs').pushObject(
|
||||||
|
newInput(this.inputOptions, this.inputs.length)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
remove(input) {
|
remove(input) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ function buildMappedJson(inputs) {
|
||||||
if (present(inpt.output)) {
|
if (present(inpt.output)) {
|
||||||
input.output = inpt.output;
|
input.output = inpt.output;
|
||||||
input.output_type = snakeCase(inpt.output_type);
|
input.output_type = snakeCase(inpt.output_type);
|
||||||
input.connector = inpt.connector;
|
input.output_connector = inpt.output_connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present(inpt.pairs)) {
|
if (present(inpt.pairs)) {
|
||||||
|
@ -74,8 +74,7 @@ function buildMappedJson(inputs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((input.type === 'assignment' && present(input.output)) ||
|
if ((input.type === 'assignment' && present(input.output)) ||
|
||||||
(input.type === 'conditional' && present(input.pairs)) ||
|
present(input.pairs)) {
|
||||||
(input.type === 'pair' && present(input.pairs))) {
|
|
||||||
|
|
||||||
result.push(input);
|
result.push(input);
|
||||||
}
|
}
|
||||||
|
@ -146,56 +145,60 @@ function buildStepJson(object) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mappedProperty(property, value) {
|
function castCase(property, value) {
|
||||||
return property.indexOf('_type') > -1 ? camelCase(value) : value;
|
return property.indexOf('_type') > -1 ? camelCase(value) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildProperty(json, property, type) {
|
||||||
|
if (mapped(property, type) && present(json[property])) {
|
||||||
|
let inputs = [];
|
||||||
|
|
||||||
|
json[property].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 = {};
|
||||||
|
|
||||||
|
Object.keys(pairJson).forEach(pairKey => {
|
||||||
|
pair[pairKey] = castCase(pairKey, pairJson[pairKey]);
|
||||||
|
});
|
||||||
|
|
||||||
|
pair.pairCount = pairCount;
|
||||||
|
|
||||||
|
pairs.push(
|
||||||
|
EmberObject.create(pair)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
input.pairs = pairs;
|
||||||
|
} else {
|
||||||
|
input[inputKey] = castCase(inputKey, inputJson[inputKey]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
inputs.push(
|
||||||
|
EmberObject.create(input)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return A(inputs);
|
||||||
|
} else {
|
||||||
|
return json[property];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function buildObject(json, type) {
|
function buildObject(json, type) {
|
||||||
let params = {
|
let params = {
|
||||||
isNew: false
|
isNew: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(json).forEach(prop => {
|
Object.keys(json).forEach(prop => {
|
||||||
if (mapped(prop, type) && present(json[prop])) {
|
params[prop] = buildProperty(json, 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 = {};
|
|
||||||
|
|
||||||
Object.keys(pairJson).forEach(pairKey => {
|
|
||||||
pair[pairKey] = mappedProperty(pairKey, pairJson[pairKey]);
|
|
||||||
});
|
|
||||||
|
|
||||||
pair.pairCount = pairCount;
|
|
||||||
|
|
||||||
pairs.push(
|
|
||||||
EmberObject.create(pair)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
input.pairs = pairs;
|
|
||||||
} else {
|
|
||||||
input[inputKey] = mappedProperty(inputKey, inputJson[inputKey]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
inputs.push(
|
|
||||||
EmberObject.create(input)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
params[prop] = A(inputs);
|
|
||||||
} else {
|
|
||||||
params[prop] = json[prop];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return EmberObject.create(params);
|
return EmberObject.create(params);
|
||||||
|
@ -228,7 +231,7 @@ function buildProperties(json) {
|
||||||
props.existingId = true;
|
props.existingId = true;
|
||||||
|
|
||||||
properties.wizard.forEach((p) => {
|
properties.wizard.forEach((p) => {
|
||||||
props[p] = json[p];
|
props[p] = buildProperty(json, p, 'wizard');
|
||||||
|
|
||||||
if (wizardHasAdvanced(p, json[p])) {
|
if (wizardHasAdvanced(p, json[p])) {
|
||||||
props.showAdvanced = true;
|
props.showAdvanced = true;
|
||||||
|
@ -242,7 +245,7 @@ function buildProperties(json) {
|
||||||
};
|
};
|
||||||
|
|
||||||
properties.step.forEach((p) => {
|
properties.step.forEach((p) => {
|
||||||
stepParams[p] = stepJson[p];
|
stepParams[p] = buildProperty(stepJson, p, 'wizard');;
|
||||||
|
|
||||||
if (stepHasAdvanced(p, stepJson[p])) {
|
if (stepHasAdvanced(p, stepJson[p])) {
|
||||||
stepParams.showAdvanced = true;
|
stepParams.showAdvanced = true;
|
||||||
|
|
|
@ -34,16 +34,19 @@ const connectors = {
|
||||||
'greater',
|
'greater',
|
||||||
'less',
|
'less',
|
||||||
'greater_or_equal',
|
'greater_or_equal',
|
||||||
'less_or_equal'
|
'less_or_equal',
|
||||||
|
'regex'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultConnector(connectorType, inputType, opts = {}) {
|
function defaultConnector(connectorType, inputType, opts = {}) {
|
||||||
if (opts[`${connectorType}Connector`]) return opts[`${connectorType}Connector`];
|
if (opts[`${connectorType}Connector`]) return opts[`${connectorType}Connector`];
|
||||||
if (inputType === 'assignment' && connectorType === 'output') return 'set';
|
|
||||||
if (inputType === 'conditional' && connectorType === 'output') return 'then';
|
if (inputType === 'conditional' && connectorType === 'output') return 'then';
|
||||||
if (inputType === 'conditional' && connectorType === 'pair') return 'equal';
|
if (inputType === 'conditional' && connectorType === 'pair') return 'equal';
|
||||||
if (inputType === 'pair') return 'equal';
|
if (inputType === 'assignment' && connectorType === 'output') return 'set';
|
||||||
|
if (inputType === 'association' && connectorType === 'pair') return 'association';
|
||||||
|
if (inputType === 'validation' && connectorType === 'pair') return 'equal';
|
||||||
|
return 'equal';
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectorContent(connectorType, inputType, opts) {
|
function connectorContent(connectorType, inputType, opts) {
|
||||||
|
@ -114,7 +117,7 @@ function newPair(inputType, options = {}) {
|
||||||
return EmberObject.create(params);
|
return EmberObject.create(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newInput(options = {}) {
|
function newInput(options = {}, count) {
|
||||||
const inputType = defaultInputType(options);
|
const inputType = defaultInputType(options);
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
|
@ -132,12 +135,16 @@ function newInput(options = {}) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
params.connector = options.inputConnector;
|
||||||
|
}
|
||||||
|
|
||||||
if (['conditional', 'assignment'].indexOf(inputType) > -1 ||
|
if (['conditional', 'assignment'].indexOf(inputType) > -1 ||
|
||||||
options.outputDefaultSelection ||
|
options.outputDefaultSelection ||
|
||||||
options.outputConnector) {
|
options.outputConnector) {
|
||||||
|
|
||||||
params['output_type'] = defaultSelectionType('output', options);
|
params['output_type'] = defaultSelectionType('output', options);
|
||||||
params['connector'] = defaultConnector('output', inputType, options);
|
params['output_connector'] = defaultConnector('output', inputType, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EmberObject.create(params);
|
return EmberObject.create(params);
|
||||||
|
|
|
@ -111,14 +111,14 @@
|
||||||
{{wizard-mapper
|
{{wizard-mapper
|
||||||
inputs=model.permitted
|
inputs=model.permitted
|
||||||
options=(hash
|
options=(hash
|
||||||
singular=true
|
|
||||||
context='wizard'
|
context='wizard'
|
||||||
inputTypes='assignment'
|
inputTypes='assignment,validation'
|
||||||
groupSelection='output'
|
groupSelection='output'
|
||||||
textSelection='key,value'
|
userFieldSelection='key'
|
||||||
|
textSelection='value'
|
||||||
|
inputConnector='and'
|
||||||
)}}
|
)}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{wizard-advanced-toggle showAdvanced=model.showAdvanced}}
|
{{wizard-advanced-toggle showAdvanced=model.showAdvanced}}
|
||||||
|
|
|
@ -248,7 +248,7 @@
|
||||||
{{wizard-mapper
|
{{wizard-mapper
|
||||||
inputs=action.custom_fields
|
inputs=action.custom_fields
|
||||||
options=(hash
|
options=(hash
|
||||||
pairConnector='set'
|
inputTypes='association'
|
||||||
wizardFieldSelection='value'
|
wizardFieldSelection='value'
|
||||||
userFieldSelection='value'
|
userFieldSelection='value'
|
||||||
keyPlaceholder='admin.wizard.action.custom_fields.key'
|
keyPlaceholder='admin.wizard.action.custom_fields.key'
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
{{wizard-mapper
|
{{wizard-mapper
|
||||||
inputs=step.required_data
|
inputs=step.required_data
|
||||||
options=(hash
|
options=(hash
|
||||||
|
inputTypes='validation'
|
||||||
wizardFieldSelection='value'
|
wizardFieldSelection='value'
|
||||||
userFieldSelection='value'
|
userFieldSelection='value'
|
||||||
keyPlaceholder="admin.wizard.submission_key"
|
keyPlaceholder="admin.wizard.submission_key"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{{#if single}}
|
{{#if hasMultiple}}
|
||||||
<span class="connector-single">
|
|
||||||
{{connectorLabel}}
|
|
||||||
</span>
|
|
||||||
{{else}}
|
|
||||||
{{combo-box
|
{{combo-box
|
||||||
value=connector
|
value=connector
|
||||||
content=connectors
|
content=connectors
|
||||||
onChange=(action (mut connector))}}
|
onChange=(action (mut connector))}}
|
||||||
|
{{else}}
|
||||||
|
<span class="connector-single">
|
||||||
|
{{connectorLabel}}
|
||||||
|
</span>
|
||||||
{{/if}}
|
{{/if}}
|
|
@ -25,7 +25,7 @@
|
||||||
{{#if hasOutput}}
|
{{#if hasOutput}}
|
||||||
{{#if hasPairs}}
|
{{#if hasPairs}}
|
||||||
{{wizard-mapper-connector
|
{{wizard-mapper-connector
|
||||||
connector=input.connector
|
connector=input.output_connector
|
||||||
connectors=connectors}}
|
connectors=connectors}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
{{#each inputs as |input|}}
|
{{#each inputs as |input|}}
|
||||||
|
{{#if input.connector}}
|
||||||
|
{{wizard-mapper-connector connector=input.connector}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{wizard-mapper-input
|
{{wizard-mapper-input
|
||||||
input=input
|
input=input
|
||||||
options=inputOptions
|
options=inputOptions
|
||||||
|
|
|
@ -2,6 +2,5 @@
|
||||||
class=fieldClass
|
class=fieldClass
|
||||||
value=field.value
|
value=field.value
|
||||||
content=field.content
|
content=field.content
|
||||||
none=(hash id="__none__" label=field.dropdown_none)
|
|
||||||
nameProperty="label"
|
nameProperty="label"
|
||||||
tabindex="9"}}
|
tabindex="9"}}
|
|
@ -17,6 +17,12 @@
|
||||||
div.mapper-block:not(:last-of-type) {
|
div.mapper-block:not(:last-of-type) {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .mapper-connector.single {
|
||||||
|
width: min-content;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
height: 20px
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[class~='mapper-input'] {
|
[class~='mapper-input'] {
|
||||||
|
@ -156,6 +162,10 @@
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mapper-connector {
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapper-pair {
|
.mapper-pair {
|
||||||
|
|
|
@ -67,8 +67,10 @@ en:
|
||||||
output: 'then'
|
output: 'then'
|
||||||
assignment:
|
assignment:
|
||||||
name: 'set'
|
name: 'set'
|
||||||
pair:
|
association:
|
||||||
name: 'pair'
|
name: 'map'
|
||||||
|
validation:
|
||||||
|
name: 'ensure'
|
||||||
|
|
||||||
selector:
|
selector:
|
||||||
label:
|
label:
|
||||||
|
@ -119,8 +121,6 @@ en:
|
||||||
description: "Description"
|
description: "Description"
|
||||||
image: "Image"
|
image: "Image"
|
||||||
image_placeholder: "Image url"
|
image_placeholder: "Image url"
|
||||||
dropdown_none: "None"
|
|
||||||
dropdown_none_placeholder: "Label"
|
|
||||||
required: "Required"
|
required: "Required"
|
||||||
required_label: "Field is Required"
|
required_label: "Field is Required"
|
||||||
min_length: "Min Length"
|
min_length: "Min Length"
|
||||||
|
@ -134,6 +134,8 @@ en:
|
||||||
content: "Content"
|
content: "Content"
|
||||||
|
|
||||||
connector:
|
connector:
|
||||||
|
and: "and"
|
||||||
|
or: "or"
|
||||||
then: "then"
|
then: "then"
|
||||||
set: "set"
|
set: "set"
|
||||||
equal: '='
|
equal: '='
|
||||||
|
@ -141,6 +143,7 @@ en:
|
||||||
less: '<'
|
less: '<'
|
||||||
greater_or_equal: '>='
|
greater_or_equal: '>='
|
||||||
less_or_equal: '<='
|
less_or_equal: '<='
|
||||||
|
regex: '=~'
|
||||||
association: '→'
|
association: '→'
|
||||||
|
|
||||||
action:
|
action:
|
||||||
|
|
|
@ -45,7 +45,7 @@ class CustomWizard::Action
|
||||||
inputs: action['recipient'],
|
inputs: action['recipient'],
|
||||||
data: data,
|
data: data,
|
||||||
user: user
|
user: user
|
||||||
).output
|
).perform
|
||||||
|
|
||||||
if params[:title] && params[:raw]
|
if params[:title] && params[:raw]
|
||||||
params[:archetype] = Archetype.private_message
|
params[:archetype] = Archetype.private_message
|
||||||
|
@ -144,7 +144,7 @@ class CustomWizard::Action
|
||||||
opts: {
|
opts: {
|
||||||
multiple: true
|
multiple: true
|
||||||
}
|
}
|
||||||
).output
|
).perform
|
||||||
|
|
||||||
groups = groups.flatten.reduce([]) do |result, g|
|
groups = groups.flatten.reduce([]) do |result, g|
|
||||||
begin
|
begin
|
||||||
|
@ -183,7 +183,7 @@ class CustomWizard::Action
|
||||||
inputs: action['category'],
|
inputs: action['category'],
|
||||||
data: data,
|
data: data,
|
||||||
user: user
|
user: user
|
||||||
).output
|
).perform
|
||||||
|
|
||||||
if output.is_a?(Array)
|
if output.is_a?(Array)
|
||||||
output.first
|
output.first
|
||||||
|
@ -199,7 +199,7 @@ class CustomWizard::Action
|
||||||
inputs: action['tags'],
|
inputs: action['tags'],
|
||||||
data: data,
|
data: data,
|
||||||
user: user,
|
user: user,
|
||||||
).output
|
).perform
|
||||||
|
|
||||||
if output.is_a?(Array)
|
if output.is_a?(Array)
|
||||||
output.flatten
|
output.flatten
|
||||||
|
@ -212,23 +212,23 @@ class CustomWizard::Action
|
||||||
|
|
||||||
def add_custom_fields(params = {})
|
def add_custom_fields(params = {})
|
||||||
if (custom_fields = action['custom_fields']).present?
|
if (custom_fields = action['custom_fields']).present?
|
||||||
custom_fields.each do |field|
|
field_map = CustomWizard::Mapper.new(
|
||||||
pair = field['pairs'].first
|
inputs: custom_fields,
|
||||||
value = mapper.map_field(pair['key'], pair['key_type'])
|
data: data,
|
||||||
key = mapper.map_field(pair['value'], pair['value_type'])
|
user: user
|
||||||
|
).perform
|
||||||
|
|
||||||
if key &&
|
field_map.each do |field|
|
||||||
value.present? &&
|
keyArr = field[:key].split('.')
|
||||||
(keyArr = key.split('.')).length === 2
|
value = field[:value]
|
||||||
|
|
||||||
if keyArr.first === 'topic'
|
if keyArr.length != 2 || keyArr.first === 'topic'
|
||||||
params[:topic_opts] ||= {}
|
params[:topic_opts] ||= {}
|
||||||
params[:topic_opts][:custom_fields] ||= {}
|
params[:topic_opts][:custom_fields] ||= {}
|
||||||
params[:topic_opts][:custom_fields][keyArr.last] = value
|
params[:topic_opts][:custom_fields][keyArr.last] = value
|
||||||
elsif keyArr.first === 'post'
|
elsif keyArr.first === 'post'
|
||||||
params[:custom_fields] ||= {}
|
params[:custom_fields] ||= {}
|
||||||
params[:custom_fields][keyArr.last.to_sym] = value
|
params[:custom_fields][keyArr.last.to_sym] = value
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -245,7 +245,7 @@ class CustomWizard::Action
|
||||||
inputs: action['title'],
|
inputs: action['title'],
|
||||||
data: data,
|
data: data,
|
||||||
user: user
|
user: user
|
||||||
).output
|
).perform
|
||||||
|
|
||||||
params[:raw] = action['post_builder'] ?
|
params[:raw] = action['post_builder'] ?
|
||||||
mapper.interpolate(action['post_template']) :
|
mapper.interpolate(action['post_template']) :
|
||||||
|
|
|
@ -235,12 +235,26 @@ class CustomWizard::Builder
|
||||||
@wizard.needs_groups = true
|
@wizard.needs_groups = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if (content = field_template['content']).present?
|
if (content_inputs = field_template['content']).present?
|
||||||
params[:content] = CustomWizard::Mapper.new(
|
content = CustomWizard::Mapper.new(
|
||||||
inputs: content,
|
inputs: content_inputs,
|
||||||
user: @wizard.user,
|
user: @wizard.user,
|
||||||
data: @submissions.last
|
data: @submissions.last,
|
||||||
).output
|
opts: {
|
||||||
|
with_type: true
|
||||||
|
}
|
||||||
|
).perform
|
||||||
|
|
||||||
|
if content[:type] == 'association'
|
||||||
|
content[:result] = content[:result].map do |item|
|
||||||
|
{
|
||||||
|
id: item[:key],
|
||||||
|
name: item[:value]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
params[:content] = content[:result]
|
||||||
end
|
end
|
||||||
|
|
||||||
field = step.add_field(params)
|
field = step.add_field(params)
|
||||||
|
@ -252,7 +266,7 @@ class CustomWizard::Builder
|
||||||
inputs: prefill,
|
inputs: prefill,
|
||||||
user: @wizard.user,
|
user: @wizard.user,
|
||||||
data: @submissions.last
|
data: @submissions.last
|
||||||
).output
|
).perform
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ class CustomWizard::Mapper
|
||||||
greater: '>',
|
greater: '>',
|
||||||
less: '<',
|
less: '<',
|
||||||
greater_or_equal: '>=',
|
greater_or_equal: '>=',
|
||||||
less_or_equal: '<='
|
less_or_equal: '<=',
|
||||||
|
regex: '=~'
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize(params)
|
def initialize(params)
|
||||||
|
@ -18,33 +19,63 @@ class CustomWizard::Mapper
|
||||||
@opts = params[:opts] || {}
|
@opts = params[:opts] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def output
|
def perform
|
||||||
multiple = @opts[:multiple]
|
multiple = @opts[:multiple]
|
||||||
output = multiple ? [] : nil
|
perform_result = multiple ? [] : nil
|
||||||
|
|
||||||
inputs.each do |input|
|
inputs.each do |input|
|
||||||
if input['type'] === 'conditional' && validate_pairs(input['pairs'])
|
input_type = input['type']
|
||||||
|
pairs = input['pairs']
|
||||||
|
|
||||||
|
if (input_type === 'conditional' && validate_pairs(pairs)) || input_type === 'assignment'
|
||||||
|
output = input['output']
|
||||||
|
output_type = input['output_type']
|
||||||
|
|
||||||
|
result = build_result(map_field(output, output_type), input_type)
|
||||||
|
|
||||||
if multiple
|
if multiple
|
||||||
output.push(map_field(input['output'], input['output_type']))
|
perform_result.push(result)
|
||||||
else
|
else
|
||||||
output = map_field(input['output'], input['output_type'])
|
perform_result = result
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if input['type'] === 'assignment'
|
if input_type === 'validation'
|
||||||
value = map_field(input['output'], input['output_type'])
|
result = build_result(validate_pairs(pairs), input_type)
|
||||||
|
|
||||||
if @opts[:multiple]
|
if multiple
|
||||||
output.push(value)
|
perform_result.push(result)
|
||||||
else
|
else
|
||||||
output = value
|
perform_result = result
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if input_type === 'association'
|
||||||
|
result = build_result(map_pairs(pairs), input_type)
|
||||||
|
|
||||||
|
if multiple
|
||||||
|
perform_result.push(result)
|
||||||
|
else
|
||||||
|
perform_result = result
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
output
|
perform_result
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_result(result, type)
|
||||||
|
if opts[:with_type]
|
||||||
|
{
|
||||||
|
type: type,
|
||||||
|
result: result
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_pairs(pairs)
|
def validate_pairs(pairs)
|
||||||
|
@ -52,10 +83,12 @@ class CustomWizard::Mapper
|
||||||
|
|
||||||
pairs.each do |pair|
|
pairs.each do |pair|
|
||||||
key = map_field(pair['key'], pair['key_type'])
|
key = map_field(pair['key'], pair['key_type'])
|
||||||
value = map_field(pair['value'], pair['value_type'])
|
operator = map_operator(pair['connector'])
|
||||||
|
value = interpolate(map_field(pair['value'], pair['value_type']))
|
||||||
|
value = "/#{value}/" if pair['connector'] == 'regex'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
failed = true unless key.public_send(operator(pair['connector']), value)
|
failed = true unless key.public_send(operator, value)
|
||||||
rescue NoMethodError
|
rescue NoMethodError
|
||||||
#
|
#
|
||||||
end
|
end
|
||||||
|
@ -64,7 +97,25 @@ class CustomWizard::Mapper
|
||||||
!failed
|
!failed
|
||||||
end
|
end
|
||||||
|
|
||||||
def operator(connector)
|
def map_pairs(pairs)
|
||||||
|
result = []
|
||||||
|
|
||||||
|
pairs.each do |pair|
|
||||||
|
key = map_field(pair['key'], pair['key_type'])
|
||||||
|
value = map_field(pair['value'], pair['value_type'])
|
||||||
|
|
||||||
|
if key && value
|
||||||
|
result.push(
|
||||||
|
key: key,
|
||||||
|
value: value
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def map_operator(connector)
|
||||||
OPERATORS[connector.to_sym] || '=='
|
OPERATORS[connector.to_sym] || '=='
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -129,8 +129,27 @@ class CustomWizard::Wizard
|
||||||
def permitted?
|
def permitted?
|
||||||
return false unless user
|
return false unless user
|
||||||
return true if user.admin? || permitted.blank?
|
return true if user.admin? || permitted.blank?
|
||||||
group_ids = permitted.first['output']
|
|
||||||
return GroupUser.exists?(group_id: group_ids, user_id: user.id)
|
mapper = CustomWizard::Mapper.new(
|
||||||
|
inputs: permitted,
|
||||||
|
user: user,
|
||||||
|
opts: {
|
||||||
|
with_type: true,
|
||||||
|
multiple: true
|
||||||
|
}
|
||||||
|
).perform
|
||||||
|
|
||||||
|
return true if mapper.blank?
|
||||||
|
|
||||||
|
mapper.all? do |m|
|
||||||
|
if m.type === 'assignment'
|
||||||
|
GroupUser.exists?(group_id: m.result, user_id: user.id)
|
||||||
|
elsif m.type === 'validation'
|
||||||
|
mapper.result
|
||||||
|
else
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset
|
def reset
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
class CustomWizardFieldSerializer < ::WizardFieldSerializer
|
class CustomWizardFieldSerializer < ::WizardFieldSerializer
|
||||||
|
|
||||||
attributes :dropdown_none,
|
attributes :image,
|
||||||
:image,
|
|
||||||
:file_types,
|
:file_types,
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
|
@ -31,10 +30,6 @@ class CustomWizardFieldSerializer < ::WizardFieldSerializer
|
||||||
I18n.t("#{object.key || i18n_key}.placeholder", default: '')
|
I18n.t("#{object.key || i18n_key}.placeholder", default: '')
|
||||||
end
|
end
|
||||||
|
|
||||||
def dropdown_none
|
|
||||||
object.dropdown_none
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_types
|
def file_types
|
||||||
object.file_types
|
object.file_types
|
||||||
end
|
end
|
||||||
|
|
Laden …
In neuem Issue referenzieren