Deduplicate guest tasks list and restore header icon
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-14 11:17:35 +01:00
parent 03c7b20cae
commit c0193c9581
4 changed files with 45 additions and 2 deletions

View File

@@ -13,6 +13,7 @@ import {
Clock, Clock,
MessageSquare, MessageSquare,
Sparkles, Sparkles,
LifeBuoy,
UploadCloud, UploadCloud,
AlertCircle, AlertCircle,
Check, Check,

View File

@@ -0,0 +1,22 @@
import { dedupeTasksById } from '../taskUtils';
describe('dedupeTasksById', () => {
it('returns empty array for empty input', () => {
expect(dedupeTasksById([])).toEqual([]);
});
it('keeps the first occurrence and preserves order', () => {
const tasks = [
{ id: 1, title: 'A' },
{ id: 2, title: 'B' },
{ id: 1, title: 'A-dup' },
{ id: 3, title: 'C' },
];
expect(dedupeTasksById(tasks)).toEqual([
{ id: 1, title: 'A' },
{ id: 2, title: 'B' },
{ id: 3, title: 'C' },
]);
});
});

View File

@@ -0,0 +1,18 @@
export type TaskIdentity = {
id: number;
};
export function dedupeTasksById<T extends TaskIdentity>(tasks: T[]): T[] {
const seen = new Set<number>();
const unique: T[] = [];
tasks.forEach((task) => {
if (seen.has(task.id)) {
return;
}
seen.add(task.id);
unique.push(task);
});
return unique;
}

View File

@@ -21,6 +21,7 @@ import { getDeviceId } from '../lib/device';
import { FADE_SCALE, FADE_UP, STAGGER_FAST, getMotionContainerProps, getMotionItemProps, prefersReducedMotion } from '../lib/motion'; import { FADE_SCALE, FADE_UP, STAGGER_FAST, getMotionContainerProps, getMotionItemProps, prefersReducedMotion } from '../lib/motion';
import PullToRefresh from '../components/PullToRefresh'; import PullToRefresh from '../components/PullToRefresh';
import { triggerHaptic } from '../lib/haptics'; import { triggerHaptic } from '../lib/haptics';
import { dedupeTasksById } from '../lib/taskUtils';
interface Task { interface Task {
id: number; id: number;
@@ -133,9 +134,10 @@ export default function TaskPickerPage() {
? payload.tasks ? payload.tasks
: []; : [];
const entry = { data: taskList, etag: response.headers.get('ETag') }; const uniqueTasks = dedupeTasksById(taskList);
const entry = { data: uniqueTasks, etag: response.headers.get('ETag') };
tasksCacheRef.current.set(cacheKey, entry); tasksCacheRef.current.set(cacheKey, entry);
setTasks(taskList); setTasks(uniqueTasks);
} catch (err) { } catch (err) {
console.error('Failed to load tasks', err); console.error('Failed to load tasks', err);
setError(err instanceof Error ? err.message : 'Unbekannter Fehler'); setError(err instanceof Error ? err.message : 'Unbekannter Fehler');