diff options
author | Sebastian <sebasjm@gmail.com> | 2023-05-15 11:45:23 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-05-15 11:45:23 -0300 |
commit | f4f798b1b4bae3073b669a562fd2b3a7880dffc3 (patch) | |
tree | 90211e3188cf9d33f0fc468bca8f039cd89b313e /packages/exchange-backoffice-ui/src/handlers/forms.ts | |
parent | db03383325063b9388c7ffa583485c3cff2b25eb (diff) | |
download | wallet-core-f4f798b1b4bae3073b669a562fd2b3a7880dffc3.tar.xz |
second form
Diffstat (limited to 'packages/exchange-backoffice-ui/src/handlers/forms.ts')
-rw-r--r-- | packages/exchange-backoffice-ui/src/handlers/forms.ts | 93 |
1 files changed, 93 insertions, 0 deletions
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<typeof InputArray>[0]; + file: Parameters<typeof InputFile>[0]; + selectMultiple: Parameters<typeof InputSelectMultiple>[0]; + text: Parameters<typeof InputText>[0]; + textArea: Parameters<typeof InputTextArea>[0]; + choiceStacked: Parameters<typeof InputChoiceStacked>[0]; + date: Parameters<typeof InputDate>[0]; + integer: Parameters<typeof InputInteger>[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<key extends keyof FieldType> = ( + props: FieldType[key], +) => VNode; + +type UIFormFieldMap = { + [key in keyof FieldType]: FieldComponentFunction<key>; +}; + +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<any>; + const c = structuredClone(field.props); + c.key = i; + return Component(c); + }), + ); +} |