diff --git a/src/components/LXCList.js b/src/components/LXCList.js index b0c08c2..8a666aa 100644 --- a/src/components/LXCList.js +++ b/src/components/LXCList.js @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { useState, useMemo } from 'react'; import StatusBadge from './StatusBadge'; /** @@ -14,18 +14,25 @@ export default function LXCList({ lxc, onPowerAction, onOpenConsole }) { return

No LXCs found.

; } - const filtered = filter - ? lxc.filter((item) => - [item.name, item.node, item.status].some((v) => v.toLowerCase().includes(filter.toLowerCase()) - )) - : lxc; + const filtered = useMemo(() => { + if (!filter) return lxc; + const q = filter.toLowerCase(); + return lxc.filter((item) => + [item.name, item.node, item.status].some((v) => v.toLowerCase().includes(q)), + ); + }, [lxc, filter]); - const groups = Object.groupBy(filtered, (item) => item.node); + const groups = useMemo(() => Object.groupBy(filtered, (item) => item.node), [filtered]); const sortedNodes = Object.keys(groups).sort(); + const autoExpand = sortedNodes.length === 1; const total = filtered.length; const running = filtered.filter((item) => item.status === 'running').length; + function toggleNode(node) { + setExpandedNodes((prev) => ({ ...prev, [node]: !prev[node] })); + } + return (
{filter && ( @@ -47,12 +54,12 @@ export default function LXCList({ lxc, onPowerAction, onOpenConsole }) { {sortedNodes.map((node) => { const running = groups[node].filter((item) => item.status === 'running'); const stopped = groups[node].filter((item) => item.status !== 'running'); - const expanded = expandedNodes[node] ?? false; + const expanded = autoExpand || expandedNodes[node] ?? false; return (