feat(viewer): show delete icon on annotation for direct block deletion (#339)
Adds a trash icon button (44×44 px touch target) directly on each annotation shape in transcription mode so users can delete a block without navigating through the sidebar. Includes keyboard support (Delete key), confirm dialog via ConfirmService, prop-chain wiring through DocumentViewer → PdfViewer → AnnotationLayer → AnnotationShape, and orphaned-annotation fallback (calls DELETE /annotations/{id} when no block is linked). Backend security regression test added for deleteBlock 403 on READ_ALL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,7 +98,7 @@ describe('AnnotationLayer', () => {
|
||||
expect(el2.style.opacity).toBe('1');
|
||||
});
|
||||
|
||||
it('does not show delete buttons (annotations owned by blocks)', async () => {
|
||||
it('does not show delete button when annotation is not hovered or active', async () => {
|
||||
render(AnnotationLayer, {
|
||||
annotations: [makeAnnotation('ann-1')],
|
||||
canDraw: true,
|
||||
@@ -107,6 +107,19 @@ describe('AnnotationLayer', () => {
|
||||
});
|
||||
|
||||
await expect.element(page.getByTestId('annotation-ann-1')).toBeInTheDocument();
|
||||
expect(page.getByRole('button', { name: /löschen/i }).query()).toBeNull();
|
||||
expect(page.getByTestId('annotation-delete-ann-1').query()).toBeNull();
|
||||
});
|
||||
|
||||
it('does not show delete button when canDraw is false even if annotation is active', async () => {
|
||||
render(AnnotationLayer, {
|
||||
annotations: [makeAnnotation('ann-1')],
|
||||
canDraw: false,
|
||||
color: '#00C7B1',
|
||||
activeAnnotationId: 'ann-1',
|
||||
onDraw: () => {}
|
||||
});
|
||||
|
||||
await expect.element(page.getByTestId('annotation-ann-1')).toBeInTheDocument();
|
||||
expect(page.getByTestId('annotation-delete-ann-1').query()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user