@upbound/monarch-blocks 0.4.1 → 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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/graph/graph-actions-provider.tsx","../src/graph/hooks/useGraphActionsContext.ts","../src/graph/hooks/useGraphActions.ts","../src/graph/graph-node.tsx","../src/lib/utils.ts","../src/graph/consts.ts","../src/graph/graph-edge.tsx","../src/graph/graph.tsx","../src/lib/data-table/contextual-filters.ts","../src/lib/data-table/utils.ts","../src/data-table/empty-view.tsx","../src/data-table/view-filter.tsx","../src/filter-bar/filter-bar.tsx","../src/lib/data-table/filter-types.ts","../src/section-header.tsx","../src/graph/graph-view.tsx","../src/graph/hooks/useAutoLayout.ts","../src/graph/hooks/useNodeVisibility.ts","../src/graph/hooks/useGetViewportNodeIds.ts","../src/graph/utils.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Edge } from 'reactflow';\n\nimport { NodeDefault, NodeLoading } from './graph-node';\nimport { GraphActionsContext } from './hooks/useGraphActionsContext';\nimport { useGraphActions } from './hooks/useGraphActions';\n\ninterface GraphActionsProviderProps {\n initialNodes?: (NodeLoading | NodeDefault)[];\n initialEdges?: Edge[];\n children: React.ReactNode;\n}\n\nexport interface GraphActionsProviderRef {\n addNodes: (newNodes: (NodeLoading | NodeDefault)[]) => void;\n addEdges: (newEdges: Edge[]) => void;\n setNodes: (nodes: (NodeLoading | NodeDefault)[]) => void;\n setEdges: (edges: Edge[]) => void;\n toggleNodeExpansion: (nodeId: string) => void;\n updateNode: (nodeId: string, node: NodeLoading | NodeDefault) => void;\n reset: () => void;\n}\n\nconst GraphActionsProvider = React.forwardRef<GraphActionsProviderRef, GraphActionsProviderProps>(\n ({ initialNodes = [], initialEdges = [], children }, ref) => {\n const graphActions = useGraphActions(initialNodes, initialEdges);\n\n React.useImperativeHandle(\n ref,\n () => ({\n addNodes: graphActions.addNodes,\n addEdges: graphActions.addEdges,\n setNodes: graphActions.setNodes,\n setEdges: graphActions.setEdges,\n toggleNodeExpansion: graphActions.toggleNodeExpansion,\n updateNode: graphActions.updateNode,\n reset: graphActions.resetGraph,\n }),\n [graphActions],\n );\n\n return <GraphActionsContext.Provider value={graphActions}>{children}</GraphActionsContext.Provider>;\n },\n);\n\nGraphActionsProvider.displayName = 'GraphActionsProvider';\n\nexport { GraphActionsProvider };\n","import { createContext, useContext } from 'react';\n\nimport { GraphActions } from './useGraphActions';\n\nexport const GraphActionsContext = createContext<GraphActions | null>(null);\n\nexport const useGraphActionsContext = (): GraphActions => {\n const context = useContext(GraphActionsContext);\n if (!context) {\n throw new Error('useGraphActionsContext must be used within GraphActionsProvider');\n }\n return context;\n};\n","import { useCallback, useState } from 'react';\nimport { Edge } from 'reactflow';\n\nimport { isDefaultNode, NodeDefault, NodeLoading } from '../graph-node';\n\nexport interface GraphActions {\n nodes: (NodeLoading | NodeDefault)[];\n edges: Edge[];\n addNodes: (newNodes: (NodeLoading | NodeDefault)[]) => void;\n addEdges: (newEdges: Edge[]) => void;\n removeNodes: (nodeIds: string[]) => void;\n removeEdges: (edgeIds: string[]) => void;\n setNodes: (nodes: (NodeLoading | NodeDefault)[]) => void;\n setEdges: (edges: Edge[]) => void;\n updateNode: (nodeId: string, node: NodeLoading | NodeDefault) => void;\n toggleNodeExpansion: (nodeId: string) => void;\n resetGraph: () => void;\n}\n\nexport const useGraphActions = (\n initialNodes: (NodeLoading | NodeDefault)[] = [],\n initialEdges: Edge[] = [],\n): GraphActions => {\n const [nodes, setNodes] = useState<(NodeLoading | NodeDefault)[]>(initialNodes);\n const [edges, setEdges] = useState<Edge[]>(initialEdges);\n\n const addNodes = useCallback((newNodes: (NodeLoading | NodeDefault)[]) => {\n setNodes(prevNodes => {\n // Filter out nodes that already exist to avoid duplicates\n const existingIds = new Set(prevNodes.map(node => node.id));\n const uniqueNewNodes = newNodes.filter(node => !existingIds.has(node.id));\n return [...prevNodes, ...uniqueNewNodes];\n });\n }, []);\n\n const addEdges = useCallback((newEdges: Edge[]) => {\n setEdges(prevEdges => {\n // Filter out edges that already exist to avoid duplicates\n const existingIds = new Set(prevEdges.map(edge => edge.id));\n const uniqueNewEdges = newEdges.filter(edge => !existingIds.has(edge.id));\n return [...prevEdges, ...uniqueNewEdges];\n });\n }, []);\n\n const removeNodes = useCallback((nodeIds: string[]) => {\n const nodeIdSet = new Set(nodeIds);\n\n setNodes(prevNodes => prevNodes.filter(node => !nodeIdSet.has(node.id)));\n\n // Also remove edges connected to removed nodes\n setEdges(prevEdges => prevEdges.filter(edge => !nodeIdSet.has(edge.source) && !nodeIdSet.has(edge.target)));\n }, []);\n\n const removeEdges = useCallback((edgeIds: string[]) => {\n const edgeIdSet = new Set(edgeIds);\n setEdges(prevEdges => prevEdges.filter(edge => !edgeIdSet.has(edge.id)));\n }, []);\n\n const resetGraph = useCallback(() => {\n setNodes(initialNodes);\n setEdges(initialEdges);\n }, [initialNodes, initialEdges]);\n\n const updateNode = useCallback((nodeId: string, node: NodeLoading | NodeDefault) => {\n setNodes(prevNodes => prevNodes.map(n => (n.id === nodeId ? node : n)));\n }, []);\n\n const toggleNodeExpansion = useCallback((nodeId: string) => {\n setNodes(prevNodes =>\n prevNodes.map(node => {\n if (node.id === nodeId && isDefaultNode(node)) {\n return {\n ...node,\n data: {\n ...node.data,\n expanded: !node.data.expanded,\n },\n };\n }\n return node;\n }),\n );\n }, []);\n\n return {\n nodes,\n edges,\n addNodes,\n addEdges,\n removeNodes,\n removeEdges,\n setNodes,\n setEdges,\n resetGraph,\n updateNode,\n toggleNodeExpansion,\n };\n};\n","'use client';\n\nimport * as React from 'react';\nimport { getIncomers, getOutgoers, Handle, Node, NodeProps, Position } from 'reactflow';\n\nimport { Badge, Card, Icon, Spinner, Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\n\nimport {\n GRAPH_NODE_COLLAPSED_HEIGHT,\n GRAPH_NODE_HEIGHT,\n GRAPH_NODE_SEP,\n GRAPH_NODE_WIDTH,\n GRAPH_RANK_SEP,\n} from './consts';\nimport { GraphEdge } from './graph-edge';\nimport { useGraphActionsContext } from './hooks/useGraphActionsContext';\n\nexport type GraphBadgeVariant =\n | 'default'\n | 'secondary'\n | 'destructive'\n | 'outline'\n | 'ghost'\n | 'link'\n | 'healthy'\n | 'unhealthy'\n | 'warning'\n | 'stale'\n | 'info'\n | 'unknown';\n\ntype BadgeWithTooltip = {\n variant?: GraphBadgeVariant;\n tooltipContent?: string;\n children: React.ReactNode;\n};\n\nexport interface NodeData<T extends object = object> {\n rawData: T;\n title: string;\n subtitle: string;\n name: string;\n typeDescriptors: {\n className?: string;\n default: string;\n compact?: string;\n };\n badges: {\n default: BadgeWithTooltip[];\n compact?: BadgeWithTooltip[];\n };\n // Additional properties for GraphNode functionality\n compact?: boolean;\n state?: 'default' | 'progressing' | 'paused';\n onClick?: (nodeId: string, data: NodeData) => void;\n // Additional properties for expanding the node\n expanded?: boolean;\n onExpandToggle?: (nodeId: string) => void;\n isExpandable?: boolean;\n isHighlighted?: boolean;\n}\n\n// Node types\nexport type NodeLoading = Node & { type: 'loading'; data?: {} };\nexport type NodeDefault<T extends object = object> = Node<NodeData<T>> & { type?: 'default' };\n\n// Type predicate to check if node is default (not loading)\nexport function isDefaultNode(node: NodeLoading | NodeDefault): node is NodeDefault {\n return node.type !== 'loading';\n}\n\nexport type GraphNodeProps<T extends NodeData | {}> = NodeProps<T>;\n\nexport function GraphNode<T extends NodeData = NodeData>({ id, data, ...props }: GraphNodeProps<T>) {\n const { nodes: originalNodes, edges: originalEdges } = useGraphActionsContext();\n\n // Use original data for edge calculations\n const nodes = originalNodes;\n const edges = originalEdges;\n\n const handleClick = React.useCallback(() => {\n data?.onClick?.(id, data);\n }, [data, id]);\n\n const compact = data?.compact ?? false;\n const state = data?.state ?? 'default';\n\n const compactBadges: BadgeWithTooltip[] = React.useMemo(() => {\n const badges = data.badges.compact || [];\n if (state === 'paused') {\n return [\n { children: <Icon name=\"pause\" size=\"xs\" />, variant: 'secondary', tooltipContent: 'Resource is paused' },\n ...badges,\n ];\n }\n return badges;\n }, [data.badges.compact, state]);\n\n const defaultBadges: BadgeWithTooltip[] = React.useMemo(() => {\n const badges = data.badges.default || [];\n if (state === 'paused') {\n return [\n {\n children: (\n <>\n <Icon name=\"pause\" size=\"xs\" className=\"mr-1\" /> Paused\n </>\n ),\n variant: 'secondary',\n tooltipContent: 'Resource is paused',\n },\n ...badges,\n ];\n }\n return badges;\n }, [data.badges.default, state]);\n\n // Create a node object for edge calculations\n const currentNode = React.useMemo(\n () => ({\n id,\n position: { x: 0, y: 0 }, // Position not needed for edge calculations\n data,\n type: props.type,\n }),\n [id, data, props.type],\n );\n\n const _hasIncomingEdge = React.useMemo(() => {\n return getIncomers(currentNode, nodes, edges).length > 0;\n }, [currentNode, nodes, edges]);\n\n const hasOutgoingEdge = React.useMemo(() => {\n return getOutgoers(currentNode, nodes, edges).length > 0;\n }, [currentNode, nodes, edges]);\n\n const targetX = GRAPH_NODE_WIDTH / 2 - 4;\n const sourceX = 4;\n\n return (\n <Card\n className={cn(\n 'relative gap-1.5 overflow-visible rounded-lg py-0',\n `flex h-[106px]! w-[260px]! flex-col pt-2.5! pb-0!`,\n `hover:shadow-md motion-safe:transition-shadow`,\n compact && `h-[47px]!`,\n )}\n style={{ height: compact ? GRAPH_NODE_COLLAPSED_HEIGHT : GRAPH_NODE_HEIGHT, width: GRAPH_NODE_WIDTH }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={{\n visibility: 'hidden',\n width: 0,\n }}\n isConnectable={false}\n />\n <div className=\"flex w-full flex-1 cursor-pointer flex-col\" onClick={handleClick}>\n <div className={cn('flex w-full justify-between gap-1 px-2.5', compact && 'flex-row-reverse items-start')}>\n {!!compact && (\n <>\n {compactBadges.length > 0 && (\n <div className=\"flex shrink-0 flex-row items-center gap-1.5 overflow-hidden\">\n {compactBadges.map(({ tooltipContent, variant, ...badge }, index) => (\n <Tooltip key={index}>\n <TooltipTrigger>\n <Badge\n variant={variant}\n {...badge}\n className=\"flex size-[20px]! cursor-default! items-center justify-center p-0!\"\n >\n {badge.children}\n </Badge>\n </TooltipTrigger>\n {tooltipContent && <TooltipContent>{tooltipContent}</TooltipContent>}\n </Tooltip>\n ))}\n </div>\n )}\n {state === 'progressing' && (\n <div className=\"flex shrink-0 flex-row items-center gap-1.5 overflow-hidden\">\n <div className=\"flex size-[20px]! items-center justify-center\">\n <Spinner size=\"sm\" />\n </div>\n </div>\n )}\n </>\n )}\n <div className=\"mr-auto grow-0 overflow-hidden\">\n <h5 className=\"text-body-sm/tight truncate font-bold\">{data.title}</h5>\n <p className=\"text-body-sm truncate leading-none\">{data.subtitle}</p>\n {!compact && <p className=\"text-body-sm text-muted-foreground mt-1 truncate\">{data.name}</p>}\n </div>\n <span\n className={cn(\n 'bg-foreground text-background inline-flex h-[26px] w-auto shrink-0 items-center justify-center rounded-md px-[7px] text-[10px] font-semibold',\n ['progressing', 'paused'].includes(state) && 'opacity-30',\n data.typeDescriptors.className,\n )}\n >\n {data.typeDescriptors.default}\n </span>\n </div>\n {!compact && (\n <>\n {(defaultBadges.length > 0 || state === 'progressing') && (\n <div className=\"mt-auto flex h-8 items-center border-t px-2.5\">\n <div className=\"flex gap-1.5 overflow-hidden overflow-x-auto\">\n {defaultBadges.map(({ tooltipContent, variant, ...badge }, index) => (\n <Tooltip key={index}>\n <TooltipTrigger>\n <Badge variant={variant} {...badge} className=\"cursor-default! py-px! whitespace-nowrap\">\n {badge.children}\n </Badge>\n </TooltipTrigger>\n {tooltipContent && <TooltipContent>{tooltipContent}</TooltipContent>}\n </Tooltip>\n ))}\n </div>\n {state === 'progressing' && (\n <div className=\"ml-auto flex size-[20px]! items-center justify-center\">\n <Spinner size=\"sm\" />\n </div>\n )}\n </div>\n )}\n </>\n )}\n </div>\n {!!hasOutgoingEdge && (\n <div\n className=\"absolute top-0 right-0 h-full w-auto translate-x-full\"\n style={{\n width: GRAPH_RANK_SEP,\n }}\n >\n <svg height={20} width={GRAPH_NODE_SEP} className=\"absolute top-1/2 -translate-y-1/2\">\n <GraphEdge\n id={`${id}-expadable`}\n sourceX={sourceX}\n sourceY={10}\n targetX={targetX}\n targetY={10}\n sourcePosition={Position.Right}\n targetPosition={Position.Left}\n source={id}\n target={id}\n stopOpacity={0}\n />\n </svg>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={data.expanded ? 'Collapse' : 'Expand'}\n className=\"bg-foreground text-background hover:bg-foreground/90 focus-visible:ring-ring/30 absolute top-[calc(50%)] left-[calc(50%)] inline-flex size-4 -translate-1/2 items-center justify-center rounded-full p-0 text-center text-[10px] leading-none duration-150 outline-none focus-visible:ring-2 motion-safe:transition-colors\"\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n data.onExpandToggle?.(id);\n }}\n >\n <Icon name={data.expanded ? 'minus' : 'plus'} size=\"xs\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>{data.expanded ? 'Collapse' : 'Expand'}</TooltipContent>\n </Tooltip>\n </div>\n )}\n <Handle\n type=\"source\"\n position={Position.Right}\n style={{\n visibility: 'hidden',\n width: 0,\n }}\n isConnectable={false}\n />\n </Card>\n );\n}\n\nexport function GraphNodeSkeleton(_props: NodeProps<{}>) {\n // Loading nodes are always in default (non-compact) mode\n const compact = false;\n\n return (\n <Card\n className={cn(\n `flex h-[106px]! w-[260px]! flex-col gap-1.5 rounded-lg px-0 py-0 pt-2.5! pb-0! hover:shadow-md motion-safe:transition-shadow`,\n compact && `h-[47px]!`,\n )}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={{\n visibility: 'hidden',\n width: 0,\n }}\n isConnectable={false}\n />\n <div className={cn('flex w-full gap-1 px-2.5', compact && 'flex-row-reverse')}>\n <div className={cn('grow-0 overflow-hidden', compact && 'mr-auto')}>\n <div className=\"bg-muted mb-1 h-3 w-16 animate-pulse rounded-sm\"></div>\n <div className=\"bg-muted h-3 w-40 animate-pulse rounded-sm\"></div>\n {!compact && <div className=\"bg-muted mt-2 h-3 w-48 animate-pulse rounded-sm\"></div>}\n </div>\n <div className={cn('bg-muted size-[26px] shrink-0 animate-pulse rounded-md', !compact && 'ml-auto')}></div>\n </div>\n {!compact && (\n <div className=\"mt-auto flex h-8 items-center border-t px-2.5\">\n <div className=\"flex gap-1.5 overflow-hidden overflow-x-auto\">\n <div className=\"bg-muted h-4 w-12 animate-pulse rounded-sm\"></div>\n <div className=\"bg-muted h-4 w-12 animate-pulse rounded-sm\"></div>\n </div>\n </div>\n )}\n <Handle\n type=\"source\"\n position={Position.Right}\n style={{\n visibility: 'hidden',\n width: 0,\n }}\n isConnectable={false}\n />\n </Card>\n );\n}\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","export const GRAPH_NODE_WIDTH = 260;\nexport const GRAPH_NODE_HEIGHT = 106;\nexport const GRAPH_NODE_COLLAPSED_HEIGHT = 47;\nexport const GRAPH_NODE_SEP = 22;\nexport const GRAPH_RANK_SEP = 54;\nexport const GRAPH_TREE_SEP = 22;\nexport const GRAPH_BORDER_RADIUS = 80;\nexport const GRAPH_OFFSET = 20;\n","'use client';\n\nimport * as React from 'react';\nimport { EdgeProps, getSmoothStepPath, getStraightPath, Position } from 'reactflow';\n\nimport { GRAPH_NODE_WIDTH } from './consts';\n\nexport const GraphEdge: React.FC<EdgeProps & { stopOpacity?: number }> = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n targetPosition,\n}) => {\n const halfDistanceWidth = (targetX - sourceX) / 2;\n\n const [straightEdgePath] = getStraightPath({\n sourceX: sourceX - 4,\n sourceY,\n targetX: Math.max(sourceX + halfDistanceWidth, GRAPH_NODE_WIDTH / 2),\n targetY: sourceY,\n });\n\n const [edgePath] = getSmoothStepPath({\n sourceX: Math.max(sourceX + halfDistanceWidth, GRAPH_NODE_WIDTH / 2),\n sourceY,\n sourcePosition: Position.Bottom,\n targetX: targetX + 4,\n targetY,\n targetPosition,\n borderRadius: 8,\n offset: 0,\n });\n\n return (\n <g id={id} className=\"react-flow__edge-path\">\n <path d={straightEdgePath} className=\"stroke-border fill-transparent stroke-2\" />\n <path d={edgePath} className=\"stroke-border fill-transparent stroke-2\" />\n </g>\n );\n};\n","'use client';\n\nimport * as React from 'react';\nimport {\n ColumnDef,\n ColumnFiltersState,\n getCoreRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n useReactTable,\n} from '@tanstack/react-table';\nimport { Edge, EdgeTypes, NodeTypes } from 'reactflow';\n\nimport { Icon, InputGroup, InputGroupAddon, InputGroupInput } from '@upbound/monarch-core';\nimport { getColumnFilterCount } from '@/lib/data-table/contextual-filters';\nimport { getTableState, hasFilterableColumns, type TableDataState } from '@/lib/data-table/utils';\nimport { cn } from '@/lib/utils';\n\nimport { DataTableEmptyView, type DataTableEmptyConfig } from '../data-table/empty-view';\nimport { ViewFilter } from '../data-table/view-filter';\nimport { SectionHeader, SectionHeaderContent, SectionHeaderTitle } from '../section-header';\nimport { GraphActionsProviderRef } from './graph-actions-provider';\nimport { NodeDefault, NodeLoading } from './graph-node';\nimport { GraphView } from './graph-view';\n\nexport interface GraphOptions<T extends object> {\n data: T[];\n nodeTransform: (item: T, data: T[]) => NodeLoading | NodeDefault | (NodeLoading | NodeDefault)[];\n edgeTransform: (item: T) => Edge[] | undefined;\n nodeTypes?: NodeTypes;\n edgeTypes?: EdgeTypes;\n}\n\nexport type GraphDataState = TableDataState;\n\nexport interface GraphEmptyView {\n empty?: DataTableEmptyConfig;\n error?: DataTableEmptyConfig;\n filter?: DataTableEmptyConfig;\n}\n\nexport interface GraphProps<T extends object> {\n id: string;\n viewportFocusNodeId?: string;\n config: GraphOptions<T>;\n columnDefinitions?: ColumnDef<T, unknown>[];\n title?: React.ReactNode;\n loading?: boolean;\n showError?: boolean;\n className?: string;\n emptyView?: GraphEmptyView;\n ActionsComponent?: React.ComponentType<{ state: GraphDataState }>;\n\n disableSearch?: boolean;\n disableFilters?: boolean;\n\n searchTerm?: string;\n onSearchTermChange?: React.Dispatch<React.SetStateAction<string>>;\n\n filters?: ColumnFiltersState;\n onFiltersChange?: React.Dispatch<React.SetStateAction<ColumnFiltersState>>;\n}\n\nexport const defaultGraphErrorConfig: DataTableEmptyConfig = {\n icon: 'triangle-exclamation',\n header: 'An error occurred',\n subheader: 'There was an error fetching the data for this graph. Please refresh the screen.',\n};\n\nexport const defaultGraphEmptyConfig: DataTableEmptyConfig = {\n icon: 'layer-group',\n header: 'No resources found',\n subheader:\n \"We couldn't find any resources to display in this graph. If you need help getting started you can learn more in the Upbound Documentation.\",\n};\n\nexport const defaultGraphNoFilterFoundConfig: DataTableEmptyConfig = {\n icon: 'magnifying-glass',\n header: 'No results found',\n subheader:\n \"We couldn't find any results that match your search term or filtering criteria. Try using different keywords, checking for typos or adjusting your filters and try again.\",\n};\n\nexport function Graph<T extends object>({\n id,\n viewportFocusNodeId,\n config,\n columnDefinitions = [],\n\n title,\n emptyView,\n showError,\n className,\n loading = false,\n ActionsComponent: Actions,\n\n disableSearch = false,\n disableFilters = false,\n\n searchTerm: parentGlobalFilter,\n onSearchTermChange: parentSetGlobalFilter,\n\n filters: parentColumnFilters,\n onFiltersChange: parentSetColumnFilters,\n\n children,\n}: React.PropsWithChildren<GraphProps<T>>) {\n const graphRef = React.useRef<GraphActionsProviderRef>(null);\n\n const [innerGlobalFilter, setInnerGlobalFilter] = React.useState('');\n const [innerColumnFilters, setInnerColumnFilters] = React.useState<ColumnFiltersState>([]);\n\n const globalFilter = parentGlobalFilter ?? innerGlobalFilter;\n const setGlobalFilter = parentSetGlobalFilter ?? setInnerGlobalFilter;\n\n // Sync the inner mirror when the parent-supplied searchTerm changes (e.g. switching views).\n React.useEffect(() => {\n if (parentGlobalFilter !== undefined) {\n setInnerGlobalFilter(parentGlobalFilter);\n }\n }, [parentGlobalFilter]);\n\n const columnFilters = parentColumnFilters ?? innerColumnFilters;\n const setColumnFilters = parentSetColumnFilters ?? setInnerColumnFilters;\n\n const table = useReactTable<T>({\n data: config.data,\n columns: columnDefinitions,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n state: { columnFilters, globalFilter },\n onColumnFiltersChange: setColumnFilters,\n onGlobalFilterChange: setGlobalFilter,\n manualFiltering: false,\n });\n\n const flatColumns = table.getAllFlatColumns();\n\n const filteredRows = table.getFilteredRowModel().rows;\n const filteredData = React.useMemo(() => filteredRows.map(row => row.original), [filteredRows]);\n\n const filterCount = columnFilters\n .map(({ id: columnFilterId, value }) =>\n getColumnFilterCount(value, table.getColumn(columnFilterId)?.columnDef.meta?.filter),\n )\n .reduce((prev, curr) => prev + curr, 0);\n\n const graphState = getTableState({ error: !!showError, loading, rowCount: filteredData.length });\n\n const shouldDisable = graphState === 'error';\n const shouldRenderGraphContent = graphState !== 'error' && graphState !== 'empty';\n\n const resetFilters = () => {\n setColumnFilters([]);\n setGlobalFilter('');\n };\n\n const memoizedNodeTypes = React.useMemo(() => config.nodeTypes, [config.nodeTypes]);\n const memoizedEdgeTypes = React.useMemo(() => config.edgeTypes, [config.edgeTypes]);\n const memoizedConfig = React.useMemo(() => config, [config]);\n\n React.useEffect(() => {\n if (!graphRef.current) {\n return;\n }\n const { setNodes, setEdges } = graphRef.current;\n\n const nodes = filteredData.map(item => memoizedConfig.nodeTransform(item, filteredData)).flat() || [];\n const nodeIds = new Set(nodes.map(node => node.id));\n const edges = (filteredData.map(memoizedConfig.edgeTransform).filter(Boolean).flat() || []).filter(\n (edge): edge is Edge =>\n Boolean(edge && edge.hasOwnProperty('source') && edge.hasOwnProperty('target')) &&\n nodeIds.has((edge as Edge).source) &&\n nodeIds.has((edge as Edge).target),\n );\n\n setNodes(nodes);\n setEdges(edges);\n }, [memoizedConfig, filteredData]);\n\n const showFilters = !disableFilters && hasFilterableColumns(flatColumns);\n const showToolbar = !disableSearch || !!Actions;\n\n const resolvedEmptyView: GraphEmptyView = {\n error: emptyView?.error ?? defaultGraphErrorConfig,\n empty: emptyView?.empty ?? defaultGraphEmptyConfig,\n filter: emptyView?.filter ?? defaultGraphNoFilterFoundConfig,\n };\n\n return (\n <div id={`graph-${id}`} className={cn('flex size-full flex-1 flex-col', className)}>\n {!!title && (\n <SectionHeader className=\"mb-4\">\n <SectionHeaderContent>\n <SectionHeaderTitle>{title}</SectionHeaderTitle>\n </SectionHeaderContent>\n </SectionHeader>\n )}\n\n {showToolbar && (\n <div className=\"mb-4 flex flex-row gap-2\">\n {!disableSearch && (\n <InputGroup className=\"w-70\">\n <InputGroupAddon align=\"inline-start\">\n <Icon name=\"magnifying-glass\" />\n </InputGroupAddon>\n <InputGroupInput\n aria-label=\"Search\"\n placeholder=\"Search…\"\n disabled={shouldDisable}\n value={globalFilter}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setGlobalFilter(e.target.value)}\n />\n </InputGroup>\n )}\n {!!Actions && (\n <div className=\"ml-auto flex items-center gap-2\">\n <Actions state={graphState} />\n </div>\n )}\n </div>\n )}\n\n {showFilters && (\n <ViewFilter\n columns={flatColumns}\n columnFilters={columnFilters}\n onColumnFiltersChange={setColumnFilters}\n className=\"mb-4\"\n />\n )}\n\n {shouldRenderGraphContent ? (\n <div className=\"relative size-full flex-1\">\n {graphState === 'loading' && <Icon name=\"circle-notch\" className=\"absolute top-4 left-4 z-10 animate-spin\" />}\n <GraphView\n viewportFocusNodeId={viewportFocusNodeId}\n ref={graphRef}\n nodeTypes={memoizedNodeTypes}\n edgeTypes={memoizedEdgeTypes}\n >\n {children}\n </GraphView>\n </div>\n ) : (\n <DataTableEmptyView\n emptyView={resolvedEmptyView}\n tableState={graphState}\n filterCount={filterCount + (!!globalFilter.trim() ? 1 : 0)}\n resetFilters={resetFilters}\n />\n )}\n </div>\n );\n}\n","import type { Cell, ColumnFilter, ColumnFiltersState, RowData } from '@tanstack/react-table';\n\nimport './table-meta';\nimport type { ColumnFilterDefinition, ColumnFilterValue } from './filter-types';\n\nfunction valueToString(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n const normalized = String(value).trim();\n return normalized || undefined;\n}\n\nfunction stringArrayFromValue(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(valueToString).filter((v): v is string => !!v);\n }\n const normalized = valueToString(value);\n return normalized ? [normalized] : [];\n}\n\n/** Flattens a scalar or array cell value into trimmed, non-empty strings — the\n * shape `celFilterConfig.onContextualFilter` and `mergeContextualIntoCelTree` want. */\nexport function columnFilterValueToStrings(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(item => String(item).trim()).filter(Boolean);\n }\n const normalized = String(value ?? '').trim();\n return normalized ? [normalized] : [];\n}\n\nexport function hasContextualFilterValue(value: ColumnFilterValue | undefined): boolean {\n if (value === undefined) return false;\n if (typeof value === 'string') return value.trim() !== '';\n if (Array.isArray(value)) {\n return value.filter(item => typeof item === 'string' && item.trim() !== '').length > 0;\n }\n return !!(value.startDate ?? value.endDate);\n}\n\nfunction getDefaultContextualFilterValue<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n filter: ColumnFilterDefinition,\n): ColumnFilterValue | undefined {\n const value = cell.getValue();\n\n if (filter.type === 'checkbox' || filter.type === 'multiText') {\n const values = stringArrayFromValue(value);\n return values.length > 0 ? values : undefined;\n }\n\n if (filter.type === 'radio' || filter.type === 'text') {\n return valueToString(value);\n }\n\n return undefined;\n}\n\n/** Derives the contextual (right-click cell) column filter, or `undefined` if\n * the column has no `meta.filter` or no value can be derived. */\nexport function getContextualColumnFilter<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n): ColumnFilter | undefined {\n const meta = cell.column.columnDef.meta;\n const filter = meta?.filter;\n if (!filter) return undefined;\n\n const value = meta?.contextualFilterValue\n ? meta.contextualFilterValue(cell)\n : getDefaultContextualFilterValue(cell, filter);\n if (!hasContextualFilterValue(value)) return undefined;\n\n return { id: cell.column.id, value };\n}\n\n/** Derives the contextual (right-click cell) global-search term, or `undefined`\n * when the column has no `meta.contextualGlobalSearchValue`. */\nexport function getContextualGlobalSearch<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n): string | undefined {\n const globalSearchValue = cell.column.columnDef.meta?.contextualGlobalSearchValue;\n if (!globalSearchValue) return undefined;\n return valueToString(globalSearchValue(cell));\n}\n\n/**\n * Merges a contextual filter into `ColumnFiltersState`. Checkbox/multiText\n * filters union with any existing values for that column (deduped); every\n * other type replaces the column's filter outright.\n */\nexport function mergeColumnFilter(\n columnFilters: ColumnFiltersState,\n nextFilter: ColumnFilter,\n filterDefinition?: ColumnFilterDefinition,\n): ColumnFiltersState {\n const shouldMergeArrayValue = filterDefinition?.type === 'checkbox' || filterDefinition?.type === 'multiText';\n\n if (!shouldMergeArrayValue) {\n return [...columnFilters.filter(filter => filter.id !== nextFilter.id), nextFilter];\n }\n\n const nextValues = stringArrayFromValue(nextFilter.value);\n if (nextValues.length === 0) return columnFilters;\n\n const existingFilter = columnFilters.find(filter => filter.id === nextFilter.id);\n const existingValues = stringArrayFromValue(existingFilter?.value);\n const mergedValues = Array.from(new Set([...existingValues, ...nextValues]));\n\n if (existingFilter && mergedValues.length === existingValues.length) return columnFilters;\n\n return [...columnFilters.filter(filter => filter.id !== nextFilter.id), { id: nextFilter.id, value: mergedValues }];\n}\n\n/**\n * Counts active filter \"slots\" for UI badges (the Filter-button count and the\n * empty-view filter count). When `filter` is omitted, falls back to a\n * best-effort shape heuristic (ambiguous for `string` vs radio and `string[]`\n * vs multiText).\n */\nexport function getColumnFilterCount(filterValue: unknown, filter?: ColumnFilterDefinition): number {\n const isCheckboxValue = (value: unknown): value is string[] | undefined =>\n value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'string'));\n const isRadioValue = (value: unknown): value is string | undefined =>\n value === undefined || typeof value === 'string';\n const isDateRangeValue = (value: unknown): value is { startDate: Date | null; endDate: Date | null } | undefined =>\n value === undefined || (typeof value === 'object' && value !== null && 'startDate' in value && 'endDate' in value);\n\n if (filter?.type === 'checkbox') {\n return isCheckboxValue(filterValue) ? (filterValue || []).length : 0;\n }\n\n if (filter?.type === 'radio') {\n return isRadioValue(filterValue) && filterValue !== undefined ? 1 : 0;\n }\n\n if (filter?.type === 'dateRange') {\n if (!isDateRangeValue(filterValue)) return 0;\n return Number(!!filterValue?.startDate) + Number(!!filterValue?.endDate);\n }\n\n if (isCheckboxValue(filterValue)) {\n return (filterValue || []).length;\n }\n\n if (isRadioValue(filterValue) && filterValue !== undefined) {\n return 1;\n }\n\n if (isDateRangeValue(filterValue)) {\n return Number(!!filterValue?.startDate) + Number(!!filterValue?.endDate);\n }\n\n return 0;\n}\n","import type { Column, ColumnOrderState, FilterFn, Row, RowData } from '@tanstack/react-table';\n\nimport './table-meta';\nimport type { DateRangeColumnFilterValue } from './filter-types';\n\nconst TO_EACH_SIDE = 2;\n\ntype ColumnPinningPosition = 'left' | 'right' | false;\n\n/**\n * Reconciles a persisted column order against the table's actual columns:\n * drops stale/duplicate ids and appends any column missing from the\n * persisted order (in `allColumnIds` order).\n */\nexport function normalizeColumnOrdering(columnOrdering: ColumnOrderState, allColumnIds: string[]): ColumnOrderState {\n const validIds = new Set(allColumnIds);\n const seenIds = new Set<string>();\n\n const trackedColumnIds = columnOrdering.filter(columnId => {\n if (!validIds.has(columnId) || seenIds.has(columnId)) return false;\n seenIds.add(columnId);\n return true;\n });\n\n return [...trackedColumnIds, ...allColumnIds.filter(columnId => !seenIds.has(columnId))];\n}\n\nexport function isSameColumnOrdering(left: ColumnOrderState, right: ColumnOrderState): boolean {\n return left.length === right.length && left.every((columnId, index) => columnId === right[index]);\n}\n\n/** Splits a full column order into left-pinned / unpinned / right-pinned buckets, preserving relative order within each. */\nexport function splitColumnOrderByPinning(\n fullColumnOrder: string[],\n getColumnPinning: (columnId: string) => ColumnPinningPosition,\n) {\n return {\n leftPinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === 'left'),\n unpinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === false),\n rightPinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === 'right'),\n };\n}\n\n/**\n * Refills only the unpinned slots of `fullColumnOrder` from `nextUnpinnedOrder`,\n * in order — pinned columns keep their exact index. This is what keeps\n * drag-reordering from relocating pinned/actions columns to the array edges.\n */\nexport function mergeUnpinnedColumnOrder(\n fullColumnOrder: string[],\n nextUnpinnedOrder: string[],\n getColumnPinning: (columnId: string) => ColumnPinningPosition,\n): ColumnOrderState {\n const nextUnpinnedIterator = nextUnpinnedOrder[Symbol.iterator]();\n\n return fullColumnOrder.map(columnId =>\n getColumnPinning(columnId) === false ? (nextUnpinnedIterator.next().value ?? columnId) : columnId,\n );\n}\n\nexport type PaginationInfo = {\n visiblePages: (number | undefined)[];\n pageCount: number;\n itemStart: number;\n itemEnd: number;\n};\n\n/** Computes the pagination footer's visible page numbers (with ellipsis markers), page count, and item range. */\nexport function getPaginationInfo(pageIndex: number, totalRows: number, pageSize: number): PaginationInfo {\n const currentPage = pageIndex + 1;\n const pageCount = Math.ceil(totalRows / pageSize);\n\n function getPages(): (number | undefined)[] {\n if (pageCount === 0) return [];\n if (pageCount === 1) return [1];\n if (pageCount === 2) return [1, 2];\n\n const runStart = Math.max(currentPage - TO_EACH_SIDE, 2);\n const runEnd = Math.min(currentPage + TO_EACH_SIDE, pageCount - 1);\n const hasBeginningEllipsis = runStart > 2;\n const hasEndingEllipsis = currentPage + 3 < pageCount;\n\n return [\n 1,\n ...(hasBeginningEllipsis ? [undefined] : []),\n ...Array.from({ length: runEnd - runStart + 1 }).map((_, i) => i + runStart),\n ...(hasEndingEllipsis ? [undefined] : []),\n pageCount,\n ];\n }\n\n return {\n pageCount,\n visiblePages: getPages(),\n itemStart: totalRows === 0 ? 0 : pageIndex * pageSize + 1,\n itemEnd: Math.min(currentPage * pageSize, totalRows),\n };\n}\n\n/** Ascending date sort; invalid dates sort first (treated as `-Infinity`). */\nexport function sortColumnByDate<T>(rowA: Row<T>, rowB: Row<T>, columnId: string): number {\n const dateA = new Date(rowA.getValue(columnId) as string | number | Date).getTime();\n const dateB = new Date(rowB.getValue(columnId) as string | number | Date).getTime();\n\n const dateNumA = isNaN(dateA) ? -Infinity : dateA;\n const dateNumB = isNaN(dateB) ? -Infinity : dateB;\n\n return dateNumA - dateNumB;\n}\n\nfunction isDateValid(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/** An invalid/missing filter range passes every row (filter inactive); an invalid row date fails (excluded). */\nexport const filterColumnByDateRange: FilterFn<RowData> = (\n row: Row<RowData>,\n columnId: string,\n filterValue: NonNullable<DateRangeColumnFilterValue>,\n) => {\n const { startDate, endDate } = filterValue;\n if (!startDate || !isDateValid(startDate) || !endDate || !isDateValid(endDate)) return true;\n\n const date = new Date(row.getValue(columnId) as string | number | Date);\n if (!isDateValid(date)) return false;\n\n return date >= startDate && date <= endDate;\n};\n\n/**\n * @deprecated Prefer TanStack's built-in `arrIncludesSome` filter fn — kept\n * only for the case-insensitive matching it does that `arrIncludesSome`\n * doesn't; a straight swap changes behavior for mixed-case data.\n */\nexport const filterColumnByArrayValues: FilterFn<RowData> = (\n row: Row<RowData>,\n columnId: string,\n arrayOfValues: string[],\n) => {\n if (arrayOfValues.length) {\n const rowValue = row.getValue(columnId) as string;\n return arrayOfValues.filter(val => val?.toLowerCase() === rowValue?.toLowerCase()).length > 0;\n }\n return true;\n};\n\n/** Sorts by `secondaryColumnId` when the primary column's values are equal. Never returns 0 (always a definite order). */\nexport function secondarySortByColumn(\n secondaryColumnId: string,\n): (rowA: Row<RowData>, rowB: Row<RowData>, columnId: string) => number {\n return (rowA: Row<RowData>, rowB: Row<RowData>, columnId: string): number => {\n const rowAPrimaryColumnValue = rowA.getValue(columnId) as string;\n const rowBPrimaryColumnValue = rowB.getValue(columnId) as string;\n const rowASecondaryColumnValue = rowA.getValue(secondaryColumnId) as string;\n const rowBSecondaryColumnValue = rowB.getValue(secondaryColumnId) as string;\n\n if (rowAPrimaryColumnValue === rowBPrimaryColumnValue) {\n return rowASecondaryColumnValue > rowBSecondaryColumnValue ? 1 : -1;\n }\n return rowAPrimaryColumnValue > rowBPrimaryColumnValue ? 1 : -1;\n };\n}\n\nexport function isFilterOnlyColumn<T>(column: Column<T, unknown>): boolean {\n return column.columnDef.meta?.filterOnly === true;\n}\n\n/** Whether at least one column defines a `meta.filter` and is filterable — i.e. there's something the plain filter row could show. */\nexport function hasFilterableColumns<T>(columns: Column<T, unknown>[]): boolean {\n return columns.some(\n column => !isFilterOnlyColumn(column) && column.getCanFilter() && !!column.columnDef.meta?.filter,\n );\n}\n\nexport type TableDataState = 'empty' | 'loading' | 'error' | 'success';\n\n/** Strict precedence: error > loading > empty > success. `loading` still renders table content (skeleton rows). */\nexport function getTableState({\n error,\n loading,\n rowCount,\n}: {\n error: boolean;\n loading: boolean;\n rowCount: number;\n}): TableDataState {\n if (error) return 'error';\n if (loading) return 'loading';\n return rowCount === 0 ? 'empty' : 'success';\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { Alert, AlertDescription } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { IconTile } from '@upbound/monarch-core';\nimport type { IconName } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport type { TableDataState } from '@/lib/data-table/utils';\n\n/**\n * Monarch-native equivalent of TableWrapper's `EmptyConfig` — same four\n * states (error / empty / filtered-empty), rebuilt on Monarch's `Empty`\n * compound API instead of a single props-driven component. Two deliberate\n * adaptations: `icon` takes a Monarch `IconName` (no FontAwesome dependency),\n * and `action` is a rendered node rather than a `ComponentType` reference.\n * `details` has no native `Empty` slot — it composes `Alert` instead.\n */\nexport type DataTableEmptyConfig = {\n icon?: IconName;\n header?: React.ReactNode;\n subheader?: React.ReactNode;\n details?: React.ReactNode;\n action?: React.ReactNode;\n className?: string;\n wrapperClassName?: string;\n};\n\nexport type DataTableEmptyView = {\n empty?: DataTableEmptyConfig;\n error?: DataTableEmptyConfig;\n filter?: DataTableEmptyConfig;\n};\n\nexport const defaultErrorConfig: DataTableEmptyConfig = {\n icon: 'circle-exclamation',\n header: 'Something went wrong',\n subheader: \"We couldn't load this data. Try again in a moment.\",\n};\n\nexport const defaultEmptyConfig: DataTableEmptyConfig = {\n icon: 'inbox',\n header: 'No results',\n subheader: \"There's nothing here yet.\",\n};\n\nexport const defaultNoFilterFoundConfig: DataTableEmptyConfig = {\n icon: 'magnifying-glass',\n header: 'No matching results',\n subheader: 'Try adjusting your search or filters.',\n};\n\nexport function DataTableEmptyView({\n emptyView,\n tableState,\n filterCount,\n resetFilters,\n className,\n}: {\n emptyView?: DataTableEmptyView;\n /** `'success'`/`'loading'` render nothing here — the table body handles those. */\n tableState: TableDataState;\n filterCount: number;\n resetFilters: () => void;\n className?: string;\n}) {\n const isFilteredEmpty = tableState === 'empty' && filterCount > 0;\n const config =\n tableState === 'error'\n ? (emptyView?.error ?? defaultErrorConfig)\n : tableState === 'empty'\n ? isFilteredEmpty\n ? (emptyView?.filter ?? defaultNoFilterFoundConfig)\n : (emptyView?.empty ?? defaultEmptyConfig)\n : null;\n\n // Mirrors a quirk in the source: an error config without its own\n // `wrapperClassName` falls back to the *empty* config's, not its own type's default.\n const wrapperClassName =\n tableState === 'error'\n ? (emptyView?.error?.wrapperClassName ?? emptyView?.empty?.wrapperClassName)\n : config?.wrapperClassName;\n\n const defaultAction =\n isFilteredEmpty && !config?.action ? (\n <Button variant=\"outline\" size=\"sm\" onClick={resetFilters}>\n <Icon name=\"xmark\" />\n Clear filters\n </Button>\n ) : null;\n\n return (\n <div className={cn('flex size-full flex-col justify-center p-6', wrapperClassName, className)}>\n {config && (\n // The error state ignores its own config's `className` for outer\n // padding, matching the source's forced `pt-0` on that branch.\n <Empty className={tableState === 'error' ? 'pt-0' : config.className}>\n <EmptyHeader>\n {config.icon && (\n <EmptyMedia>\n <IconTile variant=\"branded\">\n <Icon name={config.icon} />\n </IconTile>\n </EmptyMedia>\n )}\n {config.header && <EmptyTitle>{config.header}</EmptyTitle>}\n {config.subheader && <EmptyDescription>{config.subheader}</EmptyDescription>}\n </EmptyHeader>\n {(config.details || config.action || defaultAction) && (\n <EmptyContent>\n {config.details && (\n <Alert>\n <AlertDescription>{config.details}</AlertDescription>\n </Alert>\n )}\n {config.action ?? defaultAction}\n </EmptyContent>\n )}\n </Empty>\n )}\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { Column, ColumnFiltersState, RowData } from '@tanstack/react-table';\n\nimport { ActiveFilter, FilterBar, type FilterDefinition, type FilterOption, type FilterValue } from '@/filter-bar';\nimport {\n isCheckboxColumnFilter,\n isDateRangeColumnFilter,\n isMultiTextColumnFilter,\n isRadioColumnFilter,\n type ColumnFilterDefinition,\n type ColumnFilterOption,\n type ColumnFilterValue,\n} from '@/lib/data-table/filter-types';\nimport { isFilterOnlyColumn } from '@/lib/data-table/utils';\n\nexport type ViewFilterProps<TData extends RowData> = {\n columns: Column<TData, unknown>[];\n columnFilters: ColumnFiltersState;\n onColumnFiltersChange: React.Dispatch<React.SetStateAction<ColumnFiltersState>>;\n className?: string;\n};\n\nfunction toFilterOption(opt: string | ColumnFilterOption): FilterOption {\n return typeof opt === 'string' ? { value: opt, label: opt } : { value: opt.value, label: opt.label };\n}\n\n/** Maps a column's `meta.filter` (the `ColumnFilterDefinition` vocabulary) onto Monarch `FilterBar`'s own `FilterDefinition` shape. */\nfunction toFilterBarDefinition(key: string, filter: ColumnFilterDefinition): FilterDefinition & { order?: number } {\n const base = { key, label: filter.title, order: filter.order };\n\n if (isCheckboxColumnFilter(filter)) {\n const options = 'options' in filter && filter.options ? filter.options : [];\n return {\n ...base,\n type: 'checkbox',\n options: options.map(toFilterOption),\n searchable: filter.searchable ?? true,\n };\n }\n if (isRadioColumnFilter(filter)) {\n return {\n ...base,\n type: 'radio',\n options: filter.options.map(toFilterOption),\n searchable: filter.searchable ?? true,\n };\n }\n if (isDateRangeColumnFilter(filter)) {\n return { ...base, type: 'date', includeTime: filter.includeTime };\n }\n if (isMultiTextColumnFilter(filter)) {\n return { ...base, type: 'multiText', placeholder: filter.placeholder };\n }\n return { ...base, type: 'text', placeholder: filter.placeholder };\n}\n\n/** The empty value a filter starts at the moment it's added, before the user picks anything. */\nfunction emptyValueFor(filter: ColumnFilterDefinition): ColumnFilterValue {\n if (isCheckboxColumnFilter(filter)) return [];\n if (isRadioColumnFilter(filter)) return undefined;\n if (isDateRangeColumnFilter(filter)) return { startDate: null, endDate: null };\n if (isMultiTextColumnFilter(filter)) return [];\n return undefined;\n}\n\n/**\n * The plain (non-CEL) filter row — a thin state adapter over Monarch's\n * `FilterBar`, mirroring TableWrapper's own `ViewFilter` (itself just a\n * `FilterBar` adapter, not a hand-rolled UI). Every `meta.filter` shape\n * (checkbox, radio, dateRange, text, multiText) gets a chip here, mapped onto\n * the matching `FilterBar` chip type — checkbox and radio chips are\n * searchable by default (opt out per column via `meta.filter.searchable:\n * false`). CEL-based filtering (`celFilterConfig`) is the richer,\n * operator-driven tier this is not meant to replace.\n */\nexport function ViewFilter<TData extends RowData>({\n columns,\n columnFilters,\n onColumnFiltersChange,\n className,\n}: ViewFilterProps<TData>) {\n const filterableColumns = React.useMemo(\n () =>\n columns\n .filter(column => !isFilterOnlyColumn(column) && column.getCanFilter())\n .flatMap(column => {\n const filter = column.columnDef.meta?.filter;\n return filter ? [{ key: column.id, filter }] : [];\n }),\n [columns],\n );\n\n const filterDefinitions = React.useMemo<(FilterDefinition & { order?: number })[]>(\n () =>\n filterableColumns\n .map(({ key, filter }) => toFilterBarDefinition(key, filter))\n .sort((a, b) => {\n if (a.order == null && b.order == null) return 0;\n if (a.order == null) return 1;\n if (b.order == null) return -1;\n return a.order - b.order;\n }),\n [filterableColumns],\n );\n\n const emptyValueByKey = React.useMemo(\n () => new Map(filterableColumns.map(({ key, filter }) => [key, emptyValueFor(filter)])),\n [filterableColumns],\n );\n\n const activeFilters = React.useMemo<ActiveFilter[]>(\n () => columnFilters.map(filter => ({ key: filter.id, value: filter.value as FilterValue | undefined })),\n [columnFilters],\n );\n\n return (\n <FilterBar\n className={className}\n filters={filterDefinitions}\n activeFilters={activeFilters}\n onAddFilter={key =>\n onColumnFiltersChange(prev => [...prev.filter(f => f.id !== key), { id: key, value: emptyValueByKey.get(key) }])\n }\n onRemoveFilter={key => onColumnFiltersChange(prev => prev.filter(f => f.id !== key))}\n onChangeFilter={(key, value) =>\n onColumnFiltersChange(prev => [...prev.filter(f => f.id !== key), { id: key, value }])\n }\n />\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { type DateRange } from 'react-day-picker';\nimport { Icon } from '@upbound/monarch-core';\n\nimport { cn, sortBy } from '@/lib/utils';\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 ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\n\n// ── Types ─────────────────────────────────────────────\n\ntype FilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date';\n\ninterface FilterOption {\n value: string;\n label: string;\n icon?: React.ReactNode;\n}\n\ninterface FilterDefinitionBase {\n key: string;\n label: string;\n}\n\ninterface CheckboxFilterDefinition extends FilterDefinitionBase {\n type?: 'checkbox';\n options: FilterOption[];\n /**\n * When `true`, the chip's value popup becomes a searchable Combobox\n * (multi-select with a search input). Use for long option lists where a\n * basic dropdown becomes hard to scan. When `false` or omitted, the chip\n * uses the standard checkbox dropdown.\n */\n searchable?: boolean;\n}\n\ninterface RadioFilterDefinition extends FilterDefinitionBase {\n type: 'radio';\n options: FilterOption[];\n /** Same searchable-Combobox swap as `CheckboxFilterDefinition`, constrained to a single selection. */\n searchable?: boolean;\n}\n\ninterface TextFilterDefinition extends FilterDefinitionBase {\n type: 'text';\n placeholder?: string;\n}\n\ninterface MultiTextFilterDefinition extends FilterDefinitionBase {\n type: 'multiText';\n placeholder?: string;\n}\n\ninterface DateFilterDefinition extends FilterDefinitionBase {\n type: 'date';\n /**\n * `true` always shows Start/End time inputs, `false` never shows them,\n * and omitted auto-detects from whether the current value already carries\n * a non-midnight time component.\n */\n includeTime?: boolean;\n}\n\ntype FilterDefinition =\n | CheckboxFilterDefinition\n | RadioFilterDefinition\n | TextFilterDefinition\n | MultiTextFilterDefinition\n | DateFilterDefinition;\n\ntype CheckboxFilterValue = string[];\ntype RadioFilterValue = string;\ntype TextFilterValue = string;\ntype MultiTextFilterValue = string[];\ntype DateFilterValue = { startDate: Date | null; endDate: Date | null };\ntype FilterValue = CheckboxFilterValue | RadioFilterValue | TextFilterValue | MultiTextFilterValue | DateFilterValue;\n\ninterface ActiveFilter {\n key: string;\n value?: FilterValue;\n}\n\n// ── Value helpers ─────────────────────────────────────\n\nfunction asCheckboxValue(value: FilterValue | undefined): CheckboxFilterValue {\n return Array.isArray(value) ? value : [];\n}\n\nfunction asRadioValue(value: FilterValue | undefined): RadioFilterValue {\n return typeof value === 'string' ? value : '';\n}\n\nfunction asTextValue(value: FilterValue | undefined): TextFilterValue {\n return typeof value === 'string' ? value : '';\n}\n\nfunction asMultiTextValue(value: FilterValue | undefined): MultiTextFilterValue {\n return Array.isArray(value) ? value : [];\n}\n\nfunction asDateValue(value: FilterValue | undefined): DateFilterValue {\n if (value && typeof value === 'object' && !Array.isArray(value)) return value as DateFilterValue;\n return { startDate: null, endDate: null };\n}\n\nfunction hasExplicitTime(date: Date | null): boolean {\n if (!date) return false;\n return date.getHours() !== 0 || date.getMinutes() !== 0;\n}\n\nfunction formatTimeForInput(date: Date | null): string {\n if (!date) return '';\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;\n}\n\nfunction applyTimeToDate(date: Date, time: string): Date {\n const [hours, minutes] = time.split(':').map(Number);\n const next = new Date(date);\n next.setHours(hours || 0, minutes || 0, 0, 0);\n return next;\n}\n\nfunction formatDateLabel(date: Date): string {\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n}\n\n/** Merges the internal ref FilterBar uses to track its own root node with\n * any ref a consumer passes to `FilterBar` itself. */\nfunction composeRefs<T>(...refs: Array<React.Ref<T> | null | undefined>) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\ntype PortalContainer = React.ComponentProps<typeof ComboboxContent>['container'];\n\n// ── FilterBar ─────────────────────────────────────────\n\ninterface FilterBarProps extends React.ComponentProps<'div'> {\n filters: FilterDefinition[];\n activeFilters: ActiveFilter[];\n onAddFilter: (key: string) => void;\n onRemoveFilter: (key: string) => void;\n onChangeFilter: (key: string, value: FilterValue) => void;\n}\n\nfunction hasOrder(filter: FilterDefinition): boolean {\n return typeof (filter as { order?: unknown }).order === 'number';\n}\n\nfunction FilterBar({\n filters,\n activeFilters,\n onAddFilter,\n onRemoveFilter,\n onChangeFilter,\n className,\n children,\n ref,\n ...props\n}: FilterBarProps) {\n const usedKeys = new Set(activeFilters.map(f => f.key));\n const remainingFilters = filters.filter(f => !usedKeys.has(f.key));\n const availableFilters = filters.some(hasOrder) ? remainingFilters : sortBy(remainingFilters, f => f.label);\n const shouldShowFilters = availableFilters.length > 0 || activeFilters.length > 0;\n\n // Tracks the most recently added filter so its chip can open its value\n // popup immediately, without waiting for a second click.\n const [pendingOpenKey, setPendingOpenKey] = React.useState<string | null>(null);\n\n function handleAddFilter(key: string) {\n onAddFilter(key);\n setPendingOpenKey(key);\n }\n\n // Ref for the FilterBar'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 return (\n <div\n data-slot=\"filter-bar\"\n data-visible-filters={shouldShowFilters}\n className={cn('flex flex-wrap items-center gap-2', className)}\n ref={composeRefs(containerRef, ref)}\n {...props}\n >\n {/* Add filter button */}\n {availableFilters.length > 0 && (\n <Combobox\n items={availableFilters}\n itemToStringValue={(item: FilterDefinition) => item.label}\n itemToStringLabel={(item: FilterDefinition) => item.label}\n onValueChange={(filter: FilterDefinition | null) => {\n if (filter) handleAddFilter(filter.key);\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={containerRef} align=\"start\" className=\"w-48\">\n <ComboboxInput showTrigger={false} placeholder=\"Search filters…\" />\n <ComboboxEmpty>No filters found.</ComboboxEmpty>\n <ComboboxList>\n {(filter: FilterDefinition) => (\n <ComboboxItem key={filter.key} value={filter}>\n {filter.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n )}\n\n {/* Active filter chips */}\n {activeFilters.map(active => {\n const definition = filters.find(f => f.key === active.key);\n if (!definition) return null;\n return (\n <FilterChip\n key={active.key}\n definition={definition}\n value={active.value}\n autoOpen={active.key === pendingOpenKey}\n container={containerRef}\n onChangeValue={value => onChangeFilter(active.key, value)}\n onRemove={() => onRemoveFilter(active.key)}\n />\n );\n })}\n\n {/* Children (count, actions) — sit immediately after the last chip\n with the same `gap-2` spacing. With the parent's `flex-wrap`, a\n long row of chips will push the action onto the next line instead\n of stretching across an empty horizontal void. */}\n {children}\n </div>\n );\n}\n\n// ── FilterChip (dispatcher) ────────────────────────────\n\ninterface FilterChipProps {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n /** Opens the chip's value popup as soon as it mounts — used right after the filter is added. */\n autoOpen?: boolean;\n /** Portals a searchable checkbox/radio chip's Combobox popup here instead of the default `document.body` — see `FilterBar`'s own `containerRef` for why. */\n container?: PortalContainer;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}\n\nfunction FilterChip({ definition, value, autoOpen, container, onChangeValue, onRemove }: FilterChipProps) {\n const type = definition.type ?? 'checkbox';\n\n switch (type) {\n case 'checkbox':\n return (\n <CheckboxFilterChip\n definition={definition as CheckboxFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n container={container}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'radio':\n return (\n <RadioFilterChip\n definition={definition as RadioFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n container={container}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'text':\n return (\n <TextFilterChip\n definition={definition as TextFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'multiText':\n return (\n <MultiTextFilterChip\n definition={definition as MultiTextFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'date':\n return (\n <DateFilterChip\n definition={definition as DateFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n }\n}\n\n// ── Shared chip chrome ─────────────────────────────────\n\nfunction FilterChipRemoveButton({ label, onRemove }: { label: string; onRemove: () => void }) {\n return (\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${label} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n );\n}\n\n// ── Checkbox chip ──────────────────────────────────────\n\nfunction CheckboxFilterChip({\n definition,\n value,\n autoOpen,\n container,\n onChangeValue,\n onRemove,\n}: {\n definition: CheckboxFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n container?: PortalContainer;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, searchable = false } = definition;\n const options = sortBy(definition.options, o => o.label);\n const values = asCheckboxValue(value);\n const displayLabel =\n values.length === 0\n ? 'Any'\n : values.length === 1\n ? (options.find(o => o.value === values[0])?.label ?? values[0])\n : `${values.length} selected`;\n\n function toggle(optionValue: string) {\n const next = values.includes(optionValue) ? values.filter(v => v !== optionValue) : [...values, optionValue];\n onChangeValue(next);\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n {searchable ? (\n <Combobox\n items={options}\n itemToStringValue={(item: FilterOption) => item.label}\n multiple\n defaultOpen={autoOpen}\n value={options.filter(o => values.includes(o.value))}\n onValueChange={(selected: FilterOption[]) => onChangeValue(selected.map(s => s.value))}\n >\n <ComboboxTrigger\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={values.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n </ComboboxTrigger>\n <ComboboxContent\n container={container}\n className=\"min-w-64\"\n collisionAvoidance={{ side: 'none', align: 'shift' }}\n >\n <ComboboxInput showTrigger={false} placeholder={`Search ${label.toLowerCase()}…`} />\n {values.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(selected: FilterOption[]) => (\n <>\n {selected.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => onChangeValue([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {label.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: FilterOption) => (\n <ComboboxItem key={item.value} value={item}>\n {item.icon}\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n ) : (\n <DropdownMenu defaultOpen={autoOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={values.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n {options.map(opt => (\n <DropdownMenuCheckboxItem\n key={opt.value}\n checked={values.includes(opt.value)}\n onCheckedChange={() => toggle(opt.value)}\n >\n {opt.icon}\n {opt.label}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Radio chip ─────────────────────────────────────────\n\nfunction RadioFilterChip({\n definition,\n value,\n autoOpen,\n container,\n onChangeValue,\n onRemove,\n}: {\n definition: RadioFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n container?: PortalContainer;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, searchable = false } = definition;\n const options = sortBy(definition.options, o => o.label);\n const selectedValue = asRadioValue(value);\n const displayLabel = selectedValue ? (options.find(o => o.value === selectedValue)?.label ?? selectedValue) : 'Any';\n const selected = options.find(o => o.value === selectedValue) ?? null;\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n {searchable ? (\n <Combobox\n items={options}\n itemToStringValue={(item: FilterOption) => item.label}\n defaultOpen={autoOpen}\n value={selected}\n onValueChange={(next: FilterOption | null) => onChangeValue(next?.value ?? '')}\n >\n <ComboboxTrigger\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={selectedValue ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n </ComboboxTrigger>\n <ComboboxContent\n container={container}\n className=\"min-w-64\"\n collisionAvoidance={{ side: 'none', align: 'shift' }}\n >\n <ComboboxInput showTrigger={false} placeholder={`Search ${label.toLowerCase()}…`} />\n <ComboboxEmpty>No {label.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: FilterOption) => (\n <ComboboxItem key={item.value} value={item}>\n {item.icon}\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n ) : (\n <DropdownMenu defaultOpen={autoOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={selectedValue ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n <DropdownMenuRadioGroup value={selectedValue} onValueChange={onChangeValue}>\n {options.map(opt => (\n <DropdownMenuRadioItem key={opt.value} value={opt.value}>\n {opt.icon}\n {opt.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Text chip ──────────────────────────────────────────\n\nfunction TextFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: TextFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, placeholder } = definition;\n const text = asTextValue(value);\n const [open, setOpen] = React.useState(!!autoOpen);\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={text ? '' : 'text-muted-foreground'}>{text || 'Any'}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\">\n <Input\n autoFocus\n value={text}\n placeholder={placeholder ?? 'Enter a value…'}\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') setOpen(false);\n }}\n />\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── MultiText chip ─────────────────────────────────────\n\nfunction MultiTextFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: MultiTextFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, placeholder } = definition;\n const tokens = asMultiTextValue(value);\n const [draft, setDraft] = React.useState('');\n const displayLabel = tokens.length === 0 ? 'Any' : tokens.length === 1 ? tokens[0] : `${tokens.length} values`;\n\n function addToken() {\n const token = draft.trim();\n if (!token || tokens.includes(token)) {\n setDraft('');\n return;\n }\n onChangeValue([...tokens, token]);\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue(tokens.filter(t => t !== token));\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover defaultOpen={autoOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={tokens.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\">\n <div className=\"flex flex-col gap-2\">\n {tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {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={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 === '' && tokens.length > 0) {\n removeToken(tokens[tokens.length - 1]);\n }\n }}\n />\n </div>\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Date chip ──────────────────────────────────────────\n\nfunction DateFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: DateFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, includeTime } = definition;\n const { startDate, endDate } = asDateValue(value);\n const showTimeInputs = includeTime ?? (hasExplicitTime(startDate) || hasExplicitTime(endDate));\n\n const displayLabel = !startDate\n ? 'Any'\n : !endDate || startDate.getTime() === endDate.getTime()\n ? formatDateLabel(startDate)\n : `${formatDateLabel(startDate)} – ${formatDateLabel(endDate)}`;\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) {\n onChangeValue({ startDate: null, endDate: null });\n return;\n }\n onChangeValue({ startDate: range.from, endDate: range.to ?? range.from });\n }\n\n function pickStartTime(time: string) {\n if (!startDate) return;\n onChangeValue({ startDate: applyTimeToDate(startDate, time), endDate });\n }\n\n function pickEndTime(time: string) {\n if (!endDate) return;\n onChangeValue({ startDate, endDate: applyTimeToDate(endDate, time) });\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover defaultOpen={autoOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={startDate ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-fit\">\n <div className=\"flex flex-col gap-2\">\n <Calendar\n mode=\"range\"\n selected={{ from: startDate ?? undefined, to: endDate ?? undefined }}\n onSelect={pickRange}\n />\n {showTimeInputs && (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex w-full items-center gap-2\">\n <Label\n htmlFor={`${definition.key}-start-time`}\n className=\"text-body-sm text-muted-foreground w-10 shrink-0\"\n >\n Start\n </Label>\n <Input\n id={`${definition.key}-start-time`}\n type=\"time\"\n className=\"w-full\"\n value={formatTimeForInput(startDate)}\n onChange={e => pickStartTime(e.target.value)}\n disabled={!startDate}\n />\n </div>\n <div className=\"flex w-full items-center gap-2\">\n <Label\n htmlFor={`${definition.key}-end-time`}\n className=\"text-body-sm text-muted-foreground w-10 shrink-0\"\n >\n End\n </Label>\n <Input\n id={`${definition.key}-end-time`}\n type=\"time\"\n className=\"w-full\"\n value={formatTimeForInput(endDate)}\n onChange={e => pickEndTime(e.target.value)}\n disabled={!endDate}\n />\n </div>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\nexport {\n FilterBar,\n FilterChip,\n type FilterType,\n type FilterDefinition,\n type CheckboxFilterDefinition,\n type RadioFilterDefinition,\n type TextFilterDefinition,\n type MultiTextFilterDefinition,\n type DateFilterDefinition,\n type ActiveFilter,\n type FilterOption,\n type FilterValue,\n type CheckboxFilterValue,\n type RadioFilterValue,\n type TextFilterValue,\n type MultiTextFilterValue,\n type DateFilterValue,\n type FilterBarProps,\n};\n","/**\n * Non-CEL column filter definitions — the `meta.filter` vocabulary consumed by\n * contextual (right-click cell) filtering and by the plain filter bar.\n * Mirrors TableWrapper's `Filters/types.ts` shapes; `id` is omitted here since\n * it comes from the owning `ColumnDef.id`, not the filter definition itself.\n */\n\nexport type ColumnFilterType = 'checkbox' | 'radio' | 'dateRange' | 'text' | 'multiText';\n\nexport type ColumnFilterOption = {\n label: string;\n value: string;\n disabled?: boolean;\n children?: ColumnFilterOption[];\n};\n\nexport type FetchColumnFilterOptionsArgs = {\n query: string;\n page: number;\n signal: AbortSignal;\n};\n\nexport type FetchColumnFilterOptionsResult = {\n items: ColumnFilterOption[];\n hasMore: boolean;\n};\n\nexport type FetchColumnFilterOptions = (args: FetchColumnFilterOptionsArgs) => Promise<FetchColumnFilterOptionsResult>;\n\ntype ColumnFilterBase = {\n title: string;\n type: ColumnFilterType;\n order?: number;\n};\n\ntype StaticCheckboxColumnFilter = ColumnFilterBase & {\n type: 'checkbox';\n options: string[] | ColumnFilterOption[];\n fetchFilterOptions?: never;\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\ntype AsyncCheckboxColumnFilter = ColumnFilterBase & {\n type: 'checkbox';\n fetchFilterOptions: FetchColumnFilterOptions;\n options?: never;\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\nexport type CheckboxColumnFilter = StaticCheckboxColumnFilter | AsyncCheckboxColumnFilter;\n\nexport type RadioColumnFilter = ColumnFilterBase & {\n type: 'radio';\n options: string[] | ColumnFilterOption[];\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\nexport type DateRangeColumnFilter = ColumnFilterBase & {\n type: 'dateRange';\n /** When true, always show time inputs. When false, never show them. When omitted, auto-detect from value. */\n includeTime?: boolean;\n};\n\nexport type TextColumnFilter = ColumnFilterBase & {\n type: 'text';\n placeholder?: string;\n};\n\nexport type MultiTextColumnFilter = ColumnFilterBase & {\n type: 'multiText';\n /** Defaults to comma (`,`) when omitted. */\n delimiter?: string;\n description?: string;\n placeholder?: string;\n};\n\nexport type ColumnFilterDefinition =\n CheckboxColumnFilter | DateRangeColumnFilter | RadioColumnFilter | TextColumnFilter | MultiTextColumnFilter;\n\nexport type CheckboxColumnFilterValue = string[] | undefined;\nexport type RadioColumnFilterValue = string | undefined;\nexport type DateRangeColumnFilterValue = { startDate: Date | null; endDate: Date | null } | undefined;\nexport type TextColumnFilterValue = string | undefined;\nexport type MultiTextColumnFilterValue = string[] | undefined;\n\nexport type ColumnFilterValue =\n | CheckboxColumnFilterValue\n | RadioColumnFilterValue\n | DateRangeColumnFilterValue\n | TextColumnFilterValue\n | MultiTextColumnFilterValue;\n\nexport const isDateRangeColumnFilter = (definition: ColumnFilterDefinition): definition is DateRangeColumnFilter =>\n definition.type === 'dateRange';\n\nexport const isRadioColumnFilter = (definition: ColumnFilterDefinition): definition is RadioColumnFilter =>\n definition.type === 'radio';\n\nexport const isCheckboxColumnFilter = (definition: ColumnFilterDefinition): definition is CheckboxColumnFilter =>\n definition.type === 'checkbox';\n\nexport const isTextColumnFilter = (definition: ColumnFilterDefinition): definition is TextColumnFilter =>\n definition.type === 'text';\n\nexport const isMultiTextColumnFilter = (definition: ColumnFilterDefinition): definition is MultiTextColumnFilter =>\n definition.type === 'multiText';\n\nexport const isCheckboxColumnFilterValue = (value: unknown): value is CheckboxColumnFilterValue =>\n value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'string'));\n\nexport const isRadioColumnFilterValue = (value: unknown): value is RadioColumnFilterValue =>\n value === undefined || typeof value === 'string';\n\nexport const isDateRangeColumnFilterValue = (value: unknown): value is DateRangeColumnFilterValue =>\n value === undefined || (typeof value === 'object' && value !== null && 'startDate' in value && 'endDate' in value);\n","import { cn } from '@/lib/utils';\n\nfunction SectionHeader({ className, children, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"section-header\"\n className={cn('flex w-full items-start justify-between gap-4', className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nfunction SectionHeaderContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-content\" className={cn('flex flex-col gap-1', className)} {...props} />;\n}\n\nfunction SectionHeaderTitle({ className, ...props }: React.ComponentProps<'h2'>) {\n return <h2 data-slot=\"section-header-title\" className={cn('text-h3 text-foreground', className)} {...props} />;\n}\n\nfunction SectionHeaderDescription({ className, ...props }: React.ComponentProps<'p'>) {\n return (\n <p data-slot=\"section-header-description\" className={cn('text-body text-muted-foreground', className)} {...props} />\n );\n}\n\nfunction SectionHeaderMeta({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"section-header-meta\"\n className={cn(\n 'text-body text-muted-foreground flex flex-wrap items-center gap-4',\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--icon-default)\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction SectionHeaderActions({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-actions\" className={cn('flex items-center gap-2', className)} {...props} />;\n}\n\nfunction SectionHeaderTabs({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-tabs\" className={cn('border-b', className)} {...props} />;\n}\n\nexport {\n SectionHeader,\n SectionHeaderContent,\n SectionHeaderTitle,\n SectionHeaderDescription,\n SectionHeaderMeta,\n SectionHeaderActions,\n SectionHeaderTabs,\n};\n","'use client';\n\nimport * as React from 'react';\nimport {\n Background,\n Controls,\n Edge,\n EdgeTypes,\n MiniMap,\n NodeTypes,\n ReactFlow,\n ReactFlowProvider,\n useReactFlow,\n} from 'reactflow';\n\nimport { GraphActionsProvider, GraphActionsProviderRef } from './graph-actions-provider';\nimport { GraphEdge } from './graph-edge';\nimport { GraphNode, GraphNodeSkeleton, isDefaultNode, NodeDefault, NodeLoading } from './graph-node';\nimport { useAutoLayout } from './hooks/useAutoLayout';\nimport { useGraphActionsContext } from './hooks/useGraphActionsContext';\nimport { useNodeVisibility } from './hooks/useNodeVisibility';\n\n// Internal component that uses auto-layout\nconst GraphViewInternal: React.FC<\n React.PropsWithChildren<{\n nodeTypes?: NodeTypes;\n edgeTypes?: EdgeTypes;\n viewportFocusNodeId?: string;\n }>\n> = ({ nodeTypes: parentNodeTypes, edgeTypes: parentEdgeTypes, children, viewportFocusNodeId }) => {\n const { nodes, edges, toggleNodeExpansion } = useGraphActionsContext();\n\n const nodeTypes: NodeTypes = React.useMemo(\n () => ({\n default: GraphNode,\n loading: GraphNodeSkeleton,\n ...parentNodeTypes,\n }),\n [parentNodeTypes],\n );\n\n const edgeTypes: EdgeTypes = React.useMemo(\n () => ({\n default: GraphEdge,\n ...parentEdgeTypes,\n }),\n [parentEdgeTypes],\n );\n\n // Use node visibility hook to manage visibility based on parent expansion\n const { nodes: visibleNodes, edges: visibleEdges } = useNodeVisibility(nodes, edges);\n\n // Add onExpandToggle functionality to nodes that need it\n const nodesWithExpansion = React.useMemo(() => {\n return visibleNodes.map(node => {\n if (isDefaultNode(node) && !node.data.onExpandToggle) {\n return {\n ...node,\n data: {\n ...node.data,\n onExpandToggle: toggleNodeExpansion,\n },\n };\n }\n return node;\n });\n }, [visibleNodes, toggleNodeExpansion]);\n\n // Apply auto-layout to visible nodes and edges\n const {\n nodes: layoutedNodes,\n edges: layoutedEdges,\n nodeMap,\n } = useAutoLayout(nodesWithExpansion, visibleEdges, {\n viewportFocusNodeId,\n });\n\n useViewportFocus(nodeMap, viewportFocusNodeId);\n\n return (\n <ReactFlow\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n nodes={layoutedNodes}\n edges={layoutedEdges}\n nodesConnectable={false}\n nodesDraggable={false}\n fitView={viewportFocusNodeId ? false : true}\n fitViewOptions={{\n maxZoom: 1,\n }}\n proOptions={{\n hideAttribution: true,\n }}\n panOnScroll\n selectionOnDrag\n >\n <Background className=\"bg-muted text-muted\" />\n <Controls showInteractive={false} />\n <MiniMap zoomable pannable />\n {children}\n </ReactFlow>\n );\n};\n\nconst GraphView = React.forwardRef<\n GraphActionsProviderRef,\n React.PropsWithChildren<{\n viewportFocusNodeId?: string;\n defaultNodes?: (NodeLoading | NodeDefault)[];\n defaultEdges?: Edge[];\n nodeTypes?: NodeTypes;\n edgeTypes?: EdgeTypes;\n children?: React.ReactNode;\n }>\n>(({ defaultNodes = [], defaultEdges = [], nodeTypes, edgeTypes, children, viewportFocusNodeId }, ref) => {\n return (\n <ReactFlowProvider>\n <GraphActionsProvider ref={ref} initialNodes={defaultNodes} initialEdges={defaultEdges}>\n <GraphViewInternal nodeTypes={nodeTypes} edgeTypes={edgeTypes} viewportFocusNodeId={viewportFocusNodeId}>\n {children}\n </GraphViewInternal>\n </GraphActionsProvider>\n </ReactFlowProvider>\n );\n});\n\nGraphView.displayName = 'GraphView';\n\nexport { GraphView };\n\nfunction useViewportFocus(nodeMap: Map<string, NodeLoading | NodeDefault>, viewportFocusNodeId?: string) {\n const flow = useReactFlow();\n\n React.useEffect(() => {\n if (viewportFocusNodeId) {\n const focusNode = nodeMap.get(viewportFocusNodeId);\n if (focusNode) {\n flow.setCenter(focusNode.position.x, focusNode.position.y, { zoom: 1 });\n }\n }\n }, [viewportFocusNodeId, flow, nodeMap]);\n}\n","/**\n * Auto Layout Algorithm for Graph Positioning\n *\n * This hook implements a tree-based layout algorithm that positions nodes in a hierarchical graph.\n * The algorithm ensures proper spacing and positioning by finding the actual lowest positioned nodes.\n *\n * Flow Overview:\n * 1. Filter visible nodes (exclude hidden nodes from layout calculations)\n * 2. Build tree structure from nodes and edges using getTrees()\n * 3. Position nodes recursively with positionNodes():\n * - Calculate X position based on node depth in hierarchy\n * - Calculate Y position based on actual lowest positioned node in previous sibling's subtree\n * - Use getLowestPositionYInSubtree() to find the real bottom of each subtree\n * 4. Flatten positioned tree back to array of nodes\n * 5. Return only visible nodes with their calculated positions\n *\n * Key Features:\n * - Sibling nodes are positioned below the actual lowest node in previous sibling's entire subtree\n * - Uses Math.max to find the deepest positioned node across all child subtrees\n * - Proper horizontal spacing based on hierarchy depth\n * - Vertical spacing prevents node overlapping by using real node positions\n * - Hidden nodes are completely excluded from ReactFlow\n * - Loading nodes are properly displayed when parent is expanded\n *\n */\n\nimport { useMemo } from 'react';\nimport { Edge, Position } from 'reactflow';\n\nimport { GRAPH_NODE_HEIGHT, GRAPH_NODE_SEP, GRAPH_NODE_WIDTH, GRAPH_RANK_SEP } from '../consts';\nimport { NodeDefault, NodeLoading } from '../graph-node';\n\nexport interface AutoLayoutReturn {\n nodes: (NodeLoading | NodeDefault)[];\n edges: Edge[];\n nodeMap: Map<string, NodeLoading | NodeDefault>;\n}\n\n// Constants for positioning (adapted from console helpers)\nconst TILE_HORIZONTAL_DISTANCE = GRAPH_RANK_SEP;\nconst TILE_VERTICAL_DISTANCE = GRAPH_NODE_SEP;\nconst TILE_HEIGHT = GRAPH_NODE_HEIGHT;\nconst TILE_WIDTH = GRAPH_NODE_WIDTH;\n\n// Tree structure for positioning algorithm\nexport interface NodeTree {\n node: NodeLoading | NodeDefault;\n children?: NodeTree[];\n}\n\n// Calculate depth of a node in the tree with cycle detection\nconst getNodeDepth = (\n nodeId: string,\n edges: Edge[],\n visited: Set<string> = new Set(),\n maxDepth: number = 100,\n): number => {\n // Check for cycle detection\n if (visited.has(nodeId)) {\n console.warn(`Cycle detected in graph at node: ${nodeId}. Returning depth 0 to prevent infinite recursion.`);\n return 0; // Return 0 depth for cyclic nodes to treat them as root-level\n }\n\n // Check maximum depth limit as additional safety\n if (visited.size >= maxDepth) {\n console.warn(`Maximum depth limit (${maxDepth}) reached for node: ${nodeId}.`);\n return visited.size;\n }\n\n const parentEdge = edges.find(edge => edge.target === nodeId);\n if (!parentEdge) {\n return 0; // Root node\n }\n\n // Add current node to visited set and recurse\n const newVisited = new Set([...visited, nodeId]);\n return 1 + getNodeDepth(parentEdge.source, edges, newVisited, maxDepth);\n};\n\n// Flatten tree structure to array of nodes\nexport const flatNodeTree = (nodeTree: NodeTree): (NodeLoading | NodeDefault)[] => {\n const { node, children } = nodeTree;\n\n if (!children) {\n return [node];\n }\n\n return [node, ...children.flatMap(flatNodeTree)];\n};\n\n// Get recursively the children of the node\nexport const getChildren = (nodeId: string, nodes: (NodeLoading | NodeDefault)[], edges: Edge[]): NodeTree[] => {\n const nodeEdges = edges.filter(edge => edge.source === nodeId);\n\n return nodeEdges\n .map(edge => nodes.find(node => node.id === edge.target))\n .filter((node): node is NodeLoading | NodeDefault => node !== undefined)\n .map(node => ({\n node,\n children: getChildren(node.id, nodes, edges),\n }));\n};\n\n// Transform nodes and edges to a tree structure\n// If there are more than one root, create separate trees\nexport const getTrees = (nodes: (NodeLoading | NodeDefault)[], edges: Edge[]): NodeTree[] =>\n nodes\n .filter(node => !edges.some(edge => edge.target === node.id))\n .map(node => ({\n node,\n children: getChildren(node.id, nodes, edges),\n }));\n\n// Calculate the sum of positionY down the tree for sibling positioning\nexport const getTheSumOfPositionYDownTheTree = (nodeTree: NodeTree, sum: number = 0): number => {\n const { children } = nodeTree;\n\n if (!children?.length) {\n return sum;\n }\n\n const visibleChildren = children.filter(({ node }) => !node.hidden);\n\n if (visibleChildren.length === 0) {\n return sum;\n }\n\n // For siblings, count the direct children spacing\n // Each child takes TILE_HEIGHT + TILE_VERTICAL_DISTANCE space\n const directChildrenHeight = (visibleChildren.length - 1) * (TILE_HEIGHT + TILE_VERTICAL_DISTANCE);\n\n // Find the maximum height among all child subtrees (not just the last one)\n const childSubtreeHeights = visibleChildren.map(child => getTheSumOfPositionYDownTheTree(child, 0));\n const maxChildSubtreeHeight = childSubtreeHeights.length > 0 ? Math.max(...childSubtreeHeights) : 0;\n\n return sum + directChildrenHeight + maxChildSubtreeHeight;\n};\n\n// Find the lowest positioned node (highest Y value) in a subtree\nexport const getLowestPositionYInSubtree = (nodeTree: NodeTree): number => {\n const { node, children } = nodeTree;\n\n // Start with current node's Y position\n const lowestY = node.position.y;\n\n if (!children?.length) {\n return lowestY;\n }\n\n const visibleChildren = children.filter(({ node: { hidden } }) => !hidden);\n\n if (visibleChildren.length === 0) {\n return lowestY;\n }\n\n // Find the lowest Y position among all children recursively\n const childLowestYPositions = visibleChildren.map(child => getLowestPositionYInSubtree(child));\n const lowestChildY = Math.max(...childLowestYPositions);\n\n return Math.max(lowestY, lowestChildY);\n};\n\n// Position nodes recursively with proper sibling spacing\nexport const positionNodes = (\n treeNodes: NodeTree[],\n rootFlattenTree?: (NodeLoading | NodeDefault)[],\n allEdges?: Edge[],\n parentY?: number,\n): NodeTree[] => {\n const flattenTree = rootFlattenTree || treeNodes.flatMap(flatNodeTree);\n\n return treeNodes.reduce((actualTreeNodes, nodeTree, treeNodeIndex) => {\n const { node, children } = nodeTree;\n\n // Calculate depth for X position\n const depth = allEdges ? getNodeDepth(node.id, allEdges) : 0;\n\n // Calculate Y position based on siblings and parent position\n const getPositionY = (): number => {\n if (treeNodeIndex > 0) {\n // Find the lowest positioned node in the previous sibling's subtree\n const previousSibling = actualTreeNodes[treeNodeIndex - 1];\n const lowestYInPreviousSubtree = getLowestPositionYInSubtree(previousSibling);\n\n // Position this node below the lowest node in previous sibling's subtree\n return lowestYInPreviousSubtree + TILE_HEIGHT + TILE_VERTICAL_DISTANCE;\n }\n\n // For first child, use parent's Y position if available, otherwise use index-based positioning\n if (parentY !== undefined) {\n return parentY;\n }\n\n return (TILE_HEIGHT + TILE_VERTICAL_DISTANCE) * treeNodeIndex;\n };\n\n const position = {\n x: depth * (TILE_WIDTH + TILE_HORIZONTAL_DISTANCE),\n y: getPositionY(),\n };\n\n const positionedNode = {\n ...node,\n targetPosition: Position.Left,\n sourcePosition: Position.Right,\n position,\n };\n\n if (!children?.length) {\n return [\n ...actualTreeNodes,\n {\n ...nodeTree,\n node: positionedNode,\n },\n ];\n }\n\n const nodeWithChildren = {\n ...nodeTree,\n node: positionedNode,\n children: positionNodes(\n children.sort((a, b) => {\n // Simple sorting by node id as fallback since data structure may vary\n return a.node.id.localeCompare(b.node.id);\n }),\n flattenTree,\n allEdges,\n position.y, // Pass parent's Y position to children\n ),\n };\n\n return [...actualTreeNodes, nodeWithChildren];\n }, [] as NodeTree[]);\n};\n\n// Main layout function using the tree algorithm\nexport const getLaidOutElements = (\n nodes: (NodeLoading | NodeDefault)[],\n edges: Edge[],\n): { nodes: (NodeLoading | NodeDefault)[]; edges: Edge[] } => {\n const nodeTrees = getTrees(nodes, edges);\n const positionedNodes = positionNodes(nodeTrees, undefined, edges).flatMap(flatNodeTree);\n\n return { nodes: positionedNodes, edges };\n};\n\nexport const useAutoLayout = (\n nodes: (NodeLoading | NodeDefault)[],\n edges: Edge[],\n { viewportFocusNodeId }: { viewportFocusNodeId?: string },\n): AutoLayoutReturn => {\n const laidOutElements = useMemo(() => {\n if (nodes.length === 0) {\n return { nodes, edges, nodeMap: new Map() };\n }\n\n // Filter out hidden nodes for layout calculation\n const visibleNodes = nodes.filter(node => !node.hidden);\n const visibleNodeIds = new Set(visibleNodes.map(node => node.id));\n const visibleEdges = edges.filter(edge => visibleNodeIds.has(edge.source) && visibleNodeIds.has(edge.target));\n\n // Use the tree-based layout algorithm instead of Dagre\n const { nodes: laidOutNodes, edges: laidOutEdges } = getLaidOutElements(visibleNodes, visibleEdges);\n\n // Return all nodes but with updated positions for visible ones\n const laidOutNodeMap = new Map(laidOutNodes.map(node => [node.id, node]));\n\n // Highlight the node if viewportFocusNodeId is provided\n if (viewportFocusNodeId) {\n const highlightedNode = laidOutNodeMap.get(viewportFocusNodeId);\n if (highlightedNode) {\n laidOutNodeMap.set(viewportFocusNodeId, {\n ...highlightedNode,\n data: { ...highlightedNode.data, isHighlighted: true },\n });\n }\n }\n // Only return visible nodes with their layouted positions\n const finalNodes = nodes\n .filter(node => !node.hidden) // Filter first to avoid unnecessary mapping\n .map(node => laidOutNodeMap.get(node.id) || node); // Get laid out version or fallback to original\n\n return {\n nodes: finalNodes,\n edges: laidOutEdges,\n nodeMap: laidOutNodeMap,\n };\n }, [nodes, edges, viewportFocusNodeId]);\n\n return laidOutElements;\n};\n","import { useCallback, useMemo } from 'react';\nimport { Edge } from 'reactflow';\n\nimport { isDefaultNode, NodeDefault, NodeLoading } from '../graph-node';\n\nexport interface UseNodeVisibilityReturn {\n nodes: (NodeLoading | NodeDefault)[];\n edges: Edge[];\n}\n\nexport const useNodeVisibility = (nodes: (NodeLoading | NodeDefault)[], edges: Edge[]): UseNodeVisibilityReturn => {\n // Helper function to check if a node has real (non-loading) children\n const hasRealChildren = useCallback(\n (nodeId: string) => {\n const childEdges = edges.filter(edge => edge.source === nodeId);\n const childNodes = childEdges.map(edge => nodes.find(node => node.id === edge.target)).filter(Boolean);\n return childNodes.some(child => child && child.type !== 'loading');\n },\n [nodes, edges],\n );\n\n // Helper function to check if all ancestors are expanded\n const areAllAncestorsExpanded = useCallback(\n (nodeId: string): boolean => {\n const parentEdges = edges.filter(edge => edge.target === nodeId);\n if (parentEdges.length === 0) {\n return true;\n }\n\n for (const parentEdge of parentEdges) {\n const parentNode = nodes.find(node => node.id === parentEdge.source);\n if (!parentNode) {\n return false;\n }\n\n const isParentExpanded = isDefaultNode(parentNode) ? Boolean(parentNode.data.expanded) : true;\n\n if (!isParentExpanded) {\n return false;\n }\n }\n\n return parentEdges.every(parentEdge => areAllAncestorsExpanded(parentEdge.source));\n },\n [nodes, edges],\n );\n\n const visibleNodes = useMemo(() => {\n return nodes.map(node => {\n const shouldBeVisible = areAllAncestorsExpanded(node.id);\n\n // Loading nodes - only set visibility\n if (node.type === 'loading') {\n const loadingNode: NodeLoading = {\n id: node.id,\n position: node.position,\n type: 'loading',\n hidden: !shouldBeVisible,\n data: node.data,\n };\n return loadingNode;\n }\n\n // Default nodes - set visibility and update expansion data\n if (isDefaultNode(node)) {\n const expandedNode: NodeDefault = {\n id: node.id,\n position: node.position,\n type: node.type,\n hidden: !shouldBeVisible,\n data: {\n ...node.data,\n expanded: Boolean(node.data.expanded),\n isExpandable: hasRealChildren(node.id),\n // onExpandToggle will be added later in GraphView\n },\n };\n return expandedNode;\n }\n\n return node;\n });\n }, [nodes, areAllAncestorsExpanded, hasRealChildren]);\n\n const visibleEdges = useMemo(() => {\n const visibleNodeIds = new Set(visibleNodes.filter(node => !node.hidden).map(node => node.id));\n return edges.filter(edge => visibleNodeIds.has(edge.source) && visibleNodeIds.has(edge.target));\n }, [visibleNodes, edges]);\n\n return { nodes: visibleNodes, edges: visibleEdges };\n};\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Node, useStore, useViewport } from 'reactflow';\n\nimport { GRAPH_NODE_HEIGHT, GRAPH_NODE_WIDTH } from '../consts';\n\nconst useGetDebouncedViewport = (\n debounceDelay: number = 1000,\n): {\n x: number;\n y: number;\n zoom: number;\n width: number;\n height: number;\n nodes: Node[];\n} => {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [debouncedValues, setDebouncedValues] = useState<{\n x: number;\n y: number;\n zoom: number;\n width: number;\n height: number;\n nodes: Node[];\n }>({ x: 0, y: 0, zoom: 1, width: 0, height: 0, nodes: [] });\n\n const { x, y, zoom } = useViewport();\n const { width, height, nodes } = useStore(state => ({\n width: state.width,\n height: state.height,\n nodes: state.getNodes(),\n }));\n\n const nodesHash = nodes\n .map(n => n.id)\n .sort()\n .join(',');\n const memoizedNodes = useMemo(() => nodes, [nodesHash]);\n\n useEffect(() => {\n // Clear existing timer\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n // Set new timer\n timerRef.current = setTimeout(() => {\n setDebouncedValues({ x, y, zoom, width, height, nodes: memoizedNodes });\n timerRef.current = null;\n }, debounceDelay);\n\n // Cleanup function to clear timer on unmount or dependency change\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n }, [x, y, zoom, width, height, memoizedNodes, debounceDelay]);\n\n return debouncedValues;\n};\n\nexport const useGetViewportNodeIds = (debounceDelay: number = 1000) => {\n const { x, y, zoom, width, height, nodes } = useGetDebouncedViewport(debounceDelay);\n\n return useMemo(() => {\n return nodes\n .filter(node => {\n if (node.hidden) {\n return false;\n }\n\n const nodeX = (node.positionAbsolute?.x ?? node.position.x) * zoom + x;\n const nodeY = (node.positionAbsolute?.y ?? node.position.y) * zoom + y;\n const nodeW = GRAPH_NODE_WIDTH * zoom;\n const nodeH = GRAPH_NODE_HEIGHT * zoom;\n\n return nodeX + nodeW >= 0 && nodeX <= width && nodeY + nodeH >= 0 && nodeY <= height;\n })\n .map(node => node.id)\n .sort((a, b) => a.localeCompare(b));\n }, [x, y, zoom, width, height, nodes]);\n};\n","import { Edge, getOutgoers, Node } from 'reactflow';\n\nexport const getGraphDescendants = (node: Node, nodes: Node[], edges: Edge[]): { nodes: Node[]; edges: Edge[] } => {\n const outgoers = getOutgoers(node, nodes, edges);\n\n return outgoers.reduce(\n (acc, outgoer) => {\n const { nodes: outgoerNodes, edges: outgoerEdges } = getGraphDescendants(outgoer, nodes, edges);\n return {\n nodes: [...acc.nodes, ...outgoerNodes],\n edges: [...acc.edges, ...outgoerEdges.filter(edge => edge.source === outgoer.id)],\n };\n },\n { nodes: [node], edges: edges.filter(edge => edge.source === node.id) },\n );\n};\n"],"mappings":"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","names":["React","useCallback","Position","jsx","jsxs","_a","_b","Position","useCallback","jsx","React","Icon","Icon","jsx","jsxs","Icon","React","React","Icon","Badge","Button","Fragment","jsx","jsxs","Button","Icon","_a","Badge","jsx","jsx","React","useMemo","Position","Position","useMemo","useCallback","useMemo","useCallback","useMemo","jsx","jsxs","jsx","jsxs","_a","_b","Icon","useEffect","useMemo","useRef","useState","useRef","useState","useMemo","useEffect","getOutgoers"]}
package/dist/index.d.ts CHANGED
@@ -3,9 +3,12 @@ export { C as CelColumnDefinition, a as CelColumnOption, b as CelConditionValue,
3
3
  export { ChartAction, ChartConfig, ChartContainer, ChartDescription, ChartFooter, ChartHeader, ChartLegend, ChartLegendContent, ChartStyle, ChartTitle, ChartTooltip, ChartTooltipContent } from './chart.js';
4
4
  export { ChatInput, ChatInputProps, ChatInterface, ChatInterfaceProps, ChatMessage, ChatMessageBubble, ChatRoutine, ChatSession, ChatSessionList, ChatSessionListProps, ChatThread, ChatThreadProps, ChatToolCall } from './chat-interface.js';
5
5
  export { CodeBlock, CodeBlockBody, CodeBlockCopyButton, CodeBlockDownloadButton, CodeBlockFooter, CodeBlockHeader } from './code-block.js';
6
- export { CellContextualFilter, CellContextualFilterProps, ColumnOptions, ColumnOptionsProps, ContextualMenuAction, DataTable, DataTableBody, DataTableCelFilterConfig, DataTableCell, DataTableEmptyConfig, DataTableEmptyView, DataTableExpandedRow, DataTableGroupRow, DataTableHeader, DataTablePagination, DataTablePaginationConfig, DataTablePaginationProps, DataTableProps, DataTableRow, DataTableRowProps, DataTableSkeletonBody, DataTableValueCell, DataTableValueCellProps, ExpandButton, RowActionItem, RowActions, RowCountRelation, StickyHeaderConfig, TableHookOptions, TableLayout, TimestampCell, ViewFilter, ViewFilterProps, defaultEmptyConfig, defaultErrorConfig, defaultNoFilterFoundConfig, getActionsColumnDefinition, getExpandColumnDefinition, normalizePageSizeOptions } from './data-table.js';
6
+ export { CellContextualFilter, CellContextualFilterProps, ColumnOptions, ColumnOptionsProps, ContextualMenuAction, DataTable, DataTableBody, DataTableCelFilterConfig, DataTableCell, DataTableExpandedRow, DataTableFilterVisibilityConfig, DataTableGroupRow, DataTableHeader, DataTablePagination, DataTablePaginationConfig, DataTablePaginationProps, DataTableProps, DataTableRow, DataTableRowProps, DataTableSkeletonBody, DataTableValueCell, DataTableValueCellProps, ExpandButton, RowActionItem, RowActions, RowCountRelation, StickyHeaderConfig, TableHookOptions, TableLayout, TimestampCell, ViewFilter, ViewFilterProps, getActionsColumnDefinition, getExpandColumnDefinition, normalizePageSizeOptions } from './data-table.js';
7
+ export { D as DataTableEmptyConfig, a as DataTableEmptyView, d as defaultEmptyConfig, b as defaultErrorConfig, c as defaultNoFilterFoundConfig } from './empty-view-DO36LNvk.js';
7
8
  export { ActiveFilter, CheckboxFilterDefinition, CheckboxFilterValue, DateFilterDefinition, DateFilterValue, FilterBar, FilterBarProps, FilterChip, FilterDefinition, FilterOption, FilterType, FilterValue, MultiTextFilterDefinition, MultiTextFilterValue, RadioFilterDefinition, RadioFilterValue, TextFilterDefinition, TextFilterValue } from './filter-bar.js';
8
9
  export { FloatingWidget, FloatingWidgetProvider, useFloatingWidget } from './floating-widget.js';
10
+ export { Edge, Node } from 'reactflow';
11
+ export { AutoLayoutReturn, Graph, GraphActions, GraphActionsProvider, GraphActionsProviderRef, GraphBadgeVariant, GraphDataState, GraphEdge, GraphEmptyView, GraphNode, GraphNodeProps, GraphNodeSkeleton, GraphOptions, GraphProps, GraphView, NodeData, NodeDefault, NodeLoading, UseNodeVisibilityReturn, defaultGraphEmptyConfig, defaultGraphErrorConfig, defaultGraphNoFilterFoundConfig, getGraphDescendants, isDefaultNode, useAutoLayout, useGetViewportNodeIds, useGraphActions, useGraphActionsContext, useNodeVisibility } from './graph.js';
9
12
  export { PageHeader, PageHeaderActions, PageHeaderAvatar, PageHeaderContent, PageHeaderDescription, PageHeaderMeta, PageHeaderTabs, PageHeaderTitle } from './page-header.js';
10
13
  export { AbsoluteTimestamp, AbsoluteTimestampProps, ElapsedTime, ElapsedTimeProps, RelativeTime, RelativeTimeProps } from './relative-time.js';
11
14
  export { SectionHeader, SectionHeaderActions, SectionHeaderContent, SectionHeaderDescription, SectionHeaderMeta, SectionHeaderTabs, SectionHeaderTitle } from './section-header.js';