commit 6fb92223da27845bfb79113d8c47abf32ba93ee6
parent 2f405d63bd6523e0ccdbbd4e97daa635fe4ddb85
Author: Sebastian <sebasjm@gmail.com>
Date: Tue, 18 Mar 2025 13:55:16 -0300
rename info to attribute to prevent confusion
Diffstat:
5 files changed, 73 insertions(+), 56 deletions(-)
diff --git a/packages/aml-backoffice-ui/src/hooks/decision-request.ts b/packages/aml-backoffice-ui/src/hooks/decision-request.ts
@@ -35,9 +35,9 @@ import {
} from "@gnu-taler/taler-util";
import { buildStorageKey, FormErrors, useLocalStorage } from "@gnu-taler/web-util/browser";
-export interface ExtraInformation {
+export interface AccountAttributes {
data: object;
- formId: string;
+ formId: string | undefined;
formVersion: number;
expiration: AbsoluteTime;
errors: FormErrors<object> | undefined;
@@ -48,7 +48,7 @@ export interface DecisionRequest {
new_measures: string[] | undefined;
deadline: AbsoluteTime | undefined;
onExpire_measures: string[] | undefined;
- information: ExtraInformation | undefined;
+ attributes: AccountAttributes | undefined;
properties: Record<string, boolean> | undefined;
custom_properties: Record<string, any> | undefined;
custom_events: string[] | undefined;
@@ -57,21 +57,21 @@ export interface DecisionRequest {
justification: string | undefined;
}
-export const codecForExtraInformation = (): Codec<ExtraInformation> =>
- buildCodecForObject<ExtraInformation>()
+export const codecForAccountAttributes = (): Codec<AccountAttributes> =>
+ buildCodecForObject<AccountAttributes>()
.property("expiration", codecForAbsoluteTime)
.property("formId", codecForString())
.property("formVersion", codecForNumber())
.property("data", codecForAny())
.property("errors", codecForAny())
- .build("ExtraInformation");
+ .build("AccountAttributes");
export const codecForDecisionRequest = (): Codec<DecisionRequest> =>
buildCodecForObject<DecisionRequest>()
.property("rules", codecOptional(codecForList(codecForKycRules())))
.property("deadline", codecOptional(codecForAbsoluteTime))
.property("properties", codecOptional(codecForMap(codecForBoolean())))
- .property("information", codecOptional(codecForExtraInformation()))
+ .property("attributes", codecOptional(codecForAccountAttributes()))
.property("custom_properties", codecForAny())
.property("justification", codecOptional(codecForString()))
.property("custom_events", codecOptional(codecForList(codecForString())))
@@ -96,7 +96,7 @@ const defaultDecisionRequest: DecisionRequest = {
keep_investigating: false,
new_measures: undefined,
properties: undefined,
- information: undefined,
+ attributes: undefined,
custom_properties: undefined,
rules: undefined,
};
diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
@@ -203,7 +203,7 @@ export function CaseDetails({
onExpire_measures: undefined,
custom_events: undefined,
inhibit_events: undefined,
- information: undefined,
+ attributes: undefined,
justification: undefined,
keep_investigating: false,
new_measures: undefined,
diff --git a/packages/aml-backoffice-ui/src/pages/decision/AmlDecisionRequestWizard.tsx b/packages/aml-backoffice-ui/src/pages/decision/AmlDecisionRequestWizard.tsx
@@ -26,7 +26,7 @@ import {
useCurrentDecisionRequest,
} from "../../hooks/decision-request.js";
import { Events } from "./Events.js";
-import { Information } from "./Information.js";
+import { Attributes } from "./Information.js";
import { Justification } from "./Justification.js";
import { Measures } from "./Measures.js";
import { Properties } from "./Properties.js";
@@ -34,7 +34,7 @@ import { Rules } from "./Rules.js";
import { Summary } from "./Summary.js";
export type WizardSteps =
- | "information" // submit more information
+ | "attributes" // submit more information
| "rules" // define the limits
| "measures" // define a new form/challenge
| "properties" // define account information
@@ -43,7 +43,7 @@ export type WizardSteps =
| "summary";
const STEPS_ORDER: WizardSteps[] = [
- "information",
+ "attributes",
"properties",
"events",
"rules",
@@ -68,8 +68,8 @@ const STEPS_ORDER_MAP = STEPS_ORDER.reduce(
},
);
-function isInformationCompleted(request: DecisionRequest): boolean {
- return request.information !== undefined && request.information.errors === undefined;
+function isAttributesCompleted(request: DecisionRequest): boolean {
+ return request.attributes === undefined || request.attributes.errors === undefined;
}
function isRulesCompleted(request: DecisionRequest): boolean {
return request.rules !== undefined;
@@ -99,7 +99,7 @@ export function AmlDecisionRequestWizard({
onMove: (n: WizardSteps | undefined) => void;
}): VNode {
const { i18n } = useTranslationContext();
- const stepOrDefault = step ?? "information";
+ const stepOrDefault = step ?? "attributes";
const content = (function () {
switch (stepOrDefault) {
case "rules":
@@ -112,8 +112,8 @@ export function AmlDecisionRequestWizard({
return <Measures />;
case "justification":
return <Justification />;
- case "information":
- return <Information formId={formId}/>;
+ case "attributes":
+ return <Attributes formId={formId}/>;
case "summary":
return <Summary account={account} onMove={onMove} />;
}
@@ -161,10 +161,10 @@ function WizardSteps({
isCompleted: (r: DecisionRequest) => boolean;
};
} = {
- information: {
- label: i18n.str`Information`,
- description: i18n.str`Add more inforamtion to the account`,
- isCompleted: isInformationCompleted,
+ attributes: {
+ label: i18n.str`Attributes`,
+ description: i18n.str`Add more information about the customer`,
+ isCompleted: isAttributesCompleted,
},
rules: {
label: i18n.str`Rules`,
@@ -173,7 +173,7 @@ function WizardSteps({
},
events: {
label: i18n.str`Events`,
- description: i18n.str`Trigger notifications about the account.`,
+ description: i18n.str`Trigger notifications.`,
isCompleted: isEventsCompleted,
},
measures: {
@@ -188,12 +188,12 @@ function WizardSteps({
},
properties: {
label: i18n.str`Properties`,
- description: i18n.str`Add information about the account.`,
+ description: i18n.str`Flag the current account state.`,
isCompleted: isPropertiesCompleted,
},
summary: {
label: i18n.str`Summary`,
- description: i18n.str`Review and send.`,
+ description: i18n.str`Review and submit.`,
isCompleted: () => false,
},
};
diff --git a/packages/aml-backoffice-ui/src/pages/decision/Information.tsx b/packages/aml-backoffice-ui/src/pages/decision/Information.tsx
@@ -22,7 +22,7 @@ import { useCurrentDecisionRequest } from "../../hooks/decision-request.js";
* @param param0
* @returns
*/
-export function Information({
+export function Attributes({
formId: defaultForm,
}: {
formId: string | undefined;
@@ -30,7 +30,7 @@ export function Information({
const { i18n } = useTranslationContext();
const [request] = useCurrentDecisionRequest();
- const formByState = request.information?.formId;
+ const formByState = request.attributes?.formId;
const [selectedFormId, setSelectedFormId] = useState<string | undefined>(
formByState ?? defaultForm,
);
@@ -75,14 +75,14 @@ function FillCustomerData({
const [request, _, updateRequest] = useCurrentDecisionRequest();
const [expiration, setExpiration] = useState(
- request.information?.expiration ?? defaultExp,
+ request.attributes?.expiration ?? defaultExp,
);
const expirationHandler = {
onChange: setExpiration,
value: expiration,
};
- const form = useForm<object>(theForm.config, request.information?.data ?? {});
+ const form = useForm<object>(theForm.config, request.attributes?.data ?? {});
const data = form.status.result;
const errors = form.status.errors;
@@ -90,7 +90,7 @@ function FillCustomerData({
onComponentUnload(() => {
updateRequest({
...request,
- information: {
+ attributes: {
data,
expiration,
formId: theForm.id,
@@ -103,7 +103,20 @@ function FillCustomerData({
return (
<div>
- <div class="flex flex-column justify-between">
+ <div class="sm:flex sm:items-center">
+ <div class="sm:flex-auto">
+ <h1 class="text-base font-semibold text-gray-900">
+ <i18n.Translate>Complete the form</i18n.Translate>
+ </h1>
+ <p class="mt-2 text-sm text-gray-700">
+ <i18n.Translate>
+ These measures will ask the customer for information.
+ </i18n.Translate>
+ </p>
+ </div>
+ </div>
+
+ <div class="flex flex-column justify-between my-4">
<div>
<h1>
Form: {theForm.id} ({theForm.version})
@@ -111,7 +124,7 @@ function FillCustomerData({
<a
class="text-indigo-700 cursor-pointer p-2 text-sm leading-6 font-semibold"
onClick={() => {
- changeForm()
+ changeForm();
}}
>
<i18n.Translate>change form</i18n.Translate>
@@ -157,11 +170,10 @@ function SelectForm({
onComponentUnload(() => {
updateRequest({
...request,
- information: undefined
+ attributes: undefined,
});
});
-
return (
<div>
<FormUI design={design} handler={form.handler} />
@@ -177,18 +189,23 @@ const formDesign = (
i18n: InternationalizationAPI,
mi: FormMetadata[],
): FormDesign => ({
- type: "single-column",
- fields: [
+ type: "double-column",
+ sections: [
{
- id: "formId" as UIHandlerId,
- type: "selectOne",
- required: true,
- label: i18n.str`Form:`,
- help: i18n.str`Select a form to submit new information about the customer`,
- choices: mi.map((f) => ({
- label: f.label,
- value: f.id,
- })),
+ title: i18n.str`Include new information`,
+ description: i18n.str`Select a form to submit new information about the customer or continue to the next step`,
+ fields: [
+ {
+ id: "formId" as UIHandlerId,
+ type: "selectOne",
+ required: true,
+ label: i18n.str`Form:`,
+ choices: mi.map((f) => ({
+ label: f.label,
+ value: f.id,
+ })),
+ },
+ ],
},
],
});
diff --git a/packages/aml-backoffice-ui/src/pages/decision/Summary.tsx b/packages/aml-backoffice-ui/src/pages/decision/Summary.tsx
@@ -66,8 +66,8 @@ export function Summary({
const INVALID_JUSTIFICATION =
decision.justification === undefined || !decision.justification;
const INVALID_ACCOUNT = !account;
- const INVALID_INFORMATION =
- decision.information !== undefined && decision.information.errors !== undefined;
+ const INVALID_ATTRIBUTES =
+ decision.attributes !== undefined && decision.attributes.errors !== undefined;
const CANT_SUBMIT =
INVALID_ACCOUNT ||
@@ -76,7 +76,7 @@ export function Summary({
INVALID_MEASURES ||
INVALID_PROPERTIES ||
INVALID_RULES ||
- INVALID_INFORMATION;
+ INVALID_ATTRIBUTES;
function clearUp() {
updateDecision({
@@ -84,7 +84,7 @@ export function Summary({
custom_properties: undefined,
deadline: undefined,
inhibit_events: undefined,
- information: undefined,
+ attributes: undefined,
justification: undefined,
keep_investigating: false,
new_measures: undefined,
@@ -115,12 +115,12 @@ export function Summary({
successor_measure: decision.onExpire_measures!.join(" "),
custom_measures: {}, // TODO: compute custom measures
},
- attributes_expiration: decision.information?.expiration
+ attributes_expiration: decision.attributes?.expiration
? AbsoluteTime.toProtocolTimestamp(
- decision.information.expiration,
+ decision.attributes.expiration,
)
: undefined,
- attributes: decision.information?.data,
+ attributes: decision.attributes?.data,
properties: decision.properties!, // TODO: compute properites
new_measures: decision.new_measures!.join(" "),
};
@@ -245,20 +245,20 @@ export function Summary({
onClose={() => onMove("justification")}
>
<i18n.Translate>
- You should specify in the justification section.
+ You must specify in the justification section.
</i18n.Translate>
</Attention>
) : (
<div />
)}
- {INVALID_INFORMATION ? (
+ {INVALID_ATTRIBUTES ? (
<Attention
type="danger"
- title={i18n.str`Invalid form information`}
- onClose={() => onMove("information")}
+ title={i18n.str`Invalid attributes`}
+ onClose={() => onMove("attributes")}
>
<i18n.Translate>
- You should specify in the information section.
+ You should check form errors or submit a decision without attributes.
</i18n.Translate>
</Attention>
) : (