From c9d4122b3a5b635baf2171ba1168ed6448afc9a5 Mon Sep 17 00:00:00 2001 From: Scrum4Me Agent <30029041+madhura68@users.noreply.github.com> Date: Fri, 15 May 2026 20:08:42 +0200 Subject: [PATCH] feat(timeline): reverse-chronologische volgorde + unit-test merge/sort Extraheert mergeTimelineItems uit IdeaTimeline als exporteerbare functie en voegt een vitest-test toe die de nieuwste-boven-sortering verifieert. revalidatePath in user-questions action was al aanwezig. Co-Authored-By: Claude Sonnet 4.6 --- .../components/idea-timeline-merge.test.ts | 44 +++++++++++++++++++ components/ideas/idea-timeline.tsx | 35 ++++++++------- 2 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 __tests__/components/idea-timeline-merge.test.ts diff --git a/__tests__/components/idea-timeline-merge.test.ts b/__tests__/components/idea-timeline-merge.test.ts new file mode 100644 index 0000000..4af127d --- /dev/null +++ b/__tests__/components/idea-timeline-merge.test.ts @@ -0,0 +1,44 @@ +import { describe, it, expect } from 'vitest' +import { mergeTimelineItems } from '@/components/ideas/idea-timeline' + +describe('mergeTimelineItems', () => { + it('sorteert reverse-chronologisch: nieuwste entry staat eerst', () => { + const logs = [ + { id: 'l1', type: 'NOTE', content: 'oud', metadata: null, created_at: '2024-01-01T10:00:00.000Z' }, + ] + const questions = [ + { + id: 'q1', + question: 'Vraag?', + options: null, + status: 'open' as const, + answer: null, + created_at: '2024-01-03T12:00:00.000Z', + expires_at: '2024-01-10T12:00:00.000Z', + }, + ] + const userQuestions = [ + { + id: 'uq1', + question: 'Mijn vraag', + answer: null, + status: 'pending' as const, + created_at: '2024-01-02T08:00:00.000Z', + }, + ] + + const result = mergeTimelineItems(logs, questions, userQuestions) + + expect(result).toHaveLength(3) + expect(result[0].created_at).toBe('2024-01-03T12:00:00.000Z') + expect(result[0].kind).toBe('question') + expect(result[1].created_at).toBe('2024-01-02T08:00:00.000Z') + expect(result[1].kind).toBe('user_question') + expect(result[2].created_at).toBe('2024-01-01T10:00:00.000Z') + expect(result[2].kind).toBe('log') + }) + + it('geeft lege lijst terug bij geen input', () => { + expect(mergeTimelineItems([], [], [])).toEqual([]) + }) +}) diff --git a/components/ideas/idea-timeline.tsx b/components/ideas/idea-timeline.tsx index 5e17b94..053289c 100644 --- a/components/ideas/idea-timeline.tsx +++ b/components/ideas/idea-timeline.tsx @@ -99,6 +99,23 @@ const USER_QUESTION_STATUS_LABEL: Record answered: 'Beantwoord', } +export type TimelineEntry = + | { kind: 'log'; created_at: string; data: TimelineLog } + | { kind: 'question'; created_at: string; data: TimelineQuestion } + | { kind: 'user_question'; created_at: string; data: TimelineUserQuestion } + +export function mergeTimelineItems( + logs: TimelineLog[], + questions: TimelineQuestion[], + userQuestions: TimelineUserQuestion[], +): TimelineEntry[] { + return [ + ...logs.map((l) => ({ kind: 'log' as const, created_at: l.created_at, data: l })), + ...questions.map((q) => ({ kind: 'question' as const, created_at: q.created_at, data: q })), + ...userQuestions.map((uq) => ({ kind: 'user_question' as const, created_at: uq.created_at, data: uq })), + ].sort((a, b) => (a.created_at < b.created_at ? 1 : -1)) +} + export function IdeaTimeline({ logs, questions, @@ -107,23 +124,7 @@ export function IdeaTimeline({ ideaId, isDemo = false, }: Props) { - const merged = [ - ...logs.map((l) => ({ - kind: 'log' as const, - created_at: l.created_at, - data: l, - })), - ...questions.map((q) => ({ - kind: 'question' as const, - created_at: q.created_at, - data: q, - })), - ...userQuestions.map((uq) => ({ - kind: 'user_question' as const, - created_at: uq.created_at, - data: uq, - })), - ].sort((a, b) => (a.created_at < b.created_at ? 1 : -1)) + const merged = mergeTimelineItems(logs, questions, userQuestions) const showChatInput = planMd !== null