rita-workspace 0.2.0 → 0.3.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 +145 -78
- package/dist/index.d.mts +46 -1
- package/dist/index.d.ts +46 -1
- package/dist/index.js +109 -24
- package/dist/index.mjs +113 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,103 +2,170 @@
|
|
|
2
2
|
|
|
3
3
|
Multi-drawing workspace feature for Rita (Excalidraw fork based on B310-digital/excalidraw).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **Multiple drawings** - Create and manage multiple drawings in one workspace
|
|
8
|
+
- **Menu integration** - Seamlessly integrates with Excalidraw's hamburger menu
|
|
9
|
+
- **Auto-save** - All drawings saved locally in IndexedDB
|
|
10
|
+
- **Rename & delete** - Full drawing management via dialog
|
|
8
11
|
|
|
9
|
-
##
|
|
12
|
+
## Installation
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
```bash
|
|
15
|
+
npm install rita-workspace
|
|
16
|
+
# or
|
|
17
|
+
yarn add rita-workspace
|
|
18
|
+
```
|
|
16
19
|
|
|
17
|
-
##
|
|
20
|
+
## Integration Guide
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
- [ ] Sidebar with list of drawings
|
|
21
|
-
- [ ] Create new drawing button
|
|
22
|
-
- [ ] Switch between drawings (preserves state)
|
|
23
|
-
- [ ] Rename drawings
|
|
24
|
-
- [ ] Delete drawings
|
|
25
|
-
- [ ] Auto-save to browser storage (IndexedDB)
|
|
26
|
-
- [ ] Import existing .excalidraw files into workspace
|
|
27
|
-
|
|
28
|
-
### Future (v2.0+)
|
|
29
|
-
- [ ] Folders/categories for drawings
|
|
30
|
-
- [ ] Search drawings
|
|
31
|
-
- [ ] Thumbnail previews
|
|
32
|
-
- [ ] Export entire workspace
|
|
33
|
-
- [ ] Cloud sync (optional)
|
|
34
|
-
- [ ] Link/reference between drawings
|
|
35
|
-
|
|
36
|
-
## Technical Approach
|
|
37
|
-
|
|
38
|
-
### Storage
|
|
39
|
-
- Use IndexedDB for persistent storage (better than localStorage for binary data)
|
|
40
|
-
- Each drawing stored as separate entry with metadata
|
|
41
|
-
- Workspace metadata stored separately
|
|
42
|
-
|
|
43
|
-
### Data Structure
|
|
44
|
-
```typescript
|
|
45
|
-
interface Drawing {
|
|
46
|
-
id: string;
|
|
47
|
-
name: string;
|
|
48
|
-
createdAt: Date;
|
|
49
|
-
updatedAt: Date;
|
|
50
|
-
elements: ExcalidrawElement[];
|
|
51
|
-
appState: Partial<AppState>;
|
|
52
|
-
files: BinaryFiles;
|
|
53
|
-
}
|
|
22
|
+
Two files need to be modified in the B310/Excalidraw fork:
|
|
54
23
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
24
|
+
### 1. `excalidraw-app/App.tsx`
|
|
25
|
+
|
|
26
|
+
**Add import** (at the top with other imports):
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { WorkspaceProvider } from "rita-workspace";
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Wrap with WorkspaceProvider** (in the `ExcalidrawApp` component):
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
const ExcalidrawApp = () => {
|
|
36
|
+
// ...
|
|
37
|
+
return (
|
|
38
|
+
<TopErrorBoundary>
|
|
39
|
+
<Provider store={appJotaiStore}>
|
|
40
|
+
<WorkspaceProvider> {/* <-- Add this */}
|
|
41
|
+
<ExcalidrawWrapper />
|
|
42
|
+
</WorkspaceProvider> {/* <-- And this */}
|
|
43
|
+
</Provider>
|
|
44
|
+
</TopErrorBoundary>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
63
47
|
```
|
|
64
48
|
|
|
65
|
-
###
|
|
66
|
-
- `WorkspaceSidebar` - Collapsible sidebar showing drawing list
|
|
67
|
-
- `DrawingListItem` - Individual drawing entry with actions
|
|
68
|
-
- `NewDrawingButton` - Creates new blank drawing
|
|
69
|
-
- `WorkspaceProvider` - React context for workspace state
|
|
49
|
+
### 2. `excalidraw-app/components/AppMainMenu.tsx`
|
|
70
50
|
|
|
71
|
-
|
|
51
|
+
**Add imports** (at the top):
|
|
72
52
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
2. Maintained as a separate layer/plugin for Rita
|
|
53
|
+
```tsx
|
|
54
|
+
import React, { useState } from "react"; // Add useState
|
|
76
55
|
|
|
77
|
-
|
|
56
|
+
// Add after other imports:
|
|
57
|
+
import { WorkspaceMenuItems, DrawingsDialog } from "rita-workspace";
|
|
58
|
+
```
|
|
78
59
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
60
|
+
**Add state and menu items** (inside the component):
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
export const AppMainMenu: React.FC<{...}> = React.memo((props) => {
|
|
64
|
+
const [showDrawingsDialog, setShowDrawingsDialog] = useState(false); // Add this
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<> {/* Add fragment */}
|
|
68
|
+
<MainMenu>
|
|
69
|
+
<MainMenu.DefaultItems.LoadScene />
|
|
70
|
+
<MainMenu.DefaultItems.SaveToActiveFile />
|
|
71
|
+
|
|
72
|
+
{/* === RITA WORKSPACE: Add this block === */}
|
|
73
|
+
<MainMenu.Sub>
|
|
74
|
+
<MainMenu.Sub.Trigger>📄 Ritningar</MainMenu.Sub.Trigger>
|
|
75
|
+
<MainMenu.Sub.Content>
|
|
76
|
+
<WorkspaceMenuItems
|
|
77
|
+
onManageDrawings={() => setShowDrawingsDialog(true)}
|
|
78
|
+
/>
|
|
79
|
+
</MainMenu.Sub.Content>
|
|
80
|
+
</MainMenu.Sub>
|
|
81
|
+
{/* === END RITA WORKSPACE === */}
|
|
82
|
+
|
|
83
|
+
<MainMenu.DefaultItems.Export />
|
|
84
|
+
{/* ... rest of menu items ... */}
|
|
85
|
+
</MainMenu>
|
|
86
|
+
|
|
87
|
+
{/* === RITA WORKSPACE: Add dialog === */}
|
|
88
|
+
<DrawingsDialog
|
|
89
|
+
open={showDrawingsDialog}
|
|
90
|
+
onClose={() => setShowDrawingsDialog(false)}
|
|
91
|
+
/>
|
|
92
|
+
</> {/* Close fragment */}
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
```
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
## Result
|
|
98
|
+
|
|
99
|
+
After integration, a "📄 Ritningar" submenu appears in the hamburger menu:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
┌─────────────────────────┐
|
|
103
|
+
│ 📂 Open │
|
|
104
|
+
│ 💾 Save │
|
|
105
|
+
│ 📄 Ritningar ▶ │──┐
|
|
106
|
+
│ 📤 Export │ │ ┌─────────────────────┐
|
|
107
|
+
│ ... │ └──│ ✓ Current drawing │
|
|
108
|
+
└─────────────────────────┘ │ Sketch 2 │
|
|
109
|
+
│ Project X │
|
|
110
|
+
│ ─────────────────── │
|
|
111
|
+
│ + Ny ritning │
|
|
112
|
+
│ 📄 Hantera... │
|
|
113
|
+
└─────────────────────┘
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
### Components
|
|
119
|
+
|
|
120
|
+
| Component | Description |
|
|
121
|
+
|-----------|-------------|
|
|
122
|
+
| `WorkspaceProvider` | React context provider - wrap your app with this |
|
|
123
|
+
| `WorkspaceMenuItems` | Menu items for Excalidraw's MainMenu |
|
|
124
|
+
| `DrawingsDialog` | Modal dialog for managing all drawings |
|
|
125
|
+
|
|
126
|
+
### Hooks
|
|
127
|
+
|
|
128
|
+
| Hook | Description |
|
|
129
|
+
|------|-------------|
|
|
130
|
+
| `useWorkspace()` | Access workspace state and actions |
|
|
131
|
+
|
|
132
|
+
### useWorkspace() returns
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
const {
|
|
136
|
+
drawings, // Drawing[] - all drawings
|
|
137
|
+
activeDrawing, // Drawing | null - currently active
|
|
138
|
+
isLoading, // boolean
|
|
139
|
+
createNewDrawing, // () => Promise<Drawing>
|
|
140
|
+
switchDrawing, // (id: string) => Promise<void>
|
|
141
|
+
renameDrawing, // (id: string, name: string) => Promise<void>
|
|
142
|
+
removeDrawing, // (id: string) => Promise<void>
|
|
143
|
+
saveCurrentDrawing, // (elements, appState, files?) => Promise<void>
|
|
144
|
+
} = useWorkspace();
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Data Storage
|
|
148
|
+
|
|
149
|
+
Drawings are stored in IndexedDB with the following structure:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
interface Drawing {
|
|
153
|
+
id: string;
|
|
154
|
+
name: string;
|
|
155
|
+
elements: ExcalidrawElement[];
|
|
156
|
+
appState: Record<string, unknown>;
|
|
157
|
+
files: Record<string, unknown>;
|
|
158
|
+
createdAt: number;
|
|
159
|
+
updatedAt: number;
|
|
160
|
+
}
|
|
94
161
|
```
|
|
95
162
|
|
|
96
163
|
## Links
|
|
97
164
|
|
|
165
|
+
- **npm:** https://www.npmjs.com/package/rita-workspace
|
|
98
166
|
- **B310 Excalidraw Fork:** https://github.com/b310-digital/excalidraw
|
|
99
167
|
- **Original Excalidraw:** https://github.com/excalidraw/excalidraw
|
|
100
|
-
- **Rita:** Your local Rita deployment
|
|
101
168
|
|
|
102
169
|
## License
|
|
103
170
|
|
|
104
|
-
MIT
|
|
171
|
+
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -98,6 +98,11 @@ declare function DrawingListItem({ drawing, isActive, onSelect, onRename, onDele
|
|
|
98
98
|
*/
|
|
99
99
|
|
|
100
100
|
interface WorkspaceMenuItemsProps {
|
|
101
|
+
/**
|
|
102
|
+
* Language code (e.g., 'sv', 'en', 'sv-SE')
|
|
103
|
+
* Falls back to English if not supported
|
|
104
|
+
*/
|
|
105
|
+
lang?: string;
|
|
101
106
|
/**
|
|
102
107
|
* Called when a drawing is selected from the submenu
|
|
103
108
|
*/
|
|
@@ -137,6 +142,7 @@ interface WorkspaceMenuItemsProps {
|
|
|
137
142
|
* <MainMenu.DefaultItems.SaveToActiveFile />
|
|
138
143
|
* <MainMenu.Separator />
|
|
139
144
|
* <WorkspaceMenuItems
|
|
145
|
+
* lang="sv"
|
|
140
146
|
* renderMenuItem={(props) => <MainMenu.Item {...props} />}
|
|
141
147
|
* renderSubMenu={(props) => <MainMenu.Sub>{props.children}</MainMenu.Sub>}
|
|
142
148
|
* renderSeparator={() => <MainMenu.Separator />}
|
|
@@ -166,6 +172,11 @@ interface DrawingsDialogProps {
|
|
|
166
172
|
* Called when a drawing is selected
|
|
167
173
|
*/
|
|
168
174
|
onDrawingSelect?: (drawing: Drawing) => void;
|
|
175
|
+
/**
|
|
176
|
+
* Language code (e.g., 'sv', 'en', 'sv-SE')
|
|
177
|
+
* Falls back to English if not supported
|
|
178
|
+
*/
|
|
179
|
+
lang?: string;
|
|
169
180
|
}
|
|
170
181
|
/**
|
|
171
182
|
* DrawingsDialog - modal for managing workspace drawings
|
|
@@ -201,6 +212,40 @@ declare function useExcalidrawBridge({ excalidrawAPI, autoSaveInterval, }: UseEx
|
|
|
201
212
|
scheduleSave: () => void;
|
|
202
213
|
};
|
|
203
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Rita Workspace Translations
|
|
217
|
+
*
|
|
218
|
+
* Supports Swedish (sv) and English (en)
|
|
219
|
+
*/
|
|
220
|
+
type SupportedLanguage = 'sv' | 'en';
|
|
221
|
+
interface Translations {
|
|
222
|
+
drawings: string;
|
|
223
|
+
newDrawing: string;
|
|
224
|
+
manageDrawings: string;
|
|
225
|
+
dialogTitle: string;
|
|
226
|
+
close: string;
|
|
227
|
+
open: string;
|
|
228
|
+
rename: string;
|
|
229
|
+
delete: string;
|
|
230
|
+
save: string;
|
|
231
|
+
cancel: string;
|
|
232
|
+
confirm: string;
|
|
233
|
+
noDrawingsYet: string;
|
|
234
|
+
clickNewToStart: string;
|
|
235
|
+
modified: string;
|
|
236
|
+
confirmDelete: string;
|
|
237
|
+
shortcutNewDrawing: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get translations for a language code
|
|
241
|
+
* Falls back to English if language is not supported
|
|
242
|
+
*/
|
|
243
|
+
declare function getTranslations(langCode?: string): Translations;
|
|
244
|
+
/**
|
|
245
|
+
* Check if a language is supported
|
|
246
|
+
*/
|
|
247
|
+
declare function isLanguageSupported(langCode?: string): boolean;
|
|
248
|
+
|
|
204
249
|
interface WorkspacePluginProps {
|
|
205
250
|
children: ReactNode;
|
|
206
251
|
defaultSidebarOpen?: boolean;
|
|
@@ -224,4 +269,4 @@ interface WorkspacePluginProps {
|
|
|
224
269
|
*/
|
|
225
270
|
declare function WorkspacePlugin(props: WorkspacePluginProps): react_jsx_runtime.JSX.Element;
|
|
226
271
|
|
|
227
|
-
export { type Drawing, DrawingList, DrawingListItem, DrawingsDialog, type DrawingsDialogProps, Sidebar, type Workspace, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, deleteDrawing, duplicateDrawing, getAllDrawings, getDB, getDrawing, getOrCreateDefaultWorkspace, getWorkspace, removeDrawingFromWorkspace, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace };
|
|
272
|
+
export { type Drawing, DrawingList, DrawingListItem, DrawingsDialog, type DrawingsDialogProps, Sidebar, type SupportedLanguage, type Translations, type Workspace, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, deleteDrawing, duplicateDrawing, getAllDrawings, getDB, getDrawing, getOrCreateDefaultWorkspace, getTranslations, getWorkspace, isLanguageSupported, removeDrawingFromWorkspace, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace };
|
package/dist/index.d.ts
CHANGED
|
@@ -98,6 +98,11 @@ declare function DrawingListItem({ drawing, isActive, onSelect, onRename, onDele
|
|
|
98
98
|
*/
|
|
99
99
|
|
|
100
100
|
interface WorkspaceMenuItemsProps {
|
|
101
|
+
/**
|
|
102
|
+
* Language code (e.g., 'sv', 'en', 'sv-SE')
|
|
103
|
+
* Falls back to English if not supported
|
|
104
|
+
*/
|
|
105
|
+
lang?: string;
|
|
101
106
|
/**
|
|
102
107
|
* Called when a drawing is selected from the submenu
|
|
103
108
|
*/
|
|
@@ -137,6 +142,7 @@ interface WorkspaceMenuItemsProps {
|
|
|
137
142
|
* <MainMenu.DefaultItems.SaveToActiveFile />
|
|
138
143
|
* <MainMenu.Separator />
|
|
139
144
|
* <WorkspaceMenuItems
|
|
145
|
+
* lang="sv"
|
|
140
146
|
* renderMenuItem={(props) => <MainMenu.Item {...props} />}
|
|
141
147
|
* renderSubMenu={(props) => <MainMenu.Sub>{props.children}</MainMenu.Sub>}
|
|
142
148
|
* renderSeparator={() => <MainMenu.Separator />}
|
|
@@ -166,6 +172,11 @@ interface DrawingsDialogProps {
|
|
|
166
172
|
* Called when a drawing is selected
|
|
167
173
|
*/
|
|
168
174
|
onDrawingSelect?: (drawing: Drawing) => void;
|
|
175
|
+
/**
|
|
176
|
+
* Language code (e.g., 'sv', 'en', 'sv-SE')
|
|
177
|
+
* Falls back to English if not supported
|
|
178
|
+
*/
|
|
179
|
+
lang?: string;
|
|
169
180
|
}
|
|
170
181
|
/**
|
|
171
182
|
* DrawingsDialog - modal for managing workspace drawings
|
|
@@ -201,6 +212,40 @@ declare function useExcalidrawBridge({ excalidrawAPI, autoSaveInterval, }: UseEx
|
|
|
201
212
|
scheduleSave: () => void;
|
|
202
213
|
};
|
|
203
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Rita Workspace Translations
|
|
217
|
+
*
|
|
218
|
+
* Supports Swedish (sv) and English (en)
|
|
219
|
+
*/
|
|
220
|
+
type SupportedLanguage = 'sv' | 'en';
|
|
221
|
+
interface Translations {
|
|
222
|
+
drawings: string;
|
|
223
|
+
newDrawing: string;
|
|
224
|
+
manageDrawings: string;
|
|
225
|
+
dialogTitle: string;
|
|
226
|
+
close: string;
|
|
227
|
+
open: string;
|
|
228
|
+
rename: string;
|
|
229
|
+
delete: string;
|
|
230
|
+
save: string;
|
|
231
|
+
cancel: string;
|
|
232
|
+
confirm: string;
|
|
233
|
+
noDrawingsYet: string;
|
|
234
|
+
clickNewToStart: string;
|
|
235
|
+
modified: string;
|
|
236
|
+
confirmDelete: string;
|
|
237
|
+
shortcutNewDrawing: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get translations for a language code
|
|
241
|
+
* Falls back to English if language is not supported
|
|
242
|
+
*/
|
|
243
|
+
declare function getTranslations(langCode?: string): Translations;
|
|
244
|
+
/**
|
|
245
|
+
* Check if a language is supported
|
|
246
|
+
*/
|
|
247
|
+
declare function isLanguageSupported(langCode?: string): boolean;
|
|
248
|
+
|
|
204
249
|
interface WorkspacePluginProps {
|
|
205
250
|
children: ReactNode;
|
|
206
251
|
defaultSidebarOpen?: boolean;
|
|
@@ -224,4 +269,4 @@ interface WorkspacePluginProps {
|
|
|
224
269
|
*/
|
|
225
270
|
declare function WorkspacePlugin(props: WorkspacePluginProps): react_jsx_runtime.JSX.Element;
|
|
226
271
|
|
|
227
|
-
export { type Drawing, DrawingList, DrawingListItem, DrawingsDialog, type DrawingsDialogProps, Sidebar, type Workspace, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, deleteDrawing, duplicateDrawing, getAllDrawings, getDB, getDrawing, getOrCreateDefaultWorkspace, getWorkspace, removeDrawingFromWorkspace, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace };
|
|
272
|
+
export { type Drawing, DrawingList, DrawingListItem, DrawingsDialog, type DrawingsDialogProps, Sidebar, type SupportedLanguage, type Translations, type Workspace, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, deleteDrawing, duplicateDrawing, getAllDrawings, getDB, getDrawing, getOrCreateDefaultWorkspace, getTranslations, getWorkspace, isLanguageSupported, removeDrawingFromWorkspace, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace };
|
package/dist/index.js
CHANGED
|
@@ -46,7 +46,9 @@ __export(index_exports, {
|
|
|
46
46
|
getDB: () => getDB,
|
|
47
47
|
getDrawing: () => getDrawing,
|
|
48
48
|
getOrCreateDefaultWorkspace: () => getOrCreateDefaultWorkspace,
|
|
49
|
+
getTranslations: () => getTranslations,
|
|
49
50
|
getWorkspace: () => getWorkspace,
|
|
51
|
+
isLanguageSupported: () => isLanguageSupported,
|
|
50
52
|
removeDrawingFromWorkspace: () => removeDrawingFromWorkspace,
|
|
51
53
|
setActiveDrawing: () => setActiveDrawing,
|
|
52
54
|
updateDrawing: () => updateDrawing,
|
|
@@ -543,6 +545,71 @@ function Sidebar({ isOpen = true, onToggle, width = 250 }) {
|
|
|
543
545
|
|
|
544
546
|
// src/ui/Menu/WorkspaceMenuItems.tsx
|
|
545
547
|
var import_react4 = __toESM(require("react"));
|
|
548
|
+
|
|
549
|
+
// src/i18n/translations.ts
|
|
550
|
+
var sv = {
|
|
551
|
+
// Menu
|
|
552
|
+
drawings: "Ritningar",
|
|
553
|
+
newDrawing: "Ny ritning",
|
|
554
|
+
manageDrawings: "Hantera ritningar...",
|
|
555
|
+
// Dialog
|
|
556
|
+
dialogTitle: "Ritningar",
|
|
557
|
+
close: "St\xE4ng",
|
|
558
|
+
open: "\xD6ppna",
|
|
559
|
+
rename: "Byt namn",
|
|
560
|
+
delete: "Ta bort",
|
|
561
|
+
save: "Spara",
|
|
562
|
+
cancel: "Avbryt",
|
|
563
|
+
confirm: "Bekr\xE4fta",
|
|
564
|
+
// Messages
|
|
565
|
+
noDrawingsYet: "Inga ritningar \xE4nnu.",
|
|
566
|
+
clickNewToStart: 'Klicka "Ny ritning" f\xF6r att b\xF6rja.',
|
|
567
|
+
modified: "\xC4ndrad",
|
|
568
|
+
confirmDelete: "Vill du ta bort denna ritning?",
|
|
569
|
+
// Shortcuts
|
|
570
|
+
shortcutNewDrawing: "Ctrl+Alt+N"
|
|
571
|
+
};
|
|
572
|
+
var en = {
|
|
573
|
+
// Menu
|
|
574
|
+
drawings: "Drawings",
|
|
575
|
+
newDrawing: "New drawing",
|
|
576
|
+
manageDrawings: "Manage drawings...",
|
|
577
|
+
// Dialog
|
|
578
|
+
dialogTitle: "Drawings",
|
|
579
|
+
close: "Close",
|
|
580
|
+
open: "Open",
|
|
581
|
+
rename: "Rename",
|
|
582
|
+
delete: "Delete",
|
|
583
|
+
save: "Save",
|
|
584
|
+
cancel: "Cancel",
|
|
585
|
+
confirm: "Confirm",
|
|
586
|
+
// Messages
|
|
587
|
+
noDrawingsYet: "No drawings yet.",
|
|
588
|
+
clickNewToStart: 'Click "New drawing" to start.',
|
|
589
|
+
modified: "Modified",
|
|
590
|
+
confirmDelete: "Do you want to delete this drawing?",
|
|
591
|
+
// Shortcuts
|
|
592
|
+
shortcutNewDrawing: "Ctrl+Alt+N"
|
|
593
|
+
};
|
|
594
|
+
var translations = {
|
|
595
|
+
sv,
|
|
596
|
+
en
|
|
597
|
+
};
|
|
598
|
+
function getTranslations(langCode) {
|
|
599
|
+
if (!langCode) return en;
|
|
600
|
+
const lang = langCode.split("-")[0].toLowerCase();
|
|
601
|
+
if (lang in translations) {
|
|
602
|
+
return translations[lang];
|
|
603
|
+
}
|
|
604
|
+
return en;
|
|
605
|
+
}
|
|
606
|
+
function isLanguageSupported(langCode) {
|
|
607
|
+
if (!langCode) return false;
|
|
608
|
+
const lang = langCode.split("-")[0].toLowerCase();
|
|
609
|
+
return lang in translations;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// src/ui/Menu/WorkspaceMenuItems.tsx
|
|
546
613
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
547
614
|
var DrawingsIcon = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
548
615
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
@@ -579,6 +646,7 @@ var DefaultMenuItem = ({ icon, children, onSelect, shortcut }) => /* @__PURE__ *
|
|
|
579
646
|
}
|
|
580
647
|
);
|
|
581
648
|
var WorkspaceMenuItems = ({
|
|
649
|
+
lang,
|
|
582
650
|
onDrawingSelect,
|
|
583
651
|
onManageDrawings,
|
|
584
652
|
renderMenuItem,
|
|
@@ -586,6 +654,7 @@ var WorkspaceMenuItems = ({
|
|
|
586
654
|
renderSeparator
|
|
587
655
|
}) => {
|
|
588
656
|
const { drawings, activeDrawing, switchDrawing, createNewDrawing } = useWorkspace();
|
|
657
|
+
const t = getTranslations(lang);
|
|
589
658
|
const MenuItem = renderMenuItem || ((props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DefaultMenuItem, { ...props }));
|
|
590
659
|
const Separator = renderSeparator || (() => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("hr", { style: { margin: "4px 0", border: "none", borderTop: "1px solid #ccc" } }));
|
|
591
660
|
const handleDrawingSelect = async (drawing) => {
|
|
@@ -600,7 +669,8 @@ var WorkspaceMenuItems = ({
|
|
|
600
669
|
trigger: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
601
670
|
DrawingsIcon,
|
|
602
671
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
603
|
-
|
|
672
|
+
t.drawings,
|
|
673
|
+
" (",
|
|
604
674
|
drawings.length,
|
|
605
675
|
")"
|
|
606
676
|
] })
|
|
@@ -614,13 +684,13 @@ var WorkspaceMenuItems = ({
|
|
|
614
684
|
drawings.length > 0 && Separator(),
|
|
615
685
|
MenuItem({
|
|
616
686
|
icon: PlusIcon,
|
|
617
|
-
children:
|
|
687
|
+
children: t.newDrawing,
|
|
618
688
|
onSelect: handleNewDrawing,
|
|
619
|
-
shortcut:
|
|
689
|
+
shortcut: t.shortcutNewDrawing
|
|
620
690
|
}),
|
|
621
691
|
onManageDrawings && MenuItem({
|
|
622
692
|
icon: DrawingsIcon,
|
|
623
|
-
children:
|
|
693
|
+
children: t.manageDrawings,
|
|
624
694
|
onSelect: onManageDrawings
|
|
625
695
|
})
|
|
626
696
|
] })
|
|
@@ -629,9 +699,9 @@ var WorkspaceMenuItems = ({
|
|
|
629
699
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
630
700
|
MenuItem({
|
|
631
701
|
icon: PlusIcon,
|
|
632
|
-
children:
|
|
702
|
+
children: t.newDrawing,
|
|
633
703
|
onSelect: handleNewDrawing,
|
|
634
|
-
shortcut:
|
|
704
|
+
shortcut: t.shortcutNewDrawing
|
|
635
705
|
}),
|
|
636
706
|
drawings.slice(0, 5).map((drawing) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react4.default.Fragment, { children: MenuItem({
|
|
637
707
|
icon: activeDrawing?.id === drawing.id ? "\u2713" : DrawingsIcon,
|
|
@@ -642,7 +712,7 @@ var WorkspaceMenuItems = ({
|
|
|
642
712
|
Separator(),
|
|
643
713
|
MenuItem({
|
|
644
714
|
icon: DrawingsIcon,
|
|
645
|
-
children:
|
|
715
|
+
children: `${t.drawings} (${drawings.length})...`,
|
|
646
716
|
onSelect: onManageDrawings
|
|
647
717
|
})
|
|
648
718
|
] })
|
|
@@ -655,7 +725,8 @@ var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
|
655
725
|
var DrawingsDialog = ({
|
|
656
726
|
open,
|
|
657
727
|
onClose,
|
|
658
|
-
onDrawingSelect
|
|
728
|
+
onDrawingSelect,
|
|
729
|
+
lang
|
|
659
730
|
}) => {
|
|
660
731
|
const {
|
|
661
732
|
drawings,
|
|
@@ -665,6 +736,7 @@ var DrawingsDialog = ({
|
|
|
665
736
|
renameDrawing,
|
|
666
737
|
removeDrawing
|
|
667
738
|
} = useWorkspace();
|
|
739
|
+
const t = getTranslations(lang);
|
|
668
740
|
const [editingId, setEditingId] = (0, import_react5.useState)(null);
|
|
669
741
|
const [editName, setEditName] = (0, import_react5.useState)("");
|
|
670
742
|
const [confirmDeleteId, setConfirmDeleteId] = (0, import_react5.useState)(null);
|
|
@@ -699,8 +771,14 @@ var DrawingsDialog = ({
|
|
|
699
771
|
await removeDrawing(id);
|
|
700
772
|
setConfirmDeleteId(null);
|
|
701
773
|
}, [removeDrawing]);
|
|
774
|
+
const getLocale = () => {
|
|
775
|
+
if (!lang) return "en-US";
|
|
776
|
+
const baseLang = lang.split("-")[0].toLowerCase();
|
|
777
|
+
if (baseLang === "sv") return "sv-SE";
|
|
778
|
+
return "en-US";
|
|
779
|
+
};
|
|
702
780
|
const formatDate = (timestamp) => {
|
|
703
|
-
return new Date(timestamp).toLocaleString(
|
|
781
|
+
return new Date(timestamp).toLocaleString(getLocale(), {
|
|
704
782
|
year: "numeric",
|
|
705
783
|
month: "short",
|
|
706
784
|
day: "numeric",
|
|
@@ -756,7 +834,8 @@ var DrawingsDialog = ({
|
|
|
756
834
|
},
|
|
757
835
|
children: [
|
|
758
836
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: [
|
|
759
|
-
|
|
837
|
+
t.dialogTitle,
|
|
838
|
+
" (",
|
|
760
839
|
drawings.length,
|
|
761
840
|
")"
|
|
762
841
|
] }),
|
|
@@ -773,7 +852,7 @@ var DrawingsDialog = ({
|
|
|
773
852
|
lineHeight: 1,
|
|
774
853
|
color: "inherit"
|
|
775
854
|
},
|
|
776
|
-
"aria-label":
|
|
855
|
+
"aria-label": t.close,
|
|
777
856
|
children: "\xD7"
|
|
778
857
|
}
|
|
779
858
|
)
|
|
@@ -797,8 +876,8 @@ var DrawingsDialog = ({
|
|
|
797
876
|
color: "var(--text-secondary-color, #666)"
|
|
798
877
|
},
|
|
799
878
|
children: [
|
|
800
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children:
|
|
801
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children:
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: t.noDrawingsYet }),
|
|
880
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: t.clickNewToStart })
|
|
802
881
|
]
|
|
803
882
|
}
|
|
804
883
|
) : drawings.map((drawing) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
@@ -860,7 +939,8 @@ var DrawingsDialog = ({
|
|
|
860
939
|
marginTop: "2px"
|
|
861
940
|
},
|
|
862
941
|
children: [
|
|
863
|
-
|
|
942
|
+
t.modified,
|
|
943
|
+
": ",
|
|
864
944
|
formatDate(drawing.updatedAt)
|
|
865
945
|
]
|
|
866
946
|
}
|
|
@@ -880,7 +960,7 @@ var DrawingsDialog = ({
|
|
|
880
960
|
borderRadius: "4px",
|
|
881
961
|
cursor: "pointer"
|
|
882
962
|
},
|
|
883
|
-
children:
|
|
963
|
+
children: t.save
|
|
884
964
|
}
|
|
885
965
|
),
|
|
886
966
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -896,7 +976,7 @@ var DrawingsDialog = ({
|
|
|
896
976
|
cursor: "pointer",
|
|
897
977
|
color: "inherit"
|
|
898
978
|
},
|
|
899
|
-
children:
|
|
979
|
+
children: t.cancel
|
|
900
980
|
}
|
|
901
981
|
)
|
|
902
982
|
] }) : confirmDeleteId === drawing.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
@@ -913,7 +993,7 @@ var DrawingsDialog = ({
|
|
|
913
993
|
borderRadius: "4px",
|
|
914
994
|
cursor: "pointer"
|
|
915
995
|
},
|
|
916
|
-
children:
|
|
996
|
+
children: t.delete
|
|
917
997
|
}
|
|
918
998
|
),
|
|
919
999
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -929,7 +1009,7 @@ var DrawingsDialog = ({
|
|
|
929
1009
|
cursor: "pointer",
|
|
930
1010
|
color: "inherit"
|
|
931
1011
|
},
|
|
932
|
-
children:
|
|
1012
|
+
children: t.cancel
|
|
933
1013
|
}
|
|
934
1014
|
)
|
|
935
1015
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
@@ -947,7 +1027,7 @@ var DrawingsDialog = ({
|
|
|
947
1027
|
cursor: "pointer"
|
|
948
1028
|
},
|
|
949
1029
|
disabled: activeDrawing?.id === drawing.id,
|
|
950
|
-
children:
|
|
1030
|
+
children: t.open
|
|
951
1031
|
}
|
|
952
1032
|
),
|
|
953
1033
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -963,7 +1043,7 @@ var DrawingsDialog = ({
|
|
|
963
1043
|
cursor: "pointer",
|
|
964
1044
|
color: "inherit"
|
|
965
1045
|
},
|
|
966
|
-
title:
|
|
1046
|
+
title: t.rename,
|
|
967
1047
|
children: "\u270F\uFE0F"
|
|
968
1048
|
}
|
|
969
1049
|
),
|
|
@@ -980,7 +1060,7 @@ var DrawingsDialog = ({
|
|
|
980
1060
|
cursor: "pointer",
|
|
981
1061
|
color: "inherit"
|
|
982
1062
|
},
|
|
983
|
-
title:
|
|
1063
|
+
title: t.delete,
|
|
984
1064
|
disabled: drawings.length <= 1,
|
|
985
1065
|
children: "\u{1F5D1}\uFE0F"
|
|
986
1066
|
}
|
|
@@ -1003,7 +1083,7 @@ var DrawingsDialog = ({
|
|
|
1003
1083
|
alignItems: "center"
|
|
1004
1084
|
},
|
|
1005
1085
|
children: [
|
|
1006
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.
|
|
1086
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1007
1087
|
"button",
|
|
1008
1088
|
{
|
|
1009
1089
|
onClick: handleCreate,
|
|
@@ -1017,7 +1097,10 @@ var DrawingsDialog = ({
|
|
|
1017
1097
|
cursor: "pointer",
|
|
1018
1098
|
fontWeight: 500
|
|
1019
1099
|
},
|
|
1020
|
-
children:
|
|
1100
|
+
children: [
|
|
1101
|
+
"+ ",
|
|
1102
|
+
t.newDrawing
|
|
1103
|
+
]
|
|
1021
1104
|
}
|
|
1022
1105
|
),
|
|
1023
1106
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1033,7 +1116,7 @@ var DrawingsDialog = ({
|
|
|
1033
1116
|
cursor: "pointer",
|
|
1034
1117
|
color: "inherit"
|
|
1035
1118
|
},
|
|
1036
|
-
children:
|
|
1119
|
+
children: t.close
|
|
1037
1120
|
}
|
|
1038
1121
|
)
|
|
1039
1122
|
]
|
|
@@ -1166,7 +1249,9 @@ function WorkspacePlugin(props) {
|
|
|
1166
1249
|
getDB,
|
|
1167
1250
|
getDrawing,
|
|
1168
1251
|
getOrCreateDefaultWorkspace,
|
|
1252
|
+
getTranslations,
|
|
1169
1253
|
getWorkspace,
|
|
1254
|
+
isLanguageSupported,
|
|
1170
1255
|
removeDrawingFromWorkspace,
|
|
1171
1256
|
setActiveDrawing,
|
|
1172
1257
|
updateDrawing,
|
package/dist/index.mjs
CHANGED
|
@@ -485,6 +485,71 @@ function Sidebar({ isOpen = true, onToggle, width = 250 }) {
|
|
|
485
485
|
|
|
486
486
|
// src/ui/Menu/WorkspaceMenuItems.tsx
|
|
487
487
|
import React4 from "react";
|
|
488
|
+
|
|
489
|
+
// src/i18n/translations.ts
|
|
490
|
+
var sv = {
|
|
491
|
+
// Menu
|
|
492
|
+
drawings: "Ritningar",
|
|
493
|
+
newDrawing: "Ny ritning",
|
|
494
|
+
manageDrawings: "Hantera ritningar...",
|
|
495
|
+
// Dialog
|
|
496
|
+
dialogTitle: "Ritningar",
|
|
497
|
+
close: "St\xE4ng",
|
|
498
|
+
open: "\xD6ppna",
|
|
499
|
+
rename: "Byt namn",
|
|
500
|
+
delete: "Ta bort",
|
|
501
|
+
save: "Spara",
|
|
502
|
+
cancel: "Avbryt",
|
|
503
|
+
confirm: "Bekr\xE4fta",
|
|
504
|
+
// Messages
|
|
505
|
+
noDrawingsYet: "Inga ritningar \xE4nnu.",
|
|
506
|
+
clickNewToStart: 'Klicka "Ny ritning" f\xF6r att b\xF6rja.',
|
|
507
|
+
modified: "\xC4ndrad",
|
|
508
|
+
confirmDelete: "Vill du ta bort denna ritning?",
|
|
509
|
+
// Shortcuts
|
|
510
|
+
shortcutNewDrawing: "Ctrl+Alt+N"
|
|
511
|
+
};
|
|
512
|
+
var en = {
|
|
513
|
+
// Menu
|
|
514
|
+
drawings: "Drawings",
|
|
515
|
+
newDrawing: "New drawing",
|
|
516
|
+
manageDrawings: "Manage drawings...",
|
|
517
|
+
// Dialog
|
|
518
|
+
dialogTitle: "Drawings",
|
|
519
|
+
close: "Close",
|
|
520
|
+
open: "Open",
|
|
521
|
+
rename: "Rename",
|
|
522
|
+
delete: "Delete",
|
|
523
|
+
save: "Save",
|
|
524
|
+
cancel: "Cancel",
|
|
525
|
+
confirm: "Confirm",
|
|
526
|
+
// Messages
|
|
527
|
+
noDrawingsYet: "No drawings yet.",
|
|
528
|
+
clickNewToStart: 'Click "New drawing" to start.',
|
|
529
|
+
modified: "Modified",
|
|
530
|
+
confirmDelete: "Do you want to delete this drawing?",
|
|
531
|
+
// Shortcuts
|
|
532
|
+
shortcutNewDrawing: "Ctrl+Alt+N"
|
|
533
|
+
};
|
|
534
|
+
var translations = {
|
|
535
|
+
sv,
|
|
536
|
+
en
|
|
537
|
+
};
|
|
538
|
+
function getTranslations(langCode) {
|
|
539
|
+
if (!langCode) return en;
|
|
540
|
+
const lang = langCode.split("-")[0].toLowerCase();
|
|
541
|
+
if (lang in translations) {
|
|
542
|
+
return translations[lang];
|
|
543
|
+
}
|
|
544
|
+
return en;
|
|
545
|
+
}
|
|
546
|
+
function isLanguageSupported(langCode) {
|
|
547
|
+
if (!langCode) return false;
|
|
548
|
+
const lang = langCode.split("-")[0].toLowerCase();
|
|
549
|
+
return lang in translations;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// src/ui/Menu/WorkspaceMenuItems.tsx
|
|
488
553
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
489
554
|
var DrawingsIcon = /* @__PURE__ */ jsxs3("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
490
555
|
/* @__PURE__ */ jsx5("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
@@ -521,6 +586,7 @@ var DefaultMenuItem = ({ icon, children, onSelect, shortcut }) => /* @__PURE__ *
|
|
|
521
586
|
}
|
|
522
587
|
);
|
|
523
588
|
var WorkspaceMenuItems = ({
|
|
589
|
+
lang,
|
|
524
590
|
onDrawingSelect,
|
|
525
591
|
onManageDrawings,
|
|
526
592
|
renderMenuItem,
|
|
@@ -528,6 +594,7 @@ var WorkspaceMenuItems = ({
|
|
|
528
594
|
renderSeparator
|
|
529
595
|
}) => {
|
|
530
596
|
const { drawings, activeDrawing, switchDrawing, createNewDrawing } = useWorkspace();
|
|
597
|
+
const t = getTranslations(lang);
|
|
531
598
|
const MenuItem = renderMenuItem || ((props) => /* @__PURE__ */ jsx5(DefaultMenuItem, { ...props }));
|
|
532
599
|
const Separator = renderSeparator || (() => /* @__PURE__ */ jsx5("hr", { style: { margin: "4px 0", border: "none", borderTop: "1px solid #ccc" } }));
|
|
533
600
|
const handleDrawingSelect = async (drawing) => {
|
|
@@ -542,7 +609,8 @@ var WorkspaceMenuItems = ({
|
|
|
542
609
|
trigger: /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
543
610
|
DrawingsIcon,
|
|
544
611
|
/* @__PURE__ */ jsxs3("span", { children: [
|
|
545
|
-
|
|
612
|
+
t.drawings,
|
|
613
|
+
" (",
|
|
546
614
|
drawings.length,
|
|
547
615
|
")"
|
|
548
616
|
] })
|
|
@@ -556,13 +624,13 @@ var WorkspaceMenuItems = ({
|
|
|
556
624
|
drawings.length > 0 && Separator(),
|
|
557
625
|
MenuItem({
|
|
558
626
|
icon: PlusIcon,
|
|
559
|
-
children:
|
|
627
|
+
children: t.newDrawing,
|
|
560
628
|
onSelect: handleNewDrawing,
|
|
561
|
-
shortcut:
|
|
629
|
+
shortcut: t.shortcutNewDrawing
|
|
562
630
|
}),
|
|
563
631
|
onManageDrawings && MenuItem({
|
|
564
632
|
icon: DrawingsIcon,
|
|
565
|
-
children:
|
|
633
|
+
children: t.manageDrawings,
|
|
566
634
|
onSelect: onManageDrawings
|
|
567
635
|
})
|
|
568
636
|
] })
|
|
@@ -571,9 +639,9 @@ var WorkspaceMenuItems = ({
|
|
|
571
639
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
572
640
|
MenuItem({
|
|
573
641
|
icon: PlusIcon,
|
|
574
|
-
children:
|
|
642
|
+
children: t.newDrawing,
|
|
575
643
|
onSelect: handleNewDrawing,
|
|
576
|
-
shortcut:
|
|
644
|
+
shortcut: t.shortcutNewDrawing
|
|
577
645
|
}),
|
|
578
646
|
drawings.slice(0, 5).map((drawing) => /* @__PURE__ */ jsx5(React4.Fragment, { children: MenuItem({
|
|
579
647
|
icon: activeDrawing?.id === drawing.id ? "\u2713" : DrawingsIcon,
|
|
@@ -584,7 +652,7 @@ var WorkspaceMenuItems = ({
|
|
|
584
652
|
Separator(),
|
|
585
653
|
MenuItem({
|
|
586
654
|
icon: DrawingsIcon,
|
|
587
|
-
children:
|
|
655
|
+
children: `${t.drawings} (${drawings.length})...`,
|
|
588
656
|
onSelect: onManageDrawings
|
|
589
657
|
})
|
|
590
658
|
] })
|
|
@@ -592,12 +660,13 @@ var WorkspaceMenuItems = ({
|
|
|
592
660
|
};
|
|
593
661
|
|
|
594
662
|
// src/ui/Dialog/DrawingsDialog.tsx
|
|
595
|
-
import { useState as
|
|
663
|
+
import { useState as useState4, useCallback as useCallback2 } from "react";
|
|
596
664
|
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
597
665
|
var DrawingsDialog = ({
|
|
598
666
|
open,
|
|
599
667
|
onClose,
|
|
600
|
-
onDrawingSelect
|
|
668
|
+
onDrawingSelect,
|
|
669
|
+
lang
|
|
601
670
|
}) => {
|
|
602
671
|
const {
|
|
603
672
|
drawings,
|
|
@@ -607,9 +676,10 @@ var DrawingsDialog = ({
|
|
|
607
676
|
renameDrawing,
|
|
608
677
|
removeDrawing
|
|
609
678
|
} = useWorkspace();
|
|
610
|
-
const
|
|
611
|
-
const [
|
|
612
|
-
const [
|
|
679
|
+
const t = getTranslations(lang);
|
|
680
|
+
const [editingId, setEditingId] = useState4(null);
|
|
681
|
+
const [editName, setEditName] = useState4("");
|
|
682
|
+
const [confirmDeleteId, setConfirmDeleteId] = useState4(null);
|
|
613
683
|
const handleSelect = useCallback2(async (drawing) => {
|
|
614
684
|
await switchDrawing(drawing.id);
|
|
615
685
|
onDrawingSelect?.(drawing);
|
|
@@ -641,8 +711,14 @@ var DrawingsDialog = ({
|
|
|
641
711
|
await removeDrawing(id);
|
|
642
712
|
setConfirmDeleteId(null);
|
|
643
713
|
}, [removeDrawing]);
|
|
714
|
+
const getLocale = () => {
|
|
715
|
+
if (!lang) return "en-US";
|
|
716
|
+
const baseLang = lang.split("-")[0].toLowerCase();
|
|
717
|
+
if (baseLang === "sv") return "sv-SE";
|
|
718
|
+
return "en-US";
|
|
719
|
+
};
|
|
644
720
|
const formatDate = (timestamp) => {
|
|
645
|
-
return new Date(timestamp).toLocaleString(
|
|
721
|
+
return new Date(timestamp).toLocaleString(getLocale(), {
|
|
646
722
|
year: "numeric",
|
|
647
723
|
month: "short",
|
|
648
724
|
day: "numeric",
|
|
@@ -698,7 +774,8 @@ var DrawingsDialog = ({
|
|
|
698
774
|
},
|
|
699
775
|
children: [
|
|
700
776
|
/* @__PURE__ */ jsxs4("h2", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: [
|
|
701
|
-
|
|
777
|
+
t.dialogTitle,
|
|
778
|
+
" (",
|
|
702
779
|
drawings.length,
|
|
703
780
|
")"
|
|
704
781
|
] }),
|
|
@@ -715,7 +792,7 @@ var DrawingsDialog = ({
|
|
|
715
792
|
lineHeight: 1,
|
|
716
793
|
color: "inherit"
|
|
717
794
|
},
|
|
718
|
-
"aria-label":
|
|
795
|
+
"aria-label": t.close,
|
|
719
796
|
children: "\xD7"
|
|
720
797
|
}
|
|
721
798
|
)
|
|
@@ -739,8 +816,8 @@ var DrawingsDialog = ({
|
|
|
739
816
|
color: "var(--text-secondary-color, #666)"
|
|
740
817
|
},
|
|
741
818
|
children: [
|
|
742
|
-
/* @__PURE__ */ jsx6("p", { children:
|
|
743
|
-
/* @__PURE__ */ jsx6("p", { children:
|
|
819
|
+
/* @__PURE__ */ jsx6("p", { children: t.noDrawingsYet }),
|
|
820
|
+
/* @__PURE__ */ jsx6("p", { children: t.clickNewToStart })
|
|
744
821
|
]
|
|
745
822
|
}
|
|
746
823
|
) : drawings.map((drawing) => /* @__PURE__ */ jsxs4(
|
|
@@ -802,7 +879,8 @@ var DrawingsDialog = ({
|
|
|
802
879
|
marginTop: "2px"
|
|
803
880
|
},
|
|
804
881
|
children: [
|
|
805
|
-
|
|
882
|
+
t.modified,
|
|
883
|
+
": ",
|
|
806
884
|
formatDate(drawing.updatedAt)
|
|
807
885
|
]
|
|
808
886
|
}
|
|
@@ -822,7 +900,7 @@ var DrawingsDialog = ({
|
|
|
822
900
|
borderRadius: "4px",
|
|
823
901
|
cursor: "pointer"
|
|
824
902
|
},
|
|
825
|
-
children:
|
|
903
|
+
children: t.save
|
|
826
904
|
}
|
|
827
905
|
),
|
|
828
906
|
/* @__PURE__ */ jsx6(
|
|
@@ -838,7 +916,7 @@ var DrawingsDialog = ({
|
|
|
838
916
|
cursor: "pointer",
|
|
839
917
|
color: "inherit"
|
|
840
918
|
},
|
|
841
|
-
children:
|
|
919
|
+
children: t.cancel
|
|
842
920
|
}
|
|
843
921
|
)
|
|
844
922
|
] }) : confirmDeleteId === drawing.id ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
@@ -855,7 +933,7 @@ var DrawingsDialog = ({
|
|
|
855
933
|
borderRadius: "4px",
|
|
856
934
|
cursor: "pointer"
|
|
857
935
|
},
|
|
858
|
-
children:
|
|
936
|
+
children: t.delete
|
|
859
937
|
}
|
|
860
938
|
),
|
|
861
939
|
/* @__PURE__ */ jsx6(
|
|
@@ -871,7 +949,7 @@ var DrawingsDialog = ({
|
|
|
871
949
|
cursor: "pointer",
|
|
872
950
|
color: "inherit"
|
|
873
951
|
},
|
|
874
|
-
children:
|
|
952
|
+
children: t.cancel
|
|
875
953
|
}
|
|
876
954
|
)
|
|
877
955
|
] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
@@ -889,7 +967,7 @@ var DrawingsDialog = ({
|
|
|
889
967
|
cursor: "pointer"
|
|
890
968
|
},
|
|
891
969
|
disabled: activeDrawing?.id === drawing.id,
|
|
892
|
-
children:
|
|
970
|
+
children: t.open
|
|
893
971
|
}
|
|
894
972
|
),
|
|
895
973
|
/* @__PURE__ */ jsx6(
|
|
@@ -905,7 +983,7 @@ var DrawingsDialog = ({
|
|
|
905
983
|
cursor: "pointer",
|
|
906
984
|
color: "inherit"
|
|
907
985
|
},
|
|
908
|
-
title:
|
|
986
|
+
title: t.rename,
|
|
909
987
|
children: "\u270F\uFE0F"
|
|
910
988
|
}
|
|
911
989
|
),
|
|
@@ -922,7 +1000,7 @@ var DrawingsDialog = ({
|
|
|
922
1000
|
cursor: "pointer",
|
|
923
1001
|
color: "inherit"
|
|
924
1002
|
},
|
|
925
|
-
title:
|
|
1003
|
+
title: t.delete,
|
|
926
1004
|
disabled: drawings.length <= 1,
|
|
927
1005
|
children: "\u{1F5D1}\uFE0F"
|
|
928
1006
|
}
|
|
@@ -945,7 +1023,7 @@ var DrawingsDialog = ({
|
|
|
945
1023
|
alignItems: "center"
|
|
946
1024
|
},
|
|
947
1025
|
children: [
|
|
948
|
-
/* @__PURE__ */
|
|
1026
|
+
/* @__PURE__ */ jsxs4(
|
|
949
1027
|
"button",
|
|
950
1028
|
{
|
|
951
1029
|
onClick: handleCreate,
|
|
@@ -959,7 +1037,10 @@ var DrawingsDialog = ({
|
|
|
959
1037
|
cursor: "pointer",
|
|
960
1038
|
fontWeight: 500
|
|
961
1039
|
},
|
|
962
|
-
children:
|
|
1040
|
+
children: [
|
|
1041
|
+
"+ ",
|
|
1042
|
+
t.newDrawing
|
|
1043
|
+
]
|
|
963
1044
|
}
|
|
964
1045
|
),
|
|
965
1046
|
/* @__PURE__ */ jsx6(
|
|
@@ -975,7 +1056,7 @@ var DrawingsDialog = ({
|
|
|
975
1056
|
cursor: "pointer",
|
|
976
1057
|
color: "inherit"
|
|
977
1058
|
},
|
|
978
|
-
children:
|
|
1059
|
+
children: t.close
|
|
979
1060
|
}
|
|
980
1061
|
)
|
|
981
1062
|
]
|
|
@@ -1030,14 +1111,14 @@ function useExcalidrawBridge({
|
|
|
1030
1111
|
}
|
|
1031
1112
|
|
|
1032
1113
|
// src/WorkspacePlugin.tsx
|
|
1033
|
-
import { useState as
|
|
1114
|
+
import { useState as useState5, useEffect as useEffect4, useCallback as useCallback4 } from "react";
|
|
1034
1115
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1035
1116
|
function WorkspacePluginInner({
|
|
1036
1117
|
children,
|
|
1037
1118
|
defaultSidebarOpen = true,
|
|
1038
1119
|
sidebarWidth = 250
|
|
1039
1120
|
}) {
|
|
1040
|
-
const [sidebarOpen, setSidebarOpen] =
|
|
1121
|
+
const [sidebarOpen, setSidebarOpen] = useState5(defaultSidebarOpen);
|
|
1041
1122
|
const { activeDrawing } = useWorkspace();
|
|
1042
1123
|
useEffect4(() => {
|
|
1043
1124
|
const handleKeyDown = (e) => {
|
|
@@ -1107,7 +1188,9 @@ export {
|
|
|
1107
1188
|
getDB,
|
|
1108
1189
|
getDrawing,
|
|
1109
1190
|
getOrCreateDefaultWorkspace,
|
|
1191
|
+
getTranslations,
|
|
1110
1192
|
getWorkspace,
|
|
1193
|
+
isLanguageSupported,
|
|
1111
1194
|
removeDrawingFromWorkspace,
|
|
1112
1195
|
setActiveDrawing,
|
|
1113
1196
|
updateDrawing,
|