Commit Graph

531 Commits

Author SHA1 Message Date
Marcel
d046c89631 test(confirm): add ConfirmDialog component spec (12 tests)
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3s
CI / Backend Unit Tests (pull_request) Failing after 1s
CI / Unit & Component Tests (push) Failing after 3s
CI / Backend Unit Tests (push) Failing after 1s
Covers: title/body rendering, destructive vs primary button class,
custom labels, settle true/cancel, aria-labelledby, and hide-after-settle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:38:58 +02:00
Marcel
a2d078b8f9 refactor(persons): replace non-null assertion with null guard on removeFormEl
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:36:47 +02:00
Marcel
0b95c90e7a refactor(confirm): use import { m } instead of import * as m in ConfirmDialog
Consistent with every other component in the project.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:35:42 +02:00
Marcel
84378f11b4 refactor(confirm): use plain let for resolveRef instead of $state
resolveRef is never read reactively — it is only read synchronously
inside settle(). Using $state was misleading about the intent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:34:52 +02:00
Marcel
3a316bc382 fix(ui): center dialog, add backdrop, hover states, and cursor-pointer on buttons
- Add m-auto and w-full to ensure the native <dialog> is centred
- Add backdrop:bg-black/50 for dimmed overlay when modal is open
- Add hover:bg-danger/80 and hover:bg-primary/80 on confirm button
- Add cursor-pointer to both cancel and confirm buttons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:33:33 +02:00
Marcel
1a519eedd6 refactor(persons): replace inline delete modal with ConfirmService in NameHistoryEditCard
Some checks failed
CI / Unit & Component Tests (push) Failing after 4s
CI / Backend Unit Tests (push) Failing after 1s
CI / Unit & Component Tests (pull_request) Failing after 3s
CI / Backend Unit Tests (pull_request) Failing after 2s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:19:33 +02:00
Marcel
498679234a refactor(docs): replace inline confirmDelete toggle with ConfirmService in SaveBar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:12:01 +02:00
Marcel
14fc5cbc54 refactor(admin): replace window.confirm with ConfirmService in admin group delete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:06:54 +02:00
Marcel
0d1401ce4f refactor(admin): replace window.confirm with ConfirmService in admin user delete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 14:04:09 +02:00
Marcel
d4ead08c17 refactor(transcription): replace window.confirm with ConfirmService in TranscriptionBlock
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:47:37 +02:00
Marcel
08bd27b5cd feat(layout): mount ConfirmDialog in root layout and provide confirm service
provideConfirmService() sets up context for the entire component tree.
ConfirmDialog is mounted once at the bottom of the layout shell.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:21:34 +02:00
Marcel
1942c2a5cb feat(confirm): add ConfirmService and ConfirmDialog with deferred-Promise pattern
- confirm.svelte.ts: context-based async service returning Promise<boolean>
- ConfirmDialog.svelte: native <dialog> element, reads service from context
- Concurrent calls return false immediately (guard at top of confirm())
- SSR-safe: confirm() returns Promise.resolve(false) on server
- getConfirmService() throws descriptive error outside provider tree
- 5 Vitest tests: confirm/cancel/Escape/concurrent/outside-provider all green

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:20:37 +02:00
Marcel
fb00de6690 feat(design-system): add --c-danger/--c-danger-fg token pair for destructive actions
Light: #c0392b (5.1:1 on white — WCAG AA), dark: #e55347 (4.7:1 on surface).
Exposed as bg-danger/text-danger-fg Tailwind utilities via @theme inline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:07:46 +02:00
Marcel
52dd72ae8d feat(i18n): add btn_confirm key to de/en/es message files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:06:43 +02:00
Marcel
166f60f7d3 feat(ui): show type icon in avatar for non-person entities
Person list and detail page avatars now display a type-specific
icon (building, people group, question mark) instead of meaningless
initials for INSTITUTION, GROUP, and UNKNOWN person types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:36:34 +02:00
Marcel
a1b21d6989 refactor(ui): use CSS custom properties for PersonTypeBadge colors
Replace hardcoded Tailwind utility colors with project CSS variables
(--c-badge-institution-*, --c-badge-group-*, --c-badge-unknown-*).
Dark mode variants defined in both @media and manual toggle blocks.
Extract shared badge classes and use $derived config object.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:35:05 +02:00
Marcel
6ee1ef73c3 feat(ui): add PersonTypeBadge to person list and detail pages
Show colored badge for non-PERSON types per design spec:
- INSTITUTION: blue with building icon
- GROUP: purple with people icon
- UNKNOWN: amber with question mark icon
- PERSON: no badge (unmarked default)

