taler-typescript-core

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

commit dd6dfd767834180bc3785babce92aeacaeab0717
parent 60dc432e7775d6b0f6d8a6fed23c2cebe5780b84
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Mon,  5 Jan 2026 19:56:59 -0300

fix #10127

Diffstat:
Mpackages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mpackages/merchant-backoffice-ui/src/settings.json | 2+-
Mpackages/web-util/src/hooks/useNotifications.ts | 15+++++++++++++++
3 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx @@ -20,6 +20,7 @@ */ import { + assertUnreachable, HttpStatusCode, parsePaytoUri, Paytos, @@ -29,14 +30,13 @@ import { TalerMerchantApi, } from "@gnu-taler/taler-util"; import { - ButtonBetterBulma, LocalNotificationBannerBulma, - SafeHandlerTemplate, useLocalNotificationBetter, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { StateUpdater, useState } from "preact/hooks"; +import { ConfirmModal } from "../../../../components/modal/index.js"; import { useSessionContext } from "../../../../context/session.js"; const TALER_SCREEN_ID = 35; @@ -55,24 +55,65 @@ export function CardTable({ accounts, onCreate, onSelect }: Props): VNode { const { i18n } = useTranslationContext(); const { state: session, lib } = useSessionContext(); const [notification, safeFunctionHandler] = useLocalNotificationBetter(); + const [deleting, setDeleting] = + useState<TalerMerchantApi.BankAccountEntry | null>(null); - const remove = safeFunctionHandler( - lib.instance.deleteBankAccount.bind(lib.instance), - ).lambda((id: string) => (!session.token ? undefined! : [session.token, id])); + const remove = safeFunctionHandler((w: string) => { + return lib.instance.deleteBankAccount.bind(lib.instance)(session.token, w); + }); remove.onFail = (fail) => { switch (fail.case) { case HttpStatusCode.Unauthorized: return i18n.str`Unauthorized`; case HttpStatusCode.NotFound: return i18n.str`Not found`; + default: { + assertUnreachable(fail); + } } }; - remove.onSuccess = () => i18n.str`The bank account has been deleted.`; + remove.onSuccess = () => { + setDeleting(null); + return i18n.str`The bank account has been deleted.`; + }; return ( <Fragment> <LocalNotificationBannerBulma notification={notification} /> + {deleting && ( + <ConfirmModal + label={i18n.str`Delete account`} + description={i18n.str`Delete the account "${ + succeedOrThrow(Paytos.fromString(deleting.payto_uri)).displayName + }"`} + danger + active + onCancel={() => setDeleting(null)} + confirm={remove.withArgs(deleting.h_wire)} + > + <p> + <i18n.Translate> + If you delete the account with name{" "} + <b> + &quot; + { + succeedOrThrow(Paytos.fromString(deleting.payto_uri)) + .displayName + } + &quot; + </b>{" "} + its information will be lost + </i18n.Translate> + </p> + <p class="warning"> + <i18n.Translate> + Deleting an account can't be undone. + </i18n.Translate> + </p> + </ConfirmModal> + )} + <div class="card has-table"> <header class="card-header"> <p class="card-header-title"> @@ -105,7 +146,7 @@ export function CardTable({ accounts, onCreate, onSelect }: Props): VNode { {accounts.length > 0 ? ( <Table accounts={accounts} - onDelete={remove} + onDelete={setDeleting} onSelect={onSelect} rowSelection={rowSelection} rowSelectionHandler={rowSelectionHandler} @@ -123,7 +164,7 @@ export function CardTable({ accounts, onCreate, onSelect }: Props): VNode { interface TableProps { rowSelection: string[]; accounts: Entity[]; - onDelete: SafeHandlerTemplate<[id: string], unknown>; + onDelete: (e: Entity) => void; onSelect: (e: Entity) => void; rowSelectionHandler: StateUpdater<string[]>; } @@ -211,13 +252,13 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { </td> <td class="is-actions-cell right-sticky"> <div class="buttons is-right"> - <ButtonBetterBulma + <button class="button is-danger is-small has-tooltip-left" data-tooltip={i18n.str`Delete selected accounts from the database`} - onClick={onDelete.withArgs(acc.h_wire)} + onClick={() => onDelete(acc)} > <i18n.Translate>Delete</i18n.Translate> - </ButtonBetterBulma> + </button> </div> </td> </tr> @@ -249,13 +290,13 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { </td> <td class="is-actions-cell right-sticky"> <div class="buttons is-right"> - <ButtonBetterBulma + <button class="button is-danger is-small has-tooltip-left" data-tooltip={i18n.str`Delete selected accounts from the database`} - onClick={onDelete.withArgs(acc.h_wire)} + onClick={() => onDelete(acc)} > <i18n.Translate>Delete</i18n.Translate> - </ButtonBetterBulma> + </button> </div> </td> </tr> @@ -287,13 +328,13 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { </td> <td class="is-actions-cell right-sticky"> <div class="buttons is-right"> - <ButtonBetterBulma + <button class="button is-danger is-small has-tooltip-left" data-tooltip={i18n.str`Delete selected accounts from the database`} - onClick={onDelete.withArgs(acc.h_wire)} + onClick={() => onDelete(acc)} > <i18n.Translate>Delete</i18n.Translate> - </ButtonBetterBulma> + </button> </div> </td> </tr> @@ -325,13 +366,14 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { </td> <td class="is-actions-cell right-sticky"> <div class="buttons is-right"> - <ButtonBetterBulma + <button class="button is-danger is-small has-tooltip-left" data-tooltip={i18n.str`Delete selected accounts from the database`} - onClick={onDelete.withArgs(acc.h_wire)} + onClick={() => onDelete(acc)} + // onClick={() => onDelete(acc,)} > <i18n.Translate>Delete</i18n.Translate> - </ButtonBetterBulma> + </button> </div> </td> </tr> diff --git a/packages/merchant-backoffice-ui/src/settings.json b/packages/merchant-backoffice-ui/src/settings.json @@ -1,4 +1,4 @@ { - "backendBaseURL": "https://merchant.taler.test/", + "backendBaseURL": "https://merchant.taler/", "supportedWireMethods": ["iban"] } diff --git a/packages/web-util/src/hooks/useNotifications.ts b/packages/web-util/src/hooks/useNotifications.ts @@ -258,6 +258,21 @@ export function useLocalNotificationBetter(): [ const e = thiz.withArgs(...d); return e; }; + /** + * FIXME: there is a problem with this + * + * adding onSuccess function after creating the lambda makes the withArgs + * build handlers without onSuccess. consider this + * + * const h = safeHandler(handler).lambda((param) -> .. ) + * h.onSuccess = () => i18n.str`ok` + * const button = h.withArgs(p); + * + * button.call() + * + * the onSuccess function is undefined when button is clicked. + * But not if the lambda is created after the onSuccess assignment + */ r.onSuccess = thiz.onSuccess; r.onFail = thiz.onFail; return r as any as SH;