feat(timeline): gate the EventPill edit pencil behind canWrite

Thread a gate-closed canWrite prop through TimelineView -> YearBand ->
EventPill and the undated bucket so a Reader never sees a dead-end edit
link. canEdit now also requires canWrite; the default false keeps an
un-threaded caller closed. The real boundary stays the #781 route guard
plus the backend permission -- this only hides the link.

Refs #842
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-15 08:03:53 +02:00
parent ec0e4dfa45
commit cd238285ae
5 changed files with 92 additions and 15 deletions

View File

@@ -16,7 +16,7 @@ type TimelineEntryDTO = components['schemas']['TimelineEntryDTO'];
* the band holds ≤ 12 (REQ-011) or collapse to a single density strip above that
* (REQ-012). Entries are never re-sorted — DTO order is preserved (REQ-003).
*/
let { year }: { year: TimelineYearDTO } = $props();
let { year, canWrite = false }: { year: TimelineYearDTO; canWrite?: boolean } = $props();
type Row =
| { t: 'event'; entry: TimelineEntryDTO }
@@ -61,7 +61,7 @@ const rows = $derived.by<Row[]>(() => {
{#if row.entry.type === 'HISTORICAL'}
<WorldBand entry={row.entry} />
{:else}
<EventPill entry={row.entry} />
<EventPill entry={row.entry} canWrite={canWrite} />
{/if}
{:else if row.t === 'letter'}
<div class="letter-row" data-side={row.side}>