@sqlrooms/room-shell 0.27.0 → 0.28.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/README.md +114 -647
- package/dist/RoomShell.d.ts +3 -0
- package/dist/RoomShell.d.ts.map +1 -1
- package/dist/RoomShell.js +4 -2
- package/dist/RoomShell.js.map +1 -1
- package/dist/RoomShellCommandPalette.d.ts +24 -0
- package/dist/RoomShellCommandPalette.d.ts.map +1 -0
- package/dist/RoomShellCommandPalette.js +394 -0
- package/dist/RoomShellCommandPalette.js.map +1 -0
- package/dist/RoomShellSlice.d.ts +2 -2
- package/dist/RoomShellSlice.d.ts.map +1 -1
- package/dist/RoomShellSlice.js +175 -1
- package/dist/RoomShellSlice.js.map +1 -1
- package/dist/data-sources/FileDataSourceCard.js +1 -1
- package/dist/data-sources/FileDataSourceCard.js.map +1 -1
- package/dist/data-sources/FileDataSourcesPanel.js +1 -1
- package/dist/data-sources/FileDataSourcesPanel.js.map +1 -1
- package/dist/data-sources/TablesListPanel.js +1 -1
- package/dist/data-sources/TablesListPanel.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/panels/RoomPanel.js +1 -1
- package/dist/panels/RoomPanel.js.map +1 -1
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -1,704 +1,171 @@
|
|
|
1
|
-
|
|
1
|
+
Main SQLRooms application shell and default Room slice composition.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@sqlrooms/room-shell` bundles:
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
- base room lifecycle (`room-store`)
|
|
6
|
+
- DuckDB slice (`@sqlrooms/duckdb`)
|
|
7
|
+
- layout slice (`@sqlrooms/layout`)
|
|
8
|
+
- React shell UI (`RoomShell`, sidebar/layout/loading components)
|
|
9
|
+
|
|
10
|
+
Use this package as the default entry point for most SQLRooms apps.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npm install @sqlrooms/room-shell
|
|
16
|
-
# or
|
|
17
|
-
yarn add @sqlrooms/room-shell
|
|
15
|
+
npm install @sqlrooms/room-shell @sqlrooms/duckdb @sqlrooms/ui
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
### Creating a Room Builder
|
|
23
|
-
|
|
24
|
-
```tsx
|
|
25
|
-
import {RoomShell} from '@sqlrooms/room-shell';
|
|
26
|
-
|
|
27
|
-
function MyApp() {
|
|
28
|
-
return (
|
|
29
|
-
<RoomShell className="h-screen" roomStore={roomStore}>
|
|
30
|
-
<RoomShell.Sidebar />
|
|
31
|
-
<RoomShell.LayoutComposer />
|
|
32
|
-
<RoomShell.LoadingProgress />
|
|
33
|
-
</RoomShell>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Working with Room State
|
|
39
|
-
|
|
40
|
-
The room-shell package uses Zustand for state management. You can create a custom store with room-specific state and actions.
|
|
18
|
+
## Quick start
|
|
41
19
|
|
|
42
20
|
```tsx
|
|
43
21
|
import {
|
|
44
22
|
createRoomShellSlice,
|
|
45
23
|
createRoomStore,
|
|
24
|
+
LayoutTypes,
|
|
25
|
+
RoomShell,
|
|
46
26
|
RoomShellSliceState,
|
|
47
27
|
} from '@sqlrooms/room-shell';
|
|
28
|
+
import {DatabaseIcon} from 'lucide-react';
|
|
48
29
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
30
|
+
function DataPanel() {
|
|
31
|
+
return <div className="p-2">Data panel</div>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function MainPanel() {
|
|
35
|
+
return <div className="p-2">Main panel</div>;
|
|
36
|
+
}
|
|
55
37
|
|
|
56
|
-
|
|
57
|
-
|
|
38
|
+
type RoomState = RoomShellSliceState;
|
|
39
|
+
|
|
40
|
+
export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
|
|
58
41
|
(set, get, store) => ({
|
|
59
|
-
// Base room slice with initial configuration
|
|
60
42
|
...createRoomShellSlice({
|
|
61
43
|
config: {
|
|
62
|
-
title: 'My
|
|
63
|
-
dataSources: [
|
|
44
|
+
title: 'My SQLRooms App',
|
|
45
|
+
dataSources: [
|
|
46
|
+
{
|
|
47
|
+
type: 'url',
|
|
48
|
+
tableName: 'earthquakes',
|
|
49
|
+
url: 'https://huggingface.co/datasets/sqlrooms/earthquakes/resolve/main/earthquakes.parquet',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
64
52
|
},
|
|
65
53
|
layout: {
|
|
66
54
|
config: {
|
|
67
|
-
|
|
55
|
+
type: LayoutTypes.enum.mosaic,
|
|
56
|
+
nodes: {
|
|
57
|
+
direction: 'row',
|
|
58
|
+
first: 'data',
|
|
59
|
+
second: 'main',
|
|
60
|
+
splitPercentage: 28,
|
|
61
|
+
},
|
|
68
62
|
},
|
|
69
63
|
panels: {
|
|
70
|
-
|
|
64
|
+
data: {
|
|
65
|
+
title: 'Data',
|
|
66
|
+
icon: DatabaseIcon,
|
|
67
|
+
component: DataPanel,
|
|
68
|
+
placement: 'sidebar',
|
|
69
|
+
},
|
|
70
|
+
main: {
|
|
71
|
+
title: 'Main',
|
|
72
|
+
icon: () => null,
|
|
73
|
+
component: MainPanel,
|
|
74
|
+
placement: 'main',
|
|
75
|
+
},
|
|
71
76
|
},
|
|
72
77
|
},
|
|
73
78
|
})(set, get, store),
|
|
74
|
-
|
|
75
|
-
// Custom state and actions
|
|
76
|
-
myFeatureData: [],
|
|
77
|
-
addItem: (item) =>
|
|
78
|
-
set((state) => ({
|
|
79
|
-
myFeatureData: [...state.myFeatureData, item],
|
|
80
|
-
})),
|
|
81
|
-
removeItem: (id) =>
|
|
82
|
-
set((state) => ({
|
|
83
|
-
myFeatureData: state.myFeatureData.filter((item) => item.id !== id),
|
|
84
|
-
})),
|
|
85
79
|
}),
|
|
86
80
|
);
|
|
87
81
|
|
|
88
|
-
|
|
89
|
-
function MyComponent() {
|
|
90
|
-
// Use selectors for better performance
|
|
91
|
-
const myFeatureData = useRoomStore((state) => state.myFeatureData);
|
|
92
|
-
const addItem = useRoomStore((state) => state.addItem);
|
|
93
|
-
|
|
82
|
+
export function App() {
|
|
94
83
|
return (
|
|
95
|
-
<
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
</div>
|
|
84
|
+
<RoomShell roomStore={roomStore} className="h-screen">
|
|
85
|
+
<RoomShell.Sidebar />
|
|
86
|
+
<RoomShell.LayoutComposer />
|
|
87
|
+
<RoomShell.LoadingProgress />
|
|
88
|
+
<RoomShell.CommandPalette />
|
|
89
|
+
</RoomShell>
|
|
102
90
|
);
|
|
103
91
|
}
|
|
104
92
|
```
|
|
105
93
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
The room configuration is designed to be persisted between sessions. You can use the `persistSliceConfigs` helper to save the configuration to localStorage or any other storage:
|
|
109
|
-
|
|
110
|
-
```tsx
|
|
111
|
-
import {
|
|
112
|
-
createRoomShellSlice,
|
|
113
|
-
createRoomStore,
|
|
114
|
-
RoomShellSliceState,
|
|
115
|
-
BaseRoomConfig,
|
|
116
|
-
LayoutConfig,
|
|
117
|
-
persistSliceConfigs,
|
|
118
|
-
} from '@sqlrooms/room-shell';
|
|
119
|
-
|
|
120
|
-
// Define your custom app state
|
|
121
|
-
type MyRoomState = RoomShellSliceState & {
|
|
122
|
-
myFeatureData: any[];
|
|
123
|
-
addItem: (item: any) => void;
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
// Create a store with persistence
|
|
127
|
-
export const {roomStore, useRoomStore} = createRoomStore<MyRoomState>(
|
|
128
|
-
persistSliceConfigs(
|
|
129
|
-
{
|
|
130
|
-
name: 'my-room-storage',
|
|
131
|
-
sliceConfigSchemas: {
|
|
132
|
-
room: BaseRoomConfig,
|
|
133
|
-
layout: LayoutConfig,
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
(set, get, store) => ({
|
|
137
|
-
// Base room slice
|
|
138
|
-
...createRoomShellSlice({
|
|
139
|
-
config: {
|
|
140
|
-
title: 'My Room',
|
|
141
|
-
dataSources: [],
|
|
142
|
-
},
|
|
143
|
-
layout: {
|
|
144
|
-
config: {
|
|
145
|
-
/* layout configuration */
|
|
146
|
-
},
|
|
147
|
-
panels: {
|
|
148
|
-
/* panel definitions */
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
})(set, get, store),
|
|
152
|
-
|
|
153
|
-
// Custom state and actions
|
|
154
|
-
myFeatureData: [],
|
|
155
|
-
addItem: (item) =>
|
|
156
|
-
set((state) => ({
|
|
157
|
-
myFeatureData: [...state.myFeatureData, item],
|
|
158
|
-
})),
|
|
159
|
-
}),
|
|
160
|
-
),
|
|
161
|
-
);
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Integrating Multiple Feature Slices
|
|
165
|
-
|
|
166
|
-
For larger applications, you can organize your state into feature slices:
|
|
167
|
-
|
|
168
|
-
```tsx
|
|
169
|
-
import {
|
|
170
|
-
createRoomShellSlice,
|
|
171
|
-
createRoomStore,
|
|
172
|
-
RoomShellSliceState,
|
|
173
|
-
} from '@sqlrooms/room-shell';
|
|
174
|
-
import {createMyFeatureSlice, MyFeatureState} from './myFeatureSlice';
|
|
175
|
-
import {
|
|
176
|
-
createAnotherFeatureSlice,
|
|
177
|
-
AnotherFeatureState,
|
|
178
|
-
} from './anotherFeatureSlice';
|
|
179
|
-
|
|
180
|
-
// Combined app state type
|
|
181
|
-
type MyRoomState = RoomShellSliceState & MyFeatureState & AnotherFeatureState;
|
|
182
|
-
|
|
183
|
-
// Create a store with multiple slices
|
|
184
|
-
export const {roomStore, useRoomStore} = createRoomStore<MyRoomState>(
|
|
185
|
-
(set, get, store) => ({
|
|
186
|
-
// Base room slice
|
|
187
|
-
...createRoomShellSlice({
|
|
188
|
-
config: {
|
|
189
|
-
/* initial config */
|
|
190
|
-
},
|
|
191
|
-
layout: {
|
|
192
|
-
config: {
|
|
193
|
-
/* layout configuration */
|
|
194
|
-
},
|
|
195
|
-
panels: {
|
|
196
|
-
/* panel definitions */
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
})(set, get, store),
|
|
200
|
-
|
|
201
|
-
// Feature slices
|
|
202
|
-
...createMyFeatureSlice()(set, get, store),
|
|
203
|
-
...createAnotherFeatureSlice({
|
|
204
|
-
// Feature-specific options
|
|
205
|
-
customOption: 'value',
|
|
206
|
-
})(set, get, store),
|
|
207
|
-
}),
|
|
208
|
-
);
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Managing Data Sources
|
|
94
|
+
## Common room actions
|
|
212
95
|
|
|
213
96
|
```tsx
|
|
214
|
-
import {
|
|
215
|
-
|
|
216
|
-
TablesListPanel,
|
|
217
|
-
DataSourceType,
|
|
218
|
-
} from '@sqlrooms/room-shell';
|
|
97
|
+
import {useRoomStore} from './store';
|
|
98
|
+
import {Button} from '@sqlrooms/ui';
|
|
219
99
|
|
|
220
|
-
function
|
|
221
|
-
|
|
100
|
+
function RoomActions() {
|
|
101
|
+
const setRoomTitle = useRoomStore((state) => state.room.setRoomTitle);
|
|
222
102
|
const addDataSource = useRoomStore((state) => state.room.addDataSource);
|
|
103
|
+
const removeDataSource = useRoomStore((state) => state.room.removeDataSource);
|
|
223
104
|
const addRoomFile = useRoomStore((state) => state.room.addRoomFile);
|
|
224
105
|
|
|
225
|
-
const handleFileDrop = async (files) => {
|
|
226
|
-
for (const file of files) {
|
|
227
|
-
await addRoomFile(file);
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const handleAddCsvUrl = (url) => {
|
|
232
|
-
addDataSource({
|
|
233
|
-
type: DataSourceType.url,
|
|
234
|
-
url,
|
|
235
|
-
tableName: 'data_from_url',
|
|
236
|
-
});
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
const handleAddSqlQuery = (query) => {
|
|
240
|
-
addDataSource({
|
|
241
|
-
type: DataSourceType.sqlQuery,
|
|
242
|
-
query,
|
|
243
|
-
tableName: 'query_results',
|
|
244
|
-
});
|
|
245
|
-
};
|
|
246
|
-
|
|
247
106
|
return (
|
|
248
|
-
<div className="
|
|
249
|
-
<
|
|
250
|
-
<
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
107
|
+
<div className="flex gap-2">
|
|
108
|
+
<Button onClick={() => setRoomTitle('Updated title')}>Rename room</Button>
|
|
109
|
+
<Button
|
|
110
|
+
onClick={() =>
|
|
111
|
+
void addDataSource({
|
|
112
|
+
type: 'sql',
|
|
113
|
+
tableName: 'top_quakes',
|
|
114
|
+
sqlQuery:
|
|
115
|
+
'SELECT * FROM earthquakes ORDER BY Magnitude DESC LIMIT 100',
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
>
|
|
119
|
+
Add SQL data source
|
|
120
|
+
</Button>
|
|
121
|
+
<Button onClick={() => void removeDataSource('top_quakes')}>
|
|
122
|
+
Remove SQL data source
|
|
123
|
+
</Button>
|
|
124
|
+
<Button
|
|
125
|
+
onClick={async () => {
|
|
126
|
+
const file = new File(['id,name\n1,Alice'], 'people.csv', {
|
|
127
|
+
type: 'text/csv',
|
|
128
|
+
});
|
|
129
|
+
await addRoomFile(file);
|
|
130
|
+
}}
|
|
131
|
+
>
|
|
132
|
+
Add file
|
|
133
|
+
</Button>
|
|
254
134
|
</div>
|
|
255
135
|
);
|
|
256
136
|
}
|
|
257
137
|
```
|
|
258
138
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
```tsx
|
|
262
|
-
import {RoomPanel, RoomPanelHeader} from '@sqlrooms/room-shell';
|
|
263
|
-
|
|
264
|
-
function CustomPanel({title, children}) {
|
|
265
|
-
return (
|
|
266
|
-
<RoomPanel>
|
|
267
|
-
<RoomPanelHeader title={title} />
|
|
268
|
-
<div className="p-4">{children}</div>
|
|
269
|
-
</RoomPanel>
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## RoomStore API Reference
|
|
275
|
-
|
|
276
|
-
The RoomStore is the core of the room-shell package. It provides a comprehensive set of properties and methods for managing room state.
|
|
277
|
-
|
|
278
|
-
### State Properties
|
|
279
|
-
|
|
280
|
-
#### `room.config`
|
|
281
|
-
|
|
282
|
-
The room configuration, which can be persisted between sessions.
|
|
283
|
-
|
|
284
|
-
```tsx
|
|
285
|
-
const config = useRoomStore((state) => state.room.config);
|
|
286
|
-
console.log(config.title); // Access room title
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
#### `schema`
|
|
290
|
-
|
|
291
|
-
The database schema name used for the room.
|
|
292
|
-
|
|
293
|
-
```tsx
|
|
294
|
-
const schema = useRoomStore((state) => state.room.schema);
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
#### `tasksProgress`
|
|
298
|
-
|
|
299
|
-
A record of task progress information, useful for displaying loading indicators.
|
|
300
|
-
|
|
301
|
-
```tsx
|
|
302
|
-
const tasksProgress = useRoomStore((state) => state.room.tasksProgress);
|
|
303
|
-
// Example: { "init-db": { message: "Initializing database...", progress: 0.5 } }
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
#### `roomId`
|
|
307
|
-
|
|
308
|
-
The unique identifier for the room, undefined for new rooms.
|
|
309
|
-
|
|
310
|
-
```tsx
|
|
311
|
-
const roomId = useRoomStore((state) => state.room.roomId);
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
#### `panels`
|
|
315
|
-
|
|
316
|
-
A record of panel information, including title, icon, component, and placement.
|
|
317
|
-
|
|
318
|
-
```tsx
|
|
319
|
-
const panels = useRoomStore((state) => state.room.panels);
|
|
320
|
-
// Example: { "data-sources": { title: "Data Sources", icon: DatabaseIcon, ... } }
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
#### `isReadOnly`
|
|
324
|
-
|
|
325
|
-
Whether the room is in read-only mode.
|
|
326
|
-
|
|
327
|
-
```tsx
|
|
328
|
-
const isReadOnly = useRoomStore((state) => state.room.isReadOnly);
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
#### `tables`
|
|
332
|
-
|
|
333
|
-
An array of data tables available in the room.
|
|
334
|
-
|
|
335
|
-
```tsx
|
|
336
|
-
const tables = useRoomStore((state) => state.room.tables);
|
|
337
|
-
// Access table schemas and metadata
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
#### `roomFiles`
|
|
341
|
-
|
|
342
|
-
An array of room file information.
|
|
343
|
-
|
|
344
|
-
```tsx
|
|
345
|
-
const roomFiles = useRoomStore((state) => state.room.roomFiles);
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
#### `roomFilesProgress`
|
|
349
|
-
|
|
350
|
-
A record of file processing progress information.
|
|
351
|
-
|
|
352
|
-
```tsx
|
|
353
|
-
const roomFilesProgress = useRoomStore((state) => state.room.roomFilesProgress);
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
#### `lastSavedConfig`
|
|
357
|
-
|
|
358
|
-
The last saved room configuration, used to check for unsaved changes.
|
|
359
|
-
|
|
360
|
-
```tsx
|
|
361
|
-
const lastSavedConfig = useRoomStore((state) => state.room.lastSavedConfig);
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
#### `initialized`
|
|
365
|
-
|
|
366
|
-
Whether the room has been initialized.
|
|
367
|
-
|
|
368
|
-
```tsx
|
|
369
|
-
const initialized = useRoomStore((state) => state.room.initialized);
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
#### `isDataAvailable`
|
|
373
|
-
|
|
374
|
-
Whether the room data has been loaded.
|
|
375
|
-
|
|
376
|
-
```tsx
|
|
377
|
-
const isDataAvailable = useRoomStore((state) => state.room.isDataAvailable);
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
#### `dataSourceStates`
|
|
381
|
-
|
|
382
|
-
A record of data source states by table name.
|
|
383
|
-
|
|
384
|
-
```tsx
|
|
385
|
-
const dataSourceStates = useRoomStore((state) => state.room.dataSourceStates);
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
#### `tableRowCounts`
|
|
389
|
-
|
|
390
|
-
A record of row counts by table name.
|
|
391
|
-
|
|
392
|
-
```tsx
|
|
393
|
-
const tableRowCounts = useRoomStore((state) => state.room.tableRowCounts);
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### Methods
|
|
397
|
-
|
|
398
|
-
#### `initialize()`
|
|
399
|
-
|
|
400
|
-
Initialize the room state.
|
|
401
|
-
|
|
402
|
-
```tsx
|
|
403
|
-
const initialize = useRoomStore((state) => state.room.initialize);
|
|
404
|
-
await initialize();
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
#### `setTaskProgress(id, taskProgress)`
|
|
408
|
-
|
|
409
|
-
Set the progress of a task.
|
|
410
|
-
|
|
411
|
-
```tsx
|
|
412
|
-
const setTaskProgress = useRoomStore((state) => state.room.setTaskProgress);
|
|
413
|
-
setTaskProgress('my-task', {message: 'Processing...', progress: 0.5});
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
#### `getLoadingProgress()`
|
|
417
|
-
|
|
418
|
-
Get the current loading progress.
|
|
419
|
-
|
|
420
|
-
```tsx
|
|
421
|
-
const getLoadingProgress = useRoomStore(
|
|
422
|
-
(state) => state.room.getLoadingProgress,
|
|
423
|
-
);
|
|
424
|
-
const progress = getLoadingProgress();
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
#### `setRoomConfig(config)`
|
|
428
|
-
|
|
429
|
-
Set the room configuration.
|
|
430
|
-
|
|
431
|
-
```tsx
|
|
432
|
-
const setRoomConfig = useRoomStore((state) => state.room.setRoomConfig);
|
|
433
|
-
const config = useRoomStore((state) => state.config);
|
|
434
|
-
setRoomConfig({...config, title: 'New Title'});
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
#### `setLastSavedConfig(config)`
|
|
438
|
-
|
|
439
|
-
Set the last saved room configuration.
|
|
440
|
-
|
|
441
|
-
```tsx
|
|
442
|
-
const setLastSavedConfig = useRoomStore(
|
|
443
|
-
(state) => state.room.setLastSavedConfig,
|
|
444
|
-
);
|
|
445
|
-
const config = useRoomStore((state) => state.config);
|
|
446
|
-
setLastSavedConfig(config);
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
#### `hasUnsavedChanges()`
|
|
450
|
-
|
|
451
|
-
Check if the room has unsaved changes.
|
|
452
|
-
|
|
453
|
-
```tsx
|
|
454
|
-
const hasUnsavedChanges = useRoomStore((state) => state.room.hasUnsavedChanges);
|
|
455
|
-
if (hasUnsavedChanges()) {
|
|
456
|
-
// Prompt user to save changes
|
|
457
|
-
}
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
#### `setLayout(layout)`
|
|
461
|
-
|
|
462
|
-
Set the room layout configuration.
|
|
463
|
-
|
|
464
|
-
```tsx
|
|
465
|
-
const setLayout = useRoomStore((state) => state.room.setLayout);
|
|
466
|
-
setLayout(newLayout);
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
#### `togglePanel(panel, show)`
|
|
470
|
-
|
|
471
|
-
Toggle the visibility of a panel.
|
|
472
|
-
|
|
473
|
-
```tsx
|
|
474
|
-
const togglePanel = useRoomStore((state) => state.room.togglePanel);
|
|
475
|
-
togglePanel('data-sources', true); // Show the data sources panel
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
#### `togglePanelPin(panel)`
|
|
479
|
-
|
|
480
|
-
Toggle the pin state of a panel.
|
|
481
|
-
|
|
482
|
-
```tsx
|
|
483
|
-
const togglePanelPin = useRoomStore((state) => state.room.togglePanelPin);
|
|
484
|
-
togglePanelPin('data-sources');
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
#### `addOrUpdateSqlQueryDataSource(tableName, query, oldTableName)`
|
|
488
|
-
|
|
489
|
-
Add or update a SQL query data source.
|
|
490
|
-
|
|
491
|
-
```tsx
|
|
492
|
-
const addOrUpdateSqlQueryDataSource = useRoomStore(
|
|
493
|
-
(state) => state.room.addOrUpdateSqlQueryDataSource,
|
|
494
|
-
);
|
|
495
|
-
await addOrUpdateSqlQueryDataSource(
|
|
496
|
-
'filtered_data',
|
|
497
|
-
'SELECT * FROM data WHERE value > 10',
|
|
498
|
-
);
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
#### `removeSqlQueryDataSource(tableName)`
|
|
502
|
-
|
|
503
|
-
Remove a SQL query data source.
|
|
504
|
-
|
|
505
|
-
```tsx
|
|
506
|
-
const removeSqlQueryDataSource = useRoomStore(
|
|
507
|
-
(state) => state.room.removeSqlQueryDataSource,
|
|
508
|
-
);
|
|
509
|
-
await removeSqlQueryDataSource('filtered_data');
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
#### `addRoomFile(info, desiredTableName)`
|
|
513
|
-
|
|
514
|
-
Add a room file.
|
|
515
|
-
|
|
516
|
-
```tsx
|
|
517
|
-
const addRoomFile = useRoomStore((state) => state.room.addRoomFile);
|
|
518
|
-
const dataTable = await addRoomFile(file, 'my_data');
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
#### `removeRoomFile(pathname)`
|
|
522
|
-
|
|
523
|
-
Remove a room file.
|
|
524
|
-
|
|
525
|
-
```tsx
|
|
526
|
-
const removeRoomFile = useRoomStore((state) => state.room.removeRoomFile);
|
|
527
|
-
removeRoomFile('/path/to/file.csv');
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
#### `maybeDownloadDataSources()`
|
|
531
|
-
|
|
532
|
-
Download data sources if needed.
|
|
533
|
-
|
|
534
|
-
```tsx
|
|
535
|
-
const maybeDownloadDataSources = useRoomStore(
|
|
536
|
-
(state) => state.room.maybeDownloadDataSources,
|
|
537
|
-
);
|
|
538
|
-
await maybeDownloadDataSources();
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
#### `setRoomFiles(info)`
|
|
542
|
-
|
|
543
|
-
Set the room files.
|
|
544
|
-
|
|
545
|
-
```tsx
|
|
546
|
-
const setRoomFiles = useRoomStore((state) => state.room.setRoomFiles);
|
|
547
|
-
setRoomFiles(fileInfoArray);
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
#### `setRoomFileProgress(pathname, fileState)`
|
|
551
|
-
|
|
552
|
-
Set the progress of a room file.
|
|
553
|
-
|
|
554
|
-
```tsx
|
|
555
|
-
const setRoomFileProgress = useRoomStore(
|
|
556
|
-
(state) => state.room.setRoomFileProgress,
|
|
557
|
-
);
|
|
558
|
-
setRoomFileProgress('/path/to/file.csv', {status: 'processing'});
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
#### `addTable(tableName, data)`
|
|
562
|
-
|
|
563
|
-
Add a table to the room.
|
|
564
|
-
|
|
565
|
-
```tsx
|
|
566
|
-
const addTable = useRoomStore((state) => state.db.addTable);
|
|
567
|
-
await addTable('my_table', records);
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
#### `addDataSource(dataSource, status)`
|
|
571
|
-
|
|
572
|
-
Add a data source to the room.
|
|
573
|
-
|
|
574
|
-
```tsx
|
|
575
|
-
const addDataSource = useRoomStore((state) => state.room.addDataSource);
|
|
576
|
-
await addDataSource({
|
|
577
|
-
type: 'url',
|
|
578
|
-
url: 'https://example.com/data.csv',
|
|
579
|
-
tableName: 'external_data',
|
|
580
|
-
});
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
#### `getTable(tableName)`
|
|
584
|
-
|
|
585
|
-
Get a table by name.
|
|
586
|
-
|
|
587
|
-
```tsx
|
|
588
|
-
const getTable = useRoomStore((state) => state.room.getTable);
|
|
589
|
-
const table = getTable('my_table');
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
#### `setTables(dataTable)`
|
|
593
|
-
|
|
594
|
-
Set the room tables.
|
|
595
|
-
|
|
596
|
-
```tsx
|
|
597
|
-
const setTables = useRoomStore((state) => state.room.setTables);
|
|
598
|
-
await setTables(tableArray);
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
#### `setTableRowCount(tableName, rowCount)`
|
|
602
|
-
|
|
603
|
-
Set the row count for a table.
|
|
604
|
-
|
|
605
|
-
```tsx
|
|
606
|
-
const setTableRowCount = useRoomStore((state) => state.room.setTableRowCount);
|
|
607
|
-
setTableRowCount('my_table', 1000);
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
#### `setRoomTitle(title)`
|
|
611
|
-
|
|
612
|
-
Set the room title.
|
|
613
|
-
|
|
614
|
-
```tsx
|
|
615
|
-
const setRoomTitle = useRoomStore((state) => state.room.setRoomTitle);
|
|
616
|
-
setRoomTitle('My Awesome Room');
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
#### `setDescription(description)`
|
|
620
|
-
|
|
621
|
-
Set the room description.
|
|
622
|
-
|
|
623
|
-
```tsx
|
|
624
|
-
const setDescription = useRoomStore((state) => state.room.setDescription);
|
|
625
|
-
setDescription('This is a description of my room');
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
#### `areDatasetsReady()`
|
|
629
|
-
|
|
630
|
-
Check if all datasets are ready.
|
|
631
|
-
|
|
632
|
-
```tsx
|
|
633
|
-
const areDatasetsReady = useRoomStore((state) => state.room.areDatasetsReady);
|
|
634
|
-
if (areDatasetsReady()) {
|
|
635
|
-
// Proceed with data operations
|
|
636
|
-
}
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
#### `findTableByName(tableName)`
|
|
139
|
+
## Persistence
|
|
640
140
|
|
|
641
|
-
|
|
141
|
+
Use `persistSliceConfigs` with schemas:
|
|
642
142
|
|
|
643
143
|
```tsx
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
Update the status of all data sources based on the current tables.
|
|
651
|
-
|
|
652
|
-
```tsx
|
|
653
|
-
const updateReadyDataSources = useRoomStore(
|
|
654
|
-
(state) => state.room.updateReadyDataSources,
|
|
655
|
-
);
|
|
656
|
-
await updateReadyDataSources();
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
#### `onDataUpdated()`
|
|
660
|
-
|
|
661
|
-
Called when data has been updated.
|
|
662
|
-
|
|
663
|
-
```tsx
|
|
664
|
-
const onDataUpdated = useRoomStore((state) => state.room.onDataUpdated);
|
|
665
|
-
await onDataUpdated();
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
#### `areViewsReadyToRender()`
|
|
669
|
-
|
|
670
|
-
Check if views are ready to render.
|
|
671
|
-
|
|
672
|
-
```tsx
|
|
673
|
-
const areViewsReadyToRender = useRoomStore(
|
|
674
|
-
(state) => state.room.areViewsReadyToRender,
|
|
675
|
-
);
|
|
676
|
-
if (areViewsReadyToRender()) {
|
|
677
|
-
// Render views
|
|
678
|
-
}
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
#### `refreshTableSchemas()`
|
|
144
|
+
import {
|
|
145
|
+
BaseRoomConfig,
|
|
146
|
+
LayoutConfig,
|
|
147
|
+
createRoomStore,
|
|
148
|
+
persistSliceConfigs,
|
|
149
|
+
} from '@sqlrooms/room-shell';
|
|
682
150
|
|
|
683
|
-
|
|
151
|
+
const persistence = {
|
|
152
|
+
name: 'my-room-storage',
|
|
153
|
+
sliceConfigSchemas: {
|
|
154
|
+
room: BaseRoomConfig,
|
|
155
|
+
layout: LayoutConfig,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
684
158
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
159
|
+
createRoomStore(
|
|
160
|
+
persistSliceConfigs(persistence, (set, get, store) => ({
|
|
161
|
+
// compose slices here
|
|
162
|
+
})),
|
|
688
163
|
);
|
|
689
|
-
const updatedTables = await refreshTableSchemas();
|
|
690
164
|
```
|
|
691
165
|
|
|
692
|
-
##
|
|
166
|
+
## Related packages
|
|
693
167
|
|
|
694
|
-
-
|
|
695
|
-
-
|
|
696
|
-
-
|
|
697
|
-
-
|
|
698
|
-
- **File Processing**: Process and transform data files
|
|
699
|
-
|
|
700
|
-
For more information, visit the SQLRooms documentation.
|
|
701
|
-
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
```
|
|
168
|
+
- `@sqlrooms/sql-editor`
|
|
169
|
+
- `@sqlrooms/ai`
|
|
170
|
+
- `@sqlrooms/mosaic`
|
|
171
|
+
- `@sqlrooms/vega`
|