gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-typescript-core] branch master updated: fix #10032


From: Admin
Subject: [taler-typescript-core] branch master updated: fix #10032
Date: Thu, 12 Jun 2025 17:24:27 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository taler-typescript-core.

The following commit(s) were added to refs/heads/master by this push:
     new effe8b919 fix #10032
effe8b919 is described below

commit effe8b91907c38ad8841c79f8491e43599101952
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Jun 12 12:24:18 2025 -0300

    fix #10032
---
 packages/aml-backoffice-ui/src/Routing.tsx         | 22 ++++--
 .../src/components/ErrorLoadingWithDebug.tsx       |  9 ++-
 packages/aml-backoffice-ui/src/hooks/transfers.ts  |  3 +
 .../aml-backoffice-ui/src/pages/CaseDetails.tsx    | 60 +++------------
 packages/aml-backoffice-ui/src/pages/Transfers.tsx | 85 +++++++++++++++++-----
 .../taler-util/src/http-client/exchange-client.ts  |  6 +-
 6 files changed, 107 insertions(+), 78 deletions(-)

diff --git a/packages/aml-backoffice-ui/src/Routing.tsx 
b/packages/aml-backoffice-ui/src/Routing.tsx
index a2dd600f7..245e9dba1 100644
--- a/packages/aml-backoffice-ui/src/Routing.tsx
+++ b/packages/aml-backoffice-ui/src/Routing.tsx
@@ -16,11 +16,10 @@
 
 import {
   decodeCrockFromURI,
-  encodeCrockForURI,
   urlPattern,
   useCurrentLocation,
   useNavigationContext,
-  useTranslationContext,
+  useTranslationContext
 } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
 
@@ -34,16 +33,14 @@ import { CaseUpdate } from "./pages/CaseUpdate.js";
 import { Accounts } from "./pages/Cases.js";
 import { Dashboard } from "./pages/Dashboard.js";
 import { HandleAccountNotReady } from "./pages/HandleAccountNotReady.js";
-import { MeasureList } from "./pages/MeasureList.js";
-import { NewMeasure } from "./pages/NewMeasure.js";
 import { Officer } from "./pages/Officer.js";
 import { Search } from "./pages/Search.js";
+import { ShowCollectedInfo } from "./pages/ShowCollectedInfo.js";
 import { Transfers } from "./pages/Transfers.js";
 import {
   AmlDecisionRequestWizard,
   WizardSteps,
 } from "./pages/decision/AmlDecisionRequestWizard.js";
