@pythia-software/query-table-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +415 -132
- package/dist/index.js.map +1 -1
- package/dist/theme.css +522 -4
- package/dist/theme.css.map +1 -1
- package/package.json +7 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/renderers.ts","../src/DataTable.tsx","../src/CellMenu.tsx","../src/QueryBuilder.tsx","../src/FieldPicker.tsx","../src/SavedQueriesModal.tsx","../src/MetricsPanel.tsx","../src/SelectionToolbar.tsx"],"sourcesContent":["// renderers.ts — the cell render registry.\n//\n// This is how the table stays \"gold standard but customizable\" (the core ask).\n// The package ships ONLY truly-generic renderers. Domain-specific cells are\n// registered by the consuming app — they must NOT live in a generic package.\n// A FieldDef.render is either a key resolved\n// against `{ ...defaultRenderers, ...consumerRenderers }` or an inline function.\n\nimport type { ReactNode } from \"react\";\nimport { createElement } from \"react\";\nimport type { FieldDef, QueryState } from \"@pythia-software/query-table-core\";\n\nexport interface CellContext<Row = any, V = unknown> {\n value: V;\n row: Row;\n field: FieldDef<Row, V>;\n /** Current query — lets renderers reflect active state (e.g. highlight matches). */\n query: QueryState;\n}\n\nexport type CellRenderer<Row = any, V = unknown> = (ctx: CellContext<Row, V>) => ReactNode;\n\nexport type RenderRegistry<Row = any> = Record<string, CellRenderer<Row>>;\n\n/** The em-dash shown for empty / null values, so every renderer agrees. */\nconst EMPTY = \"—\";\n\nconst muted = (text: string): ReactNode => createElement(\"span\", { className: \"qt-muted\" }, text);\n\nfunction isEmpty(v: unknown): boolean {\n return v == null || v === \"\" || (Array.isArray(v) && v.length === 0);\n}\n\nconst SAFE_LINK_PROTOCOLS: ReadonlySet<string> = new Set([\"http:\", \"https:\", \"mailto:\", \"tel:\"]);\n\n/** Resolve a user-controlled link against a harmless HTTPS base and allow only\n * navigation protocols. This catches obfuscated forms such as `java\\nscript:`\n * that simple prefix checks miss while preserving relative and fragment URLs. */\nexport function safeLinkHref(value: unknown): string | null {\n if (isEmpty(value)) return null;\n const href = String(value).trim();\n if (!href) return null;\n try {\n const parsed = new URL(href, \"https://query-table.invalid/\");\n return SAFE_LINK_PROTOCOLS.has(parsed.protocol) ? href : null;\n } catch {\n return null;\n }\n}\n\n/** Generic, domain-free renderers shipped with the package. Keys are stable and\n * referenced from FieldDef.render. Consumers spread these and add their own. */\nexport const defaultRenderers: RenderRegistry = {\n // String(value), em-dash for null/empty\n text({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n return String(value);\n },\n\n // single-line ellipsis (CSS does the truncation; title carries the full text)\n truncate({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const s = String(value);\n return createElement(\"span\", { className: \"qt-truncate\", title: s }, s);\n },\n\n // locale-grouped number\n number({ value }) {\n if (value == null || value === \"\") return muted(EMPTY);\n const n = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(n)) return muted(EMPTY);\n return n.toLocaleString();\n },\n\n // ✓ / —\n bool_check({ value }) {\n if (value == null) return muted(EMPTY);\n return value ? \"✓\" : muted(EMPTY);\n },\n\n // ISO clamped to seconds\n datetime({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const s = String(value);\n // pgtype zero-time and other epoch placeholders read as empty.\n if (s.startsWith(\"0001-\")) return muted(EMPTY);\n return s.slice(0, 19).replace(\"T\", \" \");\n },\n\n // relative (\"5m ago\", \"yesterday\", \"Mar 4\")\n datetime_rel({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const s = String(value);\n if (s.startsWith(\"0001-\")) return muted(EMPTY);\n return createElement(\"span\", { title: s.slice(0, 19).replace(\"T\", \" \") }, formatRelative(s));\n },\n\n // human duration from a millisecond number\n duration_ms({ value }) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return muted(EMPTY);\n return formatDuration(value);\n },\n\n // humanized bytes (B/KB/MB/GB)\n byte_size({ value }) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) return muted(EMPTY);\n return formatBytes(value);\n },\n\n // string[] as pills\n tags_pills({ value }) {\n if (!Array.isArray(value) || value.length === 0) return muted(EMPTY);\n return createElement(\n \"span\",\n { className: \"qt-pills\" },\n value.map((t, i) => createElement(\"span\", { key: `${String(t)}-${i}`, className: \"qt-pill\" }, String(t))),\n );\n },\n\n // value as an <a href={value}> when its URL scheme is safe\n link({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const label = String(value);\n const href = safeLinkHref(value);\n if (!href) return createElement(\"span\", { className: \"qt-muted\", title: \"Unsafe link blocked\" }, label);\n return createElement(\n \"a\",\n { className: \"qt-link\", href, target: \"_blank\", rel: \"noopener noreferrer\", title: href },\n label,\n );\n },\n};\n\n/** Resolve a FieldDef's renderer: inline fn wins, else registry lookup, else\n * the `text` fallback. */\nexport function resolveRenderer<Row>(\n field: FieldDef<Row>,\n registry: RenderRegistry<Row>,\n): CellRenderer<Row> {\n const r = field.render;\n if (typeof r === \"function\") {\n // core's CellRenderer returns `unknown`; ours narrows that to ReactNode.\n return r as CellRenderer<Row>;\n }\n if (typeof r === \"string\") {\n const found = registry[r];\n if (found) return found;\n }\n // text fallback always exists (consumers spread defaultRenderers in).\n return (registry[\"text\"] ?? defaultRenderers[\"text\"]) as CellRenderer<Row>;\n}\n\n// ---- formatting helpers ---------------------------------------------------\n\nfunction formatDuration(ms: number): string {\n if (ms < 0) return String(ms);\n if (ms < 1) return `${ms.toFixed(2)}ms`;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n const totalSec = ms / 1000;\n if (totalSec < 60) return `${totalSec.toFixed(1)}s`;\n const h = Math.floor(totalSec / 3600);\n const m = Math.floor((totalSec % 3600) / 60);\n const s = Math.round(totalSec % 60);\n if (h > 0) return `${h}h ${m}m`;\n return `${m}m ${s}s`;\n}\n\nfunction formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\nfunction formatRelative(iso: string): string {\n const ts = Date.parse(iso);\n if (!Number.isFinite(ts)) return iso.slice(0, 19);\n const now = Date.now();\n const diffSec = Math.round((now - ts) / 1000);\n if (Math.abs(diffSec) < 30) return \"just now\";\n const past = diffSec >= 0;\n const abs = Math.abs(diffSec);\n if (abs < 60) return past ? `${abs}s ago` : `in ${abs}s`;\n if (abs < 3600) return past ? `${Math.round(abs / 60)}m ago` : `in ${Math.round(abs / 60)}m`;\n if (abs < 86400) return past ? `${Math.round(abs / 3600)}h ago` : `in ${Math.round(abs / 3600)}h`;\n const days = Math.round(abs / 86400);\n if (past && days === 1) return \"yesterday\";\n if (days < 7) return past ? `${days}d ago` : `in ${days}d`;\n const d = new Date(ts);\n const sameYear = d.getFullYear() === new Date().getFullYear();\n const opts: Intl.DateTimeFormatOptions = sameYear\n ? { month: \"short\", day: \"numeric\" }\n : { month: \"short\", day: \"numeric\", year: \"2-digit\" };\n return d.toLocaleDateString(undefined, opts);\n}\n","// DataTable — the table renderer.\n//\n// Presentation only: it draws headers (sort affordances), the checkbox column,\n// cells (via the render registry), the right-click CellMenu, column resize\n// handles, and the loading bar. All state\n// lives in the @pythia-software/query-table-react hook; DataTable receives the resolved view\n// and emits intents through onQueryChange. Its props mirror a conventional\n// schema-driven table so adoption is mechanical.\n\nimport { useEffect, useMemo, useRef, useState, type ReactNode, type SetStateAction } from \"react\";\nimport type { OrderByClause, QueryState, FieldDef, RowId, SelectColumn, WhereClause } from \"@pythia-software/query-table-core\";\nimport { isSortable, readFieldValue } from \"@pythia-software/query-table-core\";\nimport { useColumnDrag, type SelectionApi, type ColumnDragApi } from \"@pythia-software/query-table-react\";\nimport { resolveRenderer, type RenderRegistry } from \"./renderers\";\nimport type { TableClassNames } from \"./classNames\";\nimport { CellMenu } from \"./CellMenu\";\n\nexport interface DataTableProps<Row> {\n /** Ordered visible fields (widths already resolved), from `api.visibleFields`. */\n fields: FieldDef<Row>[];\n rows: Row[];\n query: QueryState;\n onQueryChange: (q: SetStateAction<QueryState>) => void;\n\n /** Resolves FieldDef.render keys. Pass `{ ...defaultRenderers, ...yours }`. */\n renderers: RenderRegistry<Row>;\n /** Row → stable id (defaults to reading the schema's idField). */\n rowId: (row: Row) => RowId | null;\n\n /** Optional checkbox column + selection behavior (from `api.selection`). */\n selection?: SelectionApi;\n\n /** Shared column-reorder drag state (`api.columnDrag`). Pass it so dragging a\n * table header also live-previews/dims the matching QueryBuilder select chip\n * (and vice versa). Omit for a self-contained, table-only drag. */\n columnDrag?: ColumnDragApi;\n\n /** Always-visible trailing column (row actions, links). */\n trailing?: (row: Row) => ReactNode;\n trailingLabel?: string;\n\n /** Total matching rows before pagination, when known. */\n total?: number | null;\n\n loading?: boolean;\n emptyMessage?: string;\n /** Tailwind / bespoke styling slots (Mode B). */\n classNames?: TableClassNames;\n}\n\nconst cx = (...parts: Array<string | undefined | false>): string =>\n parts.filter((p): p is string => Boolean(p)).join(\" \");\n\nconst MIN_WIDTH = 1;\nconst MIN_SELECTION_WIDTH = 1;\nconst MAX_WIDTH = 800;\nconst DEFAULT_WIDTH = 120;\nconst DEFAULT_SELECTION_WIDTH = 36;\nconst AUTOFIT_EXTRA_PX = 16;\nconst MENU_WIDTH = 240;\nconst MENU_ROW_HEIGHT = 32;\nconst COPY_FEEDBACK_MS = 900;\nconst SELECTION_COLUMN = \"__qt_selection__\";\ntype HeaderSortPlacement = \"set\" | \"append\" | \"prepend\";\n\ninterface MenuState<Row> {\n kind: \"cell\" | \"header\";\n field: FieldDef<Row>;\n value?: unknown;\n x: number;\n y: number;\n}\n\nexport function DataTable<Row>(props: DataTableProps<Row>): ReactNode {\n const {\n fields,\n rows,\n query,\n onQueryChange,\n renderers,\n rowId,\n selection,\n trailing,\n trailingLabel,\n total = null,\n loading,\n emptyMessage,\n classNames,\n } = props;\n\n const [menu, setMenu] = useState<MenuState<Row> | null>(null);\n const [resizingField, setResizingField] = useState<string | null>(null);\n const [draftWidths, setDraftWidths] = useState<Record<string, number>>({});\n const [selectionColumnWidth, setSelectionColumnWidth] = useState(DEFAULT_SELECTION_WIDTH);\n const [tableColumnOrder, setTableColumnOrder] = useState<string[]>([]);\n const [copiedCellKey, setCopiedCellKey] = useState<string | null>(null);\n const tableWrapRef = useRef<HTMLDivElement>(null);\n const resizeCommitRef = useRef<{ name: string; width: number } | null>(null);\n const resizingFieldRef = useRef<string | null>(null);\n const copiedCellTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Shared drag state when the host passes `api.columnDrag`; otherwise a local\n // instance keeps the table self-contained. (The hook is always called to obey\n // the rules of hooks; the local one is unused when a shared one is provided.)\n const localColumnDrag = useColumnDrag();\n const columnDrag = props.columnDrag ?? localColumnDrag;\n\n useEffect(() => {\n return () => {\n if (copiedCellTimerRef.current) {\n clearTimeout(copiedCellTimerRef.current);\n copiedCellTimerRef.current = null;\n }\n };\n }, []);\n\n function cellKey(rowIdValue: RowId | null, rowIndex: number, fieldName: string): string {\n return rowIdValue == null ? `row:${rowIndex}:${fieldName}` : `id:${rowIdValue}:${fieldName}`;\n }\n\n function isInteractiveTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return tag === \"A\" || tag === \"BUTTON\" || tag === \"INPUT\" || tag === \"SELECT\";\n }\n\n function showCopyFeedback(cellId: string) {\n if (copiedCellTimerRef.current) {\n clearTimeout(copiedCellTimerRef.current);\n copiedCellTimerRef.current = null;\n }\n setCopiedCellKey(cellId);\n copiedCellTimerRef.current = setTimeout(() => {\n setCopiedCellKey((current) => (current === cellId ? null : current));\n copiedCellTimerRef.current = null;\n }, COPY_FEEDBACK_MS);\n }\n\n async function copyCellToClipboard(e: React.MouseEvent, f: FieldDef<Row>, rowIdValue: RowId | null, rowIndex: number, value: unknown) {\n if (isInteractiveTarget(e.target)) return;\n e.preventDefault();\n e.stopPropagation();\n setMenu(null);\n try {\n if (navigator.clipboard) {\n await navigator.clipboard.writeText(valueToString(value));\n }\n } catch {\n /* clipboard denial is non-fatal */\n }\n showCopyFeedback(cellKey(rowIdValue, rowIndex, f.name));\n }\n\n const pageIds = rows.map(rowId).filter((id): id is RowId => id != null);\n const headerState = selection ? selection.pageState(pageIds) : \"none\";\n const showSel = selection != null;\n\n // ---- sort state (used only for indicators + header menu actions) ----\n function sortKeyFor(f: FieldDef<Row>): string {\n return f.sort?.field ?? f.name;\n }\n function applyHeaderSort(f: FieldDef<Row>, dir: \"asc\" | \"desc\", placement: HeaderSortPlacement) {\n if (!isSortable(f)) return;\n onQueryChange({\n ...query,\n offset: 0,\n orderBy: nextHeaderOrderBy(query.orderBy, sortKeyFor(f), dir, placement),\n });\n setMenu(null);\n }\n function removeColumn(f: FieldDef<Row>) {\n const explicit = materialize(query.select, fields);\n const nextSelect = explicit.filter((c) => c.field !== f.name);\n const nextOrderBy = query.orderBy.filter((s) => s.field !== sortKeyFor(f));\n if (nextSelect.length === 0) return;\n onQueryChange({ ...query, select: nextSelect, orderBy: nextOrderBy });\n setMenu(null);\n }\n function sortInfo(f: FieldDef<Row>): { dir: \"asc\" | \"desc\"; priority: number | null } | null {\n const key = sortKeyFor(f);\n const idx = query.orderBy.findIndex((o) => o.field === key);\n if (idx === -1) return null;\n const term = query.orderBy[idx]!;\n return { dir: term.dir, priority: query.orderBy.length > 1 ? idx + 1 : null };\n }\n\n // ---- width (resolved from query.select; written back through onQueryChange) ----\n function widthFor(name: string, f: FieldDef<Row>): number | undefined {\n const col = query.select.find((c) => c.field === name);\n return col?.width ?? f.select?.width;\n }\n function resolvedWidthFor(name: string, f: FieldDef<Row>): number | undefined {\n return draftWidths[name] ?? widthFor(name, f);\n }\n function resolvedColumnWidthFor(name: string, f?: FieldDef<Row>): number | undefined {\n if (name === SELECTION_COLUMN) return draftWidths[name] ?? selectionColumnWidth;\n return f ? resolvedWidthFor(name, f) : draftWidths[name];\n }\n function displayColumnWidthFor(name: string, f?: FieldDef<Row>): number {\n if (name === SELECTION_COLUMN) return resolvedColumnWidthFor(name) ?? DEFAULT_SELECTION_WIDTH;\n return f ? resolvedWidthFor(name, f) ?? DEFAULT_WIDTH : DEFAULT_WIDTH;\n }\n function clampWidth(width: number): number {\n return Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, Math.round(width)));\n }\n function clampColumnWidth(name: string, width: number): number {\n const min = name === SELECTION_COLUMN ? MIN_SELECTION_WIDTH : MIN_WIDTH;\n return Math.max(min, Math.min(MAX_WIDTH, Math.round(width)));\n }\n function commitColumnWidth(name: string, width: number) {\n if (name === SELECTION_COLUMN) {\n setSelectionColumnWidth(clampColumnWidth(name, width));\n return;\n }\n setWidth(name, width);\n }\n function setWidth(name: string, width: number) {\n const px = clampWidth(width);\n onQueryChange((prev) => ({ ...prev, select: writeWidth(prev.select, fields, name, px) }));\n }\n function setDraftWidth(name: string, width: number) {\n setDraftWidths((prev) => (prev[name] === width ? prev : { ...prev, [name]: width }));\n }\n function clearDraftWidth(name: string) {\n setDraftWidths((prev) => {\n if (!(name in prev)) return prev;\n const next = { ...prev };\n delete next[name];\n return next;\n });\n }\n function startResize(name: string, startWidth: number | undefined, e: React.PointerEvent<HTMLSpanElement>) {\n e.preventDefault();\n e.stopPropagation();\n const startX = e.clientX;\n const startW = startWidth ?? e.currentTarget.parentElement?.getBoundingClientRect().width ?? DEFAULT_WIDTH;\n const previousCursor = document.body.style.cursor;\n const previousUserSelect = document.body.style.userSelect;\n resizeCommitRef.current = null;\n resizingFieldRef.current = name;\n setResizingField(name);\n setDraftWidth(name, clampColumnWidth(name, startW));\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n const finish = () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", finish);\n window.removeEventListener(\"pointercancel\", finish);\n document.body.style.cursor = previousCursor;\n document.body.style.userSelect = previousUserSelect;\n const commit = resizeCommitRef.current;\n resizeCommitRef.current = null;\n resizingFieldRef.current = null;\n setResizingField(null);\n clearDraftWidth(name);\n if (commit) commitColumnWidth(commit.name, commit.width);\n };\n const onMove = (ev: PointerEvent) => {\n const next = clampColumnWidth(name, startW + (ev.clientX - startX));\n resizeCommitRef.current = { name, width: next };\n setDraftWidth(name, next);\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", finish);\n window.addEventListener(\"pointercancel\", finish);\n }\n function autofitColumn(name: string) {\n const wrap = tableWrapRef.current;\n if (!wrap) return;\n const selector = `[data-qt-field=\"${cssAttributeValue(name)}\"]`;\n let width = 0;\n wrap.querySelectorAll<HTMLElement>(selector).forEach((el) => {\n width = Math.max(width, el.scrollWidth);\n });\n if (width > 0) setWidth(name, width + AUTOFIT_EXTRA_PX);\n }\n function resizeWithKeyboard(name: string, startWidth: number | undefined, e: React.KeyboardEvent<HTMLSpanElement>) {\n if (e.key !== \"ArrowLeft\" && e.key !== \"ArrowRight\" && e.key !== \"Enter\") return;\n e.preventDefault();\n e.stopPropagation();\n if (e.key === \"Enter\") {\n autofitColumn(name);\n return;\n }\n const step = e.shiftKey ? 25 : 10;\n const direction = e.key === \"ArrowRight\" ? 1 : -1;\n commitColumnWidth(name, (startWidth ?? DEFAULT_WIDTH) + step * direction);\n }\n\n // ---- reorder (drag headers; writes the new SELECT order) ----\n // `overIndex` is a position in the list with the dragged column removed, which\n // is exactly where the live preview shows the dragged header, so the committed\n // order can never disagree with what the user saw.\n function reorderByIndex(from: string, overIndex: number) {\n const withoutDragged = tableColumnNames.filter((n) => n !== from);\n if (withoutDragged.length === tableColumnNames.length) return; // `from` not visible\n const at = Math.max(0, Math.min(overIndex, withoutDragged.length));\n withoutDragged.splice(at, 0, from);\n setTableColumnOrder(withoutDragged);\n const nextFieldOrder = withoutDragged.filter((name) => name !== SELECTION_COLUMN);\n if (!sameOrder(nextFieldOrder, fieldNames)) {\n onQueryChange({ ...query, select: reorderSelect(query.select, fields, nextFieldOrder) });\n }\n }\n\n const fieldByName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n const fieldNames = useMemo(() => fields.map((f) => f.name), [fields]);\n const tableColumnNames = useMemo(() => {\n if (!showSel) return fieldNames;\n const defaultOrder = [SELECTION_COLUMN, ...fieldNames];\n const valid = new Set(defaultOrder);\n const kept = tableColumnOrder.filter((name) => valid.has(name));\n const missing = defaultOrder.filter((name) => !kept.includes(name));\n return [...kept, ...missing];\n }, [fieldNames, showSel, tableColumnOrder]);\n const dragSource = columnDrag.source;\n // While dragging, render the WHOLE column (header + body cells + width) in the\n // order a drop would commit: the dragged column stays MOUNTED (removing the\n // drag-source node mid-drag aborts the native HTML5 drag) but slides to the\n // hovered slot and is dimmed. Because the rendered order IS the would-be\n // result, the live preview can never disagree with where the drop lands.\n const renderedColumnNames = useMemo(() => columnDrag.preview(tableColumnNames), [columnDrag, tableColumnNames]);\n\n // ---- selection ----\n function toggleHeader() {\n if (!selection) return;\n selection.setPage(pageIds, headerState !== \"all\");\n }\n\n // ---- cell menu ----\n function openMenu(e: React.MouseEvent, f: FieldDef<Row>, row: Row) {\n if (isInteractiveTarget(e.target)) return;\n e.preventDefault();\n setMenu({ kind: \"cell\", field: f, value: readFieldValue(f, row), x: e.clientX, y: e.clientY });\n }\n function openHeaderMenu(e: React.MouseEvent, f: FieldDef<Row>) {\n if (isInteractiveTarget(e.target)) return;\n e.preventDefault();\n setMenu({ kind: \"header\", field: f, x: e.clientX, y: e.clientY });\n }\n\n function onTableWheel(e: React.WheelEvent<HTMLDivElement>) {\n const wrap = tableWrapRef.current;\n if (!wrap) return;\n\n const canScrollHorizontally = wrap.scrollWidth > wrap.clientWidth;\n if (!canScrollHorizontally) return;\n\n const dx = e.deltaX;\n const dy = e.deltaY;\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n const prefersHorizontal = absDx > absDy * 1.25;\n\n if (dx === 0 && !e.shiftKey) return;\n\n if (dx === 0 && e.shiftKey) {\n e.preventDefault();\n e.stopPropagation();\n wrap.scrollLeft += dy;\n return;\n }\n\n if (e.shiftKey || prefersHorizontal) {\n e.preventDefault();\n e.stopPropagation();\n wrap.scrollLeft += dx;\n }\n }\n\n function resizeHandle(name: string, label: string, width: number | undefined): ReactNode {\n return (\n <span\n className={cx(\"qt-resize-handle\", classNames?.resizeHandle)}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={`Resize ${label} column`}\n title=\"Drag to resize. Press Enter to auto-fit.\"\n tabIndex={0}\n onPointerDown={(e) => startResize(name, width, e)}\n onKeyDown={(e) => resizeWithKeyboard(name, width, e)}\n onClick={(e) => e.stopPropagation()}\n />\n );\n }\n\n const totalCols = fields.length + (showSel ? 1 : 0) + (trailing ? 1 : 0);\n const tableWidth = renderedColumnNames.reduce((sum, name) => {\n const f = fieldByName.get(name);\n return sum + displayColumnWidthFor(name, f);\n }, trailing ? 40 : 0);\n const start = query.offset;\n const end = total != null ? Math.min(start + query.limit, total) : start + rows.length;\n const canPrev = start > 0;\n const canNext = total != null ? end < total : rows.length >= query.limit;\n const prevPage = () => onQueryChange((prev) => ({ ...prev, offset: Math.max(0, prev.offset - prev.limit) }));\n const nextPage = () => onQueryChange((prev) => ({ ...prev, offset: prev.offset + prev.limit }));\n const summaryText =\n total == null || total === 0 ? `${rows.length} rows` : `${start + 1}–${end} of ${total}`;\n\n return (\n <>\n <div\n ref={tableWrapRef}\n className={cx(\n \"qt-table-wrap\",\n loading && \"qt-table-wrap--loading\",\n !!resizingField && \"qt-table-wrap--resizing\",\n classNames?.wrap,\n )}\n onWheel={onTableWheel}\n >\n {loading && (\n <div className={cx(\"qt-loading-bar\", classNames?.loadingBar)} role=\"progressbar\" aria-label=\"loading\" />\n )}\n <table className={cx(\"qt-table\", classNames?.table)} style={{ minWidth: tableWidth }}>\n <colgroup>\n {renderedColumnNames.map((name) => {\n const f = fieldByName.get(name);\n const w = displayColumnWidthFor(name, f);\n if (name === SELECTION_COLUMN) return <col key={name} style={{ width: w }} />;\n if (!f) return null;\n return <col key={f.name} style={{ width: w }} />;\n })}\n {trailing && <col style={{ width: 40 }} />}\n </colgroup>\n <thead className={classNames?.thead}>\n <tr className={classNames?.headerRow}>\n {renderedColumnNames.map((name) => {\n if (name === SELECTION_COLUMN) {\n return (\n <th\n key={name}\n data-qt-field={name}\n className={cx(\n \"qt-th\",\n \"qt-checkbox-cell\",\n dragSource === name && \"qt-th--dragging\",\n resizingField === name && \"qt-th--resizing\",\n classNames?.th,\n classNames?.checkboxCell,\n )}\n draggable={resizingField == null}\n onDragStart={(e) => {\n if (resizingFieldRef.current) {\n e.preventDefault();\n return;\n }\n columnDrag.start(name, tableColumnNames.indexOf(name));\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", name);\n }}\n onDragOver={(e) => {\n if (!columnDrag.source) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (columnDrag.source !== name) {\n const withoutDragged = tableColumnNames.filter((n) => n !== columnDrag.source);\n let next = withoutDragged.indexOf(name);\n if (next >= 0) {\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n columnDrag.over(next);\n }\n }\n }}\n onDrop={(e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n const from = columnDrag.source || e.dataTransfer.getData(\"text/plain\");\n if (from && columnDrag.overIndex != null) reorderByIndex(from, columnDrag.overIndex);\n columnDrag.end();\n }}\n onDragEnd={() => columnDrag.end()}\n >\n <input\n type=\"checkbox\"\n checked={headerState === \"all\"}\n ref={(el) => {\n if (el) el.indeterminate = headerState === \"some\";\n }}\n onChange={toggleHeader}\n aria-label=\"select all on page\"\n />\n {resizeHandle(name, \"selection\", resolvedColumnWidthFor(name))}\n </th>\n );\n }\n const f = fieldByName.get(name);\n if (!f) return null;\n const info = sortInfo(f);\n const sortable = isSortable(f);\n return (\n <th\n // Stable key (not index-based): while dragging, React must\n // MOVE the dragged <th>, not remount it — a remount removes\n // the drag source and aborts the native drag.\n key={f.name}\n data-qt-field={f.name}\n className={cx(\n \"qt-th\",\n sortable && \"qt-th--sortable\",\n dragSource === f.name && \"qt-th--dragging\",\n resizingField === f.name && \"qt-th--resizing\",\n classNames?.th,\n )}\n style={f.select?.align ? { textAlign: f.select.align } : undefined}\n draggable={resizingField == null}\n onDragStart={(e) => {\n if (resizingFieldRef.current) {\n e.preventDefault();\n return;\n }\n columnDrag.start(f.name, tableColumnNames.indexOf(f.name));\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", f.name);\n }}\n onDragOver={(e) => {\n if (!columnDrag.source) return;\n // preventDefault on every header (incl. the dragged one) so\n // there is no dead drop zone anywhere along the row.\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (columnDrag.source !== f.name) {\n const withoutDragged = tableColumnNames.filter((n) => n !== columnDrag.source);\n let next = withoutDragged.indexOf(f.name);\n if (next >= 0) {\n // Drop after the hovered header when past its midpoint,\n // so a column can be moved into the last slot.\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n columnDrag.over(next);\n }\n }\n }}\n onDrop={(e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n const from = columnDrag.source || e.dataTransfer.getData(\"text/plain\");\n if (from && columnDrag.overIndex != null) reorderByIndex(from, columnDrag.overIndex);\n columnDrag.end();\n }}\n onDragEnd={() => columnDrag.end()}\n >\n <span\n className=\"qt-th-label\"\n onClick={(e) => openHeaderMenu(e, f)}\n style={{ cursor: \"pointer\" }}\n title=\"Click to open column actions\"\n >\n {f.label}\n {info && (\n <span className=\"qt-sort-indicator\">\n {info.dir === \"asc\" ? \" ↑\" : \" ↓\"}\n {info.priority != null && <sup className=\"qt-sort-priority\">{info.priority}</sup>}\n </span>\n )}\n </span>\n {resizeHandle(f.name, f.label, resolvedColumnWidthFor(f.name, f))}\n </th>\n );\n })}\n {trailing && <th className={cx(\"qt-th\", classNames?.th)}>{trailingLabel ?? \"\"}</th>}\n </tr>\n </thead>\n <tbody className={classNames?.tbody}>\n {rows.length === 0 && (\n <tr>\n <td colSpan={totalCols} className={cx(\"qt-cell\", \"qt-empty\", classNames?.empty)}>\n {emptyMessage ?? \"No rows.\"}\n </td>\n </tr>\n )}\n {rows.map((row, i) => {\n const id = rowId(row);\n const selected = id != null && selection ? selection.isSelected(id) : false;\n return (\n <tr\n key={id != null ? String(id) : i}\n className={cx(\"qt-row\", selected && \"qt-row--selected\", classNames?.row, selected && classNames?.rowSelected)}\n >\n {renderedColumnNames.map((name) => {\n if (name === SELECTION_COLUMN) {\n return (\n <td\n key={name}\n data-qt-field={name}\n className={cx(\n \"qt-cell\",\n \"qt-checkbox-cell\",\n dragSource === name && \"qt-cell--dragging\",\n classNames?.cell,\n classNames?.checkboxCell,\n )}\n >\n {id != null && (\n <input\n type=\"checkbox\"\n checked={selected}\n // Shift-range select is handled inside selection.toggle.\n onClick={(e) => selection!.toggle(id, e.shiftKey)}\n onChange={() => {\n /* state owned by selection; onClick drives it */\n }}\n aria-label={`select row ${String(id)}`}\n />\n )}\n </td>\n );\n }\n const f = fieldByName.get(name);\n if (!f) return null;\n const render = resolveRenderer(f, renderers);\n const value = readFieldValue(f, row);\n const key = cellKey(id, i, f.name);\n return (\n <td\n key={f.name}\n data-qt-field={f.name}\n className={cx(\"qt-cell\", dragSource === f.name && \"qt-cell--dragging\", classNames?.cell)}\n style={f.select?.align ? { textAlign: f.select.align } : undefined}\n onClick={(e) => openMenu(e, f, row)}\n onContextMenu={(e) => openMenu(e, f, row)}\n onDoubleClick={(e) => copyCellToClipboard(e, f, id, i, value)}\n >\n {copiedCellKey === key ? <span className=\"qt-cell-copy-chip\">✓ copied</span> : render({ value, row, field: f, query })}\n </td>\n );\n })}\n {trailing && <td className={cx(\"qt-cell\", \"qt-trailing-cell\", classNames?.cell)}>{trailing(row)}</td>}\n </tr>\n );\n })}\n </tbody>\n <tfoot>\n <tr className={cx(\"qt-table-summary-row\", classNames?.summaryRow)}>\n <td colSpan={totalCols} className={cx(\"qt-cell\", \"qt-table-summary-cell\", classNames?.summaryCell)}>\n <div className={cx(\"qt-table-summary\", classNames?.summaryControls)}>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.summaryButton)}\n disabled={loading || !canPrev}\n onClick={prevPage}\n >\n ← prev\n </button>\n <span className={cx(\"qt-table-summary-hint\", classNames?.summaryHint)}>{summaryText}</span>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.summaryButton)}\n disabled={loading || !canNext}\n onClick={nextPage}\n >\n next →\n </button>\n </div>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n {menu && (\n menu.kind === \"cell\" ? (\n <CellMenu\n field={menu.field}\n value={menu.value}\n x={menu.x}\n y={menu.y}\n onAddFilter={(clause: WhereClause) =>\n onQueryChange((prev) => ({ ...prev, offset: 0, where: [...prev.where, clause] }))\n }\n onClose={() => setMenu(null)}\n />\n ) : (\n <HeaderMenu\n field={menu.field}\n x={menu.x}\n y={menu.y}\n sortable={isSortable(menu.field)}\n canRemoveColumn={fields.length > 1}\n onSetSort={(placement, dir) => applyHeaderSort(menu.field, dir, placement)}\n onRemove={() => removeColumn(menu.field)}\n onClose={() => setMenu(null)}\n />\n )\n )}\n </>\n );\n}\n\nfunction HeaderMenu<Row>({\n field,\n x,\n y,\n sortable,\n canRemoveColumn,\n onSetSort,\n onRemove,\n onClose,\n}: {\n field: FieldDef<Row>;\n x: number;\n y: number;\n sortable: boolean;\n canRemoveColumn: boolean;\n onSetSort: (placement: HeaderSortPlacement, dir: \"asc\" | \"desc\") => void;\n onRemove: () => void;\n onClose: () => void;\n}) {\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n function onDocClick() {\n onClose();\n }\n window.addEventListener(\"keydown\", onKey);\n const t = setTimeout(() => window.addEventListener(\"click\", onDocClick), 0);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"click\", onDocClick);\n clearTimeout(t);\n };\n }, [onClose]);\n\n const items: ReactNode[] = [];\n const addSortItem = (placement: HeaderSortPlacement, dir: \"asc\" | \"desc\", label: string) =>\n items.push(\n <MenuItem key={`${placement}-${dir}`} disabled={!sortable} onClick={() => onSetSort(placement, dir)}>\n {label}\n </MenuItem>,\n );\n\n addSortItem(\"set\", \"asc\", \"Set Sort (Asc)\");\n addSortItem(\"set\", \"desc\", \"Set Sort (Desc)\");\n addSortItem(\"append\", \"asc\", \"Append Sort (Asc)\");\n addSortItem(\"append\", \"desc\", \"Append Sort (Desc)\");\n addSortItem(\"prepend\", \"asc\", \"Prepend Sort (Asc)\");\n addSortItem(\"prepend\", \"desc\", \"Prepend Sort (Desc)\");\n\n items.push(<div key=\"sep\" className=\"qt-cm-sep\" />);\n items.push(\n <MenuItem key=\"remove\" disabled={!canRemoveColumn} onClick={onRemove}>\n Remove Column\n </MenuItem>,\n );\n\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 9999;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 9999;\n const left = Math.max(8, Math.min(x, vw - MENU_WIDTH - 8));\n const top = Math.max(8, Math.min(y, vh - MENU_ROW_HEIGHT * items.length - 8));\n\n return (\n <div\n className=\"qt-cell-menu\"\n style={{ left, top, width: MENU_WIDTH }}\n onClick={(e) => e.stopPropagation()}\n onContextMenu={(e) => e.preventDefault()}\n role=\"menu\"\n >\n <div className=\"qt-cm-header\">\n <span className=\"qt-cm-field\">{field.label}</span>\n </div>\n {items}\n </div>\n );\n}\n\nfunction MenuItem({\n children,\n onClick,\n disabled,\n}: {\n children: ReactNode;\n onClick: () => void;\n disabled?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n className=\"qt-cm-item\"\n onClick={onClick}\n role=\"menuitem\"\n disabled={disabled}\n >\n {children}\n </button>\n );\n}\n\n/** Header menu sort helper for set / append / prepend actions. */\nfunction nextHeaderOrderBy(\n existing: OrderByClause[],\n field: string,\n dir: \"asc\" | \"desc\",\n placement: HeaderSortPlacement,\n): OrderByClause[] {\n const next = existing.filter((s) => s.field !== field);\n if (placement === \"set\") return [{ field, dir }];\n if (placement === \"append\") return [...next, { field, dir }];\n return [{ field, dir }, ...next];\n}\n\n/** Materialize the current visible order into SelectColumn[] so width/order\n * edits diverge from schema defaults cleanly (mirrors useSelect.writeSelect). */\nfunction materialize<Row>(select: SelectColumn[], fields: FieldDef<Row>[]): SelectColumn[] {\n if (select.length) return select.map((c) => ({ ...c }));\n return fields.map((f) => ({ field: f.name }));\n}\n\nfunction writeWidth<Row>(select: SelectColumn[], fields: FieldDef<Row>[], name: string, width: number): SelectColumn[] {\n const cols = materialize(select, fields);\n let found = false;\n const next = cols.map((c) => {\n if (c.field !== name) return c;\n found = true;\n return { ...c, width };\n });\n if (!found) next.push({ field: name, width });\n return next;\n}\n\nfunction reorderSelect<Row>(select: SelectColumn[], fields: FieldDef<Row>[], order: string[]): SelectColumn[] {\n const cols = materialize(select, fields);\n const byName = new Map(cols.map((c) => [c.field, c]));\n return order.map((name) => byName.get(name) ?? { field: name });\n}\n\nfunction cssAttributeValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction sameOrder(a: string[], b: string[]): boolean {\n return a.length === b.length && a.every((value, index) => value === b[index]);\n}\n\nfunction valueToString(value: unknown): string {\n if (value == null) return \"\";\n if (Array.isArray(value)) return value.join(\", \");\n return String(value);\n}\n","// CellMenu — right-click (or left-click) a cell → quick-filter popover + copy.\n// Offers only the operators valid for that field's type (opsForField), prefilled\n// with the clicked cell's value, plus \"copy value\". Anchors just off the click\n// point and clamps to the viewport. Present in both source projects; unified here.\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { FieldDef, FilterOp, WhereClause } from \"@pythia-software/query-table-core\";\nimport { NULLARY_OPS, opsForField } from \"@pythia-software/query-table-core\";\nimport type { MenuClassNames } from \"./classNames\";\n\nexport interface CellMenuProps<Row> {\n field: FieldDef<Row>;\n value: unknown;\n /** Viewport coordinates of the click. */\n x: number;\n y: number;\n onAddFilter: (clause: WhereClause) => void;\n onClose: () => void;\n classNames?: MenuClassNames;\n}\n\nconst cx = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/** Approximate sizing so the popover can clamp itself into the viewport. */\nconst MENU_WIDTH = 240;\nconst ROW_HEIGHT = 32;\nconst POINTER_OFFSET = 4;\n\nexport function CellMenu<Row>({ field, value, x, y, onAddFilter, onClose, classNames }: CellMenuProps<Row>): ReactNode {\n // Dismiss on Escape or an outside click. The opening click is deferred a tick\n // so it doesn't immediately re-close the freshly-opened menu.\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n function onDocClick() {\n onClose();\n }\n window.addEventListener(\"keydown\", onKey);\n const t = setTimeout(() => window.addEventListener(\"click\", onDocClick), 0);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"click\", onDocClick);\n clearTimeout(t);\n };\n }, [onClose]);\n\n const ops = opsForField(field);\n const isArray = Array.isArray(value);\n const isNullish = value == null || value === \"\" || (isArray && (value as unknown[]).length === 0);\n\n function apply(op: FilterOp, raw?: string) {\n const v = raw != null ? raw : valueToString(value);\n onAddFilter({ field: field.name, op, value: NULLARY_OPS.has(op) ? \"\" : v });\n onClose();\n }\n\n // Build the actionable filter items. For arrays we offer a per-element\n // shortcut (so a tag column filters by the clicked tag); otherwise we offer\n // every operator the field type allows, prefilled with the cell value.\n const filterItems: ReactNode[] = [];\n if (isArray && !isNullish) {\n (value as unknown[]).forEach((el, i) => {\n const s = String(el);\n const arrayOp: FilterOp = ops.includes(\"includes\") ? \"includes\" : ops[0] ?? \"=\";\n filterItems.push(\n <MenuItem key={`el-${i}`} classNames={classNames} onClick={() => apply(arrayOp, s)}>\n filter: {opSymbol(arrayOp)} <code>{s}</code>\n </MenuItem>,\n );\n });\n }\n for (const op of ops) {\n const nullary = NULLARY_OPS.has(op);\n // When the cell is empty, only the nullary ops make sense; when it has a\n // value, offer both (so a user can still ask \"is null\" off a present cell).\n if (isNullish && !nullary) continue;\n // Array element shortcuts above already covered the value ops.\n if (isArray && !nullary && !isNullish) continue;\n filterItems.push(\n <MenuItem key={op} classNames={classNames} onClick={() => apply(op)}>\n filter: {opSymbol(op)}\n {!nullary && !isNullish ? <> <code>{previewValue(value)}</code></> : null}\n </MenuItem>,\n );\n }\n\n const copyItem = (\n <MenuItem\n key=\"copy\"\n classNames={classNames}\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(valueToString(value));\n } catch {\n /* clipboard denial is non-fatal */\n }\n onClose();\n }}\n >\n copy value\n </MenuItem>\n );\n\n const items: ReactNode[] = [\n <div key=\"header\" className=\"qt-cm-header\">\n <span className=\"qt-cm-field\">{field.label}</span>\n <span className=\"qt-cm-value\">{previewValue(value)}</span>\n </div>,\n copyItem,\n <div key=\"sep\" className={cx(\"qt-cm-sep\", classNames?.separator)} />,\n ...filterItems,\n ];\n\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 9999;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 9999;\n const left = Math.max(8, Math.min(x + POINTER_OFFSET, vw - MENU_WIDTH - 8));\n const top = Math.max(8, Math.min(y + POINTER_OFFSET, vh - ROW_HEIGHT * items.length - 8));\n\n return (\n <div\n className={cx(\"qt-cell-menu\", classNames?.popover)}\n style={{ left, top, width: MENU_WIDTH }}\n onClick={(e) => e.stopPropagation()}\n onContextMenu={(e) => e.preventDefault()}\n role=\"menu\"\n >\n {items}\n </div>\n );\n}\n\nfunction MenuItem({\n children,\n onClick,\n classNames,\n}: {\n children: ReactNode;\n onClick: () => void;\n classNames: MenuClassNames | undefined;\n}) {\n return (\n <button type=\"button\" className={cx(\"qt-cm-item\", classNames?.item)} onClick={onClick} role=\"menuitem\">\n {children}\n </button>\n );\n}\n\nfunction opSymbol(op: FilterOp): string {\n switch (op) {\n case \"!=\":\n return \"≠\";\n case \">=\":\n return \"≥\";\n case \"<=\":\n return \"≤\";\n case \"is_null\":\n return \"is null\";\n case \"is_not_null\":\n return \"is not null\";\n default:\n return op;\n }\n}\n\nfunction valueToString(v: unknown): string {\n if (v == null) return \"\";\n if (Array.isArray(v)) return v.join(\", \");\n return String(v);\n}\n\nfunction previewValue(v: unknown): string {\n if (v == null || v === \"\") return \"(empty)\";\n if (Array.isArray(v)) {\n return v.length === 0 ? \"(empty)\" : `[${v.length}] ${v.slice(0, 2).join(\", \")}${v.length > 2 ? \"…\" : \"\"}`;\n }\n const s = String(v);\n return s.length > 50 ? s.slice(0, 50) + \"…\" : s;\n}\n","// QueryBuilder — the chip toolbar: WHERE filters, SELECT columns, ORDER BY\n// (multi-sort, reorderable), and LIMIT/OFFSET paging. Type-aware filter inputs\n// (enum/static <select>, value autocomplete via Transport.fetchDistinctValues).\n// Hosts the Save / saved-queries entry point.\n//\n// Combines a chip layout, autocomplete, draggable column chips, a grouped\n// picker, per-clause operators, and multi-sort.\n\nimport { useEffect, useId, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport type {\n AggOp,\n AggregationClause,\n DistinctValuesResult,\n FieldDef,\n FilterOp,\n OrderByClause,\n WhereClause,\n} from \"@pythia-software/query-table-core\";\nimport {\n NULLARY_OPS,\n aggOpNeedsField,\n aggOpsForField,\n filterValues as filterValuesFor,\n isGroupable,\n isMeasurable,\n queriesEqual,\n isFilterable,\n isSelectable,\n isSortable,\n opsForField,\n} from \"@pythia-software/query-table-core\";\nimport type { QueryTableApi } from \"@pythia-software/query-table-react\";\nimport type { QueryBuilderClassNames } from \"./classNames\";\nimport { FieldPicker } from \"./FieldPicker\";\nimport { SavedQueriesModal } from \"./SavedQueriesModal\";\n\nexport interface QueryBuilderProps<Row> {\n /** The controller; QueryBuilder drives it through the intent helpers. */\n api: QueryTableApi<Row>;\n /** All schema fields (for the field picker / sort picker). */\n fields: FieldDef<Row>[];\n /** Total matching rows, for the \"N of M\" paging hint. */\n total: number | null;\n /** Disable inputs while a fetch is in flight. */\n running?: boolean;\n classNames?: QueryBuilderClassNames;\n /** Use this to control collapse state from a parent UI. */\n collapsed?: boolean;\n /** Controlled collapse callback (use when `collapsed` is provided). */\n onCollapsedChange?: (collapsed: boolean) => void;\n /** Initial collapse state for uncontrolled mode. */\n defaultCollapsed?: boolean;\n}\n\nconst cx = (...parts: Array<string | undefined | false>): string =>\n parts.filter((p): p is string => Boolean(p)).join(\" \");\n\nconst MAX_AUTO_REFRESH_POLLS = 1000;\nconst DEFAULT_AUTO_REFRESH_FREQUENCY_MS = 20_000;\nconst DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS = 5 * 60_000;\n\nconst AUTO_REFRESH_FREQUENCIES = [\n { label: \"Every 5s\", value: 5_000 },\n { label: \"Every 10s\", value: 10_000 },\n { label: \"Every 20s\", value: DEFAULT_AUTO_REFRESH_FREQUENCY_MS },\n { label: \"Every 30s\", value: 30_000 },\n { label: \"Every 1m\", value: 60_000 },\n { label: \"Every 2m\", value: 2 * 60_000 },\n { label: \"Every 5m\", value: 5 * 60_000 },\n { label: \"Every 10m\", value: 10 * 60_000 },\n] as const;\n\nconst AUTO_REFRESH_TURN_OFF_AFTER = [\n { label: \"After 5m\", value: DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS },\n { label: \"After 15m\", value: 15 * 60_000 },\n { label: \"After 30m\", value: 30 * 60_000 },\n { label: \"After 1h\", value: 60 * 60_000 },\n { label: \"After 2h\", value: 2 * 60 * 60_000 },\n { label: \"After 4h\", value: 4 * 60 * 60_000 },\n { label: \"After 8h\", value: 8 * 60 * 60_000 },\n { label: \"After 12h\", value: 12 * 60 * 60_000 },\n { label: \"After 24h\", value: 24 * 60 * 60_000 },\n] as const;\n\nfunction autoRefreshPolls(frequencyMs: number, turnOffAfterMs: number): number {\n if (frequencyMs <= 0 || turnOffAfterMs <= 0) return Infinity;\n return Math.floor(turnOffAfterMs / frequencyMs);\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.round(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = minutes / 60;\n return Number.isInteger(hours) ? `${hours}h` : `${minutes}m`;\n}\n\nfunction formatStatusTime(ms: number | null): string {\n if (ms == null) return \"never\";\n return new Date(ms).toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\", second: \"2-digit\" });\n}\n\nfunction useFieldHasNull<Row>(api: QueryTableApi<Row>, fieldName: string | undefined): boolean | undefined {\n const [hasNull, setHasNull] = useState<boolean | undefined>(undefined);\n\n useEffect(() => {\n if (!fieldName) return;\n let cancelled = false;\n\n void api\n .filterValues(fieldName, \"\")\n .then((r) => {\n if (!cancelled && typeof r.hasNull === \"boolean\") {\n setHasNull(r.hasNull);\n }\n })\n .catch(() => {\n if (!cancelled) setHasNull(undefined);\n });\n\n return () => {\n cancelled = true;\n };\n }, [api, fieldName]);\n\n return hasNull;\n}\n\nfunction whereClauseAsText<Row>(clause: WhereClause, byName: Map<string, FieldDef<Row>>): string {\n const field = byName.get(clause.field)?.label ?? clause.field;\n const op = clause.op.replace(/_/g, \" \");\n if (NULLARY_OPS.has(clause.op)) return `${field} ${op}`;\n const value = clause.value === \"\" ? \"''\" : clause.value;\n return `${field} ${op} ${value}`;\n}\n\nfunction orderByAsText<Row>(term: OrderByClause, byName: Map<string, FieldDef<Row>>): string {\n const field = byName.get(term.field)?.label ?? term.field;\n const nulls = term.nulls ? ` nulls ${term.nulls}` : \"\";\n return `${field} ${term.dir}${nulls}`;\n}\n\nfunction chipFieldWidthChars(text: string, fallback = 5, max = 30): number {\n return Math.min(max, Math.max(fallback, (text || \"\").length + 1));\n}\n\nfunction chipFieldWidthForInput(text: string, fieldType: string | undefined, fallback = 5, padding = 0): number {\n const cap = fieldType === \"number\" ? 10 : 30;\n return chipFieldWidthChars(text, fallback, cap) + padding;\n}\n\nfunction chipFieldWidthForSelect(text: string, fallback = 3, max = 30): number {\n return chipFieldWidthChars(text, fallback, max) + 2;\n}\n\nfunction buildCollapsedSummary<Row>(\n where: WhereClause[],\n orderBy: OrderByClause[],\n byName: Map<string, FieldDef<Row>>,\n): string {\n const whereText = where.length === 0 ? \"all rows\" : where.map((c) => whereClauseAsText(c, byName)).join(\" and \");\n const orderText = orderBy.length === 0 ? \"(default)\" : orderBy.map((term) => orderByAsText(term, byName)).join(\", \");\n return `WHERE ${whereText} ORDER BY ${orderText}`;\n}\n\nfunction whereClauseSummaryText<Row>(where: WhereClause[], byName: Map<string, FieldDef<Row>>): string {\n return where.length === 0 ? \"all rows\" : where.map((c) => whereClauseAsText(c, byName)).join(\" and \");\n}\n\nfunction orderBySummaryText<Row>(orderBy: OrderByClause[], byName: Map<string, FieldDef<Row>>): string {\n return orderBy.length === 0 ? \"(default)\" : orderBy.map((term) => orderByAsText(term, byName)).join(\", \");\n}\n\nexport function QueryBuilder<Row>({\n api,\n fields,\n total,\n running,\n classNames,\n collapsed,\n onCollapsedChange,\n defaultCollapsed = false,\n}: QueryBuilderProps<Row>): ReactNode {\n const UNSAVED_QUERY_EDIT_ID = \"__qt-unsaved-query__\";\n const [showSaved, setShowSaved] = useState(false);\n const [showAutoRefresh, setShowAutoRefresh] = useState(false);\n const [autoRefreshFrequencyMs, setAutoRefreshFrequencyMs] = useState(DEFAULT_AUTO_REFRESH_FREQUENCY_MS);\n const [autoRefreshTurnOffAfterMs, setAutoRefreshTurnOffAfterMs] = useState(DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS);\n const [editingSavedId, setEditingSavedId] = useState<string | null>(null);\n const [editingSavedName, setEditingSavedName] = useState(\"\");\n const [lastSavedId, setLastSavedId] = useState<string | null>(null);\n const [collapsedFallback, setCollapsedFallback] = useState(defaultCollapsed);\n const collapsedControlled = typeof collapsed !== \"undefined\";\n const isCollapsed = collapsedControlled ? collapsed : collapsedFallback;\n const setCollapsed = (next: boolean) => {\n if (collapsedControlled) {\n onCollapsedChange?.(next);\n return;\n }\n setCollapsedFallback(next);\n };\n const [lastUpdatedAt, setLastUpdatedAt] = useState<number | null>(null);\n const [lastFailureAt, setLastFailureAt] = useState<number | null>(null);\n const byName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n const activeSavedQuery = useMemo(\n () => api.saved.items.find((item) => queriesEqual(item.query, api.query)),\n [api.query, api.saved.items],\n );\n const lastSavedQuery = useMemo(\n () => api.saved.items.find((item) => item.id === lastSavedId) ?? null,\n [api.saved.items, lastSavedId],\n );\n const isSavedQuery = activeSavedQuery != null;\n const isEditingUnsaved = editingSavedId === UNSAVED_QUERY_EDIT_ID;\n const bodyId = useId();\n const isEditingSaved = editingSavedId != null && activeSavedQuery?.id === editingSavedId;\n const showUpdateButton = Boolean(lastSavedQuery) && !activeSavedQuery;\n const collapsedSummary = useMemo(\n () => buildCollapsedSummary(api.query.where, api.query.orderBy, byName),\n [api.query.where, api.query.orderBy, byName],\n );\n const collapsedWhereText = useMemo(\n () => whereClauseSummaryText(api.query.where, byName),\n [api.query.where, byName],\n );\n const collapsedOrderText = useMemo(\n () => orderBySummaryText(api.query.orderBy, byName),\n [api.query.orderBy, byName],\n );\n const autoRefreshStatus = api.autoRefresh.status;\n const selectedAutoRefreshPolls = autoRefreshPolls(autoRefreshFrequencyMs, autoRefreshTurnOffAfterMs);\n const canSubmitAutoRefresh = selectedAutoRefreshPolls >= 1 && selectedAutoRefreshPolls <= MAX_AUTO_REFRESH_POLLS;\n const autoRefreshButtonText = autoRefreshStatus\n ? `⟳ Auto-Update ${formatDuration(autoRefreshStatus.frequencyMs)}`\n : \"⟳ Auto-Update\";\n const rowSummary = `${api.rows.length} of ${total ?? \"?\"}`;\n const lastUpdatedText = formatStatusTime(lastUpdatedAt);\n const failureText = api.error\n ? `Error: ${api.error.message}`\n : lastFailureAt\n ? `Last failure at ${formatStatusTime(lastFailureAt)}`\n : null;\n const isBusy = Boolean(running) || api.loading;\n const lastRowsRef = useRef<Row[] | null>(null);\n const lastTotalRef = useRef<number | null>(null);\n const previousLoadingRef = useRef(api.loading);\n const autoRefreshRef = useRef<HTMLSpanElement>(null);\n const autoRefreshPopoverRef = useRef<HTMLSpanElement>(null);\n const [autoRefreshPopoverAlignRight, setAutoRefreshPopoverAlignRight] = useState(false);\n\n useEffect(() => {\n if (activeSavedQuery) {\n setLastSavedId(activeSavedQuery.id);\n if (!isEditingSaved) {\n setEditingSavedName(activeSavedQuery.name);\n setEditingSavedId(null);\n }\n return;\n }\n\n if (!isEditingUnsaved) {\n setEditingSavedId(null);\n setEditingSavedName(\"\");\n }\n // activeSavedQuery can become null if edits/loads shift to unsaved or another query\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeSavedQuery, isEditingSaved, isEditingUnsaved]);\n\n useEffect(() => {\n if (!lastSavedId || api.saved.items.some((item) => item.id === lastSavedId)) return;\n setLastSavedId(null);\n }, [api.saved.items, lastSavedId]);\n\n useEffect(() => {\n const hasData = api.rows.length > 0 || total != null;\n const rowsChanged = lastRowsRef.current !== api.rows;\n const totalChanged = lastTotalRef.current !== total;\n const loadingDone = !api.loading;\n\n if (loadingDone && api.error) {\n setLastFailureAt(Date.now());\n lastRowsRef.current = api.rows;\n lastTotalRef.current = total;\n previousLoadingRef.current = api.loading;\n return;\n }\n\n if (\n loadingDone &&\n (previousLoadingRef.current || rowsChanged || totalChanged || lastUpdatedAt == null) &&\n hasData\n ) {\n setLastUpdatedAt(Date.now());\n setLastFailureAt(null);\n lastRowsRef.current = api.rows;\n lastTotalRef.current = total;\n }\n previousLoadingRef.current = api.loading;\n }, [api.error, api.loading, api.rows, total, lastUpdatedAt]);\n\n function saveFailed(error: unknown): void {\n const message = error instanceof Error ? error.message : \"Failed to save query.\";\n if (typeof window !== \"undefined\") window.alert(message);\n }\n\n function beginEditSavedName() {\n if (activeSavedQuery) {\n setEditingSavedId(activeSavedQuery.id);\n setEditingSavedName(activeSavedQuery.name);\n return;\n }\n if (isEditingUnsaved) return;\n setEditingSavedId(UNSAVED_QUERY_EDIT_ID);\n setEditingSavedName((next) => (next ? next : \"Custom Query\"));\n }\n\n function cancelNameEdit() {\n setEditingSavedId(null);\n setEditingSavedName(\"\");\n }\n\n async function persistSavedQuery(name: string): Promise<string | null> {\n const trimmed = name.trim();\n if (!trimmed) return null;\n try {\n const saved = await api.saved.save(trimmed);\n setLastSavedId(saved.id);\n return saved.id;\n } catch (error) {\n saveFailed(error);\n return null;\n }\n }\n\n async function commitSavedNameEdit() {\n if (!isEditingSaved || !activeSavedQuery) return;\n const trimmed = editingSavedName.trim();\n if (!trimmed || trimmed === activeSavedQuery.name) {\n cancelNameEdit();\n return;\n }\n const savedId = await persistSavedQuery(trimmed);\n if (!savedId) return;\n await api.saved.remove(activeSavedQuery.id);\n cancelNameEdit();\n }\n\n async function commitUnsavedNameEdit() {\n if (!isEditingUnsaved) return;\n const savedId = await persistSavedQuery(editingSavedName);\n if (!savedId) {\n cancelNameEdit();\n return;\n }\n cancelNameEdit();\n }\n\n async function updateLastSavedQuery() {\n if (!lastSavedQuery) return;\n const wasDefault = api.saved.defaultId === lastSavedQuery.id;\n const trimmedName = lastSavedQuery.name.trim();\n if (!trimmedName) return;\n\n try {\n await api.saved.remove(lastSavedQuery.id);\n const saved = await api.saved.save(trimmedName);\n if (wasDefault) await api.saved.setDefault(saved.id);\n setLastSavedId(saved.id);\n } catch (error) {\n saveFailed(error);\n }\n }\n\n function commitNameEditor() {\n if (isEditingSaved) {\n void commitSavedNameEdit();\n return;\n }\n if (isEditingUnsaved) {\n void commitUnsavedNameEdit();\n return;\n }\n }\n\n useEffect(() => {\n if (isCollapsed) setShowSaved(false);\n }, [isCollapsed]);\n\n useEffect(() => {\n if (!showAutoRefresh || !autoRefreshStatus) return;\n setAutoRefreshFrequencyMs(autoRefreshStatus.frequencyMs);\n setAutoRefreshTurnOffAfterMs(autoRefreshStatus.turnOffAfterMs);\n }, [showAutoRefresh, autoRefreshStatus]);\n\n useEffect(() => {\n if (!showAutoRefresh) return;\n\n function onDocumentClick(event: MouseEvent) {\n const wrapper = autoRefreshRef.current;\n const target = event.target as Node | null;\n if (!wrapper || !target) return;\n if (!wrapper.contains(target)) setShowAutoRefresh(false);\n }\n\n function onDocumentKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") setShowAutoRefresh(false);\n }\n\n function calculateAutoRefreshPosition() {\n const popover = autoRefreshPopoverRef.current;\n const wrapper = autoRefreshRef.current;\n if (!popover || !wrapper) return;\n const wrapperRect = wrapper.getBoundingClientRect();\n const popWidth = popover.offsetWidth;\n const viewportRightInset = 8;\n setAutoRefreshPopoverAlignRight(wrapperRect.right + popWidth > window.innerWidth - viewportRightInset);\n }\n\n calculateAutoRefreshPosition();\n const t = setTimeout(() => window.addEventListener(\"click\", onDocumentClick), 0);\n window.addEventListener(\"keydown\", onDocumentKeyDown);\n window.addEventListener(\"resize\", calculateAutoRefreshPosition);\n return () => {\n clearTimeout(t);\n window.removeEventListener(\"click\", onDocumentClick);\n window.removeEventListener(\"keydown\", onDocumentKeyDown);\n window.removeEventListener(\"resize\", calculateAutoRefreshPosition);\n };\n }, [showAutoRefresh]);\n\n function submitAutoRefresh() {\n if (!canSubmitAutoRefresh) return;\n try {\n api.autoRefresh.start({\n frequencyMs: autoRefreshFrequencyMs,\n turnOffAfterMs: autoRefreshTurnOffAfterMs,\n });\n setShowAutoRefresh(false);\n } catch (error) {\n saveFailed(error);\n }\n }\n\n return (\n <div className={cx(\"qt-qb\", classNames?.root)}>\n <div className=\"qt-qb-bar qt-qb-state-bar qt-qb-row\">\n <span className=\"qt-qb-state-main\">\n <span className=\"qt-qb-saved\">\n <button\n type=\"button\"\n className={cx(\"qt-qb-saved-star\", isSavedQuery ? \"qt-qb-saved-star--saved\" : \"qt-qb-saved-star--unsaved\")}\n title={isSavedQuery ? \"Rename saved query\" : \"Save query\"}\n disabled={isBusy}\n onClick={beginEditSavedName}\n >\n {isSavedQuery ? \"★\" : \"☆\"}\n </button>\n {isEditingSaved || isEditingUnsaved ? (\n <span className=\"qt-qb-saved-input-wrap\">\n <input\n type=\"text\"\n className=\"qt-qb-saved-input\"\n value={editingSavedName}\n disabled={isBusy}\n autoFocus\n onChange={(e) => setEditingSavedName(e.target.value)}\n onBlur={commitNameEditor}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitNameEditor();\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n cancelNameEdit();\n }\n }}\n onClick={(e) => e.stopPropagation()}\n />\n <button\n type=\"button\"\n className=\"qt-qb-saved-cancel\"\n title=\"Do not save\"\n onMouseDown={(e) => {\n e.preventDefault();\n cancelNameEdit();\n }}\n onClick={(e) => e.stopPropagation()}\n >\n ✕\n </button>\n </span>\n ) : (\n <button\n type=\"button\"\n className={cx(\"qt-qb-saved-name\", !activeSavedQuery && \"qt-qb-saved-name--custom\")}\n onClick={beginEditSavedName}\n >\n {activeSavedQuery ? activeSavedQuery.name : \"Custom Query\"}\n </button>\n )}\n </span>\n {isCollapsed ? (\n <span className=\"qt-qb-summary qt-truncate\" title={collapsedSummary}>\n <span className=\"qt-qb-summary-kw\">WHERE</span>{\" \"}\n <strong>{collapsedWhereText}</strong>{\" \"}\n <span className=\"qt-qb-summary-kw\">ORDER BY</span>{\" \"}\n <strong>{collapsedOrderText}</strong>\n </span>\n ) : null}\n </span>\n {showUpdateButton ? (\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={() => void updateLastSavedQuery()}\n disabled={isBusy}\n >\n {`Update Query '${lastSavedQuery?.name ?? \"query\"}'`}\n </button>\n ) : null}\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={() => setShowSaved(true)}>\n Saved{api.saved.items.length > 0 ? ` (${api.saved.items.length})` : \"\"}\n </button>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", \"qt-qb-collapse-btn\", classNames?.button)}\n onClick={() => setCollapsed(!isCollapsed)}\n aria-expanded={!isCollapsed}\n aria-controls={bodyId}\n title={isCollapsed ? \"Expand query builder\" : \"Collapse query builder\"}\n >\n <span\n className={cx(\"qt-qb-collapse-caret\", isCollapsed && \"qt-qb-collapse-caret--collapsed\")}\n aria-hidden=\"true\"\n >\n ▾\n </span>\n <span className=\"qt-sr-only\">{isCollapsed ? \"Expand query builder\" : \"Collapse query builder\"}</span>\n </button>\n </div>\n\n {!isCollapsed ? (\n <div className=\"qt-qb-bar qt-qb-editor-bar\">\n <div id={bodyId} className=\"qt-qb-body\">\n <SelectRow api={api} fields={fields} classNames={classNames} disabled={isBusy} />\n <WhereRow api={api} byName={byName} fields={fields} classNames={classNames} disabled={isBusy} />\n <OrderRow api={api} fields={fields} classNames={classNames} disabled={isBusy} />\n <WindowRow api={api} classNames={classNames} disabled={isBusy} />\n <MetricsRow api={api} fields={fields} classNames={classNames} disabled={isBusy} />\n </div>\n <div className=\"qt-qb-editor-stack\">\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={api.undo} disabled={!api.canUndo || isBusy}>\n ↶ Undo\n </button>\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={api.redo} disabled={!api.canRedo || isBusy}>\n ↷ Redo\n </button>\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={api.resetAll} disabled={isBusy}>\n Reset All\n </button>\n </div>\n </div>\n ) : null}\n\n <div className=\"qt-qb-bar qt-qb-run-bar qt-qb-row\">\n <span className=\"qt-qb-run-metric qt-qb-run-metric--strong\">{api.loading ? \"loading…\" : `${rowSummary} rows`}</span>\n <span className=\"qt-qb-run-metric\">Last updated {lastUpdatedText}</span>\n {failureText ? <span className=\"qt-qb-run-error\">{failureText}</span> : null}\n <span className=\"qt-qb-run-actions\">\n {autoRefreshStatus ? (\n <span className=\"qt-qb-auto-status\">\n {`Every ${formatDuration(autoRefreshStatus.frequencyMs)}; clear after ${formatDuration(\n autoRefreshStatus.turnOffAfterMs,\n )} (${autoRefreshStatus.pollCount} polls run)`}\n </span>\n ) : null}\n <span className=\"qt-auto-refresh\" ref={autoRefreshRef}>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", Boolean(autoRefreshStatus) && \"qt-btn--active\", classNames?.button)}\n onClick={() => setShowAutoRefresh((next) => !next)}\n aria-expanded={showAutoRefresh}\n title={autoRefreshStatus ? \"View or clear auto-update\" : \"Configure auto-update\"}\n >\n {autoRefreshButtonText}\n </button>\n {showAutoRefresh ? (\n <span\n ref={autoRefreshPopoverRef}\n className={cx(\"qt-auto-refresh-popover\", autoRefreshPopoverAlignRight && \"qt-auto-refresh-popover--align-right\")}\n role=\"dialog\"\n aria-label=\"Auto-refresh settings\"\n >\n <label className=\"qt-auto-refresh-field\">\n <span>Frequency</span>\n <select\n className=\"qt-auto-refresh-select\"\n value={autoRefreshFrequencyMs}\n onChange={(e) => setAutoRefreshFrequencyMs(Number(e.target.value))}\n >\n {AUTO_REFRESH_FREQUENCIES.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n <label className=\"qt-auto-refresh-field\">\n <span>Turn off after</span>\n <select\n className=\"qt-auto-refresh-select\"\n value={autoRefreshTurnOffAfterMs}\n onChange={(e) => setAutoRefreshTurnOffAfterMs(Number(e.target.value))}\n >\n {AUTO_REFRESH_TURN_OFF_AFTER.map((option) => (\n <option\n key={option.value}\n value={option.value}\n disabled={\n autoRefreshPolls(autoRefreshFrequencyMs, option.value) < 1 ||\n autoRefreshPolls(autoRefreshFrequencyMs, option.value) > MAX_AUTO_REFRESH_POLLS\n }\n >\n {option.label}\n </option>\n ))}\n </select>\n </label>\n <span className={cx(\"qt-auto-refresh-status\", !canSubmitAutoRefresh && \"qt-auto-refresh-status--error\")}>\n {canSubmitAutoRefresh\n ? `${selectedAutoRefreshPolls} polls maximum`\n : `Choose between 1 and 1000 polls`}\n </span>\n {autoRefreshStatus ? (\n <span className=\"qt-auto-refresh-status\">\n Active: every {formatDuration(autoRefreshStatus.frequencyMs)}, clears after{\" \"}\n {formatDuration(autoRefreshStatus.turnOffAfterMs)}. {autoRefreshStatus.pollCount} polls run.\n </span>\n ) : null}\n <span className=\"qt-auto-refresh-actions\">\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={submitAutoRefresh}\n disabled={!canSubmitAutoRefresh}\n >\n {autoRefreshStatus ? \"Update\" : \"Start\"}\n </button>\n {autoRefreshStatus ? (\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={() => {\n api.autoRefresh.stop();\n setShowAutoRefresh(false);\n }}\n >\n Clear\n </button>\n ) : null}\n </span>\n </span>\n ) : null}\n </span>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", \"qt-btn--primary\", classNames?.button)}\n onClick={api.refresh}\n disabled={isBusy}\n >\n Run Now\n </button>\n </span>\n </div>\n\n {!isCollapsed && showSaved ? (\n <SavedQueriesModal saved={api.saved} onClose={() => setShowSaved(false)} onLoad={setLastSavedId} />\n ) : null}\n </div>\n );\n}\n\n// ---- SELECT ---------------------------------------------------------------\n\nfunction SelectRow<Row>({\n api,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const { select, columnDrag } = api;\n const [adding, setAdding] = useState(false);\n const fieldLabelByName = useMemo(() => new Map(select.fields.map((f) => [f.name, f.label])), [select.fields]);\n\n // `overIndex` is a position in the list with the dragged column removed —\n // exactly where the live preview shows it. select.move removes-then-inserts at\n // that index, so the committed order matches the preview.\n function reorderByIndex(from: string, overIndex: number) {\n select.move(from, overIndex);\n }\n\n const fieldNames = select.visible.map((c) => c.field);\n const dragSource = columnDrag.source;\n\n // Live reorder, driven by the SHARED column-drag state so dragging a chip also\n // live-previews/dims the matching table column (and vice versa). The dragged\n // chip stays MOUNTED (removing the drag-source node mid-drag aborts the native\n // drag) and slides to the hovered slot, dimmed. Rendered order == drop result.\n const rendered = columnDrag.preview(fieldNames);\n\n return (\n <div className=\"qt-qb-row\">\n <span className=\"qt-qb-kw\">select</span>\n {rendered.map((name) => {\n const label = fieldLabelByName.get(name) ?? name;\n return (\n <span\n // Stable key (not index-based) so React MOVES the dragged chip instead\n // of remounting it \\u2014 a remount removes the drag source and aborts the drag.\n key={name}\n className={cx(\n \"qt-chip\",\n \"qt-chip--col\",\n dragSource === name && \"qt-chip--dragging\",\n classNames?.columnChip ?? classNames?.chip,\n )}\n draggable={!disabled}\n onDragStart={(e) => {\n columnDrag.start(name, fieldNames.indexOf(name));\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", name);\n }}\n onDragOver={(e) => {\n if (!columnDrag.source) return;\n // preventDefault on every chip (incl. the dragged one) so there is no\n // dead drop zone along the row.\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (columnDrag.source !== name) {\n const withoutDragged = fieldNames.filter((n) => n !== columnDrag.source);\n let next = withoutDragged.indexOf(name);\n if (next >= 0) {\n // Drop after the hovered chip when past its midpoint, so a column\n // can be moved into the last slot.\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n columnDrag.over(next);\n }\n }\n }}\n onDrop={(e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n const from = columnDrag.source || e.dataTransfer.getData(\"text/plain\");\n if (from && columnDrag.overIndex != null) reorderByIndex(from, columnDrag.overIndex);\n columnDrag.end();\n }}\n onDragEnd={() => columnDrag.end()}\n title=\"drag to reorder\"\n >\n <span aria-hidden className=\"qt-chip-grip\">\n ⋮⋮\n </span>\n <span className=\"qt-chip-field\">{label}</span>\n <button type=\"button\" className=\"qt-chip-x\" onClick={() => select.hide(name)} disabled={disabled}>\n ✕\n </button>\n </span>\n );\n })}\n {adding ? (\n <FieldPicker\n fields={select.hidden.filter(isSelectable)}\n onPick={(f) => {\n select.show(f.name);\n setAdding(false);\n }}\n onClose={() => setAdding(false)}\n />\n ) : (\n <button\n type=\"button\"\n className=\"qt-add\"\n onClick={() => setAdding(true)}\n disabled={disabled || select.hidden.length === 0}\n >\n + add column\n </button>\n )}\n {api.query.select.length > 0 && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={select.reset} disabled={disabled} title=\"Reset to default columns\">\n reset\n </button>\n )}\n </div>\n );\n}\n\n// ---- WHERE ----------------------------------------------------------------\n\nfunction WhereRow<Row>({\n api,\n byName,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n byName: Map<string, FieldDef<Row>>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const [adding, setAdding] = useState(false);\n\n function addClause(f: FieldDef<Row>) {\n const op = opsForField(f)[0] ?? \"=\";\n api.addFilter({ field: f.name, op, value: \"\" });\n setAdding(false);\n }\n\n const groupedWhere = useMemo(() => {\n const groups = new Map<string, { field: string; clauses: { clause: WhereClause; index: number }[] }>();\n const order: string[] = [];\n\n api.query.where.forEach((c, i) => {\n if (!groups.has(c.field)) order.push(c.field);\n const group = groups.get(c.field) ?? { field: c.field, clauses: [] };\n group.clauses.push({ clause: c, index: i });\n groups.set(c.field, group);\n });\n\n return order.map((fieldName) => groups.get(fieldName)!);\n }, [api.query.where]);\n\n return (\n <div className=\"qt-qb-row\">\n <span className=\"qt-qb-kw\">where</span>\n {api.query.where.length === 0 && !adding && <span className=\"qt-qb-hint\">all rows</span>}\n {groupedWhere.map((g) => (\n <ClauseChip\n key={g.field}\n api={api}\n field={byName.get(g.field)}\n clauses={g.clauses}\n classNames={classNames}\n disabled={disabled}\n onChange={(index, next) => api.updateFilter(index, next)}\n onRemove={(index) => api.removeFilter(index)}\n />\n ))}\n {adding ? (\n <FieldPicker\n fields={fields.filter(isFilterable)}\n gateOnDistinct\n onPick={addClause}\n onClose={() => setAdding(false)}\n />\n ) : (\n <button type=\"button\" className=\"qt-add\" onClick={() => setAdding(true)} disabled={disabled}>\n + add filter\n </button>\n )}\n {api.query.where.length > 0 && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={api.clearFilters} disabled={disabled} title=\"Reset filters\">\n reset\n </button>\n )}\n </div>\n );\n}\n\nfunction ClauseChip<Row>({\n api,\n field,\n clauses,\n classNames,\n disabled,\n onChange,\n onRemove,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row> | undefined;\n clauses: Array<{ clause: WhereClause; index: number }>;\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n onChange: (index: number, c: WhereClause) => void;\n onRemove: (index: number) => void;\n}) {\n const labelField = field?.label;\n const fieldName = clauses[0]?.clause.field;\n const fieldHasNull = useFieldHasNull(api, field?.name);\n\n return (\n <span className={cx(\"qt-chip\", \"qt-chip--where\", classNames?.chip)}>\n <span className=\"qt-chip-field\">{labelField ?? fieldName}</span>\n <span className=\"qt-chip-where-list\">\n {clauses.map((entry, idx) => {\n const clause = entry.clause;\n const baseOps: FilterOp[] = field ? opsForField(field) : [clause.op];\n const filteredBaseOps = fieldHasNull === false ? baseOps.filter((op) => !NULLARY_OPS.has(op)) : baseOps;\n const clauseOps: FilterOp[] = filteredBaseOps.includes(clause.op)\n ? filteredBaseOps\n : [...filteredBaseOps, clause.op];\n const needsValue = !NULLARY_OPS.has(clause.op);\n return (\n <span className=\"qt-chip-where-clause\" key={entry.index}>\n {idx > 0 && <span className=\"qt-chip-and\">and</span>}\n <select\n className={cx(\"qt-chip-op\", classNames?.select)}\n value={clause.op}\n disabled={disabled}\n style={{ width: `${chipFieldWidthForSelect(clause.op, 3)}ch` }}\n onChange={(e) => onChange(entry.index, { ...clause, op: e.target.value as FilterOp })}\n >\n {clauseOps.map((op) => (\n <option key={op} value={op}>\n {op}\n </option>\n ))}\n </select>\n {needsValue && (\n <ValueInput\n api={api}\n field={field}\n value={clause.value}\n classNames={classNames}\n onChange={(v) => onChange(entry.index, { ...clause, value: v })}\n />\n )}\n <button\n type=\"button\"\n className=\"qt-chip-x\"\n onClick={() => onRemove(entry.index)}\n disabled={disabled}\n >\n ✕\n </button>\n </span>\n );\n })}\n </span>\n </span>\n );\n}\n\n// ---- value input: autocomplete by default --------------------------------\n\nfunction ValueInput<Row>({\n api,\n field,\n value,\n classNames,\n onChange,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row> | undefined;\n value: string;\n classNames: QueryBuilderClassNames | undefined;\n onChange: (v: string) => void;\n}) {\n const strategy = field ? filterValuesFor(field) : { source: \"freeform\" as const };\n\n // Static closed domain → a plain <select> of the options.\n if (strategy.source === \"static\") {\n const selectedText = value || \"—\";\n const widthChars = chipFieldWidthForSelect(selectedText, 4);\n return (\n <select\n className={cx(\"qt-chip-val\", classNames?.select)}\n value={value}\n style={{ width: `${widthChars}ch` }}\n onChange={(e) => onChange(e.target.value)}\n >\n <option value=\"\">—</option>\n {strategy.options.map((o) => (\n <option key={o} value={o}>\n {o}\n </option>\n ))}\n </select>\n );\n }\n\n // Freeform → a plain input, no suggestions.\n if (strategy.source === \"freeform\" || !field) {\n const widthChars = chipFieldWidthForInput(value || \"value\", field?.type, 5, 4);\n return (\n <input\n className={cx(\"qt-chip-val\", classNames?.input)}\n value={value}\n placeholder=\"value\"\n size={widthChars}\n style={{ width: `${widthChars}ch` }}\n onChange={(e) => onChange(e.target.value)}\n />\n );\n }\n\n // Autocomplete (the default) → debounced combobox backed by api.filterValues.\n return <AutocompleteInput api={api} field={field} value={value} classNames={classNames} onChange={onChange} />;\n}\n\nfunction AutocompleteInput<Row>({\n api,\n field,\n value,\n classNames,\n onChange,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row>;\n value: string;\n classNames: QueryBuilderClassNames | undefined;\n onChange: (v: string) => void;\n}) {\n const [result, setResult] = useState<DistinctValuesResult>({ values: [], hasMore: false });\n const listId = useId();\n\n useEffect(() => {\n let cancelled = false;\n const t = setTimeout(() => {\n void api\n .filterValues(field.name, value)\n .then((r) => {\n if (!cancelled) setResult(r);\n })\n .catch(() => {\n if (!cancelled) setResult({ values: [], hasMore: false });\n });\n }, 200);\n return () => {\n cancelled = true;\n clearTimeout(t);\n };\n }, [api, field.name, value]);\n\n return (\n <span className=\"qt-autocomplete\">\n <input\n className={cx(\"qt-chip-val\", classNames?.input)}\n value={value}\n placeholder=\"value\"\n list={listId}\n size={chipFieldWidthForInput(value || \"value\", field.type, 5, 4)}\n style={{ width: `${chipFieldWidthForInput(value || \"value\", field.type, 5, 4)}ch` }}\n onChange={(e) => onChange(e.target.value)}\n />\n <datalist id={listId}>\n {result.values.map((v) => (\n <option key={v} value={v} />\n ))}\n </datalist>\n {result.hasMore && <span className=\"qt-autocomplete-hint\">keep typing to refine…</span>}\n </span>\n );\n}\n\n// ---- ORDER BY (multi-sort, reorderable) -----------------------------------\n\nfunction OrderTermChip<Row>({\n api,\n field,\n term,\n dataIndex,\n priority,\n showPriority,\n isDragSource,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n disabled,\n updateTerm,\n removeTerm,\n classNames,\n label,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row> | undefined;\n term: OrderByClause;\n /** Index of this term in the real orderBy array (for update/remove). */\n dataIndex: number;\n /** 1-based sort priority to display (reflects the live drag position). */\n priority: number;\n showPriority: boolean;\n isDragSource: boolean;\n onDragStart: () => void;\n onDragOver: (e: React.DragEvent) => void;\n onDrop: () => void;\n onDragEnd: () => void;\n disabled: boolean | undefined;\n updateTerm: (i: number, patch: Partial<OrderByClause>) => void;\n removeTerm: (i: number) => void;\n classNames: QueryBuilderClassNames | undefined;\n label: string;\n}) {\n const fieldHasNull = useFieldHasNull(api, field?.name);\n\n return (\n <span\n className={cx(\"qt-chip\", \"qt-chip--col\", \"qt-chip--sort\", isDragSource && \"qt-chip--dragging\", classNames?.chip)}\n draggable={!disabled}\n onDragStart={(e) => {\n onDragStart();\n // Firefox refuses to start a native drag unless drag data is set here.\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", term.field);\n }}\n onDragOver={onDragOver}\n onDrop={(e) => {\n e.preventDefault();\n onDrop();\n }}\n onDragEnd={onDragEnd}\n title=\"drag to reorder sort priority\"\n >\n <span aria-hidden className=\"qt-chip-grip\">\n ⋮⋮\n </span>\n {showPriority && <span className=\"qt-chip-priority\">{priority}</span>}\n <span className=\"qt-chip-field\">{label}</span>\n <button\n type=\"button\"\n className=\"qt-chip-op-btn\"\n disabled={disabled}\n onClick={() => updateTerm(dataIndex, { dir: term.dir === \"asc\" ? \"desc\" : \"asc\" })}\n >\n {term.dir === \"asc\" ? \"↑ asc\" : \"↓ desc\"}\n </button>\n {fieldHasNull !== false && (\n <button\n type=\"button\"\n className=\"qt-chip-op-btn\"\n disabled={disabled}\n title=\"where NULL values sort\"\n onClick={() => updateTerm(dataIndex, { nulls: (term.nulls ?? \"last\") === \"last\" ? \"first\" : \"last\" })}\n >\n nulls {term.nulls ?? \"last\"}\n </button>\n )}\n <button type=\"button\" className=\"qt-chip-x\" onClick={() => removeTerm(dataIndex)} disabled={disabled}>\n ✕\n </button>\n </span>\n );\n}\n\nfunction OrderRow<Row>({\n api,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const orderBy = api.query.orderBy;\n const byName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n // Local live-reorder drag state (sort terms are their own list, distinct from\n // the columns shared via api.columnDrag) — same dimmed-source + slide preview.\n const [drag, setDrag] = useState<{ source: string; overIndex: number } | null>(null);\n const [adding, setAdding] = useState(false);\n\n function setOrderBy(next: OrderByClause[]) {\n api.setSort(next);\n }\n function updateTerm(i: number, patch: Partial<OrderByClause>) {\n setOrderBy(orderBy.map((o, k) => (k === i ? { ...o, ...patch } : o)));\n }\n function removeTerm(i: number) {\n setOrderBy(orderBy.filter((_, k) => k !== i));\n }\n function addTerm(f: FieldDef<Row>) {\n const field = f.sort?.field ?? f.name;\n const nextOrderBy: OrderByClause[] = [...orderBy, { field, dir: \"desc\" }];\n\n if (orderBy.some((o) => o.field === field)) {\n setAdding(false);\n return;\n }\n\n const hasSelectColumn = api.select.visible.some((c) => c.field === field);\n if (hasSelectColumn) {\n setOrderBy(nextOrderBy);\n setAdding(false);\n return;\n }\n\n api.setQuery((q) => ({\n ...q,\n offset: 0,\n orderBy: nextOrderBy,\n select: q.select.length ? [...q.select, { field }] : [...api.select.visible, { field }],\n }));\n setAdding(false);\n }\n\n // Order-by terms are identified by their (unique) field; the drag math mirrors\n // the column chips so the live preview equals the committed order.\n const termFields = orderBy.map((o) => o.field);\n const termByField = useMemo(() => new Map(orderBy.map((o) => [o.field, o])), [orderBy]);\n function previewFields(): string[] {\n if (!drag) return termFields;\n const without = termFields.filter((f) => f !== drag.source);\n if (without.length === termFields.length) return termFields;\n const at = Math.max(0, Math.min(drag.overIndex, without.length));\n return [...without.slice(0, at), drag.source, ...without.slice(at)];\n }\n function handleSortOver(e: React.DragEvent, field: string) {\n if (!drag) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (drag.source !== field) {\n const without = termFields.filter((f) => f !== drag.source);\n let next = without.indexOf(field);\n if (next >= 0) {\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n setDrag((d) => (d && d.overIndex !== next ? { source: d.source, overIndex: next } : d));\n }\n }\n }\n function commitSortDrop() {\n if (drag) setOrderBy(previewFields().map((f) => termByField.get(f)!));\n setDrag(null);\n }\n\n const rendered = previewFields();\n const sortable = fields.filter(isSortable);\n const isDefaultOrderBy =\n orderBy.length === api.defaults.orderBy.length &&\n orderBy.every((term, i) => {\n const next = api.defaults.orderBy[i];\n return (\n term.field === next?.field &&\n term.dir === next?.dir &&\n (term.nulls ?? \"last\") === (next?.nulls ?? \"last\")\n );\n });\n\n return (\n <div className=\"qt-qb-row\">\n <span className=\"qt-qb-kw\">order by</span>\n {orderBy.length === 0 && !adding && <span className=\"qt-qb-hint\">(default)</span>}\n {rendered.map((f, pos) => {\n const term = termByField.get(f)!;\n return (\n <OrderTermChip\n // Stable key (term field) so React MOVES the dragged chip, not remounts it.\n key={f}\n api={api}\n field={byName.get(f)}\n term={term}\n dataIndex={orderBy.findIndex((o) => o.field === f)}\n priority={pos + 1}\n showPriority={orderBy.length > 1}\n isDragSource={drag?.source === f}\n onDragStart={() => setDrag({ source: f, overIndex: termFields.indexOf(f) })}\n onDragOver={(e) => handleSortOver(e, f)}\n onDrop={commitSortDrop}\n onDragEnd={() => setDrag(null)}\n disabled={disabled}\n updateTerm={updateTerm}\n removeTerm={removeTerm}\n classNames={classNames}\n label={byName.get(f)?.label ?? f}\n />\n );\n })}\n {adding ? (\n <FieldPicker fields={sortable} onPick={addTerm} onClose={() => setAdding(false)} />\n ) : (\n <button type=\"button\" className=\"qt-add\" onClick={() => setAdding(true)} disabled={disabled}>\n + add sort\n </button>\n )}\n {!isDefaultOrderBy && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={() => api.setSort(api.defaults.orderBy)} disabled={disabled}>\n reset\n </button>\n )}\n </div>\n );\n}\n\n// ---- LIMIT / OFFSET -------------------------------------------------------\n\nfunction WindowRow<Row>({\n api,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const { query } = api;\n const [limitDraft, setLimitDraft] = useState(String(query.limit));\n const [offsetDraft, setOffsetDraft] = useState(String(query.offset));\n useEffect(() => setLimitDraft(String(query.limit)), [query.limit]);\n useEffect(() => setOffsetDraft(String(query.offset)), [query.offset]);\n const hasLimitDefault = query.limit === api.defaults.limit;\n const hasOffsetDefault = query.offset === api.defaults.offset;\n const hasWindowDefault = hasLimitDefault && hasOffsetDefault;\n\n function commitLimit() {\n api.setLimit(Math.max(1, Number(limitDraft) || query.limit));\n }\n function commitOffset() {\n api.setOffset(Math.max(0, Number(offsetDraft) || 0));\n }\n\n return (\n <div className=\"qt-qb-row qt-qb-pagination\">\n <span className=\"qt-qb-kw\">limit</span>\n <input\n className={cx(\"qt-qb-num\", classNames?.input)}\n type=\"number\"\n min={1}\n value={limitDraft}\n disabled={disabled}\n onChange={(e) => setLimitDraft(e.target.value)}\n onBlur={commitLimit}\n onKeyDown={(e) => e.key === \"Enter\" && commitLimit()}\n />\n <span className=\"qt-qb-kw\">offset</span>\n <input\n className={cx(\"qt-qb-num\", classNames?.input)}\n type=\"number\"\n min={0}\n value={offsetDraft}\n disabled={disabled}\n onChange={(e) => setOffsetDraft(e.target.value)}\n onBlur={commitOffset}\n onKeyDown={(e) => e.key === \"Enter\" && commitOffset()}\n />\n {!hasWindowDefault && (\n <button\n type=\"button\"\n className=\"qt-link-btn\"\n onClick={() => {\n api.setLimit(api.defaults.limit);\n api.setOffset(api.defaults.offset);\n }}\n disabled={disabled}\n title=\"Reset limit and offset\"\n >\n reset\n </button>\n )}\n </div>\n );\n}\n\n// ---- METRICS (aggregations: op · measure · group-by, reorderable) ---------\n\nconst AGG_OPS: AggOp[] = [\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"];\nconst AGG_OP_LABELS: Record<AggOp, string> = {\n count: \"count\",\n count_distinct: \"count distinct\",\n sum: \"sum\",\n avg: \"avg\",\n min: \"min\",\n max: \"max\",\n};\n\nfunction MetricsRow<Row>({\n api,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const { aggregations } = api;\n const clauses = aggregations.clauses;\n const measurable = useMemo(() => fields.filter(isMeasurable), [fields]);\n const groupable = useMemo(() => fields.filter(isGroupable), [fields]);\n\n // Local live-reorder drag state (metrics are their own list, like the order-by\n // terms). Chips are identified by their stable clause id so React MOVES the\n // dragged chip instead of remounting it (a remount aborts the native drag).\n const [drag, setDrag] = useState<{ source: string; overIndex: number } | null>(null);\n\n const ids = clauses.map((c) => c.id);\n const byId = useMemo(() => new Map(clauses.map((c) => [c.id, c])), [clauses]);\n\n function previewIds(): string[] {\n if (!drag) return ids;\n const without = ids.filter((i) => i !== drag.source);\n if (without.length === ids.length) return ids;\n const at = Math.max(0, Math.min(drag.overIndex, without.length));\n return [...without.slice(0, at), drag.source, ...without.slice(at)];\n }\n function handleOver(e: React.DragEvent, id: string) {\n if (!drag) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (drag.source === id) return;\n const without = ids.filter((i) => i !== drag.source);\n let next = without.indexOf(id);\n if (next >= 0) {\n // Drop after the hovered chip when past its midpoint, so a metric can be\n // moved into the last slot (no clientX ⇒ insert before, like the spec).\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n setDrag((d) => (d && d.overIndex !== next ? { source: d.source, overIndex: next } : d));\n }\n }\n function commitDrop() {\n if (drag) aggregations.move(drag.source, drag.overIndex);\n setDrag(null);\n }\n\n const rendered = previewIds();\n\n return (\n <div className=\"qt-qb-row qt-qb-row--metrics\">\n <span className=\"qt-qb-kw\">metrics</span>\n {clauses.length === 0 && <span className=\"qt-qb-hint\">none</span>}\n {rendered.map((id) => {\n const clause = byId.get(id)!;\n return (\n <MetricChip\n // Stable key (clause id) so React MOVES the dragged chip, not remounts it.\n key={id}\n clause={clause}\n measurable={measurable}\n groupable={groupable}\n classNames={classNames}\n disabled={disabled}\n isDragSource={drag?.source === id}\n onDragStart={() => setDrag({ source: id, overIndex: ids.indexOf(id) })}\n onDragOver={(e) => handleOver(e, id)}\n onDrop={commitDrop}\n onDragEnd={() => setDrag(null)}\n onChangeOp={(op) => changeMetricOp(aggregations, clause, measurable, op)}\n onChangeField={(field) => aggregations.update(id, { field })}\n onAddGroup={(field) => aggregations.update(id, { groupBy: [...clause.groupBy, field] })}\n onRemoveGroup={(field) =>\n aggregations.update(id, { groupBy: clause.groupBy.filter((g) => g !== field) })\n }\n onRemove={() => aggregations.remove(id)}\n />\n );\n })}\n <button type=\"button\" className=\"qt-add\" onClick={() => aggregations.add()} disabled={disabled}>\n + add metric\n </button>\n {clauses.length > 0 && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={aggregations.clear} disabled={disabled} title=\"Remove all metrics\">\n reset\n </button>\n )}\n </div>\n );\n}\n\n/** Change a metric's op, dropping the measure if it's no longer valid for the\n * new op (e.g. switching avg→count on a text field, or to an op the field type\n * can't aggregate). `count` keeps any chosen measure. */\nfunction changeMetricOp<Row>(\n aggregations: QueryTableApi<Row>[\"aggregations\"],\n clause: AggregationClause,\n measurable: FieldDef<Row>[],\n op: AggOp,\n): void {\n const field = clause.field;\n const stillValid =\n field != null && measurable.some((f) => f.name === field && aggOpsForField(f).includes(op));\n if (field != null && !stillValid) aggregations.update(clause.id, { op, field: undefined });\n else aggregations.update(clause.id, { op });\n}\n\nfunction MetricChip<Row>({\n clause,\n measurable,\n groupable,\n classNames,\n disabled,\n isDragSource,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n onChangeOp,\n onChangeField,\n onAddGroup,\n onRemoveGroup,\n onRemove,\n}: {\n clause: AggregationClause;\n measurable: FieldDef<Row>[];\n groupable: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n isDragSource: boolean;\n onDragStart: () => void;\n onDragOver: (e: React.DragEvent) => void;\n onDrop: () => void;\n onDragEnd: () => void;\n onChangeOp: (op: AggOp) => void;\n onChangeField: (field: string | undefined) => void;\n onAddGroup: (field: string) => void;\n onRemoveGroup: (field: string) => void;\n onRemove: () => void;\n}) {\n const [addingGroup, setAddingGroup] = useState(false);\n const byName = useMemo(() => new Map(groupable.map((f) => [f.name, f])), [groupable]);\n\n // Measures valid for the current op (a measurable field whose effective ops\n // include this op). `count` may stand alone, so it gets an \"(all rows)\" choice.\n const needsField = aggOpNeedsField(clause.op);\n const measureOptions = measurable.filter((f) => aggOpsForField(f).includes(clause.op));\n\n return (\n <span\n className={cx(\"qt-chip\", \"qt-chip--agg\", isDragSource && \"qt-chip--dragging\", classNames?.chip)}\n draggable={!disabled}\n onDragStart={(e) => {\n onDragStart();\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", clause.id);\n }}\n onDragOver={onDragOver}\n onDrop={(e) => {\n e.preventDefault();\n onDrop();\n }}\n onDragEnd={onDragEnd}\n title=\"drag to reorder metrics\"\n >\n <span aria-hidden className=\"qt-chip-grip\">\n ⋮⋮\n </span>\n <select\n className={cx(\"qt-chip-op\", classNames?.select)}\n value={clause.op}\n disabled={disabled}\n onChange={(e) => onChangeOp(e.target.value as AggOp)}\n >\n {AGG_OPS.map((op) => (\n <option key={op} value={op}>\n {AGG_OP_LABELS[op]}\n </option>\n ))}\n </select>\n <select\n className={cx(\"qt-chip-val\", classNames?.select)}\n value={clause.field ?? \"\"}\n disabled={disabled}\n onChange={(e) => onChangeField(e.target.value || undefined)}\n >\n {!needsField && <option value=\"\">(all rows)</option>}\n {needsField && clause.field == null && <option value=\"\">measure…</option>}\n {measureOptions.map((f) => (\n <option key={f.name} value={f.name}>\n {f.label}\n </option>\n ))}\n </select>\n <span className=\"qt-chip-agg-by\">\n {clause.groupBy.map((g) => (\n <span className=\"qt-chip-agg-group\" key={g}>\n <span className=\"qt-chip-agg-group-label\">{byName.get(g)?.label ?? g}</span>\n <button type=\"button\" className=\"qt-chip-x\" onClick={() => onRemoveGroup(g)} disabled={disabled}>\n ✕\n </button>\n </span>\n ))}\n {addingGroup ? (\n <FieldPicker\n fields={groupable}\n excluded={clause.groupBy}\n onPick={(f) => {\n onAddGroup(f.name);\n setAddingGroup(false);\n }}\n onClose={() => setAddingGroup(false)}\n />\n ) : (\n <button\n type=\"button\"\n className=\"qt-add qt-chip-agg-add\"\n onClick={() => setAddingGroup(true)}\n disabled={disabled}\n title=\"Group by a field\"\n >\n {clause.groupBy.length === 0 ? \"+ by\" : \"+\"}\n </button>\n )}\n </span>\n <button type=\"button\" className=\"qt-chip-x\" onClick={onRemove} disabled={disabled} title=\"Remove metric\">\n ✕\n </button>\n </span>\n );\n}\n","// FieldPicker — grouped, searchable field chooser.\n// Searches label + name + aliases, groups by FieldDef.group, and surfaces\n// per-field stats (distinct count, min/max) when the Transport provides them.\n// Used to add columns and to add filters.\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport type { FieldDef, FieldStats } from \"@pythia-software/query-table-core\";\n\nexport interface FieldPickerProps<Row> {\n fields: FieldDef<Row>[];\n /** Already-shown field names, so the picker can mark/hide them. */\n excluded?: string[];\n /** Stats keyed by field name (optional). */\n stats?: Record<string, FieldStats>;\n /** When true, dim/disable fields with ≤1 distinct value (\"gate on distinct\"). */\n gateOnDistinct?: boolean;\n onPick: (field: FieldDef<Row>) => void;\n onClose?: () => void;\n}\n\nconst UNGROUPED = \"other\";\n\nexport function FieldPicker<Row>({\n fields,\n excluded,\n stats,\n gateOnDistinct,\n onPick,\n onClose,\n}: FieldPickerProps<Row>): ReactNode {\n const [search, setSearch] = useState(\"\");\n const needle = search.trim().toLowerCase();\n const excludedSet = useMemo(() => new Set(excluded ?? []), [excluded]);\n\n const matched = useMemo(\n () =>\n fields.filter((f) => {\n if (excludedSet.has(f.name)) return false;\n if (!needle) return true;\n return (\n f.label.toLowerCase().includes(needle) ||\n f.name.toLowerCase().includes(needle) ||\n (fieldAliases(f).some((a) => a.toLowerCase().includes(needle)))\n );\n }),\n [fields, excludedSet, needle],\n );\n\n const grouped = useMemo(() => groupByGroup(matched), [matched]);\n\n const firstEnabled = matched.find((f) => isEnabled(f, stats, gateOnDistinct));\n\n return (\n <div className=\"qt-picker\">\n <input\n autoFocus\n type=\"text\"\n className=\"qt-picker-input\"\n placeholder=\"search fields…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onClose?.();\n if (e.key === \"Enter\" && firstEnabled) {\n onPick(firstEnabled);\n setSearch(\"\");\n }\n }}\n // Defer so a mousedown on a list item lands before blur closes it.\n onBlur={() => setTimeout(() => onClose?.(), 150)}\n />\n <div className=\"qt-picker-list\">\n {matched.length === 0 ? (\n <div className=\"qt-picker-empty\">no matches</div>\n ) : (\n grouped.map(([group, fs]) => (\n <div key={group} className=\"qt-picker-group\">\n <div className=\"qt-picker-group-label\">{group}</div>\n {fs.map((f) => {\n const enabled = isEnabled(f, stats, gateOnDistinct);\n const s = stats?.[f.name];\n const aliasHit = aliasMatch(f, needle);\n return (\n <button\n key={f.name}\n type=\"button\"\n disabled={!enabled}\n className={enabled ? \"qt-picker-item\" : \"qt-picker-item qt-picker-item--disabled\"}\n title={enabled ? f.name : \"not useful as a filter (≤1 distinct value)\"}\n // mousedown (not click) fires before the input's blur.\n onMouseDown={(e) => {\n if (!enabled) return;\n e.preventDefault();\n onPick(f);\n setSearch(\"\");\n }}\n >\n <span className=\"qt-picker-row\">\n <span className=\"qt-picker-label\">{f.label}</span>\n <span className=\"qt-picker-name\">{f.name}</span>\n </span>\n {aliasHit && <span className=\"qt-picker-alias\">matches: {aliasHit}</span>}\n {s && (\n <span className=\"qt-picker-stats\">\n {s.distinct != null && <>{s.distinct} distinct</>}\n {s.min != null && s.max != null && (\n <>\n {\" \"}\n · {fmtStat(s.min)}…{fmtStat(s.max)}\n </>\n )}\n </span>\n )}\n </button>\n );\n })}\n </div>\n ))\n )}\n </div>\n </div>\n );\n}\n\nfunction isEnabled(f: FieldDef, stats: FieldPickerProps<any>[\"stats\"], gate: boolean | undefined): boolean {\n if (!gate) return true;\n const s = stats?.[f.name];\n if (!s || s.distinct == null) return true; // no data → don't gate\n return s.distinct > 1;\n}\n\nfunction aliasMatch(f: FieldDef, needle: string): string | undefined {\n if (!needle) return undefined;\n if (f.label.toLowerCase().includes(needle) || f.name.toLowerCase().includes(needle)) return undefined;\n return fieldAliases(f).find((a) => a.toLowerCase().includes(needle));\n}\n\nfunction fieldAliases<Row>(f: FieldDef<Row>): string[] {\n const aliases = new Set<string>();\n if (f.alias) aliases.add(f.alias);\n if (f.aliases) {\n for (const alias of f.aliases) aliases.add(alias);\n }\n return [...aliases];\n}\n\nfunction groupByGroup<Row>(fs: FieldDef<Row>[]): Array<[string, FieldDef<Row>[]]> {\n const groups = new Map<string, FieldDef<Row>[]>();\n for (const f of fs) {\n const key = f.group ?? UNGROUPED;\n const arr = groups.get(key);\n if (arr) arr.push(f);\n else groups.set(key, [f]);\n }\n return [...groups.entries()];\n}\n\nfunction fmtStat(v: string | number): string {\n if (typeof v === \"number\") return v.toLocaleString();\n const s = String(v);\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(s)) return s.slice(0, 10);\n if (s.length > 18) return s.slice(0, 15) + \"…\";\n return s;\n}\n","// SavedQueriesModal — list / load / delete named saved queries. Thin view over\n// api.saved; loading one pushes its QueryState into the controller (and the URL).\n\nimport { useEffect, type ReactNode } from \"react\";\nimport type { SavedQueriesApi } from \"@pythia-software/query-table-react\";\n\nexport interface SavedQueriesModalProps {\n saved: SavedQueriesApi;\n onClose: () => void;\n onLoad?: (savedId: string) => void;\n}\n\nexport function SavedQueriesModal({ saved, onClose, onLoad }: SavedQueriesModalProps): ReactNode {\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onClose]);\n\n return (\n <div className=\"qt-modal-backdrop\" onClick={onClose}>\n <div className=\"qt-modal\" onClick={(e) => e.stopPropagation()} role=\"dialog\" aria-label=\"Saved queries\">\n <h3 className=\"qt-modal-title\">Saved queries</h3>\n {saved.loading ? (\n <p className=\"qt-muted\">Loading…</p>\n ) : saved.items.length === 0 ? (\n <p className=\"qt-muted\">None saved yet. Save the current query from the toolbar.</p>\n ) : (\n <ul className=\"qt-saved-list\">\n {saved.items.map((s) => {\n const filters = s.query.where.length;\n const isDefault = saved.defaultId === s.id;\n return (\n <li key={s.id} className=\"qt-saved-item\">\n <button\n type=\"button\"\n className=\"qt-saved-pick\"\n onClick={() => {\n onLoad?.(s.id);\n saved.load(s.id);\n onClose();\n }}\n >\n <span className=\"qt-saved-name\">{s.name}</span>\n <span className=\"qt-saved-meta qt-muted\">\n {isDefault ? \"Default view · \" : \"\"}\n {new Date(s.savedAt).toLocaleString()} · {filters} filter{filters === 1 ? \"\" : \"s\"}\n </span>\n </button>\n {isDefault ? (\n <button\n type=\"button\"\n className=\"qt-btn qt-saved-default\"\n title=\"Clear default view\"\n onClick={() => void saved.clearDefault()}\n >\n default\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"qt-btn qt-saved-default\"\n title=\"Use as default view\"\n onClick={() => void saved.setDefault(s.id)}\n >\n make default\n </button>\n )}\n <button\n type=\"button\"\n className=\"qt-btn qt-saved-delete\"\n title=\"Delete saved query\"\n onClick={() => void saved.remove(s.id)}\n >\n delete\n </button>\n </li>\n );\n })}\n </ul>\n )}\n <div className=\"qt-modal-footer\">\n <button type=\"button\" className=\"qt-btn\" onClick={onClose}>\n close\n </button>\n </div>\n </div>\n </div>\n );\n}\n","// MetricsPanel — the dashboard strip above the table.\n//\n// Renders the optional aggregation metrics (see @pythia-software/query-table-core\n// AggregationClause). Each metric's shape follows its group-by arity:\n// 0 group-by → one big number\n// 1 group-by → a ranked bar list (label · value · share bar)\n// 2 group-by → an x/y pivot table (rows = axis 0, cols = axis 1)\n// 3+ group-by → a flat table, one column per group key + the value\n//\n// Values are formatted through the measure field's own renderer where it makes\n// sense (so AVG(total_ms) reads \"3.2s\", not \"3200\"), falling back to a locale\n// number. Counts are always plain integers.\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { EMPTY_QUERY } from \"@pythia-software/query-table-core\";\nimport type { AggOp, AggregationBucket, AggregationClause, FieldDef } from \"@pythia-software/query-table-core\";\nimport type { AggregationsApi } from \"@pythia-software/query-table-react\";\nimport { resolveRenderer, type RenderRegistry } from \"./renderers\";\n\nexport interface MetricsPanelProps<Row> {\n /** The aggregation API from useQueryTable (clauses + results + status). */\n aggregations: AggregationsApi;\n /** All schema fields, to resolve labels + the measure field's renderer. */\n fields: FieldDef<Row>[];\n /** Cell renderers (same registry as the table) for formatting measure values. */\n renderers?: RenderRegistry<Row>;\n /** Hidden entirely when there are no metrics unless this is set. */\n emptyMessage?: string;\n classNames?: { root?: string; metric?: string };\n}\n\nconst cx = (...parts: Array<string | undefined | false>): string =>\n parts.filter((p): p is string => Boolean(p)).join(\" \");\n\nconst OP_LABELS: Record<AggOp, string> = {\n count: \"Count\",\n count_distinct: \"Distinct\",\n sum: \"Sum\",\n avg: \"Avg\",\n min: \"Min\",\n max: \"Max\",\n};\n\nconst NULL_KEY = \"∅\";\n\nexport function MetricsPanel<Row>({\n aggregations,\n fields,\n renderers,\n emptyMessage,\n classNames,\n}: MetricsPanelProps<Row>): ReactNode {\n const byName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n const { clauses, results, loading, error } = aggregations;\n\n if (clauses.length === 0) {\n return emptyMessage ? <div className={cx(\"qt-metrics\", classNames?.root)}>{emptyMessage}</div> : null;\n }\n\n const resultById = new Map((results?.metrics ?? []).map((m) => [m.id, m.buckets]));\n\n return (\n <div className={cx(\"qt-metrics\", classNames?.root)}>\n {error ? <div className=\"qt-metrics-error\">Metrics failed: {error.message}</div> : null}\n {clauses.map((clause) => (\n <MetricCard\n key={clause.id}\n clause={clause}\n buckets={resultById.get(clause.id) ?? []}\n loading={loading && !resultById.has(clause.id)}\n byName={byName}\n renderers={renderers}\n className={classNames?.metric}\n />\n ))}\n </div>\n );\n}\n\nfunction MetricCard<Row>({\n clause,\n buckets,\n loading,\n byName,\n renderers,\n className,\n}: {\n clause: AggregationClause;\n buckets: AggregationBucket[];\n loading: boolean;\n byName: Map<string, FieldDef<Row>>;\n renderers: RenderRegistry<Row> | undefined;\n className: string | undefined;\n}): ReactNode {\n const measure = clause.field ? byName.get(clause.field) : undefined;\n const groupLabels = clause.groupBy.map((g) => byName.get(g)?.label ?? g);\n // One decimal-place count for the whole card (≈5 significant figures), so every\n // value lines up and we never render a 12-digit float tail.\n const decimals = useMemo(() => cardDecimals(buckets), [buckets]);\n const fmt = (v: number | string | null): ReactNode => formatMetricValue(v, clause.op, measure, renderers, decimals);\n\n return (\n <div className={cx(\"qt-metric\", `qt-metric--gb${Math.min(clause.groupBy.length, 3)}`, className)}>\n <div className=\"qt-metric-head\">\n <span className=\"qt-metric-title\">{metricTitle(clause, measure)}</span>\n {groupLabels.length > 0 && <span className=\"qt-metric-by\">by {groupLabels.join(\" × \")}</span>}\n </div>\n {loading && buckets.length === 0 ? (\n <div className=\"qt-metric-loading\">…</div>\n ) : buckets.length === 0 ? (\n <div className=\"qt-metric-empty\">no data</div>\n ) : clause.groupBy.length === 0 ? (\n <BigNumber bucket={buckets[0]!} fmt={fmt} />\n ) : clause.groupBy.length === 1 ? (\n <BarList buckets={buckets} fmt={fmt} />\n ) : clause.groupBy.length === 2 ? (\n <Pivot buckets={buckets} fmt={fmt} rowLabel={groupLabels[0]!} colLabel={groupLabels[1]!} />\n ) : (\n <FlatTable buckets={buckets} fmt={fmt} groupLabels={groupLabels} valueLabel={metricTitle(clause, measure)} />\n )}\n </div>\n );\n}\n\n// ---- 0 group-by: one big number -------------------------------------------\n\nfunction BigNumber({ bucket, fmt }: { bucket: AggregationBucket; fmt: (v: number | string | null) => ReactNode }) {\n return (\n <div className=\"qt-metric-big\">\n <span className=\"qt-metric-big-value\">{fmt(bucket.value)}</span>\n <span className=\"qt-metric-big-sub\">{bucket.count.toLocaleString()} rows</span>\n </div>\n );\n}\n\n// ---- 1 group-by: ranked bars ----------------------------------------------\n\nfunction BarList({ buckets, fmt }: { buckets: AggregationBucket[]; fmt: (v: number | string | null) => ReactNode }) {\n const max = Math.max(...buckets.map((b) => barMagnitude(b)), 0);\n return (\n <div className=\"qt-metric-bars\">\n {buckets.map((b, i) => {\n const pct = max > 0 ? (barMagnitude(b) / max) * 100 : 0;\n return (\n <div className=\"qt-metric-bar-row\" key={`${keyText(b.keys[0])}-${i}`}>\n <span className=\"qt-metric-bar-label\" title={keyText(b.keys[0])}>\n {keyNode(b.keys[0])}\n </span>\n <span className=\"qt-metric-bar-track\">\n <span className=\"qt-metric-bar-fill\" style={{ width: `${pct}%` }} />\n </span>\n <span className=\"qt-metric-bar-value\">{fmt(b.value)}</span>\n </div>\n );\n })}\n </div>\n );\n}\n\n// ---- 2 group-by: x/y pivot ------------------------------------------------\n\nfunction Pivot({\n buckets,\n fmt,\n rowLabel,\n colLabel,\n}: {\n buckets: AggregationBucket[];\n fmt: (v: number | string | null) => ReactNode;\n rowLabel: string;\n colLabel: string;\n}) {\n const rowKeys = distinctKeys(buckets, 0);\n const colKeys = distinctKeys(buckets, 1);\n const cell = new Map<string, number | string | null>();\n for (const b of buckets) cell.set(`${keyText(b.keys[0])}\\u0000${keyText(b.keys[1])}`, b.value);\n\n return (\n <div className=\"qt-metric-pivot-wrap\">\n <table className=\"qt-metric-pivot\">\n <thead>\n <tr>\n <th className=\"qt-metric-pivot-corner\">\n <span className=\"qt-metric-pivot-axes\">\n {rowLabel} <span className=\"qt-muted\">\\</span> {colLabel}\n </span>\n </th>\n {colKeys.map((c) => (\n <th key={keyText(c)} className=\"qt-metric-pivot-col\">\n {keyNode(c)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rowKeys.map((r) => (\n <tr key={keyText(r)}>\n <th className=\"qt-metric-pivot-row\">{keyNode(r)}</th>\n {colKeys.map((c) => {\n const v = cell.get(`${keyText(r)}\\u0000${keyText(c)}`);\n return (\n <td key={keyText(c)} className=\"qt-metric-pivot-cell\">\n {v === undefined ? <span className=\"qt-muted\">·</span> : fmt(v)}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ---- 3+ group-by: flat table ----------------------------------------------\n\nfunction FlatTable({\n buckets,\n fmt,\n groupLabels,\n valueLabel,\n}: {\n buckets: AggregationBucket[];\n fmt: (v: number | string | null) => ReactNode;\n groupLabels: string[];\n valueLabel: string;\n}) {\n return (\n <div className=\"qt-metric-pivot-wrap\">\n <table className=\"qt-metric-flat\">\n <thead>\n <tr>\n {groupLabels.map((g) => (\n <th key={g}>{g}</th>\n ))}\n <th className=\"qt-metric-flat-value\">{valueLabel}</th>\n </tr>\n </thead>\n <tbody>\n {buckets.map((b, i) => (\n <tr key={i}>\n {/* Index by column, not by b.keys: a bucket whose `keys` is shorter\n than the header (a malformed/partial result) must still leave the\n value in the value column rather than sliding it left. */}\n {groupLabels.map((_, j) => (\n <td key={j}>{keyNode(b.keys[j])}</td>\n ))}\n <td className=\"qt-metric-flat-value\">{fmt(b.value)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ---- helpers --------------------------------------------------------------\n\nfunction metricTitle<Row>(clause: AggregationClause, measure: FieldDef<Row> | undefined): string {\n if (clause.label) return clause.label;\n if (clause.op === \"count\" && !measure) return \"Count\";\n return `${OP_LABELS[clause.op]} ${measure?.label ?? clause.field ?? \"\"}`.trim();\n}\n\n// Default renderers that map a number to a unit-formatted string (and so already\n// bound their own decimals). Any OTHER renderer (text/link/pill/number) is skipped\n// for numeric aggregates — it would stringify the raw float — in favor of the\n// card's shared decimal formatting.\nconst UNIT_RENDER_KEYS: ReadonlySet<string> = new Set([\"duration_ms\", \"byte_size\"]);\n\nfunction formatMetricValue<Row>(\n value: number | string | null,\n op: AggOp,\n measure: FieldDef<Row> | undefined,\n renderers: RenderRegistry<Row> | undefined,\n decimals: number,\n): ReactNode {\n if (value == null) return <span className=\"qt-muted\">—</span>;\n // Counts are dimensionless integers — never run them through a column renderer.\n if (op === \"count\" || op === \"count_distinct\") {\n return typeof value === \"number\" ? formatNumber(value, 0) : String(value);\n }\n if (typeof value === \"number\") {\n const key = typeof measure?.render === \"string\" ? measure.render : undefined;\n if (key && UNIT_RENDER_KEYS.has(key) && measure && renderers) {\n const node = tryRender(measure, renderers, value);\n if (node != null) return node;\n }\n return formatNumber(value, decimals);\n }\n // min/max over text or datetime → the column's renderer, else the raw string.\n if (measure && renderers) {\n const node = tryRender(measure, renderers, value);\n if (node != null) return node;\n }\n return String(value);\n}\n\nfunction tryRender<Row>(\n measure: FieldDef<Row>,\n renderers: RenderRegistry<Row>,\n value: number | string,\n): ReactNode | null {\n try {\n const node = resolveRenderer(measure, renderers)({\n value: value as never,\n row: {} as Row,\n field: measure,\n query: EMPTY_QUERY,\n });\n return node != null && node !== \"\" ? node : null;\n } catch {\n return null;\n }\n}\n\nfunction formatNumber(value: number, decimals: number): string {\n if (!Number.isFinite(value)) return String(value);\n return value.toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals });\n}\n\n// One decimal count for every numeric value in a card: 0 when all are integers\n// (counts, integer measures), else enough places to give the largest-magnitude\n// value ≈5 significant figures (so smaller values share that precision and no\n// value shows a runaway float tail). Capped at 6.\nfunction cardDecimals(buckets: AggregationBucket[]): number {\n const nums = buckets\n .map((b) => b.value)\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v));\n if (nums.length === 0) return 0;\n if (nums.every((v) => Number.isInteger(v))) return 0;\n const maxAbs = Math.max(...nums.map((v) => Math.abs(v)));\n const intDigits = maxAbs >= 1 ? Math.floor(Math.log10(maxAbs)) + 1 : 0;\n return Math.min(6, Math.max(0, 5 - intDigits));\n}\n\nfunction barMagnitude(b: AggregationBucket): number {\n return typeof b.value === \"number\" ? Math.abs(b.value) : b.count;\n}\n\nfunction distinctKeys(buckets: AggregationBucket[], axis: number): (string | null)[] {\n const seen = new Set<string>();\n const out: (string | null)[] = [];\n for (const b of buckets) {\n const k = b.keys[axis] ?? null;\n const t = keyText(k);\n if (!seen.has(t)) {\n seen.add(t);\n out.push(k);\n }\n }\n return out;\n}\n\nfunction keyText(k: string | null | undefined): string {\n return k == null ? NULL_KEY : String(k);\n}\n\nfunction keyNode(k: string | null | undefined): ReactNode {\n return k == null ? <span className=\"qt-muted\">{NULL_KEY}</span> : String(k);\n}\n","// SelectionToolbar — the bulk-action FRAME, not the actions.\n//\n// Deliberately generic: it shows the selected count, a clear-all, and an\n// `actions` slot. The actual verbs are domain logic the consumer renders into the\n// slot. The reusable part is the selection plumbing + affordance; the verbs are\n// not. This keeps domain coupling out while still shipping the pattern.\n\nimport type { ReactNode } from \"react\";\nimport type { RowId } from \"@pythia-software/query-table-core\";\nimport type { SelectionApi } from \"@pythia-software/query-table-react\";\n\nexport interface SelectionToolbarProps {\n selection: SelectionApi;\n /** Consumer-rendered action buttons. Receives the selected ids so the consumer\n * can gate/enable actions (e.g. mixed-state rules). */\n actions: (selectedIds: RowId[]) => ReactNode;\n /** Hidden when nothing is selected unless `alwaysShow`. */\n alwaysShow?: boolean;\n className?: string;\n}\n\nconst cx = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\nexport function SelectionToolbar({ selection, actions, alwaysShow, className }: SelectionToolbarProps): ReactNode {\n if (selection.count === 0 && !alwaysShow) return null;\n\n const selectedIds = [...selection.selected];\n\n return (\n <div className={cx(\"qt-selection-toolbar\", className)} role=\"toolbar\">\n <span className=\"qt-selection-count\">\n {selection.count} selected\n </span>\n <button\n type=\"button\"\n className=\"qt-btn\"\n onClick={selection.clear}\n disabled={selection.count === 0}\n >\n clear\n </button>\n <span className=\"qt-selection-actions\">{actions(selectedIds)}</span>\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useState","Fragment","jsx","jsxs","cx","MENU_WIDTH","useState","useEffect","valueToString","MenuItem","useEffect","useMemo","useRef","useState","NULLARY_OPS","isSortable","opsForField","useMemo","useState","Fragment","jsx","jsxs","useEffect","jsx","jsxs","jsx","jsxs","cx","formatDuration","useState","useEffect","NULLARY_OPS","useMemo","useRef","opsForField","isSortable","useMemo","jsx","jsxs","cx","useMemo","jsx","jsxs","cx"]}
|
|
1
|
+
{"version":3,"sources":["../src/renderers.ts","../src/DataTable.tsx","../src/CellMenu.tsx","../src/QueryBuilder.tsx","../src/FieldPicker.tsx","../src/SavedQueriesModal.tsx","../src/MetricsPanel.tsx","../src/SelectionToolbar.tsx"],"sourcesContent":["// renderers.ts — the cell render registry.\n//\n// This is how the table stays \"gold standard but customizable\" (the core ask).\n// The package ships ONLY truly-generic renderers. Domain-specific cells are\n// registered by the consuming app — they must NOT live in a generic package.\n// A FieldDef.render is either a key resolved\n// against `{ ...defaultRenderers, ...consumerRenderers }` or an inline function.\n\nimport type { ReactNode } from \"react\";\nimport { createElement } from \"react\";\nimport type { FieldDef, QueryState } from \"@pythia-software/query-table-core\";\n\nexport interface CellContext<Row = any, V = unknown> {\n value: V;\n row: Row;\n field: FieldDef<Row, V>;\n /** Current query — lets renderers reflect active state (e.g. highlight matches). */\n query: QueryState;\n}\n\nexport type CellRenderer<Row = any, V = unknown> = (ctx: CellContext<Row, V>) => ReactNode;\n\nexport type RenderRegistry<Row = any> = Record<string, CellRenderer<Row>>;\n\n/** The em-dash shown for empty / null values, so every renderer agrees. */\nconst EMPTY = \"—\";\n\nconst muted = (text: string): ReactNode => createElement(\"span\", { className: \"qt-muted\" }, text);\n\nfunction isEmpty(v: unknown): boolean {\n return v == null || v === \"\" || (Array.isArray(v) && v.length === 0);\n}\n\nconst SAFE_LINK_PROTOCOLS: ReadonlySet<string> = new Set([\"http:\", \"https:\", \"mailto:\", \"tel:\"]);\n\n/** Resolve a user-controlled link against a harmless HTTPS base and allow only\n * navigation protocols. This catches obfuscated forms such as `java\\nscript:`\n * that simple prefix checks miss while preserving relative and fragment URLs. */\nexport function safeLinkHref(value: unknown): string | null {\n if (isEmpty(value)) return null;\n const href = String(value).trim();\n if (!href) return null;\n try {\n const parsed = new URL(href, \"https://query-table.invalid/\");\n return SAFE_LINK_PROTOCOLS.has(parsed.protocol) ? href : null;\n } catch {\n return null;\n }\n}\n\n/** Generic, domain-free renderers shipped with the package. Keys are stable and\n * referenced from FieldDef.render. Consumers spread these and add their own. */\nexport const defaultRenderers: RenderRegistry = {\n // String(value), em-dash for null/empty\n text({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n return String(value);\n },\n\n // single-line ellipsis (CSS does the truncation; title carries the full text)\n truncate({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const s = String(value);\n return createElement(\"span\", { className: \"qt-truncate\", title: s }, s);\n },\n\n // locale-grouped number\n number({ value }) {\n if (value == null || value === \"\") return muted(EMPTY);\n const n = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(n)) return muted(EMPTY);\n return n.toLocaleString();\n },\n\n // ✓ / —\n bool_check({ value }) {\n if (value == null) return muted(EMPTY);\n return value ? \"✓\" : muted(EMPTY);\n },\n\n // ISO clamped to seconds\n datetime({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const s = String(value);\n // pgtype zero-time and other epoch placeholders read as empty.\n if (s.startsWith(\"0001-\")) return muted(EMPTY);\n return s.slice(0, 19).replace(\"T\", \" \");\n },\n\n // relative (\"5m ago\", \"yesterday\", \"Mar 4\")\n datetime_rel({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const s = String(value);\n if (s.startsWith(\"0001-\")) return muted(EMPTY);\n return createElement(\"span\", { title: s.slice(0, 19).replace(\"T\", \" \") }, formatRelative(s));\n },\n\n // human duration from a millisecond number\n duration_ms({ value }) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return muted(EMPTY);\n return formatDuration(value);\n },\n\n // humanized bytes (B/KB/MB/GB)\n byte_size({ value }) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) return muted(EMPTY);\n return formatBytes(value);\n },\n\n // string[] as pills\n tags_pills({ value }) {\n if (!Array.isArray(value) || value.length === 0) return muted(EMPTY);\n return createElement(\n \"span\",\n { className: \"qt-pills\" },\n value.map((t, i) => createElement(\"span\", { key: `${String(t)}-${i}`, className: \"qt-pill\" }, String(t))),\n );\n },\n\n // value as an <a href={value}> when its URL scheme is safe\n link({ value }) {\n if (isEmpty(value)) return muted(EMPTY);\n const label = String(value);\n const href = safeLinkHref(value);\n if (!href) return createElement(\"span\", { className: \"qt-muted\", title: \"Unsafe link blocked\" }, label);\n return createElement(\n \"a\",\n { className: \"qt-link\", href, target: \"_blank\", rel: \"noopener noreferrer\", title: href },\n label,\n );\n },\n};\n\n/** Resolve a FieldDef's renderer: inline fn wins, else registry lookup, else\n * the `text` fallback. */\nexport function resolveRenderer<Row>(\n field: FieldDef<Row>,\n registry: RenderRegistry<Row>,\n): CellRenderer<Row> {\n const r = field.render;\n if (typeof r === \"function\") {\n // core's CellRenderer returns `unknown`; ours narrows that to ReactNode.\n return r as CellRenderer<Row>;\n }\n if (typeof r === \"string\") {\n const found = registry[r];\n if (found) return found;\n }\n // text fallback always exists (consumers spread defaultRenderers in).\n return (registry[\"text\"] ?? defaultRenderers[\"text\"]) as CellRenderer<Row>;\n}\n\n// ---- formatting helpers ---------------------------------------------------\n\nfunction formatDuration(ms: number): string {\n if (ms < 0) return String(ms);\n if (ms < 1) return `${ms.toFixed(2)}ms`;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n const totalSec = ms / 1000;\n if (totalSec < 60) return `${totalSec.toFixed(1)}s`;\n const h = Math.floor(totalSec / 3600);\n const m = Math.floor((totalSec % 3600) / 60);\n const s = Math.round(totalSec % 60);\n if (h > 0) return `${h}h ${m}m`;\n return `${m}m ${s}s`;\n}\n\nfunction formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\nfunction formatRelative(iso: string): string {\n const ts = Date.parse(iso);\n if (!Number.isFinite(ts)) return iso.slice(0, 19);\n const now = Date.now();\n const diffSec = Math.round((now - ts) / 1000);\n if (Math.abs(diffSec) < 30) return \"just now\";\n const past = diffSec >= 0;\n const abs = Math.abs(diffSec);\n if (abs < 60) return past ? `${abs}s ago` : `in ${abs}s`;\n if (abs < 3600) return past ? `${Math.round(abs / 60)}m ago` : `in ${Math.round(abs / 60)}m`;\n if (abs < 86400) return past ? `${Math.round(abs / 3600)}h ago` : `in ${Math.round(abs / 3600)}h`;\n const days = Math.round(abs / 86400);\n if (past && days === 1) return \"yesterday\";\n if (days < 7) return past ? `${days}d ago` : `in ${days}d`;\n const d = new Date(ts);\n const sameYear = d.getFullYear() === new Date().getFullYear();\n const opts: Intl.DateTimeFormatOptions = sameYear\n ? { month: \"short\", day: \"numeric\" }\n : { month: \"short\", day: \"numeric\", year: \"2-digit\" };\n return d.toLocaleDateString(undefined, opts);\n}\n","// DataTable — the table renderer.\n//\n// Presentation only: it draws headers (sort affordances), the checkbox column,\n// cells (via the render registry), the right-click CellMenu, column resize\n// handles, and the loading bar. All state\n// lives in the @pythia-software/query-table-react hook; DataTable receives the resolved view\n// and emits intents through onQueryChange. Its props mirror a conventional\n// schema-driven table so adoption is mechanical.\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode, type SetStateAction } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport type { OrderByClause, QueryState, FieldDef, RowId, SelectColumn, WhereClause } from \"@pythia-software/query-table-core\";\nimport { isSortable, readFieldValue } from \"@pythia-software/query-table-core\";\nimport { useColumnDrag, type SelectionApi, type ColumnDragApi } from \"@pythia-software/query-table-react\";\nimport { resolveRenderer, type RenderRegistry } from \"./renderers\";\nimport type { TableClassNames } from \"./classNames\";\nimport { CellMenu } from \"./CellMenu\";\n\nexport interface DataTableProps<Row> {\n /** Ordered visible fields (widths already resolved), from `api.visibleFields`. */\n fields: FieldDef<Row>[];\n rows: Row[];\n query: QueryState;\n onQueryChange: (q: SetStateAction<QueryState>) => void;\n\n /** Resolves FieldDef.render keys. Pass `{ ...defaultRenderers, ...yours }`. */\n renderers: RenderRegistry<Row>;\n /** Row → stable id (defaults to reading the schema's idField). */\n rowId: (row: Row) => RowId | null;\n\n /** Optional checkbox column + selection behavior (from `api.selection`). */\n selection?: SelectionApi;\n\n /** Shared column-reorder drag state (`api.columnDrag`). Pass it so dragging a\n * table header also live-previews/dims the matching QueryBuilder select chip\n * (and vice versa). Omit for a self-contained, table-only drag. */\n columnDrag?: ColumnDragApi;\n\n /** Always-visible trailing column (row actions, links). */\n trailing?: (row: Row) => ReactNode;\n trailingLabel?: string;\n\n /** Total matching rows before pagination, when known. */\n total?: number | null;\n\n loading?: boolean;\n emptyMessage?: string;\n /** Maximum height of the scroll viewport. Defaults to 600px. */\n maxHeight?: number | string;\n /** Estimated row height in pixels; measured rows replace the estimate. Defaults to 37. */\n estimateRowHeight?: number;\n /** Extra rows rendered above and below the visible range. Defaults to 8. */\n overscan?: number;\n /** Tailwind / bespoke styling slots (Mode B). */\n classNames?: TableClassNames;\n}\n\nconst cx = (...parts: Array<string | undefined | false>): string =>\n parts.filter((p): p is string => Boolean(p)).join(\" \");\n\nconst MIN_WIDTH = 1;\nconst MIN_SELECTION_WIDTH = 1;\nconst MAX_WIDTH = 800;\nconst DEFAULT_WIDTH = 120;\nconst DEFAULT_SELECTION_WIDTH = 36;\nconst AUTOFIT_EXTRA_PX = 16;\nconst MENU_WIDTH = 240;\nconst MENU_ROW_HEIGHT = 32;\nconst COPY_FEEDBACK_MS = 900;\nconst DEFAULT_MAX_HEIGHT = 600;\nconst DEFAULT_ROW_HEIGHT = 37;\nconst DEFAULT_OVERSCAN = 8;\nconst SELECTION_COLUMN = \"__qt_selection__\";\ntype HeaderSortPlacement = \"set\" | \"append\" | \"prepend\";\n\ninterface MenuState<Row> {\n kind: \"cell\" | \"header\";\n field: FieldDef<Row>;\n value?: unknown;\n x: number;\n y: number;\n}\n\nexport function DataTable<Row>(props: DataTableProps<Row>): ReactNode {\n const {\n fields,\n rows,\n query,\n onQueryChange,\n renderers,\n rowId,\n selection,\n trailing,\n trailingLabel,\n total = null,\n loading,\n emptyMessage,\n maxHeight = DEFAULT_MAX_HEIGHT,\n estimateRowHeight = DEFAULT_ROW_HEIGHT,\n overscan = DEFAULT_OVERSCAN,\n classNames,\n } = props;\n\n const [menu, setMenu] = useState<MenuState<Row> | null>(null);\n const [selectionColumnWidth, setSelectionColumnWidth] = useState(DEFAULT_SELECTION_WIDTH);\n const [tableColumnOrder, setTableColumnOrder] = useState<string[]>([]);\n const [copiedCellKey, setCopiedCellKey] = useState<string | null>(null);\n const [headerHeight, setHeaderHeight] = useState(0);\n const [showHorizontalCue, setShowHorizontalCue] = useState(false);\n const tableWrapRef = useRef<HTMLDivElement>(null);\n const tableHeadRef = useRef<HTMLTableSectionElement>(null);\n const tableRef = useRef<HTMLTableElement>(null);\n const resizeGuideRef = useRef<HTMLDivElement>(null);\n // A real <col> width change invalidates layout for every row. During a drag,\n // move only the compositor-friendly guide and apply the column width once on\n // release; refs also keep pointermove out of React's render pipeline.\n const resizeCommitRef = useRef<{ name: string; width: number } | null>(null);\n const resizePreviewRef = useRef<{\n name: string;\n width: number;\n previousWidth: number;\n startTableWidth: number;\n guideX: number;\n } | null>(null);\n const resizeFrameRef = useRef<number | null>(null);\n const cancelResizeRef = useRef<(() => void) | null>(null);\n const resizingFieldRef = useRef<string | null>(null);\n const copiedCellTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Shared drag state when the host passes `api.columnDrag`; otherwise a local\n // instance keeps the table self-contained. (The hook is always called to obey\n // the rules of hooks; the local one is unused when a shared one is provided.)\n const localColumnDrag = useColumnDrag();\n const columnDrag = props.columnDrag ?? localColumnDrag;\n const rowIds = useMemo(() => rows.map(rowId), [rowId, rows]);\n const virtualRowKeys = useMemo(\n () => rowIds.map((id, index) => (id == null ? `index:${index}` : `${typeof id}:${String(id)}`)),\n [rowIds],\n );\n const getVirtualRowKey = useCallback((index: number) => virtualRowKeys[index] ?? `index:${index}`, [virtualRowKeys]);\n const normalizedEstimate = Number.isFinite(estimateRowHeight)\n ? Math.max(1, estimateRowHeight)\n : DEFAULT_ROW_HEIGHT;\n const normalizedOverscan = Number.isFinite(overscan)\n ? Math.max(0, Math.floor(overscan))\n : DEFAULT_OVERSCAN;\n const estimateVirtualRow = useCallback(() => normalizedEstimate, [normalizedEstimate]);\n const initialViewportHeight = typeof maxHeight === \"number\" && maxHeight > 0 ? maxHeight : DEFAULT_MAX_HEIGHT;\n const initialRect = useMemo(() => ({ width: 0, height: initialViewportHeight }), [initialViewportHeight]);\n const rowVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({\n count: rows.length,\n getScrollElement: () => tableWrapRef.current,\n estimateSize: estimateVirtualRow,\n getItemKey: getVirtualRowKey,\n overscan: normalizedOverscan,\n // The header participates in normal table layout even while it is sticky.\n // Offset row measurements so the virtual range matches the body's origin.\n scrollMargin: headerHeight,\n initialRect,\n });\n\n useEffect(() => {\n return () => {\n if (copiedCellTimerRef.current) {\n clearTimeout(copiedCellTimerRef.current);\n copiedCellTimerRef.current = null;\n }\n cancelResizeRef.current?.();\n };\n }, []);\n\n useEffect(() => {\n const header = tableHeadRef.current;\n if (!header) return;\n\n const measureHeader = () => {\n const next = header.getBoundingClientRect().height;\n setHeaderHeight((current) => (current === next ? current : next));\n };\n measureHeader();\n\n if (typeof ResizeObserver === \"undefined\") {\n window.addEventListener(\"resize\", measureHeader);\n return () => window.removeEventListener(\"resize\", measureHeader);\n }\n\n const observer = new ResizeObserver(measureHeader);\n observer.observe(header);\n return () => observer.disconnect();\n }, []);\n\n function cellKey(rowIdValue: RowId | null, rowIndex: number, fieldName: string): string {\n return rowIdValue == null ? `row:${rowIndex}:${fieldName}` : `id:${rowIdValue}:${fieldName}`;\n }\n\n function isInteractiveTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return tag === \"A\" || tag === \"BUTTON\" || tag === \"INPUT\" || tag === \"SELECT\";\n }\n\n function showCopyFeedback(cellId: string) {\n if (copiedCellTimerRef.current) {\n clearTimeout(copiedCellTimerRef.current);\n copiedCellTimerRef.current = null;\n }\n setCopiedCellKey(cellId);\n copiedCellTimerRef.current = setTimeout(() => {\n setCopiedCellKey((current) => (current === cellId ? null : current));\n copiedCellTimerRef.current = null;\n }, COPY_FEEDBACK_MS);\n }\n\n async function copyCellToClipboard(e: React.MouseEvent, f: FieldDef<Row>, rowIdValue: RowId | null, rowIndex: number, value: unknown) {\n if (isInteractiveTarget(e.target)) return;\n e.preventDefault();\n e.stopPropagation();\n setMenu(null);\n try {\n if (navigator.clipboard) {\n await navigator.clipboard.writeText(valueToString(value));\n }\n } catch {\n /* clipboard denial is non-fatal */\n }\n showCopyFeedback(cellKey(rowIdValue, rowIndex, f.name));\n }\n\n const pageIds = rowIds.filter((id): id is RowId => id != null);\n const headerState = selection ? selection.pageState(pageIds) : \"none\";\n const showSel = selection != null;\n\n // ---- sort state (used only for indicators + header menu actions) ----\n function sortKeyFor(f: FieldDef<Row>): string {\n return f.sort?.field ?? f.name;\n }\n function applyHeaderSort(f: FieldDef<Row>, dir: \"asc\" | \"desc\", placement: HeaderSortPlacement) {\n if (!isSortable(f)) return;\n onQueryChange({\n ...query,\n offset: 0,\n orderBy: nextHeaderOrderBy(query.orderBy, sortKeyFor(f), dir, placement),\n });\n setMenu(null);\n }\n function removeColumn(f: FieldDef<Row>) {\n const explicit = materialize(query.select, fields);\n const nextSelect = explicit.filter((c) => c.field !== f.name);\n const nextOrderBy = query.orderBy.filter((s) => s.field !== sortKeyFor(f));\n if (nextSelect.length === 0) return;\n onQueryChange({ ...query, select: nextSelect, orderBy: nextOrderBy });\n setMenu(null);\n }\n function sortInfo(f: FieldDef<Row>): { dir: \"asc\" | \"desc\"; priority: number | null } | null {\n const key = sortKeyFor(f);\n const idx = query.orderBy.findIndex((o) => o.field === key);\n if (idx === -1) return null;\n const term = query.orderBy[idx]!;\n return { dir: term.dir, priority: query.orderBy.length > 1 ? idx + 1 : null };\n }\n\n // ---- width (resolved from query.select; written back through onQueryChange) ----\n function widthFor(name: string, f: FieldDef<Row>): number | undefined {\n const col = query.select.find((c) => c.field === name);\n return col?.width ?? f.select?.width;\n }\n function resolvedWidthFor(name: string, f: FieldDef<Row>): number | undefined {\n return widthFor(name, f);\n }\n function resolvedColumnWidthFor(name: string, f?: FieldDef<Row>): number | undefined {\n if (name === SELECTION_COLUMN) return selectionColumnWidth;\n return f ? resolvedWidthFor(name, f) : undefined;\n }\n function displayColumnWidthFor(name: string, f?: FieldDef<Row>): number {\n if (name === SELECTION_COLUMN) return resolvedColumnWidthFor(name) ?? DEFAULT_SELECTION_WIDTH;\n return f ? resolvedWidthFor(name, f) ?? DEFAULT_WIDTH : DEFAULT_WIDTH;\n }\n function clampWidth(width: number): number {\n return Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, Math.round(width)));\n }\n function clampColumnWidth(name: string, width: number): number {\n const min = name === SELECTION_COLUMN ? MIN_SELECTION_WIDTH : MIN_WIDTH;\n return Math.max(min, Math.min(MAX_WIDTH, Math.round(width)));\n }\n function commitColumnWidth(name: string, width: number) {\n if (name === SELECTION_COLUMN) {\n setSelectionColumnWidth(clampColumnWidth(name, width));\n return;\n }\n setWidth(name, width);\n }\n function setWidth(name: string, width: number) {\n const px = clampWidth(width);\n onQueryChange((prev) => ({ ...prev, select: writeWidth(prev.select, fields, name, px) }));\n }\n function applyResizeGuide() {\n const preview = resizePreviewRef.current;\n const guide = resizeGuideRef.current;\n if (!preview || !guide) return;\n guide.style.transform = `translateX(${preview.guideX}px)`;\n }\n function applyCommittedResize() {\n const preview = resizePreviewRef.current;\n const table = tableRef.current;\n if (!preview || !table) return;\n const selector = `col[data-qt-column=\"${cssAttributeValue(preview.name)}\"]`;\n const col = table.querySelector<HTMLTableColElement>(selector);\n if (col) col.style.width = `${preview.width}px`;\n table.style.minWidth = `${preview.startTableWidth + preview.width - preview.previousWidth}px`;\n }\n function startResize(name: string, startWidth: number | undefined, e: React.PointerEvent<HTMLSpanElement>) {\n e.preventDefault();\n e.stopPropagation();\n const startX = e.clientX;\n const startW = startWidth ?? e.currentTarget.parentElement?.getBoundingClientRect().width ?? DEFAULT_WIDTH;\n const previousCursor = document.body.style.cursor;\n const previousUserSelect = document.body.style.userSelect;\n const initialWidth = clampColumnWidth(name, startW);\n const wrap = tableWrapRef.current;\n const wrapRect = wrap?.getBoundingClientRect();\n const header = e.currentTarget.parentElement as HTMLTableCellElement | null;\n resizeCommitRef.current = null;\n resizePreviewRef.current = {\n name,\n width: initialWidth,\n previousWidth: displayColumnWidthFor(name, fieldByName.get(name)),\n startTableWidth: tableWidth,\n guideX: startX - (wrapRect?.left ?? 0) + (wrap?.scrollLeft ?? 0),\n };\n resizingFieldRef.current = name;\n tableWrapRef.current?.classList.add(\"qt-table-wrap--resizing\");\n header?.classList.add(\"qt-th--resizing\");\n if (header) header.draggable = false;\n if (resizeGuideRef.current) {\n resizeGuideRef.current.style.display = \"block\";\n resizeGuideRef.current.style.top = `${wrap?.scrollTop ?? 0}px`;\n resizeGuideRef.current.style.height = `${wrap?.clientHeight ?? 0}px`;\n }\n applyResizeGuide();\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n const cleanup = (commitWidth: boolean) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", finish);\n window.removeEventListener(\"pointercancel\", finish);\n if (resizeFrameRef.current != null) {\n cancelAnimationFrame(resizeFrameRef.current);\n resizeFrameRef.current = null;\n applyResizeGuide();\n }\n document.body.style.cursor = previousCursor;\n document.body.style.userSelect = previousUserSelect;\n tableWrapRef.current?.classList.remove(\"qt-table-wrap--resizing\");\n tableRef.current\n ?.querySelector<HTMLElement>(`th[data-qt-field=\"${cssAttributeValue(name)}\"]`)\n ?.classList.remove(\"qt-th--resizing\");\n if (header) header.draggable = true;\n const commit = commitWidth ? resizeCommitRef.current : null;\n if (commit) applyCommittedResize();\n if (resizeGuideRef.current) resizeGuideRef.current.style.display = \"none\";\n resizeCommitRef.current = null;\n resizePreviewRef.current = null;\n resizingFieldRef.current = null;\n cancelResizeRef.current = null;\n if (commit) commitColumnWidth(commit.name, commit.width);\n };\n const finish = () => cleanup(true);\n const onMove = (ev: PointerEvent) => {\n const next = clampColumnWidth(name, startW + (ev.clientX - startX));\n resizeCommitRef.current = { name, width: next };\n const preview = resizePreviewRef.current;\n if (preview) {\n preview.width = next;\n preview.guideX = startX + (next - startW) - (wrapRect?.left ?? 0) + (wrap?.scrollLeft ?? 0);\n }\n if (resizeFrameRef.current == null) {\n resizeFrameRef.current = requestAnimationFrame(() => {\n resizeFrameRef.current = null;\n applyResizeGuide();\n });\n }\n };\n cancelResizeRef.current = () => cleanup(false);\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", finish);\n window.addEventListener(\"pointercancel\", finish);\n }\n function autofitColumn(name: string) {\n const wrap = tableWrapRef.current;\n if (!wrap) return;\n const selector = `[data-qt-field=\"${cssAttributeValue(name)}\"]`;\n let width = 0;\n wrap.querySelectorAll<HTMLElement>(selector).forEach((el) => {\n width = Math.max(width, el.scrollWidth);\n });\n if (width > 0) setWidth(name, width + AUTOFIT_EXTRA_PX);\n }\n function resizeWithKeyboard(name: string, startWidth: number | undefined, e: React.KeyboardEvent<HTMLSpanElement>) {\n if (e.key !== \"ArrowLeft\" && e.key !== \"ArrowRight\" && e.key !== \"Enter\") return;\n e.preventDefault();\n e.stopPropagation();\n if (e.key === \"Enter\") {\n autofitColumn(name);\n return;\n }\n const step = e.shiftKey ? 25 : 10;\n const direction = e.key === \"ArrowRight\" ? 1 : -1;\n commitColumnWidth(name, (startWidth ?? DEFAULT_WIDTH) + step * direction);\n }\n\n // ---- reorder (drag headers; writes the new SELECT order) ----\n // `overIndex` is a position in the list with the dragged column removed, which\n // is exactly where the live preview shows the dragged header, so the committed\n // order can never disagree with what the user saw.\n function reorderByIndex(from: string, overIndex: number) {\n const withoutDragged = tableColumnNames.filter((n) => n !== from);\n if (withoutDragged.length === tableColumnNames.length) return; // `from` not visible\n const at = Math.max(0, Math.min(overIndex, withoutDragged.length));\n withoutDragged.splice(at, 0, from);\n setTableColumnOrder(withoutDragged);\n const nextFieldOrder = withoutDragged.filter((name) => name !== SELECTION_COLUMN);\n if (!sameOrder(nextFieldOrder, fieldNames)) {\n onQueryChange({ ...query, select: reorderSelect(query.select, fields, nextFieldOrder) });\n }\n }\n\n const fieldByName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n const fieldNames = useMemo(() => fields.map((f) => f.name), [fields]);\n const tableColumnNames = useMemo(() => {\n if (!showSel) return fieldNames;\n const defaultOrder = [SELECTION_COLUMN, ...fieldNames];\n const valid = new Set(defaultOrder);\n const kept = tableColumnOrder.filter((name) => valid.has(name));\n const missing = defaultOrder.filter((name) => !kept.includes(name));\n return [...kept, ...missing];\n }, [fieldNames, showSel, tableColumnOrder]);\n const dragSource = columnDrag.source;\n // While dragging, render the WHOLE column (header + body cells + width) in the\n // order a drop would commit: the dragged column stays MOUNTED (removing the\n // drag-source node mid-drag aborts the native HTML5 drag) but slides to the\n // hovered slot and is dimmed. Because the rendered order IS the would-be\n // result, the live preview can never disagree with where the drop lands.\n const renderedColumnNames = useMemo(() => columnDrag.preview(tableColumnNames), [columnDrag, tableColumnNames]);\n\n // ---- selection ----\n function toggleHeader() {\n if (!selection) return;\n selection.setPage(pageIds, headerState !== \"all\");\n }\n\n // ---- cell menu ----\n function openMenu(e: React.MouseEvent, f: FieldDef<Row>, row: Row) {\n if (isInteractiveTarget(e.target)) return;\n e.preventDefault();\n setMenu({ kind: \"cell\", field: f, value: readFieldValue(f, row), x: e.clientX, y: e.clientY });\n }\n function openHeaderMenu(e: React.MouseEvent, f: FieldDef<Row>) {\n if (isInteractiveTarget(e.target)) return;\n e.preventDefault();\n setMenu({ kind: \"header\", field: f, x: e.clientX, y: e.clientY });\n }\n\n function onTableWheel(e: React.WheelEvent<HTMLDivElement>) {\n const wrap = tableWrapRef.current;\n if (!wrap) return;\n\n const canScrollHorizontally = wrap.scrollWidth > wrap.clientWidth;\n if (!canScrollHorizontally) return;\n\n const dx = e.deltaX;\n const dy = e.deltaY;\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n const prefersHorizontal = absDx > absDy * 1.25;\n\n if (dx === 0 && !e.shiftKey) return;\n\n if (dx === 0 && e.shiftKey) {\n e.preventDefault();\n e.stopPropagation();\n wrap.scrollLeft += dy;\n return;\n }\n\n if (e.shiftKey || prefersHorizontal) {\n e.preventDefault();\n e.stopPropagation();\n wrap.scrollLeft += dx;\n }\n }\n\n function resizeHandle(name: string, label: string, width: number | undefined): ReactNode {\n return (\n <span\n className={cx(\"qt-resize-handle\", classNames?.resizeHandle)}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={`Resize ${label} column`}\n title=\"Drag to resize. Press Enter to auto-fit.\"\n tabIndex={0}\n onPointerDown={(e) => startResize(name, width, e)}\n onKeyDown={(e) => resizeWithKeyboard(name, width, e)}\n onClick={(e) => e.stopPropagation()}\n />\n );\n }\n\n const totalCols = fields.length + (showSel ? 1 : 0) + (trailing ? 1 : 0);\n const tableWidth = renderedColumnNames.reduce((sum, name) => {\n const f = fieldByName.get(name);\n return sum + displayColumnWidthFor(name, f);\n }, trailing ? 40 : 0);\n // A horizontal data grid is more useful than a card stack on small screens,\n // but overflow should be discoverable. Keep a lightweight cue visible only\n // while there is more content to the right.\n useEffect(() => {\n const wrap = tableWrapRef.current;\n if (!wrap) return;\n\n const updateCue = () => {\n const hasMoreToRight = wrap.scrollWidth - wrap.clientWidth - wrap.scrollLeft > 2;\n setShowHorizontalCue(hasMoreToRight);\n };\n\n updateCue();\n window.addEventListener(\"resize\", updateCue);\n const observer = typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(updateCue);\n observer?.observe(wrap);\n return () => {\n window.removeEventListener(\"resize\", updateCue);\n observer?.disconnect();\n };\n }, [renderedColumnNames, tableWidth]);\n const start = query.offset;\n const end = total != null ? Math.min(start + query.limit, total) : start + rows.length;\n const canPrev = start > 0;\n const canNext = total != null ? end < total : rows.length >= query.limit;\n const prevPage = () => onQueryChange((prev) => ({ ...prev, offset: Math.max(0, prev.offset - prev.limit) }));\n const nextPage = () => onQueryChange((prev) => ({ ...prev, offset: prev.offset + prev.limit }));\n const summaryText =\n total == null || total === 0 ? `${rows.length} rows` : `${start + 1}–${end} of ${total}`;\n const virtualRows = rowVirtualizer.getVirtualItems();\n const firstVirtualRow = virtualRows[0];\n const lastVirtualRow = virtualRows[virtualRows.length - 1];\n const paddingTop = firstVirtualRow ? Math.max(0, firstVirtualRow.start - headerHeight) : 0;\n const paddingBottom = lastVirtualRow\n ? Math.max(0, rowVirtualizer.getTotalSize() - (lastVirtualRow.end - headerHeight))\n : 0;\n\n return (\n <>\n {showHorizontalCue ? (\n <div className=\"qt-table-scroll-cue\" aria-hidden=\"true\">\n Swipe to see more <span>→</span>\n </div>\n ) : null}\n <div\n ref={tableWrapRef}\n className={cx(\n \"qt-table-wrap\",\n loading && \"qt-table-wrap--loading\",\n classNames?.wrap,\n )}\n onWheel={onTableWheel}\n style={{ maxHeight, overflowY: \"auto\" }}\n onScroll={() => {\n const wrap = tableWrapRef.current;\n if (!wrap) return;\n setShowHorizontalCue(wrap.scrollWidth - wrap.clientWidth - wrap.scrollLeft > 2);\n }}\n role=\"region\"\n aria-label=\"Scrollable data table\"\n tabIndex={0}\n >\n {loading && (\n <div className={cx(\"qt-loading-bar\", classNames?.loadingBar)} role=\"progressbar\" aria-label=\"loading\" />\n )}\n <div\n ref={resizeGuideRef}\n className={cx(\"qt-resize-guide\", classNames?.resizeGuide)}\n aria-hidden=\"true\"\n />\n <table ref={tableRef} className={cx(\"qt-table\", classNames?.table)} style={{ minWidth: tableWidth }}>\n <colgroup>\n {renderedColumnNames.map((name) => {\n const f = fieldByName.get(name);\n const w = displayColumnWidthFor(name, f);\n if (name === SELECTION_COLUMN) return <col key={name} data-qt-column={name} style={{ width: w }} />;\n if (!f) return null;\n return <col key={f.name} data-qt-column={f.name} style={{ width: w }} />;\n })}\n {trailing && <col style={{ width: 40 }} />}\n </colgroup>\n <thead ref={tableHeadRef} className={classNames?.thead}>\n <tr className={classNames?.headerRow}>\n {renderedColumnNames.map((name) => {\n if (name === SELECTION_COLUMN) {\n return (\n <th\n key={name}\n data-qt-field={name}\n className={cx(\n \"qt-th\",\n \"qt-checkbox-cell\",\n dragSource === name && \"qt-th--dragging\",\n classNames?.th,\n classNames?.checkboxCell,\n )}\n draggable\n onDragStart={(e) => {\n if (resizingFieldRef.current) {\n e.preventDefault();\n return;\n }\n columnDrag.start(name, tableColumnNames.indexOf(name));\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", name);\n }}\n onDragOver={(e) => {\n if (!columnDrag.source) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (columnDrag.source !== name) {\n const withoutDragged = tableColumnNames.filter((n) => n !== columnDrag.source);\n let next = withoutDragged.indexOf(name);\n if (next >= 0) {\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n columnDrag.over(next);\n }\n }\n }}\n onDrop={(e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n const from = columnDrag.source || e.dataTransfer.getData(\"text/plain\");\n if (from && columnDrag.overIndex != null) reorderByIndex(from, columnDrag.overIndex);\n columnDrag.end();\n }}\n onDragEnd={() => columnDrag.end()}\n >\n <input\n type=\"checkbox\"\n checked={headerState === \"all\"}\n ref={(el) => {\n if (el) el.indeterminate = headerState === \"some\";\n }}\n onChange={toggleHeader}\n aria-label=\"select all on page\"\n />\n {resizeHandle(name, \"selection\", resolvedColumnWidthFor(name))}\n </th>\n );\n }\n const f = fieldByName.get(name);\n if (!f) return null;\n const info = sortInfo(f);\n const sortable = isSortable(f);\n return (\n <th\n // Stable key (not index-based): while dragging, React must\n // MOVE the dragged <th>, not remount it — a remount removes\n // the drag source and aborts the native drag.\n key={f.name}\n data-qt-field={f.name}\n className={cx(\n \"qt-th\",\n sortable && \"qt-th--sortable\",\n dragSource === f.name && \"qt-th--dragging\",\n classNames?.th,\n )}\n style={f.select?.align ? { textAlign: f.select.align } : undefined}\n draggable\n onDragStart={(e) => {\n if (resizingFieldRef.current) {\n e.preventDefault();\n return;\n }\n columnDrag.start(f.name, tableColumnNames.indexOf(f.name));\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", f.name);\n }}\n onDragOver={(e) => {\n if (!columnDrag.source) return;\n // preventDefault on every header (incl. the dragged one) so\n // there is no dead drop zone anywhere along the row.\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (columnDrag.source !== f.name) {\n const withoutDragged = tableColumnNames.filter((n) => n !== columnDrag.source);\n let next = withoutDragged.indexOf(f.name);\n if (next >= 0) {\n // Drop after the hovered header when past its midpoint,\n // so a column can be moved into the last slot.\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n columnDrag.over(next);\n }\n }\n }}\n onDrop={(e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n const from = columnDrag.source || e.dataTransfer.getData(\"text/plain\");\n if (from && columnDrag.overIndex != null) reorderByIndex(from, columnDrag.overIndex);\n columnDrag.end();\n }}\n onDragEnd={() => columnDrag.end()}\n >\n <span\n className=\"qt-th-label\"\n onClick={(e) => openHeaderMenu(e, f)}\n style={{ cursor: \"pointer\" }}\n title=\"Click to open column actions\"\n >\n {f.label}\n {info && (\n <span className=\"qt-sort-indicator\">\n {info.dir === \"asc\" ? \" ↑\" : \" ↓\"}\n {info.priority != null && <sup className=\"qt-sort-priority\">{info.priority}</sup>}\n </span>\n )}\n </span>\n {resizeHandle(f.name, f.label, resolvedColumnWidthFor(f.name, f))}\n </th>\n );\n })}\n {trailing && <th className={cx(\"qt-th\", classNames?.th)}>{trailingLabel ?? \"\"}</th>}\n </tr>\n </thead>\n <tbody className={classNames?.tbody}>\n {rows.length === 0 && (\n <tr>\n <td colSpan={totalCols} className={cx(\"qt-cell\", \"qt-empty\", classNames?.empty)}>\n {emptyMessage ?? \"No rows.\"}\n </td>\n </tr>\n )}\n {paddingTop > 0 && (\n <tr className=\"qt-virtual-spacer\" aria-hidden=\"true\">\n <td colSpan={totalCols} style={{ height: paddingTop, padding: 0, border: 0 }} />\n </tr>\n )}\n {virtualRows.map((virtualRow) => {\n const i = virtualRow.index;\n const row = rows[i]!;\n const id = rowIds[i] ?? null;\n const selected = id != null && selection ? selection.isSelected(id) : false;\n return (\n <tr\n key={virtualRow.key}\n data-index={i}\n ref={rowVirtualizer.measureElement}\n className={cx(\"qt-row\", selected && \"qt-row--selected\", classNames?.row, selected && classNames?.rowSelected)}\n >\n {renderedColumnNames.map((name) => {\n if (name === SELECTION_COLUMN) {\n return (\n <td\n key={name}\n data-qt-field={name}\n className={cx(\n \"qt-cell\",\n \"qt-checkbox-cell\",\n dragSource === name && \"qt-cell--dragging\",\n classNames?.cell,\n classNames?.checkboxCell,\n )}\n >\n {id != null && (\n <input\n type=\"checkbox\"\n checked={selected}\n // Shift-range select is handled inside selection.toggle.\n onClick={(e) => selection!.toggle(id, e.shiftKey)}\n onChange={() => {\n /* state owned by selection; onClick drives it */\n }}\n aria-label={`select row ${String(id)}`}\n />\n )}\n </td>\n );\n }\n const f = fieldByName.get(name);\n if (!f) return null;\n const render = resolveRenderer(f, renderers);\n const value = readFieldValue(f, row);\n const key = cellKey(id, i, f.name);\n return (\n <td\n key={f.name}\n data-qt-field={f.name}\n className={cx(\"qt-cell\", dragSource === f.name && \"qt-cell--dragging\", classNames?.cell)}\n style={f.select?.align ? { textAlign: f.select.align } : undefined}\n onClick={(e) => openMenu(e, f, row)}\n onContextMenu={(e) => openMenu(e, f, row)}\n onDoubleClick={(e) => copyCellToClipboard(e, f, id, i, value)}\n >\n {copiedCellKey === key ? <span className=\"qt-cell-copy-chip\">✓ copied</span> : render({ value, row, field: f, query })}\n </td>\n );\n })}\n {trailing && <td className={cx(\"qt-cell\", \"qt-trailing-cell\", classNames?.cell)}>{trailing(row)}</td>}\n </tr>\n );\n })}\n {paddingBottom > 0 && (\n <tr className=\"qt-virtual-spacer\" aria-hidden=\"true\">\n <td colSpan={totalCols} style={{ height: paddingBottom, padding: 0, border: 0 }} />\n </tr>\n )}\n </tbody>\n <tfoot>\n <tr className={cx(\"qt-table-summary-row\", classNames?.summaryRow)}>\n <td colSpan={totalCols} className={cx(\"qt-cell\", \"qt-table-summary-cell\", classNames?.summaryCell)}>\n <div className={cx(\"qt-table-summary\", classNames?.summaryControls)}>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.summaryButton)}\n disabled={loading || !canPrev}\n onClick={prevPage}\n >\n ← prev\n </button>\n <span className={cx(\"qt-table-summary-hint\", classNames?.summaryHint)}>{summaryText}</span>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.summaryButton)}\n disabled={loading || !canNext}\n onClick={nextPage}\n >\n next →\n </button>\n </div>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n {menu && (\n menu.kind === \"cell\" ? (\n <CellMenu\n field={menu.field}\n value={menu.value}\n x={menu.x}\n y={menu.y}\n onAddFilter={(clause: WhereClause) =>\n onQueryChange((prev) => ({ ...prev, offset: 0, where: [...prev.where, clause] }))\n }\n onClose={() => setMenu(null)}\n />\n ) : (\n <HeaderMenu\n field={menu.field}\n x={menu.x}\n y={menu.y}\n sortable={isSortable(menu.field)}\n canRemoveColumn={fields.length > 1}\n onSetSort={(placement, dir) => applyHeaderSort(menu.field, dir, placement)}\n onRemove={() => removeColumn(menu.field)}\n onClose={() => setMenu(null)}\n />\n )\n )}\n </>\n );\n}\n\nfunction HeaderMenu<Row>({\n field,\n x,\n y,\n sortable,\n canRemoveColumn,\n onSetSort,\n onRemove,\n onClose,\n}: {\n field: FieldDef<Row>;\n x: number;\n y: number;\n sortable: boolean;\n canRemoveColumn: boolean;\n onSetSort: (placement: HeaderSortPlacement, dir: \"asc\" | \"desc\") => void;\n onRemove: () => void;\n onClose: () => void;\n}) {\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n function onDocClick() {\n onClose();\n }\n window.addEventListener(\"keydown\", onKey);\n const t = setTimeout(() => window.addEventListener(\"click\", onDocClick), 0);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"click\", onDocClick);\n clearTimeout(t);\n };\n }, [onClose]);\n\n const items: ReactNode[] = [];\n const addSortItem = (placement: HeaderSortPlacement, dir: \"asc\" | \"desc\", label: string) =>\n items.push(\n <MenuItem key={`${placement}-${dir}`} disabled={!sortable} onClick={() => onSetSort(placement, dir)}>\n {label}\n </MenuItem>,\n );\n\n addSortItem(\"set\", \"asc\", \"Set Sort (Asc)\");\n addSortItem(\"set\", \"desc\", \"Set Sort (Desc)\");\n addSortItem(\"append\", \"asc\", \"Append Sort (Asc)\");\n addSortItem(\"append\", \"desc\", \"Append Sort (Desc)\");\n addSortItem(\"prepend\", \"asc\", \"Prepend Sort (Asc)\");\n addSortItem(\"prepend\", \"desc\", \"Prepend Sort (Desc)\");\n\n items.push(<div key=\"sep\" className=\"qt-cm-sep\" />);\n items.push(\n <MenuItem key=\"remove\" disabled={!canRemoveColumn} onClick={onRemove}>\n Remove Column\n </MenuItem>,\n );\n\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 9999;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 9999;\n const left = Math.max(8, Math.min(x, vw - MENU_WIDTH - 8));\n const top = Math.max(8, Math.min(y, vh - MENU_ROW_HEIGHT * items.length - 8));\n\n return (\n <div\n className=\"qt-cell-menu\"\n style={{ left, top, width: MENU_WIDTH }}\n onClick={(e) => e.stopPropagation()}\n onContextMenu={(e) => e.preventDefault()}\n role=\"menu\"\n >\n <div className=\"qt-cm-header\">\n <span className=\"qt-cm-field\">{field.label}</span>\n </div>\n {items}\n </div>\n );\n}\n\nfunction MenuItem({\n children,\n onClick,\n disabled,\n}: {\n children: ReactNode;\n onClick: () => void;\n disabled?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n className=\"qt-cm-item\"\n onClick={onClick}\n role=\"menuitem\"\n disabled={disabled}\n >\n {children}\n </button>\n );\n}\n\n/** Header menu sort helper for set / append / prepend actions. */\nfunction nextHeaderOrderBy(\n existing: OrderByClause[],\n field: string,\n dir: \"asc\" | \"desc\",\n placement: HeaderSortPlacement,\n): OrderByClause[] {\n const next = existing.filter((s) => s.field !== field);\n if (placement === \"set\") return [{ field, dir }];\n if (placement === \"append\") return [...next, { field, dir }];\n return [{ field, dir }, ...next];\n}\n\n/** Materialize the current visible order into SelectColumn[] so width/order\n * edits diverge from schema defaults cleanly (mirrors useSelect.writeSelect). */\nfunction materialize<Row>(select: SelectColumn[], fields: FieldDef<Row>[]): SelectColumn[] {\n if (select.length) return select.map((c) => ({ ...c }));\n return fields.map((f) => ({ field: f.name }));\n}\n\nfunction writeWidth<Row>(select: SelectColumn[], fields: FieldDef<Row>[], name: string, width: number): SelectColumn[] {\n const cols = materialize(select, fields);\n let found = false;\n const next = cols.map((c) => {\n if (c.field !== name) return c;\n found = true;\n return { ...c, width };\n });\n if (!found) next.push({ field: name, width });\n return next;\n}\n\nfunction reorderSelect<Row>(select: SelectColumn[], fields: FieldDef<Row>[], order: string[]): SelectColumn[] {\n const cols = materialize(select, fields);\n const byName = new Map(cols.map((c) => [c.field, c]));\n return order.map((name) => byName.get(name) ?? { field: name });\n}\n\nfunction cssAttributeValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction sameOrder(a: string[], b: string[]): boolean {\n return a.length === b.length && a.every((value, index) => value === b[index]);\n}\n\nfunction valueToString(value: unknown): string {\n if (value == null) return \"\";\n if (Array.isArray(value)) return value.join(\", \");\n return String(value);\n}\n","// CellMenu — right-click (or left-click) a cell → quick-filter popover + copy.\n// Offers only the operators valid for that field's type (opsForField), prefilled\n// with the clicked cell's value, plus \"copy value\". Anchors just off the click\n// point and clamps to the viewport. Present in both source projects; unified here.\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { FieldDef, FilterOp, WhereClause } from \"@pythia-software/query-table-core\";\nimport { NULLARY_OPS, opsForField } from \"@pythia-software/query-table-core\";\nimport type { MenuClassNames } from \"./classNames\";\n\nexport interface CellMenuProps<Row> {\n field: FieldDef<Row>;\n value: unknown;\n /** Viewport coordinates of the click. */\n x: number;\n y: number;\n onAddFilter: (clause: WhereClause) => void;\n onClose: () => void;\n classNames?: MenuClassNames;\n}\n\nconst cx = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/** Approximate sizing so the popover can clamp itself into the viewport. */\nconst MENU_WIDTH = 240;\nconst ROW_HEIGHT = 32;\nconst POINTER_OFFSET = 4;\n\nexport function CellMenu<Row>({ field, value, x, y, onAddFilter, onClose, classNames }: CellMenuProps<Row>): ReactNode {\n // Dismiss on Escape or an outside click. The opening click is deferred a tick\n // so it doesn't immediately re-close the freshly-opened menu.\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n function onDocClick() {\n onClose();\n }\n window.addEventListener(\"keydown\", onKey);\n const t = setTimeout(() => window.addEventListener(\"click\", onDocClick), 0);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"click\", onDocClick);\n clearTimeout(t);\n };\n }, [onClose]);\n\n const ops = opsForField(field);\n const isArray = Array.isArray(value);\n const isNullish = value == null || value === \"\" || (isArray && (value as unknown[]).length === 0);\n\n function apply(op: FilterOp, raw?: string) {\n const v = raw != null ? raw : valueToString(value);\n onAddFilter({ field: field.name, op, value: NULLARY_OPS.has(op) ? \"\" : v });\n onClose();\n }\n\n // Build the actionable filter items. For arrays we offer a per-element\n // shortcut (so a tag column filters by the clicked tag); otherwise we offer\n // every operator the field type allows, prefilled with the cell value.\n const filterItems: ReactNode[] = [];\n if (isArray && !isNullish) {\n (value as unknown[]).forEach((el, i) => {\n const s = String(el);\n const arrayOp: FilterOp = ops.includes(\"includes\") ? \"includes\" : ops[0] ?? \"=\";\n filterItems.push(\n <MenuItem key={`el-${i}`} classNames={classNames} onClick={() => apply(arrayOp, s)}>\n filter: {opSymbol(arrayOp)} <code>{s}</code>\n </MenuItem>,\n );\n });\n }\n for (const op of ops) {\n const nullary = NULLARY_OPS.has(op);\n // When the cell is empty, only the nullary ops make sense; when it has a\n // value, offer both (so a user can still ask \"is null\" off a present cell).\n if (isNullish && !nullary) continue;\n // Array element shortcuts above already covered the value ops.\n if (isArray && !nullary && !isNullish) continue;\n filterItems.push(\n <MenuItem key={op} classNames={classNames} onClick={() => apply(op)}>\n filter: {opSymbol(op)}\n {!nullary && !isNullish ? <> <code>{previewValue(value)}</code></> : null}\n </MenuItem>,\n );\n }\n\n const copyItem = (\n <MenuItem\n key=\"copy\"\n classNames={classNames}\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(valueToString(value));\n } catch {\n /* clipboard denial is non-fatal */\n }\n onClose();\n }}\n >\n copy value\n </MenuItem>\n );\n\n const items: ReactNode[] = [\n <div key=\"header\" className=\"qt-cm-header\">\n <span className=\"qt-cm-field\">{field.label}</span>\n <span className=\"qt-cm-value\">{previewValue(value)}</span>\n </div>,\n copyItem,\n <div key=\"sep\" className={cx(\"qt-cm-sep\", classNames?.separator)} />,\n ...filterItems,\n ];\n\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 9999;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 9999;\n const left = Math.max(8, Math.min(x + POINTER_OFFSET, vw - MENU_WIDTH - 8));\n const top = Math.max(8, Math.min(y + POINTER_OFFSET, vh - ROW_HEIGHT * items.length - 8));\n\n return (\n <div\n className={cx(\"qt-cell-menu\", classNames?.popover)}\n style={{ left, top, width: MENU_WIDTH }}\n onClick={(e) => e.stopPropagation()}\n onContextMenu={(e) => e.preventDefault()}\n role=\"menu\"\n >\n {items}\n </div>\n );\n}\n\nfunction MenuItem({\n children,\n onClick,\n classNames,\n}: {\n children: ReactNode;\n onClick: () => void;\n classNames: MenuClassNames | undefined;\n}) {\n return (\n <button type=\"button\" className={cx(\"qt-cm-item\", classNames?.item)} onClick={onClick} role=\"menuitem\">\n {children}\n </button>\n );\n}\n\nfunction opSymbol(op: FilterOp): string {\n switch (op) {\n case \"!=\":\n return \"≠\";\n case \">=\":\n return \"≥\";\n case \"<=\":\n return \"≤\";\n case \"is_null\":\n return \"is null\";\n case \"is_not_null\":\n return \"is not null\";\n default:\n return op;\n }\n}\n\nfunction valueToString(v: unknown): string {\n if (v == null) return \"\";\n if (Array.isArray(v)) return v.join(\", \");\n return String(v);\n}\n\nfunction previewValue(v: unknown): string {\n if (v == null || v === \"\") return \"(empty)\";\n if (Array.isArray(v)) {\n return v.length === 0 ? \"(empty)\" : `[${v.length}] ${v.slice(0, 2).join(\", \")}${v.length > 2 ? \"…\" : \"\"}`;\n }\n const s = String(v);\n return s.length > 50 ? s.slice(0, 50) + \"…\" : s;\n}\n","// QueryBuilder — the chip toolbar: WHERE filters, SELECT columns, ORDER BY\n// (multi-sort, reorderable), and LIMIT/OFFSET paging. Type-aware filter inputs\n// (enum/static <select>, value autocomplete via Transport.fetchDistinctValues).\n// Hosts the Save / saved-queries entry point.\n//\n// Combines a chip layout, autocomplete, draggable column chips, a grouped\n// picker, per-clause operators, and multi-sort.\n\nimport { useEffect, useId, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport type {\n AggOp,\n AggregationClause,\n DistinctValuesResult,\n FieldDef,\n FilterOp,\n OrderByClause,\n WhereClause,\n} from \"@pythia-software/query-table-core\";\nimport {\n NULLARY_OPS,\n aggOpNeedsField,\n aggOpsForField,\n encodeQuery,\n filterValues as filterValuesFor,\n isGroupable,\n isMeasurable,\n queriesEqual,\n isFilterable,\n isSelectable,\n isSortable,\n opsForField,\n} from \"@pythia-software/query-table-core\";\nimport type { QueryTableApi } from \"@pythia-software/query-table-react\";\nimport type { QueryBuilderClassNames } from \"./classNames\";\nimport { FieldPicker } from \"./FieldPicker\";\nimport { SavedQueriesModal } from \"./SavedQueriesModal\";\n\nexport interface QueryBuilderProps<Row> {\n /** The controller; QueryBuilder drives it through the intent helpers. */\n api: QueryTableApi<Row>;\n /** All schema fields (for the field picker / sort picker). */\n fields: FieldDef<Row>[];\n /** Total matching rows, for the \"N of M\" paging hint. */\n total: number | null;\n /** Disable inputs while a fetch is in flight. */\n running?: boolean;\n classNames?: QueryBuilderClassNames;\n /** Use this to control collapse state from a parent UI. */\n collapsed?: boolean;\n /** Controlled collapse callback (use when `collapsed` is provided). */\n onCollapsedChange?: (collapsed: boolean) => void;\n /** Initial collapse state for uncontrolled mode. */\n defaultCollapsed?: boolean;\n}\n\nconst cx = (...parts: Array<string | undefined | false>): string =>\n parts.filter((p): p is string => Boolean(p)).join(\" \");\n\nconst MAX_AUTO_REFRESH_POLLS = 1000;\nconst DEFAULT_AUTO_REFRESH_FREQUENCY_MS = 20_000;\nconst DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS = 5 * 60_000;\nconst SHARE_FEEDBACK_MS = 2_000;\n\nconst AUTO_REFRESH_FREQUENCIES = [\n { label: \"Every 5s\", value: 5_000 },\n { label: \"Every 10s\", value: 10_000 },\n { label: \"Every 20s\", value: DEFAULT_AUTO_REFRESH_FREQUENCY_MS },\n { label: \"Every 30s\", value: 30_000 },\n { label: \"Every 1m\", value: 60_000 },\n { label: \"Every 2m\", value: 2 * 60_000 },\n { label: \"Every 5m\", value: 5 * 60_000 },\n { label: \"Every 10m\", value: 10 * 60_000 },\n] as const;\n\nconst AUTO_REFRESH_TURN_OFF_AFTER = [\n { label: \"After 5m\", value: DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS },\n { label: \"After 15m\", value: 15 * 60_000 },\n { label: \"After 30m\", value: 30 * 60_000 },\n { label: \"After 1h\", value: 60 * 60_000 },\n { label: \"After 2h\", value: 2 * 60 * 60_000 },\n { label: \"After 4h\", value: 4 * 60 * 60_000 },\n { label: \"After 8h\", value: 8 * 60 * 60_000 },\n { label: \"After 12h\", value: 12 * 60 * 60_000 },\n { label: \"After 24h\", value: 24 * 60 * 60_000 },\n] as const;\n\nfunction autoRefreshPolls(frequencyMs: number, turnOffAfterMs: number): number {\n if (frequencyMs <= 0 || turnOffAfterMs <= 0) return Infinity;\n return Math.floor(turnOffAfterMs / frequencyMs);\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.round(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = minutes / 60;\n return Number.isInteger(hours) ? `${hours}h` : `${minutes}m`;\n}\n\nfunction formatStatusTime(ms: number | null): string {\n if (ms == null) return \"never\";\n return new Date(ms).toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\", second: \"2-digit\" });\n}\n\nfunction useFieldHasNull<Row>(api: QueryTableApi<Row>, fieldName: string | undefined): boolean | undefined {\n const [hasNull, setHasNull] = useState<boolean | undefined>(undefined);\n\n useEffect(() => {\n if (!fieldName) return;\n let cancelled = false;\n\n void api\n .filterValues(fieldName, \"\")\n .then((r) => {\n if (!cancelled && typeof r.hasNull === \"boolean\") {\n setHasNull(r.hasNull);\n }\n })\n .catch(() => {\n if (!cancelled) setHasNull(undefined);\n });\n\n return () => {\n cancelled = true;\n };\n }, [api, fieldName]);\n\n return hasNull;\n}\n\nfunction whereClauseAsText<Row>(clause: WhereClause, byName: Map<string, FieldDef<Row>>): string {\n const field = byName.get(clause.field)?.label ?? clause.field;\n const op = clause.op.replace(/_/g, \" \");\n if (NULLARY_OPS.has(clause.op)) return `${field} ${op}`;\n const value = clause.value === \"\" ? \"''\" : clause.value;\n return `${field} ${op} ${value}`;\n}\n\nfunction orderByAsText<Row>(term: OrderByClause, byName: Map<string, FieldDef<Row>>): string {\n const field = byName.get(term.field)?.label ?? term.field;\n const nulls = term.nulls ? ` nulls ${term.nulls}` : \"\";\n return `${field} ${term.dir}${nulls}`;\n}\n\nfunction chipFieldWidthChars(text: string, fallback = 5, max = 30): number {\n return Math.min(max, Math.max(fallback, (text || \"\").length + 1));\n}\n\nfunction chipFieldWidthForInput(text: string, fieldType: string | undefined, fallback = 5, padding = 0): number {\n const cap = fieldType === \"number\" ? 10 : 30;\n return chipFieldWidthChars(text, fallback, cap) + padding;\n}\n\nfunction chipFieldWidthForSelect(text: string, fallback = 3, max = 30): number {\n return chipFieldWidthChars(text, fallback, max) + 2;\n}\n\nfunction buildCollapsedSummary<Row>(\n where: WhereClause[],\n orderBy: OrderByClause[],\n byName: Map<string, FieldDef<Row>>,\n): string {\n const whereText = where.length === 0 ? \"all rows\" : where.map((c) => whereClauseAsText(c, byName)).join(\" and \");\n const orderText = orderBy.length === 0 ? \"(default)\" : orderBy.map((term) => orderByAsText(term, byName)).join(\", \");\n return `WHERE ${whereText} ORDER BY ${orderText}`;\n}\n\nfunction whereClauseSummaryText<Row>(where: WhereClause[], byName: Map<string, FieldDef<Row>>): string {\n return where.length === 0 ? \"all rows\" : where.map((c) => whereClauseAsText(c, byName)).join(\" and \");\n}\n\nfunction orderBySummaryText<Row>(orderBy: OrderByClause[], byName: Map<string, FieldDef<Row>>): string {\n return orderBy.length === 0 ? \"(default)\" : orderBy.map((term) => orderByAsText(term, byName)).join(\", \");\n}\n\nexport function QueryBuilder<Row>({\n api,\n fields,\n total,\n running,\n classNames,\n collapsed,\n onCollapsedChange,\n defaultCollapsed = false,\n}: QueryBuilderProps<Row>): ReactNode {\n const UNSAVED_QUERY_EDIT_ID = \"__qt-unsaved-query__\";\n const [showSaved, setShowSaved] = useState(false);\n const [shareCopied, setShareCopied] = useState(false);\n const [showAutoRefresh, setShowAutoRefresh] = useState(false);\n const [autoRefreshFrequencyMs, setAutoRefreshFrequencyMs] = useState(DEFAULT_AUTO_REFRESH_FREQUENCY_MS);\n const [autoRefreshTurnOffAfterMs, setAutoRefreshTurnOffAfterMs] = useState(DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS);\n const [editingSavedId, setEditingSavedId] = useState<string | null>(null);\n const [editingSavedName, setEditingSavedName] = useState(\"\");\n const [lastSavedId, setLastSavedId] = useState<string | null>(null);\n const [collapsedFallback, setCollapsedFallback] = useState(defaultCollapsed);\n const collapsedControlled = typeof collapsed !== \"undefined\";\n const isCollapsed = collapsedControlled ? collapsed : collapsedFallback;\n const setCollapsed = (next: boolean) => {\n if (collapsedControlled) {\n onCollapsedChange?.(next);\n return;\n }\n setCollapsedFallback(next);\n };\n const [lastUpdatedAt, setLastUpdatedAt] = useState<number | null>(null);\n const [lastFailureAt, setLastFailureAt] = useState<number | null>(null);\n const byName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n const activeSavedQuery = useMemo(\n () => api.saved.items.find((item) => queriesEqual(item.query, api.query)),\n [api.query, api.saved.items],\n );\n const lastSavedQuery = useMemo(\n () => api.saved.items.find((item) => item.id === lastSavedId) ?? null,\n [api.saved.items, lastSavedId],\n );\n const isSavedQuery = activeSavedQuery != null;\n const isEditingUnsaved = editingSavedId === UNSAVED_QUERY_EDIT_ID;\n const bodyId = useId();\n const isEditingSaved = editingSavedId != null && activeSavedQuery?.id === editingSavedId;\n const showUpdateButton = Boolean(lastSavedQuery) && !activeSavedQuery;\n const collapsedSummary = useMemo(\n () => buildCollapsedSummary(api.query.where, api.query.orderBy, byName),\n [api.query.where, api.query.orderBy, byName],\n );\n const collapsedWhereText = useMemo(\n () => whereClauseSummaryText(api.query.where, byName),\n [api.query.where, byName],\n );\n const collapsedOrderText = useMemo(\n () => orderBySummaryText(api.query.orderBy, byName),\n [api.query.orderBy, byName],\n );\n const autoRefreshStatus = api.autoRefresh.status;\n const selectedAutoRefreshPolls = autoRefreshPolls(autoRefreshFrequencyMs, autoRefreshTurnOffAfterMs);\n const canSubmitAutoRefresh = selectedAutoRefreshPolls >= 1 && selectedAutoRefreshPolls <= MAX_AUTO_REFRESH_POLLS;\n const autoRefreshButtonText = autoRefreshStatus\n ? `⟳ Auto-Update ${formatDuration(autoRefreshStatus.frequencyMs)}`\n : \"⟳ Auto-Update\";\n const rowSummary = `${api.rows.length} of ${total ?? \"?\"}`;\n const lastUpdatedText = formatStatusTime(lastUpdatedAt);\n const failureText = api.error\n ? `Error: ${api.error.message}`\n : lastFailureAt\n ? `Last failure at ${formatStatusTime(lastFailureAt)}`\n : null;\n const isBusy = Boolean(running) || api.loading;\n const lastRowsRef = useRef<Row[] | null>(null);\n const lastTotalRef = useRef<number | null>(null);\n const previousLoadingRef = useRef(api.loading);\n const autoRefreshRef = useRef<HTMLSpanElement>(null);\n const autoRefreshPopoverRef = useRef<HTMLSpanElement>(null);\n const [autoRefreshPopoverAlignRight, setAutoRefreshPopoverAlignRight] = useState(false);\n const shareFeedbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (shareFeedbackTimerRef.current) clearTimeout(shareFeedbackTimerRef.current);\n },\n [],\n );\n\n useEffect(() => {\n setShareCopied(false);\n if (shareFeedbackTimerRef.current) {\n clearTimeout(shareFeedbackTimerRef.current);\n shareFeedbackTimerRef.current = null;\n }\n }, [api.query]);\n\n useEffect(() => {\n if (activeSavedQuery) {\n setLastSavedId(activeSavedQuery.id);\n if (!isEditingSaved) {\n setEditingSavedName(activeSavedQuery.name);\n setEditingSavedId(null);\n }\n return;\n }\n\n if (!isEditingUnsaved) {\n setEditingSavedId(null);\n setEditingSavedName(\"\");\n }\n // activeSavedQuery can become null if edits/loads shift to unsaved or another query\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeSavedQuery, isEditingSaved, isEditingUnsaved]);\n\n useEffect(() => {\n if (!lastSavedId || api.saved.items.some((item) => item.id === lastSavedId)) return;\n setLastSavedId(null);\n }, [api.saved.items, lastSavedId]);\n\n useEffect(() => {\n const hasData = api.rows.length > 0 || total != null;\n const rowsChanged = lastRowsRef.current !== api.rows;\n const totalChanged = lastTotalRef.current !== total;\n const loadingDone = !api.loading;\n\n if (loadingDone && api.error) {\n setLastFailureAt(Date.now());\n lastRowsRef.current = api.rows;\n lastTotalRef.current = total;\n previousLoadingRef.current = api.loading;\n return;\n }\n\n if (\n loadingDone &&\n (previousLoadingRef.current || rowsChanged || totalChanged || lastUpdatedAt == null) &&\n hasData\n ) {\n setLastUpdatedAt(Date.now());\n setLastFailureAt(null);\n lastRowsRef.current = api.rows;\n lastTotalRef.current = total;\n }\n previousLoadingRef.current = api.loading;\n }, [api.error, api.loading, api.rows, total, lastUpdatedAt]);\n\n function saveFailed(error: unknown): void {\n const message = error instanceof Error ? error.message : \"Failed to save query.\";\n if (typeof window !== \"undefined\") window.alert(message);\n }\n\n function beginEditSavedName() {\n if (activeSavedQuery) {\n setEditingSavedId(activeSavedQuery.id);\n setEditingSavedName(activeSavedQuery.name);\n return;\n }\n if (isEditingUnsaved) return;\n setEditingSavedId(UNSAVED_QUERY_EDIT_ID);\n setEditingSavedName((next) => (next ? next : \"Custom Query\"));\n }\n\n function cancelNameEdit() {\n setEditingSavedId(null);\n setEditingSavedName(\"\");\n }\n\n async function persistSavedQuery(name: string): Promise<string | null> {\n const trimmed = name.trim();\n if (!trimmed) return null;\n try {\n const saved = await api.saved.save(trimmed);\n setLastSavedId(saved.id);\n return saved.id;\n } catch (error) {\n saveFailed(error);\n return null;\n }\n }\n\n async function commitSavedNameEdit() {\n if (!isEditingSaved || !activeSavedQuery) return;\n const trimmed = editingSavedName.trim();\n if (!trimmed || trimmed === activeSavedQuery.name) {\n cancelNameEdit();\n return;\n }\n const savedId = await persistSavedQuery(trimmed);\n if (!savedId) return;\n await api.saved.remove(activeSavedQuery.id);\n cancelNameEdit();\n }\n\n async function commitUnsavedNameEdit() {\n if (!isEditingUnsaved) return;\n const savedId = await persistSavedQuery(editingSavedName);\n if (!savedId) {\n cancelNameEdit();\n return;\n }\n cancelNameEdit();\n }\n\n async function updateLastSavedQuery() {\n if (!lastSavedQuery) return;\n const wasDefault = api.saved.defaultId === lastSavedQuery.id;\n const trimmedName = lastSavedQuery.name.trim();\n if (!trimmedName) return;\n\n try {\n await api.saved.remove(lastSavedQuery.id);\n const saved = await api.saved.save(trimmedName);\n if (wasDefault) await api.saved.setDefault(saved.id);\n setLastSavedId(saved.id);\n } catch (error) {\n saveFailed(error);\n }\n }\n\n function commitNameEditor() {\n if (isEditingSaved) {\n void commitSavedNameEdit();\n return;\n }\n if (isEditingUnsaved) {\n void commitUnsavedNameEdit();\n return;\n }\n }\n\n useEffect(() => {\n if (isCollapsed) setShowSaved(false);\n }, [isCollapsed]);\n\n useEffect(() => {\n if (!showAutoRefresh || !autoRefreshStatus) return;\n setAutoRefreshFrequencyMs(autoRefreshStatus.frequencyMs);\n setAutoRefreshTurnOffAfterMs(autoRefreshStatus.turnOffAfterMs);\n }, [showAutoRefresh, autoRefreshStatus]);\n\n useEffect(() => {\n if (!showAutoRefresh) return;\n\n function onDocumentClick(event: MouseEvent) {\n const wrapper = autoRefreshRef.current;\n const target = event.target as Node | null;\n if (!wrapper || !target) return;\n if (!wrapper.contains(target)) setShowAutoRefresh(false);\n }\n\n function onDocumentKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") setShowAutoRefresh(false);\n }\n\n function calculateAutoRefreshPosition() {\n const popover = autoRefreshPopoverRef.current;\n const wrapper = autoRefreshRef.current;\n if (!popover || !wrapper) return;\n const wrapperRect = wrapper.getBoundingClientRect();\n const popWidth = popover.offsetWidth;\n const viewportRightInset = 8;\n setAutoRefreshPopoverAlignRight(wrapperRect.right + popWidth > window.innerWidth - viewportRightInset);\n }\n\n calculateAutoRefreshPosition();\n const t = setTimeout(() => window.addEventListener(\"click\", onDocumentClick), 0);\n window.addEventListener(\"keydown\", onDocumentKeyDown);\n window.addEventListener(\"resize\", calculateAutoRefreshPosition);\n return () => {\n clearTimeout(t);\n window.removeEventListener(\"click\", onDocumentClick);\n window.removeEventListener(\"keydown\", onDocumentKeyDown);\n window.removeEventListener(\"resize\", calculateAutoRefreshPosition);\n };\n }, [showAutoRefresh]);\n\n function submitAutoRefresh() {\n if (!canSubmitAutoRefresh) return;\n try {\n api.autoRefresh.start({\n frequencyMs: autoRefreshFrequencyMs,\n turnOffAfterMs: autoRefreshTurnOffAfterMs,\n });\n setShowAutoRefresh(false);\n } catch (error) {\n saveFailed(error);\n }\n }\n\n async function shareQuery() {\n if (typeof window === \"undefined\") return;\n\n const url = new URL(window.location.href);\n // Always derive the token from the live query. In particular, a saved\n // default must be shared by value because the recipient will not have the\n // sender's StorageAdapter contents.\n url.searchParams.set(\"q\", encodeQuery(api.query));\n\n try {\n await navigator.clipboard.writeText(url.toString());\n setShareCopied(true);\n if (shareFeedbackTimerRef.current) clearTimeout(shareFeedbackTimerRef.current);\n shareFeedbackTimerRef.current = setTimeout(() => {\n setShareCopied(false);\n shareFeedbackTimerRef.current = null;\n }, SHARE_FEEDBACK_MS);\n } catch {\n window.prompt(\"Copy this query URL\", url.toString());\n }\n }\n\n return (\n <div className={cx(\"qt-qb\", classNames?.root)}>\n <div className=\"qt-qb-bar qt-qb-state-bar qt-qb-row\">\n <span className=\"qt-qb-state-main\">\n <span className=\"qt-qb-saved\">\n <button\n type=\"button\"\n className={cx(\"qt-qb-saved-star\", isSavedQuery ? \"qt-qb-saved-star--saved\" : \"qt-qb-saved-star--unsaved\")}\n title={isSavedQuery ? \"Rename saved query\" : \"Save query\"}\n disabled={isBusy}\n onClick={beginEditSavedName}\n >\n {isSavedQuery ? \"★\" : \"☆\"}\n </button>\n {isEditingSaved || isEditingUnsaved ? (\n <span className=\"qt-qb-saved-input-wrap\">\n <input\n type=\"text\"\n className=\"qt-qb-saved-input\"\n value={editingSavedName}\n disabled={isBusy}\n autoFocus\n onChange={(e) => setEditingSavedName(e.target.value)}\n onBlur={commitNameEditor}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitNameEditor();\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n cancelNameEdit();\n }\n }}\n onClick={(e) => e.stopPropagation()}\n />\n <button\n type=\"button\"\n className=\"qt-qb-saved-cancel\"\n title=\"Do not save\"\n onMouseDown={(e) => {\n e.preventDefault();\n cancelNameEdit();\n }}\n onClick={(e) => e.stopPropagation()}\n >\n ✕\n </button>\n </span>\n ) : (\n <button\n type=\"button\"\n className={cx(\"qt-qb-saved-name\", !activeSavedQuery && \"qt-qb-saved-name--custom\")}\n onClick={beginEditSavedName}\n >\n {activeSavedQuery ? activeSavedQuery.name : \"Custom Query\"}\n </button>\n )}\n </span>\n {isCollapsed ? (\n <span className=\"qt-qb-summary qt-truncate\" title={collapsedSummary}>\n <span className=\"qt-qb-summary-kw\">WHERE</span>{\" \"}\n <strong>{collapsedWhereText}</strong>{\" \"}\n <span className=\"qt-qb-summary-kw\">ORDER BY</span>{\" \"}\n <strong>{collapsedOrderText}</strong>\n </span>\n ) : null}\n </span>\n {showUpdateButton ? (\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={() => void updateLastSavedQuery()}\n disabled={isBusy}\n >\n {`Update Query '${lastSavedQuery?.name ?? \"query\"}'`}\n </button>\n ) : null}\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={() => void shareQuery()}\n title=\"Copy a URL for this query\"\n aria-live=\"polite\"\n >\n {shareCopied ? \"Copied!\" : \"Share\"}\n </button>\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={() => setShowSaved(true)}>\n Saved{api.saved.items.length > 0 ? ` (${api.saved.items.length})` : \"\"}\n </button>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", \"qt-qb-collapse-btn\", classNames?.button)}\n onClick={() => setCollapsed(!isCollapsed)}\n aria-expanded={!isCollapsed}\n aria-controls={bodyId}\n title={isCollapsed ? \"Expand query builder\" : \"Collapse query builder\"}\n >\n <span\n className={cx(\"qt-qb-collapse-caret\", isCollapsed && \"qt-qb-collapse-caret--collapsed\")}\n aria-hidden=\"true\"\n >\n ▾\n </span>\n <span className=\"qt-sr-only\">{isCollapsed ? \"Expand query builder\" : \"Collapse query builder\"}</span>\n </button>\n </div>\n\n {!isCollapsed ? (\n <div className=\"qt-qb-bar qt-qb-editor-bar\">\n <div id={bodyId} className=\"qt-qb-body\">\n <SelectRow api={api} fields={fields} classNames={classNames} disabled={isBusy} />\n <WhereRow api={api} byName={byName} fields={fields} classNames={classNames} disabled={isBusy} />\n <OrderRow api={api} fields={fields} classNames={classNames} disabled={isBusy} />\n <WindowRow api={api} classNames={classNames} disabled={isBusy} />\n <MetricsRow api={api} fields={fields} classNames={classNames} disabled={isBusy} />\n </div>\n <div className=\"qt-qb-editor-stack\">\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={api.undo} disabled={!api.canUndo || isBusy}>\n ↶ Undo\n </button>\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={api.redo} disabled={!api.canRedo || isBusy}>\n ↷ Redo\n </button>\n <button type=\"button\" className={cx(\"qt-btn\", classNames?.button)} onClick={api.resetAll} disabled={isBusy}>\n Reset All\n </button>\n </div>\n </div>\n ) : null}\n\n <div className=\"qt-qb-bar qt-qb-run-bar qt-qb-row\">\n <span className=\"qt-qb-run-metric qt-qb-run-metric--strong\">{api.loading ? \"loading…\" : `${rowSummary} rows`}</span>\n <span className=\"qt-qb-run-metric\">Last updated {lastUpdatedText}</span>\n {failureText ? <span className=\"qt-qb-run-error\">{failureText}</span> : null}\n <span className=\"qt-qb-run-actions\">\n {autoRefreshStatus ? (\n <span className=\"qt-qb-auto-status\">\n {`Every ${formatDuration(autoRefreshStatus.frequencyMs)}; clear after ${formatDuration(\n autoRefreshStatus.turnOffAfterMs,\n )} (${autoRefreshStatus.pollCount} polls run)`}\n </span>\n ) : null}\n <span className=\"qt-auto-refresh\" ref={autoRefreshRef}>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", Boolean(autoRefreshStatus) && \"qt-btn--active\", classNames?.button)}\n onClick={() => setShowAutoRefresh((next) => !next)}\n aria-expanded={showAutoRefresh}\n title={autoRefreshStatus ? \"View or clear auto-update\" : \"Configure auto-update\"}\n >\n {autoRefreshButtonText}\n </button>\n {showAutoRefresh ? (\n <span\n ref={autoRefreshPopoverRef}\n className={cx(\"qt-auto-refresh-popover\", autoRefreshPopoverAlignRight && \"qt-auto-refresh-popover--align-right\")}\n role=\"dialog\"\n aria-label=\"Auto-refresh settings\"\n >\n <label className=\"qt-auto-refresh-field\">\n <span>Frequency</span>\n <select\n className=\"qt-auto-refresh-select\"\n value={autoRefreshFrequencyMs}\n onChange={(e) => setAutoRefreshFrequencyMs(Number(e.target.value))}\n >\n {AUTO_REFRESH_FREQUENCIES.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n <label className=\"qt-auto-refresh-field\">\n <span>Turn off after</span>\n <select\n className=\"qt-auto-refresh-select\"\n value={autoRefreshTurnOffAfterMs}\n onChange={(e) => setAutoRefreshTurnOffAfterMs(Number(e.target.value))}\n >\n {AUTO_REFRESH_TURN_OFF_AFTER.map((option) => (\n <option\n key={option.value}\n value={option.value}\n disabled={\n autoRefreshPolls(autoRefreshFrequencyMs, option.value) < 1 ||\n autoRefreshPolls(autoRefreshFrequencyMs, option.value) > MAX_AUTO_REFRESH_POLLS\n }\n >\n {option.label}\n </option>\n ))}\n </select>\n </label>\n <span className={cx(\"qt-auto-refresh-status\", !canSubmitAutoRefresh && \"qt-auto-refresh-status--error\")}>\n {canSubmitAutoRefresh\n ? `${selectedAutoRefreshPolls} polls maximum`\n : `Choose between 1 and 1000 polls`}\n </span>\n {autoRefreshStatus ? (\n <span className=\"qt-auto-refresh-status\">\n Active: every {formatDuration(autoRefreshStatus.frequencyMs)}, clears after{\" \"}\n {formatDuration(autoRefreshStatus.turnOffAfterMs)}. {autoRefreshStatus.pollCount} polls run.\n </span>\n ) : null}\n <span className=\"qt-auto-refresh-actions\">\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={submitAutoRefresh}\n disabled={!canSubmitAutoRefresh}\n >\n {autoRefreshStatus ? \"Update\" : \"Start\"}\n </button>\n {autoRefreshStatus ? (\n <button\n type=\"button\"\n className={cx(\"qt-btn\", classNames?.button)}\n onClick={() => {\n api.autoRefresh.stop();\n setShowAutoRefresh(false);\n }}\n >\n Clear\n </button>\n ) : null}\n </span>\n </span>\n ) : null}\n </span>\n <button\n type=\"button\"\n className={cx(\"qt-btn\", \"qt-btn--primary\", classNames?.button)}\n onClick={api.refresh}\n disabled={isBusy}\n >\n Run Now\n </button>\n </span>\n </div>\n\n {!isCollapsed && showSaved ? (\n <SavedQueriesModal saved={api.saved} onClose={() => setShowSaved(false)} onLoad={setLastSavedId} />\n ) : null}\n </div>\n );\n}\n\nfunction MoveButtons({\n label,\n position,\n count,\n disabled,\n onMove,\n}: {\n label: string;\n position: number;\n count: number;\n disabled: boolean | undefined;\n onMove: (position: number) => void;\n}): ReactNode {\n if (count < 2) return null;\n return (\n <span className=\"qt-chip-move-buttons\">\n <button\n type=\"button\"\n className=\"qt-chip-move\"\n disabled={disabled || position === 0}\n onClick={() => onMove(position - 1)}\n aria-label={`Move ${label} earlier`}\n title=\"Move earlier\"\n >\n ←\n </button>\n <button\n type=\"button\"\n className=\"qt-chip-move\"\n disabled={disabled || position === count - 1}\n onClick={() => onMove(position + 1)}\n aria-label={`Move ${label} later`}\n title=\"Move later\"\n >\n →\n </button>\n </span>\n );\n}\n\n// ---- SELECT ---------------------------------------------------------------\n\nfunction SelectRow<Row>({\n api,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const { select, columnDrag } = api;\n const [adding, setAdding] = useState(false);\n const fieldLabelByName = useMemo(() => new Map(select.fields.map((f) => [f.name, f.label])), [select.fields]);\n\n // `overIndex` is a position in the list with the dragged column removed —\n // exactly where the live preview shows it. select.move removes-then-inserts at\n // that index, so the committed order matches the preview.\n function reorderByIndex(from: string, overIndex: number) {\n select.move(from, overIndex);\n }\n\n const fieldNames = select.visible.map((c) => c.field);\n const dragSource = columnDrag.source;\n\n // Live reorder, driven by the SHARED column-drag state so dragging a chip also\n // live-previews/dims the matching table column (and vice versa). The dragged\n // chip stays MOUNTED (removing the drag-source node mid-drag aborts the native\n // drag) and slides to the hovered slot, dimmed. Rendered order == drop result.\n const rendered = columnDrag.preview(fieldNames);\n\n return (\n <div className=\"qt-qb-row\">\n <span className=\"qt-qb-kw\">select</span>\n {rendered.map((name, position) => {\n const label = fieldLabelByName.get(name) ?? name;\n return (\n <span\n // Stable key (not index-based) so React MOVES the dragged chip instead\n // of remounting it \\u2014 a remount removes the drag source and aborts the drag.\n key={name}\n className={cx(\n \"qt-chip\",\n \"qt-chip--col\",\n dragSource === name && \"qt-chip--dragging\",\n classNames?.columnChip ?? classNames?.chip,\n )}\n draggable={!disabled}\n onDragStart={(e) => {\n columnDrag.start(name, fieldNames.indexOf(name));\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", name);\n }}\n onDragOver={(e) => {\n if (!columnDrag.source) return;\n // preventDefault on every chip (incl. the dragged one) so there is no\n // dead drop zone along the row.\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (columnDrag.source !== name) {\n const withoutDragged = fieldNames.filter((n) => n !== columnDrag.source);\n let next = withoutDragged.indexOf(name);\n if (next >= 0) {\n // Drop after the hovered chip when past its midpoint, so a column\n // can be moved into the last slot.\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n columnDrag.over(next);\n }\n }\n }}\n onDrop={(e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n const from = columnDrag.source || e.dataTransfer.getData(\"text/plain\");\n if (from && columnDrag.overIndex != null) reorderByIndex(from, columnDrag.overIndex);\n columnDrag.end();\n }}\n onDragEnd={() => columnDrag.end()}\n title=\"drag to reorder\"\n >\n <span aria-hidden className=\"qt-chip-grip\">\n ⋮⋮\n </span>\n <span className=\"qt-chip-field\">{label}</span>\n <MoveButtons\n label={label}\n position={position}\n count={rendered.length}\n disabled={disabled}\n onMove={(nextPosition) => select.move(name, nextPosition)}\n />\n <button type=\"button\" className=\"qt-chip-x\" onClick={() => select.hide(name)} disabled={disabled}>\n ✕\n </button>\n </span>\n );\n })}\n {adding ? (\n <FieldPicker\n fields={select.hidden.filter(isSelectable)}\n onPick={(f) => {\n select.show(f.name);\n setAdding(false);\n }}\n onClose={() => setAdding(false)}\n />\n ) : (\n <button\n type=\"button\"\n className=\"qt-add\"\n onClick={() => setAdding(true)}\n disabled={disabled || select.hidden.length === 0}\n >\n + add column\n </button>\n )}\n {api.query.select.length > 0 && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={select.reset} disabled={disabled} title=\"Reset to default columns\">\n reset\n </button>\n )}\n </div>\n );\n}\n\n// ---- WHERE ----------------------------------------------------------------\n\nfunction WhereRow<Row>({\n api,\n byName,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n byName: Map<string, FieldDef<Row>>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const [adding, setAdding] = useState(false);\n\n function addClause(f: FieldDef<Row>) {\n const op = opsForField(f)[0] ?? \"=\";\n api.addFilter({ field: f.name, op, value: \"\" });\n setAdding(false);\n }\n\n const groupedWhere = useMemo(() => {\n const groups = new Map<string, { field: string; clauses: { clause: WhereClause; index: number }[] }>();\n const order: string[] = [];\n\n api.query.where.forEach((c, i) => {\n if (!groups.has(c.field)) order.push(c.field);\n const group = groups.get(c.field) ?? { field: c.field, clauses: [] };\n group.clauses.push({ clause: c, index: i });\n groups.set(c.field, group);\n });\n\n return order.map((fieldName) => groups.get(fieldName)!);\n }, [api.query.where]);\n\n return (\n <div className=\"qt-qb-row\">\n <span className=\"qt-qb-kw\">where</span>\n {api.query.where.length === 0 && !adding && <span className=\"qt-qb-hint\">all rows</span>}\n {groupedWhere.map((g) => (\n <ClauseChip\n key={g.field}\n api={api}\n field={byName.get(g.field)}\n clauses={g.clauses}\n classNames={classNames}\n disabled={disabled}\n onChange={(index, next) => api.updateFilter(index, next)}\n onRemove={(index) => api.removeFilter(index)}\n />\n ))}\n {adding ? (\n <FieldPicker\n fields={fields.filter(isFilterable)}\n gateOnDistinct\n onPick={addClause}\n onClose={() => setAdding(false)}\n />\n ) : (\n <button type=\"button\" className=\"qt-add\" onClick={() => setAdding(true)} disabled={disabled}>\n + add filter\n </button>\n )}\n {api.query.where.length > 0 && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={api.clearFilters} disabled={disabled} title=\"Reset filters\">\n reset\n </button>\n )}\n </div>\n );\n}\n\nfunction ClauseChip<Row>({\n api,\n field,\n clauses,\n classNames,\n disabled,\n onChange,\n onRemove,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row> | undefined;\n clauses: Array<{ clause: WhereClause; index: number }>;\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n onChange: (index: number, c: WhereClause) => void;\n onRemove: (index: number) => void;\n}) {\n const labelField = field?.label;\n const fieldName = clauses[0]?.clause.field;\n const fieldHasNull = useFieldHasNull(api, field?.name);\n\n return (\n <span className={cx(\"qt-chip\", \"qt-chip--where\", classNames?.chip)}>\n <span className=\"qt-chip-field\">{labelField ?? fieldName}</span>\n <span className=\"qt-chip-where-list\">\n {clauses.map((entry, idx) => {\n const clause = entry.clause;\n const baseOps: FilterOp[] = field ? opsForField(field) : [clause.op];\n const filteredBaseOps = fieldHasNull === false ? baseOps.filter((op) => !NULLARY_OPS.has(op)) : baseOps;\n const clauseOps: FilterOp[] = filteredBaseOps.includes(clause.op)\n ? filteredBaseOps\n : [...filteredBaseOps, clause.op];\n const needsValue = !NULLARY_OPS.has(clause.op);\n return (\n <span className=\"qt-chip-where-clause\" key={entry.index}>\n {idx > 0 && <span className=\"qt-chip-and\">and</span>}\n <select\n className={cx(\"qt-chip-op\", classNames?.select)}\n value={clause.op}\n disabled={disabled}\n style={{ width: `${chipFieldWidthForSelect(clause.op, 3)}ch` }}\n onChange={(e) => onChange(entry.index, { ...clause, op: e.target.value as FilterOp })}\n >\n {clauseOps.map((op) => (\n <option key={op} value={op}>\n {op}\n </option>\n ))}\n </select>\n {needsValue && (\n <ValueInput\n api={api}\n field={field}\n value={clause.value}\n classNames={classNames}\n onChange={(v) => onChange(entry.index, { ...clause, value: v })}\n />\n )}\n <button\n type=\"button\"\n className=\"qt-chip-x\"\n onClick={() => onRemove(entry.index)}\n disabled={disabled}\n >\n ✕\n </button>\n </span>\n );\n })}\n </span>\n </span>\n );\n}\n\n// ---- value input: autocomplete by default --------------------------------\n\nfunction ValueInput<Row>({\n api,\n field,\n value,\n classNames,\n onChange,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row> | undefined;\n value: string;\n classNames: QueryBuilderClassNames | undefined;\n onChange: (v: string) => void;\n}) {\n const strategy = field ? filterValuesFor(field) : { source: \"freeform\" as const };\n\n // Static closed domain → a plain <select> of the options.\n if (strategy.source === \"static\") {\n const selectedText = value || \"—\";\n const widthChars = chipFieldWidthForSelect(selectedText, 4);\n return (\n <select\n className={cx(\"qt-chip-val\", classNames?.select)}\n value={value}\n style={{ width: `${widthChars}ch` }}\n onChange={(e) => onChange(e.target.value)}\n >\n <option value=\"\">—</option>\n {strategy.options.map((o) => (\n <option key={o} value={o}>\n {o}\n </option>\n ))}\n </select>\n );\n }\n\n // Freeform → a plain input, no suggestions.\n if (strategy.source === \"freeform\" || !field) {\n const widthChars = chipFieldWidthForInput(value || \"value\", field?.type, 5, 4);\n return (\n <input\n className={cx(\"qt-chip-val\", classNames?.input)}\n value={value}\n placeholder=\"value\"\n size={widthChars}\n style={{ width: `${widthChars}ch` }}\n onChange={(e) => onChange(e.target.value)}\n />\n );\n }\n\n // Autocomplete (the default) → debounced combobox backed by api.filterValues.\n return <AutocompleteInput api={api} field={field} value={value} classNames={classNames} onChange={onChange} />;\n}\n\nfunction AutocompleteInput<Row>({\n api,\n field,\n value,\n classNames,\n onChange,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row>;\n value: string;\n classNames: QueryBuilderClassNames | undefined;\n onChange: (v: string) => void;\n}) {\n const [result, setResult] = useState<DistinctValuesResult>({ values: [], hasMore: false });\n const listId = useId();\n\n useEffect(() => {\n let cancelled = false;\n const t = setTimeout(() => {\n void api\n .filterValues(field.name, value)\n .then((r) => {\n if (!cancelled) setResult(r);\n })\n .catch(() => {\n if (!cancelled) setResult({ values: [], hasMore: false });\n });\n }, 200);\n return () => {\n cancelled = true;\n clearTimeout(t);\n };\n }, [api, field.name, value]);\n\n return (\n <span className=\"qt-autocomplete\">\n <input\n className={cx(\"qt-chip-val\", classNames?.input)}\n value={value}\n placeholder=\"value\"\n list={listId}\n size={chipFieldWidthForInput(value || \"value\", field.type, 5, 4)}\n style={{ width: `${chipFieldWidthForInput(value || \"value\", field.type, 5, 4)}ch` }}\n onChange={(e) => onChange(e.target.value)}\n />\n <datalist id={listId}>\n {result.values.map((v) => (\n <option key={v} value={v} />\n ))}\n </datalist>\n {result.hasMore && <span className=\"qt-autocomplete-hint\">keep typing to refine…</span>}\n </span>\n );\n}\n\n// ---- ORDER BY (multi-sort, reorderable) -----------------------------------\n\nfunction OrderTermChip<Row>({\n api,\n field,\n term,\n dataIndex,\n priority,\n showPriority,\n isDragSource,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n disabled,\n updateTerm,\n removeTerm,\n position,\n count,\n moveTerm,\n classNames,\n label,\n}: {\n api: QueryTableApi<Row>;\n field: FieldDef<Row> | undefined;\n term: OrderByClause;\n /** Index of this term in the real orderBy array (for update/remove). */\n dataIndex: number;\n /** 1-based sort priority to display (reflects the live drag position). */\n priority: number;\n showPriority: boolean;\n isDragSource: boolean;\n onDragStart: () => void;\n onDragOver: (e: React.DragEvent) => void;\n onDrop: () => void;\n onDragEnd: () => void;\n disabled: boolean | undefined;\n updateTerm: (i: number, patch: Partial<OrderByClause>) => void;\n removeTerm: (i: number) => void;\n position: number;\n count: number;\n moveTerm: (toIndex: number) => void;\n classNames: QueryBuilderClassNames | undefined;\n label: string;\n}) {\n const fieldHasNull = useFieldHasNull(api, field?.name);\n\n return (\n <span\n className={cx(\"qt-chip\", \"qt-chip--col\", \"qt-chip--sort\", isDragSource && \"qt-chip--dragging\", classNames?.chip)}\n draggable={!disabled}\n onDragStart={(e) => {\n onDragStart();\n // Firefox refuses to start a native drag unless drag data is set here.\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", term.field);\n }}\n onDragOver={onDragOver}\n onDrop={(e) => {\n e.preventDefault();\n onDrop();\n }}\n onDragEnd={onDragEnd}\n title=\"drag to reorder sort priority\"\n >\n <span aria-hidden className=\"qt-chip-grip\">\n ⋮⋮\n </span>\n {showPriority && <span className=\"qt-chip-priority\">{priority}</span>}\n <span className=\"qt-chip-field\">{label}</span>\n <button\n type=\"button\"\n className=\"qt-chip-op-btn\"\n disabled={disabled}\n onClick={() => updateTerm(dataIndex, { dir: term.dir === \"asc\" ? \"desc\" : \"asc\" })}\n >\n {term.dir === \"asc\" ? \"↑ asc\" : \"↓ desc\"}\n </button>\n {fieldHasNull !== false && (\n <button\n type=\"button\"\n className=\"qt-chip-op-btn\"\n disabled={disabled}\n title=\"where NULL values sort\"\n onClick={() => updateTerm(dataIndex, { nulls: (term.nulls ?? \"last\") === \"last\" ? \"first\" : \"last\" })}\n >\n nulls {term.nulls ?? \"last\"}\n </button>\n )}\n <MoveButtons\n label={label}\n position={position}\n count={count}\n disabled={disabled}\n onMove={moveTerm}\n />\n <button type=\"button\" className=\"qt-chip-x\" onClick={() => removeTerm(dataIndex)} disabled={disabled}>\n ✕\n </button>\n </span>\n );\n}\n\nfunction OrderRow<Row>({\n api,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const orderBy = api.query.orderBy;\n const byName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n // Local live-reorder drag state (sort terms are their own list, distinct from\n // the columns shared via api.columnDrag) — same dimmed-source + slide preview.\n const [drag, setDrag] = useState<{ source: string; overIndex: number } | null>(null);\n const [adding, setAdding] = useState(false);\n\n function setOrderBy(next: OrderByClause[]) {\n api.setSort(next);\n }\n function updateTerm(i: number, patch: Partial<OrderByClause>) {\n setOrderBy(orderBy.map((o, k) => (k === i ? { ...o, ...patch } : o)));\n }\n function removeTerm(i: number) {\n setOrderBy(orderBy.filter((_, k) => k !== i));\n }\n function addTerm(f: FieldDef<Row>) {\n const field = f.sort?.field ?? f.name;\n const nextOrderBy: OrderByClause[] = [...orderBy, { field, dir: \"desc\" }];\n\n if (orderBy.some((o) => o.field === field)) {\n setAdding(false);\n return;\n }\n\n const hasSelectColumn = api.select.visible.some((c) => c.field === field);\n if (hasSelectColumn) {\n setOrderBy(nextOrderBy);\n setAdding(false);\n return;\n }\n\n api.setQuery((q) => ({\n ...q,\n offset: 0,\n orderBy: nextOrderBy,\n select: q.select.length ? [...q.select, { field }] : [...api.select.visible, { field }],\n }));\n setAdding(false);\n }\n\n // Order-by terms are identified by their (unique) field; the drag math mirrors\n // the column chips so the live preview equals the committed order.\n const termFields = orderBy.map((o) => o.field);\n const termByField = useMemo(() => new Map(orderBy.map((o) => [o.field, o])), [orderBy]);\n function previewFields(): string[] {\n if (!drag) return termFields;\n const without = termFields.filter((f) => f !== drag.source);\n if (without.length === termFields.length) return termFields;\n const at = Math.max(0, Math.min(drag.overIndex, without.length));\n return [...without.slice(0, at), drag.source, ...without.slice(at)];\n }\n function handleSortOver(e: React.DragEvent, field: string) {\n if (!drag) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (drag.source !== field) {\n const without = termFields.filter((f) => f !== drag.source);\n let next = without.indexOf(field);\n if (next >= 0) {\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n setDrag((d) => (d && d.overIndex !== next ? { source: d.source, overIndex: next } : d));\n }\n }\n }\n function commitSortDrop() {\n if (drag) setOrderBy(previewFields().map((f) => termByField.get(f)!));\n setDrag(null);\n }\n\n const rendered = previewFields();\n const sortable = fields.filter(isSortable);\n const isDefaultOrderBy =\n orderBy.length === api.defaults.orderBy.length &&\n orderBy.every((term, i) => {\n const next = api.defaults.orderBy[i];\n return (\n term.field === next?.field &&\n term.dir === next?.dir &&\n (term.nulls ?? \"last\") === (next?.nulls ?? \"last\")\n );\n });\n\n return (\n <div className=\"qt-qb-row\">\n <span className=\"qt-qb-kw\">order by</span>\n {orderBy.length === 0 && !adding && <span className=\"qt-qb-hint\">(default)</span>}\n {rendered.map((f, pos) => {\n const term = termByField.get(f)!;\n return (\n <OrderTermChip\n // Stable key (term field) so React MOVES the dragged chip, not remounts it.\n key={f}\n api={api}\n field={byName.get(f)}\n term={term}\n dataIndex={orderBy.findIndex((o) => o.field === f)}\n priority={pos + 1}\n showPriority={orderBy.length > 1}\n isDragSource={drag?.source === f}\n onDragStart={() => setDrag({ source: f, overIndex: termFields.indexOf(f) })}\n onDragOver={(e) => handleSortOver(e, f)}\n onDrop={commitSortDrop}\n onDragEnd={() => setDrag(null)}\n disabled={disabled}\n updateTerm={updateTerm}\n removeTerm={removeTerm}\n position={pos}\n count={rendered.length}\n moveTerm={(toIndex) => {\n const next = [...orderBy];\n const fromIndex = next.findIndex((candidate) => candidate.field === f);\n if (fromIndex === -1) return;\n const [moved] = next.splice(fromIndex, 1);\n next.splice(toIndex, 0, moved!);\n setOrderBy(next);\n }}\n classNames={classNames}\n label={byName.get(f)?.label ?? f}\n />\n );\n })}\n {adding ? (\n <FieldPicker fields={sortable} onPick={addTerm} onClose={() => setAdding(false)} />\n ) : (\n <button type=\"button\" className=\"qt-add\" onClick={() => setAdding(true)} disabled={disabled}>\n + add sort\n </button>\n )}\n {!isDefaultOrderBy && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={() => api.setSort(api.defaults.orderBy)} disabled={disabled}>\n reset\n </button>\n )}\n </div>\n );\n}\n\n// ---- LIMIT / OFFSET -------------------------------------------------------\n\nfunction WindowRow<Row>({\n api,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const { query } = api;\n const [limitDraft, setLimitDraft] = useState(String(query.limit));\n const [offsetDraft, setOffsetDraft] = useState(String(query.offset));\n useEffect(() => setLimitDraft(String(query.limit)), [query.limit]);\n useEffect(() => setOffsetDraft(String(query.offset)), [query.offset]);\n const hasLimitDefault = query.limit === api.defaults.limit;\n const hasOffsetDefault = query.offset === api.defaults.offset;\n const hasWindowDefault = hasLimitDefault && hasOffsetDefault;\n\n function commitLimit() {\n api.setLimit(Math.max(1, Number(limitDraft) || query.limit));\n }\n function commitOffset() {\n api.setOffset(Math.max(0, Number(offsetDraft) || 0));\n }\n\n return (\n <div className=\"qt-qb-row qt-qb-pagination\">\n <label className=\"qt-qb-window-field\">\n <span className=\"qt-qb-kw\">limit</span>\n <input\n className={cx(\"qt-qb-num\", classNames?.input)}\n type=\"number\"\n min={1}\n value={limitDraft}\n disabled={disabled}\n onChange={(e) => setLimitDraft(e.target.value)}\n onBlur={commitLimit}\n onKeyDown={(e) => e.key === \"Enter\" && commitLimit()}\n />\n </label>\n <label className=\"qt-qb-window-field\">\n <span className=\"qt-qb-kw\">offset</span>\n <input\n className={cx(\"qt-qb-num\", classNames?.input)}\n type=\"number\"\n min={0}\n value={offsetDraft}\n disabled={disabled}\n onChange={(e) => setOffsetDraft(e.target.value)}\n onBlur={commitOffset}\n onKeyDown={(e) => e.key === \"Enter\" && commitOffset()}\n />\n </label>\n {!hasWindowDefault && (\n <button\n type=\"button\"\n className=\"qt-link-btn\"\n onClick={() => {\n api.setLimit(api.defaults.limit);\n api.setOffset(api.defaults.offset);\n }}\n disabled={disabled}\n title=\"Reset limit and offset\"\n >\n reset\n </button>\n )}\n </div>\n );\n}\n\n// ---- METRICS (aggregations: op · measure · group-by, reorderable) ---------\n\nconst AGG_OPS: AggOp[] = [\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"];\nconst AGG_OP_LABELS: Record<AggOp, string> = {\n count: \"count\",\n count_distinct: \"count distinct\",\n sum: \"sum\",\n avg: \"avg\",\n min: \"min\",\n max: \"max\",\n};\n\nfunction MetricsRow<Row>({\n api,\n fields,\n classNames,\n disabled,\n}: {\n api: QueryTableApi<Row>;\n fields: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n}) {\n const { aggregations } = api;\n const clauses = aggregations.clauses;\n const measurable = useMemo(() => fields.filter(isMeasurable), [fields]);\n const groupable = useMemo(() => fields.filter(isGroupable), [fields]);\n\n // Local live-reorder drag state (metrics are their own list, like the order-by\n // terms). Chips are identified by their stable clause id so React MOVES the\n // dragged chip instead of remounting it (a remount aborts the native drag).\n const [drag, setDrag] = useState<{ source: string; overIndex: number } | null>(null);\n\n const ids = clauses.map((c) => c.id);\n const byId = useMemo(() => new Map(clauses.map((c) => [c.id, c])), [clauses]);\n\n function previewIds(): string[] {\n if (!drag) return ids;\n const without = ids.filter((i) => i !== drag.source);\n if (without.length === ids.length) return ids;\n const at = Math.max(0, Math.min(drag.overIndex, without.length));\n return [...without.slice(0, at), drag.source, ...without.slice(at)];\n }\n function handleOver(e: React.DragEvent, id: string) {\n if (!drag) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (drag.source === id) return;\n const without = ids.filter((i) => i !== drag.source);\n let next = without.indexOf(id);\n if (next >= 0) {\n // Drop after the hovered chip when past its midpoint, so a metric can be\n // moved into the last slot (no clientX ⇒ insert before, like the spec).\n const rect = e.currentTarget.getBoundingClientRect();\n if (e.clientX > rect.left + rect.width / 2) next += 1;\n setDrag((d) => (d && d.overIndex !== next ? { source: d.source, overIndex: next } : d));\n }\n }\n function commitDrop() {\n if (drag) aggregations.move(drag.source, drag.overIndex);\n setDrag(null);\n }\n\n const rendered = previewIds();\n\n return (\n <div className=\"qt-qb-row qt-qb-row--metrics\">\n <span className=\"qt-qb-kw\">metrics</span>\n {clauses.length === 0 && <span className=\"qt-qb-hint\">none</span>}\n {rendered.map((id, position) => {\n const clause = byId.get(id)!;\n return (\n <MetricChip\n // Stable key (clause id) so React MOVES the dragged chip, not remounts it.\n key={id}\n clause={clause}\n measurable={measurable}\n groupable={groupable}\n classNames={classNames}\n disabled={disabled}\n isDragSource={drag?.source === id}\n onDragStart={() => setDrag({ source: id, overIndex: ids.indexOf(id) })}\n onDragOver={(e) => handleOver(e, id)}\n onDrop={commitDrop}\n onDragEnd={() => setDrag(null)}\n onChangeOp={(op) => changeMetricOp(aggregations, clause, measurable, op)}\n onChangeField={(field) => aggregations.update(id, { field })}\n onAddGroup={(field) => aggregations.update(id, { groupBy: [...clause.groupBy, field] })}\n onRemoveGroup={(field) =>\n aggregations.update(id, { groupBy: clause.groupBy.filter((g) => g !== field) })\n }\n onRemove={() => aggregations.remove(id)}\n position={position}\n count={rendered.length}\n onMove={(toIndex) => aggregations.move(id, toIndex)}\n />\n );\n })}\n <button type=\"button\" className=\"qt-add\" onClick={() => aggregations.add()} disabled={disabled}>\n + add metric\n </button>\n {clauses.length > 0 && (\n <button type=\"button\" className=\"qt-link-btn\" onClick={aggregations.clear} disabled={disabled} title=\"Remove all metrics\">\n reset\n </button>\n )}\n </div>\n );\n}\n\n/** Change a metric's op, dropping the measure if it's no longer valid for the\n * new op (e.g. switching avg→count on a text field, or to an op the field type\n * can't aggregate). `count` keeps any chosen measure. */\nfunction changeMetricOp<Row>(\n aggregations: QueryTableApi<Row>[\"aggregations\"],\n clause: AggregationClause,\n measurable: FieldDef<Row>[],\n op: AggOp,\n): void {\n const field = clause.field;\n const stillValid =\n field != null && measurable.some((f) => f.name === field && aggOpsForField(f).includes(op));\n if (field != null && !stillValid) aggregations.update(clause.id, { op, field: undefined });\n else aggregations.update(clause.id, { op });\n}\n\nfunction MetricChip<Row>({\n clause,\n measurable,\n groupable,\n classNames,\n disabled,\n isDragSource,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n onChangeOp,\n onChangeField,\n onAddGroup,\n onRemoveGroup,\n onRemove,\n position,\n count,\n onMove,\n}: {\n clause: AggregationClause;\n measurable: FieldDef<Row>[];\n groupable: FieldDef<Row>[];\n classNames: QueryBuilderClassNames | undefined;\n disabled: boolean | undefined;\n isDragSource: boolean;\n onDragStart: () => void;\n onDragOver: (e: React.DragEvent) => void;\n onDrop: () => void;\n onDragEnd: () => void;\n onChangeOp: (op: AggOp) => void;\n onChangeField: (field: string | undefined) => void;\n onAddGroup: (field: string) => void;\n onRemoveGroup: (field: string) => void;\n onRemove: () => void;\n position: number;\n count: number;\n onMove: (toIndex: number) => void;\n}) {\n const [addingGroup, setAddingGroup] = useState(false);\n const byName = useMemo(() => new Map(groupable.map((f) => [f.name, f])), [groupable]);\n\n // Measures valid for the current op (a measurable field whose effective ops\n // include this op). `count` may stand alone, so it gets an \"(all rows)\" choice.\n const needsField = aggOpNeedsField(clause.op);\n const measureOptions = measurable.filter((f) => aggOpsForField(f).includes(clause.op));\n\n return (\n <span\n className={cx(\"qt-chip\", \"qt-chip--agg\", isDragSource && \"qt-chip--dragging\", classNames?.chip)}\n draggable={!disabled}\n onDragStart={(e) => {\n onDragStart();\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", clause.id);\n }}\n onDragOver={onDragOver}\n onDrop={(e) => {\n e.preventDefault();\n onDrop();\n }}\n onDragEnd={onDragEnd}\n title=\"drag to reorder metrics\"\n >\n <span aria-hidden className=\"qt-chip-grip\">\n ⋮⋮\n </span>\n <select\n className={cx(\"qt-chip-op\", classNames?.select)}\n value={clause.op}\n disabled={disabled}\n onChange={(e) => onChangeOp(e.target.value as AggOp)}\n >\n {AGG_OPS.map((op) => (\n <option key={op} value={op}>\n {AGG_OP_LABELS[op]}\n </option>\n ))}\n </select>\n <select\n className={cx(\"qt-chip-val\", classNames?.select)}\n value={clause.field ?? \"\"}\n disabled={disabled}\n onChange={(e) => onChangeField(e.target.value || undefined)}\n >\n {!needsField && <option value=\"\">(all rows)</option>}\n {needsField && clause.field == null && <option value=\"\">measure…</option>}\n {measureOptions.map((f) => (\n <option key={f.name} value={f.name}>\n {f.label}\n </option>\n ))}\n </select>\n <span className=\"qt-chip-agg-by\">\n {clause.groupBy.map((g) => (\n <span className=\"qt-chip-agg-group\" key={g}>\n <span className=\"qt-chip-agg-group-label\">{byName.get(g)?.label ?? g}</span>\n <button type=\"button\" className=\"qt-chip-x\" onClick={() => onRemoveGroup(g)} disabled={disabled}>\n ✕\n </button>\n </span>\n ))}\n {addingGroup ? (\n <FieldPicker\n fields={groupable}\n excluded={clause.groupBy}\n onPick={(f) => {\n onAddGroup(f.name);\n setAddingGroup(false);\n }}\n onClose={() => setAddingGroup(false)}\n />\n ) : (\n <button\n type=\"button\"\n className=\"qt-add qt-chip-agg-add\"\n onClick={() => setAddingGroup(true)}\n disabled={disabled}\n title=\"Group by a field\"\n >\n {clause.groupBy.length === 0 ? \"+ by\" : \"+\"}\n </button>\n )}\n </span>\n <MoveButtons\n label={clause.label ?? `${AGG_OP_LABELS[clause.op]} metric`}\n position={position}\n count={count}\n disabled={disabled}\n onMove={onMove}\n />\n <button type=\"button\" className=\"qt-chip-x\" onClick={onRemove} disabled={disabled} title=\"Remove metric\">\n ✕\n </button>\n </span>\n );\n}\n","// FieldPicker — grouped, searchable field chooser.\n// Searches label + name + aliases, groups by FieldDef.group, and surfaces\n// per-field stats (distinct count, min/max) when the Transport provides them.\n// Used to add columns and to add filters.\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport type { FieldDef, FieldStats } from \"@pythia-software/query-table-core\";\n\nexport interface FieldPickerProps<Row> {\n fields: FieldDef<Row>[];\n /** Already-shown field names, so the picker can mark/hide them. */\n excluded?: string[];\n /** Stats keyed by field name (optional). */\n stats?: Record<string, FieldStats>;\n /** When true, dim/disable fields with ≤1 distinct value (\"gate on distinct\"). */\n gateOnDistinct?: boolean;\n onPick: (field: FieldDef<Row>) => void;\n onClose?: () => void;\n}\n\nconst UNGROUPED = \"other\";\n\nexport function FieldPicker<Row>({\n fields,\n excluded,\n stats,\n gateOnDistinct,\n onPick,\n onClose,\n}: FieldPickerProps<Row>): ReactNode {\n const [search, setSearch] = useState(\"\");\n const needle = search.trim().toLowerCase();\n const excludedSet = useMemo(() => new Set(excluded ?? []), [excluded]);\n\n const matched = useMemo(\n () =>\n fields.filter((f) => {\n if (excludedSet.has(f.name)) return false;\n if (!needle) return true;\n return (\n f.label.toLowerCase().includes(needle) ||\n f.name.toLowerCase().includes(needle) ||\n (fieldAliases(f).some((a) => a.toLowerCase().includes(needle)))\n );\n }),\n [fields, excludedSet, needle],\n );\n\n const grouped = useMemo(() => groupByGroup(matched), [matched]);\n\n const firstEnabled = matched.find((f) => isEnabled(f, stats, gateOnDistinct));\n\n return (\n <div className=\"qt-picker\">\n <input\n autoFocus\n type=\"text\"\n className=\"qt-picker-input\"\n placeholder=\"search fields…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onClose?.();\n if (e.key === \"Enter\" && firstEnabled) {\n onPick(firstEnabled);\n setSearch(\"\");\n }\n }}\n // Defer so a mousedown on a list item lands before blur closes it.\n onBlur={() => setTimeout(() => onClose?.(), 150)}\n />\n <div className=\"qt-picker-list\">\n {matched.length === 0 ? (\n <div className=\"qt-picker-empty\">no matches</div>\n ) : (\n grouped.map(([group, fs]) => (\n <div key={group} className=\"qt-picker-group\">\n <div className=\"qt-picker-group-label\">{group}</div>\n {fs.map((f) => {\n const enabled = isEnabled(f, stats, gateOnDistinct);\n const s = stats?.[f.name];\n const aliasHit = aliasMatch(f, needle);\n return (\n <button\n key={f.name}\n type=\"button\"\n disabled={!enabled}\n className={enabled ? \"qt-picker-item\" : \"qt-picker-item qt-picker-item--disabled\"}\n title={enabled ? f.name : \"not useful as a filter (≤1 distinct value)\"}\n // Pointer down fires before blur for mouse, pen, and touch.\n onPointerDown={(e) => {\n if (!enabled) return;\n e.preventDefault();\n onPick(f);\n setSearch(\"\");\n }}\n >\n <span className=\"qt-picker-row\">\n <span className=\"qt-picker-label\">{f.label}</span>\n <span className=\"qt-picker-name\">{f.name}</span>\n </span>\n {aliasHit && <span className=\"qt-picker-alias\">matches: {aliasHit}</span>}\n {s && (\n <span className=\"qt-picker-stats\">\n {s.distinct != null && <>{s.distinct} distinct</>}\n {s.min != null && s.max != null && (\n <>\n {\" \"}\n · {fmtStat(s.min)}…{fmtStat(s.max)}\n </>\n )}\n </span>\n )}\n </button>\n );\n })}\n </div>\n ))\n )}\n </div>\n </div>\n );\n}\n\nfunction isEnabled(f: FieldDef, stats: FieldPickerProps<any>[\"stats\"], gate: boolean | undefined): boolean {\n if (!gate) return true;\n const s = stats?.[f.name];\n if (!s || s.distinct == null) return true; // no data → don't gate\n return s.distinct > 1;\n}\n\nfunction aliasMatch(f: FieldDef, needle: string): string | undefined {\n if (!needle) return undefined;\n if (f.label.toLowerCase().includes(needle) || f.name.toLowerCase().includes(needle)) return undefined;\n return fieldAliases(f).find((a) => a.toLowerCase().includes(needle));\n}\n\nfunction fieldAliases<Row>(f: FieldDef<Row>): string[] {\n const aliases = new Set<string>();\n if (f.alias) aliases.add(f.alias);\n if (f.aliases) {\n for (const alias of f.aliases) aliases.add(alias);\n }\n return [...aliases];\n}\n\nfunction groupByGroup<Row>(fs: FieldDef<Row>[]): Array<[string, FieldDef<Row>[]]> {\n const groups = new Map<string, FieldDef<Row>[]>();\n for (const f of fs) {\n const key = f.group ?? UNGROUPED;\n const arr = groups.get(key);\n if (arr) arr.push(f);\n else groups.set(key, [f]);\n }\n return [...groups.entries()];\n}\n\nfunction fmtStat(v: string | number): string {\n if (typeof v === \"number\") return v.toLocaleString();\n const s = String(v);\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(s)) return s.slice(0, 10);\n if (s.length > 18) return s.slice(0, 15) + \"…\";\n return s;\n}\n","// SavedQueriesModal — list / load / delete named saved queries. Thin view over\n// api.saved; loading one pushes its QueryState into the controller (and the URL).\n\nimport { useEffect, type ReactNode } from \"react\";\nimport type { SavedQueriesApi } from \"@pythia-software/query-table-react\";\n\nexport interface SavedQueriesModalProps {\n saved: SavedQueriesApi;\n onClose: () => void;\n onLoad?: (savedId: string) => void;\n}\n\nexport function SavedQueriesModal({ saved, onClose, onLoad }: SavedQueriesModalProps): ReactNode {\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onClose]);\n\n return (\n <div className=\"qt-modal-backdrop\" onClick={onClose}>\n <div\n className=\"qt-modal\"\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Saved queries\"\n >\n <h3 className=\"qt-modal-title\">Saved queries</h3>\n {saved.loading ? (\n <p className=\"qt-muted\">Loading…</p>\n ) : saved.items.length === 0 ? (\n <p className=\"qt-muted\">None saved yet. Save the current query from the toolbar.</p>\n ) : (\n <ul className=\"qt-saved-list\">\n {saved.items.map((s) => {\n const filters = s.query.where.length;\n const isDefault = saved.defaultId === s.id;\n return (\n <li key={s.id} className=\"qt-saved-item\">\n <button\n type=\"button\"\n className=\"qt-saved-pick\"\n onClick={() => {\n onLoad?.(s.id);\n saved.load(s.id);\n onClose();\n }}\n >\n <span className=\"qt-saved-name\">{s.name}</span>\n <span className=\"qt-saved-meta qt-muted\">\n {isDefault ? \"Default view · \" : \"\"}\n {new Date(s.savedAt).toLocaleString()} · {filters} filter{filters === 1 ? \"\" : \"s\"}\n </span>\n </button>\n {isDefault ? (\n <button\n type=\"button\"\n className=\"qt-btn qt-saved-default\"\n title=\"Clear default view\"\n onClick={() => void saved.clearDefault()}\n >\n default\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"qt-btn qt-saved-default\"\n title=\"Use as default view\"\n onClick={() => void saved.setDefault(s.id)}\n >\n make default\n </button>\n )}\n <button\n type=\"button\"\n className=\"qt-btn qt-saved-delete\"\n title=\"Delete saved query\"\n onClick={() => void saved.remove(s.id)}\n >\n delete\n </button>\n </li>\n );\n })}\n </ul>\n )}\n <div className=\"qt-modal-footer\">\n <button type=\"button\" className=\"qt-btn\" onClick={onClose}>\n close\n </button>\n </div>\n </div>\n </div>\n );\n}\n","// MetricsPanel — the dashboard strip above the table.\n//\n// Renders the optional aggregation metrics (see @pythia-software/query-table-core\n// AggregationClause). Each metric's shape follows its group-by arity:\n// 0 group-by → one big number\n// 1 group-by → a ranked bar list (label · value · share bar)\n// 2 group-by → an x/y pivot table (rows = axis 0, cols = axis 1)\n// 3+ group-by → a flat table, one column per group key + the value\n//\n// Values are formatted through the measure field's own renderer where it makes\n// sense (so AVG(total_ms) reads \"3.2s\", not \"3200\"), falling back to a locale\n// number. Counts are always plain integers.\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { EMPTY_QUERY } from \"@pythia-software/query-table-core\";\nimport type { AggOp, AggregationBucket, AggregationClause, FieldDef } from \"@pythia-software/query-table-core\";\nimport type { AggregationsApi } from \"@pythia-software/query-table-react\";\nimport { resolveRenderer, type RenderRegistry } from \"./renderers\";\n\nexport interface MetricsPanelProps<Row> {\n /** The aggregation API from useQueryTable (clauses + results + status). */\n aggregations: AggregationsApi;\n /** All schema fields, to resolve labels + the measure field's renderer. */\n fields: FieldDef<Row>[];\n /** Cell renderers (same registry as the table) for formatting measure values. */\n renderers?: RenderRegistry<Row>;\n /** Hidden entirely when there are no metrics unless this is set. */\n emptyMessage?: string;\n classNames?: { root?: string; metric?: string };\n}\n\nconst cx = (...parts: Array<string | undefined | false>): string =>\n parts.filter((p): p is string => Boolean(p)).join(\" \");\n\nconst OP_LABELS: Record<AggOp, string> = {\n count: \"Count\",\n count_distinct: \"Distinct\",\n sum: \"Sum\",\n avg: \"Avg\",\n min: \"Min\",\n max: \"Max\",\n};\n\nconst NULL_KEY = \"∅\";\n\nexport function MetricsPanel<Row>({\n aggregations,\n fields,\n renderers,\n emptyMessage,\n classNames,\n}: MetricsPanelProps<Row>): ReactNode {\n const byName = useMemo(() => new Map(fields.map((f) => [f.name, f])), [fields]);\n const { clauses, results, loading, error } = aggregations;\n\n if (clauses.length === 0) {\n return emptyMessage ? <div className={cx(\"qt-metrics\", classNames?.root)}>{emptyMessage}</div> : null;\n }\n\n const resultById = new Map((results?.metrics ?? []).map((m) => [m.id, m.buckets]));\n\n return (\n <div className={cx(\"qt-metrics\", classNames?.root)}>\n {error ? <div className=\"qt-metrics-error\">Metrics failed: {error.message}</div> : null}\n {clauses.map((clause) => (\n <MetricCard\n key={clause.id}\n clause={clause}\n buckets={resultById.get(clause.id) ?? []}\n loading={loading && !resultById.has(clause.id)}\n byName={byName}\n renderers={renderers}\n className={classNames?.metric}\n />\n ))}\n </div>\n );\n}\n\nfunction MetricCard<Row>({\n clause,\n buckets,\n loading,\n byName,\n renderers,\n className,\n}: {\n clause: AggregationClause;\n buckets: AggregationBucket[];\n loading: boolean;\n byName: Map<string, FieldDef<Row>>;\n renderers: RenderRegistry<Row> | undefined;\n className: string | undefined;\n}): ReactNode {\n const measure = clause.field ? byName.get(clause.field) : undefined;\n const groupLabels = clause.groupBy.map((g) => byName.get(g)?.label ?? g);\n // One decimal-place count for the whole card (≈5 significant figures), so every\n // value lines up and we never render a 12-digit float tail.\n const decimals = useMemo(() => cardDecimals(buckets), [buckets]);\n const fmt = (v: number | string | null): ReactNode => formatMetricValue(v, clause.op, measure, renderers, decimals);\n\n return (\n <div className={cx(\"qt-metric\", `qt-metric--gb${Math.min(clause.groupBy.length, 3)}`, className)}>\n <div className=\"qt-metric-head\">\n <span className=\"qt-metric-title\">{metricTitle(clause, measure)}</span>\n {groupLabels.length > 0 && <span className=\"qt-metric-by\">by {groupLabels.join(\" × \")}</span>}\n </div>\n {loading && buckets.length === 0 ? (\n <div className=\"qt-metric-loading\">…</div>\n ) : buckets.length === 0 ? (\n <div className=\"qt-metric-empty\">no data</div>\n ) : clause.groupBy.length === 0 ? (\n <BigNumber bucket={buckets[0]!} fmt={fmt} />\n ) : clause.groupBy.length === 1 ? (\n <BarList buckets={buckets} fmt={fmt} />\n ) : clause.groupBy.length === 2 ? (\n <Pivot buckets={buckets} fmt={fmt} rowLabel={groupLabels[0]!} colLabel={groupLabels[1]!} />\n ) : (\n <FlatTable buckets={buckets} fmt={fmt} groupLabels={groupLabels} valueLabel={metricTitle(clause, measure)} />\n )}\n </div>\n );\n}\n\n// ---- 0 group-by: one big number -------------------------------------------\n\nfunction BigNumber({ bucket, fmt }: { bucket: AggregationBucket; fmt: (v: number | string | null) => ReactNode }) {\n return (\n <div className=\"qt-metric-big\">\n <span className=\"qt-metric-big-value\">{fmt(bucket.value)}</span>\n <span className=\"qt-metric-big-sub\">{bucket.count.toLocaleString()} rows</span>\n </div>\n );\n}\n\n// ---- 1 group-by: ranked bars ----------------------------------------------\n\nfunction BarList({ buckets, fmt }: { buckets: AggregationBucket[]; fmt: (v: number | string | null) => ReactNode }) {\n const max = Math.max(...buckets.map((b) => barMagnitude(b)), 0);\n return (\n <div className=\"qt-metric-bars\">\n {buckets.map((b, i) => {\n const pct = max > 0 ? (barMagnitude(b) / max) * 100 : 0;\n return (\n <div className=\"qt-metric-bar-row\" key={`${keyText(b.keys[0])}-${i}`}>\n <span className=\"qt-metric-bar-label\" title={keyText(b.keys[0])}>\n {keyNode(b.keys[0])}\n </span>\n <span className=\"qt-metric-bar-track\">\n <span className=\"qt-metric-bar-fill\" style={{ width: `${pct}%` }} />\n </span>\n <span className=\"qt-metric-bar-value\">{fmt(b.value)}</span>\n </div>\n );\n })}\n </div>\n );\n}\n\n// ---- 2 group-by: x/y pivot ------------------------------------------------\n\nfunction Pivot({\n buckets,\n fmt,\n rowLabel,\n colLabel,\n}: {\n buckets: AggregationBucket[];\n fmt: (v: number | string | null) => ReactNode;\n rowLabel: string;\n colLabel: string;\n}) {\n const rowKeys = distinctKeys(buckets, 0);\n const colKeys = distinctKeys(buckets, 1);\n const cell = new Map<string, number | string | null>();\n for (const b of buckets) cell.set(`${keyText(b.keys[0])}\\u0000${keyText(b.keys[1])}`, b.value);\n\n return (\n <div className=\"qt-metric-pivot-wrap\">\n <table className=\"qt-metric-pivot\">\n <thead>\n <tr>\n <th className=\"qt-metric-pivot-corner\">\n <span className=\"qt-metric-pivot-axes\">\n {rowLabel} <span className=\"qt-muted\">\\</span> {colLabel}\n </span>\n </th>\n {colKeys.map((c) => (\n <th key={keyText(c)} className=\"qt-metric-pivot-col\">\n {keyNode(c)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rowKeys.map((r) => (\n <tr key={keyText(r)}>\n <th className=\"qt-metric-pivot-row\">{keyNode(r)}</th>\n {colKeys.map((c) => {\n const v = cell.get(`${keyText(r)}\\u0000${keyText(c)}`);\n return (\n <td key={keyText(c)} className=\"qt-metric-pivot-cell\">\n {v === undefined ? <span className=\"qt-muted\">·</span> : fmt(v)}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ---- 3+ group-by: flat table ----------------------------------------------\n\nfunction FlatTable({\n buckets,\n fmt,\n groupLabels,\n valueLabel,\n}: {\n buckets: AggregationBucket[];\n fmt: (v: number | string | null) => ReactNode;\n groupLabels: string[];\n valueLabel: string;\n}) {\n return (\n <div className=\"qt-metric-pivot-wrap\">\n <table className=\"qt-metric-flat\">\n <thead>\n <tr>\n {groupLabels.map((g) => (\n <th key={g}>{g}</th>\n ))}\n <th className=\"qt-metric-flat-value\">{valueLabel}</th>\n </tr>\n </thead>\n <tbody>\n {buckets.map((b, i) => (\n <tr key={i}>\n {/* Index by column, not by b.keys: a bucket whose `keys` is shorter\n than the header (a malformed/partial result) must still leave the\n value in the value column rather than sliding it left. */}\n {groupLabels.map((_, j) => (\n <td key={j}>{keyNode(b.keys[j])}</td>\n ))}\n <td className=\"qt-metric-flat-value\">{fmt(b.value)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ---- helpers --------------------------------------------------------------\n\nfunction metricTitle<Row>(clause: AggregationClause, measure: FieldDef<Row> | undefined): string {\n if (clause.label) return clause.label;\n if (clause.op === \"count\" && !measure) return \"Count\";\n return `${OP_LABELS[clause.op]} ${measure?.label ?? clause.field ?? \"\"}`.trim();\n}\n\n// Default renderers that map a number to a unit-formatted string (and so already\n// bound their own decimals). Any OTHER renderer (text/link/pill/number) is skipped\n// for numeric aggregates — it would stringify the raw float — in favor of the\n// card's shared decimal formatting.\nconst UNIT_RENDER_KEYS: ReadonlySet<string> = new Set([\"duration_ms\", \"byte_size\"]);\n\nfunction formatMetricValue<Row>(\n value: number | string | null,\n op: AggOp,\n measure: FieldDef<Row> | undefined,\n renderers: RenderRegistry<Row> | undefined,\n decimals: number,\n): ReactNode {\n if (value == null) return <span className=\"qt-muted\">—</span>;\n // Counts are dimensionless integers — never run them through a column renderer.\n if (op === \"count\" || op === \"count_distinct\") {\n return typeof value === \"number\" ? formatNumber(value, 0) : String(value);\n }\n if (typeof value === \"number\") {\n const key = typeof measure?.render === \"string\" ? measure.render : undefined;\n if (key && UNIT_RENDER_KEYS.has(key) && measure && renderers) {\n const node = tryRender(measure, renderers, value);\n if (node != null) return node;\n }\n return formatNumber(value, decimals);\n }\n // min/max over text or datetime → the column's renderer, else the raw string.\n if (measure && renderers) {\n const node = tryRender(measure, renderers, value);\n if (node != null) return node;\n }\n return String(value);\n}\n\nfunction tryRender<Row>(\n measure: FieldDef<Row>,\n renderers: RenderRegistry<Row>,\n value: number | string,\n): ReactNode | null {\n try {\n const node = resolveRenderer(measure, renderers)({\n value: value as never,\n row: {} as Row,\n field: measure,\n query: EMPTY_QUERY,\n });\n return node != null && node !== \"\" ? node : null;\n } catch {\n return null;\n }\n}\n\nfunction formatNumber(value: number, decimals: number): string {\n if (!Number.isFinite(value)) return String(value);\n return value.toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals });\n}\n\n// One decimal count for every numeric value in a card: 0 when all are integers\n// (counts, integer measures), else enough places to give the largest-magnitude\n// value ≈5 significant figures (so smaller values share that precision and no\n// value shows a runaway float tail). Capped at 6.\nfunction cardDecimals(buckets: AggregationBucket[]): number {\n const nums = buckets\n .map((b) => b.value)\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v));\n if (nums.length === 0) return 0;\n if (nums.every((v) => Number.isInteger(v))) return 0;\n const maxAbs = Math.max(...nums.map((v) => Math.abs(v)));\n const intDigits = maxAbs >= 1 ? Math.floor(Math.log10(maxAbs)) + 1 : 0;\n return Math.min(6, Math.max(0, 5 - intDigits));\n}\n\nfunction barMagnitude(b: AggregationBucket): number {\n return typeof b.value === \"number\" ? Math.abs(b.value) : b.count;\n}\n\nfunction distinctKeys(buckets: AggregationBucket[], axis: number): (string | null)[] {\n const seen = new Set<string>();\n const out: (string | null)[] = [];\n for (const b of buckets) {\n const k = b.keys[axis] ?? null;\n const t = keyText(k);\n if (!seen.has(t)) {\n seen.add(t);\n out.push(k);\n }\n }\n return out;\n}\n\nfunction keyText(k: string | null | undefined): string {\n return k == null ? NULL_KEY : String(k);\n}\n\nfunction keyNode(k: string | null | undefined): ReactNode {\n return k == null ? <span className=\"qt-muted\">{NULL_KEY}</span> : String(k);\n}\n","// SelectionToolbar — the bulk-action FRAME, not the actions.\n//\n// Deliberately generic: it shows the selected count, a clear-all, and an\n// `actions` slot. The actual verbs are domain logic the consumer renders into the\n// slot. The reusable part is the selection plumbing + affordance; the verbs are\n// not. This keeps domain coupling out while still shipping the pattern.\n\nimport type { ReactNode } from \"react\";\nimport type { RowId } from \"@pythia-software/query-table-core\";\nimport type { SelectionApi } from \"@pythia-software/query-table-react\";\n\nexport interface SelectionToolbarProps {\n selection: SelectionApi;\n /** Consumer-rendered action buttons. Receives the selected ids so the consumer\n * can gate/enable actions (e.g. mixed-state rules). */\n actions: (selectedIds: RowId[]) => ReactNode;\n /** Hidden when nothing is selected unless `alwaysShow`. */\n alwaysShow?: boolean;\n className?: string;\n}\n\nconst cx = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\nexport function SelectionToolbar({ selection, actions, alwaysShow, className }: SelectionToolbarProps): ReactNode {\n if (selection.count === 0 && !alwaysShow) return null;\n\n const selectedIds = [...selection.selected];\n\n return (\n <div className={cx(\"qt-selection-toolbar\", className)} role=\"toolbar\">\n <span className=\"qt-selection-count\">\n {selection.count} selected\n </span>\n <button\n type=\"button\"\n className=\"qt-btn\"\n onClick={selection.clear}\n disabled={selection.count === 0}\n >\n clear\n </button>\n <span className=\"qt-selection-actions\">{actions(selectedIds)}</span>\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useState","Fragment","jsx","jsxs","cx","MENU_WIDTH","useState","useEffect","valueToString","MenuItem","useEffect","useMemo","useRef","useState","NULLARY_OPS","isSortable","opsForField","useMemo","useState","Fragment","jsx","jsxs","useEffect","jsx","jsxs","jsx","jsxs","cx","formatDuration","useState","useEffect","NULLARY_OPS","useMemo","useRef","opsForField","isSortable","useMemo","jsx","jsxs","cx","useMemo","jsx","jsxs","cx"]}
|