import { View, Text, Spinner, ScrollView } from "tamagui"; import React, { useMemo, useState } from "react"; import { useNavigation } from "expo-router"; import SearchInput from "@/components/ui/search-input"; import { useTermSession } from "@/stores/terminal-sessions"; import { hostFormModal } from "./form"; import { GridLayout } from "@/components/ui/grid-view"; import HostItem from "./host-item"; import { useHosts } from "../hooks/query"; import HostActions from "./host-actions"; type HostsListProps = { allowEdit?: boolean; parentId?: string | null; onParentIdChange?: (id: string | null) => void; selected?: string[]; onSelectedChange?: (ids: string[]) => void; hideGroups?: boolean; }; const HostList = ({ allowEdit = true, parentId, onParentIdChange, selected = [], onSelectedChange, hideGroups = false, }: HostsListProps) => { const openSession = useTermSession((i) => i.push); const navigation = useNavigation(); const [search, setSearch] = useState(""); const { data, isLoading } = useHosts({ parentId: !search.length ? parentId : "none", }); const hostsList = useMemo(() => { let items = data || []; if (search) { items = items.filter((item: any) => { const q = search.toLowerCase(); return ( item.label.toLowerCase().includes(q) || item.host.toLowerCase().includes(q) || item.tags.find((i: any) => i.name.toLowerCase().includes(q)) != null ); }); } return items.map((i: any) => ({ ...i, key: i.id })); }, [data, search]); const groups = useMemo( () => hostsList.filter((i: any) => i.type === "group"), [hostsList] ); const hosts = useMemo( () => hostsList.filter((i: any) => i.type !== "group"), [hostsList] ); const onSelect = (host: any) => { if (selected.includes(host.id)) { onSelectedChange?.(selected.filter((i) => i !== host.id)); } else { onSelectedChange?.([...selected, host.id]); } }; const onEdit = (host: any) => { if (!allowEdit) return; const data = { ...host, tags: host.tags?.map((i: any) => i.name) }; hostFormModal.onOpen(data); }; const onOpenTerminal = (host: any) => { const session: any = { id: host.id, label: host.label, type: host.type, params: { hostId: host.id, }, }; if (host.type === "pve") { session.params.client = host.metadata?.type === "lxc" ? "xtermjs" : "vnc"; } openSession(session); navigation.navigate("terminal" as never); }; return ( <> {isLoading ? ( Loading... ) : ( {groups.length > 0 && !hideGroups && ( <> Groups 0 ? onSelect : undefined} onMultiTap={(group) => onParentIdChange?.(group.id)} onEdit={allowEdit ? onEdit : undefined} /> )} Hosts {!hosts.length && ( No hosts found )} 0 ? onSelect : undefined} onMultiTap={onOpenTerminal} onEdit={allowEdit ? onEdit : undefined} onSelect={onSelectedChange ? onSelect : undefined} /> )} ); }; type ItemListProps = { data?: any[]; selected?: string[]; onTap?: (host: any) => void; onMultiTap?: (host: any) => void; onEdit?: (host: any) => void; onSelect?: (host: any) => void; }; const ItemList = ({ data, selected, onTap, onMultiTap, onEdit, onSelect, }: ItemListProps) => ( ( onTap?.(host)} onMultiTap={() => onMultiTap?.(host)} /> onSelect?.(host) : undefined} onEdit={onEdit ? () => onEdit?.(host) : undefined} /> )} /> ); export default React.memo(HostList);