Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-25 18:50:27 +01:00
add prefil
Dieser Commit ist enthalten in:
Ursprung
b8369146c7
Commit
2e6ab27ea0
50 geänderte Dateien mit 737 neuen und 284 gelöschten Zeilen
25
assets/javascripts/discourse/components/input-type-toggle.js.es6
Normale Datei
25
assets/javascripts/discourse/components/input-type-toggle.js.es6
Normale Datei
|
@ -0,0 +1,25 @@
|
|||
import discourseComputed from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'a',
|
||||
classNameBindings: ['type', 'active'],
|
||||
|
||||
@discourseComputed('type', 'activeType')
|
||||
active(type, activeType) {
|
||||
return type === activeType;
|
||||
},
|
||||
|
||||
@discourseComputed('type')
|
||||
label(type) {
|
||||
let map = {
|
||||
wizard: I18n.t('admin.wizard.label'),
|
||||
user: I18n.t('users_lowercase.one'),
|
||||
text: I18n.t('admin.wizard.text')
|
||||
};
|
||||
return map[type].toLowerCase();
|
||||
},
|
||||
|
||||
click() {
|
||||
this.toggle(this.type)
|
||||
}
|
||||
})
|
|
@ -1,33 +1,16 @@
|
|||
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
const ACTION_TYPES = [
|
||||
{ id: 'create_topic', name: 'Create Topic' },
|
||||
{ id: 'update_profile', name: 'Update Profile' },
|
||||
{ id: 'send_message', name: 'Send Message' },
|
||||
{ id: 'send_to_api', name: 'Send to API' },
|
||||
{ id: 'add_to_group', name: 'Add to Group' },
|
||||
{ id: 'route_to', name: 'Route To' },
|
||||
{ id: 'open_composer', name: 'Open Composer' }
|
||||
];
|
||||
|
||||
const PROFILE_FIELDS = [
|
||||
'name',
|
||||
'user_avatar',
|
||||
'date_of_birth',
|
||||
'title',
|
||||
'locale',
|
||||
'location',
|
||||
'website',
|
||||
'bio_raw',
|
||||
'profile_background',
|
||||
'card_background',
|
||||
'theme_id'
|
||||
];
|
||||
import {
|
||||
default as computed,
|
||||
observes
|
||||
} from 'discourse-common/utils/decorators';
|
||||
import {
|
||||
actionTypes,
|
||||
generateName,
|
||||
generateSelectKitContent
|
||||
} from '../lib/custom-wizard';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'wizard-custom-action',
|
||||
types: ACTION_TYPES,
|
||||
profileFields: PROFILE_FIELDS,
|
||||
types: actionTypes.map(t => ({ id: t, name: generateName(t) })),
|
||||
createTopic: Ember.computed.equal('action.type', 'create_topic'),
|
||||
updateProfile: Ember.computed.equal('action.type', 'update_profile'),
|
||||
sendMessage: Ember.computed.equal('action.type', 'send_message'),
|
||||
|
@ -36,6 +19,7 @@ export default Ember.Component.extend({
|
|||
addToGroup: Ember.computed.equal('action.type', 'add_to_group'),
|
||||
routeTo: Ember.computed.equal('action.type', 'route_to'),
|
||||
disableId: Ember.computed.not('action.isNew'),
|
||||
groupPropertyTypes: generateSelectKitContent(['id', 'name']),
|
||||
|
||||
@computed('action.type')
|
||||
basicTopicFields(actionType) {
|
||||
|
@ -52,17 +36,17 @@ export default Ember.Component.extend({
|
|||
return ['create_topic', 'send_message'].indexOf(actionType) > -1;
|
||||
},
|
||||
|
||||
@computed('availableFields')
|
||||
@computed('wizardFields')
|
||||
builderWizardFields(fields) {
|
||||
return fields.map((f) => ` w{${f.id}}`);
|
||||
},
|
||||
|
||||
@computed('availableFields')
|
||||
@computed('wizardFields')
|
||||
categoryFields(fields) {
|
||||
return fields.filter(f => f.type == 'category');
|
||||
},
|
||||
|
||||
@computed('availableFields')
|
||||
@computed('wizardFields')
|
||||
tagFields(fields) {
|
||||
return fields.filter(f => f.type == 'tag');
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed, observes, on } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed, observes, on } from 'discourse-common/utils/decorators';
|
||||
import { generateSelectKitContent } from '../lib/custom-wizard';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import { alias, equal } from "@ember/object/computed";
|
||||
import { computed } from "@ember/object";
|
||||
import {
|
||||
default as discourseComputed,
|
||||
observes
|
||||
} from "discourse-common/utils/decorators";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
@observes('activeType')
|
||||
clearValue() {
|
||||
this.set('value', null);
|
||||
},
|
||||
|
||||
@discourseComputed('customPlaceholder')
|
||||
textPlaceholder(customPlaceholder) {
|
||||
return customPlaceholder || 'admin.wizard.text';
|
||||
},
|
||||
|
||||
@discourseComputed('activeType', 'userEnabled')
|
||||
showUser(activeType, userEnabled) {
|
||||
return activeType === 'user' && userEnabled;
|
||||
},
|
||||
|
||||
@discourseComputed('activeType', 'wizardEnabled')
|
||||
showWizard(activeType, wizardEnabled) {
|
||||
return activeType === 'wizard' && wizardEnabled;
|
||||
},
|
||||
|
||||
showText: equal('activeType', 'text'),
|
||||
|
||||
@discourseComputed('options.allowWizardField', 'inputType')
|
||||
wizardEnabled(allowWizardField, inputType) {
|
||||
return allowWizardField === true || allowWizardField === inputType;
|
||||
},
|
||||
|
||||
@discourseComputed('options.allowUserField', 'inputType')
|
||||
userEnabled(allowUserField, inputType) {
|
||||
return allowUserField === true || allowUserField === inputType;
|
||||
},
|
||||
|
||||
actions: {
|
||||
toggleType(type) {
|
||||
this.set('activeType', type);
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,9 @@
|
|||
import { connectors } from '../lib/custom-wizard';
|
||||
import { gt } from "@ember/object/computed";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'pair',
|
||||
connectorNone: 'admin.wizard.connector.none',
|
||||
connectors: connectors.map(c => ({ id: c, name: I18n.t(`admin.wizard.connector.${c}`) })),
|
||||
showRemove: gt('pair.index', 0)
|
||||
})
|
|
@ -1,34 +1,19 @@
|
|||
import { default as computed, on } from 'ember-addons/ember-computed-decorators';
|
||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||
import { newPair } from '../lib/custom-wizard';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'custom-input',
|
||||
noneKey: 'admin.wizard.select_field',
|
||||
noneValue: 'admin.wizard.none',
|
||||
connectorNone: 'admin.wizard.none',
|
||||
inputKey: 'admin.wizard.key',
|
||||
customDisabled: Ember.computed.alias('input.user_field'),
|
||||
outputConnectorKey: 'admin.wizard.connector.prefill',
|
||||
outputPrefixKey: 'admin.wizard.if',
|
||||
|
||||
@computed('input.value_custom', 'input.user_field')
|
||||
valueDisabled(custom, user) {
|
||||
return Boolean(custom || user);
|
||||
actions: {
|
||||
addPair() {
|
||||
this.get('input.pairs').pushObject(
|
||||
newPair(this.options, this.input.pairs.length)
|
||||
);
|
||||
},
|
||||
|
||||
@on('init')
|
||||
setupUserFields() {
|
||||
const allowUserField = this.get('allowUserField');
|
||||
if (allowUserField) {
|
||||
const store = getOwner(this).lookup('store:main');
|
||||
store.findAll('user-field').then((result) => {
|
||||
if (result && result.content && result.content.length) {
|
||||
this.set('userFields', result.content.map((f) => {
|
||||
return {
|
||||
id: `user_field_${f.id}`,
|
||||
name: f.name
|
||||
};
|
||||
}));
|
||||
}
|
||||
});
|
||||
removePair(pair) {
|
||||
this.get('input.pairs').removeObject(pair);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||
import { on } from 'discourse-common/utils/decorators';
|
||||
import { newInput } from '../lib/custom-wizard';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'custom-inputs',
|
||||
valuePlaceholder: 'admin.wizard.value',
|
||||
|
||||
actions: {
|
||||
add() {
|
||||
if (!this.get('inputs')) {
|
||||
this.set('inputs', Ember.A());
|
||||
}
|
||||
this.get('inputs').pushObject(Ember.Object.create());
|
||||
if (!this.get('inputs')) this.set('inputs', Ember.A());
|
||||
this.get('inputs').pushObject(newInput(this.options));
|
||||
},
|
||||
|
||||
remove(input) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { observes, default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { observes, default as computed } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'wizard-custom-step',
|
||||
|
@ -16,9 +16,9 @@ export default Ember.Component.extend({
|
|||
});
|
||||
},
|
||||
|
||||
@computed('availableFields', 'wizard.steps')
|
||||
requiredContent(availableFields, steps) {
|
||||
let content = availableFields;
|
||||
@computed('wizardFields', 'wizard.steps')
|
||||
requiredContent(wizardFields, steps) {
|
||||
let content = wizardFields;
|
||||
let actions = [];
|
||||
|
||||
steps.forEach(s => {
|
||||
|
@ -37,19 +37,8 @@ export default Ember.Component.extend({
|
|||
return content;
|
||||
},
|
||||
|
||||
@computed
|
||||
requiredConnectorContent() {
|
||||
const label = (id) => I18n.t(`admin.wizard.step.required_data.connector.${id}`);
|
||||
return [
|
||||
{
|
||||
id: 'equals',
|
||||
label: label('equals')
|
||||
}
|
||||
];
|
||||
},
|
||||
|
||||
@computed('step.id', 'wizard.save_submissions')
|
||||
availableFields(currentStepId, saveSubmissions) {
|
||||
wizardFields(currentStepId, saveSubmissions) {
|
||||
const allSteps = this.get('wizard.steps');
|
||||
let steps = allSteps;
|
||||
let fields = [];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['container', 'import'],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed, on, observes } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'wizard-links',
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{{#if currentUser.admin}}
|
||||
{{nav-item route='adminWizards' label='admin.wizard.label'}}
|
||||
{{nav-item route='adminWizards' label='admin.wizard.nav'}}
|
||||
{{/if}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
import showModal from 'discourse/lib/show-modal';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
import CustomWizardApi from '../models/custom-wizard-api';
|
||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
import { generateSelectKitContent } from '../lib/custom-wizard';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
title: 'admin.wizard.after_time_modal.title',
|
||||
|
|
|
@ -2,4 +2,74 @@ function generateSelectKitContent(content) {
|
|||
return content.map(i => ({id: i, name: i}))
|
||||
}
|
||||
|
||||
export { generateSelectKitContent };
|
||||
function generateName(id) {
|
||||
return id.replace(/[_\-]+/g, ' ')
|
||||
.toLowerCase()
|
||||
.replace(/(^\w|\b\w)/g, (m) => m.toUpperCase())
|
||||
}
|
||||
|
||||
const profileFields = [
|
||||
'name',
|
||||
'user_avatar',
|
||||
'date_of_birth',
|
||||
'title',
|
||||
'locale',
|
||||
'location',
|
||||
'website',
|
||||
'bio_raw',
|
||||
'profile_background',
|
||||
'card_background',
|
||||
'theme_id'
|
||||
];
|
||||
|
||||
const connectors = [
|
||||
'equal'
|
||||
]
|
||||
|
||||
const actionTypes = [
|
||||
'create_topic',
|
||||
'update_profile',
|
||||
'create_topic',
|
||||
'update_profile',
|
||||
'send_message',
|
||||
'send_to_api',
|
||||
'add_to_group',
|
||||
'route_to',
|
||||
'open_composer'
|
||||
];
|
||||
|
||||
function newInput(options = {}) {
|
||||
let params = {
|
||||
pairs: Ember.A([newPair(options, 0)])
|
||||
}
|
||||
|
||||
if (options.hasOutput) {
|
||||
params['output'] = '';
|
||||
params['output_type'] = 'text';
|
||||
}
|
||||
|
||||
return Ember.Object.create(params);
|
||||
}
|
||||
|
||||
function newPair(options = {}, index) {
|
||||
let params = {
|
||||
index,
|
||||
key: '',
|
||||
key_type: 'text',
|
||||
value: '',
|
||||
value_type: 'text',
|
||||
connector: 'equal'
|
||||
}
|
||||
|
||||
return Ember.Object.create(params);
|
||||
}
|
||||
|
||||
export {
|
||||
generateSelectKitContent,
|
||||
profileFields,
|
||||
actionTypes,
|
||||
generateName,
|
||||
connectors,
|
||||
newInput,
|
||||
newPair
|
||||
};
|
|
@ -1,7 +1,8 @@
|
|||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
import EmberObject from "@ember/object";
|
||||
|
||||
const CustomWizardApi = Discourse.Model.extend({
|
||||
const CustomWizardApi = EmberObject.extend({
|
||||
@computed('name')
|
||||
redirectUri(name) {
|
||||
let nameParam = name.toString().dasherize();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { ajax } from 'discourse/lib/ajax';
|
||||
import EmberObject from "@ember/object";
|
||||
|
||||
const wizardProperties = [
|
||||
'name',
|
||||
|
@ -15,7 +16,7 @@ const wizardProperties = [
|
|||
'theme_id'
|
||||
];
|
||||
|
||||
const CustomWizard = Discourse.Model.extend({
|
||||
const CustomWizard = EmberObject.extend({
|
||||
save() {
|
||||
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import CustomWizard from '../models/custom-wizard';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
model(params) {
|
||||
return CustomWizard.submissions(params.wizard_id);
|
||||
},
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import CustomWizard from '../models/custom-wizard';
|
||||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { generateSelectKitContent } from '../lib/custom-wizard';
|
||||
import {
|
||||
generateSelectKitContent,
|
||||
profileFields,
|
||||
generateName
|
||||
} from '../lib/custom-wizard';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
beforeModel() {
|
||||
const param = this.paramsFor('adminWizard').wizard_id;
|
||||
const wizards = this.modelFor('admin-wizards-custom');
|
||||
|
@ -35,7 +40,8 @@ export default Discourse.Route.extend({
|
|||
return Ember.RSVP.all([
|
||||
this._getFieldTypes(model),
|
||||
this._getThemes(model),
|
||||
this._getApis(model)
|
||||
this._getApis(model),
|
||||
this._getUserFields(model)
|
||||
]);
|
||||
},
|
||||
|
||||
|
@ -60,6 +66,20 @@ export default Discourse.Route.extend({
|
|||
.then((result) => model.set('apis', result));
|
||||
},
|
||||
|
||||
_getUserFields(model) {
|
||||
return this.store.findAll('user-field').then((result) => {
|
||||
if (result && result.content) {
|
||||
let userContent = result.content.map((f) => {
|
||||
return { id: `user_field_${f.id}`, name: f.name};
|
||||
});
|
||||
let profileContent = profileFields.map((f) => {
|
||||
return { id: f, name: generateName(f) };
|
||||
});
|
||||
model.set('userFields', userContent.concat(profileContent));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
const newWizard = this.get('newWizard');
|
||||
const steps = model.get('steps') || [];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import CustomWizardApi from '../models/custom-wizard-api';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
queryParams: {
|
||||
refresh_list: {
|
||||
refreshModel: true
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import CustomWizardApi from '../models/custom-wizard-api';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
model() {
|
||||
return CustomWizardApi.list();
|
||||
},
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export default Discourse.Route.extend({
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
redirect() {
|
||||
this.transitionTo('adminWizard', 'first');
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import CustomWizard from '../models/custom-wizard';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
model() {
|
||||
return CustomWizard.all();
|
||||
},
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export default Discourse.Route.extend({
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
redirect() {
|
||||
this.transitionTo('adminWizardsCustom');
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import CustomWizard from '../models/custom-wizard';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
model() {
|
||||
return CustomWizard.all();
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import CustomWizard from '../models/custom-wizard';
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
export default DiscourseRoute.extend({
|
||||
model() {
|
||||
return CustomWizard.all();
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{{label}}
|
|
@ -27,7 +27,7 @@
|
|||
<div class="setting-value">
|
||||
{{combo-box
|
||||
value=action.title
|
||||
content=availableFields
|
||||
content=wizardFields
|
||||
nameProperty="label"
|
||||
isDisabled=action.custom_title_enabled
|
||||
none='admin.wizard.select_field'}}
|
||||
|
@ -48,7 +48,7 @@
|
|||
<div class="setting-value">
|
||||
{{combo-box
|
||||
value=action.post
|
||||
content=availableFields
|
||||
content=wizardFields
|
||||
nameProperty='label'
|
||||
isDisabled=action.post_builder
|
||||
none='admin.wizard.select_field'}}
|
||||
|
@ -65,7 +65,8 @@
|
|||
<h3>{{i18n 'admin.wizard.action.post_builder.label'}}</h3>
|
||||
</div>
|
||||
<div class="setting-value editor">
|
||||
{{d-editor value=action.post_template
|
||||
{{d-editor
|
||||
value=action.post_template
|
||||
placeholder='admin.wizard.action.interpolate_fields'
|
||||
classNames='post-builder-editor'}}
|
||||
<div>
|
||||
|
@ -119,12 +120,14 @@
|
|||
<div class="setting-label">
|
||||
<h3>{{i18n "admin.wizard.action.create_topic.tags"}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="setting-value">
|
||||
{{tag-chooser
|
||||
tags=action.tags
|
||||
filterable=true
|
||||
allowCreate=true
|
||||
isDisabled=action.custom_tag_enabled}}
|
||||
|
||||
<div class="setting-gutter">
|
||||
{{input type='checkbox' checked=action.custom_tag_enabled}}
|
||||
<span>{{i18n 'admin.wizard.action.custom_tag.label'}}</span>
|
||||
|
@ -157,11 +160,13 @@
|
|||
{{#if createTopic}}
|
||||
<div class="setting full">
|
||||
<label>{{i18n 'admin.wizard.action.add_fields' type='Topic'}}</label>
|
||||
{{wizard-custom-inputs inputs=action.add_fields
|
||||
valueContent=availableFields
|
||||
inputKey='admin.wizard.action.topic_attr'
|
||||
noneValue='admin.wizard.select_field'
|
||||
allowCustomField=true}}
|
||||
{{wizard-custom-inputs
|
||||
inputs=action.add_fields
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
options=(hash
|
||||
allowWizardField=true
|
||||
)}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
@ -170,20 +175,23 @@
|
|||
<div class="setting-label">
|
||||
<h3>{{i18n 'admin.wizard.required'}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="setting-value">
|
||||
{{combo-box
|
||||
value=action.required
|
||||
content=availableFields
|
||||
content=wizardFields
|
||||
nameProperty='label'
|
||||
none='admin.wizard.select_field'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<h3>{{i18n "admin.wizard.action.send_message.recipient"}}</h3>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{user-selector single="true"
|
||||
{{user-selector
|
||||
single="true"
|
||||
includeMentionableGroups="true"
|
||||
usernames=action.username
|
||||
allowedUsers="true"}}
|
||||
|
@ -192,21 +200,24 @@
|
|||
|
||||
<div class="setting full">
|
||||
<label>{{i18n "admin.wizard.action.add_fields" type='Message'}}</label>
|
||||
{{wizard-custom-inputs inputs=action.add_fields
|
||||
keyContent=availableFields
|
||||
valuePlaceholder='admin.wizard.action.topic_attr'}}
|
||||
{{wizard-custom-inputs
|
||||
inputs=action.add_fields
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if updateProfile}}
|
||||
<div class="setting full">
|
||||
<label>{{i18n "admin.wizard.action.add_fields" type='Profile'}}</label>
|
||||
{{wizard-custom-inputs inputs=action.profile_updates
|
||||
valueContent=profileFields
|
||||
keyContent=availableFields
|
||||
noneValue='admin.wizard.action.update_profile.profile_field'
|
||||
allowCustomField=true
|
||||
allowUserField=true}}
|
||||
{{wizard-custom-inputs
|
||||
inputs=action.profile_updates
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
options=(hash
|
||||
allowWizardField=true
|
||||
allowUserField=true
|
||||
)}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
@ -244,7 +255,8 @@
|
|||
<div class="setting-value">
|
||||
<label>{{i18n 'admin.wizard.action.post_builder.user_fields'}}{{builderUserFields}}</label>
|
||||
<label>{{i18n 'admin.wizard.action.post_builder.wizard_fields'}}{{builderWizardFields}}</label>
|
||||
{{textarea value=action.api_body
|
||||
{{textarea
|
||||
value=action.api_body
|
||||
placeholder=(i18n 'admin.wizard.action.interpolate_fields')}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -257,20 +269,36 @@
|
|||
</div>
|
||||
<div class="setting-value">
|
||||
{{combo-box
|
||||
value=action.group_id
|
||||
content=availableFields
|
||||
isDisabled=action.custom_group_enabled
|
||||
value=action.value
|
||||
content=wizardFields
|
||||
isDisabled=action.custom
|
||||
nameProperty="label"
|
||||
none='admin.wizard.select_field'}}
|
||||
|
||||
<div class="setting-gutter">
|
||||
{{input type='checkbox' checked=action.custom_group_enabled}}
|
||||
<span>{{i18n 'admin.wizard.action.add_to_group.custom_group'}}</span>
|
||||
|
||||
{{#if action.custom_group_enabled}}
|
||||
{{input value=action.group_id}}
|
||||
{{input value=action.custom}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<h3>{{i18n "admin.wizard.action.add_to_group.property"}}</h3>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{combo-box
|
||||
value=action.property
|
||||
content=groupPropertyTypes
|
||||
options=(hash
|
||||
none='admin.wizard.select_property'
|
||||
)}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if routeTo}}
|
||||
|
|
|
@ -98,7 +98,10 @@
|
|||
<div class="wizard-header small">
|
||||
{{i18n 'admin.wizard.field.choices_custom'}}
|
||||
</div>
|
||||
{{wizard-custom-inputs inputs=field.choices}}
|
||||
{{wizard-custom-inputs
|
||||
inputs=field.choices
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields}}
|
||||
{{/if}}
|
||||
|
||||
<div class="wizard-header small">
|
||||
|
@ -138,7 +141,28 @@
|
|||
<div class="setting-value">
|
||||
{{combo-box
|
||||
content=categoryPropertyTypes
|
||||
value=field.property}}
|
||||
value=field.property
|
||||
options=(hash
|
||||
none='admin.wizard.select_property'
|
||||
)}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="setting full">
|
||||
<div class="setting-label">
|
||||
<h3>{{i18n 'admin.wizard.field.prefill'}}</h3>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{wizard-custom-inputs
|
||||
inputs=field.prefill
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
options=(hash
|
||||
hasOutput=true
|
||||
enableConnectors=true
|
||||
allowWizardField=true
|
||||
allowUserField=true
|
||||
)}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<div class="type-selector">
|
||||
{{input-type-toggle
|
||||
activeType=activeType
|
||||
type='text'
|
||||
toggle=(action 'toggleType')}}
|
||||
|
||||
{{#if wizardEnabled}}
|
||||
{{input-type-toggle
|
||||
activeType=activeType
|
||||
type='wizard'
|
||||
toggle=(action 'toggleType')}}
|
||||
{{/if}}
|
||||
|
||||
{{#if userEnabled}}
|
||||
{{input-type-toggle
|
||||
activeType=activeType
|
||||
type='user'
|
||||
toggle=(action 'toggleType')}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="input">
|
||||
{{#if showText}}
|
||||
{{input
|
||||
type="text"
|
||||
value=value
|
||||
placeholder=(i18n textPlaceholder)}}
|
||||
{{/if}}
|
||||
|
||||
{{#if showWizard}}
|
||||
{{combo-box
|
||||
value=value
|
||||
content=wizardFields
|
||||
options=(hash
|
||||
none='admin.wizard.wizard_field'
|
||||
)}}
|
||||
{{/if}}
|
||||
|
||||
{{#if showUser}}
|
||||
{{combo-box
|
||||
value=value
|
||||
content=userFields
|
||||
options=(hash
|
||||
none='admin.wizard.user_field'
|
||||
)}}
|
||||
{{/if}}
|
||||
</div>
|
|
@ -0,0 +1,42 @@
|
|||
<div class="key input-block">
|
||||
{{wizard-custom-input-chooser
|
||||
inputType='key'
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
value=pair.key
|
||||
activeType=pair.key_type
|
||||
customPlaceholder=keyPlaceholder
|
||||
options=options}}
|
||||
</div>
|
||||
|
||||
<div class="connector">
|
||||
{{#if options.enableConnectors}}
|
||||
{{combo-box
|
||||
value=pair.connector
|
||||
content=connectors
|
||||
options=(hash
|
||||
none=connectorNone
|
||||
)}}
|
||||
{{/if}}
|
||||
|
||||
{{#if connectorKey}}
|
||||
<span class="key-connector">
|
||||
{{i18n connectorKey}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="value input-block">
|
||||
{{wizard-custom-input-chooser
|
||||
inputType='value'
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
value=pair.value
|
||||
activeType=pair.value_type
|
||||
customPlaceholder=valuePlaceholder
|
||||
options=options}}
|
||||
</div>
|
||||
|
||||
{{#if showRemove}}
|
||||
<a {{action removePair pair}} class="remove-pair">{{d-icon 'minus'}}</a>
|
||||
{{/if}}
|
|
@ -1,55 +1,50 @@
|
|||
<div class="key">
|
||||
{{#if keyContent}}
|
||||
{{combo-box value=input.key content=keyContent nameProperty="label" none=noneKey}}
|
||||
{{else}}
|
||||
{{input type="text" value=input.key placeholder=(i18n inputKey)}}
|
||||
{{#if options.hasOutput}}
|
||||
{{#if outputPrefixKey}}
|
||||
<div class="prefix">
|
||||
<span>{{i18n outputPrefixKey}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<div class="pairs">
|
||||
{{#each input.pairs as |pair|}}
|
||||
{{wizard-custom-input-pair
|
||||
pair=pair
|
||||
keyPlaceholder=keyPlaceholder
|
||||
valuePlaceholder=valuePlaceholder
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
options=options
|
||||
removePair=(action 'removePair')}}
|
||||
{{/each}}
|
||||
{{#if options.hasOutput}}
|
||||
<a {{action 'addPair'}} class="add-pair">{{d-icon 'plus'}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if options.hasOutput}}
|
||||
<div class="connector">
|
||||
{{#if connectorContent}}
|
||||
{{combo-box value=input.connector
|
||||
content=connectorContent
|
||||
nameProperty="label"
|
||||
none=connectorNone}}
|
||||
{{/if}}
|
||||
|
||||
{{#if connectorKey}}
|
||||
{{i18n connectorKey}}
|
||||
{{#if outputConnectorKey}}
|
||||
<span class="output-connector">
|
||||
{{i18n outputConnectorKey}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="value">
|
||||
{{#if valueContent}}
|
||||
{{combo-box value=input.value
|
||||
content=valueContent
|
||||
nameProperty="label"
|
||||
none=noneValue
|
||||
isDisabled=valueDisabled}}
|
||||
{{else}}
|
||||
{{input type="text" value=input.value placeholder=(i18n valuePlaceholder)}}
|
||||
<div class="output input-block">
|
||||
{{wizard-custom-input-chooser
|
||||
inputType='output'
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
value=input.output
|
||||
activeType=input.output_type
|
||||
customPlaceholder=outputPlaceholder
|
||||
options=options}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if allowCustomField}}
|
||||
<div class="text-divider">
|
||||
<span>{{i18n 'admin.wizard.or'}}</span>
|
||||
</div>
|
||||
|
||||
{{input type="text"
|
||||
value=input.value_custom
|
||||
placeholder=(i18n 'admin.wizard.custom_value_placeholder')
|
||||
disabled=customDisabled}}
|
||||
{{/if}}
|
||||
|
||||
{{#if allowUserField}}
|
||||
<div class="text-divider">
|
||||
<span>{{i18n 'admin.wizard.or'}}</span>
|
||||
</div>
|
||||
|
||||
{{combo-box value=input.user_field
|
||||
content=userFields
|
||||
none='admin.wizard.user_field_placeholder'}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{d-button action=remove actionParam=input icon='times' class='remove'}}
|
||||
{{d-button
|
||||
action=remove
|
||||
actionParam=input
|
||||
icon='times'
|
||||
class='remove-input'}}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
{{#each inputs as |input|}}
|
||||
{{wizard-custom-input input=input
|
||||
valueContent=valueContent
|
||||
keyContent=keyContent
|
||||
{{wizard-custom-input
|
||||
input=input
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
keyPlaceholder=keyPlaceholder
|
||||
valuePlaceholder=valuePlaceholder
|
||||
connectorContent=connectorContent
|
||||
connectorKey=connectorKey
|
||||
noneValue=noneValue
|
||||
valuePlaceholder=valuePlaceholder
|
||||
allowCustomField=allowCustomField
|
||||
allowUserField=allowUserField
|
||||
options=options
|
||||
remove=(action 'remove')}}
|
||||
{{/each}}
|
||||
|
||||
<div class="add-custom-input">
|
||||
{{d-button action='add' label='admin.wizard.add' icon='plus'}}
|
||||
</div>
|
|
@ -39,7 +39,9 @@
|
|||
<h3>{{i18n 'admin.wizard.step.description'}}</h3>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{d-editor value=step.raw_description placeholder="admin.wizard.custom_text_placeholder"}}
|
||||
{{d-editor
|
||||
value=step.raw_description
|
||||
placeholder="admin.wizard.custom_text_placeholder"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -48,10 +50,16 @@
|
|||
<h3>{{i18n 'admin.wizard.step.required_data.label'}}</h3>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{wizard-custom-inputs inputs=step.required_data
|
||||
inputKey='admin.wizard.step.required_data.key'
|
||||
valueContent=requiredContent
|
||||
connectorContent=requiredConnectorContent}}
|
||||
{{wizard-custom-inputs
|
||||
inputs=step.required_data
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
keyPlaceholder="admin.wizard.submission_key"
|
||||
options=(hash
|
||||
enableConnectors=true
|
||||
allowWizardField='value'
|
||||
allowUserField='value'
|
||||
)}}
|
||||
{{#if step.required_data}}
|
||||
<div class="required-data-message">
|
||||
<div class="label">
|
||||
|
@ -68,24 +76,36 @@
|
|||
<h3>{{i18n 'admin.wizard.step.permitted_params.label'}}</h3>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{wizard-custom-inputs inputs=step.permitted_params
|
||||
inputKey='admin.wizard.step.permitted_params.key'
|
||||
valuePlaceholder='admin.wizard.step.permitted_params.value'
|
||||
{{wizard-custom-inputs
|
||||
inputs=step.permitted_params
|
||||
userFields=userFields
|
||||
wizardFields=wizardFields
|
||||
keyPlaceholder='admin.wizard.param_key'
|
||||
valuePlaceholder='admin.wizard.submission_key'
|
||||
connectorKey='admin.wizard.step.permitted_params.connector'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{wizard-links type="field" current=currentField items=step.fields}}
|
||||
|
||||
{{#if currentField}}
|
||||
{{wizard-custom-field field=currentField types=wizard.fieldTypes removeField="removeField"}}
|
||||
{{wizard-custom-field
|
||||
field=currentField
|
||||
types=wizard.fieldTypes
|
||||
removeField="removeField"
|
||||
userFields=wizard.userFields
|
||||
wizardFields=wizardFields}}
|
||||
{{/if}}
|
||||
|
||||
{{wizard-links type="action" current=currentAction items=step.actions}}
|
||||
|
||||
{{#if currentAction}}
|
||||
{{wizard-custom-action action=currentAction
|
||||
{{wizard-custom-action
|
||||
action=currentAction
|
||||
wizard=wizard
|
||||
removeAction="removeAction"
|
||||
availableFields=availableFields}}
|
||||
wizardFields=wizardFields
|
||||
userFields=wizard.userFields}}
|
||||
{{/if}}
|
||||
|
||||
<label>{{i18n 'admin.wizard.action.available_fields'}}</label>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed, observes } from 'discourse-common/utils/decorators';
|
||||
import { renderAvatar } from 'discourse/helpers/user-avatar';
|
||||
import userSearch from '../lib/user-search';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import ComposerEditor from 'discourse/components/composer-editor';
|
||||
import { default as computed, on } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed, on } from 'discourse-common/utils/decorators';
|
||||
import { findRawTemplate } from "discourse/lib/raw-templates";
|
||||
import { throttle } from "@ember/runloop";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { observes } from 'ember-addons/ember-computed-decorators';
|
||||
import { observes } from 'discourse-common/utils/decorators';
|
||||
import Category from 'discourse/models/category';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed, observes } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
showPreview: false,
|
||||
|
|
5
assets/javascripts/wizard/components/wizard-field-group.js.es6
Normale Datei
5
assets/javascripts/wizard/components/wizard-field-group.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
|||
export default Ember.Component.extend({
|
||||
didInsertElement() {
|
||||
console.log(this.field)
|
||||
}
|
||||
})
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint no-undef: 0 */
|
||||
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import computed from "discourse-common/utils/decorators";
|
||||
import { siteDir, isRTL, isLTR } from "discourse/lib/text-direction";
|
||||
|
||||
export default Ember.TextField.extend({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default {
|
||||
name: 'custom-routes',
|
||||
|
@ -227,7 +227,8 @@ export default {
|
|||
'image',
|
||||
'user-selector',
|
||||
'text-only',
|
||||
'composer'
|
||||
'composer',
|
||||
'group'
|
||||
];
|
||||
|
||||
FieldModel.reopen({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
import getUrl from 'discourse-common/lib/get-url';
|
||||
import WizardField from 'wizard/models/wizard-field';
|
||||
import { ajax } from 'wizard/lib/ajax';
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{{combo-box
|
||||
content=wizard.groups
|
||||
value=field.value
|
||||
onChange=(action (mut field.value))
|
||||
options=(hash
|
||||
none='group.select'
|
||||
)}}
|
|
@ -872,3 +872,7 @@ input.input-location, div.input-location {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-kit.combo-box.group-dropdown {
|
||||
min-width: 220px;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
}
|
||||
|
||||
button {
|
||||
margin-top: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -88,11 +87,6 @@
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-input .remove {
|
||||
margin-left: 10px;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,11 +188,45 @@
|
|||
|
||||
.custom-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
|
||||
.type-selector a {
|
||||
color: $primary;
|
||||
margin-right: 10px;
|
||||
|
||||
&.active {
|
||||
color: $tertiary;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.pairs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.add-pair {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.remove-pair {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: -30px;
|
||||
}
|
||||
}
|
||||
|
||||
.pair {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
position: relative;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.d-icon {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -211,17 +239,37 @@
|
|||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.select-kit {
|
||||
width: 232px !important;
|
||||
.input-block, .select-kit, input {
|
||||
width: 150px;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.remove {
|
||||
margin: 0 auto;
|
||||
align-self: flex-start;
|
||||
button.remove-input {
|
||||
margin: 21px 0 0 10px;
|
||||
}
|
||||
|
||||
.connector {
|
||||
margin: 0 10px;
|
||||
|
||||
.select-kit {
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.key-connector {
|
||||
padding-bottom: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.output-connector {
|
||||
margin-top: 25px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.prefix {
|
||||
position: absolute;
|
||||
left: -20px;
|
||||
top: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ en:
|
|||
admin_js:
|
||||
admin:
|
||||
wizard:
|
||||
label: "Wizards"
|
||||
label: "Wizard"
|
||||
nav: "Wizards"
|
||||
new: "New"
|
||||
custom_label: "Custom"
|
||||
submissions_label: "Submissions"
|
||||
|
@ -46,17 +47,30 @@ en:
|
|||
url: "Url"
|
||||
key: "Key"
|
||||
or: "Or"
|
||||
if: "if"
|
||||
value: "Value"
|
||||
output: "Output"
|
||||
property: "Property"
|
||||
text: "text"
|
||||
profile: "profile"
|
||||
id: "Id"
|
||||
id_placeholder: "Underscored. Cannot be changed."
|
||||
key_placeholder: "Translation key"
|
||||
custom_text_placeholder: "Overrides translation"
|
||||
custom_field_placeholder: "Custom Field"
|
||||
custom_value_placeholder: "Custom Value"
|
||||
user_field_placeholder: "User Field"
|
||||
type: "Type"
|
||||
none: "Make a selection"
|
||||
user_field: "User Field"
|
||||
wizard_field: "Wizard Field"
|
||||
select_field: "Select Field"
|
||||
select_property: "Select Property"
|
||||
profile_field: "Profile Field"
|
||||
submission_key: 'submission key'
|
||||
param_key: 'param'
|
||||
connector:
|
||||
none: "op"
|
||||
prefill: "prefill"
|
||||
equal: "="
|
||||
|
||||
error:
|
||||
name_required: "Wizards must have a name."
|
||||
steps_required: "Wizards must have at least one step."
|
||||
|
@ -68,6 +82,7 @@ en:
|
|||
field:
|
||||
need_choices: "All dropdowns need choices."
|
||||
choices_label_empty: "Custom choice labels cannot be empty."
|
||||
|
||||
step:
|
||||
header: "Steps"
|
||||
title: "Title"
|
||||
|
@ -76,15 +91,11 @@ en:
|
|||
description: "Description"
|
||||
required_data:
|
||||
label: "Required Data"
|
||||
key: 'Submission key'
|
||||
connector:
|
||||
equals: "Equals"
|
||||
not_permitted_message: "Message shown when required data not present"
|
||||
permitted_params:
|
||||
label: "Permitted Params"
|
||||
key: 'Param'
|
||||
value: 'Submission key'
|
||||
connector: "Save as"
|
||||
connector: "save as"
|
||||
|
||||
field:
|
||||
type: "Choose a type"
|
||||
header: "Fields"
|
||||
|
@ -110,6 +121,8 @@ en:
|
|||
category: "Category"
|
||||
limit: "Limit"
|
||||
property: "Property"
|
||||
prefill: "Prefill"
|
||||
|
||||
action:
|
||||
header: "Actions<sup>*</sup>"
|
||||
include: "Include Fields"
|
||||
|
@ -132,7 +145,6 @@ en:
|
|||
tags: "Tags"
|
||||
update_profile:
|
||||
label: "Update Profile"
|
||||
profile_field: "Profile Field"
|
||||
post_builder:
|
||||
checkbox: "Post Builder"
|
||||
label: "Builder"
|
||||
|
@ -142,8 +154,9 @@ en:
|
|||
add_to_group:
|
||||
label: "Add to Group"
|
||||
group: "Group"
|
||||
group_selection: "Group Selection"
|
||||
custom_group: "Custom Group"
|
||||
group_selection: "Field"
|
||||
custom_group: "Custom"
|
||||
property: "Property"
|
||||
route_to:
|
||||
label: "Route To"
|
||||
url: "Url"
|
||||
|
@ -151,7 +164,6 @@ en:
|
|||
custom_title: "Custom Title"
|
||||
custom_category:
|
||||
label: "Custom Category"
|
||||
wizard_field: "Wizard Field"
|
||||
user_field: "User Field"
|
||||
custom_tag:
|
||||
label: "Custom Tag"
|
||||
|
@ -230,6 +242,9 @@ en:
|
|||
file_size_error: "The file must be JSON and 512kb or less"
|
||||
|
||||
wizard_js:
|
||||
group:
|
||||
select: "Select a group"
|
||||
|
||||
location:
|
||||
name:
|
||||
title: "Name (optional)"
|
||||
|
|
|
@ -44,6 +44,9 @@ class CustomWizard::Builder
|
|||
|
||||
USER_FIELDS = ['name', 'username', 'email', 'date_of_birth', 'title', 'locale']
|
||||
PROFILE_FIELDS = ['location', 'website', 'bio_raw', 'profile_background', 'card_background']
|
||||
OPERATORS = {
|
||||
'equal': '=='
|
||||
}
|
||||
|
||||
def self.fill_placeholders(string, user, data)
|
||||
result = string.gsub(/u\{(.*?)\}/) do |match|
|
||||
|
@ -99,8 +102,9 @@ class CustomWizard::Builder
|
|||
permitted_data = {}
|
||||
|
||||
permitted_params.each do |p|
|
||||
params_key = p['key'].to_sym
|
||||
submission_key = p['value'].to_sym
|
||||
pair = p['pairs'].first
|
||||
params_key = pair['key'].to_sym
|
||||
submission_key = pair['value'].to_sym
|
||||
permitted_data[submission_key] = params[params_key] if params[params_key]
|
||||
end
|
||||
|
||||
|
@ -110,15 +114,25 @@ class CustomWizard::Builder
|
|||
end
|
||||
end
|
||||
|
||||
if required_data = step_template['required_data']
|
||||
if !@submissions.last && required_data.present?
|
||||
step.permitted = false
|
||||
next
|
||||
if (required_data = step_template['required_data']).present?
|
||||
has_required_data = true
|
||||
pairs =
|
||||
|
||||
required_data.each do |required|
|
||||
required['pairs'].each do |pair|
|
||||
if pair['key'].blank? || pair['value'].blank?
|
||||
has_required_data = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
required_data.each do |rd|
|
||||
if rd['connector'] === 'equals'
|
||||
step.permitted = @submissions.last[rd['key']] == @submissions.last[rd['value']]
|
||||
if has_required_data
|
||||
if !@submissions.last
|
||||
step.permitted = false
|
||||
else
|
||||
required_data.each do |required|
|
||||
pairs = required['pairs'].map { |p| p['value'] = @submissions.last[p['value']] }
|
||||
step.permitted = false unless validate_pairs(pairs)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -127,6 +141,7 @@ class CustomWizard::Builder
|
|||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if step_template['fields'] && step_template['fields'].length
|
||||
step_template['fields'].each do |field_template|
|
||||
|
@ -217,18 +232,7 @@ class CustomWizard::Builder
|
|||
params[:value] = submission[field_template['id']] if submission[field_template['id']]
|
||||
end
|
||||
|
||||
## If a field updates a profile field, load the current value
|
||||
if step_template['actions'] && step_template['actions'].any?
|
||||
profile_actions = step_template['actions'].select { |a| a['type'] === 'update_profile' }
|
||||
|
||||
if profile_actions.any?
|
||||
profile_actions.each do |action|
|
||||
if update = action['profile_updates'].select { |u| u['key'] === field_template['id'] }.first
|
||||
params[:value] = prefill_profile_field(update) || params[:value]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
params[:value] = prefill_field(field_template, step_template) || params[:value]
|
||||
|
||||
if field_template['type'] === 'checkbox'
|
||||
params[:value] = standardise_boolean(params[:value])
|
||||
|
@ -254,6 +258,8 @@ class CustomWizard::Builder
|
|||
@wizard.needs_groups = true
|
||||
end
|
||||
|
||||
puts "ADDING FIELD: #{params.inspect}"
|
||||
|
||||
field = step.add_field(params)
|
||||
|
||||
if field_template['type'] === 'dropdown'
|
||||
|
@ -261,23 +267,80 @@ class CustomWizard::Builder
|
|||
end
|
||||
end
|
||||
|
||||
def prefill_profile_field(update)
|
||||
attribute = update['value']
|
||||
custom_field = update['value_custom']
|
||||
user_field = update['user_field']
|
||||
def prefill_field(field_template, step_template)
|
||||
if (prefill = field_template['prefill']).present?
|
||||
output = nil
|
||||
|
||||
if user_field || custom_field
|
||||
UserCustomField.where(user_id: @wizard.user.id, name: user_field || custom_field).pluck(:value).first
|
||||
elsif UserProfile.column_names.include? attribute
|
||||
UserProfile.find_by(user_id: @wizard.user.id).send(attribute)
|
||||
elsif User.column_names.include? attribute
|
||||
User.find(@wizard.user.id).send(attribute)
|
||||
prefill.each do |item|
|
||||
puts "PREFIL: #{item.inspect}"
|
||||
if validate_pairs(item['pairs'])
|
||||
puts "OUTPUT: #{get_field(item['output'], item['output_type'])}"
|
||||
output = get_field(item['output'], item['output_type'])
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
else
|
||||
actions = step_template['actions']
|
||||
|
||||
if actions && actions.any?
|
||||
profile_actions = actions.select { |a| a['type'] === 'update_profile' } || []
|
||||
|
||||
profile_actions.each do |action|
|
||||
update = action['profile_updates'].select { |u| u['key'] === field_template['id'] }.first
|
||||
get_user_field(update['value']) if update
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def validate_pairs(pairs)
|
||||
failed = false
|
||||
pairs.each do |pair|
|
||||
puts "PAIR: #{pair.inspect}"
|
||||
key = get_field(pair['key'], pair['key_type'])
|
||||
value = get_field(pair['value'], pair['value_type'])
|
||||
puts "KEY VALUE: #{key.inspect}; #{value.inspect}"
|
||||
failed = true unless key.public_send(get_operator(pair['connector']), value)
|
||||
end
|
||||
!failed
|
||||
end
|
||||
|
||||
def get_operator(connector)
|
||||
OPERATORS[connector] || '=='
|
||||
end
|
||||
|
||||
def get_field(value, type)
|
||||
method = "get_#{type}_field"
|
||||
|
||||
if self.respond_to?(method)
|
||||
self.send(method, value)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def get_wizard_field(value)
|
||||
@submissions.last &&
|
||||
!@submissions.last.key?("submitted_at") &&
|
||||
@submissions.last[value]
|
||||
end
|
||||
|
||||
def get_user_field(value)
|
||||
puts "GETTING USER FIELD: #{value.inspect}"
|
||||
if value.include?('user_field_')
|
||||
UserCustomField.where(user_id: @wizard.user.id, name: value).pluck(:value).first
|
||||
elsif UserProfile.column_names.include? value
|
||||
UserProfile.find_by(user_id: @wizard.user.id).send(value)
|
||||
elsif User.column_names.include? value
|
||||
User.find(@wizard.user.id).send(value)
|
||||
end
|
||||
end
|
||||
|
||||
def build_dropdown_list(field, template)
|
||||
field.dropdown_none = template['dropdown_none'] if template['dropdown_none']
|
||||
self.send("build_dropdown_#{template['choices_type']}", field, template)
|
||||
method = "build_dropdown_#{template['choices_type']}"
|
||||
self.send(method, field, template) if self.respond_to?(method)
|
||||
end
|
||||
|
||||
def build_dropdown_custom(field, template)
|
||||
|
@ -552,8 +615,8 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
def add_to_group(user, action, data)
|
||||
if group_id = data[action['group_id']]
|
||||
if group = Group.find(group_id)
|
||||
if value = data[action['value']]
|
||||
if group = Group.where("#{action['property']} = '#{value}'").first
|
||||
group.add(user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class CustomWizard::Field
|
||||
def self.types
|
||||
@types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'image', 'text', 'textarea', 'text-only', 'upload', 'user-selector']
|
||||
@types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'group', 'image', 'text', 'textarea', 'text-only', 'upload', 'user-selector']
|
||||
end
|
||||
|
||||
def self.require_assets
|
||||
|
|
|
@ -21,7 +21,8 @@ class CustomWizard::Wizard
|
|||
:required,
|
||||
:prompt_completion,
|
||||
:restart_on_revisit,
|
||||
:needs_categories
|
||||
:needs_categories,
|
||||
:needs_groups
|
||||
|
||||
def initialize(user=nil, attrs = {})
|
||||
@steps = []
|
||||
|
@ -29,6 +30,7 @@ class CustomWizard::Wizard
|
|||
@first_step = nil
|
||||
@required = false
|
||||
@needs_categories = false
|
||||
@needs_groups = false
|
||||
|
||||
attrs.each do |key, value|
|
||||
setter = "#{key}="
|
||||
|
@ -141,6 +143,10 @@ class CustomWizard::Wizard
|
|||
@categories ||= ::Site.new(Guardian.new(@user)).categories
|
||||
end
|
||||
|
||||
def groups
|
||||
@groups ||= ::Site.new(Guardian.new(@user)).groups
|
||||
end
|
||||
|
||||
def self.after_signup
|
||||
rows = PluginStoreRow.where(plugin_name: 'custom_wizard')
|
||||
wizards = [*rows].select { |r| r.value['after_signup'] }
|
||||
|
|
|
@ -14,6 +14,7 @@ class CustomWizardSerializer < ::WizardSerializer
|
|||
has_one :user, serializer: ::BasicUserSerializer, embed: :objects
|
||||
has_many :steps, serializer: ::CustomWizardStepSerializer, embed: :objects
|
||||
has_many :categories, serializer: ::BasicCategorySerializer, embed: :objects
|
||||
has_many :groups, serializer: ::BasicGroupSerializer, embed: :objects
|
||||
|
||||
def completed
|
||||
object.completed?
|
||||
|
@ -41,6 +42,10 @@ class CustomWizardSerializer < ::WizardSerializer
|
|||
object.needs_categories
|
||||
end
|
||||
|
||||
def include_groups?
|
||||
object.needs_groups
|
||||
end
|
||||
|
||||
def uncategorized_category_id
|
||||
SiteSetting.uncategorized_category_id
|
||||
end
|
||||
|
|
Laden …
In neuem Issue referenzieren