From cd590b18e856a128af3c31d9e7d4a621ea44024c Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 23 Apr 2024 11:31:56 -0300 Subject: tidy up: some header missing --- .../src/pages/AntiMoneyLaunderingForm.tsx | 47 ++- .../aml-backoffice-ui/src/pages/CaseDetails.tsx | 358 +++++++++++++-------- .../aml-backoffice-ui/src/pages/Cases.stories.tsx | 18 +- packages/aml-backoffice-ui/src/pages/Cases.tsx | 5 +- .../aml-backoffice-ui/src/pages/CreateAccount.tsx | 20 +- .../src/pages/HandleAccountNotReady.tsx | 19 +- .../aml-backoffice-ui/src/pages/NewFormEntry.tsx | 100 ++++-- packages/aml-backoffice-ui/src/pages/Officer.tsx | 23 +- .../src/pages/ShowConsolidated.stories.tsx | 17 +- .../src/pages/ShowConsolidated.tsx | 89 +++-- .../aml-backoffice-ui/src/pages/UnlockAccount.tsx | 19 +- .../aml-backoffice-ui/src/pages/index.stories.ts | 15 + 12 files changed, 477 insertions(+), 253 deletions(-) (limited to 'packages/aml-backoffice-ui/src/pages') diff --git a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx index c42b1e7af..77d4b8167 100644 --- a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx +++ b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx @@ -1,3 +1,18 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ import { AbsoluteTime, AmountJson, @@ -5,11 +20,11 @@ import { Codec, OperationFail, OperationOk, - OperationResult, + TalerErrorDetail, buildCodecForObject, codecForNumber, codecForString, - codecOptional, + codecOptional } from "@gnu-taler/taler-util"; import { DefaultForm, @@ -17,7 +32,7 @@ import { } from "@gnu-taler/web-util/browser"; import { h } from "preact"; import { useExchangeApiContext } from "../context/config.js"; -import { FormMetadata, uiForms } from "../forms/declaration.js"; +import { BaseForm, FormMetadata, uiForms } from "../forms/declaration.js"; import { Pages } from "../pages.js"; import { AmlExchangeBackend } from "../utils/types.js"; @@ -51,10 +66,12 @@ export function AntiMoneyLaunderingForm({ { }} + onUpdate={() => {}} onSubmit={(formValue) => { - if (formValue.state === undefined || formValue.threshold === undefined) + if (formValue.state === undefined || formValue.threshold === undefined) { return; + } + const validatedForm = formValue as BaseForm; const st = formValue.state; const amount = formValue.threshold; @@ -62,7 +79,7 @@ export function AntiMoneyLaunderingForm({ id: theForm.id, label: theForm.label, version: theForm.version, - value: formValue, + value: validatedForm, }; onSubmit(justification, st, amount); @@ -86,10 +103,10 @@ export function AntiMoneyLaunderingForm({ ); } -export type Justification = { +export type Justification = { // form values value: T; -} & Omit, "icon">, "impl">; +} & Omit, "icon">, "impl">; export function stringifyJustification(j: Justification): string { return JSON.stringify(j); @@ -114,8 +131,10 @@ type ParseJustificationFail = export function parseJustification( s: string, - listOfAllKnownForms: FormMetadata[], -): OperationOk<{ justification: Justification; metadata: FormMetadata }> | OperationFail { + listOfAllKnownForms: FormMetadata[], +): + | OperationOk<{ justification: Justification; metadata: FormMetadata }> + | OperationFail { try { const justification = JSON.parse(s); const info = codecForSimpleFormMetadata().decode(justification); @@ -123,14 +142,14 @@ export function parseJustification( return { type: "fail", case: "id-not-found", - detail: {} as any, + detail: {} as TalerErrorDetail, }; } if (!info.version) { return { type: "fail", case: "version-not-found", - detail: {} as any, + detail: {} as TalerErrorDetail, }; } const found = listOfAllKnownForms.find((f) => { @@ -140,7 +159,7 @@ export function parseJustification( return { type: "fail", case: "form-not-found", - detail: {} as any, + detail: {} as TalerErrorDetail, }; } return { @@ -154,7 +173,7 @@ export function parseJustification( return { type: "fail", case: "not-json", - detail: {} as any, + detail: {} as TalerErrorDetail, }; } } diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx index 0875f047b..a91f3d107 100644 --- a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx +++ b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx @@ -1,3 +1,18 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ import { AbsoluteTime, AmountJson, @@ -5,27 +20,39 @@ import { HttpStatusCode, TalerError, TranslatedString, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; -import { DefaultForm, ErrorLoading, InternationalizationAPI, Loading, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + DefaultForm, + ErrorLoading, + InternationalizationAPI, + Loading, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { format } from "date-fns"; -import { Fragment, VNode, h } from "preact"; +import { VNode, h } from "preact"; import { useState } from "preact/hooks"; -import { FormMetadata } from "../forms/declaration.js"; +import { BaseForm, FormMetadata, uiForms } from "../forms/declaration.js"; import { useCaseDetails } from "../hooks/useCaseDetails.js"; import { Pages } from "../pages.js"; -import { Justification, parseJustification } from "./AntiMoneyLaunderingForm.js"; -import { ShowConsolidated } from "./ShowConsolidated.js"; import { AmlExchangeBackend } from "../utils/types.js"; -import { uiForms } from "../forms/declaration.js"; +import { + Justification, + parseJustification, +} from "./AntiMoneyLaunderingForm.js"; +import { ShowConsolidated } from "./ShowConsolidated.js"; -export type AmlEvent = AmlFormEvent | AmlFormEventError | KycCollectionEvent | KycExpirationEvent; +export type AmlEvent = + | AmlFormEvent + | AmlFormEventError + | KycCollectionEvent + | KycExpirationEvent; type AmlFormEvent = { type: "aml-form"; when: AbsoluteTime; title: TranslatedString; justification: Justification; - metadata: FormMetadata; + metadata: FormMetadata; state: AmlExchangeBackend.AmlState; threshold: AmountJson; }; @@ -33,8 +60,8 @@ type AmlFormEventError = { type: "aml-form-error"; when: AbsoluteTime; title: TranslatedString; - justification: undefined, - metadata: undefined, + justification: undefined; + metadata: undefined; state: AmlExchangeBackend.AmlState; threshold: AmountJson; }; @@ -58,17 +85,24 @@ function selectSooner(a: WithTime, b: WithTime) { return AbsoluteTime.cmp(a.when, b.when); } -function titleForJustification(op: ReturnType, i18n: InternationalizationAPI): TranslatedString { +function titleForJustification( + op: ReturnType, + i18n: InternationalizationAPI, +): TranslatedString { if (op.type === "ok") { return op.body.justification.label as TranslatedString; } switch (op.case) { - case "not-json": return "error: the justification is not a form" as TranslatedString - case "id-not-found": return "error: justification form's id not found" as TranslatedString - case "version-not-found": return "error: justification form's version not found" as TranslatedString - case "form-not-found": return `error: justification form not found` as TranslatedString + case "not-json": + return i18n.str`error: the justification is not a form`; + case "id-not-found": + return i18n.str`error: justification form's id not found`; + case "version-not-found": + return i18n.str`error: justification form's version not found`; + case "form-not-found": + return i18n.str`error: justification form not found`; default: { - assertUnreachable(op.case) + assertUnreachable(op.case); } } } @@ -79,8 +113,7 @@ export function getEventsFromAmlHistory( i18n: InternationalizationAPI, ): AmlEvent[] { const ae: AmlEvent[] = aml.map((a) => { - - const just = parseJustification(a.justification, uiForms.forms(i18n)) + const just = parseJustification(a.justification, uiForms.forms(i18n)); return { type: just.type === "ok" ? "aml-form" : "aml-form-error", state: a.new_state, @@ -117,47 +150,53 @@ export function getEventsFromAmlHistory( export function CaseDetails({ account }: { account: string }) { const [selected, setSelected] = useState(AbsoluteTime.now()); - const [showForm, setShowForm] = useState<{ justification: Justification, metadata: FormMetadata }>() + const [showForm, setShowForm] = useState<{ + justification: Justification; + metadata: FormMetadata; + }>(); const { i18n } = useTranslationContext(); - const details = useCaseDetails(account) + const details = useCaseDetails(account); if (!details) { - return + return ; } if (details instanceof TalerError) { - return + return ; } if (details.type === "fail") { switch (details.case) { case HttpStatusCode.Unauthorized: case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: - case HttpStatusCode.Conflict: return
- default: assertUnreachable(details) + case HttpStatusCode.Conflict: + return
; + default: + assertUnreachable(details); } } - const { aml_history, kyc_attributes } = details.body + const { aml_history, kyc_attributes } = details.body; const events = getEventsFromAmlHistory(aml_history, kyc_attributes, i18n); if (showForm !== undefined) { - return -
- -
- -
+ return ( + +
+ +
+
+ ); } return (
@@ -165,40 +204,46 @@ export function CaseDetails({ account }: { account: string }) { href={Pages.newFormEntry.url({ account })} class="m-4 block rounded-md w-fit border-0 px-3 py-2 text-center text-sm bg-indigo-700 text-white shadow-sm hover:bg-indigo-700" > - - New AML form - + New AML form

- Case history for account {account.substring(0, 16)}... + Case history for account{" "} + {account.substring(0, 16)}...

- { - switch (e.type) { - case "aml-form": { - const { justification, metadata } = e - setShowForm({ justification, metadata }) - break; - } - case "kyc-collection": - case "kyc-expiration": { - setSelected(e.when); - break; + { + switch (e.type) { + case "aml-form": { + const { justification, metadata } = e; + setShowForm({ justification, metadata }); + break; + } + case "kyc-collection": + case "kyc-expiration": { + setSelected(e.when); + break; + } + case "aml-form-error": } - case "aml-form-error": - } - }} /> + }} + /> {/* {selected && } */} {selected && }
); } -function AmlStateBadge({ state }: { state: AmlExchangeBackend.AmlState }): VNode { +function AmlStateBadge({ + state, +}: { + state: AmlExchangeBackend.AmlState; +}): VNode { switch (state) { case AmlExchangeBackend.AmlState.normal: { return ( @@ -222,93 +267,120 @@ function AmlStateBadge({ state }: { state: AmlExchangeBackend.AmlState }): VNode ); } } - assertUnreachable(state) + assertUnreachable(state); } -function ShowTimeline({ history, onSelect }: { onSelect: (e: AmlEvent) => void, history: AmlEvent[] }): VNode { - return
-
    - {history.map((e, idx) => { - const isLast = history.length - 1 === idx; - return ( -
  • { - onSelect(e); - }} - > -
    - {!isLast ? ( - - ) : undefined} -
    - {(() => { - switch (e.type) { - case "aml-form-error": - case "aml-form": { - return
    - - - {e.threshold.currency}{" "} - {Amounts.stringifyValue(e.threshold)} - -
    - } - case "kyc-collection": { - return ( - // - - - - ); - } - case "kyc-expiration": { - // return ; - return - - - +function ShowTimeline({ + history, + onSelect, +}: { + onSelect: (e: AmlEvent) => void; + history: AmlEvent[]; +}): VNode { + return ( +
    +
      + {history.map((e, idx) => { + const isLast = history.length - 1 === idx; + return ( +
    • { + onSelect(e); + }} + > +
      + {!isLast ? ( + + ) : undefined} +
      + {(() => { + switch (e.type) { + case "aml-form-error": + case "aml-form": { + return ( +
      + + + {e.threshold.currency}{" "} + {Amounts.stringifyValue(e.threshold)} + +
      + ); + } + case "kyc-collection": { + return ( + // + + + + ); + } + case "kyc-expiration": { + // return ; + return ( + + + + ); + } } - } - assertUnreachable(e) - })()} -
      - {e.type === "aml-form" ? - - {e.title} - - : -

      {e.title}

      - } -
      - {e.when.t_ms === "never" ? ( - "never" + assertUnreachable(e); + })()} +
      + {e.type === "aml-form" ? ( + + {e.title} + ) : ( - +

      {e.title}

      )} +
      + {e.when.t_ms === "never" ? ( + "never" + ) : ( + + )} +
      -
      -
    • - ); - })} -
    -
    - -} - -function ShowEventDetails({ event }: { event: AmlEvent }): VNode { - return
    type {event.type}
    ; +
  • + ); + })} +
+
+ ); } - - diff --git a/packages/aml-backoffice-ui/src/pages/Cases.stories.tsx b/packages/aml-backoffice-ui/src/pages/Cases.stories.tsx index 3b9c8dacf..223cbbb84 100644 --- a/packages/aml-backoffice-ui/src/pages/Cases.stories.tsx +++ b/packages/aml-backoffice-ui/src/pages/Cases.stories.tsx @@ -20,9 +20,7 @@ */ import * as tests from "@gnu-taler/web-util/testing"; -import { - CasesUI as TestedComponent, -} from "./Cases.js"; +import { CasesUI as TestedComponent } from "./Cases.js"; import { AmountString } from "@gnu-taler/taler-util"; import { AmlExchangeBackend } from "../utils/types.js"; @@ -33,10 +31,12 @@ export default { export const OneRow = tests.createExample(TestedComponent, { filter: AmlExchangeBackend.AmlState.normal, onChangeFilter: () => null, - records: [{ - current_state: AmlExchangeBackend.AmlState.normal, - h_payto: "QWEQWEQWEQWE", - rowid: 1, - threshold: "USD:1" as AmountString - }] + records: [ + { + current_state: AmlExchangeBackend.AmlState.normal, + h_payto: "QWEQWEQWEQWE", + rowid: 1, + threshold: "USD:1" as AmountString, + }, + ], }); diff --git a/packages/aml-backoffice-ui/src/pages/Cases.tsx b/packages/aml-backoffice-ui/src/pages/Cases.tsx index 061286f51..7ecc85e44 100644 --- a/packages/aml-backoffice-ui/src/pages/Cases.tsx +++ b/packages/aml-backoffice-ui/src/pages/Cases.tsx @@ -17,7 +17,7 @@ import { HttpStatusCode, TalerError, TalerExchangeApi, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { ErrorLoading, @@ -70,7 +70,7 @@ export function CasesUI({ onUpdate={(v) => { onChangeFilter(v.state ?? filter); }} - onSubmit={(_v) => { }} + onSubmit={(_v) => {}} > + */ import { TranslatedString } from "@gnu-taler/taler-util"; import { createNewForm, @@ -17,7 +32,7 @@ export function CreateAccount({ password: string; repeat: string; }>(); - const [settings] = useSettings() + const [settings] = useSettings(); return (
@@ -39,7 +54,8 @@ export function CreateAccount({ ? undefined : v.password.length < 8 ? i18n.str`should have at least 8 characters` - : !v.password.match(/[a-z]/) && v.password.match(/[A-Z]/) + : !v.password.match(/[a-z]/) && + v.password.match(/[A-Z]/) ? i18n.str`should have lowercase and uppercase characters` : !v.password.match(/\d/) ? i18n.str`should have numbers` diff --git a/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx b/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx index ff800ebdc..c86906929 100644 --- a/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx +++ b/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx @@ -1,8 +1,23 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ +import { assertUnreachable } from "@gnu-taler/taler-util"; import { VNode, h } from "preact"; import { OfficerNotReady } from "../hooks/useOfficer.js"; import { CreateAccount } from "./CreateAccount.js"; import { UnlockAccount } from "./UnlockAccount.js"; -import { assertUnreachable } from "@gnu-taler/taler-util"; export function HandleAccountNotReady({ officer, @@ -31,5 +46,5 @@ export function HandleAccountNotReady({ /> ); } - assertUnreachable(officer) + assertUnreachable(officer); } diff --git a/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx b/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx index df97cc3a4..7c10132fa 100644 --- a/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx +++ b/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx @@ -1,12 +1,38 @@ -import { AbsoluteTime, Amounts, HttpStatusCode, TalerExchangeApi, TalerProtocolTimestamp, TranslatedString } from "@gnu-taler/taler-util"; -import { LocalNotificationBanner, useLocalNotification, useTranslationContext } from "@gnu-taler/web-util/browser"; +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ +import { + AbsoluteTime, + Amounts, + HttpStatusCode, + TalerExchangeApi, + TalerProtocolTimestamp, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { + LocalNotificationBanner, + useLocalNotification, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useExchangeApiContext } from "../context/config.js"; +import { uiForms } from "../forms/declaration.js"; import { useOfficer } from "../hooks/useOfficer.js"; import { Pages } from "../pages.js"; import { AntiMoneyLaunderingForm } from "./AntiMoneyLaunderingForm.js"; import { HandleAccountNotReady } from "./HandleAccountNotReady.js"; -import { uiForms } from "../forms/declaration.js"; export function NewFormEntry({ account, @@ -15,10 +41,10 @@ export function NewFormEntry({ account?: string; type?: string; }): VNode { - const { i18n } = useTranslationContext() + const { i18n } = useTranslationContext(); const officer = useOfficer(); - const { api } = useExchangeApiContext() - const [notification, notify, handleError] = useLocalNotification() + const { api } = useExchangeApiContext(); + const [notification, notify, handleError] = useLocalNotification(); if (!account) { return
no account
; @@ -38,46 +64,51 @@ export function NewFormEntry({ account={account} formId={type} onSubmit={async (justification, new_state, new_threshold) => { - const decision: Omit = { justification: JSON.stringify(justification), decision_time: TalerProtocolTimestamp.now(), h_payto: account, new_state, new_threshold: Amounts.stringify(new_threshold), - kyc_requirements: undefined - } + kyc_requirements: undefined, + }; await handleError(async () => { - const resp = await api.addDecisionDetails(officer.account, decision); + const resp = await api.addDecisionDetails( + officer.account, + decision, + ); if (resp.type === "ok") { window.location.href = Pages.cases.url; return; } switch (resp.case) { case HttpStatusCode.Forbidden: - case HttpStatusCode.Unauthorized: return notify({ - type: "error", - title: i18n.str`Wrong credentials for "${officer.account}"`, - description: resp.detail.hint as TranslatedString, - debug: resp.detail, - when: AbsoluteTime.now(), - }) - case HttpStatusCode.NotFound: return notify({ - type: "error", - title: i18n.str`Officer or account not found`, - description: resp.detail.hint as TranslatedString, - debug: resp.detail, - when: AbsoluteTime.now(), - }) - case HttpStatusCode.Conflict: return notify({ - type: "error", - title: i18n.str`Officer disabled or more recent decision was already submitted.`, - description: resp.detail.hint as TranslatedString, - debug: resp.detail, - when: AbsoluteTime.now(), - }) + case HttpStatusCode.Unauthorized: + return notify({ + type: "error", + title: i18n.str`Wrong credentials for "${officer.account}"`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + when: AbsoluteTime.now(), + }); + case HttpStatusCode.NotFound: + return notify({ + type: "error", + title: i18n.str`Officer or account not found`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + when: AbsoluteTime.now(), + }); + case HttpStatusCode.Conflict: + return notify({ + type: "error", + title: i18n.str`Officer disabled or more recent decision was already submitted.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + when: AbsoluteTime.now(), + }); } - }) + }); }} /> @@ -85,13 +116,14 @@ export function NewFormEntry({ } function SelectForm({ account }: { account: string }) { - const { i18n } = useTranslationContext() + const { i18n } = useTranslationContext(); return (
New form for account: {account.substring(0, 16)}...
- {uiForms.forms(i18n).map((form, idx) => { + {uiForms.forms(i18n).map((form) => { return ( diff --git a/packages/aml-backoffice-ui/src/pages/Officer.tsx b/packages/aml-backoffice-ui/src/pages/Officer.tsx index ec8327814..eaa961b90 100644 --- a/packages/aml-backoffice-ui/src/pages/Officer.tsx +++ b/packages/aml-backoffice-ui/src/pages/Officer.tsx @@ -1,9 +1,24 @@ -import { Fragment, h } from "preact"; -import { useOfficer } from "../hooks/useOfficer.js"; -import { HandleAccountNotReady } from "./HandleAccountNotReady.js"; +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ import { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { uiSettings } from "../settings.js"; +import { h } from "preact"; import { getInitialBackendBaseURL } from "../hooks/useBackend.js"; +import { useOfficer } from "../hooks/useOfficer.js"; +import { uiSettings } from "../settings.js"; +import { HandleAccountNotReady } from "./HandleAccountNotReady.js"; export function Officer() { const officer = useOfficer(); diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx index f985e6ff5..fa88277ec 100644 --- a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx +++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx @@ -19,24 +19,23 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { addDays } from "date-fns"; +import { AbsoluteTime, Duration, TranslatedString } from "@gnu-taler/taler-util"; +import { InternationalizationAPI } from "@gnu-taler/web-util/browser"; +import * as tests from "@gnu-taler/web-util/testing"; +import { getEventsFromAmlHistory } from "./CaseDetails.js"; import { ShowConsolidated as TestedComponent, } from "./ShowConsolidated.js"; -import * as tests from "@gnu-taler/web-util/testing"; -import { getEventsFromAmlHistory } from "./CaseDetails.js"; -import { AbsoluteTime, Duration } from "@gnu-taler/taler-util"; -import { InternationalizationAPI } from "@gnu-taler/web-util/browser"; export default { title: "show consolidated", }; const nullTranslator: InternationalizationAPI = { - str: (str: any) => str, - singular: (str: any) => str, - translate: (str: any) => str, - Translate: (str: any) => str, + str: (str: TemplateStringsArray) => str.join() as TranslatedString, + singular: (str: TemplateStringsArray) => str.join() as TranslatedString, + translate: (str: TemplateStringsArray) => [str.join()] as TranslatedString[], + Translate: () => undefined as unknown, } export const WithEmptyHistory = tests.createExample(TestedComponent, { diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx index ad350c0e6..15b109bee 100644 --- a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx +++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx @@ -1,10 +1,34 @@ -import { AbsoluteTime, AmountJson, TranslatedString } from "@gnu-taler/taler-util"; +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { + DefaultForm, + FlexibleForm, + UIFormField, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { format } from "date-fns"; import { Fragment, VNode, h } from "preact"; -import { AmlEvent } from "./CaseDetails.js"; -import { DefaultForm, FlexibleForm, UIFormField, useTranslationContext } from "@gnu-taler/web-util/browser"; import { amlStateConverter } from "../utils/converter.js"; import { AmlExchangeBackend } from "../utils/types.js"; +import { AmlEvent } from "./CaseDetails.js"; export function ShowConsolidated({ history, @@ -22,15 +46,15 @@ export function ShowConsolidated({ return { aml: { threshold: { - hidden: !form.aml + hidden: !form.aml, }, since: { - hidden: !form.aml + hidden: !form.aml, }, state: { - hidden: !form.aml - } - } + hidden: !form.aml, + }, + }, }; }, design: [ @@ -70,29 +94,31 @@ export function ShowConsolidated({ }, Object.entries(cons.kyc).length > 0 ? { - title: i18n.str`KYC`, - fields: Object.entries(cons.kyc).map(([key, field]) => { - const result: UIFormField = { - type: "text", - props: { - label: key as TranslatedString, - name: `kyc.${key}.value`, - help: `${field.provider} since ${field.since.t_ms === "never" - ? "never" - : format(field.since.t_ms, "dd/MM/yyyy") + title: i18n.str`KYC`, + fields: Object.entries(cons.kyc).map(([key, field]) => { + const result: UIFormField = { + type: "text", + props: { + label: key as TranslatedString, + name: `kyc.${key}.value`, + help: `${field.provider} since ${ + field.since.t_ms === "never" + ? "never" + : format(field.since.t_ms, "dd/MM/yyyy") }` as TranslatedString, - }, - }; - return result; - }), - } + }, + }; + return result; + }), + } : undefined, ], }; return (

- Consolidated information {until.t_ms === "never" + Consolidated information{" "} + {until.t_ms === "never" ? "" : `after ${format(until.t_ms, "dd MMMM yyyy")}`}

@@ -101,7 +127,7 @@ export function ShowConsolidated({ form={form} initial={cons} readOnly - onUpdate={() => { }} + onUpdate={() => {}} />
); @@ -115,7 +141,7 @@ interface Consolidated { }; kyc: { [field: string]: { - value: any; + value: unknown; provider: string; since: AbsoluteTime; }; @@ -134,7 +160,7 @@ function getConsolidated( value: 1000, fraction: 0, }, - since: AbsoluteTime.never() + since: AbsoluteTime.never(), }, kyc: {}, }; @@ -153,14 +179,15 @@ function getConsolidated( prev.aml = { since: cur.when, state: cur.state, - threshold: cur.threshold - } + threshold: cur.threshold, + }; break; } case "kyc-collection": { Object.keys(cur.values).forEach((field) => { + const value = (cur.values as Record)[field]; prev.kyc[field] = { - value: (cur.values as any)[field], + value, provider: cur.provider, since: cur.when, }; @@ -170,4 +197,4 @@ function getConsolidated( } return prev; }, initial); -} \ No newline at end of file +} diff --git a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx index 1b0342b12..8066155ac 100644 --- a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx +++ b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx @@ -1,3 +1,18 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ import { TranslatedString, UnwrapKeyError } from "@gnu-taler/taler-util"; import { createNewForm, notifyError, notifyInfo, useTranslationContext } from "@gnu-taler/web-util/browser"; import { VNode, h } from "preact"; @@ -36,8 +51,8 @@ export function UnlockAccount({ } catch (e) { if (e instanceof UnwrapKeyError) { notifyError( - "Could not unlock account" as any, - e.message as any, + i18n.str`Could not unlock account`, + e.message as TranslatedString, ); } else { throw e; diff --git a/packages/aml-backoffice-ui/src/pages/index.stories.ts b/packages/aml-backoffice-ui/src/pages/index.stories.ts index afe73227a..22435178b 100644 --- a/packages/aml-backoffice-ui/src/pages/index.stories.ts +++ b/packages/aml-backoffice-ui/src/pages/index.stories.ts @@ -1,3 +1,18 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ export * as a1 from "./ShowConsolidated.stories.js"; export * as a2 from "./AntiMoneyLaunderingForm.stories.js"; export * as a3 from "./Cases.stories.js"; -- cgit v1.2.3