import { orgQueries } from "@app/lib/queries"; import type { ListClientsResponse } from "@server/routers/client"; import { useQuery } from "@tanstack/react-query"; import { useMemo, useState } from "react"; import { useDebounce } from "use-debounce"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./ui/command"; import { cn } from "@app/lib/cn"; import { CheckIcon } from "lucide-react"; import { useTranslations } from "next-intl"; export type SelectedMachine = Pick< ListClientsResponse["clients"][number], "name" | "clientId" >; export type MachineSelectorProps = { orgId: string; selectedMachines?: SelectedMachine[]; onSelectMachines: (machine: SelectedMachine[]) => void; }; export function MachineSelector({ orgId, selectedMachines = [], onSelectMachines }: MachineSelectorProps) { const t = useTranslations(); const [machineSearchQuery, setMachineSearchQuery] = useState(""); const [debouncedValue] = useDebounce(machineSearchQuery, 150); const { data: machines = [] } = useQuery( orgQueries.machineClients({ orgId, perPage: 10, query: debouncedValue }) ); // always include the selected machines in the list of machines shown (if the user isn't searching) const machinesShown = useMemo(() => { const allMachines: Array = [...machines]; if (debouncedValue.trim().length === 0) { for (const machine of selectedMachines) { if ( !allMachines.find((mc) => mc.clientId === machine.clientId) ) { allMachines.unshift(machine); } } } return allMachines; }, [machines, selectedMachines, debouncedValue]); const selectedMachinesIds = new Set( selectedMachines.map((m) => m.clientId) ); return ( {t("machineNotFound")} {machinesShown.map((m) => ( { let newMachineClients = []; if (selectedMachinesIds.has(m.clientId)) { newMachineClients = selectedMachines.filter( (mc) => mc.clientId !== m.clientId ); } else { newMachineClients = [ ...selectedMachines, m ]; } onSelectMachines(newMachineClients); }} > {`${m.name}`} ))} ); }