rita-workspace 0.5.23 → 0.5.25

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 CHANGED
@@ -8,10 +8,13 @@ Multi-drawing workspace feature for Rita (Excalidraw fork based on B310-digital/
8
8
  - **Folders** - Organize drawings in folders
9
9
  - **Auto-save** - All drawings saved locally in IndexedDB
10
10
  - **Multi-tab conflict detection** - Prevents data loss when same drawing is open in multiple tabs
11
+ - **F5 preserves write ownership** - TAB_ID and openedAt persist in sessionStorage across page refresh
12
+ - **Cross-tab refresh** - Creating/renaming/deleting drawings in one tab auto-refreshes other tabs via BroadcastChannel
11
13
  - **Workspace toggle** - Preview feature that can be enabled/disabled per browser tab
12
- - **Export/Import** - Export workspace as JSON, import `.excalidraw` files
14
+ - **Export/Import** - Export workspace as JSON, export all drawings as individual .excalidraw files, import .excalidraw files
13
15
  - **i18n support** - Swedish and English with automatic Excalidraw language sync
14
16
  - **Optimized loading** - DB pre-warming and parallel initialization
17
+ - **Smart drawing naming** - counts drawings from IndexedDB to avoid duplicate names across tabs
15
18
 
16
19
  ## Installation
17
20
 
@@ -160,7 +163,7 @@ const {
160
163
  t, // Translations
161
164
 
162
165
  // Drawing actions
163
- createNewDrawing, // (name?, folderId?) => Promise<Drawing | null>
166
+ createNewDrawing, // (name?, folderId?, activate=true) => Promise<Drawing | null>
164
167
  switchDrawing, // (id) => Promise<void>
165
168
  renameDrawing, // (id, name) => Promise<void>
166
169
  removeDrawing, // (id) => Promise<void>
@@ -181,6 +184,7 @@ const {
181
184
  exportWorkspace, // () => Promise<void>
182
185
  importWorkspace, // () => Promise<void>
183
186
  exportDrawingAsExcalidraw, // (id) => Promise<void>
187
+ exportAllDrawingsAsExcalidraw, // () => Promise<void> — downloads all as .excalidraw files
184
188
  importExcalidrawFile, // () => Promise<void>
185
189
  } = useWorkspace();
186
190
  ```
package/dist/index.js CHANGED
@@ -501,10 +501,6 @@ function setTabDrawing(drawingId) {
501
501
  }
502
502
  } else {
503
503
  delete tabs[TAB_ID];
504
- try {
505
- sessionStorage.removeItem(TAB_ENTRY_KEY);
506
- } catch {
507
- }
508
504
  }
509
505
  const json = JSON.stringify(tabs);
510
506
  localStorage.setItem(TABS_KEY, json);
@@ -748,7 +744,14 @@ function WorkspaceProvider({ children, lang = "en" }) {
748
744
  const drawingIds = freshWorkspace?.drawingIds || workspace.drawingIds;
749
745
  const wsDrawings = allDrawings.filter((d) => drawingIds.includes(d.id));
750
746
  if (freshWorkspace) {
751
- setWorkspace((prev) => prev ? { ...freshWorkspace, activeDrawingId: prev.activeDrawingId } : freshWorkspace);
747
+ setWorkspace((prev) => {
748
+ if (!prev) return freshWorkspace;
749
+ const idsEqual = prev.drawingIds.length === freshWorkspace.drawingIds.length && prev.drawingIds.every((id, i) => id === freshWorkspace.drawingIds[i]);
750
+ if (idsEqual && prev.name === freshWorkspace.name) {
751
+ return prev;
752
+ }
753
+ return { ...freshWorkspace, activeDrawingId: prev.activeDrawingId };
754
+ });
752
755
  }
753
756
  setDrawings(wsDrawings);
754
757
  setFolders(allFolders);
@@ -2142,7 +2145,27 @@ var DrawingsDialog = ({
2142
2145
  borderBottom: "1px solid var(--default-border-color, #e0e0e0)"
2143
2146
  },
2144
2147
  children: [
2145
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: t.dialogTitle }),
2148
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600, display: "flex", alignItems: "center", gap: "8px" }, children: [
2149
+ t.dialogTitle,
2150
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2151
+ "span",
2152
+ {
2153
+ style: {
2154
+ fontSize: "10px",
2155
+ fontWeight: 700,
2156
+ letterSpacing: "0.5px",
2157
+ padding: "2px 8px",
2158
+ borderRadius: "10px",
2159
+ backgroundColor: "#fff3cd",
2160
+ color: "#856404",
2161
+ border: "1px solid #ffc107",
2162
+ textTransform: "uppercase"
2163
+ },
2164
+ title: "F\xF6rhandsvisning \u2014 funktionen \xE4r under utveckling och kan \xE4ndras",
2165
+ children: "BETA"
2166
+ }
2167
+ )
2168
+ ] }),
2146
2169
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2147
2170
  "button",
2148
2171
  {
@@ -2163,6 +2186,28 @@ var DrawingsDialog = ({
2163
2186
  ]
2164
2187
  }
2165
2188
  ),
2189
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2190
+ "div",
2191
+ {
2192
+ style: {
2193
+ padding: "8px 20px",
2194
+ backgroundColor: "#fff3cd",
2195
+ color: "#856404",
2196
+ fontSize: "12px",
2197
+ borderBottom: "1px solid #ffc107",
2198
+ display: "flex",
2199
+ alignItems: "center",
2200
+ gap: "8px"
2201
+ },
2202
+ children: [
2203
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u26A0\uFE0F" }),
2204
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
2205
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "F\xF6rhandsvisning:" }),
2206
+ ' Arbetsyta \xE4r under utveckling. Ta regelbundet backup via "Spara alla ritningar".'
2207
+ ] })
2208
+ ]
2209
+ }
2210
+ ),
2166
2211
  drawings.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { padding: "8px 20px", borderBottom: "1px solid var(--default-border-color, #e0e0e0)" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2167
2212
  "input",
2168
2213
  {
package/dist/index.mjs CHANGED
@@ -430,10 +430,6 @@ function setTabDrawing(drawingId) {
430
430
  }
431
431
  } else {
432
432
  delete tabs[TAB_ID];
433
- try {
434
- sessionStorage.removeItem(TAB_ENTRY_KEY);
435
- } catch {
436
- }
437
433
  }
438
434
  const json = JSON.stringify(tabs);
439
435
  localStorage.setItem(TABS_KEY, json);
@@ -677,7 +673,14 @@ function WorkspaceProvider({ children, lang = "en" }) {
677
673
  const drawingIds = freshWorkspace?.drawingIds || workspace.drawingIds;
678
674
  const wsDrawings = allDrawings.filter((d) => drawingIds.includes(d.id));
679
675
  if (freshWorkspace) {
680
- setWorkspace((prev) => prev ? { ...freshWorkspace, activeDrawingId: prev.activeDrawingId } : freshWorkspace);
676
+ setWorkspace((prev) => {
677
+ if (!prev) return freshWorkspace;
678
+ const idsEqual = prev.drawingIds.length === freshWorkspace.drawingIds.length && prev.drawingIds.every((id, i) => id === freshWorkspace.drawingIds[i]);
679
+ if (idsEqual && prev.name === freshWorkspace.name) {
680
+ return prev;
681
+ }
682
+ return { ...freshWorkspace, activeDrawingId: prev.activeDrawingId };
683
+ });
681
684
  }
682
685
  setDrawings(wsDrawings);
683
686
  setFolders(allFolders);
@@ -2071,7 +2074,27 @@ var DrawingsDialog = ({
2071
2074
  borderBottom: "1px solid var(--default-border-color, #e0e0e0)"
2072
2075
  },
2073
2076
  children: [
2074
- /* @__PURE__ */ jsx6("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: t.dialogTitle }),
2077
+ /* @__PURE__ */ jsxs4("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600, display: "flex", alignItems: "center", gap: "8px" }, children: [
2078
+ t.dialogTitle,
2079
+ /* @__PURE__ */ jsx6(
2080
+ "span",
2081
+ {
2082
+ style: {
2083
+ fontSize: "10px",
2084
+ fontWeight: 700,
2085
+ letterSpacing: "0.5px",
2086
+ padding: "2px 8px",
2087
+ borderRadius: "10px",
2088
+ backgroundColor: "#fff3cd",
2089
+ color: "#856404",
2090
+ border: "1px solid #ffc107",
2091
+ textTransform: "uppercase"
2092
+ },
2093
+ title: "F\xF6rhandsvisning \u2014 funktionen \xE4r under utveckling och kan \xE4ndras",
2094
+ children: "BETA"
2095
+ }
2096
+ )
2097
+ ] }),
2075
2098
  /* @__PURE__ */ jsx6(
2076
2099
  "button",
2077
2100
  {
@@ -2092,6 +2115,28 @@ var DrawingsDialog = ({
2092
2115
  ]
2093
2116
  }
2094
2117
  ),
2118
+ /* @__PURE__ */ jsxs4(
2119
+ "div",
2120
+ {
2121
+ style: {
2122
+ padding: "8px 20px",
2123
+ backgroundColor: "#fff3cd",
2124
+ color: "#856404",
2125
+ fontSize: "12px",
2126
+ borderBottom: "1px solid #ffc107",
2127
+ display: "flex",
2128
+ alignItems: "center",
2129
+ gap: "8px"
2130
+ },
2131
+ children: [
2132
+ /* @__PURE__ */ jsx6("span", { children: "\u26A0\uFE0F" }),
2133
+ /* @__PURE__ */ jsxs4("span", { children: [
2134
+ /* @__PURE__ */ jsx6("strong", { children: "F\xF6rhandsvisning:" }),
2135
+ ' Arbetsyta \xE4r under utveckling. Ta regelbundet backup via "Spara alla ritningar".'
2136
+ ] })
2137
+ ]
2138
+ }
2139
+ ),
2095
2140
  drawings.length > 3 && /* @__PURE__ */ jsx6("div", { style: { padding: "8px 20px", borderBottom: "1px solid var(--default-border-color, #e0e0e0)" }, children: /* @__PURE__ */ jsx6(
2096
2141
  "input",
2097
2142
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rita-workspace",
3
- "version": "0.5.23",
3
+ "version": "0.5.25",
4
4
  "description": "Multi-drawing workspace feature for Rita (Excalidraw fork)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",