import EmberObject from "@ember/object"; import { Promise } from "rsvp"; import { ajax } from "discourse/lib/ajax"; import { popupAjaxError } from "discourse/lib/ajax-error"; import discourseComputed from "discourse-common/utils/decorators"; import { listProperties, snakeCase } from "../lib/wizard"; import { buildProperties, mapped, present } from "../lib/wizard-json"; import wizardSchema from "../lib/wizard-schema"; const GUEST_GROUP_ID = -1; const CustomWizardAdmin = EmberObject.extend({ @discourseComputed("permitted.@each.output") allowGuests(permitted) { return ( permitted && permitted.filter((p) => p.output && p.output.includes(GUEST_GROUP_ID)) .length ); }, save(opts) { return new Promise((resolve, reject) => { let wizard = this.buildJson(this, "wizard"); if (wizard.error) { reject(wizard); } let data = { wizard, }; if (opts.create) { data.create = true; } ajax(`/admin/wizards/wizard/${wizard.id}`, { type: "PUT", contentType: "application/json", data: JSON.stringify(data), }).then((result) => { if (result.backend_validation_error) { reject(result); } else { resolve(result); } }); }); }, buildJson(object, type, result = {}) { let objectType = object.type || null; if (wizardSchema[type].types) { if (!objectType) { result.error = { type: "required", params: { type, property: "type" }, }; return result; } } for (let property of listProperties(type, { objectType })) { let value = object.get(property); result = this.validateValue(property, value, object, type, result); if (result.error) { break; } if (mapped(property, type)) { value = this.buildMappedJson(value); } if (value !== undefined && value !== null) { result[property] = value; } } if (!result.error) { for (let arrayObjectType of Object.keys( wizardSchema[type].objectArrays )) { let arraySchema = wizardSchema[type].objectArrays[arrayObjectType]; let objectArray = object.get(arraySchema.property); if (arraySchema.required && !present(objectArray)) { result.error = { type: "required", params: { type, property: arraySchema.property }, }; break; } result[arraySchema.property] = []; for (let item of objectArray) { let itemProps = this.buildJson(item, arrayObjectType); if (itemProps.error) { result.error = itemProps.error; break; } else { result[arraySchema.property].push(itemProps); } } } } return result; }, validateValue(property, value, object, type, result) { if (wizardSchema[type].required.indexOf(property) > -1 && !value) { result.error = { type: "required", params: { type, property }, }; } let dependent = wizardSchema[type].dependent[property]; if (dependent && value && !object[dependent]) { result.error = { type: "dependent", params: { property, dependent }, }; } if (property === "api_body") { try { value = JSON.parse(value); } catch { result.error = { type: "invalid", params: { type, property }, }; } } return result; }, buildMappedJson(value) { if (typeof value === "string" || Number.isInteger(value)) { return value; } if (!value || !value.length) { return false; } let inputs = value; let result = []; inputs.forEach((inpt) => { let input = { type: inpt.type, }; if (inpt.connector) { input.connector = inpt.connector; } if (present(inpt.output)) { input.output = inpt.output; input.output_type = snakeCase(inpt.output_type); input.output_connector = inpt.output_connector; } if (present(inpt.pairs)) { input.pairs = []; inpt.pairs.forEach((pr) => { if (present(pr.key) && present(pr.value)) { let pairParams = { index: pr.index, key: pr.key, key_type: snakeCase(pr.key_type), value: pr.value, value_type: snakeCase(pr.value_type), connector: pr.connector, }; input.pairs.push(pairParams); } }); } if ( (input.type === "assignment" && present(input.output)) || present(input.pairs) ) { result.push(input); } }); if (!result.length) { result = false; } return result; }, remove() { return ajax(`/admin/wizards/wizard/${this.id}`, { type: "DELETE", }) .then(() => this.destroy()) .catch(popupAjaxError); }, }); CustomWizardAdmin.reopenClass({ all() { return ajax("/admin/wizards/wizard", { type: "GET", }) .then((result) => { return result.wizard_list; }) .catch(popupAjaxError); }, submissions(wizardId, page = 0) { return ajax(`/admin/wizards/submissions/${wizardId}`, { type: "GET", data: { page, }, }).catch(popupAjaxError); }, create(wizardJson = {}) { const wizard = this._super.apply(this); wizard.setProperties(buildProperties(wizardJson)); return wizard; }, }); export default CustomWizardAdmin;