feat(persons): add sort toggle to person document list (issue #24)
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 1m55s
CI / Backend Unit Tests (pull_request) Successful in 2m9s
CI / E2E Tests (pull_request) Successful in 18m8s
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 1m55s
CI / Backend Unit Tests (pull_request) Successful in 2m9s
CI / E2E Tests (pull_request) Successful in 18m8s
Extracted sortDocumentsByDate utility with full Vitest coverage (6 tests), wired it into the person detail page with a DESC/ASC toggle button, and added an E2E smoke test for the toggle interaction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
44
frontend/src/lib/utils/sort.spec.ts
Normal file
44
frontend/src/lib/utils/sort.spec.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { sortDocumentsByDate } from './sort';
|
||||
|
||||
const doc = (id: string, documentDate: string | null) =>
|
||||
({ id, documentDate } as { id: string; documentDate: string | null });
|
||||
|
||||
describe('sortDocumentsByDate', () => {
|
||||
it('sorts DESC by default — newest first', () => {
|
||||
const docs = [doc('a', '1920-01-01'), doc('b', '1950-06-15'), doc('c', '1935-03-10')];
|
||||
const result = sortDocumentsByDate(docs, 'DESC');
|
||||
expect(result.map((d) => d.id)).toEqual(['b', 'c', 'a']);
|
||||
});
|
||||
|
||||
it('sorts ASC — oldest first', () => {
|
||||
const docs = [doc('a', '1920-01-01'), doc('b', '1950-06-15'), doc('c', '1935-03-10')];
|
||||
const result = sortDocumentsByDate(docs, 'ASC');
|
||||
expect(result.map((d) => d.id)).toEqual(['a', 'c', 'b']);
|
||||
});
|
||||
|
||||
it('places documents without a date last in DESC', () => {
|
||||
const docs = [doc('a', null), doc('b', '1940-01-01'), doc('c', null)];
|
||||
const result = sortDocumentsByDate(docs, 'DESC');
|
||||
expect(result[0].id).toBe('b');
|
||||
expect(result.slice(1).map((d) => d.id)).toContain('a');
|
||||
expect(result.slice(1).map((d) => d.id)).toContain('c');
|
||||
});
|
||||
|
||||
it('places documents without a date last in ASC', () => {
|
||||
const docs = [doc('a', null), doc('b', '1940-01-01'), doc('c', null)];
|
||||
const result = sortDocumentsByDate(docs, 'ASC');
|
||||
expect(result[0].id).toBe('b');
|
||||
});
|
||||
|
||||
it('does not mutate the original array', () => {
|
||||
const docs = [doc('a', '1950-01-01'), doc('b', '1920-01-01')];
|
||||
const original = [...docs];
|
||||
sortDocumentsByDate(docs, 'ASC');
|
||||
expect(docs).toEqual(original);
|
||||
});
|
||||
|
||||
it('returns an empty array unchanged', () => {
|
||||
expect(sortDocumentsByDate([], 'DESC')).toEqual([]);
|
||||
});
|
||||
});
|
||||
19
frontend/src/lib/utils/sort.ts
Normal file
19
frontend/src/lib/utils/sort.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export type SortDir = 'ASC' | 'DESC';
|
||||
|
||||
/**
|
||||
* Returns a new array of documents sorted by documentDate.
|
||||
* Documents without a date are always placed last, regardless of direction.
|
||||
*/
|
||||
export function sortDocumentsByDate<T extends { documentDate?: string | null }>(
|
||||
docs: T[],
|
||||
dir: SortDir
|
||||
): T[] {
|
||||
return [...docs].sort((a, b) => {
|
||||
const da = a.documentDate ?? '';
|
||||
const db = b.documentDate ?? '';
|
||||
if (!da && !db) return 0;
|
||||
if (!da) return 1;
|
||||
if (!db) return -1;
|
||||
return dir === 'DESC' ? db.localeCompare(da) : da.localeCompare(db);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user