diff options
author | Sebastian <sebasjm@gmail.com> | 2023-07-20 17:01:35 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-07-20 17:01:35 -0300 |
commit | 2335c3418cfbcc8a0196f0f161bab31ade99acb2 (patch) | |
tree | 76edf53acc5810ecfe215f6f99f755833a492af8 /packages/aml-backoffice-ui/src/hooks | |
parent | 24d05d87ecfb880b174e90a3d585240d190eaefe (diff) |
make signed request to exchange
Diffstat (limited to 'packages/aml-backoffice-ui/src/hooks')
-rw-r--r-- | packages/aml-backoffice-ui/src/hooks/useBackend.ts | 81 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/hooks/useCases.ts | 94 |
2 files changed, 175 insertions, 0 deletions
diff --git a/packages/aml-backoffice-ui/src/hooks/useBackend.ts b/packages/aml-backoffice-ui/src/hooks/useBackend.ts new file mode 100644 index 000000000..e68efb2e3 --- /dev/null +++ b/packages/aml-backoffice-ui/src/hooks/useBackend.ts @@ -0,0 +1,81 @@ +import { + HttpResponseOk, + RequestOptions, + useApiContext, +} from "@gnu-taler/web-util/browser"; +import { useCallback } from "preact/hooks"; +import { uiSettings } from "../settings.js"; +import { canonicalizeBaseUrl } from "@gnu-taler/taler-util"; +import { useOfficer } from "./useOfficer.js"; +import { buildQuerySignature } from "../account.js"; + +interface useBackendType { + request: <T>( + path: string, + options?: RequestOptions, + ) => Promise<HttpResponseOk<T>>; + fetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>; + paginatedFetcher: <T>( + args: [string, number, number, string], + ) => Promise<HttpResponseOk<T>>; +} +export function usePublicBackend(): useBackendType { + const { request: requestHandler } = useApiContext(); + + const baseUrl = getInitialBackendBaseURL(); + + const request = useCallback( + function requestImpl<T>( + path: string, + options: RequestOptions = {}, + ): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, path, options); + }, + [baseUrl], + ); + + const fetcher = useCallback( + function fetcherImpl<T>(endpoint: string): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, endpoint); + }, + [baseUrl], + ); + const paginatedFetcher = useCallback( + function fetcherImpl<T>([endpoint, page, size, talerAmlOfficerSignature]: [ + string, + number, + number, + string, + ]): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, endpoint, { + params: { page: page || 1, size }, + talerAmlOfficerSignature, + }); + }, + [baseUrl], + ); + return { + request, + fetcher, + paginatedFetcher, + }; +} + +export function getInitialBackendBaseURL(): string { + const overrideUrl = + typeof localStorage !== "undefined" + ? localStorage.getItem("exchange-aml-base-url") + : undefined; + if (!overrideUrl) { + //normal path + if (!uiSettings.backendBaseURL) { + console.error( + "ERROR: backendBaseURL was overridden by a setting file and missing. Setting value to 'window.origin'", + ); + return canonicalizeBaseUrl(window.origin); + } + return canonicalizeBaseUrl(uiSettings.backendBaseURL); + } + // testing/development path + return canonicalizeBaseUrl(overrideUrl); +} diff --git a/packages/aml-backoffice-ui/src/hooks/useCases.ts b/packages/aml-backoffice-ui/src/hooks/useCases.ts new file mode 100644 index 000000000..04b7c383b --- /dev/null +++ b/packages/aml-backoffice-ui/src/hooks/useCases.ts @@ -0,0 +1,94 @@ +import { useEffect, useState } from "preact/hooks"; + +import { AmlExchangeBackend } from "../types.js"; +import { + HttpResponse, + HttpResponseOk, + HttpResponsePaginated, + RequestError, +} from "@gnu-taler/web-util/browser"; +// FIX default import https://github.com/microsoft/TypeScript/issues/49189 +import _useSWR, { SWRHook } from "swr"; +import { usePublicBackend } from "./useBackend.js"; +import { AccountId, buildQuerySignature } from "../account.js"; +import { useOfficer } from "./useOfficer.js"; +const useSWR = _useSWR as unknown as SWRHook; + +const PAGE_SIZE = 10; +const MAX_RESULT_SIZE = PAGE_SIZE * 2 - 1; +/** + * FIXME: mutate result when balance change (transaction ) + * @param account + * @param args + * @returns + */ +export function useCases( + account: AccountId, + state: AmlExchangeBackend.AmlState, + signature: string | undefined, +): HttpResponsePaginated< + AmlExchangeBackend.AmlRecords, + AmlExchangeBackend.AmlError +> { + const { paginatedFetcher } = usePublicBackend(); + + const [page, setPage] = useState(1); + + const { + data: afterData, + error: afterError, + isValidating: loadingAfter, + } = useSWR< + HttpResponseOk<AmlExchangeBackend.AmlRecords>, + RequestError<AmlExchangeBackend.AmlError> + >( + [ + `aml/${account}/decisions/${AmlExchangeBackend.AmlState[state]}`, + page, + PAGE_SIZE, + signature, + ], + paginatedFetcher, + ); + + const [lastAfter, setLastAfter] = useState< + HttpResponse<AmlExchangeBackend.AmlRecords, AmlExchangeBackend.AmlError> + >({ 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 && afterData.data.records.length < PAGE_SIZE; + const isReachingStart = false; + + const pagination = { + isReachingEnd, + isReachingStart, + loadMore: () => { + if (!afterData || isReachingEnd) return; + if (afterData.data && afterData.data.records.length < MAX_RESULT_SIZE) { + setPage(page + 1); + } + }, + loadMorePrev: () => { + null; + }, + }; + + const records = !afterData + ? [] + : ((afterData ?? lastAfter).data ?? { records: [] }).records; + console.log("afterdata", afterData, lastAfter, records) + if (loadingAfter) return { loading: true, data: { records } }; + if (afterData) { + return { ok: true, data: { records }, ...pagination }; + } + return { loading: true }; +} |