@sqlrooms/cells 0.29.0-rc.3 → 0.29.0-rc.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SqlCellContent.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellContent.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EACV,kBAAkB,EAElB,OAAO,EAER,MAAM,UAAU,CAAC;AAQlB,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,KAAK,CAAC,YAAY,CAAC;CACpE,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA8KxD,CAAC"}
1
+ {"version":3,"file":"SqlCellContent.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellContent.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAElD,OAAO,KAAK,EACV,kBAAkB,EAElB,OAAO,EAER,MAAM,UAAU,CAAC;AAQlB,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,KAAK,CAAC,YAAY,CAAC;CACpE,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAyKxD,CAAC"}
@@ -3,7 +3,7 @@ import { getCoreDuckDbConnectionId } from '@sqlrooms/db';
3
3
  import { useRoomStoreApi } from '@sqlrooms/room-store';
4
4
  import { produce } from 'immer';
5
5
  import { CornerDownRightIcon } from 'lucide-react';
6
- import { useCallback, useEffect, useMemo, useRef } from 'react';
6
+ import { useCallback, useMemo } from 'react';
7
7
  import { useCellsStore } from '../hooks';
8
8
  import { SqlCellConnectionSelector } from './SqlCellConnectionSelector';
9
9
  import { SqlCellDependentsMenu } from './SqlCellDependentsMenu';
@@ -51,8 +51,8 @@ export const SqlCellContent = ({ id, cell, renderContainer, }) => {
51
51
  c.data.sql = query;
52
52
  }
53
53
  }));
