@sqlrooms/sql-editor 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SqlEditor.d.ts +0 -8
- package/dist/SqlEditor.d.ts.map +1 -1
- package/dist/SqlEditor.js +13 -9
- package/dist/SqlEditorSlice.d.ts +20 -0
- package/dist/SqlEditorSlice.d.ts.map +1 -0
- package/dist/SqlEditorSlice.js +56 -0
- package/dist/SqlEditorSliceConfig.d.ts +53 -0
- package/dist/SqlEditorSliceConfig.d.ts.map +1 -0
- package/dist/SqlEditorSliceConfig.js +14 -0
- package/dist/SqlQueryDataSourcesPanel.d.ts +7 -0
- package/dist/SqlQueryDataSourcesPanel.d.ts.map +1 -0
- package/dist/SqlQueryDataSourcesPanel.js +32 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/package.json +13 -10
package/dist/SqlEditor.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { SqlEditorConfig } from '@sqlrooms/project-config';
|
|
2
1
|
import React from 'react';
|
|
3
|
-
import { CreateTableModalProps } from './CreateTableModal';
|
|
4
2
|
export type SqlEditorProps = {
|
|
5
3
|
/** The database schema to use for queries. Defaults to 'main' */
|
|
6
4
|
schema?: string;
|
|
@@ -8,14 +6,8 @@ export type SqlEditorProps = {
|
|
|
8
6
|
isOpen: boolean;
|
|
9
7
|
/** Optional component to render SQL documentation in the side panel */
|
|
10
8
|
documentationPanel?: React.ReactNode;
|
|
11
|
-
/** Configuration object containing queries and selected query state */
|
|
12
|
-
sqlEditorConfig: SqlEditorConfig;
|
|
13
|
-
/** Callback fired when the SQL editor configuration changes */
|
|
14
|
-
onChange: (config: SqlEditorConfig) => void;
|
|
15
9
|
/** Callback fired when the SQL editor should be closed */
|
|
16
10
|
onClose: () => void;
|
|
17
|
-
/** Callback fired when a new table should be created from query results */
|
|
18
|
-
onAddOrUpdateSqlQuery: CreateTableModalProps['onAddOrUpdateSqlQuery'];
|
|
19
11
|
};
|
|
20
12
|
/**
|
|
21
13
|
* A full-featured SQL editor component with query execution, table management, and results visualization.
|
package/dist/SqlEditor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAUtE,MAAM,MAAM,cAAc,GAAG;IAC3B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAEhB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAErC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAsbvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
package/dist/SqlEditor.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { DataTableVirtualized, QueryDataTable, useArrowDataTable, } from '@sqlrooms/data-table';
|
|
3
3
|
import { DuckQueryError, escapeId, getDuckTables, useDuckDb, } from '@sqlrooms/duckdb';
|
|
4
|
-
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, SpinnerPane, Tabs, TabsContent, TabsList, TabsTrigger, Textarea,
|
|
4
|
+
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, ResizableHandle, ResizablePanel, ResizablePanelGroup, SpinnerPane, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, } from '@sqlrooms/ui';
|
|
5
5
|
import { genRandomStr, generateUniqueName } from '@sqlrooms/utils';
|
|
6
6
|
import { csvFormat } from 'd3-dsv';
|
|
7
7
|
import { saveAs } from 'file-saver';
|
|
@@ -10,6 +10,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
10
10
|
import CreateTableModal from './CreateTableModal';
|
|
11
11
|
import DeleteSqlQueryModal from './DeleteSqlQueryModal';
|
|
12
12
|
import RenameSqlQueryModal from './RenameSqlQueryModal';
|
|
13
|
+
import { useStoreWithSqlEditor } from './SqlEditorSlice';
|
|
13
14
|
import { TablesList } from './TablesList';
|
|
14
15
|
const DEFAULT_QUERY = '';
|
|
15
16
|
/**
|
|
@@ -26,8 +27,11 @@ const DEFAULT_QUERY = '';
|
|
|
26
27
|
*
|
|
27
28
|
*/
|
|
28
29
|
const SqlEditor = (props) => {
|
|
29
|
-
const { schema = 'main', documentationPanel
|
|
30
|
+
const { schema = 'main', documentationPanel } = props;
|
|
30
31
|
const duckConn = useDuckDb();
|
|
32
|
+
const addOrUpdateSqlQuery = useStoreWithSqlEditor((state) => state.sqlEditor.addOrUpdateSqlQuery);
|
|
33
|
+
const sqlEditorConfig = useStoreWithSqlEditor((s) => s.projectConfig.sqlEditor);
|
|
34
|
+
const onChangeSqlEditorConfig = useStoreWithSqlEditor((s) => s.sqlEditor.setSqlEditorConfig);
|
|
31
35
|
const [showDocs, setShowDocs] = useState(false);
|
|
32
36
|
const [tables, setTables] = useState([]);
|
|
33
37
|
const [tablesLoading, setTablesLoading] = useState(false);
|
|
@@ -98,7 +102,7 @@ const SqlEditor = (props) => {
|
|
|
98
102
|
return getQueryIndexById(sqlEditorConfig.selectedQueryId);
|
|
99
103
|
};
|
|
100
104
|
const handleTabChange = (value) => {
|
|
101
|
-
|
|
105
|
+
onChangeSqlEditorConfig({
|
|
102
106
|
...sqlEditorConfig,
|
|
103
107
|
selectedQueryId: value,
|
|
104
108
|
});
|
|
@@ -114,7 +118,7 @@ const SqlEditor = (props) => {
|
|
|
114
118
|
...newQueries[currentIndex],
|
|
115
119
|
query: e.target.value,
|
|
116
120
|
};
|
|
117
|
-
|
|
121
|
+
onChangeSqlEditorConfig({
|
|
118
122
|
...sqlEditorConfig,
|
|
119
123
|
queries: newQueries,
|
|
120
124
|
});
|
|
@@ -159,7 +163,7 @@ const SqlEditor = (props) => {
|
|
|
159
163
|
const handleFinishRename = (newName) => {
|
|
160
164
|
if (queryToRename) {
|
|
161
165
|
const newQueries = sqlEditorConfig.queries.map((q) => q.id === queryToRename.id ? { ...q, name: newName || q.name } : q);
|
|
162
|
-
|
|
166
|
+
onChangeSqlEditorConfig({
|
|
163
167
|
...sqlEditorConfig,
|
|
164
168
|
queries: newQueries,
|
|
165
169
|
});
|
|
@@ -174,7 +178,7 @@ const SqlEditor = (props) => {
|
|
|
174
178
|
if (queryId === sqlEditorConfig.selectedQueryId && currentIndex > 0) {
|
|
175
179
|
const prevId = sqlEditorConfig.queries[currentIndex - 1]?.id;
|
|
176
180
|
if (prevId) {
|
|
177
|
-
|
|
181
|
+
onChangeSqlEditorConfig({
|
|
178
182
|
...sqlEditorConfig,
|
|
179
183
|
selectedQueryId: prevId,
|
|
180
184
|
});
|
|
@@ -189,7 +193,7 @@ const SqlEditor = (props) => {
|
|
|
189
193
|
query: DEFAULT_QUERY,
|
|
190
194
|
};
|
|
191
195
|
newQueries.push(newQuery);
|
|
192
|
-
|
|
196
|
+
onChangeSqlEditorConfig({
|
|
193
197
|
...sqlEditorConfig,
|
|
194
198
|
queries: newQueries,
|
|
195
199
|
selectedQueryId: newQuery.id,
|
|
@@ -201,13 +205,13 @@ const SqlEditor = (props) => {
|
|
|
201
205
|
}, children: "Rename" }), sqlEditorConfig.queries.length > 1 && (_jsx(DropdownMenuItem, { onClick: (e) => {
|
|
202
206
|
e.stopPropagation();
|
|
203
207
|
handleDeleteQuery(q.id, e);
|
|
204
|
-
}, className: "text-red-500", children: "Delete" }))] })] })] }, q.id))) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: handleNewQuery, className: "ml-2", children: _jsx(PlusIcon, { className: "h-4 w-4" }) })] }), sqlEditorConfig.queries.map((q) => (_jsx(TabsContent, { value: q.id, className: "flex-grow data-[state=active]:flex-grow", children: _jsx(Textarea, { id: q.id, value: q.query, onChange: handleUpdateQuery, className: "h-full font-mono text-sm resize-none bg-muted" }) }, q.id)))] }) }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 50, children: _jsx("div", { className: "h-full overflow-hidden bg-muted text-sm", children: loading ? (_jsx(SpinnerPane, { h: "100%" })) : selectedTable ? (_jsx(QueryDataTable, { query: `SELECT * FROM ${schema}.${escapeId(selectedTable)}` })) : error ? (_jsx("div", { className: "w-full h-full p-5 overflow-auto", children: _jsx("pre", { className: "text-xs leading-tight text-red-500", children: error }) })) : resultsTableData ? (_jsxs("div", { className: "flex-grow overflow-hidden flex flex-col relative", children: [_jsx(DataTableVirtualized, { ...resultsTableData }), _jsxs("div", { className: "absolute bottom-0 right-0 flex gap-2 p-2", children: [_jsxs(Button, { size: "sm", disabled: !resultsTableData, onClick: handleCreateTable, children: [_jsx(PlusIcon, { className: "w-4 h-4 mr-2" }), "Create table"] }), _jsxs(Button, { size: "sm", disabled: !results, onClick: handleExport, children: [_jsx(DownloadIcon, { className: "w-4 h-4 mr-2" }), "Export"] })] })] })) : null }) })] }) }), showDocs && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 30, children: documentationPanel })] }))] }) }), _jsx(CreateTableModal, { query: currentQuery, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), onAddOrUpdateSqlQuery:
|
|
208
|
+
}, className: "text-red-500", children: "Delete" }))] })] })] }, q.id))) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: handleNewQuery, className: "ml-2", children: _jsx(PlusIcon, { className: "h-4 w-4" }) })] }), sqlEditorConfig.queries.map((q) => (_jsx(TabsContent, { value: q.id, className: "flex-grow data-[state=active]:flex-grow", children: _jsx(Textarea, { id: q.id, value: q.query, onChange: handleUpdateQuery, className: "h-full font-mono text-sm resize-none bg-muted" }) }, q.id)))] }) }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 50, children: _jsx("div", { className: "h-full overflow-hidden bg-muted text-sm", children: loading ? (_jsx(SpinnerPane, { h: "100%" })) : selectedTable ? (_jsx(QueryDataTable, { query: `SELECT * FROM ${schema}.${escapeId(selectedTable)}` })) : error ? (_jsx("div", { className: "w-full h-full p-5 overflow-auto", children: _jsx("pre", { className: "text-xs leading-tight text-red-500", children: error }) })) : resultsTableData ? (_jsxs("div", { className: "flex-grow overflow-hidden flex flex-col relative", children: [_jsx(DataTableVirtualized, { ...resultsTableData }), _jsxs("div", { className: "absolute bottom-0 right-0 flex gap-2 p-2", children: [_jsxs(Button, { size: "sm", disabled: !resultsTableData, onClick: handleCreateTable, children: [_jsx(PlusIcon, { className: "w-4 h-4 mr-2" }), "Create table"] }), _jsxs(Button, { size: "sm", disabled: !results, onClick: handleExport, children: [_jsx(DownloadIcon, { className: "w-4 h-4 mr-2" }), "Export"] })] })] })) : null }) })] }) }), showDocs && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 30, children: documentationPanel })] }))] }) }), _jsx(CreateTableModal, { query: currentQuery, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), onAddOrUpdateSqlQuery: addOrUpdateSqlQuery }), _jsx(DeleteSqlQueryModal, { isOpen: queryToDelete !== null, onClose: () => setQueryToDelete(null), onConfirm: () => {
|
|
205
209
|
const newQueries = sqlEditorConfig.queries.filter((q) => q.id !== queryToDelete);
|
|
206
210
|
const deletedIndex = getQueryIndexById(queryToDelete);
|
|
207
211
|
const selectedQueryId = newQueries[Math.min(deletedIndex, newQueries.length - 1)]?.id ||
|
|
208
212
|
newQueries[0]?.id;
|
|
209
213
|
if (selectedQueryId) {
|
|
210
|
-
|
|
214
|
+
onChangeSqlEditorConfig({
|
|
211
215
|
...sqlEditorConfig,
|
|
212
216
|
queries: newQueries,
|
|
213
217
|
selectedQueryId,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ProjectState } from '@sqlrooms/project-builder';
|
|
2
|
+
import { BaseProjectConfig } from '@sqlrooms/project-config';
|
|
3
|
+
import { SqlEditorSliceConfig } from './SqlEditorSliceConfig';
|
|
4
|
+
export declare function createDefaultSqlEditorConfig(): SqlEditorSliceConfig;
|
|
5
|
+
export type SqlEditorSliceState = {
|
|
6
|
+
sqlEditor: {
|
|
7
|
+
setSqlEditorConfig: (config: SqlEditorSliceConfig['sqlEditor']) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Pin a panel.
|
|
10
|
+
* @param panel - The panel to pin.
|
|
11
|
+
*/
|
|
12
|
+
addOrUpdateSqlQuery(tableName: string, query: string, oldTableName?: string): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare function createSqlEditorSlice<PC extends BaseProjectConfig & SqlEditorSliceConfig>(): import("zustand").StateCreator<SqlEditorSliceState>;
|
|
16
|
+
type ProjectConfigWithSqlEditor = BaseProjectConfig & SqlEditorSliceConfig;
|
|
17
|
+
type ProjectStateWithSqlEditor = ProjectState<ProjectConfigWithSqlEditor> & SqlEditorSliceState;
|
|
18
|
+
export declare function useStoreWithSqlEditor<T>(selector: (state: ProjectStateWithSqlEditor) => T): T;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=SqlEditorSlice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAKA,OAAO,EAGL,YAAY,EAEb,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,iBAAiB,EAAkB,MAAM,0BAA0B,CAAC;AAG5E,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAE5D,wBAAgB,4BAA4B,IAAI,oBAAoB,CAOnE;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE;QACT,kBAAkB,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;QACxE;;;WAGG;QACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,EAAE,SAAS,iBAAiB,GAAG,oBAAoB,yDA+CpD;AAED,KAAK,0BAA0B,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAC3E,KAAK,yBAAyB,GAAG,YAAY,CAAC,0BAA0B,CAAC,GACvE,mBAAmB,CAAC;AAEtB,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,CAAC,GAChD,CAAC,CAMH"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createTableFromQuery, getDuckTables, getDuckTableSchemas, } from '@sqlrooms/duckdb';
|
|
2
|
+
import { createProjectSlice, DataSourceStatus, useBaseProjectStore, } from '@sqlrooms/project-builder';
|
|
3
|
+
import { DataSourceTypes } from '@sqlrooms/project-config';
|
|
4
|
+
import { generateUniqueName } from '@sqlrooms/utils';
|
|
5
|
+
import { produce } from 'immer';
|
|
6
|
+
export function createDefaultSqlEditorConfig() {
|
|
7
|
+
return {
|
|
8
|
+
sqlEditor: {
|
|
9
|
+
queries: [{ id: 'default', name: 'Untitled', query: '' }],
|
|
10
|
+
selectedQueryId: 'default',
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function createSqlEditorSlice() {
|
|
15
|
+
return createProjectSlice((set, get) => ({
|
|
16
|
+
sqlEditor: {
|
|
17
|
+
setSqlEditorConfig: (config) => {
|
|
18
|
+
set((state) => produce(state, (draft) => {
|
|
19
|
+
draft.projectConfig.sqlEditor = config;
|
|
20
|
+
}));
|
|
21
|
+
},
|
|
22
|
+
addOrUpdateSqlQuery: async (tableName, query, oldTableName) => {
|
|
23
|
+
const { schema } = get();
|
|
24
|
+
const newTableName = tableName !== oldTableName
|
|
25
|
+
? generateUniqueName(tableName, await getDuckTables(schema))
|
|
26
|
+
: tableName;
|
|
27
|
+
const { rowCount } = await createTableFromQuery(newTableName, query);
|
|
28
|
+
get().setTableRowCount(newTableName, rowCount);
|
|
29
|
+
set((state) => produce(state, (draft) => {
|
|
30
|
+
const newDataSource = {
|
|
31
|
+
type: DataSourceTypes.enum.sql,
|
|
32
|
+
sqlQuery: query,
|
|
33
|
+
tableName: newTableName,
|
|
34
|
+
};
|
|
35
|
+
if (oldTableName) {
|
|
36
|
+
draft.projectConfig.dataSources =
|
|
37
|
+
draft.projectConfig.dataSources.map((dataSource) => dataSource.tableName === oldTableName
|
|
38
|
+
? newDataSource
|
|
39
|
+
: dataSource);
|
|
40
|
+
delete draft.dataSourceStates[oldTableName];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
draft.projectConfig.dataSources.push(newDataSource);
|
|
44
|
+
}
|
|
45
|
+
draft.dataSourceStates[newTableName] = {
|
|
46
|
+
status: DataSourceStatus.READY,
|
|
47
|
+
};
|
|
48
|
+
}));
|
|
49
|
+
await get().setTables(await getDuckTableSchemas());
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
export function useStoreWithSqlEditor(selector) {
|
|
55
|
+
return useBaseProjectStore((state) => selector(state));
|
|
56
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const SqlEditorSliceConfig: z.ZodObject<{
|
|
3
|
+
sqlEditor: z.ZodObject<{
|
|
4
|
+
queries: z.ZodArray<z.ZodObject<{
|
|
5
|
+
id: z.ZodString;
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
query: z.ZodString;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
query: string;
|
|
10
|
+
name: string;
|
|
11
|
+
id: string;
|
|
12
|
+
}, {
|
|
13
|
+
query: string;
|
|
14
|
+
name: string;
|
|
15
|
+
id: string;
|
|
16
|
+
}>, "many">;
|
|
17
|
+
selectedQueryId: z.ZodDefault<z.ZodString>;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
queries: {
|
|
20
|
+
query: string;
|
|
21
|
+
name: string;
|
|
22
|
+
id: string;
|
|
23
|
+
}[];
|
|
24
|
+
selectedQueryId: string;
|
|
25
|
+
}, {
|
|
26
|
+
queries: {
|
|
27
|
+
query: string;
|
|
28
|
+
name: string;
|
|
29
|
+
id: string;
|
|
30
|
+
}[];
|
|
31
|
+
selectedQueryId?: string | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
sqlEditor: {
|
|
35
|
+
queries: {
|
|
36
|
+
query: string;
|
|
37
|
+
name: string;
|
|
38
|
+
id: string;
|
|
39
|
+
}[];
|
|
40
|
+
selectedQueryId: string;
|
|
41
|
+
};
|
|
42
|
+
}, {
|
|
43
|
+
sqlEditor: {
|
|
44
|
+
queries: {
|
|
45
|
+
query: string;
|
|
46
|
+
name: string;
|
|
47
|
+
id: string;
|
|
48
|
+
}[];
|
|
49
|
+
selectedQueryId?: string | undefined;
|
|
50
|
+
};
|
|
51
|
+
}>;
|
|
52
|
+
export type SqlEditorSliceConfig = z.infer<typeof SqlEditorSliceConfig>;
|
|
53
|
+
//# sourceMappingURL=SqlEditorSliceConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlEditorSliceConfig.d.ts","sourceRoot":"","sources":["../src/SqlEditorSliceConfig.ts"],"names":[],"mappings":"AAAA,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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const SqlEditorSliceConfig = z.object({
|
|
3
|
+
sqlEditor: z.object({
|
|
4
|
+
queries: z.array(z.object({
|
|
5
|
+
id: z.string().describe('Query identifier.'),
|
|
6
|
+
name: z.string().describe('Query name.'),
|
|
7
|
+
query: z.string().describe('SQL query to execute.'),
|
|
8
|
+
})),
|
|
9
|
+
selectedQueryId: z
|
|
10
|
+
.string()
|
|
11
|
+
.default('default')
|
|
12
|
+
.describe('The id of the currently selected query.'),
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SqlQueryDataSource } from '@sqlrooms/project-config';
|
|
2
|
+
import { FC } from 'react';
|
|
3
|
+
declare const SqlQueryDataSourcesPanel: FC<{
|
|
4
|
+
queryDataSources: SqlQueryDataSource[];
|
|
5
|
+
}>;
|
|
6
|
+
export { SqlQueryDataSourcesPanel };
|
|
7
|
+
//# sourceMappingURL=SqlQueryDataSourcesPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlQueryDataSourcesPanel.d.ts","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAgB5D,OAAO,EAAC,EAAE,EAAwB,MAAM,OAAO,CAAC;AAIhD,QAAA,MAAM,wBAAwB,EAAE,EAAE,CAAC;IACjC,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;CACxC,CAwHA,CAAC;AAEF,OAAO,EAAC,wBAAwB,EAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DataSourceStatus, useBaseProjectStore } from '@sqlrooms/project-builder';
|
|
3
|
+
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@sqlrooms/ui';
|
|
4
|
+
import { EllipsisIcon, FileIcon, PencilIcon, PlusIcon, RefreshCcwIcon, XIcon, } from 'lucide-react';
|
|
5
|
+
import { useCallback, useState } from 'react';
|
|
6
|
+
import CreateTableModal from './CreateTableModal';
|
|
7
|
+
import { useStoreWithSqlEditor } from './SqlEditorSlice';
|
|
8
|
+
const SqlQueryDataSourcesPanel = (props) => {
|
|
9
|
+
const { queryDataSources } = props;
|
|
10
|
+
const [selectedDataSource, setSelectedDataSource] = useState();
|
|
11
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
12
|
+
const dataSourceStates = useBaseProjectStore((state) => state.dataSourceStates);
|
|
13
|
+
const removeSqlQueryDataSource = useBaseProjectStore((state) => state.removeSqlQueryDataSource);
|
|
14
|
+
const handleEdit = useCallback((dataSource) => {
|
|
15
|
+
setSelectedDataSource(dataSource);
|
|
16
|
+
setIsOpen(true);
|
|
17
|
+
}, []);
|
|
18
|
+
const handleClose = useCallback(() => {
|
|
19
|
+
setIsOpen(false);
|
|
20
|
+
setSelectedDataSource(undefined);
|
|
21
|
+
}, []);
|
|
22
|
+
const handleRemove = useCallback((dataSource) => {
|
|
23
|
+
const { tableName } = dataSource;
|
|
24
|
+
removeSqlQueryDataSource(tableName);
|
|
25
|
+
}, [removeSqlQueryDataSource]);
|
|
26
|
+
const addOrUpdateSqlQuery = useStoreWithSqlEditor((state) => state.sqlEditor.addOrUpdateSqlQuery);
|
|
27
|
+
const isReadOnly = useBaseProjectStore((state) => state.isReadOnly);
|
|
28
|
+
return (_jsxs("div", { className: "flex flex-col overflow-auto flex-grow", children: [_jsx("div", { className: "flex flex-col items-stretch", children: _jsxs(Button, { variant: "secondary", size: "sm", className: "text-white", 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: addOrUpdateSqlQuery }), _jsx("div", { className: "flex flex-col overflow-auto flex-grow", children: queryDataSources.map((dataSource) => (_jsxs("div", { className: "p-2 flex flex-col gap-1", children: [_jsxs("div", { className: "flex gap-1 cursor-pointer flex-row items-center", children: [_jsx("div", { className: "flex-none w-[15px]", children: _jsx(FileIcon, { className: "w-[15px]" }) }), _jsx("div", { className: "flex-1 overflow-hidden text-ellipsis", children: _jsx("span", { className: "text-xs break-words", 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: "h-6 w-6 text-muted-foreground", 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 gap-1 items-center", children: dataSourceStates[dataSource.tableName]?.status ===
|
|
29
|
+
DataSourceStatus.ERROR ? (_jsx("div", { className: "flex-1 bg-destructive/15 text-destructive text-xs p-1 rounded", children: dataSourceStates[dataSource.tableName]?.message })) : dataSourceStates[dataSource.tableName]?.status ===
|
|
30
|
+
DataSourceStatus.FETCHING ? (_jsx("div", { className: "w-full bg-secondary h-1 rounded overflow-hidden", children: _jsx("div", { className: "h-full bg-primary animate-pulse" }) })) : null })] }, dataSource.tableName))) })] }));
|
|
31
|
+
};
|
|
32
|
+
export { SqlQueryDataSourcesPanel };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,8 @@ export { default as CreateTableModal } from './CreateTableModal';
|
|
|
2
2
|
export { default as SqlEditor } from './SqlEditor';
|
|
3
3
|
export type { SqlEditorProps as Props } from './SqlEditor';
|
|
4
4
|
export { default as SqlEditorModal } from './SqlEditorModal';
|
|
5
|
+
export { createDefaultSqlEditorConfig, createSqlEditorSlice, } from './SqlEditorSlice';
|
|
6
|
+
export type { SqlEditorSliceState } from './SqlEditorSlice';
|
|
7
|
+
export { SqlQueryDataSourcesPanel } from './SqlQueryDataSourcesPanel';
|
|
8
|
+
export { SqlEditorSliceConfig } from './SqlEditorSliceConfig';
|
|
5
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,aAAa,CAAC;AACjD,YAAY,EAAC,cAAc,IAAI,KAAK,EAAC,MAAM,aAAa,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,aAAa,CAAC;AACjD,YAAY,EAAC,cAAc,IAAI,KAAK,EAAC,MAAM,aAAa,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export { default as CreateTableModal } from './CreateTableModal';
|
|
2
2
|
export { default as SqlEditor } from './SqlEditor';
|
|
3
3
|
export { default as SqlEditorModal } from './SqlEditorModal';
|
|
4
|
+
export { createDefaultSqlEditorConfig, createSqlEditorSlice, } from './SqlEditorSlice';
|
|
5
|
+
export { SqlQueryDataSourcesPanel } from './SqlQueryDataSourcesPanel';
|
|
6
|
+
export { SqlEditorSliceConfig } from './SqlEditorSliceConfig';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/sql-editor",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Ilya Boyandin <ilya@boyandin.me>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,20 +26,23 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@hookform/resolvers": "^3.10.0",
|
|
29
|
-
"@sqlrooms/data-table": "0.0
|
|
30
|
-
"@sqlrooms/duckdb": "0.0
|
|
31
|
-
"@sqlrooms/layout": "0.0
|
|
32
|
-
"@sqlrooms/project-
|
|
33
|
-
"@sqlrooms/
|
|
34
|
-
"@sqlrooms/
|
|
29
|
+
"@sqlrooms/data-table": "0.1.0",
|
|
30
|
+
"@sqlrooms/duckdb": "0.1.0",
|
|
31
|
+
"@sqlrooms/layout": "0.1.0",
|
|
32
|
+
"@sqlrooms/project-builder": "0.1.0",
|
|
33
|
+
"@sqlrooms/project-config": "0.1.0",
|
|
34
|
+
"@sqlrooms/ui": "0.1.0",
|
|
35
|
+
"@sqlrooms/utils": "0.1.0",
|
|
35
36
|
"apache-arrow": "^18.1.0",
|
|
36
37
|
"d3-dsv": "^3.0.1",
|
|
37
38
|
"file-saver": "^2.0.5",
|
|
38
|
-
"
|
|
39
|
+
"immer": "^10.1.1",
|
|
40
|
+
"lucide-react": "^0.474.0",
|
|
39
41
|
"react": "^18.2.0",
|
|
40
42
|
"react-dom": "^18.2.0",
|
|
41
43
|
"react-hook-form": "^7.54.2",
|
|
42
|
-
"zod": "^3.
|
|
44
|
+
"zod": "^3.24.1",
|
|
45
|
+
"zustand": "^5.0.3"
|
|
43
46
|
},
|
|
44
47
|
"devDependencies": {
|
|
45
48
|
"@types/d3-dsv": "^3.0.7",
|
|
@@ -47,5 +50,5 @@
|
|
|
47
50
|
"@types/react": "^18.2.48",
|
|
48
51
|
"@types/react-dom": "^18.2.18"
|
|
49
52
|
},
|
|
50
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "2d44f6636dbd53d18c32a422351e93caa182ada6"
|
|
51
54
|
}
|