gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 02/02: new payto form


From: gnunet
Subject: [taler-wallet-core] 02/02: new payto form
Date: Fri, 14 Jun 2024 17:33:29 +0200

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

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

commit 2b895bea57ae486004d8173354ccd5af52cf042e
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Fri Jun 14 12:33:17 2024 -0300

    new payto form
---
 packages/merchant-backoffice-ui/src/Routing.tsx    |   4 -
 .../src/components/form/InputPaytoForm.tsx         |   4 +-
 .../src/components/form/InputToggle.tsx            |  28 +++-
 .../src/components/menu/index.tsx                  |  16 +-
 .../src/components/modal/index.tsx                 | 103 ++++++++++++
 .../src/components/tokenfamily/TokenFamilyForm.tsx |   2 +-
 .../src/hooks/tokenfamily.ts                       |   2 +-
 .../paths/instance/accounts/create/CreatePage.tsx  | 183 ++++++++++++++-------
 .../src/paths/instance/accounts/create/index.tsx   |  22 ++-
 .../src/paths/instance/accounts/list/index.tsx     |   2 +-
 .../tokenfamilies/create/Create.stories.tsx        |   2 +-
 .../instance/tokenfamilies/create/CreatePage.tsx   |   2 +-
 .../paths/instance/tokenfamilies/create/index.tsx  |   2 +-
 .../paths/instance/tokenfamilies/list/Table.tsx    |   2 +-
 .../paths/instance/tokenfamilies/list/index.tsx    |   2 +-
 .../src/paths/instance/transfers/list/ListPage.tsx |   4 +-
 .../merchant-backoffice-ui/src/scss/toggle.scss    |  16 ++
 17 files changed, 302 insertions(+), 94 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/Routing.tsx 