-import { ShowCollectedInfo } from "./pages/ShowCollectedInfo.js";
 
 export function Routing(): VNode {
   const session = useOfficer();
@@ -136,6 +133,10 @@ export const privatePages = {
   // measuresNew: urlPattern(/\/measures\/new/, () => "#/measures/new"),
   // measures: urlPattern(/\/measures/, () => "#/measures"),
   search: urlPattern(/\/search/, () => "#/search"),
+  transfersForAccount: urlPattern<{ cid: string }>(
+    /\/transfers\/(?<cid>[a-zA-Z0-9]+)/,
+    ({ cid }) => `#/transfers/${cid}`,
+  ),
   transfers: urlPattern(/\/transfers/, () => "#/transfers"),
   accounts: urlPattern(/\/accounts/, () => "#/accounts"),
   caseUpdate: urlPattern<{ cid: string; type: string }>(
@@ -151,7 +152,7 @@ export const privatePages = {
 function PrivateRouting(): VNode {
   const { navigateTo } = useNavigationContext();
   const location = useCurrentLocation(privatePages);
-  const [,, startNewRequest] = useCurrentDecisionRequest();
+  const [, , startNewRequest] = useCurrentDecisionRequest();
   useEffect(() => {
     if (location.name === undefined) {
       navigateTo(privatePages.dashboard.url({}));
@@ -298,6 +299,7 @@ function PrivateRouting(): VNode {
       return (
         <CaseDetails
           account={location.values.cid}
+          routeToShowTransfers={privatePages.transfersForAccount}
           routeToShowCollectedInfo={privatePages.showCollectedInfo}
           onNewDecision={(r) => {
             startNewRequest(r);
@@ -337,6 +339,14 @@ function PrivateRouting(): VNode {
     case "transfers": {
       return <Transfers routeToCaseById={privatePages.caseDetails} />;
     }
+    case "transfersForAccount": {
+      return (
+        <Transfers
+          routeToCaseById={privatePages.caseDetails}
+          account={location.values.cid}
+        />
+      );
+    }
     case "showCollectedInfo": {
       return (
         <ShowCollectedInfo
diff --git 
a/packages/aml-backoffice-ui/src/components/ErrorLoadingWithDebug.tsx 
b/packages/aml-backoffice-ui/src/components/ErrorLoadingWithDebug.tsx
index 8679af050..660a45ab4 100644
--- a/packages/aml-backoffice-ui/src/components/ErrorLoadingWithDebug.tsx
+++ b/packages/aml-backoffice-ui/src/components/ErrorLoadingWithDebug.tsx
@@ -18,7 +18,12 @@ import { ErrorLoading } from "@gnu-taler/web-util/browser";
 import { VNode, h } from "preact";
 import { usePreferences } from "../hooks/preferences.js";
 
-export function ErrorLoadingWithDebug({ error }: { error: TalerError }): VNode 
{
+export function ErrorLoadingWithDebug({ error }: { error: Error }): VNode {
   const [pref] = usePreferences();
-  return <ErrorLoading error={error} showDetail={pref.showDebugInfo} />;
+  if (error instanceof TalerError) {
+    return <ErrorLoading error={error} showDetail={pref.showDebugInfo} />;
+  } else {
+    console.error(error)
+    return <ErrorLoading error={TalerError.fromException(error)} 
showDetail={pref.showDebugInfo} />;
+  }
 }
diff --git a/packages/aml-backoffice-ui/src/hooks/transfers.ts 
b/packages/aml-backoffice-ui/src/hooks/transfers.ts
index 2a6eb6367..a1fc470ef 100644
--- a/packages/aml-backoffice-ui/src/hooks/transfers.ts
+++ b/packages/aml-backoffice-ui/src/hooks/transfers.ts
@@ -117,6 +117,7 @@ export function useTransferList({
           offset,
           limit: PAGINATED_LIST_REQUEST,
           threshold,
+          account
         });
       }
       case "debit": {
@@ -125,6 +126,7 @@ export function useTransferList({
           offset,
           limit: PAGINATED_LIST_REQUEST,
           threshold,
+          account
         });
       }
       case "kyc-auth": {
@@ -133,6 +135,7 @@ export function useTransferList({
           offset,
           limit: PAGINATED_LIST_REQUEST,
           threshold,
+          account
         });
       }
     }
diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx 
b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
index 02b0da523..80328edb8 100644
--- a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
+++ b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
@@ -62,56 +62,6 @@ import { CurrentMeasureTable, MeasureInfo, Mesaures } from 
"./MeasuresTable.js";
 import { Officer } from "./Officer.js";
 import { RulesInfo } from "./RulesInfo.js";
 
-// export type AmlEvent =
-//   | AmlFormEvent
-//   | KycCollectionEvent
-//   | KycExpirationEvent;
-
-// type AmlFormEvent = {
-//   type: "aml-form";
-//   when: AbsoluteTime;
-//   title: TranslatedString;
-//   justification: Justification;
-//   metadata: FormMetadata;
-//   state: TalerExchangeApi.AmlState;
-//   threshold: AmountJson;
-// };
-// type KycCollectionEvent = {
-//   type: "kyc-collection";
-//   when: AbsoluteTime;
-//   title: TranslatedString;
-//   values: object;
-//   provider?: string;
-// };
-// type KycExpirationEvent = {
-//   type: "kyc-expiration";
-//   when: AbsoluteTime;
-//   title: TranslatedString;
-//   fields: string[];
-// };
-
-// type WithTime = { when: AbsoluteTime };
-
-// function selectSooner(a: WithTime, b: WithTime) {
-//   return AbsoluteTime.cmp(a.when, b.when);
-// }
-
-// export function getEventsFromAmlHistory(
-//   events: TalerExchangeApi.KycAttributeCollectionEvent[],
-//   i18n: InternationalizationAPI,
-// ): AmlEvent[] {
-//   const ke = events.map((event) => {
-//     return {
-//       type: "kyc-collection",
-//       title: i18n.str`User filled a form`,
-//       when: AbsoluteTime.fromProtocolTimestamp(event.collection_time),
-//       values: !event.attributes ? {} : event.attributes,
-//       provider: event.provider_name,
-//     } as AmlEvent;
-//   });
-//   return ke.sort(selectSooner);
-// }
-
 type NewDecision = {
   request: Omit<Omit<AmlDecisionRequest, "justification">, "officer_sig">;
   askInformation: boolean;
@@ -121,10 +71,12 @@ export function CaseDetails({
   account,
   routeToShowCollectedInfo,
   onNewDecision,
+  routeToShowTransfers,
 }: {
   onNewDecision: (d: Partial<DecisionRequest>) => void;
   routeToShowCollectedInfo: RouteDefinition<{ cid: string; rowId: string }>;
   account: string;
+  routeToShowTransfers: RouteDefinition<{ cid: string }>;
 }) {
   const { i18n } = useTranslationContext();
   const details = useAccountInformation(account);
@@ -188,6 +140,14 @@ export function CaseDetails({
         >
           <i18n.Translate>New decision</i18n.Translate>
         </button>
+        <a
+          href={routeToShowTransfers.url({
+            cid: account,
+          })}
+          class="m-4  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"
+        >
+          <i18n.Translate>Show transfers</i18n.Translate>
+        </a>
       </div>
     );
   }
diff --git a/packages/aml-backoffice-ui/src/pages/Transfers.tsx 
b/packages/aml-backoffice-ui/src/pages/Transfers.tsx
index 0d7f79d9f..9370b8b52 100644
--- a/packages/aml-backoffice-ui/src/pages/Transfers.tsx
+++ b/packages/aml-backoffice-ui/src/pages/Transfers.tsx
@@ -7,6 +7,8 @@ import {
   encodeCrock,
   hashNormalizedPaytoUri,
   HttpStatusCode,
+  PaytoHash,
+  stringifyPaytoUri,
   TalerError,
 } from "@gnu-taler/taler-util";
 import {
@@ -28,8 +30,10 @@ import { Officer } from "./Officer.js";
 
 export function Transfers({
   routeToCaseById,
+  account,
 }: {
   routeToCaseById: RouteDefinition<{ cid: string }>;
+  account?: PaytoHash;
 }): VNode {
   const { i18n, dateLocale } = useTranslationContext();
   const { config } = useExchangeApiContext();
@@ -85,14 +89,15 @@ export function Transfers({
   const resp = useTransferList({
     direction,
     threshold,
+    account,
   });
 
-  const isDebit = direction === "debit";
-
+  const theMoneyIsDirectedToTheExchange = direction === "debit";
+  const searchingForAnAccount = account !== undefined;
   if (!resp) {
     return <Loading />;
   }
-  if (resp instanceof TalerError) {
+  if (resp instanceof Error) {
     return <ErrorLoadingWithDebug error={resp} />;
   }
   if (resp.type === "fail") {
@@ -143,19 +148,40 @@ export function Transfers({
     return (
       <div class="px-4 mt-8">
         <div class="sm:flex sm:items-center">
-          <div class="sm:flex-auto">
+        <div class="sm:flex-auto">
+          {searchingForAnAccount ? (
+            <h1 class="text-base font-semibold leading-6 text-gray-900">
+              <i18n.Translate>Transfers history for account</i18n.Translate>
+              {' '}
+              <a
+                href={routeToCaseById.url({
+                  cid: account,
+                })}
+                class="text-indigo-600 hover:text-indigo-900 font-mono"
+              >
+                {account}
+              </a>
+            </h1>
+          ) : (
             <h1 class="text-base font-semibold leading-6 text-gray-900">
               <i18n.Translate>Transfers history</i18n.Translate>
             </h1>
-          </div>
+          )}
+        </div>
         </div>
         <FormUI design={design} model={form.model} />
 
         <Attention type="low" title={i18n.str`No transfers yet.`}>
-          <i18n.Translate>
-            There are no transfer reported to the exchange with the current
-            threshold.
-          </i18n.Translate>
+          {searchingForAnAccount ? (
+            <i18n.Translate>
+              There are no transfer for this account.
+            </i18n.Translate>
+          ) : (
+            <i18n.Translate>
+              There are no transfer reported to the exchange with the current
+              threshold.
+            </i18n.Translate>
+          )}
         </Attention>
       </div>
     );
@@ -184,9 +210,24 @@ export function Transfers({
     <div class="px-4 mt-8">
       <div class="sm:flex sm:items-center">
         <div class="sm:flex-auto">
-          <h1 class="text-base font-semibold leading-6 text-gray-900">
-            <i18n.Translate>Transfers history</i18n.Translate>
-          </h1>
+          {searchingForAnAccount ? (
+            <h1 class="text-base font-semibold leading-6 text-gray-900">
+              <i18n.Translate>Transfers history for account</i18n.Translate>
+              {' '}
+              <a
+                href={routeToCaseById.url({
+                  cid: account,
+                })}
+                class="text-indigo-600 hover:text-indigo-900 font-mono"
+              >
+                {account}
+              </a>
+            </h1>
+          ) : (
+            <h1 class="text-base font-semibold leading-6 text-gray-900">
+              <i18n.Translate>Transfers history</i18n.Translate>
+            </h1>
+          )}
         </div>
       </div>
       <FormUI design={design} model={form.model} />
@@ -251,10 +292,16 @@ export function Transfers({
                               <i18n.Translate>Amount</i18n.Translate>
                             </dt>
                             <dd class="mt-1 truncate text-gray-700">
-                              {isDebit ? i18n.str`sent` : 
i18n.str`received`}{" "}
+                              {theMoneyIsDirectedToTheExchange
+                                ? i18n.str`sent`
+                                : i18n.str`received`}{" "}
                               {item.amount ? (
                                 <span
-                                  data-negative={isDebit ? "true" : "false"}
+                                  data-negative={
+                                    theMoneyIsDirectedToTheExchange
+                                      ? "true"
+                                      : "false"
+                                  }
                                   class="data-[negative=false]:text-green-600 
data-[negative=true]:text-red-600"
                                 >
                                   <RenderAmount
@@ -279,7 +326,9 @@ export function Transfers({
                                 })}
                                 class="text-indigo-600 hover:text-indigo-900 
font-mono"
                               >
-                                {isDebit ? i18n.str`to` : i18n.str`from`}{" "}
+                                {theMoneyIsDirectedToTheExchange
+                                  ? i18n.str`to`
+                                  : i18n.str`from`}{" "}
                                 {item.payto_uri}
                               </a>
                             </dd>
@@ -291,13 +340,15 @@ export function Transfers({
                           </dl>
                         </td>
                         <td
-                          data-negative={isDebit ? "true" : "false"}
+                          data-negative={
+                            theMoneyIsDirectedToTheExchange ? "true" : "false"
+                          }
                           class="hidden sm:table-cell px-3 py-3.5 text-sm 
text-gray-500 "
                         >
                           {item.amount ? (
                             <RenderAmount
                               value={Amounts.parseOrThrow(item.amount)}
-                              negative={isDebit}
+                              negative={theMoneyIsDirectedToTheExchange}
                               withColor
                               spec={config.config.currency_specification}
                             />
diff --git a/packages/taler-util/src/http-client/exchange-client.ts 
b/packages/taler-util/src/http-client/exchange-client.ts
index 93363dc7e..40797c89b 100644
--- a/packages/taler-util/src/http-client/exchange-client.ts
+++ b/packages/taler-util/src/http-client/exchange-client.ts
@@ -1174,7 +1174,7 @@ export class TalerExchangeHttpClient {
       url.searchParams.set("threshold", Amounts.stringify(params.threshold));
     }
     if (params.account) {
-      url.searchParams.set("h_payto", Amounts.stringify(params.account));
+      url.searchParams.set("h_payto", params.account);
     }
 
     const resp = await this.fetch(url, {
@@ -1225,7 +1225,7 @@ export class TalerExchangeHttpClient {
       url.searchParams.set("threshold", Amounts.stringify(params.threshold));
     }
     if (params.account) {
-      url.searchParams.set("h_payto", Amounts.stringify(params.account));
+      url.searchParams.set("h_payto", params.account);
     }
 
     const resp = await this.fetch(url, {
@@ -1276,7 +1276,7 @@ export class TalerExchangeHttpClient {
       url.searchParams.set("threshold", Amounts.stringify(params.threshold));
     }
     if (params.account) {
-      url.searchParams.set("h_payto", Amounts.stringify(params.account));
+      url.searchParams.set("h_payto", params.account);
     }
 
     const resp = await this.fetch(url, {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]