diff options
author | Sebastian <sebasjm@gmail.com> | 2023-01-27 15:08:03 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-01-27 15:08:25 -0300 |
commit | eebb85bef4bb6bba41533fa0ff343cf2f1995761 (patch) | |
tree | 08ac7d3197d662bd8fadc747a912023364a4f9c7 /packages/merchant-backoffice-ui/src/hooks | |
parent | 1b2b5d62de5888eae895db69cf6ae51dbfddb32b (diff) | |
download | wallet-core-eebb85bef4bb6bba41533fa0ff343cf2f1995761.tar.xz |
webhook api
Diffstat (limited to 'packages/merchant-backoffice-ui/src/hooks')
-rw-r--r-- | packages/merchant-backoffice-ui/src/hooks/backend.ts | 23 | ||||
-rw-r--r-- | packages/merchant-backoffice-ui/src/hooks/webhooks.ts | 165 |
2 files changed, 188 insertions, 0 deletions
diff --git a/packages/merchant-backoffice-ui/src/hooks/backend.ts b/packages/merchant-backoffice-ui/src/hooks/backend.ts index a0639a4a0..3f3db2fa1 100644 --- a/packages/merchant-backoffice-ui/src/hooks/backend.ts +++ b/packages/merchant-backoffice-ui/src/hooks/backend.ts @@ -115,6 +115,11 @@ interface useBackendInstanceRequestType { position?: string, delta?: number, ) => Promise<HttpResponseOk<T>>; + webhookFetcher: <T>( + path: string, + position?: string, + delta?: number, + ) => Promise<HttpResponseOk<T>>; } interface useBackendBaseRequestType { request: <T>( @@ -274,6 +279,23 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { [backend, token], ); + const webhookFetcher = useCallback( + function webhookFetcherImpl<T>( + path: string, + position?: string, + delta?: number, + ): Promise<HttpResponseOk<T>> { + const params: any = {}; + if (delta !== undefined) { + params.limit = delta; + } + if (position !== undefined) params.offset = position; + + return requestHandler<T>(backend, path, { params, token }); + }, + [backend, token], + ); + return { request, fetcher, @@ -283,5 +305,6 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { tipsDetailFetcher, transferFetcher, templateFetcher, + webhookFetcher, }; } diff --git a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts new file mode 100644 index 000000000..9f196cefa --- /dev/null +++ b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts @@ -0,0 +1,165 @@ +/* + This file is part of GNU Taler + (C) 2021-2023 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +import { MerchantBackend } from "../declaration.js"; +import { useMatchMutate, useBackendInstanceRequest } from "./backend.js"; +import useSWR from "swr"; +import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants.js"; +import { useEffect, useState } from "preact/hooks"; +import { + HttpError, + HttpResponse, + HttpResponseOk, + HttpResponsePaginated, +} from "../utils/request.js"; + +export function useWebhookAPI(): WebhookAPI { + const mutateAll = useMatchMutate(); + const { request } = useBackendInstanceRequest(); + + const createWebhook = async ( + data: MerchantBackend.Webhooks.WebhookAddDetails, + ): Promise<HttpResponseOk<void>> => { + const res = await request<void>(`/private/webhooks`, { + method: "POST", + data, + }); + await mutateAll(/.*private\/webhooks.*/); + return res; + }; + + const updateWebhook = async ( + webhookId: string, + data: MerchantBackend.Webhooks.WebhookPatchDetails, + ): Promise<HttpResponseOk<void>> => { + const res = await request<void>(`/private/webhooks/${webhookId}`, { + method: "PATCH", + data, + }); + await mutateAll(/.*private\/webhooks.*/); + return res; + }; + + const deleteWebhook = async ( + webhookId: string, + ): Promise<HttpResponseOk<void>> => { + const res = await request<void>(`/private/webhooks/${webhookId}`, { + method: "DELETE", + }); + await mutateAll(/.*private\/webhooks.*/); + return res; + }; + + return { createWebhook, updateWebhook, deleteWebhook }; +} + +export interface WebhookAPI { + createWebhook: ( + data: MerchantBackend.Webhooks.WebhookAddDetails, + ) => Promise<HttpResponseOk<void>>; + updateWebhook: ( + id: string, + data: MerchantBackend.Webhooks.WebhookPatchDetails, + ) => Promise<HttpResponseOk<void>>; + deleteWebhook: (id: string) => Promise<HttpResponseOk<void>>; +} + +export interface InstanceWebhookFilter { + //FIXME: add filter to the webhook list + position?: string; +} + +export function useInstanceWebhooks( + args?: InstanceWebhookFilter, + updatePosition?: (id: string) => void, +): HttpResponsePaginated<MerchantBackend.Webhooks.WebhookSummaryResponse> { + const { webhookFetcher } = useBackendInstanceRequest(); + + const [pageAfter, setPageAfter] = useState(1); + + const totalAfter = pageAfter * PAGE_SIZE; + + const { + data: afterData, + error: afterError, + isValidating: loadingAfter, + } = useSWR< + HttpResponseOk<MerchantBackend.Webhooks.WebhookSummaryResponse>, + HttpError + >([`/private/webhooks`, args?.position, -totalAfter], webhookFetcher); + + const [lastAfter, setLastAfter] = useState< + HttpResponse<MerchantBackend.Webhooks.WebhookSummaryResponse> + >({ loading: true }); + useEffect(() => { + if (afterData) setLastAfter(afterData); + }, [afterData]); + + if (afterError) return afterError; + + const isReachingEnd = + afterData && afterData.data.webhooks.length < totalAfter; + const isReachingStart = false; + + const pagination = { + isReachingEnd, + isReachingStart, + loadMore: () => { + if (!afterData || isReachingEnd) return; + if (afterData.data.webhooks.length < MAX_RESULT_SIZE) { + setPageAfter(pageAfter + 1); + } else { + const from = `${afterData.data.webhooks[afterData.data.webhooks.length - 1] + .webhook_id + }`; + if (from && updatePosition) updatePosition(from); + } + }, + loadMorePrev: () => { + return + }, + }; + + const webhooks = !afterData ? [] : (afterData || lastAfter).data.webhooks; + + if (loadingAfter) + return { loading: true, data: { webhooks } }; + if (afterData) { + return { ok: true, data: { webhooks }, ...pagination }; + } + return { loading: true }; +} + +export function useWebhookDetails( + webhookId: string, +): HttpResponse<MerchantBackend.Webhooks.WebhookDetails> { + const { webhookFetcher } = useBackendInstanceRequest(); + + const { data, error, isValidating } = useSWR< + HttpResponseOk<MerchantBackend.Webhooks.WebhookDetails>, + HttpError + >([`/private/webhooks/${webhookId}`], webhookFetcher, { + 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; + return { loading: true }; +} |