diff --git a/frontend/src/lib/generated/api.ts b/frontend/src/lib/generated/api.ts index 3a858315..e2cb6a0e 100644 --- a/frontend/src/lib/generated/api.ts +++ b/frontend/src/lib/generated/api.ts @@ -2038,6 +2038,7 @@ export interface components { /** Format: date-time */ happenedAt: string; youMentioned: boolean; + youParticipated: boolean; /** Format: int32 */ count: number; /** Format: date-time */ diff --git a/frontend/src/routes/chronik/feedFilters.test.ts b/frontend/src/routes/chronik/feedFilters.test.ts new file mode 100644 index 00000000..391d2140 --- /dev/null +++ b/frontend/src/routes/chronik/feedFilters.test.ts @@ -0,0 +1,94 @@ +import { describe, expect, it } from 'vitest'; +import { filterFeed } from './feedFilters'; +import type { components } from '$lib/generated/api'; + +type Item = components['schemas']['ActivityFeedItemDTO']; + +function makeItem(overrides: Partial = {}): Item { + return { + kind: 'FILE_UPLOADED', + documentId: 'd1', + documentTitle: 'Brief A', + happenedAt: '2026-04-20T10:00:00Z', + youMentioned: false, + youParticipated: false, + count: 1, + actor: null, + happenedAtUntil: null, + ...overrides + }; +} + +describe('filterFeed', () => { + describe('alle', () => { + it('returns all items regardless of kind', () => { + const items = [ + makeItem({ kind: 'FILE_UPLOADED' }), + makeItem({ kind: 'COMMENT_ADDED' }), + makeItem({ kind: 'MENTION_CREATED' }) + ]; + expect(filterFeed(items, 'alle')).toHaveLength(3); + }); + }); + + describe('fuer-dich', () => { + it('includes MENTION_CREATED items', () => { + const items = [makeItem({ kind: 'MENTION_CREATED' })]; + expect(filterFeed(items, 'fuer-dich')).toHaveLength(1); + }); + + it('includes items where youMentioned is true', () => { + const items = [makeItem({ kind: 'COMMENT_ADDED', youMentioned: true })]; + expect(filterFeed(items, 'fuer-dich')).toHaveLength(1); + }); + + it('includes items where youParticipated is true', () => { + const items = [makeItem({ kind: 'COMMENT_ADDED', youParticipated: true })]; + expect(filterFeed(items, 'fuer-dich')).toHaveLength(1); + }); + + it('excludes FILE_UPLOADED with no participation', () => { + const items = [makeItem({ kind: 'FILE_UPLOADED' })]; + expect(filterFeed(items, 'fuer-dich')).toHaveLength(0); + }); + + it('excludes COMMENT_ADDED with no mention and no participation', () => { + const items = [makeItem({ kind: 'COMMENT_ADDED' })]; + expect(filterFeed(items, 'fuer-dich')).toHaveLength(0); + }); + }); + + describe('hochgeladen', () => { + it('includes only FILE_UPLOADED items', () => { + const items = [ + makeItem({ kind: 'FILE_UPLOADED' }), + makeItem({ kind: 'COMMENT_ADDED', youParticipated: true }) + ]; + expect(filterFeed(items, 'hochgeladen')).toHaveLength(1); + expect(filterFeed(items, 'hochgeladen')[0].kind).toBe('FILE_UPLOADED'); + }); + }); + + describe('transkription', () => { + it('includes TEXT_SAVED, BLOCK_REVIEWED, ANNOTATION_CREATED', () => { + const items = [ + makeItem({ kind: 'TEXT_SAVED' }), + makeItem({ kind: 'BLOCK_REVIEWED' }), + makeItem({ kind: 'ANNOTATION_CREATED' }), + makeItem({ kind: 'FILE_UPLOADED' }) + ]; + expect(filterFeed(items, 'transkription')).toHaveLength(3); + }); + }); + + describe('kommentare', () => { + it('includes COMMENT_ADDED and MENTION_CREATED', () => { + const items = [ + makeItem({ kind: 'COMMENT_ADDED' }), + makeItem({ kind: 'MENTION_CREATED' }), + makeItem({ kind: 'FILE_UPLOADED' }) + ]; + expect(filterFeed(items, 'kommentare')).toHaveLength(2); + }); + }); +}); diff --git a/frontend/src/routes/chronik/feedFilters.ts b/frontend/src/routes/chronik/feedFilters.ts new file mode 100644 index 00000000..ab66b5ab --- /dev/null +++ b/frontend/src/routes/chronik/feedFilters.ts @@ -0,0 +1,27 @@ +import type { components } from '$lib/generated/api'; +import type { FilterValue } from './+page.server'; + +type ActivityFeedItemDTO = components['schemas']['ActivityFeedItemDTO']; + +export function filterFeed( + items: ActivityFeedItemDTO[], + filter: FilterValue +): ActivityFeedItemDTO[] { + switch (filter) { + case 'alle': + return items; + case 'fuer-dich': + return items.filter( + (i) => i.kind === 'MENTION_CREATED' || i.youMentioned || i.youParticipated + ); + case 'hochgeladen': + return items.filter((i) => i.kind === 'FILE_UPLOADED'); + case 'transkription': + return items.filter( + (i) => + i.kind === 'TEXT_SAVED' || i.kind === 'BLOCK_REVIEWED' || i.kind === 'ANNOTATION_CREATED' + ); + case 'kommentare': + return items.filter((i) => i.kind === 'COMMENT_ADDED' || i.kind === 'MENTION_CREATED'); + } +}