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 +6 -2
- package/dist/index.js +51 -6
- package/dist/index.mjs +51 -6
- package/package.json +1 -1
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
|
|
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
|
|
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) =>
|
|
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.
|
|
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) =>
|
|
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__ */
|
|
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
|
{
|