Compare commits

..

3 Commits

Author SHA1 Message Date
Marcel
96d9ff5db1 fix(PersonHoverCard): move chip colon into DOM for consistent screen reader announcement
Some checks failed
CI / Unit & Component Tests (push) Failing after 3m24s
CI / OCR Service Tests (push) Successful in 29s
CI / Backend Unit Tests (push) Failing after 2m59s
CI / Unit & Component Tests (pull_request) Failing after 3m25s
CI / OCR Service Tests (pull_request) Successful in 38s
CI / Backend Unit Tests (pull_request) Failing after 3m19s
Replaces CSS ::after { content: ':' } with literal colon inside the
chip-type span. CSS-generated content is announced inconsistently
across NVDA+Chrome and VoiceOver+Safari; a real text node is always
reliable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:32:21 +02:00
Marcel
0113367d05 refactor(TranscriptionReadView): remove dead else branch in handleMentionLeave
Only mouseleave is wired in attachMentionHandlers so the else branch
could never fire.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:29:26 +02:00
Marcel
fb6bffd7ee test(TranscriptionService): verify clear() removes prior mentions before applying DTO
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:27:26 +02:00
3 changed files with 31 additions and 10 deletions

View File

@@ -241,6 +241,35 @@ class TranscriptionServiceTest {
.containsExactly(mention);
}
@Test
void updateBlock_clearsPriorMentions_beforeApplyingDto() {
UUID docId = UUID.randomUUID();
UUID blockId = UUID.randomUUID();
PersonMention prior = new PersonMention(UUID.randomUUID(), "Heinrich");
PersonMention incoming = new PersonMention(UUID.randomUUID(), "Auguste");
TranscriptionBlock block = TranscriptionBlock.builder()
.id(blockId).documentId(docId).text("old").build();
block.getMentionedPersons().add(prior);
when(blockRepository.findByIdAndDocumentId(blockId, docId)).thenReturn(Optional.of(block));
when(blockRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
when(documentService.getDocumentById(any())).thenReturn(
Document.builder().scriptType(ScriptType.TYPEWRITER).build());
UpdateTranscriptionBlockDTO dto = UpdateTranscriptionBlockDTO.builder()
.text("@Auguste text")
.mentionedPersons(List.of(incoming))
.build();
TranscriptionBlock result = transcriptionService.updateBlock(docId, blockId, dto, UUID.randomUUID());
assertThat(result.getMentionedPersons())
.containsExactly(incoming)
.doesNotContain(prior);
}
@Test
void updateBlock_triggersTraining_whenKurrentSenderPresent() {
UUID docId = UUID.randomUUID();

View File

@@ -131,7 +131,7 @@ const showMaidenName = $derived(
<div class="chips" data-testid="person-hover-card-chips">
{#each familyChips as chip (chip.id)}
<span class="chip">
<span class="chip-type">{chipLabel(chip, personId)}</span>
<span class="chip-type">{chipLabel(chip, personId)}:</span>
{otherName(chip, personId)}
</span>
{/each}
@@ -261,10 +261,6 @@ const showMaidenName = $derived(
opacity: 0.7;
}
.chip-type::after {
content: ':';
}
.notes {
font-size: 13px;
color: var(--c-ink-2);

View File

@@ -155,11 +155,7 @@ async function handleMentionEnter(event: Event) {
function handleMentionLeave(event: Event) {
const link = event.target as HTMLAnchorElement;
link.removeAttribute('aria-describedby');
if (event.type === 'mouseleave') {
scheduleCardClose();
} else {
activeCard = null;
}
scheduleCardClose();
}
/**