b/packages/merchant-backoffice-ui/src/Routing.tsx
index c290cd67f..b3fd44e74 100644
--- a/packages/merchant-backoffice-ui/src/Routing.tsx
+++ b/packages/merchant-backoffice-ui/src/Routing.tsx
@@ -94,10 +94,6 @@ export enum InstancePaths {
   order_new = "/order/new",
   order_details = "/order/:oid/details",
 
-  reserves_list = "/reserves",
-  reserves_details = "/reserves/:rid/details",
-  reserves_new = "/reserves/new",
-
   kyc = "/kyc",
 
   transfers_list = "/transfers",
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
index 9cec72c01..585894863 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
@@ -296,7 +296,7 @@ export function InputPaytoForm<T>({
       >
         <InputSelector<Entity>
           name="target"
-          label={i18n.str`Account type`}
+          label={i18n.str`Type`}
           tooltip={i18n.str`Method to use for wire transfer`}
           values={targets}
           readonly={readonly}
@@ -430,7 +430,9 @@ export function InputPaytoForm<T>({
               name="params.receiver-name"
               readonly={readonly}
               label={i18n.str`Owner's name`}
+              placeholder="John Doe"
               tooltip={i18n.str`Legal name of the person holding the account.`}
+              help={i18n.str`It should match the bank account name.`}
             />
           </Fragment>
         )}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx
index 8c935f33b..89a4dc48c 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx
@@ -18,7 +18,7 @@
  *
  * @author Sebastian Javier Marchano (sebasjm)
  */
-import { h, VNode } from "preact";
+import { ComponentChildren, h, VNode } from "preact";
 import { InputProps, useField } from "./useField.js";
 
 interface Props<T> extends InputProps<T> {
@@ -26,11 +26,12 @@ interface Props<T> extends InputProps<T> {
   readonly?: boolean;
   expand?: boolean;
   threeState?: boolean;
+  side?: ComponentChildren;
   toBoolean?: (v?: any) => boolean | undefined;
   fromBoolean?: (s: boolean | undefined) => any;
 }
 
-const defaultToBoolean = (f?: any): boolean | undefined => f || "";
+const defaultToBoolean = (f?: any): boolean | undefined => f;
 const defaultFromBoolean = (v: boolean | undefined): any => v as any;
 
 export function InputToggle<T>({
@@ -41,6 +42,7 @@ export function InputToggle<T>({
   label,
   help,
   threeState,
+  side,
   expand,
   fromBoolean = defaultFromBoolean,
   toBoolean = defaultToBoolean,
@@ -56,7 +58,7 @@ export function InputToggle<T>({
   return (
     <div class="field is-horizontal">
       <div class="field-label is-normal">
-        <label class="label" >
+        <label class="label">
           {label}
           {tooltip && (
             <span class="icon has-tooltip-right" data-tooltip={tooltip}>
@@ -68,23 +70,37 @@ export function InputToggle<T>({
       <div class="field-body is-flex-grow-3">
         <div class="field">
           <p class={expand ? "control is-expanded" : "control"}>
+            {/* {String(toBoolean(value))} */}
             <label class="toggle" style={{ marginLeft: 4, marginTop: 0 }}>
               <input
                 type="checkbox"
-                class={toBoolean(value) === undefined ? "is-indeterminate" : 
"toggle-checkbox"}
+                class={"toggle-checkbox"}
                 checked={toBoolean(value)}
                 placeholder={placeholder}
+                ref={(d) => {
+                  if (d) {
+                    d.indeterminate =
+                      !!threeState && toBoolean(value) === undefined;
+                  }
+                }}
                 readonly={readonly}
                 name={String(name)}
                 disabled={readonly}
                 onChange={onCheckboxClick}
               />
-              <div class={`toggle-switch ${readonly ? "disabled" : ""}`} 
style={{ cursor: readonly ? "default" : undefined }}></div>
+
+              <div
+                class={`toggle-switch ${readonly ? "disabled" : ""} ${
+                  toBoolean(value) === undefined ? "no-dot" : ""
+                }`}
+                style={{ cursor: readonly ? "default" : undefined }}
+              ></div>
             </label>
-            {help}
+            <p>{help}</p>
           </p>
           {error && <p class="help is-danger">{error}</p>}
         </div>
+        {side}
       </div>
     </div>
   );
diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
index baab9584c..c13839d2d 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
@@ -29,11 +29,11 @@ function getInstanceTitle(path: string, id: string): string 
{
     case InstancePaths.settings:
       return `${id}: Settings`;
     case InstancePaths.bank_new:
-      return `${id}: Account`;
+      return `${id}: New bank account`;
     case InstancePaths.bank_list:
-      return `${id}: Account`;
+      return `${id}: Bank accounts`;
     case InstancePaths.bank_update:
-      return `${id}: Account`;
+      return `${id}: Update bank Account`;
     case InstancePaths.order_list:
       return `${id}: Orders`;
     case InstancePaths.order_new:
@@ -44,10 +44,6 @@ function getInstanceTitle(path: string, id: string): string {
       return `${id}: New product`;
     case InstancePaths.inventory_update:
       return `${id}: Update product`;
-    case InstancePaths.reserves_new:
-      return `${id}: New reserve`;
-    case InstancePaths.reserves_list:
-      return `${id}: Reserves`;
     case InstancePaths.transfers_list:
       return `${id}: Transfers`;
     case InstancePaths.transfers_new:
@@ -59,11 +55,11 @@ function getInstanceTitle(path: string, id: string): string 
{
     case InstancePaths.webhooks_update:
       return `${id}: Update webhook`;
     case InstancePaths.otp_devices_list:
-      return `${id}: otp devices`;
+      return `${id}: OTP devices`;
     case InstancePaths.otp_devices_new:
-      return `${id}: New otp devices`;
+      return `${id}: New OTP device`;
     case InstancePaths.otp_devices_update:
-      return `${id}: Update otp devices`;
+      return `${id}: Update OTP device`;
     case InstancePaths.templates_new:
       return `${id}: New template`;
     case InstancePaths.templates_update:
diff --git a/packages/merchant-backoffice-ui/src/components/modal/index.tsx 
b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
index 43062d13e..518583a9c 100644
--- a/packages/merchant-backoffice-ui/src/components/modal/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
@@ -31,6 +31,8 @@ import {
   AccountLetter,
   codecForAccountLetter,
   PaytoString,
+  PaytoUri,
+  stringifyPaytoUri,
 } from "@gnu-taler/taler-util";
 
 interface Props {
@@ -288,6 +290,107 @@ export function ImportingAccountModal({
   );
 }
 
+interface CompareAccountsModalProps {
+  onCancel: () => void;
+  onConfirm: (account: PaytoString) => void;
+  formPayto: PaytoUri | undefined;
+  testPayto: PaytoUri;
+}
+
+export function CompareAccountsModal({
+  onCancel,
+  onConfirm,
+  formPayto,
+  testPayto,
+}: CompareAccountsModalProps): VNode {
+  const { i18n } = useTranslationContext();
+  return (
+    <ConfirmModal
+      label={i18n.str`Update form`}
+      description={i18n.str`Comparing account details`}
+      active
+      onCancel={onCancel}
+      onConfirm={() => onConfirm(stringifyPaytoUri(testPayto))}
+    >
+      <p>
+        <i18n.Translate>
+          Testing agaisnt the account info URL succedded but the account
+          information reported is different with the account details form.
+        </i18n.Translate>
+      </p>
+      <div class="table-container">
+        <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+          <thead>
+            <tr>
+              <td>
+                <i18n.Translate>Field</i18n.Translate>
+              </td>
+              <td>
+                <i18n.Translate>In the form</i18n.Translate>
+              </td>
+              <td>
+                <i18n.Translate>Reported</i18n.Translate>
+              </td>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>
+                <i18n.Translate>Type</i18n.Translate>
+              </td>
+              <td>{formPayto?.targetType ?? "--"}</td>
+              <td>{testPayto.targetType}</td>
+            </tr>
+            {testPayto.targetType === "iban" && (
+              <tr>
+                <td>
+                  <i18n.Translate>IBAN</i18n.Translate>
+                </td>
+                <td>{formPayto?.targetPath ?? "--"}</td>
+                <td>{testPayto.targetPath}</td>
+              </tr>
+            )}
+            {testPayto.targetType === "bitcoin" && (
+              <tr>
+                <td>
+                  <i18n.Translate>Address</i18n.Translate>
+                </td>
+                <td>{formPayto?.targetPath ?? "--"}</td>
+                <td>{testPayto.targetPath}</td>
+              </tr>
+            )}
+            {testPayto.targetType === "x-taler-bank" && (
+              <Fragment>
+                <tr>
+                  <td>
+                    <i18n.Translate>Host</i18n.Translate>
+                  </td>
+                  <td>{formPayto?.targetPath ?? "--"}</td>
+                  <td>{testPayto.targetPath}</td>
+                </tr>
+                <tr>
+                  <td>
+                    <i18n.Translate>Account id</i18n.Translate>
+                  </td>
+                  <td>{formPayto?.targetPath ?? "--"}</td>
+                  <td>{testPayto.targetPath}</td>
+                </tr>
+              </Fragment>
+            )}
+            <tr>
+              <td>
+                <i18n.Translate>Owner's name</i18n.Translate>
+              </td>
+              <td>{formPayto?.params["receiver-name"] ?? "--"}</td>
+              <td>{testPayto.params["receiver-name"]}</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+    </ConfirmModal>
+  );
+}
+
 interface DeleteModalProps {
   element: { id: string; name: string };
   onCancel: () => void;
diff --git 
a/packages/merchant-backoffice-ui/src/components/tokenfamily/TokenFamilyForm.tsx
 
b/packages/merchant-backoffice-ui/src/components/tokenfamily/TokenFamilyForm.tsx
index 1492beb48..b4c49502d 100644
--- 
a/packages/merchant-backoffice-ui/src/components/tokenfamily/TokenFamilyForm.tsx
+++ 
b/packages/merchant-backoffice-ui/src/components/tokenfamily/TokenFamilyForm.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git a/packages/merchant-backoffice-ui/src/hooks/tokenfamily.ts 
b/packages/merchant-backoffice-ui/src/hooks/tokenfamily.ts
index 62f364972..221babf30 100644
--- a/packages/merchant-backoffice-ui/src/hooks/tokenfamily.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/tokenfamily.ts
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
index 2f19d0c91..bec32bac3 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx
@@ -21,10 +21,12 @@
 
 import {
   HttpStatusCode,
+  PaytoUri,
   TalerError,
   TalerMerchantApi,
   TranslatedString,
   assertUnreachable,
+  parsePaytoUri,
 } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { Fragment, h, VNode } from "preact";
@@ -37,12 +39,16 @@ import {
 import { Input } from "../../../../components/form/Input.js";
 import { InputPaytoForm } from "../../../../components/form/InputPaytoForm.js";
 import { InputSelector } from "../../../../components/form/InputSelector.js";
-import { ImportingAccountModal } from "../../../../components/modal/index.js";
+import {
+  CompareAccountsModal,
+  ImportingAccountModal,
+} from "../../../../components/modal/index.js";
 import { undefinedIfEmpty } from "../../../../utils/table.js";
 import { safeConvertURL } from "../update/UpdatePage.js";
 import { testRevenueAPI } from "./index.js";
+import { InputToggle } from "../../../../components/form/InputToggle.js";
 
-type Entity = TalerMerchantApi.AccountAddDetails;
+type Entity = TalerMerchantApi.AccountAddDetails & { verified?: boolean };
 
 interface Props {
   onCreate: (d: TalerMerchantApi.AccountAddDetails) => Promise<void>;
@@ -55,8 +61,12 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
   const { i18n } = useTranslationContext();
 
   const [importing, setImporting] = useState(false);
+  const [revenuePayto, setRevenuePayto] = useState<PaytoUri | undefined>(
+    undefined,
+  );
   const [state, setState] = useState<Partial<Entity>>({});
   const facadeURL = safeConvertURL(state.credit_facade_url);
+
   const [testError, setTestError] = useState<TranslatedString | undefined>(
     undefined,
   );
@@ -133,70 +143,60 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
       );
       if (resp instanceof TalerError) {
         setTestError(i18n.str`The request to check the revenue API failed.`);
+        setState({
+          ...state,
+          verified: undefined,
+        });
         return;
-      }
-      if (resp.type === "fail") {
+      } else if (resp.type === "fail") {
         switch (resp.case) {
           case HttpStatusCode.BadRequest: {
             setTestError(i18n.str`Server replied with "bad request".`);
+            setState({
+              ...state,
+              verified: undefined,
+            });
             return;
           }
           case HttpStatusCode.Unauthorized: {
-            setTestError(i18n.str`Unauthorized, try with another 
credentials.`);
-
+            setTestError(i18n.str`Unauthorized, check credentials.`);
+            setState({
+              ...state,
+              verified: undefined,
+            });
             return;
           }
           case HttpStatusCode.NotFound: {
             setTestError(
               i18n.str`The endpoint doesn't seems to be a Taler Revenue API.`,
             );
+            setState({
+              ...state,
+              verified: undefined,
+            });
             return;
           }
           default: {
             assertUnreachable(resp);
           }
         }
+      } else {
+        const found = resp.body;
+        const match = state.payto_uri === found;
+        setState({
+          ...state,
+          verified: match,
+        });
+        if (!match) {
+          setRevenuePayto(parsePaytoUri(resp.body));
+        }
+        setTestError(undefined);
       }
     }
   }
 
   return (
-    <div>
-      {importing && (
-        <ImportingAccountModal
-          onCancel={() => {
-            setImporting(false);
-          }}
-          onConfirm={(ac) => {
-            const u = new URL(ac.infoURL);
-            const user = u.username;
-            const pwd = u.password;
-            u.password = "";
-            u.username = "";
-            const credit_facade_url = u.href;
-            setState({
-              payto_uri: ac.accountURI,
-              credit_facade_credentials:
-                user || pwd
-                  ? {
-                      type: "basic",
-                      password: pwd,
-                      username: user,
-                    }
-                  : undefined,
-              credit_facade_url,
-            });
-            // if (u.username && ac.accesToken) {
-            //   state.credit_facade_credentials = {
-            //     type: "bearer",
-            //     token: ac.accesToken,
-            //     username: u.username,
-            //   };
-            // } else
-            setImporting(false);
-          }}
-        />
-      )}
+    <Fragment>
       <section class="section is-main-section">
         <div class="columns">
           <div class="column" />
@@ -208,11 +208,19 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
             >
               <InputPaytoForm<Entity>
                 name="payto_uri"
-                label={i18n.str`Account`}
+                label={i18n.str`Account details`}
               />
+              <div class="message-body" style={{marginBottom: 10}}>
+                <p>
+                  <i18n.Translate>
+                    If the bank supports Taler Revenue API then you can add the
+                    endpoint URL below to keep the revenue information in sync.
+                  </i18n.Translate>
+                </p>
+              </div>
               <Input<Entity>
                 name="credit_facade_url"
-                label={i18n.str`Account info URL`}
+                label={i18n.str`Endpoint URL`}
                 
help="https://bank.demo.taler.net/accounts/_username_/taler-revenue/";
                 expand
                 tooltip={i18n.str`From where the merchant can download 
information about incoming wire transfers to this account`}
@@ -242,22 +250,39 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
                   />
                 </Fragment>
               ) : undefined}
+              <InputToggle<Entity>
+                label={i18n.str`Match`}
+                tooltip={i18n.str`Check where the information match agaisnt 
the server info.`}
+                name="verified"
+                readonly
+                threeState
+                help={
+                  testError !== undefined
+                    ? testError
+                    : state.verified === undefined
+                      ? i18n.str`Not verified`
+                      : state.verified
+                        ? i18n.str`Last test was ok`
+                        : i18n.str`Last test failed`
+                }
+                side={
+                  <button
+                    class="button is-info"
+                    data-tooltip={i18n.str`Compare info from server with 
account form`}
+                    disabled={!state.credit_facade_url}
+                    onClick={() => {
+                      testAccountInfo();
+                    }}
+                  >
+                    <i18n.Translate>Test</i18n.Translate>
+                  </button>
+                }
+              />
             </FormProvider>
 
             <div class="buttons is-right mt-5">
               <button
                 class="button is-info"
-                data-tooltip={i18n.str`Need to complete marked fields`}
-                onClick={() => {
-                  testAccountInfo();
-                }}
-              >
-                <i18n.Translate>Test account info</i18n.Translate>
-              </button>
-
-              <button
-                class="button is-info"
-                data-tooltip={i18n.str`Need to complete marked fields`}
                 onClick={() => {
                   setImporting(true);
                 }}
@@ -286,6 +311,52 @@ export function CreatePage({ onCreate, onBack }: Props): 
VNode {
           <div class="column" />
         </div>
       </section>
-    </div>
+      {!importing ? undefined : (
+        <ImportingAccountModal
+          onCancel={() => {
+            setImporting(false);
+          }}
+          onConfirm={(ac) => {
+            const u = new URL(ac.infoURL);
+            const user = u.username;
+            const pwd = u.password;
+            u.password = "";
+            u.username = "";
+            const credit_facade_url = u.href;
+            setState({
+              payto_uri: ac.accountURI,
+              credit_facade_credentials:
+                user || pwd
+                  ? {
+                      type: "basic",
+                      password: pwd,
+                      username: user,
+                    }
+                  : undefined,
+              credit_facade_url,
+            });
+            setImporting(false);
+          }}
+        />
+      )}
+      {!revenuePayto ? undefined : (
+        <CompareAccountsModal
+          onCancel={() => {
+            setRevenuePayto(undefined);
+          }}
+          onConfirm={(d) => {
+            setState({
+              ...state,
+              payto_uri: d,
+            });
+            setRevenuePayto(undefined);
+          }}
+          formPayto={
+            !state.payto_uri ? undefined : parsePaytoUri(state.payto_uri)
+          }
+          testPayto={revenuePayto}
+        />
+      )}
+    </Fragment>
   );
 }
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 9e0830e6e..2c1a13e27 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
@@ -33,7 +33,7 @@ import {
 } from "@gnu-taler/taler-util";
 import {
   BrowserFetchHttpLib,
-  useTranslationContext
+  useTranslationContext,
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
@@ -86,10 +86,13 @@ export enum TestRevenueErrorType {
 export async function testRevenueAPI(
   revenueAPI: URL,
   creds: FacadeCredentials | undefined,
-): Promise<OperationOk<void> | OperationFail<HttpStatusCode.NotFound>
-| OperationFail<HttpStatusCode.Unauthorized>
-| OperationFail<HttpStatusCode.BadRequest>
-| TalerError> {
+): Promise<
+  | OperationOk<PaytoString>
+  | OperationFail<HttpStatusCode.NotFound>
+  | OperationFail<HttpStatusCode.Unauthorized>
+  | OperationFail<HttpStatusCode.BadRequest>
+  | TalerError
+> {
   const api = new TalerRevenueHttpClient(
     revenueAPI.href,
     new BrowserFetchHttpLib(),
@@ -113,6 +116,12 @@ export async function testRevenueAPI(
       return config;
     }
 
+    const resp = await api.getHistory(auth);
+    if (resp.type === "fail") {
+      return resp;
+    }
+    
+    return opFixedSuccess(resp.body.credit_account as PaytoString);
   } catch (err) {
     if (err instanceof TalerError) {
       return err;
@@ -122,7 +131,6 @@ export async function testRevenueAPI(
       //   detail: err.errorDetail,
       // };
     }
+    throw err
   }
-
-  return opFixedSuccess(undefined);
 }
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 1eda7382d..c0ddab475 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
@@ -75,7 +75,7 @@ export default function ListOtpDevices({
         <NotificationCard notification={{
           type: "WARN",
           message: i18n.str`You need to associate a bank account to receive 
revenue.`,
-          description: i18n.str`Without this the merchant backend will refuse 
to create new orders.`
+          description: i18n.str`Without this the you won't be able to create 
new orders.`
         }} />
       }
       <ListPage
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/Create.stories.tsx
index d9ac4202c..82038c918 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/Create.stories.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/Create.stories.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/CreatePage.tsx
index cec1f3426..cab5ba9cf 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/CreatePage.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/index.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/index.tsx
index deee7d0d5..32c92cab0 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/Table.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/Table.tsx
index b5ca03cfd..1af8a1192 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/Table.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/Table.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/index.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/index.tsx
index 006c2a49c..58d071ffc 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/index.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/list/index.tsx
@@ -1,6 +1,6 @@
 /*
  This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-2024 Taler Systems S.A.
 
  GNU Taler is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
index 6738b1c6c..927e36cf7 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
@@ -73,14 +73,14 @@ export function ListPage({
           >
             <InputSelector
               name="payto_uri"
-              label={i18n.str`Account URI`}
+              label={i18n.str`Bank account`}
               values={accounts}
               fromStr={(d) => {
                 const idx = accounts.indexOf(d)
                 if (idx === -1) return undefined;
                 return d
               }}
-              placeholder={i18n.str`Select one account`}
+              placeholder={i18n.str`All accounts`}
               tooltip={i18n.str`filter by account address`}
             />
           </FormProvider>
diff --git a/packages/merchant-backoffice-ui/src/scss/toggle.scss 
b/packages/merchant-backoffice-ui/src/scss/toggle.scss
index 6c7346eb3..d3ff22997 100644
--- a/packages/merchant-backoffice-ui/src/scss/toggle.scss
+++ b/packages/merchant-backoffice-ui/src/scss/toggle.scss
@@ -49,10 +49,26 @@ $green: #56c080;
   .toggle-checkbox:checked+& {
     background: $green;
 
+    &:before {
+      left: 4px;
+    }
+  }
+  .toggle-checkbox:not(checked)+& {
+    background: $red;
+
     &:before {
       left: 30px;
     }
   }
+  .toggle-checkbox:indeterminate+& {
+    background: rgba(0, 0, 0, 0.301);
+
+    &:before {
+      left: 16px;
+      background: rgba(0, 0, 0, 0.301);
+    }
+  }
+
 }
 
 .toggle-checkbox {

-- 
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]