@sqlrooms/sql-editor 0.26.0-rc.5 → 0.26.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.
@@ -21,6 +21,11 @@ export interface QueryResultPanelProps {
21
21
  row: Row<any>;
22
22
  event: React.MouseEvent<HTMLTableRowElement>;
23
23
  }) => void;
24
+ /**
25
+ * Called when the "Ask AI" button is clicked on an error message.
26
+ * Receives the current query and error text.
27
+ */
28
+ onAskAiAboutError?: (query: string, error: string) => void;
24
29
  }
25
30
  export declare const QueryResultPanel: React.FC<QueryResultPanelProps>;
26
31
  //# sourceMappingURL=QueryResultPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryResultPanel.d.ts","sourceRoot":"","sources":["../../src/components/QueryResultPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAU/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IACnD,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;KAC9C,KAAK,IAAI,CAAC;IACX;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;KAC9C,KAAK,IAAI,CAAC;CACZ;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAkH5D,CAAC"}
1
+ {"version":3,"file":"QueryResultPanel.d.ts","sourceRoot":"","sources":["../../src/components/QueryResultPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,uBAAuB,CAAC;AAW/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IACnD,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;KAC9C,KAAK,IAAI,CAAC;IACX;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;KAC9C,KAAK,IAAI,CAAC;IACX;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA+I5D,CAAC"}
@@ -1,11 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { DataTablePaginated, useArrowDataTable } from '@sqlrooms/data-table';
3
- import { cn, Select, SelectContent, SelectItem, SelectTrigger, SpinnerPane, } from '@sqlrooms/ui';
3
+ import { cn, Select, SelectContent, SelectItem, SelectTrigger, SpinnerPane, Button, } from '@sqlrooms/ui';
4
4
  import { formatCount } from '@sqlrooms/utils';
5
5
  import React from 'react';
6
6
  import { isQueryWithResult, useStoreWithSqlEditor } from '../SqlEditorSlice';
7
- export const QueryResultPanel = ({ className, renderActions, fontSize = 'text-xs', onRowClick, onRowDoubleClick, }) => {
7
+ import { MessageCircleQuestion } from 'lucide-react';
8
+ export const QueryResultPanel = ({ className, renderActions, fontSize = 'text-xs', onRowClick, onRowDoubleClick, onAskAiAboutError, }) => {
8
9
  const queryResult = useStoreWithSqlEditor((s) => s.sqlEditor.queryResult);
10
+ const getCurrentQuery = useStoreWithSqlEditor((s) => s.sqlEditor.getCurrentQuery);
9
11
  const setQueryResultLimit = useStoreWithSqlEditor((s) => s.sqlEditor.setQueryResultLimit);
10
12
  const queryResultLimit = useStoreWithSqlEditor((s) => s.sqlEditor.queryResultLimit);
11
13
  const queryResultLimitOptions = useStoreWithSqlEditor((s) => s.sqlEditor.queryResultLimitOptions);
@@ -16,6 +18,13 @@ export const QueryResultPanel = ({ className, renderActions, fontSize = 'text-xs
16
18
  return queryResultLimitOptions;
17
19
  }, [queryResultLimitOptions, queryResultLimit]);
18
20
  const arrowTableData = useArrowDataTable(isQueryWithResult(queryResult) ? queryResult.result : undefined);
21
+ const handleAskAiAboutError = React.useCallback(() => {
22
+ if (queryResult?.status === 'error' && onAskAiAboutError) {
23
+ const currentQuery = getCurrentQuery();
24
+ const errorText = queryResult.error;
25
+ onAskAiAboutError(currentQuery, errorText);
26
+ }
27
+ }, [queryResult, getCurrentQuery, onAskAiAboutError]);
19
28
  if (!queryResult) {
20
29
  return null;
21
30
  }
@@ -26,7 +35,7 @@ export const QueryResultPanel = ({ className, renderActions, fontSize = 'text-xs
26
35
  return (_jsx("div", { className: "p-5 font-mono text-xs leading-tight text-red-500", children: "Query was aborted" }));
27
36
  }
28
37
  if (queryResult?.status === 'error') {
29
- return (_jsx("div", { className: "h-full w-full overflow-auto p-5", children: _jsx("pre", { className: "whitespace-pre-wrap text-xs leading-tight text-red-500", children: queryResult.error }) }));
38
+ return (_jsxs("div", { className: "relative h-full w-full overflow-auto p-5", children: [onAskAiAboutError && (_jsx(Button, { variant: "ghost", size: "icon", className: "absolute right-2 top-2 h-8 w-8", onClick: handleAskAiAboutError, title: "Ask AI for help", children: _jsx(MessageCircleQuestion, { className: "h-4 w-4" }) })), _jsx("pre", { className: cn('whitespace-pre-wrap text-xs leading-tight text-red-500', onAskAiAboutError && 'pr-12'), children: queryResult.error })] }));
30
39
  }
31
40
  if (queryResult?.status === 'success') {
32
41
  return (_jsx("div", { className: cn('relative flex h-full w-full flex-grow flex-col overflow-hidden', className), children: isQueryWithResult(queryResult) ? (_jsxs("div", { className: "flex h-full w-full flex-col", children: [_jsx(DataTablePaginated, { ...arrowTableData, className: "flex-grow overflow-hidden", fontSize: fontSize, isFetching: false, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick }), _jsxs("div", { className: "bg-background flex w-full items-center gap-2 px-4 py-1", children: [queryResult.result ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "font-mono text-xs", children: `${formatCount(queryResult.result.numRows ?? 0)} rows` }), _jsxs(Select, { value: queryResultLimit.toString(), onValueChange: (value) => setQueryResultLimit(parseInt(value)), children: [_jsx(SelectTrigger, { className: "h-6 w-fit", children: _jsx("div", { className: "text-xs text-gray-500", children: `Limit results to ${formatCount(queryResultLimit)} rows` }) }), _jsx(SelectContent, { children: limitOptions.map((limit) => (_jsx(SelectItem, { value: limit.toString(), children: `${formatCount(limit)} rows` }, limit))) })] })] })) : null, _jsx("div", { className: "flex-1" }), renderActions
@@ -1 +1 @@
1
- {"version":3,"file":"QueryResultPanel.js","sourceRoot":"","sources":["../../src/components/QueryResultPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataTablePaginated, useArrowDataTable} from '@sqlrooms/data-table';\nimport type {Row} from '@tanstack/react-table';\nimport {\n cn,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SpinnerPane,\n} from '@sqlrooms/ui';\nimport {formatCount} from '@sqlrooms/utils';\nimport React from 'react';\nimport {isQueryWithResult, useStoreWithSqlEditor} from '../SqlEditorSlice';\n\nexport interface QueryResultPanelProps {\n /** Custom class name for styling */\n className?: string;\n /** Custom actions to render in the query result panel */\n renderActions?: (query: string) => React.ReactNode;\n /** Custom font size for the table e.g. text-xs, text-sm, text-md, text-lg, text-base */\n fontSize?: string;\n /**\n * Called when a row in the results table is clicked.\n */\n onRowClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /**\n * Called when a row in the results table is double-clicked.\n */\n onRowDoubleClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n}\n\nexport const QueryResultPanel: React.FC<QueryResultPanelProps> = ({\n className,\n renderActions,\n fontSize = 'text-xs',\n onRowClick,\n onRowDoubleClick,\n}) => {\n const queryResult = useStoreWithSqlEditor((s) => s.sqlEditor.queryResult);\n const setQueryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setQueryResultLimit,\n );\n const queryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimit,\n );\n const queryResultLimitOptions = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimitOptions,\n );\n const limitOptions = React.useMemo(() => {\n if (!queryResultLimitOptions.includes(queryResultLimit)) {\n return [queryResultLimit, ...queryResultLimitOptions];\n }\n return queryResultLimitOptions;\n }, [queryResultLimitOptions, queryResultLimit]);\n const arrowTableData = useArrowDataTable(\n isQueryWithResult(queryResult) ? queryResult.result : undefined,\n );\n\n if (!queryResult) {\n return null;\n }\n\n if (queryResult?.status === 'loading') {\n return <SpinnerPane h=\"100%\" />;\n }\n\n if (queryResult?.status === 'aborted') {\n return (\n <div className=\"p-5 font-mono text-xs leading-tight text-red-500\">\n Query was aborted\n </div>\n );\n }\n if (queryResult?.status === 'error') {\n return (\n <div className=\"h-full w-full overflow-auto p-5\">\n <pre className=\"whitespace-pre-wrap text-xs leading-tight text-red-500\">\n {queryResult.error}\n </pre>\n </div>\n );\n }\n\n if (queryResult?.status === 'success') {\n return (\n <div\n className={cn(\n 'relative flex h-full w-full flex-grow flex-col overflow-hidden',\n className,\n )}\n >\n {isQueryWithResult(queryResult) ? (\n <div className=\"flex h-full w-full flex-col\">\n <DataTablePaginated\n {...arrowTableData}\n className=\"flex-grow overflow-hidden\"\n fontSize={fontSize}\n isFetching={false}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n />\n <div className=\"bg-background flex w-full items-center gap-2 px-4 py-1\">\n {queryResult.result ? (\n <>\n <div className=\"font-mono text-xs\">\n {`${formatCount(queryResult.result.numRows ?? 0)} rows`}\n </div>\n\n <Select\n value={queryResultLimit.toString()}\n onValueChange={(value) =>\n setQueryResultLimit(parseInt(value))\n }\n >\n <SelectTrigger className=\"h-6 w-fit\">\n <div className=\"text-xs text-gray-500\">\n {`Limit results to ${formatCount(queryResultLimit)} rows`}\n </div>\n </SelectTrigger>\n <SelectContent>\n {limitOptions.map((limit) => (\n <SelectItem key={limit} value={limit.toString()}>\n {`${formatCount(limit)} rows`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n ) : null}\n <div className=\"flex-1\" />\n {renderActions\n ? renderActions(queryResult.lastQueryStatement)\n : undefined}\n </div>\n </div>\n ) : (\n <pre className=\"p-4 text-xs leading-tight text-green-500\">\n Successfully executed query\n </pre>\n )}\n </div>\n );\n }\n\n return null;\n};\n"]}
1
+ {"version":3,"file":"QueryResultPanel.js","sourceRoot":"","sources":["../../src/components/QueryResultPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataTablePaginated, useArrowDataTable} from '@sqlrooms/data-table';\nimport type {Row} from '@tanstack/react-table';\nimport {\n cn,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SpinnerPane,\n Button,\n} from '@sqlrooms/ui';\nimport {formatCount} from '@sqlrooms/utils';\nimport React from 'react';\nimport {isQueryWithResult, useStoreWithSqlEditor} from '../SqlEditorSlice';\nimport {MessageCircleQuestion} from 'lucide-react';\n\nexport interface QueryResultPanelProps {\n /** Custom class name for styling */\n className?: string;\n /** Custom actions to render in the query result panel */\n renderActions?: (query: string) => React.ReactNode;\n /** Custom font size for the table e.g. text-xs, text-sm, text-md, text-lg, text-base */\n fontSize?: string;\n /**\n * Called when a row in the results table is clicked.\n */\n onRowClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /**\n * Called when a row in the results table is double-clicked.\n */\n onRowDoubleClick?: (args: {\n row: Row<any>;\n event: React.MouseEvent<HTMLTableRowElement>;\n }) => void;\n /**\n * Called when the \"Ask AI\" button is clicked on an error message.\n * Receives the current query and error text.\n */\n onAskAiAboutError?: (query: string, error: string) => void;\n}\n\nexport const QueryResultPanel: React.FC<QueryResultPanelProps> = ({\n className,\n renderActions,\n fontSize = 'text-xs',\n onRowClick,\n onRowDoubleClick,\n onAskAiAboutError,\n}) => {\n const queryResult = useStoreWithSqlEditor((s) => s.sqlEditor.queryResult);\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n const setQueryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setQueryResultLimit,\n );\n const queryResultLimit = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimit,\n );\n const queryResultLimitOptions = useStoreWithSqlEditor(\n (s) => s.sqlEditor.queryResultLimitOptions,\n );\n\n const limitOptions = React.useMemo(() => {\n if (!queryResultLimitOptions.includes(queryResultLimit)) {\n return [queryResultLimit, ...queryResultLimitOptions];\n }\n return queryResultLimitOptions;\n }, [queryResultLimitOptions, queryResultLimit]);\n const arrowTableData = useArrowDataTable(\n isQueryWithResult(queryResult) ? queryResult.result : undefined,\n );\n\n const handleAskAiAboutError = React.useCallback(() => {\n if (queryResult?.status === 'error' && onAskAiAboutError) {\n const currentQuery = getCurrentQuery();\n const errorText = queryResult.error;\n onAskAiAboutError(currentQuery, errorText);\n }\n }, [queryResult, getCurrentQuery, onAskAiAboutError]);\n\n if (!queryResult) {\n return null;\n }\n\n if (queryResult?.status === 'loading') {\n return <SpinnerPane h=\"100%\" />;\n }\n\n if (queryResult?.status === 'aborted') {\n return (\n <div className=\"p-5 font-mono text-xs leading-tight text-red-500\">\n Query was aborted\n </div>\n );\n }\n if (queryResult?.status === 'error') {\n return (\n <div className=\"relative h-full w-full overflow-auto p-5\">\n {onAskAiAboutError && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute right-2 top-2 h-8 w-8\"\n onClick={handleAskAiAboutError}\n title=\"Ask AI for help\"\n >\n <MessageCircleQuestion className=\"h-4 w-4\" />\n </Button>\n )}\n <pre\n className={cn(\n 'whitespace-pre-wrap text-xs leading-tight text-red-500',\n onAskAiAboutError && 'pr-12',\n )}\n >\n {queryResult.error}\n </pre>\n </div>\n );\n }\n\n if (queryResult?.status === 'success') {\n return (\n <div\n className={cn(\n 'relative flex h-full w-full flex-grow flex-col overflow-hidden',\n className,\n )}\n >\n {isQueryWithResult(queryResult) ? (\n <div className=\"flex h-full w-full flex-col\">\n <DataTablePaginated\n {...arrowTableData}\n className=\"flex-grow overflow-hidden\"\n fontSize={fontSize}\n isFetching={false}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n />\n <div className=\"bg-background flex w-full items-center gap-2 px-4 py-1\">\n {queryResult.result ? (\n <>\n <div className=\"font-mono text-xs\">\n {`${formatCount(queryResult.result.numRows ?? 0)} rows`}\n </div>\n\n <Select\n value={queryResultLimit.toString()}\n onValueChange={(value) =>\n setQueryResultLimit(parseInt(value))\n }\n >\n <SelectTrigger className=\"h-6 w-fit\">\n <div className=\"text-xs text-gray-500\">\n {`Limit results to ${formatCount(queryResultLimit)} rows`}\n </div>\n </SelectTrigger>\n <SelectContent>\n {limitOptions.map((limit) => (\n <SelectItem key={limit} value={limit.toString()}>\n {`${formatCount(limit)} rows`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n ) : null}\n <div className=\"flex-1\" />\n {renderActions\n ? renderActions(queryResult.lastQueryStatement)\n : undefined}\n </div>\n </div>\n ) : (\n <pre className=\"p-4 text-xs leading-tight text-green-500\">\n Successfully executed query\n </pre>\n )}\n </div>\n );\n }\n\n return null;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqlrooms/sql-editor",
3
- "version": "0.26.0-rc.5",
3
+ "version": "0.26.0",
4
4
  "author": "Ilya Boyandin <ilya@boyandin.me>",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -28,16 +28,16 @@
28
28
  "@hookform/resolvers": "^3.10.0",
29
29
  "@monaco-editor/react": "^4.7.0",
30
30
  "@paralleldrive/cuid2": "^2.2.2",
31
- "@sqlrooms/data-table": "0.26.0-rc.5",
32
- "@sqlrooms/duckdb": "0.26.0-rc.5",
33
- "@sqlrooms/layout": "0.26.0-rc.5",
34
- "@sqlrooms/monaco-editor": "0.26.0-rc.5",
35
- "@sqlrooms/room-config": "0.26.0-rc.5",
36
- "@sqlrooms/room-shell": "0.26.0-rc.5",
37
- "@sqlrooms/schema-tree": "0.26.0-rc.5",
38
- "@sqlrooms/sql-editor-config": "0.26.0-rc.5",
39
- "@sqlrooms/ui": "0.26.0-rc.5",
40
- "@sqlrooms/utils": "0.26.0-rc.5",
31
+ "@sqlrooms/data-table": "0.26.0",
32
+ "@sqlrooms/duckdb": "0.26.0",
33
+ "@sqlrooms/layout": "0.26.0",
34
+ "@sqlrooms/monaco-editor": "0.26.0",
35
+ "@sqlrooms/room-config": "0.26.0",
36
+ "@sqlrooms/room-shell": "0.26.0",
37
+ "@sqlrooms/schema-tree": "0.26.0",
38
+ "@sqlrooms/sql-editor-config": "0.26.0",
39
+ "@sqlrooms/ui": "0.26.0",
40
+ "@sqlrooms/utils": "0.26.0",
41
41
  "@tanstack/react-table": "^8.21.3",
42
42
  "d3-dsv": "^3.0.1",
43
43
  "file-saver": "^2.0.5",
@@ -59,5 +59,5 @@
59
59
  "@types/react": "^19.1.13",
60
60
  "@types/react-dom": "^19.1.9"
61
61
  },
62
- "gitHead": "dc1c3b765718c8748aa11cce3cc83f907d3e5963"
62
+ "gitHead": "3376e76ddfa3c54097b79a20b88a1c37814dca61"
63
63
  }