@sqlrooms/sql-editor 0.0.2 → 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.
@@ -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.
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AA4BzD,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAyB,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAO3E,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,uEAAuE;IACvE,eAAe,EAAE,eAAe,CAAC;IAEjC,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAE5C,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,2EAA2E;IAC3E,qBAAqB,EAAE,qBAAqB,CAAC,uBAAuB,CAAC,CAAC;CACvE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAibvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
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, ResizablePanelGroup, ResizablePanel, ResizableHandle, } from '@sqlrooms/ui';
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, onAddOrUpdateSqlQuery, sqlEditorConfig, onChange, } = props;
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
- onChange({
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
- onChange({
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
- onChange({
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
- onChange({
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
- onChange({
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: onAddOrUpdateSqlQuery }), _jsx(DeleteSqlQueryModal, { isOpen: queryToDelete !== null, onClose: () => setQueryToDelete(null), onConfirm: () => {
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
- onChange({
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
@@ -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,7 +1,13 @@
1
1
  {
2
2
  "name": "@sqlrooms/sql-editor",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "private": false,
5
+ "author": "Ilya Boyandin <ilya@boyandin.me>",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/sqlrooms/sqlrooms.git"
10
+ },
5
11
  "files": [
6
12
  "dist"
7
13
  ],
@@ -20,20 +26,23 @@
20
26
  },
21
27
  "dependencies": {
22
28
  "@hookform/resolvers": "^3.10.0",
23
- "@sqlrooms/data-table": "0.0.2",
24
- "@sqlrooms/duckdb": "0.0.2",
25
- "@sqlrooms/layout": "0.0.2",
26
- "@sqlrooms/project-config": "0.0.2",
27
- "@sqlrooms/ui": "0.0.2",
28
- "@sqlrooms/utils": "0.0.2",
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",
29
36
  "apache-arrow": "^18.1.0",
30
37
  "d3-dsv": "^3.0.1",
31
38
  "file-saver": "^2.0.5",
32
- "lucide-react": "^0.323.0",
39
+ "immer": "^10.1.1",
40
+ "lucide-react": "^0.474.0",
33
41
  "react": "^18.2.0",
34
42
  "react-dom": "^18.2.0",
35
43
  "react-hook-form": "^7.54.2",
36
- "zod": "^3.22.4"
44
+ "zod": "^3.24.1",
45
+ "zustand": "^5.0.3"
37
46
  },
38
47
  "devDependencies": {
39
48
  "@types/d3-dsv": "^3.0.7",
@@ -41,5 +50,5 @@
41
50
  "@types/react": "^18.2.48",
42
51
  "@types/react-dom": "^18.2.18"
43
52
  },
44
- "gitHead": "32da0b35fe906bdcef42274624d069cc49425a74"
53
+ "gitHead": "2d44f6636dbd53d18c32a422351e93caa182ada6"
45
54
  }