@sqlrooms/sql-editor 0.8.1 → 0.9.1
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 +217 -189
- package/dist/CreateTableModal.d.ts +1 -1
- package/dist/CreateTableModal.d.ts.map +1 -1
- package/dist/CreateTableModal.js +1 -5
- package/dist/CreateTableModal.js.map +1 -1
- package/dist/SqlEditor.js +2 -2
- package/dist/SqlEditor.js.map +1 -1
- package/dist/SqlEditorSlice.d.ts +4 -4
- package/dist/SqlEditorSlice.d.ts.map +1 -1
- package/dist/SqlEditorSlice.js +8 -11
- package/dist/SqlEditorSlice.js.map +1 -1
- package/dist/SqlQueryDataSourcesPanel.d.ts +2 -1
- package/dist/SqlQueryDataSourcesPanel.d.ts.map +1 -1
- package/dist/SqlQueryDataSourcesPanel.js +5 -7
- package/dist/SqlQueryDataSourcesPanel.js.map +1 -1
- package/dist/hooks/useTableManagement.js +2 -2
- package/dist/hooks/useTableManagement.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -22,72 +22,115 @@ npm install @sqlrooms/sql-editor
|
|
|
22
22
|
|
|
23
23
|
## Basic Usage
|
|
24
24
|
|
|
25
|
-
###
|
|
25
|
+
### SqlEditor and SqlEditorModal Components
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
These components must be used within a `ProjectBuilderProvider` context as they rely on the SQLRooms store:
|
|
28
28
|
|
|
29
29
|
```tsx
|
|
30
|
-
import {
|
|
30
|
+
import {ProjectBuilderProvider} from '@sqlrooms/project-builder';
|
|
31
|
+
import {SqlEditorModal} from '@sqlrooms/sql-editor';
|
|
31
32
|
import {useDisclosure} from '@sqlrooms/ui';
|
|
33
|
+
import {projectStore} from './store';
|
|
32
34
|
|
|
33
35
|
function MyApp() {
|
|
34
|
-
const {isOpen, onOpen, onClose} = useDisclosure(
|
|
36
|
+
const {isOpen, onOpen, onClose} = useDisclosure();
|
|
35
37
|
|
|
36
38
|
return (
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
{isOpen ?
|
|
40
|
-
|
|
39
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
40
|
+
<div className="my-app">
|
|
41
|
+
<button onClick={isOpen ? onClose : onOpen}>
|
|
42
|
+
{isOpen ? 'Hide' : 'Show'} SQL Editor
|
|
43
|
+
</button>
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
<SqlEditorModal isOpen={isOpen} onClose={onClose} />
|
|
46
|
+
</div>
|
|
47
|
+
</ProjectBuilderProvider>
|
|
44
48
|
);
|
|
45
49
|
}
|
|
46
50
|
```
|
|
47
51
|
|
|
48
|
-
###
|
|
52
|
+
### Store Setup for SQL Editor
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
The SQL Editor requires a properly configured store with the SQL Editor slice:
|
|
51
55
|
|
|
52
56
|
```tsx
|
|
53
|
-
import {
|
|
54
|
-
|
|
57
|
+
import {
|
|
58
|
+
createProjectSlice,
|
|
59
|
+
createProjectStore,
|
|
60
|
+
ProjectState,
|
|
61
|
+
} from '@sqlrooms/project-builder';
|
|
62
|
+
import {BaseProjectConfig} from '@sqlrooms/project-config';
|
|
63
|
+
import {
|
|
64
|
+
createDefaultSqlEditorConfig,
|
|
65
|
+
createSqlEditorSlice,
|
|
66
|
+
SqlEditorSliceConfig,
|
|
67
|
+
SqlEditorSliceState,
|
|
68
|
+
} from '@sqlrooms/sql-editor';
|
|
69
|
+
import {z} from 'zod';
|
|
55
70
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const currentQuery = useProjectStore((state) => state.getCurrentQuery());
|
|
71
|
+
// Define combined config schema
|
|
72
|
+
export const AppConfig = BaseProjectConfig.merge(SqlEditorSliceConfig);
|
|
73
|
+
export type AppConfig = z.infer<typeof AppConfig>;
|
|
60
74
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<h2>SQL Workspace</h2>
|
|
75
|
+
// Define combined state type
|
|
76
|
+
export type AppState = ProjectState<AppConfig> & SqlEditorSliceState;
|
|
64
77
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
// Create combined store
|
|
79
|
+
export const {projectStore, useProjectStore} = createProjectStore<
|
|
80
|
+
AppConfig,
|
|
81
|
+
AppState
|
|
82
|
+
>((set, get, store) => ({
|
|
83
|
+
// Base project slice
|
|
84
|
+
...createProjectSlice<AppConfig>({
|
|
85
|
+
config: {
|
|
86
|
+
title: 'SQL Workspace',
|
|
87
|
+
// ... other project config
|
|
88
|
+
...createDefaultSqlEditorConfig(),
|
|
89
|
+
},
|
|
90
|
+
})(set, get, store),
|
|
69
91
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
92
|
+
// Sql editor slice
|
|
93
|
+
...createSqlEditorSlice()(set, get, store),
|
|
94
|
+
}));
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Standalone SqlMonacoEditor Component
|
|
98
|
+
|
|
99
|
+
Unlike the full SQL Editor components, the `SqlMonacoEditor` can be used as a standalone component without requiring the store:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import {SqlMonacoEditor} from '@sqlrooms/sql-editor';
|
|
103
|
+
import {useState} from 'react';
|
|
104
|
+
|
|
105
|
+
function SimpleSqlEditor() {
|
|
106
|
+
const [query, setQuery] = useState('SELECT * FROM products');
|
|
107
|
+
|
|
108
|
+
const handleExecute = () => {
|
|
109
|
+
// Execute the query using your own logic
|
|
110
|
+
console.log('Executing query:', query);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<>
|
|
115
|
+
<SqlMonacoEditor value={query} onChange={setQuery} height="400px" />
|
|
116
|
+
<button onClick={handleExecute}>Execute</button>
|
|
117
|
+
</>
|
|
77
118
|
);
|
|
78
119
|
}
|
|
79
120
|
```
|
|
80
121
|
|
|
81
122
|
### With Custom Documentation Panel
|
|
82
123
|
|
|
83
|
-
Adding a custom documentation panel to
|
|
124
|
+
Adding a custom documentation panel to the SQL Editor:
|
|
84
125
|
|
|
85
126
|
```tsx
|
|
86
|
-
import {
|
|
127
|
+
import {SqlEditorModal} from '@sqlrooms/sql-editor';
|
|
87
128
|
import {useDisclosure} from '@sqlrooms/ui';
|
|
129
|
+
import {ProjectBuilderProvider} from '@sqlrooms/project-builder';
|
|
130
|
+
import {projectStore} from './store';
|
|
88
131
|
|
|
89
132
|
function AdvancedSqlEditor() {
|
|
90
|
-
const {isOpen, onClose} = useDisclosure(
|
|
133
|
+
const {isOpen, onOpen, onClose} = useDisclosure();
|
|
91
134
|
|
|
92
135
|
// Custom documentation component
|
|
93
136
|
const Documentation = () => (
|
|
@@ -107,48 +150,22 @@ function AdvancedSqlEditor() {
|
|
|
107
150
|
);
|
|
108
151
|
|
|
109
152
|
return (
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### Using SQL Monaco Editor Standalone
|
|
121
|
-
|
|
122
|
-
For cases where you only need the editor component without the full interface:
|
|
123
|
-
|
|
124
|
-
```tsx
|
|
125
|
-
import {SqlMonacoEditor} from '@sqlrooms/sql-editor';
|
|
126
|
-
|
|
127
|
-
function SimpleSqlEditor() {
|
|
128
|
-
const [query, setQuery] = useState('SELECT * FROM products');
|
|
129
|
-
|
|
130
|
-
const handleExecute = () => {
|
|
131
|
-
// Execute the query using your own logic
|
|
132
|
-
console.log('Executing query:', query);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
return (
|
|
136
|
-
<>
|
|
137
|
-
<SqlMonacoEditor
|
|
138
|
-
value={query}
|
|
139
|
-
onChange={setQuery}
|
|
140
|
-
onExecuteQuery={handleExecute}
|
|
141
|
-
height="400px"
|
|
153
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
154
|
+
<button onClick={onOpen}>Open SQL Editor</button>
|
|
155
|
+
<SqlEditorModal
|
|
156
|
+
isOpen={isOpen}
|
|
157
|
+
onClose={onClose}
|
|
158
|
+
schema="analytics"
|
|
159
|
+
documentationPanel={<Documentation />}
|
|
142
160
|
/>
|
|
143
|
-
|
|
144
|
-
</>
|
|
161
|
+
</ProjectBuilderProvider>
|
|
145
162
|
);
|
|
146
163
|
}
|
|
147
164
|
```
|
|
148
165
|
|
|
149
166
|
## State Management
|
|
150
167
|
|
|
151
|
-
The SQL editor provides a Zustand slice for managing state.
|
|
168
|
+
The SQL editor provides a Zustand slice for managing state. Here's how to set it up:
|
|
152
169
|
|
|
153
170
|
### Using in a Combined SQLRooms Store
|
|
154
171
|
|
|
@@ -165,25 +182,17 @@ import {
|
|
|
165
182
|
createProjectSlice,
|
|
166
183
|
createProjectStore,
|
|
167
184
|
ProjectState,
|
|
185
|
+
ProjectBuilderProvider,
|
|
168
186
|
} from '@sqlrooms/project-builder';
|
|
169
187
|
import {BaseProjectConfig} from '@sqlrooms/project-config';
|
|
170
|
-
import {
|
|
171
|
-
createAiSlice,
|
|
172
|
-
createDefaultAiConfig,
|
|
173
|
-
AiSliceState,
|
|
174
|
-
AiSliceConfig,
|
|
175
|
-
} from '@sqlrooms/ai';
|
|
176
188
|
import {z} from 'zod';
|
|
177
189
|
|
|
178
190
|
// 1. Define combined config schema
|
|
179
|
-
export const AppConfig =
|
|
180
|
-
BaseProjectConfig.merge(SqlEditorSliceConfig).merge(AiSliceConfig);
|
|
191
|
+
export const AppConfig = BaseProjectConfig.merge(SqlEditorSliceConfig);
|
|
181
192
|
export type AppConfig = z.infer<typeof AppConfig>;
|
|
182
193
|
|
|
183
194
|
// 2. Define combined state type
|
|
184
|
-
export type AppState = ProjectState<AppConfig> &
|
|
185
|
-
SqlEditorSliceState &
|
|
186
|
-
AiSliceState;
|
|
195
|
+
export type AppState = ProjectState<AppConfig> & SqlEditorSliceState;
|
|
187
196
|
|
|
188
197
|
// 3. Create combined store
|
|
189
198
|
export const {projectStore, useProjectStore} = createProjectStore<
|
|
@@ -192,29 +201,24 @@ export const {projectStore, useProjectStore} = createProjectStore<
|
|
|
192
201
|
>((set, get, store) => ({
|
|
193
202
|
// Base project slice
|
|
194
203
|
...createProjectSlice<AppConfig>({
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
...createDefaultSqlEditorConfig(),
|
|
200
|
-
...createDefaultAiConfig(),
|
|
201
|
-
},
|
|
202
|
-
// ... panels config
|
|
204
|
+
config: {
|
|
205
|
+
title: 'SQL Workspace',
|
|
206
|
+
// ... other project config
|
|
207
|
+
...createDefaultSqlEditorConfig(),
|
|
203
208
|
},
|
|
204
209
|
})(set, get, store),
|
|
205
210
|
|
|
206
211
|
// Sql editor slice
|
|
207
212
|
...createSqlEditorSlice()(set, get, store),
|
|
208
|
-
|
|
209
|
-
// Ai slice
|
|
210
|
-
...createAiSlice()(set, get, store),
|
|
211
213
|
}));
|
|
212
214
|
|
|
213
215
|
// 4. Use the store in components
|
|
214
216
|
function MyComponent() {
|
|
215
217
|
// Access SQL editor state and actions
|
|
216
|
-
const executeQuery = useProjectStore((state) => state.executeQuery);
|
|
217
|
-
const createQueryTab = useProjectStore(
|
|
218
|
+
const executeQuery = useProjectStore((state) => state.sqlEditor.executeQuery);
|
|
219
|
+
const createQueryTab = useProjectStore(
|
|
220
|
+
(state) => state.sqlEditor.createQueryTab,
|
|
221
|
+
);
|
|
218
222
|
|
|
219
223
|
// Use actions
|
|
220
224
|
const handleExecute = () => {
|
|
@@ -222,188 +226,212 @@ function MyComponent() {
|
|
|
222
226
|
};
|
|
223
227
|
|
|
224
228
|
return (
|
|
225
|
-
<
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
230
|
+
<div>
|
|
231
|
+
<button onClick={handleExecute}>Run Query</button>
|
|
232
|
+
<SqlEditorModal isOpen={true} onClose={() => {}} />
|
|
233
|
+
</div>
|
|
234
|
+
</ProjectBuilderProvider>
|
|
229
235
|
);
|
|
230
236
|
}
|
|
231
237
|
```
|
|
232
238
|
|
|
233
|
-
### Standalone SQL Editor Store
|
|
234
|
-
|
|
235
|
-
For simpler use cases where you only need the SQL editor:
|
|
236
|
-
|
|
237
|
-
```tsx
|
|
238
|
-
// Create default configuration
|
|
239
|
-
const config = createDefaultSqlEditorConfig();
|
|
240
|
-
|
|
241
|
-
// Create a store with the SQL editor slice
|
|
242
|
-
const useStore = createProjectStore({
|
|
243
|
-
sqlEditor: createSqlEditorSlice(config),
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
// Use the store in components with the provided selector hook
|
|
247
|
-
const {executeQuery, getCurrentQuery} = useStoreWithSqlEditor(useStore);
|
|
248
|
-
```
|
|
249
|
-
|
|
250
239
|
### Available State Actions
|
|
251
240
|
|
|
252
|
-
- `executeQuery(query: string, schema?: string)`: Execute a SQL query
|
|
253
|
-
- `exportResultsToCsv(results: Table, filename?: string)`: Export results to CSV
|
|
254
|
-
- `createQueryTab(initialQuery?: string)`: Create a new query tab
|
|
255
|
-
- `deleteQueryTab(queryId: string)`: Delete a query tab
|
|
256
|
-
- `renameQueryTab(queryId: string, newName: string)`: Rename a query tab
|
|
257
|
-
- `updateQueryText(queryId: string, queryText: string)`: Update query text
|
|
258
|
-
- `setSelectedQueryId(queryId: string)`: Set the selected query tab
|
|
259
|
-
- `getCurrentQuery(defaultQuery?: string)`: Get current query text
|
|
241
|
+
- `sqlEditor.executeQuery(query: string, schema?: string)`: Execute a SQL query
|
|
242
|
+
- `sqlEditor.exportResultsToCsv(results: Table, filename?: string)`: Export results to CSV
|
|
243
|
+
- `sqlEditor.createQueryTab(initialQuery?: string)`: Create a new query tab
|
|
244
|
+
- `sqlEditor.deleteQueryTab(queryId: string)`: Delete a query tab
|
|
245
|
+
- `sqlEditor.renameQueryTab(queryId: string, newName: string)`: Rename a query tab
|
|
246
|
+
- `sqlEditor.updateQueryText(queryId: string, queryText: string)`: Update query text
|
|
247
|
+
- `sqlEditor.setSelectedQueryId(queryId: string)`: Set the selected query tab
|
|
248
|
+
- `sqlEditor.getCurrentQuery(defaultQuery?: string)`: Get current query text
|
|
260
249
|
|
|
261
250
|
## Available Components
|
|
262
251
|
|
|
263
252
|
### SqlEditor
|
|
264
253
|
|
|
265
|
-
The main component providing a full-featured SQL editor interface.
|
|
254
|
+
The main component providing a full-featured SQL editor interface. Must be used within a ProjectBuilderProvider.
|
|
266
255
|
|
|
267
256
|
```tsx
|
|
268
257
|
import {SqlEditor} from '@sqlrooms/sql-editor';
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
258
|
+
import {ProjectBuilderProvider} from '@sqlrooms/project-builder';
|
|
259
|
+
import {projectStore} from './store';
|
|
260
|
+
|
|
261
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
262
|
+
<SqlEditor
|
|
263
|
+
isOpen={boolean}
|
|
264
|
+
onClose={() => void}
|
|
265
|
+
schema="main"
|
|
266
|
+
documentationPanel={ReactNode}
|
|
267
|
+
/>
|
|
268
|
+
</ProjectBuilderProvider>
|
|
276
269
|
```
|
|
277
270
|
|
|
278
271
|
### SqlMonacoEditor
|
|
279
272
|
|
|
280
|
-
A standalone SQL-specific Monaco editor component.
|
|
273
|
+
A standalone SQL-specific Monaco editor component. Can be used independently without ProjectBuilderProvider.
|
|
281
274
|
|
|
282
275
|
```tsx
|
|
283
276
|
import {SqlMonacoEditor} from '@sqlrooms/sql-editor';
|
|
277
|
+
import {useState} from 'react';
|
|
284
278
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
279
|
+
function SimpleSqlEditor() {
|
|
280
|
+
const [query, setQuery] = useState('SELECT * FROM products');
|
|
281
|
+
|
|
282
|
+
const handleExecute = () => {
|
|
283
|
+
// Execute the query using your own logic
|
|
284
|
+
console.log('Executing query:', query);
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
<>
|
|
289
|
+
<SqlMonacoEditor value={query} onChange={setQuery} height="400px" />
|
|
290
|
+
<button onClick={handleExecute}>Execute</button>
|
|
291
|
+
</>
|
|
292
|
+
);
|
|
293
|
+
}
|
|
290
294
|
```
|
|
291
295
|
|
|
292
296
|
### SqlEditorModal
|
|
293
297
|
|
|
294
|
-
A modal wrapper around the SQL editor.
|
|
298
|
+
A modal wrapper around the SQL editor. Must be used within a ProjectBuilderProvider.
|
|
295
299
|
|
|
296
300
|
```tsx
|
|
297
301
|
import {SqlEditorModal} from '@sqlrooms/sql-editor';
|
|
298
302
|
import {useDisclosure} from '@sqlrooms/ui';
|
|
303
|
+
import {ProjectBuilderProvider} from '@sqlrooms/project-builder';
|
|
304
|
+
import {projectStore} from './store';
|
|
299
305
|
|
|
300
306
|
function EditorWithModal() {
|
|
301
307
|
const {isOpen, onOpen, onClose} = useDisclosure();
|
|
302
308
|
|
|
303
309
|
return (
|
|
304
|
-
|
|
310
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
305
311
|
<button onClick={onOpen}>Open SQL Editor</button>
|
|
306
312
|
<SqlEditorModal isOpen={isOpen} onClose={onClose} />
|
|
307
|
-
|
|
313
|
+
</ProjectBuilderProvider>
|
|
308
314
|
);
|
|
309
315
|
}
|
|
310
316
|
```
|
|
311
317
|
|
|
312
318
|
### CreateTableModal
|
|
313
319
|
|
|
314
|
-
A modal for creating new tables from SQL queries.
|
|
320
|
+
A modal for creating new tables from SQL queries. Must be used within a ProjectBuilderProvider.
|
|
315
321
|
|
|
316
322
|
```tsx
|
|
317
323
|
import {CreateTableModal} from '@sqlrooms/sql-editor';
|
|
318
324
|
import {useDisclosure} from '@sqlrooms/ui';
|
|
325
|
+
import {ProjectBuilderProvider} from '@sqlrooms/project-builder';
|
|
326
|
+
import {projectStore} from './store';
|
|
327
|
+
import {useProjectStore} from './store';
|
|
319
328
|
|
|
320
329
|
function TableCreator() {
|
|
321
330
|
const {isOpen, onOpen, onClose} = useDisclosure();
|
|
331
|
+
const addOrUpdateSqlQueryDataSource = useProjectStore(
|
|
332
|
+
(state) => state.project.addOrUpdateSqlQueryDataSource,
|
|
333
|
+
);
|
|
322
334
|
|
|
323
335
|
return (
|
|
324
|
-
|
|
336
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
325
337
|
<button onClick={onOpen}>Create Table from Results</button>
|
|
326
338
|
<CreateTableModal
|
|
327
339
|
isOpen={isOpen}
|
|
328
340
|
onClose={onClose}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
tableData={queryResults}
|
|
341
|
+
onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}
|
|
342
|
+
query="SELECT * FROM users"
|
|
333
343
|
/>
|
|
334
|
-
|
|
344
|
+
</ProjectBuilderProvider>
|
|
335
345
|
);
|
|
336
346
|
}
|
|
337
347
|
```
|
|
338
348
|
|
|
339
349
|
### SqlQueryDataSourcesPanel
|
|
340
350
|
|
|
341
|
-
A panel showing available data sources for SQL queries.
|
|
351
|
+
A panel showing available data sources for SQL queries. Must be used within a ProjectBuilderProvider.
|
|
342
352
|
|
|
343
353
|
```tsx
|
|
344
354
|
import {SqlQueryDataSourcesPanel} from '@sqlrooms/sql-editor';
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
355
|
+
import {ProjectBuilderProvider} from '@sqlrooms/project-builder';
|
|
356
|
+
import {projectStore} from './store';
|
|
357
|
+
|
|
358
|
+
<ProjectBuilderProvider projectStore={projectStore}>
|
|
359
|
+
<SqlQueryDataSourcesPanel
|
|
360
|
+
onSelectTable={(tableName) => {
|
|
361
|
+
console.log(`Selected table: ${tableName}`);
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
364
|
+
</ProjectBuilderProvider>;
|
|
351
365
|
```
|
|
352
366
|
|
|
353
367
|
## Props
|
|
354
368
|
|
|
355
369
|
### SqlEditor Props
|
|
356
370
|
|
|
357
|
-
| Prop | Type
|
|
358
|
-
| ------------------ |
|
|
359
|
-
| isOpen | boolean
|
|
360
|
-
| onClose | function
|
|
361
|
-
| schema | string
|
|
362
|
-
| documentationPanel | ReactNode
|
|
363
|
-
| initialQuery | string | '' | Initial query to display in the editor |
|
|
364
|
-
| store | StoreObject | undefined | Custom Zustand store to use (optional) |
|
|
371
|
+
| Prop | Type | Default | Description |
|
|
372
|
+
| ------------------ | --------- | --------- | ------------------------------------- |
|
|
373
|
+
| isOpen | boolean | - | Whether the editor is open |
|
|
374
|
+
| onClose | function | - | Callback when the editor is closed |
|
|
375
|
+
| schema | string | 'main' | Default schema to use for queries |
|
|
376
|
+
| documentationPanel | ReactNode | undefined | Custom documentation panel to display |
|
|
365
377
|
|
|
366
378
|
### SqlMonacoEditor Props
|
|
367
379
|
|
|
368
|
-
| Prop
|
|
369
|
-
|
|
|
370
|
-
| value
|
|
371
|
-
| onChange
|
|
372
|
-
|
|
|
373
|
-
|
|
|
374
|
-
|
|
|
375
|
-
|
|
|
380
|
+
| Prop | Type | Default | Description |
|
|
381
|
+
| ---------------- | ----------- | ------- | --------------------------------------- |
|
|
382
|
+
| value | string | '' | The SQL query text |
|
|
383
|
+
| onChange | function | - | Callback when the query text changes |
|
|
384
|
+
| height | string | '300px' | Height of the editor |
|
|
385
|
+
| readOnly | boolean | false | Whether the editor is read-only |
|
|
386
|
+
| theme | string | 'dark' | Editor theme ('dark' or 'light') |
|
|
387
|
+
| tableSchemas | DataTable[] | [] | Table schemas for autocompletion |
|
|
388
|
+
| customKeywords | string[] | [] | Custom SQL keywords for autocompletion |
|
|
389
|
+
| customFunctions | string[] | [] | Custom SQL functions for autocompletion |
|
|
390
|
+
| getLatestSchemas | function | - | Callback to get latest table schemas |
|
|
391
|
+
| className | string | - | Additional CSS class names |
|
|
392
|
+
| options | object | - | Monaco editor options |
|
|
393
|
+
| onMount | function | - | Callback when editor is mounted |
|
|
376
394
|
|
|
377
395
|
### SqlEditorModal Props
|
|
378
396
|
|
|
379
|
-
| Prop
|
|
380
|
-
|
|
|
381
|
-
| isOpen
|
|
382
|
-
| onClose
|
|
383
|
-
| schema
|
|
397
|
+
| Prop | Type | Default | Description |
|
|
398
|
+
| ------------------ | --------- | --------- | ------------------------------------- |
|
|
399
|
+
| isOpen | boolean | - | Whether the modal is open |
|
|
400
|
+
| onClose | function | - | Callback when the modal is closed |
|
|
401
|
+
| schema | string | 'main' | Default schema to use for queries |
|
|
402
|
+
| documentationPanel | ReactNode | undefined | Custom documentation panel to display |
|
|
384
403
|
|
|
385
404
|
### CreateTableModal Props
|
|
386
405
|
|
|
387
|
-
| Prop
|
|
388
|
-
|
|
|
389
|
-
| isOpen
|
|
390
|
-
| onClose
|
|
391
|
-
|
|
|
392
|
-
|
|
|
406
|
+
| Prop | Type | Default | Description |
|
|
407
|
+
| --------------------- | -------- | ------- | --------------------------------- |
|
|
408
|
+
| isOpen | boolean | - | Whether the modal is open |
|
|
409
|
+
| onClose | function | - | Callback when the modal is closed |
|
|
410
|
+
| onAddOrUpdateSqlQuery | function | - | Callback when a table is created |
|
|
411
|
+
| query | string | - | SQL query that generated the data |
|
|
393
412
|
|
|
394
413
|
## Configuration
|
|
395
414
|
|
|
396
415
|
The SQL editor can be configured through the Zustand store.
|
|
397
416
|
|
|
398
417
|
```tsx
|
|
399
|
-
const config =
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
418
|
+
const config = createDefaultSqlEditorConfig();
|
|
419
|
+
// Customize if needed
|
|
420
|
+
config.sqlEditor.queries = [
|
|
421
|
+
{id: 'default', name: 'Untitled', query: 'SELECT * FROM users LIMIT 10;'},
|
|
422
|
+
];
|
|
423
|
+
config.sqlEditor.selectedQueryId = 'default';
|
|
424
|
+
|
|
425
|
+
// Use in store creation
|
|
426
|
+
const {projectStore} = createProjectStore({
|
|
427
|
+
...createProjectSlice({
|
|
428
|
+
config: {
|
|
429
|
+
...config,
|
|
430
|
+
// other config options
|
|
431
|
+
},
|
|
432
|
+
}),
|
|
433
|
+
...createSqlEditorSlice(),
|
|
434
|
+
});
|
|
407
435
|
```
|
|
408
436
|
|
|
409
437
|
For more information, visit the SQLRooms documentation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateTableModal.d.ts","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CreateTableModal.d.ts","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC;AAmB7D,OAAO,EAAC,EAAE,EAAc,MAAM,OAAO,CAAC;AAkBtC,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,qBAAqB,EAAE,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA6G/C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
package/dist/CreateTableModal.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
3
|
-
import { DuckQueryError } from '@sqlrooms/duckdb';
|
|
4
3
|
import { Alert, AlertDescription, Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Form, FormControl, FormField, FormItem, FormLabel, FormMessage, Input, } from '@sqlrooms/ui';
|
|
5
4
|
import { useCallback } from 'react';
|
|
6
5
|
import { useForm } from 'react-hook-form';
|
|
@@ -31,10 +30,7 @@ const CreateTableModal = (props) => {
|
|
|
31
30
|
onClose();
|
|
32
31
|
}
|
|
33
32
|
catch (err) {
|
|
34
|
-
form.setError('root', {
|
|
35
|
-
type: 'manual',
|
|
36
|
-
message: err instanceof DuckQueryError ? err.getMessageForUser() : `${err}`,
|
|
37
|
-
});
|
|
33
|
+
form.setError('root', { type: 'manual', message: `${err}` });
|
|
38
34
|
}
|
|
39
35
|
}, [onAddOrUpdateSqlQuery, editDataSource?.tableName, onClose, form]);
|
|
40
36
|
return (_jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: _jsx(DialogContent, { className: "sm:max-w-[800px]", children: _jsx(Form, { ...form, children: _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-4", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: editDataSource
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateTableModal.js","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"CreateTableModal.js","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import {zodResolver} from '@hookform/resolvers/zod';\nimport {SqlQueryDataSource} from '@sqlrooms/project-builder';\nimport {\n Alert,\n AlertDescription,\n Button,\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} from '@sqlrooms/ui';\nimport {FC, useCallback} from 'react';\nimport {useForm} from 'react-hook-form';\nimport * as z from 'zod';\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});\n\nexport type CreateTableModalProps = {\n query: string;\n isOpen: boolean;\n onClose: () => void;\n editDataSource?: SqlQueryDataSource;\n onAddOrUpdateSqlQuery: (\n tableName: string,\n query: string,\n oldTableName?: string,\n ) => Promise<void>;\n};\n\nconst CreateTableModal: FC<CreateTableModalProps> = (props) => {\n const {editDataSource, isOpen, onClose, onAddOrUpdateSqlQuery} = props;\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n values: {\n tableName: editDataSource?.tableName ?? '',\n query: editDataSource?.sqlQuery ?? props.query.trim(),\n },\n });\n\n const onSubmit = useCallback(\n async (values: z.infer<typeof formSchema>) => {\n try {\n const {tableName, query} = values;\n await onAddOrUpdateSqlQuery(\n tableName,\n query,\n editDataSource?.tableName,\n );\n form.reset();\n onClose();\n } catch (err) {\n form.setError('root', {type: 'manual', message: `${err}`});\n }\n },\n [onAddOrUpdateSqlQuery, editDataSource?.tableName, onClose, form],\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-[800px]\">\n {/* @ts-ignore */}\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {editDataSource\n ? 'Edit table query'\n : 'Create table from query'}\n </DialogTitle>\n {!editDataSource && (\n <DialogDescription>\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>\n {form.formState.errors.root.message}\n </AlertDescription>\n </Alert>\n )}\n\n <FormField\n // @ts-ignore\n control={form.control}\n name=\"tableName\"\n render={({field}) => (\n <FormItem>\n <FormLabel>Table name:</FormLabel>\n <FormControl>\n <Input {...field} className=\"font-mono\" autoFocus />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n // @ts-ignore\n control={form.control}\n name=\"query\"\n render={({field}) => (\n <FormItem>\n <FormLabel>SQL query:</FormLabel>\n <FormControl>\n <SqlMonacoEditor\n value={field.value}\n onChange={field.onChange}\n className=\"min-h-[200px]\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n }}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={form.formState.isSubmitting}>\n {editDataSource ? 'Update' : 'Create'}\n </Button>\n </DialogFooter>\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default CreateTableModal;\n"]}
|
package/dist/SqlEditor.js
CHANGED
|
@@ -11,7 +11,7 @@ import { useStoreWithSqlEditor } from './SqlEditorSlice';
|
|
|
11
11
|
import { TablesList } from './TablesList';
|
|
12
12
|
import { SqlMonacoEditor } from './SqlMonacoEditor';
|
|
13
13
|
import { useTableManagement, useQueryExecution, useMonacoEditor } from './hooks';
|
|
14
|
-
import {
|
|
14
|
+
import { useBaseProjectBuilderStore } from '@sqlrooms/project-builder';
|
|
15
15
|
const DEFAULT_QUERY = '';
|
|
16
16
|
/**
|
|
17
17
|
* A full-featured SQL editor component with query execution, table management, and results visualization.
|
|
@@ -29,7 +29,7 @@ const DEFAULT_QUERY = '';
|
|
|
29
29
|
const SqlEditorBase = (props) => {
|
|
30
30
|
const { schema = 'main', documentationPanel } = props;
|
|
31
31
|
// Store access - directly use the selector
|
|
32
|
-
const addOrUpdateSqlQueryDataSource =
|
|
32
|
+
const addOrUpdateSqlQueryDataSource = useBaseProjectBuilderStore((state) => state.project.addOrUpdateSqlQueryDataSource);
|
|
33
33
|
// Get query data and methods directly from the store
|
|
34
34
|
const queries = useStoreWithSqlEditor((s) => s.config.sqlEditor.queries);
|
|
35
35
|
const selectedQueryId = useStoreWithSqlEditor((s) => s.config.sqlEditor.selectedQueryId);
|
package/dist/SqlEditor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,oBAAoB,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,QAAQ,GACT,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,EAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC9D,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAC,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAC,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAC,mBAAmB,EAAC,MAAM,2BAA2B,CAAC;AAM9D,MAAM,aAAa,GAAG,EAAE,CAAC;AAgBzB;;;;;;;;;;;;GAYG;AACH,MAAM,aAAa,GAA6B,CAAC,KAAK,EAAE,EAAE;IACxD,MAAM,EAAC,MAAM,GAAG,MAAM,EAAE,kBAAkB,EAAC,GAAG,KAAK,CAAC;IAEpD,2CAA2C;IAC3C,MAAM,6BAA6B,GAAG,mBAAmB,CACvD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,6BAA6B,CACvD,CAAC;IAEF,qDAAqD;IACrD,MAAM,OAAO,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACzE,MAAM,eAAe,GAAG,qBAAqB,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAC1C,CAAC;IACF,MAAM,eAAe,GAAG,qBAAqB,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CACnC,CAAC;IACF,MAAM,kBAAkB,GAAG,qBAAqB,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,kBAAkB,CACtC,CAAC;IACF,MAAM,eAAe,GAAG,qBAAqB,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CACnC,CAAC;IACF,MAAM,cAAc,GAAG,qBAAqB,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAClC,CAAC;IACF,MAAM,cAAc,GAAG,qBAAqB,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAClC,CAAC;IACF,MAAM,cAAc,GAAG,qBAAqB,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAClC,CAAC;IAEF,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;IACxE,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAEvE,yBAAyB;IACzB,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAGxC,IAAI,CAAC,CAAC;IAEhB,eAAe;IACf,MAAM,EACJ,MAAM,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,WAAW,EACX,iBAAiB,GAClB,GAAG,kBAAkB,EAAE,CAAC;IAEzB,MAAM,EAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAC,GACxE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE5B,MAAM,EAAC,iBAAiB,EAAE,YAAY,EAAE,kBAAkB,EAAC,GACzD,eAAe,EAAE,CAAC;IAEpB,6BAA6B;IAC7B,MAAM,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAEpD,6CAA6C;IAC7C,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,KAAa,EAAE,EAAE;QAChB,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,EACD,CAAC,kBAAkB,CAAC,CACrB,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,KAAyB,EAAE,EAAE;QAC5B,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,eAAe,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC,EACD,CAAC,eAAe,EAAE,eAAe,CAAC,CACnC,CAAC;IAEF,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,OAAO,cAAc,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,OAAe,EAAE,WAAmB,EAAE,KAAuB,EAAE,EAAE;QAChE,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,gBAAgB,CAAC,EAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAC,CAAC,CAAC;IACrD,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,kBAAkB,GAAG,WAAW,CACpC,CAAC,OAAe,EAAE,EAAE;QAClB,IAAI,aAAa,EAAE,CAAC;YAClB,cAAc,CAAC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,EACD,CAAC,aAAa,EAAE,cAAc,CAAC,CAChC,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,OAAe,EAAE,KAAuB,EAAE,EAAE;QAC3C,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,wBAAwB,GAAG,WAAW,CAAC,GAAG,EAAE;QAChD,IAAI,aAAa,EAAE,CAAC;YAClB,cAAc,CAAC,aAAa,CAAC,CAAC;YAC9B,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;IAEpC,yBAAyB;IACzB,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC5C,4CAA4C;QAC5C,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE7B,gEAAgE;QAChE,MAAM,UAAU,GAAG,YAAY,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAE/D,wCAAwC;QACxC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAEjC,wCAAwC;QACxC,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC,EAAE;QACD,iBAAiB;QACjB,YAAY;QACZ,eAAe;QACf,YAAY;QACZ,QAAQ;QACR,oBAAoB;KACrB,CAAC,CAAC;IAEH,gEAAgE;IAChE,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAEzC,yDAAyD;IACzD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,KAAK,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhC,oCAAoC;IACpC,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,yCAAyC;IACzC,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,cAAK,SAAS,EAAC,yBAAyB,YACrC,kBAAkB,CAAC,CAAC,CAAC,CACpB,MAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAC3C,OAAO,EAAE,gBAAgB,aAEzB,KAAC,YAAY,IAAC,SAAS,EAAC,cAAc,GAAG,qBAElC,CACV,CAAC,CAAC,CAAC,CACF,YACE,IAAI,EAAC,0CAA0C,EAC/C,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,YAEhB,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,SAAS,aAClC,KAAC,YAAY,IAAC,SAAS,EAAC,cAAc,GAAG,qBAElC,GACP,CACL,GACG,EACN,eAAK,SAAS,EAAC,mCAAmC,aAChD,cAAK,SAAS,EAAC,yCAAyC,YACtD,aAAI,SAAS,EAAC,uBAAuB,2BAAgB,GACjD,EACN,cAAK,SAAS,EAAC,2BAA2B,YACxC,MAAC,mBAAmB,IAAC,SAAS,EAAC,YAAY,EAAC,SAAS,EAAC,QAAQ,aAE5D,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,YAC5B,aAAa,CAAC,CAAC,CAAC,CACf,KAAC,WAAW,IAAC,CAAC,EAAC,MAAM,GAAG,CACzB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAChB,eAAK,SAAS,EAAC,kBAAkB,uCACR,WAAW,CAAC,OAAO,IACtC,CACP,CAAC,CAAC,CAAC,CACF,KAAC,UAAU,IACT,MAAM,EAAC,oBAAoB,EAC3B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,iBAAiB,GAC3B,CACH,GACc,EACjB,KAAC,eAAe,IAAC,UAAU,SAAG,EAC9B,KAAC,cAAc,IACb,WAAW,EAAE,EAAE,EACf,SAAS,EAAC,+BAA+B,YAEzC,MAAC,IAAI,IACH,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAC,sCAAsC,aAEhD,eAAK,SAAS,EAAC,gDAAgD,aAC7D,MAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,cAAc,EAAE,EACpC,SAAS,EAAC,WAAW,aAErB,KAAC,QAAQ,IAAC,SAAS,EAAC,cAAc,GAAG,WAE9B,EACT,KAAC,QAAQ,IAAC,SAAS,EAAC,QAAQ,YACzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CACvB,eAAgB,SAAS,EAAC,UAAU,aAClC,KAAC,WAAW,IACV,KAAK,EAAE,CAAC,CAAC,EAAE,EACX,SAAS,EAAC,wBAAwB,YAEjC,CAAC,CAAC,IAAI,GACK,EACd,MAAC,YAAY,eACX,KAAC,mBAAmB,IAAC,OAAO,kBAC1B,cACE,SAAS,EAAC,8HAA8H,EACxI,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,YAEnC,KAAC,gBAAgB,IAAC,SAAS,EAAC,SAAS,GAAG,GACpC,GACc,EACtB,MAAC,mBAAmB,eAClB,KAAC,gBAAgB,IACf,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gHACb,CAAC,CAAC,eAAe,EAAE,CAAC;gHACpB,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;4GACrC,CAAC,uBAGgB,EAClB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CACrB,KAAC,gBAAgB,IACf,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gHACb,CAAC,CAAC,eAAe,EAAE,CAAC;gHACpB,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;4GAC7B,CAAC,EACD,SAAS,EAAC,cAAc,uBAGP,CACpB,IACmB,IACT,KArCP,CAAC,CAAC,EAAE,CAsCR,CACP,CAAC,GACO,EACX,KAAC,MAAM,IACL,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,OAAO,EACf,OAAO,EAAE,cAAc,EACvB,SAAS,EAAC,MAAM,YAEhB,KAAC,QAAQ,IAAC,SAAS,EAAC,SAAS,GAAG,GACzB,IACL,EACL,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CACvB,KAAC,WAAW,IAEV,KAAK,EAAE,CAAC,CAAC,EAAE,EACX,SAAS,EAAC,6DAA6D,YAEvE,cAAK,SAAS,EAAC,0CAA0C,YACvD,KAAC,eAAe,IACd,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAC,yBAAyB,EACnC,OAAO,EAAE;oFACP,oBAAoB,EAAE,KAAK;oFAC3B,eAAe,EAAE,IAAI;oFACrB,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC;oFACzB,QAAQ,EAAE,IAAI;oFACd,4BAA4B;oFAC5B,gBAAgB,EAAE,IAAI;oFACtB,0BAA0B,EAAE,IAAI;iFACjC,EACD,OAAO,EAAE,CACP,MAAsB,EACtB,MAAsB,EACtB,EAAE;oFACF,iBAAiB,CACf,MAAM,EACN,MAAM,EACN,CAAC,CAAC,EAAE,EACJ,cAAc,CACf,CAAC;gFACJ,CAAC,EACD,YAAY,EAAE,YAAY,EAC1B,gBAAgB,EAAE,GAAG,EAAE;oFACrB,gDAAgD;oFAChD,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wFAC3C,oDAAoD;wFACpD,2CAA2C;wFAC3C,KAAK,WAAW,EAAE,CAAC;oFACrB,CAAC;oFACD,OAAO,EAAC,YAAY,EAAC,CAAC;gFACxB,CAAC,GACD,GACE,IAxCD,CAAC,CAAC,EAAE,CAyCG,CACf,CAAC,IACG,GACQ,IACG,GACP,EACjB,KAAC,eAAe,IAAC,UAAU,SAAG,EAC9B,KAAC,cAAc,IACb,WAAW,EAAE,EAAE,EACf,SAAS,EAAC,kCAAkC,YAE3C,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,WAAW,IAAC,CAAC,EAAC,MAAM,GAAG,CACzB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAClB,KAAC,cAAc,IACb,KAAK,EAAE,iBAAiB,MAAM,IAAI,QAAQ,CAAC,aAAa,CAAC,EAAE,GAC3D,CACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CACV,cAAK,SAAS,EAAC,iCAAiC,YAC9C,cAAK,SAAS,EAAC,oCAAoC,YAChD,KAAK,GACF,GACF,CACP,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CACrB,eAAK,SAAS,EAAC,gEAAgE,aAC7E,KAAC,oBAAoB,OAAK,gBAAgB,GAAI,EAC9C,eAAK,SAAS,EAAC,sCAAsC,aACnD,MAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,CAAC,gBAAgB,EAC3B,OAAO,EAAE,iBAAiB,aAE1B,KAAC,QAAQ,IAAC,SAAS,EAAC,cAAc,GAAG,oBAE9B,EACT,MAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,CAAC,OAAO,EAClB,OAAO,EAAE,aAAa,aAEtB,KAAC,YAAY,IAAC,SAAS,EAAC,cAAc,GAAG,cAElC,IACL,IACF,CACP,CAAC,CAAC,CAAC,IAAI,GACO,IACG,GACP,EAChB,QAAQ,IAAI,CACX,8BACE,KAAC,eAAe,IAAC,UAAU,SAAG,EAE9B,KAAC,cAAc,IAAC,WAAW,EAAE,EAAE,YAC5B,kBAAkB,GACJ,IAChB,CACJ,IACmB,GAClB,EACN,KAAC,gBAAgB,IACf,KAAK,EAAE,iBAAiB,IAAI,YAAY,EACxC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,GAAG,EAAE,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAC7C,qBAAqB,EAAE,6BAA6B,GACpD,EACF,KAAC,mBAAmB,IAClB,MAAM,EAAE,aAAa,KAAK,IAAI,EAC9B,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EACrC,SAAS,EAAE,wBAAwB,GACnC,EACF,KAAC,mBAAmB,IAClB,MAAM,EAAE,aAAa,KAAK,IAAI,EAC9B,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EACrC,WAAW,EAAE,aAAa,EAAE,IAAI,IAAI,EAAE,EACtC,QAAQ,EAAE,kBAAkB,GAC5B,IACE,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,yDAAyD;AACzD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAE5C,eAAe,SAAS,CAAC","sourcesContent":["import {DataTableVirtualized, QueryDataTable} from '@sqlrooms/data-table';\nimport {escapeId} from '@sqlrooms/duckdb';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n SpinnerPane,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@sqlrooms/ui';\nimport {\n BookOpenIcon,\n DownloadIcon,\n MoreVerticalIcon,\n PlayIcon,\n PlusIcon,\n} from 'lucide-react';\nimport React, {useCallback, useEffect, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\nimport DeleteSqlQueryModal from './DeleteSqlQueryModal';\nimport RenameSqlQueryModal from './RenameSqlQueryModal';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\nimport {TablesList} from './TablesList';\nimport {SqlMonacoEditor} from './SqlMonacoEditor';\nimport type * as Monaco from 'monaco-editor';\nimport {useTableManagement, useQueryExecution, useMonacoEditor} from './hooks';\nimport {useBaseProjectStore} from '@sqlrooms/project-builder';\n\n// Define the types for Monaco Editor\ntype EditorInstance = Monaco.editor.IStandaloneCodeEditor;\ntype MonacoInstance = typeof Monaco;\n\nconst DEFAULT_QUERY = '';\n\nexport type SqlEditorProps = {\n /** The database schema to use for queries. Defaults to 'main' */\n schema?: string;\n\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\n/**\n * A full-featured SQL editor component with query execution, table management, and results visualization.\n *\n * Features:\n * - Multiple query tabs with save/rename/delete functionality\n * - Query execution with results displayed in a data table\n * - Table browser showing available tables in the schema\n * - Export results to CSV\n * - Create new tables from query results\n * - Optional SQL documentation panel\n * - Keyboard shortcuts (Cmd/Ctrl + Enter to run queries)\n *\n */\nconst SqlEditorBase: React.FC<SqlEditorProps> = (props) => {\n const {schema = 'main', documentationPanel} = props;\n\n // Store access - directly use the selector\n const addOrUpdateSqlQueryDataSource = useBaseProjectStore(\n (state) => state.project.addOrUpdateSqlQueryDataSource,\n );\n\n // Get query data and methods directly from the store\n const queries = useStoreWithSqlEditor((s) => s.config.sqlEditor.queries);\n const selectedQueryId = useStoreWithSqlEditor(\n (s) => s.config.sqlEditor.selectedQueryId,\n );\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n const setSelectedQueryId = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setSelectedQueryId,\n );\n const updateQueryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.updateQueryText,\n );\n const createQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.createQueryTab,\n );\n const deleteQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.deleteQueryTab,\n );\n const renameQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.renameQueryTab,\n );\n\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n const [lastExecutedQuery, setLastExecutedQuery] = useState<string>('');\n\n // Local state for modals\n const [queryToDelete, setQueryToDelete] = useState<string | null>(null);\n const [queryToRename, setQueryToRename] = useState<{\n id: string;\n name: string;\n } | null>(null);\n\n // Custom hooks\n const {\n tables,\n tablesLoading,\n tablesError,\n tableSchemas,\n selectedTable,\n fetchTables,\n handleSelectTable,\n } = useTableManagement();\n\n const {results, resultsTableData, loading, error, runQuery, exportResults} =\n useQueryExecution(schema);\n\n const {handleEditorMount, getQueryText, setRunQueryHandler} =\n useMonacoEditor();\n\n // Get the current query text\n const currentQuery = getCurrentQuery(DEFAULT_QUERY);\n\n // Handler functions for query tab management\n const handleTabChange = useCallback(\n (value: string) => {\n setSelectedQueryId(value);\n },\n [setSelectedQueryId],\n );\n\n const handleUpdateQuery = useCallback(\n (value: string | undefined) => {\n if (!value) return;\n updateQueryText(selectedQueryId, value);\n },\n [selectedQueryId, updateQueryText],\n );\n\n const handleNewQuery = useCallback(() => {\n return createQueryTab(DEFAULT_QUERY);\n }, [createQueryTab]);\n\n const handleStartRename = useCallback(\n (queryId: string, currentName: string, event: React.MouseEvent) => {\n event.preventDefault();\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\n const handleDeleteQuery = useCallback(\n (queryId: string, event: React.MouseEvent) => {\n event.stopPropagation();\n setQueryToDelete(queryId);\n },\n [],\n );\n\n const handleConfirmDeleteQuery = useCallback(() => {\n if (queryToDelete) {\n deleteQueryTab(queryToDelete);\n setQueryToDelete(null);\n }\n }, [queryToDelete, deleteQueryTab]);\n\n // Handle run query logic\n const handleRunQuery = useCallback(async () => {\n // Clear selected table when running a query\n handleSelectTable(undefined);\n\n // Get the query text (either selected text or the entire query)\n const queryToRun = getQueryText(selectedQueryId, currentQuery);\n\n // Store the query that's being executed\n setLastExecutedQuery(queryToRun);\n\n // Run the query and refresh tables list\n await runQuery(queryToRun);\n }, [\n handleSelectTable,\n getQueryText,\n selectedQueryId,\n currentQuery,\n runQuery,\n setLastExecutedQuery,\n ]);\n\n // Set up the run query handler reference for keyboard shortcuts\n useEffect(() => {\n setRunQueryHandler(handleRunQuery);\n }, [handleRunQuery, setRunQueryHandler]);\n\n // Check if table schemas are empty and refetch if needed\n useEffect(() => {\n if (Object.keys(tableSchemas).length === 0) {\n void fetchTables();\n }\n }, [fetchTables, tableSchemas]);\n\n // Handle toggle documentation panel\n const handleToggleDocs = useCallback(() => {\n setShowDocs(!showDocs);\n }, [showDocs]);\n\n // Handle create table from query results\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 <div className=\"absolute right-12 top-0\">\n {documentationPanel ? (\n <Button\n size=\"sm\"\n variant={showDocs ? 'secondary' : 'outline'}\n onClick={handleToggleDocs}\n >\n <BookOpenIcon className=\"mr-2 h-4 w-4\" />\n SQL reference\n </Button>\n ) : (\n <a\n href=\"https://duckdb.org/docs/sql/introduction\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <Button size=\"sm\" variant={'outline'}>\n <BookOpenIcon className=\"mr-2 h-4 w-4\" />\n SQL reference\n </Button>\n </a>\n )}\n </div>\n <div className=\"flex h-full w-full flex-col gap-2\">\n <div className=\"mb-2 ml-1 mr-10 flex items-center gap-2\">\n <h2 className=\"text-lg font-semibold\">SQL Editor</h2>\n </div>\n <div className=\"bg-muted h-full flex-grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n {/* Main panel - takes full width when docs not shown, or 70% when docs shown */}\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 {tablesLoading ? (\n <SpinnerPane h=\"100%\" />\n ) : tablesError ? (\n <div className=\"p-4 text-red-500\">\n Error loading tables: {tablesError.message}\n </div>\n ) : (\n <TablesList\n schema=\"information_schema\"\n tableNames={tables}\n selectedTable={selectedTable}\n onSelect={handleSelectTable}\n />\n )}\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel\n defaultSize={80}\n className=\"flex flex-col overflow-hidden\"\n >\n <Tabs\n value={selectedQueryId}\n onValueChange={handleTabChange}\n className=\"flex h-full flex-col overflow-hidden\"\n >\n <div className=\"border-border flex items-center gap-2 border-b\">\n <Button\n size=\"sm\"\n onClick={() => void handleRunQuery()}\n className=\"uppercase\"\n >\n <PlayIcon className=\"mr-2 h-4 w-4\" />\n Run\n </Button>\n <TabsList className=\"flex-1\">\n {queries.map((q: any) => (\n <div key={q.id} className=\"relative\">\n <TabsTrigger\n value={q.id}\n className=\"min-w-[60px] px-6 pr-8\"\n >\n {q.name}\n </TabsTrigger>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <div\n className=\"hover:bg-accent absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm\"\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVerticalIcon className=\"h-3 w-3\" />\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n handleStartRename(q.id, q.name, e);\n }}\n >\n Rename\n </DropdownMenuItem>\n {queries.length > 1 && (\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n handleDeleteQuery(q.id, e);\n }}\n className=\"text-red-500\"\n >\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))}\n </TabsList>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n onClick={handleNewQuery}\n className=\"ml-2\"\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n {queries.map((q: any) => (\n <TabsContent\n key={q.id}\n value={q.id}\n className=\"relative h-full flex-grow flex-col data-[state=active]:flex\"\n >\n <div className=\"absolute inset-0 h-full w-full flex-grow\">\n <SqlMonacoEditor\n value={q.query}\n onChange={handleUpdateQuery}\n className=\"h-full w-full flex-grow\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n // Enable keyboard shortcuts\n quickSuggestions: true,\n suggestOnTriggerCharacters: true,\n }}\n onMount={(\n editor: EditorInstance,\n monaco: MonacoInstance,\n ) => {\n handleEditorMount(\n editor,\n monaco,\n q.id,\n handleRunQuery,\n );\n }}\n tableSchemas={tableSchemas}\n getLatestSchemas={() => {\n // If tableSchemas is empty, try to fetch tables\n if (Object.keys(tableSchemas).length === 0) {\n // We can't await here, but we can trigger the fetch\n // This will update the state for next time\n void fetchTables();\n }\n return {tableSchemas};\n }}\n />\n </div>\n </TabsContent>\n ))}\n </Tabs>\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel\n defaultSize={50}\n className=\"bg-muted overflow-hidden text-sm\"\n >\n {loading ? (\n <SpinnerPane h=\"100%\" />\n ) : selectedTable ? (\n <QueryDataTable\n query={`SELECT * FROM ${schema}.${escapeId(selectedTable)}`}\n />\n ) : error ? (\n <div className=\"h-full w-full overflow-auto p-5\">\n <pre className=\"text-xs leading-tight text-red-500\">\n {error}\n </pre>\n </div>\n ) : resultsTableData ? (\n <div className=\"relative flex h-full w-full flex-grow flex-col overflow-hidden\">\n <DataTableVirtualized {...resultsTableData} />\n <div className=\"absolute bottom-0 right-0 flex gap-2\">\n <Button\n size=\"sm\"\n disabled={!resultsTableData}\n onClick={handleCreateTable}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Create table\n </Button>\n <Button\n size=\"sm\"\n disabled={!results}\n onClick={exportResults}\n >\n <DownloadIcon className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n </div>\n </div>\n ) : null}\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n {/* Documentation panel - 30% width */}\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastExecutedQuery || currentQuery}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\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 </div>\n </div>\n );\n};\n\n// Wrap with React.memo to prevent unnecessary re-renders\nconst SqlEditor = React.memo(SqlEditorBase);\n\nexport default SqlEditor;\n"]}
|
|
1
|
+
{"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataTableVirtualized, QueryDataTable} from '@sqlrooms/data-table';\nimport {escapeId} from '@sqlrooms/duckdb';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n SpinnerPane,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@sqlrooms/ui';\nimport {\n BookOpenIcon,\n DownloadIcon,\n MoreVerticalIcon,\n PlayIcon,\n PlusIcon,\n} from 'lucide-react';\nimport React, {useCallback, useEffect, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\nimport DeleteSqlQueryModal from './DeleteSqlQueryModal';\nimport RenameSqlQueryModal from './RenameSqlQueryModal';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\nimport {TablesList} from './TablesList';\nimport {SqlMonacoEditor} from './SqlMonacoEditor';\nimport type * as Monaco from 'monaco-editor';\nimport {useTableManagement, useQueryExecution, useMonacoEditor} from './hooks';\nimport {useBaseProjectBuilderStore} from '@sqlrooms/project-builder';\n\n// Define the types for Monaco Editor\ntype EditorInstance = Monaco.editor.IStandaloneCodeEditor;\ntype MonacoInstance = typeof Monaco;\n\nconst DEFAULT_QUERY = '';\n\nexport type SqlEditorProps = {\n /** The database schema to use for queries. Defaults to 'main' */\n schema?: string;\n\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\n/**\n * A full-featured SQL editor component with query execution, table management, and results visualization.\n *\n * Features:\n * - Multiple query tabs with save/rename/delete functionality\n * - Query execution with results displayed in a data table\n * - Table browser showing available tables in the schema\n * - Export results to CSV\n * - Create new tables from query results\n * - Optional SQL documentation panel\n * - Keyboard shortcuts (Cmd/Ctrl + Enter to run queries)\n *\n */\nconst SqlEditorBase: React.FC<SqlEditorProps> = (props) => {\n const {schema = 'main', documentationPanel} = props;\n\n // Store access - directly use the selector\n const addOrUpdateSqlQueryDataSource = useBaseProjectBuilderStore(\n (state) => state.project.addOrUpdateSqlQueryDataSource,\n );\n\n // Get query data and methods directly from the store\n const queries = useStoreWithSqlEditor((s) => s.config.sqlEditor.queries);\n const selectedQueryId = useStoreWithSqlEditor(\n (s) => s.config.sqlEditor.selectedQueryId,\n );\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n const setSelectedQueryId = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setSelectedQueryId,\n );\n const updateQueryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.updateQueryText,\n );\n const createQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.createQueryTab,\n );\n const deleteQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.deleteQueryTab,\n );\n const renameQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.renameQueryTab,\n );\n\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n const [lastExecutedQuery, setLastExecutedQuery] = useState<string>('');\n\n // Local state for modals\n const [queryToDelete, setQueryToDelete] = useState<string | null>(null);\n const [queryToRename, setQueryToRename] = useState<{\n id: string;\n name: string;\n } | null>(null);\n\n // Custom hooks\n const {\n tables,\n tablesLoading,\n tablesError,\n tableSchemas,\n selectedTable,\n fetchTables,\n handleSelectTable,\n } = useTableManagement();\n\n const {results, resultsTableData, loading, error, runQuery, exportResults} =\n useQueryExecution(schema);\n\n const {handleEditorMount, getQueryText, setRunQueryHandler} =\n useMonacoEditor();\n\n // Get the current query text\n const currentQuery = getCurrentQuery(DEFAULT_QUERY);\n\n // Handler functions for query tab management\n const handleTabChange = useCallback(\n (value: string) => {\n setSelectedQueryId(value);\n },\n [setSelectedQueryId],\n );\n\n const handleUpdateQuery = useCallback(\n (value: string | undefined) => {\n if (!value) return;\n updateQueryText(selectedQueryId, value);\n },\n [selectedQueryId, updateQueryText],\n );\n\n const handleNewQuery = useCallback(() => {\n return createQueryTab(DEFAULT_QUERY);\n }, [createQueryTab]);\n\n const handleStartRename = useCallback(\n (queryId: string, currentName: string, event: React.MouseEvent) => {\n event.preventDefault();\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\n const handleDeleteQuery = useCallback(\n (queryId: string, event: React.MouseEvent) => {\n event.stopPropagation();\n setQueryToDelete(queryId);\n },\n [],\n );\n\n const handleConfirmDeleteQuery = useCallback(() => {\n if (queryToDelete) {\n deleteQueryTab(queryToDelete);\n setQueryToDelete(null);\n }\n }, [queryToDelete, deleteQueryTab]);\n\n // Handle run query logic\n const handleRunQuery = useCallback(async () => {\n // Clear selected table when running a query\n handleSelectTable(undefined);\n\n // Get the query text (either selected text or the entire query)\n const queryToRun = getQueryText(selectedQueryId, currentQuery);\n\n // Store the query that's being executed\n setLastExecutedQuery(queryToRun);\n\n // Run the query and refresh tables list\n await runQuery(queryToRun);\n }, [\n handleSelectTable,\n getQueryText,\n selectedQueryId,\n currentQuery,\n runQuery,\n setLastExecutedQuery,\n ]);\n\n // Set up the run query handler reference for keyboard shortcuts\n useEffect(() => {\n setRunQueryHandler(handleRunQuery);\n }, [handleRunQuery, setRunQueryHandler]);\n\n // Check if table schemas are empty and refetch if needed\n useEffect(() => {\n if (Object.keys(tableSchemas).length === 0) {\n void fetchTables();\n }\n }, [fetchTables, tableSchemas]);\n\n // Handle toggle documentation panel\n const handleToggleDocs = useCallback(() => {\n setShowDocs(!showDocs);\n }, [showDocs]);\n\n // Handle create table from query results\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 <div className=\"absolute right-12 top-0\">\n {documentationPanel ? (\n <Button\n size=\"sm\"\n variant={showDocs ? 'secondary' : 'outline'}\n onClick={handleToggleDocs}\n >\n <BookOpenIcon className=\"mr-2 h-4 w-4\" />\n SQL reference\n </Button>\n ) : (\n <a\n href=\"https://duckdb.org/docs/sql/introduction\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <Button size=\"sm\" variant={'outline'}>\n <BookOpenIcon className=\"mr-2 h-4 w-4\" />\n SQL reference\n </Button>\n </a>\n )}\n </div>\n <div className=\"flex h-full w-full flex-col gap-2\">\n <div className=\"mb-2 ml-1 mr-10 flex items-center gap-2\">\n <h2 className=\"text-lg font-semibold\">SQL Editor</h2>\n </div>\n <div className=\"bg-muted h-full flex-grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n {/* Main panel - takes full width when docs not shown, or 70% when docs shown */}\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 {tablesLoading ? (\n <SpinnerPane h=\"100%\" />\n ) : tablesError ? (\n <div className=\"p-4 text-red-500\">\n Error loading tables: {tablesError.message}\n </div>\n ) : (\n <TablesList\n schema=\"information_schema\"\n tableNames={tables}\n selectedTable={selectedTable}\n onSelect={handleSelectTable}\n />\n )}\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel\n defaultSize={80}\n className=\"flex flex-col overflow-hidden\"\n >\n <Tabs\n value={selectedQueryId}\n onValueChange={handleTabChange}\n className=\"flex h-full flex-col overflow-hidden\"\n >\n <div className=\"border-border flex items-center gap-2 border-b\">\n <Button\n size=\"sm\"\n onClick={() => void handleRunQuery()}\n className=\"uppercase\"\n >\n <PlayIcon className=\"mr-2 h-4 w-4\" />\n Run\n </Button>\n <TabsList className=\"flex-1\">\n {queries.map((q: any) => (\n <div key={q.id} className=\"relative\">\n <TabsTrigger\n value={q.id}\n className=\"min-w-[60px] px-6 pr-8\"\n >\n {q.name}\n </TabsTrigger>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <div\n className=\"hover:bg-accent absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm\"\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVerticalIcon className=\"h-3 w-3\" />\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n handleStartRename(q.id, q.name, e);\n }}\n >\n Rename\n </DropdownMenuItem>\n {queries.length > 1 && (\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n handleDeleteQuery(q.id, e);\n }}\n className=\"text-red-500\"\n >\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))}\n </TabsList>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n onClick={handleNewQuery}\n className=\"ml-2\"\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n {queries.map((q: any) => (\n <TabsContent\n key={q.id}\n value={q.id}\n className=\"relative h-full flex-grow flex-col data-[state=active]:flex\"\n >\n <div className=\"absolute inset-0 h-full w-full flex-grow\">\n <SqlMonacoEditor\n value={q.query}\n onChange={handleUpdateQuery}\n className=\"h-full w-full flex-grow\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n // Enable keyboard shortcuts\n quickSuggestions: true,\n suggestOnTriggerCharacters: true,\n }}\n onMount={(\n editor: EditorInstance,\n monaco: MonacoInstance,\n ) => {\n handleEditorMount(\n editor,\n monaco,\n q.id,\n handleRunQuery,\n );\n }}\n tableSchemas={tableSchemas}\n getLatestSchemas={() => {\n // If tableSchemas is empty, try to fetch tables\n if (Object.keys(tableSchemas).length === 0) {\n // We can't await here, but we can trigger the fetch\n // This will update the state for next time\n void fetchTables();\n }\n return {tableSchemas};\n }}\n />\n </div>\n </TabsContent>\n ))}\n </Tabs>\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel\n defaultSize={50}\n className=\"bg-muted overflow-hidden text-sm\"\n >\n {loading ? (\n <SpinnerPane h=\"100%\" />\n ) : selectedTable ? (\n <QueryDataTable\n query={`SELECT * FROM ${schema}.${escapeId(selectedTable)}`}\n />\n ) : error ? (\n <div className=\"h-full w-full overflow-auto p-5\">\n <pre className=\"text-xs leading-tight text-red-500\">\n {error}\n </pre>\n </div>\n ) : resultsTableData ? (\n <div className=\"relative flex h-full w-full flex-grow flex-col overflow-hidden\">\n <DataTableVirtualized {...resultsTableData} />\n <div className=\"absolute bottom-0 right-0 flex gap-2\">\n <Button\n size=\"sm\"\n disabled={!resultsTableData}\n onClick={handleCreateTable}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Create table\n </Button>\n <Button\n size=\"sm\"\n disabled={!results}\n onClick={exportResults}\n >\n <DownloadIcon className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n </div>\n </div>\n ) : null}\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n {/* Documentation panel - 30% width */}\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastExecutedQuery || currentQuery}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\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 </div>\n </div>\n );\n};\n\n// Wrap with React.memo to prevent unnecessary re-renders\nconst SqlEditor = React.memo(SqlEditorBase);\n\nexport default SqlEditor;\n"]}
|
package/dist/SqlEditorSlice.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { BaseProjectConfig } from '@sqlrooms/project-
|
|
1
|
+
import { DuckDbSliceConfig } from '@sqlrooms/duckdb';
|
|
2
|
+
import { ProjectBuilderState, StateCreator, BaseProjectConfig } from '@sqlrooms/project-builder';
|
|
3
3
|
import { Table } from 'apache-arrow';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
export declare const SqlEditorSliceConfig: z.ZodObject<{
|
|
@@ -109,9 +109,9 @@ export type SqlEditorSliceState = {
|
|
|
109
109
|
getCurrentQuery(defaultQuery?: string): string;
|
|
110
110
|
};
|
|
111
111
|
};
|
|
112
|
-
export declare function createSqlEditorSlice<PC extends BaseProjectConfig & SqlEditorSliceConfig>(): StateCreator<SqlEditorSliceState>;
|
|
112
|
+
export declare function createSqlEditorSlice<PC extends BaseProjectConfig & DuckDbSliceConfig & SqlEditorSliceConfig>(): StateCreator<SqlEditorSliceState>;
|
|
113
113
|
type ProjectConfigWithSqlEditor = BaseProjectConfig & SqlEditorSliceConfig;
|
|
114
|
-
type ProjectStateWithSqlEditor =
|
|
114
|
+
type ProjectStateWithSqlEditor = ProjectBuilderState<ProjectConfigWithSqlEditor> & SqlEditorSliceState;
|
|
115
115
|
export declare function useStoreWithSqlEditor<T>(selector: (state: ProjectStateWithSqlEditor) => T): T;
|
|
116
116
|
export {};
|
|
117
117
|
//# sourceMappingURL=SqlEditorSlice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAiB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAEL,mBAAmB,EACnB,YAAY,EAEZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAInC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAc/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,wBAAgB,4BAA4B,IAAI,oBAAoB,CAOnE;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE;QACT;;;;WAIG;QACH,YAAY,CACV,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;YACT,OAAO,CAAC,EAAE,KAAK,CAAC;YAChB,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC,CAAC;QAEH;;;;WAIG;QACH,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAE5D;;;WAGG;QACH,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG;YACrC,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QAEF;;;WAGG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEtC;;;;WAIG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEvD;;;;WAIG;QACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1D;;;WAGG;QACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1C;;;WAGG;QACH,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KAChD,CAAC;CACH,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,EAAE,SAAS,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,KACpE,YAAY,CAAC,mBAAmB,CAAC,CAoIrC;AAED,KAAK,0BAA0B,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAC3E,KAAK,yBAAyB,GAC5B,mBAAmB,CAAC,0BAA0B,CAAC,GAAG,mBAAmB,CAAC;AAExE,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,CAAC,GAChD,CAAC,CAMH"}
|
package/dist/SqlEditorSlice.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DuckQueryError
|
|
2
|
-
import { createSlice,
|
|
1
|
+
import { DuckQueryError } from '@sqlrooms/duckdb';
|
|
2
|
+
import { createSlice, useBaseProjectBuilderStore, } from '@sqlrooms/project-builder';
|
|
3
3
|
import { generateUniqueName, genRandomStr } from '@sqlrooms/utils';
|
|
4
4
|
import { csvFormat } from 'd3-dsv';
|
|
5
5
|
import { saveAs } from 'file-saver';
|
|
@@ -30,16 +30,13 @@ export function createSqlEditorSlice() {
|
|
|
30
30
|
return createSlice((set, get) => ({
|
|
31
31
|
sqlEditor: {
|
|
32
32
|
executeQuery: async (query, schema = 'main') => {
|
|
33
|
-
const
|
|
34
|
-
if (!duckDb.conn) {
|
|
35
|
-
return { error: 'No DuckDB connection available' };
|
|
36
|
-
}
|
|
33
|
+
const connector = await get().db.getConnector();
|
|
37
34
|
try {
|
|
38
|
-
await
|
|
39
|
-
const results = await
|
|
40
|
-
await
|
|
35
|
+
await connector.query(`SET search_path = ${schema}`);
|
|
36
|
+
const results = await connector.query(query);
|
|
37
|
+
await connector.query(`SET search_path = main`);
|
|
41
38
|
// Refresh table schemas after query execution
|
|
42
|
-
await get().
|
|
39
|
+
await get().db.refreshTableSchemas();
|
|
43
40
|
return { results };
|
|
44
41
|
}
|
|
45
42
|
catch (e) {
|
|
@@ -129,6 +126,6 @@ export function createSqlEditorSlice() {
|
|
|
129
126
|
}));
|
|
130
127
|
}
|
|
131
128
|
export function useStoreWithSqlEditor(selector) {
|
|
132
|
-
return
|
|
129
|
+
return useBaseProjectBuilderStore((state) => selector(state));
|
|
133
130
|
}
|
|
134
131
|
//# sourceMappingURL=SqlEditorSlice.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.js","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAE,SAAS,EAAsB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EACL,WAAW,EAGX,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAC,kBAAkB,EAAE,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAC,SAAS,EAAC,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAC,MAAM,EAAC,MAAM,YAAY,CAAC;AAClC,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;QAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;YACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;SACpD,CAAC,CACH;QACD,eAAe,EAAE,CAAC;aACf,MAAM,EAAE;aACR,OAAO,CAAC,SAAS,CAAC;aAClB,QAAQ,CAAC,yCAAyC,CAAC;KACvD,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,SAAS,EAAE;YACT,OAAO,EAAE,CAAC,EAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAC,CAAC;YACvD,eAAe,EAAE,SAAS;SAC3B;KACF,CAAC;AACJ,CAAC;AAoED,MAAM,UAAU,oBAAoB;IAGlC,OAAO,WAAW,CAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACzD,SAAS,EAAE;YACT,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE;gBAC7C,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;oBACjB,OAAO,EAAC,KAAK,EAAE,gCAAgC,EAAC,CAAC;gBACnD,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;oBACvD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC/C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;oBAElD,8CAA8C;oBAC9C,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;oBAE1C,OAAO,EAAC,OAAO,EAAC,CAAC;gBACnB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACjB,MAAM,YAAY,GAChB,CAAC,YAAY,cAAc;wBACzB,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE;wBACvB,CAAC,CAAC,cAAc,CAAC;oBAErB,OAAO,EAAC,KAAK,EAAE,YAAY,IAAI,MAAM,CAAC,CAAC,CAAC,EAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YAED,kBAAkB,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;gBACxC,IAAI,CAAC,OAAO;oBAAE,OAAO;gBACrB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE;oBACpD,IAAI,EAAE,0BAA0B;iBACjC,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,EAAE,QAAQ,IAAI,UAAU,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC5D,CAAC;YAED,cAAc,EAAE,CAAC,YAAY,GAAG,EAAE,EAAE,EAAE;gBACpC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;gBAC/C,MAAM,QAAQ,GAAG;oBACf,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;oBACnB,IAAI,EAAE,kBAAkB,CACtB,UAAU,EACV,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC3C;oBACD,KAAK,EAAE,YAAY;iBACpB,CAAC;gBAEF,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC9C,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,GAAG,QAAQ,CAAC,EAAE,CAAC;gBACvD,CAAC,CAAC,CACH,CAAC;gBAEF,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE;gBAC1B,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;gBAC/C,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC;gBAExC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBACxB,8BAA8B;oBAC9B,OAAO;gBACT,CAAC;gBAED,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;gBACzD,IAAI,KAAK,KAAK,CAAC,CAAC;oBAAE,OAAO;gBAEzB,MAAM,UAAU,GAAG,eAAe,CAAC,eAAe,KAAK,OAAO,CAAC;gBAC/D,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;gBAEhE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,eAAe,CAAC;oBAEjD,+EAA+E;oBAC/E,IAAI,UAAU,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC7C,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;wBAChD,kEAAkE;wBAClE,MAAM,aAAa,GACjB,eAAe,CAAC,gBAAgB,CAAC,EAAE,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBAClE,IAAI,aAAa,EAAE,CAAC;4BAClB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,GAAG,aAAa,CAAC;wBACzD,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAED,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;gBACnC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CACxB,CAAC;oBACF,IAAI,KAAK,EAAE,CAAC;wBACV,KAAK,CAAC,IAAI,GAAG,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC;oBACrC,CAAC;gBACH,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAED,eAAe,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE;gBACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CACxB,CAAC;oBACF,IAAI,KAAK,EAAE,CAAC;wBACV,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;oBAC1B,CAAC;gBACH,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAED,kBAAkB,EAAE,CAAC,OAAO,EAAE,EAAE;gBAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,GAAG,OAAO,CAAC;gBACnD,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAED,eAAe,EAAE,CAAC,YAAY,GAAG,EAAE,EAAE,EAAE;gBACrC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;gBAC/C,MAAM,UAAU,GAAG,eAAe,CAAC,eAAe,CAAC;gBACnD,mBAAmB;gBACnB,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;gBACvE,qDAAqD;gBACrD,OAAO,KAAK,EAAE,KAAK,IAAI,YAAY,CAAC;YACtC,CAAC;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC;AAMD,MAAM,UAAU,qBAAqB,CACnC,QAAiD;IAEjD,OAAO,mBAAmB,CAIxB,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAA6C,CAAC,CAAC,CAAC;AACxE,CAAC","sourcesContent":["import {DuckQueryError, getDuckDb, getDuckTableSchemas} from '@sqlrooms/duckdb';\nimport {\n createSlice,\n ProjectState,\n StateCreator,\n useBaseProjectStore,\n} from '@sqlrooms/project-builder';\nimport {BaseProjectConfig} from '@sqlrooms/project-config';\nimport {generateUniqueName, genRandomStr} from '@sqlrooms/utils';\nimport {Table} from 'apache-arrow';\nimport {csvFormat} from 'd3-dsv';\nimport {saveAs} from 'file-saver';\nimport {produce} from 'immer';\nimport {z} from 'zod';\n\nexport const SqlEditorSliceConfig = z.object({\n sqlEditor: z.object({\n queries: z.array(\n z.object({\n id: z.string().describe('Query identifier.'),\n name: z.string().describe('Query name.'),\n query: z.string().describe('SQL query to execute.'),\n }),\n ),\n selectedQueryId: z\n .string()\n .default('default')\n .describe('The id of the currently selected query.'),\n }),\n});\nexport type SqlEditorSliceConfig = z.infer<typeof SqlEditorSliceConfig>;\n\nexport function createDefaultSqlEditorConfig(): SqlEditorSliceConfig {\n return {\n sqlEditor: {\n queries: [{id: 'default', name: 'Untitled', query: ''}],\n selectedQueryId: 'default',\n },\n };\n}\n\nexport type SqlEditorSliceState = {\n sqlEditor: {\n /**\n * Execute a SQL query and return the results.\n * @param query - The SQL query to execute.\n * @param schema - The schema to use (default: main).\n */\n executeQuery(\n query: string,\n schema?: string,\n ): Promise<{\n results?: Table;\n error?: string;\n }>;\n\n /**\n * Export query results to CSV.\n * @param results - The query results to export.\n * @param filename - Optional filename (default is generated).\n */\n exportResultsToCsv(results: Table, filename?: string): void;\n\n /**\n * Create a new query tab.\n * @param initialQuery - Optional initial query text.\n */\n createQueryTab(initialQuery?: string): {\n id: string;\n name: string;\n query: string;\n };\n\n /**\n * Delete a query tab.\n * @param queryId - The ID of the query to delete.\n */\n deleteQueryTab(queryId: string): void;\n\n /**\n * Rename a query tab.\n * @param queryId - The ID of the query to rename.\n * @param newName - The new name for the query.\n */\n renameQueryTab(queryId: string, newName: string): void;\n\n /**\n * Update the SQL text for a query.\n * @param queryId - The ID of the query to update.\n * @param queryText - The new SQL text.\n */\n updateQueryText(queryId: string, queryText: string): void;\n\n /**\n * Set the selected query tab.\n * @param queryId - The ID of the query to select.\n */\n setSelectedQueryId(queryId: string): void;\n\n /**\n * Get the currently selected query's SQL text.\n * @param defaultQuery - Optional default query text to return if no query is found.\n */\n getCurrentQuery(defaultQuery?: string): string;\n };\n};\n\nexport function createSqlEditorSlice<\n PC extends BaseProjectConfig & SqlEditorSliceConfig,\n>(): StateCreator<SqlEditorSliceState> {\n return createSlice<PC, SqlEditorSliceState>((set, get) => ({\n sqlEditor: {\n executeQuery: async (query, schema = 'main') => {\n const duckDb = await getDuckDb();\n if (!duckDb.conn) {\n return {error: 'No DuckDB connection available'};\n }\n\n try {\n await duckDb.conn.query(`SET search_path = ${schema}`);\n const results = await duckDb.conn.query(query);\n await duckDb.conn.query(`SET search_path = main`);\n\n // Refresh table schemas after query execution\n await get().project.refreshTableSchemas();\n\n return {results};\n } catch (e) {\n console.error(e);\n const errorMessage =\n e instanceof DuckQueryError\n ? e.getMessageForUser()\n : 'Query failed';\n\n return {error: errorMessage || String(e)};\n }\n },\n\n exportResultsToCsv: (results, filename) => {\n if (!results) return;\n const blob = new Blob([csvFormat(results.toArray())], {\n type: 'text/plain;charset=utf-8',\n });\n saveAs(blob, filename || `export-${genRandomStr(5)}.csv`);\n },\n\n createQueryTab: (initialQuery = '') => {\n const sqlEditorConfig = get().config.sqlEditor;\n const newQuery = {\n id: genRandomStr(8),\n name: generateUniqueName(\n 'Untitled',\n sqlEditorConfig.queries.map((q) => q.name),\n ),\n query: initialQuery,\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.config.sqlEditor.queries.push(newQuery);\n draft.config.sqlEditor.selectedQueryId = newQuery.id;\n }),\n );\n\n return newQuery;\n },\n\n deleteQueryTab: (queryId) => {\n const sqlEditorConfig = get().config.sqlEditor;\n const queries = sqlEditorConfig.queries;\n\n if (queries.length <= 1) {\n // Don't delete the last query\n return;\n }\n\n const index = queries.findIndex((q) => q.id === queryId);\n if (index === -1) return;\n\n const isSelected = sqlEditorConfig.selectedQueryId === queryId;\n const filteredQueries = queries.filter((q) => q.id !== queryId);\n\n set((state) =>\n produce(state, (draft) => {\n draft.config.sqlEditor.queries = filteredQueries;\n\n // If we're deleting the selected tab, select the previous one or the first one\n if (isSelected && filteredQueries.length > 0) {\n const newSelectedIndex = Math.max(0, index - 1);\n // Safely access the ID with fallback to the first query if needed\n const newSelectedId =\n filteredQueries[newSelectedIndex]?.id ?? filteredQueries[0]?.id;\n if (newSelectedId) {\n draft.config.sqlEditor.selectedQueryId = newSelectedId;\n }\n }\n }),\n );\n },\n\n renameQueryTab: (queryId, newName) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.config.sqlEditor.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.name = newName || query.name;\n }\n }),\n );\n },\n\n updateQueryText: (queryId, queryText) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.config.sqlEditor.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.query = queryText;\n }\n }),\n );\n },\n\n setSelectedQueryId: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.config.sqlEditor.selectedQueryId = queryId;\n }),\n );\n },\n\n getCurrentQuery: (defaultQuery = '') => {\n const sqlEditorConfig = get().config.sqlEditor;\n const selectedId = sqlEditorConfig.selectedQueryId;\n // Find query by ID\n const query = sqlEditorConfig.queries.find((q) => q.id === selectedId);\n // If found, return its query text, otherwise default\n return query?.query || defaultQuery;\n },\n },\n }));\n}\n\ntype ProjectConfigWithSqlEditor = BaseProjectConfig & SqlEditorSliceConfig;\ntype ProjectStateWithSqlEditor = ProjectState<ProjectConfigWithSqlEditor> &\n SqlEditorSliceState;\n\nexport function useStoreWithSqlEditor<T>(\n selector: (state: ProjectStateWithSqlEditor) => T,\n): T {\n return useBaseProjectStore<\n BaseProjectConfig & SqlEditorSliceConfig,\n ProjectState<ProjectConfigWithSqlEditor>,\n T\n >((state) => selector(state as unknown as ProjectStateWithSqlEditor));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.js","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DuckDbSliceConfig, DuckQueryError} from '@sqlrooms/duckdb';\nimport {\n createSlice,\n ProjectBuilderState,\n StateCreator,\n useBaseProjectBuilderStore,\n BaseProjectConfig,\n} from '@sqlrooms/project-builder';\nimport {generateUniqueName, genRandomStr} from '@sqlrooms/utils';\nimport {Table} from 'apache-arrow';\nimport {csvFormat} from 'd3-dsv';\nimport {saveAs} from 'file-saver';\nimport {produce} from 'immer';\nimport {z} from 'zod';\n\nexport const SqlEditorSliceConfig = z.object({\n sqlEditor: z.object({\n queries: z.array(\n z.object({\n id: z.string().describe('Query identifier.'),\n name: z.string().describe('Query name.'),\n query: z.string().describe('SQL query to execute.'),\n }),\n ),\n selectedQueryId: z\n .string()\n .default('default')\n .describe('The id of the currently selected query.'),\n }),\n});\nexport type SqlEditorSliceConfig = z.infer<typeof SqlEditorSliceConfig>;\n\nexport function createDefaultSqlEditorConfig(): SqlEditorSliceConfig {\n return {\n sqlEditor: {\n queries: [{id: 'default', name: 'Untitled', query: ''}],\n selectedQueryId: 'default',\n },\n };\n}\n\nexport type SqlEditorSliceState = {\n sqlEditor: {\n /**\n * Execute a SQL query and return the results.\n * @param query - The SQL query to execute.\n * @param schema - The schema to use (default: main).\n */\n executeQuery(\n query: string,\n schema?: string,\n ): Promise<{\n results?: Table;\n error?: string;\n }>;\n\n /**\n * Export query results to CSV.\n * @param results - The query results to export.\n * @param filename - Optional filename (default is generated).\n */\n exportResultsToCsv(results: Table, filename?: string): void;\n\n /**\n * Create a new query tab.\n * @param initialQuery - Optional initial query text.\n */\n createQueryTab(initialQuery?: string): {\n id: string;\n name: string;\n query: string;\n };\n\n /**\n * Delete a query tab.\n * @param queryId - The ID of the query to delete.\n */\n deleteQueryTab(queryId: string): void;\n\n /**\n * Rename a query tab.\n * @param queryId - The ID of the query to rename.\n * @param newName - The new name for the query.\n */\n renameQueryTab(queryId: string, newName: string): void;\n\n /**\n * Update the SQL text for a query.\n * @param queryId - The ID of the query to update.\n * @param queryText - The new SQL text.\n */\n updateQueryText(queryId: string, queryText: string): void;\n\n /**\n * Set the selected query tab.\n * @param queryId - The ID of the query to select.\n */\n setSelectedQueryId(queryId: string): void;\n\n /**\n * Get the currently selected query's SQL text.\n * @param defaultQuery - Optional default query text to return if no query is found.\n */\n getCurrentQuery(defaultQuery?: string): string;\n };\n};\n\nexport function createSqlEditorSlice<\n PC extends BaseProjectConfig & DuckDbSliceConfig & SqlEditorSliceConfig,\n>(): StateCreator<SqlEditorSliceState> {\n return createSlice<PC, SqlEditorSliceState>((set, get) => ({\n sqlEditor: {\n executeQuery: async (query, schema = 'main') => {\n const connector = await get().db.getConnector();\n\n try {\n await connector.query(`SET search_path = ${schema}`);\n const results = await connector.query(query);\n await connector.query(`SET search_path = main`);\n\n // Refresh table schemas after query execution\n await get().db.refreshTableSchemas();\n\n return {results};\n } catch (e) {\n console.error(e);\n const errorMessage =\n e instanceof DuckQueryError\n ? e.getMessageForUser()\n : 'Query failed';\n\n return {error: errorMessage || String(e)};\n }\n },\n\n exportResultsToCsv: (results, filename) => {\n if (!results) return;\n const blob = new Blob([csvFormat(results.toArray())], {\n type: 'text/plain;charset=utf-8',\n });\n saveAs(blob, filename || `export-${genRandomStr(5)}.csv`);\n },\n\n createQueryTab: (initialQuery = '') => {\n const sqlEditorConfig = get().config.sqlEditor;\n const newQuery = {\n id: genRandomStr(8),\n name: generateUniqueName(\n 'Untitled',\n sqlEditorConfig.queries.map((q) => q.name),\n ),\n query: initialQuery,\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.config.sqlEditor.queries.push(newQuery);\n draft.config.sqlEditor.selectedQueryId = newQuery.id;\n }),\n );\n\n return newQuery;\n },\n\n deleteQueryTab: (queryId) => {\n const sqlEditorConfig = get().config.sqlEditor;\n const queries = sqlEditorConfig.queries;\n\n if (queries.length <= 1) {\n // Don't delete the last query\n return;\n }\n\n const index = queries.findIndex((q) => q.id === queryId);\n if (index === -1) return;\n\n const isSelected = sqlEditorConfig.selectedQueryId === queryId;\n const filteredQueries = queries.filter((q) => q.id !== queryId);\n\n set((state) =>\n produce(state, (draft) => {\n draft.config.sqlEditor.queries = filteredQueries;\n\n // If we're deleting the selected tab, select the previous one or the first one\n if (isSelected && filteredQueries.length > 0) {\n const newSelectedIndex = Math.max(0, index - 1);\n // Safely access the ID with fallback to the first query if needed\n const newSelectedId =\n filteredQueries[newSelectedIndex]?.id ?? filteredQueries[0]?.id;\n if (newSelectedId) {\n draft.config.sqlEditor.selectedQueryId = newSelectedId;\n }\n }\n }),\n );\n },\n\n renameQueryTab: (queryId, newName) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.config.sqlEditor.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.name = newName || query.name;\n }\n }),\n );\n },\n\n updateQueryText: (queryId, queryText) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.config.sqlEditor.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.query = queryText;\n }\n }),\n );\n },\n\n setSelectedQueryId: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.config.sqlEditor.selectedQueryId = queryId;\n }),\n );\n },\n\n getCurrentQuery: (defaultQuery = '') => {\n const sqlEditorConfig = get().config.sqlEditor;\n const selectedId = sqlEditorConfig.selectedQueryId;\n // Find query by ID\n const query = sqlEditorConfig.queries.find((q) => q.id === selectedId);\n // If found, return its query text, otherwise default\n return query?.query || defaultQuery;\n },\n },\n }));\n}\n\ntype ProjectConfigWithSqlEditor = BaseProjectConfig & SqlEditorSliceConfig;\ntype ProjectStateWithSqlEditor =\n ProjectBuilderState<ProjectConfigWithSqlEditor> & SqlEditorSliceState;\n\nexport function useStoreWithSqlEditor<T>(\n selector: (state: ProjectStateWithSqlEditor) => T,\n): T {\n return useBaseProjectBuilderStore<\n BaseProjectConfig & SqlEditorSliceConfig,\n ProjectBuilderState<ProjectConfigWithSqlEditor>,\n T\n >((state) => selector(state as unknown as ProjectStateWithSqlEditor));\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { SqlQueryDataSource } from '@sqlrooms/project-
|
|
1
|
+
import { SqlQueryDataSource } from '@sqlrooms/project-builder';
|
|
2
2
|
import { FC } from 'react';
|
|
3
3
|
declare const SqlQueryDataSourcesPanel: FC<{
|
|
4
|
+
isReadOnly?: boolean;
|
|
4
5
|
queryDataSources: SqlQueryDataSource[];
|
|
5
6
|
}>;
|
|
6
7
|
export { SqlQueryDataSourcesPanel };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlQueryDataSourcesPanel.d.ts","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SqlQueryDataSourcesPanel.d.ts","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC;AAgB7D,OAAO,EAAC,EAAE,EAAwB,MAAM,OAAO,CAAC;AAGhD,QAAA,MAAM,wBAAwB,EAAE,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;CACxC,CAoHA,CAAC;AAEF,OAAO,EAAC,wBAAwB,EAAC,CAAC"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { DataSourceStatus,
|
|
2
|
+
import { DataSourceStatus, useBaseProjectBuilderStore, } from '@sqlrooms/project-builder';
|
|
3
3
|
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@sqlrooms/ui';
|
|
4
4
|
import { EllipsisIcon, FileIcon, PencilIcon, PlusIcon, RefreshCcwIcon, XIcon, } from 'lucide-react';
|
|
5
5
|
import { useCallback, useState } from 'react';
|
|
6
6
|
import CreateTableModal from './CreateTableModal';
|
|
7
|
-
const SqlQueryDataSourcesPanel = (
|
|
8
|
-
const { queryDataSources } = props;
|
|
7
|
+
const SqlQueryDataSourcesPanel = ({ queryDataSources, isReadOnly }) => {
|
|
9
8
|
const [selectedDataSource, setSelectedDataSource] = useState();
|
|
10
9
|
const [isOpen, setIsOpen] = useState(false);
|
|
11
|
-
const dataSourceStates =
|
|
12
|
-
const removeSqlQueryDataSource =
|
|
10
|
+
const dataSourceStates = useBaseProjectBuilderStore((state) => state.project.dataSourceStates);
|
|
11
|
+
const removeSqlQueryDataSource = useBaseProjectBuilderStore((state) => state.project.removeSqlQueryDataSource);
|
|
13
12
|
const handleEdit = useCallback((dataSource) => {
|
|
14
13
|
setSelectedDataSource(dataSource);
|
|
15
14
|
setIsOpen(true);
|
|
@@ -22,8 +21,7 @@ const SqlQueryDataSourcesPanel = (props) => {
|
|
|
22
21
|
const { tableName } = dataSource;
|
|
23
22
|
removeSqlQueryDataSource(tableName);
|
|
24
23
|
}, [removeSqlQueryDataSource]);
|
|
25
|
-
const addOrUpdateSqlQueryDataSource =
|
|
26
|
-
const isReadOnly = useBaseProjectStore((state) => state.project.isReadOnly);
|
|
24
|
+
const addOrUpdateSqlQueryDataSource = useBaseProjectBuilderStore((state) => state.project.addOrUpdateSqlQueryDataSource);
|
|
27
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 from project"] })] })] })) : null })] }), _jsx("div", { className: "flex flex-row items-center gap-1", children: dataSourceStates[dataSource.tableName]?.status ===
|
|
28
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 ===
|
|
29
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))) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlQueryDataSourcesPanel.js","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"SqlQueryDataSourcesPanel.js","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DataSourceStatus,\n useBaseProjectBuilderStore,\n} from '@sqlrooms/project-builder';\nimport {SqlQueryDataSource} from '@sqlrooms/project-builder';\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 = useBaseProjectBuilderStore(\n (state) => state.project.dataSourceStates,\n );\n const removeSqlQueryDataSource = useBaseProjectBuilderStore(\n (state) => state.project.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 = useBaseProjectBuilderStore(\n (state) => state.project.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 from project\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"]}
|
|
@@ -5,9 +5,9 @@ import { useStoreWithSqlEditor } from '../SqlEditorSlice';
|
|
|
5
5
|
*/
|
|
6
6
|
export function useTableManagement() {
|
|
7
7
|
// Get data from the store without refs
|
|
8
|
-
const rawTables = useStoreWithSqlEditor((s) => s.
|
|
8
|
+
const rawTables = useStoreWithSqlEditor((s) => s.db.tables);
|
|
9
9
|
const tables = useMemo(() => rawTables.map((t) => t.tableName), [rawTables]);
|
|
10
|
-
const refreshTableSchemas = useStoreWithSqlEditor((s) => s.
|
|
10
|
+
const refreshTableSchemas = useStoreWithSqlEditor((s) => s.db.refreshTableSchemas);
|
|
11
11
|
// Use the DataTable[] directly without transforming it
|
|
12
12
|
const tableSchemas = useMemo(() => rawTables || [], [rawTables]);
|
|
13
13
|
const [tablesLoading, setTablesLoading] = useState(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTableManagement.js","sourceRoot":"","sources":["../../src/hooks/useTableManagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAC,qBAAqB,EAAC,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,uCAAuC;IACvC,MAAM,SAAS,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"useTableManagement.js","sourceRoot":"","sources":["../../src/hooks/useTableManagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAC,qBAAqB,EAAC,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,uCAAuC;IACvC,MAAM,SAAS,GAAG,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAClD,CAAC,SAAS,CAAC,CACZ,CAAC;IACF,MAAM,mBAAmB,GAAG,qBAAqB,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAChC,CAAC;IAEF,uDAAuD;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEjE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACnE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,EAAsB,CAAC;IAEzE,gCAAgC;IAChC,MAAM,iBAAiB,GAAG,WAAW,CAAC,CAAC,KAAyB,EAAE,EAAE;QAClE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,0EAA0E;IAC1E,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzC,IAAI,CAAC;YACH,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,cAAc,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,mBAAmB;gBAAE,MAAM,mBAAmB,EAAE,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YACjD,cAAc,CAAC,KAAc,CAAC,CAAC;QACjC,CAAC;gBAAS,CAAC;YACT,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAE1B,OAAO;QACL,MAAM;QACN,aAAa;QACb,WAAW;QACX,YAAY;QACZ,aAAa;QACb,WAAW;QACX,iBAAiB;KAClB,CAAC;AACJ,CAAC","sourcesContent":["import {DataTable} from '@sqlrooms/duckdb';\nimport {useCallback, useMemo, useState} from 'react';\nimport {useStoreWithSqlEditor} from '../SqlEditorSlice';\n\n/**\n * Hook to manage SQL tables, their schemas, and sample data\n */\nexport function useTableManagement() {\n // Get data from the store without refs\n const rawTables = useStoreWithSqlEditor((s) => s.db.tables);\n const tables = useMemo(\n () => rawTables.map((t: DataTable) => t.tableName),\n [rawTables],\n );\n const refreshTableSchemas = useStoreWithSqlEditor(\n (s) => s.db.refreshTableSchemas,\n );\n\n // Use the DataTable[] directly without transforming it\n const tableSchemas = useMemo(() => rawTables || [], [rawTables]);\n\n const [tablesLoading, setTablesLoading] = useState(false);\n const [tablesError, setTablesError] = useState<Error | null>(null);\n const [selectedTable, setSelectedTable] = useState<string | undefined>();\n\n // Handler for selecting a table\n const handleSelectTable = useCallback((table: string | undefined) => {\n setSelectedTable(table);\n }, []);\n\n // The fetchTables method now just refreshes the schemas from ProjectStore\n const fetchTables = useCallback(async () => {\n try {\n setTablesLoading(true);\n setTablesError(null);\n if (refreshTableSchemas) await refreshTableSchemas();\n } catch (error) {\n console.error('Error refreshing tables:', error);\n setTablesError(error as Error);\n } finally {\n setTablesLoading(false);\n }\n }, [refreshTableSchemas]);\n\n return {\n tables,\n tablesLoading,\n tablesError,\n tableSchemas,\n selectedTable,\n fetchTables,\n handleSelectTable,\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/sql-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Ilya Boyandin <ilya@boyandin.me>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@hookform/resolvers": "^3.10.0",
|
|
29
29
|
"@monaco-editor/react": "^4.7.0",
|
|
30
|
-
"@sqlrooms/data-table": "0.
|
|
31
|
-
"@sqlrooms/duckdb": "0.
|
|
32
|
-
"@sqlrooms/layout": "0.
|
|
33
|
-
"@sqlrooms/monaco-editor": "0.
|
|
34
|
-
"@sqlrooms/project-builder": "0.
|
|
35
|
-
"@sqlrooms/project-config": "0.
|
|
36
|
-
"@sqlrooms/ui": "0.
|
|
37
|
-
"@sqlrooms/utils": "0.
|
|
30
|
+
"@sqlrooms/data-table": "0.9.1",
|
|
31
|
+
"@sqlrooms/duckdb": "0.9.1",
|
|
32
|
+
"@sqlrooms/layout": "0.9.1",
|
|
33
|
+
"@sqlrooms/monaco-editor": "0.9.1",
|
|
34
|
+
"@sqlrooms/project-builder": "0.9.1",
|
|
35
|
+
"@sqlrooms/project-config": "0.9.1",
|
|
36
|
+
"@sqlrooms/ui": "0.9.1",
|
|
37
|
+
"@sqlrooms/utils": "0.9.1",
|
|
38
38
|
"apache-arrow": "^18.1.0",
|
|
39
39
|
"d3-dsv": "^3.0.1",
|
|
40
40
|
"file-saver": "^2.0.5",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"@types/react": "^18.2.48",
|
|
56
56
|
"@types/react-dom": "^18.2.18"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "8ffc60d215729cae38631a5037866c193c7520e9"
|
|
59
59
|
}
|