aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/hooks
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-05 18:04:22 -0300
committerSebastian <sebasjm@gmail.com>2023-11-05 18:04:22 -0300
commitb58d53dd93bd8e97aecc28fae788c5c7051fd73d (patch)
tree7a402fafa4ae19a64f10eeb3042147f5f4733081 /packages/aml-backoffice-ui/src/hooks
parent31cf3187e447e2c4ec8a473362c5bacc07a874f1 (diff)
sharing components in web-util
Diffstat (limited to 'packages/aml-backoffice-ui/src/hooks')
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useBackend.ts27
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useCaseDetails.ts103
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useCases.ts126
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useOfficer.ts20
4 files changed, 103 insertions, 173 deletions
diff --git a/packages/aml-backoffice-ui/src/hooks/useBackend.ts b/packages/aml-backoffice-ui/src/hooks/useBackend.ts
index b9d66fca6..95277a915 100644
--- a/packages/aml-backoffice-ui/src/hooks/useBackend.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useBackend.ts
@@ -1,3 +1,4 @@
+import { canonicalizeBaseUrl } from "@gnu-taler/taler-util";
import {
HttpResponseOk,
RequestOptions,
@@ -5,9 +6,6 @@ import {
} 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>(
@@ -35,7 +33,7 @@ export function usePublicBackend(): useBackendType {
);
const fetcher = useCallback(
- function fetcherImpl<T>([endpoint, talerAmlOfficerSignature]: [string,string]): Promise<HttpResponseOk<T>> {
+ function fetcherImpl<T>([endpoint, talerAmlOfficerSignature]: [string, string]): Promise<HttpResponseOk<T>> {
return requestHandler<T>(baseUrl, endpoint, {
talerAmlOfficerSignature
});
@@ -66,18 +64,29 @@ export function usePublicBackend(): useBackendType {
export function getInitialBackendBaseURL(): string {
const overrideUrl =
typeof localStorage !== "undefined"
- ? localStorage.getItem("exchange-aml-base-url")
+ ? localStorage.getItem("exchange-base-url")
: undefined;
+
+ let result: string;
+
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);
+ result = window.origin
+ } else {
+ result = uiSettings.backendBaseURL;
}
- return canonicalizeBaseUrl(uiSettings.backendBaseURL);
+ } else {
+ // testing/development path
+ result = overrideUrl
+ }
+ try {
+ return canonicalizeBaseUrl(result)
+ } catch (e) {
+ //fall back
+ return canonicalizeBaseUrl(window.origin)
}
- // testing/development path
- return canonicalizeBaseUrl(overrideUrl);
}
diff --git a/packages/aml-backoffice-ui/src/hooks/useCaseDetails.ts b/packages/aml-backoffice-ui/src/hooks/useCaseDetails.ts
index 980a35f21..9db1e2aec 100644
--- a/packages/aml-backoffice-ui/src/hooks/useCaseDetails.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useCaseDetails.ts
@@ -1,34 +1,29 @@
import {
HttpResponse,
- HttpResponseOk,
- RequestError
+ HttpResponseOk
} from "@gnu-taler/web-util/browser";
import { AmlExchangeBackend } from "../types.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { AmountString, OfficerAccount, PaytoString, TalerExchangeApi, TalerExchangeResultByMethod, TalerHttpError } from "@gnu-taler/taler-util";
import _useSWR, { SWRHook, useSWRConfig } from "swr";
-import { AccountId } from "../account.js";
+import { useExchangeApiContext } from "../context/config.js";
import { usePublicBackend } from "./useBackend.js";
+import { useOfficer } from "./useOfficer.js";
const useSWR = _useSWR as unknown as SWRHook;
-export function useCaseDetails(
- account: AccountId,
- paytoHash: string,
- signature: string | undefined,
-): HttpResponse<
- AmlExchangeBackend.AmlDecisionDetails,
- AmlExchangeBackend.AmlError
-> {
- const { fetcher } = usePublicBackend();
+export function useCaseDetails(paytoHash: string) {
+ const officer = useOfficer();
+ const session = officer.state === "ready" ? officer.account : undefined;
- const { data, error } = useSWR<
- HttpResponseOk<AmlExchangeBackend.AmlDecisionDetails>,
- RequestError<AmlExchangeBackend.AmlError>
->( [
- `aml/${account}/decision/${(paytoHash)}`,
- signature,
-],
-fetcher, {
+ const { api } = useExchangeApiContext();
+
+ async function fetcher([officer, account]: [OfficerAccount, PaytoString]) {
+ return await api.getDecisionDetails(officer, account)
+ }
+
+ const { data, error } = useSWR<TalerExchangeResultByMethod<"getDecisionDetails">, TalerHttpError>(
+ !session ? undefined : [session, paytoHash], fetcher, {
refreshInterval: 0,
refreshWhenHidden: false,
revalidateOnFocus: false,
@@ -41,11 +36,11 @@ fetcher, {
});
if (data) return data;
- if (error) return error.cause;
- return { loading: true };
+ if (error) return error;
+ return undefined;
}
-const example1: AmlExchangeBackend.AmlDecisionDetails = {
+const example1: TalerExchangeApi.AmlDecisionDetails = {
aml_history: [
{
justification: "Lack of documentation",
@@ -54,7 +49,7 @@ const example1: AmlExchangeBackend.AmlDecisionDetails = {
t_s: Date.now() / 1000,
},
new_state: 2,
- new_threshold: "USD:0",
+ new_threshold: "USD:0" as AmountString,
},
{
justification: "Doing a transfer of high amount",
@@ -63,7 +58,7 @@ const example1: AmlExchangeBackend.AmlDecisionDetails = {
t_s: Date.now() / 1000 - 60 * 60 * 24 * 30 * 6,
},
new_state: 1,
- new_threshold: "USD:2000",
+ new_threshold: "USD:2000" as AmountString,
},
{
justification: "Account is known to the system",
@@ -72,7 +67,7 @@ const example1: AmlExchangeBackend.AmlDecisionDetails = {
t_s: Date.now() / 1000 - 60 * 60 * 24 * 30 * 9,
},
new_state: 0,
- new_threshold: "USD:100",
+ new_threshold: "USD:100" as AmountString,
},
],
kyc_attributes: [
@@ -103,60 +98,4 @@ const example1: AmlExchangeBackend.AmlDecisionDetails = {
],
};
-export const exampleResponse: HttpResponse<AmlExchangeBackend.AmlDecisionDetails,AmlExchangeBackend.AmlError> = {
- ok: true,
- data: example1,
-}
-
-
-export function useAmlCasesAPI(): AmlCaseAPI {
- const { request } = usePublicBackend();
- const mutateAll = useMatchMutate();
-
- const updateDecision = async (
- officer: AccountId,
- data: AmlExchangeBackend.AmlDecision,
- ): Promise<HttpResponseOk<void>> => {
- const res = await request<void>(`aml/${officer}/decision`, {
- method: "POST",
- data,
- contentType: "json",
- });
- await mutateAll(/.*aml.*/);
- return res;
- };
-
- return {
- updateDecision,
- };
-}
-
-export interface AmlCaseAPI {
- updateDecision: (
- officer: AccountId,
- data: AmlExchangeBackend.AmlDecision,
- ) => Promise<HttpResponseOk<void>>;
-}
-
-function useMatchMutate(): (
- re: RegExp,
- value?: unknown,
-) => Promise<any> {
- const { cache, mutate } = useSWRConfig();
-
- if (!(cache instanceof Map)) {
- throw new Error(
- "matchMutate requires the cache provider to be a Map instance",
- );
- }
-
- return function matchRegexMutate(re: RegExp, value?: unknown) {
- const allKeys = Array.from(cache.keys());
- const keys = allKeys.filter((key) => re.test(key));
- const mutations = keys.map((key) => {
- return mutate(key, value, true);
- });
- return Promise.all(mutations);
- };
-}
diff --git a/packages/aml-backoffice-ui/src/hooks/useCases.ts b/packages/aml-backoffice-ui/src/hooks/useCases.ts
index c07bd5f18..2a133f46d 100644
--- a/packages/aml-backoffice-ui/src/hooks/useCases.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useCases.ts
@@ -1,16 +1,13 @@
-import { useEffect, useState } from "preact/hooks";
+import { useState } from "preact/hooks";
-import { AmlExchangeBackend } from "../types.js";
import {
- HttpResponse,
- HttpResponseOk,
- HttpResponsePaginated,
- RequestError,
+ HttpResponsePaginated
} from "@gnu-taler/web-util/browser";
+import { AmlExchangeBackend } from "../types.js";
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
+import { AmountString, OfficerAccount, TalerExchangeApi, TalerExchangeResultByMethod, TalerHttpError } from "@gnu-taler/taler-util";
import _useSWR, { SWRHook } from "swr";
-import { usePublicBackend } from "./useBackend.js";
-import { AccountId, buildQuerySignature } from "../account.js";
+import { useExchangeApiContext } from "../context/config.js";
import { useOfficer } from "./useOfficer.js";
const useSWR = _useSWR as unknown as SWRHook;
@@ -22,59 +19,49 @@ const MAX_RESULT_SIZE = PAGE_SIZE * 2 - 1;
* @param args
* @returns
*/
-export function useCases(
- account: AccountId,
- state: AmlExchangeBackend.AmlState,
- signature: string | undefined,
-): HttpResponsePaginated<
- AmlExchangeBackend.AmlRecords,
- AmlExchangeBackend.AmlError
-> {
- const { paginatedFetcher } = usePublicBackend();
+export function useCases(state: AmlExchangeBackend.AmlState) {
+ const officer = useOfficer();
+ const session = officer.state === "ready" ? officer.account : undefined;
+ const { api } = useExchangeApiContext();
- const [page, setPage] = useState(1);
+ const [offset, setOffet] = useState<string>();
+
+ async function fetcher([officer, state, offset]: [OfficerAccount, AmlExchangeBackend.AmlState, string | undefined]) {
+ return await api.getDecisionsByState(officer, state, {
+ order: "asc", offset, limit: MAX_RESULT_SIZE
+ })
+ }
- 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 { data, error } = useSWR<TalerExchangeResultByMethod<"getDecisionsByState">, TalerHttpError>(
+ !session ? undefined : [session, state, offset],
+ fetcher,
);
- const [lastAfter, setLastAfter] = useState<
- HttpResponse<AmlExchangeBackend.AmlRecords, AmlExchangeBackend.AmlError>
- >({ loading: true });
+ // const [lastAfter, setLastAfter] = useState<
+ // HttpResponse<AmlExchangeBackend.AmlRecords, AmlExchangeBackend.AmlError>
+ // >({ loading: true });
- useEffect(() => {
- if (afterData) setLastAfter(afterData);
- }, [afterData]);
+ // useEffect(() => {
+ // if (afterData) setLastAfter(afterData);
+ // }, [afterData]);
- if (afterError) {
- return afterError.cause;
- }
+ // 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 isLastPage =
+ data && data.type === "ok" && data.body.records.length < PAGE_SIZE;
+ const isFirstPage = !offset;
const pagination = {
- isReachingEnd,
- isReachingStart,
+ isLastPage,
+ isFirstPage,
loadMore: () => {
- if (!afterData || isReachingEnd) return;
- if (afterData.data && afterData.data.records.length < MAX_RESULT_SIZE) {
- setPage(page + 1);
+ if (isLastPage || data?.type !== "ok") return;
+ const list = data.body.records
+ if (list.length < MAX_RESULT_SIZE) {
+ // setOffset(list[list.length-1].account_name);
}
},
loadMorePrev: () => {
@@ -82,65 +69,62 @@ export function useCases(
},
};
- const records = !afterData
- ? []
- : ((afterData ?? lastAfter).data ?? { records: [] }).records;
- if (loadingAfter) return { loading: true, data: { records } };
- if (afterData) {
- return { ok: true, data: { records }, ...pagination };
+ // const public_accountslist = data?.type !== "ok" ? [] : data.body.public_accounts;
+ if (data) {
+ if (data.type === "fail") {
+ return { data }
+ }
+ return { data, pagination }
+ }
+ if (error) {
+ return error;
}
- return { loading: true };
+ return undefined;
}
-const example1: AmlExchangeBackend.AmlRecords = {
+const example1: TalerExchangeApi.AmlRecords = {
records: [
{
current_state: 0,
h_payto: "QWEQWEQWEQWEWQE",
rowid: 1,
- threshold: "USD 100",
+ threshold: "USD 100" as AmountString,
},
{
current_state: 1,
h_payto: "ASDASDASD",
rowid: 1,
- threshold: "USD 100",
+ threshold: "USD 100" as AmountString,
},
{
current_state: 2,
h_payto: "ZXCZXCZXCXZC",
rowid: 1,
- threshold: "USD 1000",
+ threshold: "USD 1000" as AmountString,
},
{
current_state: 0,
h_payto: "QWEQWEQWEQWEWQE",
rowid: 1,
- threshold: "USD 100",
+ threshold: "USD 100" as AmountString,
},
{
current_state: 1,
h_payto: "ASDASDASD",
rowid: 1,
- threshold: "USD 100",
+ threshold: "USD 100" as AmountString,
},
{
current_state: 2,
h_payto: "ZXCZXCZXCXZC",
rowid: 1,
- threshold: "USD 1000",
+ threshold: "USD 1000" as AmountString,
},
].map((e, idx) => {
e.rowid = idx;
- e.threshold = `${e.threshold}${idx}`;
+ e.threshold = `${e.threshold}${idx}` as AmountString;
return e;
}),
};
-export const exampleResponse: HttpResponsePaginated<AmlExchangeBackend.AmlRecords,AmlExchangeBackend.AmlError> = {
- ok: true,
- data: example1,
- loadMore: () => {},
- loadMorePrev: () => {},
-}
diff --git a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
index 4ec43569b..0747170e8 100644
--- a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
@@ -1,17 +1,15 @@
import {
AbsoluteTime,
Codec,
+ LockedAccount,
+ OfficerAccount,
buildCodecForObject,
codecForAbsoluteTime,
codecForString,
+ createNewOfficerAccount,
+ unlockOfficerAccount,
} from "@gnu-taler/taler-util";
import {
- Account,
- LockedAccount,
- createNewAccount,
- unlockAccount,
-} from "../account.js";
-import {
buildStorageKey,
useLocalStorage,
useMemoryStorage,
@@ -43,7 +41,7 @@ interface OfficerLocked {
}
interface OfficerReady {
state: "ready";
- account: Account;
+ account: OfficerAccount;
forget: () => void;
lock: () => void;
}
@@ -52,7 +50,7 @@ const OFFICER_KEY = buildStorageKey("officer", codecForOfficer());
const ACCOUNT_KEY = "account";
export function useOfficer(): OfficerState {
- const accountStorage = useMemoryStorage<Account>(ACCOUNT_KEY);
+ const accountStorage = useMemoryStorage<OfficerAccount>(ACCOUNT_KEY);
const officerStorage = useLocalStorage(OFFICER_KEY);
const officer = officerStorage.value;
@@ -62,13 +60,13 @@ export function useOfficer(): OfficerState {
return {
state: "not-found",
create: async (pwd: string) => {
- const { accountId, safe, signingKey } = await createNewAccount(pwd);
+ const { id, safe, signingKey } = await createNewOfficerAccount(pwd);
officerStorage.update({
account: safe,
when: AbsoluteTime.now(),
});
- accountStorage.update({ accountId, signingKey });
+ accountStorage.update({ id, signingKey });
},
};
}
@@ -80,7 +78,7 @@ export function useOfficer(): OfficerState {
officerStorage.reset();
},
tryUnlock: async (pwd: string) => {
- const ac = await unlockAccount(officer.account, pwd);
+ const ac = await unlockOfficerAccount(officer.account, pwd);
accountStorage.update(ac);
},
};