import { orgQueries } from "@app/lib/queries"; import { useQuery } from "@tanstack/react-query"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./ui/command"; import { useMemo, useState } from "react"; import { useTranslations } from "next-intl"; import { CheckIcon } from "lucide-react"; import { cn } from "@app/lib/cn"; import type { ListResourcesResponse } from "@server/routers/resource"; import { useDebounce } from "use-debounce"; export type SelectedResource = Pick< ListResourcesResponse["resources"][number], "name" | "resourceId" | "fullDomain" | "niceId" | "ssl" >; export type ResourceSelectorProps = { orgId: string; selectedResource?: SelectedResource | null; onSelectResource: (resource: SelectedResource) => void; }; export function ResourceSelector({ orgId, selectedResource, onSelectResource }: ResourceSelectorProps) { const t = useTranslations(); const [resourceSearchQuery, setResourceSearchQuery] = useState(""); const [debouncedSearchQuery] = useDebounce(resourceSearchQuery, 150); const { data: resources = [] } = useQuery( orgQueries.resources({ orgId: orgId, query: debouncedSearchQuery, perPage: 10 }) ); // always include the selected resource in the list of resources shown const resourcesShown = useMemo(() => { const allResources: Array = [...resources]; if ( debouncedSearchQuery.trim().length === 0 && selectedResource && !allResources.find( (resource) => resource.resourceId === selectedResource?.resourceId ) ) { allResources.unshift(selectedResource); } return allResources; }, [debouncedSearchQuery, resources, selectedResource]); return ( {t("resourcesNotFound")} {resourcesShown.map((r) => ( { onSelectResource(r); }} > {`${r.name}`} ))} ); }