@upbound/monarch-blocks 0.5.0 → 0.6.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 +17 -0
- package/dist/cel-filter-bar.js +9 -3
- package/dist/cel-filter-bar.js.map +1 -1
- package/dist/chart.js.map +1 -1
- package/dist/chat-interface.js +1 -1
- package/dist/chat-interface.js.map +1 -1
- package/dist/code-block.js.map +1 -1
- package/dist/data-table.d.ts +4 -176
- package/dist/data-table.js +57 -14
- package/dist/data-table.js.map +1 -1
- package/dist/empty-view-DO36LNvk.d.ts +179 -0
- package/dist/filter-bar.js +12 -3
- package/dist/filter-bar.js.map +1 -1
- package/dist/floating-widget.js.map +1 -1
- package/dist/graph.css +73 -0
- package/dist/graph.d.ts +182 -0
- package/dist/graph.js +1780 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1004 -31
- package/dist/index.js.map +1 -1
- package/dist/page-header.js.map +1 -1
- package/dist/relative-time.js.map +1 -1
- package/dist/section-header.js.map +1 -1
- package/dist/section-nav.js.map +1 -1
- package/dist/timeline.js.map +1 -1
- package/package.json +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cel-filter-bar/cel-filter-bar.tsx","../src/lib/utils.ts","../src/hooks/use-mounted.ts","../src/hooks/use-cel-filter-editor-state.ts","../src/lib/cel-filter/constants.ts","../src/lib/cel-filter/date-utils.ts","../src/lib/cel-filter/types.ts","../src/lib/cel-filter/value-utils.ts","../src/lib/cel-filter/compile/escape-cel-string.ts","../src/lib/cel-filter/compile/operators.ts","../src/lib/cel-filter/compile/validate-condition.ts","../src/lib/cel-filter/compile/apply-display-rules.ts","../src/lib/cel-filter/schema-utils.ts","../src/lib/cel-filter/compile/compute-is-emit-ready.ts","../src/lib/cel-filter/compile/compile-cel-filter-tree.ts","../src/lib/cel-filter/tree-utils.ts","../src/lib/cel-filter/merge-contextual-into-cel-tree.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon } from '@upbound/monarch-core';\nimport { type DateRange } from 'react-day-picker';\n\nimport { cn } from '@/lib/utils';\nimport { useMounted } from '@/hooks/use-mounted';\nimport { Badge } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { ButtonGroup, ButtonGroupText } from '@upbound/monarch-core';\nimport { Calendar } from '@upbound/monarch-core';\nimport {\n Combobox,\n ComboboxChip,\n ComboboxClearAll,\n ComboboxCollection,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxLabel,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@upbound/monarch-core';\n\nimport { useCelFilterEditorState, type CelConditionEditorController } from '@/hooks/use-cel-filter-editor-state';\nimport {\n allowsMultipleConditions,\n appendCondition,\n applyDisplayRules,\n applyOperatorChange,\n calendarDayStartInstant,\n compileCelFilterTree,\n computeIsEmitReady,\n createDefaultCondition,\n dateBoundaryForOperator,\n formatCalendarDateUtc,\n formatInstantLabel,\n getAllowedOperators,\n getOperatorLabel,\n getQuantifierLabel,\n isCelFilterCondition,\n isCheckboxCelValue,\n isDateRangeOperator,\n isDateRelativeOperator,\n isDateWindowOperator,\n isRelativeDateCelValue,\n parseCalendarDate,\n readDateCelValue,\n readMapKeyCelValue,\n readMultiTextCelValue,\n readTimeOfDay,\n RELATIVE_DURATION_PRESET_VALUES,\n removeConditionById,\n replaceCondition,\n resolveColumnDefinition,\n resolveFilterShape,\n withTimeOfDay,\n type CelColumnDefinition,\n type CelColumnOption,\n type CelFilterBarProps,\n type CelFilterCondition,\n type CelOperator,\n type CompileResult,\n type DateCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type RelativeDurationPreset,\n} from '@/lib/cel-filter';\n\ntype PortalContainer = React.ComponentProps<typeof ComboboxContent>['container'];\n\nconst RELATIVE_PRESET_LABELS: Record<RelativeDurationPreset, string> = {\n '24h': 'Last 24 hours',\n '168h': 'Last 7 days',\n '720h': 'Last 30 days',\n};\n\n// Neutralizes Select's default purple focus ring/border and matches the\n// plain grey hover/focus background the rest of a pill's segments (value\n// trigger, remove button — both Button variant=\"outline\") use, so every\n// Select-based segment reads as part of one continuous control. `!` is\n// required on the hover border: Select's own hover border is a compound\n// variant (hover:not-disabled:not-aria-invalid:border-ring/50) that a plain\n// hover:border-input doesn't win against via class order alone.\nconst SEGMENT_SELECT_TRIGGER_CLASSNAME =\n 'hover:border-input! focus-visible:border-input focus-visible:ring-0 hover:bg-muted focus-visible:bg-muted aria-expanded:bg-muted';\n\n// ── CelFilterBar ──────────────────────────────────────\n\nfunction CelFilterBar({\n tree,\n onChange,\n schema,\n onCompileResultChange,\n onRestrictedOptionSelect,\n showClearButton = false,\n className,\n}: CelFilterBarProps) {\n const editor = useCelFilterEditorState();\n const onCompileResultChangeRef = React.useRef(onCompileResultChange);\n React.useEffect(() => {\n onCompileResultChangeRef.current = onCompileResultChange;\n });\n\n const rawResult = React.useMemo(() => compileCelFilterTree(tree, schema), [tree, schema]);\n const displayResult = React.useMemo(\n () =>\n applyDisplayRules(rawResult, {\n editingConditionId: editor.editingConditionId,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.committedConditionIds],\n );\n const isEmitReady = React.useMemo(\n () =>\n computeIsEmitReady(rawResult, editor.editingConditionId, schema, tree, {\n activeSurface: editor.activeSurface,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.activeSurface, editor.committedConditionIds, schema, tree],\n );\n\n React.useEffect(() => {\n onCompileResultChangeRef.current?.({ ...displayResult, isEmitReady });\n }, [displayResult, isEmitReady]);\n\n const conditions = tree.root.children.filter(isCelFilterCondition);\n\n // Ref for the CelFilterBar's own root node, used to anchor Combobox popups.\n // Helps rendering correctly the popup when rendered inside a modal Dialog/Sheet.\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n function handleAddFilter(columnId: string) {\n const condition = createDefaultCondition({ schema, columnId });\n onChange(appendCondition(tree, condition));\n editor.beginEditing(condition.id);\n editor.suppressDismissFor(condition.id);\n }\n\n function handleRemove(conditionId: string) {\n onChange(removeConditionById(tree, conditionId));\n editor.removeCondition(conditionId);\n }\n\n function handleClearAll() {\n onChange({ root: { ...tree.root, children: [] } });\n editor.clearSuppress();\n }\n\n return (\n <div data-slot=\"cel-filter-bar\" className={cn('flex flex-wrap items-center gap-2', className)} ref={containerRef}>\n <CelAddFilterButton schema={schema} conditions={conditions} onSelect={handleAddFilter} container={containerRef} />\n\n {conditions.map(condition => {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) return null;\n return (\n <CelFilterPill\n key={condition.id}\n condition={condition}\n columnDef={columnDef}\n schema={schema}\n tree={tree}\n onChange={onChange}\n controller={editor.getController(condition.id)}\n issues={displayResult.issues.filter(issue => issue.nodeId === condition.id)}\n onRemove={() => handleRemove(condition.id)}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={containerRef}\n />\n );\n })}\n\n {showClearButton && conditions.length > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={handleClearAll}>\n Clear all\n </Button>\n )}\n </div>\n );\n}\n\n// ── Add filter menu ───────────────────────────────────\n\ntype CelAddFilterGroup = { value: string; items: CelColumnDefinition[] };\n\nfunction CelAddFilterButton({\n schema,\n conditions,\n onSelect,\n container,\n}: {\n schema: CelFilterBarProps['schema'];\n conditions: CelFilterCondition[];\n onSelect: (columnId: string) => void;\n container?: PortalContainer;\n}) {\n const usedSingleInstanceColumnIds = new Set(\n conditions\n .map(condition => resolveColumnDefinition(condition, schema))\n .filter(\n (columnDef): columnDef is CelColumnDefinition => !!columnDef && !allowsMultipleConditions(columnDef.filterType),\n )\n .map(columnDef => columnDef.id),\n );\n const availableColumns = schema.columns.filter(column => !usedSingleInstanceColumnIds.has(column.id));\n\n const groupMap = new Map<string, CelColumnDefinition[]>();\n for (const column of availableColumns) {\n const key = column.group ?? '';\n const list = groupMap.get(key) ?? [];\n list.push(column);\n groupMap.set(key, list);\n }\n const groups: CelAddFilterGroup[] = Array.from(groupMap.entries()).map(([value, items]) => ({ value, items }));\n\n return (\n <Combobox\n items={groups}\n itemToStringValue={(item: CelColumnDefinition) => item.title}\n itemToStringLabel={(item: CelColumnDefinition) => item.title}\n onValueChange={(column: CelColumnDefinition | null) => {\n if (column) onSelect(column.id);\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name the\n way a plain button would — an explicit aria-label is required, not\n just a nicety. */}\n <ComboboxTrigger aria-label=\"Add filter\" render={<Button variant=\"outline\" />}>\n <Icon name=\"plus\" data-icon=\"inline-start\" />\n Add filter\n </ComboboxTrigger>\n <ComboboxContent container={container} align=\"start\" className=\"w-64\">\n <ComboboxInput showTrigger={false} placeholder=\"Search filters…\" />\n <ComboboxEmpty>No filters found.</ComboboxEmpty>\n <ComboboxList>\n {(group: CelAddFilterGroup) => (\n <ComboboxGroup key={group.value} items={group.items}>\n {group.value && <ComboboxLabel>{group.value}</ComboboxLabel>}\n <ComboboxCollection>\n {(column: CelColumnDefinition) => (\n <ComboboxItem key={column.id} value={column}>\n {column.title}\n </ComboboxItem>\n )}\n </ComboboxCollection>\n </ComboboxGroup>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Filter pill ────────────────────────────────────────\n\nfunction formatConditionSummary(\n condition: CelFilterCondition,\n columnDef: CelColumnDefinition,\n locale?: string,\n): string {\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n\n switch (shape) {\n case 'checkbox': {\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n if (value.length === 0) return 'Any';\n if (value.length === 1) {\n return columnDef.options?.find(opt => opt.value === value[0])?.label ?? value[0];\n }\n return `${value.length} ${columnDef.pluralTitle}`;\n }\n case 'radio':\n case 'static': {\n const value = typeof condition.value === 'string' ? condition.value : '';\n if (!value) return 'Any';\n return columnDef.options?.find(opt => opt.value === value)?.label ?? value;\n }\n case 'text':\n return typeof condition.value === 'string' && condition.value ? condition.value : 'Any';\n case 'multiText': {\n const value = readMultiTextCelValue(condition.value);\n if (value.tokens.length === 0) return 'Any';\n if (value.tokens.length === 1) return value.tokens[0];\n return `${value.tokens.length} values`;\n }\n case 'date': {\n const value = readDateCelValue(condition.value);\n if (isRelativeDateCelValue(value)) return value.preset ? RELATIVE_PRESET_LABELS[value.preset] : 'Any';\n if (value.range)\n return `${formatInstantLabel(value.range.start, { locale })} – ${formatInstantLabel(value.range.end, { locale })}`;\n if (value.instant) return formatInstantLabel(value.instant, { withTime: value.hasTime, locale });\n return 'Any';\n }\n case 'map': {\n const value = readMapKeyCelValue(condition.value);\n if (!value.key) return 'Any';\n return value.value ? `${value.key}=${value.value}` : value.key;\n }\n default:\n return 'Any';\n }\n}\n\nfunction CelFilterPill({\n condition,\n columnDef,\n schema,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n schema: CelFilterBarProps['schema'];\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const shape = resolveFilterShape(condition, schema) ?? columnDef.filterType;\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted. Only\n // the 'date' shape's summary is locale-sensitive, but computed unconditionally\n // since hooks can't run after the early returns below.\n const locale = mounted ? undefined : 'en-US';\n\n // checkbox/radio always compose Combobox for their value editor (own trigger\n // + popup, per Monarch's standing directive for multi/single-select pickers)\n // rather than sharing the generic Popover the other shapes use below.\n if (shape === 'checkbox') {\n return (\n <CelCheckboxComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={container}\n />\n );\n }\n if (shape === 'radio') {\n return (\n <CelRadioComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={container}\n />\n );\n }\n\n function updateValue(value: CelFilterCondition['value']) {\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value })));\n }\n\n function updateOperator(operator: CelOperator) {\n const hadValue = condition.value !== undefined;\n const next = applyOperatorChange(condition, operator, shape);\n onChange(replaceCondition(tree, condition.id, () => next));\n // Switching operators can clear an incompatible value (e.g. an instant when\n // moving to a range operator) — reopen the value popover so the user isn't\n // left with a silently invalid pill they have to notice and click back into.\n if (hadValue && next.value === undefined) controller.beginEditing();\n }\n\n const allowedOperators = getAllowedOperators(columnDef);\n\n return (\n <Popover\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {shape === 'multiText' && (\n <CelQuantifierSegment\n columnTitle={columnDef.title}\n value={readMultiTextCelValue(condition.value)}\n onChangeValue={updateValue}\n />\n )}\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef, locale)}\n </span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <PopoverContent align=\"start\" className={shape === 'date' ? 'w-fit' : 'w-72'}>\n {shape === 'text' && (\n <CelTextValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n {shape === 'multiText' && <CelMultiTextValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'date' && <CelDateValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'map' && (\n <CelKeyValueValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n// ── Operator segment ───────────────────────────────────\n// Shared between the Popover-based pill (text/multiText/date/map) and the\n// two Combobox-based pills below — always its own ButtonGroup segment,\n// never hidden inside the value editor.\n\nfunction CelOperatorSegment({\n columnTitle,\n operator,\n allowedOperators,\n hideOnSingleOperator,\n onChangeOperator,\n}: {\n columnTitle: string;\n operator: CelOperator;\n allowedOperators: CelOperator[];\n hideOnSingleOperator?: boolean;\n onChangeOperator: (operator: CelOperator) => void;\n}) {\n if (allowedOperators.length > 1) {\n return (\n <Select value={operator} onValueChange={value => onChangeOperator(value as CelOperator)}>\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} operator`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n {allowedOperators.map(op => (\n <SelectItem key={op} value={op}>\n {getOperatorLabel(op)}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n }\n if (allowedOperators.length === 1 && !hideOnSingleOperator) {\n return (\n <ButtonGroupText className=\"text-muted-foreground font-normal\">\n {getOperatorLabel(allowedOperators[0])}\n </ButtonGroupText>\n );\n }\n return null;\n}\n\n// ── Quantifier segment ─────────────────────────────────\n// multiText-only: \"any of\" / \"all of\" across a condition's tokens. Its own\n// plain Select segment appended right after the operator — not a switcher\n// living inside the value popover — with no search (only two options).\n// Hidden until there's more than one token, since quantifier is meaningless\n// (and unvalidated) for zero or one.\n\nfunction CelQuantifierSegment({\n columnTitle,\n value,\n onChangeValue,\n}: {\n columnTitle: string;\n value: MultiTextCelValue;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n if (value.tokens.length <= 1) return null;\n\n return (\n <Select\n value={value.quantifier ?? 'any'}\n onValueChange={next => {\n if (next === 'any' || next === 'all') onChangeValue({ ...value, quantifier: next });\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} quantifier`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n <SelectItem value=\"any\">{getQuantifierLabel('any')}</SelectItem>\n <SelectItem value=\"all\">{getQuantifierLabel('all')}</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n}\n\n// ── Checkbox pill (Combobox, multi-select) ────────────\n// Same Combobox composition as FilterChip's searchable branch in\n// filter-bar.tsx — Monarch's standing pattern for multi-select pickers.\n// A restricted (disabled) option is never blocked at the primitive level\n// (Base UI's own `disabled` would silently swallow the click, same failure\n// mode Radix's Checkbox has); instead every selection change is diffed\n// against the previous value and a newly-picked disabled option is reverted\n// and redirected to `onRestrictedOptionSelect`.\n\nfunction CelCheckboxComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const options = columnDef.options ?? [];\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n const selected = options.filter(option => value.includes(option.value));\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'checkbox')));\n }\n\n function applySelection(nextSelected: CelColumnOption[]) {\n const current = new Set(value);\n const nextValues = new Set(nextSelected.map(option => option.value));\n for (const option of nextSelected) {\n if (!current.has(option.value) && option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n nextValues.delete(option.value);\n }\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: Array.from(nextValues) })));\n const added = nextSelected.find(option => !current.has(option.value) && !option.disabled && option.operator);\n if (added?.operator) updateOperator(added.operator);\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n multiple\n value={selected}\n onValueChange={(next: CelColumnOption[]) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent container={container} className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n {selected.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(items: CelColumnOption[]) => (\n <>\n {items.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => applySelection([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Radio pill (Combobox, single-select) ──────────────\n// Same primitive as the checkbox pill above, constrained to one selection by\n// omitting `multiple` — no chip strip (nothing to show but the one value,\n// already in the trigger), and a valid pick auto-commits (closes) like the\n// legacy RadioGroup did.\n\nfunction CelRadioComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const options = columnDef.options ?? [];\n const value = typeof condition.value === 'string' ? condition.value : '';\n const selected = options.find(option => option.value === value) ?? null;\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'radio')));\n }\n\n function applySelection(option: CelColumnOption | null) {\n if (!option) return;\n if (option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n return;\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: option.value })));\n if (option.operator) updateOperator(option.operator);\n controller.commit();\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n value={selected}\n onValueChange={(next: CelColumnOption | null) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent container={container} className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Text value editor ─────────────────────────────────\n\nfunction CelTextValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: string) => void;\n onCommit: () => void;\n}) {\n const value = typeof condition.value === 'string' ? condition.value : '';\n\n return (\n <Input\n autoFocus\n value={value}\n placeholder=\"Enter a value…\"\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n );\n}\n\n// ── MultiText value editor ────────────────────────────\n\nfunction CelMultiTextValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n const value = readMultiTextCelValue(condition.value);\n const [draft, setDraft] = React.useState('');\n\n function addToken() {\n const token = draft.trim();\n if (!token || value.tokens.includes(token)) {\n setDraft('');\n return;\n }\n const nextTokens = [...value.tokens, token];\n // Write an explicit quantifier the moment it first becomes relevant\n // (2nd token). CelQuantifierSegment's Select displays `quantifier ?? 'any'`\n // as its value, so if the user's first pick were \"any of\" — the same as\n // that visual default — Radix would see no change and never fire\n // onValueChange, leaving quantifier stuck undefined and the\n // missing_quantifier issue stuck showing despite the pill saying \"any of\".\n const quantifier = nextTokens.length > 1 ? (value.quantifier ?? 'any') : value.quantifier;\n onChangeValue({ ...value, tokens: nextTokens, quantifier });\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue({ ...value, tokens: value.tokens.filter(t => t !== token) });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {value.tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {value.tokens.map(token => (\n <Badge key={token} variant=\"secondary\" className=\"gap-1\">\n {token}\n <button\n type=\"button\"\n aria-label={`Remove ${token}`}\n onClick={() => removeToken(token)}\n className=\"cursor-pointer\"\n >\n <Icon name=\"xmark\" size=\"xs\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n <Input\n autoFocus\n value={draft}\n placeholder=\"Type a value, press Enter…\"\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n addToken();\n } else if (e.key === 'Backspace' && draft === '' && value.tokens.length > 0) {\n removeToken(value.tokens[value.tokens.length - 1]);\n }\n }}\n />\n </div>\n );\n}\n\n// ── KeyValue value editor ─────────────────────────────\n\nfunction CelKeyValueValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MapKeyCelValue) => void;\n onCommit: () => void;\n}) {\n const value = readMapKeyCelValue(condition.value);\n const needsValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n\n return (\n <div className=\"flex flex-col gap-2\">\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Key</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n autoFocus\n value={value.key}\n onChange={e => onChangeValue({ ...value, key: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter' && !needsValue) onCommit();\n }}\n />\n </InputGroup>\n {needsValue && (\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Value</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n value={value.value ?? ''}\n onChange={e => onChangeValue({ ...value, value: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n </InputGroup>\n )}\n </div>\n );\n}\n\n// ── Date value editor ──────────────────────────────────\n\nfunction CelDateValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: DateCelValue) => void;\n}) {\n const value = readDateCelValue(condition.value);\n const operator = condition.operator;\n const relativeCapable = isDateRelativeOperator(operator);\n const isRange = isDateRangeOperator(operator);\n const showTime = !isDateWindowOperator(operator) && !isRange;\n const isRelative = isRelativeDateCelValue(value);\n\n function pickInstant(date: Date | undefined) {\n if (!date) return;\n const boundary = dateBoundaryForOperator(operator);\n const instant = formatCalendarDateUtc(date, showTime ? boundary : 'start');\n onChangeValue({ instant });\n }\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) return;\n const start = calendarDayStartInstant(formatCalendarDateUtc(range.from, 'start'));\n const end = range.to ? formatCalendarDateUtc(range.to, 'end') : formatCalendarDateUtc(range.from, 'end');\n onChangeValue({ range: { start, end } });\n }\n\n function pickTime(timeOfDay: string) {\n if (!value.instant) return;\n onChangeValue({ instant: withTimeOfDay(value.instant, timeOfDay), hasTime: true });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {/* No wrapping border here — PopoverContent already supplies the pill's\n single outer border/ring. A second border on this row would double\n up against it. `border-r` on the sidebar alone gives the divider. */}\n <div className=\"flex\">\n {relativeCapable && (\n <div className=\"flex flex-col gap-1 border-r pr-2\">\n <p className=\"text-body-sm text-muted-foreground px-2 font-medium\">Quick select</p>\n {RELATIVE_DURATION_PRESET_VALUES.map(preset => (\n <Button\n key={preset}\n type=\"button\"\n variant={isRelative && value.preset === preset ? 'secondary' : 'ghost'}\n size=\"sm\"\n className=\"justify-start\"\n onClick={() => onChangeValue({ preset })}\n >\n {RELATIVE_PRESET_LABELS[preset]}\n </Button>\n ))}\n </div>\n )}\n {isRange ? (\n <Calendar\n mode=\"range\"\n selected={\n value.range\n ? { from: parseCalendarDate(value.range.start), to: parseCalendarDate(value.range.end) }\n : undefined\n }\n onSelect={pickRange}\n />\n ) : (\n <Calendar\n mode=\"single\"\n selected={isRelative ? undefined : parseCalendarDate(value.instant)}\n onSelect={pickInstant}\n />\n )}\n </div>\n {showTime && !isRelative && (\n <div className=\"flex w-full items-center gap-2\">\n <Label htmlFor=\"cel-date-time\" className=\"text-body-sm text-muted-foreground shrink-0\">\n Time (UTC)\n </Label>\n <Input\n id=\"cel-date-time\"\n type=\"time\"\n className=\"w-full\"\n value={readTimeOfDay(value.instant)}\n onChange={e => pickTime(e.target.value)}\n disabled={!value.instant}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport { CelFilterBar };\n","import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [\n {\n text: [\n 'display-hero',\n 'display-kpi-sm',\n 'display-kpi',\n 'display-kpi-lg',\n 'display-feature',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'body-lg',\n 'body',\n 'body-sm',\n 'caption',\n 'eyebrow',\n ],\n },\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { useSyncExternalStore } from 'react';\n\nfunction subscribe() {\n return () => {};\n}\n\n/**\n * Returns `false` on the server and during initial client hydration, then\n * `true` once mounted — for values that are only valid client-side (e.g. the\n * viewer's actual `Intl` locale, vs. a fixed locale used for the server-\n * rendered/first-paint value) without a hydration mismatch. Implemented via\n * `useSyncExternalStore` rather than `useEffect` + `setState` — the latter\n * works, but re-derives the same \"true\" value on every mount and trips\n * `react-hooks/set-state-in-effect` since there's no actual subscription.\n */\nexport function useMounted() {\n return useSyncExternalStore(\n subscribe,\n () => true,\n () => false,\n );\n}\n","import { useCallback, useRef, useState } from 'react';\n\nimport { ADD_FILTER_POPOVER_SUPPRESS_MS } from '@/lib/cel-filter/constants';\nimport type { PillActiveSurface } from '@/lib/cel-filter/types';\n\nexport type CelConditionEditorController = {\n isDraft: boolean;\n activeSurface: PillActiveSurface | null;\n popoverVisible: boolean;\n isDismissSuppressed: () => boolean;\n\n beginEditing: () => void;\n openSurface: (surface: PillActiveSurface) => void;\n closeSurface: () => void;\n commit: () => void;\n handlePopoverDismiss: () => void;\n toggleSurface: (surface: PillActiveSurface) => void;\n};\n\nexport type UseCelFilterEditorStateResult = {\n editingConditionId: string | null;\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n getController: (conditionId: string) => CelConditionEditorController;\n beginEditing: (id: string, surface?: PillActiveSurface) => void;\n suppressDismissFor: (id: string, ms?: number) => void;\n removeCondition: (id: string) => void;\n clearSuppress: () => void;\n};\n\n/**\n * Single source of truth for CEL filter draft/commit, active pill segment,\n * and Radix dismiss-suppression (post-add guard + segment switches).\n */\nexport function useCelFilterEditorState(initialCommittedIds: string[] = []): UseCelFilterEditorStateResult {\n const [editingConditionId, setEditingConditionId] = useState<string | null>(null);\n const [committedConditionIds, setCommittedConditionIds] = useState<Set<string>>(() => new Set(initialCommittedIds));\n const [activeSurface, setActiveSurface] = useState<PillActiveSurface | null>(null);\n\n const suppressCloseUntilRef = useRef<{ id: string; until: number } | null>(null);\n const segmentSwitchRef = useRef(false);\n\n const isDismissSuppressed = useCallback((id: string) => {\n const entry = suppressCloseUntilRef.current;\n return entry !== null && entry.id === id && Date.now() < entry.until;\n }, []);\n\n const commitCondition = useCallback((id: string) => {\n setCommittedConditionIds(prev => {\n if (prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.add(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }, []);\n\n const beginEditing = useCallback((id: string, surface: PillActiveSurface = 'value') => {\n setEditingConditionId(id);\n setActiveSurface(surface);\n }, []);\n\n const openSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n if (editingConditionId !== id) {\n beginEditing(id, surface);\n return;\n }\n setActiveSurface(surface);\n },\n [beginEditing, editingConditionId],\n );\n\n const closeSurface = useCallback(\n (id: string) => {\n if (editingConditionId === id) {\n setActiveSurface(null);\n }\n },\n [editingConditionId],\n );\n\n const handlePopoverDismiss = useCallback(\n (id: string) => {\n if (segmentSwitchRef.current) {\n segmentSwitchRef.current = false;\n return;\n }\n if (isDismissSuppressed(id)) {\n return;\n }\n suppressCloseUntilRef.current = null;\n commitCondition(id);\n },\n [commitCondition, isDismissSuppressed],\n );\n\n const toggleSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n const isDraft = editingConditionId === id;\n const popoverVisible = isDraft && activeSurface !== null;\n\n if (isDraft && activeSurface === surface && popoverVisible) {\n closeSurface(id);\n return;\n }\n if (popoverVisible && activeSurface !== surface) {\n segmentSwitchRef.current = true;\n }\n openSurface(id, surface);\n },\n [activeSurface, closeSurface, editingConditionId, openSurface],\n );\n\n const suppressDismissFor = useCallback((id: string, ms = ADD_FILTER_POPOVER_SUPPRESS_MS) => {\n suppressCloseUntilRef.current = {\n id,\n until: Date.now() + ms,\n };\n }, []);\n\n const removeCondition = useCallback(\n (id: string) => {\n if (suppressCloseUntilRef.current?.id === id) {\n suppressCloseUntilRef.current = null;\n }\n setCommittedConditionIds(prev => {\n if (!prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n if (editingConditionId === id) {\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }\n },\n [editingConditionId],\n );\n\n const clearSuppress = useCallback(() => {\n suppressCloseUntilRef.current = null;\n }, []);\n\n const getController = useCallback(\n (conditionId: string): CelConditionEditorController => {\n const isDraft = editingConditionId === conditionId;\n const surface = isDraft ? activeSurface : null;\n\n return {\n isDraft,\n activeSurface: surface,\n popoverVisible: isDraft && activeSurface !== null,\n isDismissSuppressed: () => isDismissSuppressed(conditionId),\n beginEditing: () => beginEditing(conditionId),\n openSurface: s => openSurface(conditionId, s),\n closeSurface: () => closeSurface(conditionId),\n commit: () => {\n suppressCloseUntilRef.current = null;\n commitCondition(conditionId);\n },\n handlePopoverDismiss: () => handlePopoverDismiss(conditionId),\n toggleSurface: s => toggleSurface(conditionId, s),\n };\n },\n [\n activeSurface,\n beginEditing,\n closeSurface,\n commitCondition,\n editingConditionId,\n handlePopoverDismiss,\n isDismissSuppressed,\n openSurface,\n toggleSurface,\n ],\n );\n\n return {\n editingConditionId,\n activeSurface,\n committedConditionIds,\n getController,\n beginEditing,\n suppressDismissFor,\n removeCondition,\n clearSuppress,\n };\n}\n","/**\n * Shared limits and defaults for the CEL filter builder. Values mirror the API\n * constraints (`maxNestingDepth = 50`, `maxRegexLen = 1000`).\n */\nimport type { RelativeDurationPreset } from './types';\n\n/**\n * Trusted relative date presets emitted as fixed `duration(...)` literals in\n * compiled CEL. Hours only — `duration()` rejects a `d` unit.\n */\nexport const RELATIVE_DURATION_PRESET_VALUES = [\n '24h',\n '168h',\n '720h',\n] as const satisfies readonly RelativeDurationPreset[];\n\nexport const RELATIVE_DURATION_PRESETS = new Set<string>(RELATIVE_DURATION_PRESET_VALUES);\n\nexport function isRelativeDurationPreset(value: string): value is RelativeDurationPreset {\n return RELATIVE_DURATION_PRESETS.has(value);\n}\n\n/** API recursion depth limit for nested parentheses. v1 UI is flat; the compiler enforces this defensively. */\nexport const MAX_NESTING_DEPTH = 50;\n\n/** Maximum length of a `matches` regex pattern accepted by the API. */\nexport const MAX_REGEX_LEN = 1000;\n\n/** Debounce for inline free-text (regex) validation inside an open popover. */\nexport const CEL_VALIDATION_DEBOUNCE_MS = 300;\n\n/** Default quantifier when a multiText condition has more than one token. */\nexport const DEFAULT_MULTI_TEXT_QUANTIFIER = 'any' as const;\n\n/**\n * After adding a filter from the dropdown, ignore outside-dismiss on the new\n * pill popover for this long. Covers the menu closing plus immediate pointer\n * movement that Radix treats as an outside interaction.\n */\nexport const ADD_FILTER_POPOVER_SUPPRESS_MS = 500;\n\n/** Keys handled by searchable CEL dropdown listboxes; others stop propagation from the search input. */\nexport const CEL_DROPDOWN_NAV_KEYS = [\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n 'Enter',\n 'Escape',\n 'Tab',\n] as const;\n","/**\n * Instant helpers for the CEL date filter.\n *\n * Stored values are RFC3339 UTC strings, and everything here manipulates them as\n * text rather than through `Date`, so a filter can never drift into the viewer's\n * local timezone. Tables render timestamps in UTC, so a UTC filter is what\n * agrees with the times shown in the table.\n */\n\n/** Which end of a day/minute an instant represents. */\nexport type DateBoundary = 'start' | 'end';\n\n/** How much of the instant the user has committed to: a calendar day, or a wall-clock minute. */\nexport type DateInstantGranularity = 'day' | 'minute';\n\n/** Time an `input[type=\"time\"]` shows for a boundary the user has not edited. */\nexport const BOUNDARY_TIME_OF_DAY: Record<DateBoundary, string> = {\n start: '00:00',\n end: '23:59',\n};\n\nconst CALENDAR_DAY_PATTERN = /^(\\d{4}-\\d{2}-\\d{2})/;\nconst MINUTE_PATTERN = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})/;\nconst TIME_OF_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2})/;\n\nexport function calendarDayStartInstant(instant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T00:00:00.000Z` : instant;\n}\n\n/**\n * Derives the inclusive upper bound of a stored instant. An upper bound covers\n * the whole unit the user selected: a day runs through 23:59:59.999, a minute\n * through :59.999 — the same rule, one unit finer.\n */\nexport function inclusiveEndInstant(instant: string, granularity: DateInstantGranularity): string {\n if (granularity === 'minute') {\n const minuteMatch = MINUTE_PATTERN.exec(instant);\n return minuteMatch ? `${minuteMatch[1]}:59.999Z` : instant;\n }\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T23:59:59.999Z` : instant;\n}\n\n/** Derives inclusive end-of-day RFC3339 from a stored start instant. */\nexport function calendarDayEndInstant(startInstant: string): string {\n return inclusiveEndInstant(startInstant, 'day');\n}\n\nexport function startInstantFromEndOfDay(endInstant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(endInstant);\n return match ? `${match[1]}T00:00:00Z` : endInstant;\n}\n\n/** Strips the `:59.999` an inclusive minute bound was expanded with. */\nexport function startInstantFromEndOfMinute(endInstant: string): string {\n const match = MINUTE_PATTERN.exec(endInstant);\n return match ? `${match[1]}:00.000Z` : endInstant;\n}\n\nexport function isEndOfDayTimestamp(instant: string): boolean {\n return /T23:59:59(\\.\\d+)?Z$/.test(instant);\n}\n\nexport function isStartOfDayTimestamp(instant: string): boolean {\n return /T00:00:00(\\.0+)?Z$/.test(instant);\n}\n\n/**\n * True for an instant expanded to the end of its minute. End-of-day is also\n * end-of-minute, so callers that distinguish the two must test for day first.\n */\nexport function isEndOfMinuteTimestamp(instant: string): boolean {\n return /T\\d{2}:\\d{2}:59(\\.\\d+)?Z$/.test(instant);\n}\n\n/**\n * True when the date portion names a day that exists. `Date` rolls impossible\n * days over silently — Feb 31 becomes Mar 3 rather than failing — so a\n * round-trip through UTC is what separates a real day from a rolled-over one.\n */\nexport function isRealCalendarDay(instant: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(instant);\n if (!match) {\n return false;\n }\n const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n}\n\n/** Reads the `HH:mm` an `input[type=\"time\"]` displays for a stored instant. */\nexport function readTimeOfDay(instant: string | undefined): string {\n if (!instant) {\n return '';\n }\n const match = TIME_OF_DAY_PATTERN.exec(instant);\n return match ? match[1] : '';\n}\n\n/** Replaces the time portion of an instant. Seconds are zeroed — the input is minute-granular. */\nexport function withTimeOfDay(instant: string, timeOfDay: string): string {\n const day = CALENDAR_DAY_PATTERN.exec(instant);\n const time = /^(\\d{2}):(\\d{2})/.exec(timeOfDay);\n if (!day || !time) {\n return instant;\n }\n return `${day[1]}T${time[1]}:${time[2]}:00.000Z`;\n}\n\n/**\n * Stamps a picked calendar day as a UTC instant. The picker hands back a local\n * `Date` whose Y/M/D is the day that was clicked; that day is stored as the\n * matching UTC day so the filter lines up with the UTC timestamps in the table.\n */\nexport function formatCalendarDateUtc(date: Date, boundary: DateBoundary): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const time = boundary === 'end' ? 'T23:59:59.999Z' : 'T00:00:00.000Z';\n return `${year}-${month}-${day}${time}`;\n}\n\n/** Parses a stored RFC3339 string back into a local Date carrying the calendar day. */\nexport function parseCalendarDate(value: string | undefined): Date | undefined {\n if (!value) {\n return undefined;\n }\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value);\n if (!match) {\n return undefined;\n }\n return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));\n}\n\n/**\n * Locale date for display, plus the UTC time when the instant carries a\n * user-picked one. `locale` defaults to the runtime's own locale (matching\n * plain `toLocaleDateString()`) — callers rendered during SSR should pass a\n * fixed locale explicitly (see `cel-filter-bar.tsx`'s `useMounted()` gating)\n * so the server-rendered/first-paint value doesn't hydration-mismatch against\n * the viewer's actual browser locale.\n */\nexport function formatInstantLabel(\n instant: string | undefined,\n { withTime = false, locale }: { withTime?: boolean; locale?: string } = {},\n): string {\n const date = parseCalendarDate(instant);\n if (!date) {\n return '';\n }\n const dateLabel = date.toLocaleDateString(locale);\n const timeOfDay = withTime ? readTimeOfDay(instant) : '';\n return timeOfDay ? `${dateLabel} ${timeOfDay} UTC` : dateLabel;\n}\n","/** Stable operator ids used in code and tests. UI labels come from `getOperatorLabel`. */\nexport type CelOperator =\n | 'is'\n | 'is_not'\n | 'contains'\n | 'does_not_contain'\n | 'starts_with'\n | 'ends_with'\n | 'matches'\n | 'is_before'\n | 'is_after'\n | 'is_on_or_before'\n | 'is_on_or_after'\n | 'is_between'\n | 'is_not_between'\n | 'key_exists'\n | 'key_does_not_exist'\n | 'has_value'\n | 'does_not_have_value';\n\nexport type CelFilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date' | 'keyValue' | 'static';\n\n/** When a valid compiled expression may be emitted to consumers (API, URL, etc.). */\nexport type CelEmitOn = 'change' | 'commit';\n\n/**\n * Resolved shape used by the compiler / dispatcher to pick a value variant and\n * operator set. Columns map to their `filterType`; map fields resolve to `map`.\n */\nexport type CelFilterShape = CelFilterType | 'map';\n\nexport type CelColumnOption = {\n /** Human-readable text shown in the UI and collapsed pill display. Never compiled into CEL. */\n label: string;\n /** Canonical CEL literal stored on the condition and emitted in compiled CEL. */\n value: string;\n /** When set, selecting this option also sets the condition operator (e.g. `'is_not'` for a negated choice). */\n operator?: CelOperator;\n /** When true, the option cannot be toggled; hosts may handle the click via `onRestrictedOptionSelect`. */\n disabled?: boolean;\n};\n\n/** Payload for clicks on disabled checkbox/radio options. */\nexport type CelRestrictedOptionSelectPayload = {\n columnId: string;\n value: string;\n label: string;\n};\n\nexport type CelColumnDefinition = {\n /** Must match the API column id when targeting server-side resources. */\n id: string;\n /** Display name in the add-filter menu. */\n title: string;\n /**\n * Section heading this column is listed under in the add-filter menu. Sections appear in the\n * order each group name first occurs in `columns`; columns without a group are listed last\n * under no heading. Omit on every column to get a single flat alphabetical list.\n *\n * Group names are searchable: a phrase matching one keeps that entire section, on top of any\n * columns matched by title.\n */\n group?: string;\n /** Lowercase natural plural for consolidated multi-value pill copy (e.g. \"2 control planes\"). */\n pluralTitle: string;\n filterType: CelFilterType;\n /** Enum columns (checkbox / radio); static options only in v1. */\n options?: CelColumnOption[];\n /** Optional override; defaults from `filterType`. */\n allowedOperators?: CelOperator[];\n /** When true, hides the operator UI when only one operator is allowed. Defaults to `false`. */\n hideOnSingleOperator?: boolean;\n /** Pre-fill value when the condition is first added. Skips the initial \"pick a value\" step. */\n defaultValue?: CelConditionValue;\n /** When a valid compiled expression may be emitted. Defaults by `filterType`. */\n emitOn?: CelEmitOn;\n};\n\n/** Host-provided schema describing which columns are filterable for a given filter bar. */\nexport type CelFilterSchema = {\n columns: CelColumnDefinition[];\n};\n\n// --- Value shapes -----------------------------------------------------------\n\nexport type CheckboxCelValue = string[];\n\nexport type RadioCelValue = string;\n\nexport type TextCelValue = string;\n\nexport type MultiTextCelValue = {\n tokens: string[];\n /** Required when `tokens.length > 1`; defaults to `any` in the UI when omitted. */\n quantifier?: 'any' | 'all';\n};\n\n/** Trusted preset durations emitted as fixed literals in compiled CEL. */\nexport type RelativeDurationPreset = '24h' | '168h' | '720h';\n\nexport type DateCelValue = {\n /** RFC3339 UTC; required for single-point comparators. Mutually exclusive with `preset`. */\n instant?: string;\n /** Required for the range operators (`is_between` / `is_not_between`). Mutually exclusive with `preset`. */\n range?: {\n start: string;\n end: string;\n };\n /** Relative duration preset; mutually exclusive with `instant` / `range`. */\n preset?: RelativeDurationPreset;\n /**\n * True once the user edits a boundary time. While false the operator's default\n * day boundary applies, so an untouched condition compiles exactly as it did\n * before times were selectable. Never set without `instant` / `range` — the\n * `isDateCelValue` guard keys off those fields. Never compiled into CEL; a\n * future parser would need to re-derive it from the instants in the expression.\n */\n hasTime?: boolean;\n};\n\nexport type MapKeyCelValue = {\n key: string;\n /** Required when operator is `has_value` / `does_not_have_value`. */\n value?: string;\n};\n\n/**\n * Union of all condition value shapes. The active variant is determined by the\n * condition's `columnId` + schema `filterType`, not a discriminant on the value.\n */\nexport type CelConditionValue =\n CheckboxCelValue | RadioCelValue | TextCelValue | MultiTextCelValue | DateCelValue | MapKeyCelValue;\n\n// --- Tree nodes -------------------------------------------------------------\n\n/**\n * v1 always `and`; the shape is forward-compatible with `or` and nesting.\n * See `CelFilterGroup.children`, kept recursive so a future nested/OR-group UI\n * is additive rather than a breaking type change.\n */\nexport type CelCombinator = 'and';\n\nexport type CelFilterGroup = {\n id: string;\n type: 'group';\n combinator: CelCombinator;\n /** Root group is `0`. */\n depth: number;\n children: CelFilterNode[];\n};\n\nexport type CelFilterCondition = {\n id: string;\n type: 'condition';\n columnId: string;\n operator: CelOperator;\n /** Undefined on a newly added row until the user edits. */\n value?: CelConditionValue;\n};\n\nexport type CelFilterNode = CelFilterGroup | CelFilterCondition;\n\nexport type CelFilterTree = {\n root: CelFilterGroup;\n};\n\n// --- Validation -------------------------------------------------------------\n\n/** Closed union — `validateCondition` and `compileCelFilterTree` emit only these codes. */\nexport type ValidationIssueCode =\n // incomplete\n | 'missing_column'\n | 'missing_value'\n | 'missing_key'\n | 'missing_tokens'\n | 'missing_quantifier'\n | 'missing_instant'\n | 'missing_range'\n | 'missing_duration'\n // invalid\n | 'unknown_column'\n | 'illegal_operator'\n | 'invalid_date_mode'\n | 'regex_too_long'\n | 'invalid_timestamp'\n | 'invalid_date_range'\n | 'nesting_depth_exceeded';\n\nexport type ValidationSeverity = 'incomplete' | 'invalid';\n\nexport type ValidationIssue = {\n code: ValidationIssueCode;\n message: string;\n severity: ValidationSeverity;\n nodeId: string;\n nodeType: 'condition' | 'group';\n /** Sub-target within the condition (e.g. `value`, `key`, `instant`). */\n field?: string;\n};\n\nexport type CompileStatus = 'valid' | 'incomplete' | 'invalid';\n\nexport type CompileResult = {\n status: CompileStatus;\n /** Present when `status === 'valid'` (may be `\"\"`). */\n expression?: string;\n issues: ValidationIssue[];\n /** True iff the raw compile status is `valid`; the API / parent emission gate. */\n isEmitReady: boolean;\n};\n\n// --- Validation meta (draft / commit tracking) ------------------------------\n\nexport type CelValidationMeta = {\n editingConditionId: string | null;\n committedConditionIds: Set<string>;\n};\n\n/** Which pill sub-surface is open: operator picker, multiText quantifier, or the value editor. */\nexport type PillActiveSurface = 'operator' | 'quantifier' | 'value';\n\n// --- Public builder API -----------------------------------------------------\n\nexport type CelFilterBarProps = {\n tree: CelFilterTree;\n onChange: (tree: CelFilterTree) => void;\n schema: CelFilterSchema;\n onCompileResultChange?: (result: CompileResult) => void;\n /** Invoked when the user clicks a disabled option (instead of toggling the filter value). */\n onRestrictedOptionSelect?: (payload: CelRestrictedOptionSelectPayload) => void;\n /** Default `false`. */\n showClearButton?: boolean;\n className?: string;\n};\n\n// --- Type guards ------------------------------------------------------------\n\nexport const isCelFilterGroup = (node: CelFilterNode): node is CelFilterGroup => node.type === 'group';\n\nexport const isCelFilterCondition = (node: CelFilterNode): node is CelFilterCondition => node.type === 'condition';\n\n/** Checkbox values are arrays of option value strings. */\nexport const isCheckboxCelValue = (value: unknown): value is CheckboxCelValue =>\n Array.isArray(value) && value.every(item => typeof item === 'string');\n\n/** Radio / text values are bare strings. */\nexport const isStringCelValue = (value: unknown): value is string => typeof value === 'string';\n\nexport const isMultiTextCelValue = (value: unknown): value is MultiTextCelValue =>\n typeof value === 'object' && value !== null && 'tokens' in value;\n\nexport const isDateCelValue = (value: unknown): value is DateCelValue => {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n if ('tokens' in value || 'key' in value) {\n return false;\n }\n return 'preset' in value || 'instant' in value || 'range' in value || Object.keys(value).length === 0;\n};\n\nexport const isMapKeyCelValue = (value: unknown): value is MapKeyCelValue =>\n typeof value === 'object' && value !== null && 'key' in value;\n","import {\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from './types';\n\n/** Relative when a preset is set; preset and absolute fields are mutually exclusive. */\nexport function isRelativeDateCelValue(value: DateCelValue): boolean {\n return value.preset != null;\n}\n\nexport function readDateCelValue(value: unknown): DateCelValue {\n return isDateCelValue(value) ? value : {};\n}\n\nexport function readMapKeyCelValue(value: unknown): MapKeyCelValue {\n return isMapKeyCelValue(value) ? value : { key: '' };\n}\n\nexport function readMultiTextCelValue(value: unknown): MultiTextCelValue {\n return isMultiTextCelValue(value) ? value : { tokens: [] };\n}\n","/**\n * Escapes a user-provided string literal for safe embedding inside a CEL\n * double-quoted string. Callers wrap the result in `\"...\"` at the use site\n * (e.g. `column == \"${escapeCelString(value)}\"`).\n *\n * CEL generated output uses double-quoted strings only, so single quotes are\n * left untouched.\n */\nexport function escapeCelString(input: string): string {\n let out = '';\n\n for (const char of input) {\n switch (char) {\n case '\\\\':\n out += '\\\\\\\\';\n break;\n case '\"':\n out += '\\\\\"';\n break;\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n case '\\v':\n out += '\\\\v';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\0':\n out += '\\\\0';\n break;\n default:\n out += char;\n }\n }\n\n return out;\n}\n\n/** Convenience helper that escapes and wraps a value in double quotes. */\nexport function celStringLiteral(input: string): string {\n return `\"${escapeCelString(input)}\"`;\n}\n","/**\n * Operator metadata and CEL fragment generation.\n *\n * This is the single place that knows how `condition.operator` + value map to CEL\n * output. UI components never hand-write CEL — they read/write tree state and the\n * compiler walks it through here.\n */\nimport { type DateBoundary, inclusiveEndInstant } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterShape,\n type CelFilterType,\n type CelOperator,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { celStringLiteral } from './escape-cel-string';\n\n/** Schema column ids that collide with CEL reserved words (in the CEL library leveraged), mapped to safe CEL identifiers. */\nconst RESERVED_COLUMN_CEL_IDENTIFIERS: Record<string, string> = {\n namespace: '__namespace__',\n};\n\nconst CEL_IDENTIFIER_TO_COLUMN_ID = Object.fromEntries(\n Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).map(([columnId, celIdentifier]) => [celIdentifier, columnId]),\n);\n\nconst RESERVED_FIELD_OPERATOR_PATTERN = '(?=\\\\s*(?:in\\\\b|==|!=|<=|>=|<|>|\\\\.))';\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// --- Allowed operator sets --------------------------------------------------\n\nconst ENUM_OPERATORS: CelOperator[] = ['is', 'is_not'];\nconst TEXT_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'contains',\n 'does_not_contain',\n 'starts_with',\n 'ends_with',\n 'matches',\n];\nconst DATE_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'is_before',\n 'is_after',\n 'is_on_or_before',\n 'is_on_or_after',\n 'is_between',\n 'is_not_between',\n];\nconst MAP_OPERATORS: CelOperator[] = ['key_exists', 'key_does_not_exist', 'has_value', 'does_not_have_value'];\n\n/** Date comparators legal with a relative preset. */\nconst DATE_RELATIVE_OPERATORS: CelOperator[] = ['is_before', 'is_after', 'is_on_or_before', 'is_on_or_after'];\n\n/** Date operators that span a whole calendar day rather than compare against one instant. */\nconst DATE_WINDOW_OPERATORS: CelOperator[] = ['is', 'is_not'];\n\n/** Date operators that take a start/end range instead of a single instant. */\nconst DATE_RANGE_OPERATORS: CelOperator[] = ['is_between', 'is_not_between'];\n\n/**\n * Comparators whose bound sits at the end of the selected day/minute: \"on or\n * before Jul 23\" runs through 23:59:59.999, and \"after Jul 23\" starts once that\n * same instant has passed.\n */\nconst DATE_END_BOUNDARY_OPERATORS: CelOperator[] = ['is_on_or_before', 'is_after'];\n\nconst MAP_VALUE_OPERATORS: CelOperator[] = ['has_value', 'does_not_have_value'];\n\n/** Returns the operators allowed for a resolved filter shape. */\nexport function getAllowedOperatorsForShape(shape: CelFilterShape): CelOperator[] {\n switch (shape) {\n case 'checkbox':\n case 'radio':\n case 'static':\n return ENUM_OPERATORS;\n case 'text':\n case 'multiText':\n return TEXT_OPERATORS;\n case 'date':\n return DATE_OPERATORS;\n case 'map':\n return MAP_OPERATORS;\n default:\n return [];\n }\n}\n\n/**\n * Returns the operators allowed for a column. `allowedOperators` on a column\n * definition overrides the default set derived from its filter type.\n */\nexport function getAllowedOperators(columnDef?: CelColumnDefinition): CelOperator[] {\n if (!columnDef) {\n return [];\n }\n if (columnDef.allowedOperators) {\n return columnDef.allowedOperators;\n }\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n return getAllowedOperatorsForShape(shape);\n}\n\nexport function isDateRelativeOperator(operator: CelOperator): boolean {\n return DATE_RELATIVE_OPERATORS.includes(operator);\n}\n\n/** True for the date operators that match a whole calendar day and so take no time. */\nexport function isDateWindowOperator(operator: CelOperator): boolean {\n return DATE_WINDOW_OPERATORS.includes(operator);\n}\n\n/** True for the date operators whose value is a `range` rather than an `instant`. */\nexport function isDateRangeOperator(operator: CelOperator): boolean {\n return DATE_RANGE_OPERATORS.includes(operator);\n}\n\n/**\n * Which day boundary a date comparator compares against, and therefore the time\n * its input prefills with until the user edits it.\n */\nexport function dateBoundaryForOperator(operator: CelOperator): DateBoundary {\n return DATE_END_BOUNDARY_OPERATORS.includes(operator) ? 'end' : 'start';\n}\n\n// --- Schema resolution helpers ---------------------------------------------\n\nexport function resolveColumnDefinition(\n condition: Pick<CelFilterCondition, 'columnId'>,\n schema: CelFilterSchema,\n): CelColumnDefinition | undefined {\n if (!condition.columnId) {\n return undefined;\n }\n return schema.columns.find(column => column.id === condition.columnId);\n}\n\n/** Resolves the value/operator shape for a condition, or `undefined` for an unknown column. */\nexport function resolveFilterShape(\n condition: Pick<CelFilterCondition, 'columnId' | 'value'>,\n schema: CelFilterSchema,\n): CelFilterShape | undefined {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return undefined;\n }\n if (columnDef.filterType === 'keyValue') {\n return 'map';\n }\n if (columnDef.filterType === 'static') {\n return Array.isArray(condition.value) ? 'checkbox' : 'radio';\n }\n return columnDef.filterType;\n}\n\n// --- Operator labels --------------------------------------------------------\n\nconst OPERATOR_LABELS: Record<CelOperator, string> = {\n is: 'is',\n is_not: 'is not',\n contains: 'contains',\n does_not_contain: 'does not contain',\n starts_with: 'starts with',\n ends_with: 'ends with',\n matches: 'matches',\n is_before: 'is before',\n is_after: 'is after',\n is_on_or_before: 'is on or before',\n is_on_or_after: 'is on or after',\n is_between: 'is between',\n is_not_between: 'is not between',\n key_exists: 'key exists',\n key_does_not_exist: 'key does not exist',\n has_value: 'has value',\n does_not_have_value: 'does not have value',\n};\n\nexport function getOperatorLabel(operator: CelOperator): string {\n return OPERATOR_LABELS[operator];\n}\n\nexport function getQuantifierLabel(quantifier: 'any' | 'all'): string {\n return quantifier === 'all' ? 'all of' : 'any of';\n}\n\n// --- Multi-instance ---------------------------------------------------------\n\nconst SINGLE_INSTANCE_FILTER_TYPES: Set<CelFilterType> = new Set(['checkbox', 'radio', 'static']);\n\nexport function allowsMultipleConditions(filterType: CelFilterType): boolean {\n return !SINGLE_INSTANCE_FILTER_TYPES.has(filterType);\n}\n\n// --- Default operator on add -----------------------------------------------\n\nexport function getDefaultOperator(filterType: CelFilterType): CelOperator {\n switch (filterType) {\n case 'checkbox':\n case 'radio':\n case 'text':\n case 'static':\n return 'is';\n case 'multiText':\n return 'contains';\n case 'date':\n return 'is';\n case 'keyValue':\n return 'key_exists';\n default:\n return 'is';\n }\n}\n\n// --- Operator change value retention ----------------------------------------\n\n/**\n * Applies the minimal value-retention rules when the operator changes on an\n * existing condition. Returns a new condition; does not mutate the input.\n *\n * For dates, the clearing rules here are the enforcement half of the date state\n * machine the date editor implements: clear when the value shape changes (range\n * operators vs single-instant ones), or when a relative value would become\n * illegal under `is`/`is_not`, and drop a picked time when moving to a\n * whole-day operator. Keep both in sync.\n */\nexport function applyOperatorChange(\n condition: CelFilterCondition,\n newOperator: CelOperator,\n shape: CelFilterShape | undefined,\n): CelFilterCondition {\n const next: CelFilterCondition = { ...condition, operator: newOperator };\n const oldOperator = condition.operator;\n\n if (shape === 'date') {\n const value = condition.value;\n const isRelative = isDateCelValue(value) && isRelativeDateCelValue(value);\n // `is_between` ↔ `is_not_between` keep the range; swapping between a range\n // operator and a single-instant one cannot reuse the value.\n const changesValueShape = isDateRangeOperator(oldOperator) !== isDateRangeOperator(newOperator);\n const relativeNeedsClear = isRelative && (newOperator === 'is' || newOperator === 'is_not');\n\n if (changesValueShape || relativeNeedsClear) {\n next.value = undefined;\n return next;\n }\n if (isDateCelValue(value) && value.hasTime && isDateWindowOperator(newOperator)) {\n const { hasTime: _hasTime, ...dayOnly } = value;\n next.value = dayOnly;\n }\n return next;\n }\n\n if (shape === 'map') {\n const value = condition.value;\n if (!isMapKeyCelValue(value)) {\n return next;\n }\n const bothValueOps = MAP_VALUE_OPERATORS.includes(oldOperator) && MAP_VALUE_OPERATORS.includes(newOperator);\n next.value = bothValueOps ? { key: value.key, value: value.value } : { key: value.key };\n return next;\n }\n\n // checkbox / radio / text / multiText: every operator uses the same value shape.\n return next;\n}\n\n// --- CEL fragment generation ------------------------------------------------\n\nexport type ConditionExpression = {\n /** Raw CEL fragment without any outer grouping parentheses. */\n expression: string;\n /** True when the fragment has a bare top-level `||` and must be parenthesized to join under `&&`. */\n needsGrouping: boolean;\n};\n\nconst atomic = (expression: string): ConditionExpression => ({ expression, needsGrouping: false });\n\n/**\n * Builds the CEL fragment for a single condition. Assumes the condition has\n * already passed validation; callers must not pass incomplete/invalid conditions.\n */\nexport function buildConditionExpression(\n condition: CelFilterCondition,\n shape: CelFilterShape,\n columnDef?: CelColumnDefinition,\n): ConditionExpression {\n if (shape === 'map') {\n return buildMapExpression(condition.columnId, condition.operator, condition.value as MapKeyCelValue);\n }\n\n const columnId = columnDef?.id ?? condition.columnId ?? '';\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n\n switch (shape) {\n case 'checkbox':\n return buildCheckboxExpression(column, condition.operator, (condition.value as string[]) ?? []);\n case 'radio':\n return buildRadioExpression(column, condition.operator, String(condition.value ?? ''));\n case 'text':\n return atomic(buildTextTokenFragment(column, condition.operator, String(condition.value ?? '')));\n case 'multiText':\n return buildMultiTextExpression(column, condition.operator, condition.value as MultiTextCelValue);\n case 'date':\n return atomic(buildDateExpression(column, condition.operator, condition.value as DateCelValue));\n default:\n return atomic('');\n }\n}\n\nfunction buildCheckboxExpression(column: string, operator: CelOperator, values: string[]): ConditionExpression {\n const list = `${column} in [${values.map(celStringLiteral).join(', ')}]`;\n return atomic(operator === 'is_not' ? `!(${list})` : list);\n}\n\nfunction buildRadioExpression(column: string, operator: CelOperator, value: string): ConditionExpression {\n const literal = celStringLiteral(value);\n return atomic(operator === 'is_not' ? `${column} != ${literal}` : `${column} == ${literal}`);\n}\n\n/**\n * Builds the CEL fragment for a single text token. Single source of truth for\n * the text operator → CEL template mapping.\n *\n * `forcePositive` controls how the two negated operators (`is_not`,\n * `does_not_contain`) render:\n * - `false` (default): native negation (`col != \"x\"`, `!col.contains(\"x\")`).\n * Used for a lone token, where the negation lives on the token itself.\n * - `true`: the positive form (`col == \"x\"`, `col.contains(\"x\")`). Used when\n * composing multiple tokens, where the caller wraps the whole joined\n * expression in a single `!( … )` instead (see `buildMultiTextExpression`).\n */\nfunction buildTextTokenFragment(column: string, operator: CelOperator, value: string, forcePositive = false): string {\n const literal = celStringLiteral(value);\n switch (operator) {\n case 'is':\n return `${column} == ${literal}`;\n case 'is_not':\n return forcePositive ? `${column} == ${literal}` : `${column} != ${literal}`;\n case 'contains':\n return `${column}.contains(${literal})`;\n case 'does_not_contain':\n return forcePositive ? `${column}.contains(${literal})` : `!${column}.contains(${literal})`;\n case 'starts_with':\n return `${column}.startsWith(${literal})`;\n case 'ends_with':\n return `${column}.endsWith(${literal})`;\n case 'matches':\n return `${column}.matches(${literal})`;\n default:\n return '';\n }\n}\n\nfunction isNegatedTextOperator(operator: CelOperator): boolean {\n return operator === 'is_not' || operator === 'does_not_contain';\n}\n\nfunction buildMultiTextExpression(\n column: string,\n operator: CelOperator,\n value: MultiTextCelValue,\n): ConditionExpression {\n const tokens = value.tokens;\n\n if (tokens.length === 1) {\n return atomic(buildTextTokenFragment(column, operator, tokens[0]));\n }\n\n const connective = value.quantifier === 'all' ? ' && ' : ' || ';\n const joined = tokens.map(token => buildTextTokenFragment(column, operator, token, true)).join(connective);\n\n if (isNegatedTextOperator(operator)) {\n return atomic(`!(${joined})`);\n }\n\n // A bare top-level `||` (any quantifier) must be parenthesized when joined under `&&`.\n return { expression: joined, needsGrouping: value.quantifier !== 'all' };\n}\n\nconst DATE_RELATIVE_COMPARATOR_SYMBOLS: Partial<Record<CelOperator, string>> = {\n is_before: '<',\n is_after: '>',\n is_on_or_before: '<=',\n is_on_or_after: '>=',\n};\n\nfunction buildCalendarDayRange(column: string, startInstant: string, endInstant: string): string {\n const start = `timestamp(${celStringLiteral(startInstant)})`;\n const end = `timestamp(${celStringLiteral(endInstant)})`;\n return `${column} >= ${start} && ${column} <= ${end}`;\n}\n\nfunction buildDateExpression(column: string, operator: CelOperator, value: DateCelValue): string {\n if (isRelativeDateCelValue(value)) {\n const durationStr = value.preset ?? '';\n if (!durationStr) {\n return '';\n }\n const relativeSymbol = DATE_RELATIVE_COMPARATOR_SYMBOLS[operator] ?? '>';\n return `${column} ${relativeSymbol} now() - duration(${celStringLiteral(durationStr)})`;\n }\n\n if (isDateRangeOperator(operator) && value.range) {\n const range = buildCalendarDayRange(column, value.range.start, value.range.end);\n return operator === 'is_not_between' ? `!(${range})` : range;\n }\n\n const startInstant = value.instant ?? '';\n // `is` / `is_not` span a whole calendar day whatever the instant carries; the\n // comparators bound the minute the user picked once they have picked one.\n const granularity = value.hasTime && !isDateWindowOperator(operator) ? 'minute' : 'day';\n const endInstant = inclusiveEndInstant(startInstant, granularity);\n const startTimestamp = `timestamp(${celStringLiteral(startInstant)})`;\n const endTimestamp = `timestamp(${celStringLiteral(endInstant)})`;\n\n switch (operator) {\n case 'is':\n return buildCalendarDayRange(column, startInstant, endInstant);\n case 'is_not':\n return `!(${buildCalendarDayRange(column, startInstant, endInstant)})`;\n case 'is_before':\n return `${column} < ${startTimestamp}`;\n case 'is_on_or_before':\n return `${column} <= ${endTimestamp}`;\n case 'is_after':\n return `${column} > ${endTimestamp}`;\n case 'is_on_or_after':\n return `${column} >= ${startTimestamp}`;\n default:\n return `${column} == ${startTimestamp}`;\n }\n}\n\nfunction buildMapExpression(columnId: string, operator: CelOperator, value: MapKeyCelValue): ConditionExpression {\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n const keyLiteral = celStringLiteral(value.key);\n\n switch (operator) {\n case 'key_exists':\n return atomic(`${keyLiteral} in ${column}`);\n case 'key_does_not_exist':\n return atomic(`!(${keyLiteral} in ${column})`);\n case 'has_value':\n return atomic(`${column}[${keyLiteral}] == ${celStringLiteral(value.value ?? '')}`);\n case 'does_not_have_value':\n return atomic(`${column}[${keyLiteral}] != ${celStringLiteral(value.value ?? '')}`);\n default:\n return atomic('');\n }\n}\n\n/** Maps parsed CEL aliases back to schema column ids when building the filter tree. */\nexport function denormalizeColumnIdWithReservedNames(columnId: string): string {\n return CEL_IDENTIFIER_TO_COLUMN_ID[columnId] ?? columnId;\n}\n\n/** Rewrites reserved schema column references in a CEL expression before parsing. */\nexport function normalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (normalized, [columnId, celIdentifier]) =>\n normalized.replace(\n new RegExp(`\\\\b${escapeRegExp(columnId)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n celIdentifier,\n ),\n expression,\n );\n}\n\n/** Rewrites CEL aliases back to schema column names for API requests and external consumers. */\nexport function denormalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (denormalized, [columnId, celIdentifier]) =>\n denormalized.replace(\n new RegExp(`\\\\b${escapeRegExp(celIdentifier)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n columnId,\n ),\n expression,\n );\n}\n","import { MAX_REGEX_LEN } from '../constants';\nimport { isRealCalendarDay } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CompileStatus,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type ValidationIssue,\n type ValidationIssueCode,\n type ValidationSeverity,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { getAllowedOperators, isDateRangeOperator, isDateRelativeOperator, resolveColumnDefinition } from './operators';\n\n/** Derives the overall compile status from a set of issues (invalid beats incomplete beats valid). */\nexport function statusFromIssues(issues: ValidationIssue[]): CompileStatus {\n if (issues.some(issue => issue.severity === 'invalid')) {\n return 'invalid';\n }\n if (issues.some(issue => issue.severity === 'incomplete')) {\n return 'incomplete';\n }\n return 'valid';\n}\n\nconst SEVERITY_BY_CODE: Record<ValidationIssueCode, ValidationSeverity> = {\n missing_column: 'incomplete',\n missing_value: 'incomplete',\n missing_key: 'incomplete',\n missing_tokens: 'incomplete',\n missing_quantifier: 'incomplete',\n missing_instant: 'incomplete',\n missing_range: 'incomplete',\n missing_duration: 'incomplete',\n unknown_column: 'invalid',\n illegal_operator: 'invalid',\n invalid_date_mode: 'invalid',\n regex_too_long: 'invalid',\n invalid_timestamp: 'invalid',\n invalid_date_range: 'invalid',\n nesting_depth_exceeded: 'invalid',\n};\n\nconst MESSAGES: Record<ValidationIssueCode, string> = {\n missing_column: 'Select a column for this filter.',\n missing_value: 'Enter a value for this filter.',\n missing_key: 'Enter a key for this filter.',\n missing_tokens: 'Enter at least one value for this filter.',\n missing_quantifier: 'Choose whether to match any or all values.',\n missing_instant: 'Select a date for this filter.',\n missing_range: 'Select a start and end date for this filter.',\n missing_duration: 'Select a duration for this filter.',\n unknown_column: 'This column is not available for filtering.',\n illegal_operator: 'This operator is not allowed for this filter.',\n invalid_date_mode: 'This operator cannot be used with this date mode.',\n regex_too_long: `Pattern exceeds the maximum length of ${MAX_REGEX_LEN} characters.`,\n invalid_timestamp: 'Enter a valid date.',\n invalid_date_range: 'The start must be on or before the end.',\n nesting_depth_exceeded: 'This filter is nested too deeply.',\n};\n\n/** RFC3339 timestamp (date + time + Z or numeric offset). */\nconst RFC3339_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\n\nfunction isValidRfc3339(value: string): boolean {\n return RFC3339_RE.test(value) && !Number.isNaN(Date.parse(value)) && isRealCalendarDay(value);\n}\n\ntype IssueInput = {\n condition: CelFilterCondition;\n code: ValidationIssueCode;\n field?: string;\n};\n\nfunction makeIssue({ condition, code, field }: IssueInput): ValidationIssue {\n return {\n code,\n message: MESSAGES[code],\n severity: SEVERITY_BY_CODE[code],\n nodeId: condition.id,\n nodeType: 'condition',\n field,\n };\n}\n\n/**\n * Validates a single condition against the provided schema. Returns an empty\n * array when the condition is complete and compilable.\n */\nexport function validateCondition(condition: CelFilterCondition, schema: CelFilterSchema): ValidationIssue[] {\n if (!condition.columnId) {\n return [makeIssue({ condition, code: 'missing_column', field: 'columnId' })];\n }\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return [makeIssue({ condition, code: 'unknown_column', field: 'columnId' })];\n }\n return validateColumnCondition(condition, columnDef);\n}\n\nfunction validateColumnCondition(condition: CelFilterCondition, columnDef: CelColumnDefinition): ValidationIssue[] {\n const allowed = getAllowedOperators(columnDef);\n\n if (!allowed.includes(condition.operator)) {\n return [makeIssue({ condition, code: 'illegal_operator', field: 'operator' })];\n }\n\n switch (columnDef.filterType) {\n case 'checkbox':\n case 'static':\n return validateCheckbox(condition);\n case 'radio':\n case 'text':\n return validateSingleString(condition, columnDef.filterType);\n case 'multiText':\n return validateMultiText(condition);\n case 'date':\n return validateDate(condition);\n case 'keyValue':\n return validateMapCondition(condition);\n default:\n return [];\n }\n}\n\nfunction validateCheckbox(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!Array.isArray(value) || value.length === 0) {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n return [];\n}\n\nfunction validateSingleString(condition: CelFilterCondition, filterType: 'radio' | 'text'): ValidationIssue[] {\n const value = condition.value;\n if (typeof value !== 'string' || value === '') {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n if (filterType === 'text' && condition.operator === 'matches' && value.length > MAX_REGEX_LEN) {\n return [makeIssue({ condition, code: 'regex_too_long', field: 'pattern' })];\n }\n return [];\n}\n\nfunction validateMultiText(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!isMultiTextCelValue(value) || value.tokens.length === 0) {\n return [makeIssue({ condition, code: 'missing_tokens', field: 'tokens' })];\n }\n\n const issues: ValidationIssue[] = [];\n const multi = value as MultiTextCelValue;\n\n if (multi.tokens.length > 1 && !multi.quantifier) {\n issues.push(makeIssue({ condition, code: 'missing_quantifier', field: 'quantifier' }));\n }\n\n if (condition.operator === 'matches' && multi.tokens.some(token => token.length > MAX_REGEX_LEN)) {\n issues.push(makeIssue({ condition, code: 'regex_too_long', field: 'pattern' }));\n }\n\n return issues;\n}\n\nfunction validateDate(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n\n if (!isDateCelValue(value)) {\n // Freshly added / undefined date condition — treat as a missing single-point instant.\n return [makeIssue({ condition, code: 'missing_instant', field: 'instant' })];\n }\n\n const date = value as DateCelValue;\n\n if (isRelativeDateCelValue(date)) {\n return validateRelativeDate(condition, date);\n }\n return validateAbsoluteDate(condition, date);\n}\n\nfunction validateAbsoluteDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (isDateRangeOperator(condition.operator)) {\n const range = value.range;\n if (!range || !range.start || !range.end) {\n issues.push(makeIssue({ condition, code: 'missing_range', field: 'range' }));\n return issues;\n }\n if (!isValidRfc3339(range.start)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'start' }));\n }\n if (!isValidRfc3339(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'end' }));\n }\n if (issues.length === 0 && Date.parse(range.start) > Date.parse(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_range', field: 'range' }));\n }\n return issues;\n }\n\n if (!value.instant) {\n issues.push(makeIssue({ condition, code: 'missing_instant', field: 'instant' }));\n return issues;\n }\n if (!isValidRfc3339(value.instant)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'instant' }));\n }\n return issues;\n}\n\nfunction validateRelativeDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (!isDateRelativeOperator(condition.operator)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_mode', field: 'value' }));\n return issues;\n }\n\n if (!value.preset) {\n issues.push(makeIssue({ condition, code: 'missing_duration', field: 'preset' }));\n }\n return issues;\n}\n\nfunction validateMapCondition(condition: CelFilterCondition): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n const value = isMapKeyCelValue(condition.value) ? (condition.value as MapKeyCelValue) : undefined;\n\n if (!value || value.key === '') {\n issues.push(makeIssue({ condition, code: 'missing_key', field: 'key' }));\n }\n\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (requiresValue && (!value || !value.value)) {\n issues.push(makeIssue({ condition, code: 'missing_value', field: 'value' }));\n }\n\n return issues;\n}\n","/**\n * Applies draft/commit display rules to a raw compile result.\n *\n * Validation timing: a condition's issues are surfaced on its pill and in the\n * global panel only once it has been committed (popover closed) and is not\n * currently being edited. Group-level issues (e.g. nesting depth) always show.\n *\n * `isEmitReady` on the returned object is always `false` here — it is a\n * placeholder that `CelFilterBar` overrides via `computeIsEmitReady` before\n * calling `onCompileResultChange`. This is the single source of truth for the gate.\n */\nimport { type CelValidationMeta, type CompileResult } from '../types';\nimport { statusFromIssues } from './validate-condition';\n\nexport function applyDisplayRules(raw: CompileResult, meta: CelValidationMeta): CompileResult {\n const issues = raw.issues.filter(issue => {\n if (issue.nodeType === 'group') {\n return true;\n }\n if (issue.nodeId === meta.editingConditionId) {\n return false;\n }\n return meta.committedConditionIds.has(issue.nodeId);\n });\n\n const status = statusFromIssues(issues);\n const expression = status === 'valid' ? raw.expression : undefined;\n\n return {\n status,\n expression,\n issues,\n isEmitReady: false,\n };\n}\n","import { resolveFilterShape } from './compile/operators';\nimport type { CelColumnDefinition, CelEmitOn, CelFilterCondition, CelFilterSchema } from './types';\nimport { readMapKeyCelValue } from './value-utils';\n\nconst COMMIT_FILTER_TYPES = new Set<CelColumnDefinition['filterType']>(['text', 'multiText', 'keyValue', 'date']);\n\nexport function isMultiTextColumn(columnId: string, schema: CelFilterSchema): boolean {\n return schema.columns.find(column => column.id === columnId)?.filterType === 'multiText';\n}\n\n/** Returns when a column's valid value may be emitted; explicit `emitOn` overrides filterType defaults. */\nexport function getColumnEmitOn(columnDef: CelColumnDefinition): CelEmitOn {\n if (columnDef.emitOn) {\n return columnDef.emitOn;\n }\n return COMMIT_FILTER_TYPES.has(columnDef.filterType) ? 'commit' : 'change';\n}\n\n/** After operator change, keyValue may need the value field before the condition is complete. */\nexport function shouldOpenValueSurfaceAfterOperatorChange(\n condition: CelFilterCondition,\n schema: CelFilterSchema,\n): boolean {\n if (resolveFilterShape(condition, schema) !== 'map') {\n return false;\n }\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (!requiresValue) {\n return false;\n }\n return !readMapKeyCelValue(condition.value).value?.trim();\n}\n","import { getColumnEmitOn } from '../schema-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n type PillActiveSurface,\n} from '../types';\n\nexport type ComputeIsEmitReadyMeta = {\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n};\n\nfunction resolveEditingColumn(\n tree: CelFilterTree,\n schema: CelFilterSchema,\n editingConditionId: string,\n): CelColumnDefinition | undefined {\n const condition = tree.root.children.find(\n (child): child is CelFilterCondition => isCelFilterCondition(child) && child.id === editingConditionId,\n );\n return condition && schema.columns.find(column => column.id === condition.columnId);\n}\n\n/**\n * Gates API emission while a commit-mode condition is mid-edit. Only the\n * actively edited condition matters — one popover at a time.\n */\nexport function computeIsEmitReady(\n raw: CompileResult,\n editingConditionId: string | null,\n schema: CelFilterSchema,\n tree: CelFilterTree,\n meta: ComputeIsEmitReadyMeta,\n): boolean {\n if (raw.status !== 'valid') return false;\n if (!editingConditionId) return true;\n\n const columnDef = resolveEditingColumn(tree, schema, editingConditionId);\n // Unknown column or change-mode → nothing to gate, emit live.\n if (!columnDef || getColumnEmitOn(columnDef) === 'change') return true;\n\n // Commit-mode: emit only once the popover is closed and the draft committed.\n const popoverClosed = meta.activeSurface === null;\n return popoverClosed && meta.committedConditionIds.has(editingConditionId);\n}\n","/**\n * Compiles a CEL filter tree into a CEL string or structured validation issues.\n *\n * Pure logic — no React, no display rules. `CelFilterBar` composes\n * `applyDisplayRules(compileCelFilterTree(tree, schema), meta)`.\n */\nimport { MAX_NESTING_DEPTH } from '../constants';\nimport {\n type CelColumnDefinition,\n type CelFilterGroup,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n isCelFilterGroup,\n type ValidationIssue,\n} from '../types';\nimport {\n buildConditionExpression,\n type ConditionExpression,\n resolveColumnDefinition,\n resolveFilterShape,\n} from './operators';\nimport { statusFromIssues, validateCondition } from './validate-condition';\n\ntype GroupCompileResult = {\n issues: ValidationIssue[];\n fragments: ConditionExpression[];\n};\n\n/**\n * Combines a group's child fragments into a single fragment.\n *\n * v1 groups are always `&&`. A child fragment with a bare top-level `||`\n * (e.g. a multiText `any`) is parenthesized before joining so precedence is\n * preserved. The produced fragment reports whether *it* needs grouping when\n * placed under a parent `&&`:\n *\n * - 0 children → empty fragment.\n * - 1 child → propagated as-is so the parent decides on parens (a lone `||`\n * fragment must still be wrapped by whoever joins it under `&&`).\n * - >1 children → a pure `&&` chain, which never needs outer parens under `&&`.\n *\n * (If a future `||` group combinator ships, the connective and `needsGrouping`\n * become combinator-aware; today every group is `&&`.)\n */\nfunction combineGroupFragments(fragments: ConditionExpression[]): ConditionExpression {\n if (fragments.length === 0) {\n return { expression: '', needsGrouping: false };\n }\n if (fragments.length === 1) {\n return fragments[0];\n }\n return {\n expression: fragments\n .map(fragment => (fragment.needsGrouping ? `(${fragment.expression})` : fragment.expression))\n .join(' && '),\n needsGrouping: false,\n };\n}\n\nfunction compileGroup(group: CelFilterGroup, schema: CelFilterSchema): GroupCompileResult {\n const depthIssues: ValidationIssue[] =\n group.depth > MAX_NESTING_DEPTH\n ? [\n {\n code: 'nesting_depth_exceeded',\n message: 'This filter is nested too deeply.',\n severity: 'invalid',\n nodeId: group.id,\n nodeType: 'group',\n },\n ]\n : [];\n\n return group.children.reduce<GroupCompileResult>(\n (acc, child) => {\n if (isCelFilterGroup(child)) {\n const nested = compileGroup(child, schema);\n acc.issues.push(...nested.issues);\n if (nested.fragments.length > 0) {\n acc.fragments.push(combineGroupFragments(nested.fragments));\n }\n return acc;\n }\n\n if (isCelFilterCondition(child)) {\n const conditionIssues = validateCondition(child, schema);\n if (conditionIssues.length > 0) {\n acc.issues.push(...conditionIssues);\n return acc;\n }\n\n const shape = resolveFilterShape(child, schema);\n if (!shape) {\n return acc;\n }\n const columnDef: CelColumnDefinition | undefined = resolveColumnDefinition(child, schema);\n acc.fragments.push(buildConditionExpression(child, shape, columnDef));\n }\n\n return acc;\n },\n { issues: depthIssues, fragments: [] },\n );\n}\n\n/**\n * Walks the tree, joins root children with ` && `, and emits a CEL string when\n * everything is complete and valid. An empty root compiles to `\"\"` with status\n * `valid` (the API treats an empty filter as no filter).\n */\nexport function compileCelFilterTree(tree: CelFilterTree, schema: CelFilterSchema): CompileResult {\n const { issues, fragments } = compileGroup(tree.root, schema);\n const status = statusFromIssues(issues);\n\n if (status === 'valid') {\n return { status, expression: combineGroupFragments(fragments).expression, issues, isEmitReady: true };\n }\n\n return { status, issues, isEmitReady: false };\n}\n","/**\n * Tree factories and helpers for the CEL filter builder.\n */\nimport { getDefaultOperator } from './compile/operators';\nimport { isCelFilterCondition } from './types';\nimport type { CelFilterCondition, CelFilterSchema, CelFilterTree } from './types';\n\n/** Generates a stable unique id, falling back when `crypto.randomUUID` is unavailable. */\nexport function createCelNodeId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `cel-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Creates an empty tree whose root is a depth-0 `and` group with no children. */\nexport function createEmptyCelFilterTree(): CelFilterTree {\n return {\n root: {\n id: createCelNodeId(),\n type: 'group',\n combinator: 'and',\n depth: 0,\n children: [],\n },\n };\n}\n\nexport type CreateDefaultConditionParams = {\n schema: CelFilterSchema;\n columnId: string;\n};\n\n/**\n * Creates a new condition with the default operator for its column and an\n * undefined value (filled in by the user in the popover).\n */\nexport function createDefaultCondition({ schema, columnId }: CreateDefaultConditionParams): CelFilterCondition {\n const columnDef = schema.columns.find(column => column.id === columnId);\n if (!columnDef) {\n throw new Error(`createDefaultCondition: column \"${columnId}\" is not in schema.columns`);\n }\n\n return {\n id: createCelNodeId(),\n type: 'condition',\n columnId,\n operator: getDefaultOperator(columnDef.filterType),\n value: columnDef.defaultValue,\n };\n}\n\n/** Appends a condition to the root group's children. */\nexport function appendCondition(tree: CelFilterTree, condition: CelFilterCondition): CelFilterTree {\n return { root: { ...tree.root, children: [...tree.root.children, condition] } };\n}\n\n/** Replaces a root-level condition by id, applying `updater` to the existing condition. Root-level only — v1's UI never produces nested groups. */\nexport function replaceCondition(\n tree: CelFilterTree,\n conditionId: string,\n updater: (condition: CelFilterCondition) => CelFilterCondition,\n): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.map(child =>\n isCelFilterCondition(child) && child.id === conditionId ? updater(child) : child,\n ),\n },\n };\n}\n\n/** Removes a root-level condition by id. */\nexport function removeConditionById(tree: CelFilterTree, conditionId: string): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.filter(child => !(isCelFilterCondition(child) && child.id === conditionId)),\n },\n };\n}\n","import { calendarDayStartInstant } from './date-utils';\nimport { createCelNodeId } from './tree-utils';\nimport {\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterTree,\n isCelFilterCondition,\n isCheckboxCelValue,\n isMapKeyCelValue,\n} from './types';\n\nfunction upsertCondition(\n tree: CelFilterTree,\n matches: (condition: CelFilterCondition) => boolean,\n build: (existing: CelFilterCondition | undefined) => Omit<CelFilterCondition, 'id'>,\n): CelFilterTree {\n const index = tree.root.children.findIndex(child => isCelFilterCondition(child) && matches(child));\n const found = tree.root.children[index];\n const existing = index >= 0 && isCelFilterCondition(found) ? found : undefined;\n const condition: CelFilterCondition = {\n id: existing?.id ?? createCelNodeId(),\n ...build(existing),\n };\n\n const children =\n index >= 0\n ? tree.root.children.map((child, i) => (i === index ? condition : child))\n : [...tree.root.children, condition];\n return { root: { ...tree.root, children } };\n}\n\nfunction mergeKeyValueToken(tree: CelFilterTree, columnId: string, token: string): CelFilterTree {\n const [key, ...rest] = token.split('=');\n const mapValue = rest.join('=');\n return upsertCondition(\n tree,\n condition => condition.columnId === columnId && isMapKeyCelValue(condition.value) && condition.value.key === key,\n () => ({\n type: 'condition',\n columnId,\n operator: mapValue ? 'has_value' : 'key_exists',\n value: mapValue ? { key, value: mapValue } : { key },\n }),\n );\n}\n\n/** Upserts (or unions, for checkbox) an externally-provided value into the tree by column type. */\nexport function mergeContextualIntoCelTree(\n tree: CelFilterTree,\n schema: CelFilterSchema,\n columnId: string,\n values: string[],\n): CelFilterTree {\n if (values.length === 0) {\n return tree;\n }\n\n const columnDef = schema.columns.find(column => column.id === columnId);\n if (!columnDef) {\n return tree;\n }\n\n const matchesColumn = (condition: CelFilterCondition) => condition.columnId === columnId;\n\n switch (columnDef.filterType) {\n case 'checkbox':\n return upsertCondition(tree, matchesColumn, existing => ({\n type: 'condition',\n columnId,\n operator: 'is',\n value: Array.from(\n new Set([...(existing && isCheckboxCelValue(existing.value) ? existing.value : []), ...values]),\n ),\n }));\n case 'keyValue':\n return values.reduce((acc, token) => mergeKeyValueToken(acc, columnId, token), tree);\n case 'multiText':\n return upsertCondition(tree, matchesColumn, () => ({\n type: 'condition',\n columnId,\n operator: 'contains',\n value: { tokens: values, quantifier: 'any' },\n }));\n case 'date':\n return upsertCondition(tree, matchesColumn, () => ({\n type: 'condition',\n columnId,\n operator: 'is',\n value: { instant: calendarDayStartInstant(values[0]) },\n }));\n default:\n return upsertCondition(tree, matchesColumn, () => ({\n type: 'condition',\n columnId,\n operator: 'is',\n value: values[0],\n }));\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cel-filter-bar/cel-filter-bar.tsx","../src/lib/utils.ts","../src/hooks/use-mounted.ts","../src/hooks/use-cel-filter-editor-state.ts","../src/lib/cel-filter/constants.ts","../src/lib/cel-filter/date-utils.ts","../src/lib/cel-filter/types.ts","../src/lib/cel-filter/value-utils.ts","../src/lib/cel-filter/compile/escape-cel-string.ts","../src/lib/cel-filter/compile/operators.ts","../src/lib/cel-filter/compile/validate-condition.ts","../src/lib/cel-filter/compile/apply-display-rules.ts","../src/lib/cel-filter/schema-utils.ts","../src/lib/cel-filter/compile/compute-is-emit-ready.ts","../src/lib/cel-filter/compile/compile-cel-filter-tree.ts","../src/lib/cel-filter/tree-utils.ts","../src/lib/cel-filter/merge-contextual-into-cel-tree.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon } from '@upbound/monarch-core';\nimport { type DateRange } from 'react-day-picker';\n\nimport { cn, sortBy } from '@/lib/utils';\nimport { useMounted } from '@/hooks/use-mounted';\nimport { Badge } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { ButtonGroup, ButtonGroupText } from '@upbound/monarch-core';\nimport { Calendar } from '@upbound/monarch-core';\nimport {\n Combobox,\n ComboboxChip,\n ComboboxClearAll,\n ComboboxCollection,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxLabel,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@upbound/monarch-core';\n\nimport { useCelFilterEditorState, type CelConditionEditorController } from '@/hooks/use-cel-filter-editor-state';\nimport {\n allowsMultipleConditions,\n appendCondition,\n applyDisplayRules,\n applyOperatorChange,\n calendarDayStartInstant,\n compileCelFilterTree,\n computeIsEmitReady,\n createDefaultCondition,\n dateBoundaryForOperator,\n formatCalendarDateUtc,\n formatInstantLabel,\n getAllowedOperators,\n getOperatorLabel,\n getQuantifierLabel,\n isCelFilterCondition,\n isCheckboxCelValue,\n isDateRangeOperator,\n isDateRelativeOperator,\n isDateWindowOperator,\n isRelativeDateCelValue,\n parseCalendarDate,\n readDateCelValue,\n readMapKeyCelValue,\n readMultiTextCelValue,\n readTimeOfDay,\n RELATIVE_DURATION_PRESET_VALUES,\n removeConditionById,\n replaceCondition,\n resolveColumnDefinition,\n resolveFilterShape,\n withTimeOfDay,\n type CelColumnDefinition,\n type CelColumnOption,\n type CelFilterBarProps,\n type CelFilterCondition,\n type CelOperator,\n type CompileResult,\n type DateCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type RelativeDurationPreset,\n} from '@/lib/cel-filter';\n\ntype PortalContainer = React.ComponentProps<typeof ComboboxContent>['container'];\n\nconst RELATIVE_PRESET_LABELS: Record<RelativeDurationPreset, string> = {\n '24h': 'Last 24 hours',\n '168h': 'Last 7 days',\n '720h': 'Last 30 days',\n};\n\n// Neutralizes Select's default purple focus ring/border and matches the\n// plain grey hover/focus background the rest of a pill's segments (value\n// trigger, remove button — both Button variant=\"outline\") use, so every\n// Select-based segment reads as part of one continuous control. `!` is\n// required on the hover border: Select's own hover border is a compound\n// variant (hover:not-disabled:not-aria-invalid:border-ring/50) that a plain\n// hover:border-input doesn't win against via class order alone.\nconst SEGMENT_SELECT_TRIGGER_CLASSNAME =\n 'hover:border-input! focus-visible:border-input focus-visible:ring-0 hover:bg-muted focus-visible:bg-muted aria-expanded:bg-muted';\n\n// ── CelFilterBar ──────────────────────────────────────\n\nfunction CelFilterBar({\n tree,\n onChange,\n schema,\n onCompileResultChange,\n onRestrictedOptionSelect,\n showClearButton = false,\n className,\n}: CelFilterBarProps) {\n const editor = useCelFilterEditorState();\n const onCompileResultChangeRef = React.useRef(onCompileResultChange);\n React.useEffect(() => {\n onCompileResultChangeRef.current = onCompileResultChange;\n });\n\n const rawResult = React.useMemo(() => compileCelFilterTree(tree, schema), [tree, schema]);\n const displayResult = React.useMemo(\n () =>\n applyDisplayRules(rawResult, {\n editingConditionId: editor.editingConditionId,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.committedConditionIds],\n );\n const isEmitReady = React.useMemo(\n () =>\n computeIsEmitReady(rawResult, editor.editingConditionId, schema, tree, {\n activeSurface: editor.activeSurface,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.activeSurface, editor.committedConditionIds, schema, tree],\n );\n\n React.useEffect(() => {\n onCompileResultChangeRef.current?.({ ...displayResult, isEmitReady });\n }, [displayResult, isEmitReady]);\n\n const conditions = tree.root.children.filter(isCelFilterCondition);\n\n // Ref for the CelFilterBar's own root node, used to anchor Combobox popups.\n // Helps rendering correctly the popup when rendered inside a modal Dialog/Sheet.\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n function handleAddFilter(columnId: string) {\n const condition = createDefaultCondition({ schema, columnId });\n onChange(appendCondition(tree, condition));\n editor.beginEditing(condition.id);\n editor.suppressDismissFor(condition.id);\n }\n\n function handleRemove(conditionId: string) {\n onChange(removeConditionById(tree, conditionId));\n editor.removeCondition(conditionId);\n }\n\n function handleClearAll() {\n onChange({ root: { ...tree.root, children: [] } });\n editor.clearSuppress();\n }\n\n return (\n <div data-slot=\"cel-filter-bar\" className={cn('flex flex-wrap items-center gap-2', className)} ref={containerRef}>\n <CelAddFilterButton schema={schema} conditions={conditions} onSelect={handleAddFilter} container={containerRef} />\n\n {conditions.map(condition => {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) return null;\n return (\n <CelFilterPill\n key={condition.id}\n condition={condition}\n columnDef={columnDef}\n schema={schema}\n tree={tree}\n onChange={onChange}\n controller={editor.getController(condition.id)}\n issues={displayResult.issues.filter(issue => issue.nodeId === condition.id)}\n onRemove={() => handleRemove(condition.id)}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={containerRef}\n />\n );\n })}\n\n {showClearButton && conditions.length > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={handleClearAll}>\n Clear all\n </Button>\n )}\n </div>\n );\n}\n\n// ── Add filter menu ───────────────────────────────────\n\ntype CelAddFilterGroup = { value: string; items: CelColumnDefinition[] };\n\nfunction CelAddFilterButton({\n schema,\n conditions,\n onSelect,\n container,\n}: {\n schema: CelFilterBarProps['schema'];\n conditions: CelFilterCondition[];\n onSelect: (columnId: string) => void;\n container?: PortalContainer;\n}) {\n const usedSingleInstanceColumnIds = new Set(\n conditions\n .map(condition => resolveColumnDefinition(condition, schema))\n .filter(\n (columnDef): columnDef is CelColumnDefinition => !!columnDef && !allowsMultipleConditions(columnDef.filterType),\n )\n .map(columnDef => columnDef.id),\n );\n const availableColumns = schema.columns.filter(column => !usedSingleInstanceColumnIds.has(column.id));\n\n const groupMap = new Map<string, CelColumnDefinition[]>();\n for (const column of availableColumns) {\n const key = column.group ?? '';\n const list = groupMap.get(key) ?? [];\n list.push(column);\n groupMap.set(key, list);\n }\n const groups: CelAddFilterGroup[] = sortBy(\n Array.from(groupMap.entries()).map(([value, items]) => ({ value, items: sortBy(items, item => item.title) })),\n group => group.value,\n );\n\n return (\n <Combobox\n items={groups}\n itemToStringValue={(item: CelColumnDefinition) => item.title}\n itemToStringLabel={(item: CelColumnDefinition) => item.title}\n onValueChange={(column: CelColumnDefinition | null) => {\n if (column) onSelect(column.id);\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name the\n way a plain button would — an explicit aria-label is required, not\n just a nicety. */}\n <ComboboxTrigger aria-label=\"Add filter\" render={<Button variant=\"outline\" />}>\n <Icon name=\"plus\" data-icon=\"inline-start\" />\n Add filter\n </ComboboxTrigger>\n <ComboboxContent container={container} align=\"start\" className=\"w-64\">\n <ComboboxInput showTrigger={false} placeholder=\"Search filters…\" />\n <ComboboxEmpty>No filters found.</ComboboxEmpty>\n <ComboboxList>\n {(group: CelAddFilterGroup) => (\n <ComboboxGroup key={group.value} items={group.items}>\n {group.value && <ComboboxLabel>{group.value}</ComboboxLabel>}\n <ComboboxCollection>\n {(column: CelColumnDefinition) => (\n <ComboboxItem key={column.id} value={column}>\n {column.title}\n </ComboboxItem>\n )}\n </ComboboxCollection>\n </ComboboxGroup>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Filter pill ────────────────────────────────────────\n\nfunction formatConditionSummary(\n condition: CelFilterCondition,\n columnDef: CelColumnDefinition,\n locale?: string,\n): string {\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n\n switch (shape) {\n case 'checkbox': {\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n if (value.length === 0) return 'Any';\n if (value.length === 1) {\n return columnDef.options?.find(opt => opt.value === value[0])?.label ?? value[0];\n }\n return `${value.length} ${columnDef.pluralTitle}`;\n }\n case 'radio':\n case 'static': {\n const value = typeof condition.value === 'string' ? condition.value : '';\n if (!value) return 'Any';\n return columnDef.options?.find(opt => opt.value === value)?.label ?? value;\n }\n case 'text':\n return typeof condition.value === 'string' && condition.value ? condition.value : 'Any';\n case 'multiText': {\n const value = readMultiTextCelValue(condition.value);\n if (value.tokens.length === 0) return 'Any';\n if (value.tokens.length === 1) return value.tokens[0];\n return `${value.tokens.length} values`;\n }\n case 'date': {\n const value = readDateCelValue(condition.value);\n if (isRelativeDateCelValue(value)) return value.preset ? RELATIVE_PRESET_LABELS[value.preset] : 'Any';\n if (value.range)\n return `${formatInstantLabel(value.range.start, { locale })} – ${formatInstantLabel(value.range.end, { locale })}`;\n if (value.instant) return formatInstantLabel(value.instant, { withTime: value.hasTime, locale });\n return 'Any';\n }\n case 'map': {\n const value = readMapKeyCelValue(condition.value);\n if (!value.key) return 'Any';\n return value.value ? `${value.key}=${value.value}` : value.key;\n }\n default:\n return 'Any';\n }\n}\n\nfunction CelFilterPill({\n condition,\n columnDef,\n schema,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n schema: CelFilterBarProps['schema'];\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const shape = resolveFilterShape(condition, schema) ?? columnDef.filterType;\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted. Only\n // the 'date' shape's summary is locale-sensitive, but computed unconditionally\n // since hooks can't run after the early returns below.\n const locale = mounted ? undefined : 'en-US';\n\n // checkbox/radio always compose Combobox for their value editor (own trigger\n // + popup, per Monarch's standing directive for multi/single-select pickers)\n // rather than sharing the generic Popover the other shapes use below.\n if (shape === 'checkbox') {\n return (\n <CelCheckboxComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={container}\n />\n );\n }\n if (shape === 'radio') {\n return (\n <CelRadioComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={container}\n />\n );\n }\n\n function updateValue(value: CelFilterCondition['value']) {\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value })));\n }\n\n function updateOperator(operator: CelOperator) {\n const hadValue = condition.value !== undefined;\n const next = applyOperatorChange(condition, operator, shape);\n onChange(replaceCondition(tree, condition.id, () => next));\n // Switching operators can clear an incompatible value (e.g. an instant when\n // moving to a range operator) — reopen the value popover so the user isn't\n // left with a silently invalid pill they have to notice and click back into.\n if (hadValue && next.value === undefined) controller.beginEditing();\n }\n\n const allowedOperators = getAllowedOperators(columnDef);\n\n return (\n <Popover\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {shape === 'multiText' && (\n <CelQuantifierSegment\n columnTitle={columnDef.title}\n value={readMultiTextCelValue(condition.value)}\n onChangeValue={updateValue}\n />\n )}\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef, locale)}\n </span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <PopoverContent align=\"start\" className={shape === 'date' ? 'w-fit' : 'w-72'}>\n {shape === 'text' && (\n <CelTextValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n {shape === 'multiText' && <CelMultiTextValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'date' && <CelDateValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'map' && (\n <CelKeyValueValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n// ── Operator segment ───────────────────────────────────\n// Shared between the Popover-based pill (text/multiText/date/map) and the\n// two Combobox-based pills below — always its own ButtonGroup segment,\n// never hidden inside the value editor.\n\nfunction CelOperatorSegment({\n columnTitle,\n operator,\n allowedOperators,\n hideOnSingleOperator,\n onChangeOperator,\n}: {\n columnTitle: string;\n operator: CelOperator;\n allowedOperators: CelOperator[];\n hideOnSingleOperator?: boolean;\n onChangeOperator: (operator: CelOperator) => void;\n}) {\n if (allowedOperators.length > 1) {\n return (\n <Select value={operator} onValueChange={value => onChangeOperator(value as CelOperator)}>\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} operator`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n {allowedOperators.map(op => (\n <SelectItem key={op} value={op}>\n {getOperatorLabel(op)}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n }\n if (allowedOperators.length === 1 && !hideOnSingleOperator) {\n return (\n <ButtonGroupText className=\"text-muted-foreground font-normal\">\n {getOperatorLabel(allowedOperators[0])}\n </ButtonGroupText>\n );\n }\n return null;\n}\n\n// ── Quantifier segment ─────────────────────────────────\n// multiText-only: \"any of\" / \"all of\" across a condition's tokens. Its own\n// plain Select segment appended right after the operator — not a switcher\n// living inside the value popover — with no search (only two options).\n// Hidden until there's more than one token, since quantifier is meaningless\n// (and unvalidated) for zero or one.\n\nfunction CelQuantifierSegment({\n columnTitle,\n value,\n onChangeValue,\n}: {\n columnTitle: string;\n value: MultiTextCelValue;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n if (value.tokens.length <= 1) return null;\n\n return (\n <Select\n value={value.quantifier ?? 'any'}\n onValueChange={next => {\n if (next === 'any' || next === 'all') onChangeValue({ ...value, quantifier: next });\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} quantifier`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n <SelectItem value=\"any\">{getQuantifierLabel('any')}</SelectItem>\n <SelectItem value=\"all\">{getQuantifierLabel('all')}</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n}\n\n// ── Checkbox pill (Combobox, multi-select) ────────────\n// Same Combobox composition as FilterChip's searchable branch in\n// filter-bar.tsx — Monarch's standing pattern for multi-select pickers.\n// A restricted (disabled) option is never blocked at the primitive level\n// (Base UI's own `disabled` would silently swallow the click, same failure\n// mode Radix's Checkbox has); instead every selection change is diffed\n// against the previous value and a newly-picked disabled option is reverted\n// and redirected to `onRestrictedOptionSelect`.\n\nfunction CelCheckboxComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const options = sortBy(columnDef.options ?? [], o => o.label);\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n const selected = options.filter(option => value.includes(option.value));\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'checkbox')));\n }\n\n function applySelection(nextSelected: CelColumnOption[]) {\n const current = new Set(value);\n const nextValues = new Set(nextSelected.map(option => option.value));\n for (const option of nextSelected) {\n if (!current.has(option.value) && option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n nextValues.delete(option.value);\n }\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: Array.from(nextValues) })));\n const added = nextSelected.find(option => !current.has(option.value) && !option.disabled && option.operator);\n if (added?.operator) updateOperator(added.operator);\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n multiple\n value={selected}\n onValueChange={(next: CelColumnOption[]) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={(open: boolean) => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent container={container} className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n {selected.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(items: CelColumnOption[]) => (\n <>\n {items.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => applySelection([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Radio pill (Combobox, single-select) ──────────────\n// Same primitive as the checkbox pill above, constrained to one selection by\n// omitting `multiple` — no chip strip (nothing to show but the one value,\n// already in the trigger), and a valid pick auto-commits (closes) like the\n// legacy RadioGroup did.\n\nfunction CelRadioComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const options = sortBy(columnDef.options ?? [], o => o.label);\n const value = typeof condition.value === 'string' ? condition.value : '';\n const selected = options.find(option => option.value === value) ?? null;\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'radio')));\n }\n\n function applySelection(option: CelColumnOption | null) {\n if (!option) return;\n if (option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n return;\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: option.value })));\n if (option.operator) updateOperator(option.operator);\n controller.commit();\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n value={selected}\n onValueChange={(next: CelColumnOption | null) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={(open: boolean) => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent container={container} className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Text value editor ─────────────────────────────────\n\nfunction CelTextValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: string) => void;\n onCommit: () => void;\n}) {\n const value = typeof condition.value === 'string' ? condition.value : '';\n\n return (\n <Input\n autoFocus\n value={value}\n placeholder=\"Enter a value…\"\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n );\n}\n\n// ── MultiText value editor ────────────────────────────\n\nfunction CelMultiTextValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n const value = readMultiTextCelValue(condition.value);\n const [draft, setDraft] = React.useState('');\n\n function addToken() {\n const token = draft.trim();\n if (!token || value.tokens.includes(token)) {\n setDraft('');\n return;\n }\n const nextTokens = [...value.tokens, token];\n // Write an explicit quantifier the moment it first becomes relevant\n // (2nd token). CelQuantifierSegment's Select displays `quantifier ?? 'any'`\n // as its value, so if the user's first pick were \"any of\" — the same as\n // that visual default — Radix would see no change and never fire\n // onValueChange, leaving quantifier stuck undefined and the\n // missing_quantifier issue stuck showing despite the pill saying \"any of\".\n const quantifier = nextTokens.length > 1 ? (value.quantifier ?? 'any') : value.quantifier;\n onChangeValue({ ...value, tokens: nextTokens, quantifier });\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue({ ...value, tokens: value.tokens.filter(t => t !== token) });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {value.tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {value.tokens.map(token => (\n <Badge key={token} variant=\"secondary\" className=\"gap-1\">\n {token}\n <button\n type=\"button\"\n aria-label={`Remove ${token}`}\n onClick={() => removeToken(token)}\n className=\"cursor-pointer\"\n >\n <Icon name=\"xmark\" size=\"xs\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n <Input\n autoFocus\n value={draft}\n placeholder=\"Type a value, press Enter…\"\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n addToken();\n } else if (e.key === 'Backspace' && draft === '' && value.tokens.length > 0) {\n removeToken(value.tokens[value.tokens.length - 1]);\n }\n }}\n />\n </div>\n );\n}\n\n// ── KeyValue value editor ─────────────────────────────\n\nfunction CelKeyValueValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MapKeyCelValue) => void;\n onCommit: () => void;\n}) {\n const value = readMapKeyCelValue(condition.value);\n const needsValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n\n return (\n <div className=\"flex flex-col gap-2\">\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Key</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n autoFocus\n value={value.key}\n onChange={e => onChangeValue({ ...value, key: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter' && !needsValue) onCommit();\n }}\n />\n </InputGroup>\n {needsValue && (\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Value</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n value={value.value ?? ''}\n onChange={e => onChangeValue({ ...value, value: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n </InputGroup>\n )}\n </div>\n );\n}\n\n// ── Date value editor ──────────────────────────────────\n\nfunction CelDateValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: DateCelValue) => void;\n}) {\n const value = readDateCelValue(condition.value);\n const operator = condition.operator;\n const relativeCapable = isDateRelativeOperator(operator);\n const isRange = isDateRangeOperator(operator);\n const showTime = !isDateWindowOperator(operator) && !isRange;\n const isRelative = isRelativeDateCelValue(value);\n\n function pickInstant(date: Date | undefined) {\n if (!date) return;\n const boundary = dateBoundaryForOperator(operator);\n const instant = formatCalendarDateUtc(date, showTime ? boundary : 'start');\n onChangeValue({ instant });\n }\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) return;\n const start = calendarDayStartInstant(formatCalendarDateUtc(range.from, 'start'));\n const end = range.to ? formatCalendarDateUtc(range.to, 'end') : formatCalendarDateUtc(range.from, 'end');\n onChangeValue({ range: { start, end } });\n }\n\n function pickTime(timeOfDay: string) {\n if (!value.instant) return;\n onChangeValue({ instant: withTimeOfDay(value.instant, timeOfDay), hasTime: true });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {/* No wrapping border here — PopoverContent already supplies the pill's\n single outer border/ring. A second border on this row would double\n up against it. `border-r` on the sidebar alone gives the divider. */}\n <div className=\"flex\">\n {relativeCapable && (\n <div className=\"flex flex-col gap-1 border-r pr-2\">\n <p className=\"text-body-sm text-muted-foreground px-2 font-medium\">Quick select</p>\n {RELATIVE_DURATION_PRESET_VALUES.map(preset => (\n <Button\n key={preset}\n type=\"button\"\n variant={isRelative && value.preset === preset ? 'secondary' : 'ghost'}\n size=\"sm\"\n className=\"justify-start\"\n onClick={() => onChangeValue({ preset })}\n >\n {RELATIVE_PRESET_LABELS[preset]}\n </Button>\n ))}\n </div>\n )}\n {isRange ? (\n <Calendar\n mode=\"range\"\n selected={\n value.range\n ? { from: parseCalendarDate(value.range.start), to: parseCalendarDate(value.range.end) }\n : undefined\n }\n onSelect={pickRange}\n />\n ) : (\n <Calendar\n mode=\"single\"\n selected={isRelative ? undefined : parseCalendarDate(value.instant)}\n onSelect={pickInstant}\n />\n )}\n </div>\n {showTime && !isRelative && (\n <div className=\"flex w-full items-center gap-2\">\n <Label htmlFor=\"cel-date-time\" className=\"text-body-sm text-muted-foreground shrink-0\">\n Time (UTC)\n </Label>\n <Input\n id=\"cel-date-time\"\n type=\"time\"\n className=\"w-full\"\n value={readTimeOfDay(value.instant)}\n onChange={e => pickTime(e.target.value)}\n disabled={!value.instant}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport { CelFilterBar };\n","import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [\n {\n text: [\n 'display-hero',\n 'display-kpi-sm',\n 'display-kpi',\n 'display-kpi-lg',\n 'display-feature',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'body-lg',\n 'body',\n 'body-sm',\n 'caption',\n 'eyebrow',\n ],\n },\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function sortBy<T>(items: T[], getKey: (item: T) => string): T[] {\n return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));\n}\n","import { useSyncExternalStore } from 'react';\n\nfunction subscribe() {\n return () => {};\n}\n\n/**\n * Returns `false` on the server and during initial client hydration, then\n * `true` once mounted — for values that are only valid client-side (e.g. the\n * viewer's actual `Intl` locale, vs. a fixed locale used for the server-\n * rendered/first-paint value) without a hydration mismatch. Implemented via\n * `useSyncExternalStore` rather than `useEffect` + `setState` — the latter\n * works, but re-derives the same \"true\" value on every mount and trips\n * `react-hooks/set-state-in-effect` since there's no actual subscription.\n */\nexport function useMounted() {\n return useSyncExternalStore(\n subscribe,\n () => true,\n () => false,\n );\n}\n","import { useCallback, useRef, useState } from 'react';\n\nimport { ADD_FILTER_POPOVER_SUPPRESS_MS } from '@/lib/cel-filter/constants';\nimport type { PillActiveSurface } from '@/lib/cel-filter/types';\n\nexport type CelConditionEditorController = {\n isDraft: boolean;\n activeSurface: PillActiveSurface | null;\n popoverVisible: boolean;\n isDismissSuppressed: () => boolean;\n\n beginEditing: () => void;\n openSurface: (surface: PillActiveSurface) => void;\n closeSurface: () => void;\n commit: () => void;\n handlePopoverDismiss: () => void;\n toggleSurface: (surface: PillActiveSurface) => void;\n};\n\nexport type UseCelFilterEditorStateResult = {\n editingConditionId: string | null;\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n getController: (conditionId: string) => CelConditionEditorController;\n beginEditing: (id: string, surface?: PillActiveSurface) => void;\n suppressDismissFor: (id: string, ms?: number) => void;\n removeCondition: (id: string) => void;\n clearSuppress: () => void;\n};\n\n/**\n * Single source of truth for CEL filter draft/commit, active pill segment,\n * and Radix dismiss-suppression (post-add guard + segment switches).\n */\nexport function useCelFilterEditorState(initialCommittedIds: string[] = []): UseCelFilterEditorStateResult {\n const [editingConditionId, setEditingConditionId] = useState<string | null>(null);\n const [committedConditionIds, setCommittedConditionIds] = useState<Set<string>>(() => new Set(initialCommittedIds));\n const [activeSurface, setActiveSurface] = useState<PillActiveSurface | null>(null);\n\n const suppressCloseUntilRef = useRef<{ id: string; until: number } | null>(null);\n const segmentSwitchRef = useRef(false);\n\n const isDismissSuppressed = useCallback((id: string) => {\n const entry = suppressCloseUntilRef.current;\n return entry !== null && entry.id === id && Date.now() < entry.until;\n }, []);\n\n const commitCondition = useCallback((id: string) => {\n setCommittedConditionIds(prev => {\n if (prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.add(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }, []);\n\n const beginEditing = useCallback((id: string, surface: PillActiveSurface = 'value') => {\n setEditingConditionId(id);\n setActiveSurface(surface);\n }, []);\n\n const openSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n if (editingConditionId !== id) {\n beginEditing(id, surface);\n return;\n }\n setActiveSurface(surface);\n },\n [beginEditing, editingConditionId],\n );\n\n const closeSurface = useCallback(\n (id: string) => {\n if (editingConditionId === id) {\n setActiveSurface(null);\n }\n },\n [editingConditionId],\n );\n\n const handlePopoverDismiss = useCallback(\n (id: string) => {\n if (segmentSwitchRef.current) {\n segmentSwitchRef.current = false;\n return;\n }\n if (isDismissSuppressed(id)) {\n return;\n }\n suppressCloseUntilRef.current = null;\n commitCondition(id);\n },\n [commitCondition, isDismissSuppressed],\n );\n\n const toggleSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n const isDraft = editingConditionId === id;\n const popoverVisible = isDraft && activeSurface !== null;\n\n if (isDraft && activeSurface === surface && popoverVisible) {\n closeSurface(id);\n return;\n }\n if (popoverVisible && activeSurface !== surface) {\n segmentSwitchRef.current = true;\n }\n openSurface(id, surface);\n },\n [activeSurface, closeSurface, editingConditionId, openSurface],\n );\n\n const suppressDismissFor = useCallback((id: string, ms = ADD_FILTER_POPOVER_SUPPRESS_MS) => {\n suppressCloseUntilRef.current = {\n id,\n until: Date.now() + ms,\n };\n }, []);\n\n const removeCondition = useCallback(\n (id: string) => {\n if (suppressCloseUntilRef.current?.id === id) {\n suppressCloseUntilRef.current = null;\n }\n setCommittedConditionIds(prev => {\n if (!prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n if (editingConditionId === id) {\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }\n },\n [editingConditionId],\n );\n\n const clearSuppress = useCallback(() => {\n suppressCloseUntilRef.current = null;\n }, []);\n\n const getController = useCallback(\n (conditionId: string): CelConditionEditorController => {\n const isDraft = editingConditionId === conditionId;\n const surface = isDraft ? activeSurface : null;\n\n return {\n isDraft,\n activeSurface: surface,\n popoverVisible: isDraft && activeSurface !== null,\n isDismissSuppressed: () => isDismissSuppressed(conditionId),\n beginEditing: () => beginEditing(conditionId),\n openSurface: s => openSurface(conditionId, s),\n closeSurface: () => closeSurface(conditionId),\n commit: () => {\n suppressCloseUntilRef.current = null;\n commitCondition(conditionId);\n },\n handlePopoverDismiss: () => handlePopoverDismiss(conditionId),\n toggleSurface: s => toggleSurface(conditionId, s),\n };\n },\n [\n activeSurface,\n beginEditing,\n closeSurface,\n commitCondition,\n editingConditionId,\n handlePopoverDismiss,\n isDismissSuppressed,\n openSurface,\n toggleSurface,\n ],\n );\n\n return {\n editingConditionId,\n activeSurface,\n committedConditionIds,\n getController,\n beginEditing,\n suppressDismissFor,\n removeCondition,\n clearSuppress,\n };\n}\n","/**\n * Shared limits and defaults for the CEL filter builder. Values mirror the API\n * constraints (`maxNestingDepth = 50`, `maxRegexLen = 1000`).\n */\nimport type { RelativeDurationPreset } from './types';\n\n/**\n * Trusted relative date presets emitted as fixed `duration(...)` literals in\n * compiled CEL. Hours only — `duration()` rejects a `d` unit.\n */\nexport const RELATIVE_DURATION_PRESET_VALUES = [\n '24h',\n '168h',\n '720h',\n] as const satisfies readonly RelativeDurationPreset[];\n\nexport const RELATIVE_DURATION_PRESETS = new Set<string>(RELATIVE_DURATION_PRESET_VALUES);\n\nexport function isRelativeDurationPreset(value: string): value is RelativeDurationPreset {\n return RELATIVE_DURATION_PRESETS.has(value);\n}\n\n/** API recursion depth limit for nested parentheses. v1 UI is flat; the compiler enforces this defensively. */\nexport const MAX_NESTING_DEPTH = 50;\n\n/** Maximum length of a `matches` regex pattern accepted by the API. */\nexport const MAX_REGEX_LEN = 1000;\n\n/** Debounce for inline free-text (regex) validation inside an open popover. */\nexport const CEL_VALIDATION_DEBOUNCE_MS = 300;\n\n/** Default quantifier when a multiText condition has more than one token. */\nexport const DEFAULT_MULTI_TEXT_QUANTIFIER = 'any' as const;\n\n/**\n * After adding a filter from the dropdown, ignore outside-dismiss on the new\n * pill popover for this long. Covers the menu closing plus immediate pointer\n * movement that Radix treats as an outside interaction.\n */\nexport const ADD_FILTER_POPOVER_SUPPRESS_MS = 500;\n\n/** Keys handled by searchable CEL dropdown listboxes; others stop propagation from the search input. */\nexport const CEL_DROPDOWN_NAV_KEYS = [\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n 'Enter',\n 'Escape',\n 'Tab',\n] as const;\n","/**\n * Instant helpers for the CEL date filter.\n *\n * Stored values are RFC3339 UTC strings, and everything here manipulates them as\n * text rather than through `Date`, so a filter can never drift into the viewer's\n * local timezone. Tables render timestamps in UTC, so a UTC filter is what\n * agrees with the times shown in the table.\n */\n\n/** Which end of a day/minute an instant represents. */\nexport type DateBoundary = 'start' | 'end';\n\n/** How much of the instant the user has committed to: a calendar day, or a wall-clock minute. */\nexport type DateInstantGranularity = 'day' | 'minute';\n\n/** Time an `input[type=\"time\"]` shows for a boundary the user has not edited. */\nexport const BOUNDARY_TIME_OF_DAY: Record<DateBoundary, string> = {\n start: '00:00',\n end: '23:59',\n};\n\nconst CALENDAR_DAY_PATTERN = /^(\\d{4}-\\d{2}-\\d{2})/;\nconst MINUTE_PATTERN = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})/;\nconst TIME_OF_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2})/;\n\nexport function calendarDayStartInstant(instant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T00:00:00.000Z` : instant;\n}\n\n/**\n * Derives the inclusive upper bound of a stored instant. An upper bound covers\n * the whole unit the user selected: a day runs through 23:59:59.999, a minute\n * through :59.999 — the same rule, one unit finer.\n */\nexport function inclusiveEndInstant(instant: string, granularity: DateInstantGranularity): string {\n if (granularity === 'minute') {\n const minuteMatch = MINUTE_PATTERN.exec(instant);\n return minuteMatch ? `${minuteMatch[1]}:59.999Z` : instant;\n }\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T23:59:59.999Z` : instant;\n}\n\n/** Derives inclusive end-of-day RFC3339 from a stored start instant. */\nexport function calendarDayEndInstant(startInstant: string): string {\n return inclusiveEndInstant(startInstant, 'day');\n}\n\nexport function startInstantFromEndOfDay(endInstant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(endInstant);\n return match ? `${match[1]}T00:00:00Z` : endInstant;\n}\n\n/** Strips the `:59.999` an inclusive minute bound was expanded with. */\nexport function startInstantFromEndOfMinute(endInstant: string): string {\n const match = MINUTE_PATTERN.exec(endInstant);\n return match ? `${match[1]}:00.000Z` : endInstant;\n}\n\nexport function isEndOfDayTimestamp(instant: string): boolean {\n return /T23:59:59(\\.\\d+)?Z$/.test(instant);\n}\n\nexport function isStartOfDayTimestamp(instant: string): boolean {\n return /T00:00:00(\\.0+)?Z$/.test(instant);\n}\n\n/**\n * True for an instant expanded to the end of its minute. End-of-day is also\n * end-of-minute, so callers that distinguish the two must test for day first.\n */\nexport function isEndOfMinuteTimestamp(instant: string): boolean {\n return /T\\d{2}:\\d{2}:59(\\.\\d+)?Z$/.test(instant);\n}\n\n/**\n * True when the date portion names a day that exists. `Date` rolls impossible\n * days over silently — Feb 31 becomes Mar 3 rather than failing — so a\n * round-trip through UTC is what separates a real day from a rolled-over one.\n */\nexport function isRealCalendarDay(instant: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(instant);\n if (!match) {\n return false;\n }\n const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n}\n\n/** Reads the `HH:mm` an `input[type=\"time\"]` displays for a stored instant. */\nexport function readTimeOfDay(instant: string | undefined): string {\n if (!instant) {\n return '';\n }\n const match = TIME_OF_DAY_PATTERN.exec(instant);\n return match ? match[1] : '';\n}\n\n/** Replaces the time portion of an instant. Seconds are zeroed — the input is minute-granular. */\nexport function withTimeOfDay(instant: string, timeOfDay: string): string {\n const day = CALENDAR_DAY_PATTERN.exec(instant);\n const time = /^(\\d{2}):(\\d{2})/.exec(timeOfDay);\n if (!day || !time) {\n return instant;\n }\n return `${day[1]}T${time[1]}:${time[2]}:00.000Z`;\n}\n\n/**\n * Stamps a picked calendar day as a UTC instant. The picker hands back a local\n * `Date` whose Y/M/D is the day that was clicked; that day is stored as the\n * matching UTC day so the filter lines up with the UTC timestamps in the table.\n */\nexport function formatCalendarDateUtc(date: Date, boundary: DateBoundary): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const time = boundary === 'end' ? 'T23:59:59.999Z' : 'T00:00:00.000Z';\n return `${year}-${month}-${day}${time}`;\n}\n\n/** Parses a stored RFC3339 string back into a local Date carrying the calendar day. */\nexport function parseCalendarDate(value: string | undefined): Date | undefined {\n if (!value) {\n return undefined;\n }\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value);\n if (!match) {\n return undefined;\n }\n return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));\n}\n\n/**\n * Locale date for display, plus the UTC time when the instant carries a\n * user-picked one. `locale` defaults to the runtime's own locale (matching\n * plain `toLocaleDateString()`) — callers rendered during SSR should pass a\n * fixed locale explicitly (see `cel-filter-bar.tsx`'s `useMounted()` gating)\n * so the server-rendered/first-paint value doesn't hydration-mismatch against\n * the viewer's actual browser locale.\n */\nexport function formatInstantLabel(\n instant: string | undefined,\n { withTime = false, locale }: { withTime?: boolean; locale?: string } = {},\n): string {\n const date = parseCalendarDate(instant);\n if (!date) {\n return '';\n }\n const dateLabel = date.toLocaleDateString(locale);\n const timeOfDay = withTime ? readTimeOfDay(instant) : '';\n return timeOfDay ? `${dateLabel} ${timeOfDay} UTC` : dateLabel;\n}\n","/** Stable operator ids used in code and tests. UI labels come from `getOperatorLabel`. */\nexport type CelOperator =\n | 'is'\n | 'is_not'\n | 'contains'\n | 'does_not_contain'\n | 'starts_with'\n | 'ends_with'\n | 'matches'\n | 'is_before'\n | 'is_after'\n | 'is_on_or_before'\n | 'is_on_or_after'\n | 'is_between'\n | 'is_not_between'\n | 'key_exists'\n | 'key_does_not_exist'\n | 'has_value'\n | 'does_not_have_value';\n\nexport type CelFilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date' | 'keyValue' | 'static';\n\n/** When a valid compiled expression may be emitted to consumers (API, URL, etc.). */\nexport type CelEmitOn = 'change' | 'commit';\n\n/**\n * Resolved shape used by the compiler / dispatcher to pick a value variant and\n * operator set. Columns map to their `filterType`; map fields resolve to `map`.\n */\nexport type CelFilterShape = CelFilterType | 'map';\n\nexport type CelColumnOption = {\n /** Human-readable text shown in the UI and collapsed pill display. Never compiled into CEL. */\n label: string;\n /** Canonical CEL literal stored on the condition and emitted in compiled CEL. */\n value: string;\n /** When set, selecting this option also sets the condition operator (e.g. `'is_not'` for a negated choice). */\n operator?: CelOperator;\n /** When true, the option cannot be toggled; hosts may handle the click via `onRestrictedOptionSelect`. */\n disabled?: boolean;\n};\n\n/** Payload for clicks on disabled checkbox/radio options. */\nexport type CelRestrictedOptionSelectPayload = {\n columnId: string;\n value: string;\n label: string;\n};\n\nexport type CelColumnDefinition = {\n /** Must match the API column id when targeting server-side resources. */\n id: string;\n /** Display name in the add-filter menu. */\n title: string;\n /**\n * Section heading this column is listed under in the add-filter menu. Sections appear in the\n * order each group name first occurs in `columns`; columns without a group are listed last\n * under no heading. Omit on every column to get a single flat alphabetical list.\n *\n * Group names are searchable: a phrase matching one keeps that entire section, on top of any\n * columns matched by title.\n */\n group?: string;\n /** Lowercase natural plural for consolidated multi-value pill copy (e.g. \"2 control planes\"). */\n pluralTitle: string;\n filterType: CelFilterType;\n /** Enum columns (checkbox / radio); static options only in v1. */\n options?: CelColumnOption[];\n /** Optional override; defaults from `filterType`. */\n allowedOperators?: CelOperator[];\n /** When true, hides the operator UI when only one operator is allowed. Defaults to `false`. */\n hideOnSingleOperator?: boolean;\n /** Pre-fill value when the condition is first added. Skips the initial \"pick a value\" step. */\n defaultValue?: CelConditionValue;\n /** When a valid compiled expression may be emitted. Defaults by `filterType`. */\n emitOn?: CelEmitOn;\n};\n\n/** Host-provided schema describing which columns are filterable for a given filter bar. */\nexport type CelFilterSchema = {\n columns: CelColumnDefinition[];\n};\n\n// --- Value shapes -----------------------------------------------------------\n\nexport type CheckboxCelValue = string[];\n\nexport type RadioCelValue = string;\n\nexport type TextCelValue = string;\n\nexport type MultiTextCelValue = {\n tokens: string[];\n /** Required when `tokens.length > 1`; defaults to `any` in the UI when omitted. */\n quantifier?: 'any' | 'all';\n};\n\n/** Trusted preset durations emitted as fixed literals in compiled CEL. */\nexport type RelativeDurationPreset = '24h' | '168h' | '720h';\n\nexport type DateCelValue = {\n /** RFC3339 UTC; required for single-point comparators. Mutually exclusive with `preset`. */\n instant?: string;\n /** Required for the range operators (`is_between` / `is_not_between`). Mutually exclusive with `preset`. */\n range?: {\n start: string;\n end: string;\n };\n /** Relative duration preset; mutually exclusive with `instant` / `range`. */\n preset?: RelativeDurationPreset;\n /**\n * True once the user edits a boundary time. While false the operator's default\n * day boundary applies, so an untouched condition compiles exactly as it did\n * before times were selectable. Never set without `instant` / `range` — the\n * `isDateCelValue` guard keys off those fields. Never compiled into CEL; a\n * future parser would need to re-derive it from the instants in the expression.\n */\n hasTime?: boolean;\n};\n\nexport type MapKeyCelValue = {\n key: string;\n /** Required when operator is `has_value` / `does_not_have_value`. */\n value?: string;\n};\n\n/**\n * Union of all condition value shapes. The active variant is determined by the\n * condition's `columnId` + schema `filterType`, not a discriminant on the value.\n */\nexport type CelConditionValue =\n CheckboxCelValue | RadioCelValue | TextCelValue | MultiTextCelValue | DateCelValue | MapKeyCelValue;\n\n// --- Tree nodes -------------------------------------------------------------\n\n/**\n * v1 always `and`; the shape is forward-compatible with `or` and nesting.\n * See `CelFilterGroup.children`, kept recursive so a future nested/OR-group UI\n * is additive rather than a breaking type change.\n */\nexport type CelCombinator = 'and';\n\nexport type CelFilterGroup = {\n id: string;\n type: 'group';\n combinator: CelCombinator;\n /** Root group is `0`. */\n depth: number;\n children: CelFilterNode[];\n};\n\nexport type CelFilterCondition = {\n id: string;\n type: 'condition';\n columnId: string;\n operator: CelOperator;\n /** Undefined on a newly added row until the user edits. */\n value?: CelConditionValue;\n};\n\nexport type CelFilterNode = CelFilterGroup | CelFilterCondition;\n\nexport type CelFilterTree = {\n root: CelFilterGroup;\n};\n\n// --- Validation -------------------------------------------------------------\n\n/** Closed union — `validateCondition` and `compileCelFilterTree` emit only these codes. */\nexport type ValidationIssueCode =\n // incomplete\n | 'missing_column'\n | 'missing_value'\n | 'missing_key'\n | 'missing_tokens'\n | 'missing_quantifier'\n | 'missing_instant'\n | 'missing_range'\n | 'missing_duration'\n // invalid\n | 'unknown_column'\n | 'illegal_operator'\n | 'invalid_date_mode'\n | 'regex_too_long'\n | 'invalid_timestamp'\n | 'invalid_date_range'\n | 'nesting_depth_exceeded';\n\nexport type ValidationSeverity = 'incomplete' | 'invalid';\n\nexport type ValidationIssue = {\n code: ValidationIssueCode;\n message: string;\n severity: ValidationSeverity;\n nodeId: string;\n nodeType: 'condition' | 'group';\n /** Sub-target within the condition (e.g. `value`, `key`, `instant`). */\n field?: string;\n};\n\nexport type CompileStatus = 'valid' | 'incomplete' | 'invalid';\n\nexport type CompileResult = {\n status: CompileStatus;\n /** Present when `status === 'valid'` (may be `\"\"`). */\n expression?: string;\n issues: ValidationIssue[];\n /** True iff the raw compile status is `valid`; the API / parent emission gate. */\n isEmitReady: boolean;\n};\n\n// --- Validation meta (draft / commit tracking) ------------------------------\n\nexport type CelValidationMeta = {\n editingConditionId: string | null;\n committedConditionIds: Set<string>;\n};\n\n/** Which pill sub-surface is open: operator picker, multiText quantifier, or the value editor. */\nexport type PillActiveSurface = 'operator' | 'quantifier' | 'value';\n\n// --- Public builder API -----------------------------------------------------\n\nexport type CelFilterBarProps = {\n tree: CelFilterTree;\n onChange: (tree: CelFilterTree) => void;\n schema: CelFilterSchema;\n onCompileResultChange?: (result: CompileResult) => void;\n /** Invoked when the user clicks a disabled option (instead of toggling the filter value). */\n onRestrictedOptionSelect?: (payload: CelRestrictedOptionSelectPayload) => void;\n /** Default `false`. */\n showClearButton?: boolean;\n className?: string;\n};\n\n// --- Type guards ------------------------------------------------------------\n\nexport const isCelFilterGroup = (node: CelFilterNode): node is CelFilterGroup => node.type === 'group';\n\nexport const isCelFilterCondition = (node: CelFilterNode): node is CelFilterCondition => node.type === 'condition';\n\n/** Checkbox values are arrays of option value strings. */\nexport const isCheckboxCelValue = (value: unknown): value is CheckboxCelValue =>\n Array.isArray(value) && value.every(item => typeof item === 'string');\n\n/** Radio / text values are bare strings. */\nexport const isStringCelValue = (value: unknown): value is string => typeof value === 'string';\n\nexport const isMultiTextCelValue = (value: unknown): value is MultiTextCelValue =>\n typeof value === 'object' && value !== null && 'tokens' in value;\n\nexport const isDateCelValue = (value: unknown): value is DateCelValue => {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n if ('tokens' in value || 'key' in value) {\n return false;\n }\n return 'preset' in value || 'instant' in value || 'range' in value || Object.keys(value).length === 0;\n};\n\nexport const isMapKeyCelValue = (value: unknown): value is MapKeyCelValue =>\n typeof value === 'object' && value !== null && 'key' in value;\n","import {\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from './types';\n\n/** Relative when a preset is set; preset and absolute fields are mutually exclusive. */\nexport function isRelativeDateCelValue(value: DateCelValue): boolean {\n return value.preset != null;\n}\n\nexport function readDateCelValue(value: unknown): DateCelValue {\n return isDateCelValue(value) ? value : {};\n}\n\nexport function readMapKeyCelValue(value: unknown): MapKeyCelValue {\n return isMapKeyCelValue(value) ? value : { key: '' };\n}\n\nexport function readMultiTextCelValue(value: unknown): MultiTextCelValue {\n return isMultiTextCelValue(value) ? value : { tokens: [] };\n}\n","/**\n * Escapes a user-provided string literal for safe embedding inside a CEL\n * double-quoted string. Callers wrap the result in `\"...\"` at the use site\n * (e.g. `column == \"${escapeCelString(value)}\"`).\n *\n * CEL generated output uses double-quoted strings only, so single quotes are\n * left untouched.\n */\nexport function escapeCelString(input: string): string {\n let out = '';\n\n for (const char of input) {\n switch (char) {\n case '\\\\':\n out += '\\\\\\\\';\n break;\n case '\"':\n out += '\\\\\"';\n break;\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n case '\\v':\n out += '\\\\v';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\0':\n out += '\\\\0';\n break;\n default:\n out += char;\n }\n }\n\n return out;\n}\n\n/** Convenience helper that escapes and wraps a value in double quotes. */\nexport function celStringLiteral(input: string): string {\n return `\"${escapeCelString(input)}\"`;\n}\n","/**\n * Operator metadata and CEL fragment generation.\n *\n * This is the single place that knows how `condition.operator` + value map to CEL\n * output. UI components never hand-write CEL — they read/write tree state and the\n * compiler walks it through here.\n */\nimport { type DateBoundary, inclusiveEndInstant } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterShape,\n type CelFilterType,\n type CelOperator,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { celStringLiteral } from './escape-cel-string';\n\n/** Schema column ids that collide with CEL reserved words (in the CEL library leveraged), mapped to safe CEL identifiers. */\nconst RESERVED_COLUMN_CEL_IDENTIFIERS: Record<string, string> = {\n namespace: '__namespace__',\n};\n\nconst CEL_IDENTIFIER_TO_COLUMN_ID = Object.fromEntries(\n Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).map(([columnId, celIdentifier]) => [celIdentifier, columnId]),\n);\n\nconst RESERVED_FIELD_OPERATOR_PATTERN = '(?=\\\\s*(?:in\\\\b|==|!=|<=|>=|<|>|\\\\.))';\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// --- Allowed operator sets --------------------------------------------------\n\nconst ENUM_OPERATORS: CelOperator[] = ['is', 'is_not'];\nconst TEXT_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'contains',\n 'does_not_contain',\n 'starts_with',\n 'ends_with',\n 'matches',\n];\nconst DATE_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'is_before',\n 'is_after',\n 'is_on_or_before',\n 'is_on_or_after',\n 'is_between',\n 'is_not_between',\n];\nconst MAP_OPERATORS: CelOperator[] = ['key_exists', 'key_does_not_exist', 'has_value', 'does_not_have_value'];\n\n/** Date comparators legal with a relative preset. */\nconst DATE_RELATIVE_OPERATORS: CelOperator[] = ['is_before', 'is_after', 'is_on_or_before', 'is_on_or_after'];\n\n/** Date operators that span a whole calendar day rather than compare against one instant. */\nconst DATE_WINDOW_OPERATORS: CelOperator[] = ['is', 'is_not'];\n\n/** Date operators that take a start/end range instead of a single instant. */\nconst DATE_RANGE_OPERATORS: CelOperator[] = ['is_between', 'is_not_between'];\n\n/**\n * Comparators whose bound sits at the end of the selected day/minute: \"on or\n * before Jul 23\" runs through 23:59:59.999, and \"after Jul 23\" starts once that\n * same instant has passed.\n */\nconst DATE_END_BOUNDARY_OPERATORS: CelOperator[] = ['is_on_or_before', 'is_after'];\n\nconst MAP_VALUE_OPERATORS: CelOperator[] = ['has_value', 'does_not_have_value'];\n\n/** Returns the operators allowed for a resolved filter shape. */\nexport function getAllowedOperatorsForShape(shape: CelFilterShape): CelOperator[] {\n switch (shape) {\n case 'checkbox':\n case 'radio':\n case 'static':\n return ENUM_OPERATORS;\n case 'text':\n case 'multiText':\n return TEXT_OPERATORS;\n case 'date':\n return DATE_OPERATORS;\n case 'map':\n return MAP_OPERATORS;\n default:\n return [];\n }\n}\n\n/**\n * Returns the operators allowed for a column. `allowedOperators` on a column\n * definition overrides the default set derived from its filter type.\n */\nexport function getAllowedOperators(columnDef?: CelColumnDefinition): CelOperator[] {\n if (!columnDef) {\n return [];\n }\n if (columnDef.allowedOperators) {\n return columnDef.allowedOperators;\n }\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n return getAllowedOperatorsForShape(shape);\n}\n\nexport function isDateRelativeOperator(operator: CelOperator): boolean {\n return DATE_RELATIVE_OPERATORS.includes(operator);\n}\n\n/** True for the date operators that match a whole calendar day and so take no time. */\nexport function isDateWindowOperator(operator: CelOperator): boolean {\n return DATE_WINDOW_OPERATORS.includes(operator);\n}\n\n/** True for the date operators whose value is a `range` rather than an `instant`. */\nexport function isDateRangeOperator(operator: CelOperator): boolean {\n return DATE_RANGE_OPERATORS.includes(operator);\n}\n\n/**\n * Which day boundary a date comparator compares against, and therefore the time\n * its input prefills with until the user edits it.\n */\nexport function dateBoundaryForOperator(operator: CelOperator): DateBoundary {\n return DATE_END_BOUNDARY_OPERATORS.includes(operator) ? 'end' : 'start';\n}\n\n// --- Schema resolution helpers ---------------------------------------------\n\nexport function resolveColumnDefinition(\n condition: Pick<CelFilterCondition, 'columnId'>,\n schema: CelFilterSchema,\n): CelColumnDefinition | undefined {\n if (!condition.columnId) {\n return undefined;\n }\n return schema.columns.find(column => column.id === condition.columnId);\n}\n\n/** Resolves the value/operator shape for a condition, or `undefined` for an unknown column. */\nexport function resolveFilterShape(\n condition: Pick<CelFilterCondition, 'columnId' | 'value'>,\n schema: CelFilterSchema,\n): CelFilterShape | undefined {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return undefined;\n }\n if (columnDef.filterType === 'keyValue') {\n return 'map';\n }\n if (columnDef.filterType === 'static') {\n return Array.isArray(condition.value) ? 'checkbox' : 'radio';\n }\n return columnDef.filterType;\n}\n\n// --- Operator labels --------------------------------------------------------\n\nconst OPERATOR_LABELS: Record<CelOperator, string> = {\n is: 'is',\n is_not: 'is not',\n contains: 'contains',\n does_not_contain: 'does not contain',\n starts_with: 'starts with',\n ends_with: 'ends with',\n matches: 'matches',\n is_before: 'is before',\n is_after: 'is after',\n is_on_or_before: 'is on or before',\n is_on_or_after: 'is on or after',\n is_between: 'is between',\n is_not_between: 'is not between',\n key_exists: 'key exists',\n key_does_not_exist: 'key does not exist',\n has_value: 'has value',\n does_not_have_value: 'does not have value',\n};\n\nexport function getOperatorLabel(operator: CelOperator): string {\n return OPERATOR_LABELS[operator];\n}\n\nexport function getQuantifierLabel(quantifier: 'any' | 'all'): string {\n return quantifier === 'all' ? 'all of' : 'any of';\n}\n\n// --- Multi-instance ---------------------------------------------------------\n\nconst SINGLE_INSTANCE_FILTER_TYPES: Set<CelFilterType> = new Set(['checkbox', 'radio', 'static']);\n\nexport function allowsMultipleConditions(filterType: CelFilterType): boolean {\n return !SINGLE_INSTANCE_FILTER_TYPES.has(filterType);\n}\n\n// --- Default operator on add -----------------------------------------------\n\nexport function getDefaultOperator(filterType: CelFilterType): CelOperator {\n switch (filterType) {\n case 'checkbox':\n case 'radio':\n case 'text':\n case 'static':\n return 'is';\n case 'multiText':\n return 'contains';\n case 'date':\n return 'is';\n case 'keyValue':\n return 'key_exists';\n default:\n return 'is';\n }\n}\n\n// --- Operator change value retention ----------------------------------------\n\n/**\n * Applies the minimal value-retention rules when the operator changes on an\n * existing condition. Returns a new condition; does not mutate the input.\n *\n * For dates, the clearing rules here are the enforcement half of the date state\n * machine the date editor implements: clear when the value shape changes (range\n * operators vs single-instant ones), or when a relative value would become\n * illegal under `is`/`is_not`, and drop a picked time when moving to a\n * whole-day operator. Keep both in sync.\n */\nexport function applyOperatorChange(\n condition: CelFilterCondition,\n newOperator: CelOperator,\n shape: CelFilterShape | undefined,\n): CelFilterCondition {\n const next: CelFilterCondition = { ...condition, operator: newOperator };\n const oldOperator = condition.operator;\n\n if (shape === 'date') {\n const value = condition.value;\n const isRelative = isDateCelValue(value) && isRelativeDateCelValue(value);\n // `is_between` ↔ `is_not_between` keep the range; swapping between a range\n // operator and a single-instant one cannot reuse the value.\n const changesValueShape = isDateRangeOperator(oldOperator) !== isDateRangeOperator(newOperator);\n const relativeNeedsClear = isRelative && (newOperator === 'is' || newOperator === 'is_not');\n\n if (changesValueShape || relativeNeedsClear) {\n next.value = undefined;\n return next;\n }\n if (isDateCelValue(value) && value.hasTime && isDateWindowOperator(newOperator)) {\n const { hasTime: _hasTime, ...dayOnly } = value;\n next.value = dayOnly;\n }\n return next;\n }\n\n if (shape === 'map') {\n const value = condition.value;\n if (!isMapKeyCelValue(value)) {\n return next;\n }\n const bothValueOps = MAP_VALUE_OPERATORS.includes(oldOperator) && MAP_VALUE_OPERATORS.includes(newOperator);\n next.value = bothValueOps ? { key: value.key, value: value.value } : { key: value.key };\n return next;\n }\n\n // checkbox / radio / text / multiText: every operator uses the same value shape.\n return next;\n}\n\n// --- CEL fragment generation ------------------------------------------------\n\nexport type ConditionExpression = {\n /** Raw CEL fragment without any outer grouping parentheses. */\n expression: string;\n /** True when the fragment has a bare top-level `||` and must be parenthesized to join under `&&`. */\n needsGrouping: boolean;\n};\n\nconst atomic = (expression: string): ConditionExpression => ({ expression, needsGrouping: false });\n\n/**\n * Builds the CEL fragment for a single condition. Assumes the condition has\n * already passed validation; callers must not pass incomplete/invalid conditions.\n */\nexport function buildConditionExpression(\n condition: CelFilterCondition,\n shape: CelFilterShape,\n columnDef?: CelColumnDefinition,\n): ConditionExpression {\n if (shape === 'map') {\n return buildMapExpression(condition.columnId, condition.operator, condition.value as MapKeyCelValue);\n }\n\n const columnId = columnDef?.id ?? condition.columnId ?? '';\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n\n switch (shape) {\n case 'checkbox':\n return buildCheckboxExpression(column, condition.operator, (condition.value as string[]) ?? []);\n case 'radio':\n return buildRadioExpression(column, condition.operator, String(condition.value ?? ''));\n case 'text':\n return atomic(buildTextTokenFragment(column, condition.operator, String(condition.value ?? '')));\n case 'multiText':\n return buildMultiTextExpression(column, condition.operator, condition.value as MultiTextCelValue);\n case 'date':\n return atomic(buildDateExpression(column, condition.operator, condition.value as DateCelValue));\n default:\n return atomic('');\n }\n}\n\nfunction buildCheckboxExpression(column: string, operator: CelOperator, values: string[]): ConditionExpression {\n const list = `${column} in [${values.map(celStringLiteral).join(', ')}]`;\n return atomic(operator === 'is_not' ? `!(${list})` : list);\n}\n\nfunction buildRadioExpression(column: string, operator: CelOperator, value: string): ConditionExpression {\n const literal = celStringLiteral(value);\n return atomic(operator === 'is_not' ? `${column} != ${literal}` : `${column} == ${literal}`);\n}\n\n/**\n * Builds the CEL fragment for a single text token. Single source of truth for\n * the text operator → CEL template mapping.\n *\n * `forcePositive` controls how the two negated operators (`is_not`,\n * `does_not_contain`) render:\n * - `false` (default): native negation (`col != \"x\"`, `!col.contains(\"x\")`).\n * Used for a lone token, where the negation lives on the token itself.\n * - `true`: the positive form (`col == \"x\"`, `col.contains(\"x\")`). Used when\n * composing multiple tokens, where the caller wraps the whole joined\n * expression in a single `!( … )` instead (see `buildMultiTextExpression`).\n */\nfunction buildTextTokenFragment(column: string, operator: CelOperator, value: string, forcePositive = false): string {\n const literal = celStringLiteral(value);\n switch (operator) {\n case 'is':\n return `${column} == ${literal}`;\n case 'is_not':\n return forcePositive ? `${column} == ${literal}` : `${column} != ${literal}`;\n case 'contains':\n return `${column}.contains(${literal})`;\n case 'does_not_contain':\n return forcePositive ? `${column}.contains(${literal})` : `!${column}.contains(${literal})`;\n case 'starts_with':\n return `${column}.startsWith(${literal})`;\n case 'ends_with':\n return `${column}.endsWith(${literal})`;\n case 'matches':\n return `${column}.matches(${literal})`;\n default:\n return '';\n }\n}\n\nfunction isNegatedTextOperator(operator: CelOperator): boolean {\n return operator === 'is_not' || operator === 'does_not_contain';\n}\n\nfunction buildMultiTextExpression(\n column: string,\n operator: CelOperator,\n value: MultiTextCelValue,\n): ConditionExpression {\n const tokens = value.tokens;\n\n if (tokens.length === 1) {\n return atomic(buildTextTokenFragment(column, operator, tokens[0]));\n }\n\n const connective = value.quantifier === 'all' ? ' && ' : ' || ';\n const joined = tokens.map(token => buildTextTokenFragment(column, operator, token, true)).join(connective);\n\n if (isNegatedTextOperator(operator)) {\n return atomic(`!(${joined})`);\n }\n\n // A bare top-level `||` (any quantifier) must be parenthesized when joined under `&&`.\n return { expression: joined, needsGrouping: value.quantifier !== 'all' };\n}\n\nconst DATE_RELATIVE_COMPARATOR_SYMBOLS: Partial<Record<CelOperator, string>> = {\n is_before: '<',\n is_after: '>',\n is_on_or_before: '<=',\n is_on_or_after: '>=',\n};\n\nfunction buildCalendarDayRange(column: string, startInstant: string, endInstant: string): string {\n const start = `timestamp(${celStringLiteral(startInstant)})`;\n const end = `timestamp(${celStringLiteral(endInstant)})`;\n return `${column} >= ${start} && ${column} <= ${end}`;\n}\n\nfunction buildDateExpression(column: string, operator: CelOperator, value: DateCelValue): string {\n if (isRelativeDateCelValue(value)) {\n const durationStr = value.preset ?? '';\n if (!durationStr) {\n return '';\n }\n const relativeSymbol = DATE_RELATIVE_COMPARATOR_SYMBOLS[operator] ?? '>';\n return `${column} ${relativeSymbol} now() - duration(${celStringLiteral(durationStr)})`;\n }\n\n if (isDateRangeOperator(operator) && value.range) {\n const range = buildCalendarDayRange(column, value.range.start, value.range.end);\n return operator === 'is_not_between' ? `!(${range})` : range;\n }\n\n const startInstant = value.instant ?? '';\n // `is` / `is_not` span a whole calendar day whatever the instant carries; the\n // comparators bound the minute the user picked once they have picked one.\n const granularity = value.hasTime && !isDateWindowOperator(operator) ? 'minute' : 'day';\n const endInstant = inclusiveEndInstant(startInstant, granularity);\n const startTimestamp = `timestamp(${celStringLiteral(startInstant)})`;\n const endTimestamp = `timestamp(${celStringLiteral(endInstant)})`;\n\n switch (operator) {\n case 'is':\n return buildCalendarDayRange(column, startInstant, endInstant);\n case 'is_not':\n return `!(${buildCalendarDayRange(column, startInstant, endInstant)})`;\n case 'is_before':\n return `${column} < ${startTimestamp}`;\n case 'is_on_or_before':\n return `${column} <= ${endTimestamp}`;\n case 'is_after':\n return `${column} > ${endTimestamp}`;\n case 'is_on_or_after':\n return `${column} >= ${startTimestamp}`;\n default:\n return `${column} == ${startTimestamp}`;\n }\n}\n\nfunction buildMapExpression(columnId: string, operator: CelOperator, value: MapKeyCelValue): ConditionExpression {\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n const keyLiteral = celStringLiteral(value.key);\n\n switch (operator) {\n case 'key_exists':\n return atomic(`${keyLiteral} in ${column}`);\n case 'key_does_not_exist':\n return atomic(`!(${keyLiteral} in ${column})`);\n case 'has_value':\n return atomic(`${column}[${keyLiteral}] == ${celStringLiteral(value.value ?? '')}`);\n case 'does_not_have_value':\n return atomic(`${column}[${keyLiteral}] != ${celStringLiteral(value.value ?? '')}`);\n default:\n return atomic('');\n }\n}\n\n/** Maps parsed CEL aliases back to schema column ids when building the filter tree. */\nexport function denormalizeColumnIdWithReservedNames(columnId: string): string {\n return CEL_IDENTIFIER_TO_COLUMN_ID[columnId] ?? columnId;\n}\n\n/** Rewrites reserved schema column references in a CEL expression before parsing. */\nexport function normalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (normalized, [columnId, celIdentifier]) =>\n normalized.replace(\n new RegExp(`\\\\b${escapeRegExp(columnId)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n celIdentifier,\n ),\n expression,\n );\n}\n\n/** Rewrites CEL aliases back to schema column names for API requests and external consumers. */\nexport function denormalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (denormalized, [columnId, celIdentifier]) =>\n denormalized.replace(\n new RegExp(`\\\\b${escapeRegExp(celIdentifier)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n columnId,\n ),\n expression,\n );\n}\n","import { MAX_REGEX_LEN } from '../constants';\nimport { isRealCalendarDay } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CompileStatus,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type ValidationIssue,\n type ValidationIssueCode,\n type ValidationSeverity,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { getAllowedOperators, isDateRangeOperator, isDateRelativeOperator, resolveColumnDefinition } from './operators';\n\n/** Derives the overall compile status from a set of issues (invalid beats incomplete beats valid). */\nexport function statusFromIssues(issues: ValidationIssue[]): CompileStatus {\n if (issues.some(issue => issue.severity === 'invalid')) {\n return 'invalid';\n }\n if (issues.some(issue => issue.severity === 'incomplete')) {\n return 'incomplete';\n }\n return 'valid';\n}\n\nconst SEVERITY_BY_CODE: Record<ValidationIssueCode, ValidationSeverity> = {\n missing_column: 'incomplete',\n missing_value: 'incomplete',\n missing_key: 'incomplete',\n missing_tokens: 'incomplete',\n missing_quantifier: 'incomplete',\n missing_instant: 'incomplete',\n missing_range: 'incomplete',\n missing_duration: 'incomplete',\n unknown_column: 'invalid',\n illegal_operator: 'invalid',\n invalid_date_mode: 'invalid',\n regex_too_long: 'invalid',\n invalid_timestamp: 'invalid',\n invalid_date_range: 'invalid',\n nesting_depth_exceeded: 'invalid',\n};\n\nconst MESSAGES: Record<ValidationIssueCode, string> = {\n missing_column: 'Select a column for this filter.',\n missing_value: 'Enter a value for this filter.',\n missing_key: 'Enter a key for this filter.',\n missing_tokens: 'Enter at least one value for this filter.',\n missing_quantifier: 'Choose whether to match any or all values.',\n missing_instant: 'Select a date for this filter.',\n missing_range: 'Select a start and end date for this filter.',\n missing_duration: 'Select a duration for this filter.',\n unknown_column: 'This column is not available for filtering.',\n illegal_operator: 'This operator is not allowed for this filter.',\n invalid_date_mode: 'This operator cannot be used with this date mode.',\n regex_too_long: `Pattern exceeds the maximum length of ${MAX_REGEX_LEN} characters.`,\n invalid_timestamp: 'Enter a valid date.',\n invalid_date_range: 'The start must be on or before the end.',\n nesting_depth_exceeded: 'This filter is nested too deeply.',\n};\n\n/** RFC3339 timestamp (date + time + Z or numeric offset). */\nconst RFC3339_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\n\nfunction isValidRfc3339(value: string): boolean {\n return RFC3339_RE.test(value) && !Number.isNaN(Date.parse(value)) && isRealCalendarDay(value);\n}\n\ntype IssueInput = {\n condition: CelFilterCondition;\n code: ValidationIssueCode;\n field?: string;\n};\n\nfunction makeIssue({ condition, code, field }: IssueInput): ValidationIssue {\n return {\n code,\n message: MESSAGES[code],\n severity: SEVERITY_BY_CODE[code],\n nodeId: condition.id,\n nodeType: 'condition',\n field,\n };\n}\n\n/**\n * Validates a single condition against the provided schema. Returns an empty\n * array when the condition is complete and compilable.\n */\nexport function validateCondition(condition: CelFilterCondition, schema: CelFilterSchema): ValidationIssue[] {\n if (!condition.columnId) {\n return [makeIssue({ condition, code: 'missing_column', field: 'columnId' })];\n }\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return [makeIssue({ condition, code: 'unknown_column', field: 'columnId' })];\n }\n return validateColumnCondition(condition, columnDef);\n}\n\nfunction validateColumnCondition(condition: CelFilterCondition, columnDef: CelColumnDefinition): ValidationIssue[] {\n const allowed = getAllowedOperators(columnDef);\n\n if (!allowed.includes(condition.operator)) {\n return [makeIssue({ condition, code: 'illegal_operator', field: 'operator' })];\n }\n\n switch (columnDef.filterType) {\n case 'checkbox':\n case 'static':\n return validateCheckbox(condition);\n case 'radio':\n case 'text':\n return validateSingleString(condition, columnDef.filterType);\n case 'multiText':\n return validateMultiText(condition);\n case 'date':\n return validateDate(condition);\n case 'keyValue':\n return validateMapCondition(condition);\n default:\n return [];\n }\n}\n\nfunction validateCheckbox(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!Array.isArray(value) || value.length === 0) {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n return [];\n}\n\nfunction validateSingleString(condition: CelFilterCondition, filterType: 'radio' | 'text'): ValidationIssue[] {\n const value = condition.value;\n if (typeof value !== 'string' || value === '') {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n if (filterType === 'text' && condition.operator === 'matches' && value.length > MAX_REGEX_LEN) {\n return [makeIssue({ condition, code: 'regex_too_long', field: 'pattern' })];\n }\n return [];\n}\n\nfunction validateMultiText(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!isMultiTextCelValue(value) || value.tokens.length === 0) {\n return [makeIssue({ condition, code: 'missing_tokens', field: 'tokens' })];\n }\n\n const issues: ValidationIssue[] = [];\n const multi = value as MultiTextCelValue;\n\n if (multi.tokens.length > 1 && !multi.quantifier) {\n issues.push(makeIssue({ condition, code: 'missing_quantifier', field: 'quantifier' }));\n }\n\n if (condition.operator === 'matches' && multi.tokens.some(token => token.length > MAX_REGEX_LEN)) {\n issues.push(makeIssue({ condition, code: 'regex_too_long', field: 'pattern' }));\n }\n\n return issues;\n}\n\nfunction validateDate(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n\n if (!isDateCelValue(value)) {\n // Freshly added / undefined date condition — treat as a missing single-point instant.\n return [makeIssue({ condition, code: 'missing_instant', field: 'instant' })];\n }\n\n const date = value as DateCelValue;\n\n if (isRelativeDateCelValue(date)) {\n return validateRelativeDate(condition, date);\n }\n return validateAbsoluteDate(condition, date);\n}\n\nfunction validateAbsoluteDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (isDateRangeOperator(condition.operator)) {\n const range = value.range;\n if (!range || !range.start || !range.end) {\n issues.push(makeIssue({ condition, code: 'missing_range', field: 'range' }));\n return issues;\n }\n if (!isValidRfc3339(range.start)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'start' }));\n }\n if (!isValidRfc3339(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'end' }));\n }\n if (issues.length === 0 && Date.parse(range.start) > Date.parse(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_range', field: 'range' }));\n }\n return issues;\n }\n\n if (!value.instant) {\n issues.push(makeIssue({ condition, code: 'missing_instant', field: 'instant' }));\n return issues;\n }\n if (!isValidRfc3339(value.instant)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'instant' }));\n }\n return issues;\n}\n\nfunction validateRelativeDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (!isDateRelativeOperator(condition.operator)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_mode', field: 'value' }));\n return issues;\n }\n\n if (!value.preset) {\n issues.push(makeIssue({ condition, code: 'missing_duration', field: 'preset' }));\n }\n return issues;\n}\n\nfunction validateMapCondition(condition: CelFilterCondition): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n const value = isMapKeyCelValue(condition.value) ? (condition.value as MapKeyCelValue) : undefined;\n\n if (!value || value.key === '') {\n issues.push(makeIssue({ condition, code: 'missing_key', field: 'key' }));\n }\n\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (requiresValue && (!value || !value.value)) {\n issues.push(makeIssue({ condition, code: 'missing_value', field: 'value' }));\n }\n\n return issues;\n}\n","/**\n * Applies draft/commit display rules to a raw compile result.\n *\n * Validation timing: a condition's issues are surfaced on its pill and in the\n * global panel only once it has been committed (popover closed) and is not\n * currently being edited. Group-level issues (e.g. nesting depth) always show.\n *\n * `isEmitReady` on the returned object is always `false` here — it is a\n * placeholder that `CelFilterBar` overrides via `computeIsEmitReady` before\n * calling `onCompileResultChange`. This is the single source of truth for the gate.\n */\nimport { type CelValidationMeta, type CompileResult } from '../types';\nimport { statusFromIssues } from './validate-condition';\n\nexport function applyDisplayRules(raw: CompileResult, meta: CelValidationMeta): CompileResult {\n const issues = raw.issues.filter(issue => {\n if (issue.nodeType === 'group') {\n return true;\n }\n if (issue.nodeId === meta.editingConditionId) {\n return false;\n }\n return meta.committedConditionIds.has(issue.nodeId);\n });\n\n const status = statusFromIssues(issues);\n const expression = status === 'valid' ? raw.expression : undefined;\n\n return {\n status,\n expression,\n issues,\n isEmitReady: false,\n };\n}\n","import { resolveFilterShape } from './compile/operators';\nimport type { CelColumnDefinition, CelEmitOn, CelFilterCondition, CelFilterSchema } from './types';\nimport { readMapKeyCelValue } from './value-utils';\n\nconst COMMIT_FILTER_TYPES = new Set<CelColumnDefinition['filterType']>(['text', 'multiText', 'keyValue', 'date']);\n\nexport function isMultiTextColumn(columnId: string, schema: CelFilterSchema): boolean {\n return schema.columns.find(column => column.id === columnId)?.filterType === 'multiText';\n}\n\n/** Returns when a column's valid value may be emitted; explicit `emitOn` overrides filterType defaults. */\nexport function getColumnEmitOn(columnDef: CelColumnDefinition): CelEmitOn {\n if (columnDef.emitOn) {\n return columnDef.emitOn;\n }\n return COMMIT_FILTER_TYPES.has(columnDef.filterType) ? 'commit' : 'change';\n}\n\n/** After operator change, keyValue may need the value field before the condition is complete. */\nexport function shouldOpenValueSurfaceAfterOperatorChange(\n condition: CelFilterCondition,\n schema: CelFilterSchema,\n): boolean {\n if (resolveFilterShape(condition, schema) !== 'map') {\n return false;\n }\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (!requiresValue) {\n return false;\n }\n return !readMapKeyCelValue(condition.value).value?.trim();\n}\n","import { getColumnEmitOn } from '../schema-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n type PillActiveSurface,\n} from '../types';\n\nexport type ComputeIsEmitReadyMeta = {\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n};\n\nfunction resolveEditingColumn(\n tree: CelFilterTree,\n schema: CelFilterSchema,\n editingConditionId: string,\n): CelColumnDefinition | undefined {\n const condition = tree.root.children.find(\n (child): child is CelFilterCondition => isCelFilterCondition(child) && child.id === editingConditionId,\n );\n return condition && schema.columns.find(column => column.id === condition.columnId);\n}\n\n/**\n * Gates API emission while a commit-mode condition is mid-edit. Only the\n * actively edited condition matters — one popover at a time.\n */\nexport function computeIsEmitReady(\n raw: CompileResult,\n editingConditionId: string | null,\n schema: CelFilterSchema,\n tree: CelFilterTree,\n meta: ComputeIsEmitReadyMeta,\n): boolean {\n if (raw.status !== 'valid') return false;\n if (!editingConditionId) return true;\n\n const columnDef = resolveEditingColumn(tree, schema, editingConditionId);\n // Unknown column or change-mode → nothing to gate, emit live.\n if (!columnDef || getColumnEmitOn(columnDef) === 'change') return true;\n\n // Commit-mode: emit only once the popover is closed and the draft committed.\n const popoverClosed = meta.activeSurface === null;\n return popoverClosed && meta.committedConditionIds.has(editingConditionId);\n}\n","/**\n * Compiles a CEL filter tree into a CEL string or structured validation issues.\n *\n * Pure logic — no React, no display rules. `CelFilterBar` composes\n * `applyDisplayRules(compileCelFilterTree(tree, schema), meta)`.\n */\nimport { MAX_NESTING_DEPTH } from '../constants';\nimport {\n type CelColumnDefinition,\n type CelFilterGroup,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n isCelFilterGroup,\n type ValidationIssue,\n} from '../types';\nimport {\n buildConditionExpression,\n type ConditionExpression,\n resolveColumnDefinition,\n resolveFilterShape,\n} from './operators';\nimport { statusFromIssues, validateCondition } from './validate-condition';\n\ntype GroupCompileResult = {\n issues: ValidationIssue[];\n fragments: ConditionExpression[];\n};\n\n/**\n * Combines a group's child fragments into a single fragment.\n *\n * v1 groups are always `&&`. A child fragment with a bare top-level `||`\n * (e.g. a multiText `any`) is parenthesized before joining so precedence is\n * preserved. The produced fragment reports whether *it* needs grouping when\n * placed under a parent `&&`:\n *\n * - 0 children → empty fragment.\n * - 1 child → propagated as-is so the parent decides on parens (a lone `||`\n * fragment must still be wrapped by whoever joins it under `&&`).\n * - >1 children → a pure `&&` chain, which never needs outer parens under `&&`.\n *\n * (If a future `||` group combinator ships, the connective and `needsGrouping`\n * become combinator-aware; today every group is `&&`.)\n */\nfunction combineGroupFragments(fragments: ConditionExpression[]): ConditionExpression {\n if (fragments.length === 0) {\n return { expression: '', needsGrouping: false };\n }\n if (fragments.length === 1) {\n return fragments[0];\n }\n return {\n expression: fragments\n .map(fragment => (fragment.needsGrouping ? `(${fragment.expression})` : fragment.expression))\n .join(' && '),\n needsGrouping: false,\n };\n}\n\nfunction compileGroup(group: CelFilterGroup, schema: CelFilterSchema): GroupCompileResult {\n const depthIssues: ValidationIssue[] =\n group.depth > MAX_NESTING_DEPTH\n ? [\n {\n code: 'nesting_depth_exceeded',\n message: 'This filter is nested too deeply.',\n severity: 'invalid',\n nodeId: group.id,\n nodeType: 'group',\n },\n ]\n : [];\n\n return group.children.reduce<GroupCompileResult>(\n (acc, child) => {\n if (isCelFilterGroup(child)) {\n const nested = compileGroup(child, schema);\n acc.issues.push(...nested.issues);\n if (nested.fragments.length > 0) {\n acc.fragments.push(combineGroupFragments(nested.fragments));\n }\n return acc;\n }\n\n if (isCelFilterCondition(child)) {\n const conditionIssues = validateCondition(child, schema);\n if (conditionIssues.length > 0) {\n acc.issues.push(...conditionIssues);\n return acc;\n }\n\n const shape = resolveFilterShape(child, schema);\n if (!shape) {\n return acc;\n }\n const columnDef: CelColumnDefinition | undefined = resolveColumnDefinition(child, schema);\n acc.fragments.push(buildConditionExpression(child, shape, columnDef));\n }\n\n return acc;\n },\n { issues: depthIssues, fragments: [] },\n );\n}\n\n/**\n * Walks the tree, joins root children with ` && `, and emits a CEL string when\n * everything is complete and valid. An empty root compiles to `\"\"` with status\n * `valid` (the API treats an empty filter as no filter).\n */\nexport function compileCelFilterTree(tree: CelFilterTree, schema: CelFilterSchema): CompileResult {\n const { issues, fragments } = compileGroup(tree.root, schema);\n const status = statusFromIssues(issues);\n\n if (status === 'valid') {\n return { status, expression: combineGroupFragments(fragments).expression, issues, isEmitReady: true };\n }\n\n return { status, issues, isEmitReady: false };\n}\n","/**\n * Tree factories and helpers for the CEL filter builder.\n */\nimport { getDefaultOperator } from './compile/operators';\nimport { isCelFilterCondition } from './types';\nimport type { CelFilterCondition, CelFilterSchema, CelFilterTree } from './types';\n\n/** Generates a stable unique id, falling back when `crypto.randomUUID` is unavailable. */\nexport function createCelNodeId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `cel-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Creates an empty tree whose root is a depth-0 `and` group with no children. */\nexport function createEmptyCelFilterTree(): CelFilterTree {\n return {\n root: {\n id: createCelNodeId(),\n type: 'group',\n combinator: 'and',\n depth: 0,\n children: [],\n },\n };\n}\n\nexport type CreateDefaultConditionParams = {\n schema: CelFilterSchema;\n columnId: string;\n};\n\n/**\n * Creates a new condition with the default operator for its column and an\n * undefined value (filled in by the user in the popover).\n */\nexport function createDefaultCondition({ schema, columnId }: CreateDefaultConditionParams): CelFilterCondition {\n const columnDef = schema.columns.find(column => column.id === columnId);\n if (!columnDef) {\n throw new Error(`createDefaultCondition: column \"${columnId}\" is not in schema.columns`);\n }\n\n return {\n id: createCelNodeId(),\n type: 'condition',\n columnId,\n operator: getDefaultOperator(columnDef.filterType),\n value: columnDef.defaultValue,\n };\n}\n\n/** Appends a condition to the root group's children. */\nexport function appendCondition(tree: CelFilterTree, condition: CelFilterCondition): CelFilterTree {\n return { root: { ...tree.root, children: [...tree.root.children, condition] } };\n}\n\n/** Replaces a root-level condition by id, applying `updater` to the existing condition. Root-level only — v1's UI never produces nested groups. */\nexport function replaceCondition(\n tree: CelFilterTree,\n conditionId: string,\n updater: (condition: CelFilterCondition) => CelFilterCondition,\n): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.map(child =>\n isCelFilterCondition(child) && child.id === conditionId ? updater(child) : child,\n ),\n },\n };\n}\n\n/** Removes a root-level condition by id. */\nexport function removeConditionById(tree: CelFilterTree, conditionId: string): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.filter(child => !(isCelFilterCondition(child) && child.id === conditionId)),\n },\n };\n}\n","import { calendarDayStartInstant } from './date-utils';\nimport { createCelNodeId } from './tree-utils';\nimport {\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterTree,\n isCelFilterCondition,\n isCheckboxCelValue,\n isMapKeyCelValue,\n} from './types';\n\nfunction upsertCondition(\n tree: CelFilterTree,\n matches: (condition: CelFilterCondition) => boolean,\n build: (existing: CelFilterCondition | undefined) => Omit<CelFilterCondition, 'id'>,\n): CelFilterTree {\n const index = tree.root.children.findIndex(child => isCelFilterCondition(child) && matches(child));\n const found = tree.root.children[index];\n const existing = index >= 0 && isCelFilterCondition(found) ? found : undefined;\n const condition: CelFilterCondition = {\n id: existing?.id ?? createCelNodeId(),\n ...build(existing),\n };\n\n const children =\n index >= 0\n ? tree.root.children.map((child, i) => (i === index ? condition : child))\n : [...tree.root.children, condition];\n return { root: { ...tree.root, children } };\n}\n\nfunction mergeKeyValueToken(tree: CelFilterTree, columnId: string, token: string): CelFilterTree {\n const [key, ...rest] = token.split('=');\n const mapValue = rest.join('=');\n return upsertCondition(\n tree,\n condition => condition.columnId === columnId && isMapKeyCelValue(condition.value) && condition.value.key === key,\n () => ({\n type: 'condition',\n columnId,\n operator: mapValue ? 'has_value' : 'key_exists',\n value: mapValue ? { key, value: mapValue } : { key },\n }),\n );\n}\n\n/** Upserts (or unions, for checkbox) an externally-provided value into the tree by column type. */\nexport function mergeContextualIntoCelTree(\n tree: CelFilterTree,\n schema: CelFilterSchema,\n columnId: string,\n values: string[],\n): CelFilterTree {\n if (values.length === 0) {\n return tree;\n }\n\n const columnDef = schema.columns.find(column => column.id === columnId);\n if (!columnDef) {\n return tree;\n }\n\n const matchesColumn = (condition: CelFilterCondition) => condition.columnId === columnId;\n\n switch (columnDef.filterType) {\n case 'checkbox':\n return upsertCondition(tree, matchesColumn, existing => ({\n type: 'condition',\n columnId,\n operator: 'is',\n value: Array.from(\n new Set([...(existing && isCheckboxCelValue(existing.value) ? existing.value : []), ...values]),\n ),\n }));\n case 'keyValue':\n return values.reduce((acc, token) => mergeKeyValueToken(acc, columnId, token), tree);\n case 'multiText':\n return upsertCondition(tree, matchesColumn, () => ({\n type: 'condition',\n columnId,\n operator: 'contains',\n value: { tokens: values, quantifier: 'any' },\n }));\n case 'date':\n return upsertCondition(tree, matchesColumn, () => ({\n type: 'condition',\n columnId,\n operator: 'is',\n value: { instant: calendarDayStartInstant(values[0]) },\n }));\n default:\n return upsertCondition(tree, matchesColumn, () => ({\n type: 'condition',\n columnId,\n operator: 'is',\n value: values[0],\n }));\n }\n}\n"],"mappings":"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","names":[]}
|