From f011522848bb481c3830663a461f93b9c0f93970 Mon Sep 17 00:00:00 2001 From: janis steiner Date: Fri, 8 May 2026 00:55:47 +0200 Subject: [PATCH] better docs --- backend/api/index.php | 4 +-- frontend/assets/js/app.js | 56 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/backend/api/index.php b/backend/api/index.php index c74a4c9..033a984 100644 --- a/backend/api/index.php +++ b/backend/api/index.php @@ -506,7 +506,7 @@ function handleDocuments($method, $id, $db) { $typeLabels = ['deployment' => 'Deployment', 'attack' => 'Attack', 'incident-report' => 'Incident Report', 'remediation' => 'Remediation', 'exercise' => 'Exercise']; $typeLabel = $typeLabels[$docType] ?? ucfirst($docType); $eventTitle = $typeLabel . ': ' . $data['title']; - $eventDesc = $username . ' created document "' . $data['title'] . '" (' . $typeLabel . ')'; + $eventDesc = $username . ' created [doc:' . $docId . ']' . $data['title'] . '[/doc] (' . $typeLabel . ')'; $stmt2 = $db->prepare(" INSERT INTO events (team_id, title, description, severity, event_type, occurred_at) VALUES (?, ?, ?, 'info', 'document', ?) @@ -538,7 +538,7 @@ function handleDocuments($method, $id, $db) { $typeLabels = ['deployment' => 'Deployment', 'attack' => 'Attack', 'incident-report' => 'Incident Report', 'remediation' => 'Remediation', 'exercise' => 'Exercise']; $typeLabel = $typeLabels[$docType] ?? ucfirst($docType); $eventTitle = 'Updated ' . $typeLabel . ': ' . $docTitle; - $eventDesc = $username . ' updated document "' . $docTitle . '" (' . $typeLabel . ')'; + $eventDesc = $username . ' updated [doc:' . $id . ']' . $docTitle . '[/doc] (' . $typeLabel . ')'; $stmt2 = $db->prepare(" INSERT INTO events (team_id, title, description, severity, event_type, occurred_at) VALUES (?, ?, ?, 'info', 'document', ?) diff --git a/frontend/assets/js/app.js b/frontend/assets/js/app.js index 2edc3a3..9db8bf4 100644 --- a/frontend/assets/js/app.js +++ b/frontend/assets/js/app.js @@ -268,7 +268,7 @@ function renderTimeline() { ${date}
${esc(e.title)}
- ${e.description ? '

' + esc(e.description) + '

' : ''} + ${e.description ? '

' + renderDocLinks(e.description) + '

' : ''}
@@ -286,6 +286,58 @@ function renderTimeline() { }).join(''); } +function renderDocLinks(text) { + const parts = text.split(/(\[doc:\d+\].*?\[\/doc\])/g); + return parts.map(p => { + const m = p.match(/\[doc:(\d+)\](.*?)\[\/doc\]/); + if (m) { + return `${esc(m[2])}`; + } + return esc(p); + }).join(''); +} + +function openDocument(id) { + const tab = document.getElementById('documents-tab'); + if (tab) tab.click(); + setTimeout(() => { + const container = document.getElementById('documentContainer'); + if (!container) return; + const cards = container.querySelectorAll('.doc-card'); + cards.forEach(c => { + c.style.transition = 'box-shadow .3s, border-color .3s'; + c.style.boxShadow = ''; + c.style.borderColor = ''; + }); + const target = container.querySelector(`[data-doc-id="${id}"]`); + if (target) { + target.scrollIntoView({ behavior: 'smooth', block: 'center' }); + target.style.boxShadow = '0 0 20px rgba(59,130,246,.5)'; + target.style.borderColor = 'var(--neptune-accent)'; + setTimeout(() => { + target.style.boxShadow = ''; + target.style.borderColor = ''; + }, 3000); + } else { + loadDocuments().then(() => { + setTimeout(() => { + const el = document.getElementById('documentContainer').querySelector(`[data-doc-id="${id}"]`); + if (el) { + el.scrollIntoView({ behavior: 'smooth', block: 'center' }); + el.style.boxShadow = '0 0 20px rgba(59,130,246,.5)'; + el.style.borderColor = 'var(--neptune-accent)'; + setTimeout(() => { el.style.boxShadow = ''; el.style.borderColor = ''; }, 3000); + } + }, 100); + }); + } + const filter = document.getElementById('searchDocs'); + if (filter) filter.value = ''; + document.getElementById('docTeamFilter').value = ''; + document.getElementById('docTypeFilter').value = ''; + }, 300); +} + function renderComments(event) { if (!event.comments || !event.comments.length) return '
No comments yet
'; return event.comments.map(c => ` @@ -1030,7 +1082,7 @@ function renderDocuments() { const contentPreview = d.content ? d.content.substring(0, 150) + (d.content.length > 150 ? '...' : '') : ''; return `
-
+