@sqlrooms/cells 0.29.0-rc.1 → 0.29.0-rc.3
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 +8 -8
- package/dist/cellsSlice.d.ts.map +1 -1
- package/dist/cellsSlice.js +305 -264
- package/dist/cellsSlice.js.map +1 -1
- package/dist/components/AggregationSelector.d.ts +8 -0
- package/dist/components/AggregationSelector.d.ts.map +1 -0
- package/dist/components/AggregationSelector.js +13 -0
- package/dist/components/AggregationSelector.js.map +1 -0
- package/dist/components/CellSourceSelector.d.ts +12 -0
- package/dist/components/CellSourceSelector.d.ts.map +1 -0
- package/dist/components/CellSourceSelector.js +34 -0
- package/dist/components/CellSourceSelector.js.map +1 -0
- package/dist/components/ChartTypeSelector.d.ts +8 -0
- package/dist/components/ChartTypeSelector.d.ts.map +1 -0
- package/dist/components/ChartTypeSelector.js +13 -0
- package/dist/components/ChartTypeSelector.js.map +1 -0
- package/dist/components/CollapsibleSectionButton.d.ts +10 -0
- package/dist/components/CollapsibleSectionButton.d.ts.map +1 -0
- package/dist/components/CollapsibleSectionButton.js +10 -0
- package/dist/components/CollapsibleSectionButton.js.map +1 -0
- package/dist/components/ColorSelector.d.ts +24 -0
- package/dist/components/ColorSelector.d.ts.map +1 -0
- package/dist/components/ColorSelector.js +17 -0
- package/dist/components/ColorSelector.js.map +1 -0
- package/dist/components/FieldSelector.d.ts +11 -0
- package/dist/components/FieldSelector.d.ts.map +1 -0
- package/dist/components/FieldSelector.js +11 -0
- package/dist/components/FieldSelector.js.map +1 -0
- package/dist/components/FieldTypeIcon.d.ts +8 -0
- package/dist/components/FieldTypeIcon.d.ts.map +1 -0
- package/dist/components/FieldTypeIcon.js +27 -0
- package/dist/components/FieldTypeIcon.js.map +1 -0
- package/dist/components/InputCellContent.d.ts.map +1 -1
- package/dist/components/InputCellContent.js +3 -3
- package/dist/components/InputCellContent.js.map +1 -1
- package/dist/components/SelectionListener.d.ts +15 -0
- package/dist/components/SelectionListener.d.ts.map +1 -0
- package/dist/components/SelectionListener.js +74 -0
- package/dist/components/SelectionListener.js.map +1 -0
- package/dist/components/SqlCellConnectionSelector.d.ts +9 -0
- package/dist/components/SqlCellConnectionSelector.d.ts.map +1 -0
- package/dist/components/SqlCellConnectionSelector.js +21 -0
- package/dist/components/SqlCellConnectionSelector.js.map +1 -0
- package/dist/components/SqlCellContent.d.ts.map +1 -1
- package/dist/components/SqlCellContent.js +31 -156
- package/dist/components/SqlCellContent.js.map +1 -1
- package/dist/components/SqlCellDependentsMenu.d.ts +11 -0
- package/dist/components/SqlCellDependentsMenu.d.ts.map +1 -0
- package/dist/components/SqlCellDependentsMenu.js +62 -0
- package/dist/components/SqlCellDependentsMenu.js.map +1 -0
- package/dist/components/SqlCellEditor.d.ts +14 -0
- package/dist/components/SqlCellEditor.d.ts.map +1 -0
- package/dist/components/SqlCellEditor.js +17 -0
- package/dist/components/SqlCellEditor.js.map +1 -0
- package/dist/components/SqlCellResultNameEditor.d.ts +8 -0
- package/dist/components/SqlCellResultNameEditor.d.ts.map +1 -0
- package/dist/components/SqlCellResultNameEditor.js +38 -0
- package/dist/components/SqlCellResultNameEditor.js.map +1 -0
- package/dist/components/SqlCellResults.d.ts +17 -0
- package/dist/components/SqlCellResults.d.ts.map +1 -0
- package/dist/components/SqlCellResults.js +45 -0
- package/dist/components/SqlCellResults.js.map +1 -0
- package/dist/components/SqlCellRunButton.d.ts +5 -6
- package/dist/components/SqlCellRunButton.d.ts.map +1 -1
- package/dist/components/SqlCellRunButton.js +11 -7
- package/dist/components/SqlCellRunButton.js.map +1 -1
- package/dist/components/SqlQueryPreview.d.ts +9 -0
- package/dist/components/SqlQueryPreview.d.ts.map +1 -0
- package/dist/components/SqlQueryPreview.js +14 -0
- package/dist/components/SqlQueryPreview.js.map +1 -0
- package/dist/components/TextCellContent.d.ts.map +1 -1
- package/dist/components/TextCellContent.js +24 -7
- package/dist/components/TextCellContent.js.map +1 -1
- package/dist/components/VegaCellContent.d.ts +0 -1
- package/dist/components/VegaCellContent.d.ts.map +1 -1
- package/dist/components/VegaCellContent.js +61 -47
- package/dist/components/VegaCellContent.js.map +1 -1
- package/dist/components/VegaCellHeader.d.ts +11 -0
- package/dist/components/VegaCellHeader.d.ts.map +1 -0
- package/dist/components/VegaCellHeader.js +32 -0
- package/dist/components/VegaCellHeader.js.map +1 -0
- package/dist/components/VegaConfigPanel.d.ts +5 -0
- package/dist/components/VegaConfigPanel.d.ts.map +1 -1
- package/dist/components/VegaConfigPanel.js +53 -63
- package/dist/components/VegaConfigPanel.js.map +1 -1
- package/dist/dagUtils.d.ts +10 -9
- package/dist/dagUtils.d.ts.map +1 -1
- package/dist/dagUtils.js +76 -50
- package/dist/dagUtils.js.map +1 -1
- package/dist/defaultCellRegistry.d.ts.map +1 -1
- package/dist/defaultCellRegistry.js +79 -36
- package/dist/defaultCellRegistry.js.map +1 -1
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +24 -17
- package/dist/execution.js.map +1 -1
- package/dist/helpers.d.ts +20 -16
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +79 -44
- package/dist/helpers.js.map +1 -1
- package/dist/hooks/useVegaCellDataSource.d.ts +18 -0
- package/dist/hooks/useVegaCellDataSource.d.ts.map +1 -0
- package/dist/hooks/useVegaCellDataSource.js +40 -0
- package/dist/hooks/useVegaCellDataSource.js.map +1 -0
- package/dist/hooks/useVegaCellQuery.d.ts +16 -0
- package/dist/hooks/useVegaCellQuery.d.ts.map +1 -0
- package/dist/hooks/useVegaCellQuery.js +25 -0
- package/dist/hooks/useVegaCellQuery.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/sqlHelpers.d.ts +8 -8
- package/dist/sqlHelpers.d.ts.map +1 -1
- package/dist/sqlHelpers.js +16 -12
- package/dist/sqlHelpers.js.map +1 -1
- package/dist/types.d.ts +113 -70
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -13
- package/dist/types.js.map +1 -1
- package/dist/useValidateResultName.d.ts +34 -0
- package/dist/useValidateResultName.d.ts.map +1 -0
- package/dist/useValidateResultName.js +111 -0
- package/dist/useValidateResultName.js.map +1 -0
- package/dist/utils.d.ts +10 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +20 -4
- package/dist/utils.js.map +1 -1
- package/dist/vegaSelectionUtils.d.ts +14 -0
- package/dist/vegaSelectionUtils.d.ts.map +1 -0
- package/dist/vegaSelectionUtils.js +97 -0
- package/dist/vegaSelectionUtils.js.map +1 -0
- package/dist/vegaSpecBuilder.d.ts +34 -0
- package/dist/vegaSpecBuilder.d.ts.map +1 -0
- package/dist/vegaSpecBuilder.js +90 -0
- package/dist/vegaSpecBuilder.js.map +1 -0
- package/package.json +12 -13
- package/dist/components/DeleteSheetModal.d.ts +0 -9
- package/dist/components/DeleteSheetModal.d.ts.map +0 -1
- package/dist/components/DeleteSheetModal.js +0 -6
- package/dist/components/DeleteSheetModal.js.map +0 -1
- package/dist/components/SheetsTabBar.d.ts +0 -6
- package/dist/components/SheetsTabBar.d.ts.map +0 -1
- package/dist/components/SheetsTabBar.js +0 -57
- package/dist/components/SheetsTabBar.js.map +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { BRUSH_PARAM_NAME } from './vegaSelectionUtils';
|
|
2
|
+
/**
|
|
3
|
+
* Read the flat encoding/mark values from either a flat spec or a
|
|
4
|
+
* dual-layer cross-filter spec so the config panel dropdowns reflect
|
|
5
|
+
* the current state regardless of spec shape.
|
|
6
|
+
*/
|
|
7
|
+
export function readSpecValues(spec) {
|
|
8
|
+
if (spec?.layer && Array.isArray(spec.layer)) {
|
|
9
|
+
const fg = spec.layer[1] ?? spec.layer[0];
|
|
10
|
+
const bg = spec.layer[0];
|
|
11
|
+
return {
|
|
12
|
+
mark: fg?.mark ?? bg?.mark,
|
|
13
|
+
xField: fg?.encoding?.x?.field ?? bg?.encoding?.x?.field,
|
|
14
|
+
yField: fg?.encoding?.y?.field ?? bg?.encoding?.y?.field,
|
|
15
|
+
yAggregate: fg?.encoding?.y?.aggregate ?? bg?.encoding?.y?.aggregate,
|
|
16
|
+
color: fg?.encoding?.color?.value,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
mark: spec?.mark,
|
|
21
|
+
xField: spec?.encoding?.x?.field,
|
|
22
|
+
yField: spec?.encoding?.y?.field,
|
|
23
|
+
yAggregate: spec?.encoding?.y?.aggregate,
|
|
24
|
+
color: spec?.encoding?.color?.value,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a dual-layer Vega-Lite spec with a brush selection param on the
|
|
29
|
+
* background layer and a filter transform on the foreground layer.
|
|
30
|
+
*/
|
|
31
|
+
export function buildCrossFilterSpec(opts) {
|
|
32
|
+
const { mark, xField, xFieldType, yField, yAggregate, color } = opts;
|
|
33
|
+
const xEnc = xField
|
|
34
|
+
? {
|
|
35
|
+
field: xField,
|
|
36
|
+
...(xFieldType === 'numeric' ? { bin: { maxbins: 20 } } : {}),
|
|
37
|
+
}
|
|
38
|
+
: undefined;
|
|
39
|
+
const yEnc = yField
|
|
40
|
+
? { field: yField, aggregate: yAggregate ?? 'sum' }
|
|
41
|
+
: yAggregate === 'count'
|
|
42
|
+
? { aggregate: 'count' }
|
|
43
|
+
: undefined;
|
|
44
|
+
const encoding = {};
|
|
45
|
+
if (xEnc)
|
|
46
|
+
encoding.x = xEnc;
|
|
47
|
+
if (yEnc)
|
|
48
|
+
encoding.y = yEnc;
|
|
49
|
+
return {
|
|
50
|
+
layer: [
|
|
51
|
+
{
|
|
52
|
+
params: [
|
|
53
|
+
{
|
|
54
|
+
name: BRUSH_PARAM_NAME,
|
|
55
|
+
select: { type: 'interval', encodings: ['x'] },
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
mark,
|
|
59
|
+
encoding: {
|
|
60
|
+
...encoding,
|
|
61
|
+
color: { value: '#ddd' },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
transform: [{ filter: { param: BRUSH_PARAM_NAME } }],
|
|
66
|
+
mark,
|
|
67
|
+
encoding: {
|
|
68
|
+
...encoding,
|
|
69
|
+
...(color ? { color: { value: color } } : {}),
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
padding: 20,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** Build a simple flat spec (no cross-filtering). */
|
|
77
|
+
export function buildFlatSpec(opts) {
|
|
78
|
+
const { mark, xField, yField, yAggregate, color } = opts;
|
|
79
|
+
const encoding = {};
|
|
80
|
+
if (xField)
|
|
81
|
+
encoding.x = { field: xField };
|
|
82
|
+
if (yField)
|
|
83
|
+
encoding.y = { field: yField, aggregate: yAggregate ?? 'sum' };
|
|
84
|
+
else if (yAggregate === 'count')
|
|
85
|
+
encoding.y = { aggregate: 'count' };
|
|
86
|
+
if (color)
|
|
87
|
+
encoding.color = { value: color };
|
|
88
|
+
return { mark, encoding, padding: 20 };
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=vegaSpecBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vegaSpecBuilder.js","sourceRoot":"","sources":["../src/vegaSpecBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import {BRUSH_PARAM_NAME} from './vegaSelectionUtils';\nimport type {BrushFieldType} from './types';\n\n/**\n * Read the flat encoding/mark values from either a flat spec or a\n * dual-layer cross-filter spec so the config panel dropdowns reflect\n * the current state regardless of spec shape.\n */\nexport function readSpecValues(spec: any): {\n mark: string | undefined;\n xField: string | undefined;\n yField: string | undefined;\n yAggregate: string | undefined;\n color: string | undefined;\n} {\n if (spec?.layer && Array.isArray(spec.layer)) {\n const fg = spec.layer[1] ?? spec.layer[0];\n const bg = spec.layer[0];\n return {\n mark: fg?.mark ?? bg?.mark,\n xField: fg?.encoding?.x?.field ?? bg?.encoding?.x?.field,\n yField: fg?.encoding?.y?.field ?? bg?.encoding?.y?.field,\n yAggregate: fg?.encoding?.y?.aggregate ?? bg?.encoding?.y?.aggregate,\n color: fg?.encoding?.color?.value,\n };\n }\n return {\n mark: spec?.mark,\n xField: spec?.encoding?.x?.field,\n yField: spec?.encoding?.y?.field,\n yAggregate: spec?.encoding?.y?.aggregate,\n color: spec?.encoding?.color?.value,\n };\n}\n\n/**\n * Build a dual-layer Vega-Lite spec with a brush selection param on the\n * background layer and a filter transform on the foreground layer.\n */\nexport function buildCrossFilterSpec(opts: {\n mark: string;\n xField?: string;\n xFieldType?: BrushFieldType;\n yField?: string;\n yAggregate?: string;\n color?: string;\n}): any {\n const {mark, xField, xFieldType, yField, yAggregate, color} = opts;\n const xEnc: any = xField\n ? {\n field: xField,\n ...(xFieldType === 'numeric' ? {bin: {maxbins: 20}} : {}),\n }\n : undefined;\n const yEnc: any = yField\n ? {field: yField, aggregate: yAggregate ?? 'sum'}\n : yAggregate === 'count'\n ? {aggregate: 'count'}\n : undefined;\n\n const encoding: any = {};\n if (xEnc) encoding.x = xEnc;\n if (yEnc) encoding.y = yEnc;\n\n return {\n layer: [\n {\n params: [\n {\n name: BRUSH_PARAM_NAME,\n select: {type: 'interval', encodings: ['x']},\n },\n ],\n mark,\n encoding: {\n ...encoding,\n color: {value: '#ddd'},\n },\n },\n {\n transform: [{filter: {param: BRUSH_PARAM_NAME}}],\n mark,\n encoding: {\n ...encoding,\n ...(color ? {color: {value: color}} : {}),\n },\n },\n ],\n padding: 20,\n };\n}\n\n/** Build a simple flat spec (no cross-filtering). */\nexport function buildFlatSpec(opts: {\n mark: string;\n xField?: string;\n yField?: string;\n yAggregate?: string;\n color?: string;\n}): any {\n const {mark, xField, yField, yAggregate, color} = opts;\n const encoding: any = {};\n if (xField) encoding.x = {field: xField};\n if (yField) encoding.y = {field: yField, aggregate: yAggregate ?? 'sum'};\n else if (yAggregate === 'count') encoding.y = {aggregate: 'count'};\n if (color) encoding.color = {value: color};\n return {mark, encoding, padding: 20};\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/cells",
|
|
3
|
-
"version": "0.29.0-rc.
|
|
4
|
-
"private": false,
|
|
3
|
+
"version": "0.29.0-rc.3",
|
|
5
4
|
"type": "module",
|
|
6
5
|
"main": "dist/index.js",
|
|
7
6
|
"module": "dist/index.js",
|
|
@@ -13,7 +12,7 @@
|
|
|
13
12
|
"license": "MIT",
|
|
14
13
|
"repository": {
|
|
15
14
|
"type": "git",
|
|
16
|
-
"url": "https://github.com/sqlrooms/sqlrooms.git"
|
|
15
|
+
"url": "git+https://github.com/sqlrooms/sqlrooms.git"
|
|
17
16
|
},
|
|
18
17
|
"sideEffects": false,
|
|
19
18
|
"scripts": {
|
|
@@ -27,21 +26,21 @@
|
|
|
27
26
|
},
|
|
28
27
|
"dependencies": {
|
|
29
28
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
30
|
-
"@sqlrooms/data-table": "0.29.0-rc.
|
|
31
|
-
"@sqlrooms/db": "0.29.0-rc.
|
|
32
|
-
"@sqlrooms/duckdb": "0.29.0-rc.
|
|
33
|
-
"@sqlrooms/room-store": "0.29.0-rc.
|
|
34
|
-
"@sqlrooms/sql-editor": "0.29.0-rc.
|
|
35
|
-
"@sqlrooms/ui": "0.29.0-rc.
|
|
36
|
-
"@sqlrooms/utils": "0.29.0-rc.
|
|
37
|
-
"@sqlrooms/vega": "0.29.0-rc.
|
|
29
|
+
"@sqlrooms/data-table": "0.29.0-rc.3",
|
|
30
|
+
"@sqlrooms/db": "0.29.0-rc.3",
|
|
31
|
+
"@sqlrooms/duckdb": "0.29.0-rc.3",
|
|
32
|
+
"@sqlrooms/room-store": "0.29.0-rc.3",
|
|
33
|
+
"@sqlrooms/sql-editor": "0.29.0-rc.3",
|
|
34
|
+
"@sqlrooms/ui": "0.29.0-rc.3",
|
|
35
|
+
"@sqlrooms/utils": "0.29.0-rc.3",
|
|
36
|
+
"@sqlrooms/vega": "0.29.0-rc.3",
|
|
38
37
|
"@tanstack/react-table": "^8.21.3",
|
|
39
38
|
"apache-arrow": "17.0.0",
|
|
40
39
|
"immer": "^11.0.1",
|
|
41
40
|
"lucide-react": "^0.555.0",
|
|
42
|
-
"monaco-editor": "^0.55.1",
|
|
43
41
|
"react-hook-form": "^7.68.0",
|
|
44
42
|
"react-markdown": "^10.1.0",
|
|
43
|
+
"remark-breaks": "^4.0.0",
|
|
45
44
|
"remark-gfm": "^4.0.1",
|
|
46
45
|
"zod": "^4.1.8"
|
|
47
46
|
},
|
|
@@ -53,5 +52,5 @@
|
|
|
53
52
|
"react": "^18 || ^19",
|
|
54
53
|
"react-dom": "^18 || ^19"
|
|
55
54
|
},
|
|
56
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "4ffaf6c31d41c27f96bd3e4f5e83d431968721c3"
|
|
57
56
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
export type DeleteSheetModalProps = {
|
|
3
|
-
isOpen: boolean;
|
|
4
|
-
onClose: () => void;
|
|
5
|
-
onConfirm: () => void;
|
|
6
|
-
sheetTitle?: string;
|
|
7
|
-
};
|
|
8
|
-
export declare const DeleteSheetModal: React.FC<DeleteSheetModalProps>;
|
|
9
|
-
//# sourceMappingURL=DeleteSheetModal.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DeleteSheetModal.d.ts","sourceRoot":"","sources":["../../src/components/DeleteSheetModal.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA2B5D,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Button, } from '@sqlrooms/ui';
|
|
3
|
-
export const DeleteSheetModal = ({ isOpen, onClose, onConfirm, sheetTitle, }) => {
|
|
4
|
-
return (_jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Delete ", sheetTitle || 'Sheet'] }), _jsx(DialogDescription, { children: "Are you sure you want to delete this sheet? This action cannot be undone." })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: onClose, children: "Cancel" }), _jsx(Button, { variant: "destructive", onClick: onConfirm, children: "Delete" })] })] }) }));
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=DeleteSheetModal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DeleteSheetModal.js","sourceRoot":"","sources":["../../src/components/DeleteSheetModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,MAAM,GACP,MAAM,cAAc,CAAC;AAUtB,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,GACX,EAAE,EAAE;IACH,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE,YAC9D,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,MAAC,WAAW,0BAAS,UAAU,IAAI,OAAO,IAAe,EACzD,KAAC,iBAAiB,4FAGE,IACP,EACf,MAAC,YAAY,eACX,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,OAAO,uBAEjC,EACT,KAAC,MAAM,IAAC,OAAO,EAAC,aAAa,EAAC,OAAO,EAAE,SAAS,uBAEvC,IACI,IACD,GACT,CACV,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Button,\n} from '@sqlrooms/ui';\nimport React from 'react';\n\nexport type DeleteSheetModalProps = {\n isOpen: boolean;\n onClose: () => void;\n onConfirm: () => void;\n sheetTitle?: string;\n};\n\nexport const DeleteSheetModal: React.FC<DeleteSheetModalProps> = ({\n isOpen,\n onClose,\n onConfirm,\n sheetTitle,\n}) => {\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete {sheetTitle || 'Sheet'}</DialogTitle>\n <DialogDescription>\n Are you sure you want to delete this sheet? This action cannot be\n undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>\n Cancel\n </Button>\n <Button variant=\"destructive\" onClick={onConfirm}>\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SheetsTabBar.d.ts","sourceRoot":"","sources":["../../src/components/SheetsTabBar.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAK5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAQF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAmIpD,CAAC"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, TabStrip, } from '@sqlrooms/ui';
|
|
3
|
-
import { AppWindow, FileText, LayoutDashboard, PencilIcon, PlusIcon, TrashIcon, } from 'lucide-react';
|
|
4
|
-
import React, { useCallback, useMemo, useState } from 'react';
|
|
5
|
-
import { useCellsStore } from '../hooks';
|
|
6
|
-
import { DeleteSheetModal } from './DeleteSheetModal';
|
|
7
|
-
const TYPE_ICONS = {
|
|
8
|
-
notebook: FileText,
|
|
9
|
-
canvas: LayoutDashboard,
|
|
10
|
-
app: AppWindow,
|
|
11
|
-
};
|
|
12
|
-
export const SheetsTabBar = ({ className }) => {
|
|
13
|
-
const sheetOrder = useCellsStore((s) => s.cells.config.sheetOrder);
|
|
14
|
-
const sheets = useCellsStore((s) => s.cells.config.sheets);
|
|
15
|
-
const currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);
|
|
16
|
-
const supportedTypes = useCellsStore((s) => s.cells.supportedSheetTypes);
|
|
17
|
-
const addSheet = useCellsStore((s) => s.cells.addSheet);
|
|
18
|
-
const removeSheet = useCellsStore((s) => s.cells.removeSheet);
|
|
19
|
-
const closeSheet = useCellsStore((s) => s.cells.closeSheet);
|
|
20
|
-
const openSheet = useCellsStore((s) => s.cells.openSheet);
|
|
21
|
-
const setSheetOrder = useCellsStore((s) => s.cells.setSheetOrder);
|
|
22
|
-
const renameSheet = useCellsStore((s) => s.cells.renameSheet);
|
|
23
|
-
const setCurrentSheet = useCellsStore((s) => s.cells.setCurrentSheet);
|
|
24
|
-
const [sheetToDelete, setSheetToDelete] = useState(null);
|
|
25
|
-
const handleDeleteRequest = useCallback((sheetId) => {
|
|
26
|
-
const sheet = sheets[sheetId];
|
|
27
|
-
if (sheet && sheet.cellIds.length === 0) {
|
|
28
|
-
removeSheet(sheetId);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
setSheetToDelete(sheetId);
|
|
32
|
-
}
|
|
33
|
-
}, [sheets, removeSheet]);
|
|
34
|
-
const handleConfirmDelete = useCallback(() => {
|
|
35
|
-
if (sheetToDelete) {
|
|
36
|
-
removeSheet(sheetToDelete);
|
|
37
|
-
setSheetToDelete(null);
|
|
38
|
-
}
|
|
39
|
-
}, [sheetToDelete, removeSheet]);
|
|
40
|
-
const tabs = useMemo(() => Object.values(sheets).map((sheet) => ({
|
|
41
|
-
id: sheet.id,
|
|
42
|
-
name: sheet.title || 'Untitled',
|
|
43
|
-
type: sheet.type || 'notebook',
|
|
44
|
-
})), [sheets]);
|
|
45
|
-
return (_jsxs(TabStrip, { className: className, tabs: tabs, openTabs: sheetOrder, selectedTabId: currentSheetId, onSelect: setCurrentSheet, onRename: renameSheet, onClose: closeSheet, onOpenTabsChange: setSheetOrder, renderTabTitle: (tab) => {
|
|
46
|
-
const Icon = TYPE_ICONS[tab.type] || FileText;
|
|
47
|
-
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Icon, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("div", { className: "truncate text-sm", children: tab.name })] }));
|
|
48
|
-
}, renderTabMenu: (tab) => (_jsxs(_Fragment, { children: [_jsxs(TabStrip.MenuItem, { onClick: () => renameSheet(tab.id, tab.name), children: [_jsx(PencilIcon, { className: "mr-2 h-4 w-4" }), "Rename"] }), _jsx(TabStrip.MenuSeparator, {}), _jsxs(TabStrip.MenuItem, { variant: "destructive", onClick: () => handleDeleteRequest(tab.id), children: [_jsx(TrashIcon, { className: "mr-2 h-4 w-4" }), "Delete"] })] })), renderSearchItemActions: (tab) => (_jsxs(_Fragment, { children: [_jsx(TabStrip.SearchItemAction, { icon: _jsx(PencilIcon, { className: "h-3 w-3" }), "aria-label": `Rename ${tab.name}`, onClick: () => renameSheet(tab.id, tab.name) }), _jsx(TabStrip.SearchItemAction, { icon: _jsx(TrashIcon, { className: "h-3 w-3" }), "aria-label": `Delete ${tab.name}`, onClick: () => handleDeleteRequest(tab.id) })] })), children: [_jsx(TabStrip.SearchDropdown, {}), _jsx(TabStrip.Tabs, { tabClassName: "pl-2" }), supportedTypes.length === 1 ? (_jsx(AddNewSheetButton, { onClick: () => addSheet(undefined, supportedTypes[0]) })) : (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(AddNewSheetButton, {}) }), _jsx(DropdownMenuContent, { align: "start", children: supportedTypes.map((type) => {
|
|
49
|
-
const Icon = TYPE_ICONS[type];
|
|
50
|
-
return (_jsxs(DropdownMenuItem, { onClick: () => addSheet(undefined, type), className: "capitalize", children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), "New ", type] }, type));
|
|
51
|
-
}) })] })), _jsx(DeleteSheetModal, { isOpen: sheetToDelete !== null, onClose: () => setSheetToDelete(null), onConfirm: handleConfirmDelete, sheetTitle: sheetToDelete ? sheets[sheetToDelete]?.title : undefined })] }));
|
|
52
|
-
};
|
|
53
|
-
const AddNewSheetButton = React.forwardRef(({ className, ...props }, ref) => {
|
|
54
|
-
return (_jsx(Button, { ref: ref, size: "icon", variant: "ghost", className: `hover:bg-primary/10 h-full w-8 rounded-none ${className ?? ''}`, ...props, children: _jsx(PlusIcon, { className: "h-4 w-4" }) }));
|
|
55
|
-
});
|
|
56
|
-
AddNewSheetButton.displayName = 'AddNewSheetButton';
|
|
57
|
-
//# sourceMappingURL=SheetsTabBar.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SheetsTabBar.js","sourceRoot":"","sources":["../../src/components/SheetsTabBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n TabStrip,\n TabDescriptor,\n} from '@sqlrooms/ui';\nimport {\n AppWindow,\n FileText,\n LayoutDashboard,\n PencilIcon,\n PlusIcon,\n TrashIcon,\n} from 'lucide-react';\nimport React, {useCallback, useMemo, useState} from 'react';\nimport {useCellsStore} from '../hooks';\nimport {SheetType} from '../types';\nimport {DeleteSheetModal} from './DeleteSheetModal';\n\nexport type SheetsTabBarProps = {\n className?: string;\n};\n\nconst TYPE_ICONS: Record<SheetType, React.ElementType> = {\n notebook: FileText,\n canvas: LayoutDashboard,\n app: AppWindow,\n};\n\nexport const SheetsTabBar: React.FC<SheetsTabBarProps> = ({className}) => {\n const sheetOrder = useCellsStore((s) => s.cells.config.sheetOrder);\n const sheets = useCellsStore((s) => s.cells.config.sheets);\n const currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);\n const supportedTypes = useCellsStore((s) => s.cells.supportedSheetTypes);\n const addSheet = useCellsStore((s) => s.cells.addSheet);\n const removeSheet = useCellsStore((s) => s.cells.removeSheet);\n const closeSheet = useCellsStore((s) => s.cells.closeSheet);\n const openSheet = useCellsStore((s) => s.cells.openSheet);\n const setSheetOrder = useCellsStore((s) => s.cells.setSheetOrder);\n const renameSheet = useCellsStore((s) => s.cells.renameSheet);\n const setCurrentSheet = useCellsStore((s) => s.cells.setCurrentSheet);\n\n const [sheetToDelete, setSheetToDelete] = useState<string | null>(null);\n\n const handleDeleteRequest = useCallback(\n (sheetId: string) => {\n const sheet = sheets[sheetId];\n if (sheet && sheet.cellIds.length === 0) {\n removeSheet(sheetId);\n } else {\n setSheetToDelete(sheetId);\n }\n },\n [sheets, removeSheet],\n );\n\n const handleConfirmDelete = useCallback(() => {\n if (sheetToDelete) {\n removeSheet(sheetToDelete);\n setSheetToDelete(null);\n }\n }, [sheetToDelete, removeSheet]);\n\n const tabs = useMemo(\n () =>\n Object.values(sheets).map((sheet) => ({\n id: sheet.id,\n name: sheet.title || 'Untitled',\n type: sheet.type || 'notebook',\n })),\n [sheets],\n );\n\n return (\n <TabStrip\n className={className}\n tabs={tabs}\n openTabs={sheetOrder}\n selectedTabId={currentSheetId}\n onSelect={setCurrentSheet}\n onRename={renameSheet}\n onClose={closeSheet}\n onOpenTabsChange={setSheetOrder}\n renderTabTitle={(tab: TabDescriptor) => {\n const Icon = TYPE_ICONS[tab.type as SheetType] || FileText;\n return (\n <div className=\"flex min-w-0 items-center gap-2\">\n <Icon className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <div className=\"truncate text-sm\">{tab.name}</div>\n </div>\n );\n }}\n renderTabMenu={(tab) => (\n <>\n <TabStrip.MenuItem onClick={() => renameSheet(tab.id, tab.name)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Rename\n </TabStrip.MenuItem>\n <TabStrip.MenuSeparator />\n <TabStrip.MenuItem\n variant=\"destructive\"\n onClick={() => handleDeleteRequest(tab.id)}\n >\n <TrashIcon className=\"mr-2 h-4 w-4\" />\n Delete\n </TabStrip.MenuItem>\n </>\n )}\n renderSearchItemActions={(tab) => (\n <>\n <TabStrip.SearchItemAction\n icon={<PencilIcon className=\"h-3 w-3\" />}\n aria-label={`Rename ${tab.name}`}\n onClick={() => renameSheet(tab.id, tab.name)}\n />\n <TabStrip.SearchItemAction\n icon={<TrashIcon className=\"h-3 w-3\" />}\n aria-label={`Delete ${tab.name}`}\n onClick={() => handleDeleteRequest(tab.id)}\n />\n </>\n )}\n >\n <TabStrip.SearchDropdown />\n <TabStrip.Tabs tabClassName=\"pl-2\" />\n\n {supportedTypes.length === 1 ? (\n <AddNewSheetButton\n onClick={() => addSheet(undefined, supportedTypes[0])}\n />\n ) : (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <AddNewSheetButton />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {supportedTypes.map((type) => {\n const Icon = TYPE_ICONS[type];\n return (\n <DropdownMenuItem\n key={type}\n onClick={() => addSheet(undefined, type)}\n className=\"capitalize\"\n >\n <Icon className=\"mr-2 h-4 w-4\" />\n New {type}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <DeleteSheetModal\n isOpen={sheetToDelete !== null}\n onClose={() => setSheetToDelete(null)}\n onConfirm={handleConfirmDelete}\n sheetTitle={sheetToDelete ? sheets[sheetToDelete]?.title : undefined}\n />\n </TabStrip>\n );\n};\n\nconst AddNewSheetButton = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof Button>\n>(({className, ...props}, ref) => {\n return (\n <Button\n ref={ref}\n size=\"icon\"\n variant=\"ghost\"\n className={`hover:bg-primary/10 h-full w-8 rounded-none ${className ?? ''}`}\n {...props}\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n );\n});\nAddNewSheetButton.displayName = 'AddNewSheetButton';\n"]}
|