taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit f700a38dd22765bf8027023144e33ea4f1cf8e16
parent ae0c46261c8fd8d71b38cfdd529dcf78767d327b
Author: Sebastian <sebasjm@gmail.com>
Date:   Wed,  3 Jan 2024 17:16:26 -0300

aml forms documentation

Diffstat:
Mdesign-documents/054-dynamic-form.rst | 199+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mtaler-exchange-manual.rst | 41+++++++++++++++++++++++++++++++++++++++++
2 files changed, 144 insertions(+), 96 deletions(-)

diff --git a/design-documents/054-dynamic-form.rst b/design-documents/054-dynamic-form.rst @@ -23,14 +23,14 @@ Layout requirements ------------------- * **editable by system admin**: System admins should be able to create new forms -or edit current one shipped with the source. + or edit current one shipped with the source. * **accesibility**: Forms should meet accessibility level AA. * **responsive**: Forms should be responsive and function on all devices. * **metadata**: Generated form information should contain enough data -to handle multiple form versions. + to handle multiple form versions. Fields requirements ------------------- @@ -38,7 +38,7 @@ Fields requirements * **validations**: Each field may require custom validation * **custom data type**: A field may consist of a list, string, number, or a -complex composite structure. + complex composite structure. Proposed Solutions @@ -51,24 +51,25 @@ readOnly (flag to disable input), onUpdate (callback on form data update), and computeFormState (function to derive the form state based on current data). -``` -interface FormType<T extends object> { - value: Partial<T>; - initial?: Partial<T>; - readOnly?: boolean; - onUpdate?: (v: Partial<T>) => void; - computeFormState?: (v: Partial<T>) => FormState<T>; -} -``` +.. code-block:: javascript -`T`: is the type of the result object -`value`: is a reference to the current value of the result -`initial`: data for resetting -`readOnly`: when true, fields won't allow input -`onUpdate`: notification of the result update -`computeFormState`: compute a new state of the form based on the current value + interface FormType<T extends object> { + value: Partial<T>; + initial?: Partial<T>; + readOnly?: boolean; + onUpdate?: (v: Partial<T>) => void; + computeFormState?: (v: Partial<T>) => FormState<T>; + } + + +``T``: is the type of the result object +``value``: is a reference to the current value of the result +``initial``: data for resetting +``readOnly``: when true, fields won't allow input +``onUpdate``: notification of the result update +``computeFormState``: compute a new state of the form based on the current value -Form state have the same shape of `T` but every field type is `FieldUIOptions`. +Form state have the same shape of ``T`` but every field type is ``FieldUIOptions``. Fields type can be: * strings @@ -77,32 +78,34 @@ Fields type can be: * arrays * object -The field type `AmountJson` and `AbsoluteTime` are opaque since field is used as a whole. +The field type ``AmountJson`` and ``AbsoluteTime`` are opaque since field is used as a whole. The form can be instanciated using -``` -import { FormProvider } from "@gnu-taler/web-util/browser"; -``` +.. code-block:: javascript -Then the field component can access all the properties by the `useField(name)` hook, + import { FormProvider } from "@gnu-taler/web-util/browser"; + + +Then the field component can access all the properties by the ``useField(name)`` hook, which will return -``` -interface InputFieldHandler<Type> { - value: Type; - onChange: (s: Type) => void; - state: FieldUIOptions; - isDirty: boolean; -} -``` +.. code-block:: javascript -`value`: the current value of the field -`onChange`: a function to call anytime the user want to change the value -`state`: the state of the field (hidden, error, etc..) -`isDirty`: if the user already tried to change the value + interface InputFieldHandler<Type> { + value: Type; + onChange: (s: Type) => void; + state: FieldUIOptions; + isDirty: boolean; + } -A set of common form field exist in `@gnu-taler/web-util`: + +``value``: the current value of the field +``onChange``: a function to call anytime the user want to change the value +``state``: the state of the field (hidden, error, etc..) +``isDirty``: if the user already tried to change the value + +A set of common form field exist in ``@gnu-taler/web-util``: * InputAbsoluteTime * InputAmount @@ -111,82 +114,86 @@ A set of common form field exist in `@gnu-taler/web-util`: * InputText * InputToggle -and should be used inside a `Form` context. +and should be used inside a ``Form`` context. + +.. code-block:: javascript + + function MyFormComponent():VNode { + return <FormProvider > + <InputAmount name="amount" /> + <InputText name="subject" /> + <button type="submit"> Confirm </button> + </FormProvier> + } -``` -function MyFormComponent():VNode { - return <FormProvider ...> - <InputAmount name="amount" /> - <InputText name="subject" /> - <button type="submit"> Confirm </button> - </FormProvier> -} Example -------- Consider a form shape represented by the TypeScript type: -``` -type TheFormType = { - name: string, - age: number, - savings: AmountJson, - nextBirthday: AbsoluteTime, - pets: string[], - addres: { - street: string, - city: string, +.. code-block:: javascript + + type TheFormType = { + name: string, + age: number, + savings: AmountJson, + nextBirthday: AbsoluteTime, + pets: string[], + addres: { + street: string, + city: string, + } } -} -``` An example instance of this form could be: -``` -const theFormValue: TheFormType = { - name: "Sebastian", - age: 15, - pets: ["dog","cat"], - address: { - street: "long", - city: "big", +.. code-block:: javascript + + const theFormValue: TheFormType = { + name: "Sebastian", + age: 15, + pets: ["dog","cat"], + address: { + street: "long", + city: "big", + } } -} -``` + For such a form, a valid state can be computed using a function like -`computeFormStateBasedOnFormValues`, returning an object indicating -the state of each field, including properties such as `hidden`, -`disabled`, and `required`. - - -``` -function computeFormStateBasedOnFormValues(formValues): { - //returning fixed state as an example - //the return state will be commonly be computed from the values of the form - return { - age: { - hidden: true, - }, - pets: { - disabled: true, - elements: [{ - disabled: false, - }], - }, - address: { - street: { - required: true, - error: "the street name was not found", +``computeFormStateBasedOnFormValues``, returning an object indicating +the state of each field, including properties such as ``hidden``, +``disabled``, and ``required``. + + +.. code-block:: javascript + + function computeFormStateBasedOnFormValues(formValues): { + //returning fixed state as an example + //the return state will be commonly be computed from the values of the form + return { + age: { + hidden: true, }, - city: { - required: true, + pets: { + disabled: true, + elements: [{ + disabled: false, + }], }, - }, + address: { + street: { + required: true, + error: "the street name was not found", + }, + city: { + required: true, + }, + }, + } } -} -``` + diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst @@ -2009,6 +2009,47 @@ account for manual review. To disable this triger, simply leave the option to its default value of '[/usr/bin/]true'. To flag all new users for manual review, simply set the program to '[/usr/bin/]false'. +AML Forms +--------- + +AML forms are defined by the DD 54 dynamic forms. +The shipped implementation with of the exchange is installed in + +.. code-block:: shell-session + + ${INSTALL_PREFIX}/share/taler/exchange/spa/forms.js + + +The variable ``form`` contains the list of all form available. For +every entry in the list the next properties are expected to be present: + +``label``: used in the UI as the name of the form + +``icon``: an SVN used in the UI + +``id``: identification name, this will be saved in the exchange database +along with the values to correctly render the form again. +It should simple, short and without any character outside numbers, +letters and underscore. + +``version``: when editing a form, instead of just replacing fields +it will be better to create a new form with the same id and new version. +That way old forms in the database will used old definition of the form. +It should be a number. + +``impl`` : a function that returns the design and behavior of form. +See DD 54 dynamic forms. + +.. attention:: + + do not remove a form the list if it has been used. Otherwise you + won't be able to see the information save in the exchange database. + +To add a new one you can simply copy and paste one element, and edit it. + +It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source +from ``https://git.taler.net/wallet-core.git/``, compile and copy the file +from the ``dist/prod``. Setup Linting