commit dd6dfd767834180bc3785babce92aeacaeab0717
parent 60dc432e7775d6b0f6d8a6fed23c2cebe5780b84
Author: Sebastian <sebasjm@taler-systems.com>
Date: Mon, 5 Jan 2026 19:56:59 -0300
fix #10127
Diffstat:
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>
+ "
+ {
+ succeedOrThrow(Paytos.fromString(deleting.payto_uri))
+ .displayName
+ }
+ "
+ </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;