bericht/ROADMAP.md
Eduard Wisch cf7471d2d2
All checks were successful
Deploy bericht / deploy (push) Has been skipped
ROADMAP: tote Konstante BERICHT_TAB_ON_THIRDPARTY und Doku-Drift notiert
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>
2026-09-19 00:00:19 +02:00

14 KiB
Raw Permalink Blame History

ROADMAP — Modul Bericht

Stand: 2026-08-22 · Version im Repo: 1.5.1

Diese Datei war mit eb37a4b gelö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 unter thumbs/<name>_small.<ext> erzeugt hat. Fotos aus der PWA kommen über orders.php?action=upload_photo herein, und dort läuft kein vignette() — 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 eingebundene lib/bericht.lib.php erreichbar. Dazu ETag aus der mtime, damit wiederholte Aufrufe mit 304 enden.
  • api/orders.php?action=photos: taken_at 1.5.1 — sortiert wurde nach filemtime. Der Editor nutzt seit 1.5.0 die EXIF-Aufnahmezeit (bericht_file_taken_at(), eigener Parser weil im Prod-Container kein exif-Modul). Bei Uploads aus der Galerie ist die Upload-Zeit die falsche Reihenfolge.
  • api/reports.php: title im pages-Array 1.5.1 — api/pages.php konnte 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_path im pages-Array 1.5.1 — die PWA zeigte source_path, also das Rohbild ohne Anmerkungen. Bei Raster-Layouts (grid_2grid_6, before_after) ist das nur eines von bis zu sechs Bildern, bei title_only gar 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>.txt im Auftrags-Verzeichnis, damit die Notiz auch im Dolibarr-Auftrag und in der Anhänge-Spalte des Editors auftaucht. Der file-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.


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 2040 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 das exif-Modul im Container 90-Dolibarr-Prod-Custom nicht 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 (150620 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) in lib/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 = 10 ab 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 Endpoint ajax/fragments.php liefert Seiten- und Anhängeliste als HTML; gerendert wird über bericht_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_path wird 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: bindExtraUpload verarbeitete nur inp.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-delete lö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_THIRDPARTY ist seit 1.7.1 tot (gefunden 2026-09-18 beim Doku-Abgleich): Der Descriptor legt die Konstante weiter an (Default 1), aber seit der Reiter an der Kundenkarte über den Hook completeTabsHead kommt, fragt sie niemand mehr ab (grep -rn TAB_ON_THIRDPARTY findet 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.md ist bereits auf 1.7.1 nachgezogen): CLAUDE.md trägt noch „Stand 2026-08-22 (Version 1.5.1)" und nennt als PWA-Hosting awl.data-it-solution.de/baustelle/ — tatsächlich /custom/baustelle/ (Manifest start_url, Prod-Zugriffslog). README.md nennt für BERICHT_TAB_ON_THIRDPARTY den Default 0, der Descriptor setzt 1. 1.6.0 (md5-Abgleich), 1.7.0 (Fotoqualität, api/config.php) und 1.7.1 (Hook-Reiter) fehlen in CLAUDE.md ganz. → 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.11.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 = 1 aufgerufen — dadurch waren size und date leer 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.php wurde ohne attachment=0 verlinkt → PDFs wurden heruntergeladen statt angezeigt
  • Größen-Auswahl der Seite blieb leer, weil der DB-Wert 1 die Option 1.0 nicht traf
  • Mehrfach-Upload nahm nur die erste Datei
  • --inputbackgroundcolor wurde 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