feat(chronik): extract feedFilters.ts with youParticipated in fuer-dich

Extract filterFeed(items, filter) from +page.svelte inline switch to a
pure function, widening the fuer-dich branch to include youParticipated.
Regenerate ActivityFeedItemDTO type to include the new field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-20 21:41:04 +02:00
committed by marcel
parent 388fc5397c
commit 8b74f4ec25
3 changed files with 122 additions and 0 deletions

View File

@@ -2038,6 +2038,7 @@ export interface components {
/** Format: date-time */
happenedAt: string;
youMentioned: boolean;
youParticipated: boolean;
/** Format: int32 */
count: number;
/** Format: date-time */

View File

@@ -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> = {}): 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);
});
});
});

View File

@@ -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');
}
}