diff options
author | Sebastian <sebasjm@gmail.com> | 2023-05-16 11:33:29 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-05-16 11:33:29 -0300 |
commit | b35404a2b11905a5b3cdd0d59bdd340fb00ad086 (patch) | |
tree | 78d1b8c347e7d0c081046c2ca9423ae5ca21b4ff | |
parent | 245ab840baf1926ef2c03a8965fce85012887d92 (diff) | |
download | wallet-core-b35404a2b11905a5b3cdd0d59bdd340fb00ad086.tar.xz |
final form, i hope
-rw-r--r-- | packages/exchange-backoffice-ui/src/Dashborad.tsx | 28 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/forms/902_15e.ts | 8 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/forms/902_4e.ts | 785 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/forms/902_9e.ts | 6 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/handlers/Caption.tsx (renamed from packages/exchange-backoffice-ui/src/handlers/Separator.tsx) | 13 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/handlers/Group.tsx | 2 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/handlers/InputChoiceStacked.tsx | 6 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/handlers/InputLine.tsx | 2 | ||||
-rw-r--r-- | packages/exchange-backoffice-ui/src/handlers/forms.ts | 12 |
9 files changed, 819 insertions, 43 deletions
diff --git a/packages/exchange-backoffice-ui/src/Dashborad.tsx b/packages/exchange-backoffice-ui/src/Dashborad.tsx index dce41b496..80df4127a 100644 --- a/packages/exchange-backoffice-ui/src/Dashborad.tsx +++ b/packages/exchange-backoffice-ui/src/Dashborad.tsx @@ -1,31 +1,26 @@ -import { ComponentChildren, Fragment, VNode, h } from "preact"; import { Dialog, Menu, Transition } from "@headlessui/react"; import { + ChevronDownIcon, + MagnifyingGlassIcon, +} from "@heroicons/react/20/solid"; +import { Bars3Icon, BellIcon, - CalendarIcon, - ChartPieIcon, Cog6ToothIcon, DocumentDuplicateIcon, - FolderIcon, - HomeIcon, - UsersIcon, XMarkIcon, } from "@heroicons/react/24/outline"; -import { - ChevronDownIcon, - MagnifyingGlassIcon, -} from "@heroicons/react/20/solid"; +import { ComponentChildren, Fragment, VNode, h } from "preact"; 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_1e_v1 } from "./forms/902_1e.js"; import { v1 as form_902_4e_v1 } from "./forms/902_4e.js"; +import { v1 as form_902_5e_v1 } from "./forms/902_5e.js"; +import { v1 as form_902_9e_v1 } from "./forms/902_9e.js"; /** * references between forms @@ -92,7 +87,7 @@ const navigation = [ impl: form_902_5e_v1, }, { - name: "WIP (902.4e)", + name: "Risk profile (902.4e)", icon: DocumentDuplicateIcon, impl: form_902_4e_v1, }, @@ -159,6 +154,9 @@ function classNames(...classes: string[]) { * 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 + * + * 4.- tooltip are not placed correctly: the arrow should point the question mark + * and the text area should be bigger */ export function Dashboard({ @@ -167,7 +165,7 @@ export function Dashboard({ children?: ComponentChildren; }): VNode { const [sidebarOpen, setSidebarOpen] = useState(false); - const [selectedForm, setSelectedForm] = useState(6); + const [selectedForm, setSelectedForm] = useState(7); function changeForm(next: number) { setSelectedForm(next); } diff --git a/packages/exchange-backoffice-ui/src/forms/902_15e.ts b/packages/exchange-backoffice-ui/src/forms/902_15e.ts index 07290858e..8e3fa1350 100644 --- a/packages/exchange-backoffice-ui/src/forms/902_15e.ts +++ b/packages/exchange-backoffice-ui/src/forms/902_15e.ts @@ -32,14 +32,14 @@ export const v1: FlexibleForm<Form902_15e.Form> = { }, }, { - type: "separator", + type: "caption", props: { label: "The contracting partner confirms in accordance with Art. 41a SRO Regulations that it is a licensed and state-supervised insurance company and that it has entered into the above-mentioned contractual relationship the assets connected to the life insurance policy also mentioned above." as TranslatedString, }, }, { - type: "separator", + type: "caption", props: { label: "In relation with the above insurance policy, the contracting partner gives the following further details" as TranslatedString, @@ -127,7 +127,7 @@ export const v1: FlexibleForm<Form902_15e.Form> = { }, }, { - type: "separator", + type: "caption", props: { label: "The contracting partner hereby undertakes to automatically inform the financial intermediary of any changes. The contracting partner hereby also declares having been given permission by the above individuals and/or entities to transmit their data to the financial intermediary" as TranslatedString, @@ -150,7 +150,7 @@ export const v1: FlexibleForm<Form902_15e.Form> = { }, }, { - type: "separator", + type: "caption", props: { label: "It is a criminal offense to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)" as TranslatedString, diff --git a/packages/exchange-backoffice-ui/src/forms/902_4e.ts b/packages/exchange-backoffice-ui/src/forms/902_4e.ts index dd00beccf..ca7ef8505 100644 --- a/packages/exchange-backoffice-ui/src/forms/902_4e.ts +++ b/packages/exchange-backoffice-ui/src/forms/902_4e.ts @@ -1,20 +1,44 @@ import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util"; import { FormState } from "../handlers/FormProvider.js"; import { FlexibleForm } from "./index.js"; +import { ArrowRightIcon } from "@heroicons/react/24/outline"; +import { h as create } from "preact"; +import { ChevronRightIcon } from "@heroicons/react/24/solid"; -export const v1: FlexibleForm<Form902_12e.Form> = { +export const v1: FlexibleForm<Form902_4.Form> = { versionId: "2023-05-15", design: [ { - title: "4" as TranslatedString, + title: "Risk Profile AMLA" 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, + "Evaluation of business relationship with increased risk and definition of criteria for transaction monitoring." as TranslatedString, fields: [ { - type: "textArea", + type: "caption", + props: { + label: + "The member performs additional clarifications if the business relationship or the transaction is classified as increased risk (Art. 56 SRO Regulations)" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "text", + props: { + name: "customer", + label: "Customer" as TranslatedString, + help: "Pursuant identification form (VQF doc. Nr. 902.1) numeral 1" as TranslatedString, + }, + }, + ], + }, + { + title: "This form was completed by" as TranslatedString, + fields: [ + { + type: "text", props: { - name: "contractingPartner", - label: "Contracting partner" as TranslatedString, + label: "Full name" as TranslatedString, + name: "fullName", }, }, { @@ -28,10 +52,693 @@ export const v1: FlexibleForm<Form902_12e.Form> = { }, ], }, + { + title: + "Evaluation of politically exposed persons (PEP-Check)" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "This evaluation has to be completed by all members for every business relationship" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "choiceStacked", + props: { + label: "Foreign PEP" as TranslatedString, + tooltip: + "Definition see Art. 7 lit. g numeral 1 SRO Regulations" as TranslatedString, + help: "Is the customer, the beneficial owner or the controlling person or authorized representative a foreign PEP or closely related to such a person?" as TranslatedString, + name: "pep.foreign", + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: "Yes" as TranslatedString, + description: + "The business relationship is compulsory classified as increased risk" as TranslatedString, + value: "yes", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: + "Domestic PEP and PEP of International Organizations" as TranslatedString, + tooltip: + "Definition see Art. 7 lit. g numeral 2 and 3 SRO Regulations " as TranslatedString, + help: "Is the customer, the beneficial owner or the controlling person or authorized representative a domestic PEP or PEP in International Organizations or closely related to such a person?" as TranslatedString, + name: "pep.domestic", + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: + "Yes, but NOT risk criterion pursuant to numeral 3 subsequently increased." as TranslatedString, + value: "yes-but-no-risk", + }, + { + label: + "Yes, AND a risk criterion pursuant to numeral 3 subsequently increased." as TranslatedString, + description: + "Classification of the business relationship as increased risk is compulsory" as TranslatedString, + value: "yes", + }, + ], + }, + }, + { + type: "date", + props: { + label: + "The decision of the Senior executive body on the acceptance of a business relationship with a PEP was obtained on" as TranslatedString, + name: "pep.when", + pattern: "dd/MM/yyyy", + placeholder: "dd/MM/yyyy" as TranslatedString, + }, + }, + ], + }, + { + title: + 'Evaluation "high risk" or non-cooperative country' as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "This evaluation has to be completed by all members for every business relationship" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "choiceStacked", + props: { + label: '"High risk" or non-cooperative country' as TranslatedString, + help: 'Is the customer, the beneficial owner or the controlling person or authorized representative in a country considered by the FATF "high risk" or non-cooperative and for which FATF requires increased diligence?' as TranslatedString, + name: "highRisk.evaluation", + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: "Yes" as TranslatedString, + description: + "considered as business relationship with increased risk" as TranslatedString, + value: "yes", + }, + ], + }, + }, + { + type: "date", + props: { + label: + "The decision of the Senior executive body on the acceptance of a business relationship with a PEP was obtained on" as TranslatedString, + name: "highRisk.when", + pattern: "dd/MM/yyyy", + placeholder: "dd/MM/yyyy" as TranslatedString, + }, + }, + ], + }, + { + title: "Evaluation of business relationship risk" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "This evaluation has to be completed by all members who have in total more than 20 customers for every business relationship. At least two risk categories have to be chosen and assessed" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "group", + props: { + before: "a) Country risk (nationality)" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + label: "Domicile/residential address" as TranslatedString, + name: "evaluation.nationality.address", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + { + label: "Controlling person" as TranslatedString, + value: "controlling", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Nationality" as TranslatedString, + name: "evaluation.nationality.nationality", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.nationality.risk", + choices: [ + { + label: + "Risk 0 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "low", + }, + { + label: + "Risk 1 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "medium", + }, + { + label: + "Risk 2 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "b) Country risk (business activity)" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + label: "Place of business activity" as TranslatedString, + name: "evaluation.business.place", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.business.risk", + choices: [ + { + label: + "Risk 0 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "low", + }, + { + label: + "Risk 1 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "medium", + }, + { + label: + "Risk 2 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "c) Country risk (payments)" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Country of origin and destination of frequent payments (if known)" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.payments.risk", + choices: [ + { + label: + "Risk 0 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "low", + }, + { + label: + "Risk 1 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "medium", + }, + { + label: + "Risk 2 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "d) Industry risk" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + label: + "Nature of customer's business activity" as TranslatedString, + name: "evaluation.industry.nature", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.payments.risk", + choices: [ + { + label: + "Clearly defined, transparent, easily comprehensible business activity well known to the member" as TranslatedString, + value: "low", + }, + { + label: + "Business activity with a high level of cash transactions" as TranslatedString, + value: "medium-cash", + }, + { + label: + "Business activity not well known to the member" as TranslatedString, + value: "medium-unknown", + }, + { + label: + "Trade in munitions/arms, raw gem stones/diamonds, jewelry, international trade in exotic animals, casino and lottery business, trade in erotic wares" as TranslatedString, + value: "high-restricted", + }, + { + label: + "Member has no personal knowledge of the customer's industry" as TranslatedString, + value: "high-unknown", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "e) Contact risk" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Types of contact to the customer/ beneficial owner of the assets" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.contact.risk", + choices: [ + { + label: + "Personal acquaintance between member and customer/beneficial owner of the assets over several years (at least 2) prior to entering into the business relationship" as TranslatedString, + value: "low", + }, + { + label: + "The customer/beneficial owner was not personally known to the member for several years (at least 2) prior to entering into the business relationship; however (a) no business was entered into in the absence of the customer/beneficial owner, or (b) the customer was at least introduced/brokered by a trusted third party" as TranslatedString, + value: "medium", + }, + { + label: + "The customer/beneficial owner was not personally known to the member and business was entered into in the absence of the former (relationship by correspondence) and the customer was not introduced/brokered by a trusted third party" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "f) Product risk" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Nature of services and products requested by the customer" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.product.risk", + choices: [ + { + label: + "Easy to understand, transparent services and products whose financial background is easy to comprehend and verify" as TranslatedString, + value: "low", + }, + { + label: + "More sophisticated services/products whose financial background is not readily easy to comprehend and verify" as TranslatedString, + value: "medium", + }, + { + label: + "Main focus on offshore business (especially: relationships with domiciliary companies or other such offshore organisations)" as TranslatedString, + value: "high-offshore", + }, + { + label: + "Complex structures in particular by using a domiciliary company with fiduciary shareholders in a non-transparent jurisdiction, without comprehensible reason or for the purpose of short-term asset placement" as TranslatedString, + value: "high-structure", + }, + { + label: + "The customer or beneficial owner of the assets has a large number of accounts with pass-through transactions (pass-through accounts)" as TranslatedString, + value: "high-accounts", + }, + { + label: + "Complex services/products whose financial background can’t be understood or verified with considerable effort" as TranslatedString, + value: "high-service", + }, + { + label: + "Frequent transactions with increased risks" as TranslatedString, + value: "high-freq-tx", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "g) Criteria defined by the member" as TranslatedString, + fields: [ + { + type: "text", + props: { + label: "Criteria definition" as TranslatedString, + name: "evaluation.custom.definition", + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.custom.risk", + choices: [ + { + label: "Low" as TranslatedString, + value: "low", + }, + { + label: "Medium" as TranslatedString, + value: "medium", + }, + { + label: "High" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "caption", + props: { + label: + "Overall assessment of the business relationship" as TranslatedString, + }, + }, + { + type: "group", + props: { + before: + "A business relationship is classified as increased risk if:" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Business relationship with PEP pursuant to numeral 1 (no exception possible)" as TranslatedString, + before: create(ChevronRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "caption", + props: { + label: + 'Relationship with a person from a "high risk" or non-cooperative country according to numeral 2 (no exceptions possible)' as TranslatedString, + before: create(ChevronRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "caption", + props: { + label: + "Min. one criterion pursuant to numeral 3 was assessed with risk 2 or min. two criteria pursuant to numeral 3 were assessed with risk 1 (exception: justification by the member below why the business relationship overall does not have to be classified as increased risk despite the fact that individual risk criteria are increased)" as TranslatedString, + before: create(ChevronRightIcon, { class: "h-6 w-6" }), + }, + }, + ], + }, + }, + { + type: "textArea", + props: { + label: + "Justification for differing risk assessment" as TranslatedString, + name: "evaluation.overall.justification", + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk classified" as TranslatedString, + name: "evaluation.overall.risk", + choices: [ + { + label: + "Business relationship _without_ increased risk" as TranslatedString, + value: "without", + }, + { + label: + "Business relationship __with__ increased risk" as TranslatedString, + value: "with", + }, + ], + }, + }, + { + type: "date", + props: { + label: + "The decision of the Senior executive body on the acceptance of a business relationship with a PEP was obtained on" as TranslatedString, + name: "evaluation.when", + pattern: "dd/MM/yyyy", + placeholder: "dd/MM/yyyy" as TranslatedString, + }, + }, + ], + }, + { + title: + "Criteria for identification of increased risk transactions (transaction monitoring)" as TranslatedString, + fields: [ + { + type: "group", + props: { + before: "Criteria" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Classification as as increased risk is compulsory if" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-6 h-6" }), + label: + "Transactions for which assets with an equivalent value of CHF 100'000.- or more are physically introduced at the beginning of the business relationship, either at once or in a staggered manner" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-6 h-6" }), + label: + 'Money and asset transfers ("money transfer") whereby a single transaction or multiple transactions which appear to be related reach or exceed the amount of CHF 5,000.-' as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-6 h-6" }), + label: + 'Payments from or to a country that is considered to be "high risk" or non-cooperative by the FATF and for which increased diligence is required' as TranslatedString, + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: + "Additional criteria defined by the member" as TranslatedString, + fields: [ + { + type: "caption", + props: { + before: create(ArrowRightIcon, { class: "w-6 h-6" }), + label: + "All members have to define min. 1 additional criterion for every business relationship to identify unusual transactions" as TranslatedString, + }, + }, + { + type: "textArea", + props: { + label: "Description" as TranslatedString, + name: "criteria.additional", + }, + }, + { + type: "group", + props: { + before: + "Possible criteria (Art. 59 para. 2 SRO Regulations)" as TranslatedString, + fields: [ + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "the amount of inflowing and outflowing assets" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "type, volume and frequency of transactions usual to the business relationship (considerable variance would be unusual)" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "type, volume and frequency of transactions usual to comparable business relationships (considerable variance would be unusual)" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "description of expected transaction patterns which the client notify the member of (considerable variance would be unusual)" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + 'The country of origin or destination of payments, especially in the case of payments from or to a country considered by the FATF as "high risk" or non-cooperative' as TranslatedString, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, ], behavior: function formBehavior( - v: Partial<Form902_12e.Form>, - ): FormState<Form902_12e.Form> { + v: Partial<Form902_4.Form>, + ): FormState<Form902_4.Form> { return { when: { disabled: true, @@ -40,9 +747,67 @@ export const v1: FlexibleForm<Form902_12e.Form> = { }, }; -namespace Form902_12e { +namespace Form902_4 { export interface Form { - contractingPartner: string; + customer: string; + fullName: string; when: AbsoluteTime; + pep: { + foreign: "yes" | "no"; + domestic: "yes" | "no" | "yes-but-no-risk"; + when: AbsoluteTime; + }; + highRisk: { + evaluation: "yes" | "no"; + when: AbsoluteTime; + }; + evaluation: { + nationality: { + address: "customer" | "owner" | "controlling"; + nationality: "customer" | "owner"; + risk: "low" | "medium" | "high"; + }; + business: { + place: "customer" | "owner"; + risk: "low" | "medium" | "high"; + }; + payments: { + risk: "low" | "medium" | "high"; + }; + industry: { + nature: "customer" | "owner"; + risk: + | "low" + | "medium-cash" + | "medium-unknown" + | "high-restricted" + | "high-unknown"; + }; + contact: { + risk: "low" | "medium" | "high"; + }; + product: { + risk: + | "low" + | "medium" + | "high-offshore" + | "high-structure" + | "high-accounts" + | "high-service" + | "high-freq-tx"; + }; + custom: { + definition: string; + risk: "low" | "medium" | "high"; + }; + overall: { + justification: string; + risk: "with" | "without"; + }; + when: AbsoluteTime; + }; + criteria: { + additional: string; + }; } } diff --git a/packages/exchange-backoffice-ui/src/forms/902_9e.ts b/packages/exchange-backoffice-ui/src/forms/902_9e.ts index 053cfaa69..6d88f8578 100644 --- a/packages/exchange-backoffice-ui/src/forms/902_9e.ts +++ b/packages/exchange-backoffice-ui/src/forms/902_9e.ts @@ -26,7 +26,7 @@ export const v1: FlexibleForm<Form902_9e.Form> = { }, }, { - type: "separator", + type: "caption", props: { label: "The contracting partner hereby declares that the person(s) listed below is/are the beneficial owner(s) of the assets involved in the business relationship. If the contracting partner is also the sole beneficial owner of the assets, the contracting partner's detail must be set out below" as TranslatedString, @@ -80,7 +80,7 @@ export const v1: FlexibleForm<Form902_9e.Form> = { }, }, { - type: "separator", + type: "caption", props: { label: "The contracting partner hereby undertakes to inform automatically of any changes to the information contained herein" as TranslatedString, @@ -94,7 +94,7 @@ export const v1: FlexibleForm<Form902_9e.Form> = { }, }, { - type: "separator", + type: "caption", props: { label: "It is a criminal offense to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)" as TranslatedString, diff --git a/packages/exchange-backoffice-ui/src/handlers/Separator.tsx b/packages/exchange-backoffice-ui/src/handlers/Caption.tsx index 5fa25c3ca..fbf154d89 100644 --- a/packages/exchange-backoffice-ui/src/handlers/Separator.tsx +++ b/packages/exchange-backoffice-ui/src/handlers/Caption.tsx @@ -1,5 +1,6 @@ import { VNode, h } from "preact"; import { + IconAddon, InputLine, LabelWithTooltipMaybeRequired, UIFormProps, @@ -10,12 +11,20 @@ interface Props { label: TranslatedString; tooltip?: TranslatedString; help?: TranslatedString; + before?: VNode; + after?: VNode; } -export function Separator({ label, tooltip, help }: Props): VNode { +export function Caption({ before, after, label, tooltip, help }: Props): VNode { return ( - <div class="sm:col-span-6"> + <div class="sm:col-span-6 flex"> + {before !== undefined && ( + <span class="pointer-events-none flex items-center pr-2">{before}</span> + )} <LabelWithTooltipMaybeRequired label={label} tooltip={tooltip} /> + {after !== undefined && ( + <span class="pointer-events-none flex items-center pl-2">{after}</span> + )} {help && ( <p class="mt-2 text-sm text-gray-500" id="email-description"> {help} diff --git a/packages/exchange-backoffice-ui/src/handlers/Group.tsx b/packages/exchange-backoffice-ui/src/handlers/Group.tsx index 04af0647b..0645f6d97 100644 --- a/packages/exchange-backoffice-ui/src/handlers/Group.tsx +++ b/packages/exchange-backoffice-ui/src/handlers/Group.tsx @@ -28,7 +28,7 @@ export function Group({ /> )} </div> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> + <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-2 sm:grid-cols-6"> <RenderAllFieldsByUiConfig fields={fields} /> </div> <div class="pt-4"> diff --git a/packages/exchange-backoffice-ui/src/handlers/InputChoiceStacked.tsx b/packages/exchange-backoffice-ui/src/handlers/InputChoiceStacked.tsx index b19a0d82e..361eb39a3 100644 --- a/packages/exchange-backoffice-ui/src/handlers/InputChoiceStacked.tsx +++ b/packages/exchange-backoffice-ui/src/handlers/InputChoiceStacked.tsx @@ -19,6 +19,7 @@ export function InputChoiceStacked( name, label, tooltip, + help, placeholder, required, before, @@ -88,6 +89,11 @@ export function InputChoiceStacked( })} </div> </fieldset> + {help && ( + <p class="mt-2 text-sm text-gray-500" id="email-description"> + {help} + </p> + )} </div> ); } diff --git a/packages/exchange-backoffice-ui/src/handlers/InputLine.tsx b/packages/exchange-backoffice-ui/src/handlers/InputLine.tsx index b3a5f8e98..255654949 100644 --- a/packages/exchange-backoffice-ui/src/handlers/InputLine.tsx +++ b/packages/exchange-backoffice-ui/src/handlers/InputLine.tsx @@ -2,7 +2,7 @@ import { TranslatedString } from "@gnu-taler/taler-util"; import { ComponentChildren, Fragment, VNode, h } from "preact"; import { useField } from "./useField.js"; -interface IconAddon { +export interface IconAddon { type: "icon"; icon: VNode; } diff --git a/packages/exchange-backoffice-ui/src/handlers/forms.ts b/packages/exchange-backoffice-ui/src/handlers/forms.ts index 418754919..1d6a7daa4 100644 --- a/packages/exchange-backoffice-ui/src/handlers/forms.ts +++ b/packages/exchange-backoffice-ui/src/handlers/forms.ts @@ -8,7 +8,7 @@ import { InputArray } from "./InputArray.js"; import { InputSelectMultiple } from "./InputSelectMultiple.js"; import { InputTextArea } from "./InputTextArea.js"; import { InputFile } from "./InputFile.js"; -import { Separator } from "./Separator.js"; +import { Caption } from "./Caption.js"; import { Group } from "./Group.js"; import { InputSelectOne } from "./InputSelectOne.js"; @@ -25,7 +25,7 @@ type DoubleColumnFormSection = { */ type FieldType = { group: Parameters<typeof Group>[0]; - separator: Parameters<typeof Separator>[0]; + caption: Parameters<typeof Caption>[0]; array: Parameters<typeof InputArray>[0]; file: Parameters<typeof InputFile>[0]; selectOne: Parameters<typeof InputSelectOne>[0]; @@ -42,7 +42,7 @@ type FieldType = { */ export type UIFormField = | { type: "group"; props: FieldType["group"] } - | { type: "separator"; props: FieldType["separator"] } + | { type: "caption"; props: FieldType["caption"] } | { type: "array"; props: FieldType["array"] } | { type: "file"; props: FieldType["file"] } | { type: "selectOne"; props: FieldType["selectOne"] } @@ -66,7 +66,7 @@ type UIFormFieldMap = { */ const UIFormConfiguration: UIFormFieldMap = { group: Group, - separator: Separator, + caption: Caption, array: InputArray, text: InputText, file: InputFile, @@ -90,9 +90,7 @@ export function RenderAllFieldsByUiConfig({ const Component = UIFormConfiguration[ field.type ] as FieldComponentFunction<any>; - const c = structuredClone(field.props); - c.key = i; - return Component(c); + return Component(field.props); }), ); } |