rita-workspace 0.4.1 → 0.4.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/dist/index.d.mts CHANGED
@@ -76,6 +76,8 @@ interface Translations {
76
76
  confirmDelete: string;
77
77
  exportWorkspace: string;
78
78
  importWorkspace: string;
79
+ exportDrawing: string;
80
+ importDrawing: string;
79
81
  shortcutNewDrawing: string;
80
82
  }
81
83
  /**
@@ -102,8 +104,11 @@ interface WorkspaceContextValue {
102
104
  removeDrawing: (id: string) => Promise<void>;
103
105
  duplicateCurrentDrawing: () => Promise<Drawing | null>;
104
106
  saveCurrentDrawing: (elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
107
+ saveDrawingById: (id: string, elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
105
108
  exportWorkspace: () => Promise<void>;
106
109
  importWorkspace: () => Promise<void>;
110
+ exportDrawingAsExcalidraw: (id: string) => Promise<void>;
111
+ importExcalidrawFile: () => Promise<void>;
107
112
  }
108
113
  declare function useWorkspace(): WorkspaceContextValue;
109
114
  /**
package/dist/index.d.ts CHANGED
@@ -76,6 +76,8 @@ interface Translations {
76
76
  confirmDelete: string;
77
77
  exportWorkspace: string;
78
78
  importWorkspace: string;
79
+ exportDrawing: string;
80
+ importDrawing: string;
79
81
  shortcutNewDrawing: string;
80
82
  }
81
83
  /**
@@ -102,8 +104,11 @@ interface WorkspaceContextValue {
102
104
  removeDrawing: (id: string) => Promise<void>;
103
105
  duplicateCurrentDrawing: () => Promise<Drawing | null>;
104
106
  saveCurrentDrawing: (elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
107
+ saveDrawingById: (id: string, elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
105
108
  exportWorkspace: () => Promise<void>;
106
109
  importWorkspace: () => Promise<void>;
110
+ exportDrawingAsExcalidraw: (id: string) => Promise<void>;
111
+ importExcalidrawFile: () => Promise<void>;
107
112
  }
108
113
  declare function useWorkspace(): WorkspaceContextValue;
109
114
  /**
package/dist/index.js CHANGED
@@ -230,8 +230,10 @@ var sv = {
230
230
  modified: "\xC4ndrad",
231
231
  confirmDelete: "Vill du ta bort denna ritning?",
232
232
  // Export/Import
233
- exportWorkspace: "Exportera",
234
- importWorkspace: "Importera",
233
+ exportWorkspace: "Exportera arbetsyta",
234
+ importWorkspace: "Importera arbetsyta",
235
+ exportDrawing: "Spara som .excalidraw",
236
+ importDrawing: "\xD6ppna .excalidraw",
235
237
  // Shortcuts
236
238
  shortcutNewDrawing: "Ctrl+Alt+N"
237
239
  };
@@ -255,8 +257,10 @@ var en = {
255
257
  modified: "Modified",
256
258
  confirmDelete: "Do you want to delete this drawing?",
257
259
  // Export/Import
258
- exportWorkspace: "Export",
259
- importWorkspace: "Import",
260
+ exportWorkspace: "Export workspace",
261
+ importWorkspace: "Import workspace",
262
+ exportDrawing: "Save as .excalidraw",
263
+ importDrawing: "Open .excalidraw",
260
264
  // Shortcuts
261
265
  shortcutNewDrawing: "Ctrl+Alt+N"
262
266
  };
@@ -420,6 +424,20 @@ function WorkspaceProvider({ children, lang = "en" }) {
420
424
  setError(err instanceof Error ? err.message : "Failed to save drawing");
421
425
  }
422
426
  }, [activeDrawing]);
427
+ const saveDrawingById = (0, import_react.useCallback)(async (id, elements, appState, files) => {
428
+ try {
429
+ const updateData = {
430
+ elements,
431
+ appState
432
+ };
433
+ if (files) {
434
+ updateData.files = files;
435
+ }
436
+ await updateDrawing(id, updateData);
437
+ } catch (err) {
438
+ setError(err instanceof Error ? err.message : "Failed to save drawing");
439
+ }
440
+ }, []);
423
441
  const exportWorkspace = (0, import_react.useCallback)(async () => {
424
442
  try {
425
443
  const exportData = {
@@ -482,6 +500,70 @@ function WorkspaceProvider({ children, lang = "en" }) {
482
500
  setError(err instanceof Error ? err.message : "Failed to import workspace");
483
501
  }
484
502
  }, [workspace, t]);
503
+ const exportDrawingAsExcalidraw = (0, import_react.useCallback)(async (id) => {
504
+ try {
505
+ const drawing = drawings.find((d) => d.id === id) || await getDrawing(id);
506
+ if (!drawing) return;
507
+ const excalidrawData = {
508
+ type: "excalidraw",
509
+ version: 2,
510
+ source: "rita-workspace",
511
+ elements: drawing.elements || [],
512
+ appState: {
513
+ viewBackgroundColor: "#ffffff",
514
+ ...drawing.appState || {}
515
+ },
516
+ files: drawing.files || {}
517
+ };
518
+ const blob = new Blob([JSON.stringify(excalidrawData, null, 2)], { type: "application/json" });
519
+ const url = URL.createObjectURL(blob);
520
+ const a = document.createElement("a");
521
+ a.href = url;
522
+ a.download = `${drawing.name || "ritning"}.excalidraw`;
523
+ document.body.appendChild(a);
524
+ a.click();
525
+ document.body.removeChild(a);
526
+ URL.revokeObjectURL(url);
527
+ } catch (err) {
528
+ setError(err instanceof Error ? err.message : "Failed to export drawing");
529
+ }
530
+ }, [drawings]);
531
+ const importExcalidrawFile = (0, import_react.useCallback)(async () => {
532
+ if (!workspace) return;
533
+ try {
534
+ const input = document.createElement("input");
535
+ input.type = "file";
536
+ input.accept = ".excalidraw,.excalidraw.json,.json";
537
+ input.multiple = true;
538
+ const files = await new Promise((resolve) => {
539
+ input.onchange = () => resolve(input.files);
540
+ input.click();
541
+ });
542
+ if (!files || files.length === 0) return;
543
+ for (const file of Array.from(files)) {
544
+ const text = await file.text();
545
+ const data = JSON.parse(text);
546
+ if (!data.elements && !data.type) {
547
+ continue;
548
+ }
549
+ const name = file.name.replace(/\.(excalidraw|json)$/gi, "") || t.newDrawing;
550
+ const drawing = await createDrawing(name);
551
+ await updateDrawing(drawing.id, {
552
+ elements: data.elements || [],
553
+ appState: data.appState || {},
554
+ files: data.files || {}
555
+ });
556
+ await addDrawingToWorkspace(workspace.id, drawing.id);
557
+ }
558
+ const allDrawings = await getAllDrawings();
559
+ const ws = await getOrCreateDefaultWorkspace();
560
+ const wsDrawings = allDrawings.filter((dr) => ws.drawingIds.includes(dr.id));
561
+ setWorkspace(ws);
562
+ setDrawings(wsDrawings);
563
+ } catch (err) {
564
+ setError(err instanceof Error ? err.message : "Failed to import drawing");
565
+ }
566
+ }, [workspace, t]);
485
567
  const value = {
486
568
  workspace,
487
569
  drawings,
@@ -496,8 +578,11 @@ function WorkspaceProvider({ children, lang = "en" }) {
496
578
  removeDrawing,
497
579
  duplicateCurrentDrawing,
498
580
  saveCurrentDrawing,
581
+ saveDrawingById,
499
582
  exportWorkspace,
500
- importWorkspace
583
+ importWorkspace,
584
+ exportDrawingAsExcalidraw,
585
+ importExcalidrawFile
501
586
  };
502
587
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WorkspaceContext.Provider, { value, children });
503
588
  }
@@ -823,6 +908,8 @@ var DrawingsDialog = ({
823
908
  removeDrawing,
824
909
  exportWorkspace,
825
910
  importWorkspace,
911
+ exportDrawingAsExcalidraw,
912
+ importExcalidrawFile,
826
913
  t: contextT,
827
914
  lang: contextLang
828
915
  } = useWorkspace();
@@ -922,12 +1009,7 @@ var DrawingsDialog = ({
922
1009
  justifyContent: "space-between"
923
1010
  },
924
1011
  children: [
925
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: [
926
- t.dialogTitle,
927
- " (",
928
- drawings.length,
929
- ")"
930
- ] }),
1012
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: t.dialogTitle }),
931
1013
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
932
1014
  "button",
933
1015
  {
@@ -1119,6 +1201,23 @@ var DrawingsDialog = ({
1119
1201
  children: t.open
1120
1202
  }
1121
1203
  ),
1204
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1205
+ "button",
1206
+ {
1207
+ onClick: () => exportDrawingAsExcalidraw(drawing.id),
1208
+ style: {
1209
+ padding: "6px 12px",
1210
+ fontSize: "12px",
1211
+ backgroundColor: "transparent",
1212
+ border: "1px solid var(--default-border-color, #ccc)",
1213
+ borderRadius: "4px",
1214
+ cursor: "pointer",
1215
+ color: "inherit"
1216
+ },
1217
+ title: t.exportDrawing,
1218
+ children: "\u{1F4BE}"
1219
+ }
1220
+ ),
1122
1221
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1123
1222
  "button",
1124
1223
  {
@@ -1193,6 +1292,25 @@ var DrawingsDialog = ({
1193
1292
  ]
1194
1293
  }
1195
1294
  ),
1295
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1296
+ "button",
1297
+ {
1298
+ onClick: importExcalidrawFile,
1299
+ style: {
1300
+ padding: "10px 20px",
1301
+ fontSize: "14px",
1302
+ backgroundColor: "transparent",
1303
+ border: "1px solid var(--default-border-color, #ccc)",
1304
+ borderRadius: "6px",
1305
+ cursor: "pointer",
1306
+ color: "inherit"
1307
+ },
1308
+ children: [
1309
+ "\u{1F4C2} ",
1310
+ t.importDrawing
1311
+ ]
1312
+ }
1313
+ ),
1196
1314
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1197
1315
  "button",
1198
1316
  {
package/dist/index.mjs CHANGED
@@ -168,8 +168,10 @@ var sv = {
168
168
  modified: "\xC4ndrad",
169
169
  confirmDelete: "Vill du ta bort denna ritning?",
170
170
  // Export/Import
171
- exportWorkspace: "Exportera",
172
- importWorkspace: "Importera",
171
+ exportWorkspace: "Exportera arbetsyta",
172
+ importWorkspace: "Importera arbetsyta",
173
+ exportDrawing: "Spara som .excalidraw",
174
+ importDrawing: "\xD6ppna .excalidraw",
173
175
  // Shortcuts
174
176
  shortcutNewDrawing: "Ctrl+Alt+N"
175
177
  };
@@ -193,8 +195,10 @@ var en = {
193
195
  modified: "Modified",
194
196
  confirmDelete: "Do you want to delete this drawing?",
195
197
  // Export/Import
196
- exportWorkspace: "Export",
197
- importWorkspace: "Import",
198
+ exportWorkspace: "Export workspace",
199
+ importWorkspace: "Import workspace",
200
+ exportDrawing: "Save as .excalidraw",
201
+ importDrawing: "Open .excalidraw",
198
202
  // Shortcuts
199
203
  shortcutNewDrawing: "Ctrl+Alt+N"
200
204
  };
@@ -358,6 +362,20 @@ function WorkspaceProvider({ children, lang = "en" }) {
358
362
  setError(err instanceof Error ? err.message : "Failed to save drawing");
359
363
  }
360
364
  }, [activeDrawing]);
365
+ const saveDrawingById = useCallback(async (id, elements, appState, files) => {
366
+ try {
367
+ const updateData = {
368
+ elements,
369
+ appState
370
+ };
371
+ if (files) {
372
+ updateData.files = files;
373
+ }
374
+ await updateDrawing(id, updateData);
375
+ } catch (err) {
376
+ setError(err instanceof Error ? err.message : "Failed to save drawing");
377
+ }
378
+ }, []);
361
379
  const exportWorkspace = useCallback(async () => {
362
380
  try {
363
381
  const exportData = {
@@ -420,6 +438,70 @@ function WorkspaceProvider({ children, lang = "en" }) {
420
438
  setError(err instanceof Error ? err.message : "Failed to import workspace");
421
439
  }
422
440
  }, [workspace, t]);
441
+ const exportDrawingAsExcalidraw = useCallback(async (id) => {
442
+ try {
443
+ const drawing = drawings.find((d) => d.id === id) || await getDrawing(id);
444
+ if (!drawing) return;
445
+ const excalidrawData = {
446
+ type: "excalidraw",
447
+ version: 2,
448
+ source: "rita-workspace",
449
+ elements: drawing.elements || [],
450
+ appState: {
451
+ viewBackgroundColor: "#ffffff",
452
+ ...drawing.appState || {}
453
+ },
454
+ files: drawing.files || {}
455
+ };
456
+ const blob = new Blob([JSON.stringify(excalidrawData, null, 2)], { type: "application/json" });
457
+ const url = URL.createObjectURL(blob);
458
+ const a = document.createElement("a");
459
+ a.href = url;
460
+ a.download = `${drawing.name || "ritning"}.excalidraw`;
461
+ document.body.appendChild(a);
462
+ a.click();
463
+ document.body.removeChild(a);
464
+ URL.revokeObjectURL(url);
465
+ } catch (err) {
466
+ setError(err instanceof Error ? err.message : "Failed to export drawing");
467
+ }
468
+ }, [drawings]);
469
+ const importExcalidrawFile = useCallback(async () => {
470
+ if (!workspace) return;
471
+ try {
472
+ const input = document.createElement("input");
473
+ input.type = "file";
474
+ input.accept = ".excalidraw,.excalidraw.json,.json";
475
+ input.multiple = true;
476
+ const files = await new Promise((resolve) => {
477
+ input.onchange = () => resolve(input.files);
478
+ input.click();
479
+ });
480
+ if (!files || files.length === 0) return;
481
+ for (const file of Array.from(files)) {
482
+ const text = await file.text();
483
+ const data = JSON.parse(text);
484
+ if (!data.elements && !data.type) {
485
+ continue;
486
+ }
487
+ const name = file.name.replace(/\.(excalidraw|json)$/gi, "") || t.newDrawing;
488
+ const drawing = await createDrawing(name);
489
+ await updateDrawing(drawing.id, {
490
+ elements: data.elements || [],
491
+ appState: data.appState || {},
492
+ files: data.files || {}
493
+ });
494
+ await addDrawingToWorkspace(workspace.id, drawing.id);
495
+ }
496
+ const allDrawings = await getAllDrawings();
497
+ const ws = await getOrCreateDefaultWorkspace();
498
+ const wsDrawings = allDrawings.filter((dr) => ws.drawingIds.includes(dr.id));
499
+ setWorkspace(ws);
500
+ setDrawings(wsDrawings);
501
+ } catch (err) {
502
+ setError(err instanceof Error ? err.message : "Failed to import drawing");
503
+ }
504
+ }, [workspace, t]);
423
505
  const value = {
424
506
  workspace,
425
507
  drawings,
@@ -434,8 +516,11 @@ function WorkspaceProvider({ children, lang = "en" }) {
434
516
  removeDrawing,
435
517
  duplicateCurrentDrawing,
436
518
  saveCurrentDrawing,
519
+ saveDrawingById,
437
520
  exportWorkspace,
438
- importWorkspace
521
+ importWorkspace,
522
+ exportDrawingAsExcalidraw,
523
+ importExcalidrawFile
439
524
  };
440
525
  return /* @__PURE__ */ jsx(WorkspaceContext.Provider, { value, children });
