@sqlrooms/sql-editor 0.26.0 → 0.26.1-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/README.md +1 -0
- package/dist/SqlEditor.d.ts.map +1 -1
- package/dist/SqlEditor.js +1 -3
- package/dist/SqlEditor.js.map +1 -1
- package/dist/SqlMonacoEditor.d.ts.map +1 -1
- package/dist/SqlMonacoEditor.js +12 -7
- package/dist/SqlMonacoEditor.js.map +1 -1
- package/dist/components/QueryEditorPanelTabsList.d.ts.map +1 -1
- package/dist/components/QueryEditorPanelTabsList.js +48 -10
- package/dist/components/QueryEditorPanelTabsList.js.map +1 -1
- package/package.json +15 -14
package/README.md
CHANGED
package/dist/SqlEditor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAEL,wBAAwB,EACzB,MAAM,kCAAkC,CAAC;AAE1C,MAAM,MAAM,cAAc,GAAG;IAC3B;;0EAEsE;IACtE,MAAM,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC5C,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,IAAI,CACrB,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,EAC7C,YAAY,GAAG,kBAAkB,CAClC,CAAC;IACF,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAEL,wBAAwB,EACzB,MAAM,kCAAkC,CAAC;AAE1C,MAAM,MAAM,cAAc,GAAG;IAC3B;;0EAEsE;IACtE,MAAM,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC5C,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,IAAI,CACrB,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,EAC7C,YAAY,GAAG,kBAAkB,CAClC,CAAC;IACF,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,SAAS,4CAwFb,CAAC;AAEH,eAAe,SAAS,CAAC"}
|
package/dist/SqlEditor.js
CHANGED
|
@@ -30,9 +30,7 @@ const SqlEditor = React.memo((props) => {
|
|
|
30
30
|
const handleCreateTable = useCallback(() => {
|
|
31
31
|
setCreateTableModalOpen(true);
|
|
32
32
|
}, []);
|
|
33
|
-
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,
|
|
34
|
-
// this is for Monaco's completion menu to not being cut off
|
|
35
|
-
className: "!overflow-visible", 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: lastQueryStatement, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), onAddOrUpdateSqlQuery: addOrUpdateSqlQueryDataSource })] }));
|
|
33
|
+
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: lastQueryStatement, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), onAddOrUpdateSqlQuery: addOrUpdateSqlQueryDataSource })] }));
|
|
36
34
|
});
|
|
37
35
|
export default SqlEditor;
|
|
38
36
|
//# sourceMappingURL=SqlEditor.js.map
|
package/dist/SqlEditor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EACL,MAAM,EACN,eAAe,EACf,cAAc,EACd,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,EAAC,WAAW,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,mBAAmB,GAEpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAsBvD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAiB,CAAC,KAAK,EAAE,EAAE;IACrD,MAAM,EAAC,MAAM,GAAG,GAAG,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,GAAG,KAAK,CAAC;IAEnE,eAAe;IACf,MAAM,6BAA6B,GAAG,qBAAqB,CACzD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CACpD,CAAC;IACF,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CACrD,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,KAAK,SAAS;QAC7C,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,KAAK,QAAQ;QACxC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,kBAAkB;QAC5C,CAAC,CAAC,EAAE,CACP,CAAC;IACF,oDAAoD;IACpD,mCAAmC;IACnC,KAAK;IAEL,WAAW;IACX,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExE,WAAW;IACX,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,IAAa,EAAE,EAAE;QACrD,WAAW,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QACzC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,eAAK,SAAS,EAAC,sDAAsD,aACnE,KAAC,eAAe,IACd,KAAK,EAAC,YAAY,EAClB,QAAQ,EAAE,QAAQ,EAClB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,gBAAgB,GAC9B,EACF,cAAK,SAAS,EAAC,2BAA2B,YACxC,MAAC,mBAAmB,IAAC,SAAS,EAAC,YAAY,EAAC,SAAS,EAAC,QAAQ,aAC5D,KAAC,cAAc,IAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,YAC9C,MAAC,mBAAmB,IAAC,SAAS,EAAC,UAAU,EAAC,SAAS,EAAC,QAAQ,aAC1D,KAAC,cAAc,IAAC,WAAW,EAAE,EAAE,EAAE,SAAS,EAAC,eAAe,YACxD,MAAC,mBAAmB,IAAC,SAAS,EAAC,YAAY,aACzC,KAAC,cAAc,IAAC,WAAW,EAAE,EAAE,YAC7B,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,GAAI,GACxB,EACjB,KAAC,eAAe,IAAC,UAAU,SAAG,EAC9B,KAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {useBaseRoomShellStore} from '@sqlrooms/room-shell';\nimport {\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';\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 // Store access\n const addOrUpdateSqlQueryDataSource = useBaseRoomShellStore(\n (state) => state.room.addOrUpdateSqlQueryDataSource,\n );\n const lastQueryStatement = useStoreWithSqlEditor((s) =>\n s.sqlEditor.queryResult?.status === 'success' &&\n s.sqlEditor.queryResult?.type === 'select'\n ? s.sqlEditor.queryResult.lastQueryStatement\n : '',\n );\n // const currentQuery = useStoreWithSqlEditor((s) =>\n // s.sqlEditor.getCurrentQuery(),\n // );\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={lastQueryStatement}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\n />\n </div>\n );\n});\n\nexport default SqlEditor;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAQ/D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAGjE,MAAM,WAAW,oBACf,SAAQ,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC;IAC3C,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM;QACvB,YAAY,EAAE,SAAS,EAAE,CAAC;KAC3B,CAAC;CACH;AAQD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAyQ1D,CAAC"}
|
package/dist/SqlMonacoEditor.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
3
|
import { MonacoEditor } from '@sqlrooms/monaco-editor';
|
|
4
4
|
import { DUCKDB_KEYWORDS, DUCKDB_FUNCTIONS, SQL_LANGUAGE_CONFIGURATION, } from './constants/duckdb-dialect';
|
|
5
5
|
import { cn } from '@sqlrooms/ui';
|
|
6
6
|
import { getFunctionSuggestions } from './constants/functionSuggestions';
|
|
7
|
+
const EDITOR_OPTIONS = {
|
|
8
|
+
formatOnPaste: true,
|
|
9
|
+
formatOnType: true,
|
|
10
|
+
wordWrap: 'on',
|
|
11
|
+
};
|
|
7
12
|
/**
|
|
8
13
|
* A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
|
|
9
14
|
* This is an internal component used by SqlEditor
|
|
10
15
|
*/
|
|
11
|
-
export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunctions = [], tableSchemas = [], getLatestSchemas, onMount, className, ...
|
|
16
|
+
export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunctions = [], tableSchemas = [], getLatestSchemas, onMount, className, options, ...restProps }) => {
|
|
12
17
|
// Store references to editor and monaco
|
|
13
18
|
const editorRef = useRef(null);
|
|
14
19
|
const monacoRef = useRef(null);
|
|
@@ -209,10 +214,10 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
209
214
|
onMount(editor, monaco);
|
|
210
215
|
}
|
|
211
216
|
}, [customKeywords, customFunctions, onMount, registerCompletionProvider]);
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
const combinedOptions = useMemo(() => ({
|
|
218
|
+
...EDITOR_OPTIONS,
|
|
219
|
+
...options,
|
|
220
|
+
}), [options]);
|
|
221
|
+
return (_jsx(MonacoEditor, { language: "sql", onMount: handleEditorDidMount, className: cn('h-full', className), options: combinedOptions, ...restProps }));
|
|
217
222
|
};
|
|
218
223
|
//# sourceMappingURL=SqlMonacoEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useRef} from 'react';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport type {OnMount} from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor';\nimport {\n DUCKDB_KEYWORDS,\n DUCKDB_FUNCTIONS,\n SQL_LANGUAGE_CONFIGURATION,\n} from './constants/duckdb-dialect';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {getFunctionSuggestions} from './constants/functionSuggestions';\nexport interface SqlMonacoEditorProps\n extends Omit<MonacoEditorProps, 'language'> {\n connector?: DuckDbConnector;\n /**\n * Custom SQL keywords to add to the completion provider\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n */\n tableSchemas?: DataTable[];\n /**\n * Callback to get the latest table schemas\n * This is called from within provideCompletionItems to ensure we have the latest data\n */\n getLatestSchemas?: () => {\n tableSchemas: DataTable[];\n };\n}\n\n/**\n * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion\n * This is an internal component used by SqlEditor\n */\nexport const SqlMonacoEditor: React.FC<SqlMonacoEditorProps> = ({\n connector,\n customKeywords = [],\n customFunctions = [],\n tableSchemas = [],\n getLatestSchemas,\n onMount,\n className,\n ...props\n}) => {\n // Store references to editor and monaco\n const editorRef = useRef<any>(null);\n const monacoRef = useRef<any>(null);\n const disposableRef = useRef<any>(null);\n\n // Function to register the completion provider\n const registerCompletionProvider = useCallback(() => {\n if (!editorRef.current || !monacoRef.current) return;\n\n const monaco = monacoRef.current;\n\n // Dispose previous provider if it exists\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n\n // Register SQL completion provider\n const disposable = monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: async (model: any, position: any) => {\n try {\n // Get the latest schemas if the callback is provided\n let currentSchemas = tableSchemas;\n\n if (getLatestSchemas) {\n const latest = getLatestSchemas();\n currentSchemas = latest.tableSchemas;\n }\n\n const suggestions: Monaco.languages.CompletionItem[] = [];\n const word = model.getWordUntilPosition(position);\n const range = {\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n };\n\n // Get the text before the cursor to determine context\n const lineContent = model.getLineContent(position.lineNumber);\n const textBeforeCursor = lineContent\n .substring(0, position.column - 1)\n .trim()\n .toLowerCase();\n\n // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions\n const isTableContext = /\\b(from|join|into|update|table)\\s+\\w*$/.test(\n textBeforeCursor,\n );\n\n // Check if we're after a table name and period to prioritize column suggestions\n const isColumnContext = /\\b(\\w+)\\.\\w*$/.test(textBeforeCursor);\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Add keyword suggestions (if not in a specific context)\n if (!isColumnContext) {\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n kind: monaco.languages.CompletionItemKind.Keyword,\n insertText: keyword,\n range: range,\n detail: 'Keyword',\n sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context\n });\n });\n }\n\n // Add function suggestions (if not in a specific context)\n if (!isColumnContext) {\n functions.forEach((func) => {\n suggestions.push({\n label: func,\n kind: monaco.languages.CompletionItemKind.Function,\n insertText: func,\n range: range,\n detail: 'Function',\n sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context\n });\n });\n if (connector) {\n const functionSuggestions = await getFunctionSuggestions(\n connector,\n word.word,\n );\n for (const {name, documentation} of functionSuggestions) {\n suggestions.push({\n label: name,\n insertText: name,\n documentation: {\n value: documentation,\n isTrusted: true,\n supportHtml: true,\n },\n range: range,\n kind: monaco.languages.CompletionItemKind.Function,\n sortText: isTableContext ? 'z' + name : 'b' + name, // Lower priority in table context\n });\n }\n }\n }\n\n // Add table and column suggestions from schemas\n currentSchemas.forEach((table) => {\n const tableName = table.tableName;\n\n // Add table suggestion\n suggestions.push({\n label: tableName,\n kind: monaco.languages.CompletionItemKind.Class,\n insertText: tableName,\n range: range,\n detail: 'Table',\n documentation: {\n value: `Table: ${tableName}`,\n isTrusted: true,\n },\n sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context\n });\n\n // Extract table name from context if we're in a column context\n let contextTableName = '';\n if (isColumnContext) {\n const match = textBeforeCursor.match(/\\b(\\w+)\\.\\w*$/);\n if (match && match[1]) {\n contextTableName = match[1];\n }\n }\n\n // Only add columns for the current table if we're in a column context\n if (!isColumnContext || contextTableName === tableName) {\n // Add column suggestions\n table.columns.forEach((column) => {\n const columnName = column.name;\n const columnType = column.type;\n\n suggestions.push({\n label: columnName,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: columnName,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText:\n isColumnContext && contextTableName === tableName\n ? 'a' + columnName\n : 'd' + columnName,\n });\n\n // Only add table.column suggestions if not in a column context\n if (!isColumnContext) {\n suggestions.push({\n label: `${tableName}.${columnName}`,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: `${tableName}.${columnName}`,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {\n suggestions,\n };\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n\n // Store the disposable to clean up later\n disposableRef.current = disposable;\n }, [customKeywords, customFunctions, tableSchemas, getLatestSchemas]);\n\n // Re-register completion provider when tableSchemas change\n useEffect(() => {\n if (editorRef.current && monacoRef.current) {\n registerCompletionProvider();\n }\n }, [tableSchemas, registerCompletionProvider]);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n // Store references\n editorRef.current = editor;\n monacoRef.current = monaco;\n\n // Register SQL language if not already registered\n if (\n !monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')\n ) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Set the language configuration\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords,\n builtinFunctions: functions,\n } as any); // Using 'as any' to bypass the type checking issue\n\n // Register the completion provider\n registerCompletionProvider();\n\n // Store the disposable to clean up later if needed\n editor.onDidDispose(() => {\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n });\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [customKeywords, customFunctions, onMount, registerCompletionProvider],\n );\n\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={cn('h-full', className)}\n options={{\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n }}\n {...props}\n />\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport type {OnMount} from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor';\nimport {\n DUCKDB_KEYWORDS,\n DUCKDB_FUNCTIONS,\n SQL_LANGUAGE_CONFIGURATION,\n} from './constants/duckdb-dialect';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {getFunctionSuggestions} from './constants/functionSuggestions';\nexport interface SqlMonacoEditorProps\n extends Omit<MonacoEditorProps, 'language'> {\n connector?: DuckDbConnector;\n /**\n * Custom SQL keywords to add to the completion provider\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n */\n tableSchemas?: DataTable[];\n /**\n * Callback to get the latest table schemas\n * This is called from within provideCompletionItems to ensure we have the latest data\n */\n getLatestSchemas?: () => {\n tableSchemas: DataTable[];\n };\n}\n\nconst EDITOR_OPTIONS: MonacoEditorProps['options'] = {\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n};\n\n/**\n * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion\n * This is an internal component used by SqlEditor\n */\nexport const SqlMonacoEditor: React.FC<SqlMonacoEditorProps> = ({\n connector,\n customKeywords = [],\n customFunctions = [],\n tableSchemas = [],\n getLatestSchemas,\n onMount,\n className,\n options,\n ...restProps\n}) => {\n // Store references to editor and monaco\n const editorRef = useRef<any>(null);\n const monacoRef = useRef<any>(null);\n const disposableRef = useRef<any>(null);\n\n // Function to register the completion provider\n const registerCompletionProvider = useCallback(() => {\n if (!editorRef.current || !monacoRef.current) return;\n\n const monaco = monacoRef.current;\n\n // Dispose previous provider if it exists\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n\n // Register SQL completion provider\n const disposable = monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: async (model: any, position: any) => {\n try {\n // Get the latest schemas if the callback is provided\n let currentSchemas = tableSchemas;\n\n if (getLatestSchemas) {\n const latest = getLatestSchemas();\n currentSchemas = latest.tableSchemas;\n }\n\n const suggestions: Monaco.languages.CompletionItem[] = [];\n const word = model.getWordUntilPosition(position);\n const range = {\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n };\n\n // Get the text before the cursor to determine context\n const lineContent = model.getLineContent(position.lineNumber);\n const textBeforeCursor = lineContent\n .substring(0, position.column - 1)\n .trim()\n .toLowerCase();\n\n // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions\n const isTableContext = /\\b(from|join|into|update|table)\\s+\\w*$/.test(\n textBeforeCursor,\n );\n\n // Check if we're after a table name and period to prioritize column suggestions\n const isColumnContext = /\\b(\\w+)\\.\\w*$/.test(textBeforeCursor);\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Add keyword suggestions (if not in a specific context)\n if (!isColumnContext) {\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n kind: monaco.languages.CompletionItemKind.Keyword,\n insertText: keyword,\n range: range,\n detail: 'Keyword',\n sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context\n });\n });\n }\n\n // Add function suggestions (if not in a specific context)\n if (!isColumnContext) {\n functions.forEach((func) => {\n suggestions.push({\n label: func,\n kind: monaco.languages.CompletionItemKind.Function,\n insertText: func,\n range: range,\n detail: 'Function',\n sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context\n });\n });\n if (connector) {\n const functionSuggestions = await getFunctionSuggestions(\n connector,\n word.word,\n );\n for (const {name, documentation} of functionSuggestions) {\n suggestions.push({\n label: name,\n insertText: name,\n documentation: {\n value: documentation,\n isTrusted: true,\n supportHtml: true,\n },\n range: range,\n kind: monaco.languages.CompletionItemKind.Function,\n sortText: isTableContext ? 'z' + name : 'b' + name, // Lower priority in table context\n });\n }\n }\n }\n\n // Add table and column suggestions from schemas\n currentSchemas.forEach((table) => {\n const tableName = table.tableName;\n\n // Add table suggestion\n suggestions.push({\n label: tableName,\n kind: monaco.languages.CompletionItemKind.Class,\n insertText: tableName,\n range: range,\n detail: 'Table',\n documentation: {\n value: `Table: ${tableName}`,\n isTrusted: true,\n },\n sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context\n });\n\n // Extract table name from context if we're in a column context\n let contextTableName = '';\n if (isColumnContext) {\n const match = textBeforeCursor.match(/\\b(\\w+)\\.\\w*$/);\n if (match && match[1]) {\n contextTableName = match[1];\n }\n }\n\n // Only add columns for the current table if we're in a column context\n if (!isColumnContext || contextTableName === tableName) {\n // Add column suggestions\n table.columns.forEach((column) => {\n const columnName = column.name;\n const columnType = column.type;\n\n suggestions.push({\n label: columnName,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: columnName,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText:\n isColumnContext && contextTableName === tableName\n ? 'a' + columnName\n : 'd' + columnName,\n });\n\n // Only add table.column suggestions if not in a column context\n if (!isColumnContext) {\n suggestions.push({\n label: `${tableName}.${columnName}`,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: `${tableName}.${columnName}`,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {\n suggestions,\n };\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n\n // Store the disposable to clean up later\n disposableRef.current = disposable;\n }, [customKeywords, customFunctions, tableSchemas, getLatestSchemas]);\n\n // Re-register completion provider when tableSchemas change\n useEffect(() => {\n if (editorRef.current && monacoRef.current) {\n registerCompletionProvider();\n }\n }, [tableSchemas, registerCompletionProvider]);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n // Store references\n editorRef.current = editor;\n monacoRef.current = monaco;\n\n // Register SQL language if not already registered\n if (\n !monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')\n ) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Set the language configuration\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords,\n builtinFunctions: functions,\n } as any); // Using 'as any' to bypass the type checking issue\n\n // Register the completion provider\n registerCompletionProvider();\n\n // Store the disposable to clean up later if needed\n editor.onDidDispose(() => {\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n });\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [customKeywords, customFunctions, onMount, registerCompletionProvider],\n );\n\n const combinedOptions = useMemo(\n (): MonacoEditorProps['options'] => ({\n ...EDITOR_OPTIONS,\n ...options,\n }),\n [options],\n );\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={cn('h-full', className)}\n options={combinedOptions}\n {...restProps}\n />\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryEditorPanelTabsList.d.ts","sourceRoot":"","sources":["../../src/components/QueryEditorPanelTabsList.tsx"],"names":[],"mappings":"AAgBA,OAAO,
|
|
1
|
+
{"version":3,"file":"QueryEditorPanelTabsList.d.ts","sourceRoot":"","sources":["../../src/components/QueryEditorPanelTabsList.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAM/E,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAC,CAoUnE,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Button, cn, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, EditableText, Input, TabsList, TabsTrigger, } from '@sqlrooms/ui';
|
|
3
3
|
import { ListCollapseIcon, PlusIcon, XIcon, SearchIcon } from 'lucide-react';
|
|
4
|
-
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import { useStoreWithSqlEditor } from '../SqlEditorSlice';
|
|
6
6
|
import DeleteSqlQueryModal from './DeleteSqlQueryModal';
|
|
7
7
|
import { QueryTabMenuItem } from './QueryTabMenuItem';
|
|
@@ -9,6 +9,7 @@ import RenameSqlQueryModal from './RenameSqlQueryModal';
|
|
|
9
9
|
export const QueryEditorPanelTabsList = ({ className, }) => {
|
|
10
10
|
const queries = useStoreWithSqlEditor((s) => s.sqlEditor.config.queries);
|
|
11
11
|
const closedTabIds = useStoreWithSqlEditor((s) => s.sqlEditor.config.closedTabIds);
|
|
12
|
+
const selectedQueryId = useStoreWithSqlEditor((s) => s.sqlEditor.config.selectedQueryId);
|
|
12
13
|
const openedTabs = queries.filter((q) => !closedTabIds.includes(q.id));
|
|
13
14
|
const closedTabs = queries.filter((q) => closedTabIds.includes(q.id));
|
|
14
15
|
const renameQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.renameQueryTab);
|
|
@@ -19,6 +20,8 @@ export const QueryEditorPanelTabsList = ({ className, }) => {
|
|
|
19
20
|
const [searchQuery, setSearchQuery] = useState('');
|
|
20
21
|
// Ref for the scrollable container
|
|
21
22
|
const scrollContainerRef = useRef(null);
|
|
23
|
+
// Track previous selectedQueryId to only scroll when it actually changes
|
|
24
|
+
const prevSelectedQueryIdRef = useRef(null);
|
|
22
25
|
const closeQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.closeQueryTab);
|
|
23
26
|
const openQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.openQueryTab);
|
|
24
27
|
const createQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.createQueryTab);
|
|
@@ -60,16 +63,51 @@ export const QueryEditorPanelTabsList = ({ className, }) => {
|
|
|
60
63
|
// Handle new query creation
|
|
61
64
|
const handleNewQuery = useCallback(() => {
|
|
62
65
|
createQueryTab();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
}, [createQueryTab]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!selectedQueryId)
|
|
69
|
+
return;
|
|
70
|
+
// Only react when the selected tab actually changes
|
|
71
|
+
if (prevSelectedQueryIdRef.current === selectedQueryId)
|
|
72
|
+
return;
|
|
73
|
+
prevSelectedQueryIdRef.current = selectedQueryId;
|
|
74
|
+
const container = scrollContainerRef.current;
|
|
75
|
+
if (!container)
|
|
76
|
+
return;
|
|
77
|
+
// Only scroll if the selected tab is still open
|
|
78
|
+
const isOpened = openedTabs.some((tab) => tab.id === selectedQueryId);
|
|
79
|
+
if (!isOpened)
|
|
80
|
+
return;
|
|
81
|
+
// After the DOM is painted
|
|
82
|
+
const frameId = requestAnimationFrame(() => {
|
|
83
|
+
const activeTab = container.querySelector('[data-state="active"]');
|
|
84
|
+
if (!activeTab)
|
|
85
|
+
return;
|
|
86
|
+
const visibleLeft = container.scrollLeft;
|
|
87
|
+
const visibleRight = visibleLeft + container.clientWidth;
|
|
88
|
+
const tabLeft = activeTab.offsetLeft;
|
|
89
|
+
const tabRight = tabLeft + activeTab.offsetWidth;
|
|
90
|
+
// If the tab is already fully visible, don't scroll
|
|
91
|
+
if (tabLeft >= visibleLeft && tabRight <= visibleRight)
|
|
92
|
+
return;
|
|
93
|
+
let newScrollLeft = visibleLeft;
|
|
94
|
+
if (tabLeft < visibleLeft) {
|
|
95
|
+
newScrollLeft = Math.max(0, tabLeft - 10);
|
|
96
|
+
}
|
|
97
|
+
else if (tabRight > visibleRight) {
|
|
98
|
+
newScrollLeft = Math.min(container.scrollWidth - container.clientWidth, tabRight - container.clientWidth + 10);
|
|
99
|
+
}
|
|
100
|
+
if (newScrollLeft !== visibleLeft) {
|
|
101
|
+
container.scrollTo({
|
|
102
|
+
left: newScrollLeft,
|
|
68
103
|
behavior: 'smooth',
|
|
69
104
|
});
|
|
70
105
|
}
|
|
71
|
-
}
|
|
72
|
-
|
|
106
|
+
});
|
|
107
|
+
return () => {
|
|
108
|
+
cancelAnimationFrame(frameId);
|
|
109
|
+
};
|
|
110
|
+
}, [selectedQueryId, openedTabs]);
|
|
73
111
|
const handleConfirmDeleteQuery = useCallback(() => {
|
|
74
112
|
if (queryToDelete) {
|
|
75
113
|
deleteQueryTab(queryToDelete);
|
|
@@ -98,13 +136,13 @@ export const QueryEditorPanelTabsList = ({ className, }) => {
|
|
|
98
136
|
if (!isEditing) {
|
|
99
137
|
setEditingQueryId(null);
|
|
100
138
|
}
|
|
101
|
-
} })) }), _jsx(Button, { size: "xs", variant: "ghost", className: "hover:bg-primary/10 h-4 w-4 p-1", onMouseDown: (e) => {
|
|
139
|
+
} })) }), _jsx(Button, { asChild: true, size: "xs", variant: "ghost", className: "hover:bg-primary/10 h-4 w-4 p-1", onMouseDown: (e) => {
|
|
102
140
|
e.stopPropagation();
|
|
103
141
|
e.preventDefault();
|
|
104
142
|
}, onClick: (e) => {
|
|
105
143
|
e.stopPropagation();
|
|
106
144
|
e.preventDefault();
|
|
107
145
|
closeQueryTab(q.id);
|
|
108
|
-
}, children: _jsx(XIcon, {
|
|
146
|
+
}, children: _jsx(XIcon, { className: "h-5 w-5" }) })] }, q.id))) }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "icon", variant: "ghost", className: "ml-2 h-5 w-5 flex-shrink-0", children: _jsx(ListCollapseIcon, { className: "h-4 w-4" }) }) }), _jsxs(DropdownMenuContent, { onCloseAutoFocus: (e) => e.preventDefault(), className: "max-h-[400px] max-w-[240px] overflow-y-auto", children: [_jsxs("div", { className: "flex items-center gap-1 px-2", children: [_jsx(SearchIcon, { className: "text-muted-foreground", size: 14 }), _jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: (e) => e.stopPropagation(), onKeyUp: (e) => e.stopPropagation(), className: "border-none text-xs shadow-none focus-visible:ring-0", placeholder: "Search..." })] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuGroup, { children: [_jsx(DropdownMenuLabel, { className: "text-muted-foreground text-xs font-normal", children: "Closed" }), renderTabGroup(filteredClosedTabs, 'No closed tabs')] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuGroup, { children: [_jsx(DropdownMenuLabel, { className: "text-muted-foreground text-xs font-normal", children: "Opened" }), renderTabGroup(filteredOpenedTabs, 'No opened tabs')] })] })] }), _jsx(Button, { size: "icon", variant: "ghost", onClick: handleNewQuery, className: "h-5 w-5 flex-shrink-0", children: _jsx(PlusIcon, { className: "h-4 w-4" }) })] }), _jsx(DeleteSqlQueryModal, { isOpen: queryToDelete !== null, onClose: () => setQueryToDelete(null), onConfirm: handleConfirmDeleteQuery }), _jsx(RenameSqlQueryModal, { isOpen: queryToRename !== null, onClose: () => setQueryToRename(null), initialName: queryToRename?.name ?? '', onRename: handleFinishRename })] }));
|
|
109
147
|
};
|
|
110
148
|
//# sourceMappingURL=QueryEditorPanelTabsList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryEditorPanelTabsList.js","sourceRoot":"","sources":["../../src/components/QueryEditorPanelTabsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n cn,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n EditableText,\n Input,\n TabsList,\n TabsTrigger,\n} from '@sqlrooms/ui';\nimport {ListCollapseIcon, PlusIcon, XIcon, SearchIcon} from 'lucide-react';\nimport React, {useCallback, useMemo, useRef, useState} from 'react';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport DeleteSqlQueryModal from './DeleteSqlQueryModal';\nimport {QueryTabMenuItem} from './QueryTabMenuItem';\nimport RenameSqlQueryModal from './RenameSqlQueryModal';\n\nexport const QueryEditorPanelTabsList: React.FC<{className?: string}> = ({\n className,\n}) => {\n const queries = useStoreWithSqlEditor((s) => s.sqlEditor.config.queries);\n const closedTabIds = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.closedTabIds,\n );\n const openedTabs = queries.filter((q) => !closedTabIds.includes(q.id));\n const closedTabs = queries.filter((q) => closedTabIds.includes(q.id));\n\n const renameQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.renameQueryTab,\n );\n\n // Local state for modals and editing\n const [queryToDelete, setQueryToDelete] = useState<string | null>(null);\n const [editingQueryId, setEditingQueryId] = useState<string | null>(null);\n const [queryToRename, setQueryToRename] = useState<{\n id: string;\n name: string;\n } | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Ref for the scrollable container\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n const closeQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.closeQueryTab);\n const openQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.openQueryTab);\n const createQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.createQueryTab,\n );\n const deleteQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.deleteQueryTab,\n );\n\n // Handle rename query\n const handleStartRename = useCallback(\n (queryId: string, currentName: string) => {\n setQueryToRename({id: queryId, name: currentName});\n },\n [],\n );\n\n const handleFinishRename = useCallback(\n (newName: string) => {\n if (queryToRename) {\n renameQueryTab(queryToRename.id, newName);\n }\n setQueryToRename(null);\n },\n [queryToRename, renameQueryTab],\n );\n // Handle rename query\n const handleRename = useCallback(\n (queryId: string, newName: string) => {\n if (newName.trim() !== '') {\n renameQueryTab(queryId, newName.trim());\n }\n setEditingQueryId(null);\n },\n [renameQueryTab],\n );\n\n // Handle double click to start editing\n const handleDoubleClick = useCallback((queryId: string) => {\n setEditingQueryId(queryId);\n }, []);\n\n // Handle delete query\n const handleDeleteQuery = useCallback(\n (queryId: string) => {\n // Find the query to check if it's empty\n const queryToDelete = queries.find((q) => q.id === queryId);\n\n // If query is empty (no content), delete immediately without confirmation\n if (queryToDelete && queryToDelete.query.trim() === '') {\n deleteQueryTab(queryId);\n } else {\n // Otherwise, show confirmation modal\n setQueryToDelete(queryId);\n }\n },\n [queries, deleteQueryTab],\n );\n\n // Handle new query creation\n const handleNewQuery = useCallback(() => {\n createQueryTab();\n // Auto-scroll to the right after a short delay to ensure the tab is rendered\n setTimeout(() => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollTo({\n left: scrollContainerRef.current.scrollWidth,\n behavior: 'smooth',\n });\n }\n }, 0);\n }, [createQueryTab]);\n\n const handleConfirmDeleteQuery = useCallback(() => {\n if (queryToDelete) {\n deleteQueryTab(queryToDelete);\n setQueryToDelete(null);\n }\n }, [queryToDelete, deleteQueryTab]);\n\n const filteredClosedTabs = useMemo(() => {\n if (!searchQuery.trim()) return closedTabs;\n const lowerQuery = searchQuery.toLowerCase();\n return closedTabs.filter((tab) =>\n tab.name.toLowerCase().includes(lowerQuery),\n );\n }, [closedTabs, searchQuery]);\n\n const filteredOpenedTabs = useMemo(() => {\n if (!searchQuery.trim()) return openedTabs;\n const lowerQuery = searchQuery.toLowerCase();\n return openedTabs.filter((tab) =>\n tab.name.toLowerCase().includes(lowerQuery),\n );\n }, [openedTabs, searchQuery]);\n\n const renderTabGroup = useCallback(\n (tabs: typeof queries, emptyMessage: string) => {\n if (tabs.length === 0) {\n return (\n <DropdownMenuItem\n className=\"items-center justify-center text-xs\"\n disabled\n >\n {emptyMessage}\n </DropdownMenuItem>\n );\n }\n\n return tabs.map((tab) => (\n <QueryTabMenuItem\n key={tab.id}\n tab={tab}\n onRestore={() => openQueryTab(tab.id)}\n onRename={() => handleStartRename(tab.id, tab.name)}\n onDelete={() => handleDeleteQuery(tab.id)}\n />\n ));\n },\n [openQueryTab, handleStartRename, handleDeleteQuery],\n );\n\n return (\n <>\n <TabsList\n className={cn(\n 'flex min-w-0 justify-start gap-1 bg-transparent p-0 pt-1.5',\n className,\n )}\n >\n <div\n ref={scrollContainerRef}\n className=\"flex h-full min-w-0 items-center gap-1 overflow-x-auto overflow-y-hidden pr-1 [&::-webkit-scrollbar]:hidden\"\n >\n {openedTabs.map((q) => (\n <TabsTrigger\n key={q.id}\n value={q.id}\n className=\"data-[state=inactive]:hover:bg-primary/5 flex h-full min-w-[100px] max-w-[200px] flex-shrink-0 items-center justify-between gap-2 overflow-hidden rounded-b-none py-0 pl-4 pr-2 font-normal data-[state=active]:shadow-none\"\n >\n <div\n className=\"flex min-w-0 items-center\"\n onDoubleClick={() => handleDoubleClick(q.id)}\n >\n {editingQueryId !== q.id ? (\n <div className=\"truncate text-sm\">{q.name}</div>\n ) : (\n <EditableText\n value={q.name}\n onChange={(newName: string) => handleRename(q.id, newName)}\n className=\"h-6 min-w-0 flex-1 truncate text-sm shadow-none\"\n isEditing={editingQueryId === q.id}\n onEditingChange={(isEditing) => {\n if (!isEditing) {\n setEditingQueryId(null);\n }\n }}\n />\n )}\n </div>\n\n <Button\n size=\"xs\"\n variant=\"ghost\"\n className=\"hover:bg-primary/10 h-4 w-4 p-1\"\n onMouseDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n }}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n closeQueryTab(q.id);\n }}\n >\n <XIcon size={12} />\n </Button>\n </TabsTrigger>\n ))}\n </div>\n\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"ml-2 h-5 w-5 flex-shrink-0\"\n >\n <ListCollapseIcon className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent\n onCloseAutoFocus={(e) => e.preventDefault()}\n className=\"max-h-[400px] max-w-[240px] overflow-y-auto\"\n >\n <div className=\"flex items-center gap-1 px-2\">\n <SearchIcon className=\"text-muted-foreground\" size={14} />\n <Input\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => e.stopPropagation()}\n onKeyUp={(e) => e.stopPropagation()}\n className=\"border-none text-xs shadow-none focus-visible:ring-0\"\n placeholder=\"Search...\"\n />\n </div>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-muted-foreground text-xs font-normal\">\n Closed\n </DropdownMenuLabel>\n {renderTabGroup(filteredClosedTabs, 'No closed tabs')}\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-muted-foreground text-xs font-normal\">\n Opened\n </DropdownMenuLabel>\n {renderTabGroup(filteredOpenedTabs, 'No opened tabs')}\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n\n <Button\n size=\"icon\"\n variant=\"ghost\"\n onClick={handleNewQuery}\n className=\"h-5 w-5 flex-shrink-0\"\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n </TabsList>\n\n <DeleteSqlQueryModal\n isOpen={queryToDelete !== null}\n onClose={() => setQueryToDelete(null)}\n onConfirm={handleConfirmDeleteQuery}\n />\n <RenameSqlQueryModal\n isOpen={queryToRename !== null}\n onClose={() => setQueryToRename(null)}\n initialName={queryToRename?.name ?? ''}\n onRename={handleFinishRename}\n />\n </>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"QueryEditorPanelTabsList.js","sourceRoot":"","sources":["../../src/components/QueryEditorPanelTabsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n cn,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n EditableText,\n Input,\n TabsList,\n TabsTrigger,\n} from '@sqlrooms/ui';\nimport {ListCollapseIcon, PlusIcon, XIcon, SearchIcon} from 'lucide-react';\nimport React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport DeleteSqlQueryModal from './DeleteSqlQueryModal';\nimport {QueryTabMenuItem} from './QueryTabMenuItem';\nimport RenameSqlQueryModal from './RenameSqlQueryModal';\n\nexport const QueryEditorPanelTabsList: React.FC<{className?: string}> = ({\n className,\n}) => {\n const queries = useStoreWithSqlEditor((s) => s.sqlEditor.config.queries);\n const closedTabIds = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.closedTabIds,\n );\n const selectedQueryId = useStoreWithSqlEditor(\n (s) => s.sqlEditor.config.selectedQueryId,\n );\n const openedTabs = queries.filter((q) => !closedTabIds.includes(q.id));\n const closedTabs = queries.filter((q) => closedTabIds.includes(q.id));\n\n const renameQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.renameQueryTab,\n );\n\n // Local state for modals and editing\n const [queryToDelete, setQueryToDelete] = useState<string | null>(null);\n const [editingQueryId, setEditingQueryId] = useState<string | null>(null);\n const [queryToRename, setQueryToRename] = useState<{\n id: string;\n name: string;\n } | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Ref for the scrollable container\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n // Track previous selectedQueryId to only scroll when it actually changes\n const prevSelectedQueryIdRef = useRef<string | null>(null);\n\n const closeQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.closeQueryTab);\n const openQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.openQueryTab);\n const createQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.createQueryTab,\n );\n const deleteQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.deleteQueryTab,\n );\n\n // Handle rename query\n const handleStartRename = useCallback(\n (queryId: string, currentName: string) => {\n setQueryToRename({id: queryId, name: currentName});\n },\n [],\n );\n\n const handleFinishRename = useCallback(\n (newName: string) => {\n if (queryToRename) {\n renameQueryTab(queryToRename.id, newName);\n }\n setQueryToRename(null);\n },\n [queryToRename, renameQueryTab],\n );\n // Handle rename query\n const handleRename = useCallback(\n (queryId: string, newName: string) => {\n if (newName.trim() !== '') {\n renameQueryTab(queryId, newName.trim());\n }\n setEditingQueryId(null);\n },\n [renameQueryTab],\n );\n\n // Handle double click to start editing\n const handleDoubleClick = useCallback((queryId: string) => {\n setEditingQueryId(queryId);\n }, []);\n\n // Handle delete query\n const handleDeleteQuery = useCallback(\n (queryId: string) => {\n // Find the query to check if it's empty\n const queryToDelete = queries.find((q) => q.id === queryId);\n\n // If query is empty (no content), delete immediately without confirmation\n if (queryToDelete && queryToDelete.query.trim() === '') {\n deleteQueryTab(queryId);\n } else {\n // Otherwise, show confirmation modal\n setQueryToDelete(queryId);\n }\n },\n [queries, deleteQueryTab],\n );\n\n // Handle new query creation\n const handleNewQuery = useCallback(() => {\n createQueryTab();\n }, [createQueryTab]);\n\n useEffect(() => {\n if (!selectedQueryId) return;\n\n // Only react when the selected tab actually changes\n if (prevSelectedQueryIdRef.current === selectedQueryId) return;\n prevSelectedQueryIdRef.current = selectedQueryId;\n\n const container = scrollContainerRef.current;\n if (!container) return;\n\n // Only scroll if the selected tab is still open\n const isOpened = openedTabs.some((tab) => tab.id === selectedQueryId);\n if (!isOpened) return;\n\n // After the DOM is painted\n const frameId = requestAnimationFrame(() => {\n const activeTab = container.querySelector<HTMLElement>(\n '[data-state=\"active\"]',\n );\n if (!activeTab) return;\n\n const visibleLeft = container.scrollLeft;\n const visibleRight = visibleLeft + container.clientWidth;\n\n const tabLeft = activeTab.offsetLeft;\n const tabRight = tabLeft + activeTab.offsetWidth;\n\n // If the tab is already fully visible, don't scroll\n if (tabLeft >= visibleLeft && tabRight <= visibleRight) return;\n\n let newScrollLeft = visibleLeft;\n\n if (tabLeft < visibleLeft) {\n newScrollLeft = Math.max(0, tabLeft - 10);\n } else if (tabRight > visibleRight) {\n newScrollLeft = Math.min(\n container.scrollWidth - container.clientWidth,\n tabRight - container.clientWidth + 10,\n );\n }\n\n if (newScrollLeft !== visibleLeft) {\n container.scrollTo({\n left: newScrollLeft,\n behavior: 'smooth',\n });\n }\n });\n\n return () => {\n cancelAnimationFrame(frameId);\n };\n }, [selectedQueryId, openedTabs]);\n\n const handleConfirmDeleteQuery = useCallback(() => {\n if (queryToDelete) {\n deleteQueryTab(queryToDelete);\n setQueryToDelete(null);\n }\n }, [queryToDelete, deleteQueryTab]);\n\n const filteredClosedTabs = useMemo(() => {\n if (!searchQuery.trim()) return closedTabs;\n const lowerQuery = searchQuery.toLowerCase();\n return closedTabs.filter((tab) =>\n tab.name.toLowerCase().includes(lowerQuery),\n );\n }, [closedTabs, searchQuery]);\n\n const filteredOpenedTabs = useMemo(() => {\n if (!searchQuery.trim()) return openedTabs;\n const lowerQuery = searchQuery.toLowerCase();\n return openedTabs.filter((tab) =>\n tab.name.toLowerCase().includes(lowerQuery),\n );\n }, [openedTabs, searchQuery]);\n\n const renderTabGroup = useCallback(\n (tabs: typeof queries, emptyMessage: string) => {\n if (tabs.length === 0) {\n return (\n <DropdownMenuItem\n className=\"items-center justify-center text-xs\"\n disabled\n >\n {emptyMessage}\n </DropdownMenuItem>\n );\n }\n\n return tabs.map((tab) => (\n <QueryTabMenuItem\n key={tab.id}\n tab={tab}\n onRestore={() => openQueryTab(tab.id)}\n onRename={() => handleStartRename(tab.id, tab.name)}\n onDelete={() => handleDeleteQuery(tab.id)}\n />\n ));\n },\n [openQueryTab, handleStartRename, handleDeleteQuery],\n );\n\n return (\n <>\n <TabsList\n className={cn(\n 'flex min-w-0 justify-start gap-1 bg-transparent p-0 pt-1.5',\n className,\n )}\n >\n <div\n ref={scrollContainerRef}\n className=\"flex h-full min-w-0 items-center gap-1 overflow-x-auto overflow-y-hidden pr-1 [&::-webkit-scrollbar]:hidden\"\n >\n {openedTabs.map((q) => (\n <TabsTrigger\n key={q.id}\n value={q.id}\n className=\"data-[state=inactive]:hover:bg-primary/5 flex h-full min-w-[100px] max-w-[200px] flex-shrink-0 items-center justify-between gap-2 overflow-hidden rounded-b-none py-0 pl-4 pr-2 font-normal data-[state=active]:shadow-none\"\n >\n <div\n className=\"flex min-w-0 items-center\"\n onDoubleClick={() => handleDoubleClick(q.id)}\n >\n {editingQueryId !== q.id ? (\n <div className=\"truncate text-sm\">{q.name}</div>\n ) : (\n <EditableText\n value={q.name}\n onChange={(newName: string) => handleRename(q.id, newName)}\n className=\"h-6 min-w-0 flex-1 truncate text-sm shadow-none\"\n isEditing={editingQueryId === q.id}\n onEditingChange={(isEditing) => {\n if (!isEditing) {\n setEditingQueryId(null);\n }\n }}\n />\n )}\n </div>\n\n <Button\n asChild\n size=\"xs\"\n variant=\"ghost\"\n className=\"hover:bg-primary/10 h-4 w-4 p-1\"\n onMouseDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n }}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n closeQueryTab(q.id);\n }}\n >\n <XIcon className=\"h-5 w-5\" />\n </Button>\n </TabsTrigger>\n ))}\n </div>\n\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"ml-2 h-5 w-5 flex-shrink-0\"\n >\n <ListCollapseIcon className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent\n onCloseAutoFocus={(e) => e.preventDefault()}\n className=\"max-h-[400px] max-w-[240px] overflow-y-auto\"\n >\n <div className=\"flex items-center gap-1 px-2\">\n <SearchIcon className=\"text-muted-foreground\" size={14} />\n <Input\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => e.stopPropagation()}\n onKeyUp={(e) => e.stopPropagation()}\n className=\"border-none text-xs shadow-none focus-visible:ring-0\"\n placeholder=\"Search...\"\n />\n </div>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-muted-foreground text-xs font-normal\">\n Closed\n </DropdownMenuLabel>\n {renderTabGroup(filteredClosedTabs, 'No closed tabs')}\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-muted-foreground text-xs font-normal\">\n Opened\n </DropdownMenuLabel>\n {renderTabGroup(filteredOpenedTabs, 'No opened tabs')}\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n\n <Button\n size=\"icon\"\n variant=\"ghost\"\n onClick={handleNewQuery}\n className=\"h-5 w-5 flex-shrink-0\"\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n </TabsList>\n\n <DeleteSqlQueryModal\n isOpen={queryToDelete !== null}\n onClose={() => setQueryToDelete(null)}\n onConfirm={handleConfirmDeleteQuery}\n />\n <RenameSqlQueryModal\n isOpen={queryToRename !== null}\n onClose={() => setQueryToRename(null)}\n initialName={queryToRename?.name ?? ''}\n onRename={handleFinishRename}\n />\n </>\n );\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/sql-editor",
|
|
3
|
-
"version": "0.26.0",
|
|
3
|
+
"version": "0.26.1-rc.0",
|
|
4
4
|
"author": "Ilya Boyandin <ilya@boyandin.me>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,21 +28,21 @@
|
|
|
28
28
|
"@hookform/resolvers": "^3.10.0",
|
|
29
29
|
"@monaco-editor/react": "^4.7.0",
|
|
30
30
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
31
|
-
"@sqlrooms/data-table": "0.26.0",
|
|
32
|
-
"@sqlrooms/duckdb": "0.26.0",
|
|
33
|
-
"@sqlrooms/layout": "0.26.0",
|
|
34
|
-
"@sqlrooms/monaco-editor": "0.26.0",
|
|
35
|
-
"@sqlrooms/room-config": "0.26.0",
|
|
36
|
-
"@sqlrooms/room-shell": "0.26.0",
|
|
37
|
-
"@sqlrooms/schema-tree": "0.26.0",
|
|
38
|
-
"@sqlrooms/sql-editor-config": "0.26.0",
|
|
39
|
-
"@sqlrooms/ui": "0.26.0",
|
|
40
|
-
"@sqlrooms/utils": "0.26.0",
|
|
31
|
+
"@sqlrooms/data-table": "0.26.1-rc.0",
|
|
32
|
+
"@sqlrooms/duckdb": "0.26.1-rc.0",
|
|
33
|
+
"@sqlrooms/layout": "0.26.1-rc.0",
|
|
34
|
+
"@sqlrooms/monaco-editor": "0.26.1-rc.0",
|
|
35
|
+
"@sqlrooms/room-config": "0.26.1-rc.0",
|
|
36
|
+
"@sqlrooms/room-shell": "0.26.1-rc.0",
|
|
37
|
+
"@sqlrooms/schema-tree": "0.26.1-rc.0",
|
|
38
|
+
"@sqlrooms/sql-editor-config": "0.26.1-rc.0",
|
|
39
|
+
"@sqlrooms/ui": "0.26.1-rc.0",
|
|
40
|
+
"@sqlrooms/utils": "0.26.1-rc.0",
|
|
41
41
|
"@tanstack/react-table": "^8.21.3",
|
|
42
42
|
"d3-dsv": "^3.0.1",
|
|
43
43
|
"file-saver": "^2.0.5",
|
|
44
44
|
"immer": "^10.1.3",
|
|
45
|
-
"lucide-react": "^0.
|
|
45
|
+
"lucide-react": "^0.555.0",
|
|
46
46
|
"monaco-editor": "^0.52.2",
|
|
47
47
|
"react-hook-form": "^7.63.0",
|
|
48
48
|
"zod": "^4.1.8",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"apache-arrow": ">=17",
|
|
53
53
|
"react": ">=18",
|
|
54
|
-
"react-dom": ">=18"
|
|
54
|
+
"react-dom": ">=18",
|
|
55
|
+
"react-hook-form": "^7.57.0"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/d3-dsv": "^3.0.7",
|
|
@@ -59,5 +60,5 @@
|
|
|
59
60
|
"@types/react": "^19.1.13",
|
|
60
61
|
"@types/react-dom": "^19.1.9"
|
|
61
62
|
},
|
|
62
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "89c252c460ccd29d108cfabf7b34c4a679f85609"
|
|
63
64
|
}
|