commit 27ae504ed714be9f715daa6867d2e545bc67bc22
parent bcb75402408163c36f1c88b42e79e32fdb760922
Author: Florian Dold <florian@dold.me>
Date: Mon, 24 Mar 2025 22:49:15 +0100
forms tweaks
Diffstat:
7 files changed, 94 insertions(+), 33 deletions(-)
diff --git a/packages/web-util/src/forms/fields/InputIsoDate.tsx b/packages/web-util/src/forms/fields/InputIsoDate.tsx
@@ -15,7 +15,7 @@
*/
import { AbsoluteTime } from "@gnu-taler/taler-util";
-import { format, parse } from "date-fns";
+import { format, parse, parseISO } from "date-fns";
import { Fragment, VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { Calendar } from "../Calendar.js";
@@ -33,6 +33,11 @@ export interface InputIsoDateProps {
pattern?: string;
defaultValue?: string;
+
+ /**
+ * Default value when the calener widget is opened.
+ */
+ calendarDefaultValue?: string;
}
/**
@@ -51,15 +56,22 @@ export function InputIsoDate(
properties.handler ?? noHandlerPropsAndNoContextForField(properties.name);
useEffect(() => {
- console.log("in useEffect");
- console.log("pattern", properties.pattern);
- console.log("defaultValue", properties.defaultValue);
if (!value && !!properties.defaultValue) {
onChange(properties.defaultValue);
}
- });
+ }, [value, properties.handler, properties.defaultValue]);
- const time = parse(value!, pattern, Date.now()).getTime();
+ let calendarOpenTime: number;
+
+ if (!value) {
+ if (properties.calendarDefaultValue) {
+ calendarOpenTime = parseISO(properties.calendarDefaultValue).getTime();
+ } else {
+ calendarOpenTime = Date.now();
+ }
+ } else {
+ calendarOpenTime = parseISO(value).getTime();
+ }
return (
<Fragment>
<InputLine
@@ -96,6 +108,7 @@ export function InputIsoDate(
const d = parse(v, "yyyy-MM-dd", Date.now());
return format(d, pattern);
} catch (e) {
+ console.error(`toStringUI: failed to convert ${v}: ${e}`);
return "";
}
},
@@ -107,6 +120,7 @@ export function InputIsoDate(
const t_ms = parse(v, pattern, Date.now()).getTime();
return format(t_ms, pattern);
} catch (e) {
+ console.error(`fromStringUI: failed to convert ${v}`);
return "";
}
},
@@ -115,7 +129,7 @@ export function InputIsoDate(
{open && (
<Dialog onClose={() => setOpen(false)}>
<Calendar
- value={AbsoluteTime.fromMilliseconds(time)}
+ value={AbsoluteTime.fromMilliseconds(calendarOpenTime)}
onChange={(v) => {
// The date is always *stored* as an ISO date.
onChange(
diff --git a/packages/web-util/src/forms/fields/InputLine.tsx b/packages/web-util/src/forms/fields/InputLine.tsx
@@ -170,7 +170,7 @@ function defaultFromString(v: string) {
type InputType = "text" | "text-area" | "password" | "email" | "number";
export function InputLine(
- props: { type: InputType } & UIFormProps<string>,
+ props: { type: InputType, defaultValue?: string } & UIFormProps<string>,
): VNode {
const {
name,
@@ -261,6 +261,7 @@ export function InputLine(
onChange={(e) => {
onChange(fromString(e.currentTarget.value));
}}
+ defaultValue={props.defaultValue}
placeholder={placeholder ? placeholder : undefined}
// value={toString(value) ?? ""}
// defaultValue={toString(value)}
diff --git a/packages/web-util/src/forms/forms-types.ts b/packages/web-util/src/forms/forms-types.ts
@@ -113,6 +113,7 @@ type UIFormFieldIsoDate = {
max?: TalerProtocolTimestamp;
min?: TalerProtocolTimestamp;
pattern: string;
+ defaultCalendarValue?: string;
} & UIFormFieldBaseConfig;
type UIFormFieldAmount = {
diff --git a/packages/web-util/src/forms/forms-utils.ts b/packages/web-util/src/forms/forms-utils.ts
@@ -149,6 +149,7 @@ export function convertFormConfigToUiField(
),
pattern: config.pattern,
defaultValue: config.defaultValue,
+ calendarDefaultValue: config.defaultCalendarValue,
hidden,
},
} as UIFormField;
diff --git a/packages/web-util/src/forms/gana/VQF_902_1_customer.ts b/packages/web-util/src/forms/gana/VQF_902_1_customer.ts
@@ -37,6 +37,17 @@ export const form_vqf_902_1_customer = (i18n: InternationalizationAPI) => ({
config: design_VQF_902_1_customer(i18n),
});
+const fieldPersonalId = (
+ i18n: InternationalizationAPI,
+): UIFormElementConfig => ({
+ id: TalerFormAttributes.PERSONAL_IDENTIFICATION_DOCUMENT_COPY,
+ label: i18n.str`Copy of identification document`,
+ type: "file",
+ accept: "application/pdf",
+ tooltip: i18n.str`Only official government IDs (incl. passports) are accepted. Please scan both sides if applicable.`,
+ required: true,
+});
+
const fieldCorrespondenceLanguage = (
i18n: InternationalizationAPI,
): UIFormElementConfig => ({
@@ -133,6 +144,7 @@ export function design_VQF_902_1_customer(
type: "isoDateText",
placeholder: "dd/MM/yyyy",
pattern: "dd/MM/yyyy",
+ defaultCalendarValue: "1980-01-01",
required: true,
},
{
@@ -142,13 +154,7 @@ export function design_VQF_902_1_customer(
choices: countryNationalityList(i18n),
required: true,
},
- {
- id: TalerFormAttributes.PERSONAL_IDENTIFICATION_DOCUMENT_COPY,
- label: i18n.str`Identification document`,
- type: "file",
- accept: "application/pdf",
- required: true,
- },
+ fieldPersonalId(i18n),
{
id: TalerFormAttributes.CUSTOMER_IS_SOLE_PROPRIETOR,
label: i18n.str`Sole proprietor`,
@@ -225,13 +231,7 @@ export function design_VQF_902_1_customer(
type: "text",
required: false,
},
- {
- id: TalerFormAttributes.PERSONAL_IDENTIFICATION_DOCUMENT_COPY,
- label: i18n.str`Copy of identification document`,
- type: "file",
- accept: "application/pdf",
- required: true,
- },
+ fieldPersonalId(i18n),
],
},
{
@@ -273,6 +273,7 @@ export function design_VQF_902_1_customer(
type: "isoDateText",
placeholder: "dd/MM/yyyy",
pattern: "dd/MM/yyyy",
+ defaultCalendarValue: "1980-01-01",
required: true,
},
{
@@ -282,13 +283,7 @@ export function design_VQF_902_1_customer(
choices: countryNationalityList(i18n),
required: true,
},
- {
- id: TalerFormAttributes.PERSONAL_IDENTIFICATION_DOCUMENT_COPY,
- label: i18n.str`Copy of identification document`,
- type: "file",
- accept: "application/pdf",
- required: true,
- },
+ fieldPersonalId(i18n),
{
id: TalerFormAttributes.SIGNING_AUTHORITY_TYPE,
label: i18n.str`Signing authority of the person`,
diff --git a/packages/web-util/src/forms/gana/VQF_902_1_officer.ts b/packages/web-util/src/forms/gana/VQF_902_1_officer.ts
@@ -74,13 +74,44 @@ export function VQF_902_1_officer(
},
{
title: i18n.str`Evaluation with regard to embargo procedures/terrorism lists on establishing the business relationship`,
- description: i18n.str`Verification whether the customer, beneficial owners of the assets, controlling persons, authorized representatives or other involved persons are listed on an embargo/terrorism list (date of verification/result)`,
+ description: i18n.str`Verification whether the customer, beneficial owners of the assets, controlling persons, authorized representatives or other involved persons are listed on an embargo/terrorism list.`,
fields: [
{
+ id: TalerFormAttributes.EMBARGO_TERRORISM_CHECK_RESULT,
+ label: i18n.str`Embargo/terrorism status:`,
+ type: "choiceStacked",
+ required: true,
+ choices: [
+ {
+ label: i18n.str`Not listed an embargo/terrorism list.`,
+ value: "NOT_LISTED",
+ },
+ {
+ label: i18n.str`Listed an embargo/terrorism list.`,
+ value: "LISTED",
+ },
+ ],
+ },
+ {
id: TalerFormAttributes.EMBARGO_TERRORISM_INFO,
- label: i18n.str`Embargo information:`,
+ label: i18n.str`Embargo/terrorism information:`,
type: "textArea",
- required: false,
+ hide(value, root): boolean {
+ return (
+ root[TalerFormAttributes.EMBARGO_TERRORISM_CHECK_RESULT] !==
+ "LISTED"
+ );
+ },
+ required: true,
+ },
+ {
+ id: TalerFormAttributes.EMBARGO_TERRORISM_CHECK_DATE,
+ label: i18n.str`Verification date`,
+ type: "isoDateText",
+ required: true,
+ defaultValue: today,
+ placeholder: "dd/MM/yyyy",
+ pattern: "dd/MM/yyyy",
},
],
},
@@ -89,7 +120,7 @@ export function VQF_902_1_officer(
description: i18n.str`Optional supplemental information for the establishment of the business relationship with the customer.`,
fields: [
{
- id: TalerFormAttributes.ESTABLISHER_LIST,
+ id: TalerFormAttributes.SUPPLEMENTAL_FILES_LIST,
label: i18n.str`Supplemental Files`,
type: "array",
labelFieldId: "FILE.FILENAME",
diff --git a/packages/web-util/src/forms/gana/taler_form_attributes.ts b/packages/web-util/src/forms/gana/taler_form_attributes.ts
@@ -250,6 +250,18 @@ export const TalerFormAttributes = {
*/
EMBARGO_TERRORISM_INFO: "EMBARGO_TERRORISM_INFO" as UIHandlerId,
/**
+ * Description: Verification date.
+ *
+ * GANA Type: Date
+ */
+ EMBARGO_TERRORISM_CHECK_DATE: "EMBARGO_TERRORISM_CHECK_DATE" as UIHandlerId,
+ /**
+ * Description: Verification date.
+ *
+ * GANA Type: 'NOT_LISTED' | 'LISTED'
+ */
+ EMBARGO_TERRORISM_CHECK_RESULT: "EMBARGO_TERRORISM_CHECK_RESULT" as UIHandlerId,
+ /**
* Description:
*
* GANA Type: 'MONEY_EXCHANGE' | 'MONEY_ASSET_TRANSFER' | 'OTHER'
@@ -1503,6 +1515,12 @@ export const TalerFormAttributes = {
* GANA Type: String
*/
FORM_SALT: "FORM_SALT" as UIHandlerId,
+ /**
+ * Description: List of supplemental file attachments.
+ *
+ * GANA Type: List of records, usually the file upload and a description.
+ */
+ SUPPLEMENTAL_FILES_LIST: "SUPPLEMENTAL_FILES_LIST" as UIHandlerId,
}