summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-04-05 10:30:19 -0300
committerSebastian <sebasjm@gmail.com>2024-04-05 10:30:34 -0300
commit70151490bd79d38f8064b720fc124d1774a18235 (patch)
tree3d3238bf02743d38b243581457130804939f0473 /packages
parent493fe38a603cc7a54a9d36b235da7abad3a10a92 (diff)
downloadwallet-core-70151490bd79d38f8064b720fc124d1774a18235.tar.gz
wallet-core-70151490bd79d38f8064b720fc124d1774a18235.tar.bz2
wallet-core-70151490bd79d38f8064b720fc124d1774a18235.zip
fix listing, add cache invalidation, fix codec for accounts
Diffstat (limited to 'packages')
-rw-r--r--packages/bank-ui/src/hooks/account.ts11
-rw-r--r--packages/bank-ui/src/hooks/regional.ts8
-rw-r--r--packages/bank-ui/src/utils.ts6
-rw-r--r--packages/merchant-backoffice-ui/src/Application.tsx192
-rw-r--r--packages/merchant-backoffice-ui/src/Routing.tsx59
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/bank.ts3
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/order.test.ts2
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/order.ts11
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/otp.ts4
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/product.ts4
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/templates.ts6
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/transfer.test.ts4
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/transfer.ts4
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/webhooks.ts8
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx12
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx18
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx6
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx18
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx4
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx20
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx18
-rw-r--r--packages/merchant-backoffice-ui/src/utils/constants.ts9
-rwxr-xr-xpackages/taler-harness/bin/create_merchantAndBankAccount_pdf.sh13
-rw-r--r--packages/taler-util/src/http-client/merchant.ts173
-rw-r--r--packages/taler-util/src/http-client/types.ts4
-rw-r--r--packages/taler-util/src/time.ts6
-rw-r--r--packages/web-util/src/context/merchant-api.ts5
32 files changed, 417 insertions, 221 deletions
diff --git a/packages/bank-ui/src/hooks/account.ts b/packages/bank-ui/src/hooks/account.ts
index e1cd423de..43d43a3f2 100644
--- a/packages/bank-ui/src/hooks/account.ts
+++ b/packages/bank-ui/src/hooks/account.ts
@@ -22,12 +22,12 @@ import {
WithdrawalOperationStatus,
} from "@gnu-taler/taler-util";
import { useEffect, useState } from "preact/hooks";
-import { PAGE_SIZE } from "../utils.js";
import { useSessionState } from "./session.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import _useSWR, { SWRHook, mutate } from "swr";
import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
+import { PAGINATED_LIST_REQUEST } from "../utils.js";
const useSWR = _useSWR as unknown as SWRHook;
export interface InstanceTemplateFilter {
@@ -184,7 +184,7 @@ export function usePublicAccounts(
return await api.getPublicAccounts(
{ account },
{
- limit: PAGE_SIZE,
+ limit: PAGINATED_LIST_REQUEST,
offset: txid ? String(txid) : undefined,
order: "asc",
},
@@ -232,11 +232,12 @@ export function buildPaginatedResult<DataType, OffsetId>(
setOffset: (o: OffsetId | undefined) => void,
getId: (r: DataType) => OffsetId,
): PaginatedResult<DataType[]> {
- const isLastPage = data.length <= PAGE_SIZE;
+ const isLastPage = data.length < PAGINATED_LIST_REQUEST;
const isFirstPage = offset === undefined;
const result = structuredClone(data);
- if (result.length == PAGE_SIZE + 1) {
+ if (result.length == PAGINATED_LIST_REQUEST) {
+ //do now show the last element, used to know if this is the last page
result.pop();
}
return {
@@ -280,7 +281,7 @@ export function useTransactions(account: string, initial?: number) {
return await api.getTransactions(
{ username, token },
{
- limit: PAGE_SIZE + 1,
+ limit: PAGINATED_LIST_REQUEST,
offset: txid ? String(txid) : undefined,
order: "dec",
},
diff --git a/packages/bank-ui/src/hooks/regional.ts b/packages/bank-ui/src/hooks/regional.ts
index 909bcfcec..e0c861a0f 100644
--- a/packages/bank-ui/src/hooks/regional.ts
+++ b/packages/bank-ui/src/hooks/regional.ts
@@ -14,7 +14,6 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { PAGE_SIZE } from "../utils.js";
import { useSessionState } from "./session.js";
import {
@@ -36,6 +35,7 @@ import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
import _useSWR, { SWRHook, mutate } from "swr";
import { buildPaginatedResult } from "./account.js";
+import { PAGINATED_LIST_REQUEST } from "../utils.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
const useSWR = _useSWR as unknown as SWRHook;
@@ -232,14 +232,14 @@ export function useBusinessAccounts() {
const [offset, setOffset] = useState<number | undefined>();
- function fetcher([token, offset]: [AccessToken, number]) {
+ function fetcher([token, aid]: [AccessToken, number]) {
// FIXME: add account name filter
return api.getAccounts(
token,
{},
{
- limit: PAGE_SIZE + 1,
- offset: String(offset),
+ limit: PAGINATED_LIST_REQUEST,
+ offset: aid ? String(aid) : undefined,
order: "asc",
},
);
diff --git a/packages/bank-ui/src/utils.ts b/packages/bank-ui/src/utils.ts
index 305f13803..2cc502416 100644
--- a/packages/bank-ui/src/utils.ts
+++ b/packages/bank-ui/src/utils.ts
@@ -120,7 +120,11 @@ export enum CashoutStatus {
PENDING = "pending",
}
-export const PAGE_SIZE = 5;
+
+export const PAGINATED_LIST_SIZE = 5;
+// when doing paginated request, ask for one more
+// and use it to know if there are more to request
+export const PAGINATED_LIST_REQUEST = PAGINATED_LIST_SIZE + 1;
type Translator = ReturnType<typeof useTranslationContext>["i18n"];
diff --git a/packages/merchant-backoffice-ui/src/Application.tsx b/packages/merchant-backoffice-ui/src/Application.tsx
index 497f49c0e..1a4bd6708 100644
--- a/packages/merchant-backoffice-ui/src/Application.tsx
+++ b/packages/merchant-backoffice-ui/src/Application.tsx
@@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { TalerMerchantApi, assertUnreachable, canonicalizeBaseUrl } from "@gnu-taler/taler-util";
+import { CacheEvictor, TalerMerchantApi, TalerMerchantInstanceCacheEviction, TalerMerchantManagementCacheEviction, assertUnreachable, canonicalizeBaseUrl } from "@gnu-taler/taler-util";
import {
BrowserHashNavigationProvider,
ConfigResultFail,
@@ -33,13 +33,20 @@ import { useEffect, useState } from "preact/hooks";
import { SWRConfig } from "swr";
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 { revalidateInstanceTransfers } from "./hooks/transfer.js";
+import { revalidateInstanceWebhooks, revalidateWebhookDetails } from "./hooks/webhooks.js";
import { strings } from "./i18n/strings.js";
import { MerchantUiSettings, buildDefaultBackendBaseURL, fetchSettings } from "./settings.js";
-import { NotificationCard } from "./components/menu/index.js";
+import { revalidateInstanceOrders, revalidateOrderDetails } from "./hooks/order.js";
const WITH_LOCAL_STORAGE_CACHE = false;
-
export function Application(): VNode {
const [settings, setSettings] = useState<MerchantUiSettings>();
useEffect(() => {
@@ -57,7 +64,9 @@ export function Application(): VNode {
de: strings["de"].completeness,
}}
>
- <MerchantApiProvider baseUrl={new URL("/", baseUrl)} frameOnError={OnConfigError}>
+ <MerchantApiProvider baseUrl={new URL("/", baseUrl)} frameOnError={OnConfigError} evictors={{
+ management: swrCacheEvictor
+ }}>
<SWRConfig
value={{
provider: WITH_LOCAL_STORAGE_CACHE
@@ -169,3 +178,178 @@ function OnConfigError({ state }: { state: ConfigResultFail<TalerMerchantApi.Ver
default: assertUnreachable(state)
}
}
+
+const swrCacheEvictor= new class implements CacheEvictor<TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction> {
+ async notifySuccess(op: TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction) {
+ switch(op) {
+ case TalerMerchantManagementCacheEviction.CREATE_INSTANCE: {
+ await Promise.all([
+ revalidateBackendInstances()
+ ])
+ return
+ }
+ case TalerMerchantManagementCacheEviction.UPDATE_INSTANCE: {
+ await Promise.all([
+ revalidateManagedInstanceDetails()
+ ])
+ return
+ }
+ case TalerMerchantManagementCacheEviction.DELETE_INSTANCE:{
+ await Promise.all([
+ revalidateBackendInstances()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_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.UPDATE_BANK_ACCOUNT:{
+ await Promise.all([
+ revalidateBankAccountDetails()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT:{
+ await Promise.all([
+ revalidateInstanceBankAccounts()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_PRODUCT:{
+ await Promise.all([
+ revalidateInstanceProducts()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT:{
+ await Promise.all([
+ revalidateProductDetails()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_PRODUCT:{
+ await Promise.all([
+ revalidateInstanceProducts()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_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.UPDATE_DEVICE:{
+ await Promise.all([
+ revalidateOtpDeviceDetails()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_DEVICE:{
+ await Promise.all([
+ revalidateInstanceOtpDevices()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE:{
+ await Promise.all([
+ revalidateInstanceTemplates()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE:{
+ await Promise.all([
+ revalidateTemplateDetails()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE:{
+ await Promise.all([
+ revalidateInstanceTemplates()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK:{
+ await Promise.all([
+ revalidateInstanceWebhooks()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK:{
+ await Promise.all([
+ revalidateWebhookDetails()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK:{
+ await Promise.all([
+ revalidateInstanceWebhooks()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_ORDER:{
+ await Promise.all([
+ revalidateInstanceOrders()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_ORDER: {
+ await Promise.all([
+ revalidateOrderDetails()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_ORDER: {
+ await Promise.all([
+ revalidateInstanceOrders()
+ ])
+ return
+ }
+ case TalerMerchantInstanceCacheEviction.LAST:
+ // case TalerMerchantInstanceCacheEviction.CREATE_TOKENFAMILY:{
+ // await Promise.all([
+ // reva
+ // ])
+ // return
+ // }
+ // case TalerMerchantInstanceCacheEviction.UPDATE_TOKENFAMILY:{
+ // await Promise.all([
+ // ])
+ // return
+ // }
+ // case TalerMerchantInstanceCacheEviction.DELETE_TOKENFAMILY:{
+ // await Promise.all([
+ // ])
+ // return
+ // }
+ }
+ }
+
+}
diff --git a/packages/merchant-backoffice-ui/src/Routing.tsx b/packages/merchant-backoffice-ui/src/Routing.tsx
index 874c2b0f2..7398aaeec 100644
--- a/packages/merchant-backoffice-ui/src/Routing.tsx
+++ b/packages/merchant-backoffice-ui/src/Routing.tsx
@@ -312,8 +312,6 @@ export function Routing(_p: Props): VNode {
onUpdate={(id: string): void => {
route(`/instance/${id}/update`);
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
/>
)}
{state.isAdmin && (
@@ -322,7 +320,7 @@ export function Routing(_p: Props): VNode {
component={InstanceCreatePage}
onBack={() => route(AdminPaths.list_instances)}
onConfirm={() => {
- route(InstancePaths.order_list);
+ route(AdminPaths.list_instances);
}}
/>
)}
@@ -334,9 +332,6 @@ export function Routing(_p: Props): VNode {
onConfirm={() => {
route(AdminPaths.list_instances);
}}
- // onUpdateError={ServerErrorRedirectTo(AdminPaths.list_instances)}
- // onLoadError={ServerErrorRedirectTo(AdminPaths.list_instances)}
- // onNotFound={NotFoundPage}
/>
)}
{/**
@@ -351,10 +346,6 @@ export function Routing(_p: Props): VNode {
onConfirm={() => {
route(`/`);
}}
- // onUpdateError={noop}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
/>
{/**
* Update instance page
@@ -368,9 +359,6 @@ export function Routing(_p: Props): VNode {
onCancel={() => {
route(InstancePaths.order_list);
}}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
/>
{/**
* Inventory pages
@@ -384,9 +372,6 @@ export function Routing(_p: Props): VNode {
onSelect={(id: string) => {
route(InstancePaths.inventory_update.replace(":pid", id));
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route
path={InstancePaths.inventory_update}
@@ -397,9 +382,6 @@ export function Routing(_p: Props): VNode {
onBack={() => {
route(InstancePaths.inventory_list);
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.inventory_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route
path={InstancePaths.inventory_new}
@@ -423,9 +405,6 @@ export function Routing(_p: Props): VNode {
onSelect={(id: string) => {
route(InstancePaths.bank_update.replace(":bid", id));
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route
path={InstancePaths.bank_update}
@@ -436,9 +415,6 @@ export function Routing(_p: Props): VNode {
onBack={() => {
route(InstancePaths.bank_list);
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.inventory_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route
path={InstancePaths.bank_new}
@@ -462,16 +438,10 @@ export function Routing(_p: Props): VNode {
onSelect={(id: string) => {
route(InstancePaths.order_details.replace(":oid", id));
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route
path={InstancePaths.order_details}
component={OrderDetailsPage}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.order_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => {
route(InstancePaths.order_list);
}}
@@ -492,9 +462,6 @@ export function Routing(_p: Props): VNode {
<Route
path={InstancePaths.transfers_list}
component={TransferListPage}
- // onUnauthorized={LoginPageAccessDenied}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
onCreate={() => {
route(InstancePaths.transfers_new);
}}
@@ -515,9 +482,6 @@ export function Routing(_p: Props): VNode {
<Route
path={InstancePaths.webhooks_list}
component={WebhookListPage}
- // onUnauthorized={LoginPageAccessDenied}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
onCreate={() => {
route(InstancePaths.webhooks_new);
}}
@@ -531,9 +495,6 @@ export function Routing(_p: Props): VNode {
onConfirm={() => {
route(InstancePaths.webhooks_list);
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.webhooks_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => {
route(InstancePaths.webhooks_list);
}}
@@ -554,9 +515,6 @@ export function Routing(_p: Props): VNode {
<Route
path={InstancePaths.otp_devices_list}
component={ValidatorListPage}
- // onUnauthorized={LoginPageAccessDenied}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
onCreate={() => {
route(InstancePaths.otp_devices_new);
}}
@@ -570,9 +528,6 @@ export function Routing(_p: Props): VNode {
onConfirm={() => {
route(InstancePaths.otp_devices_list);
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.otp_devices_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => {
route(InstancePaths.otp_devices_list);
}}
@@ -593,9 +548,6 @@ export function Routing(_p: Props): VNode {
<Route
path={InstancePaths.templates_list}
component={TemplateListPage}
- // onUnauthorized={LoginPageAccessDenied}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.settings)}
onCreate={() => {
route(InstancePaths.templates_new);
}}
@@ -615,9 +567,6 @@ export function Routing(_p: Props): VNode {
onConfirm={() => {
route(InstancePaths.templates_list);
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.templates_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => {
route(InstancePaths.templates_list);
}}
@@ -638,9 +587,6 @@ export function Routing(_p: Props): VNode {
onOrderCreated={(id: string) => {
route(InstancePaths.order_details.replace(":oid", id));
}}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.templates_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => {
route(InstancePaths.templates_list);
}}
@@ -648,9 +594,6 @@ export function Routing(_p: Props): VNode {
<Route
path={InstancePaths.templates_qr}
component={TemplateQrPage}
- // onUnauthorized={LoginPageAccessDenied}
- // onLoadError={ServerErrorRedirectTo(InstancePaths.templates_list)}
- // onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => {
route(InstancePaths.templates_list);
}}
diff --git a/packages/merchant-backoffice-ui/src/hooks/bank.ts b/packages/merchant-backoffice-ui/src/hooks/bank.ts
index 513314f17..6555ec085 100644
--- a/packages/merchant-backoffice-ui/src/hooks/bank.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/bank.ts
@@ -22,6 +22,7 @@ import { useState } from "preact/hooks";
import { AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util";
import _useSWR, { SWRHook, mutate } from "swr";
import { useSessionContext } from "../context/session.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
import { buildPaginatedResult } from "./webhooks.js";
const useSWR = _useSWR as unknown as SWRHook;
@@ -43,7 +44,7 @@ export function useInstanceBankAccounts() {
async function fetcher([token, bid]: [AccessToken, string]) {
return await instance.listBankAccounts(token, {
- limit: 5,
+ limit: PAGINATED_LIST_REQUEST,
offset: bid,
order: "dec",
});
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.test.ts b/packages/merchant-backoffice-ui/src/hooks/order.test.ts
index 1aa2fcf0a..9c1eaccbb 100644
--- a/packages/merchant-backoffice-ui/src/hooks/order.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/order.test.ts
@@ -464,7 +464,7 @@ describe("order listing pagination", () => {
expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" });
});
- it("should load more if result brings more that PAGE_SIZE", async () => {
+ it("should load more if result brings more that PAGINATED_LIST_REQUEST", async () => {
const env = new ApiMockEnvironment();
const ordersFrom0to20 = Array.from({ length: 20 }).map((e, i) => ({
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.ts b/packages/merchant-backoffice-ui/src/hooks/order.ts
index b1805f6e3..79f970ec2 100644
--- a/packages/merchant-backoffice-ui/src/hooks/order.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/order.ts
@@ -16,7 +16,7 @@
import {
useMerchantApiContext
} from "@gnu-taler/web-util/browser";
-import { PAGE_SIZE } from "../utils/constants.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import { AbsoluteTime, AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util";
@@ -60,6 +60,13 @@ export interface InstanceOrderFilter {
position?: string;
}
+export function revalidateInstanceOrders() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listOrders",
+ undefined,
+ { revalidate: true },
+ );
+}
export function useInstanceOrders(
args?: InstanceOrderFilter,
updatePosition: (d: string | undefined) => void = () => { },
@@ -71,7 +78,7 @@ export function useInstanceOrders(
async function fetcher([token, o, p, r, w, d]: [AccessToken, string, boolean, boolean, boolean, AbsoluteTime]) {
return await instance.listOrders(token, {
- limit: PAGE_SIZE,
+ limit: PAGINATED_LIST_REQUEST,
offset: o,
order: "dec",
paid: p,
diff --git a/packages/merchant-backoffice-ui/src/hooks/otp.ts b/packages/merchant-backoffice-ui/src/hooks/otp.ts
index 898a27a69..9820c5f11 100644
--- a/packages/merchant-backoffice-ui/src/hooks/otp.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/otp.ts
@@ -17,7 +17,7 @@ import {
useMerchantApiContext
} from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
-import { PAGE_SIZE } from "../utils/constants.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import { AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util";
@@ -41,7 +41,7 @@ export function useInstanceOtpDevices() {
async function fetcher([token, bid]: [AccessToken, string]) {
return await instance.listOtpDevices(token, {
- limit: PAGE_SIZE,
+ limit: PAGINATED_LIST_REQUEST,
offset: bid,
order: "dec",
});
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts b/packages/merchant-backoffice-ui/src/hooks/product.ts
index cfbd4a653..7f3504c64 100644
--- a/packages/merchant-backoffice-ui/src/hooks/product.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/product.ts
@@ -22,7 +22,7 @@ import { AccessToken, OperationOk, TalerHttpError, TalerMerchantApi, TalerMercha
import { useState } from "preact/hooks";
import _useSWR, { SWRHook, mutate } from "swr";
import { useSessionContext } from "../context/session.js";
-import { PAGE_SIZE } from "../utils/constants.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
import { buildPaginatedResult } from "./webhooks.js";
const useSWR = _useSWR as unknown as SWRHook;
@@ -46,7 +46,7 @@ export function useInstanceProducts() {
async function fetcher([token, bid]: [AccessToken, number]) {
const list = await instance.listProducts(token, {
- limit: PAGE_SIZE,
+ limit: PAGINATED_LIST_REQUEST,
offset: bid === undefined ? undefined: String(bid),
order: "dec",
});
diff --git a/packages/merchant-backoffice-ui/src/hooks/templates.ts b/packages/merchant-backoffice-ui/src/hooks/templates.ts
index dbea93fdf..e0065e284 100644
--- a/packages/merchant-backoffice-ui/src/hooks/templates.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/templates.ts
@@ -17,7 +17,7 @@ import {
useMerchantApiContext
} from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
-import { PAGE_SIZE } from "../utils/constants.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import { AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util";
@@ -45,7 +45,7 @@ export function useInstanceTemplates() {
async function fetcher([token, bid]: [AccessToken, string]) {
return await instance.listTemplates(token, {
- limit: PAGE_SIZE,
+ limit: PAGINATED_LIST_REQUEST,
offset: bid,
order: "dec",
});
@@ -64,7 +64,7 @@ export function useInstanceTemplates() {
}
-export function revalidateProductDetails() {
+export function revalidateTemplateDetails() {
return mutate(
(key) => Array.isArray(key) && key[key.length - 1] === "getTemplateDetails",
undefined,
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts b/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
index d0865d236..7daaf5049 100644
--- a/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts
@@ -163,7 +163,7 @@ describe("transfer listing pagination", () => {
expect(hookBehavior).deep.eq({ result: "ok" });
});
- it("should load more if result brings more that PAGE_SIZE", async () => {
+ it("should load more if result brings more that PAGINATED_LIST_REQUEST", async () => {
const env = new ApiMockEnvironment();
const transfersFrom0to20 = Array.from({ length: 20 }).map((e, i) => ({
@@ -172,7 +172,7 @@ describe("transfer listing pagination", () => {
const transfersFrom20to40 = Array.from({ length: 20 }).map((e, i) => ({
wtid: String(i + 20),
}));
- const transfersFrom20to0 = [...transfersFrom0to20].reverse();
+ // const transfersFrom20to0 = [...transfersFrom0to20].reverse();
env.addRequestExpectation(API_LIST_TRANSFERS, {
qparam: { limit: 20, payto_uri: "payto://", offset: "1" },
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.ts b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
index 44068f52d..6c2fc1d75 100644
--- a/packages/merchant-backoffice-ui/src/hooks/transfer.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
@@ -16,7 +16,7 @@
import {
useMerchantApiContext
} from "@gnu-taler/web-util/browser";
-import { PAGE_SIZE } from "../utils/constants.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import { AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util";
@@ -51,7 +51,7 @@ export function useInstanceTransfers(
return await instance.listWireTransfers(token, {
paytoURI: p,
verified: v,
- limit: PAGE_SIZE,
+ limit: PAGINATED_LIST_REQUEST,
offset: o,
order: "dec",
});
diff --git a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
index c69db6e80..c5d0382e2 100644
--- a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts
@@ -17,7 +17,7 @@ import {
useMerchantApiContext
} from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
-import { PAGE_SIZE } from "../utils/constants.js";
+import { PAGINATED_LIST_REQUEST } from "../utils/constants.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import { AccessToken, OperationOk, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util";
@@ -43,7 +43,7 @@ export function useInstanceWebhooks() {
async function fetcher([token, bid]: [AccessToken, string]) {
return await instance.listWebhooks(token, {
- limit: 5,
+ limit: PAGINATED_LIST_REQUEST,
offset: bid,
order: "dec",
});
@@ -71,11 +71,11 @@ type PaginatedResult<T> = OperationOk<T> & {
//TODO: consider sending this to web-util
export function buildPaginatedResult<R, OffId>(data: R[], offset: OffId | undefined, setOffset: (o: OffId | undefined) => void, getId: (r: R) => OffId): PaginatedResult<R[]> {
- const isLastPage = data.length <= PAGE_SIZE;
+ const isLastPage = data.length < PAGINATED_LIST_REQUEST;
const isFirstPage = offset === undefined;
const result = structuredClone(data);
- if (result.length == PAGE_SIZE + 1) {
+ if (result.length == PAGINATED_LIST_REQUEST) {
result.pop();
}
return {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
index c3df81b87..919b608c3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
@@ -146,7 +146,7 @@ function Table({
<div class="table-container">
{hasMoreBefore && (
<button class="button is-fullwidth" onClick={onLoadMoreBefore}>
- <i18n.Translate>load newer orders</i18n.Translate>
+ <i18n.Translate>load first page</i18n.Translate>
</button>
)}
<table class="table is-striped is-hoverable is-fullwidth">
@@ -219,8 +219,10 @@ function Table({
</tbody>
</table>
{hasMoreAfter && (
- <button class="button is-fullwidth" onClick={onLoadMoreAfter}>
- <i18n.Translate>load older orders</i18n.Translate>
+ <button class="button is-fullwidth"
+ data-tooltip={i18n.str`load more orders after the last one`}
+ onClick={onLoadMoreAfter}>
+ <i18n.Translate>load next page</i18n.Translate>
</button>
)}
</div>
@@ -301,7 +303,7 @@ export function RefundModal({
: undefined,
};
const hasErrors = Object.keys(errors).some(
- (k) => (errors as any)[k] !== undefined,
+ (k) => (errors as Record<string, unknown>)[k] !== undefined,
);
const validateAndConfirm = () => {
@@ -380,7 +382,7 @@ export function RefundModal({
<FormProvider<State>
errors={errors}
object={form}
- valueHandler={(d) => setValue(d as any)}
+ valueHandler={(d) => setValue(d)}
>
<InputCurrency<State>
name="refund"
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
index 9022cc35b..8ca0a9c58 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/ListPage.tsx
@@ -52,9 +52,7 @@ export function ListPage({
onDelete={onDelete}
onSelect={onSelect}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreBefore={!onLoadMoreBefore}
onLoadMoreAfter={onLoadMoreAfter}
- hasMoreAfter={!onLoadMoreAfter}
/>
</section>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx
index 7b1ccd4fc..afe3c98e2 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/Table.tsx
@@ -32,8 +32,6 @@ interface Props {
onSelect: (e: Entity) => void;
onCreate: () => void;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -44,8 +42,6 @@ export function CardTable({
onSelect,
onLoadMoreAfter,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: Props): VNode {
const [rowSelection, rowSelectionHandler] = useState<string[]>([]);
@@ -85,8 +81,6 @@ export function CardTable({
rowSelectionHandler={rowSelectionHandler}
onLoadMoreAfter={onLoadMoreAfter}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreAfter={hasMoreAfter}
- hasMoreBefore={hasMoreBefore}
/>
) : (
<EmptyTable />
@@ -104,8 +98,6 @@ interface TableProps {
onSelect: (e: Entity) => void;
rowSelectionHandler: StateUpdater<string[]>;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -115,19 +107,17 @@ function Table({
onDelete,
onSelect,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: TableProps): VNode {
const { i18n } = useTranslationContext();
return (
<div class="table-container">
- {hasMoreBefore && (
+ {onLoadMoreBefore && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more devices before the first one`}
onClick={onLoadMoreBefore}
>
- <i18n.Translate>load newer devices</i18n.Translate>
+ <i18n.Translate>load first page</i18n.Translate>
</button>
)}
<table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -174,13 +164,13 @@ function Table({
})}
</tbody>
</table>
- {hasMoreAfter && (
+ {onLoadMoreAfter && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more devices after the last one`}
onClick={onLoadMoreAfter}
>
- <i18n.Translate>load older devices</i18n.Translate>
+ <i18n.Translate>load next page</i18n.Translate>
</button>
)}
</div>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
index 265146c01..292974e89 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
@@ -341,12 +341,6 @@ function FastProductWithInfiniteStockUpdateForm({
<div class="buttons is-expanded">
- <div class="buttons mt-5">
-
- <button class="button mt-5" onClick={onCancel}>
- <i18n.Translate>Clone</i18n.Translate>
- </button>
- </div>
<div class="buttons is-right mt-5">
<button class="button" onClick={onCancel}>
<i18n.Translate>Cancel</i18n.Translate>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
index 84ff9e0f2..66d8a2f7e 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/ListPage.tsx
@@ -57,9 +57,7 @@ export function ListPage({
onSelect={onSelect}
onNewOrder={onNewOrder}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreBefore={!onLoadMoreBefore}
onLoadMoreAfter={onLoadMoreAfter}
- hasMoreAfter={!onLoadMoreAfter}
/>
);
}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx
index 11caca970..082e622e3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/Table.tsx
@@ -34,8 +34,6 @@ interface Props {
onQR: (e: Entity) => void;
onCreate: () => void;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -48,8 +46,6 @@ export function CardTable({
onNewOrder,
onLoadMoreAfter,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: Props): VNode {
const [rowSelection, rowSelectionHandler] = useState<string[]>([]);
@@ -91,8 +87,6 @@ export function CardTable({
rowSelectionHandler={rowSelectionHandler}
onLoadMoreAfter={onLoadMoreAfter}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreAfter={hasMoreAfter}
- hasMoreBefore={hasMoreBefore}
/>
) : (
<EmptyTable />
@@ -112,8 +106,6 @@ interface TableProps {
onSelect: (e: Entity) => void;
rowSelectionHandler: StateUpdater<string[]>;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -125,19 +117,17 @@ function Table({
onQR,
onSelect,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: TableProps): VNode {
const { i18n } = useTranslationContext();
return (
<div class="table-container">
- {hasMoreBefore && (
+ {onLoadMoreBefore && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more templates before the first one`}
onClick={onLoadMoreBefore}
>
- <i18n.Translate>load newer templates</i18n.Translate>
+ <i18n.Translate>load first page</i18n.Translate>
</button>
)}
<table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -198,13 +188,13 @@ function Table({
})}
</tbody>
</table>
- {hasMoreAfter && (
+ {onLoadMoreAfter && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more templates after the last one`}
onClick={onLoadMoreAfter}
>
- <i18n.Translate>load older templates</i18n.Translate>
+ <i18n.Translate>load next page</i18n.Translate>
</button>
)}
</div>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
index e1493a870..b99549825 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
@@ -62,7 +62,7 @@ type Entity = {
interface Props {
onUpdate: (d: TalerMerchantApi.TemplatePatchDetails) => Promise<void>;
onBack?: () => void;
- template: TalerMerchantApi.TemplateDetails;
+ template: TalerMerchantApi.TemplateDetails & WithId;
}
export function UpdatePage({ template, onUpdate, onBack }: Props): VNode {
@@ -187,7 +187,7 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode {
<div class="level-left">
<div class="level-item">
<span class="is-size-4">
- {new URL(`templates/${template.otp_id}`,backendUrl.href).href}
+ {new URL(`templates/${template.id}`,backendUrl.href).href}
</span>
</div>
</div>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
index 2c0c358e2..9e5099947 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
@@ -79,7 +79,7 @@ export default function UpdateTemplate({
<Fragment>
<NotificationCard notification={notif} />
<UpdatePage
- template={result.body}
+ template={{...result.body, id: tid}}
onBack={onBack}
onUpdate={(data) => {
return lib.instance.updateTemplate(state.token, tid, data)
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 7b54dc5ed..ff2bc6c23 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
@@ -125,9 +125,7 @@ export function ListPage({
onCreate={onCreate}
onDelete={onDelete}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreBefore={!onLoadMoreBefore}
onLoadMoreAfter={onLoadMoreAfter}
- hasMoreAfter={!onLoadMoreAfter}
/>
</section>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
index cf7ebe922..b9235c669 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
@@ -34,8 +34,6 @@ interface Props {
onCreate: () => void;
accounts: string[];
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -45,8 +43,6 @@ export function CardTable({
onDelete,
onLoadMoreAfter,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: Props): VNode {
const [rowSelection, rowSelectionHandler] = useState<string[]>([]);
@@ -85,8 +81,6 @@ export function CardTable({
rowSelectionHandler={rowSelectionHandler}
onLoadMoreAfter={onLoadMoreAfter}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreAfter={hasMoreAfter}
- hasMoreBefore={hasMoreBefore}
/>
) : (
<EmptyTable />
@@ -103,8 +97,6 @@ interface TableProps {
onDelete: (id: Entity) => void;
rowSelectionHandler: StateUpdater<string[]>;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -113,20 +105,18 @@ function Table({
onLoadMoreAfter,
onDelete,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: TableProps): VNode {
const { i18n } = useTranslationContext();
const [settings] = usePreference();
return (
<div class="table-container">
- {hasMoreBefore && (
+ {onLoadMoreBefore && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more transfers before the first one`}
onClick={onLoadMoreBefore}
>
- <i18n.Translate>load newer transfers</i18n.Translate>
+ <i18n.Translate>load first page</i18n.Translate>
</button>
)}
<table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -192,13 +182,13 @@ function Table({
})}
</tbody>
</table>
- {hasMoreAfter && (
+ {onLoadMoreAfter && (
<button
class="button is-fullwidth"
- data-tooltip={i18n.str`load more transfer after the last one`}
+ data-tooltip={i18n.str`load more transfers after the last one`}
onClick={onLoadMoreAfter}
>
- <i18n.Translate>load older transfers</i18n.Translate>
+ <i18n.Translate>load next page</i18n.Translate>
</button>
)}
</div>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx
index 98bd61d8f..3f1feb8e9 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/ListPage.tsx
@@ -55,9 +55,7 @@ export function ListPage({
onDelete={onDelete}
onSelect={onSelect}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreBefore={!onLoadMoreBefore}
onLoadMoreAfter={onLoadMoreAfter}
- hasMoreAfter={!onLoadMoreAfter}
/>
</section>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx
index 2cafc7f9a..919285e78 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/Table.tsx
@@ -32,8 +32,6 @@ interface Props {
onSelect: (e: Entity) => void;
onCreate: () => void;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -44,8 +42,6 @@ export function CardTable({
onSelect,
onLoadMoreAfter,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: Props): VNode {
const [rowSelection, rowSelectionHandler] = useState<string[]>([]);
@@ -85,8 +81,6 @@ export function CardTable({
rowSelectionHandler={rowSelectionHandler}
onLoadMoreAfter={onLoadMoreAfter}
onLoadMoreBefore={onLoadMoreBefore}
- hasMoreAfter={hasMoreAfter}
- hasMoreBefore={hasMoreBefore}
/>
) : (
<EmptyTable />
@@ -104,8 +98,6 @@ interface TableProps {
onSelect: (e: Entity) => void;
rowSelectionHandler: StateUpdater<string[]>;
onLoadMoreBefore?: () => void;
- hasMoreBefore?: boolean;
- hasMoreAfter?: boolean;
onLoadMoreAfter?: () => void;
}
@@ -115,19 +107,17 @@ function Table({
onDelete,
onSelect,
onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore,
}: TableProps): VNode {
const { i18n } = useTranslationContext();
return (
<div class="table-container">
- {hasMoreBefore && (
+ {onLoadMoreBefore && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more webhooks before the first one`}
onClick={onLoadMoreBefore}
>
- <i18n.Translate>load newer webhooks</i18n.Translate>
+ <i18n.Translate>load first page</i18n.Translate>
</button>
)}
<table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -181,13 +171,13 @@ function Table({
})}
</tbody>
</table>
- {hasMoreAfter && (
+ {onLoadMoreAfter && (
<button
class="button is-fullwidth"
data-tooltip={i18n.str`load more webhooks after the last one`}
onClick={onLoadMoreAfter}
>
- <i18n.Translate>load older webhooks</i18n.Translate>
+ <i18n.Translate>load next page</i18n.Translate>
</button>
)}
</div>
diff --git a/packages/merchant-backoffice-ui/src/utils/constants.ts b/packages/merchant-backoffice-ui/src/utils/constants.ts
index 9e7a69ed0..6b4d8eade 100644
--- a/packages/merchant-backoffice-ui/src/utils/constants.ts
+++ b/packages/merchant-backoffice-ui/src/utils/constants.ts
@@ -35,11 +35,10 @@ export const CROCKFORD_BASE32_REGEX =
export const URL_REGEX =
/^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/;
-// how much rows we add every time user hit load more
-export const PAGE_SIZE = 20;
-// how bigger can be the result set
-// after this threshold, load more with move the cursor
-export const MAX_RESULT_SIZE = PAGE_SIZE * 2 - 1;
+export const PAGINATED_LIST_SIZE = 5;
+// when doing paginated request, ask for one more
+// and use it to know if there are more to request
+export const PAGINATED_LIST_REQUEST = PAGINATED_LIST_SIZE + 1;
// how much we will wait for all request, in seconds
export const DEFAULT_REQUEST_TIMEOUT = 10;
diff --git a/packages/taler-harness/bin/create_merchantAndBankAccount_pdf.sh b/packages/taler-harness/bin/create_merchantAndBankAccount_pdf.sh
index cd87c18c9..008791eff 100755
--- a/packages/taler-harness/bin/create_merchantAndBankAccount_pdf.sh
+++ b/packages/taler-harness/bin/create_merchantAndBankAccount_pdf.sh
@@ -1,7 +1,20 @@
#!/bin/bash
+# This file is in the public domain.
+
THIS_FILE=$(realpath "$0")
DIR=$(dirname "$THIS_FILE")
+# this script requires from debian packages
+# * jq
+# * sponge (from moreutils)
+# * wkhtmltopdf
+# * qrencode
+# * sponge:
+#
+# and from python pip packages
+#
+# * chevron
+
DATA=$(mktemp)
set -e
diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts
index cfe3155d1..23d7c76df 100644
--- a/packages/taler-util/src/http-client/merchant.ts
+++ b/packages/taler-util/src/http-client/merchant.ts
@@ -81,9 +81,36 @@ export type TalerMerchantInstanceErrorsByMethod<
export enum TalerMerchantInstanceCacheEviction {
CREATE_ORDER,
+ UPDATE_ORDER,
+ DELETE_ORDER,
+ UPDATE_CURRENT_INSTANCE,
+ DELETE_CURRENT_INSTANCE,
+ CREATE_BANK_ACCOUNT,
+ UPDATE_BANK_ACCOUNT,
+ DELETE_BANK_ACCOUNT,
+ CREATE_PRODUCT,
+ UPDATE_PRODUCT,
+ DELETE_PRODUCT,
+ CREATE_TRANSFER,
+ DELETE_TRANSFER,
+ CREATE_DEVICE,
+ UPDATE_DEVICE,
+ DELETE_DEVICE,
+ CREATE_TEMPLATE,
+ UPDATE_TEMPLATE,
+ DELETE_TEMPLATE,
+ CREATE_WEBHOOK,
+ UPDATE_WEBHOOK,
+ DELETE_WEBHOOK,
+ CREATE_TOKENFAMILY,
+ UPDATE_TOKENFAMILY,
+ DELETE_TOKENFAMILY,
+ LAST,
}
export enum TalerMerchantManagementCacheEviction {
- CREATE_INSTANCE,
+ CREATE_INSTANCE = TalerMerchantInstanceCacheEviction.LAST + 1,
+ UPDATE_INSTANCE,
+ DELETE_INSTANCE,
}
/**
* Protocol version spoken with the core bank.
@@ -150,8 +177,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opSuccessFromHttp(resp, codecForClaimResponse());
+ }
case HttpStatusCode.Conflict:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -173,8 +202,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opSuccessFromHttp(resp, codecForPaymentResponse());
+ }
case HttpStatusCode.BadRequest:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.PaymentRequired:
@@ -274,8 +305,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opSuccessFromHttp(resp, codecForPaidRefundStatusResponse());
+ }
case HttpStatusCode.BadRequest:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Forbidden:
@@ -302,8 +335,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opSuccessFromHttp(resp, codecForAbortResponse());
+ }
case HttpStatusCode.BadRequest:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Forbidden:
@@ -330,8 +365,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opSuccessFromHttp(resp, codecForWalletRefundResponse());
+ }
case HttpStatusCode.BadRequest:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Forbidden:
@@ -399,8 +436,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_CURRENT_INSTANCE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -461,8 +500,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_CURRENT_INSTANCE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -550,8 +591,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_BANK_ACCOUNT);
return opSuccessFromHttp(resp, codecForAccountAddResponse());
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -583,8 +626,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_BANK_ACCOUNT);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -669,8 +714,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -704,8 +751,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_PRODUCT);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound: // FIXME: missing in docs
@@ -738,8 +787,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -831,8 +882,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -860,8 +913,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_PRODUCT);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1049,8 +1104,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.NoContent:
return opEmptySuccess(resp);
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
@@ -1082,8 +1139,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_ORDER);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1120,8 +1179,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
return opSuccessFromHttp(resp, codecForMerchantRefundResponse());
+ }
case HttpStatusCode.Forbidden:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
@@ -1161,8 +1222,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TRANSFER);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1234,8 +1297,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TRANSFER);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1271,8 +1336,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_DEVICE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1302,8 +1369,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_DEVICE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1396,8 +1465,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_DEVICE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1430,8 +1501,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1461,8 +1534,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1544,8 +1619,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1615,8 +1692,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1647,8 +1726,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1731,8 +1812,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1766,8 +1849,10 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TOKENFAMILY);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1797,8 +1882,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.Ok:
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_TOKENFAMILY);
return opSuccessFromHttp(resp, codecForTokenFamilyDetails());
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1883,8 +1970,10 @@ export class TalerMerchantInstanceHttpClient {
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TOKENFAMILY);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -1913,15 +2002,15 @@ export type TalerMerchantManagementErrorsByMethod<
> = FailCasesByMethod<TalerMerchantManagementHttpClient, prop>;
export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttpClient {
- readonly cacheManagementEvictor: CacheEvictor<TalerMerchantManagementCacheEviction>;
+ readonly cacheManagementEvictor: CacheEvictor<TalerMerchantInstanceCacheEviction | TalerMerchantManagementCacheEviction>;
constructor(
readonly baseUrl: string,
httpClient?: HttpRequestLibrary,
- cacheManagementEvictor?: CacheEvictor<TalerMerchantManagementCacheEviction>,
- cacheEvictor?: CacheEvictor<TalerMerchantInstanceCacheEviction>,
+ // cacheManagementEvictor?: CacheEvictor<TalerMerchantManagementCacheEviction>,
+ cacheEvictor?: CacheEvictor<TalerMerchantInstanceCacheEviction | TalerMerchantManagementCacheEviction>,
) {
super(baseUrl, httpClient, cacheEvictor);
- this.cacheManagementEvictor = cacheManagementEvictor ?? nullEvictor;
+ this.cacheManagementEvictor = cacheEvictor ?? nullEvictor;
}
getSubInstanceAPI(instanceId: string) {
@@ -1953,9 +2042,7 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
switch (resp.status) {
case HttpStatusCode.NoContent: {
- this.cacheManagementEvictor.notifySuccess(
- TalerMerchantManagementCacheEviction.CREATE_INSTANCE,
- );
+ this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.CREATE_INSTANCE);
return opEmptySuccess(resp);
}
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
@@ -2022,8 +2109,10 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.UPDATE_INSTANCE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -2112,8 +2201,10 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
headers,
});
switch (resp.status) {
- case HttpStatusCode.NoContent:
+ case HttpStatusCode.NoContent: {
+ this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.DELETE_INSTANCE);
return opEmptySuccess(resp);
+ }
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
index dd2161deb..ea7ba341b 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -777,7 +777,7 @@ export const codecForTransferDetails =
.property("payto_uri", codecForPaytoString())
.property("exchange_url", codecForURL())
.property("transfer_serial_id", codecForNumber())
- .property("execution_time", codecForTimestamp)
+ .property("execution_time", codecOptional(codecForTimestamp))
.property("verified", codecOptional(codecForBoolean()))
.property("confirmed", codecOptional(codecForBoolean()))
.build("TalerMerchantApi.TransferDetails");
@@ -3781,6 +3781,8 @@ export namespace TalerMerchantApi {
// List of accounts that are known for the instance.
accounts: BankAccountSummaryEntry[];
}
+
+ // TODO: missing in docs
export interface BankAccountSummaryEntry {
// payto:// URI of the account.
payto_uri: PaytoString;
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts
index 2e24856ee..95b4911a0 100644
--- a/packages/taler-util/src/time.ts
+++ b/packages/taler-util/src/time.ts
@@ -604,6 +604,9 @@ export function durationAdd(d1: Duration, d2: Duration): Duration {
export const codecForAbsoluteTime: Codec<AbsoluteTime> = {
decode(x: any, c?: Context): AbsoluteTime {
+ if (x === undefined) {
+ throw Error(`got undefined and expected absolute time at ${renderContext(c)}`);
+ }
const t_ms = x.t_ms;
if (typeof t_ms === "string") {
if (t_ms === "never") {
@@ -619,6 +622,9 @@ export const codecForAbsoluteTime: Codec<AbsoluteTime> = {
export const codecForTimestamp: Codec<TalerProtocolTimestamp> = {
decode(x: any, c?: Context): TalerProtocolTimestamp {
// Compatibility, should be removed soon.
+ if (x === undefined) {
+ throw Error(`got undefined and expected timestamp at ${renderContext(c)}`);
+ }
const t_ms = x.t_ms;
if (typeof t_ms === "string") {
if (t_ms === "never") {
diff --git a/packages/web-util/src/context/merchant-api.ts b/packages/web-util/src/context/merchant-api.ts
index 26d9c9e85..604119e84 100644
--- a/packages/web-util/src/context/merchant-api.ts
+++ b/packages/web-util/src/context/merchant-api.ts
@@ -69,10 +69,7 @@ enum VersionHint {
}
type Evictors = {
- management?: CacheEvictor<TalerMerchantManagementCacheEviction>;
- instance?: (
- instanceId: string,
- ) => CacheEvictor<TalerMerchantInstanceCacheEviction>;
+ management?: CacheEvictor<TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction>;
};
type ConfigResult<T> =