feat(transcription): clicking annotation focuses corresponding block
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) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
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) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
Pass activeAnnotationId to TranscriptionEditView. An $effect watches it and sets activeBlockId to the block matching the annotation, activating its turquoise focus border. 2 new tests (RED/GREEN): - activates block matching activeAnnotationId (turquoise border) - no block activated when activeAnnotationId is null Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ type Props = {
|
||||
blocks: TranscriptionBlockData[];
|
||||
canComment: boolean;
|
||||
currentUserId: string | null;
|
||||
activeAnnotationId?: string | null;
|
||||
onBlockFocus: (blockId: string) => void;
|
||||
onSaveBlock: (blockId: string, text: string) => Promise<void>;
|
||||
onDeleteBlock: (blockId: string) => Promise<void>;
|
||||
@@ -21,12 +22,20 @@ let {
|
||||
blocks,
|
||||
canComment,
|
||||
currentUserId,
|
||||
activeAnnotationId = null,
|
||||
onBlockFocus,
|
||||
onSaveBlock,
|
||||
onDeleteBlock
|
||||
}: Props = $props();
|
||||
|
||||
let activeBlockId: string | null = $state(null);
|
||||
|
||||
// Sync: when an annotation is clicked on the PDF, activate the corresponding block
|
||||
$effect(() => {
|
||||
if (!activeAnnotationId) return;
|
||||
const block = blocks.find((b) => b.annotationId === activeAnnotationId);
|
||||
if (block) activeBlockId = block.id;
|
||||
});
|
||||
let saveStates = new SvelteMap<string, SaveState>();
|
||||
let debounceTimers = new SvelteMap<string, ReturnType<typeof setTimeout>>();
|
||||
let pendingTexts = new SvelteMap<string, string>();
|
||||
|
||||
@@ -55,6 +55,23 @@ describe('TranscriptionEditView — rendering', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('TranscriptionEditView — annotation sync', () => {
|
||||
it('activates block matching activeAnnotationId', async () => {
|
||||
renderView({ activeAnnotationId: 'a2' });
|
||||
// Block 2 (annotation a2) should have turquoise border
|
||||
const block = document.querySelector('[data-block-id="b2"]')!;
|
||||
expect(block.className).toContain('border-turquoise');
|
||||
});
|
||||
|
||||
it('does not activate any block when activeAnnotationId is null', async () => {
|
||||
renderView({ activeAnnotationId: null });
|
||||
const block1 = document.querySelector('[data-block-id="b1"]')!;
|
||||
const block2 = document.querySelector('[data-block-id="b2"]')!;
|
||||
expect(block1.className).not.toContain('border-turquoise');
|
||||
expect(block2.className).not.toContain('border-turquoise');
|
||||
});
|
||||
});
|
||||
|
||||
describe('TranscriptionEditView — reorder', () => {
|
||||
it('renders move-up button disabled on first block', async () => {
|
||||
renderView();
|
||||
|
||||
@@ -223,6 +223,7 @@ onMount(() => {
|
||||
blocks={transcriptionBlocks}
|
||||
canComment={canWrite}
|
||||
currentUserId={currentUserId}
|
||||
activeAnnotationId={activeAnnotationId}
|
||||
onBlockFocus={handleBlockFocus}
|
||||
onSaveBlock={saveBlock}
|
||||
onDeleteBlock={deleteBlock}
|
||||
|
||||
Reference in New Issue
Block a user