diff options
Diffstat (limited to 'packages/demobank-ui/src/hooks/access.ts')
-rw-r--r-- | packages/demobank-ui/src/hooks/access.ts | 401 |
1 files changed, 105 insertions, 296 deletions
diff --git a/packages/demobank-ui/src/hooks/access.ts b/packages/demobank-ui/src/hooks/access.ts index 154c43ae6..2533d32fe 100644 --- a/packages/demobank-ui/src/hooks/access.ts +++ b/packages/demobank-ui/src/hooks/access.ts @@ -14,168 +14,31 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - HttpResponse, - HttpResponseOk, - HttpResponsePaginated, - RequestError, -} from "@gnu-taler/web-util/browser"; -import { useEffect, useState } from "preact/hooks"; -import { useBackendContext } from "../context/backend.js"; +import { AccessToken, TalerCoreBankResultByMethod, TalerHttpError } from "@gnu-taler/taler-util"; +import { useState } from "preact/hooks"; import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils.js"; -import { - useAuthenticatedBackend, - useMatchMutate, - usePublicBackend, -} from "./backend.js"; +import { useBackendState } from "./backend.js"; // FIX default import https://github.com/microsoft/TypeScript/issues/49189 import _useSWR, { SWRHook } from "swr"; -import { Amounts } from "@gnu-taler/taler-util"; +import { useBankCoreApiContext } from "../context/config.js"; const useSWR = _useSWR as unknown as SWRHook; -export function useAccessAPI(): AccessAPI { - const mutateAll = useMatchMutate(); - const { request } = useAuthenticatedBackend(); - const { state } = useBackendContext(); - if (state.status === "loggedOut") { - throw Error("access-api can't be used when the user is not logged In"); - } - const account = state.username; - - const createWithdrawal = async ( - data: SandboxBackend.CoreBank.BankAccountCreateWithdrawalRequest, - ): Promise< - HttpResponseOk<SandboxBackend.CoreBank.BankAccountCreateWithdrawalResponse> - > => { - const res = - await request<SandboxBackend.CoreBank.BankAccountCreateWithdrawalResponse>( - `accounts/${account}/withdrawals`, - { - method: "POST", - data, - contentType: "json", - }, - ); - return res; - }; - const createTransaction = async ( - data: SandboxBackend.CoreBank.CreateBankAccountTransactionCreate, - ): Promise<HttpResponseOk<void>> => { - const res = await request<void>( - `accounts/${account}/transactions`, - { - method: "POST", - data, - contentType: "json", - }, - ); - await mutateAll(/.*accounts\/.*/); - return res; - }; - const deleteAccount = async (): Promise<HttpResponseOk<void>> => { - const res = await request<void>(`accounts/${account}`, { - method: "DELETE", - contentType: "json", - }); - await mutateAll(/.*accounts\/.*/); - return res; - }; - - return { - createWithdrawal, - createTransaction, - deleteAccount, - }; -} - -export function useAccessAnonAPI(): AccessAnonAPI { - const mutateAll = useMatchMutate(); - const { request } = useAuthenticatedBackend(); - - const abortWithdrawal = async (id: string): Promise<HttpResponseOk<void>> => { - const res = await request<void>(`withdrawals/${id}/abort`, { - method: "POST", - contentType: "json", - }); - await mutateAll(/.*withdrawals\/.*/); - return res; - }; - const confirmWithdrawal = async ( - id: string, - ): Promise<HttpResponseOk<void>> => { - const res = await request<void>(`withdrawals/${id}/confirm`, { - method: "POST", - contentType: "json", - }); - await mutateAll(/.*withdrawals\/.*/); - return res; - }; - - return { - abortWithdrawal, - confirmWithdrawal, - }; -} - -export function useTestingAPI(): TestingAPI { - const mutateAll = useMatchMutate(); - const { request: noAuthRequest } = usePublicBackend(); - const register = async ( - data: SandboxBackend.CoreBank.RegisterAccountRequest, - ): Promise<HttpResponseOk<void>> => { - // FIXME: This API is deprecated. The normal account registration API should be used instead. - const res = await noAuthRequest<void>(`accounts`, { - method: "POST", - data, - contentType: "json", - }); - await mutateAll(/.*accounts\/.*/); - return res; - }; - - return { register }; -} - -export interface TestingAPI { - register: ( - data: SandboxBackend.CoreBank.RegisterAccountRequest, - ) => Promise<HttpResponseOk<void>>; -} - -export interface AccessAPI { - createWithdrawal: ( - data: SandboxBackend.CoreBank.BankAccountCreateWithdrawalRequest, - ) => Promise< - HttpResponseOk<SandboxBackend.CoreBank.BankAccountCreateWithdrawalResponse> - >; - createTransaction: ( - data: SandboxBackend.CoreBank.CreateBankAccountTransactionCreate, - ) => Promise<HttpResponseOk<void>>; - deleteAccount: () => Promise<HttpResponseOk<void>>; -} -export interface AccessAnonAPI { - abortWithdrawal: (wid: string) => Promise<HttpResponseOk<void>>; - confirmWithdrawal: (wid: string) => Promise<HttpResponseOk<void>>; -} export interface InstanceTemplateFilter { //FIXME: add filter to the template list position?: string; } -export function useAccountDetails( - account: string, -): HttpResponse< - SandboxBackend.CoreBank.AccountData, - SandboxBackend.SandboxError -> { - const { fetcher } = useAuthenticatedBackend(); - - const { data, error } = useSWR< - HttpResponseOk<SandboxBackend.CoreBank.AccountData>, - RequestError<SandboxBackend.SandboxError> - >([`accounts/${account}`], fetcher, { +export function useAccountDetails(account: string) { + const { state: credentials } = useBackendState(); + const { api } = useBankCoreApiContext(); + + async function fetcher([username, token]: [string, AccessToken]) { + return await api.getAccount({ username, token }) + } + const token = credentials.status !== "loggedIn" ? undefined : credentials.token + const { data, error } = useSWR<TalerCoreBankResultByMethod<"getAccount">, TalerHttpError>([account, token], fetcher, { refreshInterval: 0, refreshWhenHidden: false, revalidateOnFocus: false, @@ -187,26 +50,22 @@ export function useAccountDetails( keepPreviousData: true, }); - if (data) { - return data; - } - if (error) return error.cause; - return { loading: true }; + if (data) return data + if (error) return error; + return undefined; } // FIXME: should poll -export function useWithdrawalDetails( - wid: string, -): HttpResponse< - SandboxBackend.CoreBank.BankAccountGetWithdrawalResponse, - SandboxBackend.SandboxError -> { - const { fetcher } = useAuthenticatedBackend(); - - const { data, error } = useSWR< - HttpResponseOk<SandboxBackend.CoreBank.BankAccountGetWithdrawalResponse>, - RequestError<SandboxBackend.SandboxError> - >([`withdrawals/${wid}`], fetcher, { +export function useWithdrawalDetails(wid: string) { + // const { state: credentials } = useBackendState(); + const { api } = useBankCoreApiContext(); + + async function fetcher(wid: string) { + return await api.getWithdrawalById(wid) + } + + const { data, error } = useSWR<TalerCoreBankResultByMethod<"getWithdrawalById">, TalerHttpError>( + [wid], fetcher, { refreshInterval: 1000, refreshWhenHidden: false, revalidateOnFocus: false, @@ -218,25 +77,22 @@ export function useWithdrawalDetails( keepPreviousData: true, }); - // if (isValidating) return { loading: true, data: data?.data }; if (data) return data; - if (error) return error.cause; - return { loading: true }; + if (error) return error; + return undefined; } -export function useTransactionDetails( - account: string, - tid: string, -): HttpResponse< - SandboxBackend.CoreBank.BankAccountTransactionInfo, - SandboxBackend.SandboxError -> { - const { paginatedFetcher } = useAuthenticatedBackend(); - - const { data, error } = useSWR< - HttpResponseOk<SandboxBackend.CoreBank.BankAccountTransactionInfo>, - RequestError<SandboxBackend.SandboxError> - >([`accounts/${account}/transactions/${tid}`], paginatedFetcher, { +export function useTransactionDetails(account: string, tid: number) { + const { state: credentials } = useBackendState(); + const token = credentials.status !== "loggedIn" ? undefined : credentials.token + const { api } = useBankCoreApiContext(); + + async function fetcher([username, token, txid]: [string, AccessToken, number]) { + return await api.getTransactionById({ username, token }, txid) + } + + const { data, error } = useSWR<TalerCoreBankResultByMethod<"getTransactionById">, TalerHttpError>( + [account, token, tid], fetcher, { refreshInterval: 0, refreshWhenHidden: false, revalidateOnFocus: false, @@ -248,60 +104,37 @@ export function useTransactionDetails( keepPreviousData: true, }); - // if (isValidating) return { loading: true, data: data?.data }; if (data) return data; - if (error) return error.cause; - return { loading: true }; + if (error) return error; + return undefined; } -interface PaginationFilter { - // page: number; -} +export function usePublicAccounts(initial?: number) { + const [offset, setOffset] = useState<number | undefined>(initial); + const { api } = useBankCoreApiContext(); + + async function fetcher(txid: number | undefined) { + return await api.getPublicAccounts({ + limit: MAX_RESULT_SIZE, + offset: txid ? String(txid) : undefined, + order: "asc" + }) + } + + const { data, error } = useSWR<TalerCoreBankResultByMethod<"getPublicAccounts">, TalerHttpError>([offset], fetcher); -export function usePublicAccounts( - args?: PaginationFilter, -): HttpResponsePaginated< - SandboxBackend.CoreBank.PublicAccountsResponse, - SandboxBackend.SandboxError -> { - const { paginatedFetcher } = usePublicBackend(); - - const [page, setPage] = useState(1); - - const { - data: afterData, - error: afterError, - isValidating: loadingAfter, - } = useSWR< - HttpResponseOk<SandboxBackend.CoreBank.PublicAccountsResponse>, - RequestError<SandboxBackend.SandboxError> - >([`public-accounts`, page, PAGE_SIZE], paginatedFetcher); - - const [lastAfter, setLastAfter] = useState< - HttpResponse< - SandboxBackend.CoreBank.PublicAccountsResponse, - SandboxBackend.SandboxError - > - >({ loading: true }); - - useEffect(() => { - if (afterData) setLastAfter(afterData); - }, [afterData]); - - if (afterError) return afterError.cause; - - // if the query returns less that we ask, then we have reach the end or beginning - const isReachingEnd = - afterData && afterData.data.public_accounts.length < PAGE_SIZE; - const isReachingStart = false; + const isLastPage = + data && data.body.public_accounts.length < PAGE_SIZE; + const isFirstPage = !initial; const pagination = { - isReachingEnd, - isReachingStart, + isLastPage, + isFirstPage, loadMore: () => { - if (!afterData || isReachingEnd) return; - if (afterData.data.public_accounts.length < MAX_RESULT_SIZE) { - setPage(page + 1); + if (isLastPage || data?.type !== "ok") return; + const list = data.body.public_accounts + if (list.length < MAX_RESULT_SIZE) { + // setOffset(list[list.length-1].account_name); } }, loadMorePrev: () => { @@ -309,43 +142,39 @@ export function usePublicAccounts( }, }; - const public_accounts = !afterData - ? [] - : (afterData || lastAfter).data.public_accounts; - if (loadingAfter) return { loading: true, data: { public_accounts } }; - if (afterData) { - return { ok: true, data: { public_accounts }, ...pagination }; + // const public_accountslist = data?.type !== "ok" ? [] : data.body.public_accounts; + if (data) { + return { ok: true, data: data.body, ...pagination } } - return { loading: true }; + if (error) { + return error; + } + return undefined; } /** - * FIXME: mutate result when balance change (transaction ) + * @param account * @param args * @returns */ -export function useTransactions( - account: string, - args?: PaginationFilter, -): HttpResponsePaginated< - SandboxBackend.CoreBank.BankAccountTransactionsResponse, - SandboxBackend.SandboxError -> { - const { paginatedFetcher } = useAuthenticatedBackend(); - - const [start, setStart] = useState<string>(); - - const { - data: afterData, - error: afterError, - isValidating: loadingAfter, - } = useSWR< - HttpResponseOk<SandboxBackend.CoreBank.BankAccountTransactionsResponse>, - RequestError<SandboxBackend.SandboxError> - >( - [`accounts/${account}/transactions`, start, PAGE_SIZE], - paginatedFetcher, { +export function useTransactions(account: string, initial?: number) { + const { state: credentials } = useBackendState(); + const token = credentials.status !== "loggedIn" ? undefined : credentials.token + + const [offset, setOffset] = useState<number | undefined>(initial); + const { api } = useBankCoreApiContext(); + + async function fetcher([username, token, txid]: [string, AccessToken, number | undefined]) { + return await api.getTransactions({ username, token }, { + limit: MAX_RESULT_SIZE, + offset: txid ? String(txid) : undefined, + order: "dec" + }) + } + + const { data, error } = useSWR<TalerCoreBankResultByMethod<"getTransactions">, TalerHttpError>( + [account, token, offset], fetcher, { refreshInterval: 0, refreshWhenHidden: false, refreshWhenOffline: false, @@ -356,50 +185,30 @@ export function useTransactions( } ); - const [lastAfter, setLastAfter] = useState< - HttpResponse< - SandboxBackend.CoreBank.BankAccountTransactionsResponse, - SandboxBackend.SandboxError - > - >({ loading: true }); - - useEffect(() => { - if (afterData) setLastAfter(afterData); - }, [afterData]); - - if (afterError) { - return afterError.cause; - } - - // if the query returns less that we ask, then we have reach the end or beginning - const isReachingEnd = - afterData && afterData.data.transactions.length < PAGE_SIZE; - const isReachingStart = start == undefined; + const isLastPage = + data && data.type === "ok" && data.body.transactions.length < PAGE_SIZE; + const isFirstPage = true; const pagination = { - isReachingEnd, - isReachingStart, + isLastPage, + isFirstPage, loadMore: () => { - if (!afterData || isReachingEnd) return; - // if (afterData.data.transactions.length < MAX_RESULT_SIZE) { - const l = afterData.data.transactions[afterData.data.transactions.length-1] - setStart(String(l.row_id)); - // } + if (isLastPage || data?.type !== "ok") return; + const list = data.body.transactions + if (list.length < MAX_RESULT_SIZE) { + setOffset(list[list.length - 1].row_id); + } }, loadMorePrev: () => { - if (!afterData || isReachingStart) return; - // if (afterData.data.transactions.length < MAX_RESULT_SIZE) { - setStart(undefined) - // } + null; }, }; - const transactions = !afterData - ? [] - : (afterData || lastAfter).data.transactions; - if (loadingAfter) return { loading: true, data: { transactions } }; - if (afterData) { - return { ok: true, data: { transactions }, ...pagination }; + if (data) { + return { ok: true, data, ...pagination } + } + if (error) { + return error; } - return { loading: true }; + return undefined; } |