Badge appears on person cards in list and on detail page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:09:16 +02:00
Marcel
1aabd9826c test(frontend): update mock data for displayName and nullable firstName
Add displayName and personType to all Person mock objects in
component and page tests. Update assertions from reversed
"lastName, firstName" format to forward-order displayName.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:47:15 +02:00
Marcel
9caef1e79e feat(i18n): add PersonType and MAIDEN_NAME translation keys
Add translations for PersonType values (PERSON, INSTITUTION, GROUP,
UNKNOWN) and PersonNameAliasType.MAIDEN_NAME in de/en/es.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:46:36 +02:00
Marcel
f11d8a38ed feat(frontend): replace all name concatenation with displayName
- Add displayName default method to PersonSummaryDTO
- Update native SQL queries to include title, person_type columns
- Add getInitials() utility to personFormat.ts
- Update abbreviateName/abbreviateCompact for nullable firstName
- Replace firstName+lastName concatenation with displayName in all
  person-displaying components and server load files
- Regenerate API types with displayName on Person and PersonSummaryDTO

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:22:30 +02:00
Marcel
0ce803c7f1 build(frontend): regenerate API types for Person changes
Person type now includes displayName (readonly, required), title,
personType (required enum), and firstName is optional.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:06:38 +02:00
Marcel
e204ed89b6 fix(ui): switch alias operations from client fetch to form actions
Some checks failed
CI / Unit & Component Tests (push) Failing after 1s
CI / Backend Unit Tests (push) Failing after 2s
CI / Unit & Component Tests (pull_request) Failing after 1s
CI / Backend Unit Tests (pull_request) Failing after 1s
Replaces raw client-side fetch with SvelteKit form actions
(addAlias, removeAlias) using the server-side API client for
proper auth handling. 10 new component tests for NameHistoryEditCard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 16:05:56 +02:00
Marcel
036843bf8f fix(ui): use mt-6 on save bar to match card spacing
Some checks failed
CI / Unit & Component Tests (push) Failing after 3s
CI / Backend Unit Tests (push) Failing after 2s
CI / Unit & Component Tests (pull_request) Failing after 2s
CI / Backend Unit Tests (pull_request) Failing after 1s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 16:01:43 +02:00
Marcel
9027f60760 fix(ui): use card-style save bar with mt-4 instead of full-bleed
Some checks failed
CI / Unit & Component Tests (push) Failing after 3s
CI / Backend Unit Tests (push) Failing after 1s
CI / Unit & Component Tests (pull_request) Failing after 1s
CI / Backend Unit Tests (pull_request) Failing after 1s
Removes -mx-4 negative margin and switches to the card pattern
(rounded border, shadow-sm, mt-4) so the save bar matches the
width of the other cards on the edit page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:59:55 +02:00
Marcel
0f5eebec29 fix(ui): move save bar to end of edit page after alias and danger zone
Some checks failed
CI / Unit & Component Tests (push) Failing after 2s
CI / Backend Unit Tests (push) Failing after 1s
CI / Unit & Component Tests (pull_request) Failing after 1s
CI / Backend Unit Tests (pull_request) Failing after 1s
Uses HTML form attribute to associate the submit button with the
person-edit-form from outside the form tag. Page now reads:
Personendaten -> Namensverlauf -> Danger zone -> Save bar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:59:05 +02:00
Marcel
f0eb3a76be test(ui): add component tests for NameHistoryCard
Some checks failed
CI / Unit & Component Tests (push) Failing after 3s
CI / Backend Unit Tests (push) Failing after 1s
CI / Unit & Component Tests (pull_request) Failing after 2s
CI / Backend Unit Tests (pull_request) Failing after 2s
Verifies alias rendering, empty state, firstName fallback,
and type label display. 5 browser-based Svelte tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:43:09 +02:00
Marcel
6d837c518c fix(a11y): include alias name in delete button aria-label
Screen readers now announce which alias is being deleted, e.g.
"Entfernen de Gruyter" instead of just "Entfernen".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:42:08 +02:00
Marcel
97646a31df fix(ui): always show Namensverlauf card on detail page
Removes the {#if} guard so the card with empty state message is
always visible for feature discoverability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:41:19 +02:00
Marcel
59f593280b fix(test): update person detail loader tests for 4th aliases API call
Some checks failed
CI / Unit & Component Tests (push) Failing after 2s
CI / Backend Unit Tests (push) Failing after 1s
CI / Unit & Component Tests (pull_request) Failing after 1s
CI / Backend Unit Tests (pull_request) Failing after 2s
Adds mock for the new GET /api/persons/{id}/aliases call added
in the parallel Promise.all.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:35:19 +02:00
Marcel
b910517690 feat(ui): add alias management to person edit page
NameHistoryEditCard with add form (type dropdown + name fields),
delete with confirmation modal, and IDOR-safe client-side fetch
calls. Placed between Personendaten and DangerZone cards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:31:41 +02:00
Marcel
002ee1010a feat(ui): add Namensverlauf read-only card to person detail page
Shows historical name aliases in the left column with type labels
and firstName fallback. Fetches aliases in parallel with other data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:31:07 +02:00
Marcel
9e13208ccd chore(api): regenerate TypeScript API types with alias endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:24:03 +02:00
Marcel
f396e079a5 feat(i18n): add alias type labels and section strings for de/en/es
Adds 16 new keys per language: alias type labels (BIRTH, WIDOWED,
DIVORCED, OTHER), section heading, empty state, add form labels,
delete confirmation, and ALIAS_NOT_FOUND error code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:21:21 +02:00
Marcel
b5ec4ebc0c refactor(ui): rename shadowed m parameter to newMode
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 1s
CI / Backend Unit Tests (pull_request) Failing after 3s
CI / Unit & Component Tests (push) Failing after 3s
CI / Backend Unit Tests (push) Failing after 2s
Avoids shadowing the Paraglide m import in the onModeChange callback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:58:54 +02:00
Marcel
10fdaf7d00 refactor(ui): use CSS variable for turquoise in flash animations
Replaces hardcoded rgba(0,199,177,...) with color-mix using
var(--color-turquoise) for dark mode compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:58:04 +02:00
Marcel
e01ef56c48 fix(i18n): use getLocale() for date formatting in panel header
Replaces hardcoded 'de-DE' with the active Paraglide locale so
dates render in the user's language.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:56:23 +02:00
Marcel
b01a9ef406 refactor(ui): use bg-turquoise/10 token for paragraph hover
Replaces hardcoded rgba value with the project's turquoise color
token for dark mode compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:54:57 +02:00
Marcel
e31b73303e fix(ui): bump paragraph hover opacity from 6% to 10%
Improves visibility of the clickability affordance on uncalibrated
displays and for senior users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:53:17 +02:00
Marcel
9d9d19ceb5 fix(a11y): increase segmented toggle height on mobile to 36px
Uses h-9 (36px) on mobile, h-7 (28px) on desktop for better tap
targets on small screens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:51:56 +02:00
Marcel
0a5c82cd0e fix(a11y): increase panel close button touch target to 44px
Changes h-8 w-8 (32px) to h-11 w-11 (44px) to meet project's
minimum touch target standard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:50:32 +02:00
Marcel
1b063d4e4b test(ui): add tests for 0 blocks and lastEditedAt on PanelHeader
Verifies blockCount=0 shows "0 Abschnitte" and that a provided
lastEditedAt value renders a formatted date containing the year.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:46:53 +02:00
Marcel
b312878b3f test(ui): add annotation-flash class tests for AnnotationLayer
Verifies flashAnnotationId applies and removes the annotation-flash
CSS class correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:45:23 +02:00
Marcel
90120ca8e8 test(ui): add flash-highlight class tests for TranscriptionReadView
Verifies highlightBlockId applies and removes the flash-highlight
CSS class correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:44:01 +02:00
Marcel
4d5b8b4ead feat(ui): add collapsible PDF strip and abbreviated labels on mobile
Some checks failed
CI / Unit & Component Tests (push) Failing after 2s
CI / Backend Unit Tests (push) Failing after 2s
CI / Unit & Component Tests (pull_request) Failing after 3s
CI / Backend Unit Tests (pull_request) Failing after 1s
PDF viewer collapses to 70px on mobile in read mode, expandable to
50vh. Toggle button with chevron. Paragraph tap auto-expands strip.
Mode toggle abbreviates to "Bearb." on small screens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:30:36 +02:00
Marcel
10cecb01f5 feat(a11y): respect prefers-reduced-motion for scroll-sync
Uses scrollIntoView behavior 'instant' instead of 'smooth', skips
CSS animations (static highlight instead), and extends timeout to
2s for reduced-motion users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:27:01 +02:00
Marcel
81b14e5026 feat(ui): add bidirectional scroll-sync with flash animations
Paragraph click flashes the PDF annotation outline (1.5s fade).
Annotation click highlights the paragraph with a background flash.
Both directions scroll the target into view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:25:23 +02:00
Marcel
e089192d7a feat(ui): wire panelMode state with read/edit view switching
Adds TranscriptionPanelHeader and TranscriptionReadView to the
document detail page. Default mode is 'read' when blocks exist,
'edit' otherwise. Annotations dimmed in read mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:21:15 +02:00
Marcel
306eef2e95 feat(ui): add TranscriptionReadView for flowing prose display
Renders transcription blocks as readable text with [unleserlich]/[...]
markers styled as italic muted text. Supports click-to-sync and
flash highlight for scroll-sync feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:14:53 +02:00
Marcel
7d98081390 feat(ui): add TranscriptionPanelHeader with mode toggle and status
Segmented Lesen/Bearbeiten control, block count, last-edited date,
and close button. Lesen disabled when no blocks exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:10:39 +02:00
Marcel
d070ae2612 feat(annotation): add dimmed prop to AnnotationLayer
Hides block number badges and disables hover/active visual feedback
when dimmed=true. Click handlers remain active for scroll-sync.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:07:23 +02:00