feat(transcription): show block numbers on PDF annotation overlays
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) Failing after 1m26s
CI / Backend Unit Tests (pull_request) Failing after 2m29s
CI / E2E Tests (pull_request) Failing after 1h28m33s
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) Failing after 1m26s
CI / Backend Unit Tests (pull_request) Failing after 2m29s
CI / E2E Tests (pull_request) Failing after 1h28m33s
Add blockNumbers prop through AnnotationLayer → PdfViewer → DocumentViewer. Each turquoise annotation rectangle now shows a numbered badge (top-left, matching the block card number in the right panel). Block numbers are derived from sorted transcriptionBlocks, mapped by annotationId, creating a visual link between PDF regions and block cards. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,12 +12,14 @@ let {
|
|||||||
annotations = [],
|
annotations = [],
|
||||||
canDraw,
|
canDraw,
|
||||||
color,
|
color,
|
||||||
|
blockNumbers = {},
|
||||||
onDraw,
|
onDraw,
|
||||||
onAnnotationClick
|
onAnnotationClick
|
||||||
}: {
|
}: {
|
||||||
annotations: Annotation[];
|
annotations: Annotation[];
|
||||||
canDraw: boolean;
|
canDraw: boolean;
|
||||||
color: string;
|
color: string;
|
||||||
|
blockNumbers?: Record<string, number>;
|
||||||
onDraw: (rect: DrawRect) => void;
|
onDraw: (rect: DrawRect) => void;
|
||||||
onAnnotationClick?: (id: string) => void;
|
onAnnotationClick?: (id: string) => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
@@ -125,7 +127,32 @@ const containerStyle = $derived(
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.15s ease, box-shadow 0.15s ease;
|
transition: background-color 0.15s ease, box-shadow 0.15s ease;
|
||||||
"
|
"
|
||||||
></div>
|
>
|
||||||
|
{#if blockNumbers[annotation.id]}
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
left: -8px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: {annotation.color};
|
||||||
|
color: white;
|
||||||
|
font-size: 11px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
pointer-events: none;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{blockNumbers[annotation.id]}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
{#if drawRect && drawRect.width > 0}
|
{#if drawRect && drawRect.width > 0}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type Props = {
|
|||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
transcribeMode?: boolean;
|
transcribeMode?: boolean;
|
||||||
|
blockNumbers?: Record<string, number>;
|
||||||
activeAnnotationId: string | null;
|
activeAnnotationId: string | null;
|
||||||
onAnnotationClick: (id: string) => void;
|
onAnnotationClick: (id: string) => void;
|
||||||
onTranscriptionDraw?: (rect: DrawRect) => void;
|
onTranscriptionDraw?: (rect: DrawRect) => void;
|
||||||
@@ -28,6 +29,7 @@ let {
|
|||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
transcribeMode = false,
|
transcribeMode = false,
|
||||||
|
blockNumbers = {},
|
||||||
activeAnnotationId = $bindable(),
|
activeAnnotationId = $bindable(),
|
||||||
onAnnotationClick,
|
onAnnotationClick,
|
||||||
onTranscriptionDraw
|
onTranscriptionDraw
|
||||||
@@ -83,6 +85,7 @@ let {
|
|||||||
url={fileUrl}
|
url={fileUrl}
|
||||||
documentId={doc.id}
|
documentId={doc.id}
|
||||||
transcribeMode={transcribeMode}
|
transcribeMode={transcribeMode}
|
||||||
|
blockNumbers={blockNumbers}
|
||||||
bind:activeAnnotationId={activeAnnotationId}
|
bind:activeAnnotationId={activeAnnotationId}
|
||||||
onAnnotationClick={onAnnotationClick}
|
onAnnotationClick={onAnnotationClick}
|
||||||
onTranscriptionDraw={onTranscriptionDraw}
|
onTranscriptionDraw={onTranscriptionDraw}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ let {
|
|||||||
url,
|
url,
|
||||||
documentId = '',
|
documentId = '',
|
||||||
transcribeMode = false,
|
transcribeMode = false,
|
||||||
|
blockNumbers = {},
|
||||||
activeAnnotationId = $bindable<string | null>(null),
|
activeAnnotationId = $bindable<string | null>(null),
|
||||||
onAnnotationClick,
|
onAnnotationClick,
|
||||||
onTranscriptionDraw,
|
onTranscriptionDraw,
|
||||||
@@ -19,6 +20,7 @@ let {
|
|||||||
url: string;
|
url: string;
|
||||||
documentId?: string;
|
documentId?: string;
|
||||||
transcribeMode?: boolean;
|
transcribeMode?: boolean;
|
||||||
|
blockNumbers?: Record<string, number>;
|
||||||
activeAnnotationId?: string | null;
|
activeAnnotationId?: string | null;
|
||||||
onAnnotationClick?: (id: string) => void;
|
onAnnotationClick?: (id: string) => void;
|
||||||
onTranscriptionDraw?: (rect: DrawRect) => void;
|
onTranscriptionDraw?: (rect: DrawRect) => void;
|
||||||
@@ -424,6 +426,7 @@ function zoomOut() {
|
|||||||
annotations={visibleAnnotations.filter((a) => a.pageNumber === currentPage)}
|
annotations={visibleAnnotations.filter((a) => a.pageNumber === currentPage)}
|
||||||
canDraw={transcribeMode}
|
canDraw={transcribeMode}
|
||||||
color={TRANSCRIPTION_COLOR}
|
color={TRANSCRIPTION_COLOR}
|
||||||
|
blockNumbers={blockNumbers}
|
||||||
onDraw={handleDraw}
|
onDraw={handleDraw}
|
||||||
onAnnotationClick={handleAnnotationClick}
|
onAnnotationClick={handleAnnotationClick}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -55,6 +55,14 @@ let activeAnnotationId = $state<string | null>(null);
|
|||||||
|
|
||||||
let transcriptionBlocks = $state<TranscriptionBlockData[]>([]);
|
let transcriptionBlocks = $state<TranscriptionBlockData[]>([]);
|
||||||
|
|
||||||
|
const blockNumbers = $derived(
|
||||||
|
Object.fromEntries(
|
||||||
|
[...transcriptionBlocks]
|
||||||
|
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||||
|
.map((b, i) => [b.annotationId, i + 1])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
async function loadTranscriptionBlocks() {
|
async function loadTranscriptionBlocks() {
|
||||||
if (!doc?.id) return;
|
if (!doc?.id) return;
|
||||||
try {
|
try {
|
||||||
@@ -197,6 +205,7 @@ onMount(() => {
|
|||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
error={fileError}
|
error={fileError}
|
||||||
transcribeMode={transcribeMode}
|
transcribeMode={transcribeMode}
|
||||||
|
blockNumbers={blockNumbers}
|
||||||
bind:activeAnnotationId={activeAnnotationId}
|
bind:activeAnnotationId={activeAnnotationId}
|
||||||
onAnnotationClick={handleAnnotationClick}
|
onAnnotationClick={handleAnnotationClick}
|
||||||
onTranscriptionDraw={createBlockFromDraw}
|
onTranscriptionDraw={createBlockFromDraw}
|
||||||
|
|||||||
Reference in New Issue
Block a user