From f4f798b1b4bae3073b669a562fd2b3a7880dffc3 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 15 May 2023 11:45:23 -0300 Subject: second form --- .../exchange-backoffice-ui/src/handlers/forms.ts | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 packages/exchange-backoffice-ui/src/handlers/forms.ts (limited to 'packages/exchange-backoffice-ui/src/handlers/forms.ts') diff --git a/packages/exchange-backoffice-ui/src/handlers/forms.ts b/packages/exchange-backoffice-ui/src/handlers/forms.ts new file mode 100644 index 000000000..b5d1a2b20 --- /dev/null +++ b/packages/exchange-backoffice-ui/src/handlers/forms.ts @@ -0,0 +1,93 @@ +import { TranslatedString } from "@gnu-taler/taler-util"; +import { InputText } from "./InputText.js"; +import { InputDate } from "./InputDate.js"; +import { InputInteger } from "./InputInteger.js"; +import { h as create, Fragment, VNode } from "preact"; +import { InputChoiceStacked } from "./InputChoice.js"; +import { InputArray } from "./InputArray.js"; +import { InputSelectMultiple } from "./InputSelectMultiple.js"; +import { InputTextArea } from "./InputTextArea.js"; +import { InputFile } from "./InputFile.js"; + +export type DoubleColumnForm = DoubleColumnFormSection[]; + +type DoubleColumnFormSection = { + title: TranslatedString; + description?: TranslatedString; + fields: UIFormField[]; +}; + +/** + * Constrain the type with the ui props + */ +type FieldType = { + separator: {}; + array: Parameters[0]; + file: Parameters[0]; + selectMultiple: Parameters[0]; + text: Parameters[0]; + textArea: Parameters[0]; + choiceStacked: Parameters[0]; + date: Parameters[0]; + integer: Parameters[0]; +}; + +/** + * List all the form fields so typescript can type-check the form instance + */ +export type UIFormField = + | { type: "separator"; props: FieldType["separator"] } + | { type: "array"; props: FieldType["array"] } + | { type: "file"; props: FieldType["file"] } + | { type: "selectMultiple"; props: FieldType["selectMultiple"] } + | { type: "text"; props: FieldType["text"] } + | { type: "textArea"; props: FieldType["textArea"] } + | { type: "choiceStacked"; props: FieldType["choiceStacked"] } + | { type: "integer"; props: FieldType["integer"] } + | { type: "date"; props: FieldType["date"] }; + +type FieldComponentFunction = ( + props: FieldType[key], +) => VNode; + +type UIFormFieldMap = { + [key in keyof FieldType]: FieldComponentFunction; +}; + +function Separator(): VNode { + return create("div", {}); +} + +/** + * Maps input type with component implementation + */ +const UIFormConfiguration: UIFormFieldMap = { + separator: Separator, + array: InputArray, + text: InputText, + file: InputFile, + textArea: InputTextArea, + date: InputDate, + choiceStacked: InputChoiceStacked, + integer: InputInteger, + selectMultiple: InputSelectMultiple, +}; + +export function RenderAllFieldsByUiConfig({ + fields, +}: { + fields: UIFormField[]; +}): VNode { + return create( + Fragment, + {}, + fields.map((field, i) => { + const Component = UIFormConfiguration[ + field.type + ] as FieldComponentFunction; + const c = structuredClone(field.props); + c.key = i; + return Component(c); + }), + ); +} -- cgit v1.2.3