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