diff options
author | Sebastian <sebasjm@gmail.com> | 2024-04-03 09:52:53 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2024-04-03 14:56:29 -0300 |
commit | 56da180423029a1b53d2be343eed4f073e96dc89 (patch) | |
tree | e8fd31dcc4c7bc6866b139de097c8f2c01f93597 /packages/merchant-backoffice-ui/src/hooks/product.ts | |
parent | c53c6b8b3c0a66f3862883ec1314c6d4bf68af32 (diff) | |
download | wallet-core-56da180423029a1b53d2be343eed4f073e96dc89.tar.xz |
wip #8655: updating paginated queries
Diffstat (limited to 'packages/merchant-backoffice-ui/src/hooks/product.ts')
-rw-r--r-- | packages/merchant-backoffice-ui/src/hooks/product.ts | 227 |
1 files changed, 78 insertions, 149 deletions
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts b/packages/merchant-backoffice-ui/src/hooks/product.ts index 0eb54f717..6721136a5 100644 --- a/packages/merchant-backoffice-ui/src/hooks/product.ts +++ b/packages/merchant-backoffice-ui/src/hooks/product.ts @@ -14,164 +14,93 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { - HttpResponse, - HttpResponseOk, - RequestError, + useMerchantApiContext } from "@gnu-taler/web-util/browser"; -import { useBackendInstanceRequest, useMatchMutate } from "./backend.js"; // FIX default import https://github.com/microsoft/TypeScript/issues/49189 -import _useSWR, { SWRHook, useSWRConfig } from "swr"; -import { TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util"; +import { AccessToken, OperationOk, TalerHttpError, TalerMerchantApi, TalerMerchantManagementErrorsByMethod, TalerMerchantManagementResultByMethod, opFixedSuccess } from "@gnu-taler/taler-util"; +import { useState } from "preact/hooks"; +import _useSWR, { SWRHook, mutate } from "swr"; +import { useSessionContext } from "../context/session.js"; +import { PAGE_SIZE } from "../utils/constants.js"; +import { buildPaginatedResult } from "./webhooks.js"; const useSWR = _useSWR as unknown as SWRHook; -// export interface ProductAPI { -// getProduct: ( -// id: string, -// ) => Promise<void>; -// createProduct: ( -// data: TalerMerchantApi.ProductAddDetail, -// ) => Promise<void>; -// updateProduct: ( -// id: string, -// data: TalerMerchantApi.ProductPatchDetail, -// ) => Promise<void>; -// deleteProduct: (id: string) => Promise<void>; -// lockProduct: ( -// id: string, -// data: TalerMerchantApi.LockRequest, -// ) => Promise<void>; -// } - -// export function useProductAPI(): ProductAPI { -// const mutateAll = useMatchMutate(); -// const { mutate } = useSWRConfig(); - -// const { request } = useBackendInstanceRequest(); - -// const createProduct = async ( -// data: TalerMerchantApi.ProductAddDetail, -// ): Promise<void> => { -// const res = await request(`/private/products`, { -// method: "POST", -// data, -// }); - -// return await mutateAll(/.*\/private\/products.*/); -// }; - -// const updateProduct = async ( -// productId: string, -// data: TalerMerchantApi.ProductPatchDetail, -// ): Promise<void> => { -// const r = await request(`/private/products/${productId}`, { -// method: "PATCH", -// data, -// }); - -// return await mutateAll(/.*\/private\/products.*/); -// }; - -// const deleteProduct = async (productId: string): Promise<void> => { -// await request(`/private/products/${productId}`, { -// method: "DELETE", -// }); -// await mutate([`/private/products`]); -// }; - -// const lockProduct = async ( -// productId: string, -// data: TalerMerchantApi.LockRequest, -// ): Promise<void> => { -// await request(`/private/products/${productId}/lock`, { -// method: "POST", -// data, -// }); - -// return await mutateAll(/.*"\/private\/products.*/); -// }; - -// const getProduct = async ( -// productId: string, -// ): Promise<void> => { -// await request(`/private/products/${productId}`, { -// method: "GET", -// }); - -// return -// }; - -// return { createProduct, updateProduct, deleteProduct, lockProduct, getProduct }; -// } - -export function useInstanceProducts(): HttpResponse< - (TalerMerchantApi.ProductDetail & WithId)[], - TalerErrorDetail -> { - const { fetcher, multiFetcher } = useBackendInstanceRequest(); - - const { data: list, error: listError } = useSWR< - HttpResponseOk<TalerMerchantApi.InventorySummaryResponse>, - RequestError<TalerErrorDetail> - >([`/private/products`], fetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - }); - - const paths = (list?.data.products || []).map( - (p) => `/private/products/${p.product_id}`, +type ProductWithId = TalerMerchantApi.ProductDetail & { id: string, serial: number }; +function notUndefined(c: ProductWithId | undefined): c is ProductWithId { + return c !== undefined; +} + +export function revalidateInstanceProducts() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "listProductsWithId", + undefined, + { revalidate: true }, ); - const { data: products, error: productError } = useSWR< - HttpResponseOk<TalerMerchantApi.ProductDetail>[], - RequestError<TalerErrorDetail> - >([paths], multiFetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - }); - - if (listError) return listError.cause; - if (productError) return productError.cause; - - if (products) { - const dataWithId = products.map((d) => { - //take the id from the queried url - return { - ...d.data, - id: d.info?.url.replace(/.*\/private\/products\//, "") || "", - }; +} +export function useInstanceProducts() { + const { state: session } = useSessionContext(); + const { lib: { management } } = useMerchantApiContext(); + + const [offset, setOffset] = useState<number | undefined>(); + + async function fetcher([token, bid]: [AccessToken, number]) { + const list = await management.listProducts(token, { + limit: PAGE_SIZE, + offset: String(bid), + order: "dec", }); - return { ok: true, data: dataWithId }; + if (list.type !== "ok") { + return list; + } + const all: Array<ProductWithId | undefined> = await Promise.all( + list.body.products.map(async (c) => { + const r = await management.getProductDetails(token, c.product_id); + if (r.type === "fail") { + return undefined; + } + return { ...r.body, id: c.product_id, serial: c.product_serial }; + }), + ); + const products = all.filter(notUndefined); + + return opFixedSuccess({ products }); } - return { loading: true }; + + const { data, error } = useSWR< + OperationOk<{ products: ProductWithId[] }> | + TalerMerchantManagementErrorsByMethod<"listProducts">, + TalerHttpError + >([session.token, offset, "listProductsWithId"], fetcher); + + if (error) return error; + if (data === undefined) return undefined; + if (data.type !== "ok") return data; + + return buildPaginatedResult(data.body.products, offset, setOffset, (d) => d.serial) +} + +export function revalidateProductDetails() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getProductDetails", + undefined, + { revalidate: true }, + ); } +export function useProductDetails(productId: string) { + const { state: session } = useSessionContext(); + const { lib: { management } } = useMerchantApiContext(); + + async function fetcher([pid, token]: [string, AccessToken]) { + return await management.getProductDetails(token, pid); + } + + const { data, error } = useSWR< + TalerMerchantManagementResultByMethod<"getProductDetails">, + TalerHttpError + >([productId, session.token, "getProductDetails"], fetcher); -export function useProductDetails( - productId: string, -): HttpResponse< - TalerMerchantApi.ProductDetail, - TalerErrorDetail -> { - const { fetcher } = useBackendInstanceRequest(); - - const { data, error, isValidating } = useSWR< - HttpResponseOk<TalerMerchantApi.ProductDetail>, - RequestError<TalerErrorDetail> - >([`/private/products/${productId}`], fetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - }); - - 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; } |