refactor(person): fold year range into section headings, remove standalone stats bar
The floating stats bar was visually disconnected and showed a combined document count already visible from the per-section badges. Replaced it with a year range shown inline next to each section heading (e.g. "Gesendete Dokumente · 12 · 1921–1945"), making the range contextually relevant per direction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -125,6 +125,29 @@ test.describe('Person detail — sent and received documents', () => {
|
|||||||
await expect(page.getByRole('heading', { name: /Empfangene Dokumente/i })).toBeVisible();
|
await expect(page.getByRole('heading', { name: /Empfangene Dokumente/i })).toBeVisible();
|
||||||
await page.screenshot({ path: 'test-results/e2e/person-sent-received.png' });
|
await page.screenshot({ path: 'test-results/e2e/person-sent-received.png' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('shows year range next to document count when documents have dates', async ({ page }) => {
|
||||||
|
// Navigate to the first person who has documents with dates
|
||||||
|
await page.goto('/persons');
|
||||||
|
const personLinks = page.locator('a[href^="/persons/"]:not([href="/persons/new"])');
|
||||||
|
const count = await personLinks.count();
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
await page.goto('/persons');
|
||||||
|
await personLinks.nth(i).click();
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
|
||||||
|
// Check if either section heading has a year range (4 digits)
|
||||||
|
const sentHeading = page.getByRole('heading', { name: /Gesendete Dokumente/i }).locator('..');
|
||||||
|
const hasYearRange = await sentHeading.locator('span').filter({ hasText: /\d{4}/ }).count();
|
||||||
|
if (hasYearRange > 0) {
|
||||||
|
await expect(sentHeading.locator('span').filter({ hasText: /\d{4}/ }).first()).toBeVisible();
|
||||||
|
await page.screenshot({ path: 'test-results/e2e/person-year-range.png' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If no person has dated documents, the test is a no-op (year range is optional)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Person detail — conversations link', () => {
|
test.describe('Person detail — conversations link', () => {
|
||||||
|
|||||||
@@ -24,15 +24,18 @@
|
|||||||
|
|
||||||
const allDocuments = $derived([...sentDocuments, ...receivedDocuments]);
|
const allDocuments = $derived([...sentDocuments, ...receivedDocuments]);
|
||||||
|
|
||||||
const docStats = $derived(() => {
|
function yearRange(docs: typeof sentDocuments) {
|
||||||
const dated = allDocuments.filter(d => d.documentDate);
|
const years = docs
|
||||||
const years = dated.map(d => parseInt(d.documentDate!.substring(0, 4)));
|
.filter(d => d.documentDate)
|
||||||
return {
|
.map(d => parseInt(d.documentDate!.substring(0, 4)));
|
||||||
total: allDocuments.length,
|
if (!years.length) return null;
|
||||||
minYear: years.length ? Math.min(...years) : null,
|
const min = Math.min(...years);
|
||||||
maxYear: years.length ? Math.max(...years) : null,
|
const max = Math.max(...years);
|
||||||
};
|
return min === max ? `${min}` : `${min} – ${max}`;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
const sentYearRange = $derived(yearRange(sentDocuments));
|
||||||
|
const receivedYearRange = $derived(yearRange(receivedDocuments));
|
||||||
|
|
||||||
const coCorrespondents = $derived(() => {
|
const coCorrespondents = $derived(() => {
|
||||||
const freq = new Map<string, { id: string; name: string; count: number }>();
|
const freq = new Map<string, { id: string; name: string; count: number }>();
|
||||||
@@ -327,21 +330,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Document Statistics Bar -->
|
|
||||||
{#if docStats().total > 0}
|
|
||||||
<div class="mb-8 px-4 py-3 bg-brand-sand/30 rounded-sm flex items-center gap-2 font-sans text-sm text-brand-navy/70">
|
|
||||||
<span>{docStats().total} Dokumente</span>
|
|
||||||
{#if docStats().minYear !== null}
|
|
||||||
<span class="text-brand-mint">·</span>
|
|
||||||
{#if docStats().minYear === docStats().maxYear}
|
|
||||||
<span>{docStats().minYear}</span>
|
|
||||||
{:else}
|
|
||||||
<span>{docStats().minYear} – {docStats().maxYear}</span>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- Sort control -->
|
<!-- Sort control -->
|
||||||
{#if allDocuments.length > 0}
|
{#if allDocuments.length > 0}
|
||||||
<div class="flex justify-end mb-4">
|
<div class="flex justify-end mb-4">
|
||||||
@@ -362,6 +350,9 @@
|
|||||||
<span class="bg-brand-navy text-white text-xs font-bold px-2 py-1 rounded-full">
|
<span class="bg-brand-navy text-white text-xs font-bold px-2 py-1 rounded-full">
|
||||||
{sentDocuments.length}
|
{sentDocuments.length}
|
||||||
</span>
|
</span>
|
||||||
|
{#if sentYearRange}
|
||||||
|
<span class="text-xs font-sans text-gray-400">{sentYearRange}</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if sentDocuments.length === 0}
|
{#if sentDocuments.length === 0}
|
||||||
@@ -423,6 +414,9 @@
|
|||||||
<span class="bg-brand-navy text-white text-xs font-bold px-2 py-1 rounded-full">
|
<span class="bg-brand-navy text-white text-xs font-bold px-2 py-1 rounded-full">
|
||||||
{receivedDocuments.length}
|
{receivedDocuments.length}
|
||||||
</span>
|
</span>
|
||||||
|
{#if receivedYearRange}
|
||||||
|
<span class="text-xs font-sans text-gray-400">{receivedYearRange}</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if receivedDocuments.length === 0}
|
{#if receivedDocuments.length === 0}
|
||||||
|
|||||||
Reference in New Issue
Block a user