diff options
Diffstat (limited to 'packages/web-util')
-rw-r--r-- | packages/web-util/src/forms/InputAbsoluteTime.stories.tsx | 2 | ||||
-rw-r--r-- | packages/web-util/src/forms/InputAmount.tsx | 29 | ||||
-rw-r--r-- | packages/web-util/src/forms/InputArray.tsx | 28 | ||||
-rw-r--r-- | packages/web-util/src/forms/InputChoiceHorizontal.tsx | 5 | ||||
-rw-r--r-- | packages/web-util/src/forms/converter.ts | 21 | ||||
-rw-r--r-- | packages/web-util/src/forms/forms.ts | 93 | ||||
-rw-r--r-- | packages/web-util/src/forms/ui-form.ts | 382 |
7 files changed, 253 insertions, 307 deletions
diff --git a/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx b/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx index 0d54c3f69..6b792bfee 100644 --- a/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx +++ b/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx @@ -47,7 +47,7 @@ const form: FlexibleForm_Deprecated<TargetObject> = { design: [{ title: "this is a simple form" as TranslatedString, fields: [{ - type: "absoluteTime", + type: "absoluteTimeText", properties: { label: "label of the field" as TranslatedString, name: "today", diff --git a/packages/web-util/src/forms/InputAmount.tsx b/packages/web-util/src/forms/InputAmount.tsx index e8683468e..647d2c823 100644 --- a/packages/web-util/src/forms/InputAmount.tsx +++ b/packages/web-util/src/forms/InputAmount.tsx @@ -18,25 +18,26 @@ export function InputAmount<T extends object, K extends keyof T>( : (value as any).currency; return ( <InputLine<T, K> + {...props} type="text" before={{ type: "text", text: currency as TranslatedString, }} - //@ts-ignore - converter={ props.converter ?? { - - fromStringUI: (v): AmountJson => { - return ( - Amounts.parse(`${currency}:${v}`) ?? - Amounts.zeroOfCurrency(currency) - ); - }, - toStringUI: (v: AmountJson) => { - return v === undefined ? "" : Amounts.stringifyValue(v); - }, - }} - {...props} + //@ts-ignore + converter={ + props.converter ?? { + fromStringUI: (v): AmountJson => { + return ( + Amounts.parse(`${currency}:${v}`) ?? + Amounts.zeroOfCurrency(currency) + ); + }, + toStringUI: (v: AmountJson) => { + return v === undefined ? "" : Amounts.stringifyValue(v); + }, + } + } /> ); } diff --git a/packages/web-util/src/forms/InputArray.tsx b/packages/web-util/src/forms/InputArray.tsx index 1ac96437c..d90028508 100644 --- a/packages/web-util/src/forms/InputArray.tsx +++ b/packages/web-util/src/forms/InputArray.tsx @@ -99,7 +99,7 @@ export function InputArray<T extends object, K extends keyof T>( const [selectedIndex, setSelected] = useState<number | undefined>(undefined); const selected = selectedIndex === undefined ? undefined : list[selectedIndex]; - + return ( <div class="sm:col-span-6"> <LabelWithTooltipMaybeRequired @@ -110,9 +110,10 @@ export function InputArray<T extends object, K extends keyof T>( <div class="-space-y-px rounded-md bg-white "> {list.map((v, idx) => { + const label = getValueDeeper(v, labelField.split(".")) return ( <Option - label={v[labelField] as TranslatedString} + label={label as TranslatedString} key={idx} isSelected={selectedIndex === idx} isLast={idx === list.length - 1} @@ -158,7 +159,7 @@ export function InputArray<T extends object, K extends keyof T>( // elements should be present in the state object since this is expected to be an array //@ts-ignore // return state.elements[selectedIndex]; - return {} + return {}; }} onSubmit={(v) => { const newValue = [...list]; @@ -202,3 +203,24 @@ export function InputArray<T extends object, K extends keyof T>( </div> ); } + + + +export function getValueDeeper( + object: Record<string, any>, + names: string[], +): string { + if (names.length === 0) { + return object as any as string; + } + const [head, ...rest] = names; + if (!head) { + return getValueDeeper(object, rest); + } + if (object === undefined) { + return "" + } + return getValueDeeper(object[head], rest); +} + + diff --git a/packages/web-util/src/forms/InputChoiceHorizontal.tsx b/packages/web-util/src/forms/InputChoiceHorizontal.tsx index d8361718d..86d3aa926 100644 --- a/packages/web-util/src/forms/InputChoiceHorizontal.tsx +++ b/packages/web-util/src/forms/InputChoiceHorizontal.tsx @@ -34,11 +34,12 @@ export function InputChoiceHorizontal<T extends object, K extends keyof T>( <fieldset class="mt-2"> <div class="isolate inline-flex rounded-md shadow-sm"> {choices.map((choice, idx) => { + const convertedValue = converter?.fromStringUI(choice.value as any) const isFirst = idx === 0; const isLast = idx === choices.length - 1; let clazz = "relative inline-flex items-center px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 focus:z-10"; - if (converter?.fromStringUI(choice.value as any) === value) { + if (convertedValue !== undefined && convertedValue === value) { clazz += " text-white bg-indigo-600 hover:bg-indigo-500 ring-2 ring-indigo-600 hover:ring-indigo-500"; } else { @@ -61,7 +62,7 @@ export function InputChoiceHorizontal<T extends object, K extends keyof T>( class={clazz} onClick={(e) => { onChange( - (value === choice.value ? undefined : converter?.fromStringUI(choice.value as any)) as any, + (value === choice.value ? undefined : convertedValue) as any, ); }} > diff --git a/packages/web-util/src/forms/converter.ts b/packages/web-util/src/forms/converter.ts index 3a522bf7e..eee891776 100644 --- a/packages/web-util/src/forms/converter.ts +++ b/packages/web-util/src/forms/converter.ts @@ -53,6 +53,15 @@ function parseAmlState(s: string | undefined): TalerExchangeApi.AmlState { } } +const nullConverter: StringConverter<string> = { + fromStringUI(v: string | undefined): string { + return v ?? ""; + }, + toStringUI(v: unknown): string { + return v as string; + }, +}; + function amountConverter(config: any): StringConverter<AmountJson> { const currency = config["currency"]; if (!currency || typeof currency !== "string") { @@ -61,7 +70,9 @@ function amountConverter(config: any): StringConverter<AmountJson> { return { fromStringUI(v: string | undefined): AmountJson { // FIXME: requires currency - return Amounts.parse(`${currency}:${v}`) ?? Amounts.zeroOfCurrency(currency); + return ( + Amounts.parse(`${currency}:${v}`) ?? Amounts.zeroOfCurrency(currency) + ); }, toStringUI(v: unknown): string { return v === undefined ? "" : Amounts.stringifyValue(v as AmountJson); @@ -82,7 +93,7 @@ function absTimeConverter(config: any): StringConverter<AbsoluteTime> { try { const time = parse(v, pattern, new Date()); return AbsoluteTime.fromMilliseconds(time.getTime()); - } catch(e) { + } catch (e) { return AbsoluteTime.never(); } }, @@ -91,9 +102,9 @@ function absTimeConverter(config: any): StringConverter<AbsoluteTime> { const d = v as AbsoluteTime; if (d.t_ms === "never") return "never"; try { - return format(d.t_ms, pattern) + return format(d.t_ms, pattern); } catch (e) { - return "" + return ""; } }, }; @@ -115,5 +126,5 @@ export function getConverterById( // @ts-expect-error check this return amlStateConverter; } - return undefined!; + return nullConverter as StringConverter<unknown>; } diff --git a/packages/web-util/src/forms/forms.ts b/packages/web-util/src/forms/forms.ts index 4bd6b4924..4c5050830 100644 --- a/packages/web-util/src/forms/forms.ts +++ b/packages/web-util/src/forms/forms.ts @@ -14,9 +14,9 @@ import { InputText } from "./InputText.js"; import { InputTextArea } from "./InputTextArea.js"; import { InputToggle } from "./InputToggle.js"; import { Addon, StringConverter, UIFieldHandler } from "./FormProvider.js"; -import { InternationalizationAPI, UIFieldBaseDescription } from "../index.browser.js"; +import { InternationalizationAPI, UIFieldElementDescription } from "../index.browser.js"; import { assertUnreachable, TranslatedString } from "@gnu-taler/taler-util"; -import {UIFormFieldBaseConfig, UIFormFieldConfig} from "./ui-form.js"; +import {UIFormFieldBaseConfig, UIFormElementConfig} from "./ui-form.js"; /** * Constrain the type with the ui props */ @@ -31,7 +31,7 @@ type FieldType<T extends object = any, K extends keyof T = any> = { textArea: Parameters<typeof InputTextArea<T, K>>[0]; choiceStacked: Parameters<typeof InputChoiceStacked<T, K>>[0]; choiceHorizontal: Parameters<typeof InputChoiceHorizontal<T, K>>[0]; - absoluteTime: Parameters<typeof InputAbsoluteTime<T, K>>[0]; + absoluteTimeText: Parameters<typeof InputAbsoluteTime<T, K>>[0]; integer: Parameters<typeof InputInteger<T, K>>[0]; toggle: Parameters<typeof InputToggle<T, K>>[0]; amount: Parameters<typeof InputAmount<T, K>>[0]; @@ -64,8 +64,8 @@ export type UIFormField = | { type: "integer"; properties: FieldType["integer"] } | { type: "toggle"; properties: FieldType["toggle"] } | { - type: "absoluteTime"; - properties: FieldType["absoluteTime"]; + type: "absoluteTimeText"; + properties: FieldType["absoluteTimeText"]; }; type FieldComponentFunction<key extends keyof FieldType> = ( @@ -89,7 +89,7 @@ const UIFormConfiguration: UIFormFieldMap = { file: InputFile, textArea: InputTextArea, //@ts-ignore - absoluteTime: InputAbsoluteTime, + absoluteTimeText: InputAbsoluteTime, //@ts-ignore choiceStacked: InputChoiceStacked, //@ts-ignore @@ -156,7 +156,7 @@ export function RenderAllFieldsByUiConfig({ */ export function convertUiField( i18n_: InternationalizationAPI, - fieldConfig: UIFormFieldConfig[], + fieldConfig: UIFormElementConfig[], form: object, getConverterById: GetConverterById, ): UIFormField[] { @@ -166,7 +166,7 @@ export function convertUiField( case "caption": { const resp: UIFormField = { type: config.type, - properties: converBaseFieldsProps(i18n_, config.properties), + properties: converBaseFieldsProps(i18n_, config), }; return resp; } @@ -174,8 +174,8 @@ export function convertUiField( const resp: UIFormField = { type: config.type, properties: { - ...converBaseFieldsProps(i18n_, config.properties), - fields: convertUiField(i18n_, config.properties.fields, form, getConverterById), + ...converBaseFieldsProps(i18n_, config), + fields: convertUiField(i18n_, config.fields, form, getConverterById), }, }; return resp; @@ -187,19 +187,19 @@ export function convertUiField( return { type: "array", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), - labelField: config.properties.labelFieldId, - fields: convertUiField(i18n_, config.properties.fields, form, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + labelField: config.labelFieldId, + fields: convertUiField(i18n_, config.fields, form, getConverterById), }, } as UIFormField; } - case "absoluteTime": { + case "absoluteTimeText": { return { - type: "absoluteTime", + type: "absoluteTimeText", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), }, } as UIFormField; } @@ -207,8 +207,9 @@ export function convertUiField( return { type: "amount", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + currency: config.currency, }, } as UIFormField; } @@ -216,9 +217,9 @@ export function convertUiField( return { type: "choiceHorizontal", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), - choices: config.properties.choices, + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + choices: config.choices, }, } as UIFormField; } @@ -226,9 +227,9 @@ export function convertUiField( return { type: "choiceStacked", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), - choices: config.properties.choices, + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + choices: config.choices, }, }as UIFormField; @@ -237,10 +238,10 @@ export function convertUiField( return { type: "file", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), - accept: config.properties.accept, - maxBites: config.properties.maxBytes, + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + accept: config.accept, + maxBites: config.maxBytes, }, } as UIFormField; } @@ -248,8 +249,8 @@ export function convertUiField( return { type: "integer", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), }, } as UIFormField; } @@ -257,9 +258,9 @@ export function convertUiField( return { type: "selectMultiple", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), - choices: config.properties.choices, + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + choices: config.choices, }, } as UIFormField; } @@ -267,9 +268,9 @@ export function convertUiField( return { type: "selectOne", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), - choices: config.properties.choices, + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), + choices: config.choices, }, } as UIFormField; } @@ -277,8 +278,8 @@ export function convertUiField( return { type: "text", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), }, } as UIFormField; } @@ -286,8 +287,8 @@ export function convertUiField( return { type: "text", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), }, } as UIFormField; } @@ -295,8 +296,8 @@ export function convertUiField( return { type: "toggle", properties: { - ...converBaseFieldsProps(i18n_, config.properties), - ...converInputFieldsProps(form, config.properties, getConverterById), + ...converBaseFieldsProps(i18n_, config), + ...converInputFieldsProps(form, config, getConverterById), }, } as UIFormField; } @@ -340,7 +341,7 @@ function converInputFieldsProps( function converBaseFieldsProps( i18n_: InternationalizationAPI, - p: UIFieldBaseDescription, + p: UIFieldElementDescription, ) { return { after: getAddonById(p.addonAfterId), @@ -353,7 +354,7 @@ function converBaseFieldsProps( }; } -function getValueDeeper2( +export function getValueDeeper2( object: Record<string, any>, names: string[], ): UIFieldHandler { diff --git a/packages/web-util/src/forms/ui-form.ts b/packages/web-util/src/forms/ui-form.ts index ef9ad96e1..012499d6d 100644 --- a/packages/web-util/src/forms/ui-form.ts +++ b/packages/web-util/src/forms/ui-form.ts @@ -14,18 +14,18 @@ import { TalerProtocolTimestamp, } from "@gnu-taler/taler-util"; -export type FlexibleForm = DoubleColumnForm; +export type FormConfiguration = DoubleColumnForm; -export interface DoubleColumnForm { +export type DoubleColumnForm = { type: "double-column"; - design: Array<DoubleColumnFormSection>; + design: DoubleColumnFormSection[]; // behavior?: (form: Partial<T>) => FormState<T>; -} +}; export type DoubleColumnFormSection = { title: string; description?: string; - fields: UIFormFieldConfig[]; + fields: UIFormElementConfig[]; }; // export interface BaseForm { @@ -33,92 +33,74 @@ export type DoubleColumnFormSection = { // threshold: AmountJson; // } -export type UIFormFieldConfig = - | UIFormFieldConfigAbsoluteTime - | UIFormFieldConfigAmount - | UIFormFieldConfigArray - | UIFormFieldConfigCaption - | UIFormFieldConfigChoiseHorizontal - | UIFormFieldConfigChoiseStacked - | UIFormFieldConfigFile - | UIFormFieldConfigGroup - | UIFormFieldConfigInteger - | UIFormFieldConfigSelectMultiple - | UIFormFieldConfigSelectOne - | UIFormFieldConfigText - | UIFormFieldConfigTextArea - | UIFormFieldConfigToggle; - -type UIFormFieldConfigAbsoluteTime = { - type: "absoluteTime"; - properties: UIFormFieldBaseConfig & { - max?: TalerProtocolTimestamp; - min?: TalerProtocolTimestamp; - pattern: string; - }; -}; - -type UIFormFieldConfigAmount = { +export type UIFormElementConfig = + | UIFormElementGroup + | UIFormElementCaption + | UIFormFieldAbsoluteTime + | UIFormFieldAmount + | UIFormFieldArray + | UIFormFieldChoiseHorizontal + | UIFormFieldChoiseStacked + | UIFormFieldFile + | UIFormFieldInteger + | UIFormFieldSelectMultiple + | UIFormFieldSelectOne + | UIFormFieldText + | UIFormFieldTextArea + | UIFormFieldToggle; + +type UIFormFieldAbsoluteTime = { + type: "absoluteTimeText"; + max?: TalerProtocolTimestamp; + min?: TalerProtocolTimestamp; + pattern: string; +} & UIFormFieldBaseConfig; + +type UIFormFieldAmount = { type: "amount"; - properties: UIFormFieldBaseConfig & { - max?: Integer; - min?: Integer; - currency: string; - }; -}; + max?: Integer; + min?: Integer; + currency: string; +} & UIFormFieldBaseConfig; -type UIFormFieldConfigArray = { +type UIFormFieldArray = { type: "array"; - properties: UIFormFieldBaseConfig & { - // id of the field shown when the array is collapsed - labelFieldId: UIHandlerId; - fields: UIFormFieldConfig[]; - }; -}; + // id of the field shown when the array is collapsed + labelFieldId: UIHandlerId; + fields: UIFormElementConfig[]; +} & UIFormFieldBaseConfig; -type UIFormFieldConfigCaption = { - type: "caption"; - properties: UIFieldBaseDescription; -}; +type UIFormElementCaption = { type: "caption" } & UIFieldElementDescription; -type UIFormFieldConfigGroup = { +type UIFormElementGroup = { type: "group"; - properties: UIFieldBaseDescription & { - fields: UIFormFieldConfig[]; - }; -}; + fields: UIFormElementConfig[]; +} & UIFieldElementDescription; -type UIFormFieldConfigChoiseHorizontal = { +type UIFormFieldChoiseHorizontal = { type: "choiceHorizontal"; - properties: UIFormFieldBaseConfig & { - choices: Array<SelectUiChoice>; - }; -}; + choices: Array<SelectUiChoice>; +} & UIFormFieldBaseConfig; -type UIFormFieldConfigChoiseStacked = { +type UIFormFieldChoiseStacked = { type: "choiceStacked"; - properties: UIFormFieldBaseConfig & { - choices: Array<SelectUiChoice>; - }; -}; + choices: Array<SelectUiChoice>; +} & UIFormFieldBaseConfig; -type UIFormFieldConfigFile = { +type UIFormFieldFile = { type: "file"; - properties: UIFormFieldBaseConfig & { - maxBytes?: Integer; - minBytes?: Integer; - // comma-separated list of one or more file types - // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept#unique_file_type_specifiers - accept?: string; - }; -}; -type UIFormFieldConfigInteger = { + maxBytes?: Integer; + minBytes?: Integer; + // comma-separated list of one or more file types + // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept#unique_file_type_specifiers + accept?: string; +} & UIFormFieldBaseConfig; + +type UIFormFieldInteger = { type: "integer"; - properties: UIFormFieldBaseConfig & { - max?: Integer; - min?: Integer; - }; -}; + max?: Integer; + min?: Integer; +} & UIFormFieldBaseConfig; interface SelectUiChoice { label: string; @@ -126,41 +108,30 @@ interface SelectUiChoice { value: string; } -type UIFormFieldConfigSelectMultiple = { +type UIFormFieldSelectMultiple = { type: "selectMultiple"; - properties: UIFormFieldBaseConfig & { - max?: Integer; - min?: Integer; - unique?: boolean; - choices: Array<SelectUiChoice>; - }; -}; -type UIFormFieldConfigSelectOne = { + max?: Integer; + min?: Integer; + unique?: boolean; + choices: Array<SelectUiChoice>; +} & UIFormFieldBaseConfig; + +type UIFormFieldSelectOne = { type: "selectOne"; - properties: UIFormFieldBaseConfig & { - choices: Array<SelectUiChoice>; - }; -}; -type UIFormFieldConfigText = { - type: "text"; - properties: UIFormFieldBaseConfig; -}; -type UIFormFieldConfigTextArea = { - type: "textArea"; - properties: UIFormFieldBaseConfig; -}; -type UIFormFieldConfigToggle = { - type: "toggle"; - properties: UIFormFieldBaseConfig; -}; + choices: Array<SelectUiChoice>; +} & UIFormFieldBaseConfig; +type UIFormFieldText = { type: "text" } & UIFormFieldBaseConfig; +type UIFormFieldTextArea = { type: "textArea" } & UIFormFieldBaseConfig; +type UIFormFieldToggle = { type: "toggle" } & UIFormFieldBaseConfig; -export type UIFieldBaseDescription = { +export type UIFieldElementDescription = { /* label if the field, visible for the user */ label: string; + /* long text to be shown on user demand */ tooltip?: string; - /* short text to be shown close to the field */ + /* short text to be shown close to the field, usually below and dimmer*/ help?: string; /* name of the field, useful for a11y */ @@ -168,13 +139,15 @@ export type UIFieldBaseDescription = { /* if the field should be initially hidden */ hidden?: boolean; + /* ui element to show before */ addonBeforeId?: string; + /* ui element to show after */ addonAfterId?: string; }; -export type UIFormFieldBaseConfig = UIFieldBaseDescription & { +export type UIFormFieldBaseConfig = UIFieldElementDescription & { /* example to be shown inside the field */ placeholder?: string; @@ -200,7 +173,7 @@ export type UIHandlerId = string & { [__handlerId]: true }; const codecForUiFieldId = codecForString as () => Codec<UIHandlerId>; const codecForUIFormFieldBaseDescriptionTemplate = < - T extends UIFieldBaseDescription, + T extends UIFieldElementDescription, >() => buildCodecForObject<T>() .property("addonAfterId", codecOptional(codecForString())) @@ -221,62 +194,35 @@ const codecForUIFormFieldBaseConfigTemplate = < .property("required", codecOptional(codecForBoolean())) .property("placeholder", codecOptional(codecForString())); -const codecForUIFormFieldBaseConfig = (): Codec<UIFormFieldBaseConfig> => - codecForUIFormFieldBaseConfigTemplate().build("UIFieldToggleProperties"); - -const codecForUIFormFieldAbsoluteTimeConfig = (): Codec< - UIFormFieldConfigAbsoluteTime["properties"] -> => - codecForUIFormFieldBaseConfigTemplate< - UIFormFieldConfigAbsoluteTime["properties"] - >() +const codecForUiFormFieldAbsoluteTime = (): Codec<UIFormFieldAbsoluteTime> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldAbsoluteTime>() + .property("type", codecForConstString("absoluteTimeText")) .property("pattern", codecForString()) .property("max", codecOptional(codecForTimestamp)) .property("min", codecOptional(codecForTimestamp)) - .build("UIFormFieldConfigAbsoluteTime.properties"); - -const codecForUiFormFieldAbsoluteTime = - (): Codec<UIFormFieldConfigAbsoluteTime> => - buildCodecForObject<UIFormFieldConfigAbsoluteTime>() - .property("type", codecForConstString("absoluteTime")) - .property("properties", codecForUIFormFieldAbsoluteTimeConfig()) - .build("UIFormFieldConfigAbsoluteTime"); - -const codecForUIFormFieldAmountConfig = (): Codec< - UIFormFieldConfigAmount["properties"] -> => - codecForUIFormFieldBaseConfigTemplate<UIFormFieldConfigAmount["properties"]>() + .build("UIFormFieldAbsoluteTime"); + +const codecForUiFormFieldAmount = (): Codec<UIFormFieldAmount> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldAmount>() + .property("type", codecForConstString("amount")) .property("currency", codecForString()) .property("max", codecOptional(codecForNumber())) .property("min", codecOptional(codecForNumber())) - .build("UIFormFieldConfigAmount.properties"); - -const codecForUiFormFieldAmount = (): Codec<UIFormFieldConfigAmount> => - buildCodecForObject<UIFormFieldConfigAmount>() - .property("type", codecForConstString("amount")) - .property("properties", codecForUIFormFieldAmountConfig()) - .build("UIFormFieldConfigAmount"); + .build("UIFormFieldAmount"); -const codecForUIFormFieldArrayConfig = (): Codec< - UIFormFieldConfigArray["properties"] -> => - codecForUIFormFieldBaseConfigTemplate<UIFormFieldConfigArray["properties"]>() +const codecForUiFormFieldArray = (): Codec<UIFormFieldArray> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldArray>() + .property("type", codecForConstString("array")) .property("labelFieldId", codecForUiFieldId()) + .property("tooltip", codecOptional(codecForString())) // eslint-disable-next-line @typescript-eslint/no-use-before-define .property("fields", codecForList(codecForUiFormField())) - .build("UIFormFieldConfigArray.properties"); - -const codecForUiFormFieldArray = (): Codec<UIFormFieldConfigArray> => - buildCodecForObject<UIFormFieldConfigArray>() - .property("type", codecForConstString("array")) - .property("properties", codecForUIFormFieldArrayConfig()) - .build("UIFormFieldConfigArray"); + .build("UIFormFieldArray"); -const codecForUiFormFieldCaption = (): Codec<UIFormFieldConfigCaption> => - buildCodecForObject<UIFormFieldConfigCaption>() +const codecForUiFormFieldCaption = (): Codec<UIFormElementCaption> => + codecForUIFormFieldBaseDescriptionTemplate<UIFormElementCaption>() .property("type", codecForConstString("caption")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigCaption"); + .build("UIFormFieldCaption"); const codecForUiFormSelectUiChoice = (): Codec<SelectUiChoice> => buildCodecForObject<SelectUiChoice>() @@ -285,115 +231,79 @@ const codecForUiFormSelectUiChoice = (): Codec<SelectUiChoice> => .property("value", codecForString()) .build("SelectUiChoice"); -const codecForUIFormFieldWithChoiseConfig = (): Codec< - UIFormFieldConfigChoiseHorizontal["properties"] -> => - codecForUIFormFieldBaseConfigTemplate< - UIFormFieldConfigChoiseHorizontal["properties"] - >() - .property("choices", codecForList(codecForUiFormSelectUiChoice())) - .build("UIFormFieldConfigChoiseHorizontal.properties"); - const codecForUiFormFieldChoiceHorizontal = - (): Codec<UIFormFieldConfigChoiseHorizontal> => - buildCodecForObject<UIFormFieldConfigChoiseHorizontal>() + (): Codec<UIFormFieldChoiseHorizontal> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldChoiseHorizontal>() .property("type", codecForConstString("choiceHorizontal")) - .property("properties", codecForUIFormFieldWithChoiseConfig()) - .build("UIFormFieldConfigChoiseHorizontal"); - -const codecForUiFormFieldChoiceStacked = - (): Codec<UIFormFieldConfigChoiseStacked> => - buildCodecForObject<UIFormFieldConfigChoiseStacked>() - .property("type", codecForConstString("choiceStacked")) - .property("properties", codecForUIFormFieldWithChoiseConfig()) - .build("UIFormFieldConfigChoiseStacked"); - -const codecForUIFormFieldFileConfig = (): Codec< - UIFormFieldConfigFile["properties"] -> => - codecForUIFormFieldBaseConfigTemplate<UIFormFieldConfigFile["properties"]>() + .property("choices", codecForList(codecForUiFormSelectUiChoice())) + .build("UIFormFieldChoiseHorizontal"); + +const codecForUiFormFieldChoiceStacked = (): Codec<UIFormFieldChoiseStacked> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldChoiseStacked>() + .property("type", codecForConstString("choiceStacked")) + .property("choices", codecForList(codecForUiFormSelectUiChoice())) + .build("UIFormFieldChoiseStacked"); + +const codecForUiFormFieldFile = (): Codec<UIFormFieldFile> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldFile>() + .property("type", codecForConstString("file")) .property("accept", codecOptional(codecForString())) .property("maxBytes", codecOptional(codecForNumber())) .property("minBytes", codecOptional(codecForNumber())) - .build("UIFormFieldConfigFile.properties"); + .build("UIFormFieldFile"); -const codecForUiFormFieldFile = (): Codec<UIFormFieldConfigFile> => - buildCodecForObject<UIFormFieldConfigFile>() - .property("type", codecForConstString("file")) - .property("properties", codecForUIFormFieldFileConfig()) - .build("UIFormFieldConfigFile"); - -const codecForUIFormFieldWithFieldsConfig = (): Codec< - UIFormFieldConfigGroup["properties"] -> => - codecForUIFormFieldBaseDescriptionTemplate< - UIFormFieldConfigGroup["properties"] - >() +const codecForUiFormFieldGroup = (): Codec<UIFormElementGroup> => + codecForUIFormFieldBaseDescriptionTemplate<UIFormElementGroup>() + .property("type", codecForConstString("group")) // eslint-disable-next-line @typescript-eslint/no-use-before-define .property("fields", codecForList(codecForUiFormField())) - .build("UIFormFieldConfigGroup.properties"); - -const codecForUiFormFieldGroup = (): Codec<UIFormFieldConfigGroup> => - buildCodecForObject<UIFormFieldConfigGroup>() - .property("type", codecForConstString("group")) - .property("properties", codecForUIFormFieldWithFieldsConfig()) .build("UiFormFieldGroup"); -const codecForUiFormFieldInteger = (): Codec<UIFormFieldConfigInteger> => - buildCodecForObject<UIFormFieldConfigInteger>() +const codecForUiFormFieldInteger = (): Codec<UIFormFieldInteger> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldInteger>() .property("type", codecForConstString("integer")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigInteger"); - -const codecForUIFormFieldSelectMultipleConfig = (): Codec< - UIFormFieldConfigSelectMultiple["properties"] -> => - codecForUIFormFieldBaseConfigTemplate< - UIFormFieldConfigSelectMultiple["properties"] - >() + // .property("properties", codecForUIFormFieldBaseConfig()) .property("max", codecOptional(codecForNumber())) .property("min", codecOptional(codecForNumber())) - .property("unique", codecOptional(codecForBoolean())) - .property("choices", codecForList(codecForUiFormSelectUiChoice())) - .build("UIFormFieldConfigSelectMultiple.properties"); + .build("UIFormFieldInteger"); const codecForUiFormFieldSelectMultiple = - (): Codec<UIFormFieldConfigSelectMultiple> => - buildCodecForObject<UIFormFieldConfigSelectMultiple>() + (): Codec<UIFormFieldSelectMultiple> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldSelectMultiple>() .property("type", codecForConstString("selectMultiple")) - .property("properties", codecForUIFormFieldSelectMultipleConfig()) + .property("max", codecOptional(codecForNumber())) + .property("min", codecOptional(codecForNumber())) + .property("unique", codecOptional(codecForBoolean())) + .property("choices", codecForList(codecForUiFormSelectUiChoice())) .build("UiFormFieldSelectMultiple"); -const codecForUiFormFieldSelectOne = (): Codec<UIFormFieldConfigSelectOne> => - buildCodecForObject<UIFormFieldConfigSelectOne>() +const codecForUiFormFieldSelectOne = (): Codec<UIFormFieldSelectOne> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldSelectOne>() .property("type", codecForConstString("selectOne")) - .property("properties", codecForUIFormFieldWithChoiseConfig()) - .build("UIFormFieldConfigSelectOne"); + .property("choices", codecForList(codecForUiFormSelectUiChoice())) + .build("UIFormFieldSelectOne"); -const codecForUiFormFieldText = (): Codec<UIFormFieldConfigText> => - buildCodecForObject<UIFormFieldConfigText>() +const codecForUiFormFieldText = (): Codec<UIFormFieldText> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldText>() .property("type", codecForConstString("text")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigText"); + .build("UIFormFieldText"); -const codecForUiFormFieldTextArea = (): Codec<UIFormFieldConfigTextArea> => - buildCodecForObject<UIFormFieldConfigTextArea>() +const codecForUiFormFieldTextArea = (): Codec<UIFormFieldTextArea> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldTextArea>() .property("type", codecForConstString("textArea")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigTextArea"); + .build("UIFormFieldTextArea"); -const codecForUiFormFieldToggle = (): Codec<UIFormFieldConfigToggle> => - buildCodecForObject<UIFormFieldConfigToggle>() +const codecForUiFormFieldToggle = (): Codec<UIFormFieldToggle> => + codecForUIFormFieldBaseConfigTemplate<UIFormFieldToggle>() .property("type", codecForConstString("toggle")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigToggle"); + .build("UIFormFieldToggle"); -const codecForUiFormField = (): Codec<UIFormFieldConfig> => - buildCodecForUnion<UIFormFieldConfig>() +const codecForUiFormField = (): Codec<UIFormElementConfig> => + buildCodecForUnion<UIFormElementConfig>() .discriminateOn("type") .alternative("array", codecForLazy(codecForUiFormFieldArray)) .alternative("group", codecForLazy(codecForUiFormFieldGroup)) - .alternative("absoluteTime", codecForUiFormFieldAbsoluteTime()) + .alternative("absoluteTimeText", codecForUiFormFieldAbsoluteTime()) .alternative("amount", codecForUiFormFieldAmount()) .alternative("caption", codecForUiFormFieldCaption()) .alternative("choiceHorizontal", codecForUiFormFieldChoiceHorizontal()) @@ -420,18 +330,18 @@ const codecForDoubleColumnForm = (): Codec<DoubleColumnForm> => .property("design", codecForList(codecForDoubleColumnFormSection())) .build("DoubleColumnForm"); -const codecForFlexibleForm = (): Codec<FlexibleForm> => - buildCodecForUnion<FlexibleForm>() +const codecForFormConfiguration = (): Codec<FormConfiguration> => + buildCodecForUnion<FormConfiguration>() .discriminateOn("type") .alternative("double-column", codecForDoubleColumnForm()) - .build<FlexibleForm>("FlexibleForm"); + .build<FormConfiguration>("FormConfiguration"); const codecForFormMetadata = (): Codec<FormMetadata> => buildCodecForObject<FormMetadata>() .property("label", codecForString()) .property("id", codecForString()) .property("version", codecForNumber()) - .property("config", codecForFlexibleForm()) + .property("config", codecForFormConfiguration()) .build("FormMetadata"); export const codecForUIForms = (): Codec<UiForms> => @@ -443,7 +353,7 @@ export type FormMetadata = { label: string; id: string; version: number; - config: FlexibleForm; + config: FormConfiguration; }; export interface UiForms { |