diff options
Diffstat (limited to 'packages/bank-ui/src/hooks/account.ts')
-rw-r--r-- | packages/bank-ui/src/hooks/account.ts | 123 |
1 files changed, 66 insertions, 57 deletions
diff --git a/packages/bank-ui/src/hooks/account.ts b/packages/bank-ui/src/hooks/account.ts index 24309183f..43d43a3f2 100644 --- a/packages/bank-ui/src/hooks/account.ts +++ b/packages/bank-ui/src/hooks/account.ts @@ -16,17 +16,18 @@ import { AccessToken, + OperationOk, TalerCoreBankResultByMethod, TalerHttpError, 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 { @@ -44,7 +45,9 @@ export function revalidateAccountDetails() { export function useAccountDetails(account: string) { const { state: credentials } = useSessionState(); - const { lib: { bank: api } } = useBankCoreApiContext(); + const { + lib: { bank: api }, + } = useBankCoreApiContext(); async function fetcher([username, token]: [string, AccessToken]) { return await api.getAccount({ username, token }); @@ -70,7 +73,9 @@ export function revalidateWithdrawalDetails() { } export function useWithdrawalDetails(wid: string) { - const { lib: { bank: api } } = useBankCoreApiContext(); + const { + lib: { bank: api }, + } = useBankCoreApiContext(); const [latestStatus, setLatestStatus] = useState<WithdrawalOperationStatus>(); async function fetcher([wid, old_state]: [ @@ -123,7 +128,9 @@ export function useTransactionDetails(account: string, tid: number) { const { state: credentials } = useSessionState(); const token = credentials.status !== "loggedIn" ? undefined : credentials.token; - const { lib: { bank: api } } = useBankCoreApiContext(); + const { + lib: { bank: api }, + } = useBankCoreApiContext(); async function fetcher([username, token, txid]: [ string, @@ -166,7 +173,9 @@ export function usePublicAccounts( ) { const [offset, setOffset] = useState<number | undefined>(initial); - const { lib: { bank: api } } = useBankCoreApiContext(); + const { + lib: { bank: api }, + } = useBankCoreApiContext(); async function fetcher([account, txid]: [ string | undefined, @@ -175,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", }, @@ -197,36 +206,54 @@ export function usePublicAccounts( keepPreviousData: true, }); - const isLastPage = - data && data.type === "ok" && data.body.public_accounts.length <= PAGE_SIZE; - const isFirstPage = !offset; + if (error) return error; + if (data === undefined) return undefined; + // if (data.type !== "ok") return data; + + //TODO: row_id should not be optional + return buildPaginatedResult( + data.body.public_accounts, + offset, + setOffset, + (d) => d.row_id ?? 0, + ); +} - const result = - data && data.type == "ok" ? structuredClone(data.body.public_accounts) : []; - if (result.length == PAGE_SIZE + 1) { +type PaginatedResult<T> = OperationOk<T> & { + isLastPage: boolean; + isFirstPage: boolean; + loadNext(): void; + loadFirst(): void; +}; +//TODO: consider sending this to web-util +export function buildPaginatedResult<DataType, OffsetId>( + data: DataType[], + offset: OffsetId | undefined, + setOffset: (o: OffsetId | undefined) => void, + getId: (r: DataType) => OffsetId, +): PaginatedResult<DataType[]> { + const isLastPage = data.length < PAGINATED_LIST_REQUEST; + const isFirstPage = offset === undefined; + + const result = structuredClone(data); + if (result.length == PAGINATED_LIST_REQUEST) { + //do now show the last element, used to know if this is the last page result.pop(); } - const pagination = { - result, + return { + type: "ok", + body: result, isLastPage, isFirstPage, loadNext: () => { if (!result.length) return; - setOffset(result[result.length - 1].row_id); + const id = getId(result[result.length - 1]); + setOffset(id); }, loadFirst: () => { - setOffset(0); + setOffset(undefined); }, }; - - // const public_accountslist = data?.type !== "ok" ? [] : data.body.public_accounts; - if (data) { - return { ok: true, data: data.body, ...pagination }; - } - if (error) { - return error; - } - return undefined; } export function revalidateTransactions() { @@ -242,7 +269,9 @@ export function useTransactions(account: string, initial?: number) { credentials.status !== "loggedIn" ? undefined : credentials.token; const [offset, setOffset] = useState<number | undefined>(initial); - const { lib: { bank: api } } = useBankCoreApiContext(); + const { + lib: { bank: api }, + } = useBankCoreApiContext(); async function fetcher([username, token, txid]: [ string, @@ -252,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", }, @@ -271,34 +300,14 @@ export function useTransactions(account: string, initial?: number) { revalidateOnFocus: false, revalidateOnReconnect: false, }); - - const isLastPage = - data && data.type === "ok" && data.body.transactions.length <= PAGE_SIZE; - const isFirstPage = !offset; - - const result = - data && data.type == "ok" ? structuredClone(data.body.transactions) : []; - if (result.length == PAGE_SIZE + 1) { - result.pop(); - } - const pagination = { - result, - isLastPage, - isFirstPage, - loadNext: () => { - if (!result.length) return; - setOffset(result[result.length - 1].row_id); - }, - loadFirst: () => { - setOffset(0); - }, - }; - - if (data) { - return { ok: true, data, ...pagination }; - } - if (error) { - return error; - } - return undefined; + if (error) return error; + if (data === undefined) return undefined; + if (data.type !== "ok") return data; + + return buildPaginatedResult( + data.body.transactions, + offset, + setOffset, + (d) => d.row_id, + ); } |