feat: enhance canvas and layout components with new features and improvements
- Added remote image patterns to the Next.js configuration for enhanced image handling. - Updated TypeScript configuration to exclude the 'implement' directory. - Refactored layout component to fetch initial authentication token and pass it to Providers. - Replaced CanvasToolbar with CanvasSidebar for improved UI layout and functionality. - Enhanced Canvas component with new drag-and-drop file upload capabilities and batch node movement. - Updated various node components to support new status handling and improved user interactions. - Added debounced saving for note and prompt nodes to optimize performance.
This commit is contained in:
103
implement/README.md
Normal file
103
implement/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Bild-Upload via Convex Storage — Einbau-Anleitung
|
||||
|
||||
## Konzept
|
||||
|
||||
Der Upload-Flow nutzt Convex File Storage in 3 Schritten:
|
||||
1. **generateUploadUrl** → kurzlebige Upload-URL vom Backend
|
||||
2. **fetch(POST)** → Datei direkt an Convex Storage senden
|
||||
3. **updateData** → `storageId` im Node speichern
|
||||
|
||||
Die **URL wird serverseitig** in der `nodes.list` Query aufgelöst — nicht
|
||||
am Client. Das heißt: der Node speichert nur die `storageId`, und bei
|
||||
jedem Query-Aufruf wird `ctx.storage.getUrl(storageId)` aufgerufen und
|
||||
als `data.url` zurückgegeben.
|
||||
|
||||
## Dateien
|
||||
|
||||
```
|
||||
upload-files/
|
||||
convex/
|
||||
storage.ts → convex/storage.ts (NEU)
|
||||
nodes-list-patch.ts → PATCH für convex/nodes.ts (NUR die list Query ersetzen)
|
||||
components/canvas/nodes/
|
||||
image-node.tsx → ERSETZT alte Version
|
||||
|
||||
Gesamt: 3 Dateien (1 neu, 1 Patch, 1 Ersatz)
|
||||
```
|
||||
|
||||
## Einbau-Schritte
|
||||
|
||||
### 1. `convex/storage.ts` anlegen
|
||||
Kopiere die Datei direkt. Sie enthält eine einzige Mutation: `generateUploadUrl`.
|
||||
|
||||
### 2. `convex/nodes.ts` — `list` Query patchen
|
||||
Ersetze **nur die `list` Query** in deiner bestehenden `convex/nodes.ts`
|
||||
mit der Version aus `nodes-list-patch.ts`. Der Rest der Datei
|
||||
(create, move, resize, etc.) bleibt unverändert.
|
||||
|
||||
Die Änderung: Nach dem `collect()` wird über alle Nodes iteriert.
|
||||
Wenn ein Node `data.storageId` hat, wird `ctx.storage.getUrl()` aufgerufen
|
||||
und das Ergebnis als `data.url` eingefügt.
|
||||
|
||||
**Wichtig:** Du brauchst den `Id` Import oben in der Datei:
|
||||
```ts
|
||||
import type { Doc, Id } from "./_generated/dataModel";
|
||||
```
|
||||
(Du hast `Doc` wahrscheinlich schon importiert — füge `Id` hinzu falls nötig.)
|
||||
|
||||
### 3. `image-node.tsx` ersetzen
|
||||
Die neue Version hat:
|
||||
- **Click-to-Upload**: Klick auf den leeren Node öffnet File-Picker
|
||||
- **Drag & Drop**: Bilder direkt auf den Node ziehen (Files vom OS)
|
||||
- **Ersetzen-Button**: Wenn bereits ein Bild vorhanden, oben rechts "Ersetzen"
|
||||
- **Upload-Spinner**: Während des Uploads dreht sich ein Spinner
|
||||
- **Dateiname**: Wird unter dem Bild angezeigt
|
||||
|
||||
## Upload-Flow im Detail
|
||||
|
||||
```
|
||||
User zieht Bild auf Image-Node
|
||||
│
|
||||
├─ handleDrop() → uploadFile(file)
|
||||
│
|
||||
├─ 1. generateUploadUrl() → Convex Mutation
|
||||
│ ← postUrl (kurzlebig)
|
||||
│
|
||||
├─ 2. fetch(postUrl, { body: file })
|
||||
│ ← { storageId: "kg..." }
|
||||
│
|
||||
├─ 3. updateData({ nodeId, data: { storageId, filename, mimeType } })
|
||||
│ → Convex speichert storageId im Node
|
||||
│
|
||||
└─ 4. nodes.list Query feuert automatisch neu (Realtime)
|
||||
→ ctx.storage.getUrl(storageId) → data.url
|
||||
→ Image-Node rendert das Bild
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Test 1: Click-to-Upload
|
||||
- Erstelle einen Image-Node (Sidebar oder Toolbar)
|
||||
- Klicke auf "Klicken oder hierhin ziehen"
|
||||
- ✅ File-Picker öffnet sich
|
||||
- Wähle ein Bild (PNG/JPG/WebP)
|
||||
- ✅ Spinner erscheint kurz, dann wird das Bild angezeigt
|
||||
- ✅ Convex Dashboard: `data.storageId` ist gesetzt
|
||||
|
||||
### Test 2: Drag & Drop (File vom OS)
|
||||
- Ziehe ein Bild aus dem Finder/Explorer direkt auf den Image-Node
|
||||
- ✅ Drop-Zone wird blau hervorgehoben
|
||||
- ✅ Bild wird hochgeladen und angezeigt
|
||||
|
||||
### Test 3: Bild ersetzen
|
||||
- Klicke "Ersetzen" oben rechts am Image-Node
|
||||
- Wähle ein neues Bild
|
||||
- ✅ Altes Bild wird ersetzt, neue storageId in Convex
|
||||
|
||||
### Test 4: URL wird serverseitig aufgelöst
|
||||
- Lade die Seite neu
|
||||
- ✅ Bild wird weiterhin angezeigt (URL wird bei jedem Query neu aufgelöst)
|
||||
|
||||
### Test 5: Nicht-Bild-Dateien werden ignoriert
|
||||
- Versuche eine .txt oder .pdf auf den Node zu ziehen
|
||||
- ✅ Nichts passiert (nur image/* wird akzeptiert)
|
||||
Reference in New Issue
Block a user