aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/hooks
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-04-11 23:48:55 -0300
committerSebastian <sebasjm@gmail.com>2024-04-11 23:48:55 -0300
commit9bafc6864b9e0ef237b6975165f23ba31f0d8d88 (patch)
treeb8b12d8b78c874384368adc5a8600363c04b54c5 /packages/aml-backoffice-ui/src/hooks
parent516bda58bb53738fa4d2ae0b10a25e53c138180b (diff)
fix AML spa memo and fix #8615
Diffstat (limited to 'packages/aml-backoffice-ui/src/hooks')
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useCases.ts87
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useOfficer.ts21
2 files changed, 48 insertions, 60 deletions
diff --git a/packages/aml-backoffice-ui/src/hooks/useCases.ts b/packages/aml-backoffice-ui/src/hooks/useCases.ts
index 68deb7db9..2bc9b5f0f 100644
--- a/packages/aml-backoffice-ui/src/hooks/useCases.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useCases.ts
@@ -1,14 +1,18 @@
import { useState } from "preact/hooks";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
-import { AmountString, HttpStatusCode, OfficerAccount, OperationFail, TalerExchangeApi, TalerExchangeResultByMethod, TalerHttpError } from "@gnu-taler/taler-util";
+import { OfficerAccount, OfficerId, OperationOk, TalerExchangeResultByMethod, TalerHttpError, decodeCrock, encodeCrock } from "@gnu-taler/taler-util";
import _useSWR, { SWRHook } from "swr";
import { useExchangeApiContext } from "../context/config.js";
-import { useOfficer } from "./useOfficer.js";
import { AmlExchangeBackend } from "../utils/types.js";
+import { useOfficer } from "./useOfficer.js";
const useSWR = _useSWR as unknown as SWRHook;
-const PAGE_SIZE = 10;
+export const PAGINATED_LIST_SIZE = 10;
+// 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;
+
/**
* FIXME: mutate result when balance change (transaction )
* @param account
@@ -24,69 +28,56 @@ export function useCases(state: AmlExchangeBackend.AmlState) {
async function fetcher([officer, state, offset]: [OfficerAccount, AmlExchangeBackend.AmlState, string | undefined]) {
return await api.getDecisionsByState(officer, state, {
- order: "asc", offset, limit: PAGE_SIZE + 1
+ order: "asc", offset, limit: PAGINATED_LIST_REQUEST
})
}
const { data, error } = useSWR<TalerExchangeResultByMethod<"getDecisionsByState">, TalerHttpError>(
- !session ? undefined : [session, state, offset],
+ !session ? undefined : [session, state, offset, "getDecisionsByState"],
fetcher,
);
- // const [lastAfter, setLastAfter] = useState<
- // HttpResponse<AmlExchangeBackend.AmlRecords, AmlExchangeBackend.AmlError>
- // >({ loading: true });
+ if (error) return error;
+ if (data === undefined) return undefined;
+ if (data.type !== "ok") return data;
- // useEffect(() => {
- // if (afterData) setLastAfter(afterData);
- // }, [afterData]);
+ return buildPaginatedResult(data.body.records, offset, setOffset, (d) => String(d.rowid));
+}
- // if (afterError) {
- // return afterError.cause;
- // }
+type PaginatedResult<T> = OperationOk<T> & {
+ isLastPage: boolean;
+ isFirstPage: boolean;
+ loadNext(): void;
+ loadFirst(): void;
+}
+
+//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[]> {
- // if the query returns less that we ask, then we have reach the end or beginning
- const isLastPage =
- data && data.type === "ok" && data.body.records.length <= PAGE_SIZE;
- const isFirstPage = !offset;
+ const isLastPage = data.length < PAGINATED_LIST_REQUEST;
+ const isFirstPage = offset === undefined;
- const pagination = {
+ const result = structuredClone(data);
+ if (result.length == PAGINATED_LIST_REQUEST) {
+ result.pop();
+ }
+ return {
+ type: "ok",
+ body: result,
isLastPage,
isFirstPage,
- loadMore: () => {
- if (isLastPage || data?.type !== "ok") return;
- const list = data.body.records
- setOffset(String(list[list.length - 1].rowid));
+ loadNext: () => {
+ if (!result.length) return;
+ const id = getId(result[result.length - 1])
+ setOffset(id);
},
- reset: () => {
- setOffset(undefined)
+ loadFirst: () => {
+ setOffset(undefined);
},
};
-
- // const public_accountslist = data?.type !== "ok" ? [] : data.body.public_accounts;
- if (!session) {
- return {
- data: {
- type: "fail",
- case: HttpStatusCode.Unauthorized,
- detail: {}
- } as OperationFail<never>
- }
- }
-
- if (data) {
- if (data.type === "fail") {
- return { data }
- }
- const records = isLastPage ? data.body.records : removeLastElement(data.body.records)
- return { data: { type: "ok" as const, body: { records } }, pagination }
- }
- if (error) {
- return error;
- }
- return undefined;
}
+
function removeLastElement<T>(list: Array<T>): Array<T> {
if (list.length === 0) {
return list;
diff --git a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
index fe989f3eb..1bf2b308b 100644
--- a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
@@ -8,19 +8,17 @@ import {
buildCodecForObject,
codecForAbsoluteTime,
codecForString,
- codecOptional,
createNewOfficerAccount,
decodeCrock,
encodeCrock,
- unlockOfficerAccount,
+ unlockOfficerAccount
} from "@gnu-taler/taler-util";
import {
buildStorageKey,
- useLocalStorage,
- useMemoryStorage,
+ useLocalStorage
} from "@gnu-taler/web-util/browser";
import { useMemo } from "preact/hooks";
-import { useExchangeApiContext, useMaybeExchangeApiContext } from "../context/config.js";
+import { useMaybeExchangeApiContext } from "../context/config.js";
export interface Officer {
account: LockedAccount;
@@ -66,7 +64,6 @@ interface OfficerReady {
const OFFICER_KEY = buildStorageKey("officer", codecForOfficer());
const DEV_ACCOUNT_KEY = buildStorageKey("account-dev", codecForOfficerAccount());
-const ACCOUNT_KEY = "account";
export function useOfficer(): OfficerState {
const exchangeContext = useMaybeExchangeApiContext();
@@ -74,18 +71,18 @@ export function useOfficer(): OfficerState {
const accountStorage = useLocalStorage(DEV_ACCOUNT_KEY);
const account = useMemo(() => {
if (!accountStorage.value) return undefined
+
return {
id: accountStorage.value.id as OfficerId,
signingKey: decodeCrock(accountStorage.value.strKey) as SigningKey
}
- }, [accountStorage.value])
-
-
- // const accountStorage = useMemoryStorage<OfficerAccount>(ACCOUNT_KEY);
- // const account = accountStorage.value;
+ }, [accountStorage.value?.id, accountStorage.value?.strKey])
const officerStorage = useLocalStorage(OFFICER_KEY);
- const officer = officerStorage.value;
+ const officer = useMemo(() => {
+ if (!officerStorage.value) return undefined
+ return officerStorage.value
+ }, [officerStorage.value?.account, officerStorage.value?.when.t_ms])
if (officer === undefined) {
return {