441
526
  }
@@ -761,6 +846,8 @@ var DrawingsDialog = ({
761
846
  removeDrawing,
762
847
  exportWorkspace,
763
848
  importWorkspace,
849
+ exportDrawingAsExcalidraw,
850
+ importExcalidrawFile,
764
851
  t: contextT,
765
852
  lang: contextLang
766
853
  } = useWorkspace();
@@ -860,12 +947,7 @@ var DrawingsDialog = ({
860
947
  justifyContent: "space-between"
861
948
  },
862
949
  children: [
863
- /* @__PURE__ */ jsxs4("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: [
864
- t.dialogTitle,
865
- " (",
866
- drawings.length,
867
- ")"
868
- ] }),
950
+ /* @__PURE__ */ jsx6("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: t.dialogTitle }),
869
951
  /* @__PURE__ */ jsx6(
870
952
  "button",
871
953
  {
@@ -1057,6 +1139,23 @@ var DrawingsDialog = ({
1057
1139
  children: t.open
1058
1140
  }
1059
1141
  ),
1142
+ /* @__PURE__ */ jsx6(
1143
+ "button",
1144
+ {
1145
+ onClick: () => exportDrawingAsExcalidraw(drawing.id),
1146
+ style: {
1147
+ padding: "6px 12px",
1148
+ fontSize: "12px",
1149
+ backgroundColor: "transparent",
1150
+ border: "1px solid var(--default-border-color, #ccc)",
1151
+ borderRadius: "4px",
1152
+ cursor: "pointer",
1153
+ color: "inherit"
1154
+ },
1155
+ title: t.exportDrawing,
1156
+ children: "\u{1F4BE}"
1157
+ }
1158
+ ),
1060
1159
  /* @__PURE__ */ jsx6(
1061
1160
  "button",
1062
1161
  {
@@ -1131,6 +1230,25 @@ var DrawingsDialog = ({
1131
1230
  ]
1132
1231
  }
1133
1232
  ),
1233
+ /* @__PURE__ */ jsxs4(
1234
+ "button",
1235
+ {
1236
+ onClick: importExcalidrawFile,
1237
+ style: {
1238
+ padding: "10px 20px",
1239
+ fontSize: "14px",
1240
+ backgroundColor: "transparent",
1241
+ border: "1px solid var(--default-border-color, #ccc)",
1242
+ borderRadius: "6px",
1243
+ cursor: "pointer",
1244
+ color: "inherit"
1245
+ },
1246
+ children: [
1247
+ "\u{1F4C2} ",
1248
+ t.importDrawing
1249
+ ]
1250
+ }
1251
+ ),
1134
1252
  /* @__PURE__ */ jsxs4(
1135
1253
  "button",
1136
1254
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rita-workspace",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Multi-drawing workspace feature for Rita (Excalidraw fork)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",