2023-05-10 05:53:37 +02:00
|
|
|
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";
|
2023-05-16 06:23:44 +02:00
|
|
|
import { InputChoiceStacked } from "./InputChoiceStacked.js";
|
2023-05-10 05:53:37 +02:00
|
|
|
import { InputArray } from "./InputArray.js";
|
|
|
|
import { InputSelectMultiple } from "./InputSelectMultiple.js";
|
|
|
|
import { InputTextArea } from "./InputTextArea.js";
|
2023-05-11 20:49:28 +02:00
|
|
|
import { InputFile } from "./InputFile.js";
|
2023-05-16 16:33:29 +02:00
|
|
|
import { Caption } from "./Caption.js";
|
2023-05-16 06:23:44 +02:00
|
|
|
import { Group } from "./Group.js";
|
|
|
|
import { InputSelectOne } from "./InputSelectOne.js";
|
2023-05-19 18:26:47 +02:00
|
|
|
import { FormProvider } from "./FormProvider.js";
|
|
|
|
import { InputLine } from "./InputLine.js";
|
2023-05-10 05:53:37 +02:00
|
|
|
|
|
|
|
export type DoubleColumnForm = DoubleColumnFormSection[];
|
|
|
|
|
|
|
|
type DoubleColumnFormSection = {
|
|
|
|
title: TranslatedString;
|
|
|
|
description?: TranslatedString;
|
|
|
|
fields: UIFormField[];
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constrain the type with the ui props
|
|
|
|
*/
|
|
|
|
type FieldType = {
|
2023-05-16 06:23:44 +02:00
|
|
|
group: Parameters<typeof Group>[0];
|
2023-05-16 16:33:29 +02:00
|
|
|
caption: Parameters<typeof Caption>[0];
|
2023-05-10 05:53:37 +02:00
|
|
|
array: Parameters<typeof InputArray>[0];
|
2023-05-11 20:49:28 +02:00
|
|
|
file: Parameters<typeof InputFile>[0];
|
2023-05-16 06:23:44 +02:00
|
|
|
selectOne: Parameters<typeof InputSelectOne>[0];
|
2023-05-10 05:53:37 +02:00
|
|
|
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 =
|
2023-05-16 06:23:44 +02:00
|
|
|
| { type: "group"; props: FieldType["group"] }
|
2023-05-16 16:33:29 +02:00
|
|
|
| { type: "caption"; props: FieldType["caption"] }
|
2023-05-10 05:53:37 +02:00
|
|
|
| { type: "array"; props: FieldType["array"] }
|
2023-05-11 20:49:28 +02:00
|
|
|
| { type: "file"; props: FieldType["file"] }
|
2023-05-16 06:23:44 +02:00
|
|
|
| { type: "selectOne"; props: FieldType["selectOne"] }
|
2023-05-10 05:53:37 +02:00
|
|
|
| { 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>;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Maps input type with component implementation
|
|
|
|
*/
|
|
|
|
const UIFormConfiguration: UIFormFieldMap = {
|
2023-05-16 06:23:44 +02:00
|
|
|
group: Group,
|
2023-05-16 16:33:29 +02:00
|
|
|
caption: Caption,
|
2023-05-10 05:53:37 +02:00
|
|
|
array: InputArray,
|
|
|
|
text: InputText,
|
2023-05-11 20:49:28 +02:00
|
|
|
file: InputFile,
|
2023-05-10 05:53:37 +02:00
|
|
|
textArea: InputTextArea,
|
|
|
|
date: InputDate,
|
|
|
|
choiceStacked: InputChoiceStacked,
|
|
|
|
integer: InputInteger,
|
2023-05-16 06:23:44 +02:00
|
|
|
selectOne: InputSelectOne,
|
2023-05-10 05:53:37 +02:00
|
|
|
selectMultiple: InputSelectMultiple,
|
|
|
|
};
|
|
|
|
|
|
|
|
export function RenderAllFieldsByUiConfig({
|
|
|
|
fields,
|
|
|
|
}: {
|
|
|
|
fields: UIFormField[];
|
|
|
|
}): VNode {
|
|
|
|
return create(
|
|
|
|
Fragment,
|
|
|
|
{},
|
2023-05-15 16:45:23 +02:00
|
|
|
fields.map((field, i) => {
|
2023-05-10 05:53:37 +02:00
|
|
|
const Component = UIFormConfiguration[
|
|
|
|
field.type
|
|
|
|
] as FieldComponentFunction<any>;
|
2023-05-16 16:33:29 +02:00
|
|
|
return Component(field.props);
|
2023-05-10 05:53:37 +02:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
2023-05-19 18:26:47 +02:00
|
|
|
|
|
|
|
type FormSet<T> = {
|
|
|
|
Provider: typeof FormProvider<T>;
|
|
|
|
InputLine: typeof InputLine<T>;
|
|
|
|
};
|
|
|
|
export function createNewForm<T>(): FormSet<T> {
|
|
|
|
return {
|
|
|
|
Provider: FormProvider,
|
|
|
|
InputLine: InputLine,
|
|
|
|
};
|
|
|
|
}
|