From c7a84438d1a53de9673fdddd6e860ead3b369502 Mon Sep 17 00:00:00 2001 From: rene Date: Wed, 27 May 2026 14:42:47 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20Notes-Karten=20=E2=80=94=20Zeilenumbruch?= =?UTF-8?q?,=20Clamp=20+=20Detail-Modal=20beim=20Klick,=20SW=20by-v1119?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-Report: Zeilenumbrüche in Notes-Karten gingen nicht, kein Scroll, keine Detail-Ansicht. Drei Probleme behoben: 1. _truncate-Limit zu aggressiv (150 Zeichen) → erhöht auf 600 Zeichen damit Karten lange Notizen mit Newlines sichtbar anzeigen können (CSS-Clamp erledigt visuell den Rest) 2. .list-item-text + .notes-card-text Override-Konflikt list-item-text hat fest -webkit-line-clamp:2 mit display:-webkit-box. Notes-Override hatte display:block — das deaktiviert clamp komplett, aber dann zeigt der Text die ersten 150 Zeichen ohne Newline-Hinweis. → Neuer Override: display:-webkit-box + -webkit-line-clamp:5 + white-space:pre-wrap → 5 Zeilen mit Newlines sichtbar, Rest '…' 3. Keine Detail-Ansicht beim Klick auf Karte → Neue Funktion _openDetailModal(note): - Voller Notiz-Text scrollbar (.notes-detail-text mit max-height:60vh) - Rubrik-Icon + Label im Titel - Parent-Label, Micro-Badges, Meta (Zeit + Ort) - Footer: 'Bearbeiten' (öffnet Edit-Modal) + 'Schließen' → Card-Click bindet darauf; Klicks auf Action-Buttons werden via closest('.list-item-action-btn') ignoriert (kein doppeltes Handling) --- VERSION | 2 +- backend/static/index.html | 24 +++++------ backend/static/js/app.js | 2 +- backend/static/js/pages/notes.js | 71 ++++++++++++++++++++++++++++++-- backend/static/landing.html | 2 +- backend/static/sw.js | 2 +- 6 files changed, 84 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 5568a07..63539d7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1118 \ No newline at end of file +1119 \ No newline at end of file diff --git a/backend/static/index.html b/backend/static/index.html index b1e995d..753b442 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -86,14 +86,14 @@ Ban Yaro - + - - - - - + + + + + @@ -617,11 +617,11 @@ - - - - - + + + + + @@ -631,7 +631,7 @@ - + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 5a51556..d24a3b8 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '1118'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '1119'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator) window.APP_VERSION = APP_VERSION; diff --git a/backend/static/js/pages/notes.js b/backend/static/js/pages/notes.js index f983cc2..6fceffe 100644 --- a/backend/static/js/pages/notes.js +++ b/backend/static/js/pages/notes.js @@ -68,7 +68,10 @@ window.Page_notes = (() => { } catch (_) { return 'Älteres'; } } - function _truncate(str, max = 150) { + function _truncate(str, max = 600) { + // Karten zeigen max 5 Zeilen via CSS-Clamp — Text muss lang genug + // sein dass die Clamp greift. Bei sehr langen Notes: vor Clamp abschneiden + // damit der String nicht riesig in der DOM-Page steht. if (!str) return ''; return str.length > max ? str.slice(0, max) + '…' : str; } @@ -248,8 +251,12 @@ window.Page_notes = (() => { /* .notes-card-meta { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--c-text-muted); } */ /* Notes-Override: Actions in Top-Zeile rechts ausrichten (statt align-self:center bei list-item-actions) */ .notes-card-actions { margin-left: auto; align-self: flex-start; } - /* Notes-Override: Text ohne -webkit-line-clamp (komplett anzeigen) + pre-wrap */ - .notes-card-text { line-height: 1.55; white-space: pre-wrap; margin: 0; display: block; -webkit-line-clamp: unset; overflow: visible; color: var(--c-text); } + /* Notes-Override: Newlines (pre-wrap) + max 5 Zeilen mit "…", Rest in Detail-Modal */ + .notes-card-text { line-height: 1.55; white-space: pre-wrap; margin: 0; color: var(--c-text); + display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; overflow: hidden; } + /* Detail-Modal: voller Notiz-Text scrollbar */ + .notes-detail-text { white-space: pre-wrap; line-height: 1.6; font-size: var(--text-base); + color: var(--c-text); margin: 0; max-height: 60vh; overflow-y: auto; } /* TODO nach Migration entfernen: ersetzt durch .list-item-micro-badges / .list-item-micro-badge */ /* .notes-micro-badges { display: flex; flex-wrap: wrap; gap: var(--space-1); } */ /* .notes-micro-badge { font-size: var(--text-xs); padding: 2px 6px; border-radius: var(--radius-sm); background: var(--c-surface-2); color: var(--c-text-secondary); } */ @@ -458,6 +465,64 @@ window.Page_notes = (() => { } }); }); + + // Karte selbst klickbar → Detail-Modal mit vollem Text + _container.querySelectorAll('.notes-card').forEach(card => { + card.addEventListener('click', e => { + // Klicks auf Action-Buttons nicht doppelt verarbeiten + if (e.target.closest('.list-item-action-btn')) return; + const note = _notes.find(n => n.id === parseInt(card.dataset.id, 10)); + if (note) _openDetailModal(note); + }); + }); + } + + // ---------------------------------------------------------- + // Detail-Modal: voller Notiz-Text + Meta + Bearbeiten/Löschen + // ---------------------------------------------------------- + function _openDetailModal(note) { + const rb = RUBRIKEN.find(r => r.id === note.rubrik) || RUBRIKEN[0]; + const meta = (() => { try { return JSON.parse(note.meta || '{}'); } catch { return {}; } })(); + const microBadges = []; + if (meta.erfolg) microBadges.push(`🐾 ${meta.erfolg}/5`); + if (meta.umgebung) microBadges.push({ zuhause: '🏠 Zuhause', natur: '🌿 Natur', stadt: '🌆 Stadt' }[meta.umgebung] || meta.umgebung); + if (meta.hund_stimmung) microBadges.push({ super: '😊 Super', ok: '😐 Ok', mude: '😔 Müde' }[meta.hund_stimmung] || meta.hund_stimmung); + + UI.modal.open({ + title: `${UI.icon(rb.icon)} ${UI.escape(rb.label)}`, + body: ` +
+ ${note.parent_label + ? `
${UI.escape(note.parent_label)}
` : ''} + +

${UI.escape(note.text || '')}

+ + ${microBadges.length ? ` +
+ ${microBadges.map(b => `${UI.escape(b)}`).join('')} +
` : ''} + +
+ + ${UI.escape(_formatTime(note.updated_at || note.created_at))} + ${note.location_name + ? ` ${UI.escape(note.location_name)}` : ''} +
+
+ `, + footer: ` +
+ + +
+ `, + }); + document.getElementById('notes-detail-edit')?.addEventListener('click', () => { + UI.modal.close(); + _openEditModal(note); + }); } // ---------------------------------------------------------- diff --git a/backend/static/landing.html b/backend/static/landing.html index 478aa8d..11781f5 100644 --- a/backend/static/landing.html +++ b/backend/static/landing.html @@ -4,7 +4,7 @@ - + Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz diff --git a/backend/static/sw.js b/backend/static/sw.js index 8d8b530..ecb64f7 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -4,7 +4,7 @@ ============================================================ */ // ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab -const VER = '1118'; +const VER = '1119'; const CACHE_VERSION = `by-v${VER}`; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten