aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/hooks/form.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/aml-backoffice-ui/src/hooks/form.ts')
-rw-r--r--packages/aml-backoffice-ui/src/hooks/form.ts249
1 files changed, 217 insertions, 32 deletions
diff --git a/packages/aml-backoffice-ui/src/hooks/form.ts b/packages/aml-backoffice-ui/src/hooks/form.ts
index 752444bd2..033d1d950 100644
--- a/packages/aml-backoffice-ui/src/hooks/form.ts
+++ b/packages/aml-backoffice-ui/src/hooks/form.ts
@@ -19,10 +19,11 @@ import {
AmountJson,
TalerExchangeApi,
TranslatedString,
+ assertUnreachable,
} from "@gnu-taler/taler-util";
-import { UIFieldHandler } from "@gnu-taler/web-util/browser";
+import { Addon, InternationalizationAPI, UIFieldBaseDescription, UIFieldHandler, UIFormField, UIFormFieldBaseConfig, UIFormFieldConfig, UIHandlerId } from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
-import { UIFormFieldConfig, UIHandlerId } from "../context/ui-forms.js";
+import { getConverterById } from "../utils/converter.js";
// export type UIField = {
// value: string | undefined;
@@ -93,41 +94,17 @@ function constructFormHandler<T>(
updateForm(setValueDeeper(form, path, newValue));
}
- const currentValue: unknown = getValueDeeper(form, path)
- const currentError: unknown = errors === undefined ? undefined : getValueDeeper(errors, path)
+ const currentValue = getValueDeeper<string>(form as any, path, undefined)
+ const currentError = getValueDeeper<TranslatedString>(errors as any, path, undefined)
const field: UIFieldHandler = {
- // @ts-expect-error FIXME better typing
error: currentError,
- // @ts-expect-error FIXME better typing
value: currentValue,
onChange: updater,
- state: {},
+ state: {}, //FIXME: add the state of the field (hidden, )
};
return setValueDeeper(handleForm, path, field)
- /**
- * There is no clear way to know if this object is a custom field
- * or a group of fields
- */
- // if (typeof currentValue === "object") {
- // // @ts-expect-error FIXME better typing
- // const group = constructFormHandler(currentValue, updater, currentError);
- // // @ts-expect-error FIXME better typing
- // prev[fieldName] = group;
- // return prev;
- // }
-
- // const field: UIFieldHandler = {
- // // @ts-expect-error FIXME better typing
- // error: currentError,
- // // @ts-expect-error FIXME better typing
- // value: currentValue,
- // onChange: updater,
- // state: {},
- // };
- // handleForm[fieldName] = field;
- // return handleForm;
}, {} as FormHandler<T>);
return handler;
@@ -156,22 +133,40 @@ export function useFormState<T>(
return [handler, status];
}
+interface Tree<T> extends Record<string, Tree<T> | T> {}
-function getValueDeeper(
+function getValueDeeper<T>(
+ object: Tree<T> | undefined,
+ names: string[],
+ notFoundValue?: T,
+): T | undefined {
+ if (names.length === 0) return object as T;
+ const [head, ...rest] = names;
+ if (!head) {
+ return getValueDeeper(object, rest, notFoundValue);
+ }
+ if (object === undefined) {
+ return notFoundValue
+ }
+ return getValueDeeper(object[head] as Tree<T>, rest, notFoundValue);
+}
+
+function getValueDeeper2(
object: Record<string, any>,
names: string[],
): UIFieldHandler {
if (names.length === 0) return object as UIFieldHandler;
const [head, ...rest] = names;
if (!head) {
- return getValueDeeper(object, rest);
+ return getValueDeeper2(object, rest);
}
if (object === undefined) {
throw Error("handler not found");
}
- return getValueDeeper(object[head], rest);
+ return getValueDeeper2(object[head], rest);
}
+
function setValueDeeper(object: any, names: string[], value: any): any {
if (names.length === 0) return value;
const [head, ...rest] = names;
@@ -183,3 +178,193 @@ function setValueDeeper(object: any, names: string[], value: any): any {
}
return { ...object, [head]: setValueDeeper(object[head] ?? {}, rest, value) };
}
+
+function getAddonById(_id: string | undefined): Addon {
+ return undefined!;
+}
+
+
+function converInputFieldsProps(
+ form: FormHandler<unknown>,
+ p: UIFormFieldBaseConfig,
+) {
+ return {
+ converter: getConverterById(p.converterId, p),
+ handler: getValueDeeper2(form, p.id.split(".")),
+ name: p.name,
+ required: p.required,
+ disabled: p.disabled,
+ help: p.help,
+ placeholder: p.placeholder,
+ tooltip: p.tooltip,
+ label: p.label as TranslatedString,
+ };
+}
+
+function converBaseFieldsProps(
+ i18n_: InternationalizationAPI,
+ p: UIFieldBaseDescription,
+) {
+ return {
+ after: getAddonById(p.addonAfterId),
+ before: getAddonById(p.addonBeforeId),
+ hidden: p.hidden,
+ name: p.name,
+ help: i18n_.str`${p.help}`,
+ label: i18n_.str`${p.label}`,
+ tooltip: i18n_.str`${p.tooltip}`,
+ };
+}
+
+export function convertUiField(
+ i18n_: InternationalizationAPI,
+ fieldConfig: UIFormFieldConfig[],
+ form: FormHandler<unknown>,
+): UIFormField[] {
+ return fieldConfig.map((config) => {
+ // NON input fields
+ switch (config.type) {
+ case "caption": {
+ const resp: UIFormField = {
+ type: config.type,
+ properties: converBaseFieldsProps(i18n_, config.properties),
+ };
+ return resp;
+ }
+ case "group": {
+ const resp: UIFormField = {
+ type: config.type,
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ fields: convertUiField(i18n_, config.properties.fields, form),
+ },
+ };
+ return resp;
+ }
+ }
+ // Input Fields
+ switch (config.type) {
+ case "array": {
+ return {
+ type: "array",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ labelField: config.properties.labelFieldId,
+ fields: convertUiField(i18n_, config.properties.fields, form),
+ },
+ } as UIFormField;
+ }
+ case "absoluteTime": {
+ return {
+ type: "absoluteTime",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ },
+ } as UIFormField;
+ }
+ case "amount": {
+ return {
+ type: "amount",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ },
+ } as UIFormField;
+ }
+ case "choiceHorizontal": {
+ return {
+ type: "choiceHorizontal",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ choices: config.properties.choices,
+ },
+ } as UIFormField;
+ }
+ case "choiceStacked": {
+ return {
+ type: "choiceStacked",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ choices: config.properties.choices,
+
+ },
+ }as UIFormField;
+ }
+ case "file":{
+ console.log("ASDASD", config.properties.accept)
+ return {
+ type: "file",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ accept: config.properties.accept,
+ maxBites: config.properties.maxBytes,
+ },
+ } as UIFormField;
+ }
+ case "integer":{
+ return {
+ type: "integer",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ },
+ } as UIFormField;
+ }
+ case "selectMultiple":{
+ return {
+ type: "selectMultiple",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ choices: config.properties.choices,
+ },
+ } as UIFormField;
+ }
+ case "selectOne": {
+ return {
+ type: "selectOne",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ choices: config.properties.choices,
+ },
+ } as UIFormField;
+ }
+ case "text": {
+ return {
+ type: "text",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ },
+ } as UIFormField;
+ }
+ case "textArea": {
+ return {
+ type: "text",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ },
+ } as UIFormField;
+ }
+ case "toggle": {
+ return {
+ type: "toggle",
+ properties: {
+ ...converBaseFieldsProps(i18n_, config.properties),
+ ...converInputFieldsProps(form, config.properties),
+ },
+ } as UIFormField;
+ }
+ default: {
+ assertUnreachable(config);
+ }
+ }
+ });
+}