4.4 KiB
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 |
| 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— EndpunktGET /api/programs/:id/downloadmuss im Server hinzugefügt werden (liefert die rohe Datei mitContent-Disposition: attachment). - Upload
.gcode— Datei vom Desktop in den Service laden (Phase 2). - Umbenennen —
PUT /api/programs/:idmit neuemname.
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="<id>.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: <gcode-Datei> }
→ speichert unter slugify(filename) in GCodeFiles/
Im Frontend: <input type="file" accept=".gcode,.ngc"> + 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/<dir>/<id>.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: <ActiveState-JSON>\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 → <input> 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