"use client"; // Group container for the composite search builder. Renders its op // (AND / OR), optional NOT flag, live count, and children (leaves or // nested groups). When the root group is in compact mode (single leaf, // no negation), the parent renders just the leaf directly without this // wrapper to keep the simple-search case visually minimal. import { isGroup, isLeaf, newGroup, newLeaf, type GroupNode, type QueryNode, } from "../lib/searchQuery"; import type { GroupState, LeafState } from "../lib/searchEval"; import QueryLeafView from "./QueryLeafView"; import { Button } from "./ui/button"; import { Checkbox } from "./ui/checkbox"; const negateCheckboxClass = "border-destructive/60 data-[state=checked]:bg-destructive data-[state=checked]:border-destructive data-[state=checked]:text-destructive-foreground"; type Props = { group: GroupNode; isRoot: boolean; depth: number; leafStates: ReadonlyMap; groupStates: ReadonlyMap; onChangeNode: (id: string, next: QueryNode) => void; onRemoveNode: (id: string) => void; onAddChild: (groupId: string, child: QueryNode) => void; onWrapLeaf: (leafId: string) => void; onUnwrapGroup: (groupId: string) => void; }; export default function QueryGroupView({ group, isRoot, depth, leafStates, groupStates, onChangeNode, onRemoveNode, onAddChild, onWrapLeaf, onUnwrapGroup, }: Props) { const state = groupStates.get(group.id); const onlyLeafCount = group.children.filter(isLeaf).length; const indent = depth === 0 ? "" : "pl-4 border-l-2 border-border"; return (
{!isRoot && ( )} {state && ( → {state.slugCount} video{state.slugCount === 1 ? "" : "s"} )} {!isRoot && (
)}
{group.children.map((child) => { if (isLeaf(child)) { return ( 1 || !isRoot} onChange={(next) => onChangeNode(child.id, next)} onDelete={() => onRemoveNode(child.id)} onWrapInGroup={() => onWrapLeaf(child.id)} isOnlyLeaf={onlyLeafCount === 1} /> ); } if (isGroup(child)) { return ( ); } return null; })}
); }