@sqlrooms/sql-editor 0.27.0 → 0.28.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/SqlEditor.js CHANGED
@@ -27,7 +27,7 @@ const SqlEditor = React.memo((props) => {
27
27
  const handleCreateTable = useCallback(() => {
28
28
  setCreateTableModalOpen(true);
29
29
  }, []);
30
- return (_jsxs("div", { className: "relative flex h-full w-full flex-col overflow-hidden", children: [_jsx(SqlEditorHeader, { title: "SQL Editor", showDocs: showDocs, documentationPanel: documentationPanel, onToggleDocs: handleToggleDocs }), _jsx("div", { className: "bg-muted h-full flex-grow", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: showDocs ? 70 : 100, children: _jsxs(ResizablePanelGroup, { direction: "vertical", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: 50, className: "flex flex-row", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", children: [_jsx(ResizablePanel, { defaultSize: 20, children: _jsx(TableStructurePanel, { schema: schema }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 80, children: _jsx(QueryEditorPanel, {}) })] }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 50, children: _jsx(QueryResultPanel, { onRowClick: queryResultProps?.onRowClick, onRowDoubleClick: queryResultProps?.onRowDoubleClick, renderActions: () => (_jsx("div", { className: "flex gap-2", children: _jsxs(Button, { size: "xs", onClick: handleCreateTable, children: [_jsx(PlusIcon, { className: "h-4 w-4" }), "New table"] }) })) }) })] }) }), showDocs && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 30, children: documentationPanel })] }))] }) }), _jsx(CreateTableModal, { query: lastQuery, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), allowMultipleStatements: true, showSchemaSelection: true })] }));
30
+ return (_jsxs("div", { className: "relative flex h-full w-full flex-col overflow-hidden", children: [_jsx(SqlEditorHeader, { title: "SQL Editor", showDocs: showDocs, documentationPanel: documentationPanel, onToggleDocs: handleToggleDocs }), _jsx("div", { className: "bg-muted h-full grow", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: showDocs ? 70 : 100, children: _jsxs(ResizablePanelGroup, { direction: "vertical", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: 50, className: "flex flex-row", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", children: [_jsx(ResizablePanel, { defaultSize: 20, children: _jsx(TableStructurePanel, { schema: schema }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 80, children: _jsx(QueryEditorPanel, {}) })] }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 50, children: _jsx(QueryResultPanel, { onRowClick: queryResultProps?.onRowClick, onRowDoubleClick: queryResultProps?.onRowDoubleClick, renderActions: () => (_jsx("div", { className: "flex gap-2", children: _jsxs(Button, { size: "xs", onClick: handleCreateTable, children: [_jsx(PlusIcon, { className: "h-4 w-4" }), "New table"] }) })) }) })] }) }), showDocs && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 30, children: documentationPanel })] }))] }) }), _jsx(CreateTableModal, { query: lastQuery, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), allowMultipleStatements: true, showSchemaSelection: true })] }));
31
31
  });
32
32
  SqlEditor.displayName = 'SqlEditor';
33
33
  export default SqlEditor;
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@sqlrooms/ui';\nimport {PlusIcon} from 'lucide-react';\nimport React, {useCallback, useState} from 'react';\nimport CreateTableModal from './components/CreateTableModal';\nimport {QueryEditorPanel} from './components/QueryEditorPanel';\nimport {QueryResultPanel} from './components/QueryResultPanel';\nimport {SqlEditorHeader} from './components/SqlEditorHeader';\nimport {\n TableStructurePanel,\n TableStructurePanelProps,\n} from './components/TableStructurePanel';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\n\nexport type SqlEditorProps = {\n /** The database schema to use. Defaults to '*'.\n * If '*' is provided, all tables will be shown.\n * If a function is provided, it will be used to filter the tables. */\n schema?: TableStructurePanelProps['schema'];\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n /**\n * Props forwarded to `QueryResultPanel` to configure result behavior.\n * This provides a single entry point for table interactions.\n */\n queryResultProps?: Pick<\n React.ComponentProps<typeof QueryResultPanel>,\n 'onRowClick' | 'onRowDoubleClick'\n >;\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\nconst SqlEditor = React.memo<SqlEditorProps>((props) => {\n const {schema = '*', documentationPanel, queryResultProps} = props;\n\n const lastQuery = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n const qr = s.sqlEditor.queryResultsById[selectedId];\n if (qr?.status === 'success' && qr?.type === 'select') return qr.query;\n return s.sqlEditor.getCurrentQuery();\n });\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n\n // Handlers\n const handleToggleDocs = useCallback((show: boolean) => {\n setShowDocs(show);\n }, []);\n\n const handleCreateTable = useCallback(() => {\n setCreateTableModalOpen(true);\n }, []);\n\n return (\n <div className=\"relative flex h-full w-full flex-col overflow-hidden\">\n <SqlEditorHeader\n title=\"SQL Editor\"\n showDocs={showDocs}\n documentationPanel={documentationPanel}\n onToggleDocs={handleToggleDocs}\n />\n <div className=\"bg-muted h-full flex-grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n <ResizablePanel defaultSize={showDocs ? 70 : 100}>\n <ResizablePanelGroup direction=\"vertical\" className=\"h-full\">\n <ResizablePanel defaultSize={50} className=\"flex flex-row\">\n <ResizablePanelGroup direction=\"horizontal\">\n <ResizablePanel defaultSize={20}>\n <TableStructurePanel schema={schema} />\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={80}>\n <QueryEditorPanel />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={50}>\n <QueryResultPanel\n onRowClick={queryResultProps?.onRowClick}\n onRowDoubleClick={queryResultProps?.onRowDoubleClick}\n renderActions={() => (\n <div className=\"flex gap-2\">\n <Button size=\"xs\" onClick={handleCreateTable}>\n <PlusIcon className=\"h-4 w-4\" />\n New table\n </Button>\n </div>\n )}\n />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastQuery}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n allowMultipleStatements={true}\n showSchemaSelection={true}\n />\n </div>\n );\n});\nSqlEditor.displayName = 'SqlEditor';\n\nexport default SqlEditor;\n"]}
1
+ {"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@sqlrooms/ui';\nimport {PlusIcon} from 'lucide-react';\nimport React, {useCallback, useState} from 'react';\nimport CreateTableModal from './components/CreateTableModal';\nimport {QueryEditorPanel} from './components/QueryEditorPanel';\nimport {QueryResultPanel} from './components/QueryResultPanel';\nimport {SqlEditorHeader} from './components/SqlEditorHeader';\nimport {\n TableStructurePanel,\n TableStructurePanelProps,\n} from './components/TableStructurePanel';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\n\nexport type SqlEditorProps = {\n /** The database schema to use. Defaults to '*'.\n * If '*' is provided, all tables will be shown.\n * If a function is provided, it will be used to filter the tables. */\n schema?: TableStructurePanelProps['schema'];\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n /**\n * Props forwarded to `QueryResultPanel` to configure result behavior.\n * This provides a single entry point for table interactions.\n */\n queryResultProps?: Pick<\n React.ComponentProps<typeof QueryResultPanel>,\n 'onRowClick' | 'onRowDoubleClick'\n >;\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\nconst SqlEditor = React.memo<SqlEditorProps>((props) => {\n const {schema = '*', documentationPanel, queryResultProps} = props;\n\n const lastQuery = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n const qr = s.sqlEditor.queryResultsById[selectedId];\n if (qr?.status === 'success' && qr?.type === 'select') return qr.query;\n return s.sqlEditor.getCurrentQuery();\n });\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n\n // Handlers\n const handleToggleDocs = useCallback((show: boolean) => {\n setShowDocs(show);\n }, []);\n\n const handleCreateTable = useCallback(() => {\n setCreateTableModalOpen(true);\n }, []);\n\n return (\n <div className=\"relative flex h-full w-full flex-col overflow-hidden\">\n <SqlEditorHeader\n title=\"SQL Editor\"\n showDocs={showDocs}\n documentationPanel={documentationPanel}\n onToggleDocs={handleToggleDocs}\n />\n <div className=\"bg-muted h-full grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n <ResizablePanel defaultSize={showDocs ? 70 : 100}>\n <ResizablePanelGroup direction=\"vertical\" className=\"h-full\">\n <ResizablePanel defaultSize={50} className=\"flex flex-row\">\n <ResizablePanelGroup direction=\"horizontal\">\n <ResizablePanel defaultSize={20}>\n <TableStructurePanel schema={schema} />\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={80}>\n <QueryEditorPanel />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={50}>\n <QueryResultPanel\n onRowClick={queryResultProps?.onRowClick}\n onRowDoubleClick={queryResultProps?.onRowDoubleClick}\n renderActions={() => (\n <div className=\"flex gap-2\">\n <Button size=\"xs\" onClick={handleCreateTable}>\n <PlusIcon className=\"h-4 w-4\" />\n New table\n </Button>\n </div>\n )}\n />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastQuery}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n allowMultipleStatements={true}\n showSchemaSelection={true}\n />\n </div>\n );\n});\nSqlEditor.displayName = 'SqlEditor';\n\nexport default SqlEditor;\n"]}
@@ -39,7 +39,7 @@ const SqlEditorModal = (props) => {
39
39
  if (!open)
40
40
  onClose();
41
41
  }, [onClose]);
42
- return (_jsxs(Dialog, { open: isOpen, onOpenChange: handleOpenChange, children: [_jsx(DialogOverlay, { className: "bg-background/80" }), _jsxs(DialogContent, { className: "h-[100vh] max-h-[100vh] w-[100vw] max-w-[100vw] p-3", children: [_jsxs(DialogHeader, { className: "sr-only", children: [_jsx(DialogTitle, { children: "SQL Editor" }), _jsx(DialogDescription, { children: "SQL editor for querying and managing database tables" })] }), _jsx(Suspense, { fallback: _jsx(SpinnerPane, { h: "100%" }), children: _jsx(SqlEditor, { ...props }) })] })] }));
42
+ return (_jsxs(Dialog, { open: isOpen, onOpenChange: handleOpenChange, children: [_jsx(DialogOverlay, { className: "bg-background/80" }), _jsxs(DialogContent, { className: "h-screen max-h-screen w-screen max-w-[100vw] p-3", children: [_jsxs(DialogHeader, { className: "sr-only", children: [_jsx(DialogTitle, { children: "SQL Editor" }), _jsx(DialogDescription, { children: "SQL editor for querying and managing database tables" })] }), _jsx(Suspense, { fallback: _jsx(SpinnerPane, { h: "100%" }), children: _jsx(SqlEditor, { ...props }) })] })] }));
43
43
  };
44
44
  export default SqlEditorModal;
45
45
  //# sourceMappingURL=SqlEditorModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditorModal.js","sourceRoot":"","sources":["../src/SqlEditorModal.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EACL,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAc,EAAC,QAAQ,EAAE,WAAW,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,SAA2B,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,cAAc,GAA6B,CAAC,KAAK,EAAE,EAAE;IACzD,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,KAAK,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,IAAa,EAAE,EAAE;QAChB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;IACvB,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,CACL,MAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,aAClD,KAAC,aAAa,IAAC,SAAS,EAAC,kBAAkB,GAAG,EAC9C,MAAC,aAAa,IAAC,SAAS,EAAC,qDAAqD,aAC5E,MAAC,YAAY,IAAC,SAAS,EAAC,SAAS,aAC/B,KAAC,WAAW,6BAAyB,EACrC,KAAC,iBAAiB,uEAEE,IACP,EACf,KAAC,QAAQ,IAAC,QAAQ,EAAE,KAAC,WAAW,IAAC,CAAC,EAAC,MAAM,GAAG,YAC1C,KAAC,SAAS,OAAK,KAAK,GAAI,GACf,IACG,IACT,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["'use client';\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogOverlay,\n DialogTitle,\n SpinnerPane,\n} from '@sqlrooms/ui';\nimport React, {Suspense, useCallback} from 'react';\nimport SqlEditor, {SqlEditorProps} from './SqlEditor';\n\n/**\n * A modal wrapper for the SQL Editor component that provides a full-screen dialog interface.\n *\n * This component wraps the main SqlEditor component in a modal dialog, making it suitable for\n * overlay/popup usage scenarios. It inherits all props from SqlEditorProps and handles the\n * modal-specific behavior.\n *\n * @example\n * ```tsx\n * <SqlEditorModal\n * isOpen={true}\n * onClose={() => setIsOpen(false)}\n * sqlEditorConfig={config}\n * onChange={handleConfigChange}\n * />\n * ```\n *\n * @see {@link SqlEditor} for detailed documentation of all available props\n *\n * @see {@link SqlEditorProps}\n * The component accepts all props from SqlEditorProps:\n * - `isOpen` - Whether the SQL editor modal is currently visible\n * - `onClose` - Callback fired when the modal should be closed\n * - `sqlEditorConfig` - Configuration object containing queries and selected query state\n * - `onChange` - Callback fired when the SQL editor configuration changes\n * - `schema` - Optional database schema to use for queries (defaults to 'main')\n * - `documentationPanel` - Optional component to render SQL documentation in the side panel\n * - `onAddOrUpdateSqlQuery` - Callback fired when a new table should be created from query results\n */\nconst SqlEditorModal: React.FC<SqlEditorProps> = (props) => {\n const {isOpen, onClose} = props;\n\n // Memoize the handler to prevent re-renders\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) onClose();\n },\n [onClose],\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={handleOpenChange}>\n <DialogOverlay className=\"bg-background/80\" />\n <DialogContent className=\"h-[100vh] max-h-[100vh] w-[100vw] max-w-[100vw] p-3\">\n <DialogHeader className=\"sr-only\">\n <DialogTitle>SQL Editor</DialogTitle>\n <DialogDescription>\n SQL editor for querying and managing database tables\n </DialogDescription>\n </DialogHeader>\n <Suspense fallback={<SpinnerPane h=\"100%\" />}>\n <SqlEditor {...props} />\n </Suspense>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default SqlEditorModal;\n"]}
1
+ {"version":3,"file":"SqlEditorModal.js","sourceRoot":"","sources":["../src/SqlEditorModal.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EACL,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAc,EAAC,QAAQ,EAAE,WAAW,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,SAA2B,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,cAAc,GAA6B,CAAC,KAAK,EAAE,EAAE;IACzD,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,KAAK,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,IAAa,EAAE,EAAE;QAChB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;IACvB,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,CACL,MAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,aAClD,KAAC,aAAa,IAAC,SAAS,EAAC,kBAAkB,GAAG,EAC9C,MAAC,aAAa,IAAC,SAAS,EAAC,kDAAkD,aACzE,MAAC,YAAY,IAAC,SAAS,EAAC,SAAS,aAC/B,KAAC,WAAW,6BAAyB,EACrC,KAAC,iBAAiB,uEAEE,IACP,EACf,KAAC,QAAQ,IAAC,QAAQ,EAAE,KAAC,WAAW,IAAC,CAAC,EAAC,MAAM,GAAG,YAC1C,KAAC,SAAS,OAAK,KAAK,GAAI,GACf,IACG,IACT,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["'use client';\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogOverlay,\n DialogTitle,\n SpinnerPane,\n} from '@sqlrooms/ui';\nimport React, {Suspense, useCallback} from 'react';\nimport SqlEditor, {SqlEditorProps} from './SqlEditor';\n\n/**\n * A modal wrapper for the SQL Editor component that provides a full-screen dialog interface.\n *\n * This component wraps the main SqlEditor component in a modal dialog, making it suitable for\n * overlay/popup usage scenarios. It inherits all props from SqlEditorProps and handles the\n * modal-specific behavior.\n *\n * @example\n * ```tsx\n * <SqlEditorModal\n * isOpen={true}\n * onClose={() => setIsOpen(false)}\n * sqlEditorConfig={config}\n * onChange={handleConfigChange}\n * />\n * ```\n *\n * @see {@link SqlEditor} for detailed documentation of all available props\n *\n * @see {@link SqlEditorProps}\n * The component accepts all props from SqlEditorProps:\n * - `isOpen` - Whether the SQL editor modal is currently visible\n * - `onClose` - Callback fired when the modal should be closed\n * - `sqlEditorConfig` - Configuration object containing queries and selected query state\n * - `onChange` - Callback fired when the SQL editor configuration changes\n * - `schema` - Optional database schema to use for queries (defaults to 'main')\n * - `documentationPanel` - Optional component to render SQL documentation in the side panel\n * - `onAddOrUpdateSqlQuery` - Callback fired when a new table should be created from query results\n */\nconst SqlEditorModal: React.FC<SqlEditorProps> = (props) => {\n const {isOpen, onClose} = props;\n\n // Memoize the handler to prevent re-renders\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) onClose();\n },\n [onClose],\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={handleOpenChange}>\n <DialogOverlay className=\"bg-background/80\" />\n <DialogContent className=\"h-screen max-h-screen w-screen max-w-[100vw] p-3\">\n <DialogHeader className=\"sr-only\">\n <DialogTitle>SQL Editor</DialogTitle>\n <DialogDescription>\n SQL editor for querying and managing database tables\n </DialogDescription>\n </DialogHeader>\n <Suspense fallback={<SpinnerPane h=\"100%\" />}>\n <SqlEditor {...props} />\n </Suspense>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default SqlEditorModal;\n"]}
@@ -162,7 +162,7 @@ const CreateTableForm = ({ query, onClose, onRequestClose, editDataSource, allow
162
162
  ? 'Create view from query'
163
163
  : 'Create table from query' }), !editDataSource && (_jsx(DialogDescription, { children: watchView
164
164
  ? 'Create a new view from an SQL query.'
165
- : 'Create a new table from the results of an SQL query.' }))] }), form.formState.errors.root && (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { className: "whitespace-pre-wrap font-mono text-xs", children: form.formState.errors.root.message }) })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(FormField, { control: form.control, name: "tableName", render: ({ field }) => (_jsxs(FormItem, { className: "min-w-0 flex-[2]", children: [_jsx(FormLabel, { className: "text-xs", children: watchView ? 'View name' : 'Table name' }), _jsx(FormControl, { children: _jsx(Input, { ...field, className: "h-9 font-mono text-xs", autoFocus: true, disabled: isSubmitting }) }), _jsx(FormMessage, { className: "text-xs" })] })) }), showSchemaSelection && (_jsxs(_Fragment, { children: [_jsx(FormField, { control: form.control, name: "schema", render: ({ field }) => (_jsxs(FormItem, { className: "min-w-0 flex-1", children: [_jsx(FormLabel, { className: "text-xs", children: "Schema" }), _jsx(FormControl, { children: _jsx(SchemaCombobox, { value: field.value, onChange: field.onChange, options: schemas, placeholder: "Schema...", searchPlaceholder: "Search...", emptyMessage: "No schemas.", disabled: isSubmitting }) })] })) }), (databases.length > 1 || watchTemp) && (_jsx(FormField, { control: form.control, name: "database", render: ({ field }) => (_jsxs(FormItem, { className: "min-w-0 flex-1", children: [_jsx(FormLabel, { className: "text-xs", children: "Database" }), _jsx(FormControl, { children: _jsx(SchemaCombobox, { value: watchTemp ? 'temp' : field.value, onChange: field.onChange, options: databases, placeholder: "Database...", searchPlaceholder: "Search...", emptyMessage: "No databases.", disabled: isSubmitting || watchTemp }) })] })) }))] }))] }), _jsx(FormField, { control: form.control, name: "query", render: ({ field }) => (_jsxs(FormItem, { className: "relative flex h-[200px] flex-col", children: [_jsx(FormControl, { children: _jsx(SqlMonacoEditor, { connector: connector, value: field.value, onChange: field.onChange, className: "absolute inset-0 h-full w-full", options: {
165
+ : 'Create a new table from the results of an SQL query.' }))] }), form.formState.errors.root && (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { className: "font-mono text-xs whitespace-pre-wrap", children: form.formState.errors.root.message }) })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(FormField, { control: form.control, name: "tableName", render: ({ field }) => (_jsxs(FormItem, { className: "min-w-0 flex-2", children: [_jsx(FormLabel, { className: "text-xs", children: watchView ? 'View name' : 'Table name' }), _jsx(FormControl, { children: _jsx(Input, { ...field, className: "h-9 font-mono text-xs", autoFocus: true, disabled: isSubmitting }) }), _jsx(FormMessage, { className: "text-xs" })] })) }), showSchemaSelection && (_jsxs(_Fragment, { children: [_jsx(FormField, { control: form.control, name: "schema", render: ({ field }) => (_jsxs(FormItem, { className: "min-w-0 flex-1", children: [_jsx(FormLabel, { className: "text-xs", children: "Schema" }), _jsx(FormControl, { children: _jsx(SchemaCombobox, { value: field.value, onChange: field.onChange, options: schemas, placeholder: "Schema...", searchPlaceholder: "Search...", emptyMessage: "No schemas.", disabled: isSubmitting }) })] })) }), (databases.length > 1 || watchTemp) && (_jsx(FormField, { control: form.control, name: "database", render: ({ field }) => (_jsxs(FormItem, { className: "min-w-0 flex-1", children: [_jsx(FormLabel, { className: "text-xs", children: "Database" }), _jsx(FormControl, { children: _jsx(SchemaCombobox, { value: watchTemp ? 'temp' : field.value, onChange: field.onChange, options: databases, placeholder: "Database...", searchPlaceholder: "Search...", emptyMessage: "No databases.", disabled: isSubmitting || watchTemp }) })] })) }))] }))] }), _jsx(FormField, { control: form.control, name: "query", render: ({ field }) => (_jsxs(FormItem, { className: "relative flex h-[200px] flex-col", children: [_jsx(FormControl, { children: _jsx(SqlMonacoEditor, { connector: connector, value: field.value, onChange: field.onChange, className: "absolute inset-0 h-full w-full", options: {
166
166
  scrollBeyondLastLine: false,
167
167
  automaticLayout: true,
168
168
  minimap: { enabled: false },
@@ -1 +1 @@
1
- {"version":3,"file":"CreateTableModal.js","sourceRoot":"","sources":["../../src/components/CreateTableModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import {zodResolver} from '@hookform/resolvers/zod';\nimport {makeQualifiedTableName} from '@sqlrooms/duckdb';\nimport {SqlQueryDataSource} from '@sqlrooms/room-shell';\nimport {\n Alert,\n AlertDescription,\n Button,\n Checkbox,\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n Label,\n Popover,\n PopoverContent,\n PopoverTrigger,\n Spinner,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n cn,\n} from '@sqlrooms/ui';\nimport {Check, ChevronsUpDown, HelpCircle} from 'lucide-react';\nimport {FC, useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useForm} from 'react-hook-form';\nimport * as z from 'zod';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {SqlMonacoEditor} from '../SqlMonacoEditor';\n\nconst VALID_TABLE_OR_COLUMN_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;\n\nconst formSchema = z.object({\n tableName: z\n .string()\n .min(1, 'Table name is required')\n .regex(\n VALID_TABLE_OR_COLUMN_REGEX,\n 'Only letters, digits and underscores are allowed; should not start with a digit',\n ),\n query: z.string().min(1, 'Query is required'),\n schema: z.string().optional(),\n database: z.string().optional(),\n replace: z.boolean(),\n temp: z.boolean(),\n view: z.boolean(),\n});\n\ntype FormValues = z.infer<typeof formSchema>;\n\n/**\n * Initial values for the create table form.\n */\nexport type CreateTableFormInitialValues = Partial<{\n tableName: string;\n replace: boolean;\n temp: boolean;\n view: boolean;\n schema: string;\n database: string;\n}>;\n\nexport type CreateTableModalProps = {\n query: string;\n isOpen: boolean;\n onClose: () => void;\n editDataSource?: SqlQueryDataSource;\n /**\n * Allow multiple statements in the query. When true, preceding statements\n * will be executed before the final SELECT is wrapped in CREATE TABLE/VIEW.\n */\n allowMultipleStatements?: boolean;\n /**\n * Show schema/database selection UI.\n * @default false\n */\n showSchemaSelection?: boolean;\n /**\n * @deprecated Use createTableFromQuery directly instead.\n * When not provided, the modal will call createTableFromQuery directly.\n */\n onAddOrUpdateSqlQuery?: (\n tableName: string,\n query: string,\n oldTableName?: string,\n abortSignal?: AbortSignal,\n ) => Promise<void>;\n /**\n * Additional class name for the dialog content.\n */\n className?: string;\n /**\n * Initial values for the form fields.\n */\n initialValues?: CreateTableFormInitialValues;\n};\n\ntype CreateTableFormProps = {\n query: string;\n onClose: () => void;\n onRequestClose: () => void;\n editDataSource?: SqlQueryDataSource;\n allowMultipleStatements?: boolean;\n showSchemaSelection?: boolean;\n onAddOrUpdateSqlQuery?: (\n tableName: string,\n query: string,\n oldTableName?: string,\n abortSignal?: AbortSignal,\n ) => Promise<void>;\n initialValues?: CreateTableFormInitialValues;\n onSubmittingChange?: (isSubmitting: boolean) => void;\n onRegisterCancel?: (cancel: () => void) => void;\n};\n\nconst isAbortError = (err: unknown): boolean => {\n if (err instanceof DOMException) {\n return err.name === 'AbortError';\n }\n if (err instanceof Error) {\n return err.name === 'AbortError' || /cancelled|canceled/i.test(err.message);\n }\n return false;\n};\n\n/**\n * Compact searchable combobox for selecting schema or database.\n */\nconst SchemaCombobox: FC<{\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n options: string[];\n placeholder: string;\n searchPlaceholder: string;\n emptyMessage: string;\n disabled?: boolean;\n}> = ({\n value,\n onChange,\n options,\n placeholder,\n searchPlaceholder,\n emptyMessage,\n disabled,\n}) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"h-9 w-full min-w-0 justify-between font-mono text-xs\"\n disabled={disabled}\n >\n <span className=\"min-w-0 truncate\">{value || placeholder}</span>\n <ChevronsUpDown className=\"ml-1 h-3 w-3 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[180px] p-0\">\n <Command>\n <CommandInput placeholder={searchPlaceholder} className=\"text-xs\" />\n <CommandList>\n <CommandEmpty className=\"text-xs\">{emptyMessage}</CommandEmpty>\n <CommandGroup>\n {options.map((option) => (\n <CommandItem\n key={option}\n value={option}\n className=\"text-xs\"\n onSelect={(currentValue) => {\n onChange(currentValue === value ? undefined : currentValue);\n setOpen(false);\n }}\n >\n <Check\n className={cn(\n 'mr-2 h-3 w-3',\n value === option ? 'opacity-100' : 'opacity-0',\n )}\n />\n {option}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n};\n\n/**\n * Compact checkbox option with clickable label and tooltip.\n */\nconst OptionCheckbox: FC<{\n id: string;\n label: string;\n tooltip: string;\n checked: boolean;\n onCheckedChange: (checked: boolean) => void;\n disabled?: boolean;\n}> = ({id, label, tooltip, checked, onCheckedChange, disabled}) => (\n <div className=\"flex items-center gap-1.5\">\n <Checkbox\n id={id}\n checked={checked}\n onCheckedChange={onCheckedChange}\n disabled={disabled}\n className=\"h-3.5 w-3.5\"\n />\n <Label\n htmlFor={id}\n className={cn(\n 'cursor-pointer text-xs font-normal',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n >\n {label}\n </Label>\n <Tooltip>\n <TooltipTrigger asChild>\n <HelpCircle className=\"text-muted-foreground h-3 w-3 cursor-help\" />\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-[200px] text-xs\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n </div>\n);\n\nconst CreateTableForm: FC<CreateTableFormProps> = ({\n query,\n onClose,\n onRequestClose,\n editDataSource,\n allowMultipleStatements = false,\n showSchemaSelection = false,\n onAddOrUpdateSqlQuery,\n initialValues,\n onSubmittingChange,\n onRegisterCancel,\n}) => {\n const connector = useStoreWithSqlEditor((state) => state.db.connector);\n const createTableFromQuery = useStoreWithSqlEditor(\n (state) => state.db.createTableFromQuery,\n );\n const refreshTableSchemas = useStoreWithSqlEditor(\n (state) => state.db.refreshTableSchemas,\n );\n const tables = useStoreWithSqlEditor((state) => state.db.tables);\n const currentSchema = useStoreWithSqlEditor(\n (state) => state.db.currentSchema,\n );\n const currentDatabase = useStoreWithSqlEditor(\n (state) => state.db.currentDatabase,\n );\n\n // Extract unique schemas and databases from tables (excluding system ones)\n const {schemas, databases} = useMemo(() => {\n const schemaSet = new Set<string>();\n const databaseSet = new Set<string>();\n\n for (const table of tables) {\n if (table.table.schema && !table.table.schema.startsWith('pg_')) {\n schemaSet.add(table.table.schema);\n }\n if (table.table.database) {\n databaseSet.add(table.table.database);\n }\n }\n\n // Ensure current schema/database are included\n if (currentSchema) schemaSet.add(currentSchema);\n if (currentDatabase) databaseSet.add(currentDatabase);\n\n return {\n schemas: Array.from(schemaSet).sort(),\n databases: Array.from(databaseSet).sort(),\n };\n }, [tables, currentSchema, currentDatabase]);\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema as any),\n defaultValues: {\n tableName: editDataSource?.tableName ?? initialValues?.tableName ?? '',\n query: editDataSource?.sqlQuery ?? query.trim(),\n schema: initialValues?.schema ?? currentSchema,\n database: initialValues?.database ?? currentDatabase,\n replace: initialValues?.replace ?? false,\n temp: initialValues?.temp ?? false,\n view: initialValues?.view ?? false,\n },\n });\n\n const isSubmitting = form.formState.isSubmitting;\n const [isCancelling, setIsCancelling] = useState(false);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n };\n }, []);\n useEffect(() => {\n onSubmittingChange?.(isSubmitting);\n }, [isSubmitting, onSubmittingChange]);\n\n const onSubmit = useCallback(\n async (values: FormValues) => {\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n setIsCancelling(false);\n try {\n const {tableName, query, schema, database, replace, temp, view} =\n values;\n\n if (onAddOrUpdateSqlQuery) {\n // Legacy path: use the callback\n await onAddOrUpdateSqlQuery(\n tableName,\n query,\n editDataSource?.tableName,\n abortController.signal,\n );\n } else {\n // New path: call createTableFromQuery directly\n const qualifiedName =\n schema || database\n ? makeQualifiedTableName({table: tableName, schema, database})\n : tableName;\n\n await createTableFromQuery(qualifiedName, query, {\n replace,\n temp,\n view,\n allowMultipleStatements,\n abortSignal: abortController.signal,\n });\n\n // Refresh table schemas to show the new table\n await refreshTableSchemas();\n }\n\n form.reset();\n onClose();\n } catch (err) {\n if (isAbortError(err)) {\n return;\n }\n form.setError('root', {type: 'manual', message: `${err}`});\n } finally {\n abortControllerRef.current = null;\n setIsCancelling(false);\n }\n },\n [\n onAddOrUpdateSqlQuery,\n editDataSource?.tableName,\n createTableFromQuery,\n allowMultipleStatements,\n refreshTableSchemas,\n onClose,\n form,\n ],\n );\n\n const watchView = form.watch('view');\n const watchTemp = form.watch('temp');\n const watchTableName = form.watch('tableName');\n\n const handleCancel = useCallback(async () => {\n if (abortControllerRef.current) {\n setIsCancelling(true);\n abortControllerRef.current.abort();\n }\n }, []);\n useEffect(() => {\n onRegisterCancel?.(handleCancel);\n }, [handleCancel, onRegisterCancel]);\n\n return (\n <TooltipProvider delayDuration={200}>\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {editDataSource\n ? 'Edit table query'\n : watchView\n ? 'Create view from query'\n : 'Create table from query'}\n </DialogTitle>\n {!editDataSource && (\n <DialogDescription>\n {watchView\n ? 'Create a new view from an SQL query.'\n : 'Create a new table from the results of an SQL query.'}\n </DialogDescription>\n )}\n </DialogHeader>\n\n {form.formState.errors.root && (\n <Alert variant=\"destructive\">\n <AlertDescription className=\"whitespace-pre-wrap font-mono text-xs\">\n {form.formState.errors.root.message}\n </AlertDescription>\n </Alert>\n )}\n\n {/* Table name, schema, database in single row */}\n <div className=\"flex items-start gap-3\">\n <FormField\n control={form.control}\n name=\"tableName\"\n render={({field}) => (\n <FormItem className=\"min-w-0 flex-[2]\">\n <FormLabel className=\"text-xs\">\n {watchView ? 'View name' : 'Table name'}\n </FormLabel>\n <FormControl>\n <Input\n {...field}\n className=\"h-9 font-mono text-xs\"\n autoFocus\n disabled={isSubmitting}\n />\n </FormControl>\n <FormMessage className=\"text-xs\" />\n </FormItem>\n )}\n />\n\n {showSchemaSelection && (\n <>\n <FormField\n control={form.control}\n name=\"schema\"\n render={({field}) => (\n <FormItem className=\"min-w-0 flex-1\">\n <FormLabel className=\"text-xs\">Schema</FormLabel>\n <FormControl>\n <SchemaCombobox\n value={field.value}\n onChange={field.onChange}\n options={schemas}\n placeholder=\"Schema...\"\n searchPlaceholder=\"Search...\"\n emptyMessage=\"No schemas.\"\n disabled={isSubmitting}\n />\n </FormControl>\n </FormItem>\n )}\n />\n\n {(databases.length > 1 || watchTemp) && (\n <FormField\n control={form.control}\n name=\"database\"\n render={({field}) => (\n <FormItem className=\"min-w-0 flex-1\">\n <FormLabel className=\"text-xs\">Database</FormLabel>\n <FormControl>\n <SchemaCombobox\n value={watchTemp ? 'temp' : field.value}\n onChange={field.onChange}\n options={databases}\n placeholder=\"Database...\"\n searchPlaceholder=\"Search...\"\n emptyMessage=\"No databases.\"\n disabled={isSubmitting || watchTemp}\n />\n </FormControl>\n </FormItem>\n )}\n />\n )}\n </>\n )}\n </div>\n\n <FormField\n control={form.control}\n name=\"query\"\n render={({field}) => (\n <FormItem className=\"relative flex h-[200px] flex-col\">\n <FormControl>\n <SqlMonacoEditor\n connector={connector}\n value={field.value}\n onChange={field.onChange}\n className=\"absolute inset-0 h-full w-full\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n folding: false,\n lineNumbers: 'off',\n readOnly: isSubmitting,\n fixedOverflowWidgets: false, // default true doesn't work well in a modal\n }}\n />\n </FormControl>\n <FormMessage className=\"text-xs\" />\n </FormItem>\n )}\n />\n\n {/* Compact options row */}\n {!onAddOrUpdateSqlQuery && (\n <div className=\"flex items-center gap-6 rounded-md border px-3 py-2\">\n <FormField\n control={form.control}\n name=\"view\"\n render={({field}) => (\n <OptionCheckbox\n id=\"create-table-view\"\n label=\"View\"\n tooltip=\"Create a view instead of a table. Views store the query, not the data.\"\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={isSubmitting}\n />\n )}\n />\n\n {/* <FormField\n control={form.control}\n name=\"temp\"\n render={({field}) => (\n <OptionCheckbox\n id=\"create-table-temp\"\n label=\"Temporary\"\n tooltip={`${watchView ? 'View' : 'Table'} will be deleted when the session ends.`}\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={isSubmitting}\n />\n )}\n /> */}\n\n <FormField\n control={form.control}\n name=\"replace\"\n render={({field}) => (\n <OptionCheckbox\n id=\"create-table-replace\"\n label=\"Overwrite\"\n tooltip={`Overwrite existing ${watchView ? 'view' : 'table'} with the same name if it exists.`}\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={isSubmitting}\n />\n )}\n />\n </div>\n )}\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onRequestClose}>\n Close\n </Button>\n <Button\n type={isSubmitting ? 'button' : 'submit'}\n onClick={isSubmitting ? handleCancel : undefined}\n disabled={isSubmitting ? isCancelling : !watchTableName?.trim()}\n >\n {isSubmitting && <Spinner className=\"mr-2\" />}\n {isSubmitting\n ? isCancelling\n ? 'Cancelling...'\n : 'Cancel'\n : editDataSource\n ? 'Update'\n : 'Create'}\n </Button>\n </DialogFooter>\n </form>\n </Form>\n </TooltipProvider>\n );\n};\n\nconst CreateTableModal: FC<CreateTableModalProps> = (props) => {\n const {\n isOpen,\n onClose,\n query,\n editDataSource,\n allowMultipleStatements,\n showSchemaSelection,\n onAddOrUpdateSqlQuery,\n className,\n initialValues,\n } = props;\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isConfirmOpen, setIsConfirmOpen] = useState(false);\n const cancelRef = useRef<(() => void) | null>(null);\n\n const resetState = useCallback(() => {\n setIsSubmitting(false);\n setIsConfirmOpen(false);\n cancelRef.current = null;\n }, []);\n\n const handleClose = useCallback(() => {\n resetState();\n onClose();\n }, [onClose, resetState]);\n\n const handleRequestClose = useCallback(() => {\n if (!isSubmitting) {\n handleClose();\n return;\n }\n setIsConfirmOpen(true);\n }, [handleClose, isSubmitting]);\n\n const handleConfirmClose = useCallback(() => {\n cancelRef.current?.();\n handleClose();\n }, [handleClose]);\n\n return (\n <Dialog\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) {\n handleRequestClose();\n }\n }}\n >\n <DialogContent className={cn('w-3xl max-w-[80%]', className)}>\n {isOpen && (\n <CreateTableForm\n query={query}\n onClose={handleClose}\n onRequestClose={handleRequestClose}\n editDataSource={editDataSource}\n allowMultipleStatements={allowMultipleStatements}\n showSchemaSelection={showSchemaSelection}\n onAddOrUpdateSqlQuery={onAddOrUpdateSqlQuery}\n initialValues={initialValues}\n onSubmittingChange={setIsSubmitting}\n onRegisterCancel={(cancel) => {\n cancelRef.current = cancel;\n }}\n />\n )}\n </DialogContent>\n <Dialog open={isConfirmOpen} onOpenChange={setIsConfirmOpen}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Cancel running query?</DialogTitle>\n <DialogDescription>\n A query is still running. Cancelling it will stop the query and\n close this dialog.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setIsConfirmOpen(false)}\n >\n Keep running\n </Button>\n <Button type=\"button\" onClick={handleConfirmClose}>\n Cancel & close\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </Dialog>\n );\n};\n\nexport default CreateTableModal;\n"]}
1
+ {"version":3,"file":"CreateTableModal.js","sourceRoot":"","sources":["../../src/components/CreateTableModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,MAAM,EACN,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,EACL,KAAK,EACL,OAAO,EACP,cAAc,EACd,cAAc,EACd,OAAO,EACP,OAAO,EACP,cAAc,EACd,eAAe,EACf,cAAc,EACd,EAAE,GACH,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,KAAK,EAAE,cAAc,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAK,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAC,qBAAqB,EAAC,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAEnD,MAAM,2BAA2B,GAAG,+BAA+B,CAAC;AAEpE,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;SAChC,KAAK,CACJ,2BAA2B,EAC3B,iFAAiF,CAClF;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;CAClB,CAAC,CAAC;AAqEH,MAAM,YAAY,GAAG,CAAC,GAAY,EAAW,EAAE;IAC7C,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;IACnC,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,cAAc,GAQf,CAAC,EACJ,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO,CACL,MAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,aACxC,KAAC,cAAc,IAAC,OAAO,kBACrB,MAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,UAAU,mBACA,IAAI,EACnB,SAAS,EAAC,sDAAsD,EAChE,QAAQ,EAAE,QAAQ,aAElB,eAAM,SAAS,EAAC,kBAAkB,YAAE,KAAK,IAAI,WAAW,GAAQ,EAChE,KAAC,cAAc,IAAC,SAAS,EAAC,kCAAkC,GAAG,IACxD,GACM,EACjB,KAAC,cAAc,IAAC,SAAS,EAAC,eAAe,YACvC,MAAC,OAAO,eACN,KAAC,YAAY,IAAC,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAC,SAAS,GAAG,EACpE,MAAC,WAAW,eACV,KAAC,YAAY,IAAC,SAAS,EAAC,SAAS,YAAE,YAAY,GAAgB,EAC/D,KAAC,YAAY,cACV,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,MAAC,WAAW,IAEV,KAAK,EAAE,MAAM,EACb,SAAS,EAAC,SAAS,EACnB,QAAQ,EAAE,CAAC,YAAY,EAAE,EAAE;4CACzB,QAAQ,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;4CAC5D,OAAO,CAAC,KAAK,CAAC,CAAC;wCACjB,CAAC,aAED,KAAC,KAAK,IACJ,SAAS,EAAE,EAAE,CACX,cAAc,EACd,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAC/C,GACD,EACD,MAAM,KAdF,MAAM,CAeC,CACf,CAAC,GACW,IACH,IACN,GACK,IACT,CACX,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,cAAc,GAOf,CAAC,EAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CACjE,eAAK,SAAS,EAAC,2BAA2B,aACxC,KAAC,QAAQ,IACP,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,aAAa,GACvB,EACF,KAAC,KAAK,IACJ,OAAO,EAAE,EAAE,EACX,SAAS,EAAE,EAAE,CACX,oCAAoC,EACpC,QAAQ,IAAI,+BAA+B,CAC5C,YAEA,KAAK,GACA,EACR,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBACrB,KAAC,UAAU,IAAC,SAAS,EAAC,2CAA2C,GAAG,GACrD,EACjB,KAAC,cAAc,IAAC,IAAI,EAAC,KAAK,EAAC,SAAS,EAAC,uBAAuB,YACzD,OAAO,GACO,IACT,IACN,CACP,CAAC;AAEF,MAAM,eAAe,GAA6B,CAAC,EACjD,KAAK,EACL,OAAO,EACP,cAAc,EACd,cAAc,EACd,uBAAuB,GAAG,KAAK,EAC/B,mBAAmB,GAAG,KAAK,EAC3B,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,GACjB,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,qBAAqB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,oBAAoB,GAAG,qBAAqB,CAChD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,CACzC,CAAC;IACF,MAAM,mBAAmB,GAAG,qBAAqB,CAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,CACxC,CAAC;IACF,MAAM,MAAM,GAAG,qBAAqB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,qBAAqB,CACzC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,CAClC,CAAC;IACF,MAAM,eAAe,GAAG,qBAAqB,CAC3C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,CACpC,CAAC;IAEF,2EAA2E;IAC3E,MAAM,EAAC,OAAO,EAAE,SAAS,EAAC,GAAG,OAAO,CAAC,GAAG,EAAE;QACxC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QACpC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;QAEtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChE,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACzB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,IAAI,aAAa;YAAE,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,eAAe;YAAE,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAEtD,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE;YACrC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE;SAC1C,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC;IAE7C,MAAM,IAAI,GAAG,OAAO,CAAa;QAC/B,QAAQ,EAAE,WAAW,CAAC,UAAiB,CAAC;QACxC,aAAa,EAAE;YACb,SAAS,EAAE,cAAc,EAAE,SAAS,IAAI,aAAa,EAAE,SAAS,IAAI,EAAE;YACtE,KAAK,EAAE,cAAc,EAAE,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE;YAC/C,MAAM,EAAE,aAAa,EAAE,MAAM,IAAI,aAAa;YAC9C,QAAQ,EAAE,aAAa,EAAE,QAAQ,IAAI,eAAe;YACpD,OAAO,EAAE,aAAa,EAAE,OAAO,IAAI,KAAK;YACxC,IAAI,EAAE,aAAa,EAAE,IAAI,IAAI,KAAK;YAClC,IAAI,EAAE,aAAa,EAAE,IAAI,IAAI,KAAK;SACnC;KACF,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;IACjD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,kBAAkB,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAC;IAEhE,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACpC,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAC;QACpC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,EAAE,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAEvC,MAAM,QAAQ,GAAG,WAAW,CAC1B,KAAK,EAAE,MAAkB,EAAE,EAAE;QAC3B,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,kBAAkB,CAAC,OAAO,GAAG,eAAe,CAAC;QAC7C,eAAe,CAAC,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,EAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAC,GAC7D,MAAM,CAAC;YAET,IAAI,qBAAqB,EAAE,CAAC;gBAC1B,gCAAgC;gBAChC,MAAM,qBAAqB,CACzB,SAAS,EACT,KAAK,EACL,cAAc,EAAE,SAAS,EACzB,eAAe,CAAC,MAAM,CACvB,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,+CAA+C;gBAC/C,MAAM,aAAa,GACjB,MAAM,IAAI,QAAQ;oBAChB,CAAC,CAAC,sBAAsB,CAAC,EAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC;oBAC9D,CAAC,CAAC,SAAS,CAAC;gBAEhB,MAAM,oBAAoB,CAAC,aAAa,EAAE,KAAK,EAAE;oBAC/C,OAAO;oBACP,IAAI;oBACJ,IAAI;oBACJ,uBAAuB;oBACvB,WAAW,EAAE,eAAe,CAAC,MAAM;iBACpC,CAAC,CAAC;gBAEH,8CAA8C;gBAC9C,MAAM,mBAAmB,EAAE,CAAC;YAC9B,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAC,CAAC,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAC;YAClC,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,EACD;QACE,qBAAqB;QACrB,cAAc,EAAE,SAAS;QACzB,oBAAoB;QACpB,uBAAuB;QACvB,mBAAmB;QACnB,OAAO;QACP,IAAI;KACL,CACF,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAE/C,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAC/B,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrC,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,EAAE,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAErC,OAAO,CACL,KAAC,eAAe,IAAC,aAAa,EAAE,GAAG,YACjC,KAAC,IAAI,OAAK,IAAI,YACZ,gBAAM,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAC,WAAW,aAChE,MAAC,YAAY,eACX,KAAC,WAAW,cACT,cAAc;oCACb,CAAC,CAAC,kBAAkB;oCACpB,CAAC,CAAC,SAAS;wCACT,CAAC,CAAC,wBAAwB;wCAC1B,CAAC,CAAC,yBAAyB,GACnB,EACb,CAAC,cAAc,IAAI,CAClB,KAAC,iBAAiB,cACf,SAAS;oCACR,CAAC,CAAC,sCAAsC;oCACxC,CAAC,CAAC,sDAAsD,GACxC,CACrB,IACY,EAEd,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAC7B,KAAC,KAAK,IAAC,OAAO,EAAC,aAAa,YAC1B,KAAC,gBAAgB,IAAC,SAAS,EAAC,uCAAuC,YAChE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAClB,GACb,CACT,EAGD,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,WAAW,EAChB,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,IAAC,SAAS,EAAC,gBAAgB,aAClC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,YAC3B,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,GAC7B,EACZ,KAAC,WAAW,cACV,KAAC,KAAK,OACA,KAAK,EACT,SAAS,EAAC,uBAAuB,EACjC,SAAS,QACT,QAAQ,EAAE,YAAY,GACtB,GACU,EACd,KAAC,WAAW,IAAC,SAAS,EAAC,SAAS,GAAG,IAC1B,CACZ,GACD,EAED,mBAAmB,IAAI,CACtB,8BACE,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,QAAQ,EACb,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,IAAC,SAAS,EAAC,gBAAgB,aAClC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,uBAAmB,EACjD,KAAC,WAAW,cACV,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAC,WAAW,EACvB,iBAAiB,EAAC,WAAW,EAC7B,YAAY,EAAC,aAAa,EAC1B,QAAQ,EAAE,YAAY,GACtB,GACU,IACL,CACZ,GACD,EAED,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,CACtC,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,UAAU,EACf,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,IAAC,SAAS,EAAC,gBAAgB,aAClC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,yBAAqB,EACnD,KAAC,WAAW,cACV,KAAC,cAAc,IACb,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EACvC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,OAAO,EAAE,SAAS,EAClB,WAAW,EAAC,aAAa,EACzB,iBAAiB,EAAC,WAAW,EAC7B,YAAY,EAAC,eAAe,EAC5B,QAAQ,EAAE,YAAY,IAAI,SAAS,GACnC,GACU,IACL,CACZ,GACD,CACH,IACA,CACJ,IACG,EAEN,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,OAAO,EACZ,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,IAAC,SAAS,EAAC,kCAAkC,aACpD,KAAC,WAAW,cACV,KAAC,eAAe,IACd,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,SAAS,EAAC,gCAAgC,EAC1C,OAAO,EAAE;4CACP,oBAAoB,EAAE,KAAK;4CAC3B,eAAe,EAAE,IAAI;4CACrB,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC;4CACzB,QAAQ,EAAE,IAAI;4CACd,OAAO,EAAE,KAAK;4CACd,WAAW,EAAE,KAAK;4CAClB,QAAQ,EAAE,YAAY;4CACtB,oBAAoB,EAAE,KAAK,EAAE,4CAA4C;yCAC1E,GACD,GACU,EACd,KAAC,WAAW,IAAC,SAAS,EAAC,SAAS,GAAG,IAC1B,CACZ,GACD,EAGD,CAAC,qBAAqB,IAAI,CACzB,eAAK,SAAS,EAAC,qDAAqD,aAClE,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,MAAM,EACX,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,KAAC,cAAc,IACb,EAAE,EAAC,mBAAmB,EACtB,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,wEAAwE,EAChF,OAAO,EAAE,KAAK,CAAC,KAAK,EACpB,eAAe,EAAE,KAAK,CAAC,QAAQ,EAC/B,QAAQ,EAAE,YAAY,GACtB,CACH,GACD,EAiBF,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,SAAS,EACd,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,KAAC,cAAc,IACb,EAAE,EAAC,sBAAsB,EACzB,KAAK,EAAC,WAAW,EACjB,OAAO,EAAE,sBAAsB,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,mCAAmC,EAC9F,OAAO,EAAE,KAAK,CAAC,KAAK,EACpB,eAAe,EAAE,KAAK,CAAC,QAAQ,EAC/B,QAAQ,EAAE,YAAY,GACtB,CACH,GACD,IACE,CACP,EAED,MAAC,YAAY,eACX,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,cAAc,sBAEtD,EACT,MAAC,MAAM,IACL,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EACxC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAChD,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,aAE9D,YAAY,IAAI,KAAC,OAAO,IAAC,SAAS,EAAC,MAAM,GAAG,EAC5C,YAAY;wCACX,CAAC,CAAC,YAAY;4CACZ,CAAC,CAAC,eAAe;4CACjB,CAAC,CAAC,QAAQ;wCACZ,CAAC,CAAC,cAAc;4CACd,CAAC,CAAC,QAAQ;4CACV,CAAC,CAAC,QAAQ,IACP,IACI,IACV,GACF,GACS,CACnB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAA8B,CAAC,KAAK,EAAE,EAAE;IAC5D,MAAM,EACJ,MAAM,EACN,OAAO,EACP,KAAK,EACL,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,EACT,aAAa,GACd,GAAG,KAAK,CAAC;IACV,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,eAAe,CAAC,KAAK,CAAC,CAAC;QACvB,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACxB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IAE1B,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,WAAW,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhC,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QACtB,WAAW,EAAE,CAAC;IAChB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,OAAO,CACL,MAAC,MAAM,IACL,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,kBAAkB,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,aAED,KAAC,aAAa,IAAC,SAAS,EAAE,EAAE,CAAC,mBAAmB,EAAE,SAAS,CAAC,YACzD,MAAM,IAAI,CACT,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,kBAAkB,EAClC,cAAc,EAAE,cAAc,EAC9B,uBAAuB,EAAE,uBAAuB,EAChD,mBAAmB,EAAE,mBAAmB,EACxC,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,eAAe,EACnC,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE;wBAC3B,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;oBAC7B,CAAC,GACD,CACH,GACa,EAChB,KAAC,MAAM,IAAC,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,YACzD,MAAC,aAAa,IAAC,SAAS,EAAC,UAAU,aACjC,MAAC,YAAY,eACX,KAAC,WAAW,wCAAoC,EAChD,KAAC,iBAAiB,qGAGE,IACP,EACf,MAAC,YAAY,eACX,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,6BAG/B,EACT,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,kBAAkB,+BAExC,IACI,IACD,GACT,IACF,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import {zodResolver} from '@hookform/resolvers/zod';\nimport {makeQualifiedTableName} from '@sqlrooms/duckdb';\nimport {SqlQueryDataSource} from '@sqlrooms/room-shell';\nimport {\n Alert,\n AlertDescription,\n Button,\n Checkbox,\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n Label,\n Popover,\n PopoverContent,\n PopoverTrigger,\n Spinner,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n cn,\n} from '@sqlrooms/ui';\nimport {Check, ChevronsUpDown, HelpCircle} from 'lucide-react';\nimport {FC, useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useForm} from 'react-hook-form';\nimport * as z from 'zod';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {SqlMonacoEditor} from '../SqlMonacoEditor';\n\nconst VALID_TABLE_OR_COLUMN_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;\n\nconst formSchema = z.object({\n tableName: z\n .string()\n .min(1, 'Table name is required')\n .regex(\n VALID_TABLE_OR_COLUMN_REGEX,\n 'Only letters, digits and underscores are allowed; should not start with a digit',\n ),\n query: z.string().min(1, 'Query is required'),\n schema: z.string().optional(),\n database: z.string().optional(),\n replace: z.boolean(),\n temp: z.boolean(),\n view: z.boolean(),\n});\n\ntype FormValues = z.infer<typeof formSchema>;\n\n/**\n * Initial values for the create table form.\n */\nexport type CreateTableFormInitialValues = Partial<{\n tableName: string;\n replace: boolean;\n temp: boolean;\n view: boolean;\n schema: string;\n database: string;\n}>;\n\nexport type CreateTableModalProps = {\n query: string;\n isOpen: boolean;\n onClose: () => void;\n editDataSource?: SqlQueryDataSource;\n /**\n * Allow multiple statements in the query. When true, preceding statements\n * will be executed before the final SELECT is wrapped in CREATE TABLE/VIEW.\n */\n allowMultipleStatements?: boolean;\n /**\n * Show schema/database selection UI.\n * @default false\n */\n showSchemaSelection?: boolean;\n /**\n * @deprecated Use createTableFromQuery directly instead.\n * When not provided, the modal will call createTableFromQuery directly.\n */\n onAddOrUpdateSqlQuery?: (\n tableName: string,\n query: string,\n oldTableName?: string,\n abortSignal?: AbortSignal,\n ) => Promise<void>;\n /**\n * Additional class name for the dialog content.\n */\n className?: string;\n /**\n * Initial values for the form fields.\n */\n initialValues?: CreateTableFormInitialValues;\n};\n\ntype CreateTableFormProps = {\n query: string;\n onClose: () => void;\n onRequestClose: () => void;\n editDataSource?: SqlQueryDataSource;\n allowMultipleStatements?: boolean;\n showSchemaSelection?: boolean;\n onAddOrUpdateSqlQuery?: (\n tableName: string,\n query: string,\n oldTableName?: string,\n abortSignal?: AbortSignal,\n ) => Promise<void>;\n initialValues?: CreateTableFormInitialValues;\n onSubmittingChange?: (isSubmitting: boolean) => void;\n onRegisterCancel?: (cancel: () => void) => void;\n};\n\nconst isAbortError = (err: unknown): boolean => {\n if (err instanceof DOMException) {\n return err.name === 'AbortError';\n }\n if (err instanceof Error) {\n return err.name === 'AbortError' || /cancelled|canceled/i.test(err.message);\n }\n return false;\n};\n\n/**\n * Compact searchable combobox for selecting schema or database.\n */\nconst SchemaCombobox: FC<{\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n options: string[];\n placeholder: string;\n searchPlaceholder: string;\n emptyMessage: string;\n disabled?: boolean;\n}> = ({\n value,\n onChange,\n options,\n placeholder,\n searchPlaceholder,\n emptyMessage,\n disabled,\n}) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"h-9 w-full min-w-0 justify-between font-mono text-xs\"\n disabled={disabled}\n >\n <span className=\"min-w-0 truncate\">{value || placeholder}</span>\n <ChevronsUpDown className=\"ml-1 h-3 w-3 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[180px] p-0\">\n <Command>\n <CommandInput placeholder={searchPlaceholder} className=\"text-xs\" />\n <CommandList>\n <CommandEmpty className=\"text-xs\">{emptyMessage}</CommandEmpty>\n <CommandGroup>\n {options.map((option) => (\n <CommandItem\n key={option}\n value={option}\n className=\"text-xs\"\n onSelect={(currentValue) => {\n onChange(currentValue === value ? undefined : currentValue);\n setOpen(false);\n }}\n >\n <Check\n className={cn(\n 'mr-2 h-3 w-3',\n value === option ? 'opacity-100' : 'opacity-0',\n )}\n />\n {option}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n};\n\n/**\n * Compact checkbox option with clickable label and tooltip.\n */\nconst OptionCheckbox: FC<{\n id: string;\n label: string;\n tooltip: string;\n checked: boolean;\n onCheckedChange: (checked: boolean) => void;\n disabled?: boolean;\n}> = ({id, label, tooltip, checked, onCheckedChange, disabled}) => (\n <div className=\"flex items-center gap-1.5\">\n <Checkbox\n id={id}\n checked={checked}\n onCheckedChange={onCheckedChange}\n disabled={disabled}\n className=\"h-3.5 w-3.5\"\n />\n <Label\n htmlFor={id}\n className={cn(\n 'cursor-pointer text-xs font-normal',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n >\n {label}\n </Label>\n <Tooltip>\n <TooltipTrigger asChild>\n <HelpCircle className=\"text-muted-foreground h-3 w-3 cursor-help\" />\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-[200px] text-xs\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n </div>\n);\n\nconst CreateTableForm: FC<CreateTableFormProps> = ({\n query,\n onClose,\n onRequestClose,\n editDataSource,\n allowMultipleStatements = false,\n showSchemaSelection = false,\n onAddOrUpdateSqlQuery,\n initialValues,\n onSubmittingChange,\n onRegisterCancel,\n}) => {\n const connector = useStoreWithSqlEditor((state) => state.db.connector);\n const createTableFromQuery = useStoreWithSqlEditor(\n (state) => state.db.createTableFromQuery,\n );\n const refreshTableSchemas = useStoreWithSqlEditor(\n (state) => state.db.refreshTableSchemas,\n );\n const tables = useStoreWithSqlEditor((state) => state.db.tables);\n const currentSchema = useStoreWithSqlEditor(\n (state) => state.db.currentSchema,\n );\n const currentDatabase = useStoreWithSqlEditor(\n (state) => state.db.currentDatabase,\n );\n\n // Extract unique schemas and databases from tables (excluding system ones)\n const {schemas, databases} = useMemo(() => {\n const schemaSet = new Set<string>();\n const databaseSet = new Set<string>();\n\n for (const table of tables) {\n if (table.table.schema && !table.table.schema.startsWith('pg_')) {\n schemaSet.add(table.table.schema);\n }\n if (table.table.database) {\n databaseSet.add(table.table.database);\n }\n }\n\n // Ensure current schema/database are included\n if (currentSchema) schemaSet.add(currentSchema);\n if (currentDatabase) databaseSet.add(currentDatabase);\n\n return {\n schemas: Array.from(schemaSet).sort(),\n databases: Array.from(databaseSet).sort(),\n };\n }, [tables, currentSchema, currentDatabase]);\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema as any),\n defaultValues: {\n tableName: editDataSource?.tableName ?? initialValues?.tableName ?? '',\n query: editDataSource?.sqlQuery ?? query.trim(),\n schema: initialValues?.schema ?? currentSchema,\n database: initialValues?.database ?? currentDatabase,\n replace: initialValues?.replace ?? false,\n temp: initialValues?.temp ?? false,\n view: initialValues?.view ?? false,\n },\n });\n\n const isSubmitting = form.formState.isSubmitting;\n const [isCancelling, setIsCancelling] = useState(false);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n };\n }, []);\n useEffect(() => {\n onSubmittingChange?.(isSubmitting);\n }, [isSubmitting, onSubmittingChange]);\n\n const onSubmit = useCallback(\n async (values: FormValues) => {\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n setIsCancelling(false);\n try {\n const {tableName, query, schema, database, replace, temp, view} =\n values;\n\n if (onAddOrUpdateSqlQuery) {\n // Legacy path: use the callback\n await onAddOrUpdateSqlQuery(\n tableName,\n query,\n editDataSource?.tableName,\n abortController.signal,\n );\n } else {\n // New path: call createTableFromQuery directly\n const qualifiedName =\n schema || database\n ? makeQualifiedTableName({table: tableName, schema, database})\n : tableName;\n\n await createTableFromQuery(qualifiedName, query, {\n replace,\n temp,\n view,\n allowMultipleStatements,\n abortSignal: abortController.signal,\n });\n\n // Refresh table schemas to show the new table\n await refreshTableSchemas();\n }\n\n form.reset();\n onClose();\n } catch (err) {\n if (isAbortError(err)) {\n return;\n }\n form.setError('root', {type: 'manual', message: `${err}`});\n } finally {\n abortControllerRef.current = null;\n setIsCancelling(false);\n }\n },\n [\n onAddOrUpdateSqlQuery,\n editDataSource?.tableName,\n createTableFromQuery,\n allowMultipleStatements,\n refreshTableSchemas,\n onClose,\n form,\n ],\n );\n\n const watchView = form.watch('view');\n const watchTemp = form.watch('temp');\n const watchTableName = form.watch('tableName');\n\n const handleCancel = useCallback(async () => {\n if (abortControllerRef.current) {\n setIsCancelling(true);\n abortControllerRef.current.abort();\n }\n }, []);\n useEffect(() => {\n onRegisterCancel?.(handleCancel);\n }, [handleCancel, onRegisterCancel]);\n\n return (\n <TooltipProvider delayDuration={200}>\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {editDataSource\n ? 'Edit table query'\n : watchView\n ? 'Create view from query'\n : 'Create table from query'}\n </DialogTitle>\n {!editDataSource && (\n <DialogDescription>\n {watchView\n ? 'Create a new view from an SQL query.'\n : 'Create a new table from the results of an SQL query.'}\n </DialogDescription>\n )}\n </DialogHeader>\n\n {form.formState.errors.root && (\n <Alert variant=\"destructive\">\n <AlertDescription className=\"font-mono text-xs whitespace-pre-wrap\">\n {form.formState.errors.root.message}\n </AlertDescription>\n </Alert>\n )}\n\n {/* Table name, schema, database in single row */}\n <div className=\"flex items-start gap-3\">\n <FormField\n control={form.control}\n name=\"tableName\"\n render={({field}) => (\n <FormItem className=\"min-w-0 flex-2\">\n <FormLabel className=\"text-xs\">\n {watchView ? 'View name' : 'Table name'}\n </FormLabel>\n <FormControl>\n <Input\n {...field}\n className=\"h-9 font-mono text-xs\"\n autoFocus\n disabled={isSubmitting}\n />\n </FormControl>\n <FormMessage className=\"text-xs\" />\n </FormItem>\n )}\n />\n\n {showSchemaSelection && (\n <>\n <FormField\n control={form.control}\n name=\"schema\"\n render={({field}) => (\n <FormItem className=\"min-w-0 flex-1\">\n <FormLabel className=\"text-xs\">Schema</FormLabel>\n <FormControl>\n <SchemaCombobox\n value={field.value}\n onChange={field.onChange}\n options={schemas}\n placeholder=\"Schema...\"\n searchPlaceholder=\"Search...\"\n emptyMessage=\"No schemas.\"\n disabled={isSubmitting}\n />\n </FormControl>\n </FormItem>\n )}\n />\n\n {(databases.length > 1 || watchTemp) && (\n <FormField\n control={form.control}\n name=\"database\"\n render={({field}) => (\n <FormItem className=\"min-w-0 flex-1\">\n <FormLabel className=\"text-xs\">Database</FormLabel>\n <FormControl>\n <SchemaCombobox\n value={watchTemp ? 'temp' : field.value}\n onChange={field.onChange}\n options={databases}\n placeholder=\"Database...\"\n searchPlaceholder=\"Search...\"\n emptyMessage=\"No databases.\"\n disabled={isSubmitting || watchTemp}\n />\n </FormControl>\n </FormItem>\n )}\n />\n )}\n </>\n )}\n </div>\n\n <FormField\n control={form.control}\n name=\"query\"\n render={({field}) => (\n <FormItem className=\"relative flex h-[200px] flex-col\">\n <FormControl>\n <SqlMonacoEditor\n connector={connector}\n value={field.value}\n onChange={field.onChange}\n className=\"absolute inset-0 h-full w-full\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n folding: false,\n lineNumbers: 'off',\n readOnly: isSubmitting,\n fixedOverflowWidgets: false, // default true doesn't work well in a modal\n }}\n />\n </FormControl>\n <FormMessage className=\"text-xs\" />\n </FormItem>\n )}\n />\n\n {/* Compact options row */}\n {!onAddOrUpdateSqlQuery && (\n <div className=\"flex items-center gap-6 rounded-md border px-3 py-2\">\n <FormField\n control={form.control}\n name=\"view\"\n render={({field}) => (\n <OptionCheckbox\n id=\"create-table-view\"\n label=\"View\"\n tooltip=\"Create a view instead of a table. Views store the query, not the data.\"\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={isSubmitting}\n />\n )}\n />\n\n {/* <FormField\n control={form.control}\n name=\"temp\"\n render={({field}) => (\n <OptionCheckbox\n id=\"create-table-temp\"\n label=\"Temporary\"\n tooltip={`${watchView ? 'View' : 'Table'} will be deleted when the session ends.`}\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={isSubmitting}\n />\n )}\n /> */}\n\n <FormField\n control={form.control}\n name=\"replace\"\n render={({field}) => (\n <OptionCheckbox\n id=\"create-table-replace\"\n label=\"Overwrite\"\n tooltip={`Overwrite existing ${watchView ? 'view' : 'table'} with the same name if it exists.`}\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={isSubmitting}\n />\n )}\n />\n </div>\n )}\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onRequestClose}>\n Close\n </Button>\n <Button\n type={isSubmitting ? 'button' : 'submit'}\n onClick={isSubmitting ? handleCancel : undefined}\n disabled={isSubmitting ? isCancelling : !watchTableName?.trim()}\n >\n {isSubmitting && <Spinner className=\"mr-2\" />}\n {isSubmitting\n ? isCancelling\n ? 'Cancelling...'\n : 'Cancel'\n : editDataSource\n ? 'Update'\n : 'Create'}\n </Button>\n </DialogFooter>\n </form>\n </Form>\n </TooltipProvider>\n );\n};\n\nconst CreateTableModal: FC<CreateTableModalProps> = (props) => {\n const {\n isOpen,\n onClose,\n query,\n editDataSource,\n allowMultipleStatements,\n showSchemaSelection,\n onAddOrUpdateSqlQuery,\n className,\n initialValues,\n } = props;\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isConfirmOpen, setIsConfirmOpen] = useState(false);\n const cancelRef = useRef<(() => void) | null>(null);\n\n const resetState = useCallback(() => {\n setIsSubmitting(false);\n setIsConfirmOpen(false);\n cancelRef.current = null;\n }, []);\n\n const handleClose = useCallback(() => {\n resetState();\n onClose();\n }, [onClose, resetState]);\n\n const handleRequestClose = useCallback(() => {\n if (!isSubmitting) {\n handleClose();\n return;\n }\n setIsConfirmOpen(true);\n }, [handleClose, isSubmitting]);\n\n const handleConfirmClose = useCallback(() => {\n cancelRef.current?.();\n handleClose();\n }, [handleClose]);\n\n return (\n <Dialog\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) {\n handleRequestClose();\n }\n }}\n >\n <DialogContent className={cn('w-3xl max-w-[80%]', className)}>\n {isOpen && (\n <CreateTableForm\n query={query}\n onClose={handleClose}\n onRequestClose={handleRequestClose}\n editDataSource={editDataSource}\n allowMultipleStatements={allowMultipleStatements}\n showSchemaSelection={showSchemaSelection}\n onAddOrUpdateSqlQuery={onAddOrUpdateSqlQuery}\n initialValues={initialValues}\n onSubmittingChange={setIsSubmitting}\n onRegisterCancel={(cancel) => {\n cancelRef.current = cancel;\n }}\n />\n )}\n </DialogContent>\n <Dialog open={isConfirmOpen} onOpenChange={setIsConfirmOpen}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Cancel running query?</DialogTitle>\n <DialogDescription>\n A query is still running. Cancelling it will stop the query and\n close this dialog.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setIsConfirmOpen(false)}\n >\n Keep running\n </Button>\n <Button type=\"button\" onClick={handleConfirmClose}>\n Cancel & close\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </Dialog>\n );\n};\n\nexport default CreateTableModal;\n"]}
@@ -10,6 +10,6 @@ export const QueryEditorPanel = ({ className, }) => {
10
10
  const isSelectedOpen = openTabs.includes(selectedQueryId);
11
11
  return (_jsxs("div", { className: cn('flex h-full flex-col',
12
12
  // this is for Monaco's completion menu to not being cut off
13
- 'overflow-visible', className), children: [_jsxs("div", { className: "border-border flex items-center gap-4 border-b px-2 pt-1", children: [_jsx(QueryEditorPanelTabsList, {}), _jsx("div", { className: "flex-1" }), _jsx(QueryEditorPanelActions, {})] }), isSelectedOpen ? (_jsx("div", { className: "bg-background h-full w-full py-1", children: _jsx("div", { className: "relative h-full flex-grow", children: _jsx("div", { className: "absolute inset-0", children: _jsx(QueryEditorPanelEditor, { queryId: selectedQueryId }) }) }) })) : (_jsx("div", { className: "text-muted-foreground flex h-full items-center justify-center text-sm", children: "No open queries" }))] }));
13
+ 'overflow-visible', className), children: [_jsxs("div", { className: "border-border flex items-center gap-4 border-b px-2 pt-1", children: [_jsx(QueryEditorPanelTabsList, {}), _jsx("div", { className: "flex-1" }), _jsx(QueryEditorPanelActions, {})] }), isSelectedOpen ? (_jsx("div", { className: "bg-background h-full w-full py-1", children: _jsx("div", { className: "relative h-full grow", children: _jsx("div", { className: "absolute inset-0", children: _jsx(QueryEditorPanelEditor, { queryId: selectedQueryId }) }) }) })) : (_jsx("div", { className: "text-muted-foreground flex h-full items-center justify-center text-sm", children: "No open queries" }))] }));
14
14
  };
15
15
  //# sourceMappingURL=QueryEditorPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryEditorPanel.js","sourceRoot":"","sources":["../../src/components/QueryEditorPanel.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAChC,OAAO,EAAC,qBAAqB,EAAC,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC;AAOpE,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,GACV,EAAE,EAAE;IACH,MAAM,eAAe,GAAG,qBAAqB,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAC1C,CAAC;IACF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE3E,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAE1D,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,sBAAsB;QACtB,4DAA4D;QAC5D,kBAAkB,EAClB,SAAS,CACV,aAED,eAAK,SAAS,EAAC,0DAA0D,aACvE,KAAC,wBAAwB,KAAG,EAC5B,cAAK,SAAS,EAAC,QAAQ,GAAG,EAC1B,KAAC,uBAAuB,KAAG,IACvB,EACL,cAAc,CAAC,CAAC,CAAC,CAChB,cAAK,SAAS,EAAC,kCAAkC,YAC/C,cAAK,SAAS,EAAC,2BAA2B,YACxC,cAAK,SAAS,EAAC,kBAAkB,YAC/B,KAAC,sBAAsB,IAAC,OAAO,EAAE,eAAe,GAAI,GAChD,GACF,GACF,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,uEAAuE,gCAEhF,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport {cn} from '@sqlrooms/ui';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {QueryEditorPanelActions} from './QueryEditorPanelActions';\nimport {QueryEditorPanelEditor} from './QueryEditorPanelEditor';\nimport {QueryEditorPanelTabsList} from './QueryEditorPanelTabsList';\n\nexport interface QueryEditorPanelProps {\n /** Custom class name for styling */\n className?: string;\n}\n\nexport const QueryEditorPanel: React.FC<QueryEditorPanelProps> = ({\n className,\n}) => {\n const selectedQueryId = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.selectedQueryId,\n );\n const openTabs = useStoreWithSqlEditor((s) => s.sqlEditor.config.openTabs);\n\n const isSelectedOpen = openTabs.includes(selectedQueryId);\n\n return (\n <div\n className={cn(\n 'flex h-full flex-col',\n // this is for Monaco's completion menu to not being cut off\n 'overflow-visible',\n className,\n )}\n >\n <div className=\"border-border flex items-center gap-4 border-b px-2 pt-1\">\n <QueryEditorPanelTabsList />\n <div className=\"flex-1\" />\n <QueryEditorPanelActions />\n </div>\n {isSelectedOpen ? (\n <div className=\"bg-background h-full w-full py-1\">\n <div className=\"relative h-full flex-grow\">\n <div className=\"absolute inset-0\">\n <QueryEditorPanelEditor queryId={selectedQueryId} />\n </div>\n </div>\n </div>\n ) : (\n <div className=\"text-muted-foreground flex h-full items-center justify-center text-sm\">\n No open queries\n </div>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"QueryEditorPanel.js","sourceRoot":"","sources":["../../src/components/QueryEditorPanel.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAChC,OAAO,EAAC,qBAAqB,EAAC,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC;AAOpE,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,GACV,EAAE,EAAE;IACH,MAAM,eAAe,GAAG,qBAAqB,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAC1C,CAAC;IACF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE3E,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAE1D,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,sBAAsB;QACtB,4DAA4D;QAC5D,kBAAkB,EAClB,SAAS,CACV,aAED,eAAK,SAAS,EAAC,0DAA0D,aACvE,KAAC,wBAAwB,KAAG,EAC5B,cAAK,SAAS,EAAC,QAAQ,GAAG,EAC1B,KAAC,uBAAuB,KAAG,IACvB,EACL,cAAc,CAAC,CAAC,CAAC,CAChB,cAAK,SAAS,EAAC,kCAAkC,YAC/C,cAAK,SAAS,EAAC,sBAAsB,YACnC,cAAK,SAAS,EAAC,kBAAkB,YAC/B,KAAC,sBAAsB,IAAC,OAAO,EAAE,eAAe,GAAI,GAChD,GACF,GACF,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,uEAAuE,gCAEhF,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport {cn} from '@sqlrooms/ui';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {QueryEditorPanelActions} from './QueryEditorPanelActions';\nimport {QueryEditorPanelEditor} from './QueryEditorPanelEditor';\nimport {QueryEditorPanelTabsList} from './QueryEditorPanelTabsList';\n\nexport interface QueryEditorPanelProps {\n /** Custom class name for styling */\n className?: string;\n}\n\nexport const QueryEditorPanel: React.FC<QueryEditorPanelProps> = ({\n className,\n}) => {\n const selectedQueryId = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.selectedQueryId,\n );\n const openTabs = useStoreWithSqlEditor((s) => s.sqlEditor.config.openTabs);\n\n const isSelectedOpen = openTabs.includes(selectedQueryId);\n\n return (\n <div\n className={cn(\n 'flex h-full flex-col',\n // this is for Monaco's completion menu to not being cut off\n 'overflow-visible',\n className,\n )}\n >\n <div className=\"border-border flex items-center gap-4 border-b px-2 pt-1\">\n <QueryEditorPanelTabsList />\n <div className=\"flex-1\" />\n <QueryEditorPanelActions />\n </div>\n {isSelectedOpen ? (\n <div className=\"bg-background h-full w-full py-1\">\n <div className=\"relative h-full grow\">\n <div className=\"absolute inset-0\">\n <QueryEditorPanelEditor queryId={selectedQueryId} />\n </div>\n </div>\n </div>\n ) : (\n <div className=\"text-muted-foreground flex h-full items-center justify-center text-sm\">\n No open queries\n </div>\n )}\n </div>\n );\n};\n"]}
@@ -40,6 +40,6 @@ export const QueryEditorPanelEditor = ({ className, queryId }) => {
40
40
  }
41
41
  });
42
42
  }, [queryId, runQuery]);
43
- return (_jsx(SqlMonacoEditor, { connector: connector, value: queryText ?? '', onChange: handleUpdateQuery, className: cn('h-full w-full flex-grow', className), options: MONACO_OPTIONS, onMount: handleEditorMount, tableSchemas: tableSchemas }));
43
+ return (_jsx(SqlMonacoEditor, { connector: connector, value: queryText ?? '', onChange: handleUpdateQuery, className: cn('h-full w-full grow', className), options: MONACO_OPTIONS, onMount: handleEditorMount, tableSchemas: tableSchemas }));
44
44
  };
45
45
  //# sourceMappingURL=QueryEditorPanelEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryEditorPanelEditor.js","sourceRoot":"","sources":["../../src/components/QueryEditorPanelEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {cn} from '@sqlrooms/ui';\nimport type * as Monaco from 'monaco-editor';\nimport {useCallback, useRef} from 'react';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {SqlMonacoEditor} from '../SqlMonacoEditor';\n\ntype EditorInstance = Monaco.editor.IStandaloneCodeEditor;\ntype MonacoInstance = typeof Monaco;\n\nconst MONACO_OPTIONS: Monaco.editor.IStandaloneEditorConstructionOptions = {\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n quickSuggestions: true,\n suggestOnTriggerCharacters: true,\n};\n\nexport const QueryEditorPanelEditor: React.FC<{\n className?: string;\n queryId: string;\n}> = ({className, queryId}) => {\n const tableSchemas = useStoreWithSqlEditor((s) => s.db.tables);\n const runQuery = useStoreWithSqlEditor((s) => s.sqlEditor.parseAndRunQuery);\n const connector = useStoreWithSqlEditor((s) => s.db.connector);\n\n const queryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.queries.find((q) => q.id === queryId)?.query,\n );\n const updateQueryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.updateQueryText,\n );\n // Editor instance ref for keyboard shortcuts\n const editorRef = useRef<{\n [key: string]: EditorInstance;\n }>({});\n\n // Handle query text update\n const handleUpdateQuery = useCallback(\n (value: string | undefined) => {\n if (!value) return;\n updateQueryText(queryId, value);\n },\n [queryId, updateQueryText],\n );\n\n // Handle editor mount\n const handleEditorMount = useCallback(\n (editor: EditorInstance, monaco: MonacoInstance) => {\n editorRef.current[queryId] = editor;\n // Add keyboard shortcut for running query\n editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {\n const model = editor.getModel();\n const selection = editor.getSelection();\n if (model && selection && !selection.isEmpty()) {\n runQuery(model.getValueInRange(selection));\n } else {\n runQuery(editor.getValue());\n }\n });\n },\n [queryId, runQuery],\n );\n\n return (\n <SqlMonacoEditor\n connector={connector}\n value={queryText ?? ''}\n onChange={handleUpdateQuery}\n className={cn('h-full w-full flex-grow', className)}\n options={MONACO_OPTIONS}\n onMount={handleEditorMount}\n tableSchemas={tableSchemas}\n />\n );\n};\n"]}
1
+ {"version":3,"file":"QueryEditorPanelEditor.js","sourceRoot":"","sources":["../../src/components/QueryEditorPanelEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {cn} from '@sqlrooms/ui';\nimport type * as Monaco from 'monaco-editor';\nimport {useCallback, useRef} from 'react';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {SqlMonacoEditor} from '../SqlMonacoEditor';\n\ntype EditorInstance = Monaco.editor.IStandaloneCodeEditor;\ntype MonacoInstance = typeof Monaco;\n\nconst MONACO_OPTIONS: Monaco.editor.IStandaloneEditorConstructionOptions = {\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n quickSuggestions: true,\n suggestOnTriggerCharacters: true,\n};\n\nexport const QueryEditorPanelEditor: React.FC<{\n className?: string;\n queryId: string;\n}> = ({className, queryId}) => {\n const tableSchemas = useStoreWithSqlEditor((s) => s.db.tables);\n const runQuery = useStoreWithSqlEditor((s) => s.sqlEditor.parseAndRunQuery);\n const connector = useStoreWithSqlEditor((s) => s.db.connector);\n\n const queryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.queries.find((q) => q.id === queryId)?.query,\n );\n const updateQueryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.updateQueryText,\n );\n // Editor instance ref for keyboard shortcuts\n const editorRef = useRef<{\n [key: string]: EditorInstance;\n }>({});\n\n // Handle query text update\n const handleUpdateQuery = useCallback(\n (value: string | undefined) => {\n if (!value) return;\n updateQueryText(queryId, value);\n },\n [queryId, updateQueryText],\n );\n\n // Handle editor mount\n const handleEditorMount = useCallback(\n (editor: EditorInstance, monaco: MonacoInstance) => {\n editorRef.current[queryId] = editor;\n // Add keyboard shortcut for running query\n editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {\n const model = editor.getModel();\n const selection = editor.getSelection();\n if (model && selection && !selection.isEmpty()) {\n runQuery(model.getValueInRange(selection));\n } else {\n runQuery(editor.getValue());\n }\n });\n },\n [queryId, runQuery],\n );\n\n return (\n <SqlMonacoEditor\n connector={connector}\n value={queryText ?? ''}\n onChange={handleUpdateQuery}\n className={cn('h-full w-full grow', className)}\n options={MONACO_OPTIONS}\n onMount={handleEditorMount}\n tableSchemas={tableSchemas}\n />\n );\n};\n"]}
@@ -71,19 +71,19 @@ const QueryResultPanelRoot = ({ className, renderActions, fontSize = 'text-xs',
71
71
  // Backward compat: if no children but onAskAiAboutError is provided, render default button
72
72
  const errorActions = children ??
73
73
  (onAskAiAboutError && (_jsx(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: handleAskAiAboutError, title: "Ask AI for help", children: _jsx(MessageCircleQuestion, { className: "h-4 w-4" }) })));
74
- return (_jsxs("div", { className: "relative h-full w-full overflow-auto p-5", children: [errorActions && (_jsx("div", { className: "absolute right-2 top-2", children: errorActions })), _jsx("pre", { className: cn('whitespace-pre-wrap text-xs leading-tight text-red-500', errorActions && 'pr-12'), children: queryResult.error })] }));
74
+ return (_jsxs("div", { className: "relative h-full w-full overflow-auto p-5", children: [errorActions && (_jsx("div", { className: "absolute top-2 right-2", children: errorActions })), _jsx("pre", { className: cn('text-xs leading-tight whitespace-pre-wrap text-red-500', errorActions && 'pr-12'), children: queryResult.error })] }));
75
75
  }
76
76
  if (queryResult?.status === 'success') {
77
- const contentWrapperClassName = cn('relative flex h-full w-full flex-grow flex-col overflow-hidden', className);
77
+ const contentWrapperClassName = cn('relative flex h-full w-full grow flex-col overflow-hidden', className);
78
78
  // Result shows the EXPLAIN schema
79
79
  if (queryResult.type === 'explain') {
80
- return (_jsx("div", { className: contentWrapperClassName, children: _jsxs("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [_jsx("pre", { className: "flex-1 overflow-auto whitespace-pre-wrap break-words p-4 font-mono text-xs leading-tight", children: explainText }), _jsxs("div", { className: "bg-background flex w-full items-center gap-2 px-4 py-1", children: [_jsx("div", { className: "font-mono text-xs", children: "EXPLAIN" }), _jsx("div", { className: "flex-1" }), renderActions
80
+ return (_jsx("div", { className: contentWrapperClassName, children: _jsxs("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [_jsx("pre", { className: "flex-1 overflow-auto p-4 font-mono text-xs leading-tight wrap-break-word whitespace-pre-wrap", children: explainText }), _jsxs("div", { className: "bg-background flex w-full items-center gap-2 px-4 py-1", children: [_jsx("div", { className: "font-mono text-xs", children: "EXPLAIN" }), _jsx("div", { className: "flex-1" }), renderActions
81
81
  ? renderActions(queryResult.lastQueryStatement)
82
82
  : undefined] })] }) }));
83
83
  }
84
84
  // Result shows the SELECT/PRAGMA table
85
85
  if (isQueryWithResult(queryResult)) {
86
- return (_jsx("div", { className: contentWrapperClassName, children: _jsxs("div", { className: "flex h-full w-full flex-col", children: [_jsx(DataTablePaginated, { data: arrowTableData?.data, columns: arrowTableData?.columns, className: "flex-grow overflow-hidden", fontSize: fontSize, isFetching: false, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, enableRowSelection: enableRowSelection, rowSelection: rowSelection, onRowSelectionChange: onRowSelectionChange }), _jsxs("div", { className: "bg-background flex w-full items-center gap-2 px-4 py-1", children: [queryResult.result ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "font-mono text-xs", children: `${formatCount(queryResult.result.numRows ?? 0)} rows` }), queryResult.type === 'select' ? (_jsx(QueryResultLimitSelect, { value: queryResultLimit, onChange: setQueryResultLimit, options: queryResultLimitOptions })) : null] })) : null, _jsx("div", { className: "flex-1" }), renderActions
86
+ return (_jsx("div", { className: contentWrapperClassName, children: _jsxs("div", { className: "flex h-full w-full flex-col", children: [_jsx(DataTablePaginated, { data: arrowTableData?.data, columns: arrowTableData?.columns, className: "grow overflow-hidden", fontSize: fontSize, isFetching: false, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, enableRowSelection: enableRowSelection, rowSelection: rowSelection, onRowSelectionChange: onRowSelectionChange }), _jsxs("div", { className: "bg-background flex w-full items-center gap-2 px-4 py-1", children: [queryResult.result ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "font-mono text-xs", children: `${formatCount(queryResult.result.numRows ?? 0)} rows` }), queryResult.type === 'select' ? (_jsx(QueryResultLimitSelect, { value: queryResultLimit, onChange: setQueryResultLimit, options: queryResultLimitOptions })) : null] })) : null, _jsx("div", { className: "flex-1" }), renderActions
87
87
  ? renderActions(queryResult.lastQueryStatement)
88
88
  : undefined] })] }) }));
89
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"QueryResultPanel.js","sourceRoot":"","sources":["../../src/components/QueryResultPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n ArrowDataTableValueFormatter,\n DataTablePaginated,\n useArrowDataTable,\n} from '@sqlrooms/data-table';\nimport {\n Button,\n cn,\n SpinnerPane,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@sqlrooms/ui';\nimport {formatCount} from '@sqlrooms/utils';\nimport type {Row, RowSelectionState} from '@tanstack/react-table';\nimport {MessageCircleQuestion} from 'lucide-react';\nimport React from 'react';\nimport {isQueryWithResult, useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {QueryResultLimitSelect} from './QueryResultLimitSelect';\n\n/**\n * Turns DuckDB's EXPLAIN result table into a readable plan string.\n * Prefer the `explain_value` column (DuckDB default); otherwise fall back\n * to the first column and join all rows with newlines.\n */\nfunction arrowTableToExplainText(result: any): string {\n if (!result) return '';\n\n const numRows: number = result.numRows ?? 0;\n const fields: {name: string}[] = result.schema?.fields ?? [];\n const fieldNames = fields.map((f) => f.name);\n\n const hasExplainValueColumn = fieldNames.includes('explain_value');\n const columnName = hasExplainValueColumn ? 'explain_value' : fieldNames[0];\n if (!columnName) return '';\n\n const col = result.getChild?.(columnName);\n if (!col) return '';\n\n const lines: string[] = [];\n for (let i = 0; i < numRows; i++) {\n const v = col.get(i);\n if (v != null && String(v).length > 0) lines.push(String(v));\n }\n return lines.join('\\n');\n}\n\nexport interface QueryResultPanelProps {\n /** Custom class name for styling */\n className?: string;\n /** Custom actions to render in the query result panel */\n renderActions?: (query: string) => React.ReactNode;\n /** Custom font size for the table e.g. text-xs, text-sm, text-md, text-lg, text-base */\n fontSize?: string;\n /**\n * Called when a row in the results table is clicked.\n */\n onRowClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /**\n * Called when a row in the results table is double-clicked.\n */\n onRowDoubleClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /** Custom content to render in the error state (e.g., QueryResultPanel.AskAi) */\n children?: React.ReactNode;\n /**\n * @deprecated Use children with QueryResultPanel.AskAi instead\n * Called when the \"Ask AI\" button is clicked on an error message.\n * Receives the current query and error text.\n */\n onAskAiAboutError?: (query: string, error: string) => void;\n /**\n * Enables row selection with checkboxes.\n */\n enableRowSelection?: boolean;\n /**\n * Controlled row selection state. Keys are row indices, values are selection status.\n */\n rowSelection?: RowSelectionState;\n /**\n * Called when row selection changes.\n */\n onRowSelectionChange?: (rowSelection: RowSelectionState) => void;\n /** Custom value formatter for arrow data */\n formatValue?: ArrowDataTableValueFormatter;\n}\n\nconst QueryResultPanelRoot: React.FC<QueryResultPanelProps> = ({\n className,\n renderActions,\n fontSize = 'text-xs',\n onRowClick,\n onRowDoubleClick,\n children,\n onAskAiAboutError,\n enableRowSelection,\n rowSelection,\n onRowSelectionChange,\n formatValue,\n}) => {\n const queryResult = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n return s.sqlEditor.queryResultsById[selectedId];\n });\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n const setQueryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setQueryResultLimit,\n );\n const queryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimit,\n );\n const queryResultLimitOptions = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimitOptions,\n );\n\n const tableForDataTable =\n isQueryWithResult(queryResult) && queryResult.type !== 'explain'\n ? queryResult.result\n : undefined;\n\n const arrowTableData = useArrowDataTable(tableForDataTable, {formatValue});\n\n const explainText = React.useMemo(() => {\n if (queryResult?.status !== 'success' || queryResult.type !== 'explain') {\n return undefined;\n }\n return arrowTableToExplainText(queryResult.result);\n }, [queryResult]);\n\n const handleAskAiAboutError = React.useCallback(() => {\n if (queryResult?.status === 'error' && onAskAiAboutError) {\n const currentQuery = getCurrentQuery();\n const errorText = queryResult.error;\n onAskAiAboutError?.(currentQuery, errorText);\n }\n }, [queryResult, getCurrentQuery, onAskAiAboutError]);\n\n if (!queryResult) {\n return null;\n }\n\n if (queryResult?.status === 'loading') {\n return <SpinnerPane h=\"100%\" />;\n }\n\n if (queryResult?.status === 'aborted') {\n return (\n <div className=\"p-5 font-mono text-xs leading-tight text-red-500\">\n Query was aborted\n </div>\n );\n }\n if (queryResult?.status === 'error') {\n // Backward compat: if no children but onAskAiAboutError is provided, render default button\n const errorActions =\n children ??\n (onAskAiAboutError && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={handleAskAiAboutError}\n title=\"Ask AI for help\"\n >\n <MessageCircleQuestion className=\"h-4 w-4\" />\n </Button>\n ));\n\n return (\n <div className=\"relative h-full w-full overflow-auto p-5\">\n {errorActions && (\n <div className=\"absolute right-2 top-2\">{errorActions}</div>\n )}\n <pre\n className={cn(\n 'whitespace-pre-wrap text-xs leading-tight text-red-500',\n errorActions && 'pr-12',\n )}\n >\n {queryResult.error}\n </pre>\n </div>\n );\n }\n\n if (queryResult?.status === 'success') {\n const contentWrapperClassName = cn(\n 'relative flex h-full w-full flex-grow flex-col overflow-hidden',\n className,\n );\n\n // Result shows the EXPLAIN schema\n if (queryResult.type === 'explain') {\n return (\n <div className={contentWrapperClassName}>\n <div className=\"flex h-full w-full flex-col overflow-hidden\">\n <pre className=\"flex-1 overflow-auto whitespace-pre-wrap break-words p-4 font-mono text-xs leading-tight\">\n {explainText}\n </pre>\n <div className=\"bg-background flex w-full items-center gap-2 px-4 py-1\">\n <div className=\"font-mono text-xs\">EXPLAIN</div>\n <div className=\"flex-1\" />\n {renderActions\n ? renderActions(queryResult.lastQueryStatement)\n : undefined}\n </div>\n </div>\n </div>\n );\n }\n\n // Result shows the SELECT/PRAGMA table\n if (isQueryWithResult(queryResult)) {\n return (\n <div className={contentWrapperClassName}>\n <div className=\"flex h-full w-full flex-col\">\n <DataTablePaginated\n data={arrowTableData?.data}\n columns={arrowTableData?.columns}\n className=\"flex-grow overflow-hidden\"\n fontSize={fontSize}\n isFetching={false}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n enableRowSelection={enableRowSelection}\n rowSelection={rowSelection}\n onRowSelectionChange={onRowSelectionChange}\n />\n <div className=\"bg-background flex w-full items-center gap-2 px-4 py-1\">\n {queryResult.result ? (\n <>\n <div className=\"font-mono text-xs\">\n {`${formatCount(queryResult.result.numRows ?? 0)} rows`}\n </div>\n\n {queryResult.type === 'select' ? (\n <QueryResultLimitSelect\n value={queryResultLimit}\n onChange={setQueryResultLimit}\n options={queryResultLimitOptions}\n />\n ) : null}\n </>\n ) : null}\n <div className=\"flex-1\" />\n {renderActions\n ? renderActions(queryResult.lastQueryStatement)\n : undefined}\n </div>\n </div>\n </div>\n );\n }\n\n // Fallback message to show when the query result is not a SELECT/PRAGMA or EXPLAIN\n return (\n <div className={contentWrapperClassName}>\n <pre className=\"p-4 text-xs leading-tight text-green-500\">\n Successfully executed query\n </pre>\n </div>\n );\n }\n\n return null;\n};\n\nexport interface QueryResultPanelAskAiProps {\n /** Called when clicked with the current query and error message */\n onClick?: (query: string, error: string) => void;\n /** Custom icon (defaults to MessageCircleQuestion) */\n icon?: React.ReactNode;\n /** Custom className */\n className?: string;\n /** Tooltip text to display on hover */\n tooltipContent?: string;\n}\n\nconst QueryResultPanelAskAi = React.forwardRef<\n HTMLButtonElement,\n QueryResultPanelAskAiProps\n>(({onClick, icon, className, tooltipContent = 'Ask AI for help'}, ref) => {\n const queryResult = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n return s.sqlEditor.queryResultsById[selectedId];\n });\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n\n // Only render in error state\n if (queryResult?.status !== 'error') return null;\n\n const handleClick = () => {\n onClick?.(getCurrentQuery(), queryResult.error);\n };\n\n return (\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n className={cn('h-8 w-8', className)}\n onClick={handleClick}\n >\n {icon ?? <MessageCircleQuestion className=\"h-4 w-4\" />}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{tooltipContent}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n});\nQueryResultPanelAskAi.displayName = 'QueryResultPanel.AskAi';\n\nexport const QueryResultPanel = Object.assign(QueryResultPanelRoot, {\n AskAi: QueryResultPanelAskAi,\n});\n"]}
1
+ {"version":3,"file":"QueryResultPanel.js","sourceRoot":"","sources":["../../src/components/QueryResultPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n ArrowDataTableValueFormatter,\n DataTablePaginated,\n useArrowDataTable,\n} from '@sqlrooms/data-table';\nimport {\n Button,\n cn,\n SpinnerPane,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@sqlrooms/ui';\nimport {formatCount} from '@sqlrooms/utils';\nimport type {Row, RowSelectionState} from '@tanstack/react-table';\nimport {MessageCircleQuestion} from 'lucide-react';\nimport React from 'react';\nimport {isQueryWithResult, useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {QueryResultLimitSelect} from './QueryResultLimitSelect';\n\n/**\n * Turns DuckDB's EXPLAIN result table into a readable plan string.\n * Prefer the `explain_value` column (DuckDB default); otherwise fall back\n * to the first column and join all rows with newlines.\n */\nfunction arrowTableToExplainText(result: any): string {\n if (!result) return '';\n\n const numRows: number = result.numRows ?? 0;\n const fields: {name: string}[] = result.schema?.fields ?? [];\n const fieldNames = fields.map((f) => f.name);\n\n const hasExplainValueColumn = fieldNames.includes('explain_value');\n const columnName = hasExplainValueColumn ? 'explain_value' : fieldNames[0];\n if (!columnName) return '';\n\n const col = result.getChild?.(columnName);\n if (!col) return '';\n\n const lines: string[] = [];\n for (let i = 0; i < numRows; i++) {\n const v = col.get(i);\n if (v != null && String(v).length > 0) lines.push(String(v));\n }\n return lines.join('\\n');\n}\n\nexport interface QueryResultPanelProps {\n /** Custom class name for styling */\n className?: string;\n /** Custom actions to render in the query result panel */\n renderActions?: (query: string) => React.ReactNode;\n /** Custom font size for the table e.g. text-xs, text-sm, text-md, text-lg, text-base */\n fontSize?: string;\n /**\n * Called when a row in the results table is clicked.\n */\n onRowClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /**\n * Called when a row in the results table is double-clicked.\n */\n onRowDoubleClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /** Custom content to render in the error state (e.g., QueryResultPanel.AskAi) */\n children?: React.ReactNode;\n /**\n * @deprecated Use children with QueryResultPanel.AskAi instead\n * Called when the \"Ask AI\" button is clicked on an error message.\n * Receives the current query and error text.\n */\n onAskAiAboutError?: (query: string, error: string) => void;\n /**\n * Enables row selection with checkboxes.\n */\n enableRowSelection?: boolean;\n /**\n * Controlled row selection state. Keys are row indices, values are selection status.\n */\n rowSelection?: RowSelectionState;\n /**\n * Called when row selection changes.\n */\n onRowSelectionChange?: (rowSelection: RowSelectionState) => void;\n /** Custom value formatter for arrow data */\n formatValue?: ArrowDataTableValueFormatter;\n}\n\nconst QueryResultPanelRoot: React.FC<QueryResultPanelProps> = ({\n className,\n renderActions,\n fontSize = 'text-xs',\n onRowClick,\n onRowDoubleClick,\n children,\n onAskAiAboutError,\n enableRowSelection,\n rowSelection,\n onRowSelectionChange,\n formatValue,\n}) => {\n const queryResult = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n return s.sqlEditor.queryResultsById[selectedId];\n });\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n const setQueryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setQueryResultLimit,\n );\n const queryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimit,\n );\n const queryResultLimitOptions = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimitOptions,\n );\n\n const tableForDataTable =\n isQueryWithResult(queryResult) && queryResult.type !== 'explain'\n ? queryResult.result\n : undefined;\n\n const arrowTableData = useArrowDataTable(tableForDataTable, {formatValue});\n\n const explainText = React.useMemo(() => {\n if (queryResult?.status !== 'success' || queryResult.type !== 'explain') {\n return undefined;\n }\n return arrowTableToExplainText(queryResult.result);\n }, [queryResult]);\n\n const handleAskAiAboutError = React.useCallback(() => {\n if (queryResult?.status === 'error' && onAskAiAboutError) {\n const currentQuery = getCurrentQuery();\n const errorText = queryResult.error;\n onAskAiAboutError?.(currentQuery, errorText);\n }\n }, [queryResult, getCurrentQuery, onAskAiAboutError]);\n\n if (!queryResult) {\n return null;\n }\n\n if (queryResult?.status === 'loading') {\n return <SpinnerPane h=\"100%\" />;\n }\n\n if (queryResult?.status === 'aborted') {\n return (\n <div className=\"p-5 font-mono text-xs leading-tight text-red-500\">\n Query was aborted\n </div>\n );\n }\n if (queryResult?.status === 'error') {\n // Backward compat: if no children but onAskAiAboutError is provided, render default button\n const errorActions =\n children ??\n (onAskAiAboutError && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={handleAskAiAboutError}\n title=\"Ask AI for help\"\n >\n <MessageCircleQuestion className=\"h-4 w-4\" />\n </Button>\n ));\n\n return (\n <div className=\"relative h-full w-full overflow-auto p-5\">\n {errorActions && (\n <div className=\"absolute top-2 right-2\">{errorActions}</div>\n )}\n <pre\n className={cn(\n 'text-xs leading-tight whitespace-pre-wrap text-red-500',\n errorActions && 'pr-12',\n )}\n >\n {queryResult.error}\n </pre>\n </div>\n );\n }\n\n if (queryResult?.status === 'success') {\n const contentWrapperClassName = cn(\n 'relative flex h-full w-full grow flex-col overflow-hidden',\n className,\n );\n\n // Result shows the EXPLAIN schema\n if (queryResult.type === 'explain') {\n return (\n <div className={contentWrapperClassName}>\n <div className=\"flex h-full w-full flex-col overflow-hidden\">\n <pre className=\"flex-1 overflow-auto p-4 font-mono text-xs leading-tight wrap-break-word whitespace-pre-wrap\">\n {explainText}\n </pre>\n <div className=\"bg-background flex w-full items-center gap-2 px-4 py-1\">\n <div className=\"font-mono text-xs\">EXPLAIN</div>\n <div className=\"flex-1\" />\n {renderActions\n ? renderActions(queryResult.lastQueryStatement)\n : undefined}\n </div>\n </div>\n </div>\n );\n }\n\n // Result shows the SELECT/PRAGMA table\n if (isQueryWithResult(queryResult)) {\n return (\n <div className={contentWrapperClassName}>\n <div className=\"flex h-full w-full flex-col\">\n <DataTablePaginated\n data={arrowTableData?.data}\n columns={arrowTableData?.columns}\n className=\"grow overflow-hidden\"\n fontSize={fontSize}\n isFetching={false}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n enableRowSelection={enableRowSelection}\n rowSelection={rowSelection}\n onRowSelectionChange={onRowSelectionChange}\n />\n <div className=\"bg-background flex w-full items-center gap-2 px-4 py-1\">\n {queryResult.result ? (\n <>\n <div className=\"font-mono text-xs\">\n {`${formatCount(queryResult.result.numRows ?? 0)} rows`}\n </div>\n\n {queryResult.type === 'select' ? (\n <QueryResultLimitSelect\n value={queryResultLimit}\n onChange={setQueryResultLimit}\n options={queryResultLimitOptions}\n />\n ) : null}\n </>\n ) : null}\n <div className=\"flex-1\" />\n {renderActions\n ? renderActions(queryResult.lastQueryStatement)\n : undefined}\n </div>\n </div>\n </div>\n );\n }\n\n // Fallback message to show when the query result is not a SELECT/PRAGMA or EXPLAIN\n return (\n <div className={contentWrapperClassName}>\n <pre className=\"p-4 text-xs leading-tight text-green-500\">\n Successfully executed query\n </pre>\n </div>\n );\n }\n\n return null;\n};\n\nexport interface QueryResultPanelAskAiProps {\n /** Called when clicked with the current query and error message */\n onClick?: (query: string, error: string) => void;\n /** Custom icon (defaults to MessageCircleQuestion) */\n icon?: React.ReactNode;\n /** Custom className */\n className?: string;\n /** Tooltip text to display on hover */\n tooltipContent?: string;\n}\n\nconst QueryResultPanelAskAi = React.forwardRef<\n HTMLButtonElement,\n QueryResultPanelAskAiProps\n>(({onClick, icon, className, tooltipContent = 'Ask AI for help'}, ref) => {\n const queryResult = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n return s.sqlEditor.queryResultsById[selectedId];\n });\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n\n // Only render in error state\n if (queryResult?.status !== 'error') return null;\n\n const handleClick = () => {\n onClick?.(getCurrentQuery(), queryResult.error);\n };\n\n return (\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n className={cn('h-8 w-8', className)}\n onClick={handleClick}\n >\n {icon ?? <MessageCircleQuestion className=\"h-4 w-4\" />}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{tooltipContent}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n});\nQueryResultPanelAskAi.displayName = 'QueryResultPanel.AskAi';\n\nexport const QueryResultPanel = Object.assign(QueryResultPanelRoot, {\n AskAi: QueryResultPanelAskAi,\n});\n"]}
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button, cn } from '@sqlrooms/ui';
3
3
  import { SqlReferenceButton, SqlReferenceButtonContent, } from './SqlReferenceButton';
4
4
  export const SqlEditorHeader = ({ className, title, showDocs, documentationPanel, onToggleDocs, children, }) => {
5
- return (_jsxs("div", { className: cn('flex w-full items-center gap-2 px-2 py-1', className), children: [title && _jsx("h2", { className: "text-md ml-1 font-semibold", children: title }), children, _jsx("div", { className: "flex-grow" }), documentationPanel ? (_jsx(Button, { size: "sm", variant: showDocs ? 'secondary' : 'outline', onClick: () => onToggleDocs?.(!showDocs), children: _jsx(SqlReferenceButtonContent, {}) })) : (_jsx(SqlReferenceButton, {}))] }));
5
+ return (_jsxs("div", { className: cn('flex w-full items-center gap-2 px-2 py-1', className), children: [title && _jsx("h2", { className: "text-md ml-1 font-semibold", children: title }), children, _jsx("div", { className: "grow" }), documentationPanel ? (_jsx(Button, { size: "sm", variant: showDocs ? 'secondary' : 'outline', onClick: () => onToggleDocs?.(!showDocs), children: _jsx(SqlReferenceButtonContent, {}) })) : (_jsx(SqlReferenceButton, {}))] }));
6
6
  };
7
7
  //# sourceMappingURL=SqlEditorHeader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditorHeader.js","sourceRoot":"","sources":["../../src/components/SqlEditorHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAE,EAAE,EAAC,MAAM,cAAc,CAAC;AAExC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAe9B,MAAM,CAAC,MAAM,eAAe,GAAmC,CAAC,EAC9D,SAAS,EACT,KAAK,EACL,QAAQ,EACR,kBAAkB,EAClB,YAAY,EACZ,QAAQ,GACT,EAAE,EAAE;IACH,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,0CAA0C,EAAE,SAAS,CAAC,aACtE,KAAK,IAAI,aAAI,SAAS,EAAC,4BAA4B,YAAE,KAAK,GAAM,EAChE,QAAQ,EACT,cAAK,SAAS,EAAC,WAAW,GAAG,EAC5B,kBAAkB,CAAC,CAAC,CAAC,CACpB,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAC3C,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,YAExC,KAAC,yBAAyB,KAAG,GACtB,CACV,CAAC,CAAC,CAAC,CACF,KAAC,kBAAkB,KAAG,CACvB,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {Button, cn} from '@sqlrooms/ui';\nimport React, {PropsWithChildren} from 'react';\nimport {\n SqlReferenceButton,\n SqlReferenceButtonContent,\n} from './SqlReferenceButton';\n\nexport type SqlEditorHeaderProps = PropsWithChildren<{\n /** Custom class name for styling */\n className?: string;\n /** The title of the SQL editor */\n title?: string;\n /** Whether to show the documentation panel */\n showDocs?: boolean;\n /** Optional documentation panel component */\n documentationPanel?: React.ReactNode;\n /** Callback when the documentation visibility is toggled */\n onToggleDocs?: (show: boolean) => void;\n}>;\n\nexport const SqlEditorHeader: React.FC<SqlEditorHeaderProps> = ({\n className,\n title,\n showDocs,\n documentationPanel,\n onToggleDocs,\n children,\n}) => {\n return (\n <div className={cn('flex w-full items-center gap-2 px-2 py-1', className)}>\n {title && <h2 className=\"text-md ml-1 font-semibold\">{title}</h2>}\n {children}\n <div className=\"flex-grow\" />\n {documentationPanel ? (\n <Button\n size=\"sm\"\n variant={showDocs ? 'secondary' : 'outline'}\n onClick={() => onToggleDocs?.(!showDocs)}\n >\n <SqlReferenceButtonContent />\n </Button>\n ) : (\n <SqlReferenceButton />\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SqlEditorHeader.js","sourceRoot":"","sources":["../../src/components/SqlEditorHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAE,EAAE,EAAC,MAAM,cAAc,CAAC;AAExC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAe9B,MAAM,CAAC,MAAM,eAAe,GAAmC,CAAC,EAC9D,SAAS,EACT,KAAK,EACL,QAAQ,EACR,kBAAkB,EAClB,YAAY,EACZ,QAAQ,GACT,EAAE,EAAE;IACH,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,0CAA0C,EAAE,SAAS,CAAC,aACtE,KAAK,IAAI,aAAI,SAAS,EAAC,4BAA4B,YAAE,KAAK,GAAM,EAChE,QAAQ,EACT,cAAK,SAAS,EAAC,MAAM,GAAG,EACvB,kBAAkB,CAAC,CAAC,CAAC,CACpB,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAC3C,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,YAExC,KAAC,yBAAyB,KAAG,GACtB,CACV,CAAC,CAAC,CAAC,CACF,KAAC,kBAAkB,KAAG,CACvB,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {Button, cn} from '@sqlrooms/ui';\nimport React, {PropsWithChildren} from 'react';\nimport {\n SqlReferenceButton,\n SqlReferenceButtonContent,\n} from './SqlReferenceButton';\n\nexport type SqlEditorHeaderProps = PropsWithChildren<{\n /** Custom class name for styling */\n className?: string;\n /** The title of the SQL editor */\n title?: string;\n /** Whether to show the documentation panel */\n showDocs?: boolean;\n /** Optional documentation panel component */\n documentationPanel?: React.ReactNode;\n /** Callback when the documentation visibility is toggled */\n onToggleDocs?: (show: boolean) => void;\n}>;\n\nexport const SqlEditorHeader: React.FC<SqlEditorHeaderProps> = ({\n className,\n title,\n showDocs,\n documentationPanel,\n onToggleDocs,\n children,\n}) => {\n return (\n <div className={cn('flex w-full items-center gap-2 px-2 py-1', className)}>\n {title && <h2 className=\"text-md ml-1 font-semibold\">{title}</h2>}\n {children}\n <div className=\"grow\" />\n {documentationPanel ? (\n <Button\n size=\"sm\"\n variant={showDocs ? 'secondary' : 'outline'}\n onClick={() => onToggleDocs?.(!showDocs)}\n >\n <SqlReferenceButtonContent />\n </Button>\n ) : (\n <SqlReferenceButton />\n )}\n </div>\n );\n};\n"]}
@@ -22,7 +22,7 @@ const SqlQueryDataSourcesPanel = ({ queryDataSources, isReadOnly }) => {
22
22
  removeSqlQueryDataSource(tableName);
23
23
  }, [removeSqlQueryDataSource]);
24
24
  const addOrUpdateSqlQueryDataSource = useBaseRoomShellStore((state) => state.room.addOrUpdateSqlQueryDataSource);
25
- return (_jsxs("div", { className: "flex flex-grow flex-col overflow-auto", children: [_jsx("div", { className: "flex flex-col items-stretch", children: _jsxs(Button, { variant: "secondary", size: "sm", onClick: () => setIsOpen(true), disabled: isReadOnly, children: [_jsx(PlusIcon, { className: "mr-2 h-4 w-4" }), "Add"] }) }), _jsx(CreateTableModal, { isOpen: isOpen, onClose: handleClose, editDataSource: selectedDataSource, query: "", onAddOrUpdateSqlQuery: addOrUpdateSqlQueryDataSource }), _jsx("div", { className: "flex flex-grow flex-col overflow-auto", children: queryDataSources.map((dataSource) => (_jsxs("div", { className: "flex flex-col gap-1 p-2", children: [_jsxs("div", { className: "flex cursor-pointer flex-row items-center gap-1", children: [_jsx("div", { className: "w-[15px] flex-none", children: _jsx(FileIcon, { className: "w-[15px]" }) }), _jsx("div", { className: "flex-1 overflow-hidden text-ellipsis", children: _jsx("span", { className: "break-words text-xs", children: dataSource.tableName }) }), _jsx("div", { className: "flex-none", children: !isReadOnly ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "icon", variant: "ghost", className: "text-muted-foreground h-6 w-6", children: _jsx(EllipsisIcon, { className: "h-5 w-5" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: () => handleEdit(dataSource), children: [_jsx(PencilIcon, { className: "mr-2 h-4 w-4" }), "Edit"] }), _jsxs(DropdownMenuItem, { disabled: true, children: [_jsx(RefreshCcwIcon, { className: "mr-2 h-4 w-4" }), "Refresh"] }), _jsxs(DropdownMenuItem, { onClick: () => handleRemove(dataSource), children: [_jsx(XIcon, { className: "mr-2 h-4 w-4" }), "Remove query"] })] })] })) : null })] }), _jsx("div", { className: "flex flex-row items-center gap-1", children: dataSourceStates[dataSource.tableName]?.status ===
25
+ return (_jsxs("div", { className: "flex grow flex-col overflow-auto", children: [_jsx("div", { className: "flex flex-col items-stretch", children: _jsxs(Button, { variant: "secondary", size: "sm", onClick: () => setIsOpen(true), disabled: isReadOnly, children: [_jsx(PlusIcon, { className: "mr-2 h-4 w-4" }), "Add"] }) }), _jsx(CreateTableModal, { isOpen: isOpen, onClose: handleClose, editDataSource: selectedDataSource, query: "", onAddOrUpdateSqlQuery: addOrUpdateSqlQueryDataSource }), _jsx("div", { className: "flex grow flex-col overflow-auto", children: queryDataSources.map((dataSource) => (_jsxs("div", { className: "flex flex-col gap-1 p-2", children: [_jsxs("div", { className: "flex cursor-pointer flex-row items-center gap-1", children: [_jsx("div", { className: "w-[15px] flex-none", children: _jsx(FileIcon, { className: "w-[15px]" }) }), _jsx("div", { className: "flex-1 overflow-hidden text-ellipsis", children: _jsx("span", { className: "text-xs wrap-break-word", children: dataSource.tableName }) }), _jsx("div", { className: "flex-none", children: !isReadOnly ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "icon", variant: "ghost", className: "text-muted-foreground h-6 w-6", children: _jsx(EllipsisIcon, { className: "h-5 w-5" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: () => handleEdit(dataSource), children: [_jsx(PencilIcon, { className: "mr-2 h-4 w-4" }), "Edit"] }), _jsxs(DropdownMenuItem, { disabled: true, children: [_jsx(RefreshCcwIcon, { className: "mr-2 h-4 w-4" }), "Refresh"] }), _jsxs(DropdownMenuItem, { onClick: () => handleRemove(dataSource), children: [_jsx(XIcon, { className: "mr-2 h-4 w-4" }), "Remove query"] })] })] })) : null })] }), _jsx("div", { className: "flex flex-row items-center gap-1", children: dataSourceStates[dataSource.tableName]?.status ===
26
26
  DataSourceStatus.ERROR ? (_jsx("div", { className: "bg-destructive/15 text-destructive flex-1 rounded p-1 text-xs", children: dataSourceStates[dataSource.tableName]?.message })) : dataSourceStates[dataSource.tableName]?.status ===
27
27
  DataSourceStatus.FETCHING ? (_jsx("div", { className: "bg-secondary h-1 w-full overflow-hidden rounded", children: _jsx("div", { className: "bg-primary h-full animate-pulse" }) })) : null })] }, dataSource.tableName))) })] }));
28
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SqlQueryDataSourcesPanel.js","sourceRoot":"","sources":["../../src/components/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataSourceStatus, useBaseRoomShellStore} from '@sqlrooms/room-shell';\nimport {SqlQueryDataSource} from '@sqlrooms/room-shell';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@sqlrooms/ui';\nimport {\n EllipsisIcon,\n FileIcon,\n PencilIcon,\n PlusIcon,\n RefreshCcwIcon,\n XIcon,\n} from 'lucide-react';\nimport {FC, useCallback, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\n\nconst SqlQueryDataSourcesPanel: FC<{\n isReadOnly?: boolean;\n queryDataSources: SqlQueryDataSource[];\n}> = ({queryDataSources, isReadOnly}) => {\n const [selectedDataSource, setSelectedDataSource] =\n useState<SqlQueryDataSource>();\n const [isOpen, setIsOpen] = useState(false);\n const dataSourceStates = useBaseRoomShellStore(\n (state) => state.room.dataSourceStates,\n );\n const removeSqlQueryDataSource = useBaseRoomShellStore(\n (state) => state.room.removeSqlQueryDataSource,\n );\n\n const handleEdit = useCallback((dataSource: SqlQueryDataSource) => {\n setSelectedDataSource(dataSource);\n setIsOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setIsOpen(false);\n setSelectedDataSource(undefined);\n }, []);\n\n const handleRemove = useCallback(\n (dataSource: SqlQueryDataSource) => {\n const {tableName} = dataSource;\n removeSqlQueryDataSource(tableName);\n },\n [removeSqlQueryDataSource],\n );\n\n const addOrUpdateSqlQueryDataSource = useBaseRoomShellStore(\n (state) => state.room.addOrUpdateSqlQueryDataSource,\n );\n\n return (\n <div className=\"flex flex-grow flex-col overflow-auto\">\n <div className=\"flex flex-col items-stretch\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => setIsOpen(true)}\n disabled={isReadOnly}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Add\n </Button>\n </div>\n <CreateTableModal\n isOpen={isOpen}\n onClose={handleClose}\n editDataSource={selectedDataSource}\n query=\"\"\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\n />\n\n <div className=\"flex flex-grow flex-col overflow-auto\">\n {queryDataSources.map((dataSource) => (\n <div key={dataSource.tableName} className=\"flex flex-col gap-1 p-2\">\n <div className=\"flex cursor-pointer flex-row items-center gap-1\">\n <div className=\"w-[15px] flex-none\">\n <FileIcon className=\"w-[15px]\" />\n </div>\n <div className=\"flex-1 overflow-hidden text-ellipsis\">\n <span className=\"break-words text-xs\">\n {dataSource.tableName}\n </span>\n </div>\n <div className=\"flex-none\">\n {!isReadOnly ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"text-muted-foreground h-6 w-6\"\n >\n <EllipsisIcon className=\"h-5 w-5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => handleEdit(dataSource)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem disabled>\n <RefreshCcwIcon className=\"mr-2 h-4 w-4\" />\n Refresh\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => handleRemove(dataSource)}\n >\n <XIcon className=\"mr-2 h-4 w-4\" />\n Remove query\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n </div>\n <div className=\"flex flex-row items-center gap-1\">\n {dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.ERROR ? (\n <div className=\"bg-destructive/15 text-destructive flex-1 rounded p-1 text-xs\">\n {dataSourceStates[dataSource.tableName]?.message}\n </div>\n ) : dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.FETCHING ? (\n <div className=\"bg-secondary h-1 w-full overflow-hidden rounded\">\n <div className=\"bg-primary h-full animate-pulse\" />\n </div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport {SqlQueryDataSourcesPanel};\n"]}
1
+ {"version":3,"file":"SqlQueryDataSourcesPanel.js","sourceRoot":"","sources":["../../src/components/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataSourceStatus, useBaseRoomShellStore} from '@sqlrooms/room-shell';\nimport {SqlQueryDataSource} from '@sqlrooms/room-shell';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@sqlrooms/ui';\nimport {\n EllipsisIcon,\n FileIcon,\n PencilIcon,\n PlusIcon,\n RefreshCcwIcon,\n XIcon,\n} from 'lucide-react';\nimport {FC, useCallback, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\n\nconst SqlQueryDataSourcesPanel: FC<{\n isReadOnly?: boolean;\n queryDataSources: SqlQueryDataSource[];\n}> = ({queryDataSources, isReadOnly}) => {\n const [selectedDataSource, setSelectedDataSource] =\n useState<SqlQueryDataSource>();\n const [isOpen, setIsOpen] = useState(false);\n const dataSourceStates = useBaseRoomShellStore(\n (state) => state.room.dataSourceStates,\n );\n const removeSqlQueryDataSource = useBaseRoomShellStore(\n (state) => state.room.removeSqlQueryDataSource,\n );\n\n const handleEdit = useCallback((dataSource: SqlQueryDataSource) => {\n setSelectedDataSource(dataSource);\n setIsOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setIsOpen(false);\n setSelectedDataSource(undefined);\n }, []);\n\n const handleRemove = useCallback(\n (dataSource: SqlQueryDataSource) => {\n const {tableName} = dataSource;\n removeSqlQueryDataSource(tableName);\n },\n [removeSqlQueryDataSource],\n );\n\n const addOrUpdateSqlQueryDataSource = useBaseRoomShellStore(\n (state) => state.room.addOrUpdateSqlQueryDataSource,\n );\n\n return (\n <div className=\"flex grow flex-col overflow-auto\">\n <div className=\"flex flex-col items-stretch\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => setIsOpen(true)}\n disabled={isReadOnly}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Add\n </Button>\n </div>\n <CreateTableModal\n isOpen={isOpen}\n onClose={handleClose}\n editDataSource={selectedDataSource}\n query=\"\"\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\n />\n\n <div className=\"flex grow flex-col overflow-auto\">\n {queryDataSources.map((dataSource) => (\n <div key={dataSource.tableName} className=\"flex flex-col gap-1 p-2\">\n <div className=\"flex cursor-pointer flex-row items-center gap-1\">\n <div className=\"w-[15px] flex-none\">\n <FileIcon className=\"w-[15px]\" />\n </div>\n <div className=\"flex-1 overflow-hidden text-ellipsis\">\n <span className=\"text-xs wrap-break-word\">\n {dataSource.tableName}\n </span>\n </div>\n <div className=\"flex-none\">\n {!isReadOnly ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"text-muted-foreground h-6 w-6\"\n >\n <EllipsisIcon className=\"h-5 w-5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => handleEdit(dataSource)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem disabled>\n <RefreshCcwIcon className=\"mr-2 h-4 w-4\" />\n Refresh\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => handleRemove(dataSource)}\n >\n <XIcon className=\"mr-2 h-4 w-4\" />\n Remove query\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n </div>\n <div className=\"flex flex-row items-center gap-1\">\n {dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.ERROR ? (\n <div className=\"bg-destructive/15 text-destructive flex-1 rounded p-1 text-xs\">\n {dataSourceStates[dataSource.tableName]?.message}\n </div>\n ) : dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.FETCHING ? (\n <div className=\"bg-secondary h-1 w-full overflow-hidden rounded\">\n <div className=\"bg-primary h-full animate-pulse\" />\n </div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport {SqlQueryDataSourcesPanel};\n"]}
@@ -40,7 +40,7 @@ export const SqlQueryPreview = ({ query, className, defaultLimit = 100, limitOpt
40
40
  const arrowTableData = useArrowDataTable(queryResult.data?.arrowTable);
41
41
  // Show error if validation failed
42
42
  if (error) {
43
- return (_jsxs("div", { className: cn('flex items-center gap-2 p-3 text-red-500', className), children: [_jsx(AlertCircle, { className: "h-4 w-4 flex-shrink-0" }), _jsx("span", { className: "text-xs", children: error })] }));
43
+ return (_jsxs("div", { className: cn('flex items-center gap-2 p-3 text-red-500', className), children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "text-xs", children: error })] }));
44
44
  }
45
45
  // Don't render if no query
46
46
  if (!limitedQuery) {
@@ -1 +1 @@
1
- {"version":3,"file":"SqlQueryPreview.js","sourceRoot":"","sources":["../../src/components/SqlQueryPreview.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataTablePaginated, useArrowDataTable} from '@sqlrooms/data-table';\nimport {makeLimitQuery, separateLastStatement, useSql} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {AlertCircle} from 'lucide-react';\nimport React, {useMemo, useState} from 'react';\nimport {QueryResultLimitSelect} from './QueryResultLimitSelect';\n\nexport interface SqlQueryPreviewProps {\n /**\n * The SQL query to preview\n */\n query: string;\n /**\n * Custom class name\n */\n className?: string;\n /**\n * Default limit for results\n * @default 100\n */\n defaultLimit?: number;\n /**\n * Options for the limit dropdown\n * @default [100, 500, 1000]\n */\n limitOptions?: number[];\n}\n\n/**\n * SQL query preview component with validation and results display.\n * Only allows single SELECT statements.\n * Displays results without pagination (just limited rows).\n */\nexport const SqlQueryPreview: React.FC<SqlQueryPreviewProps> = ({\n query,\n className,\n defaultLimit = 100,\n limitOptions = [100, 500, 1000],\n}) => {\n const [limit, setLimit] = useState(defaultLimit);\n\n // Validate and prepare query\n const {limitedQuery, error} = useMemo(() => {\n if (!query.trim()) {\n return {limitedQuery: '', error: null};\n }\n\n const {precedingStatements, lastStatement} = separateLastStatement(query);\n\n // Only allow single statements\n if (precedingStatements.length > 0) {\n return {\n limitedQuery: '',\n error: 'Only single SELECT statements are allowed for preview',\n };\n }\n\n // Apply limit to the query\n const limited = makeLimitQuery(lastStatement, {\n limit,\n sanitize: true,\n });\n\n return {limitedQuery: limited, error: null};\n }, [query, limit]);\n\n // Execute query\n const queryResult = useSql({\n query: limitedQuery,\n enabled: !!limitedQuery,\n });\n\n const arrowTableData = useArrowDataTable(queryResult.data?.arrowTable);\n\n // Show error if validation failed\n if (error) {\n return (\n <div\n className={cn('flex items-center gap-2 p-3 text-red-500', className)}\n >\n <AlertCircle className=\"h-4 w-4 flex-shrink-0\" />\n <span className=\"text-xs\">{error}</span>\n </div>\n );\n }\n\n // Don't render if no query\n if (!limitedQuery) {\n return null;\n }\n\n // Show query error\n if (queryResult.error) {\n return (\n <div className={cn('p-3', className)}>\n <pre className=\"text-xs leading-tight text-red-500\">\n {queryResult.error?.message ?? 'Unknown error'}\n </pre>\n </div>\n );\n }\n\n return (\n <div className={cn('flex h-full flex-col', className)}>\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n <DataTablePaginated\n {...arrowTableData}\n fontSize=\"text-xs\"\n isFetching={queryResult.isLoading}\n footerActions={\n <QueryResultLimitSelect\n value={limit}\n onChange={setLimit}\n options={limitOptions}\n />\n }\n />\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SqlQueryPreview.js","sourceRoot":"","sources":["../../src/components/SqlQueryPreview.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataTablePaginated, useArrowDataTable} from '@sqlrooms/data-table';\nimport {makeLimitQuery, separateLastStatement, useSql} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {AlertCircle} from 'lucide-react';\nimport React, {useMemo, useState} from 'react';\nimport {QueryResultLimitSelect} from './QueryResultLimitSelect';\n\nexport interface SqlQueryPreviewProps {\n /**\n * The SQL query to preview\n */\n query: string;\n /**\n * Custom class name\n */\n className?: string;\n /**\n * Default limit for results\n * @default 100\n */\n defaultLimit?: number;\n /**\n * Options for the limit dropdown\n * @default [100, 500, 1000]\n */\n limitOptions?: number[];\n}\n\n/**\n * SQL query preview component with validation and results display.\n * Only allows single SELECT statements.\n * Displays results without pagination (just limited rows).\n */\nexport const SqlQueryPreview: React.FC<SqlQueryPreviewProps> = ({\n query,\n className,\n defaultLimit = 100,\n limitOptions = [100, 500, 1000],\n}) => {\n const [limit, setLimit] = useState(defaultLimit);\n\n // Validate and prepare query\n const {limitedQuery, error} = useMemo(() => {\n if (!query.trim()) {\n return {limitedQuery: '', error: null};\n }\n\n const {precedingStatements, lastStatement} = separateLastStatement(query);\n\n // Only allow single statements\n if (precedingStatements.length > 0) {\n return {\n limitedQuery: '',\n error: 'Only single SELECT statements are allowed for preview',\n };\n }\n\n // Apply limit to the query\n const limited = makeLimitQuery(lastStatement, {\n limit,\n sanitize: true,\n });\n\n return {limitedQuery: limited, error: null};\n }, [query, limit]);\n\n // Execute query\n const queryResult = useSql({\n query: limitedQuery,\n enabled: !!limitedQuery,\n });\n\n const arrowTableData = useArrowDataTable(queryResult.data?.arrowTable);\n\n // Show error if validation failed\n if (error) {\n return (\n <div\n className={cn('flex items-center gap-2 p-3 text-red-500', className)}\n >\n <AlertCircle className=\"h-4 w-4 shrink-0\" />\n <span className=\"text-xs\">{error}</span>\n </div>\n );\n }\n\n // Don't render if no query\n if (!limitedQuery) {\n return null;\n }\n\n // Show query error\n if (queryResult.error) {\n return (\n <div className={cn('p-3', className)}>\n <pre className=\"text-xs leading-tight text-red-500\">\n {queryResult.error?.message ?? 'Unknown error'}\n </pre>\n </div>\n );\n }\n\n return (\n <div className={cn('flex h-full flex-col', className)}>\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n <DataTablePaginated\n {...arrowTableData}\n fontSize=\"text-xs\"\n isFetching={queryResult.isLoading}\n footerActions={\n <QueryResultLimitSelect\n value={limit}\n onChange={setLimit}\n options={limitOptions}\n />\n }\n />\n </div>\n </div>\n );\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqlrooms/sql-editor",
3
- "version": "0.27.0",
3
+ "version": "0.28.0-rc.0",
4
4
  "author": "SQLRooms Contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,14 +29,14 @@
29
29
  "@hookform/resolvers": "^5.0.0",
30
30
  "@monaco-editor/react": "^4.7.0",
31
31
  "@paralleldrive/cuid2": "^3.0.0",
32
- "@sqlrooms/data-table": "0.27.0",
33
- "@sqlrooms/duckdb": "0.27.0",
34
- "@sqlrooms/monaco-editor": "0.27.0",
35
- "@sqlrooms/room-shell": "0.27.0",
36
- "@sqlrooms/schema-tree": "0.27.0",
37
- "@sqlrooms/sql-editor-config": "0.27.0",
38
- "@sqlrooms/ui": "0.27.0",
39
- "@sqlrooms/utils": "0.27.0",
32
+ "@sqlrooms/data-table": "0.28.0-rc.0",
33
+ "@sqlrooms/duckdb": "0.28.0-rc.0",
34
+ "@sqlrooms/monaco-editor": "0.28.0-rc.0",
35
+ "@sqlrooms/room-shell": "0.28.0-rc.0",
36
+ "@sqlrooms/schema-tree": "0.28.0-rc.0",
37
+ "@sqlrooms/sql-editor-config": "0.28.0-rc.0",
38
+ "@sqlrooms/ui": "0.28.0-rc.0",
39
+ "@sqlrooms/utils": "0.28.0-rc.0",
40
40
  "@tanstack/react-table": "^8.21.3",
41
41
  "d3-dsv": "^3.0.1",
42
42
  "file-saver": "^2.0.5",
@@ -58,5 +58,5 @@
58
58
  "@types/react": "^19.1.13",
59
59
  "@types/react-dom": "^19.1.9"
60
60
  },
61
- "gitHead": "f215995ab4adeac4c58171739261a15cbba9e82b"
61
+ "gitHead": "87a478edbff690e04c38cc717db8e11e844565c8"
62
62
  }