Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-24 02:10:29 +01:00
434 Zeilen
11 KiB
JavaScript
434 Zeilen
11 KiB
JavaScript
import { getOwner } from "@ember/application";
|
|
import Component from "@ember/component";
|
|
import { computed } from "@ember/object";
|
|
import { alias, equal, gt, or } from "@ember/object/computed";
|
|
import { bind, later } from "@ember/runloop";
|
|
import { service } from "@ember/service";
|
|
import $ from "jquery";
|
|
import {
|
|
default as discourseComputed,
|
|
observes,
|
|
} from "discourse-common/utils/decorators";
|
|
import I18n from "I18n";
|
|
import {
|
|
generateName,
|
|
sentenceCase,
|
|
snakeCase,
|
|
userProperties,
|
|
} from "../lib/wizard";
|
|
import { defaultSelectionType, selectionTypes } from "../lib/wizard-mapper";
|
|
|
|
const customFieldActionMap = {
|
|
topic: ["create_topic", "send_message"],
|
|
post: ["create_topic", "send_message"],
|
|
category: ["create_category"],
|
|
group: ["create_group"],
|
|
user: ["update_profile"],
|
|
};
|
|
|
|
const values = ["present", "true", "false"];
|
|
|
|
export default Component.extend({
|
|
classNameBindings: [":mapper-selector", "activeType"],
|
|
subscription: service(),
|
|
|
|
showText: computed("activeType", function () {
|
|
return this.showInput("text");
|
|
}),
|
|
showWizardField: computed("activeType", function () {
|
|
return this.showInput("wizardField");
|
|
}),
|
|
showWizardAction: computed("activeType", function () {
|
|
return this.showInput("wizardAction");
|
|
}),
|
|
showUserField: computed("activeType", function () {
|
|
return this.showInput("userField");
|
|
}),
|
|
showUserFieldOptions: computed("activeType", function () {
|
|
return this.showInput("userFieldOptions");
|
|
}),
|
|
showCategory: computed("activeType", function () {
|
|
return this.showInput("category");
|
|
}),
|
|
showTag: computed("activeType", function () {
|
|
return this.showInput("tag");
|
|
}),
|
|
showGroup: computed("activeType", function () {
|
|
return this.showInput("group");
|
|
}),
|
|
showUser: computed("activeType", function () {
|
|
return this.showInput("user");
|
|
}),
|
|
showList: computed("activeType", function () {
|
|
return this.showInput("list");
|
|
}),
|
|
showCustomField: computed("activeType", function () {
|
|
return this.showInput("customField");
|
|
}),
|
|
showValue: computed("activeType", function () {
|
|
return this.showInput("value");
|
|
}),
|
|
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");
|
|
}),
|
|
guestGroup: computed("options.guestGroup", "inputType", function () {
|
|
return this.optionEnabled("guestGroup");
|
|
}),
|
|
includeMessageableGroups: computed(
|
|
"options.includeMessageableGroups",
|
|
"inputType",
|
|
function () {
|
|
return this.optionEnabled("includeMessageableGroups");
|
|
}
|
|
),
|
|
userEnabled: computed("options.userSelection", "inputType", function () {
|
|
return this.optionEnabled("userSelection");
|
|
}),
|
|
listEnabled: computed("options.listSelection", "inputType", function () {
|
|
return this.optionEnabled("listSelection");
|
|
}),
|
|
valueEnabled: equal("connector", "is"),
|
|
|
|
@discourseComputed(
|
|
"site.groups",
|
|
"guestGroup",
|
|
"subscription.subscriptionType"
|
|
)
|
|
groups(groups, guestGroup, subscriptionType) {
|
|
let result = groups;
|
|
if (!guestGroup) {
|
|
return result;
|
|
}
|
|
|
|
if (["standard", "business"].includes(subscriptionType)) {
|
|
let guestIndex;
|
|
result.forEach((r, index) => {
|
|
if (r.id === 0) {
|
|
r.name = I18n.t("admin.wizard.selector.label.users");
|
|
guestIndex = index;
|
|
}
|
|
});
|
|
result.splice(guestIndex, 0, {
|
|
id: -1,
|
|
name: I18n.t("admin.wizard.selector.label.guests"),
|
|
});
|
|
}
|
|
|
|
return result;
|
|
},
|
|
categories: alias("site.categories"),
|
|
showComboBox: or(
|
|
"showWizardField",
|
|
"showWizardAction",
|
|
"showUserField",
|
|
"showUserFieldOptions",
|
|
"showCustomField",
|
|
"showValue"
|
|
),
|
|
showMultiSelect: or("showCategory", "showGroup"),
|
|
hasTypes: gt("selectorTypes.length", 1),
|
|
showTypes: false,
|
|
|
|
didInsertElement() {
|
|
this._super(...arguments);
|
|
if (
|
|
!this.activeType ||
|
|
(this.activeType && !this[`${this.activeType}Enabled`])
|
|
) {
|
|
later(() => this.resetActiveType());
|
|
}
|
|
|
|
$(document).on("click", bind(this, this.documentClick));
|
|
},
|
|
|
|
willDestroyElement() {
|
|
this._super(...arguments);
|
|
$(document).off("click", bind(this, this.documentClick));
|
|
},
|
|
|
|
documentClick(e) {
|
|
if (this._state === "destroying") {
|
|
return;
|
|
}
|
|
let $target = $(e.target);
|
|
|
|
if (!$target.parents(".type-selector").length && this.showTypes) {
|
|
this.set("showTypes", false);
|
|
}
|
|
},
|
|
|
|
@discourseComputed("connector")
|
|
selectorTypes() {
|
|
return selectionTypes
|
|
.filter((type) => this[`${type}Enabled`])
|
|
.map((type) => ({ type, label: this.typeLabel(type) }));
|
|
},
|
|
|
|
@discourseComputed("activeType")
|
|
activeTypeLabel(activeType) {
|
|
return this.typeLabel(activeType);
|
|
},
|
|
|
|
typeLabel(type) {
|
|
return type
|
|
? I18n.t(`admin.wizard.selector.label.${snakeCase(type)}`)
|
|
: null;
|
|
},
|
|
|
|
comboBoxAllowAny: or("showWizardField", "showWizardAction"),
|
|
|
|
@discourseComputed
|
|
showController() {
|
|
return getOwner(this).lookup("controller:admin-wizards-wizard-show");
|
|
},
|
|
|
|
@discourseComputed(
|
|
"activeType",
|
|
"showController.wizardFields.[]",
|
|
"showController.wizard.actions.[]",
|
|
"showController.userFields.[]",
|
|
"showController.currentField.id",
|
|
"showController.currentAction.id",
|
|
"showController.customFields"
|
|
)
|
|
comboBoxContent(
|
|
activeType,
|
|
wizardFields,
|
|
wizardActions,
|
|
userFields,
|
|
currentFieldId,
|
|
currentActionId,
|
|
customFields
|
|
) {
|
|
let content;
|
|
let context;
|
|
let contextType;
|
|
|
|
if (this.options.context) {
|
|
let contextAttrs = this.options.context.split(".");
|
|
context = contextAttrs[0];
|
|
contextType = contextAttrs[1];
|
|
}
|
|
|
|
if (activeType === "wizardField") {
|
|
content = wizardFields;
|
|
|
|
if (context === "field") {
|
|
content = content.filter((field) => field.id !== currentFieldId);
|
|
}
|
|
}
|
|
|
|
if (activeType === "wizardAction") {
|
|
content = wizardActions.map((a) => ({
|
|
id: a.id,
|
|
label: `${generateName(a.type)} (${a.id})`,
|
|
type: a.type,
|
|
}));
|
|
|
|
if (context === "action") {
|
|
content = content.filter((a) => a.id !== currentActionId);
|
|
}
|
|
}
|
|
|
|
if (activeType === "userField") {
|
|
content = userProperties
|
|
.map((f) => ({
|
|
id: f,
|
|
name: generateName(f),
|
|
}))
|
|
.concat(userFields || []);
|
|
|
|
if (
|
|
context === "action" &&
|
|
this.inputType === "association" &&
|
|
this.selectorType === "key"
|
|
) {
|
|
const excludedFields = ["username", "email", "trust_level"];
|
|
content = content.filter(
|
|
(userField) => excludedFields.indexOf(userField.id) === -1
|
|
);
|
|
}
|
|
}
|
|
|
|
if (activeType === "userFieldOptions") {
|
|
content = userFields;
|
|
}
|
|
|
|
if (activeType === "customField") {
|
|
content = customFields
|
|
.filter((f) => {
|
|
return (
|
|
f.type !== "json" &&
|
|
customFieldActionMap[f.klass].includes(contextType)
|
|
);
|
|
})
|
|
.map((f) => ({
|
|
id: f.name,
|
|
name: `${sentenceCase(f.klass)} ${f.name} (${f.type})`,
|
|
}));
|
|
}
|
|
|
|
if (activeType === "value") {
|
|
content = values.map((value) => ({
|
|
id: value,
|
|
name: value,
|
|
}));
|
|
}
|
|
|
|
return content;
|
|
},
|
|
|
|
@discourseComputed("activeType")
|
|
multiSelectContent(activeType) {
|
|
return {
|
|
category: this.categories,
|
|
group: this.groups,
|
|
list: "",
|
|
}[activeType];
|
|
},
|
|
|
|
@discourseComputed("activeType", "inputType")
|
|
placeholderKey(activeType) {
|
|
if (
|
|
activeType === "text" &&
|
|
this.options[`${this.selectorType}Placeholder`]
|
|
) {
|
|
return this.options[`${this.selectorType}Placeholder`];
|
|
} else {
|
|
return `admin.wizard.selector.placeholder.${snakeCase(activeType)}`;
|
|
}
|
|
},
|
|
|
|
@discourseComputed("activeType")
|
|
multiSelectOptions(activeType) {
|
|
let result = {
|
|
none: this.placeholderKey,
|
|
};
|
|
|
|
if (activeType === "list") {
|
|
result.allowAny = true;
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
@discourseComputed("includeMessageableGroups", "options.userLimit")
|
|
userOptions(includeMessageableGroups, userLimit) {
|
|
const opts = {
|
|
includeMessageableGroups,
|
|
};
|
|
if (userLimit) {
|
|
opts.maximum = userLimit;
|
|
}
|
|
return opts;
|
|
},
|
|
|
|
optionEnabled(type) {
|
|
const options = this.options;
|
|
if (!options) {
|
|
return false;
|
|
}
|
|
|
|
const option = options[type];
|
|
if (option === true) {
|
|
return true;
|
|
}
|
|
if (typeof option !== "string") {
|
|
return false;
|
|
}
|
|
|
|
return option.split(",").filter((o) => {
|
|
return [this.selectorType, this.inputType].indexOf(o) !== -1;
|
|
}).length;
|
|
},
|
|
|
|
showInput(type) {
|
|
return this.activeType === type && this[`${type}Enabled`];
|
|
},
|
|
|
|
changeValue(value) {
|
|
this.set("value", value);
|
|
this.onUpdate("selector", this.activeType);
|
|
},
|
|
|
|
@observes("inputType")
|
|
resetActiveType() {
|
|
this.set(
|
|
"activeType",
|
|
defaultSelectionType(this.selectorType, this.options, this.connector)
|
|
);
|
|
},
|
|
|
|
actions: {
|
|
toggleType(type) {
|
|
this.set("activeType", type);
|
|
this.set("showTypes", false);
|
|
this.set("value", null);
|
|
this.onUpdate("selector");
|
|
},
|
|
|
|
toggleTypes() {
|
|
this.toggleProperty("showTypes");
|
|
},
|
|
|
|
changeValue(value) {
|
|
this.changeValue(value);
|
|
},
|
|
|
|
changeInputValue(event) {
|
|
this.changeValue(event.target.value);
|
|
},
|
|
|
|
changeUserValue(value) {
|
|
this.changeValue(value);
|
|
},
|
|
},
|
|
});
|