From 1e47014936612af831a1947daca609fbdab9cf46 Mon Sep 17 00:00:00 2001 From: nischit Date: Fri, 20 Dec 2024 07:47:09 +0545 Subject: [PATCH] webhook config backwards compatible --- .../src/@3rdweb-sdk/react/hooks/useEngine.ts | 3 +- .../components/add-webhook-button.tsx | 40 ++-- .../webhooks/components/engine-webhooks.tsx | 16 +- .../webhooks/components/webhooks-table.tsx | 197 ++++++++++-------- 4 files changed, 154 insertions(+), 102 deletions(-) diff --git a/apps/dashboard/src/@3rdweb-sdk/react/hooks/useEngine.ts b/apps/dashboard/src/@3rdweb-sdk/react/hooks/useEngine.ts index 521752814b3..1db660155c9 100644 --- a/apps/dashboard/src/@3rdweb-sdk/react/hooks/useEngine.ts +++ b/apps/dashboard/src/@3rdweb-sdk/react/hooks/useEngine.ts @@ -118,7 +118,8 @@ type EngineFeature = | "CONTRACT_SUBSCRIPTIONS" | "IP_ALLOWLIST" | "HETEROGENEOUS_WALLET_TYPES" - | "SMART_BACKEND_WALLETS"; + | "SMART_BACKEND_WALLETS" + | "WEBHOOK_CONFIG"; interface EngineSystemHealth { status: string; diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/add-webhook-button.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/add-webhook-button.tsx index daf5654e6b0..2e270bdf9c0 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/add-webhook-button.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/add-webhook-button.tsx @@ -27,6 +27,7 @@ import { beautifyString } from "./webhooks-table"; interface AddWebhookButtonProps { instanceUrl: string; authToken: string; + supportesWebhookConfig: boolean; } const WEBHOOK_EVENT_TYPES = [ @@ -42,6 +43,7 @@ const WEBHOOK_EVENT_TYPES = [ export const AddWebhookButton: React.FC = ({ instanceUrl, authToken, + supportesWebhookConfig = false, }) => { const { isOpen, onOpen, onClose } = useDisclosure(); const { mutate: createWebhook } = useEngineCreateWebhook({ @@ -75,14 +77,18 @@ export const AddWebhookButton: React.FC = ({ className="!bg-background rounded-lg border border-border" as="form" onSubmit={form.handleSubmit((data) => { - const { config, ..._data } = data; - const finalData: CreateWebhookInput = _data; - if (config) { - try { - finalData.config = JSON.parse(config); - } catch (_) { - toast.error("Config must be a valid json string"); - return; + let finalData: CreateWebhookInput = data; + + if (supportesWebhookConfig) { + const { config, ..._data } = data; + finalData = _data; + if (config) { + try { + finalData.config = JSON.parse(config); + } catch (_) { + toast.error("Config must be a valid json string"); + return; + } } } @@ -140,14 +146,16 @@ export const AddWebhookButton: React.FC = ({ {...form.register("url", { required: true })} /> - - Config - - + {supportesWebhookConfig && ( + + Config + + + )} diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/engine-webhooks.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/engine-webhooks.tsx index 26bc2c9176a..1c54239a9bf 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/engine-webhooks.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/engine-webhooks.tsx @@ -1,6 +1,9 @@ "use client"; -import { useEngineWebhooks } from "@3rdweb-sdk/react/hooks/useEngine"; +import { + useEngineSystemHealth, + useEngineWebhooks, +} from "@3rdweb-sdk/react/hooks/useEngine"; import { Heading, Link, Text } from "tw-components"; import { AddWebhookButton } from "./add-webhook-button"; import { WebhooksTable } from "./webhooks-table"; @@ -18,6 +21,10 @@ export const EngineWebhooks: React.FC = ({ authToken, instanceUrl, }); + const healthQuery = useEngineSystemHealth(instanceUrl); + + const supportesWebhookConfig = + healthQuery.data?.features?.includes("WEBHOOK_CONFIG") || false; return (
@@ -42,8 +49,13 @@ export const EngineWebhooks: React.FC = ({ isPending={webhooks.isPending} isFetched={webhooks.isFetched} authToken={authToken} + supportesWebhookConfig={supportesWebhookConfig} + /> + -
); }; diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/webhooks-table.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/webhooks-table.tsx index 0eba36896cf..ba2c68dcf35 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/webhooks-table.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/webhooks/components/webhooks-table.tsx @@ -27,7 +27,7 @@ import { TWTable } from "components/shared/TWTable"; import { format, formatDistanceToNowStrict } from "date-fns"; import { useTrack } from "hooks/analytics/useTrack"; import { MailQuestion, TrashIcon } from "lucide-react"; -import { useState } from "react"; +import { useMemo, useState } from "react"; import { toast } from "sonner"; import { Card, FormLabel, Text } from "tw-components"; import { shortenString } from "utils/usedapp-external"; @@ -50,88 +50,18 @@ interface WebhooksTableProps { isPending: boolean; isFetched: boolean; authToken: string; + supportesWebhookConfig: boolean; } const columnHelper = createColumnHelper(); -const columns = [ - columnHelper.accessor("name", { - header: "Name", - cell: (cell) => { - return {cell.getValue()}; - }, - }), - columnHelper.accessor("eventType", { - header: "Event Type", - cell: (cell) => { - return {beautifyString(cell.getValue())}; - }, - }), - columnHelper.accessor("secret", { - header: "Secret", - cell: (cell) => { - return ( - - ); - }, - }), - columnHelper.accessor("url", { - header: "URL", - cell: (cell) => { - const url = cell.getValue(); - return ( - - {url} - - ); - }, - }), - columnHelper.accessor("config", { - header: "Config", - cell: (cell) => { - const config = cell.getValue(); - return {jsonStringify(config)}; - }, - }), - columnHelper.accessor("createdAt", { - header: "Created At", - cell: (cell) => { - const value = cell.getValue(); - if (!value) { - return; - } - - const date = new Date(value); - return ( - - {format(date, "PP pp z")} - - } - shouldWrapChildren - > - {formatDistanceToNowStrict(date, { addSuffix: true })} - - ); - }, - }), -]; - export const WebhooksTable: React.FC = ({ instanceUrl, webhooks, isPending, isFetched, authToken, + supportesWebhookConfig = false, }) => { const [selectedWebhook, setSelectedWebhook] = useState(); const deleteDisclosure = useDisclosure(); @@ -139,12 +69,95 @@ export const WebhooksTable: React.FC = ({ const activeWebhooks = webhooks.filter((webhook) => webhook.active); + const columns = useMemo(() => { + const _columns = [ + columnHelper.accessor("name", { + header: "Name", + cell: (cell) => { + return {cell.getValue()}; + }, + }), + columnHelper.accessor("eventType", { + header: "Event Type", + cell: (cell) => { + return {beautifyString(cell.getValue())}; + }, + }), + columnHelper.accessor("secret", { + header: "Secret", + cell: (cell) => { + return ( + + ); + }, + }), + columnHelper.accessor("url", { + header: "URL", + cell: (cell) => { + const url = cell.getValue(); + return ( + + {url} + + ); + }, + }), + columnHelper.accessor("createdAt", { + header: "Created At", + cell: (cell) => { + const value = cell.getValue(); + if (!value) { + return; + } + + const date = new Date(value); + return ( + + {format(date, "PP pp z")} + + } + shouldWrapChildren + > + + {formatDistanceToNowStrict(date, { addSuffix: true })} + + + ); + }, + }), + ]; + + if (supportesWebhookConfig) { + _columns.push( + columnHelper.accessor("config", { + header: "Config", + cell: (cell) => { + const config = cell.getValue(); + return {jsonStringify(config)}; + }, + }), + ); + } + + return _columns; + }, [supportesWebhookConfig]); + return ( <> = ({ disclosure={deleteDisclosure} instanceUrl={instanceUrl} authToken={authToken} + supportesWebhookConfig={supportesWebhookConfig} /> )} {selectedWebhook && testDisclosure.isOpen && ( @@ -182,6 +196,7 @@ export const WebhooksTable: React.FC = ({ disclosure={testDisclosure} instanceUrl={instanceUrl} authToken={authToken} + supportesWebhookConfig={supportesWebhookConfig} /> )} @@ -193,12 +208,14 @@ interface DeleteWebhookModalProps { disclosure: UseDisclosureReturn; instanceUrl: string; authToken: string; + supportesWebhookConfig: boolean; } function DeleteWebhookModal({ webhook, disclosure, instanceUrl, authToken, + supportesWebhookConfig = false, }: DeleteWebhookModalProps) { const deleteWebhook = useEngineDeleteWebhook({ authToken, @@ -254,10 +271,14 @@ function DeleteWebhookModal({ URL {webhook.url} - - Config - {jsonStringify(webhook.config)} - + {supportesWebhookConfig && ( + + Config + + {jsonStringify(webhook.config)} + + + )} Created at @@ -285,12 +306,14 @@ interface TestWebhookModalProps { disclosure: UseDisclosureReturn; instanceUrl: string; authToken: string; + supportesWebhookConfig: boolean; } function TestWebhookModal({ webhook, disclosure, instanceUrl, authToken, + supportesWebhookConfig = false, }: TestWebhookModalProps) { const { mutate: testWebhook, isPending } = useEngineTestWebhook({ instanceUrl, @@ -322,12 +345,20 @@ function TestWebhookModal({
URL - {webhook.url} - - - Config - {webhook.config} + + {webhook.url} + + {supportesWebhookConfig && ( + + Config + + + {jsonStringify(webhook.config)} + + + + )}