taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit c08a54a06fc880d546dac901b2a739813192dc6c
parent 657784c93318232ac509a426bf055eed9be81884
Author: Florian Dold <florian@dold.me>
Date:   Mon, 21 Jul 2025 14:36:04 +0200

aml: sort events properly, show full payto

Diffstat:
Mpackages/aml-backoffice-ui/src/pages/AccountDetails.tsx | 47++++++++++++++++++++++++++++++++++-------------
Mpackages/aml-backoffice-ui/src/pages/AccountList.tsx | 3++-
Mpackages/taler-util/src/types-taler-exchange.ts | 3+++
3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/packages/aml-backoffice-ui/src/pages/AccountDetails.tsx b/packages/aml-backoffice-ui/src/pages/AccountDetails.tsx @@ -17,7 +17,6 @@ import { AbsoluteTime, assertUnreachable, HttpStatusCode, - LegitimizationMeasureDetails, TalerError, TalerExchangeApi, TalerFormAttributes, @@ -31,19 +30,17 @@ import { } from "@gnu-taler/web-util/browser"; import { format } from "date-fns"; import { h, VNode } from "preact"; +import { Fragment } from "preact/jsx-runtime"; import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js"; import { ShowDecisionLimitInfo } from "../components/ShowDecisionLimitInfo.js"; +import { ShowDefaultRules } from "../components/ShowDefaultRules.js"; +import { ShowLegistimizationInfo } from "../components/ShowLegitimizationInfo.js"; import { useAccountInformation } from "../hooks/account.js"; import { DecisionRequest } from "../hooks/decision-request.js"; import { useAccountDecisions } from "../hooks/decisions.js"; -import { ShowDefaultRules } from "../components/ShowDefaultRules.js"; -import { Fragment } from "preact/jsx-runtime"; +import { useCurrentLegitimizations } from "../hooks/legitimizations.js"; import { useServerMeasures } from "../hooks/server-info.js"; import { BANK_RULES, WALLET_RULES } from "./decision/Rules.js"; -import { useCurrentLegitimizations } from "../hooks/legitimizations.js"; -import { computeMeasureInformation } from "../utils/computeAvailableMesaures.js"; -import { CurrentMeasureTable } from "../components/MeasuresTable.js"; -import { ShowLegistimizationInfo } from "../components/ShowLegitimizationInfo.js"; const TALER_SCREEN_ID = 116; @@ -98,7 +95,15 @@ export function AccountDetails({ return <ErrorLoadingWithDebug error={legistimizations} />; } - const { details: collectionEvents } = details.body; + const collectionEvents = details.body.details; + + collectionEvents.sort((a, b) => + AbsoluteTime.cmp( + AbsoluteTime.fromProtocolTimestamp(a.collection_time), + AbsoluteTime.fromProtocolTimestamp(b.collection_time), + ), + ); + const activeDecision = history.body.find((d) => d.is_active); const restDecisions = !activeDecision ? history.body @@ -155,12 +160,28 @@ export function AccountDetails({ return ( <div class="min-w-60"> - <header class="flex items-center justify-between border-b border-white/5 px-4 py-4 sm:px-6 sm:py-6 lg:px-8 gap-2"> + <header class="flex flex-col justify-between border-b border-white/5 px-4 py-4 sm:px-6 sm:py-6 lg:px-8 gap-2"> <h1 class="text-base font-semibold leading-7 text-black"> - <i18n.Translate>Case history for account:</i18n.Translate> + <i18n.Translate>Case history for selected account</i18n.Translate> </h1> - <div>{account}</div> - <CopyButton class="" getContent={() => account} /> + <div> + <p> + <span class="font-bold"> + <i18n.Translate>ID:</i18n.Translate> + </span>{" "} + {account} <CopyButton class="" getContent={() => account} /> + </p> + <p> + <span class="font-bold"> + <i18n.Translate>Payto:</i18n.Translate> + </span>{" "} + {activeDecision?.full_payto ?? "N/A"}{" "} + <CopyButton + class="" + getContent={() => activeDecision?.full_payto ?? "N/A"} + /> + </p> + </div> </header> {!activeDecision || !activeDecision.to_investigate ? undefined : ( @@ -180,7 +201,7 @@ export function AccountDetails({ </h1> <p class="mt-1 text-sm leading-6 text-gray-600"> <i18n.Translate> - Every event when the user was asked information. + Every attribute collection event (via form upload or KYC provider). </i18n.Translate> </p> </div> diff --git a/packages/aml-backoffice-ui/src/pages/AccountList.tsx b/packages/aml-backoffice-ui/src/pages/AccountList.tsx @@ -156,7 +156,7 @@ export function AccountList({ scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-80" > - <i18n.Translate>Account Id</i18n.Translate> + <i18n.Translate>Account Identification</i18n.Translate> </th> <th scope="col" @@ -180,6 +180,7 @@ export function AccountList({ > {r.h_payto} </a> + <p class="text-gray-500 text-xs">{r.full_payto}</p> </div> </td> <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-900"> diff --git a/packages/taler-util/src/types-taler-exchange.ts b/packages/taler-util/src/types-taler-exchange.ts @@ -2146,6 +2146,8 @@ export interface AmlDecision { // Identifies a GNU Taler wallet or an affected bank account. h_payto: PaytoHash; + full_payto?: string; + // True if the underlying payto://-URI is for a wallet // Since protocol **v25**. is_wallet: boolean; @@ -2719,6 +2721,7 @@ export const codecForKycDetail = (): Codec<KycDetail> => export const codecForAmlDecision = (): Codec<AmlDecision> => buildCodecForObject<AmlDecision>() .property("h_payto", codecForString()) + .property("full_payto", codecOptional(codecForString())) .property("rowid", codecForNumber()) .property("is_wallet", codecForBoolean()) .property("justification", codecOptional(codecForString()))