aboutsummaryrefslogtreecommitdiff
path: root/packages/exchange-backoffice-ui
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-05-15 15:38:04 -0300
committerSebastian <sebasjm@gmail.com>2023-05-15 15:38:04 -0300
commit02fb71c0ff69d293911f4b0945ab964a87402d0c (patch)
tree175f5c86289b1703d4815e3597bda8b9f81d4f84 /packages/exchange-backoffice-ui
parentf4f798b1b4bae3073b669a562fd2b3a7880dffc3 (diff)
third form and placeholder for the next ones
Diffstat (limited to 'packages/exchange-backoffice-ui')
-rw-r--r--packages/exchange-backoffice-ui/src/Dashborad.tsx103
-rw-r--r--packages/exchange-backoffice-ui/src/NiceForm.tsx65
-rw-r--r--packages/exchange-backoffice-ui/src/forms/902_12e.ts433
-rw-r--r--packages/exchange-backoffice-ui/src/forms/902_13e.ts512
-rw-r--r--packages/exchange-backoffice-ui/src/forms/902_15e.ts48
-rw-r--r--packages/exchange-backoffice-ui/src/forms/902_4e.ts48
-rw-r--r--packages/exchange-backoffice-ui/src/forms/902_5e.ts48
-rw-r--r--packages/exchange-backoffice-ui/src/forms/902_9e.ts48
-rw-r--r--packages/exchange-backoffice-ui/src/handlers/FormProvider.tsx7
9 files changed, 1273 insertions, 39 deletions
diff --git a/packages/exchange-backoffice-ui/src/Dashborad.tsx b/packages/exchange-backoffice-ui/src/Dashborad.tsx
index 3ad2b7745..f31160fee 100644
--- a/packages/exchange-backoffice-ui/src/Dashborad.tsx
+++ b/packages/exchange-backoffice-ui/src/Dashborad.tsx
@@ -20,6 +20,40 @@ import { useEffect, useRef, useState } from "preact/hooks";
import { NiceForm } from "./NiceForm.js";
import { v1 as form_902_1e_v1 } from "./forms/902_1e.js";
import { v1 as form_902_11e_v1 } from "./forms/902_11e.js";
+import { v1 as form_902_12e_v1 } from "./forms/902_12e.js";
+import { v1 as form_902_13e_v1 } from "./forms/902_13e.js";
+import { v1 as form_902_15e_v1 } from "./forms/902_15e.js";
+import { v1 as form_902_9e_v1 } from "./forms/902_9e.js";
+import { v1 as form_902_5e_v1 } from "./forms/902_5e.js";
+import { v1 as form_902_4e_v1 } from "./forms/902_4e.js";
+
+/**
+ * references between forms
+ *
+ * 902.1e
+ * --> 902.11 (operational legal entity or partnership)
+ * --> 902.12 (a foundation)
+ * --> 902.13 (a trust)
+ * --> 902.15 (life insurance policy)
+ * --> 902.9 (all other cases)
+ * --> 902.5 (cash transaction with no customer profile)
+ * --> 902.4 (risk profile)
+ *
+ * 902.11
+ * --> 902.9 (beneficial owner in fiduciary holding assets)
+ *
+ * 902.12
+ *
+ * 902.13
+ *
+ * 902.15
+ *
+ * 902.9
+ *
+ * 902.5
+ *
+ * 902.4
+ */
const navigation = [
{
@@ -32,6 +66,36 @@ const navigation = [
icon: DocumentDuplicateIcon,
impl: form_902_11e_v1,
},
+ {
+ name: "Foundations (902.12e)",
+ icon: DocumentDuplicateIcon,
+ impl: form_902_12e_v1,
+ },
+ {
+ name: "Declaration for trusts (902.13e)",
+ icon: DocumentDuplicateIcon,
+ impl: form_902_13e_v1,
+ },
+ {
+ name: "WIP (902.15e)",
+ icon: DocumentDuplicateIcon,
+ impl: form_902_15e_v1,
+ },
+ {
+ name: "WIP (902.9e)",
+ icon: DocumentDuplicateIcon,
+ impl: form_902_9e_v1,
+ },
+ {
+ name: "WIP (902.5e)",
+ icon: DocumentDuplicateIcon,
+ impl: form_902_5e_v1,
+ },
+ {
+ name: "WIP (902.4e)",
+ icon: DocumentDuplicateIcon,
+ impl: form_902_4e_v1,
+ },
];
const teams = [
{ id: 1, name: "Heroicons", href: "#", initial: "H", current: false },
@@ -69,15 +133,47 @@ function classNames(...classes: string[]) {
* @returns
*/
+/**
+ * TO BE FIXED:
+ *
+ * 1.- when the form change to other form and both form share the same structure
+ * the same input component may be rendered in the same place,
+ * since input are uncontrolled the are not re-rendered and since they are
+ * uncontrolled it will keep the value of the previous form.
+ * One solutions could be to remove the form when unloading and when the new
+ * form load it will start without previous vdom, preventing the cache
+ * to create this behavior.
+ * Other solutions could be using IDs in the fields that are constructed
+ * with the ID of the form, so two fields of different form will need to re-render
+ * cleaning up the state of the previous form.
+ *
+ * 2.- currently the design prop and the behavior prop of the flexible form
+ * are two side of the same coin. From the design point of view, it is important
+ * to design the form in a list-of-field manner and there may be additional
+ * content that is not directly mapped to the form structure (object)
+ * So maybe we want to change the current shape so the computation of the state
+ * of the form is in a field level, but this computation required the field value and
+ * the whole form values and state (since one field may be disabled/hidden) because
+ * of the value of other field.
+ *
+ * 3.- given the previous requirement, maybe the name of the field of the form could be
+ * a function (P: F -> V) where F is the form (or parent object) and V is the type of the
+ * property. That will help with the typing of the forms props
+ */
+
export function Dashboard({
children,
}: {
children?: ComponentChildren;
}): VNode {
const [sidebarOpen, setSidebarOpen] = useState(false);
- const [selectedForm, setSelectedForm] = useState(1);
+ const [selectedForm, setSelectedForm] = useState(3);
+ function changeForm(next: number) {
+ setSelectedForm(next);
+ }
const logRef = useRef<HTMLPreElement>(null);
const storedValue = {
+ fullName: "the logged fullName",
when: {
t_ms: new Date().getTime(),
},
@@ -92,7 +188,6 @@ export function Dashboard({
});
const showingFrom = navigation[selectedForm];
- console.log(showingFrom);
return (
<>
<div>
@@ -164,7 +259,7 @@ export function Dashboard({
{navigation.map((item, idx) => (
<li
key={item.name}
- onClick={(e) => setSelectedForm(idx)}
+ onClick={(e) => changeForm(idx)}
>
<a
href="#"
@@ -250,7 +345,7 @@ export function Dashboard({
<li>
<ul role="list" class="-mx-2 space-y-1">
{navigation.map((item, idx) => (
- <li key={item.name} onClick={(e) => setSelectedForm(idx)}>
+ <li key={item.name} onClick={(e) => changeForm(idx)}>
<a
href="#"
class={classNames(
diff --git a/packages/exchange-backoffice-ui/src/NiceForm.tsx b/packages/exchange-backoffice-ui/src/NiceForm.tsx
index 64f8aceea..b7790bbec 100644
--- a/packages/exchange-backoffice-ui/src/NiceForm.tsx
+++ b/packages/exchange-backoffice-ui/src/NiceForm.tsx
@@ -14,43 +14,40 @@ export function NiceForm<T extends object>({
onUpdate: (d: Partial<T>) => void;
}) {
const { i18n } = useTranslationContext();
- console.log("render");
return (
- <Fragment>
- <FormProvider
- initialValue={initial}
- onUpdate={onUpdate}
- computeFormState={form.behavior}
- >
- <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
- {form.design.map((section, i) => {
- return (
- <div 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={section.fields}
- />
- </div>
+ <FormProvider
+ initialValue={initial}
+ onUpdate={onUpdate}
+ computeFormState={form.behavior}
+ >
+ <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
+ {form.design.map((section, i) => {
+ return (
+ <div 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={section.fields}
+ />
</div>
</div>
</div>
- );
- })}
- </div>
- </FormProvider>
- </Fragment>
+ </div>
+ );
+ })}
+ </div>
+ </FormProvider>
);
}
diff --git a/packages/exchange-backoffice-ui/src/forms/902_12e.ts b/packages/exchange-backoffice-ui/src/forms/902_12e.ts
new file mode 100644
index 000000000..e58850660
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/forms/902_12e.ts
@@ -0,0 +1,433 @@
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
+import { FormState } from "../handlers/FormProvider.js";
+import { FlexibleForm } from "./index.js";
+
+export const v1: FlexibleForm<Form902_12e.Form> = {
+ versionId: "2023-05-15",
+ design: [
+ {
+ title: "Foundations" as TranslatedString,
+ fields: [
+ {
+ type: "textArea",
+ props: {
+ name: "contractingPartner",
+ label: "Contracting partner" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "knownAs",
+ label:
+ "The undersigned hereby declare(s) that as board member of the foundation, or of the highest supervisory body of an underlying company of a foundation, known as" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "foundation.name",
+ label:
+ "Name and information pertaining to the foundation" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "foundation.type",
+ label: "Type of foundation" as TranslatedString,
+ choices: [
+ {
+ label: "Discretionary foundation" as TranslatedString,
+ value: "discretionary",
+ },
+ {
+ label: "Non-discretionary foundation" as TranslatedString,
+ value: "non-discretionary",
+ },
+ ],
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "foundation.revocability",
+ label: "Revocability" as TranslatedString,
+ choices: [
+ {
+ label: "Revocable foundation" as TranslatedString,
+ value: "revocable",
+ },
+ {
+ label: "Irrevocable foundation" as TranslatedString,
+ value: "irrevocable",
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Information pertaining to the (ultimate economic, not fiduciary) founder (individual(s) or entity/ies)" as TranslatedString,
+ labelField: "fullName",
+ name: "founders",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfDeath",
+ label: "Date of death" as TranslatedString,
+ help: "if deceased" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToRevoke",
+ required: true,
+ label:
+ "Does the founder have the right to revoke the foundation?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "If the foundation results from the restructuring of pre-existing foundation (re-settlement) or the merger of pre-existing foundations, the following information pertaining to the (actual) founder(s) of the pre-existing foundation(s) has to be given" as TranslatedString,
+ labelField: "fullName",
+ name: "preExistingFounders",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfDeath",
+ label: "Date of death" as TranslatedString,
+ help: "if deceased" as TranslatedString,
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Pertaining to the beneficiary/-ies at the time of the signing of this form" as TranslatedString,
+ labelField: "fullName",
+ name: "beneficiaryWhenSigning",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToClaim",
+ label:
+ "Has the beneficiary an actual right to claim distribution?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ {
+ type: "textArea",
+ props: {
+ label:
+ "in addition to certain beneficiaries or if there is/are no defined beneficiary/ies pertaining to (a) group(s) of beneficiaries (e.g. descendants of the founder) known at the time of the signing of this form" as TranslatedString,
+ name: "beneficiaryExtra",
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Information pertaining to further persons having the right to determine or nominate representatives (e.g.) members of the foundation board), if these representatives may dispose over the assets or have the right to change the distribution of the assets or the nomination of beneficiaries" as TranslatedString,
+ labelField: "fullName",
+ name: "withRightToNominate",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToClaim",
+ label:
+ "has the person the right to revoke the foundation?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ {
+ type: "textArea",
+ props: {
+ label:
+ "in addition to certain beneficiaries or if there is/are no defined beneficiary/ies pertaining to (a) group(s) of beneficiaries (e.g. descendants of the founder) known at the time of the signing of this form" as TranslatedString,
+ name: "beneficiaryExtra",
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "date",
+ props: {
+ name: "when",
+ pattern: "dd/MM/yyyy",
+ label: "Date" as TranslatedString,
+ help: "format 'dd/MM/yyyy'" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "signature",
+ label: "Signature" as TranslatedString,
+ },
+ },
+ ],
+ },
+ ],
+ behavior: function formBehavior(
+ v: Partial<Form902_12e.Form>,
+ ): FormState<Form902_12e.Form> {
+ return {
+ founders: {
+ elements: (v.founders ?? []).map((f) => {
+ return {
+ rightToRevoke: {
+ hidden: v.foundation?.revocability !== "revocable",
+ },
+ };
+ }),
+ },
+ withRightToNominate: {
+ elements: (v.withRightToNominate ?? []).map((f) => {
+ return {
+ rightToRevoke: {
+ hidden: v.foundation?.revocability !== "revocable",
+ },
+ };
+ }),
+ },
+ when: {
+ disabled: true,
+ },
+ };
+ },
+};
+
+namespace Form902_12e {
+ interface Foundation {
+ name: string;
+ type: "discretionary" | "non-discretionary";
+ revocability: "revocable" | "irrevocable";
+ }
+ interface Person {
+ fullName: string;
+ address: string;
+ country: string;
+ dateOfBirth: AbsoluteTime;
+ nationality: string;
+ }
+ type WithRevoke<T> = {
+ rightToRevoke: "yes" | "no";
+ } & T;
+ type WithClaim<T> = {
+ rightToClaim: "yes" | "no";
+ } & T;
+ type WithDeath<T> = {
+ dateOfDeath: AbsoluteTime;
+ } & T;
+
+ type Founder = WithRevoke<WithDeath<Person>>;
+ type Beneficiary = WithClaim<Person>;
+
+ export interface Form {
+ contractingPartner: string;
+ knownAs: string;
+ boardMember: string;
+ foundation: Foundation;
+ founders: Array<Founder>;
+ preExistingFounders: Array<Founder>;
+ beneficiaryWhenSigning: Array<Beneficiary>;
+ beneficiaryExtra: Array<Beneficiary>;
+ withRightToNominate: Array<WithRevoke<Person>>;
+ when: AbsoluteTime;
+ }
+}
diff --git a/packages/exchange-backoffice-ui/src/forms/902_13e.ts b/packages/exchange-backoffice-ui/src/forms/902_13e.ts
new file mode 100644
index 000000000..04dd95bc0
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/forms/902_13e.ts
@@ -0,0 +1,512 @@
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
+import { FormState } from "../handlers/FormProvider.js";
+import { FlexibleForm } from "./index.js";
+
+export const v1: FlexibleForm<Form902_13e.Form> = {
+ versionId: "2023-05-15",
+ design: [
+ {
+ title: "Declaration for trusts" as TranslatedString,
+ fields: [
+ {
+ type: "textArea",
+ props: {
+ name: "contractingPartner",
+ label: "Contracting partner" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "knownAs",
+ label:
+ "The undersigned hereby declare(s) that as trustee or a member of highest supervisory body of an underlying company of a trust known as" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "trust.name",
+ label:
+ "Name and information pertaining to the trust" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "trust.type",
+ label: "Type of trust" as TranslatedString,
+ choices: [
+ {
+ label: "Discretionary trust" as TranslatedString,
+ value: "discretionary",
+ },
+ {
+ label: "Non-discretionary trust" as TranslatedString,
+ value: "non-discretionary",
+ },
+ ],
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "trust.revocability",
+ label: "Revocability" as TranslatedString,
+ choices: [
+ {
+ label: "Revocable foundation" as TranslatedString,
+ value: "revocable",
+ },
+ {
+ label: "Irrevocable foundation" as TranslatedString,
+ value: "irrevocable",
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Information pertaining to the (ultimate economic, not fiduciary) settlor of the trust (individual(s) or entity/ies)" as TranslatedString,
+ labelField: "fullName",
+ name: "settlors",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfDeath",
+ label: "Date of death" as TranslatedString,
+ help: "if deceased" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToRevoke",
+ required: true,
+ label:
+ "Does the founder have the right to revoke the trust?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "If the trust results from the restructuring of pre-existing trust (re-settlement) or the merger of pre-existing trusts, the following information pertaining to the (actual) settlor of the pre-existing trust(s) has to be given" as TranslatedString,
+ labelField: "fullName",
+ name: "preExistingSettlors",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfDeath",
+ label: "Date of death" as TranslatedString,
+ help: "if deceased" as TranslatedString,
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Pertaining to the beneficiary/-ies at the time of the signing of this form" as TranslatedString,
+ labelField: "fullName",
+ name: "beneficiaryWhenSigning",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToClaim",
+ label:
+ "Has the beneficiary an actual right to claim distribution?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ {
+ type: "textArea",
+ props: {
+ label:
+ "in addition to certain beneficiaries or if there is/are no defined beneficiary/ies pertaining to (a) group(s) of beneficiaries (e.g. descendants of the settlor) known at the time of the signing of this form" as TranslatedString,
+ name: "beneficiaryExtra",
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Information pertaining to the protector(s) as well as (a) further person(s) having the right to revoke the trust (in case of revocable trusts) or to appoint the trustee of a trust" as TranslatedString,
+ labelField: "asd",
+ name: "nothing",
+ fields: [],
+ },
+ },
+
+ {
+ type: "array",
+ props: {
+ label:
+ "Information pertaining to the protectors" as TranslatedString,
+ labelField: "fullName",
+ name: "protectors",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToClaim",
+ label:
+ "Does the protector have the right to revoke the trust?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "array",
+ props: {
+ label:
+ "Information pertaining to further persons" as TranslatedString,
+ labelField: "fullName",
+ name: "furtherPersons",
+ fields: [
+ {
+ type: "text",
+ props: {
+ name: "fullName",
+ label:
+ "Last name(s), first name(s)/entity" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "address",
+ label:
+ "Actual address of domicile/registered office" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "country",
+ label: "Country" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "dateOfBirth",
+ label: "Date of birth" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "nationality",
+ label: "Nationality" as TranslatedString,
+ },
+ },
+ {
+ type: "choiceStacked",
+ props: {
+ name: "rightToClaim",
+ label:
+ "Has this further person the right to revoke the trust?" as TranslatedString,
+ choices: [
+ {
+ label: "Yes" as TranslatedString,
+ value: "yes",
+ },
+ {
+ label: "No" as TranslatedString,
+ value: "no",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: "date",
+ props: {
+ name: "when",
+ pattern: "dd/MM/yyyy",
+ label: "Date" as TranslatedString,
+ help: "format 'dd/MM/yyyy'" as TranslatedString,
+ },
+ },
+ {
+ type: "text",
+ props: {
+ name: "signature",
+ label: "Signature" as TranslatedString,
+ },
+ },
+ ],
+ },
+ ],
+ behavior: function formBehavior(
+ v: Partial<Form902_13e.Form>,
+ ): FormState<Form902_13e.Form> {
+ return {
+ settlors: {
+ elements: (v.settlors ?? []).map((f) => {
+ return {
+ rightToRevoke: {
+ hidden: v.foundation?.revocability !== "revocable",
+ },
+ };
+ }),
+ },
+ protectors: {
+ elements: (v.protectors ?? []).map((f) => {
+ return {
+ rightToRevoke: {
+ hidden: v.foundation?.revocability !== "revocable",
+ },
+ };
+ }),
+ },
+ furtherPersons: {
+ elements: (v.furtherPersons ?? []).map((f) => {
+ return {
+ rightToRevoke: {
+ hidden: v.foundation?.revocability !== "revocable",
+ },
+ };
+ }),
+ },
+ when: {
+ disabled: true,
+ },
+ };
+ },
+};
+
+namespace Form902_13e {
+ interface Foundation {
+ name: string;
+ type: "discretionary" | "non-discretionary";
+ revocability: "revocable" | "irrevocable";
+ }
+ interface Person {
+ fullName: string;
+ address: string;
+ country: string;
+ dateOfBirth: AbsoluteTime;
+ nationality: string;
+ }
+ type WithRevoke<T> = {
+ rightToRevoke: "yes" | "no";
+ } & T;
+ type WithClaim<T> = {
+ rightToClaim: "yes" | "no";
+ } & T;
+ type WithDeath<T> = {
+ dateOfDeath: AbsoluteTime;
+ } & T;
+
+ type Founder = WithRevoke<WithDeath<Person>>;
+ type Beneficiary = WithClaim<Person>;
+
+ export interface Form {
+ contractingPartner: string;
+ knownAs: string;
+ boardMember: string;
+ foundation: Foundation;
+ settlors: Array<Founder>;
+ preExistingSettlors: Array<Founder>;
+ beneficiaryWhenSigning: Array<Beneficiary>;
+ beneficiaryExtra: Array<Beneficiary>;
+ protectors: Array<WithRevoke<Person>>;
+ furtherPersons: Array<WithRevoke<Person>>;
+ when: AbsoluteTime;
+ }
+}
diff --git a/packages/exchange-backoffice-ui/src/forms/902_15e.ts b/packages/exchange-backoffice-ui/src/forms/902_15e.ts
new file mode 100644
index 000000000..8f927cdc2
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/forms/902_15e.ts
@@ -0,0 +1,48 @@
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
+import { FlexibleForm, languageList } from "./index.js";
+import { FormState } from "../handlers/FormProvider.js";
+
+export const v1: FlexibleForm<Form902_12e.Form> = {
+ versionId: "2023-05-15",
+ design: [
+ {
+ title: "15" as TranslatedString,
+ description:
+ "for operating legal entities and partnership that are contracting partner as well as analogously for operating legal entities and partnership that are beneficial owners." as TranslatedString,
+ fields: [
+ {
+ type: "textArea",
+ props: {
+ name: "contractingPartner",
+ label: "Contracting partner" as TranslatedString,
+ },
+ },
+ {
+ type: "date",
+ props: {
+ name: "when",
+ pattern: "dd/MM/yyyy",
+ label: "Date" as TranslatedString,
+ help: "format 'dd/MM/yyyy'" as TranslatedString,
+ },
+ },
+ ],
+ },
+ ],
+ behavior: function formBehavior(
+ v: Partial<Form902_12e.Form>,
+ ): FormState<Form902_12e.Form> {
+ return {
+ when: {
+ disabled: true,
+ },
+ };
+ },
+};
+
+namespace Form902_12e {
+ export interface Form {
+ contractingPartner: string;
+ when: AbsoluteTime;
+ }
+}
diff --git a/packages/exchange-backoffice-ui/src/forms/902_4e.ts b/packages/exchange-backoffice-ui/src/forms/902_4e.ts
new file mode 100644
index 000000000..6e8d7f1e2
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/forms/902_4e.ts
@@ -0,0 +1,48 @@
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
+import { FlexibleForm, languageList } from "./index.js";
+import { FormState } from "../handlers/FormProvider.js";
+
+export const v1: FlexibleForm<Form902_12e.Form> = {
+ versionId: "2023-05-15",
+ design: [
+ {
+ title: "4" as TranslatedString,
+ description:
+ "for operating legal entities and partnership that are contracting partner as well as analogously for operating legal entities and partnership that are beneficial owners." as TranslatedString,
+ fields: [
+ {
+ type: "textArea",
+ props: {
+ name: "contractingPartner",
+ label: "Contracting partner" as TranslatedString,
+ },
+ },
+ {
+ type: "date",
+ props: {
+ name: "when",
+ pattern: "dd/MM/yyyy",
+ label: "Date" as TranslatedString,
+ help: "format 'dd/MM/yyyy'" as TranslatedString,
+ },
+ },
+ ],
+ },
+ ],
+ behavior: function formBehavior(
+ v: Partial<Form902_12e.Form>,
+ ): FormState<Form902_12e.Form> {
+ return {
+ when: {
+ disabled: true,
+ },
+ };
+ },
+};
+
+namespace Form902_12e {
+ export interface Form {
+ contractingPartner: string;
+ when: AbsoluteTime;
+ }
+}
diff --git a/packages/exchange-backoffice-ui/src/forms/902_5e.ts b/packages/exchange-backoffice-ui/src/forms/902_5e.ts
new file mode 100644
index 000000000..20013e727
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/forms/902_5e.ts
@@ -0,0 +1,48 @@
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
+import { FlexibleForm, languageList } from "./index.js";
+import { FormState } from "../handlers/FormProvider.js";
+
+export const v1: FlexibleForm<Form902_12e.Form> = {
+ versionId: "2023-05-15",
+ design: [
+ {
+ title: "5" as TranslatedString,
+ description:
+ "for operating legal entities and partnership that are contracting partner as well as analogously for operating legal entities and partnership that are beneficial owners." as TranslatedString,
+ fields: [
+ {
+ type: "textArea",
+ props: {
+ name: "contractingPartner",
+ label: "Contracting partner" as TranslatedString,
+ },
+ },
+ {
+ type: "date",
+ props: {
+ name: "when",
+ pattern: "dd/MM/yyyy",
+ label: "Date" as TranslatedString,
+ help: "format 'dd/MM/yyyy'" as TranslatedString,
+ },
+ },
+ ],
+ },
+ ],
+ behavior: function formBehavior(
+ v: Partial<Form902_12e.Form>,
+ ): FormState<Form902_12e.Form> {
+ return {
+ when: {
+ disabled: true,
+ },
+ };
+ },
+};
+
+namespace Form902_12e {
+ export interface Form {
+ contractingPartner: string;
+ when: AbsoluteTime;
+ }
+}
diff --git a/packages/exchange-backoffice-ui/src/forms/902_9e.ts b/packages/exchange-backoffice-ui/src/forms/902_9e.ts
new file mode 100644
index 000000000..d68caba23
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/forms/902_9e.ts
@@ -0,0 +1,48 @@
+import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
+import { FlexibleForm, languageList } from "./index.js";
+import { FormState } from "../handlers/FormProvider.js";
+
+export const v1: FlexibleForm<Form902_12e.Form> = {
+ versionId: "2023-05-15",
+ design: [
+ {
+ title: "9" as TranslatedString,
+ description:
+ "for operating legal entities and partnership that are contracting partner as well as analogously for operating legal entities and partnership that are beneficial owners." as TranslatedString,
+ fields: [
+ {
+ type: "textArea",
+ props: {
+ name: "contractingPartner",
+ label: "Contracting partner" as TranslatedString,
+ },
+ },
+ {
+ type: "date",
+ props: {
+ name: "when",
+ pattern: "dd/MM/yyyy",
+ label: "Date" as TranslatedString,
+ help: "format 'dd/MM/yyyy'" as TranslatedString,
+ },
+ },
+ ],
+ },
+ ],
+ behavior: function formBehavior(
+ v: Partial<Form902_12e.Form>,
+ ): FormState<Form902_12e.Form> {
+ return {
+ when: {
+ disabled: true,
+ },
+ };
+ },
+};
+
+namespace Form902_12e {
+ export interface Form {
+ contractingPartner: string;
+ when: AbsoluteTime;
+ }
+}
diff --git a/packages/exchange-backoffice-ui/src/handlers/FormProvider.tsx b/packages/exchange-backoffice-ui/src/handlers/FormProvider.tsx
index 4019fbc89..4397fc197 100644
--- a/packages/exchange-backoffice-ui/src/handlers/FormProvider.tsx
+++ b/packages/exchange-backoffice-ui/src/handlers/FormProvider.tsx
@@ -1,6 +1,6 @@
import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
import { ComponentChildren, VNode, createContext, h } from "preact";
-import { MutableRef, StateUpdater, useRef } from "preact/hooks";
+import { MutableRef, StateUpdater, useEffect, useRef } from "preact/hooks";
export interface FormType<T> {
value: MutableRef<Partial<T>>;
@@ -49,6 +49,11 @@ export function FormProvider<T>({
children: ComponentChildren;
}): VNode {
const value = useRef(initialValue ?? {});
+ useEffect(() => {
+ return function onUnload() {
+ value.current = {};
+ };
+ });
return (
<FormContext.Provider
value={{ initialValue, value, onUpdate, computeFormState }}