# ROADMAP — appRobotFileservice Web-UI (Datei-Browser) ## Ziel Einfache Web-Oberfläche direkt auf Port 2100, die GCode-Programme verwaltet. Kein Framework, kein Build-Schritt — reines HTML/CSS/JS, serviert als static files. --- ## Phase 1 — Datei-Browser (aktuell implementiert) **Dateien:** `public/index.html`, `public/index.css` ### Funktionen | Feature | Status | Endpunkt | |---|---|---| | Programm-Liste laden | ✅ | `GET /api/programs` | | Aktives Programm anzeigen (Zeilenliste in Grad) | ✅ | `GET /api/active` | | Programm als aktiv setzen (FLoad) | ✅ | `PUT /api/active` | | Programm löschen | ✅ | `DELETE /api/programs/:id` | | Stepping: First / Prev / Next / Last | ✅ | `POST /api/active/first|prev|next|last` | | Programm leeren (FClear) | ✅ | `POST /api/active/clear` | | Cursor in Tabelle hervorheben + auto-scrollen | ✅ | — | | Auto-Refresh (5 s Polling) | ✅ | — | | Collapse-Karten (wie appRobotHoming) | ✅ | — | ### Was Phase 1 noch fehlt - **Download `.gcode`** — Endpunkt `GET /api/programs/:id/download` muss im Server hinzugefügt werden (liefert die rohe Datei mit `Content-Disposition: attachment`). - **Upload `.gcode`** — Datei vom Desktop in den Service laden (Phase 2). - **Umbenennen** — `PUT /api/programs/:id` mit neuem `name`. --- ## Phase 2 — Datei-Verwaltung ### Download-Endpunkt (kleines Backend-Feature für Phase 1.5) ``` GET /api/programs/:id/download → Content-Type: text/plain → Content-Disposition: attachment; filename=".gcode" → Body: rohe .gcode-Datei ``` Implementierung: 1 Route in `src/routes/programs.js` + `store.gcodePath(id)`. ### Upload ``` POST /api/programs/upload Body: multipart/form-data { file: } → speichert unter slugify(filename) in GCodeFiles/ ``` Im Frontend: `` + `FormData` fetch. ### Umbenennen / Metadaten bearbeiten `PUT /api/programs/:id` ist bereits vorhanden — nur das Frontend-Formular fehlt. Inline-Eingabefeld in der Programm-Zeile, Enter → PUT. --- ## Phase 3 — Verzeichnis-Navigation Aktuell: alles flach im `GCodeFiles/`-Ordner. Später: Unterordner für Projekte (z. B. `GCodeFiles/greifen/`, `GCodeFiles/ablegen/`). ### Backend Neue Konfiguration: `storageDir` bleibt Wurzel; zusätzlicher optionaler `subDir`-Parameter. ``` GET /api/programs?dir=greifen → listet GCodeFiles/greifen/ PUT /api/active { id, dir } → lädt GCodeFiles//.gcode POST /api/dirs { name } → legt Unterordner an DELETE /api/dirs/:name → löscht (leer) Unterordner ``` Wichtig: Pfad-Traversal verhindern — `assertValidId` auf jede Pfad-Komponente anwenden. ### Frontend Breadcrumb-Leiste oberhalb der Programmliste: ``` GCodeFiles/ > greifen/ > [zurück] ``` Doppelklick auf Ordner-Zeile → navigiert hinein. Klick auf Breadcrumb-Segment → navigiert zurück. --- ## Phase 4 — Live-Updates (WebSocket oder SSE) Aktuell: Polling alle 5 s. Besser: Server-Sent Events (SSE) oder WebSocket, damit die UI sofort reagiert wenn der Driver per FPoint einen neuen Punkt schreibt. ### Option A — Server-Sent Events (einfach, read-only) ``` GET /api/events → text/event-stream → event: active-changed\ndata: \n\n ``` Der Fileservice emittiert nach jedem `_persist()` ein SSE-Event. Frontend: `new EventSource('/api/events')` statt `setInterval`. ### Option B — WebSocket (bidirektional, für spätere Steuerung) Erlaubt auch WS-basierte FCode-Befehle direkt von der Web-UI. Aufwändiger, aber konsistent mit dem Driver-Pattern. **Empfehlung für Phase 4:** SSE — eine Zeile Mehraufwand gegenüber Polling, kein zusätzliches Protokoll. --- ## Phase 5 — Inline-Editor Einzelne Zeilen direkt im Browser bearbeiten. ``` PUT /api/active/lines/:index { line: "G90 G1 x0 y300 z0 a90.00 …" } DELETE /api/active/lines/:index POST /api/active/lines { line, atIndex } ``` Alle drei Endpunkte sind bereits im Backend implementiert. Frontend: Klick auf Tabellenzeile → `` erscheint inline; Escape abbricht, Enter speichert. --- ## Datei-Übersicht (nach Phase 1) ``` appRobotFileservice/ public/ index.html HTML-Struktur + JavaScript (inline) index.css Design-System (identisch mit appRobotHoming/styles.css) doc/ fileBrowser_ROADMAP.md diese Datei src/ server.js +express.static('public/') routes/ programs.js TODO Phase 2: /download-Endpunkt active.js komplett ```