From a7c8f0f3edd738a59d719105cda3aa8821886b90 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 15 Apr 2024 12:01:16 -0300 Subject: fix #8604 --- .../merchant-backoffice-ui/src/Application.tsx | 383 +++++++++++---------- packages/merchant-backoffice-ui/src/Routing.tsx | 10 +- .../src/components/form/InputCurrency.tsx | 3 +- .../instance/DefaultInstanceFormFields.tsx | 5 +- .../src/components/menu/SideBar.tsx | 21 +- .../src/components/menu/index.tsx | 13 +- .../src/components/product/ProductForm.tsx | 13 +- .../merchant-backoffice-ui/src/context/session.ts | 282 ++++++++------- packages/merchant-backoffice-ui/src/hooks/bank.ts | 9 +- .../merchant-backoffice-ui/src/hooks/instance.ts | 11 +- packages/merchant-backoffice-ui/src/hooks/order.ts | 7 +- packages/merchant-backoffice-ui/src/hooks/otp.ts | 9 +- .../merchant-backoffice-ui/src/hooks/product.ts | 7 +- .../merchant-backoffice-ui/src/hooks/templates.ts | 7 +- .../merchant-backoffice-ui/src/hooks/transfer.ts | 5 +- .../merchant-backoffice-ui/src/hooks/webhooks.ts | 9 +- .../src/paths/admin/create/CreatePage.tsx | 45 ++- .../src/paths/admin/create/index.tsx | 7 +- .../src/paths/admin/list/TableActive.tsx | 13 +- .../src/paths/admin/list/index.tsx | 5 +- .../src/paths/instance/accounts/create/index.tsx | 9 +- .../src/paths/instance/accounts/list/index.tsx | 5 +- .../src/paths/instance/accounts/update/index.tsx | 5 +- .../src/paths/instance/details/index.tsx | 5 +- .../paths/instance/orders/create/CreatePage.tsx | 7 +- .../src/paths/instance/orders/create/index.tsx | 7 +- .../paths/instance/orders/details/DetailPage.tsx | 8 +- .../src/paths/instance/orders/details/index.tsx | 7 +- .../src/paths/instance/orders/list/Table.tsx | 6 +- .../src/paths/instance/orders/list/index.tsx | 7 +- .../otp_devices/create/CreatedSuccessfully.tsx | 5 +- .../paths/instance/otp_devices/create/index.tsx | 10 +- .../src/paths/instance/otp_devices/list/index.tsx | 5 +- .../paths/instance/otp_devices/update/index.tsx | 5 +- .../src/paths/instance/products/create/index.tsx | 8 +- .../src/paths/instance/products/list/index.tsx | 5 +- .../src/paths/instance/products/update/index.tsx | 5 +- .../paths/instance/templates/create/CreatePage.tsx | 9 +- .../src/paths/instance/templates/create/index.tsx | 4 +- .../src/paths/instance/templates/list/index.tsx | 5 +- .../src/paths/instance/templates/qr/QrPage.tsx | 24 +- .../paths/instance/templates/update/UpdatePage.tsx | 9 +- .../src/paths/instance/templates/update/index.tsx | 5 +- .../src/paths/instance/templates/use/index.tsx | 6 +- .../src/paths/instance/token/DetailPage.tsx | 18 +- .../src/paths/instance/token/index.tsx | 98 ++++-- .../src/paths/instance/transfers/create/index.tsx | 9 +- .../src/paths/instance/update/index.tsx | 7 +- .../src/paths/instance/webhooks/create/index.tsx | 10 +- .../src/paths/instance/webhooks/list/index.tsx | 7 +- .../src/paths/instance/webhooks/update/index.tsx | 5 +- .../src/paths/login/index.tsx | 119 +------ packages/taler-harness/src/index.ts | 96 ++++-- packages/taler-util/src/codec.ts | 34 ++ .../taler-util/src/http-client/authentication.ts | 4 +- packages/taler-util/src/http-client/types.ts | 16 +- packages/taler-util/src/http-client/utils.ts | 2 +- packages/web-util/src/context/activity.ts | 2 +- packages/web-util/src/context/merchant-api.ts | 34 +- 59 files changed, 719 insertions(+), 777 deletions(-) diff --git a/packages/merchant-backoffice-ui/src/Application.tsx b/packages/merchant-backoffice-ui/src/Application.tsx index d5a05e821..097e98567 100644 --- a/packages/merchant-backoffice-ui/src/Application.tsx +++ b/packages/merchant-backoffice-ui/src/Application.tsx @@ -19,14 +19,21 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { CacheEvictor, TalerMerchantApi, TalerMerchantInstanceCacheEviction, TalerMerchantManagementCacheEviction, assertUnreachable, canonicalizeBaseUrl } from "@gnu-taler/taler-util"; +import { + CacheEvictor, + TalerMerchantApi, + TalerMerchantInstanceCacheEviction, + TalerMerchantManagementCacheEviction, + assertUnreachable, + canonicalizeBaseUrl, +} from "@gnu-taler/taler-util"; import { BrowserHashNavigationProvider, ConfigResultFail, MerchantApiProvider, TalerWalletIntegrationBrowserProvider, TranslationProvider, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { VNode, h } from "preact"; import { useEffect, useState } from "preact/hooks"; @@ -35,16 +42,43 @@ import { Routing } from "./Routing.js"; import { Loading } from "./components/exception/loading.js"; import { NotificationCard } from "./components/menu/index.js"; import { SettingsProvider } from "./context/settings.js"; -import { revalidateBankAccountDetails, revalidateInstanceBankAccounts } from "./hooks/bank.js"; -import { revalidateBackendInstances, revalidateInstanceDetails, revalidateManagedInstanceDetails } from "./hooks/instance.js"; -import { revalidateInstanceOtpDevices, revalidateOtpDeviceDetails } from "./hooks/otp.js"; -import { revalidateInstanceProducts, revalidateProductDetails } from "./hooks/product.js"; -import { revalidateInstanceTemplates, revalidateTemplateDetails } from "./hooks/templates.js"; +import { + revalidateBankAccountDetails, + revalidateInstanceBankAccounts, +} from "./hooks/bank.js"; +import { + revalidateBackendInstances, + revalidateInstanceDetails, + revalidateManagedInstanceDetails, +} from "./hooks/instance.js"; +import { + revalidateInstanceOtpDevices, + revalidateOtpDeviceDetails, +} from "./hooks/otp.js"; +import { + revalidateInstanceProducts, + revalidateProductDetails, +} from "./hooks/product.js"; +import { + revalidateInstanceTemplates, + revalidateTemplateDetails, +} from "./hooks/templates.js"; import { revalidateInstanceTransfers } from "./hooks/transfer.js"; -import { revalidateInstanceWebhooks, revalidateWebhookDetails } from "./hooks/webhooks.js"; +import { + revalidateInstanceWebhooks, + revalidateWebhookDetails, +} from "./hooks/webhooks.js"; import { strings } from "./i18n/strings.js"; -import { MerchantUiSettings, buildDefaultBackendBaseURL, fetchSettings } from "./settings.js"; -import { revalidateInstanceOrders, revalidateOrderDetails } from "./hooks/order.js"; +import { + MerchantUiSettings, + buildDefaultBackendBaseURL, + fetchSettings, +} from "./settings.js"; +import { + revalidateInstanceOrders, + revalidateOrderDetails, +} from "./hooks/order.js"; +import { SessionContextProvider } from "./context/session.js"; const WITH_LOCAL_STORAGE_CACHE = false; export function Application(): VNode { @@ -64,42 +98,48 @@ export function Application(): VNode { de: strings["de"].completeness, }} > - - + + - - - - - - + // do not go to loading again if already has data + keepPreviousData: true, + }} + > + + + + + + + @@ -150,187 +190,157 @@ function localStorageProvider(): Map { return map; } -function OnConfigError({ state }: { state: ConfigResultFail | undefined }): VNode { +function OnConfigError({ + state, +}: { + state: ConfigResultFail | undefined; +}): VNode { const { i18n } = useTranslationContext(); if (!state) { - return checking compatibility with server... + return ( + checking compatibility with server... + ); } switch (state.type) { case "error": { - return + return ( + + ); } case "incompatible": { - return + return ( + + ); } - default: assertUnreachable(state) + default: + assertUnreachable(state); } } -const swrCacheEvictor= new class implements CacheEvictor { - async notifySuccess(op: TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction) { - switch(op) { +const swrCacheEvictor = new (class + implements + CacheEvictor< + TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction + > +{ + async notifySuccess( + op: + | TalerMerchantManagementCacheEviction + | TalerMerchantInstanceCacheEviction, + ) { + switch (op) { case TalerMerchantManagementCacheEviction.CREATE_INSTANCE: { - await Promise.all([ - revalidateBackendInstances() - ]) - return + await Promise.all([revalidateBackendInstances()]); + return; } case TalerMerchantManagementCacheEviction.UPDATE_INSTANCE: { - await Promise.all([ - revalidateManagedInstanceDetails() - ]) - return + await Promise.all([revalidateManagedInstanceDetails()]); + return; } - case TalerMerchantManagementCacheEviction.DELETE_INSTANCE:{ - await Promise.all([ - revalidateBackendInstances() - ]) - return + case TalerMerchantManagementCacheEviction.DELETE_INSTANCE: { + await Promise.all([revalidateBackendInstances()]); + return; } - case TalerMerchantInstanceCacheEviction.UPDATE_CURRENT_INSTANCE:{ - await Promise.all([ - revalidateInstanceDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.UPDATE_CURRENT_INSTANCE: { + await Promise.all([revalidateInstanceDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_CURRENT_INSTANCE:{ - await Promise.all([ - revalidateInstanceDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_CURRENT_INSTANCE: { + await Promise.all([revalidateInstanceDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_BANK_ACCOUNT:{ - await Promise.all([ - revalidateInstanceBankAccounts() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_BANK_ACCOUNT: { + await Promise.all([revalidateInstanceBankAccounts()]); + return; } - case TalerMerchantInstanceCacheEviction.UPDATE_BANK_ACCOUNT:{ - await Promise.all([ - revalidateBankAccountDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.UPDATE_BANK_ACCOUNT: { + await Promise.all([revalidateBankAccountDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT:{ - await Promise.all([ - revalidateInstanceBankAccounts() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT: { + await Promise.all([revalidateInstanceBankAccounts()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_PRODUCT:{ - await Promise.all([ - revalidateInstanceProducts() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_PRODUCT: { + await Promise.all([revalidateInstanceProducts()]); + return; } - case TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT:{ - await Promise.all([ - revalidateProductDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT: { + await Promise.all([revalidateProductDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_PRODUCT:{ - await Promise.all([ - revalidateInstanceProducts() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_PRODUCT: { + await Promise.all([revalidateInstanceProducts()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_TRANSFER:{ - await Promise.all([ - revalidateInstanceTransfers() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_TRANSFER: { + await Promise.all([revalidateInstanceTransfers()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_TRANSFER:{ - await Promise.all([ - revalidateInstanceTransfers() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_TRANSFER: { + await Promise.all([revalidateInstanceTransfers()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_DEVICE:{ - await Promise.all([ - revalidateInstanceOtpDevices() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_DEVICE: { + await Promise.all([revalidateInstanceOtpDevices()]); + return; } - case TalerMerchantInstanceCacheEviction.UPDATE_DEVICE:{ - await Promise.all([ - revalidateOtpDeviceDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.UPDATE_DEVICE: { + await Promise.all([revalidateOtpDeviceDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_DEVICE:{ - await Promise.all([ - revalidateInstanceOtpDevices() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_DEVICE: { + await Promise.all([revalidateInstanceOtpDevices()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE:{ - await Promise.all([ - revalidateInstanceTemplates() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE: { + await Promise.all([revalidateInstanceTemplates()]); + return; } - case TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE:{ - await Promise.all([ - revalidateTemplateDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE: { + await Promise.all([revalidateTemplateDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE:{ - await Promise.all([ - revalidateInstanceTemplates() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE: { + await Promise.all([revalidateInstanceTemplates()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK:{ - await Promise.all([ - revalidateInstanceWebhooks() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK: { + await Promise.all([revalidateInstanceWebhooks()]); + return; } - case TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK:{ - await Promise.all([ - revalidateWebhookDetails() - ]) - return + case TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK: { + await Promise.all([revalidateWebhookDetails()]); + return; } - case TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK:{ - await Promise.all([ - revalidateInstanceWebhooks() - ]) - return + case TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK: { + await Promise.all([revalidateInstanceWebhooks()]); + return; } - case TalerMerchantInstanceCacheEviction.CREATE_ORDER:{ - await Promise.all([ - revalidateInstanceOrders() - ]) - return + case TalerMerchantInstanceCacheEviction.CREATE_ORDER: { + await Promise.all([revalidateInstanceOrders()]); + return; } case TalerMerchantInstanceCacheEviction.UPDATE_ORDER: { - await Promise.all([ - revalidateOrderDetails() - ]) - return + await Promise.all([revalidateOrderDetails()]); + return; } case TalerMerchantInstanceCacheEviction.DELETE_ORDER: { - await Promise.all([ - revalidateInstanceOrders() - ]) - return + await Promise.all([revalidateInstanceOrders()]); + return; } case TalerMerchantInstanceCacheEviction.LAST: // case TalerMerchantInstanceCacheEviction.CREATE_TOKENFAMILY:{ @@ -351,5 +361,4 @@ const swrCacheEvictor= new class implements CacheEvictor 1); - const shouldLogin = - state.status === "loggedOut" || state.status === "expired"; + const shouldLogin = state.status === "loggedOut"; // function ServerErrorRedirectTo(to: InstancePaths | AdminPaths) { // return function ServerErrorRedirectToImpl( diff --git a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx index 76d38db84..11396b88e 100644 --- a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx +++ b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx @@ -23,6 +23,7 @@ import { ComponentChildren, h, VNode } from "preact"; import { InputWithAddon } from "./InputWithAddon.js"; import { InputProps } from "./useField.js"; import { AmountString } from "@gnu-taler/taler-util"; +import { useSessionContext } from "../../context/session.js"; export interface Props extends InputProps { expand?: boolean; @@ -43,7 +44,7 @@ export function InputCurrency({ children, side, }: Props): VNode { - const { config } = useMerchantApiContext(); + const { config } = useSessionContext(); return ( name={name} diff --git a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx index 2a24dfbe2..dd41b6fbd 100644 --- a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx +++ b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx @@ -33,6 +33,7 @@ import { InputLocation } from "../form/InputLocation.js"; import { InputSelector } from "../form/InputSelector.js"; import { InputToggle } from "../form/InputToggle.js"; import { InputWithAddon } from "../form/InputWithAddon.js"; +import { useSessionContext } from "../../context/session.js"; export function DefaultInstanceFormFields({ readonlyId, @@ -42,13 +43,13 @@ export function DefaultInstanceFormFields({ showId: boolean; }): VNode { const { i18n } = useTranslationContext(); - const { url: backendUrl } = useMerchantApiContext(); + const { state } = useSessionContext(); return ( {showId && ( name="id" - addonBefore={new URL("instances/", backendUrl.href).href} + addonBefore={new URL("instances/", state.backendUrl.href).href} readonly={readonlyId} label={i18n.str`Identifier`} tooltip={i18n.str`Name of the instance in URLs. The 'default' instance is special in that it is used to administer other instances.`} diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx index 9819c1911..2090704d9 100644 --- a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx +++ b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx @@ -19,15 +19,12 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { - useMerchantApiContext, - useTranslationContext, -} from "@gnu-taler/web-util/browser"; +import { TalerError } from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useSessionContext } from "../../context/session.js"; import { useInstanceKYCDetails } from "../../hooks/instance.js"; import { LangSelector } from "./LangSelector.js"; -import { TalerError } from "@gnu-taler/taler-util"; // const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined; @@ -38,6 +35,7 @@ interface Props { export function Sidebar({ mobile }: Props): VNode { const { i18n } = useTranslationContext(); + const { state, logOut, config } = useSessionContext(); const kycStatus = useInstanceKYCDetails(); const needKYC = @@ -45,11 +43,9 @@ export function Sidebar({ mobile }: Props): VNode { !(kycStatus instanceof TalerError) && kycStatus.type === "ok" && !!kycStatus.body; - const { state, logOut } = useSessionContext(); const isLoggedIn = state.status === "loggedIn"; const hasToken = isLoggedIn && state.token !== undefined; - const { config, url: backendURL } = useMerchantApiContext(); - + return (