rita-workspace 0.5.0 → 0.5.1
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 +36 -3
- package/dist/index.d.ts +36 -3
- package/dist/index.js +614 -184
- package/dist/index.mjs +608 -184
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/storage/db.ts
|
|
2
2
|
import { openDB } from "idb";
|
|
3
3
|
var DB_NAME = "rita-workspace";
|
|
4
|
-
var DB_VERSION =
|
|
4
|
+
var DB_VERSION = 2;
|
|
5
5
|
var dbInstance = null;
|
|
6
6
|
async function getDB() {
|
|
7
7
|
if (dbInstance) return dbInstance;
|
|
8
8
|
dbInstance = await openDB(DB_NAME, DB_VERSION, {
|
|
9
|
-
upgrade(db) {
|
|
9
|
+
upgrade(db, oldVersion) {
|
|
10
10
|
if (!db.objectStoreNames.contains("workspaces")) {
|
|
11
11
|
const workspaceStore = db.createObjectStore("workspaces", { keyPath: "id" });
|
|
12
12
|
workspaceStore.createIndex("by-updated", "updatedAt");
|
|
@@ -15,6 +15,10 @@ async function getDB() {
|
|
|
15
15
|
const drawingStore = db.createObjectStore("drawings", { keyPath: "id" });
|
|
16
16
|
drawingStore.createIndex("by-updated", "updatedAt");
|
|
17
17
|
}
|
|
18
|
+
if (oldVersion < 2) {
|
|
19
|
+
const folderStore = db.createObjectStore("folders", { keyPath: "id" });
|
|
20
|
+
folderStore.createIndex("by-name", "name");
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
23
|
});
|
|
20
24
|
return dbInstance;
|
|
@@ -28,12 +32,13 @@ async function closeDB() {
|
|
|
28
32
|
|
|
29
33
|
// src/storage/drawingStore.ts
|
|
30
34
|
import { nanoid } from "nanoid";
|
|
31
|
-
async function createDrawing(name = "Untitled", elements = [], appState = {}) {
|
|
35
|
+
async function createDrawing(name = "Untitled", elements = [], appState = {}, folderId) {
|
|
32
36
|
const db = await getDB();
|
|
33
37
|
const now = Date.now();
|
|
34
38
|
const drawing = {
|
|
35
39
|
id: nanoid(),
|
|
36
40
|
name,
|
|
41
|
+
folderId: folderId || null,
|
|
37
42
|
elements,
|
|
38
43
|
appState,
|
|
39
44
|
files: {},
|
|
@@ -76,9 +81,62 @@ async function duplicateDrawing(id, newName) {
|
|
|
76
81
|
return createDrawing(
|
|
77
82
|
newName || `${existing.name} (copy)`,
|
|
78
83
|
existing.elements,
|
|
79
|
-
existing.appState
|
|
84
|
+
existing.appState,
|
|
85
|
+
existing.folderId
|
|
80
86
|
);
|
|
81
87
|
}
|
|
88
|
+
async function moveDrawingToFolder(drawingId, folderId) {
|
|
89
|
+
return updateDrawing(drawingId, { folderId });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/storage/folderStore.ts
|
|
93
|
+
import { nanoid as nanoid2 } from "nanoid";
|
|
94
|
+
async function createFolder(name) {
|
|
95
|
+
const db = await getDB();
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const folder = {
|
|
98
|
+
id: nanoid2(),
|
|
99
|
+
name,
|
|
100
|
+
createdAt: now,
|
|
101
|
+
updatedAt: now
|
|
102
|
+
};
|
|
103
|
+
await db.put("folders", folder);
|
|
104
|
+
return folder;
|
|
105
|
+
}
|
|
106
|
+
async function getFolder(id) {
|
|
107
|
+
const db = await getDB();
|
|
108
|
+
return db.get("folders", id);
|
|
109
|
+
}
|
|
110
|
+
async function getAllFolders() {
|
|
111
|
+
const db = await getDB();
|
|
112
|
+
return db.getAllFromIndex("folders", "by-name");
|
|
113
|
+
}
|
|
114
|
+
async function renameFolder(id, name) {
|
|
115
|
+
const db = await getDB();
|
|
116
|
+
const existing = await db.get("folders", id);
|
|
117
|
+
if (!existing) return void 0;
|
|
118
|
+
const updated = {
|
|
119
|
+
...existing,
|
|
120
|
+
name,
|
|
121
|
+
updatedAt: Date.now()
|
|
122
|
+
};
|
|
123
|
+
await db.put("folders", updated);
|
|
124
|
+
return updated;
|
|
125
|
+
}
|
|
126
|
+
async function deleteFolder(id) {
|
|
127
|
+
const db = await getDB();
|
|
128
|
+
const allDrawings = await db.getAll("drawings");
|
|
129
|
+
const tx = db.transaction(["drawings", "folders"], "readwrite");
|
|
130
|
+
for (const drawing of allDrawings) {
|
|
131
|
+
if (drawing.folderId === id) {
|
|
132
|
+
drawing.folderId = null;
|
|
133
|
+
drawing.updatedAt = Date.now();
|
|
134
|
+
await tx.objectStore("drawings").put(drawing);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
await tx.objectStore("folders").delete(id);
|
|
138
|
+
await tx.done;
|
|
139
|
+
}
|
|
82
140
|
|
|
83
141
|
// src/storage/workspaceStore.ts
|
|
84
142
|
var DEFAULT_WORKSPACE_ID = "default";
|
|
@@ -184,6 +242,14 @@ var sv = {
|
|
|
184
242
|
importWorkspace: "Importera arbetsyta",
|
|
185
243
|
exportDrawing: "Spara som .excalidraw",
|
|
186
244
|
importDrawing: "\xD6ppna .excalidraw",
|
|
245
|
+
// Folders
|
|
246
|
+
createFolder: "Skapa mapp",
|
|
247
|
+
renameFolder: "Byt namn p\xE5 mapp",
|
|
248
|
+
deleteFolder: "Ta bort mapp",
|
|
249
|
+
deleteFolderConfirm: "Vill du ta bort denna mapp? Ritningarna flyttas till rotniv\xE5n.",
|
|
250
|
+
moveToFolder: "Flytta till mapp",
|
|
251
|
+
moveToRoot: "Ingen mapp",
|
|
252
|
+
newFolderName: "Ny mapp",
|
|
187
253
|
// Shortcuts
|
|
188
254
|
shortcutNewDrawing: "Ctrl+Alt+N"
|
|
189
255
|
};
|
|
@@ -223,6 +289,14 @@ var en = {
|
|
|
223
289
|
importWorkspace: "Import workspace",
|
|
224
290
|
exportDrawing: "Save as .excalidraw",
|
|
225
291
|
importDrawing: "Open .excalidraw",
|
|
292
|
+
// Folders
|
|
293
|
+
createFolder: "Create folder",
|
|
294
|
+
renameFolder: "Rename folder",
|
|
295
|
+
deleteFolder: "Delete folder",
|
|
296
|
+
deleteFolderConfirm: "Delete this folder? Drawings will be moved to root.",
|
|
297
|
+
moveToFolder: "Move to folder",
|
|
298
|
+
moveToRoot: "No folder",
|
|
299
|
+
newFolderName: "New folder",
|
|
226
300
|
// Shortcuts
|
|
227
301
|
shortcutNewDrawing: "Ctrl+Alt+N"
|
|
228
302
|
};
|
|
@@ -305,6 +379,7 @@ function isDrawingOpenedEarlierInOtherTab(drawingId) {
|
|
|
305
379
|
function WorkspaceProvider({ children, lang = "en" }) {
|
|
306
380
|
const [workspace, setWorkspace] = useState(null);
|
|
307
381
|
const [drawings, setDrawings] = useState([]);
|
|
382
|
+
const [folders, setFolders] = useState([]);
|
|
308
383
|
const [activeDrawing, setActiveDrawing2] = useState(null);
|
|
309
384
|
const [isLoading, setIsLoading] = useState(true);
|
|
310
385
|
const [error, setError] = useState(null);
|
|
@@ -380,6 +455,8 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
380
455
|
const allDrawings = await getAllDrawings();
|
|
381
456
|
const wsDrawings = allDrawings.filter((d) => ws.drawingIds.includes(d.id));
|
|
382
457
|
setDrawings(wsDrawings);
|
|
458
|
+
const allFolders = await getAllFolders();
|
|
459
|
+
setFolders(allFolders);
|
|
383
460
|
const lastDrawingId = sessionStorage.getItem("rita-workspace-tab-drawing");
|
|
384
461
|
let active = null;
|
|
385
462
|
if (lastDrawingId) {
|
|
@@ -412,14 +489,16 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
412
489
|
const allDrawings = await getAllDrawings();
|
|
413
490
|
const wsDrawings = allDrawings.filter((d) => workspace.drawingIds.includes(d.id));
|
|
414
491
|
setDrawings(wsDrawings);
|
|
492
|
+
const allFolders = await getAllFolders();
|
|
493
|
+
setFolders(allFolders);
|
|
415
494
|
} catch (err) {
|
|
416
495
|
}
|
|
417
496
|
}, [workspace]);
|
|
418
|
-
const createNewDrawing = useCallback(async (name) => {
|
|
497
|
+
const createNewDrawing = useCallback(async (name, folderId) => {
|
|
419
498
|
if (!workspace) return null;
|
|
420
499
|
try {
|
|
421
500
|
const defaultName = `${t.newDrawing} ${drawings.length + 1}`;
|
|
422
|
-
const drawing = await createDrawing(name || defaultName);
|
|
501
|
+
const drawing = await createDrawing(name || defaultName, [], {}, folderId);
|
|
423
502
|
await addDrawingToWorkspace(workspace.id, drawing.id);
|
|
424
503
|
setDrawings((prev) => [...prev, drawing]);
|
|
425
504
|
setActiveDrawing2(drawing);
|
|
@@ -652,9 +731,52 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
652
731
|
setError(err instanceof Error ? err.message : "Failed to import drawing");
|
|
653
732
|
}
|
|
654
733
|
}, [workspace, t]);
|
|
734
|
+
const createFolder2 = useCallback(async (name) => {
|
|
735
|
+
try {
|
|
736
|
+
const folder = await createFolder(name);
|
|
737
|
+
setFolders((prev) => [...prev, folder]);
|
|
738
|
+
return folder;
|
|
739
|
+
} catch (err) {
|
|
740
|
+
setError(err instanceof Error ? err.message : "Failed to create folder");
|
|
741
|
+
return null;
|
|
742
|
+
}
|
|
743
|
+
}, []);
|
|
744
|
+
const renameFolder2 = useCallback(async (id, name) => {
|
|
745
|
+
try {
|
|
746
|
+
const updated = await renameFolder(id, name);
|
|
747
|
+
if (updated) {
|
|
748
|
+
setFolders((prev) => prev.map((f) => f.id === id ? updated : f));
|
|
749
|
+
}
|
|
750
|
+
} catch (err) {
|
|
751
|
+
setError(err instanceof Error ? err.message : "Failed to rename folder");
|
|
752
|
+
}
|
|
753
|
+
}, []);
|
|
754
|
+
const deleteFolder2 = useCallback(async (id) => {
|
|
755
|
+
try {
|
|
756
|
+
await deleteFolder(id);
|
|
757
|
+
setFolders((prev) => prev.filter((f) => f.id !== id));
|
|
758
|
+
setDrawings((prev) => prev.map((d) => d.folderId === id ? { ...d, folderId: null } : d));
|
|
759
|
+
} catch (err) {
|
|
760
|
+
setError(err instanceof Error ? err.message : "Failed to delete folder");
|
|
761
|
+
}
|
|
762
|
+
}, []);
|
|
763
|
+
const moveDrawingToFolder2 = useCallback(async (drawingId, folderId) => {
|
|
764
|
+
try {
|
|
765
|
+
const updated = await moveDrawingToFolder(drawingId, folderId);
|
|
766
|
+
if (updated) {
|
|
767
|
+
setDrawings((prev) => prev.map((d) => d.id === drawingId ? updated : d));
|
|
768
|
+
if (activeDrawing?.id === drawingId) {
|
|
769
|
+
setActiveDrawing2(updated);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
} catch (err) {
|
|
773
|
+
setError(err instanceof Error ? err.message : "Failed to move drawing");
|
|
774
|
+
}
|
|
775
|
+
}, [activeDrawing]);
|
|
655
776
|
const value = {
|
|
656
777
|
workspace,
|
|
657
778
|
drawings,
|
|
779
|
+
folders,
|
|
658
780
|
activeDrawing,
|
|
659
781
|
isLoading,
|
|
660
782
|
error,
|
|
@@ -666,6 +788,10 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
666
788
|
renameDrawing,
|
|
667
789
|
removeDrawing,
|
|
668
790
|
duplicateCurrentDrawing,
|
|
791
|
+
createFolder: createFolder2,
|
|
792
|
+
renameFolder: renameFolder2,
|
|
793
|
+
deleteFolder: deleteFolder2,
|
|
794
|
+
moveDrawingToFolder: moveDrawingToFolder2,
|
|
669
795
|
saveCurrentDrawing,
|
|
670
796
|
saveDrawingById,
|
|
671
797
|
refreshDrawings,
|
|
@@ -1019,11 +1145,16 @@ var DrawingsDialog = ({
|
|
|
1019
1145
|
}) => {
|
|
1020
1146
|
const {
|
|
1021
1147
|
drawings,
|
|
1148
|
+
folders,
|
|
1022
1149
|
activeDrawing,
|
|
1023
1150
|
switchDrawing,
|
|
1024
1151
|
createNewDrawing,
|
|
1025
1152
|
renameDrawing,
|
|
1026
1153
|
removeDrawing,
|
|
1154
|
+
createFolder: createFolder2,
|
|
1155
|
+
renameFolder: renameFolder2,
|
|
1156
|
+
deleteFolder: deleteFolder2,
|
|
1157
|
+
moveDrawingToFolder: moveDrawingToFolder2,
|
|
1027
1158
|
exportWorkspace,
|
|
1028
1159
|
importWorkspace,
|
|
1029
1160
|
exportDrawingAsExcalidraw,
|
|
@@ -1037,21 +1168,39 @@ var DrawingsDialog = ({
|
|
|
1037
1168
|
const [editingId, setEditingId] = useState4(null);
|
|
1038
1169
|
const [editName, setEditName] = useState4("");
|
|
1039
1170
|
const [confirmDeleteId, setConfirmDeleteId] = useState4(null);
|
|
1171
|
+
const [switchingId, setSwitchingId] = useState4(null);
|
|
1172
|
+
const [expandedFolders, setExpandedFolders] = useState4(/* @__PURE__ */ new Set());
|
|
1173
|
+
const [creatingFolder, setCreatingFolder] = useState4(false);
|
|
1174
|
+
const [newFolderName, setNewFolderName] = useState4("");
|
|
1175
|
+
const [editingFolderId, setEditingFolderId] = useState4(null);
|
|
1176
|
+
const [editFolderName, setEditFolderName] = useState4("");
|
|
1177
|
+
const [confirmDeleteFolderId, setConfirmDeleteFolderId] = useState4(null);
|
|
1178
|
+
const [movingDrawingId, setMovingDrawingId] = useState4(null);
|
|
1179
|
+
const [searchQuery, setSearchQuery] = useState4("");
|
|
1040
1180
|
const [position, setPosition] = useState4(null);
|
|
1041
1181
|
const dragRef = useRef3(null);
|
|
1042
1182
|
const dialogRef = useRef3(null);
|
|
1183
|
+
const newFolderInputRef = useRef3(null);
|
|
1043
1184
|
const prevOpenRef = useRef3(false);
|
|
1044
1185
|
useEffect3(() => {
|
|
1045
1186
|
if (open) {
|
|
1046
1187
|
refreshDrawings();
|
|
1047
1188
|
if (!prevOpenRef.current) {
|
|
1048
1189
|
setPosition(null);
|
|
1190
|
+
setSearchQuery("");
|
|
1191
|
+
setExpandedFolders(new Set(folders.map((f) => f.id)));
|
|
1049
1192
|
}
|
|
1050
1193
|
}
|
|
1051
1194
|
prevOpenRef.current = open;
|
|
1052
|
-
}, [open, refreshDrawings]);
|
|
1195
|
+
}, [open, refreshDrawings, folders]);
|
|
1196
|
+
useEffect3(() => {
|
|
1197
|
+
if (creatingFolder && newFolderInputRef.current) {
|
|
1198
|
+
newFolderInputRef.current.focus();
|
|
1199
|
+
}
|
|
1200
|
+
}, [creatingFolder]);
|
|
1053
1201
|
const handleMouseDown = useCallback2((e) => {
|
|
1054
1202
|
if (e.target.closest("button")) return;
|
|
1203
|
+
if (e.target.closest("input")) return;
|
|
1055
1204
|
if (!dialogRef.current) return;
|
|
1056
1205
|
const rect = dialogRef.current.getBoundingClientRect();
|
|
1057
1206
|
const currentX = position?.x ?? rect.left;
|
|
@@ -1072,11 +1221,13 @@ var DrawingsDialog = ({
|
|
|
1072
1221
|
document.addEventListener("mouseup", handleMouseUp);
|
|
1073
1222
|
}, [position]);
|
|
1074
1223
|
const handleSelect = useCallback2(async (drawing) => {
|
|
1224
|
+
setSwitchingId(drawing.id);
|
|
1075
1225
|
await switchDrawing(drawing.id);
|
|
1076
1226
|
onDrawingSelect?.(drawing);
|
|
1227
|
+
setSwitchingId(null);
|
|
1077
1228
|
}, [switchDrawing, onDrawingSelect]);
|
|
1078
|
-
const handleCreate = useCallback2(async () => {
|
|
1079
|
-
const newDrawing = await createNewDrawing();
|
|
1229
|
+
const handleCreate = useCallback2(async (folderId) => {
|
|
1230
|
+
const newDrawing = await createNewDrawing(void 0, folderId);
|
|
1080
1231
|
if (newDrawing) onDrawingSelect?.(newDrawing);
|
|
1081
1232
|
}, [createNewDrawing, onDrawingSelect]);
|
|
1082
1233
|
const handleStartEdit = useCallback2((drawing) => {
|
|
@@ -1098,6 +1249,42 @@ var DrawingsDialog = ({
|
|
|
1098
1249
|
await removeDrawing(id);
|
|
1099
1250
|
setConfirmDeleteId(null);
|
|
1100
1251
|
}, [removeDrawing]);
|
|
1252
|
+
const handleCreateFolder = useCallback2(async () => {
|
|
1253
|
+
if (newFolderName.trim()) {
|
|
1254
|
+
const folder = await createFolder2(newFolderName.trim());
|
|
1255
|
+
if (folder) {
|
|
1256
|
+
setExpandedFolders((prev) => /* @__PURE__ */ new Set([...prev, folder.id]));
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
setCreatingFolder(false);
|
|
1260
|
+
setNewFolderName("");
|
|
1261
|
+
}, [newFolderName, createFolder2]);
|
|
1262
|
+
const handleSaveFolderEdit = useCallback2(async () => {
|
|
1263
|
+
if (editingFolderId && editFolderName.trim()) {
|
|
1264
|
+
await renameFolder2(editingFolderId, editFolderName.trim());
|
|
1265
|
+
}
|
|
1266
|
+
setEditingFolderId(null);
|
|
1267
|
+
setEditFolderName("");
|
|
1268
|
+
}, [editingFolderId, editFolderName, renameFolder2]);
|
|
1269
|
+
const handleDeleteFolder = useCallback2(async (id) => {
|
|
1270
|
+
await deleteFolder2(id);
|
|
1271
|
+
setConfirmDeleteFolderId(null);
|
|
1272
|
+
}, [deleteFolder2]);
|
|
1273
|
+
const handleMoveToFolder = useCallback2(async (drawingId, folderId) => {
|
|
1274
|
+
await moveDrawingToFolder2(drawingId, folderId);
|
|
1275
|
+
setMovingDrawingId(null);
|
|
1276
|
+
}, [moveDrawingToFolder2]);
|
|
1277
|
+
const toggleFolder = useCallback2((folderId) => {
|
|
1278
|
+
setExpandedFolders((prev) => {
|
|
1279
|
+
const next = new Set(prev);
|
|
1280
|
+
if (next.has(folderId)) {
|
|
1281
|
+
next.delete(folderId);
|
|
1282
|
+
} else {
|
|
1283
|
+
next.add(folderId);
|
|
1284
|
+
}
|
|
1285
|
+
return next;
|
|
1286
|
+
});
|
|
1287
|
+
}, []);
|
|
1101
1288
|
const getLocale = () => {
|
|
1102
1289
|
if (!effectiveLang) return "en-US";
|
|
1103
1290
|
const baseLang = effectiveLang.split("-")[0].toLowerCase();
|
|
@@ -1112,6 +1299,14 @@ var DrawingsDialog = ({
|
|
|
1112
1299
|
});
|
|
1113
1300
|
};
|
|
1114
1301
|
if (!open) return null;
|
|
1302
|
+
const query = searchQuery.toLowerCase().trim();
|
|
1303
|
+
const filteredDrawings = query ? drawings.filter((d) => d.name.toLowerCase().includes(query)) : drawings;
|
|
1304
|
+
const rootDrawings = filteredDrawings.filter((d) => !d.folderId);
|
|
1305
|
+
const drawingsByFolder = {};
|
|
1306
|
+
for (const folder of folders) {
|
|
1307
|
+
drawingsByFolder[folder.id] = filteredDrawings.filter((d) => d.folderId === folder.id);
|
|
1308
|
+
}
|
|
1309
|
+
const filteredFolders = query ? folders.filter((f) => f.name.toLowerCase().includes(query) || (drawingsByFolder[f.id] || []).length > 0) : folders;
|
|
1115
1310
|
const dialogStyle = position ? {
|
|
1116
1311
|
position: "fixed",
|
|
1117
1312
|
left: position.x,
|
|
@@ -1145,6 +1340,324 @@ var DrawingsDialog = ({
|
|
|
1145
1340
|
color: "var(--text-secondary-color, #888)",
|
|
1146
1341
|
padding: "16px 20px 8px"
|
|
1147
1342
|
};
|
|
1343
|
+
const renderDrawingRow = (drawing) => /* @__PURE__ */ jsxs4(
|
|
1344
|
+
"div",
|
|
1345
|
+
{
|
|
1346
|
+
onClick: () => {
|
|
1347
|
+
if (editingId || confirmDeleteId || switchingId || movingDrawingId) return;
|
|
1348
|
+
if (activeDrawing?.id !== drawing.id) handleSelect(drawing);
|
|
1349
|
+
},
|
|
1350
|
+
style: {
|
|
1351
|
+
padding: "10px 12px",
|
|
1352
|
+
display: "flex",
|
|
1353
|
+
alignItems: "center",
|
|
1354
|
+
gap: "12px",
|
|
1355
|
+
borderRadius: "8px",
|
|
1356
|
+
marginBottom: "4px",
|
|
1357
|
+
cursor: editingId || confirmDeleteId || switchingId ? "default" : "pointer",
|
|
1358
|
+
backgroundColor: activeDrawing?.id === drawing.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.1))" : "transparent",
|
|
1359
|
+
transition: "background-color 0.15s",
|
|
1360
|
+
opacity: switchingId && switchingId !== drawing.id ? 0.5 : 1
|
|
1361
|
+
},
|
|
1362
|
+
children: [
|
|
1363
|
+
renderThumbnail && /* @__PURE__ */ jsx6("div", { style: {
|
|
1364
|
+
width: "64px",
|
|
1365
|
+
height: "48px",
|
|
1366
|
+
flexShrink: 0,
|
|
1367
|
+
borderRadius: "4px",
|
|
1368
|
+
overflow: "hidden",
|
|
1369
|
+
border: "1px solid var(--default-border-color, #e0e0e0)",
|
|
1370
|
+
backgroundColor: "#fff",
|
|
1371
|
+
display: "flex",
|
|
1372
|
+
alignItems: "center",
|
|
1373
|
+
justifyContent: "center"
|
|
1374
|
+
}, children: renderThumbnail(drawing) }),
|
|
1375
|
+
/* @__PURE__ */ jsx6("div", { style: { flex: 1, minWidth: 0 }, children: editingId === drawing.id ? /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "6px", alignItems: "center" }, children: [
|
|
1376
|
+
/* @__PURE__ */ jsx6(
|
|
1377
|
+
"input",
|
|
1378
|
+
{
|
|
1379
|
+
type: "text",
|
|
1380
|
+
value: editName,
|
|
1381
|
+
onChange: (e) => setEditName(e.target.value),
|
|
1382
|
+
onKeyDown: (e) => {
|
|
1383
|
+
if (e.key === "Enter") handleSaveEdit();
|
|
1384
|
+
if (e.key === "Escape") handleCancelEdit();
|
|
1385
|
+
},
|
|
1386
|
+
onClick: (e) => e.stopPropagation(),
|
|
1387
|
+
autoFocus: true,
|
|
1388
|
+
style: {
|
|
1389
|
+
flex: 1,
|
|
1390
|
+
padding: "4px 8px",
|
|
1391
|
+
fontSize: "14px",
|
|
1392
|
+
border: "1px solid var(--color-primary, #6c63ff)",
|
|
1393
|
+
borderRadius: "4px",
|
|
1394
|
+
outline: "none"
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
),
|
|
1398
|
+
/* @__PURE__ */ jsx6(
|
|
1399
|
+
"button",
|
|
1400
|
+
{
|
|
1401
|
+
onClick: (e) => {
|
|
1402
|
+
e.stopPropagation();
|
|
1403
|
+
handleSaveEdit();
|
|
1404
|
+
},
|
|
1405
|
+
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "var(--color-primary, #6c63ff)", color: "#fff", border: "none", borderRadius: "4px", cursor: "pointer" },
|
|
1406
|
+
children: t.save
|
|
1407
|
+
}
|
|
1408
|
+
),
|
|
1409
|
+
/* @__PURE__ */ jsx6(
|
|
1410
|
+
"button",
|
|
1411
|
+
{
|
|
1412
|
+
onClick: (e) => {
|
|
1413
|
+
e.stopPropagation();
|
|
1414
|
+
handleCancelEdit();
|
|
1415
|
+
},
|
|
1416
|
+
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "transparent", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", color: "inherit" },
|
|
1417
|
+
children: t.cancel
|
|
1418
|
+
}
|
|
1419
|
+
)
|
|
1420
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1421
|
+
/* @__PURE__ */ jsxs4("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
|
|
1422
|
+
/* @__PURE__ */ jsxs4(
|
|
1423
|
+
"span",
|
|
1424
|
+
{
|
|
1425
|
+
onClick: (e) => {
|
|
1426
|
+
e.stopPropagation();
|
|
1427
|
+
handleStartEdit(drawing);
|
|
1428
|
+
},
|
|
1429
|
+
style: {
|
|
1430
|
+
fontWeight: activeDrawing?.id === drawing.id ? 600 : 400,
|
|
1431
|
+
fontSize: "14px",
|
|
1432
|
+
overflow: "hidden",
|
|
1433
|
+
textOverflow: "ellipsis",
|
|
1434
|
+
whiteSpace: "nowrap",
|
|
1435
|
+
cursor: "text"
|
|
1436
|
+
},
|
|
1437
|
+
title: t.rename,
|
|
1438
|
+
children: [
|
|
1439
|
+
switchingId === drawing.id ? /* @__PURE__ */ jsx6("span", { style: { display: "inline-block", animation: "spin 1s linear infinite", marginRight: "4px" }, children: "\u23F3" }) : activeDrawing?.id === drawing.id ? "\u2713 " : "",
|
|
1440
|
+
drawing.name
|
|
1441
|
+
]
|
|
1442
|
+
}
|
|
1443
|
+
),
|
|
1444
|
+
/* @__PURE__ */ jsx6(
|
|
1445
|
+
"button",
|
|
1446
|
+
{
|
|
1447
|
+
onClick: (e) => {
|
|
1448
|
+
e.stopPropagation();
|
|
1449
|
+
handleStartEdit(drawing);
|
|
1450
|
+
},
|
|
1451
|
+
style: { background: "none", border: "none", cursor: "pointer", padding: "0 2px", fontSize: "12px", opacity: 0.4, flexShrink: 0 },
|
|
1452
|
+
title: t.rename,
|
|
1453
|
+
children: "\u270F\uFE0F"
|
|
1454
|
+
}
|
|
1455
|
+
)
|
|
1456
|
+
] }),
|
|
1457
|
+
/* @__PURE__ */ jsxs4("div", { style: { fontSize: "11px", color: "var(--text-secondary-color, #888)", marginTop: "1px" }, children: [
|
|
1458
|
+
t.modified,
|
|
1459
|
+
": ",
|
|
1460
|
+
formatDate(drawing.updatedAt)
|
|
1461
|
+
] })
|
|
1462
|
+
] }) }),
|
|
1463
|
+
/* @__PURE__ */ jsx6("div", { style: { display: "flex", gap: "2px", alignItems: "center" }, children: confirmDeleteId === drawing.id ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1464
|
+
/* @__PURE__ */ jsx6(
|
|
1465
|
+
"button",
|
|
1466
|
+
{
|
|
1467
|
+
onClick: (e) => {
|
|
1468
|
+
e.stopPropagation();
|
|
1469
|
+
handleDelete(drawing.id);
|
|
1470
|
+
},
|
|
1471
|
+
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "#dc3545", color: "#fff", border: "none", borderRadius: "4px", cursor: "pointer" },
|
|
1472
|
+
children: t.delete
|
|
1473
|
+
}
|
|
1474
|
+
),
|
|
1475
|
+
/* @__PURE__ */ jsx6(
|
|
1476
|
+
"button",
|
|
1477
|
+
{
|
|
1478
|
+
onClick: (e) => {
|
|
1479
|
+
e.stopPropagation();
|
|
1480
|
+
setConfirmDeleteId(null);
|
|
1481
|
+
},
|
|
1482
|
+
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "transparent", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", color: "inherit" },
|
|
1483
|
+
children: t.cancel
|
|
1484
|
+
}
|
|
1485
|
+
)
|
|
1486
|
+
] }) : movingDrawingId === drawing.id ? /* @__PURE__ */ jsxs4("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", flexDirection: "column", gap: "2px", fontSize: "12px" }, children: [
|
|
1487
|
+
/* @__PURE__ */ jsx6(
|
|
1488
|
+
"button",
|
|
1489
|
+
{
|
|
1490
|
+
onClick: () => handleMoveToFolder(drawing.id, null),
|
|
1491
|
+
style: { padding: "3px 8px", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", backgroundColor: !drawing.folderId ? "var(--color-primary-light, rgba(108, 99, 255, 0.1))" : "transparent", color: "inherit", textAlign: "left" },
|
|
1492
|
+
children: t.moveToRoot
|
|
1493
|
+
}
|
|
1494
|
+
),
|
|
1495
|
+
folders.map((folder) => /* @__PURE__ */ jsxs4(
|
|
1496
|
+
"button",
|
|
1497
|
+
{
|
|
1498
|
+
onClick: () => handleMoveToFolder(drawing.id, folder.id),
|
|
1499
|
+
style: { padding: "3px 8px", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", backgroundColor: drawing.folderId === folder.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.1))" : "transparent", color: "inherit", textAlign: "left" },
|
|
1500
|
+
children: [
|
|
1501
|
+
"\u{1F4C1} ",
|
|
1502
|
+
folder.name
|
|
1503
|
+
]
|
|
1504
|
+
},
|
|
1505
|
+
folder.id
|
|
1506
|
+
)),
|
|
1507
|
+
/* @__PURE__ */ jsx6(
|
|
1508
|
+
"button",
|
|
1509
|
+
{
|
|
1510
|
+
onClick: () => setMovingDrawingId(null),
|
|
1511
|
+
style: { padding: "3px 8px", border: "none", cursor: "pointer", backgroundColor: "transparent", color: "var(--text-secondary-color, #888)", textAlign: "left" },
|
|
1512
|
+
children: t.cancel
|
|
1513
|
+
}
|
|
1514
|
+
)
|
|
1515
|
+
] }) : editingId !== drawing.id && /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1516
|
+
folders.length > 0 && /* @__PURE__ */ jsx6(
|
|
1517
|
+
"button",
|
|
1518
|
+
{
|
|
1519
|
+
onClick: (e) => {
|
|
1520
|
+
e.stopPropagation();
|
|
1521
|
+
setMovingDrawingId(drawing.id);
|
|
1522
|
+
},
|
|
1523
|
+
style: { background: "none", border: "none", cursor: "pointer", padding: "4px", fontSize: "14px", opacity: 0.5 },
|
|
1524
|
+
title: t.moveToFolder,
|
|
1525
|
+
children: "\u{1F4C1}"
|
|
1526
|
+
}
|
|
1527
|
+
),
|
|
1528
|
+
/* @__PURE__ */ jsx6(
|
|
1529
|
+
"button",
|
|
1530
|
+
{
|
|
1531
|
+
onClick: (e) => {
|
|
1532
|
+
e.stopPropagation();
|
|
1533
|
+
exportDrawingAsExcalidraw(drawing.id);
|
|
1534
|
+
},
|
|
1535
|
+
style: { background: "none", border: "none", cursor: "pointer", padding: "4px", fontSize: "14px", opacity: 0.5 },
|
|
1536
|
+
title: t.exportDrawing,
|
|
1537
|
+
children: "\u{1F4BE}"
|
|
1538
|
+
}
|
|
1539
|
+
),
|
|
1540
|
+
/* @__PURE__ */ jsx6(
|
|
1541
|
+
"button",
|
|
1542
|
+
{
|
|
1543
|
+
onClick: (e) => {
|
|
1544
|
+
e.stopPropagation();
|
|
1545
|
+
setConfirmDeleteId(drawing.id);
|
|
1546
|
+
},
|
|
1547
|
+
style: { background: "none", border: "none", cursor: "pointer", padding: "4px", fontSize: "14px", opacity: 0.5 },
|
|
1548
|
+
title: t.delete,
|
|
1549
|
+
disabled: drawings.length <= 1,
|
|
1550
|
+
children: "\u{1F5D1}\uFE0F"
|
|
1551
|
+
}
|
|
1552
|
+
)
|
|
1553
|
+
] }) })
|
|
1554
|
+
]
|
|
1555
|
+
},
|
|
1556
|
+
drawing.id
|
|
1557
|
+
);
|
|
1558
|
+
const renderFolderGroup = (folder) => {
|
|
1559
|
+
const folderDrawings = drawingsByFolder[folder.id] || [];
|
|
1560
|
+
const isExpanded = expandedFolders.has(folder.id);
|
|
1561
|
+
return /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "4px" }, children: [
|
|
1562
|
+
/* @__PURE__ */ jsxs4(
|
|
1563
|
+
"div",
|
|
1564
|
+
{
|
|
1565
|
+
onClick: () => toggleFolder(folder.id),
|
|
1566
|
+
style: {
|
|
1567
|
+
padding: "8px 12px",
|
|
1568
|
+
display: "flex",
|
|
1569
|
+
alignItems: "center",
|
|
1570
|
+
gap: "8px",
|
|
1571
|
+
borderRadius: "8px",
|
|
1572
|
+
cursor: "pointer",
|
|
1573
|
+
backgroundColor: "var(--color-surface-mid, rgba(0, 0, 0, 0.03))"
|
|
1574
|
+
},
|
|
1575
|
+
children: [
|
|
1576
|
+
/* @__PURE__ */ jsx6("span", { style: { fontSize: "12px", width: "16px", textAlign: "center", flexShrink: 0 }, children: isExpanded ? "\u25BC" : "\u25B6" }),
|
|
1577
|
+
/* @__PURE__ */ jsx6("span", { style: { fontSize: "16px", flexShrink: 0 }, children: "\u{1F4C1}" }),
|
|
1578
|
+
/* @__PURE__ */ jsx6("div", { style: { flex: 1, minWidth: 0 }, children: editingFolderId === folder.id ? /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "6px", alignItems: "center" }, onClick: (e) => e.stopPropagation(), children: [
|
|
1579
|
+
/* @__PURE__ */ jsx6(
|
|
1580
|
+
"input",
|
|
1581
|
+
{
|
|
1582
|
+
type: "text",
|
|
1583
|
+
value: editFolderName,
|
|
1584
|
+
onChange: (e) => setEditFolderName(e.target.value),
|
|
1585
|
+
onKeyDown: (e) => {
|
|
1586
|
+
if (e.key === "Enter") handleSaveFolderEdit();
|
|
1587
|
+
if (e.key === "Escape") {
|
|
1588
|
+
setEditingFolderId(null);
|
|
1589
|
+
setEditFolderName("");
|
|
1590
|
+
}
|
|
1591
|
+
},
|
|
1592
|
+
autoFocus: true,
|
|
1593
|
+
style: { flex: 1, padding: "2px 6px", fontSize: "14px", border: "1px solid var(--color-primary, #6c63ff)", borderRadius: "4px", outline: "none" }
|
|
1594
|
+
}
|
|
1595
|
+
),
|
|
1596
|
+
/* @__PURE__ */ jsx6(
|
|
1597
|
+
"button",
|
|
1598
|
+
{
|
|
1599
|
+
onClick: handleSaveFolderEdit,
|
|
1600
|
+
style: { padding: "2px 8px", fontSize: "12px", backgroundColor: "var(--color-primary, #6c63ff)", color: "#fff", border: "none", borderRadius: "4px", cursor: "pointer" },
|
|
1601
|
+
children: t.save
|
|
1602
|
+
}
|
|
1603
|
+
)
|
|
1604
|
+
] }) : /* @__PURE__ */ jsxs4("span", { style: { fontWeight: 600, fontSize: "14px" }, children: [
|
|
1605
|
+
folder.name,
|
|
1606
|
+
/* @__PURE__ */ jsxs4("span", { style: { fontWeight: 400, fontSize: "12px", color: "var(--text-secondary-color, #888)", marginLeft: "6px" }, children: [
|
|
1607
|
+
"(",
|
|
1608
|
+
folderDrawings.length,
|
|
1609
|
+
")"
|
|
1610
|
+
] })
|
|
1611
|
+
] }) }),
|
|
1612
|
+
confirmDeleteFolderId === folder.id ? /* @__PURE__ */ jsxs4("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", gap: "4px" }, children: [
|
|
1613
|
+
/* @__PURE__ */ jsx6(
|
|
1614
|
+
"button",
|
|
1615
|
+
{
|
|
1616
|
+
onClick: () => handleDeleteFolder(folder.id),
|
|
1617
|
+
style: { padding: "2px 8px", fontSize: "12px", backgroundColor: "#dc3545", color: "#fff", border: "none", borderRadius: "4px", cursor: "pointer" },
|
|
1618
|
+
children: t.delete
|
|
1619
|
+
}
|
|
1620
|
+
),
|
|
1621
|
+
/* @__PURE__ */ jsx6(
|
|
1622
|
+
"button",
|
|
1623
|
+
{
|
|
1624
|
+
onClick: () => setConfirmDeleteFolderId(null),
|
|
1625
|
+
style: { padding: "2px 8px", fontSize: "12px", backgroundColor: "transparent", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", color: "inherit" },
|
|
1626
|
+
children: t.cancel
|
|
1627
|
+
}
|
|
1628
|
+
)
|
|
1629
|
+
] }) : editingFolderId !== folder.id && /* @__PURE__ */ jsxs4("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", gap: "2px" }, children: [
|
|
1630
|
+
/* @__PURE__ */ jsx6(
|
|
1631
|
+
"button",
|
|
1632
|
+
{
|
|
1633
|
+
onClick: () => {
|
|
1634
|
+
setEditingFolderId(folder.id);
|
|
1635
|
+
setEditFolderName(folder.name);
|
|
1636
|
+
},
|
|
1637
|
+
style: { background: "none", border: "none", cursor: "pointer", padding: "2px", fontSize: "12px", opacity: 0.5 },
|
|
1638
|
+
title: t.renameFolder,
|
|
1639
|
+
children: "\u270F\uFE0F"
|
|
1640
|
+
}
|
|
1641
|
+
),
|
|
1642
|
+
/* @__PURE__ */ jsx6(
|
|
1643
|
+
"button",
|
|
1644
|
+
{
|
|
1645
|
+
onClick: () => setConfirmDeleteFolderId(folder.id),
|
|
1646
|
+
style: { background: "none", border: "none", cursor: "pointer", padding: "2px", fontSize: "12px", opacity: 0.5 },
|
|
1647
|
+
title: t.deleteFolder,
|
|
1648
|
+
children: "\u{1F5D1}\uFE0F"
|
|
1649
|
+
}
|
|
1650
|
+
)
|
|
1651
|
+
] })
|
|
1652
|
+
]
|
|
1653
|
+
}
|
|
1654
|
+
),
|
|
1655
|
+
isExpanded && /* @__PURE__ */ jsxs4("div", { style: { paddingLeft: "24px", marginTop: "2px" }, children: [
|
|
1656
|
+
folderDrawings.length === 0 && /* @__PURE__ */ jsx6("div", { style: { padding: "8px 12px", fontSize: "12px", color: "var(--text-secondary-color, #888)", fontStyle: "italic" }, children: t.noDrawingsYet }),
|
|
1657
|
+
folderDrawings.map(renderDrawingRow)
|
|
1658
|
+
] })
|
|
1659
|
+
] }, folder.id);
|
|
1660
|
+
};
|
|
1148
1661
|
return /* @__PURE__ */ jsx6(
|
|
1149
1662
|
"div",
|
|
1150
1663
|
{
|
|
@@ -1200,181 +1713,32 @@ var DrawingsDialog = ({
|
|
|
1200
1713
|
]
|
|
1201
1714
|
}
|
|
1202
1715
|
),
|
|
1716
|
+
drawings.length > 3 && /* @__PURE__ */ jsx6("div", { style: { padding: "8px 20px", borderBottom: "1px solid var(--default-border-color, #e0e0e0)" }, children: /* @__PURE__ */ jsx6(
|
|
1717
|
+
"input",
|
|
1718
|
+
{
|
|
1719
|
+
type: "text",
|
|
1720
|
+
value: searchQuery,
|
|
1721
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
1722
|
+
placeholder: "\u{1F50D}",
|
|
1723
|
+
style: {
|
|
1724
|
+
width: "100%",
|
|
1725
|
+
padding: "6px 12px",
|
|
1726
|
+
fontSize: "14px",
|
|
1727
|
+
border: "1px solid var(--default-border-color, #e0e0e0)",
|
|
1728
|
+
borderRadius: "6px",
|
|
1729
|
+
outline: "none",
|
|
1730
|
+
backgroundColor: "transparent",
|
|
1731
|
+
color: "inherit",
|
|
1732
|
+
boxSizing: "border-box"
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
) }),
|
|
1203
1736
|
/* @__PURE__ */ jsxs4("div", { style: { flex: 1, overflow: "auto" }, children: [
|
|
1204
|
-
drawings.length > 0 && /* @__PURE__ */
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
if (activeDrawing?.id !== drawing.id) handleSelect(drawing);
|
|
1210
|
-
},
|
|
1211
|
-
style: {
|
|
1212
|
-
padding: "10px 12px",
|
|
1213
|
-
display: "flex",
|
|
1214
|
-
alignItems: "center",
|
|
1215
|
-
gap: "12px",
|
|
1216
|
-
borderRadius: "8px",
|
|
1217
|
-
marginBottom: "4px",
|
|
1218
|
-
cursor: editingId || confirmDeleteId ? "default" : "pointer",
|
|
1219
|
-
backgroundColor: activeDrawing?.id === drawing.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.1))" : "transparent",
|
|
1220
|
-
transition: "background-color 0.15s"
|
|
1221
|
-
},
|
|
1222
|
-
children: [
|
|
1223
|
-
renderThumbnail && /* @__PURE__ */ jsx6("div", { style: {
|
|
1224
|
-
width: "64px",
|
|
1225
|
-
height: "48px",
|
|
1226
|
-
flexShrink: 0,
|
|
1227
|
-
borderRadius: "4px",
|
|
1228
|
-
overflow: "hidden",
|
|
1229
|
-
border: "1px solid var(--default-border-color, #e0e0e0)",
|
|
1230
|
-
backgroundColor: "#fff",
|
|
1231
|
-
display: "flex",
|
|
1232
|
-
alignItems: "center",
|
|
1233
|
-
justifyContent: "center"
|
|
1234
|
-
}, children: renderThumbnail(drawing) }),
|
|
1235
|
-
/* @__PURE__ */ jsx6("div", { style: { flex: 1, minWidth: 0 }, children: editingId === drawing.id ? /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "6px", alignItems: "center" }, children: [
|
|
1236
|
-
/* @__PURE__ */ jsx6(
|
|
1237
|
-
"input",
|
|
1238
|
-
{
|
|
1239
|
-
type: "text",
|
|
1240
|
-
value: editName,
|
|
1241
|
-
onChange: (e) => setEditName(e.target.value),
|
|
1242
|
-
onKeyDown: (e) => {
|
|
1243
|
-
if (e.key === "Enter") handleSaveEdit();
|
|
1244
|
-
if (e.key === "Escape") handleCancelEdit();
|
|
1245
|
-
},
|
|
1246
|
-
onClick: (e) => e.stopPropagation(),
|
|
1247
|
-
autoFocus: true,
|
|
1248
|
-
style: {
|
|
1249
|
-
flex: 1,
|
|
1250
|
-
padding: "4px 8px",
|
|
1251
|
-
fontSize: "14px",
|
|
1252
|
-
border: "1px solid var(--color-primary, #6c63ff)",
|
|
1253
|
-
borderRadius: "4px",
|
|
1254
|
-
outline: "none"
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
),
|
|
1258
|
-
/* @__PURE__ */ jsx6(
|
|
1259
|
-
"button",
|
|
1260
|
-
{
|
|
1261
|
-
onClick: (e) => {
|
|
1262
|
-
e.stopPropagation();
|
|
1263
|
-
handleSaveEdit();
|
|
1264
|
-
},
|
|
1265
|
-
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "var(--color-primary, #6c63ff)", color: "#fff", border: "none", borderRadius: "4px", cursor: "pointer" },
|
|
1266
|
-
children: t.save
|
|
1267
|
-
}
|
|
1268
|
-
),
|
|
1269
|
-
/* @__PURE__ */ jsx6(
|
|
1270
|
-
"button",
|
|
1271
|
-
{
|
|
1272
|
-
onClick: (e) => {
|
|
1273
|
-
e.stopPropagation();
|
|
1274
|
-
handleCancelEdit();
|
|
1275
|
-
},
|
|
1276
|
-
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "transparent", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", color: "inherit" },
|
|
1277
|
-
children: t.cancel
|
|
1278
|
-
}
|
|
1279
|
-
)
|
|
1280
|
-
] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1281
|
-
/* @__PURE__ */ jsxs4("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
|
|
1282
|
-
/* @__PURE__ */ jsxs4(
|
|
1283
|
-
"span",
|
|
1284
|
-
{
|
|
1285
|
-
onClick: (e) => {
|
|
1286
|
-
e.stopPropagation();
|
|
1287
|
-
handleStartEdit(drawing);
|
|
1288
|
-
},
|
|
1289
|
-
style: {
|
|
1290
|
-
fontWeight: activeDrawing?.id === drawing.id ? 600 : 400,
|
|
1291
|
-
fontSize: "14px",
|
|
1292
|
-
overflow: "hidden",
|
|
1293
|
-
textOverflow: "ellipsis",
|
|
1294
|
-
whiteSpace: "nowrap",
|
|
1295
|
-
cursor: "text"
|
|
1296
|
-
},
|
|
1297
|
-
title: t.rename,
|
|
1298
|
-
children: [
|
|
1299
|
-
activeDrawing?.id === drawing.id && "\u2713 ",
|
|
1300
|
-
drawing.name
|
|
1301
|
-
]
|
|
1302
|
-
}
|
|
1303
|
-
),
|
|
1304
|
-
/* @__PURE__ */ jsx6(
|
|
1305
|
-
"button",
|
|
1306
|
-
{
|
|
1307
|
-
onClick: (e) => {
|
|
1308
|
-
e.stopPropagation();
|
|
1309
|
-
handleStartEdit(drawing);
|
|
1310
|
-
},
|
|
1311
|
-
style: { background: "none", border: "none", cursor: "pointer", padding: "0 2px", fontSize: "12px", opacity: 0.4, flexShrink: 0 },
|
|
1312
|
-
title: t.rename,
|
|
1313
|
-
children: "\u270F\uFE0F"
|
|
1314
|
-
}
|
|
1315
|
-
)
|
|
1316
|
-
] }),
|
|
1317
|
-
/* @__PURE__ */ jsxs4("div", { style: { fontSize: "11px", color: "var(--text-secondary-color, #888)", marginTop: "1px" }, children: [
|
|
1318
|
-
t.modified,
|
|
1319
|
-
": ",
|
|
1320
|
-
formatDate(drawing.updatedAt)
|
|
1321
|
-
] })
|
|
1322
|
-
] }) }),
|
|
1323
|
-
/* @__PURE__ */ jsx6("div", { style: { display: "flex", gap: "2px" }, children: confirmDeleteId === drawing.id ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1324
|
-
/* @__PURE__ */ jsx6(
|
|
1325
|
-
"button",
|
|
1326
|
-
{
|
|
1327
|
-
onClick: (e) => {
|
|
1328
|
-
e.stopPropagation();
|
|
1329
|
-
handleDelete(drawing.id);
|
|
1330
|
-
},
|
|
1331
|
-
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "#dc3545", color: "#fff", border: "none", borderRadius: "4px", cursor: "pointer" },
|
|
1332
|
-
children: t.delete
|
|
1333
|
-
}
|
|
1334
|
-
),
|
|
1335
|
-
/* @__PURE__ */ jsx6(
|
|
1336
|
-
"button",
|
|
1337
|
-
{
|
|
1338
|
-
onClick: (e) => {
|
|
1339
|
-
e.stopPropagation();
|
|
1340
|
-
setConfirmDeleteId(null);
|
|
1341
|
-
},
|
|
1342
|
-
style: { padding: "4px 10px", fontSize: "12px", backgroundColor: "transparent", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "4px", cursor: "pointer", color: "inherit" },
|
|
1343
|
-
children: t.cancel
|
|
1344
|
-
}
|
|
1345
|
-
)
|
|
1346
|
-
] }) : editingId !== drawing.id && /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1347
|
-
/* @__PURE__ */ jsx6(
|
|
1348
|
-
"button",
|
|
1349
|
-
{
|
|
1350
|
-
onClick: (e) => {
|
|
1351
|
-
e.stopPropagation();
|
|
1352
|
-
exportDrawingAsExcalidraw(drawing.id);
|
|
1353
|
-
},
|
|
1354
|
-
style: { background: "none", border: "none", cursor: "pointer", padding: "4px", fontSize: "14px", opacity: 0.5 },
|
|
1355
|
-
title: t.exportDrawing,
|
|
1356
|
-
children: "\u{1F4BE}"
|
|
1357
|
-
}
|
|
1358
|
-
),
|
|
1359
|
-
/* @__PURE__ */ jsx6(
|
|
1360
|
-
"button",
|
|
1361
|
-
{
|
|
1362
|
-
onClick: (e) => {
|
|
1363
|
-
e.stopPropagation();
|
|
1364
|
-
setConfirmDeleteId(drawing.id);
|
|
1365
|
-
},
|
|
1366
|
-
style: { background: "none", border: "none", cursor: "pointer", padding: "4px", fontSize: "14px", opacity: 0.5 },
|
|
1367
|
-
title: t.delete,
|
|
1368
|
-
disabled: drawings.length <= 1,
|
|
1369
|
-
children: "\u{1F5D1}\uFE0F"
|
|
1370
|
-
}
|
|
1371
|
-
)
|
|
1372
|
-
] }) })
|
|
1373
|
-
]
|
|
1374
|
-
},
|
|
1375
|
-
drawing.id
|
|
1376
|
-
)) }),
|
|
1377
|
-
drawings.length === 0 && /* @__PURE__ */ jsxs4("div", { style: { padding: "24px 20px", textAlign: "center", color: "var(--text-secondary-color, #666)" }, children: [
|
|
1737
|
+
(drawings.length > 0 || folders.length > 0) && /* @__PURE__ */ jsxs4("div", { style: { padding: "8px 20px 0" }, children: [
|
|
1738
|
+
filteredFolders.map(renderFolderGroup),
|
|
1739
|
+
rootDrawings.map(renderDrawingRow)
|
|
1740
|
+
] }),
|
|
1741
|
+
drawings.length === 0 && folders.length === 0 && /* @__PURE__ */ jsxs4("div", { style: { padding: "24px 20px", textAlign: "center", color: "var(--text-secondary-color, #666)" }, children: [
|
|
1378
1742
|
/* @__PURE__ */ jsx6("p", { children: t.noDrawingsYet }),
|
|
1379
1743
|
/* @__PURE__ */ jsx6("p", { children: t.clickNewToStart })
|
|
1380
1744
|
] }),
|
|
@@ -1386,7 +1750,7 @@ var DrawingsDialog = ({
|
|
|
1386
1750
|
icon: "\u{1F4C4}",
|
|
1387
1751
|
label: t.createNewDrawing,
|
|
1388
1752
|
description: t.createNewDrawingDesc,
|
|
1389
|
-
onClick: handleCreate,
|
|
1753
|
+
onClick: () => handleCreate(),
|
|
1390
1754
|
primary: true
|
|
1391
1755
|
}
|
|
1392
1756
|
),
|
|
@@ -1398,6 +1762,60 @@ var DrawingsDialog = ({
|
|
|
1398
1762
|
description: t.openFromFileDesc,
|
|
1399
1763
|
onClick: importExcalidrawFile
|
|
1400
1764
|
}
|
|
1765
|
+
),
|
|
1766
|
+
creatingFolder ? /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "8px", alignItems: "center", padding: "4px 0" }, children: [
|
|
1767
|
+
/* @__PURE__ */ jsx6(
|
|
1768
|
+
"input",
|
|
1769
|
+
{
|
|
1770
|
+
ref: newFolderInputRef,
|
|
1771
|
+
type: "text",
|
|
1772
|
+
value: newFolderName,
|
|
1773
|
+
onChange: (e) => setNewFolderName(e.target.value),
|
|
1774
|
+
onKeyDown: (e) => {
|
|
1775
|
+
if (e.key === "Enter") handleCreateFolder();
|
|
1776
|
+
if (e.key === "Escape") {
|
|
1777
|
+
setCreatingFolder(false);
|
|
1778
|
+
setNewFolderName("");
|
|
1779
|
+
}
|
|
1780
|
+
},
|
|
1781
|
+
placeholder: t.newFolderName,
|
|
1782
|
+
style: {
|
|
1783
|
+
flex: 1,
|
|
1784
|
+
padding: "8px 12px",
|
|
1785
|
+
fontSize: "14px",
|
|
1786
|
+
border: "1px solid var(--color-primary, #6c63ff)",
|
|
1787
|
+
borderRadius: "8px",
|
|
1788
|
+
outline: "none"
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
),
|
|
1792
|
+
/* @__PURE__ */ jsx6(
|
|
1793
|
+
"button",
|
|
1794
|
+
{
|
|
1795
|
+
onClick: handleCreateFolder,
|
|
1796
|
+
style: { padding: "8px 16px", fontSize: "14px", backgroundColor: "var(--color-primary, #6c63ff)", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer" },
|
|
1797
|
+
children: t.save
|
|
1798
|
+
}
|
|
1799
|
+
),
|
|
1800
|
+
/* @__PURE__ */ jsx6(
|
|
1801
|
+
"button",
|
|
1802
|
+
{
|
|
1803
|
+
onClick: () => {
|
|
1804
|
+
setCreatingFolder(false);
|
|
1805
|
+
setNewFolderName("");
|
|
1806
|
+
},
|
|
1807
|
+
style: { padding: "8px 16px", fontSize: "14px", backgroundColor: "transparent", border: "1px solid var(--default-border-color, #ccc)", borderRadius: "8px", cursor: "pointer", color: "inherit" },
|
|
1808
|
+
children: t.cancel
|
|
1809
|
+
}
|
|
1810
|
+
)
|
|
1811
|
+
] }) : /* @__PURE__ */ jsx6(
|
|
1812
|
+
ActionButton,
|
|
1813
|
+
{
|
|
1814
|
+
icon: "\u{1F4C1}",
|
|
1815
|
+
label: t.createFolder,
|
|
1816
|
+
description: "",
|
|
1817
|
+
onClick: () => setCreatingFolder(true)
|
|
1818
|
+
}
|
|
1401
1819
|
)
|
|
1402
1820
|
] }),
|
|
1403
1821
|
/* @__PURE__ */ jsx6("div", { style: sectionHeaderStyle, children: t.sectionWorkspace }),
|
|
@@ -1643,16 +2061,22 @@ export {
|
|
|
1643
2061
|
addDrawingToWorkspace,
|
|
1644
2062
|
closeDB,
|
|
1645
2063
|
createDrawing,
|
|
2064
|
+
createFolder,
|
|
1646
2065
|
deleteDrawing,
|
|
2066
|
+
deleteFolder,
|
|
1647
2067
|
duplicateDrawing,
|
|
1648
2068
|
getAllDrawings,
|
|
2069
|
+
getAllFolders,
|
|
1649
2070
|
getDB,
|
|
1650
2071
|
getDrawing,
|
|
2072
|
+
getFolder,
|
|
1651
2073
|
getOrCreateDefaultWorkspace,
|
|
1652
2074
|
getTranslations,
|
|
1653
2075
|
getWorkspace,
|
|
1654
2076
|
isLanguageSupported,
|
|
2077
|
+
moveDrawingToFolder,
|
|
1655
2078
|
removeDrawingFromWorkspace,
|
|
2079
|
+
renameFolder,
|
|
1656
2080
|
setActiveDrawing,
|
|
1657
2081
|
updateDrawing,
|
|
1658
2082
|
updateWorkspace,
|