diff options
Diffstat (limited to 'packages/aml-backoffice-ui/src/context/ui-forms.ts')
-rw-r--r-- | packages/aml-backoffice-ui/src/context/ui-forms.ts | 439 |
1 files changed, 1 insertions, 438 deletions
diff --git a/packages/aml-backoffice-ui/src/context/ui-forms.ts b/packages/aml-backoffice-ui/src/context/ui-forms.ts index 9cf6125c9..3a25234d2 100644 --- a/packages/aml-backoffice-ui/src/context/ui-forms.ts +++ b/packages/aml-backoffice-ui/src/context/ui-forms.ts @@ -14,20 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - buildCodecForObject, - buildCodecForUnion, - Codec, - codecForBoolean, - codecForConstString, - codecForList, - codecForNumber, - codecForString, - codecForTimestamp, - codecOptional, - Integer, - TalerProtocolTimestamp, -} from "@gnu-taler/taler-util"; +import { codecForUIForms, UiForms } from "@gnu-taler/web-util/browser"; import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext } from "preact/hooks"; @@ -60,431 +47,7 @@ export const UiFormsProvider = ({ }); }; -export type FormMetadata = { - label: string; - id: string; - version: number; - config: FlexibleForm; -}; - -type FlexibleForm = DoubleColumnForm; - -export interface DoubleColumnForm { - type: "double-column"; - design: Array<DoubleColumnFormSection>; - // behavior?: (form: Partial<T>) => FormState<T>; -} - -export type DoubleColumnFormSection = { - title: string; - description?: string; - fields: UIFormFieldConfig[]; -}; - -// export interface BaseForm { -// state: TalerExchangeApi.AmlState; -// threshold: AmountJson; -// } - -export interface UiForms { - // Where libeufin backend is localted - // default: window.origin without "webui/" - forms: Array<FormMetadata>; -} - -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 = { - type: "amount"; - properties: UIFormFieldBaseConfig & { - max?: Integer; - min?: Integer; - currency: string; - }; -}; - -type UIFormFieldConfigArray = { - type: "array"; - properties: UIFormFieldBaseConfig & { - // id of the field shown when the array is collapsed - labelFieldId: UIHandlerId; - fields: UIFormFieldConfig[]; - }; -}; - -type UIFormFieldConfigCaption = { - type: "caption"; - properties: UIFieldBaseDescription; -}; - -type UIFormFieldConfigGroup = { - type: "group"; - properties: UIFieldBaseDescription & { - fields: UIFormFieldConfig[]; - }; -}; - -type UIFormFieldConfigChoiseHorizontal = { - type: "choiceHorizontal"; - properties: UIFormFieldBaseConfig & { - choices: Array<SelectUiChoice>; - }; -}; - -type UIFormFieldConfigChoiseStacked = { - type: "choiceStacked"; - properties: UIFormFieldBaseConfig & { - choices: Array<SelectUiChoice>; - }; -}; - -type UIFormFieldConfigFile = { - 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 = { - type: "integer"; - properties: UIFormFieldBaseConfig & { - max?: Integer; - min?: Integer; - }; -}; - -interface SelectUiChoice { - label: string; - description?: string; - value: string; -} - -type UIFormFieldConfigSelectMultiple = { - type: "selectMultiple"; - properties: UIFormFieldBaseConfig & { - max?: Integer; - min?: Integer; - unique?: boolean; - choices: Array<SelectUiChoice>; - }; -}; -type UIFormFieldConfigSelectOne = { - 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; -}; - -export type UIFieldBaseDescription = { - /* 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 */ - help?: string; - - /* name of the field, useful for a11y */ - name: string; - - /* if the field should be initialy hidden */ - hidden?: boolean; - /* ui element to show before */ - addonBeforeId?: string; - /* ui element to show after */ - addonAfterId?: string; -}; - -export type UIFormFieldBaseConfig = UIFieldBaseDescription & { - /* example to be shown inside the field */ - placeholder?: string; - - /* show a mark as required */ - required?: boolean; - - /* readonly and dim */ - disabled?: boolean; - - /* conversion id to conver the string into the value type - the id should be known to the ui impl - */ - converterId?: string; - - /* property id of the form */ - id: UIHandlerId; -}; - -declare const __handlerId: unique symbol; -export type UIHandlerId = string & { [__handlerId]: true }; - -// FIXME: validate well formed ui field id -const codecForUiFieldId = codecForString as () => Codec<UIHandlerId>; - -const codecForUIFormFieldBaseDescriptionTemplate = < - T extends UIFieldBaseDescription, ->() => - buildCodecForObject<T>() - .property("addonAfterId", codecOptional(codecForString())) - .property("addonBeforeId", codecOptional(codecForString())) - .property("hidden", codecOptional(codecForBoolean())) - .property("help", codecOptional(codecForString())) - .property("label", codecForString()) - .property("name", codecForString()) - .property("tooltip", codecOptional(codecForString())); - -const codecForUIFormFieldBaseConfigTemplate = < - T extends UIFormFieldBaseConfig, ->() => - codecForUIFormFieldBaseDescriptionTemplate<T>() - .property("id", codecForUiFieldId()) - .property("converterId", codecOptional(codecForString())) - .property("disabled", codecOptional(codecForBoolean())) - .property("required", codecOptional(codecForBoolean())) - .property("placeholder", codecOptional(codecForString())); -const codecForUIFormFieldBaseConfig = (): Codec<UIFormFieldBaseConfig> => - codecForUIFormFieldBaseConfigTemplate().build("UIFieldToggleProperties"); - -const codecForUIFormFieldAbsoluteTimeConfig = (): Codec< - UIFormFieldConfigAbsoluteTime["properties"] -> => - codecForUIFormFieldBaseConfigTemplate< - UIFormFieldConfigAbsoluteTime["properties"] - >() - .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"]>() - .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"); - -const codecForUIFormFieldArrayConfig = (): Codec< - UIFormFieldConfigArray["properties"] -> => - codecForUIFormFieldBaseConfigTemplate<UIFormFieldConfigArray["properties"]>() - .property("labelFieldId", codecForUiFieldId()) - .property("fields", codecForList(codecForUiFormField())) - .build("UIFormFieldConfigArray.properties"); - -const codecForUiFormFieldArray = (): Codec<UIFormFieldConfigArray> => - buildCodecForObject<UIFormFieldConfigArray>() - .property("type", codecForConstString("array")) - .property("properties", codecForUIFormFieldArrayConfig()) - .build("UIFormFieldConfigArray"); - -const codecForUiFormFieldCaption = (): Codec<UIFormFieldConfigCaption> => - buildCodecForObject<UIFormFieldConfigCaption>() - .property("type", codecForConstString("caption")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigCaption"); - -const codecForUiFormSelectUiChoice = (): Codec<SelectUiChoice> => - buildCodecForObject<SelectUiChoice>() - .property("description", codecForString()) - .property("label", codecForString()) - .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>() - .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 codecForUiFormFieldFile = (): Codec<UIFormFieldConfigFile> => - buildCodecForObject<UIFormFieldConfigFile>() - .property("type", codecForConstString("file")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigFile"); - -const codecForUIFormFieldWithFieldsConfig = (): Codec< - UIFormFieldConfigGroup["properties"] -> => - codecForUIFormFieldBaseDescriptionTemplate< - UIFormFieldConfigGroup["properties"] - >() - .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>() - .property("type", codecForConstString("integer")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigInteger"); - -const codecForUIFormFieldSelectMultipleConfig = (): Codec< - UIFormFieldConfigSelectMultiple["properties"] -> => - codecForUIFormFieldBaseConfigTemplate< - UIFormFieldConfigSelectMultiple["properties"] - >() - .property("max", codecOptional(codecForNumber())) - .property("min", codecOptional(codecForNumber())) - .property("unique", codecOptional(codecForBoolean())) - .property("choices", codecForList(codecForUiFormSelectUiChoice())) - .build("UIFormFieldConfigSelectMultiple.properties"); - -const codecForUiFormFieldSelectMultiple = - (): Codec<UIFormFieldConfigSelectMultiple> => - buildCodecForObject<UIFormFieldConfigSelectMultiple>() - .property("type", codecForConstString("selectMultiple")) - .property("properties", codecForUIFormFieldSelectMultipleConfig()) - .build("UiFormFieldSelectMultiple"); - -const codecForUiFormFieldSelectOne = (): Codec<UIFormFieldConfigSelectOne> => - buildCodecForObject<UIFormFieldConfigSelectOne>() - .property("type", codecForConstString("selectOne")) - .property("properties", codecForUIFormFieldWithChoiseConfig()) - .build("UIFormFieldConfigSelectOne"); - -const codecForUiFormFieldText = (): Codec<UIFormFieldConfigText> => - buildCodecForObject<UIFormFieldConfigText>() - .property("type", codecForConstString("text")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigText"); - -const codecForUiFormFieldTextArea = (): Codec<UIFormFieldConfigTextArea> => - buildCodecForObject<UIFormFieldConfigTextArea>() - .property("type", codecForConstString("textArea")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigTextArea"); - -const codecForUiFormFieldToggle = (): Codec<UIFormFieldConfigToggle> => - buildCodecForObject<UIFormFieldConfigToggle>() - .property("type", codecForConstString("toggle")) - .property("properties", codecForUIFormFieldBaseConfig()) - .build("UIFormFieldConfigToggle"); - -const codecForUiFormField = (): Codec<UIFormFieldConfig> => - buildCodecForUnion<UIFormFieldConfig>() - .discriminateOn("type") - .alternative("absoluteTime", codecForUiFormFieldAbsoluteTime()) - .alternative("amount", codecForUiFormFieldAmount()) - .alternative("array", codecForUiFormFieldArray()) - .alternative("caption", codecForUiFormFieldCaption()) - .alternative("choiceHorizontal", codecForUiFormFieldChoiceHorizontal()) - .alternative("choiceStacked", codecForUiFormFieldChoiceStacked()) - .alternative("file", codecForUiFormFieldFile()) - .alternative("group", codecForUiFormFieldGroup()) - .alternative("integer", codecForUiFormFieldInteger()) - .alternative("selectMultiple", codecForUiFormFieldSelectMultiple()) - .alternative("selectOne", codecForUiFormFieldSelectOne()) - .alternative("text", codecForUiFormFieldText()) - .alternative("textArea", codecForUiFormFieldTextArea()) - .alternative("toggle", codecForUiFormFieldToggle()) - .build("UIFormField"); - -const codecForDoubleColumnFormSection = (): Codec<DoubleColumnFormSection> => - buildCodecForObject<DoubleColumnFormSection>() - .property("title", codecForString()) - .property("description", codecForString()) - .property("fields", codecForList(codecForUiFormField())) - .build("DoubleColumnFormSection"); - -const codecForDoubleColumnForm = (): Codec<DoubleColumnForm> => - buildCodecForObject<DoubleColumnForm>() - .property("type", codecForConstString("double-column")) - .property("design", codecForList(codecForDoubleColumnFormSection())) - .build("DoubleColumnForm"); - -const codecForFlexibleForm = (): Codec<FlexibleForm> => - buildCodecForUnion<FlexibleForm>() - .discriminateOn("type") - .alternative("double-column", codecForDoubleColumnForm()) - .build<FlexibleForm>("FlexibleForm"); - -const codecForFormMetadata = (): Codec<FormMetadata> => - buildCodecForObject<FormMetadata>() - .property("label", codecForString()) - .property("id", codecForString()) - .property("version", codecForNumber()) - .property("config", codecForFlexibleForm()) - .build("FormMetadata"); -const codecForUIForms = (): Codec<UiForms> => - buildCodecForObject<UiForms>() - .property("forms", codecForList(codecForFormMetadata())) - .build("UiForms"); function removeUndefineField<T extends object>(obj: T): T { const keys = Object.keys(obj) as Array<keyof T>; |