Apply prettier đź’„ (#80)
* Apply prettier * applied prettier for similar-topics-validator Co-authored-by: Faizaan Gagan <fzngagan@gmail.com>
Dieser Commit ist enthalten in:
Ursprung
94a02157af
Commit
cf50a7deb3
90 geänderte Dateien mit 2441 neuen und 2048 gelöschten Zeilen
|
@ -2,118 +2,127 @@ import Component from "@ember/component";
|
||||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
import { or, alias } from "@ember/object/computed";
|
import { or, alias } from "@ember/object/computed";
|
||||||
|
|
||||||
const generateContent = function(array, type) {
|
const generateContent = function (array, type) {
|
||||||
return array.map(key => ({
|
return array.map((key) => ({
|
||||||
id: key,
|
id: key,
|
||||||
name: I18n.t(`admin.wizard.custom_field.${type}.${key}`)
|
name: I18n.t(`admin.wizard.custom_field.${type}.${key}`),
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: 'tr',
|
tagName: "tr",
|
||||||
topicSerializers: ['topic_view', 'topic_list_item'],
|
topicSerializers: ["topic_view", "topic_list_item"],
|
||||||
postSerializers: ['post'],
|
postSerializers: ["post"],
|
||||||
groupSerializers: ['basic_group'],
|
groupSerializers: ["basic_group"],
|
||||||
categorySerializers: ['basic_category'],
|
categorySerializers: ["basic_category"],
|
||||||
klassContent: generateContent(['topic', 'post', 'group', 'category'], 'klass'),
|
klassContent: generateContent(
|
||||||
typeContent: generateContent(['string', 'boolean', 'integer', 'json'], 'type'),
|
["topic", "post", "group", "category"],
|
||||||
showInputs: or('field.new', 'field.edit'),
|
"klass"
|
||||||
classNames: ['custom-field-input'],
|
),
|
||||||
loading: or('saving', 'destroying'),
|
typeContent: generateContent(
|
||||||
destroyDisabled: alias('loading'),
|
["string", "boolean", "integer", "json"],
|
||||||
closeDisabled: alias('loading'),
|
"type"
|
||||||
|
),
|
||||||
|
showInputs: or("field.new", "field.edit"),
|
||||||
|
classNames: ["custom-field-input"],
|
||||||
|
loading: or("saving", "destroying"),
|
||||||
|
destroyDisabled: alias("loading"),
|
||||||
|
closeDisabled: alias("loading"),
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this.set('originalField', JSON.parse(JSON.stringify(this.field)));
|
this.set("originalField", JSON.parse(JSON.stringify(this.field)));
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('field.klass')
|
@discourseComputed("field.klass")
|
||||||
serializerContent(klass, p2) {
|
serializerContent(klass, p2) {
|
||||||
const serializers = this.get(`${klass}Serializers`);
|
const serializers = this.get(`${klass}Serializers`);
|
||||||
|
|
||||||
if (serializers) {
|
if (serializers) {
|
||||||
return generateContent(serializers, 'serializers');
|
return generateContent(serializers, "serializers");
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('field.klass')
|
@observes("field.klass")
|
||||||
clearSerializersWhenClassChanges() {
|
clearSerializersWhenClassChanges() {
|
||||||
this.set('field.serializers', null);
|
this.set("field.serializers", null);
|
||||||
},
|
},
|
||||||
|
|
||||||
compareArrays(array1, array2) {
|
compareArrays(array1, array2) {
|
||||||
return array1.length === array2.length && array1.every((value, index) => {
|
return (
|
||||||
return value === array2[index];
|
array1.length === array2.length &&
|
||||||
});
|
array1.every((value, index) => {
|
||||||
|
return value === array2[index];
|
||||||
|
})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
'saving',
|
"saving",
|
||||||
'field.name',
|
"field.name",
|
||||||
'field.klass',
|
"field.klass",
|
||||||
'field.type',
|
"field.type",
|
||||||
'field.serializers'
|
"field.serializers"
|
||||||
)
|
)
|
||||||
saveDisabled(saving) {
|
saveDisabled(saving) {
|
||||||
if (saving) return true;
|
if (saving) return true;
|
||||||
|
|
||||||
const originalField = this.originalField;
|
const originalField = this.originalField;
|
||||||
if (!originalField) return false;
|
if (!originalField) return false;
|
||||||
|
|
||||||
return ['name', 'klass', 'type', 'serializers'].every(attr => {
|
return ["name", "klass", "type", "serializers"].every((attr) => {
|
||||||
let current = this.get(attr);
|
let current = this.get(attr);
|
||||||
let original = originalField[attr];
|
let original = originalField[attr];
|
||||||
|
|
||||||
if (!current) return false;
|
if (!current) return false;
|
||||||
|
|
||||||
if (attr == 'serializers') {
|
if (attr == "serializers") {
|
||||||
return this.compareArrays(current, original);
|
return this.compareArrays(current, original);
|
||||||
} else {
|
} else {
|
||||||
return current == original;
|
return current == original;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
edit() {
|
edit() {
|
||||||
this.set('field.edit', true);
|
this.set("field.edit", true);
|
||||||
},
|
},
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
if (this.field.edit) {
|
if (this.field.edit) {
|
||||||
this.set('field.edit', false);
|
this.set("field.edit", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.set('destroying', true);
|
this.set("destroying", true);
|
||||||
this.removeField(this.field);
|
this.removeField(this.field);
|
||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
this.set('saving', true);
|
this.set("saving", true);
|
||||||
|
|
||||||
const field = this.field;
|
const field = this.field;
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
id: field.id,
|
id: field.id,
|
||||||
klass: field.klass,
|
klass: field.klass,
|
||||||
type: field.type,
|
type: field.type,
|
||||||
serializers: field.serializers,
|
serializers: field.serializers,
|
||||||
name: field.name
|
name: field.name,
|
||||||
}
|
};
|
||||||
|
|
||||||
this.saveField(data).then((result) => {
|
this.saveField(data).then((result) => {
|
||||||
this.set('saving', false);
|
this.set("saving", false);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.set('field.edit', false);
|
this.set("field.edit", false);
|
||||||
} else {
|
} else {
|
||||||
this.set('saveIcon', 'times');
|
this.set("saveIcon", "times");
|
||||||
}
|
}
|
||||||
setTimeout(() => this.set('saveIcon', null), 10000);
|
setTimeout(() => this.set("saveIcon", null), 10000);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import Component from '@ember/component';
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: 'wizard-advanced-toggle',
|
classNames: "wizard-advanced-toggle",
|
||||||
|
|
||||||
@discourseComputed('showAdvanced')
|
@discourseComputed("showAdvanced")
|
||||||
toggleClass(showAdvanced) {
|
toggleClass(showAdvanced) {
|
||||||
let classes = 'btn'
|
let classes = "btn";
|
||||||
if (showAdvanced) classes += ' btn-primary';
|
if (showAdvanced) classes += " btn-primary";
|
||||||
return classes;
|
return classes;
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
toggleAdvanced() {
|
toggleAdvanced() {
|
||||||
this.toggleProperty('showAdvanced');
|
this.toggleProperty("showAdvanced");
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,89 +1,98 @@
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import { equal, empty, or, and } from "@ember/object/computed";
|
import { equal, empty, or, and } from "@ember/object/computed";
|
||||||
import { generateName, selectKitContent } from '../lib/wizard';
|
import { generateName, selectKitContent } from "../lib/wizard";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import wizardSchema from '../lib/wizard-schema';
|
import wizardSchema from "../lib/wizard-schema";
|
||||||
import UndoChanges from '../mixins/undo-changes';
|
import UndoChanges from "../mixins/undo-changes";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { notificationLevels } from '../lib/wizard';
|
import { notificationLevels } from "../lib/wizard";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Component.extend(UndoChanges, {
|
export default Component.extend(UndoChanges, {
|
||||||
componentType: 'action',
|
componentType: "action",
|
||||||
classNameBindings: [':wizard-custom-action', 'visible'],
|
classNameBindings: [":wizard-custom-action", "visible"],
|
||||||
visible: computed('currentActionId', function() { return this.action.id === this.currentActionId }),
|
visible: computed("currentActionId", function () {
|
||||||
createTopic: equal('action.type', 'create_topic'),
|
return this.action.id === this.currentActionId;
|
||||||
updateProfile: equal('action.type', 'update_profile'),
|
}),
|
||||||
watchCategories: equal('action.type', 'watch_categories'),
|
createTopic: equal("action.type", "create_topic"),
|
||||||
sendMessage: equal('action.type', 'send_message'),
|
updateProfile: equal("action.type", "update_profile"),
|
||||||
openComposer: equal('action.type', 'open_composer'),
|
watchCategories: equal("action.type", "watch_categories"),
|
||||||
sendToApi: equal('action.type', 'send_to_api'),
|
sendMessage: equal("action.type", "send_message"),
|
||||||
addToGroup: equal('action.type', 'add_to_group'),
|
openComposer: equal("action.type", "open_composer"),
|
||||||
routeTo: equal('action.type', 'route_to'),
|
sendToApi: equal("action.type", "send_to_api"),
|
||||||
createCategory: equal('action.type', 'create_category'),
|
addToGroup: equal("action.type", "add_to_group"),
|
||||||
createGroup: equal('action.type', 'create_group'),
|
routeTo: equal("action.type", "route_to"),
|
||||||
apiEmpty: empty('action.api'),
|
createCategory: equal("action.type", "create_category"),
|
||||||
groupPropertyTypes: selectKitContent(['id', 'name']),
|
createGroup: equal("action.type", "create_group"),
|
||||||
hasAdvanced: or('hasCustomFields', 'routeTo'),
|
apiEmpty: empty("action.api"),
|
||||||
showAdvanced: and('hasAdvanced', 'action.type'),
|
groupPropertyTypes: selectKitContent(["id", "name"]),
|
||||||
hasCustomFields: or('basicTopicFields', 'updateProfile', 'createGroup', 'createCategory'),
|
hasAdvanced: or("hasCustomFields", "routeTo"),
|
||||||
basicTopicFields: or('createTopic', 'sendMessage', 'openComposer'),
|
showAdvanced: and("hasAdvanced", "action.type"),
|
||||||
publicTopicFields: or('createTopic', 'openComposer'),
|
hasCustomFields: or(
|
||||||
showPostAdvanced: or('createTopic', 'sendMessage'),
|
"basicTopicFields",
|
||||||
actionTypes: Object.keys(wizardSchema.action.types).map(type => {
|
"updateProfile",
|
||||||
|
"createGroup",
|
||||||
|
"createCategory"
|
||||||
|
),
|
||||||
|
basicTopicFields: or("createTopic", "sendMessage", "openComposer"),
|
||||||
|
publicTopicFields: or("createTopic", "openComposer"),
|
||||||
|
showPostAdvanced: or("createTopic", "sendMessage"),
|
||||||
|
actionTypes: Object.keys(wizardSchema.action.types).map((type) => {
|
||||||
return {
|
return {
|
||||||
id: type,
|
id: type,
|
||||||
name: I18n.t(`admin.wizard.action.${type}.label`)
|
name: I18n.t(`admin.wizard.action.${type}.label`),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
availableNotificationLevels: notificationLevels.map((type, index) => {
|
availableNotificationLevels: notificationLevels.map((type, index) => {
|
||||||
return {
|
return {
|
||||||
id: type,
|
id: type,
|
||||||
name: I18n.t(`admin.wizard.action.watch_categories.notification_level.${type}`)
|
name: I18n.t(
|
||||||
|
`admin.wizard.action.watch_categories.notification_level.${type}`
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
messageUrl: 'https://thepavilion.io/t/2810',
|
messageUrl: "https://thepavilion.io/t/2810",
|
||||||
|
|
||||||
@discourseComputed('action.type')
|
@discourseComputed("action.type")
|
||||||
messageKey(type) {
|
messageKey(type) {
|
||||||
let key = 'type';
|
let key = "type";
|
||||||
if (type) {
|
if (type) {
|
||||||
key = 'edit';
|
key = "edit";
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('wizard.steps')
|
@discourseComputed("wizard.steps")
|
||||||
runAfterContent(steps) {
|
runAfterContent(steps) {
|
||||||
let content = steps.map(function(step) {
|
let content = steps.map(function (step) {
|
||||||
return {
|
return {
|
||||||
id: step.id,
|
id: step.id,
|
||||||
name: step.title || step.id
|
name: step.title || step.id,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
content.unshift({
|
content.unshift({
|
||||||
id: 'wizard_completion',
|
id: "wizard_completion",
|
||||||
name: I18n.t('admin.wizard.action.run_after.wizard_completion')
|
name: I18n.t("admin.wizard.action.run_after.wizard_completion"),
|
||||||
});
|
});
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('apis')
|
@discourseComputed("apis")
|
||||||
availableApis(apis) {
|
availableApis(apis) {
|
||||||
return apis.map(a => {
|
return apis.map((a) => {
|
||||||
return {
|
return {
|
||||||
id: a.name,
|
id: a.name,
|
||||||
name: a.title
|
name: a.title,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('apis', 'action.api')
|
@discourseComputed("apis", "action.api")
|
||||||
availableEndpoints(apis, api) {
|
availableEndpoints(apis, api) {
|
||||||
if (!api) return [];
|
if (!api) return [];
|
||||||
return apis.find(a => a.name === api).endpoints;
|
return apis.find((a) => a.name === api).endpoints;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,117 +1,119 @@
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import { equal, or, alias } from "@ember/object/computed";
|
import { equal, or, alias } from "@ember/object/computed";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import { selectKitContent } from '../lib/wizard';
|
import { selectKitContent } from "../lib/wizard";
|
||||||
import UndoChanges from '../mixins/undo-changes';
|
import UndoChanges from "../mixins/undo-changes";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import wizardSchema from '../lib/wizard-schema';
|
import wizardSchema from "../lib/wizard-schema";
|
||||||
|
|
||||||
export default Component.extend(UndoChanges, {
|
export default Component.extend(UndoChanges, {
|
||||||
componentType: 'field',
|
componentType: "field",
|
||||||
classNameBindings: [':wizard-custom-field', 'visible'],
|
classNameBindings: [":wizard-custom-field", "visible"],
|
||||||
visible: computed('currentFieldId', function() { return this.field.id === this.currentFieldId }),
|
visible: computed("currentFieldId", function () {
|
||||||
isDropdown: equal('field.type', 'dropdown'),
|
return this.field.id === this.currentFieldId;
|
||||||
isUpload: equal('field.type', 'upload'),
|
}),
|
||||||
isCategory: equal('field.type', 'category'),
|
isDropdown: equal("field.type", "dropdown"),
|
||||||
isGroup: equal('field.type', 'group'),
|
isUpload: equal("field.type", "upload"),
|
||||||
isTag: equal('field.type', 'tag'),
|
isCategory: equal("field.type", "category"),
|
||||||
isText: equal('field.type', 'text'),
|
isGroup: equal("field.type", "group"),
|
||||||
isTextarea: equal('field.type', 'textarea'),
|
isTag: equal("field.type", "tag"),
|
||||||
isUrl: equal('field.type', 'url'),
|
isText: equal("field.type", "text"),
|
||||||
isComposer: equal('field.type', 'composer'),
|
isTextarea: equal("field.type", "textarea"),
|
||||||
showPrefill: or('isText', 'isCategory', 'isTag', 'isGroup', 'isDropdown'),
|
isUrl: equal("field.type", "url"),
|
||||||
showContent: or('isCategory', 'isTag', 'isGroup', 'isDropdown'),
|
isComposer: equal("field.type", "composer"),
|
||||||
showLimit: or('isCategory', 'isTag'),
|
showPrefill: or("isText", "isCategory", "isTag", "isGroup", "isDropdown"),
|
||||||
isTextType: or('isText', 'isTextarea', 'isComposer'),
|
showContent: or("isCategory", "isTag", "isGroup", "isDropdown"),
|
||||||
categoryPropertyTypes: selectKitContent(['id', 'slug']),
|
showLimit: or("isCategory", "isTag"),
|
||||||
showAdvanced: alias('field.type'),
|
isTextType: or("isText", "isTextarea", "isComposer"),
|
||||||
messageUrl: 'https://thepavilion.io/t/2809',
|
categoryPropertyTypes: selectKitContent(["id", "slug"]),
|
||||||
|
showAdvanced: alias("field.type"),
|
||||||
@discourseComputed('field.type')
|
messageUrl: "https://thepavilion.io/t/2809",
|
||||||
|
|
||||||
|
@discourseComputed("field.type")
|
||||||
validations(type) {
|
validations(type) {
|
||||||
const applicableToField = [];
|
const applicableToField = [];
|
||||||
|
|
||||||
for(let validation in wizardSchema.field.validations) {
|
for (let validation in wizardSchema.field.validations) {
|
||||||
if ((wizardSchema.field.validations[validation]["types"]).includes(type)) {
|
if (wizardSchema.field.validations[validation]["types"].includes(type)) {
|
||||||
applicableToField.push(validation)
|
applicableToField.push(validation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return applicableToField;
|
return applicableToField;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('field.type')
|
@discourseComputed("field.type")
|
||||||
isDateTime(type) {
|
isDateTime(type) {
|
||||||
return ['date_time', 'date', 'time'].indexOf(type) > -1;
|
return ["date_time", "date", "time"].indexOf(type) > -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('field.type')
|
@discourseComputed("field.type")
|
||||||
messageKey(type) {
|
messageKey(type) {
|
||||||
let key = 'type';
|
let key = "type";
|
||||||
if (type) {
|
if (type) {
|
||||||
key = 'edit';
|
key = "edit";
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
},
|
},
|
||||||
|
|
||||||
setupTypeOutput(fieldType, options) {
|
setupTypeOutput(fieldType, options) {
|
||||||
const selectionType = {
|
const selectionType = {
|
||||||
category: 'category',
|
category: "category",
|
||||||
tag: 'tag',
|
tag: "tag",
|
||||||
group: 'group'
|
group: "group",
|
||||||
}[fieldType];
|
}[fieldType];
|
||||||
|
|
||||||
if (selectionType) {
|
if (selectionType) {
|
||||||
options[`${selectionType}Selection`] = 'output';
|
options[`${selectionType}Selection`] = "output";
|
||||||
options.outputDefaultSelection = selectionType;
|
options.outputDefaultSelection = selectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('field.type')
|
@discourseComputed("field.type")
|
||||||
contentOptions(fieldType) {
|
contentOptions(fieldType) {
|
||||||
let options = {
|
let options = {
|
||||||
wizardFieldSelection: true,
|
wizardFieldSelection: true,
|
||||||
textSelection: 'key,value',
|
textSelection: "key,value",
|
||||||
userFieldSelection: 'key,value',
|
userFieldSelection: "key,value",
|
||||||
context: 'field'
|
context: "field",
|
||||||
}
|
};
|
||||||
|
|
||||||
options = this.setupTypeOutput(fieldType, options);
|
options = this.setupTypeOutput(fieldType, options);
|
||||||
|
|
||||||
if (this.isDropdown) {
|
if (this.isDropdown) {
|
||||||
options.wizardFieldSelection = 'key,value';
|
options.wizardFieldSelection = "key,value";
|
||||||
options.userFieldOptionsSelection = 'output';
|
options.userFieldOptionsSelection = "output";
|
||||||
options.textSelection = 'key,value,output';
|
options.textSelection = "key,value,output";
|
||||||
options.inputTypes = 'conditional,association,assignment';
|
options.inputTypes = "conditional,association,assignment";
|
||||||
options.pairConnector = 'association';
|
options.pairConnector = "association";
|
||||||
options.keyPlaceholder = 'admin.wizard.key';
|
options.keyPlaceholder = "admin.wizard.key";
|
||||||
options.valuePlaceholder = 'admin.wizard.value';
|
options.valuePlaceholder = "admin.wizard.value";
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('field.type')
|
@discourseComputed("field.type")
|
||||||
prefillOptions(fieldType) {
|
prefillOptions(fieldType) {
|
||||||
let options = {
|
let options = {
|
||||||
wizardFieldSelection: true,
|
wizardFieldSelection: true,
|
||||||
textSelection: true,
|
textSelection: true,
|
||||||
userFieldSelection: 'key,value',
|
userFieldSelection: "key,value",
|
||||||
context: 'field'
|
context: "field",
|
||||||
}
|
};
|
||||||
|
|
||||||
return this.setupTypeOutput(fieldType, options);
|
return this.setupTypeOutput(fieldType, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
imageUploadDone(upload) {
|
imageUploadDone(upload) {
|
||||||
this.set("field.image", upload.url);
|
this.set("field.image", upload.url);
|
||||||
},
|
},
|
||||||
|
|
||||||
imageUploadDeleted() {
|
imageUploadDeleted() {
|
||||||
this.set("field.image", null);
|
this.set("field.image", null);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: 'wizard-custom-step',
|
classNames: "wizard-custom-step",
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
bannerUploadDone(upload) {
|
bannerUploadDone(upload) {
|
||||||
this.set("step.banner", upload.url);
|
this.set("step.banner", upload.url);
|
||||||
},
|
},
|
||||||
|
|
||||||
bannerUploadDeleted() {
|
bannerUploadDeleted() {
|
||||||
this.set("step.banner", null);
|
this.set("step.banner", null);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import { default as discourseComputed, on, observes } from 'discourse-common/utils/decorators';
|
import {
|
||||||
import { generateName } from '../lib/wizard';
|
default as discourseComputed,
|
||||||
import { default as wizardSchema, setWizardDefaults } from '../lib/wizard-schema';
|
on,
|
||||||
|
observes,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
|
import { generateName } from "../lib/wizard";
|
||||||
|
import {
|
||||||
|
default as wizardSchema,
|
||||||
|
setWizardDefaults,
|
||||||
|
} from "../lib/wizard-schema";
|
||||||
import { notEmpty } from "@ember/object/computed";
|
import { notEmpty } from "@ember/object/computed";
|
||||||
import { scheduleOnce, bind } from "@ember/runloop";
|
import { scheduleOnce, bind } from "@ember/runloop";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
@ -8,56 +15,63 @@ import Component from "@ember/component";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':wizard-links', 'itemType'],
|
classNameBindings: [":wizard-links", "itemType"],
|
||||||
items: A(),
|
items: A(),
|
||||||
anyLinks: notEmpty('links'),
|
anyLinks: notEmpty("links"),
|
||||||
|
|
||||||
@on('didInsertElement')
|
@on("didInsertElement")
|
||||||
@observes('links.[]')
|
@observes("links.[]")
|
||||||
setupSortable() {
|
setupSortable() {
|
||||||
scheduleOnce('afterRender', () => (this.applySortable()));
|
scheduleOnce("afterRender", () => this.applySortable());
|
||||||
},
|
},
|
||||||
|
|
||||||
applySortable() {
|
applySortable() {
|
||||||
$(this.element).find(".link-list")
|
$(this.element)
|
||||||
.sortable({ tolerance: 'pointer' })
|
.find(".link-list")
|
||||||
.on('sortupdate', (e, ui) => {
|
.sortable({ tolerance: "pointer" })
|
||||||
this.updateItemOrder(ui.item.data('id'), ui.item.index());
|
.on("sortupdate", (e, ui) => {
|
||||||
|
this.updateItemOrder(ui.item.data("id"), ui.item.index());
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
updateItemOrder(itemId, newIndex) {
|
updateItemOrder(itemId, newIndex) {
|
||||||
const items = this.items;
|
const items = this.items;
|
||||||
const item = items.findBy('id', itemId);
|
const item = items.findBy("id", itemId);
|
||||||
items.removeObject(item);
|
items.removeObject(item);
|
||||||
items.insertAt(newIndex, item);
|
items.insertAt(newIndex, item);
|
||||||
scheduleOnce('afterRender', this, () => this.applySortable());
|
scheduleOnce("afterRender", this, () => this.applySortable());
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('itemType')
|
@discourseComputed("itemType")
|
||||||
header: (itemType) => `admin.wizard.${itemType}.header`,
|
header: (itemType) => `admin.wizard.${itemType}.header`,
|
||||||
|
|
||||||
@discourseComputed('current', 'items.@each.id', 'items.@each.type', 'items.@each.label', 'items.@each.title')
|
@discourseComputed(
|
||||||
|
"current",
|
||||||
|
"items.@each.id",
|
||||||
|
"items.@each.type",
|
||||||
|
"items.@each.label",
|
||||||
|
"items.@each.title"
|
||||||
|
)
|
||||||
links(current, items) {
|
links(current, items) {
|
||||||
if (!items) return;
|
if (!items) return;
|
||||||
|
|
||||||
return items.map((item) => {
|
return items.map((item) => {
|
||||||
if (item) {
|
if (item) {
|
||||||
let link = {
|
let link = {
|
||||||
id: item.id
|
id: item.id,
|
||||||
}
|
};
|
||||||
|
|
||||||
let label = item.label || item.title || item.id;
|
let label = item.label || item.title || item.id;
|
||||||
if (this.generateLabels && item.type) {
|
if (this.generateLabels && item.type) {
|
||||||
label = generateName(item.type);
|
label = generateName(item.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
link.label = `${label} (${item.id})`;
|
link.label = `${label} (${item.id})`;
|
||||||
|
|
||||||
let classes = 'btn';
|
let classes = "btn";
|
||||||
if (current && item.id === current.id) {
|
if (current && item.id === current.id) {
|
||||||
classes += ' btn-primary';
|
classes += " btn-primary";
|
||||||
};
|
}
|
||||||
|
|
||||||
link.classes = classes;
|
link.classes = classes;
|
||||||
|
|
||||||
|
@ -68,69 +82,73 @@ export default Component.extend({
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
add() {
|
add() {
|
||||||
const items = this.get('items');
|
const items = this.get("items");
|
||||||
const itemType = this.itemType;
|
const itemType = this.itemType;
|
||||||
let params = setWizardDefaults({}, itemType);
|
let params = setWizardDefaults({}, itemType);
|
||||||
|
|
||||||
params.isNew = true;
|
params.isNew = true;
|
||||||
|
|
||||||
let next = 1;
|
let next = 1;
|
||||||
|
|
||||||
if (items.length) {
|
if (items.length) {
|
||||||
next = Math.max.apply(Math, items.map((i) => {
|
next =
|
||||||
let parts = i.id.split('_');
|
Math.max.apply(
|
||||||
let lastPart = parts[parts.length - 1];
|
Math,
|
||||||
return isNaN(lastPart) ? 0 : lastPart;
|
items.map((i) => {
|
||||||
})) + 1;
|
let parts = i.id.split("_");
|
||||||
|
let lastPart = parts[parts.length - 1];
|
||||||
|
return isNaN(lastPart) ? 0 : lastPart;
|
||||||
|
})
|
||||||
|
) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = `${itemType}_${next}`;
|
let id = `${itemType}_${next}`;
|
||||||
|
|
||||||
if (itemType === 'field') {
|
if (itemType === "field") {
|
||||||
id = `${this.parentId}_${id}`;
|
id = `${this.parentId}_${id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.id = id;
|
params.id = id;
|
||||||
|
|
||||||
let objectArrays = wizardSchema[itemType].objectArrays;
|
let objectArrays = wizardSchema[itemType].objectArrays;
|
||||||
if (objectArrays) {
|
if (objectArrays) {
|
||||||
Object.keys(objectArrays).forEach(objectType => {
|
Object.keys(objectArrays).forEach((objectType) => {
|
||||||
params[objectArrays[objectType].property] = A();
|
params[objectArrays[objectType].property] = A();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
const newItem = EmberObject.create(params);
|
const newItem = EmberObject.create(params);
|
||||||
items.pushObject(newItem);
|
items.pushObject(newItem);
|
||||||
|
|
||||||
this.set('current', newItem);
|
this.set("current", newItem);
|
||||||
},
|
},
|
||||||
|
|
||||||
change(itemId) {
|
change(itemId) {
|
||||||
this.set('current', this.items.findBy('id', itemId));
|
this.set("current", this.items.findBy("id", itemId));
|
||||||
},
|
},
|
||||||
|
|
||||||
remove(itemId) {
|
remove(itemId) {
|
||||||
const items = this.items;
|
const items = this.items;
|
||||||
let item;
|
let item;
|
||||||
let index;
|
let index;
|
||||||
|
|
||||||
items.forEach((it, ind) => {
|
items.forEach((it, ind) => {
|
||||||
if (it.id === itemId) {
|
if (it.id === itemId) {
|
||||||
item = it;
|
item = it;
|
||||||
index = ind;
|
index = ind;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let nextIndex;
|
let nextIndex;
|
||||||
if (this.current.id === itemId) {
|
if (this.current.id === itemId) {
|
||||||
nextIndex = index < (items.length-2) ? (index+1) : (index-1);
|
nextIndex = index < items.length - 2 ? index + 1 : index - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
items.removeObject(item);
|
items.removeObject(item);
|
||||||
|
|
||||||
if (nextIndex) {
|
if (nextIndex) {
|
||||||
this.set('current', items[nextIndex]);
|
this.set("current", items[nextIndex]);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,35 +1,39 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { gt } from '@ember/object/computed';
|
import { gt } from "@ember/object/computed";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import { defaultConnector } from '../lib/wizard-mapper';
|
import { defaultConnector } from "../lib/wizard-mapper";
|
||||||
import { later } from "@ember/runloop";
|
import { later } from "@ember/runloop";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':mapper-connector', ':mapper-block', 'hasMultiple::single'],
|
classNameBindings: [
|
||||||
hasMultiple: gt('connectors.length', 1),
|
":mapper-connector",
|
||||||
connectorLabel: computed(function() {
|
":mapper-block",
|
||||||
|
"hasMultiple::single",
|
||||||
|
],
|
||||||
|
hasMultiple: gt("connectors.length", 1),
|
||||||
|
connectorLabel: computed(function () {
|
||||||
let key = this.connector;
|
let key = this.connector;
|
||||||
let path = this.inputTypes ? `input.${key}.name` : `connector.${key}`;
|
let path = this.inputTypes ? `input.${key}.name` : `connector.${key}`;
|
||||||
return I18n.t(`admin.wizard.${path}`);
|
return I18n.t(`admin.wizard.${path}`);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
if (!this.connector) {
|
if (!this.connector) {
|
||||||
later(() => {
|
later(() => {
|
||||||
this.set(
|
this.set(
|
||||||
'connector',
|
"connector",
|
||||||
defaultConnector(this.connectorType, this.inputType, this.options)
|
defaultConnector(this.connectorType, this.inputType, this.options)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
changeConnector(value) {
|
changeConnector(value) {
|
||||||
this.set('connector', value);
|
this.set("connector", value);
|
||||||
this.onUpdate('connector', this.connectorType);
|
this.onUpdate("connector", this.connectorType);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,69 +1,78 @@
|
||||||
import { computed, set } from "@ember/object";
|
import { computed, set } from "@ember/object";
|
||||||
import { alias, equal, or, not } from "@ember/object/computed";
|
import { alias, equal, or, not } from "@ember/object/computed";
|
||||||
import { newPair, connectorContent, inputTypesContent, defaultSelectionType, defaultConnector } from '../lib/wizard-mapper';
|
import {
|
||||||
|
newPair,
|
||||||
|
connectorContent,
|
||||||
|
inputTypesContent,
|
||||||
|
defaultSelectionType,
|
||||||
|
defaultConnector,
|
||||||
|
} from "../lib/wizard-mapper";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':mapper-input', 'inputType'],
|
classNameBindings: [":mapper-input", "inputType"],
|
||||||
inputType: alias('input.type'),
|
inputType: alias("input.type"),
|
||||||
isConditional: equal('inputType', 'conditional'),
|
isConditional: equal("inputType", "conditional"),
|
||||||
isAssignment: equal('inputType', 'assignment'),
|
isAssignment: equal("inputType", "assignment"),
|
||||||
isAssociation: equal('inputType', 'association'),
|
isAssociation: equal("inputType", "association"),
|
||||||
isValidation: equal('inputType', 'validation'),
|
isValidation: equal("inputType", "validation"),
|
||||||
hasOutput: or('isConditional', 'isAssignment'),
|
hasOutput: or("isConditional", "isAssignment"),
|
||||||
hasPairs: or('isConditional', 'isAssociation', 'isValidation'),
|
hasPairs: or("isConditional", "isAssociation", "isValidation"),
|
||||||
canAddPair: not('isAssignment'),
|
canAddPair: not("isAssignment"),
|
||||||
connectors: computed(function() { return connectorContent('output', this.input.type, this.options) }),
|
connectors: computed(function () {
|
||||||
inputTypes: computed(function() { return inputTypesContent(this.options) }),
|
return connectorContent("output", this.input.type, this.options);
|
||||||
|
}),
|
||||||
@observes('input.type')
|
inputTypes: computed(function () {
|
||||||
|
return inputTypesContent(this.options);
|
||||||
|
}),
|
||||||
|
|
||||||
|
@observes("input.type")
|
||||||
setupType() {
|
setupType() {
|
||||||
if (this.hasPairs && (!this.input.pairs || this.input.pairs.length < 1)) {
|
if (this.hasPairs && (!this.input.pairs || this.input.pairs.length < 1)) {
|
||||||
this.send('addPair');
|
this.send("addPair");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasOutput) {
|
if (this.hasOutput) {
|
||||||
this.set('input.output', null);
|
this.set("input.output", null);
|
||||||
|
|
||||||
if (!this.input.outputConnector) {
|
if (!this.input.outputConnector) {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
this.set('input.output_type', defaultSelectionType('output', options));
|
this.set("input.output_type", defaultSelectionType("output", options));
|
||||||
this.set('input.output_connector', defaultConnector('output', this.inputType, options));
|
this.set(
|
||||||
|
"input.output_connector",
|
||||||
|
defaultConnector("output", this.inputType, options)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addPair() {
|
addPair() {
|
||||||
if (!this.input.pairs) {
|
if (!this.input.pairs) {
|
||||||
this.set('input.pairs', A());
|
this.set("input.pairs", A());
|
||||||
}
|
}
|
||||||
|
|
||||||
const pairs = this.input.pairs;
|
const pairs = this.input.pairs;
|
||||||
const pairCount = pairs.length + 1;
|
const pairCount = pairs.length + 1;
|
||||||
|
|
||||||
pairs.forEach(p => (set(p, 'pairCount', pairCount)));
|
pairs.forEach((p) => set(p, "pairCount", pairCount));
|
||||||
|
|
||||||
pairs.pushObject(
|
pairs.pushObject(
|
||||||
newPair(
|
newPair(
|
||||||
this.input.type,
|
this.input.type,
|
||||||
Object.assign(
|
Object.assign({}, this.options, { index: pairs.length, pairCount })
|
||||||
{},
|
|
||||||
this.options,
|
|
||||||
{ index: pairs.length, pairCount }
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
removePair(pair) {
|
removePair(pair) {
|
||||||
const pairs = this.input.pairs;
|
const pairs = this.input.pairs;
|
||||||
const pairCount = pairs.length - 1;
|
const pairCount = pairs.length - 1;
|
||||||
|
|
||||||
pairs.forEach(p => (set(p, 'pairCount', pairCount)));
|
pairs.forEach((p) => set(p, "pairCount", pairCount));
|
||||||
pairs.removeObject(pair);
|
pairs.removeObject(pair);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
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";
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default 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() { return this.pair.index < (this.pair.pairCount - 1) }),
|
showJoin: computed("pair.pairCount", function () {
|
||||||
connectors: computed(function() { return connectorContent('pair', this.inputType, this.options) })
|
return this.pair.index < this.pair.pairCount - 1;
|
||||||
});
|
}),
|
||||||
|
connectors: computed(function () {
|
||||||
|
return connectorContent("pair", this.inputType, this.options);
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import discourseComputed from 'discourse-common/utils/decorators';
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: 'a',
|
tagName: "a",
|
||||||
classNameBindings: ['active'],
|
classNameBindings: ["active"],
|
||||||
|
|
||||||
@discourseComputed('item.type', 'activeType')
|
@discourseComputed("item.type", "activeType")
|
||||||
active(type, activeType) { return type === activeType },
|
active(type, activeType) {
|
||||||
|
return type === activeType;
|
||||||
|
},
|
||||||
|
|
||||||
click() {
|
click() {
|
||||||
this.toggle(this.item.type)
|
this.toggle(this.item.type);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,51 +1,132 @@
|
||||||
import { alias, or, gt } from "@ember/object/computed";
|
import { alias, or, gt } from "@ember/object/computed";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import { default as discourseComputed, observes, on } from "discourse-common/utils/decorators";
|
import {
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
default as discourseComputed,
|
||||||
import { defaultSelectionType, selectionTypes } from '../lib/wizard-mapper';
|
observes,
|
||||||
import { snakeCase, generateName, userProperties } from '../lib/wizard';
|
on,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
import { defaultSelectionType, selectionTypes } from "../lib/wizard-mapper";
|
||||||
|
import { snakeCase, generateName, userProperties } from "../lib/wizard";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { bind, later } from "@ember/runloop";
|
import { bind, later } from "@ember/runloop";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':mapper-selector', 'activeType'],
|
classNameBindings: [":mapper-selector", "activeType"],
|
||||||
|
|
||||||
showText: computed('activeType', function() { return this.showInput('text') }),
|
showText: computed("activeType", function () {
|
||||||
showWizardField: computed('activeType', function() { return this.showInput('wizardField') }),
|
return this.showInput("text");
|
||||||
showWizardAction: computed('activeType', function() { return this.showInput('wizardAction') }),
|
}),
|
||||||
showUserField: computed('activeType', function() { return this.showInput('userField') }),
|
showWizardField: computed("activeType", function () {
|
||||||
showUserFieldOptions: computed('activeType', function() { return this.showInput('userFieldOptions') }),
|
return this.showInput("wizardField");
|
||||||
showCategory: computed('activeType', function() { return this.showInput('category') }),
|
}),
|
||||||
showTag: computed('activeType', function() { return this.showInput('tag') }),
|
showWizardAction: computed("activeType", function () {
|
||||||
showGroup: computed('activeType', function() { return this.showInput('group') }),
|
return this.showInput("wizardAction");
|
||||||
showUser: computed('activeType', function() { return this.showInput('user') }),
|
}),
|
||||||
showList: computed('activeType', function() { return this.showInput('list') }),
|
showUserField: computed("activeType", function () {
|
||||||
showCustomField: computed('activeType', function() { return this.showInput('customField') }),
|
return this.showInput("userField");
|
||||||
textEnabled: computed('options.textSelection', 'inputType', function() { return this.optionEnabled('textSelection') }),
|
}),
|
||||||
wizardFieldEnabled: computed('options.wizardFieldSelection', 'inputType', function() { return this.optionEnabled('wizardFieldSelection') }),
|
showUserFieldOptions: computed("activeType", function () {
|
||||||
wizardActionEnabled: computed('options.wizardActionSelection', 'inputType', function() { return this.optionEnabled('wizardActionSelection') }),
|
return this.showInput("userFieldOptions");
|
||||||
customFieldEnabled: computed('options.customFieldSelection', 'inputType', function() { return this.optionEnabled('customFieldSelection') }),
|
}),
|
||||||
userFieldEnabled: computed('options.userFieldSelection', 'inputType', function() { return this.optionEnabled('userFieldSelection') }),
|
showCategory: computed("activeType", function () {
|
||||||
userFieldOptionsEnabled: computed('options.userFieldOptionsSelection', 'inputType', function() { return this.optionEnabled('userFieldOptionsSelection') }),
|
return this.showInput("category");
|
||||||
categoryEnabled: computed('options.categorySelection', 'inputType', function() { return this.optionEnabled('categorySelection') }),
|
}),
|
||||||
tagEnabled: computed('options.tagSelection', 'inputType', function() { return this.optionEnabled('tagSelection') }),
|
showTag: computed("activeType", function () {
|
||||||
groupEnabled: computed('options.groupSelection', 'inputType', function() { return this.optionEnabled('groupSelection') }),
|
return this.showInput("tag");
|
||||||
userEnabled: computed('options.userSelection', 'inputType', function() { return this.optionEnabled('userSelection') }),
|
}),
|
||||||
listEnabled: computed('options.listSelection', 'inputType', function() { return this.optionEnabled('listSelection') }),
|
showGroup: computed("activeType", function () {
|
||||||
|
return this.showInput("group");
|
||||||
groups: alias('site.groups'),
|
}),
|
||||||
categories: alias('site.categories'),
|
showUser: computed("activeType", function () {
|
||||||
showComboBox: or('showWizardField', 'showWizardAction', 'showUserField', 'showUserFieldOptions', 'showCustomField'),
|
return this.showInput("user");
|
||||||
showMultiSelect: or('showCategory', 'showGroup'),
|
}),
|
||||||
hasTypes: gt('selectorTypes.length', 1),
|
showList: computed("activeType", function () {
|
||||||
|
return this.showInput("list");
|
||||||
|
}),
|
||||||
|
showCustomField: computed("activeType", function () {
|
||||||
|
return this.showInput("customField");
|
||||||
|
}),
|
||||||
|
textEnabled: computed("options.textSelection", "inputType", function () {
|
||||||
|
return this.optionEnabled("textSelection");
|
||||||
|
}),
|
||||||
|
wizardFieldEnabled: computed(
|
||||||
|
"options.wizardFieldSelection",
|
||||||
|
"inputType",
|
||||||
|
function () {
|
||||||
|
return this.optionEnabled("wizardFieldSelection");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
wizardActionEnabled: computed(
|
||||||
|
"options.wizardActionSelection",
|
||||||
|
"inputType",
|
||||||
|
function () {
|
||||||
|
return this.optionEnabled("wizardActionSelection");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
customFieldEnabled: computed(
|
||||||
|
"options.customFieldSelection",
|
||||||
|
"inputType",
|
||||||
|
function () {
|
||||||
|
return this.optionEnabled("customFieldSelection");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
userFieldEnabled: computed(
|
||||||
|
"options.userFieldSelection",
|
||||||
|
"inputType",
|
||||||
|
function () {
|
||||||
|
return this.optionEnabled("userFieldSelection");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
userFieldOptionsEnabled: computed(
|
||||||
|
"options.userFieldOptionsSelection",
|
||||||
|
"inputType",
|
||||||
|
function () {
|
||||||
|
return this.optionEnabled("userFieldOptionsSelection");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
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");
|
||||||
|
}),
|
||||||
|
|
||||||
|
groups: alias("site.groups"),
|
||||||
|
categories: alias("site.categories"),
|
||||||
|
showComboBox: or(
|
||||||
|
"showWizardField",
|
||||||
|
"showWizardAction",
|
||||||
|
"showUserField",
|
||||||
|
"showUserFieldOptions",
|
||||||
|
"showCustomField"
|
||||||
|
),
|
||||||
|
showMultiSelect: or("showCategory", "showGroup"),
|
||||||
|
hasTypes: gt("selectorTypes.length", 1),
|
||||||
showTypes: false,
|
showTypes: false,
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
if (!this.activeType || (this.activeType && !this[`${this.activeType}Enabled`])) {
|
if (
|
||||||
|
!this.activeType ||
|
||||||
|
(this.activeType && !this[`${this.activeType}Enabled`])
|
||||||
|
) {
|
||||||
later(() => this.resetActiveType());
|
later(() => this.resetActiveType());
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on("click", bind(this, this.documentClick));
|
$(document).on("click", bind(this, this.documentClick));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -56,42 +137,45 @@ export default Component.extend({
|
||||||
documentClick(e) {
|
documentClick(e) {
|
||||||
if (this._state == "destroying") return;
|
if (this._state == "destroying") return;
|
||||||
let $target = $(e.target);
|
let $target = $(e.target);
|
||||||
|
|
||||||
if (!$target.parents('.type-selector').length && this.showTypes) {
|
if (!$target.parents(".type-selector").length && this.showTypes) {
|
||||||
this.set('showTypes', false);
|
this.set("showTypes", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
selectorTypes() {
|
selectorTypes() {
|
||||||
return selectionTypes.filter(type => (this[`${type}Enabled`]))
|
return selectionTypes
|
||||||
.map(type => ({ type, label: this.typeLabel(type) }));
|
.filter((type) => this[`${type}Enabled`])
|
||||||
|
.map((type) => ({ type, label: this.typeLabel(type) }));
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('activeType')
|
@discourseComputed("activeType")
|
||||||
activeTypeLabel(activeType) {
|
activeTypeLabel(activeType) {
|
||||||
return this.typeLabel(activeType);
|
return this.typeLabel(activeType);
|
||||||
},
|
},
|
||||||
|
|
||||||
typeLabel(type) {
|
typeLabel(type) {
|
||||||
return type ? I18n.t(`admin.wizard.selector.label.${snakeCase(type)}`) : null;
|
return type
|
||||||
|
? I18n.t(`admin.wizard.selector.label.${snakeCase(type)}`)
|
||||||
|
: null;
|
||||||
},
|
},
|
||||||
|
|
||||||
comboBoxAllowAny: or('showWizardField', 'showWizardAction'),
|
comboBoxAllowAny: or("showWizardField", "showWizardAction"),
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
showController() {
|
showController() {
|
||||||
return getOwner(this).lookup('controller:admin-wizards-wizard-show');
|
return getOwner(this).lookup("controller:admin-wizards-wizard-show");
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
'activeType',
|
"activeType",
|
||||||
'showController.wizardFields.[]',
|
"showController.wizardFields.[]",
|
||||||
'showController.wizard.actions.[]',
|
"showController.wizard.actions.[]",
|
||||||
'showController.userFields.[]',
|
"showController.userFields.[]",
|
||||||
'showController.currentField.id',
|
"showController.currentField.id",
|
||||||
'showController.currentAction.id',
|
"showController.currentAction.id",
|
||||||
'showController.customFields'
|
"showController.customFields"
|
||||||
)
|
)
|
||||||
comboBoxContent(
|
comboBoxContent(
|
||||||
activeType,
|
activeType,
|
||||||
|
@ -103,133 +187,144 @@ export default Component.extend({
|
||||||
customFields
|
customFields
|
||||||
) {
|
) {
|
||||||
let content;
|
let content;
|
||||||
|
|
||||||
if (activeType === 'wizardField') {
|
if (activeType === "wizardField") {
|
||||||
content = wizardFields;
|
content = wizardFields;
|
||||||
|
|
||||||
if (this.options.context === 'field') {
|
if (this.options.context === "field") {
|
||||||
content = content.filter(field => field.id !== currentFieldId);
|
content = content.filter((field) => field.id !== currentFieldId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeType === 'wizardAction') {
|
if (activeType === "wizardAction") {
|
||||||
content = wizardActions.map(a => ({
|
content = wizardActions.map((a) => ({
|
||||||
id: a.id,
|
id: a.id,
|
||||||
label: `${generateName(a.type)} (${a.id})`,
|
label: `${generateName(a.type)} (${a.id})`,
|
||||||
type: a.type
|
type: a.type,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (this.options.context === 'action') {
|
if (this.options.context === "action") {
|
||||||
content = content.filter(a => a.id !== currentActionId);
|
content = content.filter((a) => a.id !== currentActionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeType === 'userField') {
|
if (activeType === "userField") {
|
||||||
content = userProperties.map((f) => ({
|
content = userProperties
|
||||||
id: f,
|
.map((f) => ({
|
||||||
name: generateName(f)
|
id: f,
|
||||||
})).concat((userFields || []));
|
name: generateName(f),
|
||||||
|
}))
|
||||||
if (this.options.context === 'action' &&
|
.concat(userFields || []);
|
||||||
this.inputType === 'association' &&
|
|
||||||
this.selectorType === 'key') {
|
if (
|
||||||
|
this.options.context === "action" &&
|
||||||
const excludedFields = ['username','email', 'trust_level'];
|
this.inputType === "association" &&
|
||||||
content = content.filter(userField => excludedFields.indexOf(userField.id) === -1);
|
this.selectorType === "key"
|
||||||
|
) {
|
||||||
|
const excludedFields = ["username", "email", "trust_level"];
|
||||||
|
content = content.filter(
|
||||||
|
(userField) => excludedFields.indexOf(userField.id) === -1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeType === 'userFieldOptions') {
|
if (activeType === "userFieldOptions") {
|
||||||
content = userFields;
|
content = userFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeType === 'customField') {
|
if (activeType === "customField") {
|
||||||
content = customFields;
|
content = customFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('activeType')
|
@discourseComputed("activeType")
|
||||||
multiSelectContent(activeType) {
|
multiSelectContent(activeType) {
|
||||||
return {
|
return {
|
||||||
category: this.categories,
|
category: this.categories,
|
||||||
group: this.groups,
|
group: this.groups,
|
||||||
list: ''
|
list: "",
|
||||||
}[activeType];
|
}[activeType];
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('activeType', 'inputType')
|
@discourseComputed("activeType", "inputType")
|
||||||
placeholderKey(activeType, inputType) {
|
placeholderKey(activeType, inputType) {
|
||||||
if (activeType === 'text' && this.options[`${this.selectorType}Placeholder`]) {
|
if (
|
||||||
|
activeType === "text" &&
|
||||||
|
this.options[`${this.selectorType}Placeholder`]
|
||||||
|
) {
|
||||||
return this.options[`${this.selectorType}Placeholder`];
|
return this.options[`${this.selectorType}Placeholder`];
|
||||||
} else {
|
} else {
|
||||||
return `admin.wizard.selector.placeholder.${snakeCase(activeType)}`;
|
return `admin.wizard.selector.placeholder.${snakeCase(activeType)}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('activeType')
|
@discourseComputed("activeType")
|
||||||
multiSelectOptions(activeType) {
|
multiSelectOptions(activeType) {
|
||||||
let result = {
|
let result = {
|
||||||
none: this.placeholderKey
|
none: this.placeholderKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (activeType === 'list') {
|
if (activeType === "list") {
|
||||||
result.allowAny = true;
|
result.allowAny = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
optionEnabled(type) {
|
optionEnabled(type) {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
if (!options) return false;
|
if (!options) return false;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
return option.split(',').filter(option => {
|
return option.split(",").filter((option) => {
|
||||||
return [this.selectorType, this.inputType].indexOf(option) !== -1;
|
return [this.selectorType, this.inputType].indexOf(option) !== -1;
|
||||||
}).length;
|
}).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
showInput(type) {
|
showInput(type) {
|
||||||
return this.activeType === type && this[`${type}Enabled`];
|
return this.activeType === type && this[`${type}Enabled`];
|
||||||
},
|
},
|
||||||
|
|
||||||
changeValue(value) {
|
changeValue(value) {
|
||||||
this.set('value', value);
|
this.set("value", value);
|
||||||
this.onUpdate('selector', this.activeType);
|
this.onUpdate("selector", this.activeType);
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('inputType')
|
@observes("inputType")
|
||||||
resetActiveType() {
|
resetActiveType() {
|
||||||
this.set('activeType', defaultSelectionType(this.selectorType, this.options));
|
this.set(
|
||||||
|
"activeType",
|
||||||
|
defaultSelectionType(this.selectorType, this.options)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
toggleType(type) {
|
toggleType(type) {
|
||||||
this.set('activeType', type);
|
this.set("activeType", type);
|
||||||
this.set('showTypes', false);
|
this.set("showTypes", false);
|
||||||
this.set('value', null);
|
this.set("value", null);
|
||||||
this.onUpdate('selector');
|
this.onUpdate("selector");
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleTypes() {
|
toggleTypes() {
|
||||||
this.toggleProperty('showTypes');
|
this.toggleProperty("showTypes");
|
||||||
},
|
},
|
||||||
|
|
||||||
changeValue(value) {
|
changeValue(value) {
|
||||||
this.changeValue(value);
|
this.changeValue(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
changeInputValue(event) {
|
changeInputValue(event) {
|
||||||
this.changeValue(event.target.value);
|
this.changeValue(event.target.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
changeUserValue(previousValue, value) {
|
changeUserValue(previousValue, value) {
|
||||||
this.changeValue(value);
|
this.changeValue(value);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,84 +1,90 @@
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
import { newInput, selectionTypes } from '../lib/wizard-mapper';
|
import { newInput, selectionTypes } from "../lib/wizard-mapper";
|
||||||
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
|
import {
|
||||||
|
default as discourseComputed,
|
||||||
|
observes,
|
||||||
|
on,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
import { later } from "@ember/runloop";
|
import { later } from "@ember/runloop";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: 'wizard-mapper',
|
classNames: "wizard-mapper",
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
if (this.inputs && this.inputs.constructor !== Array) {
|
if (this.inputs && this.inputs.constructor !== Array) {
|
||||||
later(() => this.set('inputs', null));
|
later(() => this.set("inputs", null));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('inputs.@each.type')
|
@discourseComputed("inputs.@each.type")
|
||||||
canAdd(inputs) {
|
canAdd(inputs) {
|
||||||
return !inputs ||
|
return (
|
||||||
inputs.constructor !== Array ||
|
!inputs ||
|
||||||
inputs.every(i => {
|
inputs.constructor !== Array ||
|
||||||
return ['assignment','association'].indexOf(i.type) === -1;
|
inputs.every((i) => {
|
||||||
});
|
return ["assignment", "association"].indexOf(i.type) === -1;
|
||||||
|
})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('options.@each.inputType')
|
@discourseComputed("options.@each.inputType")
|
||||||
inputOptions(options) {
|
inputOptions(options) {
|
||||||
let result = {
|
let result = {
|
||||||
inputTypes: options.inputTypes || 'assignment,conditional',
|
inputTypes: options.inputTypes || "assignment,conditional",
|
||||||
inputConnector: options.inputConnector || 'or',
|
inputConnector: options.inputConnector || "or",
|
||||||
pairConnector: options.pairConnector || null,
|
pairConnector: options.pairConnector || null,
|
||||||
outputConnector: options.outputConnector || null,
|
outputConnector: options.outputConnector || null,
|
||||||
context: options.context || null
|
context: options.context || null,
|
||||||
}
|
};
|
||||||
|
|
||||||
let inputTypes = ['key', 'value', 'output'];
|
let inputTypes = ["key", "value", "output"];
|
||||||
inputTypes.forEach(type => {
|
inputTypes.forEach((type) => {
|
||||||
result[`${type}Placeholder`] = options[`${type}Placeholder`] || null;
|
result[`${type}Placeholder`] = options[`${type}Placeholder`] || null;
|
||||||
result[`${type}DefaultSelection`] = options[`${type}DefaultSelection`] || null;
|
result[`${type}DefaultSelection`] =
|
||||||
|
options[`${type}DefaultSelection`] || null;
|
||||||
});
|
});
|
||||||
|
|
||||||
selectionTypes.forEach(type => {
|
selectionTypes.forEach((type) => {
|
||||||
if (options[`${type}Selection`] !== undefined) {
|
if (options[`${type}Selection`] !== undefined) {
|
||||||
result[`${type}Selection`] = options[`${type}Selection`]
|
result[`${type}Selection`] = options[`${type}Selection`];
|
||||||
} else {
|
} else {
|
||||||
result[`${type}Selection`] = type === 'text' ? true : false;
|
result[`${type}Selection`] = type === "text" ? true : false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
onUpdate() {
|
onUpdate() {},
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
add() {
|
add() {
|
||||||
if (!this.get('inputs')) {
|
if (!this.get("inputs")) {
|
||||||
this.set('inputs', A());
|
this.set("inputs", A());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.get('inputs').pushObject(
|
this.get("inputs").pushObject(
|
||||||
newInput(this.inputOptions, this.inputs.length)
|
newInput(this.inputOptions, this.inputs.length)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.onUpdate(this.property, 'input');
|
this.onUpdate(this.property, "input");
|
||||||
},
|
},
|
||||||
|
|
||||||
remove(input) {
|
remove(input) {
|
||||||
const inputs = this.inputs;
|
const inputs = this.inputs;
|
||||||
inputs.removeObject(input);
|
inputs.removeObject(input);
|
||||||
|
|
||||||
if (inputs.length) {
|
if (inputs.length) {
|
||||||
inputs[0].set('connector', null);
|
inputs[0].set("connector", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onUpdate(this.property, 'input');
|
this.onUpdate(this.property, "input");
|
||||||
},
|
},
|
||||||
|
|
||||||
inputUpdated(component, type) {
|
inputUpdated(component, type) {
|
||||||
this.onUpdate(this.property, component, type);
|
this.onUpdate(this.property, component, type);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import { not, notEmpty } from "@ember/object/computed";
|
import { not, notEmpty } from "@ember/object/computed";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
error: 'times-circle',
|
error: "times-circle",
|
||||||
success: 'check-circle',
|
success: "check-circle",
|
||||||
info: 'info-circle'
|
info: "info-circle",
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNameBindings: [':wizard-message', 'type', 'loading'],
|
classNameBindings: [":wizard-message", "type", "loading"],
|
||||||
showDocumentation: not('loading'),
|
showDocumentation: not("loading"),
|
||||||
showIcon: not('loading'),
|
showIcon: not("loading"),
|
||||||
hasItems: notEmpty('items'),
|
hasItems: notEmpty("items"),
|
||||||
|
|
||||||
@discourseComputed('type')
|
@discourseComputed("type")
|
||||||
icon(type) {
|
icon(type) {
|
||||||
return icons[type] || 'info-circle';
|
return icons[type] || "info-circle";
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('key', 'component', 'opts')
|
@discourseComputed("key", "component", "opts")
|
||||||
message(key, component, opts) {
|
message(key, component, opts) {
|
||||||
return I18n.t(`admin.wizard.message.${component}.${key}`, opts || {});
|
return I18n.t(`admin.wizard.message.${component}.${key}`, opts || {});
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('component')
|
@discourseComputed("component")
|
||||||
documentation(component) {
|
documentation(component) {
|
||||||
return I18n.t(`admin.wizard.message.${component}.documentation`);
|
return I18n.t(`admin.wizard.message.${component}.documentation`);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -9,17 +9,12 @@ export default Component.extend({
|
||||||
classNames: ["realtime-validations"],
|
classNames: ["realtime-validations"],
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
timeUnits() {
|
timeUnits() {
|
||||||
return [
|
return ["days", "weeks", "months", "years"].map((unit) => {
|
||||||
"days",
|
return {
|
||||||
"weeks",
|
id: unit,
|
||||||
"months",
|
name: I18n.t(`admin.wizard.field.validations.time_units.${unit}`),
|
||||||
"years"
|
};
|
||||||
].map((unit) => {
|
});
|
||||||
return {
|
|
||||||
id: unit,
|
|
||||||
name: I18n.t(`admin.wizard.field.validations.time_units.${unit}`)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -28,7 +23,7 @@ export default Component.extend({
|
||||||
|
|
||||||
if (!this.field.validations) {
|
if (!this.field.validations) {
|
||||||
const validations = {};
|
const validations = {};
|
||||||
|
|
||||||
this.validations.forEach((validation) => {
|
this.validations.forEach((validation) => {
|
||||||
validations[validation] = {};
|
validations[validation] = {};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,71 +1,75 @@
|
||||||
import { default as discourseComputed, on } from 'discourse-common/utils/decorators';
|
import {
|
||||||
|
default as discourseComputed,
|
||||||
|
on,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
import { notEmpty } from "@ember/object/computed";
|
import { notEmpty } from "@ember/object/computed";
|
||||||
import { userProperties } from '../lib/wizard';
|
import { userProperties } from "../lib/wizard";
|
||||||
import { scheduleOnce } from "@ember/runloop";
|
import { scheduleOnce } from "@ember/runloop";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
const excludedUserProperties = [
|
const excludedUserProperties = [
|
||||||
'avatar',
|
"avatar",
|
||||||
'profile_background',
|
"profile_background",
|
||||||
'card_background'
|
"card_background",
|
||||||
];
|
];
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: 'wizard-text-editor',
|
classNames: "wizard-text-editor",
|
||||||
barEnabled: true,
|
barEnabled: true,
|
||||||
previewEnabled: true,
|
previewEnabled: true,
|
||||||
fieldsEnabled: true,
|
fieldsEnabled: true,
|
||||||
hasWizardFields: notEmpty('wizardFieldList'),
|
hasWizardFields: notEmpty("wizardFieldList"),
|
||||||
hasWizardActions: notEmpty('wizardActionList'),
|
hasWizardActions: notEmpty("wizardActionList"),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
if (!this.barEnabled) {
|
if (!this.barEnabled) {
|
||||||
scheduleOnce('afterRender', () => {
|
scheduleOnce("afterRender", () => {
|
||||||
$(this.element).find('.d-editor-button-bar').addClass('hidden');
|
$(this.element).find(".d-editor-button-bar").addClass("hidden");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('forcePreview')
|
@discourseComputed("forcePreview")
|
||||||
previewLabel(forcePreview) {
|
previewLabel(forcePreview) {
|
||||||
return I18n.t("admin.wizard.editor.preview", {
|
return I18n.t("admin.wizard.editor.preview", {
|
||||||
action: I18n.t(`admin.wizard.editor.${forcePreview ? 'hide' : 'show'}`)
|
action: I18n.t(`admin.wizard.editor.${forcePreview ? "hide" : "show"}`),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('showPopover')
|
@discourseComputed("showPopover")
|
||||||
popoverLabel(showPopover) {
|
popoverLabel(showPopover) {
|
||||||
return I18n.t("admin.wizard.editor.popover", {
|
return I18n.t("admin.wizard.editor.popover", {
|
||||||
action: I18n.t(`admin.wizard.editor.${showPopover ? 'hide' : 'show'}`)
|
action: I18n.t(`admin.wizard.editor.${showPopover ? "hide" : "show"}`),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed()
|
@discourseComputed()
|
||||||
userPropertyList() {
|
userPropertyList() {
|
||||||
return userProperties.filter((f) => !excludedUserProperties.includes(f))
|
return userProperties
|
||||||
|
.filter((f) => !excludedUserProperties.includes(f))
|
||||||
.map((f) => ` u{${f}}`);
|
.map((f) => ` u{${f}}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('wizardFields')
|
@discourseComputed("wizardFields")
|
||||||
wizardFieldList(wizardFields) {
|
wizardFieldList(wizardFields) {
|
||||||
return wizardFields.map((f) => ` w{${f.id}}`);
|
return wizardFields.map((f) => ` w{${f.id}}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('wizardActions')
|
@discourseComputed("wizardActions")
|
||||||
wizardActionList(wizardActions) {
|
wizardActionList(wizardActions) {
|
||||||
return wizardActions.map((a) => ` w{${a.id}}`);
|
return wizardActions.map((a) => ` w{${a.id}}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
togglePreview() {
|
togglePreview() {
|
||||||
this.toggleProperty('forcePreview');
|
this.toggleProperty("forcePreview");
|
||||||
},
|
},
|
||||||
|
|
||||||
togglePopover() {
|
togglePopover() {
|
||||||
this.toggleProperty('showPopover');
|
this.toggleProperty("showPopover");
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import ValueList from 'admin/components/value-list';
|
import ValueList from "admin/components/value-list";
|
||||||
|
|
||||||
export default ValueList.extend({
|
export default ValueList.extend({
|
||||||
_saveValues() {
|
_saveValues() {
|
||||||
|
@ -8,5 +8,5 @@ export default ValueList.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onChange(this.collection.join(this.inputDelimiter || "\n"));
|
this.onChange(this.collection.join(this.inputDelimiter || "\n"));
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
export default {
|
export default {
|
||||||
shouldRender(_, ctx) {
|
shouldRender(_, ctx) {
|
||||||
return ctx.siteSettings.custom_wizard_enabled &&
|
return (
|
||||||
ctx.site.complete_custom_wizard;
|
ctx.siteSettings.custom_wizard_enabled && ctx.site.complete_custom_wizard
|
||||||
}
|
);
|
||||||
}
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -1,93 +1,139 @@
|
||||||
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 discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import { not, and, equal } from "@ember/object/computed";
|
import { not, and, equal } from "@ember/object/computed";
|
||||||
import { selectKitContent } from '../lib/wizard';
|
import { selectKitContent } from "../lib/wizard";
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
queryParams: ['refresh_list'],
|
queryParams: ["refresh_list"],
|
||||||
loadingSubscriptions: false,
|
loadingSubscriptions: false,
|
||||||
notAuthorized: not('api.authorized'),
|
notAuthorized: not("api.authorized"),
|
||||||
endpointMethods: selectKitContent(['GET', 'PUT', 'POST', 'PATCH', 'DELETE']),
|
endpointMethods: selectKitContent(["GET", "PUT", "POST", "PATCH", "DELETE"]),
|
||||||
showRemove: not('isNew'),
|
showRemove: not("isNew"),
|
||||||
showRedirectUri: and('threeLeggedOauth', 'api.name'),
|
showRedirectUri: and("threeLeggedOauth", "api.name"),
|
||||||
responseIcon: null,
|
responseIcon: null,
|
||||||
contentTypes: selectKitContent(['application/json', 'application/x-www-form-urlencoded']),
|
contentTypes: selectKitContent([
|
||||||
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]),
|
"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,
|
||||||
|
]),
|
||||||
|
|
||||||
@discourseComputed('saveDisabled', 'api.authType', 'api.authUrl', 'api.tokenUrl', 'api.clientId', 'api.clientSecret', 'threeLeggedOauth')
|
@discourseComputed(
|
||||||
authDisabled(saveDisabled, authType, authUrl, tokenUrl, clientId, clientSecret, threeLeggedOauth) {
|
"saveDisabled",
|
||||||
if (saveDisabled || !authType || !tokenUrl || !clientId || !clientSecret) return true;
|
"api.authType",
|
||||||
|
"api.authUrl",
|
||||||
|
"api.tokenUrl",
|
||||||
|
"api.clientId",
|
||||||
|
"api.clientSecret",
|
||||||
|
"threeLeggedOauth"
|
||||||
|
)
|
||||||
|
authDisabled(
|
||||||
|
saveDisabled,
|
||||||
|
authType,
|
||||||
|
authUrl,
|
||||||
|
tokenUrl,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
threeLeggedOauth
|
||||||
|
) {
|
||||||
|
if (saveDisabled || !authType || !tokenUrl || !clientId || !clientSecret)
|
||||||
|
return true;
|
||||||
if (threeLeggedOauth) return !authUrl;
|
if (threeLeggedOauth) return !authUrl;
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('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: equal('api.authType', 'basic'),
|
isBasicAuth: equal("api.authType", "basic"),
|
||||||
|
|
||||||
@discourseComputed('api.authType')
|
@discourseComputed("api.authType")
|
||||||
isOauth(authType) {
|
isOauth(authType) {
|
||||||
return authType && authType.indexOf('oauth') > -1;
|
return authType && authType.indexOf("oauth") > -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
twoLeggedOauth: equal('api.authType', 'oauth_2'),
|
twoLeggedOauth: equal("api.authType", "oauth_2"),
|
||||||
threeLeggedOauth: equal('api.authType', 'oauth_3'),
|
threeLeggedOauth: equal("api.authType", "oauth_3"),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addParam() {
|
addParam() {
|
||||||
this.get('api.authParams').pushObject({});
|
this.get("api.authParams").pushObject({});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeParam(param) {
|
removeParam(param) {
|
||||||
this.get('api.authParams').removeObject(param);
|
this.get("api.authParams").removeObject(param);
|
||||||
},
|
},
|
||||||
|
|
||||||
addEndpoint() {
|
addEndpoint() {
|
||||||
this.get('api.endpoints').pushObject({});
|
this.get("api.endpoints").pushObject({});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeEndpoint(endpoint) {
|
removeEndpoint(endpoint) {
|
||||||
this.get('api.endpoints').removeObject(endpoint);
|
this.get("api.endpoints").removeObject(endpoint);
|
||||||
},
|
},
|
||||||
|
|
||||||
authorize() {
|
authorize() {
|
||||||
const api = this.get('api');
|
const api = this.get("api");
|
||||||
const { name, authType, authUrl, authParams } = api;
|
const { name, authType, authUrl, authParams } = api;
|
||||||
|
|
||||||
this.set('authErrorMessage', '');
|
this.set("authErrorMessage", "");
|
||||||
|
|
||||||
if (authType === 'oauth_2') {
|
if (authType === "oauth_2") {
|
||||||
this.set('authorizing', true);
|
this.set("authorizing", true);
|
||||||
ajax(`/admin/wizards/apis/${name.underscore()}/authorize`).catch(popupAjaxError)
|
ajax(`/admin/wizards/apis/${name.underscore()}/authorize`)
|
||||||
.then(result => {
|
.catch(popupAjaxError)
|
||||||
|
.then((result) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.set('api', CustomWizardApi.create(result.api));
|
this.set("api", CustomWizardApi.create(result.api));
|
||||||
} else if (result.failed && result.message) {
|
} else if (result.failed && result.message) {
|
||||||
this.set('authErrorMessage', result.message);
|
this.set("authErrorMessage", result.message);
|
||||||
} else {
|
} else {
|
||||||
this.set('authErrorMessage', 'Authorization Failed');
|
this.set("authErrorMessage", "Authorization Failed");
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.set('authErrorMessage', '');
|
this.set("authErrorMessage", "");
|
||||||
}, 6000);
|
}, 6000);
|
||||||
}).finally(() => this.set('authorizing', false));
|
})
|
||||||
} else if (authType === 'oauth_3') {
|
.finally(() => this.set("authorizing", false));
|
||||||
let query = '?';
|
} else if (authType === "oauth_3") {
|
||||||
|
let query = "?";
|
||||||
|
|
||||||
query += `client_id=${api.clientId}`;
|
query += `client_id=${api.clientId}`;
|
||||||
query += `&redirect_uri=${encodeURIComponent(api.redirectUri)}`;
|
query += `&redirect_uri=${encodeURIComponent(api.redirectUri)}`;
|
||||||
query += `&response_type=code`;
|
query += `&response_type=code`;
|
||||||
|
|
||||||
if (authParams) {
|
if (authParams) {
|
||||||
authParams.forEach(p => {
|
authParams.forEach((p) => {
|
||||||
query += `&${p.key}=${encodeURIComponent(p.value)}`;
|
query += `&${p.key}=${encodeURIComponent(p.value)}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -97,7 +143,7 @@ export default Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
const api = this.get('api');
|
const api = this.get("api");
|
||||||
const name = api.name;
|
const name = api.name;
|
||||||
const authType = api.authType;
|
const authType = api.authType;
|
||||||
let refreshList = false;
|
let refreshList = false;
|
||||||
|
@ -106,35 +152,37 @@ export default Controller.extend({
|
||||||
if (!name || !authType) return;
|
if (!name || !authType) return;
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
auth_type: authType
|
auth_type: authType,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (api.title) data['title'] = api.title;
|
if (api.title) data["title"] = api.title;
|
||||||
|
|
||||||
const originalTitle = this.get('api.originalTitle');
|
const originalTitle = this.get("api.originalTitle");
|
||||||
if (api.get('isNew') || (originalTitle && (api.title !== originalTitle))) {
|
if (api.get("isNew") || (originalTitle && api.title !== originalTitle)) {
|
||||||
refreshList = true;
|
refreshList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api.get('isNew')) {
|
if (api.get("isNew")) {
|
||||||
data['new'] = true;
|
data["new"] = true;
|
||||||
};
|
}
|
||||||
|
|
||||||
let requiredParams;
|
let requiredParams;
|
||||||
|
|
||||||
if (authType === 'basic') {
|
if (authType === "basic") {
|
||||||
requiredParams = ['username', 'password'];
|
requiredParams = ["username", "password"];
|
||||||
} else if (authType === 'oauth_2') {
|
} else if (authType === "oauth_2") {
|
||||||
requiredParams = ['tokenUrl', 'clientId', 'clientSecret'];
|
requiredParams = ["tokenUrl", "clientId", "clientSecret"];
|
||||||
} else if (authType === 'oauth_3') {
|
} else if (authType === "oauth_3") {
|
||||||
requiredParams = ['authUrl', 'tokenUrl', 'clientId', 'clientSecret'];
|
requiredParams = ["authUrl", "tokenUrl", "clientId", "clientSecret"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiredParams) {
|
if (requiredParams) {
|
||||||
for (let rp of requiredParams) {
|
for (let rp of requiredParams) {
|
||||||
if (!api[rp]) {
|
if (!api[rp]) {
|
||||||
let key = rp.replace('auth', '');
|
let key = rp.replace("auth", "");
|
||||||
error = `${I18n.t(`admin.wizard.api.auth.${key.underscore()}`)} is required for ${authType}`;
|
error = `${I18n.t(
|
||||||
|
`admin.wizard.api.auth.${key.underscore()}`
|
||||||
|
)} is required for ${authType}`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
data[rp.underscore()] = api[rp];
|
data[rp.underscore()] = api[rp];
|
||||||
|
@ -143,73 +191,79 @@ export default Controller.extend({
|
||||||
|
|
||||||
const params = api.authParams;
|
const params = api.authParams;
|
||||||
if (params.length) {
|
if (params.length) {
|
||||||
data['auth_params'] = JSON.stringify(params);
|
data["auth_params"] = JSON.stringify(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoints = api.endpoints;
|
const endpoints = api.endpoints;
|
||||||
if (endpoints.length) {
|
if (endpoints.length) {
|
||||||
for (let e of endpoints) {
|
for (let e of endpoints) {
|
||||||
if (!e.name) {
|
if (!e.name) {
|
||||||
error = 'Every endpoint must have a name';
|
error = "Every endpoint must have a name";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data['endpoints'] = JSON.stringify(endpoints);
|
data["endpoints"] = JSON.stringify(endpoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
this.set('error', error);
|
this.set("error", error);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.set('error', '');
|
this.set("error", "");
|
||||||
}, 6000);
|
}, 6000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('updating', true);
|
this.set("updating", true);
|
||||||
|
|
||||||
ajax(`/admin/wizards/api/${name.underscore()}`, {
|
ajax(`/admin/wizards/api/${name.underscore()}`, {
|
||||||
type: 'PUT',
|
type: "PUT",
|
||||||
data
|
data,
|
||||||
}).catch(popupAjaxError)
|
})
|
||||||
.then(result => {
|
.catch(popupAjaxError)
|
||||||
|
.then((result) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.send('afterSave', result.api.name);
|
this.send("afterSave", result.api.name);
|
||||||
} else {
|
} else {
|
||||||
this.set('responseIcon', 'times');
|
this.set("responseIcon", "times");
|
||||||
}
|
}
|
||||||
}).finally(() => this.set('updating', false));
|
})
|
||||||
|
.finally(() => this.set("updating", false));
|
||||||
},
|
},
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
const name = this.get('api.name');
|
const name = this.get("api.name");
|
||||||
if (!name) return;
|
if (!name) return;
|
||||||
|
|
||||||
this.set('updating', true);
|
this.set("updating", true);
|
||||||
|
|
||||||
ajax(`/admin/wizards/api/${name.underscore()}`, {
|
ajax(`/admin/wizards/api/${name.underscore()}`, {
|
||||||
type: 'DELETE'
|
type: "DELETE",
|
||||||
}).catch(popupAjaxError)
|
})
|
||||||
.then(result => {
|
.catch(popupAjaxError)
|
||||||
|
.then((result) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.send('afterDestroy');
|
this.send("afterDestroy");
|
||||||
}
|
}
|
||||||
}).finally(() => this.set('updating', false));
|
})
|
||||||
|
.finally(() => this.set("updating", false));
|
||||||
},
|
},
|
||||||
|
|
||||||
clearLogs() {
|
clearLogs() {
|
||||||
const name = this.get('api.name');
|
const name = this.get("api.name");
|
||||||
if (!name) return;
|
if (!name) return;
|
||||||
|
|
||||||
ajax(`/admin/wizards/api/${name.underscore()}/logs`, {
|
ajax(`/admin/wizards/api/${name.underscore()}/logs`, {
|
||||||
type: 'DELETE'
|
type: "DELETE",
|
||||||
}).catch(popupAjaxError)
|
})
|
||||||
.then(result => {
|
.catch(popupAjaxError)
|
||||||
|
.then((result) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.transitionToRoute('adminWizardsApis').then(() => {
|
this.transitionToRoute("adminWizardsApis").then(() => {
|
||||||
this.send('refreshModel');
|
this.send("refreshModel");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).finally(() => this.set('updating', false));
|
})
|
||||||
}
|
.finally(() => this.set("updating", false));
|
||||||
}
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,55 +1,57 @@
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import EmberObject from '@ember/object';
|
import EmberObject from "@ember/object";
|
||||||
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 CustomWizardCustomField from "../models/custom-wizard-custom-field";
|
import CustomWizardCustomField from "../models/custom-wizard-custom-field";
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
messageKey: 'create',
|
messageKey: "create",
|
||||||
fieldKeys: ['klass', 'type', 'serializers', 'name'],
|
fieldKeys: ["klass", "type", "serializers", "name"],
|
||||||
documentationUrl: "https://thepavilion.io/t/3572",
|
documentationUrl: "https://thepavilion.io/t/3572",
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addField() {
|
addField() {
|
||||||
this.get('customFields').pushObject(
|
this.get("customFields").pushObject(
|
||||||
CustomWizardCustomField.create({ edit: true })
|
CustomWizardCustomField.create({ edit: true })
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveField(field) {
|
saveField(field) {
|
||||||
return CustomWizardCustomField.saveField(field)
|
return CustomWizardCustomField.saveField(field).then((result) => {
|
||||||
.then(result => {
|
if (result.success) {
|
||||||
if (result.success) {
|
this.setProperties({
|
||||||
|
messageKey: "saved",
|
||||||
|
messageType: "success",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (result.messages) {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
messageKey: 'saved',
|
messageKey: "error",
|
||||||
messageType: 'success'
|
messageType: "error",
|
||||||
|
messageOpts: { messages: result.messages },
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
if (result.messages) {
|
|
||||||
this.setProperties({
|
|
||||||
messageKey: 'error',
|
|
||||||
messageType: 'error',
|
|
||||||
messageOpts: { messages: result.messages }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
setTimeout(() => this.setProperties({
|
|
||||||
messageKey: 'create',
|
setTimeout(
|
||||||
messageType: null,
|
() =>
|
||||||
messageOpts: null
|
this.setProperties({
|
||||||
}), 10000);
|
messageKey: "create",
|
||||||
|
messageType: null,
|
||||||
return result;
|
messageOpts: null,
|
||||||
});
|
}),
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeField(field) {
|
removeField(field) {
|
||||||
return CustomWizardCustomField.destroyField(field)
|
return CustomWizardCustomField.destroyField(field).then((result) => {
|
||||||
.then(result => {
|
this.get("customFields").removeObject(field);
|
||||||
this.get('customFields').removeObject(field);
|
});
|
||||||
});
|
},
|
||||||
}
|
},
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { default as computed } from 'discourse-common/utils/decorators';
|
import { default as computed } from "discourse-common/utils/decorators";
|
||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { notEmpty } from "@ember/object/computed";
|
import { notEmpty } from "@ember/object/computed";
|
||||||
import CustomWizardLogs from '../models/custom-wizard-logs';
|
import CustomWizardLogs from "../models/custom-wizard-logs";
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
|
@ -11,40 +11,40 @@ export default Controller.extend({
|
||||||
page: 0,
|
page: 0,
|
||||||
canLoadMore: true,
|
canLoadMore: true,
|
||||||
logs: [],
|
logs: [],
|
||||||
|
|
||||||
loadLogs() {
|
loadLogs() {
|
||||||
if (!this.canLoadMore) return;
|
if (!this.canLoadMore) return;
|
||||||
|
|
||||||
this.set("refreshing", true);
|
this.set("refreshing", true);
|
||||||
|
|
||||||
CustomWizardLogs.list()
|
CustomWizardLogs.list()
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
if (!result || result.length === 0) {
|
if (!result || result.length === 0) {
|
||||||
this.set('canLoadMore', false);
|
this.set("canLoadMore", false);
|
||||||
}
|
}
|
||||||
this.set("logs", this.logs.concat(result));
|
this.set("logs", this.logs.concat(result));
|
||||||
})
|
})
|
||||||
.finally(() => this.set("refreshing", false));
|
.finally(() => this.set("refreshing", false));
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('hasLogs', 'refreshing')
|
@computed("hasLogs", "refreshing")
|
||||||
noResults(hasLogs, refreshing) {
|
noResults(hasLogs, refreshing) {
|
||||||
return !hasLogs && !refreshing;
|
return !hasLogs && !refreshing;
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
loadMore() {
|
loadMore() {
|
||||||
this.set('page', this.page += 1);
|
this.set("page", (this.page += 1));
|
||||||
this.loadLogs();
|
this.loadLogs();
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
canLoadMore: true,
|
canLoadMore: true,
|
||||||
page: 0,
|
page: 0,
|
||||||
logs: []
|
logs: [],
|
||||||
})
|
});
|
||||||
this.loadLogs();
|
this.loadLogs();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,76 +1,80 @@
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import {
|
import {
|
||||||
default as discourseComputed,
|
default as discourseComputed,
|
||||||
observes
|
observes,
|
||||||
} from 'discourse-common/utils/decorators';
|
} from "discourse-common/utils/decorators";
|
||||||
import { empty } from "@ember/object/computed";
|
import { empty } from "@ember/object/computed";
|
||||||
import CustomWizardManager from '../models/custom-wizard-manager';
|
import CustomWizardManager from "../models/custom-wizard-manager";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { underscore } from "@ember/string";
|
import { underscore } from "@ember/string";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
messageUrl: 'https://thepavilion.io/t/3652',
|
messageUrl: "https://thepavilion.io/t/3652",
|
||||||
messageKey: 'info',
|
messageKey: "info",
|
||||||
messageIcon: 'info-circle',
|
messageIcon: "info-circle",
|
||||||
messageClass: 'info',
|
messageClass: "info",
|
||||||
importDisabled: empty('file'),
|
importDisabled: empty("file"),
|
||||||
exportWizards: A(),
|
exportWizards: A(),
|
||||||
destroyWizards: A(),
|
destroyWizards: A(),
|
||||||
exportDisabled: empty('exportWizards'),
|
exportDisabled: empty("exportWizards"),
|
||||||
destoryDisabled: empty('destroyWizards'),
|
destoryDisabled: empty("destroyWizards"),
|
||||||
|
|
||||||
setMessage(type, key, opts={}, items=[]) {
|
setMessage(type, key, opts = {}, items = []) {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
messageKey: key,
|
messageKey: key,
|
||||||
messageOpts: opts,
|
messageOpts: opts,
|
||||||
messageType: type,
|
messageType: type,
|
||||||
messageItems: items
|
messageItems: items,
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
messageKey: 'info',
|
messageKey: "info",
|
||||||
messageOpts: null,
|
messageOpts: null,
|
||||||
messageType: null,
|
messageType: null,
|
||||||
messageItems: null
|
messageItems: null,
|
||||||
})
|
});
|
||||||
}, 10000);
|
}, 10000);
|
||||||
},
|
},
|
||||||
|
|
||||||
buildWizardLink(wizard) {
|
buildWizardLink(wizard) {
|
||||||
let html = `<a href='/admin/wizards/wizard/${wizard.id}'>${wizard.name}</a>`;
|
let html = `<a href='/admin/wizards/wizard/${wizard.id}'>${wizard.name}</a>`;
|
||||||
html += `<span class='action'>${I18n.t('admin.wizard.manager.imported')}</span>`;
|
html += `<span class='action'>${I18n.t(
|
||||||
|
"admin.wizard.manager.imported"
|
||||||
|
)}</span>`;
|
||||||
return {
|
return {
|
||||||
icon: 'check-circle',
|
icon: "check-circle",
|
||||||
html
|
html,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
buildDestroyedItem(destroyed) {
|
buildDestroyedItem(destroyed) {
|
||||||
let html = `<span data-wizard-id="${destroyed.id}">${destroyed.name}</span>`;
|
let html = `<span data-wizard-id="${destroyed.id}">${destroyed.name}</span>`;
|
||||||
html += `<span class='action'>${I18n.t('admin.wizard.manager.destroyed')}</span>`;
|
html += `<span class='action'>${I18n.t(
|
||||||
|
"admin.wizard.manager.destroyed"
|
||||||
|
)}</span>`;
|
||||||
return {
|
return {
|
||||||
icon: 'check-circle',
|
icon: "check-circle",
|
||||||
html
|
html,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
buildFailureItem(failure) {
|
buildFailureItem(failure) {
|
||||||
return {
|
return {
|
||||||
icon: 'times-circle',
|
icon: "times-circle",
|
||||||
html: `${failure.id}: ${failure.messages}`
|
html: `${failure.id}: ${failure.messages}`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
clearFile() {
|
clearFile() {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
file: null,
|
file: null,
|
||||||
filename: null
|
filename: null,
|
||||||
});
|
});
|
||||||
$('#file-upload').val('');
|
$("#file-upload").val("");
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('importing', 'destroying')
|
@observes("importing", "destroying")
|
||||||
setLoadingMessages() {
|
setLoadingMessages() {
|
||||||
if (this.importing) {
|
if (this.importing) {
|
||||||
this.setMessage("loading", "importing");
|
this.setMessage("loading", "importing");
|
||||||
|
@ -82,47 +86,49 @@ export default Controller.extend({
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
upload() {
|
upload() {
|
||||||
$('#file-upload').click();
|
$("#file-upload").click();
|
||||||
},
|
},
|
||||||
|
|
||||||
clearFile() {
|
clearFile() {
|
||||||
this.clearFile();
|
this.clearFile();
|
||||||
},
|
},
|
||||||
|
|
||||||
setFile(event) {
|
setFile(event) {
|
||||||
let maxFileSize = 512 * 1024;
|
let maxFileSize = 512 * 1024;
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
|
|
||||||
if (file === undefined) {
|
if (file === undefined) {
|
||||||
this.set('file', null);
|
this.set("file", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxFileSize < file.size) {
|
if (maxFileSize < file.size) {
|
||||||
this.setMessage("error", "file_size_error");
|
this.setMessage("error", "file_size_error");
|
||||||
this.set("file", null);
|
this.set("file", null);
|
||||||
$('#file-upload').val('');
|
$("#file-upload").val("");
|
||||||
} else {
|
} else {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
file,
|
file,
|
||||||
filename: file.name
|
filename: file.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
selectWizard(event) {
|
selectWizard(event) {
|
||||||
const type = event.target.classList.contains('export') ? 'export' : 'destroy';
|
const type = event.target.classList.contains("export")
|
||||||
|
? "export"
|
||||||
|
: "destroy";
|
||||||
const wizards = this.get(`${type}Wizards`);
|
const wizards = this.get(`${type}Wizards`);
|
||||||
const checked = event.target.checked;
|
const checked = event.target.checked;
|
||||||
|
|
||||||
let wizardId = event.target.closest('tr').getAttribute('data-wizard-id');
|
let wizardId = event.target.closest("tr").getAttribute("data-wizard-id");
|
||||||
|
|
||||||
if (wizardId) {
|
if (wizardId) {
|
||||||
wizardId = underscore(wizardId);
|
wizardId = underscore(wizardId);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
wizards.addObject(wizardId);
|
wizards.addObject(wizardId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,99 +137,113 @@ export default Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
import() {
|
import() {
|
||||||
const file = this.get('file');
|
const file = this.get("file");
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
this.setMessage("error", 'no_file');
|
this.setMessage("error", "no_file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let $formData = new FormData();
|
let $formData = new FormData();
|
||||||
$formData.append('file', file);
|
$formData.append("file", file);
|
||||||
|
|
||||||
this.set('importing', true);
|
this.set("importing", true);
|
||||||
this.setMessage("loading", "importing");
|
this.setMessage("loading", "importing");
|
||||||
|
|
||||||
CustomWizardManager.import($formData).then(result => {
|
CustomWizardManager.import($formData)
|
||||||
if (result.error) {
|
.then((result) => {
|
||||||
this.setMessage("error", "server_error", {
|
if (result.error) {
|
||||||
message: result.error
|
this.setMessage("error", "server_error", {
|
||||||
});
|
message: result.error,
|
||||||
} else {
|
});
|
||||||
this.setMessage("success", "import_complete", {},
|
} else {
|
||||||
result.imported.map(imported => {
|
this.setMessage(
|
||||||
return this.buildWizardLink(imported);
|
"success",
|
||||||
}).concat(
|
"import_complete",
|
||||||
result.failures.map(failure => {
|
{},
|
||||||
return this.buildFailureItem(failure);
|
result.imported
|
||||||
})
|
.map((imported) => {
|
||||||
)
|
return this.buildWizardLink(imported);
|
||||||
);
|
})
|
||||||
|
.concat(
|
||||||
if (result.imported.length) {
|
result.failures.map((failure) => {
|
||||||
this.get('wizards').addObjects(result.imported);
|
return this.buildFailureItem(failure);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.imported.length) {
|
||||||
|
this.get("wizards").addObjects(result.imported);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
this.clearFile();
|
||||||
this.clearFile();
|
})
|
||||||
}).finally(() => {
|
.finally(() => {
|
||||||
this.set('importing', false);
|
this.set("importing", false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
export() {
|
export() {
|
||||||
const exportWizards = this.get('exportWizards');
|
const exportWizards = this.get("exportWizards");
|
||||||
|
|
||||||
if (!exportWizards.length) {
|
if (!exportWizards.length) {
|
||||||
this.setMessage("error", 'none_selected');
|
this.setMessage("error", "none_selected");
|
||||||
} else {
|
} else {
|
||||||
CustomWizardManager.export(exportWizards);
|
CustomWizardManager.export(exportWizards);
|
||||||
exportWizards.clear();
|
exportWizards.clear();
|
||||||
$('input.export').prop("checked", false);
|
$("input.export").prop("checked", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
const destroyWizards = this.get('destroyWizards');
|
const destroyWizards = this.get("destroyWizards");
|
||||||
|
|
||||||
if (!destroyWizards.length) {
|
if (!destroyWizards.length) {
|
||||||
this.setMessage("error", 'none_selected');
|
this.setMessage("error", "none_selected");
|
||||||
} else {
|
} else {
|
||||||
this.set('destroying', true);
|
this.set("destroying", true);
|
||||||
|
|
||||||
CustomWizardManager.destroy(destroyWizards).then((result) => {
|
CustomWizardManager.destroy(destroyWizards)
|
||||||
if (result.error) {
|
.then((result) => {
|
||||||
this.setMessage("error", "server_error", {
|
if (result.error) {
|
||||||
message: result.error
|
this.setMessage("error", "server_error", {
|
||||||
});
|
message: result.error,
|
||||||
} else {
|
});
|
||||||
this.setMessage("success", "destroy_complete", {},
|
} else {
|
||||||
result.destroyed.map(destroyed => {
|
this.setMessage(
|
||||||
return this.buildDestroyedItem(destroyed);
|
"success",
|
||||||
}).concat(
|
"destroy_complete",
|
||||||
result.failures.map(failure => {
|
{},
|
||||||
return this.buildFailureItem(failure);
|
result.destroyed
|
||||||
})
|
.map((destroyed) => {
|
||||||
)
|
return this.buildDestroyedItem(destroyed);
|
||||||
);
|
})
|
||||||
|
.concat(
|
||||||
if (result.destroyed.length) {
|
result.failures.map((failure) => {
|
||||||
const destroyedIds = result.destroyed.map(d => d.id);
|
return this.buildFailureItem(failure);
|
||||||
const destroyWizards = this.get('destroyWizards');
|
})
|
||||||
const wizards = this.get('wizards');
|
)
|
||||||
|
|
||||||
wizards.removeObjects(
|
|
||||||
wizards.filter(w => {
|
|
||||||
return destroyedIds.includes(w.id);
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
destroyWizards.removeObjects(destroyedIds);
|
if (result.destroyed.length) {
|
||||||
|
const destroyedIds = result.destroyed.map((d) => d.id);
|
||||||
|
const destroyWizards = this.get("destroyWizards");
|
||||||
|
const wizards = this.get("wizards");
|
||||||
|
|
||||||
|
wizards.removeObjects(
|
||||||
|
wizards.filter((w) => {
|
||||||
|
return destroyedIds.includes(w.id);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
destroyWizards.removeObjects(destroyedIds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}).finally(() => {
|
.finally(() => {
|
||||||
this.set('destroying', false);
|
this.set("destroying", false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,5 +2,5 @@ import Controller from "@ember/controller";
|
||||||
import { fmt } from "discourse/lib/computed";
|
import { fmt } from "discourse/lib/computed";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
downloadUrl: fmt("wizard.id", "/admin/wizards/submissions/%@/download")
|
downloadUrl: fmt("wizard.id", "/admin/wizards/submissions/%@/download"),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,123 +1,139 @@
|
||||||
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
|
import {
|
||||||
|
default as discourseComputed,
|
||||||
|
observes,
|
||||||
|
on,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
import { notEmpty, alias } from "@ember/object/computed";
|
import { notEmpty, alias } from "@ember/object/computed";
|
||||||
import showModal from 'discourse/lib/show-modal';
|
import showModal from "discourse/lib/show-modal";
|
||||||
import { generateId, wizardFieldList } from '../lib/wizard';
|
import { generateId, wizardFieldList } 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, later } from "@ember/runloop";
|
import { scheduleOnce, later } from "@ember/runloop";
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import copyText from "discourse/lib/copy-text";
|
import copyText from "discourse/lib/copy-text";
|
||||||
import CustomWizard from '../models/custom-wizard';
|
import CustomWizard from "../models/custom-wizard";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
hasName: notEmpty('wizard.name'),
|
hasName: notEmpty("wizard.name"),
|
||||||
|
|
||||||
@observes('currentStep')
|
@observes("currentStep")
|
||||||
resetCurrentObjects() {
|
resetCurrentObjects() {
|
||||||
const currentStep = this.currentStep;
|
const currentStep = this.currentStep;
|
||||||
|
|
||||||
if (currentStep) {
|
if (currentStep) {
|
||||||
const fields = currentStep.fields;
|
const fields = currentStep.fields;
|
||||||
this.set('currentField', fields && fields.length ? fields[0] : null)
|
this.set("currentField", fields && fields.length ? fields[0] : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleOnce('afterRender', () => ($("body").addClass('admin-wizard')));
|
scheduleOnce("afterRender", () => $("body").addClass("admin-wizard"));
|
||||||
},
|
|
||||||
|
|
||||||
@observes('wizard.name')
|
|
||||||
setId() {
|
|
||||||
const wizard = this.wizard;
|
|
||||||
if (wizard && !wizard.existingId) {
|
|
||||||
this.set('wizard.id', generateId(wizard.name));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed('wizard.id')
|
|
||||||
wizardUrl(wizardId) {
|
|
||||||
return window.location.origin + '/w/' + dasherize(wizardId);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('wizard.after_time_scheduled')
|
@observes("wizard.name")
|
||||||
nextSessionScheduledLabel(scheduled) {
|
setId() {
|
||||||
return scheduled ?
|
const wizard = this.wizard;
|
||||||
moment(scheduled).format('MMMM Do, HH:mm') :
|
if (wizard && !wizard.existingId) {
|
||||||
I18n.t('admin.wizard.after_time_time_label');
|
this.set("wizard.id", generateId(wizard.name));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('currentStep.id', 'wizard.save_submissions', 'currentStep.fields.@each.label')
|
@discourseComputed("wizard.id")
|
||||||
|
wizardUrl(wizardId) {
|
||||||
|
return window.location.origin + "/w/" + dasherize(wizardId);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("wizard.after_time_scheduled")
|
||||||
|
nextSessionScheduledLabel(scheduled) {
|
||||||
|
return scheduled
|
||||||
|
? moment(scheduled).format("MMMM Do, HH:mm")
|
||||||
|
: I18n.t("admin.wizard.after_time_time_label");
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed(
|
||||||
|
"currentStep.id",
|
||||||
|
"wizard.save_submissions",
|
||||||
|
"currentStep.fields.@each.label"
|
||||||
|
)
|
||||||
wizardFields(currentStepId, saveSubmissions) {
|
wizardFields(currentStepId, saveSubmissions) {
|
||||||
let steps = this.wizard.steps;
|
let steps = this.wizard.steps;
|
||||||
if (!saveSubmissions) {
|
if (!saveSubmissions) {
|
||||||
steps = [steps.findBy('id', currentStepId)];
|
steps = [steps.findBy("id", currentStepId)];
|
||||||
}
|
}
|
||||||
return wizardFieldList(steps);
|
return wizardFieldList(steps);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
save() {
|
save() {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
saving: true,
|
saving: true,
|
||||||
error: null
|
error: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const wizard = this.wizard;
|
const wizard = this.wizard;
|
||||||
const creating = this.creating;
|
const creating = this.creating;
|
||||||
let opts = {};
|
let opts = {};
|
||||||
|
|
||||||
if (creating) {
|
if (creating) {
|
||||||
opts.create = true;
|
opts.create = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wizard.save(opts).then((result) => {
|
wizard
|
||||||
this.send('afterSave', result.wizard_id);
|
.save(opts)
|
||||||
}).catch((result) => {
|
.then((result) => {
|
||||||
let errorType = 'failed';
|
this.send("afterSave", result.wizard_id);
|
||||||
let errorParams = {};
|
})
|
||||||
|
.catch((result) => {
|
||||||
if (result.error) {
|
let errorType = "failed";
|
||||||
errorType = result.error.type;
|
let errorParams = {};
|
||||||
errorParams = result.error.params;
|
|
||||||
}
|
if (result.error) {
|
||||||
|
errorType = result.error.type;
|
||||||
this.set('error', I18n.t(`admin.wizard.error.${errorType}`, errorParams));
|
errorParams = result.error.params;
|
||||||
|
}
|
||||||
later(() => this.set('error', null), 10000);
|
|
||||||
}).finally(() => this.set('saving', false));
|
this.set(
|
||||||
|
"error",
|
||||||
|
I18n.t(`admin.wizard.error.${errorType}`, errorParams)
|
||||||
|
);
|
||||||
|
|
||||||
|
later(() => this.set("error", null), 10000);
|
||||||
|
})
|
||||||
|
.finally(() => this.set("saving", false));
|
||||||
},
|
},
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this.wizard.remove().then(() => this.send('afterDestroy'));
|
this.wizard.remove().then(() => this.send("afterDestroy"));
|
||||||
},
|
},
|
||||||
|
|
||||||
setNextSessionScheduled() {
|
setNextSessionScheduled() {
|
||||||
let controller = showModal('next-session-scheduled', {
|
let controller = showModal("next-session-scheduled", {
|
||||||
model: {
|
model: {
|
||||||
dateTime: this.wizard.after_time_scheduled,
|
dateTime: this.wizard.after_time_scheduled,
|
||||||
update: (dateTime) => this.set('wizard.after_time_scheduled', dateTime)
|
update: (dateTime) =>
|
||||||
}
|
this.set("wizard.after_time_scheduled", dateTime),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.setup();
|
controller.setup();
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleAdvanced() {
|
toggleAdvanced() {
|
||||||
this.toggleProperty('wizard.showAdvanced');
|
this.toggleProperty("wizard.showAdvanced");
|
||||||
},
|
},
|
||||||
|
|
||||||
copyUrl() {
|
copyUrl() {
|
||||||
const $copyRange = $('<p id="copy-range"></p>');
|
const $copyRange = $('<p id="copy-range"></p>');
|
||||||
$copyRange.html(this.wizardUrl);
|
$copyRange.html(this.wizardUrl);
|
||||||
|
|
||||||
$(document.body).append($copyRange);
|
$(document.body).append($copyRange);
|
||||||
|
|
||||||
if (copyText(this.wizardUrl, $copyRange[0])) {
|
if (copyText(this.wizardUrl, $copyRange[0])) {
|
||||||
this.set("copiedUrl", true);
|
this.set("copiedUrl", true);
|
||||||
later(() => this.set("copiedUrl", false), 2000);
|
later(() => this.set("copiedUrl", false), 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
$copyRange.remove();
|
$copyRange.remove();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import { equal } from '@ember/object/computed';
|
import { equal } from "@ember/object/computed";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
creating: equal('wizardId', 'create'),
|
creating: equal("wizardId", "create"),
|
||||||
|
|
||||||
@discourseComputed('creating', 'wizardId')
|
@discourseComputed("creating", "wizardId")
|
||||||
wizardListVal(creating, wizardId) {
|
wizardListVal(creating, wizardId) {
|
||||||
return creating ? null : wizardId;
|
return creating ? null : wizardId;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('creating', 'wizardId')
|
@discourseComputed("creating", "wizardId")
|
||||||
messageKey(creating, wizardId) {
|
messageKey(creating, wizardId) {
|
||||||
let key = 'select';
|
let key = "select";
|
||||||
if (creating) {
|
if (creating) {
|
||||||
key = 'create';
|
key = "create";
|
||||||
} else if (wizardId) {
|
} else if (wizardId) {
|
||||||
key = 'edit';
|
key = "edit";
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
},
|
},
|
||||||
|
|
||||||
messageUrl: "https://thepavilion.io/c/knowledge/discourse/custom-wizard"
|
messageUrl: "https://thepavilion.io/c/knowledge/discourse/custom-wizard",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
title: 'admin.wizard.after_time_modal.title',
|
title: "admin.wizard.after_time_modal.title",
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
this.set('bufferedDateTime', moment(this.model.dateTime));
|
this.set("bufferedDateTime", moment(this.model.dateTime));
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('bufferedDateTime')
|
@discourseComputed("bufferedDateTime")
|
||||||
submitDisabled(dateTime) {
|
submitDisabled(dateTime) {
|
||||||
return moment().isAfter(dateTime);
|
return moment().isAfter(dateTime);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
submit() {
|
submit() {
|
||||||
const dateTime = this.get('bufferedDateTime');
|
const dateTime = this.get("bufferedDateTime");
|
||||||
this.get('model.update')(moment(dateTime).utc().toISOString());
|
this.get("model.update")(moment(dateTime).utc().toISOString());
|
||||||
this.send("closeModal");
|
this.send("closeModal");
|
||||||
},
|
},
|
||||||
|
|
||||||
dateTimeChanged(dateTime) {
|
dateTimeChanged(dateTime) {
|
||||||
this.set('bufferedDateTime', dateTime);
|
this.set("bufferedDateTime", dateTime);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,25 +1,55 @@
|
||||||
export default {
|
export default {
|
||||||
resource: 'admin',
|
resource: "admin",
|
||||||
map() {
|
map() {
|
||||||
this.route('adminWizards', { path: '/wizards', resetNamespace: true }, function() {
|
this.route(
|
||||||
|
"adminWizards",
|
||||||
this.route('adminWizardsWizard', { path: '/wizard/', resetNamespace: true }, function() {
|
{ path: "/wizards", resetNamespace: true },
|
||||||
this.route('adminWizardsWizardShow', { path: '/:wizardId/', resetNamespace: true });
|
function () {
|
||||||
});
|
this.route(
|
||||||
|
"adminWizardsWizard",
|
||||||
this.route('adminWizardsCustomFields', { path: '/custom-fields', resetNamespace: true });
|
{ path: "/wizard/", resetNamespace: true },
|
||||||
|
function () {
|
||||||
this.route('adminWizardsSubmissions', { path: '/submissions', resetNamespace: true }, function() {
|
this.route("adminWizardsWizardShow", {
|
||||||
this.route('adminWizardsSubmissionsShow', { path: '/:wizardId/', resetNamespace: true });
|
path: "/:wizardId/",
|
||||||
})
|
resetNamespace: true,
|
||||||
|
});
|
||||||
this.route('adminWizardsApi', { path: '/api', resetNamespace: true }, function() {
|
}
|
||||||
this.route('adminWizardsApiShow', { path: '/:name', resetNamespace: true });
|
);
|
||||||
});
|
|
||||||
|
|
||||||
this.route('adminWizardsLogs', { path: '/logs', resetNamespace: true });
|
|
||||||
|
|
||||||
this.route('adminWizardsManager', { path: '/manager', resetNamespace: true });
|
this.route("adminWizardsCustomFields", {
|
||||||
});
|
path: "/custom-fields",
|
||||||
}
|
resetNamespace: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route(
|
||||||
|
"adminWizardsSubmissions",
|
||||||
|
{ path: "/submissions", resetNamespace: true },
|
||||||
|
function () {
|
||||||
|
this.route("adminWizardsSubmissionsShow", {
|
||||||
|
path: "/:wizardId/",
|
||||||
|
resetNamespace: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.route(
|
||||||
|
"adminWizardsApi",
|
||||||
|
{ path: "/api", resetNamespace: true },
|
||||||
|
function () {
|
||||||
|
this.route("adminWizardsApiShow", {
|
||||||
|
path: "/:name",
|
||||||
|
resetNamespace: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.route("adminWizardsLogs", { path: "/logs", resetNamespace: true });
|
||||||
|
|
||||||
|
this.route("adminWizardsManager", {
|
||||||
|
path: "/manager",
|
||||||
|
resetNamespace: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { registerUnbound } from 'discourse-common/lib/helpers';
|
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||||
import { dasherize } from "@ember/string";
|
import { dasherize } from "@ember/string";
|
||||||
|
|
||||||
registerUnbound('dasherize', function(string) {
|
registerUnbound("dasherize", function (string) {
|
||||||
return dasherize(string);
|
return dasherize(string);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { withPluginApi } from 'discourse/lib/plugin-api';
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
import DiscourseURL from 'discourse/lib/url';
|
import DiscourseURL from "discourse/lib/url";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'custom-wizard-edits',
|
name: "custom-wizard-edits",
|
||||||
initialize(container) {
|
initialize(container) {
|
||||||
const siteSettings = container.lookup('site-settings:main');
|
const siteSettings = container.lookup("site-settings:main");
|
||||||
|
|
||||||
if (!siteSettings.custom_wizard_enabled) return;
|
if (!siteSettings.custom_wizard_enabled) return;
|
||||||
|
|
||||||
const existing = DiscourseURL.routeTo;
|
const existing = DiscourseURL.routeTo;
|
||||||
DiscourseURL.routeTo = function(path, opts) {
|
DiscourseURL.routeTo = function (path, opts) {
|
||||||
if (path && path.indexOf('/w/') > -1) {
|
if (path && path.indexOf("/w/") > -1) {
|
||||||
return window.location = path;
|
return (window.location = path);
|
||||||
}
|
}
|
||||||
return existing.apply(this, [path, opts]);
|
return existing.apply(this, [path, opts]);
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,36 +1,42 @@
|
||||||
import ApplicationRoute from 'discourse/routes/application';
|
import ApplicationRoute from "discourse/routes/application";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "custom-wizard-redirect",
|
name: "custom-wizard-redirect",
|
||||||
after: "message-bus",
|
after: "message-bus",
|
||||||
|
|
||||||
initialize: function (container) {
|
initialize: function (container) {
|
||||||
const messageBus = container.lookup('message-bus:main');
|
const messageBus = container.lookup("message-bus:main");
|
||||||
const siteSettings = container.lookup('site-settings:main');
|
const siteSettings = container.lookup("site-settings:main");
|
||||||
|
|
||||||
if (!siteSettings.custom_wizard_enabled || !messageBus) return;
|
if (!siteSettings.custom_wizard_enabled || !messageBus) return;
|
||||||
|
|
||||||
messageBus.subscribe("/redirect_to_wizard", function (wizardId) {
|
messageBus.subscribe("/redirect_to_wizard", function (wizardId) {
|
||||||
const wizardUrl = window.location.origin + '/w/' + wizardId;
|
const wizardUrl = window.location.origin + "/w/" + wizardId;
|
||||||
window.location.href = wizardUrl;
|
window.location.href = wizardUrl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ApplicationRoute.reopen({
|
ApplicationRoute.reopen({
|
||||||
actions: {
|
actions: {
|
||||||
willTransition(transition) {
|
willTransition(transition) {
|
||||||
const redirectToWizard = this.get('currentUser.redirect_to_wizard');
|
const redirectToWizard = this.get("currentUser.redirect_to_wizard");
|
||||||
const excludedPaths = Discourse.SiteSettings.wizard_redirect_exclude_paths.split('|').concat(['loading']);
|
const excludedPaths = Discourse.SiteSettings.wizard_redirect_exclude_paths
|
||||||
|
.split("|")
|
||||||
|
.concat(["loading"]);
|
||||||
|
|
||||||
if (redirectToWizard && (!transition.intent.name || !excludedPaths.find((p) => {
|
if (
|
||||||
return transition.intent.name.indexOf(p) > -1;
|
redirectToWizard &&
|
||||||
}))) {
|
(!transition.intent.name ||
|
||||||
|
!excludedPaths.find((p) => {
|
||||||
|
return transition.intent.name.indexOf(p) > -1;
|
||||||
|
}))
|
||||||
|
) {
|
||||||
transition.abort();
|
transition.abort();
|
||||||
window.location = '/w/' + redirectToWizard.dasherize();
|
window.location = "/w/" + redirectToWizard.dasherize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._super(transition);
|
return this._super(transition);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { listProperties, camelCase, snakeCase } from '../lib/wizard';
|
import { listProperties, camelCase, snakeCase } from "../lib/wizard";
|
||||||
import wizardSchema from '../lib/wizard-schema';
|
import wizardSchema from "../lib/wizard-schema";
|
||||||
import EmberObject from '@ember/object';
|
import EmberObject from "@ember/object";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
|
|
||||||
function present(val) {
|
function present(val) {
|
||||||
if (val === null || val === undefined) {
|
if (val === null || val === undefined) {
|
||||||
return false;
|
return false;
|
||||||
} else if (typeof val === 'object') {
|
} else if (typeof val === "object") {
|
||||||
return Object.keys(val).length !== 0;
|
return Object.keys(val).length !== 0;
|
||||||
} else if (typeof val === 'string' || val.constructor === Array) {
|
} else if (typeof val === "string" || val.constructor === Array) {
|
||||||
return val && val.length;
|
return val && val.length;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -20,51 +20,44 @@ function mapped(property, type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function castCase(property, value) {
|
function castCase(property, value) {
|
||||||
return property.indexOf('_type') > -1 ? camelCase(value) : value;
|
return property.indexOf("_type") > -1 ? camelCase(value) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildProperty(json, property, type) {
|
function buildProperty(json, property, type) {
|
||||||
let value = json[property];
|
let value = json[property];
|
||||||
|
|
||||||
if (mapped(property, type) &&
|
if (mapped(property, type) && present(value) && value.constructor === Array) {
|
||||||
present(value) &&
|
|
||||||
value.constructor === Array) {
|
|
||||||
|
|
||||||
let inputs = [];
|
let inputs = [];
|
||||||
|
|
||||||
value.forEach(inputJson => {
|
value.forEach((inputJson) => {
|
||||||
let input = {}
|
let input = {};
|
||||||
|
|
||||||
Object.keys(inputJson).forEach(inputKey => {
|
Object.keys(inputJson).forEach((inputKey) => {
|
||||||
if (inputKey === 'pairs') {
|
if (inputKey === "pairs") {
|
||||||
let pairs = [];
|
let pairs = [];
|
||||||
let pairCount = inputJson.pairs.length;
|
let pairCount = inputJson.pairs.length;
|
||||||
|
|
||||||
inputJson.pairs.forEach(pairJson => {
|
inputJson.pairs.forEach((pairJson) => {
|
||||||
let pair = {};
|
let pair = {};
|
||||||
|
|
||||||
Object.keys(pairJson).forEach(pairKey => {
|
Object.keys(pairJson).forEach((pairKey) => {
|
||||||
pair[pairKey] = castCase(pairKey, pairJson[pairKey]);
|
pair[pairKey] = castCase(pairKey, pairJson[pairKey]);
|
||||||
});
|
});
|
||||||
|
|
||||||
pair.pairCount = pairCount;
|
pair.pairCount = pairCount;
|
||||||
|
|
||||||
pairs.push(
|
pairs.push(EmberObject.create(pair));
|
||||||
EmberObject.create(pair)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
input.pairs = pairs;
|
input.pairs = pairs;
|
||||||
} else {
|
} else {
|
||||||
input[inputKey] = castCase(inputKey, inputJson[inputKey]);
|
input[inputKey] = castCase(inputKey, inputJson[inputKey]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
inputs.push(
|
inputs.push(EmberObject.create(input));
|
||||||
EmberObject.create(input)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return A(inputs);
|
return A(inputs);
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
||||||
|
@ -73,48 +66,48 @@ function buildProperty(json, property, type) {
|
||||||
|
|
||||||
function buildObject(json, type) {
|
function buildObject(json, type) {
|
||||||
let props = {
|
let props = {
|
||||||
isNew: false
|
isNew: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.keys(json).forEach(prop => {
|
Object.keys(json).forEach((prop) => {
|
||||||
props[prop] = buildProperty(json, prop, type)
|
props[prop] = buildProperty(json, prop, type);
|
||||||
});
|
});
|
||||||
|
|
||||||
return EmberObject.create(props);
|
return EmberObject.create(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildObjectArray(json, type) {
|
function buildObjectArray(json, type) {
|
||||||
let array = A();
|
let array = A();
|
||||||
|
|
||||||
if (present(json)) {
|
if (present(json)) {
|
||||||
json.forEach((objJson) => {
|
json.forEach((objJson) => {
|
||||||
let object = buildObject(objJson, type);
|
let object = buildObject(objJson, type);
|
||||||
|
|
||||||
if (hasAdvancedProperties(object, type)) {
|
if (hasAdvancedProperties(object, type)) {
|
||||||
object.set('showAdvanced', true);
|
object.set("showAdvanced", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
array.pushObject(object);
|
array.pushObject(object);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildBasicProperties(json, type, props) {
|
function buildBasicProperties(json, type, props) {
|
||||||
listProperties(type).forEach((p) => {
|
listProperties(type).forEach((p) => {
|
||||||
props[p] = buildProperty(json, p, type);
|
props[p] = buildProperty(json, p, type);
|
||||||
|
|
||||||
if (hasAdvancedProperties(json, type)) {
|
if (hasAdvancedProperties(json, type)) {
|
||||||
props.showAdvanced = true;
|
props.showAdvanced = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasAdvancedProperties(object, type) {
|
function hasAdvancedProperties(object, type) {
|
||||||
return Object.keys(object).some(p => {
|
return Object.keys(object).some((p) => {
|
||||||
return wizardSchema[type].advanced.indexOf(p) > -1 && present(object[p]);
|
return wizardSchema[type].advanced.indexOf(p) > -1 && present(object[p]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -122,59 +115,55 @@ function hasAdvancedProperties(object, type) {
|
||||||
/// to be removed: necessary due to action array being moved from step to wizard
|
/// to be removed: necessary due to action array being moved from step to wizard
|
||||||
function actionPatch(json) {
|
function actionPatch(json) {
|
||||||
let actions = json.actions || [];
|
let actions = json.actions || [];
|
||||||
|
|
||||||
json.steps.forEach(step => {
|
json.steps.forEach((step) => {
|
||||||
if (step.actions && step.actions.length) {
|
if (step.actions && step.actions.length) {
|
||||||
step.actions.forEach(action => {
|
step.actions.forEach((action) => {
|
||||||
action.run_after = 'wizard_completion';
|
action.run_after = "wizard_completion";
|
||||||
actions.push(action);
|
actions.push(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
json.actions = actions;
|
json.actions = actions;
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
|
|
||||||
function buildProperties(json) {
|
function buildProperties(json) {
|
||||||
let props = {
|
let props = {
|
||||||
steps: A(),
|
steps: A(),
|
||||||
actions: A()
|
actions: A(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (present(json)) {
|
if (present(json)) {
|
||||||
props.existingId = true;
|
props.existingId = true;
|
||||||
props = buildBasicProperties(json, 'wizard', props);
|
props = buildBasicProperties(json, "wizard", props);
|
||||||
|
|
||||||
if (present(json.steps)) {
|
if (present(json.steps)) {
|
||||||
json.steps.forEach((stepJson) => {
|
json.steps.forEach((stepJson) => {
|
||||||
let stepProps = {
|
let stepProps = {
|
||||||
isNew: false
|
isNew: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
stepProps = buildBasicProperties(stepJson, 'step', stepProps);
|
stepProps = buildBasicProperties(stepJson, "step", stepProps);
|
||||||
stepProps.fields = buildObjectArray(stepJson.fields, 'field');
|
stepProps.fields = buildObjectArray(stepJson.fields, "field");
|
||||||
|
|
||||||
props.steps.pushObject(EmberObject.create(stepProps));
|
props.steps.pushObject(EmberObject.create(stepProps));
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
json = actionPatch(json); // to be removed - see above
|
json = actionPatch(json); // to be removed - see above
|
||||||
|
|
||||||
props.actions = buildObjectArray(json.actions, 'action');
|
props.actions = buildObjectArray(json.actions, "action");
|
||||||
} else {
|
} else {
|
||||||
listProperties('wizard').forEach(prop => {
|
listProperties("wizard").forEach((prop) => {
|
||||||
props[prop] = wizardSchema.wizard.basic[prop];
|
props[prop] = wizardSchema.wizard.basic[prop];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { buildProperties, present, mapped };
|
||||||
buildProperties,
|
|
||||||
present,
|
|
||||||
mapped
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,71 +5,71 @@ import I18n from "I18n";
|
||||||
// Inputs
|
// Inputs
|
||||||
|
|
||||||
function defaultInputType(options = {}) {
|
function defaultInputType(options = {}) {
|
||||||
return options.inputTypes.split(',')[0];
|
return options.inputTypes.split(",")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapInputTypes(types) {
|
function mapInputTypes(types) {
|
||||||
return types.map(function(type) {
|
return types.map(function (type) {
|
||||||
return {
|
return {
|
||||||
id: type,
|
id: type,
|
||||||
name: I18n.t(`admin.wizard.input.${type}.name`)
|
name: I18n.t(`admin.wizard.input.${type}.name`),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function inputTypesContent(options = {}) {
|
function inputTypesContent(options = {}) {
|
||||||
return options.inputTypes ?
|
return options.inputTypes
|
||||||
mapInputTypes(options.inputTypes.split(',')) :
|
? mapInputTypes(options.inputTypes.split(","))
|
||||||
mapInputTypes(selectableInputTypes);
|
: mapInputTypes(selectableInputTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// connectorTypes
|
// connectorTypes
|
||||||
|
|
||||||
const connectors = {
|
const connectors = {
|
||||||
pair: [
|
pair: [
|
||||||
'equal',
|
"equal",
|
||||||
'greater',
|
"greater",
|
||||||
'less',
|
"less",
|
||||||
'greater_or_equal',
|
"greater_or_equal",
|
||||||
'less_or_equal',
|
"less_or_equal",
|
||||||
'regex',
|
"regex",
|
||||||
'is'
|
"is",
|
||||||
],
|
],
|
||||||
output: [
|
output: ["then", "set"],
|
||||||
'then',
|
};
|
||||||
'set',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
function defaultConnector(connectorType, inputType, options={}) {
|
function defaultConnector(connectorType, inputType, options = {}) {
|
||||||
if (connectorType === 'input') {
|
if (connectorType === "input") {
|
||||||
return defaultInputType(options);
|
return defaultInputType(options);
|
||||||
}
|
}
|
||||||
if (connectorType === 'pair') {
|
if (connectorType === "pair") {
|
||||||
if (inputType === 'conditional') return 'equal';
|
if (inputType === "conditional") return "equal";
|
||||||
if (inputType === 'association') return 'association';
|
if (inputType === "association") return "association";
|
||||||
if (inputType === 'validation') return 'equal';
|
if (inputType === "validation") return "equal";
|
||||||
}
|
}
|
||||||
if (connectorType === 'output') {
|
if (connectorType === "output") {
|
||||||
if (inputType === 'conditional') return 'then';
|
if (inputType === "conditional") return "then";
|
||||||
if (inputType === 'assignment') return 'set';
|
if (inputType === "assignment") return "set";
|
||||||
}
|
}
|
||||||
return 'equal';
|
return "equal";
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectorContent(connectorType, inputType, opts) {
|
function connectorContent(connectorType, inputType, opts) {
|
||||||
let connector = opts[`${connectorType}Connector`];
|
let connector = opts[`${connectorType}Connector`];
|
||||||
|
|
||||||
if ((!connector && connectorType === 'output') || inputType === 'association') {
|
if (
|
||||||
|
(!connector && connectorType === "output") ||
|
||||||
|
inputType === "association"
|
||||||
|
) {
|
||||||
connector = defaultConnector(connectorType, inputType);
|
connector = defaultConnector(connectorType, inputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = connector ? [connector] : connectors[connectorType];
|
let content = connector ? [connector] : connectors[connectorType];
|
||||||
|
|
||||||
return content.map(function(item) {
|
return content.map(function (item) {
|
||||||
return {
|
return {
|
||||||
id: item,
|
id: item,
|
||||||
name: I18n.t(`admin.wizard.connector.${item}`)
|
name: I18n.t(`admin.wizard.connector.${item}`),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -77,38 +77,39 @@ function connectorContent(connectorType, inputType, opts) {
|
||||||
// Selectors
|
// Selectors
|
||||||
|
|
||||||
const selectionTypes = [
|
const selectionTypes = [
|
||||||
'text',
|
"text",
|
||||||
'list',
|
"list",
|
||||||
'wizardField',
|
"wizardField",
|
||||||
'wizardAction',
|
"wizardAction",
|
||||||
'userField',
|
"userField",
|
||||||
'userFieldOptions',
|
"userFieldOptions",
|
||||||
'group',
|
"group",
|
||||||
'category',
|
"category",
|
||||||
'tag',
|
"tag",
|
||||||
'user',
|
"user",
|
||||||
'customField'
|
"customField",
|
||||||
]
|
];
|
||||||
|
|
||||||
function defaultSelectionType(inputType, options = {}) {
|
function defaultSelectionType(inputType, options = {}) {
|
||||||
if (options[`${inputType}DefaultSelection`]) {
|
if (options[`${inputType}DefaultSelection`]) {
|
||||||
return options[`${inputType}DefaultSelection`];
|
return options[`${inputType}DefaultSelection`];
|
||||||
}
|
}
|
||||||
|
|
||||||
let type = selectionTypes[0];
|
let type = selectionTypes[0];
|
||||||
|
|
||||||
for (let t of selectionTypes) {
|
for (let t of selectionTypes) {
|
||||||
let inputTypes = options[`${t}Selection`];
|
let inputTypes = options[`${t}Selection`];
|
||||||
|
|
||||||
if (inputTypes === true ||
|
if (
|
||||||
((typeof inputTypes === 'string') &&
|
inputTypes === true ||
|
||||||
inputTypes.split(',').indexOf(inputType) > -1)) {
|
(typeof inputTypes === "string" &&
|
||||||
|
inputTypes.split(",").indexOf(inputType) > -1)
|
||||||
|
) {
|
||||||
type = t;
|
type = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,46 +119,42 @@ function newPair(inputType, options = {}) {
|
||||||
let params = {
|
let params = {
|
||||||
index: options.index,
|
index: options.index,
|
||||||
pairCount: options.pairCount,
|
pairCount: options.pairCount,
|
||||||
key: '',
|
key: "",
|
||||||
key_type: defaultSelectionType('key', options),
|
key_type: defaultSelectionType("key", options),
|
||||||
value: '',
|
value: "",
|
||||||
value_type: defaultSelectionType('value', options),
|
value_type: defaultSelectionType("value", options),
|
||||||
connector: defaultConnector('pair', inputType, options)
|
connector: defaultConnector("pair", inputType, options),
|
||||||
}
|
};
|
||||||
|
|
||||||
return EmberObject.create(params);
|
return EmberObject.create(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newInput(options = {}, count) {
|
function newInput(options = {}, count) {
|
||||||
const inputType = defaultInputType(options);
|
const inputType = defaultInputType(options);
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
type: inputType,
|
type: inputType,
|
||||||
pairs: A(
|
pairs: A([
|
||||||
[
|
newPair(
|
||||||
newPair(
|
inputType,
|
||||||
inputType,
|
Object.assign({}, options, { index: 0, pairCount: 1 })
|
||||||
Object.assign({},
|
),
|
||||||
options,
|
]),
|
||||||
{ index: 0, pairCount: 1 }
|
};
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
params.connector = options.inputConnector;
|
params.connector = options.inputConnector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['conditional', 'assignment'].indexOf(inputType) > -1 ||
|
if (
|
||||||
options.outputDefaultSelection ||
|
["conditional", "assignment"].indexOf(inputType) > -1 ||
|
||||||
options.outputConnector) {
|
options.outputDefaultSelection ||
|
||||||
|
options.outputConnector
|
||||||
params['output_type'] = defaultSelectionType('output', options);
|
) {
|
||||||
params['output_connector'] = defaultConnector('output', inputType, options);
|
params["output_type"] = defaultSelectionType("output", options);
|
||||||
|
params["output_connector"] = defaultConnector("output", inputType, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EmberObject.create(params);
|
return EmberObject.create(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,5 +166,5 @@ export {
|
||||||
inputTypesContent,
|
inputTypesContent,
|
||||||
selectionTypes,
|
selectionTypes,
|
||||||
newInput,
|
newInput,
|
||||||
newPair
|
newPair,
|
||||||
}
|
};
|
||||||
|
|
|
@ -14,30 +14,24 @@ const wizard = {
|
||||||
prompt_completion: null,
|
prompt_completion: null,
|
||||||
restart_on_revisit: null,
|
restart_on_revisit: null,
|
||||||
theme_id: null,
|
theme_id: null,
|
||||||
permitted: null
|
permitted: null,
|
||||||
},
|
},
|
||||||
mapped: [
|
mapped: ["permitted"],
|
||||||
'permitted'
|
advanced: ["restart_on_revisit"],
|
||||||
],
|
required: ["id"],
|
||||||
advanced: [
|
|
||||||
'restart_on_revisit',
|
|
||||||
],
|
|
||||||
required: [
|
|
||||||
'id',
|
|
||||||
],
|
|
||||||
dependent: {
|
dependent: {
|
||||||
after_time: 'after_time_scheduled'
|
after_time: "after_time_scheduled",
|
||||||
},
|
},
|
||||||
objectArrays: {
|
objectArrays: {
|
||||||
step: {
|
step: {
|
||||||
property: 'steps',
|
property: "steps",
|
||||||
required: false
|
required: false,
|
||||||
},
|
},
|
||||||
action: {
|
action: {
|
||||||
property: 'actions',
|
property: "actions",
|
||||||
required: false
|
required: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const step = {
|
const step = {
|
||||||
|
@ -49,28 +43,19 @@ const step = {
|
||||||
raw_description: null,
|
raw_description: null,
|
||||||
required_data: null,
|
required_data: null,
|
||||||
required_data_message: null,
|
required_data_message: null,
|
||||||
permitted_params: null
|
permitted_params: null,
|
||||||
},
|
|
||||||
mapped: [
|
|
||||||
'required_data',
|
|
||||||
'permitted_params'
|
|
||||||
],
|
|
||||||
advanced: [
|
|
||||||
'required_data',
|
|
||||||
'permitted_params'
|
|
||||||
],
|
|
||||||
required: [
|
|
||||||
'id'
|
|
||||||
],
|
|
||||||
dependent: {
|
|
||||||
},
|
},
|
||||||
|
mapped: ["required_data", "permitted_params"],
|
||||||
|
advanced: ["required_data", "permitted_params"],
|
||||||
|
required: ["id"],
|
||||||
|
dependent: {},
|
||||||
objectArrays: {
|
objectArrays: {
|
||||||
field: {
|
field: {
|
||||||
property: 'fields',
|
property: "fields",
|
||||||
required: false
|
required: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const field = {
|
const field = {
|
||||||
basic: {
|
basic: {
|
||||||
|
@ -80,32 +65,21 @@ const field = {
|
||||||
description: null,
|
description: null,
|
||||||
required: null,
|
required: null,
|
||||||
key: null,
|
key: null,
|
||||||
type: null
|
type: null,
|
||||||
},
|
},
|
||||||
types: {},
|
types: {},
|
||||||
mapped: [
|
mapped: ["prefill", "content"],
|
||||||
'prefill',
|
advanced: ["property", "key"],
|
||||||
'content'
|
required: ["id", "type"],
|
||||||
],
|
dependent: {},
|
||||||
advanced: [
|
objectArrays: {},
|
||||||
'property',
|
};
|
||||||
'key'
|
|
||||||
],
|
|
||||||
required: [
|
|
||||||
'id',
|
|
||||||
'type'
|
|
||||||
],
|
|
||||||
dependent: {
|
|
||||||
},
|
|
||||||
objectArrays: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const action = {
|
const action = {
|
||||||
basic: {
|
basic: {
|
||||||
id: null,
|
id: null,
|
||||||
run_after: 'wizard_completion',
|
run_after: "wizard_completion",
|
||||||
type: null
|
type: null,
|
||||||
},
|
},
|
||||||
types: {
|
types: {
|
||||||
create_topic: {
|
create_topic: {
|
||||||
|
@ -129,7 +103,7 @@ const action = {
|
||||||
custom_fields: null,
|
custom_fields: null,
|
||||||
required: null,
|
required: null,
|
||||||
recipient: null,
|
recipient: null,
|
||||||
suppress_notifications: null
|
suppress_notifications: null,
|
||||||
},
|
},
|
||||||
open_composer: {
|
open_composer: {
|
||||||
title: null,
|
title: null,
|
||||||
|
@ -138,30 +112,30 @@ const action = {
|
||||||
post_template: null,
|
post_template: null,
|
||||||
category: null,
|
category: null,
|
||||||
tags: null,
|
tags: null,
|
||||||
custom_fields: null
|
custom_fields: null,
|
||||||
},
|
},
|
||||||
update_profile: {
|
update_profile: {
|
||||||
profile_updates: null,
|
profile_updates: null,
|
||||||
custom_fields: null
|
custom_fields: null,
|
||||||
},
|
},
|
||||||
watch_categories: {
|
watch_categories: {
|
||||||
categories: null,
|
categories: null,
|
||||||
notification_level: null,
|
notification_level: null,
|
||||||
mute_remainder: null,
|
mute_remainder: null,
|
||||||
wizard_user: true,
|
wizard_user: true,
|
||||||
usernames: null
|
usernames: null,
|
||||||
},
|
},
|
||||||
send_to_api: {
|
send_to_api: {
|
||||||
api: null,
|
api: null,
|
||||||
api_endpoint: null,
|
api_endpoint: null,
|
||||||
api_body: null
|
api_body: null,
|
||||||
},
|
},
|
||||||
add_to_group: {
|
add_to_group: {
|
||||||
group: null
|
group: null,
|
||||||
},
|
},
|
||||||
route_to: {
|
route_to: {
|
||||||
url: null,
|
url: null,
|
||||||
code: null
|
code: null,
|
||||||
},
|
},
|
||||||
create_category: {
|
create_category: {
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -170,7 +144,7 @@ const action = {
|
||||||
text_color: "FFFFFF",
|
text_color: "FFFFFF",
|
||||||
parent_category_id: null,
|
parent_category_id: null,
|
||||||
permissions: null,
|
permissions: null,
|
||||||
custom_fields: null
|
custom_fields: null,
|
||||||
},
|
},
|
||||||
create_group: {
|
create_group: {
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -184,61 +158,56 @@ const action = {
|
||||||
messageable_level: null,
|
messageable_level: null,
|
||||||
visibility_level: null,
|
visibility_level: null,
|
||||||
members_visibility_level: null,
|
members_visibility_level: null,
|
||||||
custom_fields: null
|
custom_fields: null,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mapped: [
|
mapped: [
|
||||||
'title',
|
"title",
|
||||||
'category',
|
"category",
|
||||||
'tags',
|
"tags",
|
||||||
'visible',
|
"visible",
|
||||||
'custom_fields',
|
"custom_fields",
|
||||||
'required',
|
"required",
|
||||||
'recipient',
|
"recipient",
|
||||||
'profile_updates',
|
"profile_updates",
|
||||||
'group',
|
"group",
|
||||||
'url',
|
"url",
|
||||||
'categories',
|
"categories",
|
||||||
'mute_remainder',
|
"mute_remainder",
|
||||||
'name',
|
"name",
|
||||||
'slug',
|
"slug",
|
||||||
'color',
|
"color",
|
||||||
'text_color',
|
"text_color",
|
||||||
'parent_category_id',
|
"parent_category_id",
|
||||||
'permissions',
|
"permissions",
|
||||||
'full_name',
|
"full_name",
|
||||||
'bio_raw',
|
"bio_raw",
|
||||||
'owner_usernames',
|
"owner_usernames",
|
||||||
'usernames',
|
"usernames",
|
||||||
'grant_trust_level',
|
"grant_trust_level",
|
||||||
'mentionable_level',
|
"mentionable_level",
|
||||||
'messageable_level',
|
"messageable_level",
|
||||||
'visibility_level',
|
"visibility_level",
|
||||||
'members_visibility_level'
|
"members_visibility_level",
|
||||||
],
|
],
|
||||||
advanced: [
|
advanced: [
|
||||||
'code',
|
"code",
|
||||||
'custom_fields',
|
"custom_fields",
|
||||||
'skip_redirect',
|
"skip_redirect",
|
||||||
'suppress_notifications',
|
"suppress_notifications",
|
||||||
'required'
|
"required",
|
||||||
],
|
],
|
||||||
required: [
|
required: ["id", "type"],
|
||||||
'id',
|
dependent: {},
|
||||||
'type'
|
objectArrays: {},
|
||||||
],
|
};
|
||||||
dependent: {
|
|
||||||
},
|
|
||||||
objectArrays: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wizardSchema = {
|
const wizardSchema = {
|
||||||
wizard,
|
wizard,
|
||||||
step,
|
step,
|
||||||
field,
|
field,
|
||||||
action
|
action,
|
||||||
}
|
};
|
||||||
|
|
||||||
export function buildFieldTypes(types) {
|
export function buildFieldTypes(types) {
|
||||||
wizardSchema.field.types = types;
|
wizardSchema.field.types = types;
|
||||||
|
@ -252,34 +221,34 @@ if (Discourse.SiteSettings.wizard_apis_enabled) {
|
||||||
wizardSchema.action.types.send_to_api = {
|
wizardSchema.action.types.send_to_api = {
|
||||||
api: null,
|
api: null,
|
||||||
api_endpoint: null,
|
api_endpoint: null,
|
||||||
api_body: null
|
api_body: null,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setWizardDefaults(obj, itemType, opts={}) {
|
export function setWizardDefaults(obj, itemType, opts = {}) {
|
||||||
const objSchema = wizardSchema[itemType];
|
const objSchema = wizardSchema[itemType];
|
||||||
const basicDefaults = objSchema.basic;
|
const basicDefaults = objSchema.basic;
|
||||||
|
|
||||||
Object.keys(basicDefaults).forEach(property => {
|
Object.keys(basicDefaults).forEach((property) => {
|
||||||
let defaultValue = get(basicDefaults, property);
|
let defaultValue = get(basicDefaults, property);
|
||||||
if (defaultValue) {
|
if (defaultValue) {
|
||||||
set(obj, property, defaultValue);
|
set(obj, property, defaultValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (objSchema.types) {
|
if (objSchema.types) {
|
||||||
const typeDefaults = objSchema.types[obj.type];
|
const typeDefaults = objSchema.types[obj.type];
|
||||||
|
|
||||||
if (typeDefaults) {
|
if (typeDefaults) {
|
||||||
Object.keys(typeDefaults).forEach(property => {
|
Object.keys(typeDefaults).forEach((property) => {
|
||||||
if (typeDefaults.hasOwnProperty(property)) {
|
if (typeDefaults.hasOwnProperty(property)) {
|
||||||
set(obj, property, get(typeDefaults, property));
|
set(obj, property, get(typeDefaults, property));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default wizardSchema;
|
export default wizardSchema;
|
||||||
|
|
|
@ -1,110 +1,111 @@
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import wizardSchema from './wizard-schema';
|
import wizardSchema from "./wizard-schema";
|
||||||
|
|
||||||
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) {
|
||||||
return id ? sentenceCase(id) : '';
|
return id ? sentenceCase(id) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateId(name, opts={}) {
|
function generateId(name, opts = {}) {
|
||||||
return name ? snakeCase(name) : '';
|
return name ? snakeCase(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
|
||||||
.map(x => x.toLowerCase())
|
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
||||||
.join('_');
|
.map((x) => x.toLowerCase())
|
||||||
|
.join("_");
|
||||||
}
|
}
|
||||||
|
|
||||||
function camelCase(string) {
|
function camelCase(string) {
|
||||||
return string.replace(/([-_][a-z])/ig, ($1) => {
|
return string.replace(/([-_][a-z])/gi, ($1) => {
|
||||||
return $1.toUpperCase()
|
return $1.toUpperCase().replace("-", "").replace("_", "");
|
||||||
.replace('-', '')
|
|
||||||
.replace('_', '');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const userProperties = [
|
const userProperties = [
|
||||||
'name',
|
"name",
|
||||||
'username',
|
"username",
|
||||||
'email',
|
"email",
|
||||||
'avatar',
|
"avatar",
|
||||||
'date_of_birth',
|
"date_of_birth",
|
||||||
'title',
|
"title",
|
||||||
'profile_background',
|
"profile_background",
|
||||||
'card_background',
|
"card_background",
|
||||||
'locale',
|
"locale",
|
||||||
'location',
|
"location",
|
||||||
'website',
|
"website",
|
||||||
'bio_raw',
|
"bio_raw",
|
||||||
'trust_level',
|
"trust_level",
|
||||||
'email_level',
|
"email_level",
|
||||||
'email_messages_level',
|
"email_messages_level",
|
||||||
'email_digests'
|
"email_digests",
|
||||||
];
|
];
|
||||||
|
|
||||||
const notificationLevels = [
|
const notificationLevels = [
|
||||||
'regular',
|
"regular",
|
||||||
'watching',
|
"watching",
|
||||||
'tracking',
|
"tracking",
|
||||||
'watching_first_post',
|
"watching_first_post",
|
||||||
'muted'
|
"muted",
|
||||||
];
|
];
|
||||||
|
|
||||||
function listProperties(type, opts={}) {
|
function listProperties(type, opts = {}) {
|
||||||
let properties = Object.keys(wizardSchema[type].basic);
|
let properties = Object.keys(wizardSchema[type].basic);
|
||||||
|
|
||||||
const types = wizardSchema[type].types;
|
const types = wizardSchema[type].types;
|
||||||
|
|
||||||
if (types) {
|
if (types) {
|
||||||
let typeProperties = [];
|
let typeProperties = [];
|
||||||
|
|
||||||
if (opts.allTypes) {
|
if (opts.allTypes) {
|
||||||
Object.keys(types).forEach(type => {
|
Object.keys(types).forEach((type) => {
|
||||||
typeProperties = typeProperties.concat(Object.keys(types[type]));
|
typeProperties = typeProperties.concat(Object.keys(types[type]));
|
||||||
});
|
});
|
||||||
} else if (opts.objectType && types[opts.objectType]) {
|
} else if (opts.objectType && types[opts.objectType]) {
|
||||||
typeProperties = Object.keys(types[opts.objectType]);
|
typeProperties = Object.keys(types[opts.objectType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
properties = properties.concat(typeProperties);
|
properties = properties.concat(typeProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
function wizardFieldList(steps = [], opts = {}) {
|
function wizardFieldList(steps = [], opts = {}) {
|
||||||
let upToIndex = null;
|
let upToIndex = null;
|
||||||
|
|
||||||
if (opts.upTo) {
|
if (opts.upTo) {
|
||||||
upToIndex = steps.map((s) => (s.id)).indexOf(opts.upTo);
|
upToIndex = steps.map((s) => s.id).indexOf(opts.upTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return steps.reduce((result, step, index) => {
|
return steps.reduce((result, step, index) => {
|
||||||
let fields = step.fields;
|
let fields = step.fields;
|
||||||
|
|
||||||
if (fields && fields.length > 0) {
|
if (fields && fields.length > 0) {
|
||||||
|
|
||||||
if (upToIndex === null || index < upToIndex) {
|
if (upToIndex === null || index < upToIndex) {
|
||||||
result.push(...fields.map((field) => {
|
result.push(
|
||||||
return EmberObject.create({
|
...fields.map((field) => {
|
||||||
id: field.id,
|
return EmberObject.create({
|
||||||
label: `${field.label} (${field.id})`,
|
id: field.id,
|
||||||
type: field.type
|
label: `${field.label} (${field.id})`,
|
||||||
});
|
type: field.type,
|
||||||
}));
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
@ -118,5 +119,5 @@ export {
|
||||||
userProperties,
|
userProperties,
|
||||||
listProperties,
|
listProperties,
|
||||||
notificationLevels,
|
notificationLevels,
|
||||||
wizardFieldList
|
wizardFieldList,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { listProperties } from '../lib/wizard';
|
import { listProperties } from "../lib/wizard";
|
||||||
import { default as wizardSchema } from '../lib/wizard-schema';
|
import { default as wizardSchema } from "../lib/wizard-schema";
|
||||||
import { set, get } from "@ember/object";
|
import { set, get } from "@ember/object";
|
||||||
import Mixin from "@ember/object/mixin";
|
import Mixin from "@ember/object/mixin";
|
||||||
import { observes } from 'discourse-common/utils/decorators';
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
import { deepEqual } from 'discourse-common/lib/object';
|
import { deepEqual } from "discourse-common/lib/object";
|
||||||
|
|
||||||
export default Mixin.create({
|
export default Mixin.create({
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
|
@ -14,9 +14,9 @@ export default Mixin.create({
|
||||||
|
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
originalObject: JSON.parse(JSON.stringify(obj)),
|
originalObject: JSON.parse(JSON.stringify(obj)),
|
||||||
undoIcon: obj.isNew ? 'times' : 'undo',
|
undoIcon: obj.isNew ? "times" : "undo",
|
||||||
undoKey: `admin.wizard.${obj.isNew ? 'clear' : 'undo'}`
|
undoKey: `admin.wizard.${obj.isNew ? "clear" : "undo"}`,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
|
@ -24,33 +24,33 @@ export default Mixin.create({
|
||||||
this.removeObservers();
|
this.removeObservers();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeObservers(objType=null) {
|
removeObservers(objType = null) {
|
||||||
const componentType = this.componentType;
|
const componentType = this.componentType;
|
||||||
const obj = this.get(componentType);
|
const obj = this.get(componentType);
|
||||||
|
|
||||||
let opts = {
|
let opts = {
|
||||||
objectType: objType || obj.type
|
objectType: objType || obj.type,
|
||||||
}
|
};
|
||||||
|
|
||||||
listProperties(componentType, opts).forEach(property => {
|
listProperties(componentType, opts).forEach((property) => {
|
||||||
obj.removeObserver(property, this, this.toggleUndo);
|
obj.removeObserver(property, this, this.toggleUndo);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupObservers(objType=null) {
|
setupObservers(objType = null) {
|
||||||
const componentType = this.componentType;
|
const componentType = this.componentType;
|
||||||
const obj = this.get(componentType);
|
const obj = this.get(componentType);
|
||||||
|
|
||||||
let opts = {
|
let opts = {
|
||||||
objectType: objType || obj.type
|
objectType: objType || obj.type,
|
||||||
}
|
};
|
||||||
|
|
||||||
listProperties(componentType, opts).forEach(property => {
|
listProperties(componentType, opts).forEach((property) => {
|
||||||
obj.addObserver(property, this, this.toggleUndo);
|
obj.addObserver(property, this, this.toggleUndo);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
revertToOriginal(revertBasic=false) {
|
revertToOriginal(revertBasic = false) {
|
||||||
const original = JSON.parse(JSON.stringify(this.originalObject));
|
const original = JSON.parse(JSON.stringify(this.originalObject));
|
||||||
const componentType = this.componentType;
|
const componentType = this.componentType;
|
||||||
const obj = this.get(componentType);
|
const obj = this.get(componentType);
|
||||||
|
@ -58,7 +58,7 @@ export default Mixin.create({
|
||||||
const basicDefaults = objSchema.basic;
|
const basicDefaults = objSchema.basic;
|
||||||
|
|
||||||
if (revertBasic) {
|
if (revertBasic) {
|
||||||
Object.keys(basicDefaults).forEach(property => {
|
Object.keys(basicDefaults).forEach((property) => {
|
||||||
let value;
|
let value;
|
||||||
|
|
||||||
if (original.hasOwnProperty(property)) {
|
if (original.hasOwnProperty(property)) {
|
||||||
|
@ -74,7 +74,7 @@ export default Mixin.create({
|
||||||
if (objSchema.types && obj.type) {
|
if (objSchema.types && obj.type) {
|
||||||
let typeDefaults = objSchema.types[obj.type];
|
let typeDefaults = objSchema.types[obj.type];
|
||||||
|
|
||||||
Object.keys(typeDefaults).forEach(property => {
|
Object.keys(typeDefaults).forEach((property) => {
|
||||||
let value;
|
let value;
|
||||||
|
|
||||||
if (original.type === obj.type && original.hasOwnProperty(property)) {
|
if (original.type === obj.type && original.hasOwnProperty(property)) {
|
||||||
|
@ -91,36 +91,36 @@ export default Mixin.create({
|
||||||
toggleUndo() {
|
toggleUndo() {
|
||||||
const current = this.get(this.componentType);
|
const current = this.get(this.componentType);
|
||||||
const original = this.originalObject;
|
const original = this.originalObject;
|
||||||
this.set('showUndo', !deepEqual(current, original));
|
this.set("showUndo", !deepEqual(current, original));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
undoChanges() {
|
undoChanges() {
|
||||||
const componentType = this.componentType;
|
const componentType = this.componentType;
|
||||||
const original = this.get('originalObject');
|
const original = this.get("originalObject");
|
||||||
const obj = this.get(componentType);
|
const obj = this.get(componentType);
|
||||||
|
|
||||||
this.removeObservers(obj.type);
|
this.removeObservers(obj.type);
|
||||||
this.revertToOriginal(true);
|
this.revertToOriginal(true);
|
||||||
this.set('showUndo', false);
|
this.set("showUndo", false);
|
||||||
this.setupObservers(this.get(componentType).type);
|
this.setupObservers(this.get(componentType).type);
|
||||||
},
|
},
|
||||||
|
|
||||||
changeType(type) {
|
changeType(type) {
|
||||||
const componentType = this.componentType;
|
const componentType = this.componentType;
|
||||||
const original = this.get('originalObject');
|
const original = this.get("originalObject");
|
||||||
const obj = this.get(componentType);
|
const obj = this.get(componentType);
|
||||||
|
|
||||||
this.removeObservers(obj.type);
|
this.removeObservers(obj.type);
|
||||||
obj.set('type', type);
|
obj.set("type", type);
|
||||||
this.revertToOriginal();
|
this.revertToOriginal();
|
||||||
this.set('showUndo', type !== original.type);
|
this.set("showUndo", type !== original.type);
|
||||||
this.setupObservers(type);
|
this.setupObservers(type);
|
||||||
},
|
},
|
||||||
|
|
||||||
mappedFieldUpdated(property, mappedComponent, type) {
|
mappedFieldUpdated(property, mappedComponent, type) {
|
||||||
const obj = this.get(this.componentType);
|
const obj = this.get(this.componentType);
|
||||||
obj.notifyPropertyChange(property);
|
obj.notifyPropertyChange(property);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed } from "discourse-common/utils/decorators";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
|
|
||||||
const CustomWizardApi = EmberObject.extend({
|
const CustomWizardApi = EmberObject.extend({
|
||||||
@discourseComputed('name')
|
@discourseComputed("name")
|
||||||
redirectUri(name) {
|
redirectUri(name) {
|
||||||
let nameParam = name.toString().dasherize();
|
let nameParam = name.toString().dasherize();
|
||||||
const baseUrl = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '');
|
const baseUrl =
|
||||||
|
location.protocol +
|
||||||
|
"//" +
|
||||||
|
location.hostname +
|
||||||
|
(location.port ? ":" + location.port : "");
|
||||||
return baseUrl + `/admin/wizards/apis/${nameParam}/redirect`;
|
return baseUrl + `/admin/wizards/apis/${nameParam}/redirect`;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
CustomWizardApi.reopenClass({
|
CustomWizardApi.reopenClass({
|
||||||
|
@ -38,7 +42,7 @@ CustomWizardApi.reopenClass({
|
||||||
tokenRefreshAt: authorization.token_refresh_at,
|
tokenRefreshAt: authorization.token_refresh_at,
|
||||||
endpoints: A(endpoints),
|
endpoints: A(endpoints),
|
||||||
isNew: params.isNew,
|
isNew: params.isNew,
|
||||||
log: params.log
|
log: params.log,
|
||||||
});
|
});
|
||||||
|
|
||||||
return api;
|
return api;
|
||||||
|
@ -46,19 +50,19 @@ CustomWizardApi.reopenClass({
|
||||||
|
|
||||||
find(name) {
|
find(name) {
|
||||||
return ajax(`/admin/wizards/api/${name}`, {
|
return ajax(`/admin/wizards/api/${name}`, {
|
||||||
type: 'GET'
|
type: "GET",
|
||||||
}).then(result => {
|
}).then((result) => {
|
||||||
return CustomWizardApi.create(result);
|
return CustomWizardApi.create(result);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
return ajax("/admin/wizards/api", {
|
return ajax("/admin/wizards/api", {
|
||||||
type: 'GET'
|
type: "GET",
|
||||||
}).then(result => {
|
}).then((result) => {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CustomWizardApi;
|
export default CustomWizardApi;
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
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 EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
|
||||||
const CustomWizardCustomField = EmberObject.extend({
|
const CustomWizardCustomField = EmberObject.extend({
|
||||||
isNew: isEmpty('id')
|
isNew: isEmpty("id"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const basePath = '/admin/wizards/custom-fields';
|
const basePath = "/admin/wizards/custom-fields";
|
||||||
|
|
||||||
CustomWizardCustomField.reopenClass({
|
CustomWizardCustomField.reopenClass({
|
||||||
listFields() {
|
listFields() {
|
||||||
return ajax(basePath).catch(popupAjaxError);
|
return ajax(basePath).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveField(customField) {
|
saveField(customField) {
|
||||||
return ajax(basePath, {
|
return ajax(basePath, {
|
||||||
type: 'PUT',
|
type: "PUT",
|
||||||
data: {
|
data: {
|
||||||
custom_field: customField
|
custom_field: customField,
|
||||||
}
|
},
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyField(field) {
|
destroyField(field) {
|
||||||
return ajax(`${basePath}/${field.name}`, {
|
return ajax(`${basePath}/${field.name}`, {
|
||||||
type: 'DELETE'
|
type: "DELETE",
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CustomWizardCustomField;
|
export default CustomWizardCustomField;
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
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 EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
|
||||||
const CustomWizardLogs = EmberObject.extend();
|
const CustomWizardLogs = EmberObject.extend();
|
||||||
|
|
||||||
CustomWizardLogs.reopenClass({
|
CustomWizardLogs.reopenClass({
|
||||||
list(page = 0) {
|
list(page = 0) {
|
||||||
return ajax('/admin/wizards/logs', {
|
return ajax("/admin/wizards/logs", {
|
||||||
data: {
|
data: {
|
||||||
page
|
page,
|
||||||
}
|
},
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CustomWizardLogs;
|
export default CustomWizardLogs;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
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 EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
|
||||||
const CustomWizardManager = EmberObject.extend();
|
const CustomWizardManager = EmberObject.extend();
|
||||||
|
@ -9,35 +9,35 @@ const basePath = "admin/wizards/manager";
|
||||||
CustomWizardManager.reopenClass({
|
CustomWizardManager.reopenClass({
|
||||||
import($formData) {
|
import($formData) {
|
||||||
return ajax(`/${basePath}/import`, {
|
return ajax(`/${basePath}/import`, {
|
||||||
type: 'POST',
|
type: "POST",
|
||||||
data: $formData,
|
data: $formData,
|
||||||
processData: false,
|
processData: false,
|
||||||
contentType: false,
|
contentType: false,
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
export(wizardIds) {
|
export(wizardIds) {
|
||||||
let url = `${Discourse.BaseUrl}/${basePath}/export?`;
|
let url = `${Discourse.BaseUrl}/${basePath}/export?`;
|
||||||
|
|
||||||
wizardIds.forEach((wizardId, index) => {
|
wizardIds.forEach((wizardId, index) => {
|
||||||
let step = 'wizard_ids[]=' + wizardId;
|
let step = "wizard_ids[]=" + wizardId;
|
||||||
if (index !== wizardIds[wizardIds.length - 1]) {
|
if (index !== wizardIds[wizardIds.length - 1]) {
|
||||||
step += '&';
|
step += "&";
|
||||||
}
|
}
|
||||||
url += step;
|
url += step;
|
||||||
});
|
});
|
||||||
|
|
||||||
location.href = url;
|
location.href = url;
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy(wizardIds) {
|
destroy(wizardIds) {
|
||||||
return ajax(`/${basePath}/destroy`, {
|
return ajax(`/${basePath}/destroy`, {
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
data: {
|
data: {
|
||||||
wizard_ids: wizardIds
|
wizard_ids: wizardIds,
|
||||||
}
|
},
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CustomWizardManager;
|
export default CustomWizardManager;
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import { buildProperties, present, mapped } from '../lib/wizard-json';
|
import { buildProperties, present, mapped } from "../lib/wizard-json";
|
||||||
import { listProperties, camelCase, snakeCase } from '../lib/wizard';
|
import { listProperties, camelCase, snakeCase } from "../lib/wizard";
|
||||||
import wizardSchema from '../lib/wizard-schema';
|
import wizardSchema from "../lib/wizard-schema";
|
||||||
import { Promise } from "rsvp";
|
import { Promise } from "rsvp";
|
||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
|
||||||
const CustomWizard = EmberObject.extend({
|
const CustomWizard = EmberObject.extend({
|
||||||
save(opts) {
|
save(opts) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let wizard = this.buildJson(this, 'wizard');
|
let wizard = this.buildJson(this, "wizard");
|
||||||
|
|
||||||
if (wizard.error) {
|
if (wizard.error) {
|
||||||
reject(wizard);
|
reject(wizard);
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
wizard
|
wizard,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (opts.create) {
|
if (opts.create) {
|
||||||
data.create = true;
|
data.create = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ajax(`/admin/wizards/wizard/${wizard.id}`, {
|
ajax(`/admin/wizards/wizard/${wizard.id}`, {
|
||||||
type: 'PUT',
|
type: "PUT",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify(data),
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
reject(result);
|
reject(result);
|
||||||
|
@ -39,53 +39,55 @@ const CustomWizard = EmberObject.extend({
|
||||||
|
|
||||||
buildJson(object, type, result = {}) {
|
buildJson(object, type, result = {}) {
|
||||||
let objectType = object.type || null;
|
let objectType = object.type || null;
|
||||||
|
|
||||||
if (wizardSchema[type].types) {
|
if (wizardSchema[type].types) {
|
||||||
if (!objectType) {
|
if (!objectType) {
|
||||||
result.error = {
|
result.error = {
|
||||||
type: 'required',
|
type: "required",
|
||||||
params: { type, property: 'type' }
|
params: { type, property: "type" },
|
||||||
}
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let property of listProperties(type, { objectType })) {
|
for (let property of listProperties(type, { objectType })) {
|
||||||
let value = object.get(property);
|
let value = object.get(property);
|
||||||
|
|
||||||
result = this.validateValue(property, value, object, type, result);
|
result = this.validateValue(property, value, object, type, result);
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapped(property, type)) {
|
if (mapped(property, type)) {
|
||||||
value = this.buildMappedJson(value);
|
value = this.buildMappedJson(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value !== undefined && value !== null) {
|
if (value !== undefined && value !== null) {
|
||||||
result[property] = value;
|
result[property] = value;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if (!result.error) {
|
if (!result.error) {
|
||||||
for (let arrayObjectType of Object.keys(wizardSchema[type].objectArrays)) {
|
for (let arrayObjectType of Object.keys(
|
||||||
|
wizardSchema[type].objectArrays
|
||||||
|
)) {
|
||||||
let arraySchema = wizardSchema[type].objectArrays[arrayObjectType];
|
let arraySchema = wizardSchema[type].objectArrays[arrayObjectType];
|
||||||
let objectArray = object.get(arraySchema.property);
|
let objectArray = object.get(arraySchema.property);
|
||||||
|
|
||||||
if (arraySchema.required && !present(objectArray)) {
|
if (arraySchema.required && !present(objectArray)) {
|
||||||
result.error = {
|
result.error = {
|
||||||
type: 'required',
|
type: "required",
|
||||||
params: { type, property: arraySchema.property }
|
params: { type, property: arraySchema.property },
|
||||||
}
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result[arraySchema.property] = [];
|
result[arraySchema.property] = [];
|
||||||
|
|
||||||
for (let item of objectArray) {
|
for (let item of objectArray) {
|
||||||
let itemProps = this.buildJson(item, arrayObjectType);
|
let itemProps = this.buildJson(item, arrayObjectType);
|
||||||
|
|
||||||
if (itemProps.error) {
|
if (itemProps.error) {
|
||||||
result.error = itemProps.error;
|
result.error = itemProps.error;
|
||||||
break;
|
break;
|
||||||
|
@ -93,115 +95,119 @@ const CustomWizard = EmberObject.extend({
|
||||||
result[arraySchema.property].push(itemProps);
|
result[arraySchema.property].push(itemProps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateValue(property, value, object, type, result) {
|
validateValue(property, value, object, type, result) {
|
||||||
if (wizardSchema[type].required.indexOf(property) > -1 && !value) {
|
if (wizardSchema[type].required.indexOf(property) > -1 && !value) {
|
||||||
result.error = {
|
result.error = {
|
||||||
type: 'required',
|
type: "required",
|
||||||
params: { type, property }
|
params: { type, property },
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let dependent = wizardSchema[type].dependent[property];
|
let dependent = wizardSchema[type].dependent[property];
|
||||||
if (dependent && value && !object[dependent]) {
|
if (dependent && value && !object[dependent]) {
|
||||||
result.error = {
|
result.error = {
|
||||||
type: 'dependent',
|
type: "dependent",
|
||||||
params: { property, dependent }
|
params: { property, dependent },
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property === 'api_body') {
|
if (property === "api_body") {
|
||||||
try {
|
try {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
result.error = {
|
result.error = {
|
||||||
type: 'invalid',
|
type: "invalid",
|
||||||
params: { type, property }
|
params: { type, property },
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
buildMappedJson(inputs) {
|
buildMappedJson(inputs) {
|
||||||
if (!inputs || !inputs.length) return false;
|
if (!inputs || !inputs.length) return false;
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
inputs.forEach(inpt => {
|
inputs.forEach((inpt) => {
|
||||||
let input = {
|
let input = {
|
||||||
type: inpt.type,
|
type: inpt.type,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (inpt.connector) {
|
if (inpt.connector) {
|
||||||
input.connector = inpt.connector;
|
input.connector = inpt.connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present(inpt.output)) {
|
if (present(inpt.output)) {
|
||||||
input.output = inpt.output;
|
input.output = inpt.output;
|
||||||
input.output_type = snakeCase(inpt.output_type);
|
input.output_type = snakeCase(inpt.output_type);
|
||||||
input.output_connector = inpt.output_connector;
|
input.output_connector = inpt.output_connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present(inpt.pairs)) {
|
if (present(inpt.pairs)) {
|
||||||
input.pairs = [];
|
input.pairs = [];
|
||||||
|
|
||||||
inpt.pairs.forEach(pr => {
|
inpt.pairs.forEach((pr) => {
|
||||||
if (present(pr.key) && present(pr.value)) {
|
if (present(pr.key) && present(pr.value)) {
|
||||||
|
|
||||||
let pairParams = {
|
let pairParams = {
|
||||||
index: pr.index,
|
index: pr.index,
|
||||||
key: pr.key,
|
key: pr.key,
|
||||||
key_type: snakeCase(pr.key_type),
|
key_type: snakeCase(pr.key_type),
|
||||||
value: pr.value,
|
value: pr.value,
|
||||||
value_type: snakeCase(pr.value_type),
|
value_type: snakeCase(pr.value_type),
|
||||||
connector: pr.connector
|
connector: pr.connector,
|
||||||
}
|
};
|
||||||
|
|
||||||
input.pairs.push(pairParams);
|
input.pairs.push(pairParams);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((input.type === 'assignment' && present(input.output)) ||
|
if (
|
||||||
present(input.pairs)) {
|
(input.type === "assignment" && present(input.output)) ||
|
||||||
|
present(input.pairs)
|
||||||
|
) {
|
||||||
result.push(input);
|
result.push(input);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.length) {
|
if (!result.length) {
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
return ajax(`/admin/wizards/wizard/${this.id}`, {
|
return ajax(`/admin/wizards/wizard/${this.id}`, {
|
||||||
type: 'DELETE'
|
type: "DELETE",
|
||||||
}).then(() => this.destroy()).catch(popupAjaxError);
|
})
|
||||||
}
|
.then(() => this.destroy())
|
||||||
|
.catch(popupAjaxError);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
CustomWizard.reopenClass({
|
CustomWizard.reopenClass({
|
||||||
all() {
|
all() {
|
||||||
return ajax("/admin/wizards/wizard", {
|
return ajax("/admin/wizards/wizard", {
|
||||||
type: 'GET'
|
type: "GET",
|
||||||
}).then(result => {
|
})
|
||||||
return result.wizard_list;
|
.then((result) => {
|
||||||
}).catch(popupAjaxError);
|
return result.wizard_list;
|
||||||
|
})
|
||||||
|
.catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
submissions(wizardId) {
|
submissions(wizardId) {
|
||||||
return ajax(`/admin/wizards/submissions/${wizardId}`, {
|
return ajax(`/admin/wizards/submissions/${wizardId}`, {
|
||||||
type: "GET"
|
type: "GET",
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -209,7 +215,7 @@ CustomWizard.reopenClass({
|
||||||
const wizard = this._super.apply(this);
|
const wizard = this._super.apply(this);
|
||||||
wizard.setProperties(buildProperties(wizardJson));
|
wizard.setProperties(buildProperties(wizardJson));
|
||||||
return wizard;
|
return wizard;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CustomWizard;
|
export default CustomWizard;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import CustomWizardApi from '../models/custom-wizard-api';
|
import CustomWizardApi from "../models/custom-wizard-api";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
if (params.name === 'create') {
|
if (params.name === "create") {
|
||||||
return CustomWizardApi.create({ isNew: true });
|
return CustomWizardApi.create({ isNew: true });
|
||||||
} else {
|
} else {
|
||||||
return CustomWizardApi.find(params.name);
|
return CustomWizardApi.find(params.name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model){
|
setupController(controller, model) {
|
||||||
controller.set("api", model);
|
controller.set("api", model);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,45 +1,44 @@
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import CustomWizardApi from '../models/custom-wizard-api';
|
import CustomWizardApi from "../models/custom-wizard-api";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
model() {
|
model() {
|
||||||
return CustomWizardApi.list();
|
return CustomWizardApi.list();
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const showParams = this.paramsFor('adminWizardsApiShow');
|
const showParams = this.paramsFor("adminWizardsApiShow");
|
||||||
const apiName = showParams.name == 'create' ? null : showParams.name;
|
const apiName = showParams.name == "create" ? null : showParams.name;
|
||||||
const apiList = (model || []).map(api => {
|
const apiList = (model || []).map((api) => {
|
||||||
return {
|
return {
|
||||||
id: api.name,
|
id: api.name,
|
||||||
name: api.title
|
name: api.title,
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
apiName,
|
apiName,
|
||||||
apiList
|
apiList,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
changeApi(apiName) {
|
changeApi(apiName) {
|
||||||
this.controllerFor('adminWizardsApi').set('apiName', apiName);
|
this.controllerFor("adminWizardsApi").set("apiName", apiName);
|
||||||
this.transitionTo('adminWizardsApiShow', apiName);
|
this.transitionTo("adminWizardsApiShow", apiName);
|
||||||
},
|
},
|
||||||
|
|
||||||
afterDestroy() {
|
afterDestroy() {
|
||||||
this.transitionTo('adminWizardsApi').then(() => this.refresh());
|
this.transitionTo("adminWizardsApi").then(() => this.refresh());
|
||||||
},
|
},
|
||||||
|
|
||||||
afterSave(apiName) {
|
afterSave(apiName) {
|
||||||
this.refresh().then(() => this.send('changeApi', apiName));
|
this.refresh().then(() => this.send("changeApi", apiName));
|
||||||
},
|
},
|
||||||
|
|
||||||
createApi() {
|
createApi() {
|
||||||
this.controllerFor('adminWizardsApi').set('apiName', 'create');
|
this.controllerFor("adminWizardsApi").set("apiName", "create");
|
||||||
this.transitionTo('adminWizardsApiShow', 'create');
|
this.transitionTo("adminWizardsApiShow", "create");
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
});
|
||||||
});
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ export default DiscourseRoute.extend({
|
||||||
model() {
|
model() {
|
||||||
return CustomWizardCustomField.listFields();
|
return CustomWizardCustomField.listFields();
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const customFields = A(model || []);
|
const customFields = A(model || []);
|
||||||
controller.set('customFields', customFields);
|
controller.set("customFields", customFields);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import CustomWizardLogs from '../models/custom-wizard-logs';
|
import CustomWizardLogs from "../models/custom-wizard-logs";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
|
@ -7,6 +7,6 @@ export default DiscourseRoute.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
controller.set('logs', model);
|
controller.set("logs", model);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import CustomWizard from '../models/custom-wizard';
|
import CustomWizard from "../models/custom-wizard";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
model() {
|
model() {
|
||||||
return CustomWizard.all();
|
return CustomWizard.all();
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
controller.set('wizards', model)
|
controller.set("wizards", model);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import CustomWizard from '../models/custom-wizard';
|
import CustomWizard from "../models/custom-wizard";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
|
@ -25,12 +25,12 @@ export default DiscourseRoute.extend({
|
||||||
});
|
});
|
||||||
submissions.push(submission);
|
submissions.push(submission);
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
wizard: model.wizard,
|
wizard: model.wizard,
|
||||||
submissions,
|
submissions,
|
||||||
fields
|
fields,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
model() {
|
model() {
|
||||||
return ajax(`/admin/wizards/wizard`);
|
return ajax(`/admin/wizards/wizard`);
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const showParams = this.paramsFor('adminWizardsSubmissionsShow');
|
const showParams = this.paramsFor("adminWizardsSubmissionsShow");
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
wizardId: showParams.wizardId,
|
wizardId: showParams.wizardId,
|
||||||
wizardList: model.wizard_list
|
wizardList: model.wizard_list,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
changeWizard(wizardId) {
|
changeWizard(wizardId) {
|
||||||
this.controllerFor('adminWizardsSubmissions').set('wizardId', wizardId);
|
this.controllerFor("adminWizardsSubmissions").set("wizardId", wizardId);
|
||||||
this.transitionTo('adminWizardsSubmissionsShow', wizardId);
|
this.transitionTo("adminWizardsSubmissionsShow", wizardId);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,47 +1,49 @@
|
||||||
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 DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { selectKitContent } from '../lib/wizard';
|
import { selectKitContent } from "../lib/wizard";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
if (params.wizardId === 'create') {
|
if (params.wizardId === "create") {
|
||||||
return { create: true };
|
return { create: true };
|
||||||
} else {
|
} else {
|
||||||
return ajax(`/admin/wizards/wizard/${params.wizardId}`);
|
return ajax(`/admin/wizards/wizard/${params.wizardId}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
if (model.none) {
|
if (model.none) {
|
||||||
return this.transitionTo('adminWizardsWizard');
|
return this.transitionTo("adminWizardsWizard");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const parentModel = this.modelFor('adminWizardsWizard');
|
const parentModel = this.modelFor("adminWizardsWizard");
|
||||||
const wizard = CustomWizard.create((!model || model.create) ? {} : model);
|
const wizard = CustomWizard.create(!model || model.create ? {} : model);
|
||||||
const fieldTypes = Object.keys(parentModel.field_types).map(type => {
|
const fieldTypes = Object.keys(parentModel.field_types).map((type) => {
|
||||||
return {
|
return {
|
||||||
id: type,
|
id: type,
|
||||||
name: I18n.t(`admin.wizard.field.type.${type}`)
|
name: I18n.t(`admin.wizard.field.type.${type}`),
|
||||||
};
|
};
|
||||||
})
|
});
|
||||||
|
|
||||||
let props = {
|
let props = {
|
||||||
wizardList: parentModel.wizard_list,
|
wizardList: parentModel.wizard_list,
|
||||||
fieldTypes,
|
fieldTypes,
|
||||||
userFields: parentModel.userFields,
|
userFields: parentModel.userFields,
|
||||||
customFields: selectKitContent(parentModel.custom_fields.map(f => f.name)),
|
customFields: selectKitContent(
|
||||||
|
parentModel.custom_fields.map((f) => f.name)
|
||||||
|
),
|
||||||
apis: parentModel.apis,
|
apis: parentModel.apis,
|
||||||
themes: parentModel.themes,
|
themes: parentModel.themes,
|
||||||
wizard,
|
wizard,
|
||||||
currentStep: wizard.steps[0],
|
currentStep: wizard.steps[0],
|
||||||
currentAction: wizard.actions[0],
|
currentAction: wizard.actions[0],
|
||||||
creating: model.create
|
creating: model.create,
|
||||||
};
|
};
|
||||||
|
|
||||||
controller.setProperties(props);
|
controller.setProperties(props);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { buildFieldTypes, buildFieldValidations } from '../lib/wizard-schema';
|
import { buildFieldTypes, buildFieldValidations } from "../lib/wizard-schema";
|
||||||
import EmberObject, { set } from "@ember/object";
|
import EmberObject, { set } from "@ember/object";
|
||||||
import { A } from "@ember/array";
|
import { A } from "@ember/array";
|
||||||
import { all } from "rsvp";
|
import { all } from "rsvp";
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
model() {
|
model() {
|
||||||
return ajax("/admin/wizards/wizard");
|
return ajax("/admin/wizards/wizard");
|
||||||
},
|
},
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
buildFieldTypes(model.field_types);
|
buildFieldTypes(model.field_types);
|
||||||
buildFieldValidations(model.realtime_validations);
|
buildFieldValidations(model.realtime_validations);
|
||||||
|
@ -17,80 +17,86 @@ export default DiscourseRoute.extend({
|
||||||
return all([
|
return all([
|
||||||
this._getThemes(model),
|
this._getThemes(model),
|
||||||
this._getApis(model),
|
this._getApis(model),
|
||||||
this._getUserFields(model)
|
this._getUserFields(model),
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getThemes(model) {
|
_getThemes(model) {
|
||||||
return ajax('/admin/themes')
|
return ajax("/admin/themes").then((result) => {
|
||||||
.then((result) => {
|
set(
|
||||||
set(model, 'themes', result.themes.map(t => {
|
model,
|
||||||
|
"themes",
|
||||||
|
result.themes.map((t) => {
|
||||||
return {
|
return {
|
||||||
id: t.id,
|
id: t.id,
|
||||||
name: t.name
|
name: t.name,
|
||||||
}
|
};
|
||||||
}));
|
})
|
||||||
});
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_getApis(model) {
|
_getApis(model) {
|
||||||
return ajax('/admin/wizards/api')
|
return ajax("/admin/wizards/api").then((result) =>
|
||||||
.then((result) => set(model, 'apis', result));
|
set(model, "apis", result)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getUserFields(model) {
|
_getUserFields(model) {
|
||||||
return this.store.findAll('user-field').then((result) => {
|
return this.store.findAll("user-field").then((result) => {
|
||||||
if (result && result.content) {
|
if (result && result.content) {
|
||||||
set(model, 'userFields',
|
set(
|
||||||
|
model,
|
||||||
|
"userFields",
|
||||||
result.content.map((f) => ({
|
result.content.map((f) => ({
|
||||||
id: `user_field_${f.id}`,
|
id: `user_field_${f.id}`,
|
||||||
name: f.name
|
name: f.name,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
currentWizard() {
|
currentWizard() {
|
||||||
const params = this.paramsFor('adminWizardsWizardShow');
|
const params = this.paramsFor("adminWizardsWizardShow");
|
||||||
|
|
||||||
if (params && params.wizardId) {
|
if (params && params.wizardId) {
|
||||||
return params.wizardId;
|
return params.wizardId;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
wizardList: model.wizard_list,
|
wizardList: model.wizard_list,
|
||||||
wizardId: this.currentWizard(),
|
wizardId: this.currentWizard(),
|
||||||
custom_fields: A(model.custom_fields.map(f => EmberObject.create(f)))
|
custom_fields: A(model.custom_fields.map((f) => EmberObject.create(f))),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
changeWizard(wizardId) {
|
changeWizard(wizardId) {
|
||||||
this.controllerFor('adminWizardsWizard').set('wizardId', wizardId);
|
this.controllerFor("adminWizardsWizard").set("wizardId", wizardId);
|
||||||
|
|
||||||
if (wizardId) {
|
if (wizardId) {
|
||||||
this.transitionTo('adminWizardsWizardShow', wizardId);
|
this.transitionTo("adminWizardsWizardShow", wizardId);
|
||||||
} else {
|
} else {
|
||||||
this.transitionTo('adminWizardsWizard');
|
this.transitionTo("adminWizardsWizard");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
afterDestroy() {
|
afterDestroy() {
|
||||||
this.transitionTo('adminWizardsWizard').then(() => this.refresh());
|
this.transitionTo("adminWizardsWizard").then(() => this.refresh());
|
||||||
},
|
},
|
||||||
|
|
||||||
afterSave(wizardId) {
|
afterSave(wizardId) {
|
||||||
this.refresh().then(() => this.send('changeWizard', wizardId));
|
this.refresh().then(() => this.send("changeWizard", wizardId));
|
||||||
},
|
},
|
||||||
|
|
||||||
createWizard() {
|
createWizard() {
|
||||||
this.controllerFor('adminWizardsWizard').set('wizardId', 'create');
|
this.controllerFor("adminWizardsWizard").set("wizardId", "create");
|
||||||
this.transitionTo('adminWizardsWizardShow', 'create');
|
this.transitionTo("adminWizardsWizardShow", "create");
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import DiscourseRoute from "discourse/routes/discourse";
|
||||||
export default DiscourseRoute.extend({
|
export default DiscourseRoute.extend({
|
||||||
beforeModel(transition) {
|
beforeModel(transition) {
|
||||||
if (transition.targetName === "adminWizards.index") {
|
if (transition.targetName === "adminWizards.index") {
|
||||||
this.transitionTo('adminWizardsWizard');
|
this.transitionTo("adminWizardsWizard");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { default as computed, observes } from 'discourse-common/utils/decorators';
|
import {
|
||||||
import { renderAvatar } from 'discourse/helpers/user-avatar';
|
default as computed,
|
||||||
import userSearch from '../lib/user-search';
|
observes,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
|
import { renderAvatar } from "discourse/helpers/user-avatar";
|
||||||
|
import userSearch from "../lib/user-search";
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
|
||||||
const template = function(params) {
|
const template = function (params) {
|
||||||
const options = params.options;
|
const options = params.options;
|
||||||
let html = "<div class='autocomplete'>";
|
let html = "<div class='autocomplete'>";
|
||||||
|
|
||||||
|
@ -11,7 +14,7 @@ const template = function(params) {
|
||||||
html += "<ul>";
|
html += "<ul>";
|
||||||
options.users.forEach((u) => {
|
options.users.forEach((u) => {
|
||||||
html += `<li><a href title="${u.name}">`;
|
html += `<li><a href title="${u.name}">`;
|
||||||
html += renderAvatar(u, { imageSize: 'tiny' });
|
html += renderAvatar(u, { imageSize: "tiny" });
|
||||||
html += `<span class='username'>${u.username}</span>`;
|
html += `<span class='username'>${u.username}</span>`;
|
||||||
if (u.name) {
|
if (u.name) {
|
||||||
html += `<span class='name'>${u.name}</span>`;
|
html += `<span class='name'>${u.name}</span>`;
|
||||||
|
@ -19,7 +22,7 @@ const template = function(params) {
|
||||||
html += `</a></li>`;
|
html += `</a></li>`;
|
||||||
});
|
});
|
||||||
html += "</ul>";
|
html += "</ul>";
|
||||||
};
|
}
|
||||||
|
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
|
|
||||||
|
@ -27,10 +30,10 @@ const template = function(params) {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Ember.TextField.extend({
|
export default Ember.TextField.extend({
|
||||||
attributeBindings: ['autofocus', 'maxLength'],
|
attributeBindings: ["autofocus", "maxLength"],
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
autocapitalize: false,
|
autocapitalize: false,
|
||||||
name: 'user-selector',
|
name: "user-selector",
|
||||||
id: "custom-member-selector",
|
id: "custom-member-selector",
|
||||||
|
|
||||||
@computed("placeholderKey")
|
@computed("placeholderKey")
|
||||||
|
@ -38,101 +41,107 @@ export default Ember.TextField.extend({
|
||||||
return placeholderKey ? WizardI18n(placeholderKey) : "";
|
return placeholderKey ? WizardI18n(placeholderKey) : "";
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('usernames')
|
@observes("usernames")
|
||||||
_update() {
|
_update() {
|
||||||
if (this.get('canReceiveUpdates') === 'true')
|
if (this.get("canReceiveUpdates") === "true")
|
||||||
this.didInsertElement({updateData: true});
|
this.didInsertElement({ updateData: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement(opts) {
|
didInsertElement(opts) {
|
||||||
this._super();
|
this._super();
|
||||||
var self = this,
|
var self = this,
|
||||||
selected = [],
|
selected = [],
|
||||||
groups = [],
|
groups = [],
|
||||||
currentUser = this.currentUser,
|
currentUser = this.currentUser,
|
||||||
includeMentionableGroups = this.get('includeMentionableGroups') === 'true',
|
includeMentionableGroups =
|
||||||
includeMessageableGroups = this.get('includeMessageableGroups') === 'true',
|
this.get("includeMentionableGroups") === "true",
|
||||||
includeGroups = this.get('includeGroups') === 'true',
|
includeMessageableGroups =
|
||||||
allowedUsers = this.get('allowedUsers') === 'true';
|
this.get("includeMessageableGroups") === "true",
|
||||||
|
includeGroups = this.get("includeGroups") === "true",
|
||||||
|
allowedUsers = this.get("allowedUsers") === "true";
|
||||||
|
|
||||||
function excludedUsernames() {
|
function excludedUsernames() {
|
||||||
// hack works around some issues with allowAny eventing
|
// hack works around some issues with allowAny eventing
|
||||||
const usernames = self.get('single') ? [] : selected;
|
const usernames = self.get("single") ? [] : selected;
|
||||||
|
|
||||||
if (currentUser && self.get('excludeCurrentUser')) {
|
if (currentUser && self.get("excludeCurrentUser")) {
|
||||||
return usernames.concat([currentUser.get('username')]);
|
return usernames.concat([currentUser.get("username")]);
|
||||||
}
|
}
|
||||||
return usernames;
|
return usernames;
|
||||||
}
|
}
|
||||||
|
|
||||||
$(this.element).val(this.get('usernames')).autocomplete({
|
$(this.element)
|
||||||
template,
|
.val(this.get("usernames"))
|
||||||
disabled: this.get('disabled'),
|
.autocomplete({
|
||||||
single: this.get('single'),
|
template,
|
||||||
allowAny: this.get('allowAny'),
|
disabled: this.get("disabled"),
|
||||||
updateData: (opts && opts.updateData) ? opts.updateData : false,
|
single: this.get("single"),
|
||||||
|
allowAny: this.get("allowAny"),
|
||||||
|
updateData: opts && opts.updateData ? opts.updateData : false,
|
||||||
|
|
||||||
dataSource(term) {
|
dataSource(term) {
|
||||||
const termRegex = /[^a-zA-Z0-9_\-\.@\+]/;
|
const termRegex = /[^a-zA-Z0-9_\-\.@\+]/;
|
||||||
|
|
||||||
var results = userSearch({
|
var results = userSearch({
|
||||||
term: term.replace(termRegex, ''),
|
term: term.replace(termRegex, ""),
|
||||||
topicId: self.get('topicId'),
|
topicId: self.get("topicId"),
|
||||||
exclude: excludedUsernames(),
|
exclude: excludedUsernames(),
|
||||||
includeGroups,
|
includeGroups,
|
||||||
allowedUsers,
|
allowedUsers,
|
||||||
includeMentionableGroups,
|
includeMentionableGroups,
|
||||||
includeMessageableGroups
|
includeMessageableGroups,
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
},
|
|
||||||
|
|
||||||
transformComplete(v) {
|
|
||||||
if (v.username || v.name) {
|
|
||||||
if (!v.username) { groups.push(v.name); }
|
|
||||||
return v.username || v.name;
|
|
||||||
} else {
|
|
||||||
var excludes = excludedUsernames();
|
|
||||||
return v.usernames.filter(function(item){
|
|
||||||
return excludes.indexOf(item) === -1;
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onChangeItems(items) {
|
return results;
|
||||||
var hasGroups = false;
|
},
|
||||||
items = items.map(function(i) {
|
|
||||||
if (groups.indexOf(i) > -1) { hasGroups = true; }
|
|
||||||
return i.username ? i.username : i;
|
|
||||||
});
|
|
||||||
self.set('usernames', items.join(","));
|
|
||||||
self.set('hasGroups', hasGroups);
|
|
||||||
|
|
||||||
selected = items;
|
transformComplete(v) {
|
||||||
if (self.get('onChangeCallback')) self.sendAction('onChangeCallback');
|
if (v.username || v.name) {
|
||||||
},
|
if (!v.username) {
|
||||||
|
groups.push(v.name);
|
||||||
|
}
|
||||||
|
return v.username || v.name;
|
||||||
|
} else {
|
||||||
|
var excludes = excludedUsernames();
|
||||||
|
return v.usernames.filter(function (item) {
|
||||||
|
return excludes.indexOf(item) === -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
reverseTransform(i) {
|
onChangeItems(items) {
|
||||||
return { username: i };
|
var hasGroups = false;
|
||||||
}
|
items = items.map(function (i) {
|
||||||
|
if (groups.indexOf(i) > -1) {
|
||||||
|
hasGroups = true;
|
||||||
|
}
|
||||||
|
return i.username ? i.username : i;
|
||||||
|
});
|
||||||
|
self.set("usernames", items.join(","));
|
||||||
|
self.set("hasGroups", hasGroups);
|
||||||
|
|
||||||
});
|
selected = items;
|
||||||
|
if (self.get("onChangeCallback")) self.sendAction("onChangeCallback");
|
||||||
|
},
|
||||||
|
|
||||||
|
reverseTransform(i) {
|
||||||
|
return { username: i };
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this._super();
|
this._super();
|
||||||
$(this.element).autocomplete('destroy');
|
$(this.element).autocomplete("destroy");
|
||||||
},
|
},
|
||||||
|
|
||||||
// THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT
|
// THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT
|
||||||
@observes('usernames')
|
@observes("usernames")
|
||||||
_clearInput: function() {
|
_clearInput: function () {
|
||||||
if (arguments.length > 1) {
|
if (arguments.length > 1) {
|
||||||
if (Em.isEmpty(this.get("usernames"))) {
|
if (Em.isEmpty(this.get("usernames"))) {
|
||||||
$(this.element).parent().find("a").click();
|
$(this.element).parent().find("a").click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,44 +10,48 @@ import { categoryBadgeHTML } from "discourse/helpers/category-link";
|
||||||
import { dasherize } from "@ember/string";
|
import { dasherize } from "@ember/string";
|
||||||
|
|
||||||
export default WizardFieldValidator.extend({
|
export default WizardFieldValidator.extend({
|
||||||
classNames: ['similar-topics-validator'],
|
classNames: ["similar-topics-validator"],
|
||||||
similarTopics: null,
|
similarTopics: null,
|
||||||
hasInput: notEmpty('field.value'),
|
hasInput: notEmpty("field.value"),
|
||||||
hasSimilarTopics: notEmpty('similarTopics'),
|
hasSimilarTopics: notEmpty("similarTopics"),
|
||||||
hasNotSearched: equal('similarTopics', null),
|
hasNotSearched: equal("similarTopics", null),
|
||||||
noSimilarTopics: computed('similarTopics', function() {
|
noSimilarTopics: computed("similarTopics", function () {
|
||||||
return this.similarTopics !== null && this.similarTopics.length == 0;
|
return this.similarTopics !== null && this.similarTopics.length == 0;
|
||||||
}),
|
}),
|
||||||
showSimilarTopics: computed('typing', 'hasSimilarTopics', function() {
|
showSimilarTopics: computed("typing", "hasSimilarTopics", function () {
|
||||||
return this.hasSimilarTopics && !this.typing;
|
return this.hasSimilarTopics && !this.typing;
|
||||||
}),
|
}),
|
||||||
showNoSimilarTopics: computed('typing', 'noSimilarTopics', function() {
|
showNoSimilarTopics: computed("typing", "noSimilarTopics", function () {
|
||||||
return this.noSimilarTopics && !this.typing;
|
return this.noSimilarTopics && !this.typing;
|
||||||
}),
|
}),
|
||||||
hasValidationCategories: notEmpty('validationCategories'),
|
hasValidationCategories: notEmpty("validationCategories"),
|
||||||
insufficientCharacters: computed('typing', 'field.value', function() {
|
insufficientCharacters: computed("typing", "field.value", function () {
|
||||||
return this.hasInput && this.field.value.length < 5 && !this.typing;
|
return this.hasInput && this.field.value.length < 5 && !this.typing;
|
||||||
}),
|
}),
|
||||||
insufficientCharactersCategories: and('insufficientCharacters', 'hasValidationCategories'),
|
insufficientCharactersCategories: and(
|
||||||
|
"insufficientCharacters",
|
||||||
@discourseComputed('validation.categories')
|
"hasValidationCategories"
|
||||||
|
),
|
||||||
|
|
||||||
|
@discourseComputed("validation.categories")
|
||||||
validationCategories(categoryIds) {
|
validationCategories(categoryIds) {
|
||||||
if (categoryIds) return categoryIds.map(id => this.site.categoriesById[id]);
|
if (categoryIds)
|
||||||
|
return categoryIds.map((id) => this.site.categoriesById[id]);
|
||||||
|
|
||||||
return A();
|
return A();
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('validationCategories')
|
@discourseComputed("validationCategories")
|
||||||
catLinks(categories) {
|
catLinks(categories) {
|
||||||
return categories.map(category => categoryBadgeHTML(category)).join("");
|
return categories.map((category) => categoryBadgeHTML(category)).join("");
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
'loading',
|
"loading",
|
||||||
'showSimilarTopics',
|
"showSimilarTopics",
|
||||||
'showNoSimilarTopics',
|
"showNoSimilarTopics",
|
||||||
'insufficientCharacters',
|
"insufficientCharacters",
|
||||||
'insufficientCharactersCategories'
|
"insufficientCharactersCategories"
|
||||||
)
|
)
|
||||||
currentState(
|
currentState(
|
||||||
loading,
|
loading,
|
||||||
|
@ -58,30 +62,31 @@ export default WizardFieldValidator.extend({
|
||||||
) {
|
) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case loading:
|
case loading:
|
||||||
return 'loading';
|
return "loading";
|
||||||
case showSimilarTopics:
|
case showSimilarTopics:
|
||||||
return 'results';
|
return "results";
|
||||||
case showNoSimilarTopics:
|
case showNoSimilarTopics:
|
||||||
return 'no_results';
|
return "no_results";
|
||||||
case insufficientCharactersCategories:
|
case insufficientCharactersCategories:
|
||||||
return 'insufficient_characters_categories';
|
return "insufficient_characters_categories";
|
||||||
case insufficientCharacters:
|
case insufficientCharacters:
|
||||||
return 'insufficient_characters';
|
return "insufficient_characters";
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('currentState')
|
@discourseComputed("currentState")
|
||||||
currentStateClass (currentState) {
|
currentStateClass(currentState) {
|
||||||
if (currentState) return `similar-topics-${dasherize(currentState)}`;
|
if (currentState) return `similar-topics-${dasherize(currentState)}`;
|
||||||
|
|
||||||
return "similar-topics";
|
return "similar-topics";
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('currentState')
|
@discourseComputed("currentState")
|
||||||
currentStateKey (currentState) {
|
currentStateKey(currentState) {
|
||||||
if (currentState) return `realtime_validations.similar_topics.${currentState}`;
|
if (currentState)
|
||||||
|
return `realtime_validations.similar_topics.${currentState}`;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
@ -91,15 +96,15 @@ export default WizardFieldValidator.extend({
|
||||||
@observes("field.value")
|
@observes("field.value")
|
||||||
customValidate() {
|
customValidate() {
|
||||||
const field = this.field;
|
const field = this.field;
|
||||||
|
|
||||||
if (!field.value) {
|
if (!field.value) {
|
||||||
this.set('similarTopics', null);
|
this.set("similarTopics", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const value = field.value;
|
const value = field.value;
|
||||||
|
|
||||||
this.set("typing", true);
|
this.set("typing", true);
|
||||||
|
|
||||||
const lastKeyUp = new Date();
|
const lastKeyUp = new Date();
|
||||||
this._lastKeyUp = lastKeyUp;
|
this._lastKeyUp = lastKeyUp;
|
||||||
|
|
||||||
|
@ -113,7 +118,7 @@ export default WizardFieldValidator.extend({
|
||||||
this.set("typing", false);
|
this.set("typing", false);
|
||||||
|
|
||||||
if (value && value.length < 5) {
|
if (value && value.length < 5) {
|
||||||
this.set('similarTopics', null);
|
this.set("similarTopics", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,23 +127,25 @@ export default WizardFieldValidator.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateSimilarTopics() {
|
updateSimilarTopics() {
|
||||||
this.set('updating', true);
|
this.set("updating", true);
|
||||||
|
|
||||||
this.backendValidate({
|
this.backendValidate({
|
||||||
title: this.get("field.value"),
|
title: this.get("field.value"),
|
||||||
categories: this.get("validation.categories"),
|
categories: this.get("validation.categories"),
|
||||||
time_unit: this.get("validation.time_unit"),
|
time_unit: this.get("validation.time_unit"),
|
||||||
time_n_value: this.get("validation.time_n_value")
|
time_n_value: this.get("validation.time_n_value"),
|
||||||
}).then((result) => {
|
})
|
||||||
const similarTopics = A(
|
.then((result) => {
|
||||||
deepMerge(result["topics"], result["similar_topics"])
|
const similarTopics = A(
|
||||||
);
|
deepMerge(result["topics"], result["similar_topics"])
|
||||||
similarTopics.forEach(function (topic, index) {
|
);
|
||||||
similarTopics[index] = EmberObject.create(topic);
|
similarTopics.forEach(function (topic, index) {
|
||||||
});
|
similarTopics[index] = EmberObject.create(topic);
|
||||||
|
});
|
||||||
|
|
||||||
this.set("similarTopics", similarTopics);
|
this.set("similarTopics", similarTopics);
|
||||||
}).finally(() => this.set('updating', false));
|
})
|
||||||
|
.finally(() => this.set("updating", false));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -4,14 +4,14 @@ import { ajax } from "discourse/lib/ajax";
|
||||||
import { getToken } from "wizard/lib/ajax";
|
import { getToken } from "wizard/lib/ajax";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ['validator'],
|
classNames: ["validator"],
|
||||||
classNameBindings: ["isValid", "isInvalid"],
|
classNameBindings: ["isValid", "isInvalid"],
|
||||||
validMessageKey: null,
|
validMessageKey: null,
|
||||||
invalidMessageKey: null,
|
invalidMessageKey: null,
|
||||||
isValid: null,
|
isValid: null,
|
||||||
isInvalid: equal("isValid", false),
|
isInvalid: equal("isValid", false),
|
||||||
layoutName: "components/validator", // useful for sharing the template with extending components
|
layoutName: "components/validator", // useful for sharing the template with extending components
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import CategorySelector from 'select-kit/components/category-selector';
|
import CategorySelector from "select-kit/components/category-selector";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import { makeArray } from "discourse-common/lib/helpers";
|
import { makeArray } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
export default CategorySelector.extend({
|
export default CategorySelector.extend({
|
||||||
content: computed("categories.[]", "blacklist.[]", "whitelist.[]", function() {
|
content: computed(
|
||||||
return this._super().filter(category => {
|
"categories.[]",
|
||||||
const whitelist = makeArray(this.whitelist);
|
"blacklist.[]",
|
||||||
return !whitelist.length || whitelist.indexOf(category.id) > -1;
|
"whitelist.[]",
|
||||||
});
|
function () {
|
||||||
})
|
return this._super().filter((category) => {
|
||||||
})
|
const whitelist = makeArray(this.whitelist);
|
||||||
|
return !whitelist.length || whitelist.indexOf(category.id) > -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
|
@ -20,7 +20,7 @@ import {
|
||||||
import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
|
import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
|
||||||
import { alias } from "@ember/object/computed";
|
import { alias } from "@ember/object/computed";
|
||||||
import { uploadIcon } from "discourse/lib/uploads";
|
import { uploadIcon } from "discourse/lib/uploads";
|
||||||
import WizardI18n from '../lib/wizard-i18n';
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
|
||||||
const uploadMarkdownResolvers = [];
|
const uploadMarkdownResolvers = [];
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ['wizard-composer-hyperlink'],
|
classNames: ["wizard-composer-hyperlink"],
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addLink() {
|
addLink() {
|
||||||
this.addLink(this.linkName, this.linkUrl);
|
this.addLink(this.linkName, this.linkUrl);
|
||||||
},
|
},
|
||||||
|
|
||||||
hideBox() {
|
hideBox() {
|
||||||
this.hideBox();
|
this.hideBox();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
import DateInput from "discourse/components/date-input";
|
import DateInput from "discourse/components/date-input";
|
||||||
|
|
||||||
export default DateInput.extend();
|
export default DateInput.extend();
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import DateTimeInput from "discourse/components/date-time-input";
|
import DateTimeInput from "discourse/components/date-time-input";
|
||||||
import discourseComputed from 'discourse-common/utils/decorators';
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default DateTimeInput.extend({
|
export default DateTimeInput.extend({
|
||||||
@discourseComputed('timeFirst', 'tabindex')
|
@discourseComputed("timeFirst", "tabindex")
|
||||||
timeTabindex(timeFirst, tabindex) {
|
timeTabindex(timeFirst, tabindex) {
|
||||||
return timeFirst ? tabindex : tabindex + 1;
|
return timeFirst ? tabindex : tabindex + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('timeFirst', 'tabindex')
|
@discourseComputed("timeFirst", "tabindex")
|
||||||
dateTabindex(timeFirst, tabindex) {
|
dateTabindex(timeFirst, tabindex) {
|
||||||
return timeFirst ? tabindex + 1 : tabindex;
|
return timeFirst ? tabindex + 1 : tabindex;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,32 +1,39 @@
|
||||||
import { observes } from 'discourse-common/utils/decorators';
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
import Category from 'discourse/models/category';
|
import Category from "discourse/models/category";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
const property = this.field.property || 'id';
|
const property = this.field.property || "id";
|
||||||
const value = this.field.value;
|
const value = this.field.value;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.set('categories', [...value].reduce((result, v) => {
|
this.set(
|
||||||
let val = property === 'id' ? Category.findById(v) : Category.findBySlug(v);
|
"categories",
|
||||||
if (val) result.push(val);
|
[...value].reduce((result, v) => {
|
||||||
return result;
|
let val =
|
||||||
}, []));
|
property === "id" ? Category.findById(v) : Category.findBySlug(v);
|
||||||
|
if (val) result.push(val);
|
||||||
|
return result;
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('categories')
|
@observes("categories")
|
||||||
setValue() {
|
setValue() {
|
||||||
const categories = (this.categories || []).filter(c => !!c);
|
const categories = (this.categories || []).filter((c) => !!c);
|
||||||
const property = this.field.property || 'id';
|
const property = this.field.property || "id";
|
||||||
|
|
||||||
if (categories.length) {
|
if (categories.length) {
|
||||||
this.set('field.value', categories.reduce((result, c) => {
|
this.set(
|
||||||
if (c && c[property]) {
|
"field.value",
|
||||||
result.push(c[property])
|
categories.reduce((result, c) => {
|
||||||
}
|
if (c && c[property]) {
|
||||||
return result;
|
result.push(c[property]);
|
||||||
}, []));
|
}
|
||||||
|
return result;
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,41 +1,47 @@
|
||||||
import { default as computed, observes } from 'discourse-common/utils/decorators';
|
import {
|
||||||
|
default as computed,
|
||||||
|
observes,
|
||||||
|
} from "discourse-common/utils/decorators";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
showPreview: false,
|
showPreview: false,
|
||||||
classNameBindings: [":wizard-field-composer", "showPreview:show-preview:hide-preview"],
|
classNameBindings: [
|
||||||
|
":wizard-field-composer",
|
||||||
|
"showPreview:show-preview:hide-preview",
|
||||||
|
],
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this.set('composer', EmberObject.create({
|
this.set(
|
||||||
loading: false,
|
"composer",
|
||||||
reply: this.get('field.value')
|
EmberObject.create({
|
||||||
}))
|
loading: false,
|
||||||
|
reply: this.get("field.value"),
|
||||||
|
})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('composer.reply')
|
@observes("composer.reply")
|
||||||
setField() {
|
setField() {
|
||||||
this.set('field.value', this.get('composer.reply'));
|
this.set("field.value", this.get("composer.reply"));
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('showPreview')
|
@computed("showPreview")
|
||||||
togglePreviewLabel(showPreview) {
|
togglePreviewLabel(showPreview) {
|
||||||
return showPreview ? 'wizard_composer.hide_preview' : 'wizard_composer.show_preview';
|
return showPreview
|
||||||
|
? "wizard_composer.hide_preview"
|
||||||
|
: "wizard_composer.show_preview";
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
togglePreview() {
|
togglePreview() {
|
||||||
this.toggleProperty('showPreview');
|
this.toggleProperty("showPreview");
|
||||||
},
|
},
|
||||||
|
|
||||||
groupsMentioned() {
|
groupsMentioned() {},
|
||||||
},
|
afterRefresh() {},
|
||||||
afterRefresh() {
|
cannotSeeMention() {},
|
||||||
},
|
importQuote() {},
|
||||||
cannotSeeMention() {
|
showUploadSelector() {},
|
||||||
},
|
},
|
||||||
importQuote() {
|
|
||||||
},
|
|
||||||
showUploadSelector() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { observes } from 'discourse-common/utils/decorators';
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
@observes('dateTime')
|
@observes("dateTime")
|
||||||
setValue() {
|
setValue() {
|
||||||
this.set('field.value', this.dateTime.format(this.field.format));
|
this.set("field.value", this.dateTime.format(this.field.format));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onChange(value) {
|
onChange(value) {
|
||||||
this.set('dateTime', moment(value));
|
this.set("dateTime", moment(value));
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { observes } from 'discourse-common/utils/decorators';
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
@observes('date')
|
@observes("date")
|
||||||
setValue() {
|
setValue() {
|
||||||
this.set('field.value', this.date.format(this.field.format));
|
this.set("field.value", this.date.format(this.field.format));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onChange(value) {
|
onChange(value) {
|
||||||
this.set('date', moment(value));
|
this.set("date", moment(value));
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { observes } from 'discourse-common/utils/decorators';
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
@observes('time')
|
@observes("time")
|
||||||
setValue() {
|
setValue() {
|
||||||
this.set('field.value', this.time.format(this.field.format));
|
this.set("field.value", this.time.format(this.field.format));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onChange(value) {
|
onChange(value) {
|
||||||
this.set('time',
|
this.set(
|
||||||
|
"time",
|
||||||
moment({
|
moment({
|
||||||
hours: value.hours,
|
hours: value.hours,
|
||||||
minutes: value.minutes
|
minutes: value.minutes,
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,10 +20,10 @@ export default Ember.Component.extend({
|
||||||
formData: {
|
formData: {
|
||||||
synchronous: true,
|
synchronous: true,
|
||||||
type: `wizard_${id}`,
|
type: `wizard_${id}`,
|
||||||
authenticity_token: getToken()
|
authenticity_token: getToken(),
|
||||||
},
|
},
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
dropZone: $upload
|
dropZone: $upload,
|
||||||
});
|
});
|
||||||
|
|
||||||
$upload.on("fileuploadsubmit", () => this.set("uploading", true));
|
$upload.on("fileuploadsubmit", () => this.set("uploading", true));
|
||||||
|
@ -31,12 +31,16 @@ export default Ember.Component.extend({
|
||||||
$upload.on("fileuploaddone", (e, response) => {
|
$upload.on("fileuploaddone", (e, response) => {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
"field.value": response.result,
|
"field.value": response.result,
|
||||||
"uploading": false
|
uploading: false,
|
||||||
});
|
});
|
||||||
if ( Discourse.SiteSettings.wizard_recognised_image_upload_formats.split('|').includes(response.result.extension)) {
|
if (
|
||||||
|
Discourse.SiteSettings.wizard_recognised_image_upload_formats
|
||||||
|
.split("|")
|
||||||
|
.includes(response.result.extension)
|
||||||
|
) {
|
||||||
this.setProperties({
|
this.setProperties({
|
||||||
"isImage": true
|
isImage: true,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -51,9 +55,9 @@ export default Ember.Component.extend({
|
||||||
title: "",
|
title: "",
|
||||||
text: message,
|
text: message,
|
||||||
type: "warning",
|
type: "warning",
|
||||||
confirmButtonColor: "#6699ff"
|
confirmButtonColor: "#6699ff",
|
||||||
});
|
});
|
||||||
this.set("uploading", false);
|
this.set("uploading", false);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import ComboBox from 'select-kit/components/combo-box';
|
import ComboBox from "select-kit/components/combo-box";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
import { makeArray } from "discourse-common/lib/helpers";
|
import { makeArray } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
export default ComboBox.extend({
|
export default ComboBox.extend({
|
||||||
content: computed("groups.[]", "field.content.[]", function() {
|
content: computed("groups.[]", "field.content.[]", function () {
|
||||||
const whitelist = makeArray(this.field.content);
|
const whitelist = makeArray(this.field.content);
|
||||||
return this.groups.filter(group => {
|
return this.groups
|
||||||
return !whitelist.length || whitelist.indexOf(group.id) > -1;
|
.filter((group) => {
|
||||||
}).map(g => {
|
return !whitelist.length || whitelist.indexOf(group.id) > -1;
|
||||||
return {
|
})
|
||||||
id: g.id,
|
.map((g) => {
|
||||||
name: g.full_name ? g.full_name : g.name
|
return {
|
||||||
}
|
id: g.id,
|
||||||
});
|
name: g.full_name ? g.full_name : g.name,
|
||||||
})
|
};
|
||||||
})
|
});
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import CustomWizard from '../models/custom';
|
import CustomWizard from "../models/custom";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
siteName: function() {
|
siteName: function () {
|
||||||
return Wizard.SiteSettings.title;
|
return Wizard.SiteSettings.title;
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
skip() {
|
skip() {
|
||||||
CustomWizard.skip(this.get('wizardId'));
|
CustomWizard.skip(this.get("wizardId"));
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,10 +2,10 @@ import Component from "@ember/component";
|
||||||
import { bind } from "@ember/runloop";
|
import { bind } from "@ember/runloop";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ['wizard-similar-topics'],
|
classNames: ["wizard-similar-topics"],
|
||||||
showTopics: true,
|
showTopics: true,
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
$(document).on("click", bind(this, this.documentClick));
|
$(document).on("click", bind(this, this.documentClick));
|
||||||
},
|
},
|
||||||
|
@ -18,19 +18,19 @@ export default Component.extend({
|
||||||
if (this._state == "destroying") return;
|
if (this._state == "destroying") return;
|
||||||
let $target = $(e.target);
|
let $target = $(e.target);
|
||||||
|
|
||||||
if (!$target.hasClass('show-topics')) {
|
if (!$target.hasClass("show-topics")) {
|
||||||
this.set('showTopics', false);
|
this.set("showTopics", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('topics')
|
@observes("topics")
|
||||||
toggleShowWhenTopicsChange() {
|
toggleShowWhenTopicsChange() {
|
||||||
this.set('showTopics', true);
|
this.set("showTopics", true);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
toggleShowTopics() {
|
toggleShowTopics() {
|
||||||
this.set('showTopics', true);
|
this.set("showTopics", true);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import TagChooser from 'select-kit/components/tag-chooser';
|
import TagChooser from "select-kit/components/tag-chooser";
|
||||||
import { makeArray } from "discourse-common/lib/helpers";
|
import { makeArray } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
export default TagChooser.extend({
|
export default TagChooser.extend({
|
||||||
|
@ -7,5 +7,5 @@ export default TagChooser.extend({
|
||||||
const whitelist = makeArray(context.whitelist);
|
const whitelist = makeArray(context.whitelist);
|
||||||
return !whitelist.length || whitelist.indexOf(tag.id) > 1;
|
return !whitelist.length || whitelist.indexOf(tag.id) > 1;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -5,14 +5,20 @@ import { siteDir, isRTL, isLTR } from "discourse/lib/text-direction";
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
|
||||||
export default Ember.TextField.extend({
|
export default Ember.TextField.extend({
|
||||||
attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus', 'maxLength', 'dir'],
|
attributeBindings: [
|
||||||
|
"autocorrect",
|
||||||
|
"autocapitalize",
|
||||||
|
"autofocus",
|
||||||
|
"maxLength",
|
||||||
|
"dir",
|
||||||
|
],
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
dir() {
|
dir() {
|
||||||
if (Wizard.SiteSettings.support_mixed_text_direction) {
|
if (Wizard.SiteSettings.support_mixed_text_direction) {
|
||||||
let val = this.value;
|
let val = this.value;
|
||||||
if (val) {
|
if (val) {
|
||||||
return isRTL(val) ? 'rtl' : 'ltr';
|
return isRTL(val) ? "rtl" : "ltr";
|
||||||
} else {
|
} else {
|
||||||
return siteDir();
|
return siteDir();
|
||||||
}
|
}
|
||||||
|
@ -23,11 +29,11 @@ export default Ember.TextField.extend({
|
||||||
if (Wizard.SiteSettings.support_mixed_text_direction) {
|
if (Wizard.SiteSettings.support_mixed_text_direction) {
|
||||||
let val = this.value;
|
let val = this.value;
|
||||||
if (isRTL(val)) {
|
if (isRTL(val)) {
|
||||||
this.set('dir', 'rtl');
|
this.set("dir", "rtl");
|
||||||
} else if (isLTR(val)) {
|
} else if (isLTR(val)) {
|
||||||
this.set('dir', 'ltr');
|
this.set("dir", "ltr");
|
||||||
} else {
|
} else {
|
||||||
this.set('dir', siteDir());
|
this.set("dir", siteDir());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -35,5 +41,5 @@ export default Ember.TextField.extend({
|
||||||
@computed("placeholderKey")
|
@computed("placeholderKey")
|
||||||
placeholder(placeholderKey) {
|
placeholder(placeholderKey) {
|
||||||
return placeholderKey ? WizardI18n(placeholderKey) : "";
|
return placeholderKey ? WizardI18n(placeholderKey) : "";
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
import TimeInput from "discourse/components/time-input";
|
import TimeInput from "discourse/components/time-input";
|
||||||
|
|
||||||
export default TimeInput.extend();
|
export default TimeInput.extend();
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
import StepController from 'wizard/controllers/step';
|
import StepController from "wizard/controllers/step";
|
||||||
import getUrl from 'discourse-common/lib/get-url';
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
|
||||||
export default StepController.extend({
|
export default StepController.extend({
|
||||||
actions: {
|
actions: {
|
||||||
goNext(response) {
|
goNext(response) {
|
||||||
const next = this.get('step.next');
|
const next = this.get("step.next");
|
||||||
if (response.redirect_on_next) {
|
if (response.redirect_on_next) {
|
||||||
window.location.href = response.redirect_on_next;
|
window.location.href = response.redirect_on_next;
|
||||||
} else if (response.refresh_required) {
|
} else if (response.refresh_required) {
|
||||||
const id = this.get('wizard.id');
|
const id = this.get("wizard.id");
|
||||||
window.location.href = getUrl(`/w/${id}/steps/${next}`);
|
window.location.href = getUrl(`/w/${id}/steps/${next}`);
|
||||||
} else {
|
} else {
|
||||||
this.transitionToRoute('custom.step', next);
|
this.transitionToRoute("custom.step", next);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
goBack() {
|
goBack() {
|
||||||
this.transitionToRoute('custom.step', this.get('step.previous'));
|
this.transitionToRoute("custom.step", this.get("step.previous"));
|
||||||
},
|
},
|
||||||
|
|
||||||
showMessage(message) {
|
showMessage(message) {
|
||||||
this.set('stepMessage', message);
|
this.set("stepMessage", message);
|
||||||
},
|
},
|
||||||
|
|
||||||
resetWizard() {
|
resetWizard() {
|
||||||
const id = this.get('wizard.id');
|
const id = this.get("wizard.id");
|
||||||
const stepId = this.get('step.id');
|
const stepId = this.get("step.id");
|
||||||
window.location.href = getUrl(`/w/${id}/steps/${stepId}?reset=true`);
|
window.location.href = getUrl(`/w/${id}/steps/${stepId}?reset=true`);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
queryParams: ['reset']
|
queryParams: ["reset"],
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { buildResolver } from "discourse-common/resolver";
|
import { buildResolver } from "discourse-common/resolver";
|
||||||
|
|
||||||
export default Ember.Application.extend({
|
export default Ember.Application.extend({
|
||||||
rootElement: '#custom-wizard-main',
|
rootElement: "#custom-wizard-main",
|
||||||
Resolver: buildResolver("wizard"),
|
Resolver: buildResolver("wizard"),
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
@ -11,7 +11,7 @@ export default Ember.Application.extend({
|
||||||
if (!module) {
|
if (!module) {
|
||||||
throw new Error(key + " must export an initializer.");
|
throw new Error(key + " must export an initializer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = module.default;
|
const init = module.default;
|
||||||
const oldInitialize = init.initialize;
|
const oldInitialize = init.initialize;
|
||||||
init.initialize = () => {
|
init.initialize = () => {
|
||||||
|
@ -21,8 +21,8 @@ export default Ember.Application.extend({
|
||||||
this.initializer(init);
|
this.initializer(init);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(requirejs._eak_seen).forEach(key => {
|
Object.keys(requirejs._eak_seen).forEach((key) => {
|
||||||
if (/\/initializers\//.test(key)) {
|
if (/\/initializers\//.test(key)) {
|
||||||
const module = requirejs(key, null, null, true);
|
const module = requirejs(key, null, null, true);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
|
@ -31,5 +31,5 @@ export default Ember.Application.extend({
|
||||||
this.initializer(module.default);
|
this.initializer(module.default);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
import { registerUnbound } from "discourse-common/lib/helpers";
|
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default registerUnbound("char-counter", function(body, maxLength) {
|
export default registerUnbound("char-counter", function (body, maxLength) {
|
||||||
let bodyLength = body ? body.length : 0;
|
let bodyLength = body ? body.length : 0;
|
||||||
let finalString;
|
let finalString;
|
||||||
|
|
||||||
if (maxLength) {
|
if (maxLength) {
|
||||||
let isOverMax = bodyLength > maxLength ? "true" : "false";
|
let isOverMax = bodyLength > maxLength ? "true" : "false";
|
||||||
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t('wizard.x_characters', { count: parseInt(maxLength) })}</div>`;
|
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t(
|
||||||
} else {
|
"wizard.x_characters",
|
||||||
finalString = `<div class="body-length">${I18n.t('wizard.x_characters', { count: parseInt(bodyLength) })}</div>`;
|
{ count: parseInt(maxLength) }
|
||||||
}
|
)}</div>`;
|
||||||
|
} else {
|
||||||
|
finalString = `<div class="body-length">${I18n.t("wizard.x_characters", {
|
||||||
|
count: parseInt(bodyLength),
|
||||||
|
})}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
return new Handlebars.SafeString(finalString);
|
return new Handlebars.SafeString(finalString);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { registerUnbound } from "discourse-common/lib/helpers";
|
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
export default registerUnbound("dir-span", function(str) {
|
export default registerUnbound("dir-span", function (str) {
|
||||||
return new Handlebars.SafeString(str);
|
return new Handlebars.SafeString(str);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { registerUnbound } from "discourse-common/lib/helpers";
|
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
export default registerUnbound("plugin-outlet", function(attrs) {
|
export default registerUnbound("plugin-outlet", function (attrs) {
|
||||||
return new Handlebars.SafeString('');
|
return new Handlebars.SafeString("");
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { registerUnbound } from 'discourse-common/lib/helpers';
|
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||||
import WizardI18n from '../lib/wizard-i18n';
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
|
||||||
export default registerUnbound("wizard-i18n", (key, params) => {
|
export default registerUnbound("wizard-i18n", (key, params) => {
|
||||||
return WizardI18n(key, params);
|
return WizardI18n(key, params);
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,20 +5,22 @@ export default {
|
||||||
name: "custom-wizard-field",
|
name: "custom-wizard-field",
|
||||||
initialize(app) {
|
initialize(app) {
|
||||||
if (window.location.pathname.indexOf("/w/") < 0) return;
|
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||||||
|
|
||||||
const FieldComponent = requirejs("wizard/components/wizard-field").default;
|
const FieldComponent = requirejs("wizard/components/wizard-field").default;
|
||||||
const FieldModel = requirejs("wizard/models/wizard-field").default;
|
const FieldModel = requirejs("wizard/models/wizard-field").default;
|
||||||
const { cook } = requirejs("discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite");
|
const { cook } = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite"
|
||||||
|
);
|
||||||
const DEditor = requirejs("discourse/components/d-editor").default;
|
const DEditor = requirejs("discourse/components/d-editor").default;
|
||||||
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
||||||
const { toMarkdown } = requirejs("discourse/lib/to-markdown");
|
const { toMarkdown } = requirejs("discourse/lib/to-markdown");
|
||||||
|
|
||||||
FieldComponent.reopen({
|
FieldComponent.reopen({
|
||||||
classNameBindings: ["field.id"],
|
classNameBindings: ["field.id"],
|
||||||
|
|
||||||
@discourseComputed("field.type")
|
@discourseComputed("field.type")
|
||||||
textType(fieldType) {
|
textType(fieldType) {
|
||||||
return ['text', 'textarea'].includes(fieldType);
|
return ["text", "textarea"].includes(fieldType);
|
||||||
},
|
},
|
||||||
|
|
||||||
cookedDescription: function () {
|
cookedDescription: function () {
|
||||||
|
@ -81,35 +83,43 @@ export default {
|
||||||
return valid;
|
return valid;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isInside = (text, regex) => {
|
const isInside = (text, regex) => {
|
||||||
const matches = text.match(regex);
|
const matches = text.match(regex);
|
||||||
return matches && matches.length % 2;
|
return matches && matches.length % 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
DEditor.reopen({
|
DEditor.reopen({
|
||||||
isComposer: true,
|
isComposer: true,
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super();
|
this._super();
|
||||||
if (this.wizardComposerEvents) {
|
if (this.wizardComposerEvents) {
|
||||||
this.appEvents.on("wizard-editor:insert-text", this, "_wizardInsertText");
|
this.appEvents.on(
|
||||||
this.appEvents.on("wizard-editor:replace-text", this, "_wizardReplaceText");
|
"wizard-editor:insert-text",
|
||||||
|
this,
|
||||||
|
"_wizardInsertText"
|
||||||
|
);
|
||||||
|
this.appEvents.on(
|
||||||
|
"wizard-editor:replace-text",
|
||||||
|
this,
|
||||||
|
"_wizardReplaceText"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_wizardInsertText(args = {}) {
|
_wizardInsertText(args = {}) {
|
||||||
if (args.fieldId === this.fieldId) {
|
if (args.fieldId === this.fieldId) {
|
||||||
this._insertText(args.text, args.options);
|
this._insertText(args.text, args.options);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_wizardReplaceText(args = {}) {
|
_wizardReplaceText(args = {}) {
|
||||||
if (args.fieldId === this.fieldId) {
|
if (args.fieldId === this.fieldId) {
|
||||||
this._replaceText(args.oldVal, args.newVal, args.opts = {});
|
this._replaceText(args.oldVal, args.newVal, (args.opts = {}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
paste(e) {
|
paste(e) {
|
||||||
if (!$(".d-editor-input").is(":focus")) {
|
if (!$(".d-editor-input").is(":focus")) {
|
||||||
return;
|
return;
|
||||||
|
@ -140,7 +150,7 @@ export default {
|
||||||
if (table) {
|
if (table) {
|
||||||
this.appEvents.trigger("wizard-editor:insert-text", {
|
this.appEvents.trigger("wizard-editor:insert-text", {
|
||||||
fieldId: this.fieldId,
|
fieldId: this.fieldId,
|
||||||
text: table
|
text: table,
|
||||||
});
|
});
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +179,7 @@ export default {
|
||||||
|
|
||||||
this.appEvents.trigger("composer:insert-text", {
|
this.appEvents.trigger("composer:insert-text", {
|
||||||
fieldId: this.fieldId,
|
fieldId: this.fieldId,
|
||||||
text: markdown
|
text: markdown,
|
||||||
});
|
});
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
@ -180,5 +190,5 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
|
@ -2,16 +2,21 @@ export default {
|
||||||
name: "custom-wizard-step",
|
name: "custom-wizard-step",
|
||||||
initialize(app) {
|
initialize(app) {
|
||||||
if (window.location.pathname.indexOf("/w/") < 0) return;
|
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||||||
|
|
||||||
const CustomWizard = requirejs("discourse/plugins/discourse-custom-wizard/wizard/models/custom").default;
|
const CustomWizard = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
||||||
|
).default;
|
||||||
const StepModel = requirejs("wizard/models/step").default;
|
const StepModel = requirejs("wizard/models/step").default;
|
||||||
const StepComponent = requirejs("wizard/components/wizard-step").default;
|
const StepComponent = requirejs("wizard/components/wizard-step").default;
|
||||||
const ajax = requirejs("wizard/lib/ajax").ajax;
|
const ajax = requirejs("wizard/lib/ajax").ajax;
|
||||||
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
||||||
const discourseComputed = requirejs("discourse-common/utils/decorators").default;
|
const discourseComputed = requirejs("discourse-common/utils/decorators")
|
||||||
const cook = requirejs("discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite").cook;
|
.default;
|
||||||
|
const cook = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite"
|
||||||
|
).cook;
|
||||||
const { schedule } = requirejs("@ember/runloop");
|
const { schedule } = requirejs("@ember/runloop");
|
||||||
|
|
||||||
StepModel.reopen({
|
StepModel.reopen({
|
||||||
save() {
|
save() {
|
||||||
const wizardId = this.get("wizardId");
|
const wizardId = this.get("wizardId");
|
||||||
|
@ -69,10 +74,10 @@ export default {
|
||||||
Ember.run.later(() => this.set("message", null), 6000);
|
Ember.run.later(() => this.set("message", null), 6000);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
StepComponent.reopen({
|
StepComponent.reopen({
|
||||||
classNameBindings: ["step.id"],
|
classNameBindings: ["step.id"],
|
||||||
|
|
||||||
autoFocus() {
|
autoFocus() {
|
||||||
schedule("afterRender", () => {
|
schedule("afterRender", () => {
|
||||||
const $invalid = $(
|
const $invalid = $(
|
||||||
|
@ -82,14 +87,16 @@ export default {
|
||||||
if ($invalid.length) {
|
if ($invalid.length) {
|
||||||
return $invalid.focus();
|
return $invalid.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(".wizard-focusable:first").focus();
|
$(".wizard-focusable:first").focus();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
animateInvalidFields() {
|
animateInvalidFields() {
|
||||||
schedule("afterRender", () => {
|
schedule("afterRender", () => {
|
||||||
let $element = $(".invalid input[type=text],.invalid textarea,.invalid input[type=checkbox],.invalid .select-kit");
|
let $element = $(
|
||||||
|
".invalid input[type=text],.invalid textarea,.invalid input[type=checkbox],.invalid .select-kit"
|
||||||
|
);
|
||||||
|
|
||||||
if ($element.length) {
|
if ($element.length) {
|
||||||
$([document.documentElement, document.body]).animate(
|
$([document.documentElement, document.body]).animate(
|
||||||
|
@ -128,13 +135,13 @@ export default {
|
||||||
if (!src) return;
|
if (!src) return;
|
||||||
return getUrl(src);
|
return getUrl(src);
|
||||||
}.property("step.banner"),
|
}.property("step.banner"),
|
||||||
|
|
||||||
@discourseComputed('step.fields.[]')
|
@discourseComputed("step.fields.[]")
|
||||||
primaryButtonIndex(fields) {
|
primaryButtonIndex(fields) {
|
||||||
return fields.length + 1;
|
return fields.length + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed('step.fields.[]')
|
@discourseComputed("step.fields.[]")
|
||||||
secondaryButtonIndex(fields) {
|
secondaryButtonIndex(fields) {
|
||||||
return fields.length + 2;
|
return fields.length + 2;
|
||||||
},
|
},
|
||||||
|
@ -176,5 +183,5 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
|
@ -6,18 +6,27 @@ export default {
|
||||||
const EmberObject = requirejs("@ember/object").default;
|
const EmberObject = requirejs("@ember/object").default;
|
||||||
const Router = requirejs("wizard/router").default;
|
const Router = requirejs("wizard/router").default;
|
||||||
const ApplicationRoute = requirejs("wizard/routes/application").default;
|
const ApplicationRoute = requirejs("wizard/routes/application").default;
|
||||||
const CustomWizard = requirejs("discourse/plugins/discourse-custom-wizard/wizard/models/custom").default;
|
const CustomWizard = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
||||||
|
).default;
|
||||||
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
||||||
const Store = requirejs("discourse/models/store").default;
|
const Store = requirejs("discourse/models/store").default;
|
||||||
const registerRawHelpers = requirejs("discourse-common/lib/raw-handlebars-helpers").registerRawHelpers;
|
const registerRawHelpers = requirejs(
|
||||||
const createHelperContext = requirejs("discourse-common/lib/helpers").createHelperContext;
|
"discourse-common/lib/raw-handlebars-helpers"
|
||||||
const RawHandlebars = requirejs("discourse-common/lib/raw-handlebars").default;
|
).registerRawHelpers;
|
||||||
const Site = requirejs("discourse/plugins/discourse-custom-wizard/wizard/models/site").default;
|
const createHelperContext = requirejs("discourse-common/lib/helpers")
|
||||||
|
.createHelperContext;
|
||||||
|
const RawHandlebars = requirejs("discourse-common/lib/raw-handlebars")
|
||||||
|
.default;
|
||||||
|
const Site = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/models/site"
|
||||||
|
).default;
|
||||||
const RestAdapter = requirejs("discourse/adapters/rest").default;
|
const RestAdapter = requirejs("discourse/adapters/rest").default;
|
||||||
const Session = requirejs("discourse/models/session").default;
|
const Session = requirejs("discourse/models/session").default;
|
||||||
const setDefaultOwner = requirejs("discourse-common/lib/get-owner").setDefaultOwner;
|
const setDefaultOwner = requirejs("discourse-common/lib/get-owner")
|
||||||
|
.setDefaultOwner;
|
||||||
const messageBus = requirejs("message-bus-client").default;
|
const messageBus = requirejs("message-bus-client").default;
|
||||||
|
|
||||||
const container = app.__container__;
|
const container = app.__container__;
|
||||||
Discourse.Model = EmberObject.extend();
|
Discourse.Model = EmberObject.extend();
|
||||||
Discourse.__container__ = container;
|
Discourse.__container__ = container;
|
||||||
|
@ -66,7 +75,7 @@ export default {
|
||||||
site.set("can_create_tag", false);
|
site.set("can_create_tag", false);
|
||||||
app.register("session:main", Session.current(), { instantiate: false });
|
app.register("session:main", Session.current(), { instantiate: false });
|
||||||
targets.forEach((t) => app.inject(t, "session", "session:main"));
|
targets.forEach((t) => app.inject(t, "session", "session:main"));
|
||||||
|
|
||||||
createHelperContext({
|
createHelperContext({
|
||||||
siteSettings: container.lookup("site-settings:main"),
|
siteSettings: container.lookup("site-settings:main"),
|
||||||
currentUser: container.lookup("current-user:main"),
|
currentUser: container.lookup("current-user:main"),
|
||||||
|
@ -74,13 +83,13 @@ export default {
|
||||||
session: container.lookup("session:main"),
|
session: container.lookup("session:main"),
|
||||||
capabilities: container.lookup("capabilities:main"),
|
capabilities: container.lookup("capabilities:main"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const session = container.lookup("session:main");
|
const session = container.lookup("session:main");
|
||||||
const setupData = document.getElementById("data-discourse-setup").dataset;
|
const setupData = document.getElementById("data-discourse-setup").dataset;
|
||||||
session.set("highlightJsPath", setupData.highlightJsPath);
|
session.set("highlightJsPath", setupData.highlightJsPath);
|
||||||
|
|
||||||
Router.reopen({
|
Router.reopen({
|
||||||
rootURL: getUrl("/w/")
|
rootURL: getUrl("/w/"),
|
||||||
});
|
});
|
||||||
|
|
||||||
Router.map(function () {
|
Router.map(function () {
|
||||||
|
|
|
@ -1,23 +1,28 @@
|
||||||
import { ajax } from 'wizard/lib/ajax';
|
import { ajax } from "wizard/lib/ajax";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL from "discourse-common/lib/get-url";
|
||||||
|
|
||||||
const _loaded = {};
|
const _loaded = {};
|
||||||
const _loading = {};
|
const _loading = {};
|
||||||
|
|
||||||
function loadWithTag(path, cb) {
|
function loadWithTag(path, cb) {
|
||||||
const head = document.getElementsByTagName('head')[0];
|
const head = document.getElementsByTagName("head")[0];
|
||||||
|
|
||||||
let finished = false;
|
let finished = false;
|
||||||
let s = document.createElement('script');
|
let s = document.createElement("script");
|
||||||
s.src = path;
|
s.src = path;
|
||||||
if (Ember.Test) {
|
if (Ember.Test) {
|
||||||
Ember.Test.registerWaiter(() => finished);
|
Ember.Test.registerWaiter(() => finished);
|
||||||
}
|
}
|
||||||
head.appendChild(s);
|
head.appendChild(s);
|
||||||
|
|
||||||
s.onload = s.onreadystatechange = function(_, abort) {
|
s.onload = s.onreadystatechange = function (_, abort) {
|
||||||
finished = true;
|
finished = true;
|
||||||
if (abort || !s.readyState || s.readyState === "loaded" || s.readyState === "complete") {
|
if (
|
||||||
|
abort ||
|
||||||
|
!s.readyState ||
|
||||||
|
s.readyState === "loaded" ||
|
||||||
|
s.readyState === "complete"
|
||||||
|
) {
|
||||||
s = s.onload = s.onreadystatechange = null;
|
s = s.onload = s.onreadystatechange = null;
|
||||||
if (!abort) {
|
if (!abort) {
|
||||||
Ember.run(null, cb);
|
Ember.run(null, cb);
|
||||||
|
@ -31,38 +36,42 @@ export function loadCSS(url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function loadScript(url, opts) {
|
export default function loadScript(url, opts) {
|
||||||
|
|
||||||
// TODO: Remove this once plugins have been updated not to use it:
|
// TODO: Remove this once plugins have been updated not to use it:
|
||||||
if (url === "defer/html-sanitizer-bundle") { return Ember.RSVP.Promise.resolve(); }
|
if (url === "defer/html-sanitizer-bundle") {
|
||||||
|
return Ember.RSVP.Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
$('script').each((i, tag) => {
|
$("script").each((i, tag) => {
|
||||||
const src = tag.getAttribute('src');
|
const src = tag.getAttribute("src");
|
||||||
|
|
||||||
if (src && (opts.scriptTag || src !== url)) {
|
if (src && (opts.scriptTag || src !== url)) {
|
||||||
_loaded[tag.getAttribute('src')] = true;
|
_loaded[tag.getAttribute("src")] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return new Ember.RSVP.Promise(function (resolve) {
|
||||||
return new Ember.RSVP.Promise(function(resolve) {
|
|
||||||
url = getURL(url);
|
url = getURL(url);
|
||||||
|
|
||||||
// If we already loaded this url
|
// If we already loaded this url
|
||||||
if (_loaded[url]) { return resolve(); }
|
if (_loaded[url]) {
|
||||||
if (_loading[url]) { return _loading[url].then(resolve);}
|
return resolve();
|
||||||
|
}
|
||||||
|
if (_loading[url]) {
|
||||||
|
return _loading[url].then(resolve);
|
||||||
|
}
|
||||||
|
|
||||||
let done;
|
let done;
|
||||||
_loading[url] = new Ember.RSVP.Promise(function(_done){
|
_loading[url] = new Ember.RSVP.Promise(function (_done) {
|
||||||
done = _done;
|
done = _done;
|
||||||
});
|
});
|
||||||
|
|
||||||
_loading[url].then(function(){
|
_loading[url].then(function () {
|
||||||
delete _loading[url];
|
delete _loading[url];
|
||||||
});
|
});
|
||||||
|
|
||||||
const cb = function(data) {
|
const cb = function (data) {
|
||||||
if (opts && opts.css) {
|
if (opts && opts.css) {
|
||||||
$("head").append("<style>" + data + "</style>");
|
$("head").append("<style>" + data + "</style>");
|
||||||
}
|
}
|
||||||
|
@ -76,7 +85,7 @@ export default function loadScript(url, opts) {
|
||||||
// Scripts should always load from CDN
|
// Scripts should always load from CDN
|
||||||
// CSS is type text, to accept it from a CDN we would need to handle CORS
|
// CSS is type text, to accept it from a CDN we would need to handle CORS
|
||||||
if (!opts.css && Discourse.CDN && url[0] === "/" && url[1] !== "/") {
|
if (!opts.css && Discourse.CDN && url[0] === "/" && url[1] !== "/") {
|
||||||
cdnUrl = Discourse.CDN.replace(/\/$/,"") + url;
|
cdnUrl = Discourse.CDN.replace(/\/$/, "") + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some javascript depends on the path of where it is loaded (ace editor)
|
// Some javascript depends on the path of where it is loaded (ace editor)
|
||||||
|
@ -88,7 +97,11 @@ export default function loadScript(url, opts) {
|
||||||
}
|
}
|
||||||
loadWithTag(cdnUrl, cb);
|
loadWithTag(cdnUrl, cb);
|
||||||
} else {
|
} else {
|
||||||
ajax({url: cdnUrl, dataType: opts.css ? "text": "script", cache: true}).then(cb);
|
ajax({
|
||||||
|
url: cdnUrl,
|
||||||
|
dataType: opts.css ? "text" : "script",
|
||||||
|
cache: true,
|
||||||
|
}).then(cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import loadScript from './load-script';
|
import loadScript from "./load-script";
|
||||||
import { default as PrettyText } from 'pretty-text/pretty-text';
|
import { default as PrettyText } from "pretty-text/pretty-text";
|
||||||
|
|
||||||
export function cook(text, options) {
|
export function cook(text, options) {
|
||||||
return new Handlebars.SafeString(new PrettyText(options).cook(text));
|
return new Handlebars.SafeString(new PrettyText(options).cook(text));
|
||||||
|
@ -10,8 +10,8 @@ export function cook(text, options) {
|
||||||
export function cookAsync(text, options) {
|
export function cookAsync(text, options) {
|
||||||
if (Discourse.MarkdownItURL) {
|
if (Discourse.MarkdownItURL) {
|
||||||
return loadScript(Discourse.MarkdownItURL)
|
return loadScript(Discourse.MarkdownItURL)
|
||||||
.then(()=>cook(text, options))
|
.then(() => cook(text, options))
|
||||||
.catch(e => Ember.Logger.error(e));
|
.catch((e) => Ember.Logger.error(e));
|
||||||
} else {
|
} else {
|
||||||
return Ember.RSVP.Promise.resolve(cook(text));
|
return Ember.RSVP.Promise.resolve(cook(text));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,23 @@
|
||||||
import { CANCELLED_STATUS } from 'discourse/lib/autocomplete';
|
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
||||||
import { debounce } from "@ember/runloop";
|
import { debounce } from "@ember/runloop";
|
||||||
import getUrl from 'discourse-common/lib/get-url';
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
|
||||||
var cache = {},
|
var cache = {},
|
||||||
cacheTopicId,
|
cacheTopicId,
|
||||||
cacheTime,
|
cacheTime,
|
||||||
currentTerm,
|
currentTerm,
|
||||||
oldSearch;
|
oldSearch;
|
||||||
|
|
||||||
function performSearch(term, topicId, includeGroups, includeMentionableGroups, includeMessageableGroups, allowedUsers, group, resultsFn) {
|
function performSearch(
|
||||||
|
term,
|
||||||
|
topicId,
|
||||||
|
includeGroups,
|
||||||
|
includeMentionableGroups,
|
||||||
|
includeMessageableGroups,
|
||||||
|
allowedUsers,
|
||||||
|
group,
|
||||||
|
resultsFn
|
||||||
|
) {
|
||||||
var cached = cache[term];
|
var cached = cache[term];
|
||||||
if (cached) {
|
if (cached) {
|
||||||
resultsFn(cached);
|
resultsFn(cached);
|
||||||
|
@ -16,42 +25,49 @@ function performSearch(term, topicId, includeGroups, includeMentionableGroups, i
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to be able to cancel this
|
// need to be able to cancel this
|
||||||
oldSearch = $.ajax(getUrl('/u/search/users'), {
|
oldSearch = $.ajax(getUrl("/u/search/users"), {
|
||||||
data: { term: term,
|
data: {
|
||||||
topic_id: topicId,
|
term: term,
|
||||||
include_groups: includeGroups,
|
topic_id: topicId,
|
||||||
include_mentionable_groups: includeMentionableGroups,
|
include_groups: includeGroups,
|
||||||
include_messageable_groups: includeMessageableGroups,
|
include_mentionable_groups: includeMentionableGroups,
|
||||||
group: group,
|
include_messageable_groups: includeMessageableGroups,
|
||||||
topic_allowed_users: allowedUsers }
|
group: group,
|
||||||
|
topic_allowed_users: allowedUsers,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var returnVal = CANCELLED_STATUS;
|
var returnVal = CANCELLED_STATUS;
|
||||||
|
|
||||||
oldSearch.then(function (r) {
|
oldSearch
|
||||||
cache[term] = r;
|
.then(function (r) {
|
||||||
cacheTime = new Date();
|
cache[term] = r;
|
||||||
// If there is a newer search term, return null
|
cacheTime = new Date();
|
||||||
if (term === currentTerm) { returnVal = r; }
|
// If there is a newer search term, return null
|
||||||
|
if (term === currentTerm) {
|
||||||
}).always(function(){
|
returnVal = r;
|
||||||
oldSearch = null;
|
}
|
||||||
resultsFn(returnVal);
|
})
|
||||||
});
|
.always(function () {
|
||||||
|
oldSearch = null;
|
||||||
|
resultsFn(returnVal);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function organizeResults(r, options) {
|
function organizeResults(r, options) {
|
||||||
if (r === CANCELLED_STATUS) { return r; }
|
if (r === CANCELLED_STATUS) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
var exclude = options.exclude || [],
|
var exclude = options.exclude || [],
|
||||||
limit = options.limit || 5,
|
limit = options.limit || 5,
|
||||||
users = [],
|
users = [],
|
||||||
emails = [],
|
emails = [],
|
||||||
groups = [],
|
groups = [],
|
||||||
results = [];
|
results = [];
|
||||||
|
|
||||||
if (r.users) {
|
if (r.users) {
|
||||||
r.users.every(function(u) {
|
r.users.every(function (u) {
|
||||||
if (exclude.indexOf(u.username) === -1) {
|
if (exclude.indexOf(u.username) === -1) {
|
||||||
users.push(u);
|
users.push(u);
|
||||||
results.push(u);
|
results.push(u);
|
||||||
|
@ -62,13 +78,17 @@ function organizeResults(r, options) {
|
||||||
|
|
||||||
if (options.term.match(/@/)) {
|
if (options.term.match(/@/)) {
|
||||||
let e = { username: options.term };
|
let e = { username: options.term };
|
||||||
emails = [ e ];
|
emails = [e];
|
||||||
results.push(e);
|
results.push(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.groups) {
|
if (r.groups) {
|
||||||
r.groups.every(function(g) {
|
r.groups.every(function (g) {
|
||||||
if (results.length > limit && options.term.toLowerCase() !== g.name.toLowerCase()) return false;
|
if (
|
||||||
|
results.length > limit &&
|
||||||
|
options.term.toLowerCase() !== g.name.toLowerCase()
|
||||||
|
)
|
||||||
|
return false;
|
||||||
if (exclude.indexOf(g.name) === -1) {
|
if (exclude.indexOf(g.name) === -1) {
|
||||||
groups.push(g);
|
groups.push(g);
|
||||||
results.push(g);
|
results.push(g);
|
||||||
|
@ -83,16 +103,14 @@ function organizeResults(r, options) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function userSearch(options) {
|
export default function userSearch(options) {
|
||||||
var term = options.term || "",
|
var term = options.term || "",
|
||||||
includeGroups = options.includeGroups,
|
includeGroups = options.includeGroups,
|
||||||
includeMentionableGroups = options.includeMentionableGroups,
|
includeMentionableGroups = options.includeMentionableGroups,
|
||||||
includeMessageableGroups = options.includeMessageableGroups,
|
includeMessageableGroups = options.includeMessageableGroups,
|
||||||
allowedUsers = options.allowedUsers,
|
allowedUsers = options.allowedUsers,
|
||||||
topicId = options.topicId,
|
topicId = options.topicId,
|
||||||
group = options.group;
|
group = options.group;
|
||||||
|
|
||||||
|
|
||||||
if (oldSearch) {
|
if (oldSearch) {
|
||||||
oldSearch.abort();
|
oldSearch.abort();
|
||||||
|
@ -101,26 +119,26 @@ export default function userSearch(options) {
|
||||||
|
|
||||||
currentTerm = term;
|
currentTerm = term;
|
||||||
|
|
||||||
return new Ember.RSVP.Promise(function(resolve) {
|
return new Ember.RSVP.Promise(function (resolve) {
|
||||||
// TODO site setting for allowed regex in username
|
// TODO site setting for allowed regex in username
|
||||||
if (term.match(/[^\w_\-\.@\+]/)) {
|
if (term.match(/[^\w_\-\.@\+]/)) {
|
||||||
resolve([]);
|
resolve([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (((new Date() - cacheTime) > 30000) || (cacheTopicId !== topicId)) {
|
if (new Date() - cacheTime > 30000 || cacheTopicId !== topicId) {
|
||||||
cache = {};
|
cache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheTopicId = topicId;
|
cacheTopicId = topicId;
|
||||||
|
|
||||||
var clearPromise = setTimeout(function(){
|
var clearPromise = setTimeout(function () {
|
||||||
resolve(CANCELLED_STATUS);
|
resolve(CANCELLED_STATUS);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
// TODO: Use discouseDebounce after it is available on stable.
|
// TODO: Use discouseDebounce after it is available on stable.
|
||||||
debounce(
|
debounce(
|
||||||
this,
|
this,
|
||||||
function() {
|
function () {
|
||||||
performSearch(
|
performSearch(
|
||||||
term,
|
term,
|
||||||
topicId,
|
topicId,
|
||||||
|
@ -129,13 +147,13 @@ export default function userSearch(options) {
|
||||||
includeMessageableGroups,
|
includeMessageableGroups,
|
||||||
allowedUsers,
|
allowedUsers,
|
||||||
group,
|
group,
|
||||||
function(r) {
|
function (r) {
|
||||||
clearTimeout(clearPromise);
|
clearTimeout(clearPromise);
|
||||||
resolve(organizeResults(r, options));
|
resolve(organizeResults(r, options));
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
300
|
300
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
// lite version of discourse/lib/utilities
|
// lite version of discourse/lib/utilities
|
||||||
|
|
||||||
export function determinePostReplaceSelection({ selection, needle, replacement }) {
|
export function determinePostReplaceSelection({
|
||||||
const diff = (replacement.end - replacement.start) - (needle.end - needle.start);
|
selection,
|
||||||
|
needle,
|
||||||
|
replacement,
|
||||||
|
}) {
|
||||||
|
const diff =
|
||||||
|
replacement.end - replacement.start - (needle.end - needle.start);
|
||||||
|
|
||||||
if (selection.end <= needle.start) {
|
if (selection.end <= needle.start) {
|
||||||
// Selection ends (and starts) before needle.
|
// Selection ends (and starts) before needle.
|
||||||
|
@ -30,7 +35,7 @@ export function determinePostReplaceSelection({ selection, needle, replacement }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const toArray = items => {
|
const toArray = (items) => {
|
||||||
items = items || [];
|
items = items || [];
|
||||||
|
|
||||||
if (!Array.isArray(items)) {
|
if (!Array.isArray(items)) {
|
||||||
|
@ -41,20 +46,26 @@ const toArray = items => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function clipboardData(e, canUpload) {
|
export function clipboardData(e, canUpload) {
|
||||||
const clipboard = e.clipboardData ||
|
const clipboard =
|
||||||
e.originalEvent.clipboardData ||
|
e.clipboardData ||
|
||||||
e.delegatedEvent.originalEvent.clipboardData;
|
e.originalEvent.clipboardData ||
|
||||||
|
e.delegatedEvent.originalEvent.clipboardData;
|
||||||
|
|
||||||
const types = toArray(clipboard.types);
|
const types = toArray(clipboard.types);
|
||||||
let files = toArray(clipboard.files);
|
let files = toArray(clipboard.files);
|
||||||
|
|
||||||
if (types.includes("Files") && files.length === 0) { // for IE
|
if (types.includes("Files") && files.length === 0) {
|
||||||
files = toArray(clipboard.items).filter(i => i.kind === "file");
|
// for IE
|
||||||
|
files = toArray(clipboard.items).filter((i) => i.kind === "file");
|
||||||
}
|
}
|
||||||
|
|
||||||
canUpload = files && canUpload && !types.includes("text/plain");
|
canUpload = files && canUpload && !types.includes("text/plain");
|
||||||
const canUploadImage = canUpload && files.filter(f => f.type.match('^image/'))[0];
|
const canUploadImage =
|
||||||
const canPasteHtml = Discourse.SiteSettings.enable_rich_text_paste && types.includes("text/html") && !canUploadImage;
|
canUpload && files.filter((f) => f.type.match("^image/"))[0];
|
||||||
|
const canPasteHtml =
|
||||||
|
Discourse.SiteSettings.enable_rich_text_paste &&
|
||||||
|
types.includes("text/html") &&
|
||||||
|
!canUploadImage;
|
||||||
|
|
||||||
return { clipboard, types, canUpload, canPasteHtml };
|
return { clipboard, types, canUpload, canPasteHtml };
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,32 @@ import I18n from "I18n";
|
||||||
|
|
||||||
const getThemeId = () => {
|
const getThemeId = () => {
|
||||||
let themeId = parseInt($("meta[name=discourse_theme_ids]")[0].content, 10);
|
let themeId = parseInt($("meta[name=discourse_theme_ids]")[0].content, 10);
|
||||||
|
|
||||||
if (!isNaN(themeId)) {
|
if (!isNaN(themeId)) {
|
||||||
return themeId.toString();
|
return themeId.toString();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const translationExists = (key) => {
|
const translationExists = (key) => {
|
||||||
return I18n.findTranslation(key, { locale: I18n.locale }) ||
|
return (
|
||||||
I18n.findTranslation(key, { locale: I18n.defaultLocale });
|
I18n.findTranslation(key, { locale: I18n.locale }) ||
|
||||||
}
|
I18n.findTranslation(key, { locale: I18n.defaultLocale })
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const WizardI18n = (key, params={}) => {
|
const WizardI18n = (key, params = {}) => {
|
||||||
const themeId = getThemeId();
|
const themeId = getThemeId();
|
||||||
if (!themeId) return I18n.t(key, params);
|
if (!themeId) return I18n.t(key, params);
|
||||||
|
|
||||||
const themeKey = `theme_translations.${themeId}.${key}`;
|
const themeKey = `theme_translations.${themeId}.${key}`;
|
||||||
|
|
||||||
if (translationExists(themeKey)) {
|
if (translationExists(themeKey)) {
|
||||||
return I18n.t(themeKey, params);
|
return I18n.t(themeKey, params);
|
||||||
} else {
|
} else {
|
||||||
return I18n.t(key, params);
|
return I18n.t(key, params);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export default WizardI18n;
|
export default WizardI18n;
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import { default as computed } from 'discourse-common/utils/decorators';
|
import { default as computed } from "discourse-common/utils/decorators";
|
||||||
import getUrl from 'discourse-common/lib/get-url';
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
import WizardField from 'wizard/models/wizard-field';
|
import WizardField from "wizard/models/wizard-field";
|
||||||
import { ajax } from 'wizard/lib/ajax';
|
import { ajax } from "wizard/lib/ajax";
|
||||||
import Step from 'wizard/models/step';
|
import Step from "wizard/models/step";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
|
||||||
const CustomWizard = EmberObject.extend({
|
const CustomWizard = EmberObject.extend({
|
||||||
@computed('steps.length')
|
@computed("steps.length")
|
||||||
totalSteps: length => length,
|
totalSteps: (length) => length,
|
||||||
|
|
||||||
skip() {
|
skip() {
|
||||||
if (this.required && (!this.completed && this.permitted)) return;
|
if (this.required && !this.completed && this.permitted) return;
|
||||||
CustomWizard.skip(this.id);
|
CustomWizard.skip(this.id);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
CustomWizard.reopenClass({
|
CustomWizard.reopenClass({
|
||||||
skip(wizardId) {
|
skip(wizardId) {
|
||||||
ajax({ url: `/w/${wizardId}/skip`, type: 'PUT' }).then((result) => {
|
ajax({ url: `/w/${wizardId}/skip`, type: "PUT" }).then((result) => {
|
||||||
CustomWizard.finished(result);
|
CustomWizard.finished(result);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -28,52 +28,52 @@ CustomWizard.reopenClass({
|
||||||
url = result.redirect_on_complete;
|
url = result.redirect_on_complete;
|
||||||
}
|
}
|
||||||
window.location.href = getUrl(url);
|
window.location.href = getUrl(url);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function findCustomWizard(wizardId, params = {}) {
|
export function findCustomWizard(wizardId, params = {}) {
|
||||||
let url = `/w/${wizardId}`;
|
let url = `/w/${wizardId}`;
|
||||||
|
|
||||||
let paramKeys = Object.keys(params).filter(k => {
|
let paramKeys = Object.keys(params).filter((k) => {
|
||||||
if (k === 'wizard_id') return false;
|
if (k === "wizard_id") return false;
|
||||||
return !!params[k];
|
return !!params[k];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (paramKeys.length) {
|
if (paramKeys.length) {
|
||||||
url += '?';
|
url += "?";
|
||||||
paramKeys.forEach((k,i) => {
|
paramKeys.forEach((k, i) => {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
url += '&';
|
url += "&";
|
||||||
}
|
}
|
||||||
url += `${k}=${params[k]}`;
|
url += `${k}=${params[k]}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ajax({ url, cache: false, dataType: 'json' }).then(result => {
|
return ajax({ url, cache: false, dataType: "json" }).then((result) => {
|
||||||
const wizard = result;
|
const wizard = result;
|
||||||
if (!wizard) return null;
|
if (!wizard) return null;
|
||||||
|
|
||||||
if (!wizard.completed) {
|
if (!wizard.completed) {
|
||||||
wizard.steps = wizard.steps.map(step => {
|
wizard.steps = wizard.steps.map((step) => {
|
||||||
const stepObj = Step.create(step);
|
const stepObj = Step.create(step);
|
||||||
|
|
||||||
stepObj.fields.sort((a, b) => {
|
stepObj.fields.sort((a, b) => {
|
||||||
return parseFloat(a.number) - parseFloat(b.number);
|
return parseFloat(a.number) - parseFloat(b.number);
|
||||||
});
|
});
|
||||||
|
|
||||||
let tabindex = 1;
|
let tabindex = 1;
|
||||||
stepObj.fields.forEach((f, i) => {
|
stepObj.fields.forEach((f, i) => {
|
||||||
f.tabindex = tabindex;
|
f.tabindex = tabindex;
|
||||||
|
|
||||||
if (['date_time'].includes(f.type)) {
|
if (["date_time"].includes(f.type)) {
|
||||||
tabindex = tabindex + 2;
|
tabindex = tabindex + 2;
|
||||||
} else {
|
} else {
|
||||||
tabindex++;
|
tabindex++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stepObj.fields = stepObj.fields.map(f => WizardField.create(f));
|
stepObj.fields = stepObj.fields.map((f) => WizardField.create(f));
|
||||||
|
|
||||||
return stepObj;
|
return stepObj;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ export function findCustomWizard(wizardId, params = {}) {
|
||||||
if (wizard.categories) {
|
if (wizard.categories) {
|
||||||
let subcatMap = {};
|
let subcatMap = {};
|
||||||
let categoriesById = {};
|
let categoriesById = {};
|
||||||
let categories = wizard.categories.map(c => {
|
let categories = wizard.categories.map((c) => {
|
||||||
if (c.parent_category_id) {
|
if (c.parent_category_id) {
|
||||||
subcatMap[c.parent_category_id] =
|
subcatMap[c.parent_category_id] =
|
||||||
subcatMap[c.parent_category_id] || [];
|
subcatMap[c.parent_category_id] || [];
|
||||||
|
@ -91,25 +91,31 @@ export function findCustomWizard(wizardId, params = {}) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Associate the categories with their parents
|
// Associate the categories with their parents
|
||||||
categories.forEach(c => {
|
categories.forEach((c) => {
|
||||||
let subcategoryIds = subcatMap[c.get("id")];
|
let subcategoryIds = subcatMap[c.get("id")];
|
||||||
if (subcategoryIds) {
|
if (subcategoryIds) {
|
||||||
c.set("subcategories", subcategoryIds.map(id => categoriesById[id]));
|
c.set(
|
||||||
|
"subcategories",
|
||||||
|
subcategoryIds.map((id) => categoriesById[id])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (c.get("parent_category_id")) {
|
if (c.get("parent_category_id")) {
|
||||||
c.set("parentCategory", categoriesById[c.get("parent_category_id")]);
|
c.set("parentCategory", categoriesById[c.get("parent_category_id")]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.Site.currentProp('categoriesList', categories);
|
Discourse.Site.currentProp("categoriesList", categories);
|
||||||
Discourse.Site.currentProp('sortedCategories', categories);
|
Discourse.Site.currentProp("sortedCategories", categories);
|
||||||
Discourse.Site.currentProp('listByActivity', categories);
|
Discourse.Site.currentProp("listByActivity", categories);
|
||||||
Discourse.Site.currentProp('categoriesById', categoriesById);
|
Discourse.Site.currentProp("categoriesById", categoriesById);
|
||||||
Discourse.Site.currentProp('uncategorized_category_id', wizard.uncategorized_category_id);
|
Discourse.Site.currentProp(
|
||||||
|
"uncategorized_category_id",
|
||||||
|
wizard.uncategorized_category_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CustomWizard.create(wizard);
|
return CustomWizard.create(wizard);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export default CustomWizard;
|
export default CustomWizard;
|
||||||
|
|
|
@ -7,4 +7,4 @@ export default Site.reopenClass({
|
||||||
const store = Discourse.__container__.lookup("service:store");
|
const store = Discourse.__container__.lookup("service:store");
|
||||||
return store.createRecord("site", {});
|
return store.createRecord("site", {});
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
const appModel = this.modelFor('custom');
|
const appModel = this.modelFor("custom");
|
||||||
if (appModel && appModel.permitted && !appModel.completed && appModel.start) {
|
if (
|
||||||
this.replaceWith('custom.step', appModel.start);
|
appModel &&
|
||||||
|
appModel.permitted &&
|
||||||
|
!appModel.completed &&
|
||||||
|
appModel.start
|
||||||
|
) {
|
||||||
|
this.replaceWith("custom.step", appModel.start);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
return this.modelFor('custom');
|
return this.modelFor("custom");
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
if (model) {
|
if (model) {
|
||||||
const completed = model.get('completed');
|
const completed = model.get("completed");
|
||||||
const permitted = model.get('permitted');
|
const permitted = model.get("permitted");
|
||||||
const wizardId = model.get('id');
|
const wizardId = model.get("id");
|
||||||
const user = model.get('user');
|
const user = model.get("user");
|
||||||
const name = model.get('name');
|
const name = model.get("name");
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
requiresLogin: !user,
|
requiresLogin: !user,
|
||||||
|
@ -24,10 +29,10 @@ export default Ember.Route.extend({
|
||||||
name,
|
name,
|
||||||
completed,
|
completed,
|
||||||
notPermitted: !permitted,
|
notPermitted: !permitted,
|
||||||
wizardId
|
wizardId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
controller.set('noWizard', true);
|
controller.set("noWizard", true);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,37 +2,38 @@ import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
const appModel = this.modelFor('custom');
|
const appModel = this.modelFor("custom");
|
||||||
const allSteps = appModel.steps;
|
const allSteps = appModel.steps;
|
||||||
if (allSteps) {
|
if (allSteps) {
|
||||||
const step = allSteps.findBy('id', params.step_id);
|
const step = allSteps.findBy("id", params.step_id);
|
||||||
return step ? step : allSteps[0];
|
return step ? step : allSteps[0];
|
||||||
};
|
}
|
||||||
|
|
||||||
return appModel;
|
return appModel;
|
||||||
},
|
},
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
if (model.completed) return this.transitionTo('index');
|
if (model.completed) return this.transitionTo("index");
|
||||||
return model.set("wizardId", this.modelFor('custom').id);
|
return model.set("wizardId", this.modelFor("custom").id);
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
let props = {
|
let props = {
|
||||||
step: model,
|
step: model,
|
||||||
wizard: this.modelFor('custom')
|
wizard: this.modelFor("custom"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!model.permitted) {
|
if (!model.permitted) {
|
||||||
props['stepMessage'] = {
|
props["stepMessage"] = {
|
||||||
state: 'not-permitted',
|
state: "not-permitted",
|
||||||
text: model.permitted_message || WizardI18n('wizard.step_not_permitted')
|
text:
|
||||||
|
model.permitted_message || WizardI18n("wizard.step_not_permitted"),
|
||||||
};
|
};
|
||||||
if (model.index > 0) {
|
if (model.index > 0) {
|
||||||
props['showReset'] = true;
|
props["showReset"] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.setProperties(props);
|
controller.setProperties(props);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
redirect() {
|
redirect() {
|
||||||
this.transitionTo('custom.index');
|
this.transitionTo("custom.index");
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
/* eslint no-undef: 0 */
|
/* eslint no-undef: 0 */
|
||||||
|
|
||||||
import { findCustomWizard } from '../models/custom';
|
import { findCustomWizard } from "../models/custom";
|
||||||
import { ajax } from 'wizard/lib/ajax';
|
import { ajax } from "wizard/lib/ajax";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
beforeModel(transition) {
|
beforeModel(transition) {
|
||||||
this.set('queryParams', transition.intent.queryParams);
|
this.set("queryParams", transition.intent.queryParams);
|
||||||
},
|
},
|
||||||
|
|
||||||
model(params) {
|
model(params) {
|
||||||
return findCustomWizard(params.wizard_id, this.get('queryParams'));
|
return findCustomWizard(params.wizard_id, this.get("queryParams"));
|
||||||
},
|
},
|
||||||
|
|
||||||
afterModel() {
|
afterModel() {
|
||||||
return ajax({
|
return ajax({
|
||||||
url: `/site/settings`,
|
url: `/site/settings`,
|
||||||
type: 'GET',
|
type: "GET",
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
$.extend(Wizard.SiteSettings, result);
|
$.extend(Wizard.SiteSettings, result);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const background = model ? model.get('background') : 'AliceBlue';
|
const background = model ? model.get("background") : "AliceBlue";
|
||||||
Ember.run.scheduleOnce('afterRender', this, function(){
|
Ember.run.scheduleOnce("afterRender", this, function () {
|
||||||
$('body.custom-wizard').css('background', background);
|
$("body.custom-wizard").css("background", background);
|
||||||
if (model) {
|
if (model) {
|
||||||
$('#custom-wizard-main').addClass(model.get('id').dasherize());
|
$("#custom-wizard-main").addClass(model.get("id").dasherize());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
customWizard: true,
|
customWizard: true,
|
||||||
logoUrl: Wizard.SiteSettings.logo_small,
|
logoUrl: Wizard.SiteSettings.logo_small,
|
||||||
reset: null
|
reset: null,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
Laden …
In neuem Issue referenzieren