import { toKebabCase, toPascalCase } from "js-convert-case"; import { formTemplate } from "../form.js"; import extract_fields_from_collection from "../../utils/extract-fields-from-collection.js"; import { wrapAttribute } from "../../utils/wrap-attributes.js"; export async function editItemFormTemplate( edit_action_name: string, newfilefullpath: string, collection_name: string, list_action: string ): Promise { const collection_fields = await extract_fields_from_collection(collection_name); const formFieldsGetterVar = `get${toPascalCase(collection_name)}FormFields`; const collectionVar = `${toPascalCase(collection_name)}`; return formTemplate(edit_action_name, { success_message: "Changes saved!", postimport: `import {${formFieldsGetterVar}, get${toPascalCase( collection_name )}FormControls }from "../shared.js"; import { ${collectionVar} } from "src/back/collections/collections.js"; import { ${list_action}URL } from "src/back/routes/urls.js"; import {tempstream} from "tempstream"; import type { FormDataValue } from "@sealcode/sealgen"; import type { CollectionInputWithAllKeys } from "sealious"; `, get_fields: formFieldsGetterVar, get_controls: `(fields: ReturnType)=>[ new Controls.FormHeader("Edit ${toPascalCase( collection_name )}"), ...get${toPascalCase(collection_name)}FormControls(fields)]`, can_access: `canAccess = async (ctx: Context) => { const policy = ${toPascalCase(collection_name)}.getPolicy("edit"); const response = await policy.check(ctx.$context, async () => { const id = await this.getID(ctx); const { items: [item], } = await ctx.$app.collections${wrapAttribute(collection_name)}.list(ctx.$context).ids([id]).fetch(); return item!; }); return { canAccess: response?.allowed || false, message: response?.reason || "" }; };`, onsubmit: ` async onSubmit(ctx: Context, formData: FormData) { const fctx = this.makeFormControlContext(ctx, formData, true); const id = await this.getID(ctx); const {items: [item]} = await ctx.$app.collections["${toKebabCase( collection_name )}"] .list(ctx.$context) .ids([id]) .fetch(); if (!item) { throw new Error("Unknown id: " + id); } item.setMultipleExtraSafe( { ${collection_fields .map((field_info) => field_info.form_field.generateCreateValueGetter( field_info, { form_field_types: "FormFieldTypes", sealious_field: `${collectionVar}.fields${wrapAttribute( field_info.name )}`, form_fields: "this.fields", } ) ) .join(",\n")} } as CollectionInputWithAllKeys ); await item.save(ctx.$context); for(const field of Object.values(this.fields)){ // eslint-disable-next-line no-await-in-loop await field.postSealiousEdit(ctx, item, formData) } } `, other_methods: ` async getID(ctx: Context): Promise{ const param_name = "id"; const id = ctx.params[param_name]; if (!id) { throw new Error("Missing URL parameter: " + param_name); } return id } `, get_initial_values: `async getInitialValues(ctx: Context): Promise<{ [key in keyof typeof this.fields]: FormDataValue | undefined }> { const id = await this.getID(ctx); const { items: [item], } = await ctx.$app.collections["${toKebabCase(collection_name)}"] .list(ctx.$context) .ids([id]) .attach({}) .fetch(); if (!item) { throw new Error("Item with given id not found: " + id); } return { ${collection_fields .map((field_info) => field_info.form_field.generateInitialValue(field_info, { form_field_types: "FieldTypes", form_fields: "this.fields", }) ) .join(",\n")} }; } `, render: ` async render(ctx: Context, data: FormData, show_field_errors: boolean) { return html({ ctx, title: "Edit ${toPascalCase(collection_name)}", body: tempstream/* HTML */ \`
← Back to ${collection_name} list \${await super.render(ctx, data, show_field_errors)}
\`, description: "", css_clumps: ["admin-forms"]} ); }`, }); }