1
0
Fork 0
Dieser Commit ist enthalten in:
Angus McLeod 2020-04-05 11:37:09 +10:00
Ursprung 666c4f1eb4
Commit 7b3ed54f29
46 geänderte Dateien mit 363 neuen und 496 gelöschten Zeilen

Datei anzeigen

@ -1,13 +1,9 @@
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators'; import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
import { equal, not, empty, or } from "@ember/object/computed"; import { equal, not, empty, or } from "@ember/object/computed";
import { import { actionTypes, generateName, selectKitContent, profileFields } from '../lib/wizard';
actionTypes, import Component from "@ember/component";
generateName,
selectKitContent,
profileFields
} from '../lib/wizard';
export default Ember.Component.extend({ export default Component.extend({
classNames: 'wizard-custom-action', classNames: 'wizard-custom-action',
types: actionTypes.map(t => ({ id: t, name: generateName(t) })), types: actionTypes.map(t => ({ id: t, name: generateName(t) })),
createTopic: equal('action.type', 'create_topic'), createTopic: equal('action.type', 'create_topic'),

Datei anzeigen

@ -1,8 +1,9 @@
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators'; import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
import { equal, not, or } from "@ember/object/computed"; import { equal, not, or } from "@ember/object/computed";
import { selectKitContent } from '../lib/wizard'; import { selectKitContent } from '../lib/wizard';
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNames: 'wizard-custom-field', classNames: 'wizard-custom-field',
isDropdown: equal('field.type', 'dropdown'), isDropdown: equal('field.type', 'dropdown'),
isUpload: equal('field.type', 'upload'), isUpload: equal('field.type', 'upload'),
@ -10,13 +11,9 @@ export default Ember.Component.extend({
isGroup: equal('field.type', 'group'), isGroup: equal('field.type', 'group'),
isTag: equal('field.type', 'tag'), isTag: equal('field.type', 'tag'),
disableId: not('field.isNew'), disableId: not('field.isNew'),
choicesTypes: selectKitContent(['translation', 'custom']),
choicesTranslation: equal('field.choices_type', 'translation'),
choicesCustom: equal('field.choices_type', 'custom'),
categoryPropertyTypes: selectKitContent(['id', 'slug']), categoryPropertyTypes: selectKitContent(['id', 'slug']),
prefillEnabled: or('isCategory', 'isTag', 'isGroup'), prefillEnabled: or('isCategory', 'isTag', 'isGroup', 'isDropdown'),
contentEnabled: or('isCategory', 'isTag', 'isGroup'), contentEnabled: or('isCategory', 'isTag', 'isGroup', 'isDropdown'),
hasAdvanced: or('isCategory', 'isTag', 'isGroup'),
@discourseComputed('field.type') @discourseComputed('field.type')
isInput: (type) => type === 'text' || type === 'textarea' || type === 'url', isInput: (type) => type === 'text' || type === 'textarea' || type === 'url',
@ -33,34 +30,41 @@ export default Ember.Component.extend({
}, },
@discourseComputed('field.type') @discourseComputed('field.type')
prefillOptions(fieldType) { contentOptions(fieldType) {
if (!this.prefillEnabled) return {};
let options = { let options = {
hasOutput: true, wizardFieldSelection: true,
textSelection: 'key,value', textSelection: 'key,value',
wizardSelection: true,
userFieldSelection: 'key,value' userFieldSelection: 'key,value'
} }
options[`${fieldType}Selection`] = 'output'; if (this.isDropdown) {
options[`outputDefaultSelection`] = fieldType; options.inputTypes = 'pair,assignment';
options.pairConnector = 'equal';
options.keyPlaceholder = 'admin.wizard.key';
options.valuePlaceholder = 'admin.wizard.value';
}
return options; return options;
}, },
@discourseComputed('field.type') @discourseComputed('field.type')
contentOptions(fieldType) { prefillOptions(fieldType) {
if (!this.contentEnabled) return {};
let options = { let options = {
hasOutput: true, wizardFieldSelection: true,
wizardSelection: 'key,value', textSelection: 'key,value',
userFieldSelection: 'key,value', userFieldSelection: 'key,value'
textSelection: 'key,value' }
if (!this.isDropdown) {
let selectionType = {
category: 'category',
tag: 'tag',
group: 'group',
dropdown: 'text'
}[fieldType];
options[`${selectionType}Selection`] = 'output';
options.outputDefaultSelection = selectionType;
} }
options[`${fieldType}Selection`] = 'output';
return options; return options;
}, },

Datei anzeigen

@ -1,8 +1,9 @@
import { observes, on, default as discourseComputed } from 'discourse-common/utils/decorators'; import { observes, on, default as discourseComputed } from 'discourse-common/utils/decorators';
import { not } from "@ember/object/computed"; import { not } from "@ember/object/computed";
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNames: 'wizard-custom-step', classNames: 'wizard-custom-step',
currentField: null, currentField: null,
currentAction: null, currentAction: null,

Datei anzeigen

@ -1,6 +1,9 @@
export default Ember.Component.extend({ import Component from "@ember/component";
import { A } from "@ember/array";
export default Component.extend({
classNames: ['container', 'export'], classNames: ['container', 'export'],
selected: Ember.A(), selected: A(),
actions: { actions: {
checkChanged(event) { checkChanged(event) {

Datei anzeigen

@ -1,11 +1,13 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import { default as computed } from 'discourse-common/utils/decorators'; import { default as discourseComputed } from 'discourse-common/utils/decorators';
import { notEmpty } from "@ember/object/computed";
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNames: ['container', 'import'], classNames: ['container', 'import'],
hasLogs: Ember.computed.notEmpty('logs'), hasLogs: notEmpty('logs'),
@computed('successIds', 'failureIds') @discourseComputed('successIds', 'failureIds')
logs(successIds, failureIds) { logs(successIds, failureIds) {
let logs = []; let logs = [];

Datei anzeigen

@ -1,11 +1,13 @@
import { default as computed, on, observes } from 'discourse-common/utils/decorators'; import { default as discourseComputed, on, observes } from 'discourse-common/utils/decorators';
import { notEmpty } from "@ember/object/computed"; import { notEmpty } from "@ember/object/computed";
import { scheduleOnce } from "@ember/runloop"; import { scheduleOnce, bind } from "@ember/runloop";
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import Component from "@ember/component";
import { A } from "@ember/array";
export default Ember.Component.extend({ export default Component.extend({
classNameBindings: [':wizard-links', 'type'], classNameBindings: [':wizard-links', 'type'],
items: Ember.A(), items: A(),
anyLinks: notEmpty('links'), anyLinks: notEmpty('links'),
@on('didInsertElement') @on('didInsertElement')
@ -18,7 +20,7 @@ export default Ember.Component.extend({
$(this.element).find("ul").sortable({tolerance: 'pointer'}).on('sortupdate', (e, ui) => { $(this.element).find("ul").sortable({tolerance: 'pointer'}).on('sortupdate', (e, ui) => {
const itemId = ui.item.data('id'); const itemId = ui.item.data('id');
const index = ui.item.index(); const index = ui.item.index();
Ember.run.bind(this, this.updateItemOrder(itemId, index)); bind(this, this.updateItemOrder(itemId, index));
}); });
}, },
@ -30,10 +32,10 @@ export default Ember.Component.extend({
scheduleOnce('afterRender', this, () => this.applySortable()); scheduleOnce('afterRender', this, () => this.applySortable());
}, },
@computed('type') @discourseComputed('type')
header: (type) => `admin.wizard.${type}.header`, header: (type) => `admin.wizard.${type}.header`,
@computed('items.@each.id', 'current') @discourseComputed('items.@each.id', 'current')
links(items, current) { links(items, current) {
if (!items) return; if (!items) return;
@ -64,8 +66,8 @@ export default Ember.Component.extend({
let params = { id: newId, isNew: true }; let params = { id: newId, isNew: true };
if (type === 'step') { if (type === 'step') {
params['fields'] = Ember.A(); params['fields'] = A();
params['actions'] = Ember.A(); params['actions'] = A();
}; };
const newItem = EmberObject.create(params); const newItem = EmberObject.create(params);

Datei anzeigen

@ -1,13 +1,16 @@
import { computed, set } from "@ember/object"; import { computed, set } from "@ember/object";
import { alias, equal } from "@ember/object/computed"; import { alias, equal, or } from "@ember/object/computed";
import { newPair, connectorContent, inputTypesContent } from '../lib/wizard-mapper'; import { newPair, connectorContent, inputTypesContent } from '../lib/wizard-mapper';
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNameBindings: [':mapper-input', 'type'], classNameBindings: [':mapper-input', 'type'],
inputType: alias('input.type'), inputType: alias('input.type'),
isConditional: equal('inputType', 'conditional'), isConditional: equal('inputType', 'conditional'),
hasOutput: alias('options.hasOutput'), isAssignment: equal('inputType', 'assignment'),
hasPairs: computed('hasOutput', 'isConditional', function() { return !this.hasOutput || this.isConditional; }), isPair: equal('inputType', 'pair'),
hasOutput: or('isConditional', 'isAssignment'),
hasPairs: or('isConditional', 'isPair'),
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) }),

Datei anzeigen

@ -1,15 +1,12 @@
import { connectorContent } from '../lib/wizard-mapper'; import { connectorContent } from '../lib/wizard-mapper';
import { gt, or, alias } from "@ember/object/computed"; import { gt, or, alias } from "@ember/object/computed";
import { computed, observes } from "@ember/object"; import { computed, observes } from "@ember/object";
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNameBindings: [':mapper-pair', 'hasConnector::no-connector'], classNameBindings: [':mapper-pair', 'hasConnector::no-connector'],
firstPair: gt('pair.index', 0), firstPair: gt('pair.index', 0),
showRemove: alias('firstPair'), showRemove: alias('firstPair'),
showJoin: computed('pair.pairCount', function() { showJoin: computed('pair.pairCount', function() { return this.pair.index < (this.pair.pairCount - 1) }),
return this.pair.index < (this.pair.pairCount - 1); connectors: computed(function() { return connectorContent('pair', this.inputType, this.options) })
}),
connectors: computed(function() {
return connectorContent('pair', this.inputType, this.options);
})
}); });

Datei anzeigen

@ -1,27 +1,17 @@
import discourseComputed from 'discourse-common/utils/decorators'; import discourseComputed from 'discourse-common/utils/decorators';
import { snakeCase } from '../lib/wizard';
import { selectionTypes } from '../lib/wizard-mapper';
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
tagName: 'a', tagName: 'a',
classNameBindings: ['type', 'active'], classNameBindings: ['type', 'active'],
@discourseComputed('type', 'activeType') @discourseComputed('type', 'activeType')
active(type, activeType) { active(type, activeType) { return type === activeType },
return type === activeType;
},
@discourseComputed('type') @discourseComputed('type')
label(type) { label(type) { return I18n.t(`admin.wizard.selector.label.${snakeCase(type)}`) },
let map = {
text: I18n.t('admin.wizard.text'),
wizard: I18n.t('admin.wizard.label'),
userField: I18n.t('users_lowercase.one'),
category: I18n.t('categories.category'),
tag: I18n.t('tagging.tags'),
group: I18n.t('groups.title.one'),
user: I18n.t('users_lowercase.other')
};
return map[type].toLowerCase();
},
click() { click() {
this.toggle(this.type) this.toggle(this.type)

Datei anzeigen

@ -1,15 +1,38 @@
import { alias } from "@ember/object/computed"; import { alias, or } 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 } from "discourse-common/utils/decorators";
import { getOwner } from 'discourse-common/lib/get-owner'; import { getOwner } from 'discourse-common/lib/get-owner';
import { defaultSelectionType } from '../lib/wizard-mapper'; import { defaultSelectionType, selectionTypes } from '../lib/wizard-mapper';
import { snakeCase, selectKitContent } from '../lib/wizard';
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNames: 'mapper-selector', classNames: 'mapper-selector',
groups: alias('site.groups'), groups: alias('site.groups'),
categories: computed(function() { categories: computed(function() { return selectKitContent(this.site.categories) }),
return this.site.categories.map(c => ({ id: c.id, name: c.name })); showText: computed('activeType', function() { return this.showInput('text') }),
}), showWizardField: computed('activeType', function() { return this.showInput('wizardField') }),
showUserField: computed('activeType', function() { return this.showInput('userField') }),
showCategory: computed('activeType', function() { return this.showInput('category') }),
showTag: computed('activeType', function() { return this.showInput('tag') }),
showGroup: computed('activeType', function() { return this.showInput('group') }),
showUser: computed('activeType', function() { return this.showInput('user') }),
showList: computed('activeType', function() { return this.showInput('list') }),
showComboBox: or('showWizardField', 'showUserField'),
showMultiSelect: or('showCategory', 'showGroup'),
textEnabled: computed('options.textSelection', 'inputType', function() { return this.optionEnabled('textSelection') }),
wizardFieldEnabled: computed('options.wizardFieldSelection', 'inputType', function() { return this.optionEnabled('wizardFieldSelection') }),
userFieldEnabled: computed('options.userFieldSelection', 'inputType', function() { return this.optionEnabled('userFieldSelection') }),
categoryEnabled: computed('options.categorySelection', 'inputType', function() { return this.optionEnabled('categorySelection') }),
tagEnabled: computed('options.tagSelection', 'inputType', function() { return this.optionEnabled('tagSelection') }),
groupEnabled: computed('options.groupSelection', 'inputType', function() { return this.optionEnabled('groupSelection') }),
userEnabled: computed('options.userSelection', 'inputType', function() { return this.optionEnabled('userSelection') }),
listEnabled: computed('options.listSelection', 'inputType', function() { return this.optionEnabled('listSelection') }),
@discourseComputed('activeType')
selectorTypes(activeType) {
return selectionTypes.filter(type => (this[`${type}Enabled`]));
},
@discourseComputed @discourseComputed
userFields() { userFields() {
@ -32,23 +55,41 @@ export default Ember.Component.extend({
clearValue() { clearValue() {
this.set('value', null); this.set('value', null);
}, },
@discourseComputed('customPlaceholder') @discourseComputed('activeType')
textPlaceholder(customPlaceholder) { comboBoxContent(activeType) {
return customPlaceholder || 'admin.wizard.text'; return this[`${activeType}Fields`];
}, },
showInput(type) { @discourseComputed('activeType')
return this.activeType === type && this[`${type}Enabled`]; multiSelectContent(activeType) {
return {
category: this.categories,
group: this.groups,
list: ''
}[activeType];
}, },
showText: computed('activeType', function() { return this.showInput('text') }), @discourseComputed('activeType')
showWizard: computed('activeType', function() { return this.showInput('wizard') }), placeholder(activeType) {
showUserField: computed('activeType', function() { return this.showInput('userField') }), if (activeType === 'text' && this.options[`${this.selectorType}Placeholder`]) {
showCategory: computed('activeType', function() { return this.showInput('category') }), return this.options[`${this.selectorType}Placeholder`];
showTag: computed('activeType', function() { return this.showInput('tag') }), }
showGroup: computed('activeType', function() { return this.showInput('group') }), return `admin.wizard.selector.placeholder.${snakeCase(activeType)}`;
showUser: computed('activeType', function() { return this.showInput('user') }), },
@discourseComputed('activeType')
multiSelectOptions(activeType) {
let result = {
none: this.placeholder
};
if (activeType === 'list') {
result.allowAny = true;
}
return result;
},
optionEnabled(type) { optionEnabled(type) {
const options = this.options; const options = this.options;
@ -57,19 +98,15 @@ export default Ember.Component.extend({
const option = options[type]; const option = options[type];
if (option === true) return true; if (option === true) return true;
if (typeof option !== 'string') return false; if (typeof option !== 'string') return false;
const types = [this.selectorType, this.inputType]; return option.split(',').filter(option => {
return [this.selectorType, this.inputType].indexOf(option) !== -1;
return option.split(',').filter(o => types.indexOf(o) !== -1).length }).length;
}, },
textEnabled: computed('options.textSelection', 'inputType', function() { return this.optionEnabled('textSelection') }), showInput(type) {
wizardEnabled: computed('options.wizardSelection', 'inputType', function() { return this.optionEnabled('wizardSelection') }), return this.activeType === type && this[`${type}Enabled`];
userFieldEnabled: computed('options.userFieldSelection', 'inputType', function() { return this.optionEnabled('userFieldSelection') }), },
categoryEnabled: computed('options.categorySelection', 'inputType', function() { return this.optionEnabled('categorySelection') }),
tagEnabled: computed('options.tagSelection', 'inputType', function() { return this.optionEnabled('tagSelection') }),
groupEnabled: computed('options.groupSelection', 'inputType', function() { return this.optionEnabled('groupSelection') }),
userEnabled: computed('options.userSelection', 'inputType', function() { return this.optionEnabled('userSelection') }),
actions: { actions: {
toggleType(type) { toggleType(type) {

Datei anzeigen

@ -1,9 +1,11 @@
import { getOwner } from 'discourse-common/lib/get-owner'; import { getOwner } from 'discourse-common/lib/get-owner';
import { on } from 'discourse-common/utils/decorators'; import { on } from 'discourse-common/utils/decorators';
import { newInput } from '../lib/wizard-mapper'; import { newInput, selectionTypes } from '../lib/wizard-mapper';
import { default as discourseComputed } from 'discourse-common/utils/decorators'; import { default as discourseComputed, observes } from 'discourse-common/utils/decorators';
import Component from "@ember/component";
import { A } from "@ember/array";
export default Ember.Component.extend({ export default Component.extend({
classNames: 'wizard-mapper', classNames: 'wizard-mapper',
@discourseComputed('inputs.[]', 'options.singular') @discourseComputed('inputs.[]', 'options.singular')
@ -11,29 +13,38 @@ export default Ember.Component.extend({
return !singular || !inputs || inputs.length < 1; return !singular || !inputs || inputs.length < 1;
}, },
@discourseComputed('options') @discourseComputed('options.@each')
inputOptions(options) { inputOptions(options) {
return { let result = {
hasOutput: options.hasOutput || false, inputTypes: options.inputTypes || 'conditional,assignment',
inputTypes: options.inputTypes || null,
pairConnector: options.pairConnector || null, pairConnector: options.pairConnector || null,
outputConnector: options.outputConnector || null, outputConnector: options.outputConnector || null
textSelection: options.textSelection || true,
wizardSelection: options.wizardSelection || false,
userFieldSelection: options.userFieldSelection || false,
categorySelection: options.categorySelection || false,
tagSelection: options.tagSelection || false,
groupSelection: options.groupSelection || false,
userSelection: options.userSelection || false,
keyDefaultSelection: options.keyDefaultSelection || null,
valueDefaultSelection: options.valueDefaultSelection || null,
outputDefaultSelection: options.outputDefaultSelection || null
} }
let inputTypes = ['key', 'value', 'output'];
inputTypes.forEach(type => {
result[`${type}DefaultSelection`] = options[`${type}DefaultSelection`] || null;
});
selectionTypes.forEach(type => {
if (options[`${type}Selection`]) {
result[`${type}Selection`] = options[`${type}Selection`]
} else {
result[`${type}Selection`] = type === 'text' ? true : false;
}
});
return result;
},
@observes('options.inputTypes')
clearInputs() {
this.get('inputs').clear();
}, },
actions: { actions: {
add() { add() {
if (!this.get('inputs')) this.set('inputs', Ember.A()); if (!this.get('inputs')) this.set('inputs', A());
this.get('inputs').pushObject(newInput(this.inputOptions)); this.get('inputs').pushObject(newInput(this.inputOptions));
}, },

Datei anzeigen

@ -1,11 +1,9 @@
import { import { default as discourseComputed, on } from 'discourse-common/utils/decorators';
default as discourseComputed,
on
} from 'discourse-common/utils/decorators';
import { profileFields } from '../lib/wizard'; import { profileFields } from '../lib/wizard';
import { scheduleOnce } from "@ember/runloop"; import { scheduleOnce } from "@ember/runloop";
import Component from "@ember/component";
export default Ember.Component.extend({ export default Component.extend({
classNames: 'wizard-text-editor', classNames: 'wizard-text-editor',
barEnabled: true, barEnabled: true,
previewEnabled: true, previewEnabled: true,

Datei anzeigen

@ -5,9 +5,10 @@ import { generateId } from '../lib/wizard';
import { buildProperties } from '../lib/wizard-json'; import { buildProperties } from '../lib/wizard-json';
import { dasherize } from "@ember/string"; import { dasherize } from "@ember/string";
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { scheduleOnce } from "@ember/runloop"; import { scheduleOnce, later } from "@ember/runloop";
import Controller from "@ember/controller";
export default Ember.Controller.extend({ export default Controller.extend({
hasName: notEmpty('model.name'), hasName: notEmpty('model.name'),
init() { init() {
@ -84,7 +85,7 @@ export default Ember.Controller.extend({
}).catch((result) => { }).catch((result) => {
this.set('saving', false); this.set('saving', false);
this.set('error', I18n.t(`admin.wizard.error.${result.error}`)); this.set('error', I18n.t(`admin.wizard.error.${result.error}`));
Ember.run.later(() => this.set('error', null), 10000); later(() => this.set('error', null), 10000);
}); });
}, },

Datei anzeigen

@ -1,42 +1,44 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import { popupAjaxError } from 'discourse/lib/ajax-error'; import { popupAjaxError } from 'discourse/lib/ajax-error';
import CustomWizardApi from '../models/custom-wizard-api'; import CustomWizardApi from '../models/custom-wizard-api';
import { default as computed } from 'discourse-common/utils/decorators'; import { default as discourseComputed } from 'discourse-common/utils/decorators';
import { not, and, equal } from "@ember/object/computed";
import { selectKitContent } from '../lib/wizard'; import { selectKitContent } from '../lib/wizard';
import Controller from "@ember/controller";
export default Ember.Controller.extend({ export default Controller.extend({
queryParams: ['refresh_list'], queryParams: ['refresh_list'],
loadingSubscriptions: false, loadingSubscriptions: false,
notAuthorized: Ember.computed.not('api.authorized'), notAuthorized: not('api.authorized'),
endpointMethods: selectKitContent(['GET', 'PUT', 'POST', 'PATCH', 'DELETE']), endpointMethods: selectKitContent(['GET', 'PUT', 'POST', 'PATCH', 'DELETE']),
showRemove: Ember.computed.not('isNew'), showRemove: not('isNew'),
showRedirectUri: Ember.computed.and('threeLeggedOauth', 'api.name'), showRedirectUri: and('threeLeggedOauth', 'api.name'),
responseIcon: null, responseIcon: null,
contentTypes: selectKitContent(['application/json', 'application/x-www-form-urlencoded']), contentTypes: selectKitContent(['application/json', 'application/x-www-form-urlencoded']),
successCodes: selectKitContent([100, 101, 102, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 303, 304, 305, 306, 307, 308]), successCodes: selectKitContent([100, 101, 102, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 303, 304, 305, 306, 307, 308]),
@computed('saveDisabled', 'api.authType', 'api.authUrl', 'api.tokenUrl', 'api.clientId', 'api.clientSecret', 'threeLeggedOauth') @discourseComputed('saveDisabled', 'api.authType', 'api.authUrl', 'api.tokenUrl', 'api.clientId', 'api.clientSecret', 'threeLeggedOauth')
authDisabled(saveDisabled, authType, authUrl, tokenUrl, clientId, clientSecret, threeLeggedOauth) { authDisabled(saveDisabled, authType, authUrl, tokenUrl, clientId, clientSecret, threeLeggedOauth) {
if (saveDisabled || !authType || !tokenUrl || !clientId || !clientSecret) return true; if (saveDisabled || !authType || !tokenUrl || !clientId || !clientSecret) return true;
if (threeLeggedOauth) return !authUrl; if (threeLeggedOauth) return !authUrl;
return false; return false;
}, },
@computed('api.name', 'api.authType') @discourseComputed('api.name', 'api.authType')
saveDisabled(name, authType) { saveDisabled(name, authType) {
return !name || !authType; return !name || !authType;
}, },
authorizationTypes: selectKitContent(['none', 'basic', 'oauth_2', 'oauth_3']), authorizationTypes: selectKitContent(['none', 'basic', 'oauth_2', 'oauth_3']),
isBasicAuth: Ember.computed.equal('api.authType', 'basic'), isBasicAuth: equal('api.authType', 'basic'),
@computed('api.authType') @discourseComputed('api.authType')
isOauth(authType) { isOauth(authType) {
return authType && authType.indexOf('oauth') > -1; return authType && authType.indexOf('oauth') > -1;
}, },
twoLeggedOauth: Ember.computed.equal('api.authType', 'oauth_2'), twoLeggedOauth: equal('api.authType', 'oauth_2'),
threeLeggedOauth: Ember.computed.equal('api.authType', 'oauth_3'), threeLeggedOauth: equal('api.authType', 'oauth_3'),
actions: { actions: {
addParam() { addParam() {

Datei anzeigen

@ -1,3 +1,5 @@
export default Ember.Controller.extend({ import Controller from "@ember/controller";
export default Controller.extend({
queryParams: ['refresh'] queryParams: ['refresh']
}); });

Datei anzeigen

@ -1 +1,3 @@
export default Ember.Controller.extend(); import Controller from "@ember/controller";
export default Controller.extend();

Datei anzeigen

@ -1,7 +1,8 @@
import { default as computed } from 'discourse-common/utils/decorators'; import { default as computed } from 'discourse-common/utils/decorators';
import { scheduleOnce } from "@ember/runloop"; import { scheduleOnce } from "@ember/runloop";
import Controller from "@ember/controller";
export default Ember.Controller.extend({ export default Controller.extend({
title: 'admin.wizard.after_time_modal.title', title: 'admin.wizard.after_time_modal.title',
setup() { setup() {

Datei anzeigen

@ -1,5 +1,6 @@
import { registerUnbound } from 'discourse-common/lib/helpers'; import { registerUnbound } from 'discourse-common/lib/helpers';
import { dasherize } from "@ember/string";
registerUnbound('dasherize', function(string) { registerUnbound('dasherize', function(string) {
return Ember.String.dasherize(string); return dasherize(string);
}); });

Datei anzeigen

@ -1,11 +1,6 @@
import { import { properties, mappedProperties, advancedProperties, camelCase, snakeCase } from '../lib/wizard';
properties,
mappedProperties,
advancedProperties,
camelCase,
snakeCase
} from '../lib/wizard';
import EmberObject from '@ember/object'; import EmberObject from '@ember/object';
import { A } from "@ember/array";
function present(val) { function present(val) {
if (val === null || val === undefined) { if (val === null || val === undefined) {
@ -197,7 +192,7 @@ function buildObject(json, type) {
); );
}); });
params[prop] = Ember.A(inputs); params[prop] = A(inputs);
} else { } else {
params[prop] = json[prop]; params[prop] = json[prop];
} }
@ -223,7 +218,7 @@ function hasAdvanced(params, type) {
} }
function buildProperties(json) { function buildProperties(json) {
let steps = Ember.A(); let steps = A();
let props = { let props = {
steps steps
}; };
@ -254,7 +249,7 @@ function buildProperties(json) {
} }
}); });
stepParams.fields = Ember.A(); stepParams.fields = A();
if (present(stepJson.fields)) { if (present(stepJson.fields)) {
stepJson.fields.forEach((f) => { stepJson.fields.forEach((f) => {
@ -268,7 +263,7 @@ function buildProperties(json) {
}); });
} }
stepParams.actions = Ember.A(); stepParams.actions = A();
if (present(stepJson.actions)) { if (present(stepJson.actions)) {
stepJson.actions.forEach((a) => { stepJson.actions.forEach((a) => {
@ -299,7 +294,7 @@ function buildProperties(json) {
props.prompt_completion = false; props.prompt_completion = false;
props.restart_on_revisit = false; props.restart_on_revisit = false;
props.permitted = null; props.permitted = null;
props.steps = Ember.A(); props.steps = A();
} }
return props; return props;

Datei anzeigen

@ -1,15 +1,9 @@
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { A } from "@ember/array";
// Inputs // Inputs
const selectableInputTypes = [
'conditional',
'assignment'
]
function defaultInputType(options = {}) { function defaultInputType(options = {}) {
if (!options.hasOutput) return 'pair';
if (!options.inputTypes) return selectableInputTypes[0];
return options.inputTypes.split(',')[0]; return options.inputTypes.split(',')[0];
} }
@ -73,12 +67,13 @@ function connectorContent(connectorType, inputType, opts) {
const selectionTypes = [ const selectionTypes = [
'text', 'text',
'wizard', 'wizardField',
'userField', 'userField',
'group', 'group',
'category', 'category',
'tag', 'tag',
'user' 'user',
'list'
] ]
function defaultSelectionType(inputType, options = {}) { function defaultSelectionType(inputType, options = {}) {
@ -122,9 +117,11 @@ function newPair(inputType, options = {}) {
function newInput(options = {}) { function newInput(options = {}) {
const inputType = defaultInputType(options); const inputType = defaultInputType(options);
console.log(inputType);
let params = { let params = {
type: inputType, type: inputType,
pairs: Ember.A( pairs: A(
[ [
newPair( newPair(
inputType, inputType,
@ -137,7 +134,7 @@ function newInput(options = {}) {
) )
} }
if (options.hasOutput) { if (['conditional', 'assignment'].indexOf(inputType) > -1) {
params['output_type'] = defaultSelectionType('output', options); params['output_type'] = defaultSelectionType('output', options);
params['connector'] = defaultConnector('output', inputType, options); params['connector'] = defaultConnector('output', inputType, options);
} }
@ -150,6 +147,7 @@ export {
defaultSelectionType, defaultSelectionType,
connectorContent, connectorContent,
inputTypesContent, inputTypesContent,
selectionTypes,
newInput, newInput,
newPair, newPair
} }

Datei anzeigen

@ -1,5 +1,5 @@
function selectKitContent(content) { function selectKitContent(content) {
return content.map(i => ({id: i, name: i})) return content.map(i => ({id: i, name: i}));
} }
function generateName(id) { function generateName(id) {
@ -13,13 +13,13 @@ function generateId(name) {
function sentenceCase(string) { function sentenceCase(string) {
return string.replace(/[_\-]+/g, ' ') return string.replace(/[_\-]+/g, ' ')
.toLowerCase() .toLowerCase()
.replace(/(^\w|\b\w)/g, (m) => m.toUpperCase()) .replace(/(^\w|\b\w)/g, (m) => m.toUpperCase());
} }
function snakeCase(string) { function snakeCase(string) {
return string.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) return string.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
.map(x => x.toLowerCase()) .map(x => x.toLowerCase())
.join('_') .join('_');
} }
function camelCase(string) { function camelCase(string) {
@ -124,7 +124,6 @@ const mappedProperties = {
'permitted_params' 'permitted_params'
], ],
field: [ field: [
'choices',
'prefill', 'prefill',
'content' 'content'
], ],

Datei anzeigen

@ -1,6 +1,7 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import { default as computed } from 'discourse-common/utils/decorators'; import { default as computed } from 'discourse-common/utils/decorators';
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { A } from "@ember/array";
const CustomWizardApi = EmberObject.extend({ const CustomWizardApi = EmberObject.extend({
@computed('name') @computed('name')
@ -28,14 +29,14 @@ CustomWizardApi.reopenClass({
clientSecret: authorization.client_secret, clientSecret: authorization.client_secret,
username: authorization.username, username: authorization.username,
password: authorization.password, password: authorization.password,
authParams: Ember.A(authorization.auth_params), authParams: A(authorization.auth_params),
authorized: authorization.authorized, authorized: authorization.authorized,
accessToken: authorization.access_token, accessToken: authorization.access_token,
refreshToken: authorization.refresh_token, refreshToken: authorization.refresh_token,
code: authorization.code, code: authorization.code,
tokenExpiresAt: authorization.token_expires_at, tokenExpiresAt: authorization.token_expires_at,
tokenRefreshAt: authorization.token_refresh_at, tokenRefreshAt: authorization.token_refresh_at,
endpoints: Ember.A(endpoints), endpoints: A(endpoints),
isNew: params.isNew, isNew: params.isNew,
log: params.log log: params.log
}); });

Datei anzeigen

@ -1,10 +1,11 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { buildStepJson, buildJson, buildProperties } from '../lib/wizard-json'; import { buildStepJson, buildJson, buildProperties } from '../lib/wizard-json';
import { Promise } from "rsvp";
const CustomWizard = EmberObject.extend({ const CustomWizard = EmberObject.extend({
save() { save() {
return new Ember.RSVP.Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let wizardJson = buildJson(this, 'wizard'); let wizardJson = buildJson(this, 'wizard');
if (wizardJson.after_time && !wizardJson.after_time_scheduled) { if (wizardJson.after_time && !wizardJson.after_time_scheduled) {

Datei anzeigen

@ -1,11 +1,8 @@
import CustomWizard from '../models/custom-wizard'; import CustomWizard from '../models/custom-wizard';
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import { import { selectKitContent, profileFields, generateName } from '../lib/wizard';
selectKitContent,
profileFields,
generateName
} from '../lib/wizard';
import DiscourseRoute from "discourse/routes/discourse"; import DiscourseRoute from "discourse/routes/discourse";
import { all } from "rsvp";
export default DiscourseRoute.extend({ export default DiscourseRoute.extend({
beforeModel() { beforeModel() {
@ -39,7 +36,7 @@ export default DiscourseRoute.extend({
}, },
afterModel(model) { afterModel(model) {
return Ember.RSVP.all([ return all([
this._getFieldTypes(model), this._getFieldTypes(model),
this._getThemes(model), this._getThemes(model),
this._getApis(model), this._getApis(model),

Datei anzeigen

@ -114,7 +114,6 @@
options=(hash options=(hash
singular=true singular=true
inputTypes='assignment' inputTypes='assignment'
hasOutput=true
groupSelection='output' groupSelection='output'
textSelection='key,value' textSelection='key,value'
)}} )}}

Datei anzeigen

@ -135,8 +135,8 @@
<div class="controls"> <div class="controls">
{{#each api.authParams as |param|}} {{#each api.authParams as |param|}}
<div class="param"> <div class="param">
{{input value=param.key placeholder=(i18n 'admin.wizard.api.auth.params.key')}} {{input value=param.key placeholder=(i18n 'admin.wizard.key')}}
{{input value=param.value placeholder=(i18n 'admin.wizard.api.auth.params.value')}} {{input value=param.value placeholder=(i18n 'admin.wizard.value')}}
{{d-button action=(action "removeParam") actionParam=param icon='times'}} {{d-button action=(action "removeParam") actionParam=param icon='times'}}
</div> </div>
{{/each}} {{/each}}

Datei anzeigen

@ -24,8 +24,7 @@
{{wizard-mapper {{wizard-mapper
inputs=action.title inputs=action.title
options=(hash options=(hash
hasOutput=true wizardFieldSelection=true
wizardSelection=true
userFieldSelection='key,value' userFieldSelection='key,value'
)}} )}}
</div> </div>
@ -43,7 +42,7 @@
nameProperty='label' nameProperty='label'
onChange=(action (mut action.post)) onChange=(action (mut action.post))
options=(hash options=(hash
none='admin.wizard.select_field' none='admin.wizard.selector.placeholder.wizard_field'
isDisabled=action.post_builder isDisabled=action.post_builder
)}} )}}
@ -79,9 +78,8 @@
{{wizard-mapper {{wizard-mapper
inputs=action.category inputs=action.category
options=(hash options=(hash
hasOutput=true
textSelection='key,value' textSelection='key,value'
wizardSelection=true wizardFieldSelection=true
userFieldSelection='key,value' userFieldSelection='key,value'
categorySelection='output' categorySelection='output'
outputDefaultSelection='category' outputDefaultSelection='category'
@ -98,9 +96,8 @@
{{wizard-mapper {{wizard-mapper
inputs=action.tags inputs=action.tags
options=(hash options=(hash
hasOutput=true
tagSelection='output' tagSelection='output'
wizardSelection=true wizardFieldSelection=true
userFieldSelection='key,value' userFieldSelection='key,value'
)}} )}}
</div> </div>
@ -117,9 +114,8 @@
{{wizard-mapper {{wizard-mapper
inputs=action.recipient inputs=action.recipient
options=(hash options=(hash
hasOutput=true
textSelection='value,output' textSelection='value,output'
wizardSelection=true wizardFieldSelection=true
userFieldSelection='key,value' userFieldSelection='key,value'
groupSelection='key,value' groupSelection='key,value'
userSelection='output' userSelection='output'
@ -137,12 +133,12 @@
{{wizard-mapper {{wizard-mapper
inputs=action.profile_updates inputs=action.profile_updates
keyPlaceholder='admin.wizard.action.update_profile.key'
options=(hash options=(hash
pairConnector='set' pairConnector='set'
userFieldSelection='key' userFieldSelection='key'
wizardSelection='value' wizardFieldSelection='value'
keyDefaultSelection='userField' keyDefaultSelection='userField'
keyPlaceholder='admin.wizard.action.update_profile.key'
)}} )}}
</div> </div>
{{/if}} {{/if}}
@ -208,9 +204,8 @@
{{wizard-mapper {{wizard-mapper
inputs=action.group inputs=action.group
options=(hash options=(hash
hasOutput=true
textSelection='value,output' textSelection='value,output'
wizardSelection='key,value,assignment' wizardFieldSelection='key,value,assignment'
userFieldSelection='key,value,assignment' userFieldSelection='key,value,assignment'
groupSelection='value,output' groupSelection='value,output'
outputDefaultSelection='group' outputDefaultSelection='group'
@ -246,11 +241,11 @@
<div class="setting-value"> <div class="setting-value">
{{wizard-mapper {{wizard-mapper
inputs=action.custom_fields inputs=action.custom_fields
keyPlaceholder='admin.wizard.action.custom_fields.key'
options=(hash options=(hash
pairConnector='set' pairConnector='set'
wizardSelection='value' wizardFieldSelection='value'
userFieldSelection='value' userFieldSelection='value'
keyPlaceholder='admin.wizard.action.custom_fields.key'
)}} )}}
</div> </div>
</div> </div>
@ -267,7 +262,7 @@
inputs=action.required inputs=action.required
options=(hash options=(hash
textSelection='value' textSelection='value'
wizardSelection=true wizardFieldSelection=true
userFieldSelection=true userFieldSelection=true
groupSelection=true groupSelection=true
)}} )}}

Datei anzeigen

@ -69,41 +69,6 @@
</div> </div>
{{/if}} {{/if}}
{{#if isDropdown}}
<div class="wizard-dropdown-choices">
<div class="wizard-header small underline">
{{i18n 'admin.wizard.field.choices_label'}}
</div>
{{combo-box
value=field.choices_type
content=choicesTypes
onChange=(action (mut field.choices_type))
options=(hash
none="admin.wizard.field.choices_type"
)}}
{{#if choicesTranslation}}
<div class="wizard-header small">
{{i18n 'admin.wizard.field.choices_translation'}}
</div>
{{input name="key" value=field.choices_key placeholderKey="admin.wizard.translation_placeholder"}}
{{/if}}
{{#if choicesCustom}}
<div class="wizard-header small">
{{i18n 'admin.wizard.field.choices_custom'}}
</div>
{{wizard-mapper inputs=field.choices}}
{{/if}}
<div class="wizard-header small">
{{i18n 'admin.wizard.field.dropdown_none'}}
</div>
{{input name="dropdown_none" value=field.dropdown_none placeholder=(i18n 'admin.wizard.field.dropdown_none_placeholder')}}
</div>
{{/if}}
{{#if isUpload}} {{#if isUpload}}
<div class="setting"> <div class="setting">
<div class="setting-label"> <div class="setting-label">
@ -128,63 +93,61 @@
</div> </div>
{{/if}} {{/if}}
{{#if hasAdvanced}} {{wizard-advanced-toggle showAdvanced=field.showAdvanced}}
{{wizard-advanced-toggle showAdvanced=field.showAdvanced}}
{{#if field.showAdvanced}} {{#if field.showAdvanced}}
<div class="advanced-settings"> <div class="advanced-settings">
{{#if isCategory}} {{#if isCategory}}
<div class="setting">
<div class="setting-label">
<label>{{i18n 'admin.wizard.field.property'}}</label>
</div>
<div class="setting-value">
{{combo-box
value=field.property
content=categoryPropertyTypes
onChange=(action (mut field.property))
options=(hash
none='admin.wizard.select_property'
)}}
</div>
</div>
{{/if}}
{{#if prefillEnabled}}
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n 'admin.wizard.field.prefill'}}</label>
</div>
<div class="setting-value">
{{wizard-mapper inputs=field.prefill options=prefillOptions}}
</div>
</div>
{{/if}}
{{#if contentEnabled}}
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n 'admin.wizard.field.content'}}</label>
</div>
<div class="setting-value">
{{wizard-mapper inputs=field.content options=contentOptions}}
</div>
</div>
{{/if}}
<div class="setting"> <div class="setting">
<div class="setting-label"> <div class="setting-label">
<label>{{i18n 'admin.wizard.translation'}}</label> <label>{{i18n 'admin.wizard.field.property'}}</label>
</div> </div>
<div class="setting-value"> <div class="setting-value">
{{input name="key" value=field.key placeholderKey="admin.wizard.translation_placeholder"}} {{combo-box
value=field.property
content=categoryPropertyTypes
onChange=(action (mut field.property))
options=(hash
none='admin.wizard.select_property'
)}}
</div> </div>
</div> </div>
{{/if}}
{{#if prefillEnabled}}
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n 'admin.wizard.field.prefill'}}</label>
</div>
<div class="setting-value">
{{wizard-mapper inputs=field.prefill options=prefillOptions}}
</div>
</div>
{{/if}}
{{#if contentEnabled}}
<div class="setting full field-mapper-setting">
<div class="setting-label">
<label>{{i18n 'admin.wizard.field.content'}}</label>
</div>
<div class="setting-value">
{{wizard-mapper inputs=field.content options=contentOptions}}
</div>
</div>
{{/if}}
<div class="setting">
<div class="setting-label">
<label>{{i18n 'admin.wizard.translation'}}</label>
</div>
<div class="setting-value">
{{input name="key" value=field.key placeholderKey="admin.wizard.translation_placeholder"}}
</div>
</div> </div>
{{/if}}
</div>
{{/if}} {{/if}}

Datei anzeigen

@ -46,10 +46,10 @@
<div class="setting-value"> <div class="setting-value">
{{wizard-mapper {{wizard-mapper
inputs=step.required_data inputs=step.required_data
keyPlaceholder="admin.wizard.submission_key"
options=(hash options=(hash
wizardSelection='value' wizardFieldSelection='value'
userFieldSelection='value' userFieldSelection='value'
keyPlaceholder="admin.wizard.submission_key"
)}} )}}
{{#if step.required_data}} {{#if step.required_data}}
<div class="required-data-message"> <div class="required-data-message">
@ -69,10 +69,10 @@
<div class="setting-value"> <div class="setting-value">
{{wizard-mapper {{wizard-mapper
inputs=step.permitted_params inputs=step.permitted_params
keyPlaceholder='admin.wizard.param_key'
valuePlaceholder='admin.wizard.submission_key'
options=(hash options=(hash
pairConnector='set' pairConnector='set'
keyPlaceholder='admin.wizard.param_key'
valuePlaceholder='admin.wizard.submission_key'
)}} )}}
</div> </div>
</div> </div>

Datei anzeigen

@ -1,9 +1,7 @@
{{#if hasOutput}} {{wizard-mapper-connector
{{wizard-mapper-connector connector=input.type
connector=input.type connectors=inputTypes
connectors=inputTypes inputTypes=true}}
inputTypes=true}}
{{/if}}
{{#if hasPairs}} {{#if hasPairs}}
<div class="mapper-pairs mapper-block"> <div class="mapper-pairs mapper-block">
@ -12,8 +10,6 @@
pair=pair pair=pair
last=pair.last last=pair.last
inputType=inputType inputType=inputType
keyPlaceholder=keyPlaceholder
valuePlaceholder=valuePlaceholder
options=options options=options
removePair=(action 'removePair')}} removePair=(action 'removePair')}}
{{/each}} {{/each}}
@ -39,7 +35,6 @@
inputType=inputType inputType=inputType
value=input.output value=input.output
activeType=input.output_type activeType=input.output_type
customPlaceholder=outputPlaceholder
options=options}} options=options}}
</div> </div>
{{/if}} {{/if}}

Datei anzeigen

@ -4,7 +4,6 @@
inputType=inputType inputType=inputType
value=pair.key value=pair.key
activeType=pair.key_type activeType=pair.key_type
customPlaceholder=keyPlaceholder
options=options}} options=options}}
</div> </div>
@ -18,7 +17,6 @@
inputType=inputType inputType=inputType
value=pair.value value=pair.value
activeType=pair.value_type activeType=pair.value_type
customPlaceholder=valuePlaceholder
options=options}} options=options}}
</div> </div>

Datei anzeigen

@ -1,52 +1,10 @@
<div class="type-selector"> <div class="type-selector">
{{#if textEnabled}} {{#each selectorTypes as |type|}}
{{wizard-mapper-selector-type {{wizard-mapper-selector-type
activeType=activeType activeType=activeType
type='text' type=type
toggle=(action 'toggleType')}} toggle=(action 'toggleType')}}
{{/if}} {{/each}}
{{#if wizardEnabled}}
{{wizard-mapper-selector-type
activeType=activeType
type='wizard'
toggle=(action 'toggleType')}}
{{/if}}
{{#if userFieldEnabled}}
{{wizard-mapper-selector-type
activeType=activeType
type='userField'
toggle=(action 'toggleType')}}
{{/if}}
{{#if categoryEnabled}}
{{wizard-mapper-selector-type
activeType=activeType
type='category'
toggle=(action 'toggleType')}}
{{/if}}
{{#if tagEnabled}}
{{wizard-mapper-selector-type
activeType=activeType
type='tag'
toggle=(action 'toggleType')}}
{{/if}}
{{#if groupEnabled}}
{{wizard-mapper-selector-type
activeType=activeType
type='group'
toggle=(action 'toggleType')}}
{{/if}}
{{#if userEnabled}}
{{wizard-mapper-selector-type
activeType=activeType
type='user'
toggle=(action 'toggleType')}}
{{/if}}
</div> </div>
<div class="input"> <div class="input">
@ -54,60 +12,44 @@
{{input {{input
type="text" type="text"
value=value value=value
placeholder=(i18n textPlaceholder)}} placeholder=(i18n placeholder)}}
{{/if}}
{{#if showWizard}}
{{combo-box
value=value
content=wizardFields
onChange=(action (mut value))
options=(hash
none='admin.wizard.wizard_field'
)}}
{{/if}} {{/if}}
{{#if showUserField}} {{#if showComboBox}}
{{combo-box {{combo-box
value=value value=value
content=userFields content=comboBoxContent
onChange=(action (mut value)) onChange=(action (mut value))
options=(hash options=(hash
none='admin.wizard.user_field' none=placeholder
)}} )}}
{{/if}} {{/if}}
{{#if showCategory}} {{#if showMultiSelect}}
{{multi-select {{multi-select
content=categories content=multiSelectContent
value=value value=value
onChange=(action (mut value)) onChange=(action (mut value))
options=(hash options=multiSelectOptions}}
none='admin.wizard.select_category' {{/if}}
)}}
{{#if showList}}
{{value-list values=value}}
{{/if}} {{/if}}
{{#if showTag}} {{#if showTag}}
{{tag-chooser {{tag-chooser
tags=value tags=value
filterable=true}} filterable=true
{{/if}}
{{#if showGroup}}
{{multi-select
content=groups
value=value
onChange=(action (mut value))
options=(hash options=(hash
none='admin.wizard.select_group' none=placeholder
)}} )}}
{{/if}} {{/if}}
{{#if showUser}} {{#if showUser}}
{{user-selector {{user-selector
topicId=topicId
includeMessageableGroups='true' includeMessageableGroups='true'
placeholderKey="composer.users_placeholder" placeholderKey=placeholder
usernames=value usernames=value
autocomplete="discourse"}} autocomplete="discourse"}}
{{/if}} {{/if}}

Datei anzeigen

@ -1,8 +1,6 @@
{{#each inputs as |input|}} {{#each inputs as |input|}}
{{wizard-mapper-input {{wizard-mapper-input
input=input input=input
keyPlaceholder=keyPlaceholder
valuePlaceholder=valuePlaceholder
options=inputOptions options=inputOptions
remove=(action 'remove')}} remove=(action 'remove')}}
{{/each}} {{/each}}

Datei anzeigen

@ -1,4 +1,5 @@
import { default as computed } from 'discourse-common/utils/decorators'; import { default as computed } from 'discourse-common/utils/decorators';
import { dasherize } from "@ember/string";
export default { export default {
name: 'custom-routes', name: 'custom-routes',
@ -219,7 +220,7 @@ export default {
const type = this.get('field.type'); const type = this.get('field.type');
const id = this.get('field.id'); const id = this.get('field.id');
if (['text-only'].includes(type)) return false; if (['text-only'].includes(type)) return false;
return (type === 'component') ? Ember.String.dasherize(id) : `wizard-field-${type}`; return (type === 'component') ? dasherize(id) : `wizard-field-${type}`;
}.property('field.type', 'field.id') }.property('field.type', 'field.id')
}); });

Datei anzeigen

@ -1,7 +1,7 @@
{{combo-box elementId=field.id {{combo-box elementId=field.id
class=fieldClass class=fieldClass
value=field.value value=field.value
content=field.choices content=field.content
none=(hash id="__none__" label=field.dropdown_none) none=(hash id="__none__" label=field.dropdown_none)
nameProperty="label" nameProperty="label"
tabindex="9"}} tabindex="9"}}

Datei anzeigen

@ -379,17 +379,6 @@ body.admin-wizard {
position: relative; position: relative;
} }
.wizard-dropdown-choices {
padding: 15px;
margin-bottom: 20px;
background-color: $secondary;
width: 100%;
.wizard-header:not(.underline) {
margin-top: 15px;
}
}
.required-data-message { .required-data-message {
display: inline-block; display: inline-block;
margin-top: 20px; margin-top: 20px;

Datei anzeigen

@ -24,11 +24,10 @@
align-items: flex-start; align-items: flex-start;
width: min-content; width: min-content;
position: relative; position: relative;
padding-bottom: 30px; padding: 25px 7px 7px 7px;
margin-bottom: 10px;
&:last-of-type { background: rgba($secondary, 0.5);
padding-bottom: 0; border: 2px solid $primary-low;
}
.d-icon { .d-icon {
text-align: center; text-align: center;
@ -42,11 +41,16 @@
background-color: $primary-low; background-color: $primary-low;
border-color: #ddd; border-color: #ddd;
} }
.output {
position: relative;
}
a.remove-input { a.remove-input {
position: absolute; position: absolute;
right: -25px; right: -25px;
top: 5px; top: 50%;
transform: translateY(-50%);
} }
} }
@ -54,10 +58,6 @@
display: block; display: block;
} }
.mapper-input + .add-mapper-input {
padding-top: 10px;
}
.mapper-connector { .mapper-connector {
width: auto; width: auto;
min-width: 40px; min-width: 40px;
@ -105,6 +105,15 @@
margin-right: 0; margin-right: 0;
} }
} }
.value-list .remove-value-btn {
background: none;
border: none;
.d-icon {
color: $primary;
}
}
} }
.mapper-pairs { .mapper-pairs {

Datei anzeigen

@ -42,20 +42,13 @@ en:
remove: "Delete Wizard" remove: "Delete Wizard"
add: "Add" add: "Add"
url: "Url" url: "Url"
key: "Key"
value: "Value" value: "Value"
property: "Property"
text: "text"
profile: "profile" profile: "profile"
translation: "Translation" translation: "Translation"
translation_placeholder: "key" translation_placeholder: "key"
type: "Type" type: "Type"
none: "Make a selection" none: "Make a selection"
user_field: "User Field"
wizard_field: "Wizard Field"
select_field: "Select Field"
select_property: "Select Property"
select_group: "Select Group"
profile_field: "Profile Field"
submission_key: 'submission key' submission_key: 'submission key'
param_key: 'param' param_key: 'param'
group: "Group" group: "Group"
@ -74,7 +67,31 @@ en:
output: 'then' output: 'then'
assignment: assignment:
name: 'set' name: 'set'
pair:
name: 'pair'
selector:
label:
text: "text"
wizard_field: "wizard ○"
user_field: "user ○"
user: "user"
category: "category"
tag: "tag"
group: "group"
list: "list"
placeholder:
text: "Enter text"
property: "Select property"
wizard_field: "Select field"
user_field: "Select field"
user: "Select user"
category: "Select category"
tag: "Select tag"
group: "Select group"
list: "Enter item"
error: error:
name_required: "Wizards must have a name." name_required: "Wizards must have a name."
steps_required: "Wizards must have at least one step." steps_required: "Wizards must have at least one step."
@ -83,9 +100,6 @@ en:
type_required: "All fields need a type." type_required: "All fields need a type."
after_time_need_time: "After time is enabled but no time is set." after_time_need_time: "After time is enabled but no time is set."
after_time_invalid: "After time is invalid." after_time_invalid: "After time is invalid."
field:
need_choices: "All dropdowns need choices."
choices_label_empty: "Custom choice labels cannot be empty."
step: step:
header: "Steps" header: "Steps"
@ -107,13 +121,6 @@ en:
image_placeholder: "Image url" image_placeholder: "Image url"
dropdown_none: "None" dropdown_none: "None"
dropdown_none_placeholder: "Label" dropdown_none_placeholder: "Label"
choices_label: "Dropdown Choices"
choices_type: "Choose a type"
choices_translation: "Translation"
choices_custom: "Custom"
choice:
value: "Value"
label: "Label"
required: "Required" required: "Required"
required_label: "Field is Required" required_label: "Field is Required"
min_length: "Min Length" min_length: "Min Length"
@ -214,8 +221,6 @@ en:
params: params:
label: 'Params' label: 'Params'
new: 'New param' new: 'New param'
key: 'key'
value: 'value'
status: status:
label: "Status" label: "Status"

Datei anzeigen

@ -59,9 +59,6 @@ fr:
type_required: "Tous les champs ont besoin d'un type." type_required: "Tous les champs ont besoin d'un type."
after_time_need_time: "Le délai est activé mais aucune heure n'est établie." after_time_need_time: "Le délai est activé mais aucune heure n'est établie."
after_time_invalid: "Le délai est invalide." after_time_invalid: "Le délai est invalide."
field:
need_choices: "Tous les menus déroulants ont besoin d'options."
choices_label_empty: "Les étiquettes pour le choix personnalisé ne peuvent être vides."
step: step:
header: "Étapes" header: "Étapes"
title: "Titre" title: "Titre"
@ -74,15 +71,6 @@ fr:
description: "Description" description: "Description"
image: "Image" image: "Image"
image_placeholder: "URL de l'image" image_placeholder: "URL de l'image"
dropdown_none: "Aucun"
dropdown_none_placeholder: "Clé de traduction"
choices_label: "Options du menu déroulant"
choices_type: "Choisir un type"
choices_translation: "Traduction"
choices_custom: "Personnalisé"
choice:
value: "Valeur"
label: "Étiquette"
required: "Requis" required: "Requis"
required_label: "Le champ est obligatoire" required_label: "Le champ est obligatoire"
min_length: "Longueur min." min_length: "Longueur min."
@ -103,7 +91,6 @@ fr:
category: "Catégorie" category: "Catégorie"
update_profile: update_profile:
label: "Mettre à jour le profil" label: "Mettre à jour le profil"
profile_field: "Champ du profil"
post_builder: post_builder:
checkbox: "Générateur de message" checkbox: "Générateur de message"
label: "Générateur" label: "Générateur"

Datei anzeigen

@ -63,14 +63,6 @@ class CustomWizard::AdminController < ::ApplicationController
error = 'type_required' error = 'type_required'
break break
end end
if f["type"] === 'dropdown'
choices = f["choices"]
if (!choices || choices.length < 1) && !f["choices_key"]
error = 'field.need_choices'
break
end
end
end end
end end

Datei anzeigen

@ -244,10 +244,6 @@ class CustomWizard::Builder
end end
field = step.add_field(params) field = step.add_field(params)
if field_template['type'] === 'dropdown'
build_dropdown_list(field, field_template)
end
end end
def prefill_field(field_template, step_template) def prefill_field(field_template, step_template)
@ -260,26 +256,6 @@ class CustomWizard::Builder
end end
end end
def build_dropdown_list(field, template)
field.dropdown_none = template['dropdown_none'] if template['dropdown_none']
method = "build_dropdown_#{template['choices_type']}"
self.send(method, field, template) if self.respond_to?(method)
end
def build_dropdown_custom(field, template)
template['choices'].each do |c|
field.add_choice(c['key'], label: c['value'])
end
end
def build_dropdown_translation(field, template)
choices = I18n.t(template['choices_key'])
if choices.is_a?(Hash)
choices.each { |k, v| field.add_choice(k, label: v) }
end
end
def validate_field(field, updater, step_template) def validate_field(field, updater, step_template)
value = updater.fields[field['id']] value = updater.fields[field['id']]
min_length = false min_length = false

Datei anzeigen

@ -1,17 +0,0 @@
module CustomWizardChoiceExtension
def initialize(id, opts)
@id = id
@opts = opts
@data = opts[:data]
@extra_label = opts[:extra_label]
@icon = opts[:icon]
end
def label
@label ||= PrettyText.cook(@opts[:label])
end
end
class Wizard::Choice
prepend CustomWizardChoiceExtension if SiteSetting.custom_wizard_enabled
end

Datei anzeigen

@ -9,8 +9,6 @@ module CustomWizardFieldExtension
:property, :property,
:content :content
attr_accessor :dropdown_none
def initialize(attrs) def initialize(attrs)
@attrs = attrs || {} @attrs = attrs || {}
@id = attrs[:id] @id = attrs[:id]
@ -21,8 +19,6 @@ module CustomWizardFieldExtension
@key = attrs[:key] @key = attrs[:key]
@min_length = attrs[:min_length] @min_length = attrs[:min_length]
@value = attrs[:value] @value = attrs[:value]
@choices = []
@dropdown_none = attrs[:dropdown_none]
@file_types = attrs[:file_types] @file_types = attrs[:file_types]
@limit = attrs[:limit] @limit = attrs[:limit]
@property = attrs[:property] @property = attrs[:property]

Datei anzeigen

@ -63,7 +63,6 @@ after_initialize do
../lib/custom_wizard/api/authorization.rb ../lib/custom_wizard/api/authorization.rb
../lib/custom_wizard/api/endpoint.rb ../lib/custom_wizard/api/endpoint.rb
../lib/custom_wizard/api/log_entry.rb ../lib/custom_wizard/api/log_entry.rb
../lib/wizard/choice.rb
../lib/wizard/field.rb ../lib/wizard/field.rb
../lib/wizard/step.rb ../lib/wizard/step.rb
../serializers/custom_wizard/api/authorization_serializer.rb ../serializers/custom_wizard/api/authorization_serializer.rb

Datei anzeigen

@ -8,9 +8,7 @@ class CustomWizardFieldSerializer < ::WizardFieldSerializer
:limit, :limit,
:property, :property,
:content :content
has_many :choices, serializer: WizardFieldChoiceSerializer, embed: :objects
def label def label
return object.label if object.label.present? return object.label if object.label.present?
I18n.t("#{object.key || i18n_key}.label", default: '') I18n.t("#{object.key || i18n_key}.label", default: '')

Datei anzeigen

@ -28,8 +28,6 @@ describe CustomWizard::Builder do
let(:text_only_field) {{"id": "text_only","type": "text-only","label": "Text only"}} let(:text_only_field) {{"id": "text_only","type": "text-only","label": "Text only"}}
let(:upload_field) {{"id": "upload","type": "upload","file_types": ".jpg,.png,.pdf","label": "Upload"}} let(:upload_field) {{"id": "upload","type": "upload","file_types": ".jpg,.png,.pdf","label": "Upload"}}
let(:user_selector_field) {{"id": "user_selector","type": "user-selector","label": "User selector"}} let(:user_selector_field) {{"id": "user_selector","type": "user-selector","label": "User selector"}}
let(:dropdown_custom_field) {{"id": "dropdown_custom","type": "dropdown","choices_type": "custom","choices": [{"key": "option_1","value": "Option 1"},{"key": "option_2","value": "Option 2"}]}}
let(:dropdown_translation_field) {{"id": "dropdown_translation","type": "dropdown","choices_type": "translation","choices_key": "key1.key2"}}
let(:create_topic_action) {{"id":"create_topic","type":"create_topic","title":"text","post":"textarea"}} let(:create_topic_action) {{"id":"create_topic","type":"create_topic","title":"text","post":"textarea"}}
let(:send_message_action) {{"id":"send_message","type":"send_message","title":"text","post":"textarea","username":"angus"}} let(:send_message_action) {{"id":"send_message","type":"send_message","title":"text","post":"textarea","username":"angus"}}
let(:route_to_action) {{"id":"route_to","type":"route_to","url":"https://google.com"}} let(:route_to_action) {{"id":"route_to","type":"route_to","url":"https://google.com"}}