diff --git a/web/components/Modal.tsx b/web/components/Modal.tsx index 641ff95..16c9abb 100644 --- a/web/components/Modal.tsx +++ b/web/components/Modal.tsx @@ -15,8 +15,8 @@ export const Modal = forwardRef(

{title}

{children} - diff --git a/web/islands/ListSources.tsx b/web/islands/ListSources.tsx index 5dc8467..57f68b1 100644 --- a/web/islands/ListSources.tsx +++ b/web/islands/ListSources.tsx @@ -97,7 +97,7 @@ export const ListSources = ({ entries }: ListSourcesProps) => { return ( <>
- diff --git a/web/islands/ListWebhook.tsx b/web/islands/ListWebhook.tsx index 6d48a6f..a52b26c 100644 --- a/web/islands/ListWebhook.tsx +++ b/web/islands/ListWebhook.tsx @@ -1,4 +1,10 @@ -import { useCallback, useEffect, useRef, useState } from "preact/hooks"; +import { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "preact/hooks"; import { CollapsibleTable, CollapsibleTableRow, @@ -26,29 +32,32 @@ export const ListWebhook = ({ entries }: ListWebhookProps) => { const modalRef = useRef(null); const [toast, setToast] = useState(null); const [sources, setSources] = useState([]); + const [selectedAddress, setSelectedAddress] = useState(); + const addresses = useMemo( + () => [...new Set(sources.map((source) => source.address))], + [sources], + ); + const abiHashes = useMemo( + () => + sources + .filter((source) => source.address === selectedAddress) + .map((source) => source.abiHash), + [sources, selectedAddress], + ); useEffect(() => { - const getAbis = async () => { + const getSources = async () => { const res = await fetch("/api/sources"); setSources(await res.json()); }; - getAbis(); + getSources(); }, []); const handleSubmit = useCallback(async (e: Event) => { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); - const addressAbiHash = formData.get("address_abiHash"); - if (!addressAbiHash) { - setToast({ type: "error", text: "Failed to register a webhook entry." }); - return; - } - - const [address, abiHash] = addressAbiHash.toString().split(":"); - formData.set("sourceAddress", address); - formData.set("abiHash", abiHash); const res = await fetch("/api/webhook", { method: "POST", @@ -85,25 +94,23 @@ export const ListWebhook = ({ entries }: ListWebhookProps) => { return ( <>
-
`${e.address}:${e.abiHash}`} - entryTransform={(e) => ( - <> -
Address: {e.address}
-
ABI: {e.abiHash}
- - )} + name="sourceAddress" + list={addresses} + onSelect={setSelectedAddress} /> + + diff --git a/web/islands/SearchDropdown.tsx b/web/islands/SearchDropdown.tsx index d7f59fd..0f646d6 100644 --- a/web/islands/SearchDropdown.tsx +++ b/web/islands/SearchDropdown.tsx @@ -1,5 +1,5 @@ import { useCallback, useMemo, useRef, useState } from "preact/hooks"; -import type { ComponentChild, VNode } from "preact"; +import type { ComponentChild } from "preact"; export interface SearchDropdownProps { list: T[]; @@ -11,9 +11,10 @@ export interface SearchDropdownProps { } export const SearchDropdown = (props: SearchDropdownProps) => { - if (props.list.length === 0) return null; - - if (!props.entrySelector && typeof props.list[0] !== "string") { + if ( + props.list.length > 0 && typeof props.list[0] !== "string" && + !props.entrySelector + ) { throw new Error( "entrySelector should be provided if list is not string array.", ); @@ -58,10 +59,15 @@ export const SearchDropdown = (props: SearchDropdownProps) => { return ( <> -