From 3418a2fcb4b73374b5433052d05978cf9212093c Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 19 Jun 2024 08:30:22 -0300 Subject: filter accounts based on active status --- packages/merchant-backoffice-ui/src/hooks/bank.ts | 26 +- .../src/paths/instance/accounts/create/index.tsx | 14 +- .../src/paths/instance/accounts/list/ListPage.tsx | 7 +- .../src/paths/instance/accounts/list/Table.tsx | 473 +++++++++++---------- .../src/paths/instance/accounts/list/index.tsx | 52 +-- .../paths/instance/accounts/update/UpdatePage.tsx | 5 +- 6 files changed, 308 insertions(+), 269 deletions(-) (limited to 'packages') diff --git a/packages/merchant-backoffice-ui/src/hooks/bank.ts b/packages/merchant-backoffice-ui/src/hooks/bank.ts index 8857ad839..4c917fe9e 100644 --- a/packages/merchant-backoffice-ui/src/hooks/bank.ts +++ b/packages/merchant-backoffice-ui/src/hooks/bank.ts @@ -13,18 +13,19 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ -import { - useMerchantApiContext -} from "@gnu-taler/web-util/browser"; +import { useMerchantApiContext } from "@gnu-taler/web-util/browser"; // FIX default import https://github.com/microsoft/TypeScript/issues/49189 -import { AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util"; +import { + AccessToken, + TalerHttpError, + TalerMerchantManagementResultByMethod, +} from "@gnu-taler/taler-util"; import _useSWR, { SWRHook, mutate } from "swr"; import { useSessionContext } from "../context/session.js"; const useSWR = _useSWR as unknown as SWRHook; -export interface InstanceBankAccountFilter { -} +export interface InstanceBankAccountFilter {} export function revalidateInstanceBankAccounts() { return mutate( @@ -35,7 +36,9 @@ export function revalidateInstanceBankAccounts() { } export function useInstanceBankAccounts() { const { state: session } = useSessionContext(); - const { lib: { instance } } = useSessionContext(); + const { + lib: { instance }, + } = useSessionContext(); // const [offset, setOffset] = useState(); @@ -57,19 +60,24 @@ export function useInstanceBankAccounts() { if (data.type !== "ok") return data; // return buildPaginatedResult(data.body.accounts, offset, setOffset, (d) => d.h_wire) + const filtered = data.body.accounts.filter((a) => a.active); + data.body.accounts = filtered; return data; } export function revalidateBankAccountDetails() { return mutate( - (key) => Array.isArray(key) && key[key.length - 1] === "getBankAccountDetails", + (key) => + Array.isArray(key) && key[key.length - 1] === "getBankAccountDetails", undefined, { revalidate: true }, ); } export function useBankAccountDetails(h_wire: string) { const { state: session } = useSessionContext(); - const { lib: { instance } } = useSessionContext(); + const { + lib: { instance }, + } = useSessionContext(); async function fetcher([token, wireId]: [AccessToken, string]) { return await instance.getBankAccountDetails(token, wireId); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx index 2c1a13e27..6994c579c 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx @@ -63,7 +63,15 @@ export default function CreateValidator({ onConfirm, onBack }: Props): VNode { onCreate={async (request: Entity) => { return api.instance .addBankAccount(state.token, request) - .then(() => { + .then((created) => { + if (created.type === "fail") { + setNotif({ + message: i18n.str`could not create account`, + type: "ERROR", + description: created.detail.hint, + }); + return; + } onConfirm(); }) .catch((error) => { @@ -120,7 +128,7 @@ export async function testRevenueAPI( if (resp.type === "fail") { return resp; } - + return opFixedSuccess(resp.body.credit_account as PaytoString); } catch (err) { if (err instanceof TalerError) { @@ -131,6 +139,6 @@ export async function testRevenueAPI( // detail: err.errorDetail, // }; } - throw err + throw err; } } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx index 4ee68cd80..7e0b89f39 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/ListPage.tsx @@ -24,12 +24,12 @@ import { h, VNode } from "preact"; import { CardTable } from "./Table.js"; export interface Props { - devices: TalerMerchantApi.BankAccountSummaryEntry[]; + devices: TalerMerchantApi.BankAccountEntry[]; // onLoadMoreBefore?: () => void; // onLoadMoreAfter?: () => void; onCreate: () => void; - onDelete: (e: TalerMerchantApi.BankAccountSummaryEntry) => void; - onSelect: (e: TalerMerchantApi.BankAccountSummaryEntry) => void; + onDelete: (e: TalerMerchantApi.BankAccountEntry) => void; + onSelect: (e: TalerMerchantApi.BankAccountEntry) => void; } export function ListPage({ @@ -40,7 +40,6 @@ export function ListPage({ // onLoadMoreBefore, // onLoadMoreAfter, }: Props): VNode { - return (
; } -function Table({ - accounts, - onDelete, - onSelect, -}: TableProps): VNode { +function Table({ accounts, onDelete, onSelect }: TableProps): VNode { const { i18n } = useTranslationContext(); - const emptyList: Record = { "bitcoin": [], "x-taler-bank": [], "iban": [], "unknown": [], } + const emptyList: Record< + PaytoType | "unknown", + { parsed: PaytoUri; acc: Entity }[] + > = { bitcoin: [], "x-taler-bank": [], iban: [], unknown: [] }; const accountsByType = accounts.reduce((prev, acc) => { - const parsed = parsePaytoUri(acc.payto_uri) - if (!parsed) return prev //skip - if (parsed.targetType !== "bitcoin" && parsed.targetType !== "x-taler-bank" && parsed.targetType !== "iban") { - prev["unknown"].push({ parsed, acc }) + const parsed = parsePaytoUri(acc.payto_uri); + if (!parsed) return prev; //skip + if ( + parsed.targetType !== "bitcoin" && + parsed.targetType !== "x-taler-bank" && + parsed.targetType !== "iban" + ) { + prev["unknown"].push({ parsed, acc }); } else { - prev[parsed.targetType].push({ parsed, acc }) + prev[parsed.targetType].push({ parsed, acc }); } - return prev - }, emptyList) - - const bitcoinAccounts = accountsByType["bitcoin"] - const talerbankAccounts = accountsByType["x-taler-bank"] - const ibanAccounts = accountsByType["iban"] - const unkownAccounts = accountsByType["unknown"] + return prev; + }, emptyList); + const bitcoinAccounts = accountsByType["bitcoin"]; + const talerbankAccounts = accountsByType["x-taler-bank"]; + const ibanAccounts = accountsByType["iban"]; + const unkownAccounts = accountsByType["unknown"]; return ( + {bitcoinAccounts.length > 0 && ( +
+

+ Bitcoin type accounts +

+ + + + + + + + + + {bitcoinAccounts.map(({ parsed, acc }, idx) => { + const ac = parsed as PaytoUriBitcoin; + return ( + + + + + + + ); + })} + +
+ Address + + Sewgit 1 + + Sewgit 2 + +
onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.targetPath} + onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.segwitAddrs[0]} + onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.segwitAddrs[1]} + +
+ +
+
+
+ )} - {bitcoinAccounts.length > 0 &&
-

Bitcoin type accounts

- - - - - - - - - - {bitcoinAccounts.map(({ parsed, acc }, idx) => { - const ac = parsed as PaytoUriBitcoin - return ( - - - - - - - ); - })} - -
- Address - - Sewgit 1 - - Sewgit 2 - -
onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.targetPath} - onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.segwitAddrs[0]} - onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.segwitAddrs[1]} - -
- -
-
-
} - - - - {talerbankAccounts.length > 0 &&
-

Taler type accounts

- - - - - - - - - {talerbankAccounts.map(({ parsed, acc }, idx) => { - const ac = parsed as PaytoUriTalerBank - return ( - - - - - - ); - })} - -
- Host - - Account name - -
onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.host} - onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.account} - -
- -
-
-
} + {talerbankAccounts.length > 0 && ( +
+

+ Taler type accounts +

+ + + + + + + + + {talerbankAccounts.map(({ parsed, acc }, idx) => { + const ac = parsed as PaytoUriTalerBank; + return ( + + + + + + ); + })} + +
+ Host + + Account name + +
onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.host} + onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.account} + +
+ +
+
+
+ )} - {ibanAccounts.length > 0 &&
-

IBAN type accounts

- - - - - - - - - {ibanAccounts.map(({ parsed, acc }, idx) => { - const ac = parsed as PaytoUriIBAN - return ( - - - - - - ); - })} - -
- Account name - - IBAN - -
onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.params["receiver-name"]} - onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.iban} - -
- -
-
-
} + {ibanAccounts.length > 0 && ( +
+

+ IBAN type accounts +

+ + + + + + + + + {ibanAccounts.map(({ parsed, acc }, idx) => { + const ac = parsed as PaytoUriIBAN; + return ( + + + + + + ); + })} + +
+ Account name + + IBAN + +
onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.params["receiver-name"]} + onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.iban} + +
+ +
+
+
+ )} - {unkownAccounts.length > 0 &&
-

Other type accounts

- - - - - - - - - {unkownAccounts.map(({ parsed, acc }, idx) => { - const ac = parsed as PaytoUriUnknown - return ( - - - - - - ); - })} - -
- Type - - Path - -
onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.targetType} - onSelect(acc)} - style={{ cursor: "pointer" }} - > - {ac.targetPath} - -
- -
-
-
} + {unkownAccounts.length > 0 && ( +
+

+ Other type accounts +

+ + + + + + + + + {unkownAccounts.map(({ parsed, acc }, idx) => { + const ac = parsed as PaytoUriUnknown; + return ( + + + + + + ); + })} + +
+ Type + + Path + +
onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.targetType} + onSelect(acc)} + style={{ cursor: "pointer" }} + > + {ac.targetPath} + +
+ +
+
+
+ )}
- ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx index c0ddab475..9d09473bc 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx @@ -19,10 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util"; import { - useTranslationContext -} from "@gnu-taler/web-util/browser"; + HttpStatusCode, + TalerError, + TalerMerchantApi, + assertUnreachable, +} from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; @@ -40,30 +43,27 @@ interface Props { onSelect: (id: string) => void; } -export default function ListOtpDevices({ - onCreate, - onSelect, -}: Props): VNode { +export default function ListOtpDevices({ onCreate, onSelect }: Props): VNode { const { i18n } = useTranslationContext(); const [notif, setNotif] = useState(undefined); const { lib: api } = useSessionContext(); const { state } = useSessionContext(); const result = useInstanceBankAccounts(); - if (!result) return + if (!result) return ; if (result instanceof TalerError) { - return + return ; } if (result.type === "fail") { - switch(result.case) { + switch (result.case) { case HttpStatusCode.NotFound: { - return + return ; } case HttpStatusCode.Unauthorized: { - return + return ; } default: { - assertUnreachable(result) + assertUnreachable(result); } } } @@ -71,13 +71,15 @@ export default function ListOtpDevices({ return ( - {result.body.accounts.length < 1 && - - } + {result.body.accounts.length < 1 && ( + + )} { onSelect(e.h_wire); }} - onDelete={(e: TalerMerchantApi.BankAccountSummaryEntry) => { - return api.instance.deleteBankAccount(state.token, e.h_wire) + onDelete={(e: TalerMerchantApi.BankAccountEntry) => { + return api.instance + .deleteBankAccount(state.token, e.h_wire) .then(() => setNotif({ message: i18n.str`bank account delete successfully`, @@ -102,9 +105,8 @@ export default function ListOtpDevices({ type: "ERROR", description: error.message, }), - ) - } - } + ); + }} /> ); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx index 00833071b..812b2aa50 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx @@ -34,7 +34,7 @@ import { InputSelector } from "../../../../components/form/InputSelector.js"; import { undefinedIfEmpty } from "../../../../utils/table.js"; import { WithId } from "../../../../declaration.js"; -type Entity = TalerMerchantApi.BankAccountEntry & WithId; +type Entity = TalerMerchantApi.BankAccountDetail & WithId; const accountAuthType = ["unedit", "none", "basic"]; interface Props { @@ -68,7 +68,7 @@ export function UpdatePage({ account, onUpdate, onBack }: Props): VNode { ? i18n.str`URL should not contain params` : facadeURL.hash ? i18n.str`URL should not hash param` - : undefined, + : undefined, credit_facade_credentials: undefinedIfEmpty({ username: state.credit_facade_credentials?.type !== "basic" @@ -83,7 +83,6 @@ export function UpdatePage({ account, onUpdate, onBack }: Props): VNode { : !state.credit_facade_credentials.password ? i18n.str`required` : undefined, - }), }; -- cgit v1.2.3