From 014ad600d79df7e31d70c33e7820238cc8018f56 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 27 Aug 2024 13:45:57 -0300 Subject: more aml info --- .../aml-backoffice-ui/src/pages/CaseDetails.tsx | 173 +++++++++++++++++++-- packages/aml-backoffice-ui/src/pages/Cases.tsx | 25 ++- .../src/pages/ShowConsolidated.tsx | 68 ++++---- 3 files changed, 202 insertions(+), 64 deletions(-) (limited to 'packages/aml-backoffice-ui/src/pages') diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx index d42e1f2c6..b26e6f430 100644 --- a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx +++ b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx @@ -32,22 +32,25 @@ import { codecOptional, } from "@gnu-taler/taler-util"; import { + Attention, DefaultForm, - ErrorLoading, FormMetadata, InternationalizationAPI, Loading, - useTranslationContext, + ShowInputErrorLabel, + Time, + useExchangeApiContext, + useTranslationContext } from "@gnu-taler/web-util/browser"; -import { format } from "date-fns"; -import { VNode, h } from "preact"; +import { format, formatDuration, intervalToDuration } from "date-fns"; +import { Fragment, Ref, VNode, h } from "preact"; import { useState } from "preact/hooks"; -import { privatePages } from "../Routing.js"; +import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js"; import { useUiFormsContext } from "../context/ui-forms.js"; import { preloadedForms } from "../forms/index.js"; import { useAccountInformation } from "../hooks/account.js"; +import { useAccountDecisions } from "../hooks/decisions.js"; import { ShowConsolidated } from "./ShowConsolidated.js"; -import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js"; export type AmlEvent = | AmlFormEvent @@ -175,10 +178,12 @@ export function CaseDetails({ account }: { account: string }) { const { i18n } = useTranslationContext(); const details = useAccountInformation(account); + const history = useAccountDecisions(account); + const { forms } = useUiFormsContext(); const allForms = [...forms, ...preloadedForms(i18n)]; - if (!details) { + if (!details || !history) { return ; } if (details instanceof TalerError) { @@ -195,8 +200,22 @@ export function CaseDetails({ account }: { account: string }) { assertUnreachable(details); } } + if (history instanceof TalerError) { + return ; + } + if (history.type === "fail") { + switch (history.case) { + // case HttpStatusCode.Unauthorized: + case HttpStatusCode.Forbidden: + case HttpStatusCode.NotFound: + case HttpStatusCode.Conflict: + return
; + default: + assertUnreachable(history); + } + } const { details: accountDetails } = details.body; - + const activeDesicion = history.body.find(d => d.is_active) const events = getEventsFromAmlHistory( accountDetails, @@ -227,10 +246,25 @@ export function CaseDetails({ account }: { account: string }) { return (
+ Freeze account + + + New threshold + + - New AML form + Ask more information
@@ -241,6 +275,10 @@ export function CaseDetails({ account }: { account: string }) {
+ {!activeDesicion ? : + {!activeDesicion.to_investigate ? undefined : } + + } { @@ -265,6 +303,59 @@ export function CaseDetails({ account }: { account: string }) { ); } +function ShowActiveDecision({ decision }: { decision: TalerExchangeApi.AmlDecision }): VNode { + const { i18n } = useTranslationContext(); + const { config } = useExchangeApiContext() + + return +

+ Current active rules +

+ +
+ +
+ {decision.limits.rules.map(r => { + const bySpec = Amounts.stringifyValueWithSpec(Amounts.parseOrThrow(r.threshold), config.currency_specification) + return
+ +

+ over {r.timeframe.d_us === "forever" ? "" : formatDuration(intervalToDuration({ start: 0, end: r.timeframe.d_us / 1000 }))} +

+
+ })} + +
+} + function AmlStateBadge({ state }: { state: TalerExchangeApi.AmlState }): VNode { switch (state) { case TalerExchangeApi.AmlState.normal: { @@ -392,7 +483,7 @@ function ShowTimeline({ "never" ) : ( )}
@@ -407,6 +498,66 @@ function ShowTimeline({ ); } +function InputAmount( + { + currency, + name, + value, + left, + onChange, + }: { + currency: string; + name: string; + left?: boolean | undefined; + value: string | undefined; + onChange?: (s: string) => void; + }, + ref: Ref, +): VNode { + const FRAC_SEPARATOR = "," + const { config } = useExchangeApiContext(); + return ( +
+
+
+ {currency} +
+ { + if (!onChange) return; + const l = e.currentTarget.value.length; + const sep_pos = e.currentTarget.value.indexOf(FRAC_SEPARATOR); + if ( + sep_pos !== -1 && + l - sep_pos - 1 > + config.currency_specification.num_fractional_input_digits + ) { + e.currentTarget.value = e.currentTarget.value.substring( + 0, + sep_pos + + config.currency_specification.num_fractional_input_digits + + 1, + ); + } + onChange(e.currentTarget.value); + }} + /> +
+
+ ); +} + export type Justification> = { // form values value: T; diff --git a/packages/aml-backoffice-ui/src/pages/Cases.tsx b/packages/aml-backoffice-ui/src/pages/Cases.tsx index e468d80ad..9a569cd60 100644 --- a/packages/aml-backoffice-ui/src/pages/Cases.tsx +++ b/packages/aml-backoffice-ui/src/pages/Cases.tsx @@ -148,12 +148,6 @@ export function CasesUI({ > Status - - Threshold - @@ -172,11 +166,8 @@ export function CasesUI({
- - {r.rowid} - - ??? + {r.to_investigate ? : undefined} ); @@ -191,6 +182,12 @@ export function CasesUI({ ); } +function ToInvestigateIcon(): VNode { + return + + +} + export function Cases() { // const [stateFilter, setStateFilter] = useState( @@ -257,10 +254,10 @@ export function Cases() { records={list.body} onFirstPage={list.isFirstPage ? undefined : list.loadFirst} onNext={list.isLastPage ? undefined : list.loadNext} - // filter={stateFilter} - // onChangeFilter={(d) => { - // setStateFilter(d); - // }} + // filter={stateFilter} + // onChangeFilter={(d) => { + // setStateFilter(d); + // }} /> ); } diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx index 2fbbefe0c..cea8157b0 100644 --- a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx +++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx @@ -30,6 +30,26 @@ import { format } from "date-fns"; import { Fragment, VNode, h } from "preact"; import { AmlEvent } from "./CaseDetails.js"; +/** + * the exchange doesn't hava a consistent api + * https://bugs.gnunet.org/view.php?id=9142 + * + * @param data + * @returns + */ +function fixProvidedInfo(data: object): object { + return Object.entries(data).reduce((prev, [key,value]) => { + prev[key] = value + if (typeof value === "object" && value["value"]) { + const v = value["value"] + if (typeof v === "object" && v["text"]) { + prev[key].value = v["text"] + } + } + return prev + }, {} as any) +} + export function ShowConsolidated({ history, until, @@ -41,54 +61,24 @@ export function ShowConsolidated({ const cons = getConsolidated(history, until); + const fixed = fixProvidedInfo(cons.kyc); + console.log("fixed", fixed) const form: FormConfiguration = { type: "double-column", design: [ - { - title: i18n.str`AML`, - fields: [ - { - type: "amount", - id: ".aml.threshold" as UIHandlerId, - currency: "NETZBON", - label: i18n.str`Threshold`, - name: "aml.threshold", - }, - { - type: "choiceHorizontal", - label: i18n.str`State`, - name: "aml.state", - id: ".aml.state" as UIHandlerId, - choices: [ - { - label: i18n.str`Frozen`, - value: "frozen", - }, - { - label: i18n.str`Pending`, - value: "pending", - }, - { - label: i18n.str`Normal`, - value: "normal", - }, - ], - }, - ], - }, - Object.entries(cons.kyc).length > 0 + Object.entries(fixed).length > 0 ? { - title: i18n.str`KYC`, - fields: Object.entries(cons.kyc).map(([key, field]) => { + title: i18n.str`KYC collected info`, + fields: Object.entries(fixed).map(([key, field]) => { const result: UIFormElementConfig = { type: "text", label: key as TranslatedString, id: `kyc.${key}.value` as UIHandlerId, name: `kyc.${key}.value`, - help: `${field.provider} since ${ + help: `At ${ field.since.t_ms === "never" ? "never" - : format(field.since.t_ms, "dd/MM/yyyy") + : format(field.since.t_ms, "dd/MM/yyyy HH:mm:ss") }` as TranslatedString, }; return result; @@ -99,12 +89,12 @@ export function ShowConsolidated({ }; return ( -

+ {/*

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

+ */}