From e8ab95159ed9e8ed248308b41ad1e5c06ff9c7cf Mon Sep 17 00:00:00 2001 From: ferdi2go Date: Thu, 15 Oct 2026 08:27:01 +0000 Subject: [PATCH] =?UTF-8?q?Bugtracker=20in=20=E2=80=9EBugs"=20umbenennen?= =?UTF-8?q?=20und=20Erfolgsmeldung=20einblenden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reiter, Panel, Käfer-Beschriftungen und Doku sprechen von Bugs statt Fehlern. Nach dem Senden schließt sich das Panel sofort und eine Einblendung bestätigt die Meldung. Co-Authored-By: Claude Fable 5.1 --- .vch-description | 2 +- CLAUDE.md | 2 +- README.md | 8 ++++---- public/app.js | 21 +++++++++++---------- public/index.html | 30 +++++++++++++++--------------- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/.vch-description b/.vch-description index 035d7fb..c7791db 100644 --- a/.vch-description +++ b/.vch-description @@ -1 +1 @@ -Rotatory lost fair und zufällig aus, wer das tägliche Morning Meeting moderiert: pro Wochentag ein Hauptmoderator und ein Nebenmoderator aus der Belegschaft. Urlaub, Krankheit, Feiertage, Teilzeit-Freitage und Personen, die nicht moderieren, werden automatisch berücksichtigt. Die Monatsübersicht zeigt auf jedem Tag die Fotos der beiden Moderatoren, sodass jeder auf einen Blick sieht, wer dran ist. Einzelne Tage lassen sich manuell festlegen oder neu auslosen. Die Belegschaft samt Fotos und die Abwesenheiten kommen auf Wunsch direkt aus der Nextcloud, und auf Knopfdruck landet der Plan als Termine im geteilten Nextcloud-Kalender des Teams. Teammitglieder können ohne Anmeldung einen Tausch anfragen und Fehler mit Screenshot melden; die Bearbeitung ist per Passwort geschützt. +Rotatory lost fair und zufällig aus, wer das tägliche Morning Meeting moderiert: pro Wochentag ein Hauptmoderator und ein Nebenmoderator aus der Belegschaft. Urlaub, Krankheit, Feiertage, Teilzeit-Freitage und Personen, die nicht moderieren, werden automatisch berücksichtigt. Die Monatsübersicht zeigt auf jedem Tag die Fotos der beiden Moderatoren, sodass jeder auf einen Blick sieht, wer dran ist. Einzelne Tage lassen sich manuell festlegen oder neu auslosen. Die Belegschaft samt Fotos und die Abwesenheiten kommen auf Wunsch direkt aus der Nextcloud, und auf Knopfdruck landet der Plan als Termine im geteilten Nextcloud-Kalender des Teams. Teammitglieder können ohne Anmeldung einen Tausch anfragen und Bugs mit Screenshot melden; die Bearbeitung ist per Passwort geschützt. diff --git a/CLAUDE.md b/CLAUDE.md index 7824d6c..73bdea8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,7 +25,7 @@ Wofür dieses Projekt gut ist, und was jemand wissen muss, der hier weiterarbeit - Vor dem Commit linten und formatieren - Tests für die tragende Fachlogik - Wenig Abhängigkeiten — was Browser und Node schon können, reicht meistens. Ausnahme mit - Begründung: `public/vendor/html2canvas.min.js` (Screenshots für Fehlermeldungen; der Browser + Begründung: `public/vendor/html2canvas.min.js` (Screenshots für Bug-Meldungen; der Browser kann Seiten nicht selbst fotografieren), selbst gehostet, nichts von fremden Servern laden - Semantisches HTML, mobil zuerst, bedienbar per Tastatur, ausreichender Kontrast - Konfiguration über Umgebungsvariablen; keine Zugangsdaten im Quelltext diff --git a/README.md b/README.md index 057b662..bb3b0b1 100644 --- a/README.md +++ b/README.md @@ -90,13 +90,13 @@ Bearbeiter sehen alle Anfragen unter „Anfragen" mit Zähler in der Navigation manuell wählen, „Erledigt" und „Ablehnen" schließen die Anfrage ohne Änderung. Nach einem Tausch den Zeitraum erneut nach Nextcloud schreiben. -## Fehler melden +## Bugs melden Unten rechts sitzt ein Käfer-Button. Ein Klick nimmt den sichtbaren Bildschirm auf (mit der selbst gehosteten Bibliothek html2canvas, die die Seite aus dem Seiteninhalt nachzeichnet), zeigt ihn als Vorschau, in der sich rote Rechtecke aufziehen lassen, und fragt nach einer Beschreibung und optional dem Namen. Dafür ist keine Anmeldung nötig; pro Adresse sind zehn -Meldungen je Stunde möglich. Bearbeiter sehen die Meldungen unter „Fehler" mit Zähler. +Meldungen je Stunde möglich. Bearbeiter sehen die Meldungen unter „Bugs" mit Zähler. „Prompt kopieren" legt eine fertige Anweisung für Claude Code in die Zwischenablage, die Vorlage dafür steht in den Einstellungen; „Screenshot kopieren" das Bild dazu. Bilder in die Zwischenablage legen erlauben Browser nur über https; auf einer http-Adresse öffnet @@ -139,7 +139,7 @@ server/ ics.js iCalendar-Erzeugung nextcloud.js CalDAV/CardDAV-Client (Discovery, PROPFIND, MKCALENDAR, REPORT, PUT, DELETE) requests.js Tauschanfragen prüfen und ausführen - bugs.js Fehlermeldungen: Screenshot prüfen, Prompt-Vorlage + bugs.js Bug-Meldungen: Screenshot prüfen, Prompt-Vorlage auth.js Bearbeitungsschutz (Cookie, Bremse) ical.js iCalendar- und vCard-Leser, Namenszuordnung env.js .env-Leser @@ -149,5 +149,5 @@ test/ node:test ``` Abhängigkeiten: nur `express`; im Browser zusätzlich die selbst gehostete Bibliothek -html2canvas (`public/vendor/`, MIT) für Screenshots in Fehlermeldungen. Fotos werden im Browser +html2canvas (`public/vendor/`, MIT) für Screenshots in Bug-Meldungen. Fotos werden im Browser per Canvas verkleinert, `fetch` und `crypto` kommen aus Node. diff --git a/public/app.js b/public/app.js index 0dc959e..eb53600 100644 --- a/public/app.js +++ b/public/app.js @@ -51,7 +51,7 @@ async function api(path, { method = 'GET', body, raw } = {}) { } // ---------- Anmeldung zum Bearbeiten ---------- -const EDITOR_VIEWS = ['personen', 'abwesenheiten', 'anfragen', 'fehler', 'einstellungen']; +const EDITOR_VIEWS = ['personen', 'abwesenheiten', 'anfragen', 'bugs', 'einstellungen']; function isEditor() { return !state.data || state.data.auth?.editor !== false; } function applyAuthUI() { const a = state.data?.auth || { protected: false, editor: true }; @@ -148,7 +148,7 @@ function avatarEl(p, cls = '') { // ---------- Navigation ---------- function showView(name) { - const known = ['kalender', 'personen', 'abwesenheiten', 'anfragen', 'fehler', 'einstellungen']; + const known = ['kalender', 'personen', 'abwesenheiten', 'anfragen', 'bugs', 'einstellungen']; if (!known.includes(name)) name = 'kalender'; if (!isEditor() && EDITOR_VIEWS.includes(name)) name = 'kalender'; if (name === 'abwesenheiten' && state.data) prepareAbsenceImport(); @@ -1140,14 +1140,14 @@ $('#holiday-add').addEventListener('submit', async (e) => { } catch (err) { toast(err.message, true); } }); -// ---------- Fehler melden (für alle) ---------- +// ---------- Bug melden (für alle) ---------- const bugPanel = $('#bug-panel'); const bugCanvas = $('#bug-canvas'); const bugState = { base: null, rects: [], draft: null, sending: false, capture: null, closeTimer: null, target: null }; function viewName() { const v = location.hash.slice(1) || 'kalender'; - const names = { kalender: 'Kalender', personen: 'Personen', abwesenheiten: 'Abwesenheiten', anfragen: 'Anfragen', fehler: 'Fehler', einstellungen: 'Einstellungen' }; + const names = { kalender: 'Kalender', personen: 'Personen', abwesenheiten: 'Abwesenheiten', anfragen: 'Anfragen', bugs: 'Bugs', einstellungen: 'Einstellungen' }; const month = v === 'kalender' ? ` (${MONTHS[state.month.getMonth()]} ${state.month.getFullYear()})` : ''; return `${names[v] || v}${month}${isEditor() ? ', angemeldet' : ''}`; } @@ -1351,12 +1351,13 @@ $('#bug-form').addEventListener('submit', async (e) => { return; } bugState.sending = false; - out.textContent = 'Danke, der Fehler ist gemeldet.'; - bugState.closeTimer = setTimeout(() => { bugState.closeTimer = null; closeBugPanel(); }, 2000); + // Panel sofort schließen und die Bestätigung unten einblenden + closeBugPanel(); + toast('Bug erfolgreich gemeldet. Danke für den Hinweis.'); if (isEditor()) load().catch((err) => toast(err.message, true)); }); -// ---------- Fehlermeldungen bearbeiten (nur Bearbeiter) ---------- +// ---------- Bugs bearbeiten (nur Bearbeiter) ---------- const canCopyImages = () => Boolean(window.isSecureContext && navigator.clipboard && navigator.clipboard.write && window.ClipboardItem); async function copyText(text) { if (window.isSecureContext && navigator.clipboard?.writeText) { await navigator.clipboard.writeText(text); return; } @@ -1394,7 +1395,7 @@ function bugRow(b) { a.title = 'Screenshot in voller Größe öffnen'; const img = document.createElement('img'); img.src = `bugs/${b.id}.png`; - img.alt = 'Screenshot zur Fehlermeldung'; + img.alt = 'Screenshot zum Bug'; img.loading = 'lazy'; a.appendChild(img); li.appendChild(a); @@ -1431,7 +1432,7 @@ function bugRow(b) { } if (b.status === 'offen') btn('Erledigt', 'ghost', () => run(() => api(`api/bugs/${b.id}`, { method: 'PUT', body: { status: 'erledigt' } }), 'Als erledigt markiert.')); else btn('Wieder öffnen', 'ghost', () => run(() => api(`api/bugs/${b.id}`, { method: 'PUT', body: { status: 'offen' } }))); - btn('Löschen', 'ghost danger', () => { if (confirm('Diese Fehlermeldung samt Screenshot löschen?')) run(() => api(`api/bugs/${b.id}`, { method: 'DELETE' }), 'Meldung gelöscht.'); }); + btn('Löschen', 'ghost danger', () => { if (confirm('Diesen Bug samt Screenshot löschen?')) run(() => api(`api/bugs/${b.id}`, { method: 'DELETE' }), 'Bug gelöscht.'); }); grow.appendChild(actions); li.appendChild(grow); return li; @@ -1443,7 +1444,7 @@ function renderBugs() { $('#bugs-clipboard-hint').hidden = canCopyImages(); const list = $('#bug-list'); list.textContent = ''; - if (open.length === 0) list.innerHTML = '
  • Keine offenen Fehlermeldungen.
  • '; + if (open.length === 0) list.innerHTML = '
  • Keine offenen Bugs.
  • '; for (const b of open) list.appendChild(bugRow(b)); const doneList = $('#bug-list-done'); doneList.textContent = ''; diff --git a/public/index.html b/public/index.html index 10541d1..a156b3e 100644 --- a/public/index.html +++ b/public/index.html @@ -17,7 +17,7 @@ Personen Abwesenheiten Anfragen - Fehler + Bugs Einstellungen @@ -158,10 +158,10 @@ - -