@sqlrooms/cells 0.29.0-rc.1 → 0.29.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cellsSlice.d.ts.map +1 -1
- package/dist/cellsSlice.js +191 -73
- package/dist/cellsSlice.js.map +1 -1
- package/dist/components/AggregationSelector.d.ts +8 -0
- package/dist/components/AggregationSelector.d.ts.map +1 -0
- package/dist/components/AggregationSelector.js +13 -0
- package/dist/components/AggregationSelector.js.map +1 -0
- package/dist/components/CellSourceSelector.d.ts +11 -0
- package/dist/components/CellSourceSelector.d.ts.map +1 -0
- package/dist/components/CellSourceSelector.js +35 -0
- package/dist/components/CellSourceSelector.js.map +1 -0
- package/dist/components/ChartTypeSelector.d.ts +8 -0
- package/dist/components/ChartTypeSelector.d.ts.map +1 -0
- package/dist/components/ChartTypeSelector.js +13 -0
- package/dist/components/ChartTypeSelector.js.map +1 -0
- package/dist/components/CollapsibleSectionButton.d.ts +10 -0
- package/dist/components/CollapsibleSectionButton.d.ts.map +1 -0
- package/dist/components/CollapsibleSectionButton.js +10 -0
- package/dist/components/CollapsibleSectionButton.js.map +1 -0
- package/dist/components/ColorSelector.d.ts +24 -0
- package/dist/components/ColorSelector.d.ts.map +1 -0
- package/dist/components/ColorSelector.js +17 -0
- package/dist/components/ColorSelector.js.map +1 -0
- package/dist/components/FieldSelector.d.ts +11 -0
- package/dist/components/FieldSelector.d.ts.map +1 -0
- package/dist/components/FieldSelector.js +11 -0
- package/dist/components/FieldSelector.js.map +1 -0
- package/dist/components/FieldTypeIcon.d.ts +8 -0
- package/dist/components/FieldTypeIcon.d.ts.map +1 -0
- package/dist/components/FieldTypeIcon.js +27 -0
- package/dist/components/FieldTypeIcon.js.map +1 -0
- package/dist/components/InputCellContent.d.ts.map +1 -1
- package/dist/components/InputCellContent.js +3 -3
- package/dist/components/InputCellContent.js.map +1 -1
- package/dist/components/SelectionListener.d.ts +15 -0
- package/dist/components/SelectionListener.d.ts.map +1 -0
- package/dist/components/SelectionListener.js +74 -0
- package/dist/components/SelectionListener.js.map +1 -0
- package/dist/components/SheetsTabBar.d.ts.map +1 -1
- package/dist/components/SheetsTabBar.js +2 -1
- package/dist/components/SheetsTabBar.js.map +1 -1
- package/dist/components/SqlCellBody.d.ts +6 -0
- package/dist/components/SqlCellBody.d.ts.map +1 -0
- package/dist/components/SqlCellBody.js +12 -0
- package/dist/components/SqlCellBody.js.map +1 -0
- package/dist/components/SqlCellConnectionSelector.d.ts +9 -0
- package/dist/components/SqlCellConnectionSelector.d.ts.map +1 -0
- package/dist/components/SqlCellConnectionSelector.js +21 -0
- package/dist/components/SqlCellConnectionSelector.js.map +1 -0
- package/dist/components/SqlCellContent.d.ts.map +1 -1
- package/dist/components/SqlCellContent.js +29 -154
- package/dist/components/SqlCellContent.js.map +1 -1
- package/dist/components/SqlCellDependentsMenu.d.ts +11 -0
- package/dist/components/SqlCellDependentsMenu.d.ts.map +1 -0
- package/dist/components/SqlCellDependentsMenu.js +62 -0
- package/dist/components/SqlCellDependentsMenu.js.map +1 -0
- package/dist/components/SqlCellEditor.d.ts +14 -0
- package/dist/components/SqlCellEditor.d.ts.map +1 -0
- package/dist/components/SqlCellEditor.js +17 -0
- package/dist/components/SqlCellEditor.js.map +1 -0
- package/dist/components/SqlCellResultNameEditor.d.ts +8 -0
- package/dist/components/SqlCellResultNameEditor.d.ts.map +1 -0
- package/dist/components/SqlCellResultNameEditor.js +38 -0
- package/dist/components/SqlCellResultNameEditor.js.map +1 -0
- package/dist/components/SqlCellResults.d.ts +17 -0
- package/dist/components/SqlCellResults.d.ts.map +1 -0
- package/dist/components/SqlCellResults.js +45 -0
- package/dist/components/SqlCellResults.js.map +1 -0
- package/dist/components/SqlCellRunButton.d.ts +5 -6
- package/dist/components/SqlCellRunButton.d.ts.map +1 -1
- package/dist/components/SqlCellRunButton.js +11 -7
- package/dist/components/SqlCellRunButton.js.map +1 -1
- package/dist/components/SqlQueryPreview.d.ts +9 -0
- package/dist/components/SqlQueryPreview.d.ts.map +1 -0
- package/dist/components/SqlQueryPreview.js +14 -0
- package/dist/components/SqlQueryPreview.js.map +1 -0
- package/dist/components/TextCellContent.d.ts.map +1 -1
- package/dist/components/TextCellContent.js +24 -7
- package/dist/components/TextCellContent.js.map +1 -1
- package/dist/components/VegaCellContent.d.ts +0 -1
- package/dist/components/VegaCellContent.d.ts.map +1 -1
- package/dist/components/VegaCellContent.js +61 -47
- package/dist/components/VegaCellContent.js.map +1 -1
- package/dist/components/VegaCellHeader.d.ts +11 -0
- package/dist/components/VegaCellHeader.d.ts.map +1 -0
- package/dist/components/VegaCellHeader.js +31 -0
- package/dist/components/VegaCellHeader.js.map +1 -0
- package/dist/components/VegaConfigPanel.d.ts +5 -0
- package/dist/components/VegaConfigPanel.d.ts.map +1 -1
- package/dist/components/VegaConfigPanel.js +53 -63
- package/dist/components/VegaConfigPanel.js.map +1 -1
- package/dist/crdt.d.ts +61 -0
- package/dist/crdt.d.ts.map +1 -0
- package/dist/crdt.js +82 -0
- package/dist/crdt.js.map +1 -0
- package/dist/dagSlice.d.ts +3 -0
- package/dist/dagSlice.d.ts.map +1 -0
- package/dist/dagSlice.js +51 -0
- package/dist/dagSlice.js.map +1 -0
- package/dist/dagUtils.d.ts +2 -1
- package/dist/dagUtils.d.ts.map +1 -1
- package/dist/dagUtils.js +35 -11
- package/dist/dagUtils.js.map +1 -1
- package/dist/defaultCellRegistry.d.ts.map +1 -1
- package/dist/defaultCellRegistry.js +63 -24
- package/dist/defaultCellRegistry.js.map +1 -1
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +2 -1
- package/dist/execution.js.map +1 -1
- package/dist/helpers.d.ts +14 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +56 -2
- package/dist/helpers.js.map +1 -1
- package/dist/hooks/useVegaCellDataSource.d.ts +18 -0
- package/dist/hooks/useVegaCellDataSource.d.ts.map +1 -0
- package/dist/hooks/useVegaCellDataSource.js +40 -0
- package/dist/hooks/useVegaCellDataSource.js.map +1 -0
- package/dist/hooks/useVegaCellQuery.d.ts +16 -0
- package/dist/hooks/useVegaCellQuery.d.ts.map +1 -0
- package/dist/hooks/useVegaCellQuery.js +25 -0
- package/dist/hooks/useVegaCellQuery.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/sqlHelpers.d.ts +3 -3
- package/dist/sqlHelpers.d.ts.map +1 -1
- package/dist/sqlHelpers.js +9 -5
- package/dist/sqlHelpers.js.map +1 -1
- package/dist/typeGuards.d.ts +2 -0
- package/dist/typeGuards.d.ts.map +1 -0
- package/dist/typeGuards.js +4 -0
- package/dist/typeGuards.js.map +1 -0
- package/dist/types.d.ts +97 -26
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -2
- package/dist/types.js.map +1 -1
- package/dist/useValidateResultName.d.ts +34 -0
- package/dist/useValidateResultName.d.ts.map +1 -0
- package/dist/useValidateResultName.js +111 -0
- package/dist/useValidateResultName.js.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +16 -0
- package/dist/utils.js.map +1 -1
- package/dist/validation.d.ts +16 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +40 -0
- package/dist/validation.js.map +1 -0
- package/dist/vegaSelectionUtils.d.ts +14 -0
- package/dist/vegaSelectionUtils.d.ts.map +1 -0
- package/dist/vegaSelectionUtils.js +97 -0
- package/dist/vegaSelectionUtils.js.map +1 -0
- package/dist/vegaSpecBuilder.d.ts +34 -0
- package/dist/vegaSpecBuilder.d.ts.map +1 -0
- package/dist/vegaSpecBuilder.js +90 -0
- package/dist/vegaSpecBuilder.js.map +1 -0
- package/package.json +12 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlCellContent.js","sourceRoot":"","sources":["../../src/components/SqlCellContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DataTablePaginated,\n QueryDataTableActionsMenu,\n useArrowDataTable,\n} from '@sqlrooms/data-table';\nimport {getCoreDuckDbConnectionId, type DbConnection} from '@sqlrooms/db';\nimport {useRoomStoreApi} from '@sqlrooms/room-store';\nimport {SqlMonacoEditor} from '@sqlrooms/sql-editor';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n EditableText,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@sqlrooms/ui';\nimport {convertToValidColumnOrTableName} from '@sqlrooms/utils';\nimport type {PaginationState, SortingState} from '@tanstack/react-table';\nimport {type Draft, produce} from 'immer';\nimport {CornerDownRightIcon} from 'lucide-react';\nimport type * as Monaco from 'monaco-editor';\nimport React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useCellsStore} from '../hooks';\nimport type {CellContainerProps, CellsRootState, SqlCell} from '../types';\nimport {getEffectiveResultName, isValidSqlIdentifier} from '../utils';\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 currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);\n const cellsData = useCellsStore((s) => s.cells.config.data);\n const sheets = useCellsStore((s) => s.cells.config.sheets);\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\n // Re-read the cache whenever resultVersion or pageVersion changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const cellResult = useMemo(\n () => getCellResult(id),\n [getCellResult, id, resultVersion, pageVersion],\n );\n const arrowTableData = useArrowDataTable(cellResult?.arrowTable);\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 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 validateResultName = useCallback((value: string) => {\n const nextValue = value.trim();\n return Boolean(nextValue) && isValidSqlIdentifier(nextValue);\n }, []);\n\n const handleResultNameInputChange = useCallback(\n (value: string) => {\n setIsResultNameInvalid(!validateResultName(value));\n },\n [validateResultName],\n );\n\n const handleResultNameChange = useCallback(\n (value: string) => {\n const nextValue = value.trim();\n if (!validateResultName(nextValue)) {\n setIsResultNameInvalid(true);\n return;\n }\n\n updateCell(id, (c) =>\n produce(c, (draft) => {\n if (draft.type === 'sql') {\n draft.data.resultName = nextValue;\n }\n }),\n );\n setIsResultNameInvalid(false);\n },\n [id, updateCell, validateResultName],\n );\n\n const effectiveResultName = getEffectiveResultName(\n cell.data,\n convertToValidColumnOrTableName,\n );\n const explicitResultName = cell.data.resultName || '';\n const selectedConnectorId =\n cell.data.connectorId || getCoreDuckDbConnectionId();\n const connectionOptions = useMemo(() => {\n const entries = Object.values(dbConnections);\n if (!entries.length) {\n return [{id: getCoreDuckDbConnectionId(), title: 'Core DuckDB'}];\n }\n return entries.map((conn: DbConnection) => ({\n id: conn.id,\n title: conn.title || conn.id,\n }));\n }, [dbConnections]);\n const [dependentsMenuOpen, setDependentsMenuOpen] = useState(false);\n const closeDependentsMenuTimerRef = useRef<ReturnType<\n typeof setTimeout\n > | null>(null);\n const [isResultNameInvalid, setIsResultNameInvalid] = useState(false);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const downstreamCellIds = useMemo(() => {\n if (!currentSheetId) return [];\n return getDownstream(currentSheetId, id);\n }, [currentSheetId, getDownstream, id, cellsData, sheets]);\n\n const downstreamCells = useMemo(\n () =>\n downstreamCellIds.map((cellId) => {\n const downstreamCell = cellsData[cellId];\n return {\n id: cellId,\n label: downstreamCell?.data?.title?.trim() || 'Untitled',\n };\n }),\n [cellsData, downstreamCellIds],\n );\n\n const scrollToDependentCell = useCallback((targetCellId: string) => {\n const selectorTargets = [\n `[data-cell-container-id=\"${targetCellId}\"]`,\n `#cell-${targetCellId}`,\n ];\n const el =\n selectorTargets\n .map((selector) => document.querySelector<HTMLElement>(selector))\n .find(Boolean) ?? null;\n if (el) {\n el.scrollIntoView({behavior: 'smooth', block: 'center'});\n }\n }, []);\n\n const status =\n cellStatus?.type === 'sql'\n ? {\n state: cellStatus.status,\n message: cellStatus.lastError,\n resultName: cellStatus.resultView || cellStatus.resultName,\n lastRunTime: cellStatus.lastRunTime,\n }\n : undefined;\n\n const resultName = status?.resultName;\n const isRunning = status?.state === 'running';\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 // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n if (resultName) {\n fetchCellResultPage(id, pagination, sorting);\n }\n }, [pagination, sorting, id, fetchCellResultPage]);\n\n const clearDependentsCloseTimer = useCallback(() => {\n if (closeDependentsMenuTimerRef.current) {\n clearTimeout(closeDependentsMenuTimerRef.current);\n closeDependentsMenuTimerRef.current = null;\n }\n }, []);\n\n const openDependentsMenu = useCallback(() => {\n clearDependentsCloseTimer();\n setDependentsMenuOpen(true);\n }, [clearDependentsCloseTimer]);\n\n const scheduleCloseDependentsMenu = useCallback(() => {\n clearDependentsCloseTimer();\n closeDependentsMenuTimerRef.current = setTimeout(() => {\n setDependentsMenuOpen(false);\n closeDependentsMenuTimerRef.current = null;\n }, 120);\n }, [clearDependentsCloseTimer]);\n\n useEffect(() => {\n return () => {\n clearDependentsCloseTimer();\n };\n }, [clearDependentsCloseTimer]);\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 const handleRunRef = useRef(handleRun);\n useEffect(() => {\n handleRunRef.current = handleRun;\n }, [handleRun]);\n\n const handleSqlEditorMount = useCallback(\n (editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco) => {\n // Use onKeyDown instead of addCommand to scope the shortcut\n // to THIS specific editor instance. Monaco's addCommand registers\n // globally, so the last editor mounted wins -- breaking multi-cell\n // notebooks.\n editor.onKeyDown((e) => {\n if ((e.ctrlKey || e.metaKey) && e.keyCode === monaco.KeyCode.Enter) {\n e.preventDefault();\n e.stopPropagation();\n // Flush the current editor value directly to the store\n // synchronously before running. Monaco's onChange may not have\n // fired yet for the latest content, so we read the editor model\n // directly and write it to the Zustand store in a single\n // synchronous call, bypassing the async updateCell path.\n const currentSql = editor.getValue();\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 = currentSql;\n }\n }),\n );\n handleRunRef.current();\n }\n });\n },\n [id, storeApi],\n );\n\n const content = (\n <div className=\"flex flex-col\">\n <div className=\"h-full w-full py-1\">\n <div className=\"relative h-full min-h-[200px] w-full\">\n <SqlMonacoEditor\n className=\"absolute inset-0 h-full w-full\"\n value={cell.data.sql}\n onChange={handleSqlChange}\n onMount={handleSqlEditorMount}\n options={{\n minimap: {enabled: false},\n scrollBeyondLastLine: false,\n scrollbar: {\n alwaysConsumeMouseWheel: false,\n },\n }}\n />\n </div>\n </div>\n {status?.state === 'error' ? (\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 {status.message}\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={`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 </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 {downstreamCells.length > 0 ? (\n <DropdownMenu\n open={dependentsMenuOpen}\n onOpenChange={setDependentsMenuOpen}\n >\n <DropdownMenuTrigger asChild>\n <Button\n className=\"h-5\"\n size=\"xs\"\n variant=\"secondary\"\n aria-label={`${downstreamCells.length} dependent cells`}\n onMouseEnter={openDependentsMenu}\n onMouseLeave={scheduleCloseDependentsMenu}\n >\n {downstreamCells.length}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n onCloseAutoFocus={(e) => e.preventDefault()}\n onMouseEnter={openDependentsMenu}\n onMouseLeave={scheduleCloseDependentsMenu}\n >\n <DropdownMenuLabel className=\"text-xs\">\n Referenced in\n </DropdownMenuLabel>\n {downstreamCells.map((dependentCell) => (\n <DropdownMenuItem\n key={dependentCell.id}\n className=\"cursor-pointer text-xs\"\n onSelect={(e) => {\n e.preventDefault();\n scrollToDependentCell(dependentCell.id);\n }}\n >\n {dependentCell.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n <Tooltip open={isResultNameInvalid}>\n <TooltipTrigger asChild>\n <div>\n <EditableText\n className={`h-6 w-40 font-mono text-xs text-green-500 shadow-none ${\n isResultNameInvalid\n ? 'border-red-500 ring-1 ring-red-500 focus:border-red-500 focus:ring-red-500'\n : ''\n }`}\n value={explicitResultName || effectiveResultName}\n onInputChange={handleResultNameInputChange}\n onChange={handleResultNameChange}\n />\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n <span className=\"text-xs\">Invalid result name</span>\n </TooltipContent>\n </Tooltip>\n </div>\n );\n\n return renderContainer({\n header: (\n <div className=\"flex w-full items-center gap-2\">\n <div className=\"flex-1\">\n <select\n className=\"border-input bg-background text-foreground h-7 rounded border px-2 text-xs\"\n value={selectedConnectorId}\n onChange={(e) => handleConnectorChange(e.target.value)}\n >\n {connectionOptions.map((connection) => (\n <option key={connection.id} value={connection.id}>\n {connection.title}\n </option>\n ))}\n </select>\n </div>\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, 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 currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);\n const cellsData = useCellsStore((s) => s.cells.config.data);\n const sheets = useCellsStore((s) => s.cells.config.sheets);\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 currentSheetId={currentSheetId}\n cellsData={cellsData}\n sheets={sheets}\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"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CellsSliceConfig } from '../types';
|
|
3
|
+
export type SqlCellDependentsMenuProps = {
|
|
4
|
+
cellId: string;
|
|
5
|
+
currentSheetId: string | undefined;
|
|
6
|
+
cellsData: CellsSliceConfig['data'];
|
|
7
|
+
sheets: CellsSliceConfig['sheets'];
|
|
8
|
+
getDownstream: (sheetId: string, cellId: string) => string[];
|
|
9
|
+
};
|
|
10
|
+
export declare const SqlCellDependentsMenu: React.FC<SqlCellDependentsMenuProps>;
|
|
11
|
+
//# sourceMappingURL=SqlCellDependentsMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCellDependentsMenu.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellDependentsMenu.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAE/C,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;CAC9D,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CA4GtE,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger, } from '@sqlrooms/ui';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
export const SqlCellDependentsMenu = ({ cellId, currentSheetId, cellsData, sheets, getDownstream, }) => {
|
|
5
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
6
|
+
const closeMenuTimerRef = useRef(null);
|
|
7
|
+
const downstreamCellIds = useMemo(() => {
|
|
8
|
+
if (!currentSheetId)
|
|
9
|
+
return [];
|
|
10
|
+
return getDownstream(currentSheetId, cellId);
|
|
11
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12
|
+
}, [currentSheetId, getDownstream, cellId, cellsData, sheets]);
|
|
13
|
+
const downstreamCells = useMemo(() => downstreamCellIds.map((downstreamCellId) => {
|
|
14
|
+
const downstreamCell = cellsData[downstreamCellId];
|
|
15
|
+
return {
|
|
16
|
+
id: downstreamCellId,
|
|
17
|
+
label: downstreamCell?.data?.title?.trim() || 'Untitled',
|
|
18
|
+
};
|
|
19
|
+
}), [cellsData, downstreamCellIds]);
|
|
20
|
+
const scrollToCell = useCallback((targetCellId) => {
|
|
21
|
+
const selectorTargets = [
|
|
22
|
+
`[data-cell-container-id="${targetCellId}"]`,
|
|
23
|
+
`#cell-${targetCellId}`,
|
|
24
|
+
];
|
|
25
|
+
const el = selectorTargets
|
|
26
|
+
.map((selector) => document.querySelector(selector))
|
|
27
|
+
.find(Boolean) ?? null;
|
|
28
|
+
if (el) {
|
|
29
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
30
|
+
}
|
|
31
|
+
}, []);
|
|
32
|
+
const clearCloseTimer = useCallback(() => {
|
|
33
|
+
if (closeMenuTimerRef.current) {
|
|
34
|
+
clearTimeout(closeMenuTimerRef.current);
|
|
35
|
+
closeMenuTimerRef.current = null;
|
|
36
|
+
}
|
|
37
|
+
}, []);
|
|
38
|
+
const openMenu = useCallback(() => {
|
|
39
|
+
clearCloseTimer();
|
|
40
|
+
setMenuOpen(true);
|
|
41
|
+
}, [clearCloseTimer]);
|
|
42
|
+
const scheduleCloseMenu = useCallback(() => {
|
|
43
|
+
clearCloseTimer();
|
|
44
|
+
closeMenuTimerRef.current = setTimeout(() => {
|
|
45
|
+
setMenuOpen(false);
|
|
46
|
+
closeMenuTimerRef.current = null;
|
|
47
|
+
}, 120);
|
|
48
|
+
}, [clearCloseTimer]);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
return () => {
|
|
51
|
+
clearCloseTimer();
|
|
52
|
+
};
|
|
53
|
+
}, [clearCloseTimer]);
|
|
54
|
+
if (downstreamCells.length === 0) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return (_jsxs(DropdownMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { className: "h-5", size: "xs", variant: "secondary", "aria-label": `${downstreamCells.length} dependent cells`, onMouseEnter: openMenu, onMouseLeave: scheduleCloseMenu, children: downstreamCells.length }) }), _jsxs(DropdownMenuContent, { align: "start", onCloseAutoFocus: (e) => e.preventDefault(), onMouseEnter: openMenu, onMouseLeave: scheduleCloseMenu, children: [_jsx(DropdownMenuLabel, { className: "text-xs", children: "Referenced in" }), downstreamCells.map((dependentCell) => (_jsx(DropdownMenuItem, { className: "cursor-pointer text-xs", onSelect: (e) => {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
scrollToCell(dependentCell.id);
|
|
60
|
+
}, children: dependentCell.label }, dependentCell.id)))] })] }));
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=SqlCellDependentsMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCellDependentsMenu.js","sourceRoot":"","sources":["../../src/components/SqlCellDependentsMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from '@sqlrooms/ui';\nimport React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport type {CellsSliceConfig} from '../types';\n\nexport type SqlCellDependentsMenuProps = {\n cellId: string;\n currentSheetId: string | undefined;\n cellsData: CellsSliceConfig['data'];\n sheets: CellsSliceConfig['sheets'];\n getDownstream: (sheetId: string, cellId: string) => string[];\n};\n\nexport const SqlCellDependentsMenu: React.FC<SqlCellDependentsMenuProps> = ({\n cellId,\n currentSheetId,\n cellsData,\n sheets,\n getDownstream,\n}) => {\n const [menuOpen, setMenuOpen] = useState(false);\n const closeMenuTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const downstreamCellIds = useMemo(() => {\n if (!currentSheetId) return [];\n return getDownstream(currentSheetId, cellId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentSheetId, getDownstream, cellId, cellsData, sheets]);\n\n const downstreamCells = useMemo(\n () =>\n downstreamCellIds.map((downstreamCellId) => {\n const downstreamCell = cellsData[downstreamCellId];\n return {\n id: downstreamCellId,\n label: downstreamCell?.data?.title?.trim() || 'Untitled',\n };\n }),\n [cellsData, downstreamCellIds],\n );\n\n const scrollToCell = useCallback((targetCellId: string) => {\n const selectorTargets = [\n `[data-cell-container-id=\"${targetCellId}\"]`,\n `#cell-${targetCellId}`,\n ];\n const el =\n selectorTargets\n .map((selector) => document.querySelector<HTMLElement>(selector))\n .find(Boolean) ?? null;\n if (el) {\n el.scrollIntoView({behavior: 'smooth', block: 'center'});\n }\n }, []);\n\n const clearCloseTimer = useCallback(() => {\n if (closeMenuTimerRef.current) {\n clearTimeout(closeMenuTimerRef.current);\n closeMenuTimerRef.current = null;\n }\n }, []);\n\n const openMenu = useCallback(() => {\n clearCloseTimer();\n setMenuOpen(true);\n }, [clearCloseTimer]);\n\n const scheduleCloseMenu = useCallback(() => {\n clearCloseTimer();\n closeMenuTimerRef.current = setTimeout(() => {\n setMenuOpen(false);\n closeMenuTimerRef.current = null;\n }, 120);\n }, [clearCloseTimer]);\n\n useEffect(() => {\n return () => {\n clearCloseTimer();\n };\n }, [clearCloseTimer]);\n\n if (downstreamCells.length === 0) {\n return null;\n }\n\n return (\n <DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n className=\"h-5\"\n size=\"xs\"\n variant=\"secondary\"\n aria-label={`${downstreamCells.length} dependent cells`}\n onMouseEnter={openMenu}\n onMouseLeave={scheduleCloseMenu}\n >\n {downstreamCells.length}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n onCloseAutoFocus={(e) => e.preventDefault()}\n onMouseEnter={openMenu}\n onMouseLeave={scheduleCloseMenu}\n >\n <DropdownMenuLabel className=\"text-xs\">Referenced in</DropdownMenuLabel>\n {downstreamCells.map((dependentCell) => (\n <DropdownMenuItem\n key={dependentCell.id}\n className=\"cursor-pointer text-xs\"\n onSelect={(e) => {\n e.preventDefault();\n scrollToCell(dependentCell.id);\n }}\n >\n {dependentCell.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n};\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DataTable, DuckDbConnector } from '@sqlrooms/duckdb';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface SqlCellEditorProps {
|
|
4
|
+
sql: string;
|
|
5
|
+
connector?: DuckDbConnector;
|
|
6
|
+
tableSchemas?: DataTable[];
|
|
7
|
+
onChange: (value: string | undefined) => void;
|
|
8
|
+
onRunQuery: (query: string) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* SQL query editor with collapse/expand functionality
|
|
12
|
+
*/
|
|
13
|
+
export declare const SqlCellEditor: React.FC<SqlCellEditorProps>;
|
|
14
|
+
//# sourceMappingURL=SqlCellEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCellEditor.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEjE,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC9C,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsCtD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SqlCodeMirrorEditor } from '@sqlrooms/sql-editor';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { CollapsibleSectionButton } from './CollapsibleSectionButton';
|
|
5
|
+
import { SqlQueryPreview } from './SqlQueryPreview';
|
|
6
|
+
/**
|
|
7
|
+
* SQL query editor with collapse/expand functionality
|
|
8
|
+
*/
|
|
9
|
+
export const SqlCellEditor = ({ sql, connector, tableSchemas, onChange, onRunQuery, }) => {
|
|
10
|
+
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
11
|
+
return (_jsxs("div", { className: "group relative w-full py-1", children: [_jsx(CollapsibleSectionButton, { isCollapsed: isCollapsed, onToggle: () => setIsCollapsed(!isCollapsed) }), isCollapsed ? (_jsx("div", { className: "text-muted-foreground ml-5 px-2 py-1 text-xs", children: sql && _jsx(SqlQueryPreview, { sql: sql }) })) : (_jsx("div", { className: "w-full px-1", children: _jsx(SqlCodeMirrorEditor, { className: "h-auto min-h-[48px] w-full", connector: connector, tableSchemas: tableSchemas, value: sql, onChange: onChange, onRunQuery: onRunQuery, options: {
|
|
12
|
+
lineNumbers: true,
|
|
13
|
+
lineWrapping: false,
|
|
14
|
+
highlightActiveLine: true,
|
|
15
|
+
} }) }))] }));
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=SqlCellEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCellEditor.js","sourceRoot":"","sources":["../../src/components/SqlCellEditor.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAc,EAAC,QAAQ,EAAC,MAAM,OAAO,CAAC;AACtC,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAUlD;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAC1D,GAAG,EACH,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,GACX,EAAE,EAAE;IACH,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEtD,OAAO,CACL,eAAK,SAAS,EAAC,4BAA4B,aACzC,KAAC,wBAAwB,IACvB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,WAAW,CAAC,GAC5C,EACD,WAAW,CAAC,CAAC,CAAC,CACb,cAAK,SAAS,EAAC,8CAA8C,YAC1D,GAAG,IAAI,KAAC,eAAe,IAAC,GAAG,EAAE,GAAG,GAAI,GACjC,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,aAAa,YAC1B,KAAC,mBAAmB,IAClB,SAAS,EAAC,4BAA4B,EACtC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE;wBACP,WAAW,EAAE,IAAI;wBACjB,YAAY,EAAE,KAAK;wBACnB,mBAAmB,EAAE,IAAI;qBAC1B,GACD,GACE,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {SqlCodeMirrorEditor} from '@sqlrooms/sql-editor';\nimport React, {useState} from 'react';\nimport {CollapsibleSectionButton} from './CollapsibleSectionButton';\nimport {SqlQueryPreview} from './SqlQueryPreview';\n\nexport interface SqlCellEditorProps {\n sql: string;\n connector?: DuckDbConnector;\n tableSchemas?: DataTable[];\n onChange: (value: string | undefined) => void;\n onRunQuery: (query: string) => void;\n}\n\n/**\n * SQL query editor with collapse/expand functionality\n */\nexport const SqlCellEditor: React.FC<SqlCellEditorProps> = ({\n sql,\n connector,\n tableSchemas,\n onChange,\n onRunQuery,\n}) => {\n const [isCollapsed, setIsCollapsed] = useState(false);\n\n return (\n <div className=\"group relative w-full py-1\">\n <CollapsibleSectionButton\n isCollapsed={isCollapsed}\n onToggle={() => setIsCollapsed(!isCollapsed)}\n />\n {isCollapsed ? (\n <div className=\"text-muted-foreground ml-5 px-2 py-1 text-xs\">\n {sql && <SqlQueryPreview sql={sql} />}\n </div>\n ) : (\n <div className=\"w-full px-1\">\n <SqlCodeMirrorEditor\n className=\"h-auto min-h-[48px] w-full\"\n connector={connector}\n tableSchemas={tableSchemas}\n value={sql}\n onChange={onChange}\n onRunQuery={onRunQuery}\n options={{\n lineNumbers: true,\n lineWrapping: false,\n highlightActiveLine: true,\n }}\n />\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type SqlCellResultNameEditorProps = {
|
|
3
|
+
cellId: string;
|
|
4
|
+
value: string;
|
|
5
|
+
onChange: (value: string) => void;
|
|
6
|
+
};
|
|
7
|
+
export declare const SqlCellResultNameEditor: React.FC<SqlCellResultNameEditorProps>;
|
|
8
|
+
//# sourceMappingURL=SqlCellResultNameEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCellResultNameEditor.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellResultNameEditor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAC5C,4BAA4B,CAiE7B,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn, EditableText, Tooltip, TooltipContent, TooltipTrigger, } from '@sqlrooms/ui';
|
|
3
|
+
import { useCallback, useState } from 'react';
|
|
4
|
+
import { useValidateResultName } from '../useValidateResultName';
|
|
5
|
+
export const SqlCellResultNameEditor = ({ cellId, value, onChange }) => {
|
|
6
|
+
const [currentInput, setCurrentInput] = useState('');
|
|
7
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
8
|
+
const currentValue = isEditing ? currentInput.trim() : value;
|
|
9
|
+
// Get validation function from hook
|
|
10
|
+
const errorMessage = useValidateResultName(cellId, currentValue);
|
|
11
|
+
const handleInputChange = useCallback((newValue) => {
|
|
12
|
+
setCurrentInput(newValue);
|
|
13
|
+
}, []);
|
|
14
|
+
// Called on Enter or Blur - only commit if valid
|
|
15
|
+
const handleChange = useCallback((newValue) => {
|
|
16
|
+
if (!errorMessage && newValue !== value) {
|
|
17
|
+
// Valid and changed - commit to store
|
|
18
|
+
onChange(newValue);
|
|
19
|
+
}
|
|
20
|
+
// If invalid or unchanged - don't commit, EditableText will reset to value prop
|
|
21
|
+
}, [errorMessage, value, onChange]);
|
|
22
|
+
// Called when editing starts/ends (including Escape)
|
|
23
|
+
const handleEditingChange = useCallback((editing) => {
|
|
24
|
+
setIsEditing(editing);
|
|
25
|
+
if (editing) {
|
|
26
|
+
// Track what user is typing for validation
|
|
27
|
+
setCurrentInput(value);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Clear tracked input
|
|
31
|
+
setCurrentInput('');
|
|
32
|
+
}
|
|
33
|
+
}, [value]);
|
|
34
|
+
return (_jsxs(Tooltip, { open: Boolean(errorMessage), children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { children: _jsx(EditableText, { className: cn('h-6 w-40 font-mono text-xs text-green-500 shadow-none', {
|
|
35
|
+
'border-red-500 ring-1 ring-red-500 focus:border-red-500 focus:ring-red-500': Boolean(errorMessage),
|
|
36
|
+
}), value: value, onInputChange: handleInputChange, onChange: handleChange, onEditingChange: handleEditingChange }) }) }), _jsx(TooltipContent, { side: "top", children: errorMessage && _jsx("span", { className: "text-xs", children: errorMessage }) })] }));
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=SqlCellResultNameEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCellResultNameEditor.js","sourceRoot":"","sources":["../../src/components/SqlCellResultNameEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,EAAE,EACF,YAAY,EACZ,OAAO,EACP,cAAc,EACd,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAc,EAAC,WAAW,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,EAAC,qBAAqB,EAAC,MAAM,0BAA0B,CAAC;AAQ/D,MAAM,CAAC,MAAM,uBAAuB,GAEhC,CAAC,EAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAC,EAAE,EAAE;IAChC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAC7D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAE3D,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAE7D,oCAAoC;IACpC,MAAM,YAAY,GAAG,qBAAqB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAEjE,MAAM,iBAAiB,GAAG,WAAW,CAAC,CAAC,QAAgB,EAAE,EAAE;QACzD,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,iDAAiD;IACjD,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,QAAgB,EAAE,EAAE;QACnB,IAAI,CAAC,YAAY,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YACxC,sCAAsC;YACtC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QACD,gFAAgF;IAClF,CAAC,EACD,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAChC,CAAC;IAEF,qDAAqD;IACrD,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,OAAgB,EAAE,EAAE;QACnB,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,IAAI,OAAO,EAAE,CAAC;YACZ,2CAA2C;YAC3C,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,sBAAsB;YACtB,eAAe,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAC;IAEF,OAAO,CACL,MAAC,OAAO,IAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,aAClC,KAAC,cAAc,IAAC,OAAO,kBACrB,wBACE,KAAC,YAAY,IACX,SAAS,EAAE,EAAE,CACX,uDAAuD,EACvD;4BACE,4EAA4E,EAC1E,OAAO,CAAC,YAAY,CAAC;yBACxB,CACF,EACD,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,iBAAiB,EAChC,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,mBAAmB,GACpC,GACE,GACS,EACjB,KAAC,cAAc,IAAC,IAAI,EAAC,KAAK,YACvB,YAAY,IAAI,eAAM,SAAS,EAAC,SAAS,YAAE,YAAY,GAAQ,GACjD,IACT,CACX,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n cn,\n EditableText,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@sqlrooms/ui';\nimport React, {useCallback, useState} from 'react';\nimport {useValidateResultName} from '../useValidateResultName';\n\nexport type SqlCellResultNameEditorProps = {\n cellId: string;\n value: string;\n onChange: (value: string) => void;\n};\n\nexport const SqlCellResultNameEditor: React.FC<\n SqlCellResultNameEditorProps\n> = ({cellId, value, onChange}) => {\n const [currentInput, setCurrentInput] = useState<string>('');\n const [isEditing, setIsEditing] = useState<boolean>(false);\n\n const currentValue = isEditing ? currentInput.trim() : value;\n\n // Get validation function from hook\n const errorMessage = useValidateResultName(cellId, currentValue);\n\n const handleInputChange = useCallback((newValue: string) => {\n setCurrentInput(newValue);\n }, []);\n\n // Called on Enter or Blur - only commit if valid\n const handleChange = useCallback(\n (newValue: string) => {\n if (!errorMessage && newValue !== value) {\n // Valid and changed - commit to store\n onChange(newValue);\n }\n // If invalid or unchanged - don't commit, EditableText will reset to value prop\n },\n [errorMessage, value, onChange],\n );\n\n // Called when editing starts/ends (including Escape)\n const handleEditingChange = useCallback(\n (editing: boolean) => {\n setIsEditing(editing);\n if (editing) {\n // Track what user is typing for validation\n setCurrentInput(value);\n } else {\n // Clear tracked input\n setCurrentInput('');\n }\n },\n [value],\n );\n\n return (\n <Tooltip open={Boolean(errorMessage)}>\n <TooltipTrigger asChild>\n <div>\n <EditableText\n className={cn(\n 'h-6 w-40 font-mono text-xs text-green-500 shadow-none',\n {\n 'border-red-500 ring-1 ring-red-500 focus:border-red-500 focus:ring-red-500':\n Boolean(errorMessage),\n },\n )}\n value={value}\n onInputChange={handleInputChange}\n onChange={handleChange}\n onEditingChange={handleEditingChange}\n />\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n {errorMessage && <span className=\"text-xs\">{errorMessage}</span>}\n </TooltipContent>\n </Tooltip>\n );\n};\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PaginationState, SortingState } from '@tanstack/react-table';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { CellResultData } from '../types';
|
|
4
|
+
export interface SqlCellResultsProps {
|
|
5
|
+
cellId: string;
|
|
6
|
+
cellResult?: CellResultData | undefined;
|
|
7
|
+
resultName?: string;
|
|
8
|
+
isRunning?: boolean;
|
|
9
|
+
errorMessage?: string;
|
|
10
|
+
resultVersion: number;
|
|
11
|
+
fetchCellResultPage: (cellId: string, pagination: PaginationState, sorting: SortingState) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* SQL query results display with collapse/expand functionality
|
|
15
|
+
*/
|
|
16
|
+
export declare const SqlCellResults: React.FC<SqlCellResultsProps>;
|
|
17
|
+
//# sourceMappingURL=SqlCellResults.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { DataTablePaginated, QueryDataTableActionsMenu, useArrowDataTable, } from '@sqlrooms/data-table';
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { cn } from '@sqlrooms/ui';
|
|
5
|
+
import { CollapsibleSectionButton } from './CollapsibleSectionButton';
|
|
6
|
+
/**
|
|
7
|
+
* SQL query results display with collapse/expand functionality
|
|
8
|
+
*/
|
|
9
|
+
export const SqlCellResults = ({ cellId, cellResult, resultName, isRunning, errorMessage, resultVersion, fetchCellResultPage, }) => {
|
|
10
|
+
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
11
|
+
const arrowTableData = useArrowDataTable(cellResult?.arrowTable);
|
|
12
|
+
// Pagination and sorting state for the result table
|
|
13
|
+
const [sorting, setSorting] = useState([]);
|
|
14
|
+
const [pagination, setPagination] = useState({
|
|
15
|
+
pageIndex: 0,
|
|
16
|
+
pageSize: 10,
|
|
17
|
+
});
|
|
18
|
+
// Fetch new page when pagination or sorting changes (not on initial render
|
|
19
|
+
// since executeSqlCell already fetches the first page)
|
|
20
|
+
const isFirstRender = useRef(true);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (isFirstRender.current) {
|
|
23
|
+
isFirstRender.current = false;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (resultName) {
|
|
27
|
+
fetchCellResultPage(cellId, pagination, sorting);
|
|
28
|
+
}
|
|
29
|
+
}, [pagination, sorting, cellId, fetchCellResultPage, resultName]);
|
|
30
|
+
// Reset pagination when a new result arrives (new run)
|
|
31
|
+
const prevResultVersion = useRef(resultVersion);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (resultVersion !== prevResultVersion.current) {
|
|
34
|
+
prevResultVersion.current = resultVersion;
|
|
35
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
36
|
+
setPagination((prev) => prev.pageIndex === 0 ? prev : { ...prev, pageIndex: 0 });
|
|
37
|
+
setSorting((prev) => (prev.length === 0 ? prev : []));
|
|
38
|
+
}
|
|
39
|
+
}, [resultVersion]);
|
|
40
|
+
if (!errorMessage && (!resultName || !arrowTableData)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return (_jsxs("div", { className: "group relative w-full", children: [_jsx(CollapsibleSectionButton, { isCollapsed: isCollapsed, onToggle: () => setIsCollapsed(!isCollapsed) }), isCollapsed ? (_jsx("div", { className: "ml-5 px-2 py-1 text-xs", children: errorMessage ? (_jsx("span", { className: "font-normal text-red-600", children: errorMessage })) : cellResult?.totalRows !== undefined ? (_jsxs("span", { className: "text-muted-foreground font-normal", children: [cellResult.totalRows.toLocaleString(), " rows"] })) : null })) : (_jsx(_Fragment, { children: errorMessage ? (_jsx("div", { className: "relative max-h-[400px] overflow-auto p-4", children: _jsx("span", { className: "font-mono text-xs whitespace-pre-wrap text-red-600", children: errorMessage }) })) : resultName && arrowTableData ? (_jsxs("div", { className: "relative min-h-[200px] overflow-hidden", children: [_jsx(DataTablePaginated, { className: "absolute inset-0 h-full w-full", fontSize: "text-xs", data: arrowTableData.data, columns: arrowTableData.columns, numRows: cellResult?.totalRows, pagination: pagination, onPaginationChange: setPagination, sorting: sorting, onSortingChange: setSorting, isFetching: isRunning, footerActions: _jsx(QueryDataTableActionsMenu, { query: `SELECT * FROM ${resultName}` }) }), _jsx("div", { "aria-hidden": !isRunning, className: cn('bg-background/45 pointer-events-none absolute inset-0 z-10 transition-opacity duration-200', isRunning ? 'animate-pulse opacity-100' : 'opacity-0') })] })) : null }))] }));
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=SqlCellResults.js.map
|
|
@@ -0,0 +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,17 +1,16 @@
|
|
|
1
|
+
import { type RunButtonProps } from '@sqlrooms/ui';
|
|
1
2
|
import { SqlCellRunStatus } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Props for the standalone run/cancel control used by SQL cells.
|
|
4
|
-
*/
|
|
5
3
|
type SqlCellRunButtonProps = {
|
|
6
4
|
onRun: () => void;
|
|
7
5
|
onCancel?: () => void;
|
|
8
6
|
status?: SqlCellRunStatus;
|
|
9
7
|
runLabel?: string;
|
|
10
8
|
disabled?: boolean;
|
|
11
|
-
}
|
|
9
|
+
} & Pick<RunButtonProps, 'variant' | 'cancelVariant' | 'className'>;
|
|
12
10
|
/**
|
|
13
|
-
* Renders the run/cancel control for a SQL cell
|
|
11
|
+
* Renders the run/cancel control for a SQL cell.
|
|
12
|
+
* Thin wrapper that maps {@link SqlCellRunStatus} to {@link RunQueryButton} state.
|
|
14
13
|
*/
|
|
15
|
-
export declare function SqlCellRunButton({ onRun, onCancel, status, runLabel, disabled, }: SqlCellRunButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function SqlCellRunButton({ onRun, onCancel, status, runLabel, disabled, ...rest }: SqlCellRunButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
16
15
|
export {};
|
|
17
16
|
//# sourceMappingURL=SqlCellRunButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlCellRunButton.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellRunButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SqlCellRunButton.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellRunButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,cAAc,EAAC,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAE1C,KAAK,qBAAqB,GAAG;IAC3B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,eAAe,GAAG,WAAW,CAAC,CAAC;AAEpE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,qBAAqB,2CAkBvB"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import {
|
|
3
|
-
import { Play } from 'lucide-react';
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { RunButton } from '@sqlrooms/ui';
|
|
4
3
|
/**
|
|
5
|
-
* Renders the run/cancel control for a SQL cell
|
|
4
|
+
* Renders the run/cancel control for a SQL cell.
|
|
5
|
+
* Thin wrapper that maps {@link SqlCellRunStatus} to {@link RunQueryButton} state.
|
|
6
6
|
*/
|
|
7
|
-
export function SqlCellRunButton({ onRun, onCancel, status, runLabel
|
|
8
|
-
const
|
|
9
|
-
|
|
7
|
+
export function SqlCellRunButton({ onRun, onCancel, status, runLabel, disabled, ...rest }) {
|
|
8
|
+
const state = status?.state === 'running'
|
|
9
|
+
? 'running'
|
|
10
|
+
: status?.state === 'cancel'
|
|
11
|
+
? 'cancelling'
|
|
12
|
+
: 'idle';
|
|
13
|
+
return (_jsx(RunButton, { state: state, onRun: onRun, onCancel: onCancel, runLabel: runLabel, disabled: disabled, ...rest }));
|
|
10
14
|
}
|
|
11
15
|
//# sourceMappingURL=SqlCellRunButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlCellRunButton.js","sourceRoot":"","sources":["../../src/components/SqlCellRunButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"SqlCellRunButton.js","sourceRoot":"","sources":["../../src/components/SqlCellRunButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,SAAS,EAAsB,MAAM,cAAc,CAAC;AAW5D;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,GAAG,IAAI,EACe;IACtB,MAAM,KAAK,GACT,MAAM,EAAE,KAAK,KAAK,SAAS;QACzB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,QAAQ;YAC1B,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,MAAM,CAAC;IAEf,OAAO,CACL,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,KACd,IAAI,GACR,CACH,CAAC;AACJ,CAAC","sourcesContent":["import {RunButton, type RunButtonProps} from '@sqlrooms/ui';\nimport {SqlCellRunStatus} from '../types';\n\ntype SqlCellRunButtonProps = {\n onRun: () => void;\n onCancel?: () => void;\n status?: SqlCellRunStatus;\n runLabel?: string;\n disabled?: boolean;\n} & Pick<RunButtonProps, 'variant' | 'cancelVariant' | 'className'>;\n\n/**\n * Renders the run/cancel control for a SQL cell.\n * Thin wrapper that maps {@link SqlCellRunStatus} to {@link RunQueryButton} state.\n */\nexport function SqlCellRunButton({\n onRun,\n onCancel,\n status,\n runLabel,\n disabled,\n ...rest\n}: SqlCellRunButtonProps) {\n const state =\n status?.state === 'running'\n ? 'running'\n : status?.state === 'cancel'\n ? 'cancelling'\n : 'idle';\n\n return (\n <RunButton\n state={state}\n onRun={onRun}\n onCancel={onCancel}\n runLabel={runLabel}\n disabled={disabled}\n {...rest}\n />\n );\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface SqlQueryPreviewProps {
|
|
3
|
+
sql: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Shows a preview of SQL code - displays first non-empty line with "..." if more lines exist
|
|
7
|
+
*/
|
|
8
|
+
export declare const SqlQueryPreview: React.FC<SqlQueryPreviewProps>;
|
|
9
|
+
//# sourceMappingURL=SqlQueryPreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlQueryPreview.d.ts","sourceRoot":"","sources":["../../src/components/SqlQueryPreview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAGrC,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAgB1D,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { getSqlQueryPreview } from '../utils';
|
|
4
|
+
/**
|
|
5
|
+
* Shows a preview of SQL code - displays first non-empty line with "..." if more lines exist
|
|
6
|
+
*/
|
|
7
|
+
export const SqlQueryPreview = ({ sql }) => {
|
|
8
|
+
const { firstLine, hasMoreLines } = useMemo(() => getSqlQueryPreview(sql), [sql]);
|
|
9
|
+
if (!firstLine) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { className: "truncate font-mono", children: firstLine }), hasMoreLines && _jsx("span", { className: "ml-1", children: "..." })] }));
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=SqlQueryPreview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlQueryPreview.js","sourceRoot":"","sources":["../../src/components/SqlQueryPreview.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,EAAC,kBAAkB,EAAC,MAAM,UAAU,CAAC;AAM5C;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAmC,CAAC,EAAC,GAAG,EAAC,EAAE,EAAE;IACvE,MAAM,EAAC,SAAS,EAAE,YAAY,EAAC,GAAG,OAAO,CACvC,GAAG,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAC7B,CAAC,GAAG,CAAC,CACN,CAAC;IAEF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,8BACE,eAAM,SAAS,EAAC,oBAAoB,YAAE,SAAS,GAAQ,EACtD,YAAY,IAAI,eAAM,SAAS,EAAC,MAAM,oBAAW,IACjD,CACJ,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import React, {useMemo} from 'react';\nimport {getSqlQueryPreview} from '../utils';\n\nexport interface SqlQueryPreviewProps {\n sql: string;\n}\n\n/**\n * Shows a preview of SQL code - displays first non-empty line with \"...\" if more lines exist\n */\nexport const SqlQueryPreview: React.FC<SqlQueryPreviewProps> = ({sql}) => {\n const {firstLine, hasMoreLines} = useMemo(\n () => getSqlQueryPreview(sql),\n [sql],\n );\n\n if (!firstLine) {\n return null;\n }\n\n return (\n <>\n <span className=\"truncate font-mono\">{firstLine}</span>\n {hasMoreLines && <span className=\"ml-1\">...</span>}\n </>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextCellContent.d.ts","sourceRoot":"","sources":["../../src/components/TextCellContent.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TextCellContent.d.ts","sourceRoot":"","sources":["../../src/components/TextCellContent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAKtE,OAAO,KAAK,EAAC,kBAAkB,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AAE3D,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,CAwE1D,CAAC"}
|
|
@@ -1,26 +1,43 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { produce } from 'immer';
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
4
|
import Markdown from 'react-markdown';
|
|
5
|
+
import remarkBreaks from 'remark-breaks';
|
|
4
6
|
import remarkGfm from 'remark-gfm';
|
|
5
|
-
import { Button } from '@sqlrooms/ui';
|
|
6
7
|
import { useCellsStore } from '../hooks';
|
|
7
|
-
import { produce } from 'immer';
|
|
8
8
|
export const TextCellContent = ({ id, cell, renderContainer, }) => {
|
|
9
9
|
const updateCell = useCellsStore((s) => s.cells.updateCell);
|
|
10
10
|
const [isEditing, setIsEditing] = useState(false);
|
|
11
11
|
const [draftText, setDraftText] = useState(cell.data.text);
|
|
12
|
+
const textareaRef = useRef(null);
|
|
12
13
|
const saveText = useCallback(() => {
|
|
13
|
-
updateCell(id, (
|
|
14
|
+
updateCell(id, (cell) => produce(cell, (draft) => {
|
|
14
15
|
if (draft.type === 'text') {
|
|
15
16
|
draft.data.text = draftText;
|
|
16
17
|
}
|
|
17
18
|
}));
|
|
18
19
|
setIsEditing(false);
|
|
19
20
|
}, [id, draftText, updateCell]);
|
|
20
|
-
const
|
|
21
|
-
|
|
21
|
+
const cancelEdit = useCallback(() => {
|
|
22
|
+
setDraftText(cell.data.text);
|
|
23
|
+
setIsEditing(false);
|
|
24
|
+
}, [cell.data.text]);
|
|
25
|
+
// Auto-resize textarea
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const textarea = textareaRef.current;
|
|
28
|
+
if (textarea && isEditing) {
|
|
29
|
+
textarea.style.height = 'auto';
|
|
30
|
+
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
31
|
+
}
|
|
32
|
+
}, [draftText, isEditing]);
|
|
33
|
+
const content = (_jsxs("div", { className: "flex flex-col divide-y dark:divide-gray-800", onDoubleClick: () => !isEditing && setIsEditing(true), children: [isEditing && (_jsx("textarea", { ref: textareaRef, className: "bg-accent w-full resize-none overflow-hidden p-3 text-sm leading-relaxed outline-none", value: draftText, onChange: (e) => setDraftText(e.target.value), placeholder: "Write text... (Markdown supported)", autoFocus: true, onBlur: saveText, rows: 1, onKeyDown: (e) => {
|
|
34
|
+
if (e.key === 'Escape') {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
cancelEdit();
|
|
37
|
+
}
|
|
38
|
+
} })), !isEditing && (_jsx("div", { className: "prose dark:prose-invert max-w-none flex-1 p-3 text-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm, remarkBreaks], children: cell.data.text || '_No content yet. Double click to edit._' }) }))] }));
|
|
22
39
|
return renderContainer({
|
|
23
|
-
|
|
40
|
+
showHeader: false,
|
|
24
41
|
content,
|
|
25
42
|
});
|
|
26
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextCellContent.js","sourceRoot":"","sources":["../../src/components/TextCellContent.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAC,
|
|
1
|
+
{"version":3,"file":"TextCellContent.js","sourceRoot":"","sources":["../../src/components/TextCellContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import {produce} from 'immer';\nimport React, {useCallback, useEffect, useRef, useState} from 'react';\nimport Markdown from 'react-markdown';\nimport remarkBreaks from 'remark-breaks';\nimport remarkGfm from 'remark-gfm';\nimport {useCellsStore} from '../hooks';\nimport type {CellContainerProps, TextCell} from '../types';\n\nexport type TextCellContentProps = {\n id: string;\n cell: TextCell;\n renderContainer: (props: CellContainerProps) => React.ReactElement;\n};\n\nexport const TextCellContent: React.FC<TextCellContentProps> = ({\n id,\n cell,\n renderContainer,\n}) => {\n const updateCell = useCellsStore((s) => s.cells.updateCell);\n const [isEditing, setIsEditing] = useState(false);\n const [draftText, setDraftText] = useState(cell.data.text);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const saveText = useCallback(() => {\n updateCell(id, (cell) =>\n produce(cell, (draft) => {\n if (draft.type === 'text') {\n draft.data.text = draftText;\n }\n }),\n );\n setIsEditing(false);\n }, [id, draftText, updateCell]);\n\n const cancelEdit = useCallback(() => {\n setDraftText(cell.data.text);\n setIsEditing(false);\n }, [cell.data.text]);\n\n // Auto-resize textarea\n useEffect(() => {\n const textarea = textareaRef.current;\n if (textarea && isEditing) {\n textarea.style.height = 'auto';\n textarea.style.height = `${textarea.scrollHeight}px`;\n }\n }, [draftText, isEditing]);\n\n const content = (\n <div\n className=\"flex flex-col divide-y dark:divide-gray-800\"\n onDoubleClick={() => !isEditing && setIsEditing(true)}\n >\n {isEditing && (\n <textarea\n ref={textareaRef}\n className=\"bg-accent w-full resize-none overflow-hidden p-3 text-sm leading-relaxed outline-none\"\n value={draftText}\n onChange={(e) => setDraftText(e.target.value)}\n placeholder=\"Write text... (Markdown supported)\"\n autoFocus\n onBlur={saveText}\n rows={1}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n cancelEdit();\n }\n }}\n />\n )}\n {!isEditing && (\n <div className=\"prose dark:prose-invert max-w-none flex-1 p-3 text-sm\">\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>\n {cell.data.text || '_No content yet. Double click to edit._'}\n </Markdown>\n </div>\n )}\n </div>\n );\n\n return renderContainer({\n showHeader: false,\n content,\n });\n};\n"]}
|