gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: working on array input


From: gnunet
Subject: [taler-wallet-core] branch master updated: working on array input
Date: Mon, 09 Dec 2024 14:50:23 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 9f401ff16 working on array input
9f401ff16 is described below

commit 9f401ff1601181f9476f10b6a42daf1fc372115c
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Dec 9 10:50:02 2024 -0300

    working on array input
---
 .../src/pages/ShowConsolidated.tsx                 |   1 -
 packages/kyc-ui/src/forms.json                     | 376 ++++++++++++++++++++-
 packages/kyc-ui/src/hooks/form.ts                  |   1 +
 packages/kyc-ui/src/pages/FillForm.tsx             |  88 ++---
 packages/kyc-ui/src/pages/TriggerKyc.tsx           | 188 ++++++++---
 packages/web-util/src/forms/InputArray.stories.tsx |  81 ++++-
 packages/web-util/src/forms/InputArray.tsx         |  83 +++--
 packages/web-util/src/forms/InputLine.tsx          |   2 +-
 packages/web-util/src/forms/forms.ts               |   5 +-
 9 files changed, 683 insertions(+), 142 deletions(-)

diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx 
b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
index fcec8609a..6ec6b787a 100644
--- a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
+++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
@@ -69,7 +69,6 @@ export function ShowConsolidated({
   const formConfig: FormConfiguration = {
     type: "double-column",
     design: Object.entries(fixed).length > 0 ? [
-
       {
         title: i18n.str`KYC collected info`,
         fields: Object.entries(fixed).map(([key, field]) => {
diff --git a/packages/kyc-ui/src/forms.json b/packages/kyc-ui/src/forms.json
index b0c198574..8e7d6bcdc 100644
--- a/packages/kyc-ui/src/forms.json
+++ b/packages/kyc-ui/src/forms.json
@@ -12,34 +12,34 @@
             "description": "Establishment of the beneficial owner of the 
assets and/or controlling person",
             "fields": [
               {
-                "type": "choiceStacked",
                 "id": "LEGAL_ENTITY_TYPE",
                 "label": "The customer is",
                 "required": true,
+                "type": "choiceStacked",
                 "choices": [
                   {
                     "label": "a natural person and there are no doubts that 
this person is the sole beneficial owner of the assets",
-                    "value": "natural"
+                    "value": "NATURAL"
                   },
                   {
                     "label": "a foundation (or a similar construct; incl. 
underlying companies)",
-                    "value": "foundation"
+                    "value": "FOUNDATION"
                   },
                   {
                     "label": "an operation legal entity or partnership",
-                    "value": "legal-entity"
+                    "value": "OPERATIONAL"
                   },
                   {
                     "label": "a trust (incl. underlying companies)",
-                    "value": "trust"
+                    "value": "TRUST"
                   },
                   {
                     "label": "a life insurance policy with separately managed 
accounts/securities accounts",
-                    "value": "insurance"
+                    "value": "LIFEINSURANCE"
                   },
                   {
                     "label": "all other cases",
-                    "value": "other"
+                    "value": "OTHER"
                   }
                 ]
               }
@@ -66,7 +66,7 @@
                 "choices": [
                   {
                     "label": "natural",
-                    "value": "natural"
+                    "value": "NATURAL"
                   }
                 ]
               }
@@ -77,7 +77,7 @@
     },
     {
       "label": "VQF legal entity form",
-      "id": "vqf-legal-entity",
+      "id": "vqf-operational",
       "version": 1,
       "config": {
         "type": "double-column",
@@ -93,7 +93,7 @@
                 "choices": [
                   {
                     "label": "legal entity",
-                    "value": "natural"
+                    "value": "NATURAL"
                   }
                 ]
               }
@@ -120,7 +120,7 @@
                 "choices": [
                   {
                     "label": "foundation",
-                    "value": "natural"
+                    "value": "NATURAL"
                   }
                 ]
               }
@@ -147,7 +147,7 @@
                 "choices": [
                   {
                     "label": "trust",
-                    "value": "natural"
+                    "value": "NATURAL"
                   }
                 ]
               }
@@ -174,7 +174,7 @@
                 "choices": [
                   {
                     "label": "insurance",
-                    "value": "natural"
+                    "value": "NATURAL"
                   }
                 ]
               }
@@ -201,9 +201,357 @@
                 "choices": [
                   {
                     "label": "other",
-                    "value": "natural"
+                    "value": "NATURAL"
+                  }
+                ]
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "label": "GLS Onboarding form",
+      "id": "gls-onboarding",
+      "version": 1,
+      "config": {
+        "type": "double-column",
+        "design": [
+          {
+            "title": "Personal information",
+            "fields": [
+              {
+                "type": "text",
+                "id": "PERSON_FULL_NAME",
+                "label": "Full name",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "PERSON_LAST_NAME",
+                "label": "Last name",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "CONTACT_PHONE",
+                "label": "Phone",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "CONTACT_EMAIL",
+                "label": "E-Mail",
+                "required": true
+              },
+              {
+                "type": "toggle",
+                "id": "ACCEPTED_TERMS_OF_SERVICE",
+                "label": "I accept terms of service",
+                "required": true
+              }
+            ]
+          },
+          {
+            "title": "Business information",
+            "fields": [
+              {
+                "type": "text",
+                "id": "BUSINESS_DISPLAY_NAME",
+                "label": "Name",
+                "required": true
+              },
+              {
+                "type": "selectOne",
+                "id": "BUSINESS_TYPE",
+                "label": "The company type is",
+                "required": true,
+                "choices": [
+                  {
+                    "label": "GmbH",
+                    "value": "GMBH"
+                  },
+                  {
+                    "label": "ug",
+                    "value": "UG"
+                  },
+                  {
+                    "label": "an operation legal entity or partnership",
+                    "value": "OPERATIONAL"
+                  },
+                  {
+                    "label": "ohg",
+                    "value": "OHG"
+                  },
+                  {
+                    "label": "kg",
+                    "value": "KG"
+                  },
+                  {
+                    "label": "eg",
+                    "value": "EG"
+                  },
+                  {
+                    "label": "eV",
+                    "value": "EV"
+                  },
+                  {
+                    "label": "PartG",
+                    "value": "PARTG"
+                  },
+                  {
+                    "label": "ek",
+                    "value": "EK"
+                  },
+                  {
+                    "label": "AG (nicht börsennotiert)",
+                    "value": "AGNB"
+                  },
+                  {
+                    "label": "AG (börsennotiert)",
+                    "value": "AGB"
+                  },
+                  {
+                    "label": "GbR",
+                    "value": "GBR"
+                  },
+                  {
+                    "label": "n.e.V.",
+                    "value": "NEV"
+                  },
+                  {
+                    "label": "Partei",
+                    "value": "PARTEI"
+                  },
+                  {
+                    "label": "GmbH i.G.",
+                    "value": "GMBHIG"
+                  },
+                  {
+                    "label": "eG. i.G.",
+                    "value": "EGIG"
+                  },
+                  {
+                    "label": "e.V. i.G.",
+                    "value": "EVIG"
+                  },
+                  {
+                    "label": "Other",
+                    "value": "OTHER"
                   }
                 ]
+              },
+              {
+                "type": "text",
+                "id": "BUSINESS_REGISTRATION_ID",
+                "label": "Registration ID",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "BUSINESS_LEGAL_JURISDICTION",
+                "label": "Legal jurisdiction",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "BUSINESS_REGISTRATION_DATE",
+                "label": "Founding date",
+                "required": true
+              },
+              {
+                "type": "toggle",
+                "id": "BUSINESS_IS_NON_PROFIT",
+                "label": "I this company a non-profit?",
+                "required": true
+              }
+            ]
+          },
+          {
+            "title": "Business industry",
+            "fields": [
+              {
+                "type": "selectOne",
+                "id": "BUSINESS_INDUSTRY",
+                "label": "Industry",
+                "choices": [{
+                  "label": "Car",
+                  "value": "CAR"
+                },{
+                  "label": "Food",
+                  "value": "FOOD"
+                },{
+                  "description": "preventing... not doing it",
+                  "label": "Money laundry",
+                  "value": "MONEY"
+                }],
+                "required": true
+              }
+            ]
+          },
+          {
+            "title": "Adress",
+            "fields": [
+              {
+                "type": "text",
+                "id": "ADDRESS_STREET_NAME",
+                "label": "Street name",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_STREET_NUMBER",
+                "label": "Street number",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_BUILDING_NAME",
+                "label": "Building name",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_BUILDING_NUMBER",
+                "label": "Building number",
+                "required": true
+              },
+              {
+                "type": "textArea",
+                "id": "ADDRESS_LINES",
+                "label": "Additional address reference",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_TOWN_LOCATION",
+                "label": "Building number",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_TOWN_DISTRICT",
+                "label": "Building number",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_COUNTRY_SUBDIVISION",
+                "label": "Building number",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "ADDRESS_COUNTRY_CC",
+                "label": "Building number",
+                "required": true
+              }
+            ]
+          },
+          {
+            "title": "Tax information",
+            "fields": [
+              {
+                "type": "text",
+                "id": "TAX_COUNTRY_CC",
+                "label": "Country tax",
+                "required": true
+              },
+              {
+                "type": "text",
+                "id": "TAX_ID",
+                "label": "Tax identifier",
+                "required": true
+              },
+              {
+                "type": "toggle",
+                "id": "TAX_IS_USA_LAW",
+                "label": "Is business founded or under USA law?",
+                "required": true
+              },
+              {
+                "type": "toggle",
+                "id": "TAX_IS_ACTIVE",
+                "label": "Is the business economically active?",
+                "required": true
+              },
+              {
+                "type": "toggle",
+                "id": "TAX_IS_DEDUCTED",
+                "label": "Is the business economically active",
+                "required": true
+              }
+            ]
+          },
+          {
+            "title": "Representatives",
+            "fields": [
+              {
+                "type": "array",
+                "id": "BUSINESS_LEGAL_REPRESENTATIVES",
+                "labelFieldId": "CONTACT_PHONE",
+                "label": "List of natural persons that are legal 
representatives or shareholders",
+                "fields": [
+                  {
+                    "type": "text",
+                    "id": "PERSON_FULL_NAME",
+                    "label": "Name",
+                    "required": true
+                  },
+                  {
+                    "type": "text",
+                    "id": "PERSON_DATE_OF_BIRTH",
+                    "label": "Date of birth",
+                    "required": true
+                  },
+                  {
+                    "type": "text",
+                    "id": "CONTACT_PHONE",
+                    "label": "Phone",
+                    "required": true
+                  },
+                  {
+                    "type": "text",
+                    "id": "CONTACT_EMAIL",
+                    "label": "E-Mail",
+                    "required": true
+                  },
+                  {
+                    "type": "text",
+                    "id": "PERSON_NATIONALITY_CC",
+                    "label": "Nationality",
+                    "required": true
+                  },
+                  {
+                    "id": "PERSON_BUSINESS_REPRESENTATIVE_TYPE",
+                    "label": "Full name",
+                    "required": true,
+                    "type": "choiceStacked",
+                    "choices": [
+                      {
+                        "label": "Individual",
+                        "value": "INDIVIDUAL"
+                      },
+                      {
+                        "label": "Authorized to represent",
+                        "value": "AUTHORIZED"
+                      },
+                      {
+                        "label": "Majority",
+                        "value": "MAJORITY"
+                      },
+                      {
+                        "label": "In pair",
+                        "value": "IN_PAIR"
+                      },
+                      {
+                        "label": "Other",
+                        "value": "OTHERS"
+                      }
+                    ]
+                  }
+                ],
+                "required": true
               }
             ]
           }
diff --git a/packages/kyc-ui/src/hooks/form.ts 
b/packages/kyc-ui/src/hooks/form.ts
index 452deabaf..c2f5b41b5 100644
--- a/packages/kyc-ui/src/hooks/form.ts
+++ b/packages/kyc-ui/src/hooks/form.ts
@@ -92,6 +92,7 @@ function constructFormHandler<T>(
     const path = fieldId.split(".");
 
     function updater(newValue: unknown) {
+      console.log("----",path, newValue)
       updateForm(setValueDeeper(form, path, newValue));
     }
 
diff --git a/packages/kyc-ui/src/pages/FillForm.tsx 
b/packages/kyc-ui/src/pages/FillForm.tsx
index 52b893e40..760603318 100644
--- a/packages/kyc-ui/src/pages/FillForm.tsx
+++ b/packages/kyc-ui/src/pages/FillForm.tsx
@@ -24,6 +24,7 @@ import {
 import {
   Button,
   FormMetadata,
+  FormProvider,
   InternationalizationAPI,
   LocalNotificationBanner,
   RenderAllFieldsByUiConfig,
@@ -89,13 +90,8 @@ export function FillForm({
       : undefined;
 
   const { forms } = useUiFormsContext();
-  const allForms = customForm ? [...forms, customForm] : forms
-  const theForm = searchForm(
-    i18n,
-    allForms,
-    formId,
-    requirement.context,
-  );
+  const allForms = customForm ? [...forms, customForm] : forms;
+  const theForm = searchForm(i18n, allForms, formId, requirement.context);
   if (!theForm) {
     return <div>form with id {formId} not found</div>;
   }
@@ -107,12 +103,13 @@ export function FillForm({
   const requiredFields: Array<UIHandlerId> = [];
 
   theForm.config.design.forEach((section) => {
-    Array.prototype.push.apply(shape, getShapeFromFields(section.fields));
+    Array.prototype.push.apply(shape, getShapeFromFields(section.fields, ""));
     Array.prototype.push.apply(
       requiredFields,
       getRequiredFields(section.fields),
     );
   });
+
   const [form, state] = useFormState<FormType>(shape, {}, (st) => {
     const partialErrors = undefinedIfEmpty<FormErrors<FormType>>({});
 
@@ -186,43 +183,44 @@ export function FillForm({
     <div class="rounded-lg bg-white px-5 py-6 shadow m-4">
       <LocalNotificationBanner notification={notification} />
       <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
-        {theForm.config.design.map((section, i) => {
-          if (!section) return <Fragment />;
-          return (
-            <div
-              key={i}
-              class="grid grid-cols-1 gap-x-8 gap-y-8 pt-5 md:grid-cols-3"
-            >
-              <div class="px-4 sm:px-0">
-                <h2 class="text-base font-semibold leading-7 text-gray-900">
-                  {section.title}
-                </h2>
-                {section.description && (
-                  <p class="mt-1 text-sm leading-6 text-gray-600">
-                    {section.description}
-                  </p>
-                )}
-              </div>
-              <div class="bg-white shadow-sm ring-1 ring-gray-900/5 rounded-md 
md:col-span-2">
-                <div class="p-3">
-                  <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 
sm:grid-cols-6">
-                    <RenderAllFieldsByUiConfig
-                      key={i}
-                      fields={convertUiField(
-                        i18n,
-                        section.fields,
-                        form,
-                        getConverterById,
-                      )}
-                    />
+          {theForm.config.design.map((section, i) => {
+            if (!section) return <Fragment />;
+            return (
+              <div
+                key={i}
+                class="grid grid-cols-1 gap-x-8 gap-y-8 pt-5 md:grid-cols-3"
+              >
+                <div class="px-4 sm:px-0">
+                  <h2 class="text-base font-semibold leading-7 text-gray-900">
+                    {section.title}
+                  </h2>
+                  {section.description && (
+                    <p class="mt-1 text-sm leading-6 text-gray-600">
+                      {section.description}
+                    </p>
+                  )}
+                </div>
+                <div class="bg-white shadow-sm ring-1 ring-gray-900/5 
rounded-md md:col-span-2">
+                  <div class="p-3">
+                    <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 
sm:grid-cols-6">
+                      <RenderAllFieldsByUiConfig
+                        key={i}
+                        fields={convertUiField(
+                          i18n,
+                          section.fields,
+                          form,
+                          getConverterById,
+                        )}
+                      />
+                    </div>
                   </div>
                 </div>
               </div>
-            </div>
-          );
-        })}
+            );
+          })}
       </div>
 
+      <pre>{JSON.stringify(state.result, undefined, 2)}</pre>
       <div class="mt-6 flex items-center justify-end gap-x-6">
         <button
           onClick={onComplete}
@@ -262,7 +260,10 @@ function getRequiredFields(fields: UIFormElementConfig[]): 
Array<UIHandlerId> {
   });
   return shape;
 }
-function getShapeFromFields(fields: UIFormElementConfig[]): Array<UIHandlerId> 
{
+function getShapeFromFields(
+  fields: UIFormElementConfig[],
+  parent: string,
+): Array<UIHandlerId> {
   const shape: Array<UIHandlerId> = [];
   fields.forEach((field) => {
     if ("id" in field) {
@@ -273,7 +274,10 @@ function getShapeFromFields(fields: 
UIFormElementConfig[]): Array<UIHandlerId> {
       }
       shape.push(field.id);
     } else if (field.type === "group") {
-      Array.prototype.push.apply(shape, getShapeFromFields(field.fields));
+      Array.prototype.push.apply(
+        shape,
+        getShapeFromFields(field.fields, parent),
+      );
     }
   });
   return shape;
diff --git a/packages/kyc-ui/src/pages/TriggerKyc.tsx 
b/packages/kyc-ui/src/pages/TriggerKyc.tsx
index c7d2fa4cb..ce4730011 100644
--- a/packages/kyc-ui/src/pages/TriggerKyc.tsx
+++ b/packages/kyc-ui/src/pages/TriggerKyc.tsx
@@ -131,25 +131,25 @@ export function TriggerKyc({ onKycStarted }: Props): 
VNode {
 
   useEffect(() => {
     if (!kycAccount) return;
-    const paytoHash = kycAccount
+    const paytoHash = kycAccount;
     async function check() {
-      const {signingKey} = await accountPromise;
+      const { signingKey } = await accountPromise;
       const result = await lib.exchange.checkKycStatus(signingKey, paytoHash);
       if (result.type === "ok") {
         if (result.body) {
-          onKycStarted(result.body.access_token)
+          onKycStarted(result.body.access_token);
         } else {
-          console.log("empty body")
+          console.log("empty body");
         }
       } else {
-        switch(result.case) {
-          case HttpStatusCode.Forbidden:{
+        switch (result.case) {
+          case HttpStatusCode.Forbidden: {
             notify({
               type: "error",
               title: i18n.str`could not create token`,
               description: i18n.str`access denied`,
               when: AbsoluteTime.now(),
-            })
+            });
           }
           case HttpStatusCode.NotFound: {
             notify({
@@ -157,7 +157,7 @@ export function TriggerKyc({ onKycStarted }: Props): VNode {
               title: i18n.str`could not create token`,
               description: i18n.str`not found`,
               when: AbsoluteTime.now(),
-            })
+            });
           }
           case HttpStatusCode.Conflict: {
             notify({
@@ -165,49 +165,52 @@ export function TriggerKyc({ onKycStarted }: Props): 
VNode {
               title: i18n.str`could not create token`,
               description: i18n.str`conflict`,
               when: AbsoluteTime.now(),
-            })
-
+            });
           }
         }
       }
     }
-    check()
+    check();
   }, [kycAccount]);
 
-  const submitHandler =
-    theForm === undefined || state.status === "fail"
-      ? undefined
-      : withErrorHandler(
-          async () => {
-            const account = await accountPromise;
+  function triggerAmount(amount:AmountJson) {
+    return withErrorHandler(
+      async () => {
+        const account = await accountPromise;
 
-            return lib.exchange.notifyKycBalanceLimit(
-              account,
-              Amounts.stringify(state.result.amount),
-            );
-          },
-          (res) => {
-            notify({
-              type: "info",
-              title: i18n.str`No kyc required`,
-              when: AbsoluteTime.now(),
-            });
-          },
-          (fail) => {
-            switch (fail.case) {
-              case HttpStatusCode.Forbidden:
-                return i18n.str`Access denied trying to test balance.`;
-              case HttpStatusCode.UnavailableForLegalReasons:
-                setKycAccount(fail.body.h_payto);
-                return i18n.str`Unavailable For Legal Reasons`;
-              default:
-                assertUnreachable(fail);
-            }
-          },
+        return lib.exchange.notifyKycBalanceLimit(
+          account,
+          Amounts.stringify(amount),
         );
+      },
+      (res) => {
+        notify({
+          type: "info",
+          title: i18n.str`No kyc required`,
+          when: AbsoluteTime.now(),
+        });
+      },
+      (fail) => {
+        switch (fail.case) {
+          case HttpStatusCode.Forbidden:
+            return i18n.str`Access denied trying to test balance.`;
+          case HttpStatusCode.UnavailableForLegalReasons:
+            setKycAccount(fail.body.h_payto);
+            return i18n.str`Unavailable For Legal Reasons`;
+          default:
+            assertUnreachable(fail);
+        }
+      },
+    )
+  }
+
+  const sendFormValue =
+    theForm === undefined || state.status === "fail"
+      ? undefined
+      : triggerAmount(state.result.amount);
 
   if (kycAccount) {
-    return <div>loading...</div>
+    return <div>loading...</div>;
   }
 
   return (
@@ -260,13 +263,114 @@ export function TriggerKyc({ onKycStarted }: Props): 
VNode {
         </button>
         <Button
           type="submit"
-          handler={submitHandler}
+          handler={sendFormValue}
           // disabled={!submitHandler}
           class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
         >
           <i18n.Translate>Confirm</i18n.Translate>
         </Button>
       </div>
+
+      <div class="grid grid-cols-1 gap-x-8 gap-y-4 ">
+        <p>
+          <i18n.Translate>
+            This actions will trigger wallet balance kyc above 1000000
+            threshold, the exchange should be properly configured to trigger 
the
+            desired kyc flow.
+          </i18n.Translate>
+        </p>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000070`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger TOPS Terms of service</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000080`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger GLS onboarding</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000000`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF Start</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000010`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF Natural</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000020`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF operational</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000030`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF foundation</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000040`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF insurance</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000050`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF trust</i18n.Translate>
+          </Button>
+        </div>
+        <div>
+          <Button
+            type="submit"
+            
handler={triggerAmount(Amounts.parseOrThrow(`${config.currency}:1000060`))}
+            // disabled={!submitHandler}
+            class="disabled:opacity-50 disabled:cursor-default rounded-md 
bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+          >
+            <i18n.Translate>Trigger VQF other</i18n.Translate>
+          </Button>
+        </div>
+        
+      </div>
     </div>
   );
 }
diff --git a/packages/web-util/src/forms/InputArray.stories.tsx 
b/packages/web-util/src/forms/InputArray.stories.tsx
index fc6889189..6f478fd07 100644
--- a/packages/web-util/src/forms/InputArray.stories.tsx
+++ b/packages/web-util/src/forms/InputArray.stories.tsx
@@ -61,20 +61,21 @@ const form: FlexibleForm_Deprecated<TargetObject> = {
         {
           type: "array",
           label: "People" as TranslatedString,
-          fields: [        {
-            id: "name" as UIHandlerId,
-            type: "text",
-            required: true,
-            label: "Name" as TranslatedString,
-          },
-          {
-            id: "age" as UIHandlerId,
-            type: "integer",
-            required: true,
-            label: "Age" as TranslatedString,
-          },
-  ],
-          id: "name" as UIHandlerId,
+          fields: [
+            {
+              id: "name" as UIHandlerId,
+              type: "text",
+              required: true,
+              label: "Name" as TranslatedString,
+            },
+            {
+              id: "age" as UIHandlerId,
+              type: "integer",
+              required: true,
+              label: "Age" as TranslatedString,
+            },
+          ],
+          id: "people" as UIHandlerId,
           labelFieldId: "name" as UIHandlerId,
         },
       ],
@@ -82,7 +83,57 @@ const form: FlexibleForm_Deprecated<TargetObject> = {
   ],
 };
 
-export const SimpleComment = tests.createExample(TestedComponent, {
+export const FormWithArray = tests.createExample(TestedComponent, {
   initial,
   form,
 });
+
+const initial2: any = {
+};
+
+const form2: FlexibleForm_Deprecated<TargetObject> = {
+  design: [
+    {
+      title: "Personal information" as TranslatedString,
+      fields: [
+        {
+          type: "text",
+          id: "PERSON_FULL_NAME" as UIHandlerId,
+          label: "Full name",
+          required: true,
+        },
+      ],
+    },
+    {
+      title: "Representatives" as TranslatedString,
+      fields: [
+        {
+          type: "array",
+          id: "BUSINESS_LEGAL_REPRESENTATIVES" as UIHandlerId,
+          labelFieldId: "PERSON_FULL_NAME" as UIHandlerId,
+          label:
+            "List of natural persons that are legal representatives or 
shareholders",
+          fields: [
+            {
+              type: "text",
+              id: "PERSON_FULL_NAME" as UIHandlerId,
+              label: "Name",
+              required: true,
+            },
+            {
+              type: "text",
+              id: "PERSON_DATE_OF_BIRTH" as UIHandlerId,
+              label: "Date of birth",
+              required: true,
+            },
+          ],
+        },
+      ],
+    },
+  ],
+};
+
+export const NonMixingProperties = tests.createExample(TestedComponent, {
+  initial: initial2,
+  form: form2,
+});
diff --git a/packages/web-util/src/forms/InputArray.tsx 
b/packages/web-util/src/forms/InputArray.tsx
index 6b14a65b7..5db185561 100644
--- a/packages/web-util/src/forms/InputArray.tsx
+++ b/packages/web-util/src/forms/InputArray.tsx
@@ -5,6 +5,7 @@ import { FormProvider, UIFormProps } from "./FormProvider.js";
 import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
 import { RenderAllFieldsByUiConfig, UIFormField } from "./forms.js";
 import { useField } from "./useField.js";
+import { UIFormElementConfig, UIHandlerId } from "./ui-form.js";
 
 function Option({
   label,
@@ -79,6 +80,28 @@ export function noHandlerPropsAndNoContextForField(
   );
 }
 
+function getShapeFromFields(
+  fields: UIFormElementConfig[],
+): Array<UIHandlerId> {
+  const shape: Array<UIHandlerId> = [];
+  fields.forEach((field) => {
+    if ("id" in field) {
+      // FIXME: this should be a validation when loading the form
+      // consistency check
+      if (shape.indexOf(field.id) !== -1) {
+        throw Error(`already present: ${field.id}`);
+      }
+      shape.push(field.id);
+    } else if (field.type === "group") {
+      Array.prototype.push.apply(
+        shape,
+        getShapeFromFields(field.fields),
+      );
+    }
+  });
+  return shape;
+}
+
 export function InputArray<T extends object, K extends keyof T>(
   props: {
     fields: UIFormField[];
@@ -102,6 +125,16 @@ export function InputArray<T extends object, K extends 
keyof T>(
   const selected =
     selectedIndex === undefined ? undefined : list[selectedIndex];
 
+  const shape: Array<UIHandlerId> = [];
+  const requiredFields: Array<UIHandlerId> = [];
+
+    Array.prototype.push.apply(shape, getShapeFromFields(fields));
+    Array.prototype.push.apply(
+      requiredFields,
+      getRequiredFields(fields),
+    );
+  
+
   return (
     <div class="sm:col-span-6">
       <LabelWithTooltipMaybeRequired
@@ -153,36 +186,36 @@ export function InputArray<T extends object, K extends 
keyof T>(
            * This form provider act as a substate of the parent form
            * Consider creating an InnerFormProvider since not every feature is 
expected
            */
-          <FormProvider
-            initial={selected}
-            readOnly={state.disabled}
-            computeFormState={(v) => {
-              // current state is ignored
-              // the state is defined by the parent form
+          // <FormProvider
+          //   initial={selected ?? {}}
+          //   readOnly={state.disabled}
+          //   computeFormState={(v) => {
+          //     // current state is ignored
+          //     // the state is defined by the parent form
 
-              // elements should be present in the state object since this is 
expected to be an array
-              //@ts-ignore
-              // return state.elements[selectedIndex];
-              return {};
-            }}
-            onSubmit={(v) => {
-              const newValue = [...list];
-              newValue.splice(selectedIndex, 1, v);
-              onChange(newValue as any);
-              setSelectedIndex(undefined);
-            }}
-            onUpdate={(v) => {
-              const newValue = [...list];
-              newValue.splice(selectedIndex, 1, v);
-              onChange(newValue as any);
-            }}
-          >
+          //     // elements should be present in the state object since this 
is expected to be an array
+          //     //@ts-ignore
+          //     // return state.elements[selectedIndex];
+          //     return {};
+          //   }}
+          //   onSubmit={(v) => {
+          //     const newValue = [...list];
+          //     newValue.splice(selectedIndex, 1, v);
+          //     onChange(newValue as any);
+          //     setSelectedIndex(undefined);
+          //   }}
+          //   onUpdate={(v) => {
+          //     const newValue = [...list];
+          //     newValue.splice(selectedIndex, 1, v);
+          //     onChange(newValue as any);
+          //   }}
+          // >
             <div class="px-4 py-6">
               <div class="grid grid-cols-1 gap-y-8 ">
-                <RenderAllFieldsByUiConfig fields={fields} />
+                <RenderAllFieldsByUiConfig fields={fields}  />
               </div>
             </div>
-          </FormProvider>
+          // </FormProvider>
         )}
         {selectedIndex !== undefined && (
           <div class="flex items-center justify-end gap-x-6">
diff --git a/packages/web-util/src/forms/InputLine.tsx 
b/packages/web-util/src/forms/InputLine.tsx
index 4c0176195..db5e00551 100644
--- a/packages/web-util/src/forms/InputLine.tsx
+++ b/packages/web-util/src/forms/InputLine.tsx
@@ -164,7 +164,7 @@ export function InputLine<T extends object, K extends keyof 
T>(
   //FIXME: remove deprecated
   const fieldCtx = useField<T, K>(props.name);
   const { value, onChange, state, error } =
-    props.handler ?? fieldCtx ?? 
noHandlerPropsAndNoContextForField(props.name);
+    props.handler ?? noHandlerPropsAndNoContextForField(props.name);
 
   // const [text, setText] = useState("");
   const fromString: (s: string) => any =
diff --git a/packages/web-util/src/forms/forms.ts 
b/packages/web-util/src/forms/forms.ts
index 70c090fb1..ce9b9e258 100644
--- a/packages/web-util/src/forms/forms.ts
+++ b/packages/web-util/src/forms/forms.ts
@@ -19,7 +19,7 @@ import {
   UIFieldElementDescription,
 } from "../index.browser.js";
 import { assertUnreachable, TranslatedString } from "@gnu-taler/taler-util";
-import { UIFormFieldBaseConfig, UIFormElementConfig } from "./ui-form.js";
+import { UIFormFieldBaseConfig, UIFormElementConfig, UIHandlerId } from 
"./ui-form.js";
 import { HtmlIframe } from "./HtmlIframe.js";
 /**
  * Constrain the type with the ui props
@@ -215,7 +215,7 @@ export function convertUiField(
             fields: convertUiField(
               i18n_,
               config.fields,
-              form,
+              (form as any)[config.id].value ?? {},
               getConverterById,
             ),
           },
@@ -349,6 +349,7 @@ function converInputFieldsProps(
   getConverterById: GetConverterById,
 ) {
   const names = p.id.split(".");
+  console.log("NAMES", names, getValueDeeper2(form, names), form !== undefined)
   return {
     converter: getConverterById(p.converterId, p),
     handler: getValueDeeper2(form, names),

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]