aboutsummaryrefslogtreecommitdiff
path: root/packages/web-util
diff options
context:
space:
mode:
Diffstat (limited to 'packages/web-util')
-rw-r--r--packages/web-util/src/forms/InputAbsoluteTime.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputAmount.tsx29
-rw-r--r--packages/web-util/src/forms/InputArray.tsx28
-rw-r--r--packages/web-util/src/forms/InputChoiceHorizontal.tsx5
-rw-r--r--packages/web-util/src/forms/converter.ts21
-rw-r--r--packages/web-util/src/forms/forms.ts93
-rw-r--r--packages/web-util/src/forms/ui-form.ts382
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 {