feat(timeline): add live filter, actor chips, group headers, copy button, source toggle, count badge

- Live search/filter bar: filters events by keyword across event, actor, source_excerpt, date
- Actor filter chips: click to filter by actor, multi-select, teal active state
- Year/month group headers when sorted chronologically (── 2023 ──, Mar 2024 ──)
- Per-event copy button (hover-revealed 📋): copies "date · actor · event" to clipboard
- "Hide/show sources" toggle: collapses all source excerpts without re-rendering
- Count badge: "23 events · 3 actors · 2022–2025" above the list
- applyTimelineFilters() unifies sort + actor + text filters in one re-render pass
- CSV export now includes end_date column
- Reset all filter state on each new run

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 15:46:59 +02:00
parent 59b39ff85b
commit ffcf887428
7 changed files with 807 additions and 49 deletions
+5 -3
View File
@@ -65,8 +65,9 @@ try {
if (mb_strlen($advocateRole, 'UTF-8') > 200) {
throw new DbnToolsHttpException('advocate_role is too long.', 422, 'advocate_role_too_long');
}
$priorContext = is_array($input['prior_context'] ?? null) ? $input['prior_context'] : null;
$branchNotes = mb_substr(trim((string)($input['branch_notes'] ?? '')), 0, 1000, 'UTF-8');
$priorContext = is_array($input['prior_context'] ?? null) ? $input['prior_context'] : null;
$branchNotes = mb_substr(trim((string)($input['branch_notes'] ?? '')), 0, 1000, 'UTF-8');
$subQsOverride = is_array($input['sub_questions_override'] ?? null) ? $input['sub_questions_override'] : [];
if (mb_strlen($seedQuery, 'UTF-8') > 4000) {
throw new DbnToolsHttpException('Query is too long.', 422, 'query_too_long');
@@ -125,7 +126,8 @@ try {
$emit,
$advocateRole,
$priorContext,
$branchNotes
$branchNotes,
$subQsOverride
);
$result['ok'] = true;