diff options
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 }; +}  | 
