Beim Doku-Abgleich der Baustelle-PWA gefunden: - BERICHT_TAB_ON_THIRDPARTY wird seit 1.7.1 (Hook completeTabsHead) nirgends mehr ausgewertet, der Reiter ist nicht mehr abschaltbar - CLAUDE.md steht auf 1.5.1 und nennt die falsche PWA-Adresse, README nennt fuer die Konstante Default 0 (Descriptor: 1) Nur Notiz, keine Code-Aenderung. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
14 KiB
ROADMAP — Modul Bericht
Stand: 2026-08-22 · Version im Repo: 1.5.1
Diese Datei war mit
eb37a4bgelöscht worden, weil alle Punkte abgehakt waren. Sie bleibt ab jetzt liegen — erledigte Punkte werden abgehakt, nicht entfernt.
0. API-Seite für die Baustelle-PWA ✅ 1.5.1
Die PWA (data/baustelle-pwa) spricht ausschließlich api/. Mit 1.5.0 war Infrastruktur
entstanden, die dort nicht ankam — mit 1.5.1 nachgezogen. Gegenstück: ROADMAP.md im PWA-Repo, Abschnitt 1.
api/photo.php:size=thumb&w=<px>✅ 1.5.1 — bis dahin lieferte der Endpoint nur ein Thumbnail, wenn Dolibarr schon eines unterthumbs/<name>_small.<ext>erzeugt hat. Fotos aus der PWA kommen überorders.php?action=upload_photoherein, und dort läuft keinvignette()— es gibt also nie eins, und die PWA lädt für jede Kachel das volle Foto.bericht_attachment_thumb()(1.5.0, GD + Cache + EXIF-Rotation) macht genau das Richtige und ist über die bereits eingebundenelib/bericht.lib.phperreichbar. Dazu ETag aus der mtime, damit wiederholte Aufrufe mit 304 enden.api/orders.php?action=photos:taken_at✅ 1.5.1 — sortiert wurde nachfilemtime. Der Editor nutzt seit 1.5.0 die EXIF-Aufnahmezeit (bericht_file_taken_at(), eigener Parser weil im Prod-Container keinexif-Modul). Bei Uploads aus der Galerie ist die Upload-Zeit die falsche Reihenfolge.api/reports.php:titleimpages-Array ✅ 1.5.1 —api/pages.phpkonnte den Seitentitel setzen und die PWA rendert ihn, aber das Detail gab ihn nicht aus. Der Titel wirkte in der PWA deshalb, als würde er nicht gespeichert.api/reports.php:composite_pathimpages-Array ✅ 1.5.1 — die PWA zeigtesource_path, also das Rohbild ohne Anmerkungen. Bei Raster-Layouts (grid_2…grid_6,before_after) ist das nur eines von bis zu sechs Bildern, beititle_onlygar keins (die PWA zeigte dann eine ❌-Kachel).- Neu:
api/note.php✅ 1.5.1 — Textnotizen zum Auftrag (Liste, Lesen, Anlegen, Ändern, Löschen). Ablage wie bei der Sprachnotiz:notiz_<betreff>_<datum>.txtim Auftrags-Verzeichnis, damit die Notiz auch im Dolibarr-Auftrag und in der Anhänge-Spalte des Editors auftaucht. Derfile-Parameter ist gegen ein Muster geprüft (Pfad-Ausbruch).
Gegenstück in der PWA: siehe ROADMAP.md im Repo baustelle-pwa, Abschnitte 1 und 3 —
dort ebenfalls erledigt.
1. Anhänge-Spalte (links im Editor) — Hauptbaustelle
Ausgangslage (Eddy, 21.08.2026): „die Dateinamen können in dem schmalen Fenster nicht ganz
angezeigt werden, ich habe Schwierigkeiten die richtigen Bilder auszusuchen."
Die Spalte ist 260 px breit und zeigt pro Datei nur eine Zeile 🖼 langer_dateiname… 2,3 MB 🗑️.
Bei 20–40 Baustellenfotos mit Namen wie IMG_20260812_141233_HDR.jpg ist das unbrauchbar.
1.1 Miniatur-Vorschau statt Dateiname ✅ 1.5.0
- Kachel-Raster (2 Spalten) statt Liste
- Server-Thumbnails für Bilder (GD, gecacht) — Original-Handyfotos werden nicht mehr voll geladen
- PDF-Anhänge: Seite 1 als Miniatur (PDF.js, clientseitig, lazy)
- Klick auf Miniatur → Lightbox (Zoom/Pan/Swipe),
✕bzw. Esc schließt — PDFs im Vollbild-Viewer - Dateiname zweizeilig unter der Kachel + voller Name als Tooltip
1.2 Auswahl bedienbar machen ✅ 1.5.0
- Checkbox als Overlay auf der Kachel (großes Klickziel), Klick auf die Namenszeile wählt ebenfalls aus
- Auswahl-Reihenfolge sichtbar (① ② ③) — bestimmt die Slot-Reihenfolge im Grid-Layout (vorher: DOM-Reihenfolge, also nicht steuerbar)
- „Alle / Keine" pro Herkunfts-Gruppe + Zähler „3 ausgewählt"
- Bereits im Bericht verwendete Anhänge werden markiert (✓-Badge, ausgegraut)
1.3 Sortierung und Filter ✅ 1.5.0
- Sortierung nach Aufnahmezeit (auf- und absteigend), Name, Größe — jeweils innerhalb der Herkunfts-Gruppe, damit die Zuordnung zum Beleg erhalten bleibt
- Filter: alle · nur Bilder · nur PDFs · noch nicht verwendet
- Aufnahmezeit steht unter der Kachel (
12.08. 11:48 · 56 Kb) - EXIF-Parser in PHP (
bericht_jpeg_taken_at), weil dasexif-Modul im Container90-Dolibarr-Prod-Customnicht geladen ist. Gegen das PHP-Modul geprüft: identische Werte. Fallback auf das Dateidatum, wenn kein EXIF vorhanden ist. - Auswahl von Sortierung/Filter/Ansicht wird gemerkt (localStorage)
1.4 Spaltenbreite, Kachelgröße, Ziehen und Ablegen ✅ 1.5.0
- Spaltenbreite ziehbar — Trennlinie zwischen Anhängen und Arbeitsfläche (150–620 px), Doppelklick setzt auf 260 px zurück; Breite wird gemerkt
- Ein-/ausklappbar über „«" in der Kopfzeile — eingeklappt bleiben 26 px stehen
- Kachelgröße klein / mittel / groß über „⤢" (in der kleinsten Stufe entfällt die Größenangabe)
- Kachel auf die Seitenliste ziehen → neue Seite(n). Sind mehrere Kacheln angekreuzt und man zieht eine davon, kommen alle mit.
- Kachel auf die Arbeitsfläche ziehen → ersetzt das Bild der offenen Seite
- Kachel auf einen Raster-Platz ziehen → setzt genau diesen Platz
- Dateien vom Rechner auf die Spalte ziehen → Upload (nicht unterstützte Typen werden benannt und übersprungen)
- SortableJS bekam
group: {put: false}— sonst streiten sich Sortierung und Ablegen um die gleichen Ereignisse
2. Seitenansicht ("Arbeitstisch") ✅ 1.5.0
Vorher zeigte der Editor ein A4-Blatt, auf dem das Foto formatfüllend lag. Beim PDF wurde dieses ganze Blatt nochmal in den Satzspiegel eingepasst — der Inhalt schrumpfte also ein zweites Mal, und die Vorschau entsprach nicht dem Ergebnis. Seiten, die nie im Editor gespeichert wurden, liefen zudem über den Kopfbereich (Logo/Titel) hinweg.
- Eine gemeinsame Geometrie-Quelle:
bericht_page_geometry($format, $orientation, $has_note)inlib/bericht.lib.php— liefert Seitenmaß, Ränder (10 mm), Kopfbereich (30 mm), Fußbereich (16 mm), Notizzone und den Inhaltsbereich. Editor und PDF rechnen damit. - Arbeitsfläche = Inhaltsbereich. Drumherum das Blatt mit schraffierter Kopf-/Fußzone (das, was TCPDF selbst druckt) und einer Notizzone, sobald die Seite eine Notiz hat.
- PDF setzt das Composite 1:1 in den Inhaltsbereich statt es erneut einzupassen
- Alle Layout-Zweige der PDF-Erzeugung (Einzelbild, Raster, Vorher/Nachher, Notiz)
auf dieselbe Geometrie umgestellt — vorher rechneten sie mit
margin = 10ab Blattkante und schoben Bilder unter den Kopfbereich - Raster-Vorschau (
ajax/page_image.php) rendert im Format des Inhaltsbereichs - Umschalter „📐 Rand" in der Werkzeugleiste (Zustand wird gemerkt)
- Rückwärtskompatibel: Composites aus der Zeit davor haben Blatt-Proportion und werden an der Proportion erkannt und proportional eingepasst statt verzerrt
3. Bild einer Seite austauschen ✅ 1.5.0
ajax/replace_page_source.php— tauscht die Quelle einer Seite; Reihenfolge, Notiz und Anmerkungen bleiben erhalten (vorher: Seite löschen und hinten neu anhängen)- Raster-Seiten: einzelner Platz austauschbar (nutzt das vorhandene
set_slot_image.php, für das es bis dahin keine Bedienung gab) - Bedienung: „🔄" auf der Seitenminiatur → Statusleiste am unteren Rand → links auf das Ersatzbild klicken. Esc bricht ab. Bei Rastern vorher den Platz (1…n) wählen.
- Finalisierte Berichte werden serverseitig abgewiesen
4. Editor / Arbeitsablauf
- Kein
location.reload()mehr ✅ 1.5.0 — Hinzufügen, Löschen, Hochladen, Bildtausch und der QR-Upload aktualisieren nur noch die betroffenen Listen. Neuer Endpointajax/fragments.phpliefert Seiten- und Anhängeliste als HTML; gerendert wird überbericht_print_page_list()/bericht_print_attachment_list(), dieselben Funktionen wie beim Seitenaufbau. Der Editor bleibt auf der bearbeiteten Seite, Zoom und Ansicht bleiben erhalten. Einzige Ausnahme: nach dem Finalisieren wird bewusst neu geladen, weil der Bericht den Status wechselt und die ganze Karte anders aussieht. - Autosave ✅ 1.5.0 — 4 Sekunden nach der letzten Änderung wird gespeichert, ebenso beim Seitenwechsel und beim Wegschalten des Tabs. Zustand steht in der Fußleiste („● nicht gespeichert" / „✓ gespeichert"), beim Verlassen der Seite warnt der Browser. Wichtig: das Aufbauen einer Seite (und Zoomen) löst Fabric-Events aus, zählt aber nicht als Änderung — sonst stünde direkt nach dem Öffnen „nicht gespeichert" da.
- Tastenkürzel ✅ 1.5.0 — V/P/R/K/A/T für die Werkzeuge, Entf löscht die Auswahl (das Hintergrundbild ist ausgenommen), Strg+Z/Y, Strg+S, ↑/↓ blättert durch die Seiten. In Eingabefeldern und bei offenem Dialog oder offener Großansicht greifen sie nicht. Die Kürzel stehen in den Tooltips der Schaltflächen.
- Seitenliste: Mehrfachauswahl ✅ 1.5.0 — Klick auf die Seitennummer markiert, Umschalt
erweitert bis dorthin. Sammelleiste mit Verdoppeln (⧉), Löschen (🗑️) und Aufheben (Esc).
Neuer Endpoint
ajax/page_bulk.php; Kopien landen direkt hinter ihrem Original (bericht_reorder_with_copies()), nach dem Löschen wird lückenlos neu nummeriert.composite_pathwird bewusst nicht mitkopiert — sonst zeigten beide Seiten auf dieselbe Datei und das Bearbeiten der einen überschriebe die andere. - Raster-Plätze direkt anklicken ✅ 1.5.0 — über der Arbeitsfläche liegt ein Gitter mit
einer Schaltfläche je Platz (bei Vorher/Nachher entsprechend beschriftet). Klick setzt das
links ausgewählte Bild, Ablegen per Drag setzt das gezogene. Die Aufteilung entspricht
BerichtPage::slotRectsInBox(). Die Plätze reagieren nur im Auswahlmodus — beim Zeichnen haben die Werkzeuge Vorrang, sonst käme man auf Raster-Seiten nicht mehr zum Zeichnen. - Seitenwechsel serialisiert ✅ 1.5.0 — beim schnellen Durchklicken überlappten sich zwei
Durchläufe von
loadPage(): der zweite speicherte die noch nicht umgeschaltete Seite ein zweites Mal, und beide rendern in denselben Canvas — so konnte die Notiz der einen Seite bei der anderen landen. Jeder Aufruf bekommt jetzt eine Nummer und bricht ab, sobald ein neuerer gestartet ist.
5. Kleinkram / Fixes
- Mehrfach-Upload:
bindExtraUploadverarbeitete nurinp.files[0]— Mehrfachauswahl im Dateidialog war möglich, es kam aber nur eine Datei an ✅ 1.5.0 - Upload-Fortschritt ✅ 1.5.0 — der Knopf zeigt beim Mehrfach-Upload „⏳ 3 / 8"
att-deletelöscht die Datei wirklich aus den Dokumenten des Belegs ✅ 1.5.0 — der Dialog sagt das jetzt deutlich und warnt zusätzlich, wenn die Datei im Bericht in Gebrauch ist.BERICHT_TAB_ON_THIRDPARTYist seit 1.7.1 tot (gefunden 2026-09-18 beim Doku-Abgleich): Der Descriptor legt die Konstante weiter an (Default1), aber seit der Reiter an der Kundenkarte über den HookcompleteTabsHeadkommt, fragt sie niemand mehr ab (grep -rn TAB_ON_THIRDPARTYfindet nur Descriptor, README, CLAUDE.md, ChangeLog). Der Reiter lässt sich also nicht mehr abschalten. Entweder im Hook auswerten (getDolGlobalInt('BERICHT_TAB_ON_THIRDPARTY', 1)) oder Konstante samt Admin-Schalter entfernen.- Doku-Drift im Modul (gefunden 2026-09-18, zentrale Spec
dolibarr-docs/module/bericht.mdist bereits auf 1.7.1 nachgezogen):CLAUDE.mdträgt noch „Stand 2026-08-22 (Version 1.5.1)" und nennt als PWA-Hostingawl.data-it-solution.de/baustelle/— tatsächlich/custom/baustelle/(Manifeststart_url, Prod-Zugriffslog).README.mdnennt fürBERICHT_TAB_ON_THIRDPARTYden Default0, der Descriptor setzt1. 1.6.0 (md5-Abgleich), 1.7.0 (Fotoqualität,api/config.php) und 1.7.1 (Hook-Reiter) fehlen inCLAUDE.mdganz. → eigener/docs-Lauf im Bericht-Repo.
Erledigt
1.5.1 — 2026-08-22
API-Seite zur PWA nachgezogen (Abschnitt 0): Thumbnail-Endpoint size=thumb statt Ausliefern
der Originaldateien (9,8 KB statt 235 KB je Kachel, mit ETag/304), EXIF-Aufnahmezeit in der
Anhängeliste, title und composite_path in der Bericht-Detailantwort, neuer Endpoint
api/note.php für Textnotizen.
1.5.0 — 2026-08-21
Vollständig abgearbeitet. Anhänge-Kachelraster mit Miniaturen (1.1–1.4), Server-Thumbnail-Endpoint, PDF-Lightbox, Arbeitstisch mit echter Seitengeometrie (2), Bildaustausch auf bestehenden Seiten (3), Arbeiten ohne Neuladen, Autosave, Tastenkürzel, Sammelaktionen auf Seiten und Raster-Plätze (4).
Nebenbei gefundene und behobene Fehler:
dol_dir_list()wurde ohne$mode = 1aufgerufen — dadurch warensizeunddateleer und in der Anhängeliste stand „ Bytes" ohne Zahl- PDF.js-Worker-Pfad war hartkodiert ohne
/custom-Präfix → PDF.js lief im „fake worker"-Modus auf dem Hauptthread (spürbar langsamer beim Rendern) document.phpwurde ohneattachment=0verlinkt → PDFs wurden heruntergeladen statt angezeigt- Größen-Auswahl der Seite blieb leer, weil der DB-Wert
1die Option1.0nicht traf - Mehrfach-Upload nahm nur die erste Datei
--inputbackgroundcolorwurde im Modul als „im AwlDark nicht vorhanden" behandelt; die Variable existiert (KB #512, per DevTools bestätigt) — Editor-Eingabefelder nutzen jetzt dieselben Farben wie Dolibarr selbst