All checks were successful
Deploy bericht / deploy (push) Successful in 13s
Anhaenge-Spalte: Kachelraster mit Server-Thumbnails statt Dateinamen-Liste (Bilder per GD, PDFs per PDF.js), Grossansicht per Klick, Auswahlreihenfolge sichtbar, Sortierung/Filter (Aufnahmezeit per eigenem EXIF-Parser, da im Prod-Container ohne exif-Modul), ziehbare Spaltenbreite, Kachelgroesse, Drag & Drop auf Seitenliste/Arbeitsflaeche/Raster-Plaetze. Arbeitstisch zeigt jetzt Kopf-, Inhalts- und Fussbereich passend zur echten Seitengeometrie (bericht_page_geometry()) - Editor und PDF-Erzeugung rechnen mit denselben Werten, das PDF setzt die Arbeitsflaeche 1:1 statt sie ein zweites Mal einzupassen. Neu: Bild einer Seite austauschen (auch einzelne Raster-Plaetze), Seiten mehrfach markieren und sammeln loeschen/duplizieren, Autosave mit Verlassen-Warnung, Tastenkuerzel, kein location.reload() mehr nach Hinzufuegen/Loeschen/Hochladen (ajax/fragments.php). Nebenbei behoben: dol_dir_list() ohne mode=1 (Dateigroesse leer), PDF.js-Worker-Pfad ohne /custom-Praefix, PDFs liefen als Download statt inline, Groessen-Select blieb leer, Mehrfach-Upload nahm nur die erste Datei, Race-Condition bei schnellem Seitenwechsel. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
151 lines
9.6 KiB
Markdown
151 lines
9.6 KiB
Markdown
# ROADMAP — Modul Bericht
|
||
|
||
Stand: 2026-08-21 · Version im Repo: 1.5.0
|
||
|
||
---
|
||
|
||
## 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
|
||
- [x] Kachel-Raster (2 Spalten) statt Liste
|
||
- [x] Server-Thumbnails für Bilder (GD, gecacht) — Original-Handyfotos werden **nicht** mehr voll geladen
|
||
- [x] PDF-Anhänge: Seite 1 als Miniatur (PDF.js, clientseitig, lazy)
|
||
- [x] Klick auf Miniatur → Lightbox (Zoom/Pan/Swipe), `✕` bzw. Esc schließt — PDFs im Vollbild-Viewer
|
||
- [x] Dateiname zweizeilig unter der Kachel + voller Name als Tooltip
|
||
|
||
### 1.2 Auswahl bedienbar machen ✅ 1.5.0
|
||
- [x] Checkbox als Overlay auf der Kachel (großes Klickziel), Klick auf die Namenszeile wählt ebenfalls aus
|
||
- [x] Auswahl-Reihenfolge sichtbar (① ② ③) — bestimmt die Slot-Reihenfolge im Grid-Layout
|
||
(vorher: DOM-Reihenfolge, also nicht steuerbar)
|
||
- [x] „Alle / Keine" pro Herkunfts-Gruppe + Zähler „3 ausgewählt"
|
||
- [x] Bereits im Bericht verwendete Anhänge werden markiert (✓-Badge, ausgegraut)
|
||
|
||
### 1.3 Sortierung und Filter ✅ 1.5.0
|
||
- [x] Sortierung nach **Aufnahmezeit** (auf- und absteigend), Name, Größe — jeweils innerhalb der
|
||
Herkunfts-Gruppe, damit die Zuordnung zum Beleg erhalten bleibt
|
||
- [x] Filter: alle · nur Bilder · nur PDFs · noch nicht verwendet
|
||
- [x] Aufnahmezeit steht unter der Kachel (`12.08. 11:48 · 56 Kb`)
|
||
- [x] 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.
|
||
- [x] Auswahl von Sortierung/Filter/Ansicht wird gemerkt (localStorage)
|
||
|
||
### 1.4 Spaltenbreite, Kachelgröße, Ziehen und Ablegen ✅ 1.5.0
|
||
- [x] **Spaltenbreite ziehbar** — Trennlinie zwischen Anhängen und Arbeitsfläche (150–620 px),
|
||
Doppelklick setzt auf 260 px zurück; Breite wird gemerkt
|
||
- [x] **Ein-/ausklappbar** über „«" in der Kopfzeile — eingeklappt bleiben 26 px stehen
|
||
- [x] **Kachelgröße** klein / mittel / groß über „⤢" (in der kleinsten Stufe entfällt die Größenangabe)
|
||
- [x] **Kachel auf die Seitenliste ziehen** → neue Seite(n). Sind mehrere Kacheln angekreuzt und man
|
||
zieht eine davon, kommen alle mit.
|
||
- [x] **Kachel auf die Arbeitsfläche ziehen** → ersetzt das Bild der offenen Seite
|
||
- [x] **Kachel auf einen Raster-Platz ziehen** → setzt genau diesen Platz
|
||
- [x] **Dateien vom Rechner auf die Spalte ziehen** → Upload (nicht unterstützte Typen werden
|
||
benannt und übersprungen)
|
||
- [x] 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.
|
||
|
||
- [x] 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.
|
||
- [x] 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.
|
||
- [x] PDF setzt das Composite 1:1 in den Inhaltsbereich statt es erneut einzupassen
|
||
- [x] 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
|
||
- [x] Raster-Vorschau (`ajax/page_image.php`) rendert im Format des Inhaltsbereichs
|
||
- [x] Umschalter „📐 Rand" in der Werkzeugleiste (Zustand wird gemerkt)
|
||
- [x] 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
|
||
|
||
- [x] `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)
|
||
- [x] Raster-Seiten: einzelner Platz austauschbar (nutzt das vorhandene `set_slot_image.php`,
|
||
für das es bis dahin keine Bedienung gab)
|
||
- [x] 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.
|
||
- [x] Finalisierte Berichte werden serverseitig abgewiesen
|
||
|
||
---
|
||
|
||
## 4. Editor / Arbeitsablauf
|
||
|
||
- [x] **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.
|
||
- [x] **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.
|
||
- [x] **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.
|
||
- [x] **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.
|
||
- [x] **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.
|
||
- [x] **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
|
||
|
||
- [x] **Mehrfach-Upload**: `bindExtraUpload` verarbeitete nur `inp.files[0]` — Mehrfachauswahl im
|
||
Dateidialog war möglich, es kam aber nur eine Datei an ✅ 1.5.0
|
||
- [x] Upload-Fortschritt ✅ 1.5.0 — der Knopf zeigt beim Mehrfach-Upload „⏳ 3 / 8"
|
||
- [x] `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.
|
||
|
||
---
|
||
|
||
## Erledigt
|
||
|
||
### 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 = 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
|