54
- handleRunRef.current();
55
- }, [id, storeApi]);
54
+ runCell(id);
55
+ }, [id, runCell, storeApi]);
56
56
  const handleConnectorChange = useCallback((connectorId) => {
57
57
  updateCell(id, (c) => produce(c, (draft) => {
58
58
  if (draft.type === 'sql') {
@@ -82,10 +82,6 @@ export const SqlCellContent = ({ id, cell, renderContainer, }) => {
82
82
  }
83
83
  : undefined;
84
84
  const isRunning = status?.state === 'running';
85
- const handleRunRef = useRef(handleRun);
86
- useEffect(() => {
87
- handleRunRef.current = handleRun;
88
- }, [handleRun]);
89
85
  const content = (_jsxs("div", { className: "flex flex-col", children: [_jsx(SqlCellEditor, { sql: cell.data.sql, connector: connector, tableSchemas: tableSchemas, onChange: handleSqlChange, onRunQuery: handleRunQuery }), _jsx(SqlCellResults, { cellId: id, cellResult: cellResult, resultName: resultName, isRunning: isRunning, errorMessage: status?.state === 'error' ? status.message : undefined, resultVersion: resultVersion, fetchCellResultPage: fetchCellResultPage })] }));
90
86
  const footer = (_jsxs("div", { className: "text-muted-foreground flex items-center gap-1 px-2 py-1 text-xs", children: [_jsx(CornerDownRightIcon, { className: "h-3 w-3" }), _jsx(SqlCellDependentsMenu, { cellId: id, artifactId: artifactId, cellsData: cellsData, artifacts: artifacts, getDownstream: getDownstream }), _jsx(SqlCellResultNameEditor, { cellId: id, value: resultName, onChange: handleResultNameChange })] }));
91
87
  return renderContainer({
@@ -1 +1 @@
1
- {"version":3,"file":"SqlCellContent.js","sourceRoot":"","sources":["../../src/components/SqlCellContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import {getCoreDuckDbConnectionId} from '@sqlrooms/db';\nimport {useRoomStoreApi} from '@sqlrooms/room-store';\nimport {type Draft, produce} from 'immer';\nimport {CornerDownRightIcon} from 'lucide-react';\nimport React, {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {useCellsStore} from '../hooks';\nimport type {\n CellContainerProps,\n CellsRootState,\n SqlCell,\n SqlCellStatus,\n} from '../types';\nimport {SqlCellConnectionSelector} from './SqlCellConnectionSelector';\nimport {SqlCellDependentsMenu} from './SqlCellDependentsMenu';\nimport {SqlCellEditor} from './SqlCellEditor';\nimport {SqlCellResultNameEditor} from './SqlCellResultNameEditor';\nimport {SqlCellResults} from './SqlCellResults';\nimport {SqlCellRunButton} from './SqlCellRunButton';\n\nexport type SqlCellContentProps = {\n id: string;\n cell: SqlCell;\n renderContainer: (props: CellContainerProps) => React.ReactElement;\n};\n\nexport const SqlCellContent: React.FC<SqlCellContentProps> = ({\n id,\n cell,\n renderContainer,\n}) => {\n const storeApi = useRoomStoreApi<CellsRootState>();\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n const runCell = useCellsStore((s) => s.cells.runCell);\n const cancelCell = useCellsStore((s) => s.cells.cancelCell);\n const getDownstream = useCellsStore((s) => s.cells.getDownstream);\n const artifactId = useCellsStore((s) => s.cells.getArtifactIdForCell(id));\n const cellsData = useCellsStore((s) => s.cells.config.data);\n const artifacts = useCellsStore((s) => s.cells.config.artifacts);\n const cellStatus = useCellsStore((s) => s.cells.status[id]);\n const resultVersion = useCellsStore((s) => s.cells.resultVersion?.[id] ?? 0);\n const pageVersion = useCellsStore((s) => s.cells.pageVersion?.[id] ?? 0);\n const getCellResult = useCellsStore((s) => s.cells.getCellResult);\n const fetchCellResultPage = useCellsStore((s) => s.cells.fetchCellResultPage);\n const dbConnections = useCellsStore((s) => s.db.config.connections);\n const connector = useCellsStore((s) => s.db.connector);\n const tableSchemas = useCellsStore((s) => s.db.tables);\n\n // Re-read the cache whenever resultVersion or pageVersion changes\n const cellResult = useMemo(\n () => getCellResult(id),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getCellResult, id, resultVersion, pageVersion],\n );\n\n const handleSqlChange = useCallback(\n (v: string | undefined) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.sql = v || '';\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const handleRun = useCallback(() => {\n runCell(id);\n }, [id, runCell]);\n\n const handleRunQuery = useCallback(\n (query: string) => {\n // Sync the actual query being executed to store before running\n // to avoid race condition with onChange callback\n storeApi.setState(\n produce(storeApi.getState(), (draft: Draft<CellsRootState>) => {\n const c = draft.cells?.config?.data?.[id];\n if (c && c.type === 'sql') {\n c.data.sql = query;\n }\n }),\n );\n handleRunRef.current();\n },\n [id, storeApi],\n );\n\n const handleConnectorChange = useCallback(\n (connectorId: string) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.connectorId = connectorId || undefined;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const handleCancel = useCallback(() => {\n cancelCell(id);\n }, [id, cancelCell]);\n\n const handleResultNameChange = useCallback(\n (value: string) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.resultName = value;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const resultName = cell.data.resultName || '';\n const selectedConnectorId =\n cell.data.connectorId || getCoreDuckDbConnectionId();\n\n const status =\n cellStatus?.type === 'sql'\n ? {\n state: (cellStatus as SqlCellStatus).status,\n message: (cellStatus as SqlCellStatus).lastError,\n resultName:\n (cellStatus as SqlCellStatus).resultView ||\n (cellStatus as SqlCellStatus).resultName,\n lastRunTime: (cellStatus as SqlCellStatus).lastRunTime,\n }\n : undefined;\n\n const isRunning = status?.state === 'running';\n\n const handleRunRef = useRef(handleRun);\n useEffect(() => {\n handleRunRef.current = handleRun;\n }, [handleRun]);\n\n const content = (\n <div className=\"flex flex-col\">\n <SqlCellEditor\n sql={cell.data.sql}\n connector={connector}\n tableSchemas={tableSchemas}\n onChange={handleSqlChange}\n onRunQuery={handleRunQuery}\n />\n <SqlCellResults\n cellId={id}\n cellResult={cellResult}\n resultName={resultName}\n isRunning={isRunning}\n errorMessage={status?.state === 'error' ? status.message : undefined}\n resultVersion={resultVersion}\n fetchCellResultPage={fetchCellResultPage}\n />\n </div>\n );\n\n const footer = (\n <div className=\"text-muted-foreground flex items-center gap-1 px-2 py-1 text-xs\">\n <CornerDownRightIcon className=\"h-3 w-3\" />\n <SqlCellDependentsMenu\n cellId={id}\n artifactId={artifactId}\n cellsData={cellsData}\n artifacts={artifacts}\n getDownstream={getDownstream}\n />\n <SqlCellResultNameEditor\n cellId={id}\n value={resultName}\n onChange={handleResultNameChange}\n />\n </div>\n );\n\n return renderContainer({\n header: (\n <div className=\"flex w-full items-center gap-2\">\n <SqlCellConnectionSelector\n connectors={dbConnections}\n selectedConnectorId={selectedConnectorId}\n onChange={handleConnectorChange}\n />\n <SqlCellRunButton\n onRun={handleRun}\n onCancel={handleCancel}\n status={status}\n runLabel=\"Run\"\n />\n </div>\n ),\n content,\n footer,\n });\n};\n"]}
1
+ {"version":3,"file":"SqlCellContent.js","sourceRoot":"","sources":["../../src/components/SqlCellContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import {getCoreDuckDbConnectionId} from '@sqlrooms/db';\nimport {useRoomStoreApi} from '@sqlrooms/room-store';\nimport {type Draft, produce} from 'immer';\nimport {CornerDownRightIcon} from 'lucide-react';\nimport React, {useCallback, useMemo} from 'react';\nimport {useCellsStore} from '../hooks';\nimport type {\n CellContainerProps,\n CellsRootState,\n SqlCell,\n SqlCellStatus,\n} from '../types';\nimport {SqlCellConnectionSelector} from './SqlCellConnectionSelector';\nimport {SqlCellDependentsMenu} from './SqlCellDependentsMenu';\nimport {SqlCellEditor} from './SqlCellEditor';\nimport {SqlCellResultNameEditor} from './SqlCellResultNameEditor';\nimport {SqlCellResults} from './SqlCellResults';\nimport {SqlCellRunButton} from './SqlCellRunButton';\n\nexport type SqlCellContentProps = {\n id: string;\n cell: SqlCell;\n renderContainer: (props: CellContainerProps) => React.ReactElement;\n};\n\nexport const SqlCellContent: React.FC<SqlCellContentProps> = ({\n id,\n cell,\n renderContainer,\n}) => {\n const storeApi = useRoomStoreApi<CellsRootState>();\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n const runCell = useCellsStore((s) => s.cells.runCell);\n const cancelCell = useCellsStore((s) => s.cells.cancelCell);\n const getDownstream = useCellsStore((s) => s.cells.getDownstream);\n const artifactId = useCellsStore((s) => s.cells.getArtifactIdForCell(id));\n const cellsData = useCellsStore((s) => s.cells.config.data);\n const artifacts = useCellsStore((s) => s.cells.config.artifacts);\n const cellStatus = useCellsStore((s) => s.cells.status[id]);\n const resultVersion = useCellsStore((s) => s.cells.resultVersion?.[id] ?? 0);\n const pageVersion = useCellsStore((s) => s.cells.pageVersion?.[id] ?? 0);\n const getCellResult = useCellsStore((s) => s.cells.getCellResult);\n const fetchCellResultPage = useCellsStore((s) => s.cells.fetchCellResultPage);\n const dbConnections = useCellsStore((s) => s.db.config.connections);\n const connector = useCellsStore((s) => s.db.connector);\n const tableSchemas = useCellsStore((s) => s.db.tables);\n\n // Re-read the cache whenever resultVersion or pageVersion changes\n const cellResult = useMemo(\n () => getCellResult(id),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getCellResult, id, resultVersion, pageVersion],\n );\n\n const handleSqlChange = useCallback(\n (v: string | undefined) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.sql = v || '';\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const handleRun = useCallback(() => {\n runCell(id);\n }, [id, runCell]);\n\n const handleRunQuery = useCallback(\n (query: string) => {\n // Sync the actual query being executed to store before running\n // to avoid race condition with onChange callback\n storeApi.setState(\n produce(storeApi.getState(), (draft: Draft<CellsRootState>) => {\n const c = draft.cells?.config?.data?.[id];\n if (c && c.type === 'sql') {\n c.data.sql = query;\n }\n }),\n );\n runCell(id);\n },\n [id, runCell, storeApi],\n );\n\n const handleConnectorChange = useCallback(\n (connectorId: string) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.connectorId = connectorId || undefined;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const handleCancel = useCallback(() => {\n cancelCell(id);\n }, [id, cancelCell]);\n\n const handleResultNameChange = useCallback(\n (value: string) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.resultName = value;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const resultName = cell.data.resultName || '';\n const selectedConnectorId =\n cell.data.connectorId || getCoreDuckDbConnectionId();\n\n const status =\n cellStatus?.type === 'sql'\n ? {\n state: (cellStatus as SqlCellStatus).status,\n message: (cellStatus as SqlCellStatus).lastError,\n resultName:\n (cellStatus as SqlCellStatus).resultView ||\n (cellStatus as SqlCellStatus).resultName,\n lastRunTime: (cellStatus as SqlCellStatus).lastRunTime,\n }\n : undefined;\n\n const isRunning = status?.state === 'running';\n\n const content = (\n <div className=\"flex flex-col\">\n <SqlCellEditor\n sql={cell.data.sql}\n connector={connector}\n tableSchemas={tableSchemas}\n onChange={handleSqlChange}\n onRunQuery={handleRunQuery}\n />\n <SqlCellResults\n cellId={id}\n cellResult={cellResult}\n resultName={resultName}\n isRunning={isRunning}\n errorMessage={status?.state === 'error' ? status.message : undefined}\n resultVersion={resultVersion}\n fetchCellResultPage={fetchCellResultPage}\n />\n </div>\n );\n\n const footer = (\n <div className=\"text-muted-foreground flex items-center gap-1 px-2 py-1 text-xs\">\n <CornerDownRightIcon className=\"h-3 w-3\" />\n <SqlCellDependentsMenu\n cellId={id}\n artifactId={artifactId}\n cellsData={cellsData}\n artifacts={artifacts}\n getDownstream={getDownstream}\n />\n <SqlCellResultNameEditor\n cellId={id}\n value={resultName}\n onChange={handleResultNameChange}\n />\n </div>\n );\n\n return renderContainer({\n header: (\n <div className=\"flex w-full items-center gap-2\">\n <SqlCellConnectionSelector\n connectors={dbConnections}\n selectedConnectorId={selectedConnectorId}\n onChange={handleConnectorChange}\n />\n <SqlCellRunButton\n onRun={handleRun}\n onCancel={handleCancel}\n status={status}\n runLabel=\"Run\"\n />\n </div>\n ),\n content,\n footer,\n });\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SqlCellResults.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellResults.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,eAAe,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAoC,MAAM,OAAO,CAAC;AAGzD,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,CACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,YAAY,KAClB,IAAI,CAAC;CACX;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA0GxD,CAAC"}
1
+ {"version":3,"file":"SqlCellResults.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellResults.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,eAAe,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAoC,MAAM,OAAO,CAAC;AAGzD,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,CACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,YAAY,KAClB,IAAI,CAAC;CACX;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAyGxD,CAAC"}
@@ -32,7 +32,6 @@ export const SqlCellResults = ({ cellId, cellResult, resultName, isRunning, erro
32
32
  useEffect(() => {
33
33
  if (resultVersion !== prevResultVersion.current) {
34
34
  prevResultVersion.current = resultVersion;
35
- // eslint-disable-next-line react-hooks/set-state-in-effect
36
35
  setPagination((prev) => prev.pageIndex === 0 ? prev : { ...prev, pageIndex: 0 });
37
36
  setSorting((prev) => (prev.length === 0 ? prev : []));
38
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SqlCellResults.js","sourceRoot":"","sources":["../../src/components/SqlCellResults.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DataTablePaginated,\n QueryDataTableActionsMenu,\n useArrowDataTable,\n} from '@sqlrooms/data-table';\nimport type {PaginationState, SortingState} from '@tanstack/react-table';\nimport React, {useEffect, useRef, useState} from 'react';\nimport {cn} from '@sqlrooms/ui';\nimport {CollapsibleSectionButton} from './CollapsibleSectionButton';\nimport {CellResultData} from '../types';\n\nexport interface SqlCellResultsProps {\n cellId: string;\n cellResult?: CellResultData | undefined;\n resultName?: string;\n isRunning?: boolean;\n errorMessage?: string;\n resultVersion: number;\n fetchCellResultPage: (\n cellId: string,\n pagination: PaginationState,\n sorting: SortingState,\n ) => void;\n}\n\n/**\n * SQL query results display with collapse/expand functionality\n */\nexport const SqlCellResults: React.FC<SqlCellResultsProps> = ({\n cellId,\n cellResult,\n resultName,\n isRunning,\n errorMessage,\n resultVersion,\n fetchCellResultPage,\n}) => {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const arrowTableData = useArrowDataTable(cellResult?.arrowTable);\n\n // Pagination and sorting state for the result table\n const [sorting, setSorting] = useState<SortingState>([]);\n const [pagination, setPagination] = useState<PaginationState>({\n pageIndex: 0,\n pageSize: 10,\n });\n\n // Fetch new page when pagination or sorting changes (not on initial render\n // since executeSqlCell already fetches the first page)\n const isFirstRender = useRef(true);\n\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n if (resultName) {\n fetchCellResultPage(cellId, pagination, sorting);\n }\n }, [pagination, sorting, cellId, fetchCellResultPage, resultName]);\n\n // Reset pagination when a new result arrives (new run)\n const prevResultVersion = useRef(resultVersion);\n useEffect(() => {\n if (resultVersion !== prevResultVersion.current) {\n prevResultVersion.current = resultVersion;\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setPagination((prev) =>\n prev.pageIndex === 0 ? prev : {...prev, pageIndex: 0},\n );\n setSorting((prev) => (prev.length === 0 ? prev : []));\n }\n }, [resultVersion]);\n\n if (!errorMessage && (!resultName || !arrowTableData)) {\n return null;\n }\n\n return (\n <div className=\"group relative w-full\">\n <CollapsibleSectionButton\n isCollapsed={isCollapsed}\n onToggle={() => setIsCollapsed(!isCollapsed)}\n />\n {isCollapsed ? (\n <div className=\"ml-5 px-2 py-1 text-xs\">\n {errorMessage ? (\n <span className=\"font-normal text-red-600\">{errorMessage}</span>\n ) : cellResult?.totalRows !== undefined ? (\n <span className=\"text-muted-foreground font-normal\">\n {cellResult.totalRows.toLocaleString()} rows\n </span>\n ) : null}\n </div>\n ) : (\n <>\n {errorMessage ? (\n <div className=\"relative max-h-[400px] overflow-auto p-4\">\n <span className=\"font-mono text-xs whitespace-pre-wrap text-red-600\">\n {errorMessage}\n </span>\n </div>\n ) : resultName && arrowTableData ? (\n <div className=\"relative min-h-[200px] overflow-hidden\">\n <DataTablePaginated\n className=\"absolute inset-0 h-full w-full\"\n fontSize=\"text-xs\"\n data={arrowTableData.data}\n columns={arrowTableData.columns}\n numRows={cellResult?.totalRows}\n pagination={pagination}\n onPaginationChange={setPagination}\n sorting={sorting}\n onSortingChange={setSorting}\n isFetching={isRunning}\n footerActions={\n <QueryDataTableActionsMenu\n query={`SELECT * FROM ${resultName}`}\n />\n }\n />\n <div\n aria-hidden={!isRunning}\n className={cn(\n 'bg-background/45 pointer-events-none absolute inset-0 z-10 transition-opacity duration-200',\n isRunning ? 'animate-pulse opacity-100' : 'opacity-0',\n )}\n />\n </div>\n ) : null}\n </>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SqlCellResults.js","sourceRoot":"","sources":["../../src/components/SqlCellResults.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DataTablePaginated,\n QueryDataTableActionsMenu,\n useArrowDataTable,\n} from '@sqlrooms/data-table';\nimport type {PaginationState, SortingState} from '@tanstack/react-table';\nimport React, {useEffect, useRef, useState} from 'react';\nimport {cn} from '@sqlrooms/ui';\nimport {CollapsibleSectionButton} from './CollapsibleSectionButton';\nimport {CellResultData} from '../types';\n\nexport interface SqlCellResultsProps {\n cellId: string;\n cellResult?: CellResultData | undefined;\n resultName?: string;\n isRunning?: boolean;\n errorMessage?: string;\n resultVersion: number;\n fetchCellResultPage: (\n cellId: string,\n pagination: PaginationState,\n sorting: SortingState,\n ) => void;\n}\n\n/**\n * SQL query results display with collapse/expand functionality\n */\nexport const SqlCellResults: React.FC<SqlCellResultsProps> = ({\n cellId,\n cellResult,\n resultName,\n isRunning,\n errorMessage,\n resultVersion,\n fetchCellResultPage,\n}) => {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const arrowTableData = useArrowDataTable(cellResult?.arrowTable);\n\n // Pagination and sorting state for the result table\n const [sorting, setSorting] = useState<SortingState>([]);\n const [pagination, setPagination] = useState<PaginationState>({\n pageIndex: 0,\n pageSize: 10,\n });\n\n // Fetch new page when pagination or sorting changes (not on initial render\n // since executeSqlCell already fetches the first page)\n const isFirstRender = useRef(true);\n\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n if (resultName) {\n fetchCellResultPage(cellId, pagination, sorting);\n }\n }, [pagination, sorting, cellId, fetchCellResultPage, resultName]);\n\n // Reset pagination when a new result arrives (new run)\n const prevResultVersion = useRef(resultVersion);\n useEffect(() => {\n if (resultVersion !== prevResultVersion.current) {\n prevResultVersion.current = resultVersion;\n setPagination((prev) =>\n prev.pageIndex === 0 ? prev : {...prev, pageIndex: 0},\n );\n setSorting((prev) => (prev.length === 0 ? prev : []));\n }\n }, [resultVersion]);\n\n if (!errorMessage && (!resultName || !arrowTableData)) {\n return null;\n }\n\n return (\n <div className=\"group relative w-full\">\n <CollapsibleSectionButton\n isCollapsed={isCollapsed}\n onToggle={() => setIsCollapsed(!isCollapsed)}\n />\n {isCollapsed ? (\n <div className=\"ml-5 px-2 py-1 text-xs\">\n {errorMessage ? (\n <span className=\"font-normal text-red-600\">{errorMessage}</span>\n ) : cellResult?.totalRows !== undefined ? (\n <span className=\"text-muted-foreground font-normal\">\n {cellResult.totalRows.toLocaleString()} rows\n </span>\n ) : null}\n </div>\n ) : (\n <>\n {errorMessage ? (\n <div className=\"relative max-h-[400px] overflow-auto p-4\">\n <span className=\"font-mono text-xs whitespace-pre-wrap text-red-600\">\n {errorMessage}\n </span>\n </div>\n ) : resultName && arrowTableData ? (\n <div className=\"relative min-h-[200px] overflow-hidden\">\n <DataTablePaginated\n className=\"absolute inset-0 h-full w-full\"\n fontSize=\"text-xs\"\n data={arrowTableData.data}\n columns={arrowTableData.columns}\n numRows={cellResult?.totalRows}\n pagination={pagination}\n onPaginationChange={setPagination}\n sorting={sorting}\n onSortingChange={setSorting}\n isFetching={isRunning}\n footerActions={\n <QueryDataTableActionsMenu\n query={`SELECT * FROM ${resultName}`}\n />\n }\n />\n <div\n aria-hidden={!isRunning}\n className={cn(\n 'bg-background/45 pointer-events-none absolute inset-0 z-10 transition-opacity duration-200',\n isRunning ? 'animate-pulse opacity-100' : 'opacity-0',\n )}\n />\n </div>\n ) : null}\n </>\n )}\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"VegaCellContent.d.ts","sourceRoot":"","sources":["../../src/components/VegaCellContent.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,kBAAkB,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AAa3D,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,KAAK,CAAC,YAAY,CAAC;CACpE,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA6J1D,CAAC"}
1
+ {"version":3,"file":"VegaCellContent.d.ts","sourceRoot":"","sources":["../../src/components/VegaCellContent.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,kBAAkB,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AAY3D,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,KAAK,CAAC,YAAY,CAAC;CACpE,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAyF1D,CAAC"}
@@ -2,11 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useDebouncedValue } from '@sqlrooms/ui';
3
3
  import { VegaLiteChart } from '@sqlrooms/vega';
4
4
  import { produce } from 'immer';
5
- import { useCallback, useState } from 'react';
5
+ import { useState } from 'react';
6
6
  import { useCellsStore } from '../hooks';
7
7
  import { useVegaCellQuery } from '../hooks/useVegaCellQuery';
8
8
  import { useVegaCellDataSource } from '../hooks/useVegaCellDataSource';
9
- import { SelectionListener } from './SelectionListener';
10
9
  import { VegaConfigPanel } from './VegaConfigPanel';
11
10
  import { VegaCellHeader } from './VegaCellHeader';
12
11
  import { toDataSourceCell, toDataSourceTable } from '../helpers';
@@ -18,9 +17,6 @@ const DEFAULT_SPEC = {
18
17
  };
19
18
  export const VegaCellContent = ({ id, cell, renderContainer, }) => {
20
19
  const updateCell = useCellsStore((s) => s.cells.updateCell);
21
- const crossFilterEnabled = cell.data.crossFilter?.enabled !== false;
22
- const brushField = cell.data.crossFilter?.brushField;
23
- const brushFieldType = cell.data.crossFilter?.brushFieldType;
24
20
  const [isEditing, setIsEditing] = useState(false);
25
21
  // Local state with debounced persistence
26
22
  const [localSpec, handleSpecChange] = useDebouncedValue(cell.data.vegaSpec ?? DEFAULT_SPEC, (spec) => {
@@ -30,11 +26,8 @@ export const VegaCellContent = ({ id, cell, renderContainer, }) => {
30
26
  }));
31
27
  }, 300);
32
28
  const { selectedSqlId, selectedTableRef, selectedSqlStatus, baseSqlQuery, lastRunTime, hasDataSource, } = useVegaCellDataSource(cell);
33
- const { selectedSqlQuery, crossFilterPredicate } = useVegaCellQuery({
34
- cellId: id,
29
+ const { selectedSqlQuery } = useVegaCellQuery({
35
30
  baseSqlQuery,
36
- selectedSqlId,
37
- crossFilterEnabled,
38
31
  });
39
32
  // Encode selection value: "cell:<id>" or "table:<schema.table>"
40
33
  const selectValue = selectedSqlId
@@ -42,36 +35,8 @@ export const VegaCellContent = ({ id, cell, renderContainer, }) => {
42
35
  : selectedTableRef
43
36
  ? toDataSourceTable(selectedTableRef)
44
37
  : undefined;
45
- const handleCrossFilterToggle = useCallback((enabled) => {
46
- updateCell(id, (c) => produce(c, (draft) => {
47
- if (draft.type === 'vega') {
48
- if (!draft.data.crossFilter)
49
- draft.data.crossFilter = {};
50
- draft.data.crossFilter.enabled = enabled;
51
- }
52
- }));
53
- }, [id, updateCell]);
54
- const handleBrushFieldChange = useCallback((field) => {
55
- updateCell(id, (c) => produce(c, (draft) => {
56
- if (draft.type === 'vega') {
57
- if (!draft.data.crossFilter)
58
- draft.data.crossFilter = {};
59
- draft.data.crossFilter.brushField = field;
60
- }
61
- }));
62
- }, [id, updateCell]);
63
- const handleBrushFieldTypeChange = useCallback((fieldType) => {
64
- updateCell(id, (c) => produce(c, (draft) => {
65
- if (draft.type === 'vega') {
66
- if (!draft.data.crossFilter)
67
- draft.data.crossFilter = {};
68
- draft.data.crossFilter.brushFieldType = fieldType;
69
- }
70
- }));
71
- }, [id, updateCell]);
72
- const header = (_jsx(VegaCellHeader, { cellId: id, selectValue: selectValue, onEditToggle: () => setIsEditing((prev) => !prev), hasDataSource: hasDataSource, crossFilterEnabled: crossFilterEnabled, brushField: brushField, crossFilterPredicate: crossFilterPredicate }));
73
- const showSelectionListener = crossFilterEnabled && brushField && selectedSqlId && selectedSqlStatus;
74
- const content = (_jsxs("div", { className: "flex h-[400px]", children: [isEditing && (_jsx(VegaConfigPanel, { sqlQuery: baseSqlQuery, lastRunTime: lastRunTime, spec: localSpec, crossFilterEnabled: crossFilterEnabled, onSpecChange: handleSpecChange, onCrossFilterToggle: handleCrossFilterToggle, onBrushFieldChange: handleBrushFieldChange, onBrushFieldTypeChange: handleBrushFieldTypeChange })), _jsx("div", { onDoubleClick: () => hasDataSource && setIsEditing((prev) => !prev), className: "flex h-full w-full p-2", children: !hasDataSource ? (_jsx("div", { className: "flex h-full w-full items-center justify-center text-gray-400", children: "Please select a data source first." })) : !selectedSqlStatus && !selectedTableRef ? (_jsx("div", { className: "flex h-full w-full items-center justify-center text-gray-400", children: "No chart data available, please run the SQL cell first." })) : (_jsx(VegaLiteChart, { sqlQuery: selectedSqlQuery, spec: localSpec, className: "h-full w-full", aspectRatio: isEditing ? undefined : DEFAULT_ASPECT_RATIO, children: showSelectionListener && (_jsx(SelectionListener, { cellId: id, sqlId: selectedSqlId, brushField: brushField, brushFieldType: brushFieldType })) })) })] }));
38
+ const header = (_jsx(VegaCellHeader, { cellId: id, selectValue: selectValue, onEditToggle: () => setIsEditing((prev) => !prev), hasDataSource: hasDataSource }));
39
+ const content = (_jsxs("div", { className: "flex h-[400px]", children: [isEditing && (_jsx(VegaConfigPanel, { sqlQuery: baseSqlQuery, lastRunTime: lastRunTime, spec: localSpec, onSpecChange: handleSpecChange })), _jsx("div", { onDoubleClick: () => hasDataSource && setIsEditing((prev) => !prev), className: "flex h-full w-full p-2", children: !hasDataSource ? (_jsx("div", { className: "flex h-full w-full items-center justify-center text-gray-400", children: "Please select a data source first." })) : !selectedSqlStatus && !selectedTableRef ? (_jsx("div", { className: "flex h-full w-full items-center justify-center text-gray-400", children: "No chart data available, please run the SQL cell first." })) : (_jsx(VegaLiteChart, { sqlQuery: selectedSqlQuery, spec: localSpec, className: "h-full w-full", aspectRatio: isEditing ? undefined : DEFAULT_ASPECT_RATIO })) })] }));
75
40
  return renderContainer({
76
41
  header,
77
42
  content,
@@ -1 +1 @@
1
- {"version":3,"file":"VegaCellContent.js","sourceRoot":"","sources":["../../src/components/VegaCellContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAC,WAAW,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AACvC,OAAO,EAAC,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAC,qBAAqB,EAAC,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAE/D,MAAM,oBAAoB,GAAG,CAAC,GAAG,CAAC,CAAC;AACnC,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,EAAC,IAAI,EAAE,aAAa,EAAC;IAC3B,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,EAAE;CACH,CAAC;AAQX,MAAM,CAAC,MAAM,eAAe,GAAmC,CAAC,EAC9D,EAAE,EACF,IAAI,EACJ,eAAe,GAChB,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,KAAK,KAAK,CAAC;IACpE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC;IAE7D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,yCAAyC;IACzC,MAAM,CAAC,SAAS,EAAE,gBAAgB,CAAC,GAAG,iBAAiB,CACrD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,YAAY,EAClC,CAAC,IAAI,EAAE,EAAE;QACP,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CACnB,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxD,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,EACD,GAAG,CACJ,CAAC;IAEF,MAAM,EACJ,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,aAAa,GACd,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAEhC,MAAM,EAAC,gBAAgB,EAAE,oBAAoB,EAAC,GAAG,gBAAgB,CAAC;QAChE,MAAM,EAAE,EAAE;QACV,YAAY;QACZ,aAAa;QACb,kBAAkB;KACnB,CAAC,CAAC;IAEH,gEAAgE;IAChE,MAAM,WAAW,GAAG,aAAa;QAC/B,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC;QACjC,CAAC,CAAC,gBAAgB;YAChB,CAAC,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YACrC,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,uBAAuB,GAAG,WAAW,CACzC,CAAC,OAAgB,EAAE,EAAE;QACnB,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CACnB,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,EACD,CAAC,EAAE,EAAE,UAAU,CAAC,CACjB,CAAC;IAEF,MAAM,sBAAsB,GAAG,WAAW,CACxC,CAAC,KAAyB,EAAE,EAAE;QAC5B,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CACnB,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,EACD,CAAC,EAAE,EAAE,UAAU,CAAC,CACjB,CAAC;IAEF,MAAM,0BAA0B,GAAG,WAAW,CAC5C,CAAC,SAA6B,EAAE,EAAE;QAChC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CACnB,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,GAAG,SAAS,CAAC;YACpD,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,EACD,CAAC,EAAE,EAAE,UAAU,CAAC,CACjB,CAAC;IAEF,MAAM,MAAM,GAAG,CACb,KAAC,cAAc,IACb,MAAM,EAAE,EAAE,EACV,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACjD,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,UAAU,EACtB,oBAAoB,EAAE,oBAAoB,GAC1C,CACH,CAAC;IAEF,MAAM,qBAAqB,GACzB,kBAAkB,IAAI,UAAU,IAAI,aAAa,IAAI,iBAAiB,CAAC;IAEzE,MAAM,OAAO,GAAG,CACd,eAAK,SAAS,EAAC,gBAAgB,aAC5B,SAAS,IAAI,CACZ,KAAC,eAAe,IACd,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,SAAS,EACf,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,gBAAgB,EAC9B,mBAAmB,EAAE,uBAAuB,EAC5C,kBAAkB,EAAE,sBAAsB,EAC1C,sBAAsB,EAAE,0BAA0B,GAClD,CACH,EACD,cACE,aAAa,EAAE,GAAG,EAAE,CAAC,aAAa,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACnE,SAAS,EAAC,wBAAwB,YAEjC,CAAC,aAAa,CAAC,CAAC,CAAC,CAChB,cAAK,SAAS,EAAC,8DAA8D,mDAEvE,CACP,CAAC,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAC5C,cAAK,SAAS,EAAC,8DAA8D,wEAEvE,CACP,CAAC,CAAC,CAAC,CACF,KAAC,aAAa,IACZ,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE,SAAS,EACf,SAAS,EAAC,eAAe,EACzB,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,YAExD,qBAAqB,IAAI,CACxB,KAAC,iBAAiB,IAChB,MAAM,EAAE,EAAE,EACV,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,GAC9B,CACH,GACa,CACjB,GACG,IACF,CACP,CAAC;IAEF,OAAO,eAAe,CAAC;QACrB,MAAM;QACN,OAAO;KACR,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import {useDebouncedValue} from '@sqlrooms/ui';\nimport {VegaLiteChart} from '@sqlrooms/vega';\nimport {produce} from 'immer';\nimport {useCallback, useState} from 'react';\nimport {useCellsStore} from '../hooks';\nimport {useVegaCellQuery} from '../hooks/useVegaCellQuery';\nimport {useVegaCellDataSource} from '../hooks/useVegaCellDataSource';\nimport type {CellContainerProps, VegaCell} from '../types';\nimport {SelectionListener} from './SelectionListener';\nimport {VegaConfigPanel} from './VegaConfigPanel';\nimport {VegaCellHeader} from './VegaCellHeader';\nimport {toDataSourceCell, toDataSourceTable} from '../helpers';\n\nconst DEFAULT_ASPECT_RATIO = 3 / 2;\nconst DEFAULT_SPEC = {\n data: {name: 'queryResult'},\n mark: 'bar',\n padding: 20,\n} as const;\n\nexport type VegaCellContentProps = {\n id: string;\n cell: VegaCell;\n renderContainer: (props: CellContainerProps) => React.ReactElement;\n};\n\nexport const VegaCellContent: React.FC<VegaCellContentProps> = ({\n id,\n cell,\n renderContainer,\n}) => {\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n\n const crossFilterEnabled = cell.data.crossFilter?.enabled !== false;\n const brushField = cell.data.crossFilter?.brushField;\n const brushFieldType = cell.data.crossFilter?.brushFieldType;\n\n const [isEditing, setIsEditing] = useState(false);\n\n // Local state with debounced persistence\n const [localSpec, handleSpecChange] = useDebouncedValue(\n cell.data.vegaSpec ?? DEFAULT_SPEC,\n (spec) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'vega') draft.data.vegaSpec = spec;\n }),\n );\n },\n 300,\n );\n\n const {\n selectedSqlId,\n selectedTableRef,\n selectedSqlStatus,\n baseSqlQuery,\n lastRunTime,\n hasDataSource,\n } = useVegaCellDataSource(cell);\n\n const {selectedSqlQuery, crossFilterPredicate} = useVegaCellQuery({\n cellId: id,\n baseSqlQuery,\n selectedSqlId,\n crossFilterEnabled,\n });\n\n // Encode selection value: \"cell:<id>\" or \"table:<schema.table>\"\n const selectValue = selectedSqlId\n ? toDataSourceCell(selectedSqlId)\n : selectedTableRef\n ? toDataSourceTable(selectedTableRef)\n : undefined;\n\n const handleCrossFilterToggle = useCallback(\n (enabled: boolean) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'vega') {\n if (!draft.data.crossFilter) draft.data.crossFilter = {};\n draft.data.crossFilter.enabled = enabled;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const handleBrushFieldChange = useCallback(\n (field: string | undefined) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'vega') {\n if (!draft.data.crossFilter) draft.data.crossFilter = {};\n draft.data.crossFilter.brushField = field;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const handleBrushFieldTypeChange = useCallback(\n (fieldType: string | undefined) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'vega') {\n if (!draft.data.crossFilter) draft.data.crossFilter = {};\n draft.data.crossFilter.brushFieldType = fieldType;\n }\n }),\n );\n },\n [id, updateCell],\n );\n\n const header = (\n <VegaCellHeader\n cellId={id}\n selectValue={selectValue}\n onEditToggle={() => setIsEditing((prev) => !prev)}\n hasDataSource={hasDataSource}\n crossFilterEnabled={crossFilterEnabled}\n brushField={brushField}\n crossFilterPredicate={crossFilterPredicate}\n />\n );\n\n const showSelectionListener =\n crossFilterEnabled && brushField && selectedSqlId && selectedSqlStatus;\n\n const content = (\n <div className=\"flex h-[400px]\">\n {isEditing && (\n <VegaConfigPanel\n sqlQuery={baseSqlQuery}\n lastRunTime={lastRunTime}\n spec={localSpec}\n crossFilterEnabled={crossFilterEnabled}\n onSpecChange={handleSpecChange}\n onCrossFilterToggle={handleCrossFilterToggle}\n onBrushFieldChange={handleBrushFieldChange}\n onBrushFieldTypeChange={handleBrushFieldTypeChange}\n />\n )}\n <div\n onDoubleClick={() => hasDataSource && setIsEditing((prev) => !prev)}\n className=\"flex h-full w-full p-2\"\n >\n {!hasDataSource ? (\n <div className=\"flex h-full w-full items-center justify-center text-gray-400\">\n Please select a data source first.\n </div>\n ) : !selectedSqlStatus && !selectedTableRef ? (\n <div className=\"flex h-full w-full items-center justify-center text-gray-400\">\n No chart data available, please run the SQL cell first.\n </div>\n ) : (\n <VegaLiteChart\n sqlQuery={selectedSqlQuery}\n spec={localSpec}\n className=\"h-full w-full\"\n aspectRatio={isEditing ? undefined : DEFAULT_ASPECT_RATIO}\n >\n {showSelectionListener && (\n <SelectionListener\n cellId={id}\n sqlId={selectedSqlId}\n brushField={brushField}\n brushFieldType={brushFieldType}\n />\n )}\n </VegaLiteChart>\n )}\n </div>\n </div>\n );\n\n return renderContainer({\n header,\n content,\n });\n};\n"]}
1
+ {"version":3,"file":"VegaCellContent.js","sourceRoot":"","sources":["../../src/components/VegaCellContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import {useDebouncedValue} from '@sqlrooms/ui';\nimport {VegaLiteChart} from '@sqlrooms/vega';\nimport {produce} from 'immer';\nimport {useState} from 'react';\nimport {useCellsStore} from '../hooks';\nimport {useVegaCellQuery} from '../hooks/useVegaCellQuery';\nimport {useVegaCellDataSource} from '../hooks/useVegaCellDataSource';\nimport type {CellContainerProps, VegaCell} from '../types';\nimport {VegaConfigPanel} from './VegaConfigPanel';\nimport {VegaCellHeader} from './VegaCellHeader';\nimport {toDataSourceCell, toDataSourceTable} from '../helpers';\n\nconst DEFAULT_ASPECT_RATIO = 3 / 2;\nconst DEFAULT_SPEC = {\n data: {name: 'queryResult'},\n mark: 'bar',\n padding: 20,\n} as const;\n\nexport type VegaCellContentProps = {\n id: string;\n cell: VegaCell;\n renderContainer: (props: CellContainerProps) => React.ReactElement;\n};\n\nexport const VegaCellContent: React.FC<VegaCellContentProps> = ({\n id,\n cell,\n renderContainer,\n}) => {\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n\n const [isEditing, setIsEditing] = useState(false);\n\n // Local state with debounced persistence\n const [localSpec, handleSpecChange] = useDebouncedValue(\n cell.data.vegaSpec ?? DEFAULT_SPEC,\n (spec) => {\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'vega') draft.data.vegaSpec = spec;\n }),\n );\n },\n 300,\n );\n\n const {\n selectedSqlId,\n selectedTableRef,\n selectedSqlStatus,\n baseSqlQuery,\n lastRunTime,\n hasDataSource,\n } = useVegaCellDataSource(cell);\n\n const {selectedSqlQuery} = useVegaCellQuery({\n baseSqlQuery,\n });\n\n // Encode selection value: \"cell:<id>\" or \"table:<schema.table>\"\n const selectValue = selectedSqlId\n ? toDataSourceCell(selectedSqlId)\n : selectedTableRef\n ? toDataSourceTable(selectedTableRef)\n : undefined;\n\n const header = (\n <VegaCellHeader\n cellId={id}\n selectValue={selectValue}\n onEditToggle={() => setIsEditing((prev) => !prev)}\n hasDataSource={hasDataSource}\n />\n );\n\n const content = (\n <div className=\"flex h-[400px]\">\n {isEditing && (\n <VegaConfigPanel\n sqlQuery={baseSqlQuery}\n lastRunTime={lastRunTime}\n spec={localSpec}\n onSpecChange={handleSpecChange}\n />\n )}\n <div\n onDoubleClick={() => hasDataSource && setIsEditing((prev) => !prev)}\n className=\"flex h-full w-full p-2\"\n >\n {!hasDataSource ? (\n <div className=\"flex h-full w-full items-center justify-center text-gray-400\">\n Please select a data source first.\n </div>\n ) : !selectedSqlStatus && !selectedTableRef ? (\n <div className=\"flex h-full w-full items-center justify-center text-gray-400\">\n No chart data available, please run the SQL cell first.\n </div>\n ) : (\n <VegaLiteChart\n sqlQuery={selectedSqlQuery}\n spec={localSpec}\n className=\"h-full w-full\"\n aspectRatio={isEditing ? undefined : DEFAULT_ASPECT_RATIO}\n />\n )}\n </div>\n </div>\n );\n\n return renderContainer({\n header,\n content,\n });\n};\n"]}
@@ -3,9 +3,6 @@ export type VegaCellHeaderProps = {
3
3
  selectValue: string | undefined;
4
4
  onEditToggle: () => void;
5
5
  hasDataSource: boolean;
6
- crossFilterEnabled: boolean;
7
- brushField: string | undefined;
8
- crossFilterPredicate: string | null;
9
6
  };
10
7
  export declare const VegaCellHeader: React.FC<VegaCellHeaderProps>;
11
8
  //# sourceMappingURL=VegaCellHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VegaCellHeader.d.ts","sourceRoot":"","sources":["../../src/components/VegaCellHeader.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAqExD,CAAC"}
1
+ {"version":3,"file":"VegaCellHeader.d.ts","sourceRoot":"","sources":["../../src/components/VegaCellHeader.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgDxD,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Tooltip, TooltipContent, TooltipTrigger } from '@sqlrooms/ui';
2
+ import { Button } from '@sqlrooms/ui';
3
3
  import { produce } from 'immer';
4
- import { Filter, Settings } from 'lucide-react';
4
+ import { Settings } from 'lucide-react';
5
5
  import { fromDataSourceCell, fromDataSourceTable } from '../helpers';
6
6
  import { CellSourceSelector } from './CellSourceSelector';
7
7
  import { useCellsStore } from '../hooks';
8
- export const VegaCellHeader = ({ cellId, selectValue, onEditToggle, hasDataSource, crossFilterEnabled, brushField, crossFilterPredicate, }) => {
8
+ export const VegaCellHeader = ({ cellId, selectValue, onEditToggle, hasDataSource, }) => {
9
9
  const updateCell = useCellsStore((s) => s.cells.updateCell);
10
10
  const artifactId = useCellsStore((s) => s.cells.getArtifactIdForCell(cellId));
11
11
  const handleDataSourceChange = (value) => {
@@ -25,8 +25,6 @@ export const VegaCellHeader = ({ cellId, selectValue, onEditToggle, hasDataSourc
25
25
  }
26
26
  }));
27
27
  };
28
- return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CellSourceSelector, { artifactId: artifactId ?? '', value: selectValue, onValueChange: handleDataSourceChange }), _jsx(Button, { size: "xs", variant: "secondary", className: "h-6", onClick: onEditToggle, disabled: !hasDataSource, children: _jsx(Settings, { className: "h-4 w-4" }) }), crossFilterEnabled && brushField && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { className: "flex items-center", children: _jsx(Filter, { className: `h-3.5 w-3.5 ${crossFilterPredicate ? 'text-blue-500' : 'text-gray-400'}` }) }) }), _jsx(TooltipContent, { side: "bottom", children: _jsx("p", { className: "text-xs", children: crossFilterPredicate
29
- ? `Filtered: ${crossFilterPredicate}`
30
- : `Cross-filter on ${brushField}` }) })] }))] }));
28
+ return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CellSourceSelector, { artifactId: artifactId ?? '', value: selectValue, onValueChange: handleDataSourceChange }), _jsx(Button, { size: "xs", variant: "secondary", className: "h-6", onClick: onEditToggle, disabled: !hasDataSource, children: _jsx(Settings, { className: "h-4 w-4" }) })] }));
31
29
  };
32
30
  //# sourceMappingURL=VegaCellHeader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VegaCellHeader.js","sourceRoot":"","sources":["../../src/components/VegaCellHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAC,MAAM,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,YAAY,CAAC;AACnE,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAYvC,MAAM,CAAC,MAAM,cAAc,GAAkC,CAAC,EAC5D,MAAM,EACN,WAAW,EACX,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,oBAAoB,GACrB,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9E,MAAM,sBAAsB,GAAG,CAAC,KAAa,EAAE,EAAE;QAC/C,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CACvB,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;YAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAE5C,IAAI,eAAe,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC;gBACnC,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC7B,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,kBAAkB,IACjB,UAAU,EAAE,UAAU,IAAI,EAAE,EAC5B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,sBAAsB,GACrC,EACF,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAC,WAAW,EACnB,SAAS,EAAC,KAAK,EACf,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,CAAC,aAAa,YAExB,KAAC,QAAQ,IAAC,SAAS,EAAC,SAAS,GAAG,GACzB,EACR,kBAAkB,IAAI,UAAU,IAAI,CACnC,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBACrB,cAAK,SAAS,EAAC,mBAAmB,YAChC,KAAC,MAAM,IACL,SAAS,EAAE,eAAe,oBAAoB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,EAAE,GACpF,GACE,GACS,EACjB,KAAC,cAAc,IAAC,IAAI,EAAC,QAAQ,YAC3B,YAAG,SAAS,EAAC,SAAS,YACnB,oBAAoB;gCACnB,CAAC,CAAC,aAAa,oBAAoB,EAAE;gCACrC,CAAC,CAAC,mBAAmB,UAAU,EAAE,GACjC,GACW,IACT,CACX,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport {produce} from 'immer';\nimport {Filter, Settings} from 'lucide-react';\nimport {fromDataSourceCell, fromDataSourceTable} from '../helpers';\nimport {CellSourceSelector} from './CellSourceSelector';\nimport {useCellsStore} from '../hooks';\n\nexport type VegaCellHeaderProps = {\n cellId: string;\n selectValue: string | undefined;\n onEditToggle: () => void;\n hasDataSource: boolean;\n crossFilterEnabled: boolean;\n brushField: string | undefined;\n crossFilterPredicate: string | null;\n};\n\nexport const VegaCellHeader: React.FC<VegaCellHeaderProps> = ({\n cellId,\n selectValue,\n onEditToggle,\n hasDataSource,\n crossFilterEnabled,\n brushField,\n crossFilterPredicate,\n}) => {\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n const artifactId = useCellsStore((s) => s.cells.getArtifactIdForCell(cellId));\n\n const handleDataSourceChange = (value: string) => {\n updateCell(cellId, (c) =>\n produce(c, (draft) => {\n if (draft.type !== 'vega') {\n return;\n }\n\n const cellIdFromValue = fromDataSourceCell(value);\n const tableRef = fromDataSourceTable(value);\n\n if (cellIdFromValue) {\n draft.data.sqlId = cellIdFromValue;\n delete draft.data.tableRef;\n } else if (tableRef) {\n draft.data.tableRef = tableRef;\n delete draft.data.sqlId;\n }\n }),\n );\n };\n\n return (\n <div className=\"flex items-center gap-2\">\n <CellSourceSelector\n artifactId={artifactId ?? ''}\n value={selectValue}\n onValueChange={handleDataSourceChange}\n />\n <Button\n size=\"xs\"\n variant=\"secondary\"\n className=\"h-6\"\n onClick={onEditToggle}\n disabled={!hasDataSource}\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n {crossFilterEnabled && brushField && (\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"flex items-center\">\n <Filter\n className={`h-3.5 w-3.5 ${crossFilterPredicate ? 'text-blue-500' : 'text-gray-400'}`}\n />\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p className=\"text-xs\">\n {crossFilterPredicate\n ? `Filtered: ${crossFilterPredicate}`\n : `Cross-filter on ${brushField}`}\n </p>\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"VegaCellHeader.js","sourceRoot":"","sources":["../../src/components/VegaCellHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,YAAY,CAAC;AACnE,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AASvC,MAAM,CAAC,MAAM,cAAc,GAAkC,CAAC,EAC5D,MAAM,EACN,WAAW,EACX,YAAY,EACZ,aAAa,GACd,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9E,MAAM,sBAAsB,GAAG,CAAC,KAAa,EAAE,EAAE;QAC/C,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CACvB,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;YAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAE5C,IAAI,eAAe,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC;gBACnC,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC7B,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,kBAAkB,IACjB,UAAU,EAAE,UAAU,IAAI,EAAE,EAC5B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,sBAAsB,GACrC,EACF,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAC,WAAW,EACnB,SAAS,EAAC,KAAK,EACf,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,CAAC,aAAa,YAExB,KAAC,QAAQ,IAAC,SAAS,EAAC,SAAS,GAAG,GACzB,IACL,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {Button} from '@sqlrooms/ui';\nimport {produce} from 'immer';\nimport {Settings} from 'lucide-react';\nimport {fromDataSourceCell, fromDataSourceTable} from '../helpers';\nimport {CellSourceSelector} from './CellSourceSelector';\nimport {useCellsStore} from '../hooks';\n\nexport type VegaCellHeaderProps = {\n cellId: string;\n selectValue: string | undefined;\n onEditToggle: () => void;\n hasDataSource: boolean;\n};\n\nexport const VegaCellHeader: React.FC<VegaCellHeaderProps> = ({\n cellId,\n selectValue,\n onEditToggle,\n hasDataSource,\n}) => {\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n const artifactId = useCellsStore((s) => s.cells.getArtifactIdForCell(cellId));\n\n const handleDataSourceChange = (value: string) => {\n updateCell(cellId, (c) =>\n produce(c, (draft) => {\n if (draft.type !== 'vega') {\n return;\n }\n\n const cellIdFromValue = fromDataSourceCell(value);\n const tableRef = fromDataSourceTable(value);\n\n if (cellIdFromValue) {\n draft.data.sqlId = cellIdFromValue;\n delete draft.data.tableRef;\n } else if (tableRef) {\n draft.data.tableRef = tableRef;\n delete draft.data.sqlId;\n }\n }),\n );\n };\n\n return (\n <div className=\"flex items-center gap-2\">\n <CellSourceSelector\n artifactId={artifactId ?? ''}\n value={selectValue}\n onValueChange={handleDataSourceChange}\n />\n <Button\n size=\"xs\"\n variant=\"secondary\"\n className=\"h-6\"\n onClick={onEditToggle}\n disabled={!hasDataSource}\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n </div>\n );\n};\n"]}
@@ -1,13 +1,8 @@
1
1
  import React from 'react';
2
- import type { BrushFieldType } from '../types';
3
2
  export declare const VegaConfigPanel: React.FC<{
4
3
  spec: any;
5
4
  sqlQuery: string;
6
5
  lastRunTime?: number;
7
- crossFilterEnabled: boolean;
8
6
  onSpecChange: (spec: any) => void;
9
- onCrossFilterToggle: (enabled: boolean) => void;
10
- onBrushFieldChange: (field: string | undefined) => void;
11
- onBrushFieldTypeChange: (fieldType: BrushFieldType | undefined) => void;
12
7
  }>;
13
8
  //# sourceMappingURL=VegaConfigPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VegaConfigPanel.d.ts","sourceRoot":"","sources":["../../src/components/VegaConfigPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAW7C,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;IACrC,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAClC,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACxD,sBAAsB,EAAE,CAAC,SAAS,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC;CACzE,CAyJA,CAAC"}
1
+ {"version":3,"file":"VegaConfigPanel.d.ts","sourceRoot":"","sources":["../../src/components/VegaConfigPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;IACrC,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;CACnC,CA2FA,CAAC"}
@@ -1,62 +1,31 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Tabs, TabsContent, TabsList, TabsTrigger, Label, Separator, Switch, } from '@sqlrooms/ui';
2
+ import { Tabs, TabsContent, TabsList, TabsTrigger, Label, Separator, } from '@sqlrooms/ui';
3
3
  import { useSql } from '@sqlrooms/duckdb';
4
- import { getArrowColumnTypeCategory } from '@sqlrooms/duckdb';
5
- import { readSpecValues, buildCrossFilterSpec, buildFlatSpec, } from '../vegaSpecBuilder';
4
+ import { readSpecValues, buildFlatSpec } from '../vegaSpecBuilder';
6
5
  import { FieldSelector } from './FieldSelector';
7
6
  import { ColorSelector, colorOptions } from './ColorSelector';
8
7
  import { ChartTypeSelector } from './ChartTypeSelector';
9
8
  import { AggregationSelector } from './AggregationSelector';
10
- export const VegaConfigPanel = ({ sqlQuery, lastRunTime, spec, crossFilterEnabled, onSpecChange, onCrossFilterToggle, onBrushFieldChange, onBrushFieldTypeChange, }) => {
9
+ export const VegaConfigPanel = ({ sqlQuery, lastRunTime, spec, onSpecChange }) => {
11
10
  const result = useSql({ query: sqlQuery, version: lastRunTime });
12
11
  const arrowTable = result.data?.arrowTable;
13
12
  const fields = arrowTable?.schema?.fields || [];
14
- const detectBrushFieldType = (fieldName) => {
15
- const arrowField = arrowTable?.schema?.fields?.find((field) => field.name === fieldName);
16
- if (!arrowField) {
17
- return 'numeric';
18
- }
19
- const category = getArrowColumnTypeCategory(arrowField.type);
20
- if (category === 'datetime')
21
- return 'temporal';
22
- if (category === 'string')
23
- return 'string';
24
- return 'numeric';
25
- };
26
13
  const current = readSpecValues(spec);
27
- const rebuild = (overrides, cfEnabled = crossFilterEnabled) => {
14
+ const rebuild = (overrides) => {
28
15
  const merged = { ...current, ...overrides };
29
- const builder = cfEnabled ? buildCrossFilterSpec : buildFlatSpec;
30
- onSpecChange(builder({
16
+ onSpecChange(buildFlatSpec({
31
17
  mark: merged.mark ?? 'bar',
32
18
  xField: merged.xField,
33
- xFieldType: merged.xField
34
- ? detectBrushFieldType(merged.xField)
35
- : undefined,
36
19
  yField: merged.yField,
37
20
  yAggregate: merged.yAggregate,
38
21
  color: merged.color ?? colorOptions[0]?.value,
39
22
  }));
40
- if ('xField' in overrides) {
41
- onBrushFieldChange(cfEnabled ? overrides.xField : undefined);
42
- onBrushFieldTypeChange(cfEnabled && overrides.xField
43
- ? detectBrushFieldType(overrides.xField)
44
- : undefined);
45
- }
46
23
  };
47
24
  const handleMarkChange = (mark) => rebuild({ mark });
48
25
  const handleXFieldChange = (field) => rebuild({ xField: field });
49
26
  const handleYFieldChange = (field) => rebuild({ yField: field, yAggregate: current.yAggregate ?? 'sum' });
50
27
  const handleYAggregationChange = (aggregate) => rebuild({ yAggregate: aggregate });
51
28
  const handleColorChange = (color) => rebuild({ color });
52
- const handleCrossFilterToggle = (enabled) => {
53
- onCrossFilterToggle(enabled);
54
- rebuild({}, enabled);
55
- onBrushFieldChange(enabled ? current.xField : undefined);
56
- onBrushFieldTypeChange(enabled && current.xField
57
- ? detectBrushFieldType(current.xField)
58
- : undefined);
59
- };
60
- return (_jsx("div", { className: "w-80 border-r p-4 text-xs", children: _jsxs("div", { className: "space-y-3", children: [_jsx(ChartTypeSelector, { value: current.mark, onValueChange: handleMarkChange }), _jsx(Separator, {}), _jsxs(Tabs, { defaultValue: "general", className: "w-full", children: [_jsxs(TabsList, { className: "grid w-full grid-cols-2", children: [_jsx(TabsTrigger, { value: "general", className: "text-xs", children: "General" }), _jsx(TabsTrigger, { value: "styles", className: "text-xs", children: "Styles" })] }), _jsxs(TabsContent, { value: "general", className: "mt-4 space-y-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "X-Axis" }), _jsx(FieldSelector, { value: current.xField, fields: fields, onValueChange: handleXFieldChange })] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Y-Axis" }), _jsxs("div", { className: "grid grid-cols-[2fr_1fr] gap-2", children: [_jsx(FieldSelector, { value: current.yField, fields: fields, onValueChange: handleYFieldChange }), _jsx(AggregationSelector, { value: current.yAggregate, onValueChange: handleYAggregationChange })] })] }), _jsx(Separator, {}), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Cross-filter" }), _jsx(Switch, { checked: crossFilterEnabled, onCheckedChange: handleCrossFilterToggle })] })] }), _jsx(TabsContent, { value: "styles", className: "mt-4 space-y-4", children: _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Color" }), _jsx(ColorSelector, { value: current.color, onValueChange: handleColorChange })] }) })] })] }) }));
29
+ return (_jsx("div", { className: "w-80 border-r p-4 text-xs", children: _jsxs("div", { className: "space-y-3", children: [_jsx(ChartTypeSelector, { value: current.mark, onValueChange: handleMarkChange }), _jsx(Separator, {}), _jsxs(Tabs, { defaultValue: "general", className: "w-full", children: [_jsxs(TabsList, { className: "grid w-full grid-cols-2", children: [_jsx(TabsTrigger, { value: "general", className: "text-xs", children: "General" }), _jsx(TabsTrigger, { value: "styles", className: "text-xs", children: "Styles" })] }), _jsxs(TabsContent, { value: "general", className: "mt-4 space-y-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "X-Axis" }), _jsx(FieldSelector, { value: current.xField, fields: fields, onValueChange: handleXFieldChange })] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Y-Axis" }), _jsxs("div", { className: "grid grid-cols-[2fr_1fr] gap-2", children: [_jsx(FieldSelector, { value: current.yField, fields: fields, onValueChange: handleYFieldChange }), _jsx(AggregationSelector, { value: current.yAggregate, onValueChange: handleYAggregationChange })] })] })] }), _jsx(TabsContent, { value: "styles", className: "mt-4 space-y-4", children: _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Color" }), _jsx(ColorSelector, { value: current.color, onValueChange: handleColorChange })] }) })] })] }) }));
61
30
  };
62
31
  //# sourceMappingURL=VegaConfigPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VegaConfigPanel.js","sourceRoot":"","sources":["../../src/components/VegaConfigPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Label,\n Separator,\n Switch,\n} from '@sqlrooms/ui';\nimport {useSql} from '@sqlrooms/duckdb';\nimport {getArrowColumnTypeCategory} from '@sqlrooms/duckdb';\nimport type {BrushFieldType} from '../types';\nimport {\n readSpecValues,\n buildCrossFilterSpec,\n buildFlatSpec,\n} from '../vegaSpecBuilder';\nimport {FieldSelector} from './FieldSelector';\nimport {ColorSelector, colorOptions} from './ColorSelector';\nimport {ChartTypeSelector} from './ChartTypeSelector';\nimport {AggregationSelector} from './AggregationSelector';\n\nexport const VegaConfigPanel: React.FC<{\n spec: any;\n sqlQuery: string;\n lastRunTime?: number;\n crossFilterEnabled: boolean;\n onSpecChange: (spec: any) => void;\n onCrossFilterToggle: (enabled: boolean) => void;\n onBrushFieldChange: (field: string | undefined) => void;\n onBrushFieldTypeChange: (fieldType: BrushFieldType | undefined) => void;\n}> = ({\n sqlQuery,\n lastRunTime,\n spec,\n crossFilterEnabled,\n onSpecChange,\n onCrossFilterToggle,\n onBrushFieldChange,\n onBrushFieldTypeChange,\n}) => {\n const result = useSql({query: sqlQuery, version: lastRunTime});\n const arrowTable = result.data?.arrowTable;\n const fields = arrowTable?.schema?.fields || [];\n\n const detectBrushFieldType = (fieldName: string): BrushFieldType => {\n const arrowField = arrowTable?.schema?.fields?.find(\n (field) => field.name === fieldName,\n );\n\n if (!arrowField) {\n return 'numeric';\n }\n\n const category = getArrowColumnTypeCategory(arrowField.type);\n if (category === 'datetime') return 'temporal';\n if (category === 'string') return 'string';\n return 'numeric';\n };\n\n const current = readSpecValues(spec);\n\n const rebuild = (\n overrides: Partial<ReturnType<typeof readSpecValues>>,\n cfEnabled = crossFilterEnabled,\n ) => {\n const merged = {...current, ...overrides};\n const builder = cfEnabled ? buildCrossFilterSpec : buildFlatSpec;\n onSpecChange(\n builder({\n mark: merged.mark ?? 'bar',\n xField: merged.xField,\n xFieldType: merged.xField\n ? detectBrushFieldType(merged.xField)\n : undefined,\n yField: merged.yField,\n yAggregate: merged.yAggregate,\n color: merged.color ?? colorOptions[0]?.value,\n }),\n );\n if ('xField' in overrides) {\n onBrushFieldChange(cfEnabled ? overrides.xField : undefined);\n onBrushFieldTypeChange(\n cfEnabled && overrides.xField\n ? detectBrushFieldType(overrides.xField)\n : undefined,\n );\n }\n };\n\n const handleMarkChange = (mark: string) => rebuild({mark});\n const handleXFieldChange = (field: string) => rebuild({xField: field});\n const handleYFieldChange = (field: string) =>\n rebuild({yField: field, yAggregate: current.yAggregate ?? 'sum'});\n const handleYAggregationChange = (aggregate: string) =>\n rebuild({yAggregate: aggregate});\n const handleColorChange = (color: string) => rebuild({color});\n\n const handleCrossFilterToggle = (enabled: boolean) => {\n onCrossFilterToggle(enabled);\n rebuild({}, enabled);\n onBrushFieldChange(enabled ? current.xField : undefined);\n onBrushFieldTypeChange(\n enabled && current.xField\n ? detectBrushFieldType(current.xField)\n : undefined,\n );\n };\n\n return (\n <div className=\"w-80 border-r p-4 text-xs\">\n <div className=\"space-y-3\">\n <ChartTypeSelector\n value={current.mark}\n onValueChange={handleMarkChange}\n />\n\n <Separator />\n\n <Tabs defaultValue=\"general\" className=\"w-full\">\n <TabsList className=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"general\" className=\"text-xs\">\n General\n </TabsTrigger>\n <TabsTrigger value=\"styles\" className=\"text-xs\">\n Styles\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"general\" className=\"mt-4 space-y-4\">\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">\n X-Axis\n </Label>\n <FieldSelector\n value={current.xField}\n fields={fields}\n onValueChange={handleXFieldChange}\n />\n </div>\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">\n Y-Axis\n </Label>\n <div className=\"grid grid-cols-[2fr_1fr] gap-2\">\n <FieldSelector\n value={current.yField}\n fields={fields}\n onValueChange={handleYFieldChange}\n />\n\n <AggregationSelector\n value={current.yAggregate}\n onValueChange={handleYAggregationChange}\n />\n </div>\n </div>\n\n <Separator />\n\n <div className=\"flex items-center justify-between\">\n <Label className=\"text-xs font-medium text-gray-400\">\n Cross-filter\n </Label>\n <Switch\n checked={crossFilterEnabled}\n onCheckedChange={handleCrossFilterToggle}\n />\n </div>\n </TabsContent>\n\n <TabsContent value=\"styles\" className=\"mt-4 space-y-4\">\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">Color</Label>\n <ColorSelector\n value={current.color}\n onValueChange={handleColorChange}\n />\n </div>\n </TabsContent>\n </Tabs>\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"VegaConfigPanel.js","sourceRoot":"","sources":["../../src/components/VegaConfigPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Label,\n Separator,\n} from '@sqlrooms/ui';\nimport {useSql} from '@sqlrooms/duckdb';\nimport {readSpecValues, buildFlatSpec} from '../vegaSpecBuilder';\nimport {FieldSelector} from './FieldSelector';\nimport {ColorSelector, colorOptions} from './ColorSelector';\nimport {ChartTypeSelector} from './ChartTypeSelector';\nimport {AggregationSelector} from './AggregationSelector';\n\nexport const VegaConfigPanel: React.FC<{\n spec: any;\n sqlQuery: string;\n lastRunTime?: number;\n onSpecChange: (spec: any) => void;\n}> = ({sqlQuery, lastRunTime, spec, onSpecChange}) => {\n const result = useSql({query: sqlQuery, version: lastRunTime});\n const arrowTable = result.data?.arrowTable;\n const fields = arrowTable?.schema?.fields || [];\n\n const current = readSpecValues(spec);\n\n const rebuild = (overrides: Partial<ReturnType<typeof readSpecValues>>) => {\n const merged = {...current, ...overrides};\n onSpecChange(\n buildFlatSpec({\n mark: merged.mark ?? 'bar',\n xField: merged.xField,\n yField: merged.yField,\n yAggregate: merged.yAggregate,\n color: merged.color ?? colorOptions[0]?.value,\n }),\n );\n };\n\n const handleMarkChange = (mark: string) => rebuild({mark});\n const handleXFieldChange = (field: string) => rebuild({xField: field});\n const handleYFieldChange = (field: string) =>\n rebuild({yField: field, yAggregate: current.yAggregate ?? 'sum'});\n const handleYAggregationChange = (aggregate: string) =>\n rebuild({yAggregate: aggregate});\n const handleColorChange = (color: string) => rebuild({color});\n\n return (\n <div className=\"w-80 border-r p-4 text-xs\">\n <div className=\"space-y-3\">\n <ChartTypeSelector\n value={current.mark}\n onValueChange={handleMarkChange}\n />\n\n <Separator />\n\n <Tabs defaultValue=\"general\" className=\"w-full\">\n <TabsList className=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"general\" className=\"text-xs\">\n General\n </TabsTrigger>\n <TabsTrigger value=\"styles\" className=\"text-xs\">\n Styles\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"general\" className=\"mt-4 space-y-4\">\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">\n X-Axis\n </Label>\n <FieldSelector\n value={current.xField}\n fields={fields}\n onValueChange={handleXFieldChange}\n />\n </div>\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">\n Y-Axis\n </Label>\n <div className=\"grid grid-cols-[2fr_1fr] gap-2\">\n <FieldSelector\n value={current.yField}\n fields={fields}\n onValueChange={handleYFieldChange}\n />\n\n <AggregationSelector\n value={current.yAggregate}\n onValueChange={handleYAggregationChange}\n />\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"styles\" className=\"mt-4 space-y-4\">\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">Color</Label>\n <ColorSelector\n value={current.color}\n onValueChange={handleColorChange}\n />\n </div>\n </TabsContent>\n </Tabs>\n </div>\n </div>\n );\n};\n"]}
@@ -1,6 +1,5 @@
1
1
  export type VegaCellQuery = {
2
2
  selectedSqlQuery: string;
3
- crossFilterPredicate: string | null;
4
3
  };
5
4
  /**
6
5
  * Builds the final SQL query for a Vega cell with optional cross-filter predicates.
@@ -8,9 +7,6 @@ export type VegaCellQuery = {
8
7
  * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.
9
8
  */
10
9
  export declare function useVegaCellQuery(params: {
11
- cellId: string;
12
10
  baseSqlQuery: string;
13
- selectedSqlId: string | undefined;
14
- crossFilterEnabled: boolean;
15
11
  }): VegaCellQuery;
16
12
  //# sourceMappingURL=useVegaCellQuery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useVegaCellQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useVegaCellQuery.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kBAAkB,EAAE,OAAO,CAAC;CAC7B,GAAG,aAAa,CA2BhB"}
1
+ {"version":3,"file":"useVegaCellQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useVegaCellQuery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,aAAa,CAMhB"}
@@ -1,25 +1,12 @@
1
- import { useCellsStore } from '../hooks';
2
1
  /**
3
2
  * Builds the final SQL query for a Vega cell with optional cross-filter predicates.
4
3
  * If cross-filtering is enabled and active, wraps the base query as a subquery
5
4
  * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.
6
5
  */
7
6
  export function useVegaCellQuery(params) {
8
- const { cellId, baseSqlQuery, selectedSqlId, crossFilterEnabled } = params;
9
- const getCrossFilterPredicate = useCellsStore((s) => s.cells.getCrossFilterPredicate);
10
- // Subscribe to cross-filter selections so we re-render when siblings change
11
- const crossFilterGroup = useCellsStore((s) => selectedSqlId ? s.cells.crossFilterSelections[selectedSqlId] : undefined);
12
- // Needed to satisfy exhaustive-deps for the memoized predicate
13
- void crossFilterGroup;
14
- const crossFilterPredicate = selectedSqlId && crossFilterEnabled
15
- ? getCrossFilterPredicate(cellId, selectedSqlId)
16
- : null;
17
- const selectedSqlQuery = crossFilterPredicate
18
- ? `SELECT * FROM (${baseSqlQuery.replace(/;\s*$/, '')}) AS _cells_base WHERE ${crossFilterPredicate}`
19
- : baseSqlQuery;
7
+ const { baseSqlQuery } = params;
20
8
  return {
21
- selectedSqlQuery,
22
- crossFilterPredicate,
9
+ selectedSqlQuery: baseSqlQuery,
23
10
  };
24
11
  }
25
12
  //# sourceMappingURL=useVegaCellQuery.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useVegaCellQuery.js","sourceRoot":"","sources":["../../src/hooks/useVegaCellQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAOvC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAKhC;IACC,MAAM,EAAC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAC,GAAG,MAAM,CAAC;IAEzE,MAAM,uBAAuB,GAAG,aAAa,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,uBAAuB,CACvC,CAAC;IAEF,4EAA4E;IAC5E,MAAM,gBAAgB,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CACzE,CAAC;IACF,+DAA+D;IAC/D,KAAK,gBAAgB,CAAC;IAEtB,MAAM,oBAAoB,GACxB,aAAa,IAAI,kBAAkB;QACjC,CAAC,CAAC,uBAAuB,CAAC,MAAM,EAAE,aAAa,CAAC;QAChD,CAAC,CAAC,IAAI,CAAC;IAEX,MAAM,gBAAgB,GAAG,oBAAoB;QAC3C,CAAC,CAAC,kBAAkB,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,0BAA0B,oBAAoB,EAAE;QACrG,CAAC,CAAC,YAAY,CAAC;IAEjB,OAAO;QACL,gBAAgB;QAChB,oBAAoB;KACrB,CAAC;AACJ,CAAC","sourcesContent":["import {useCellsStore} from '../hooks';\n\nexport type VegaCellQuery = {\n selectedSqlQuery: string;\n crossFilterPredicate: string | null;\n};\n\n/**\n * Builds the final SQL query for a Vega cell with optional cross-filter predicates.\n * If cross-filtering is enabled and active, wraps the base query as a subquery\n * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.\n */\nexport function useVegaCellQuery(params: {\n cellId: string;\n baseSqlQuery: string;\n selectedSqlId: string | undefined;\n crossFilterEnabled: boolean;\n}): VegaCellQuery {\n const {cellId, baseSqlQuery, selectedSqlId, crossFilterEnabled} = params;\n\n const getCrossFilterPredicate = useCellsStore(\n (s) => s.cells.getCrossFilterPredicate,\n );\n\n // Subscribe to cross-filter selections so we re-render when siblings change\n const crossFilterGroup = useCellsStore((s) =>\n selectedSqlId ? s.cells.crossFilterSelections[selectedSqlId] : undefined,\n );\n // Needed to satisfy exhaustive-deps for the memoized predicate\n void crossFilterGroup;\n\n const crossFilterPredicate =\n selectedSqlId && crossFilterEnabled\n ? getCrossFilterPredicate(cellId, selectedSqlId)\n : null;\n\n const selectedSqlQuery = crossFilterPredicate\n ? `SELECT * FROM (${baseSqlQuery.replace(/;\\s*$/, '')}) AS _cells_base WHERE ${crossFilterPredicate}`\n : baseSqlQuery;\n\n return {\n selectedSqlQuery,\n crossFilterPredicate,\n };\n}\n"]}
1
+ {"version":3,"file":"useVegaCellQuery.js","sourceRoot":"","sources":["../../src/hooks/useVegaCellQuery.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAEhC;IACC,MAAM,EAAC,YAAY,EAAC,GAAG,MAAM,CAAC;IAE9B,OAAO;QACL,gBAAgB,EAAE,YAAY;KAC/B,CAAC;AACJ,CAAC","sourcesContent":["export type VegaCellQuery = {\n selectedSqlQuery: string;\n};\n\n/**\n * Builds the final SQL query for a Vega cell with optional cross-filter predicates.\n * If cross-filtering is enabled and active, wraps the base query as a subquery\n * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.\n */\nexport function useVegaCellQuery(params: {\n baseSqlQuery: string;\n}): VegaCellQuery {\n const {baseSqlQuery} = params;\n\n return {\n selectedSqlQuery: baseSqlQuery,\n };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -18,7 +18,6 @@ export { getRenderableDependencyEdges } from './dagUtils';
18
18
  export { findArtifactIdForCell, normalizeCellDependencies, resolveArtifactSchemaName, toDataSourceCell, toDataSourceTable, isDataSourceCell, isDataSourceTable, fromDataSourceCell, fromDataSourceTable, } from './helpers';
19
19
  export { useCellsStore } from './hooks';
20
20
  export { findSqlDependencies, findSqlDependenciesFromAst, renderSqlWithInputs, runSqlWithCallbacks, } from './sqlHelpers';
21
- export { buildCrossFilterPredicate, BRUSH_PARAM_NAME, } from './vegaSelectionUtils';
22
21
  export * from './types';
23
22
  export declare const SqlCell: {
24
23
  RunButton: typeof SqlCellRunButtonComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,cAAc,IAAI,uBAAuB,EAAC,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAC,gBAAgB,IAAI,yBAAyB,EAAC,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,uBAAuB,IAAI,cAAc,EAAC,CAAC;AACnD,OAAO,EAAC,yBAAyB,IAAI,gBAAgB,EAAC,CAAC;AACvD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAC,yBAAyB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,4BAA4B,EAAC,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,SAAS,CAAC;AAExB,eAAO,MAAM,OAAO;;;CAGnB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,cAAc,IAAI,uBAAuB,EAAC,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAC,gBAAgB,IAAI,yBAAyB,EAAC,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,uBAAuB,IAAI,cAAc,EAAC,CAAC;AACnD,OAAO,EAAC,yBAAyB,IAAI,gBAAgB,EAAC,CAAC;AACvD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAC,yBAAyB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,4BAA4B,EAAC,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,cAAc,SAAS,CAAC;AAExB,eAAO,MAAM,OAAO;;;CAGnB,CAAC"}
package/dist/index.js CHANGED
@@ -17,7 +17,6 @@ export { getRenderableDependencyEdges } from './dagUtils';
17
17
  export { findArtifactIdForCell, normalizeCellDependencies, resolveArtifactSchemaName, toDataSourceCell, toDataSourceTable, isDataSourceCell, isDataSourceTable, fromDataSourceCell, fromDataSourceTable, } from './helpers';
18
18
  export { useCellsStore } from './hooks';
19
19
  export { findSqlDependencies, findSqlDependenciesFromAst, renderSqlWithInputs, runSqlWithCallbacks, } from './sqlHelpers';
20
- export { buildCrossFilterPredicate, BRUSH_PARAM_NAME, } from './vegaSelectionUtils';
21
20
  export * from './types';
22
21
  export const SqlCell = {
23
22
  RunButton: SqlCellRunButtonComponent,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,cAAc,IAAI,uBAAuB,EAAC,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAC,gBAAgB,IAAI,yBAAyB,EAAC,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,uBAAuB,IAAI,cAAc,EAAC,CAAC;AACnD,OAAO,EAAC,yBAAyB,IAAI,gBAAgB,EAAC,CAAC;AACvD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAC,yBAAyB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,4BAA4B,EAAC,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,SAAS,CAAC;AAExB,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,SAAS,EAAE,yBAAyB;IACpC,OAAO,EAAE,uBAAuB;CACjC,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nimport {SqlCellContent as SqlCellContentComponent} from './components/SqlCellContent';\nimport {SqlCellRunButton as SqlCellRunButtonComponent} from './components/SqlCellRunButton';\n\nexport {createCellsSlice} from './cellsSlice';\nexport type {CellsRootState} from './types';\nexport {initializeInput} from './components/Input/helpers';\nexport {InputCellContent} from './components/InputCellContent';\nexport {SqlCellContentComponent as SqlCellContent};\nexport {SqlCellRunButtonComponent as SqlCellRunButton};\nexport {TextCellContent} from './components/TextCellContent';\nexport {VegaCellContent} from './components/VegaCellContent';\nexport {CellSourceSelector} from './components/CellSourceSelector';\nexport {createDefaultCellRegistry} from './defaultCellRegistry';\nexport {getRenderableDependencyEdges} from './dagUtils';\nexport {\n findArtifactIdForCell,\n normalizeCellDependencies,\n resolveArtifactSchemaName,\n toDataSourceCell,\n toDataSourceTable,\n isDataSourceCell,\n isDataSourceTable,\n fromDataSourceCell,\n fromDataSourceTable,\n} from './helpers';\nexport {useCellsStore} from './hooks';\nexport {\n findSqlDependencies,\n findSqlDependenciesFromAst,\n renderSqlWithInputs,\n runSqlWithCallbacks,\n} from './sqlHelpers';\nexport {\n buildCrossFilterPredicate,\n BRUSH_PARAM_NAME,\n} from './vegaSelectionUtils';\nexport * from './types';\n\nexport const SqlCell = {\n RunButton: SqlCellRunButtonComponent,\n Content: SqlCellContentComponent,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,cAAc,IAAI,uBAAuB,EAAC,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAC,gBAAgB,IAAI,yBAAyB,EAAC,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,uBAAuB,IAAI,cAAc,EAAC,CAAC;AACnD,OAAO,EAAC,yBAAyB,IAAI,gBAAgB,EAAC,CAAC;AACvD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAC,yBAAyB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,4BAA4B,EAAC,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,cAAc,SAAS,CAAC;AAExB,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,SAAS,EAAE,yBAAyB;IACpC,OAAO,EAAE,uBAAuB;CACjC,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nimport {SqlCellContent as SqlCellContentComponent} from './components/SqlCellContent';\nimport {SqlCellRunButton as SqlCellRunButtonComponent} from './components/SqlCellRunButton';\n\nexport {createCellsSlice} from './cellsSlice';\nexport type {CellsRootState} from './types';\nexport {initializeInput} from './components/Input/helpers';\nexport {InputCellContent} from './components/InputCellContent';\nexport {SqlCellContentComponent as SqlCellContent};\nexport {SqlCellRunButtonComponent as SqlCellRunButton};\nexport {TextCellContent} from './components/TextCellContent';\nexport {VegaCellContent} from './components/VegaCellContent';\nexport {CellSourceSelector} from './components/CellSourceSelector';\nexport {createDefaultCellRegistry} from './defaultCellRegistry';\nexport {getRenderableDependencyEdges} from './dagUtils';\nexport {\n findArtifactIdForCell,\n normalizeCellDependencies,\n resolveArtifactSchemaName,\n toDataSourceCell,\n toDataSourceTable,\n isDataSourceCell,\n isDataSourceTable,\n fromDataSourceCell,\n fromDataSourceTable,\n} from './helpers';\nexport {useCellsStore} from './hooks';\nexport {\n findSqlDependencies,\n findSqlDependenciesFromAst,\n renderSqlWithInputs,\n runSqlWithCallbacks,\n} from './sqlHelpers';\nexport * from './types';\n\nexport const SqlCell = {\n RunButton: SqlCellRunButtonComponent,\n Content: SqlCellContentComponent,\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,13 @@
1
1
  {
2
2
  "name": "@sqlrooms/cells",
3
- "version": "0.29.0-rc.3",
3
+ "version": "0.29.0-rc.4",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/sqlrooms/sqlrooms.git"
7
+ },
8
+ "license": "MIT",
9
+ "author": "SQLRooms Contributors",
10
+ "sideEffects": false,
4
11
  "type": "module",
5
12
  "main": "dist/index.js",
6
13
  "module": "dist/index.js",
@@ -8,32 +15,25 @@
8
15
  "files": [
9
16
  "dist"
10
17
  ],
11
- "author": "SQLRooms Contributors",
12
- "license": "MIT",
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/sqlrooms/sqlrooms.git"
16
- },
17
- "sideEffects": false,
18
18
  "scripts": {
19
- "dev": "tsc -w",
20
19
  "build": "tsc",
20
+ "dev": "tsc -w",
21
+ "lint": "eslint .",
21
22
  "test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest",
22
23
  "test:watch": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --watch",
23
- "lint": "eslint .",
24
24
  "typecheck": "tsc --noEmit",
25
25
  "typedoc": "typedoc"
26
26
  },
27
27
  "dependencies": {
28
28
  "@paralleldrive/cuid2": "^2.2.2",
29
- "@sqlrooms/data-table": "0.29.0-rc.3",
30
- "@sqlrooms/db": "0.29.0-rc.3",
31
- "@sqlrooms/duckdb": "0.29.0-rc.3",
32
- "@sqlrooms/room-store": "0.29.0-rc.3",
33
- "@sqlrooms/sql-editor": "0.29.0-rc.3",
34
- "@sqlrooms/ui": "0.29.0-rc.3",
35
- "@sqlrooms/utils": "0.29.0-rc.3",
36
- "@sqlrooms/vega": "0.29.0-rc.3",
29
+ "@sqlrooms/data-table": "0.29.0-rc.4",
30
+ "@sqlrooms/db": "0.29.0-rc.4",
31
+ "@sqlrooms/duckdb": "0.29.0-rc.4",
32
+ "@sqlrooms/room-store": "0.29.0-rc.4",
33
+ "@sqlrooms/sql-editor": "0.29.0-rc.4",
34
+ "@sqlrooms/ui": "0.29.0-rc.4",
35
+ "@sqlrooms/utils": "0.29.0-rc.4",
36
+ "@sqlrooms/vega": "0.29.0-rc.4",
37
37
  "@tanstack/react-table": "^8.21.3",
38
38
  "apache-arrow": "17.0.0",
39
39
  "immer": "^11.0.1",
@@ -52,5 +52,5 @@
52
52
  "react": "^18 || ^19",
53
53
  "react-dom": "^18 || ^19"
54
54
  },
55
- "gitHead": "4ffaf6c31d41c27f96bd3e4f5e83d431968721c3"
55
+ "gitHead": "8694bab9d3d915a06d28675ad801b21444bcc55f"
56
56
  }
@@ -1,15 +0,0 @@
1
- import React from 'react';
2
- import type { BrushFieldType } from '../types';
3
- type SelectionListenerProps = {
4
- cellId: string;
5
- sqlId: string;
6
- brushField: string;
7
- brushFieldType?: BrushFieldType;
8
- };
9
- /**
10
- * Attaches a debounced Vega signal listener for the brush param
11
- * and reports selection changes to the cross-filter state.
12
- */
13
- export declare const SelectionListener: React.FC<SelectionListenerProps>;
14
- export {};
15
- //# sourceMappingURL=SelectionListener.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SelectionListener.d.ts","sourceRoot":"","sources":["../../src/components/SelectionListener.tsx"],"names":[],"mappings":"AACA,OAAO,KAA0B,MAAM,OAAO,CAAC;AAE/C,OAAO,KAAK,EAAC,cAAc,EAAuB,MAAM,UAAU,CAAC;AAGnE,KAAK,sBAAsB,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA8E9D,CAAC"}
@@ -1,74 +0,0 @@
1
- import { useVegaChartContext } from '@sqlrooms/vega';
2
- import { useEffect, useRef } from 'react';
3
- import { useCellsStore } from '../hooks';
4
- import { BRUSH_PARAM_NAME } from '../vegaSelectionUtils';
5
- /**
6
- * Attaches a debounced Vega signal listener for the brush param
7
- * and reports selection changes to the cross-filter state.
8
- */
9
- export const SelectionListener = ({ cellId, sqlId, brushField, brushFieldType, }) => {
10
- const { embed } = useVegaChartContext();
11
- const setCrossFilterSelection = useCellsStore((s) => s.cells.setCrossFilterSelection);
12
- const timerRef = useRef(null);
13
- useEffect(() => {
14
- if (!embed?.view) {
15
- return;
16
- }
17
- const handler = (_name, value) => {
18
- if (timerRef.current) {
19
- clearTimeout(timerRef.current);
20
- }
21
- timerRef.current = setTimeout(() => {
22
- if (!value || Object.keys(value).length === 0) {
23
- setCrossFilterSelection(cellId, sqlId, null);
24
- return;
25
- }
26
- const fieldValue = value.x ?? value[brushField];
27
- if (Array.isArray(fieldValue) && fieldValue.length === 2) {
28
- const selection = {
29
- field: brushField,
30
- fieldType: brushFieldType,
31
- type: 'interval',
32
- value: fieldValue,
33
- };
34
- setCrossFilterSelection(cellId, sqlId, selection);
35
- }
36
- else {
37
- setCrossFilterSelection(cellId, sqlId, null);
38
- }
39
- }, 200);
40
- };
41
- try {
42
- embed.view.addSignalListener(BRUSH_PARAM_NAME, handler);
43
- }
44
- catch (error) {
45
- // Signal doesn't exist yet (view is still rendering a spec without the brush param).
46
- // Will retry when embed reference changes after the new spec is compiled.
47
- console.warn('Failed to add signal listener:', error);
48
- return;
49
- }
50
- return () => {
51
- if (timerRef.current) {
52
- clearTimeout(timerRef.current);
53
- }
54
- try {
55
- embed.view.removeSignalListener(BRUSH_PARAM_NAME, handler);
56
- }
57
- catch (error) {
58
- // View may have been finalized
59
- console.warn('Failed to remove signal listener:', error);
60
- }
61
- // Clear this chart's selection from crossFilterSelections
62
- setCrossFilterSelection(cellId, sqlId, null);
63
- };
64
- }, [
65
- embed,
66
- cellId,
67
- sqlId,
68
- brushField,
69
- brushFieldType,
70
- setCrossFilterSelection,
71
- ]);
72
- return null;
73
- };
74
- //# sourceMappingURL=SelectionListener.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SelectionListener.js","sourceRoot":"","sources":["../../src/components/SelectionListener.tsx"],"names":[],"mappings":"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","sourcesContent":["import {SignalListenerHandler, useVegaChartContext} from '@sqlrooms/vega';\nimport React, {useEffect, useRef} from 'react';\nimport {useCellsStore} from '../hooks';\nimport type {BrushFieldType, CrossFilterSelection} from '../types';\nimport {BRUSH_PARAM_NAME} from '../vegaSelectionUtils';\n\ntype SelectionListenerProps = {\n cellId: string;\n sqlId: string;\n brushField: string;\n brushFieldType?: BrushFieldType;\n};\n\n/**\n * Attaches a debounced Vega signal listener for the brush param\n * and reports selection changes to the cross-filter state.\n */\nexport const SelectionListener: React.FC<SelectionListenerProps> = ({\n cellId,\n sqlId,\n brushField,\n brushFieldType,\n}) => {\n const {embed} = useVegaChartContext();\n const setCrossFilterSelection = useCellsStore(\n (s) => s.cells.setCrossFilterSelection,\n );\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!embed?.view) {\n return;\n }\n\n const handler: SignalListenerHandler = (_name, value) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n timerRef.current = setTimeout(() => {\n if (!value || Object.keys(value).length === 0) {\n setCrossFilterSelection(cellId, sqlId, null);\n return;\n }\n\n const fieldValue = value.x ?? value[brushField];\n\n if (Array.isArray(fieldValue) && fieldValue.length === 2) {\n const selection: CrossFilterSelection = {\n field: brushField,\n fieldType: brushFieldType,\n type: 'interval',\n value: fieldValue,\n };\n setCrossFilterSelection(cellId, sqlId, selection);\n } else {\n setCrossFilterSelection(cellId, sqlId, null);\n }\n }, 200);\n };\n\n try {\n embed.view.addSignalListener(BRUSH_PARAM_NAME, handler);\n } catch (error) {\n // Signal doesn't exist yet (view is still rendering a spec without the brush param).\n // Will retry when embed reference changes after the new spec is compiled.\n console.warn('Failed to add signal listener:', error);\n return;\n }\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n try {\n embed.view.removeSignalListener(BRUSH_PARAM_NAME, handler);\n } catch (error) {\n // View may have been finalized\n console.warn('Failed to remove signal listener:', error);\n }\n\n // Clear this chart's selection from crossFilterSelections\n setCrossFilterSelection(cellId, sqlId, null);\n };\n }, [\n embed,\n cellId,\n sqlId,\n brushField,\n brushFieldType,\n setCrossFilterSelection,\n ]);\n\n return null;\n};\n"]}