@semiont/react-ui 0.2.45 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PdfAnnotationCanvas.client-COQREPXU.mjs → PdfAnnotationCanvas.client-PVTVPDBQ.mjs} +3 -4
- package/dist/PdfAnnotationCanvas.client-PVTVPDBQ.mjs.map +1 -0
- package/dist/{ar-7SUXNE34.mjs → ar-APUOG2AP.mjs} +46 -6
- package/dist/ar-APUOG2AP.mjs.map +1 -0
- package/dist/{bn-XOET3DOI.mjs → bn-EFK2LJGK.mjs} +46 -6
- package/dist/bn-EFK2LJGK.mjs.map +1 -0
- package/dist/{chunk-JH7BXE2P.mjs → chunk-7DW2P4UE.mjs} +45 -5
- package/dist/chunk-7DW2P4UE.mjs.map +1 -0
- package/dist/{chunk-Q2KV6Y2J.mjs → chunk-7GEYABC6.mjs} +32 -32
- package/dist/{chunk-3JTO27MH.mjs → chunk-D4GAAQMM.mjs} +2 -9
- package/dist/{cs-X63DXX7L.mjs → cs-A26MEEQE.mjs} +46 -6
- package/dist/cs-A26MEEQE.mjs.map +1 -0
- package/dist/{da-OWTCV57A.mjs → da-U3L2FHSZ.mjs} +46 -6
- package/dist/da-U3L2FHSZ.mjs.map +1 -0
- package/dist/{de-77BMFDVF.mjs → de-Y5BHEBT7.mjs} +46 -6
- package/dist/de-Y5BHEBT7.mjs.map +1 -0
- package/dist/dist-YLEIY3JJ.mjs +547 -0
- package/dist/dist-YLEIY3JJ.mjs.map +1 -0
- package/dist/{el-FIBNLH2V.mjs → el-HU7LAWQY.mjs} +46 -6
- package/dist/el-HU7LAWQY.mjs.map +1 -0
- package/dist/{en-XWEPVTB4.mjs → en-HAKDCFKL.mjs} +5 -3
- package/dist/{es-726NTS53.mjs → es-4BN64QH5.mjs} +46 -6
- package/dist/es-4BN64QH5.mjs.map +1 -0
- package/dist/{fa-3N4CIWE6.mjs → fa-6ELTBARU.mjs} +46 -6
- package/dist/fa-6ELTBARU.mjs.map +1 -0
- package/dist/{fi-JOM3M7Z4.mjs → fi-DJ4WGIFW.mjs} +46 -6
- package/dist/fi-DJ4WGIFW.mjs.map +1 -0
- package/dist/{fr-56QSXS7E.mjs → fr-23XM6H6H.mjs} +46 -6
- package/dist/fr-23XM6H6H.mjs.map +1 -0
- package/dist/{he-SNAXPJEK.mjs → he-JSWJC2XU.mjs} +46 -6
- package/dist/he-JSWJC2XU.mjs.map +1 -0
- package/dist/{hi-CRBRD5TB.mjs → hi-BENHG3OJ.mjs} +46 -6
- package/dist/hi-BENHG3OJ.mjs.map +1 -0
- package/dist/{id-BRCVLICF.mjs → id-4HHQJQNF.mjs} +46 -6
- package/dist/id-4HHQJQNF.mjs.map +1 -0
- package/dist/index.css +108 -12
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +399 -147
- package/dist/index.mjs +3573 -2226
- package/dist/index.mjs.map +1 -1
- package/dist/{it-M2Z27BNB.mjs → it-U6I5PDKU.mjs} +46 -6
- package/dist/it-U6I5PDKU.mjs.map +1 -0
- package/dist/{ja-TZUKW7HD.mjs → ja-K3YBDWDP.mjs} +46 -6
- package/dist/ja-K3YBDWDP.mjs.map +1 -0
- package/dist/{ko-NKBGGOL6.mjs → ko-KC2HXRXG.mjs} +46 -6
- package/dist/ko-KC2HXRXG.mjs.map +1 -0
- package/dist/{magic-string.es-7FJ3LUGB.mjs → magic-string.es-K77I4ZQN.mjs} +2 -2
- package/dist/{ms-XFXPN6RX.mjs → ms-KY5QGBNN.mjs} +46 -6
- package/dist/ms-KY5QGBNN.mjs.map +1 -0
- package/dist/{nl-MVYXAS5C.mjs → nl-6PZFLGY2.mjs} +46 -6
- package/dist/nl-6PZFLGY2.mjs.map +1 -0
- package/dist/{no-XOLO4JPV.mjs → no-5QR7PLVJ.mjs} +46 -6
- package/dist/no-5QR7PLVJ.mjs.map +1 -0
- package/dist/{pl-TRWLMMC4.mjs → pl-4GV2NQXE.mjs} +46 -6
- package/dist/pl-4GV2NQXE.mjs.map +1 -0
- package/dist/{pt-M3TE24UI.mjs → pt-F3F5QD2P.mjs} +46 -6
- package/dist/pt-F3F5QD2P.mjs.map +1 -0
- package/dist/{ro-QBFG2T64.mjs → ro-TFYL2IQB.mjs} +46 -6
- package/dist/ro-TFYL2IQB.mjs.map +1 -0
- package/dist/{sv-IUECBXWX.mjs → sv-PRVF2QLR.mjs} +46 -6
- package/dist/sv-PRVF2QLR.mjs.map +1 -0
- package/dist/test-utils.mjs +16994 -22140
- package/dist/test-utils.mjs.map +1 -1
- package/dist/{th-US7KIN5Q.mjs → th-SUQOQFUZ.mjs} +46 -6
- package/dist/th-SUQOQFUZ.mjs.map +1 -0
- package/dist/{tr-DWJ2FFUK.mjs → tr-AYUJZOFJ.mjs} +46 -6
- package/dist/tr-AYUJZOFJ.mjs.map +1 -0
- package/dist/{uk-M4ZE4DPZ.mjs → uk-YY5WGLBM.mjs} +46 -6
- package/dist/uk-YY5WGLBM.mjs.map +1 -0
- package/dist/{vi-FERZNPSH.mjs → vi-6RO77ITD.mjs} +46 -6
- package/dist/{vi-FERZNPSH.mjs.map → vi-6RO77ITD.mjs.map} +1 -1
- package/dist/{zh-3J2I3WYK.mjs → zh-L6GA65H6.mjs} +46 -6
- package/dist/zh-L6GA65H6.mjs.map +1 -0
- package/package.json +18 -14
- package/src/components/Button/Button.tsx +23 -25
- package/src/components/annotation/AnnotateToolbar.tsx +1 -1
- package/src/components/annotation-popups/SharedPopupElements.tsx +5 -7
- package/src/components/image-annotation/SvgDrawingCanvas.tsx +3 -4
- package/src/components/modals/ConfigureGenerationStep.tsx +190 -0
- package/src/components/modals/ConfigureSearchStep.tsx +105 -0
- package/src/components/modals/ContextSummary.tsx +183 -0
- package/src/components/modals/GatherContextStep.tsx +89 -0
- package/src/components/modals/KeyboardShortcutsHelpModal.tsx +4 -6
- package/src/components/modals/ProposeEntitiesModal.tsx +4 -6
- package/src/components/modals/ReferenceWizardModal.tsx +326 -0
- package/src/components/modals/ResourceSearchModal.tsx +4 -6
- package/src/components/modals/SearchModal.css +43 -0
- package/src/components/modals/SearchModal.tsx +4 -6
- package/src/components/modals/SearchResultsStep.tsx +126 -0
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +3 -4
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +36 -14
- package/src/components/resource/AnnotateView.tsx +4 -4
- package/src/components/resource/AnnotationHistory.tsx +2 -2
- package/src/components/resource/BrowseView.tsx +4 -4
- package/src/components/resource/ResourceViewer.tsx +5 -8
- package/src/components/resource/__tests__/AnnotationHistory.test.tsx +16 -16
- package/src/components/resource/__tests__/BrowseView.test.tsx +2 -2
- package/src/components/resource/__tests__/HistoryEvent.test.tsx +1 -1
- package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +1 -1
- package/src/components/resource/panels/AssessmentEntry.tsx +9 -11
- package/src/components/resource/panels/AssessmentPanel.tsx +1 -1
- package/src/components/resource/panels/CommentEntry.tsx +10 -12
- package/src/components/resource/panels/CommentsPanel.tsx +1 -1
- package/src/components/resource/panels/HighlightEntry.tsx +9 -11
- package/src/components/resource/panels/HighlightPanel.tsx +2 -2
- package/src/components/resource/panels/ReferenceEntry.tsx +57 -104
- package/src/components/resource/panels/ReferencesPanel.css +85 -13
- package/src/components/resource/panels/ReferencesPanel.tsx +2 -3
- package/src/components/resource/panels/TagEntry.tsx +9 -11
- package/src/components/resource/panels/TaggingPanel.tsx +1 -1
- package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +4 -4
- package/src/components/resource/panels/__tests__/AssistSection.test.tsx +7 -7
- package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +3 -3
- package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +2 -2
- package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +64 -101
- package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +1 -1
- package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +7 -7
- package/src/components/viewers/ImageViewer.tsx +3 -6
- package/src/components/viewers/__tests__/ImageViewer.test.tsx +3 -3
- package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +5 -5
- package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +141 -0
- package/src/features/admin-exchange/__tests__/ExportCard.test.tsx +41 -0
- package/src/features/admin-exchange/__tests__/ImportCard.test.tsx +148 -0
- package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +106 -0
- package/src/features/admin-exchange/components/AdminExchangePage.tsx +120 -0
- package/src/features/admin-exchange/components/ExportCard.tsx +35 -0
- package/src/features/admin-exchange/components/ImportCard.tsx +188 -0
- package/src/features/admin-exchange/components/ImportProgress.tsx +86 -0
- package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +3 -3
- package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +2 -2
- package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +4 -4
- package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +3 -3
- package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +117 -0
- package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +121 -0
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +5 -5
- package/src/features/resource-compose/components/ResourceComposePage.tsx +56 -1
- package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +1 -1
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +2 -2
- package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +14 -14
- package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +12 -11
- package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +2 -2
- package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +22 -115
- package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +3 -3
- package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +20 -20
- package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +7 -7
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +43 -20
- package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +2 -2
- package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +45 -82
- package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +4 -4
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +151 -74
- package/src/integrations/tailwind-plugin.js +3 -3
- package/src/styles/core/buttons.css +31 -0
- package/src/styles/features/exchange.css +404 -0
- package/src/styles/index.css +1 -0
- package/translations/ar.json +42 -4
- package/translations/bn.json +42 -4
- package/translations/cs.json +42 -4
- package/translations/da.json +128 -90
- package/translations/de.json +122 -84
- package/translations/el.json +42 -4
- package/translations/en.json +42 -4
- package/translations/es.json +42 -4
- package/translations/fa.json +42 -4
- package/translations/fi.json +68 -30
- package/translations/fr.json +42 -4
- package/translations/he.json +42 -4
- package/translations/hi.json +42 -4
- package/translations/id.json +43 -5
- package/translations/it.json +62 -24
- package/translations/ja.json +43 -5
- package/translations/ko.json +42 -4
- package/translations/ms.json +43 -5
- package/translations/nl.json +41 -3
- package/translations/no.json +104 -66
- package/translations/pl.json +42 -4
- package/translations/pt.json +43 -5
- package/translations/ro.json +42 -4
- package/translations/sv.json +42 -4
- package/translations/th.json +42 -4
- package/translations/tr.json +42 -4
- package/translations/uk.json +42 -4
- package/translations/vi.json +42 -4
- package/translations/zh.json +42 -4
- package/dist/PdfAnnotationCanvas.client-COQREPXU.mjs.map +0 -1
- package/dist/ar-7SUXNE34.mjs.map +0 -1
- package/dist/bn-XOET3DOI.mjs.map +0 -1
- package/dist/chunk-JH7BXE2P.mjs.map +0 -1
- package/dist/cs-X63DXX7L.mjs.map +0 -1
- package/dist/da-OWTCV57A.mjs.map +0 -1
- package/dist/de-77BMFDVF.mjs.map +0 -1
- package/dist/el-FIBNLH2V.mjs.map +0 -1
- package/dist/es-726NTS53.mjs.map +0 -1
- package/dist/fa-3N4CIWE6.mjs.map +0 -1
- package/dist/fi-JOM3M7Z4.mjs.map +0 -1
- package/dist/fr-56QSXS7E.mjs.map +0 -1
- package/dist/he-SNAXPJEK.mjs.map +0 -1
- package/dist/hi-CRBRD5TB.mjs.map +0 -1
- package/dist/id-BRCVLICF.mjs.map +0 -1
- package/dist/it-M2Z27BNB.mjs.map +0 -1
- package/dist/ja-TZUKW7HD.mjs.map +0 -1
- package/dist/ko-NKBGGOL6.mjs.map +0 -1
- package/dist/ms-XFXPN6RX.mjs.map +0 -1
- package/dist/nl-MVYXAS5C.mjs.map +0 -1
- package/dist/no-XOLO4JPV.mjs.map +0 -1
- package/dist/pl-TRWLMMC4.mjs.map +0 -1
- package/dist/pt-M3TE24UI.mjs.map +0 -1
- package/dist/ro-QBFG2T64.mjs.map +0 -1
- package/dist/sv-IUECBXWX.mjs.map +0 -1
- package/dist/th-US7KIN5Q.mjs.map +0 -1
- package/dist/tr-DWJ2FFUK.mjs.map +0 -1
- package/dist/uk-M4ZE4DPZ.mjs.map +0 -1
- package/dist/zh-3J2I3WYK.mjs.map +0 -1
- package/src/examples/ButtonUsageExample.tsx +0 -242
- package/src/examples/button-css-modules.module.css +0 -164
- package/src/examples/button-styled-components.tsx +0 -215
- package/src/examples/button-tailwind.css +0 -51
- /package/dist/{chunk-Q2KV6Y2J.mjs.map → chunk-7GEYABC6.mjs.map} +0 -0
- /package/dist/{chunk-3JTO27MH.mjs.map → chunk-D4GAAQMM.mjs.map} +0 -0
- /package/dist/{en-XWEPVTB4.mjs.map → en-HAKDCFKL.mjs.map} +0 -0
- /package/dist/{magic-string.es-7FJ3LUGB.mjs.map → magic-string.es-K77I4ZQN.mjs.map} +0 -0
|
@@ -11,7 +11,7 @@ import { describe, test, expect, vi, beforeEach } from 'vitest';
|
|
|
11
11
|
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
|
|
12
12
|
import userEvent from '@testing-library/user-event';
|
|
13
13
|
import { PdfAnnotationCanvas } from '../PdfAnnotationCanvas';
|
|
14
|
-
import {
|
|
14
|
+
import { resourceId } from '@semiont/core';
|
|
15
15
|
import type { components } from '@semiont/core';
|
|
16
16
|
|
|
17
17
|
type Annotation = components['schemas']['Annotation'];
|
|
@@ -40,16 +40,24 @@ vi.mock('../../../lib/browser-pdfjs', () => ({
|
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
42
|
describe('PdfAnnotationCanvas', () => {
|
|
43
|
-
const
|
|
43
|
+
const mockResourceId = resourceId('123');
|
|
44
44
|
|
|
45
45
|
beforeEach(() => {
|
|
46
46
|
vi.clearAllMocks();
|
|
47
|
+
|
|
48
|
+
// jsdom doesn't fire image onLoad or support clientWidth/clientHeight.
|
|
49
|
+
// Mock requestAnimationFrame to run callbacks synchronously and
|
|
50
|
+
// provide dimensions on the image element so the SVG overlay renders.
|
|
51
|
+
vi.stubGlobal('requestAnimationFrame', (cb: FrameRequestCallback) => {
|
|
52
|
+
cb(0);
|
|
53
|
+
return 0;
|
|
54
|
+
});
|
|
47
55
|
});
|
|
48
56
|
|
|
49
57
|
test('renders loading state initially', () => {
|
|
50
58
|
render(
|
|
51
59
|
<PdfAnnotationCanvas
|
|
52
|
-
resourceUri={
|
|
60
|
+
resourceUri={mockResourceId}
|
|
53
61
|
drawingMode={null}
|
|
54
62
|
/>
|
|
55
63
|
);
|
|
@@ -60,7 +68,7 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
60
68
|
test('renders page navigation controls after loading', async () => {
|
|
61
69
|
render(
|
|
62
70
|
<PdfAnnotationCanvas
|
|
63
|
-
resourceUri={
|
|
71
|
+
resourceUri={mockResourceId}
|
|
64
72
|
drawingMode={null}
|
|
65
73
|
/>
|
|
66
74
|
);
|
|
@@ -76,7 +84,7 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
76
84
|
test('previous button is disabled on first page', async () => {
|
|
77
85
|
render(
|
|
78
86
|
<PdfAnnotationCanvas
|
|
79
|
-
resourceUri={
|
|
87
|
+
resourceUri={mockResourceId}
|
|
80
88
|
drawingMode={null}
|
|
81
89
|
/>
|
|
82
90
|
);
|
|
@@ -92,7 +100,7 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
92
100
|
test('next button is disabled on last page', async () => {
|
|
93
101
|
render(
|
|
94
102
|
<PdfAnnotationCanvas
|
|
95
|
-
resourceUri={
|
|
103
|
+
resourceUri={mockResourceId}
|
|
96
104
|
drawingMode={null}
|
|
97
105
|
/>
|
|
98
106
|
);
|
|
@@ -124,7 +132,7 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
124
132
|
id: 'ann-1',
|
|
125
133
|
body: [],
|
|
126
134
|
target: {
|
|
127
|
-
source:
|
|
135
|
+
source: mockResourceId,
|
|
128
136
|
selector: {
|
|
129
137
|
type: 'FragmentSelector',
|
|
130
138
|
value: 'page=1&viewrect=100,200,150,100',
|
|
@@ -138,7 +146,7 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
138
146
|
|
|
139
147
|
render(
|
|
140
148
|
<PdfAnnotationCanvas
|
|
141
|
-
resourceUri={
|
|
149
|
+
resourceUri={mockResourceId}
|
|
142
150
|
existingAnnotations={mockAnnotations}
|
|
143
151
|
drawingMode={null}
|
|
144
152
|
/>
|
|
@@ -148,12 +156,26 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
148
156
|
expect(screen.getByText(/page 1 of 3/i)).toBeInTheDocument();
|
|
149
157
|
});
|
|
150
158
|
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
// jsdom doesn't fire image onLoad or provide clientWidth/clientHeight.
|
|
160
|
+
// Wait for the image element to appear, then simulate load with dimensions.
|
|
161
|
+
await waitFor(() => {
|
|
162
|
+
const img = document.querySelector('.semiont-pdf-annotation-canvas__image') as HTMLImageElement;
|
|
163
|
+
expect(img).toBeInTheDocument();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const img = document.querySelector('.semiont-pdf-annotation-canvas__image') as HTMLImageElement;
|
|
167
|
+
Object.defineProperty(img, 'clientWidth', { value: 612, configurable: true });
|
|
168
|
+
Object.defineProperty(img, 'clientHeight', { value: 792, configurable: true });
|
|
169
|
+
fireEvent.load(img);
|
|
170
|
+
|
|
171
|
+
await waitFor(() => {
|
|
172
|
+
// Annotation should be rendered in SVG
|
|
173
|
+
const svg = document.querySelector('.semiont-pdf-annotation-canvas__svg');
|
|
174
|
+
expect(svg).toBeInTheDocument();
|
|
154
175
|
|
|
155
|
-
|
|
156
|
-
|
|
176
|
+
const rects = svg?.querySelectorAll('rect');
|
|
177
|
+
expect(rects?.length).toBeGreaterThan(0);
|
|
178
|
+
});
|
|
157
179
|
});
|
|
158
180
|
|
|
159
181
|
test('emits annotate:requested via eventBus when drawing with sufficient drag', async () => {
|
|
@@ -167,7 +189,7 @@ describe('PdfAnnotationCanvas', () => {
|
|
|
167
189
|
|
|
168
190
|
render(
|
|
169
191
|
<PdfAnnotationCanvas
|
|
170
|
-
resourceUri={
|
|
192
|
+
resourceUri={mockResourceId}
|
|
171
193
|
drawingMode="rectangle"
|
|
172
194
|
selectedMotivation="highlighting"
|
|
173
195
|
eventBus={mockEventBus as any}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useRef, useEffect, useCallback, lazy, Suspense } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { resourceId as toResourceId } from '@semiont/core';
|
|
5
5
|
import { getMimeCategory, isPdfMimeType } from '@semiont/api-client';
|
|
6
6
|
import { ANNOTATORS } from '../../lib/annotation-registry';
|
|
7
7
|
import { segmentTextWithAnnotations } from '../../lib/text-segmentation';
|
|
@@ -247,7 +247,7 @@ export function AnnotateView({
|
|
|
247
247
|
{resourceUri && (
|
|
248
248
|
<Suspense fallback={<div className="semiont-annotate-view__loading">Loading PDF viewer...</div>}>
|
|
249
249
|
<PdfAnnotationCanvas
|
|
250
|
-
resourceUri={
|
|
250
|
+
resourceUri={toResourceId(resourceUri)}
|
|
251
251
|
existingAnnotations={allAnnotations}
|
|
252
252
|
drawingMode={selectedMotivation ? selectedShape : null}
|
|
253
253
|
selectedMotivation={selectedMotivation}
|
|
@@ -277,7 +277,7 @@ export function AnnotateView({
|
|
|
277
277
|
<div className="semiont-annotate-view__content">
|
|
278
278
|
{resourceUri && (
|
|
279
279
|
<SvgDrawingCanvas
|
|
280
|
-
resourceUri={
|
|
280
|
+
resourceUri={toResourceId(resourceUri)}
|
|
281
281
|
existingAnnotations={allAnnotations}
|
|
282
282
|
drawingMode={selectedMotivation ? selectedShape : null}
|
|
283
283
|
selectedMotivation={selectedMotivation}
|
|
@@ -300,7 +300,7 @@ export function AnnotateView({
|
|
|
300
300
|
</p>
|
|
301
301
|
{resourceUri && (
|
|
302
302
|
<a
|
|
303
|
-
href={resourceUri}
|
|
303
|
+
href={`/api/resources/${resourceUri}`}
|
|
304
304
|
download
|
|
305
305
|
className="semiont-button semiont-button--primary"
|
|
306
306
|
>
|
|
@@ -4,13 +4,13 @@ import React, { useEffect, useRef } from 'react';
|
|
|
4
4
|
import { useTranslations } from '../../contexts/TranslationContext';
|
|
5
5
|
import type { RouteBuilder, LinkComponentProps } from '../../contexts/RoutingContext';
|
|
6
6
|
import { useResources } from '../../lib/api-hooks';
|
|
7
|
-
import type {
|
|
7
|
+
import type { ResourceId } from '@semiont/core';
|
|
8
8
|
import type { StoredEvent } from '@semiont/core';
|
|
9
9
|
import { getAnnotationUriFromEvent } from '@semiont/core';
|
|
10
10
|
import { HistoryEvent } from './HistoryEvent';
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
|
-
rUri:
|
|
13
|
+
rUri: ResourceId;
|
|
14
14
|
hoveredAnnotationId?: string | null;
|
|
15
15
|
onEventHover?: (annotationId: string | null) => void;
|
|
16
16
|
onEventClick?: (annotationId: string | null) => void;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { useEffect, useRef, useCallback, useMemo, memo, lazy, Suspense } from 'react';
|
|
4
4
|
import ReactMarkdown from 'react-markdown';
|
|
5
5
|
import remarkGfm from 'remark-gfm';
|
|
6
|
-
import {
|
|
6
|
+
import { resourceId as toResourceId } from '@semiont/core';
|
|
7
7
|
import { getMimeCategory, isPdfMimeType } from '@semiont/api-client';
|
|
8
8
|
import { ANNOTATORS } from '../../lib/annotation-registry';
|
|
9
9
|
import { createHoverHandlers } from '../../hooks/useBeckonFlow';
|
|
@@ -240,7 +240,7 @@ export const BrowseView = memo(function BrowseView({
|
|
|
240
240
|
<div ref={containerRef} className="semiont-browse-view__content">
|
|
241
241
|
<Suspense fallback={<div className="semiont-browse-view__loading">Loading PDF viewer...</div>}>
|
|
242
242
|
<PdfAnnotationCanvas
|
|
243
|
-
resourceUri={
|
|
243
|
+
resourceUri={toResourceId(resourceUri)}
|
|
244
244
|
existingAnnotations={allAnnotations}
|
|
245
245
|
drawingMode={null}
|
|
246
246
|
selectedMotivation={null}
|
|
@@ -264,7 +264,7 @@ export const BrowseView = memo(function BrowseView({
|
|
|
264
264
|
/>
|
|
265
265
|
<div ref={containerRef} className="semiont-browse-view__content">
|
|
266
266
|
<ImageViewer
|
|
267
|
-
resourceUri={resourceUri
|
|
267
|
+
resourceUri={toResourceId(resourceUri)}
|
|
268
268
|
mimeType={mimeType}
|
|
269
269
|
alt="Resource content"
|
|
270
270
|
/>
|
|
@@ -280,7 +280,7 @@ export const BrowseView = memo(function BrowseView({
|
|
|
280
280
|
Preview not available for {mimeType}
|
|
281
281
|
</p>
|
|
282
282
|
<a
|
|
283
|
-
href={resourceUri}
|
|
283
|
+
href={`/api/resources/${resourceUri}`}
|
|
284
284
|
download
|
|
285
285
|
className="semiont-button semiont-button--primary"
|
|
286
286
|
>
|
|
@@ -7,7 +7,7 @@ import { BrowseView } from './BrowseView';
|
|
|
7
7
|
import { PopupContainer } from '../annotation-popups/SharedPopupElements';
|
|
8
8
|
import { JsonLdView } from '../annotation-popups/JsonLdView';
|
|
9
9
|
import type { components } from '@semiont/core';
|
|
10
|
-
import {
|
|
10
|
+
import { resourceId as toResourceId, annotationId as toAnnotationId } from '@semiont/core';
|
|
11
11
|
import { getExactText, getTargetSelector, isHighlight, isAssessment, isReference, isComment, isTag, getBodySource } from '@semiont/api-client';
|
|
12
12
|
import { useEventBus } from '../../contexts/EventBusContext';
|
|
13
13
|
import { useEventSubscriptions } from '../../contexts/useEventSubscription';
|
|
@@ -84,7 +84,7 @@ export function ResourceViewer({
|
|
|
84
84
|
if (!resource['@id']) {
|
|
85
85
|
throw new Error('Resource has no @id');
|
|
86
86
|
}
|
|
87
|
-
const rUri =
|
|
87
|
+
const rUri = toResourceId(resource['@id']);
|
|
88
88
|
|
|
89
89
|
// Helper to get MIME type from resource
|
|
90
90
|
const getMimeType = (): string => {
|
|
@@ -251,7 +251,7 @@ export function ResourceViewer({
|
|
|
251
251
|
|
|
252
252
|
// Handle deleting annotations - emit event instead of direct call
|
|
253
253
|
const handleDeleteAnnotation = useCallback((id: string) => {
|
|
254
|
-
eventBus.get('mark:delete').next({ annotationId: id });
|
|
254
|
+
eventBus.get('mark:delete').next({ annotationId: toAnnotationId(id) });
|
|
255
255
|
}, []); // eventBus is stable
|
|
256
256
|
|
|
257
257
|
// Handle annotation clicks - memoized
|
|
@@ -279,11 +279,8 @@ export function ResourceViewer({
|
|
|
279
279
|
if (selectedClick === 'follow' && isReference(annotation)) {
|
|
280
280
|
const bodySource = getBodySource(annotation.body);
|
|
281
281
|
if (bodySource) {
|
|
282
|
-
//
|
|
283
|
-
|
|
284
|
-
if (resourceId) {
|
|
285
|
-
navigate(`/know/resource/${resourceId}`, { resourceId });
|
|
286
|
-
}
|
|
282
|
+
// bodySource is already a bare resource ID
|
|
283
|
+
navigate(`/know/resource/${bodySource}`, { resourceId: bodySource });
|
|
287
284
|
}
|
|
288
285
|
return;
|
|
289
286
|
}
|
|
@@ -4,7 +4,7 @@ import { screen } from '@testing-library/react';
|
|
|
4
4
|
import '@testing-library/jest-dom';
|
|
5
5
|
import { AnnotationHistory } from '../AnnotationHistory';
|
|
6
6
|
import { renderWithProviders } from '../../../test-utils';
|
|
7
|
-
import type { StoredEvent,
|
|
7
|
+
import type { StoredEvent, ResourceId } from '@semiont/core';
|
|
8
8
|
|
|
9
9
|
// Mock @semiont/core - must use importOriginal to preserve EventBus etc.
|
|
10
10
|
vi.mock('@semiont/core', async (importOriginal) => {
|
|
@@ -52,7 +52,7 @@ vi.mock('../HistoryEvent', () => ({
|
|
|
52
52
|
import { getAnnotationUriFromEvent } from '@semiont/core';
|
|
53
53
|
const mockGetAnnotationUri = getAnnotationUriFromEvent as ReturnType<typeof vi.fn>;
|
|
54
54
|
|
|
55
|
-
const
|
|
55
|
+
const testRId = 'res-1' as ResourceId;
|
|
56
56
|
|
|
57
57
|
function makeStoredEvent(id: string, type: string, seq: number, overrides: Record<string, any> = {}): StoredEvent {
|
|
58
58
|
return {
|
|
@@ -60,7 +60,7 @@ function makeStoredEvent(id: string, type: string, seq: number, overrides: Recor
|
|
|
60
60
|
id,
|
|
61
61
|
type,
|
|
62
62
|
timestamp: '2026-03-06T12:00:00Z',
|
|
63
|
-
resourceId: '
|
|
63
|
+
resourceId: 'res-1',
|
|
64
64
|
userId: 'user-1',
|
|
65
65
|
version: 1,
|
|
66
66
|
payload: {},
|
|
@@ -90,7 +90,7 @@ describe('AnnotationHistory', () => {
|
|
|
90
90
|
|
|
91
91
|
renderWithProviders(
|
|
92
92
|
<AnnotationHistory
|
|
93
|
-
rUri={
|
|
93
|
+
rUri={testRId}
|
|
94
94
|
Link={MockLink}
|
|
95
95
|
routes={mockRoutes}
|
|
96
96
|
/>
|
|
@@ -105,7 +105,7 @@ describe('AnnotationHistory', () => {
|
|
|
105
105
|
|
|
106
106
|
const { container } = renderWithProviders(
|
|
107
107
|
<AnnotationHistory
|
|
108
|
-
rUri={
|
|
108
|
+
rUri={testRId}
|
|
109
109
|
Link={MockLink}
|
|
110
110
|
routes={mockRoutes}
|
|
111
111
|
/>
|
|
@@ -119,7 +119,7 @@ describe('AnnotationHistory', () => {
|
|
|
119
119
|
|
|
120
120
|
const { container } = renderWithProviders(
|
|
121
121
|
<AnnotationHistory
|
|
122
|
-
rUri={
|
|
122
|
+
rUri={testRId}
|
|
123
123
|
Link={MockLink}
|
|
124
124
|
routes={mockRoutes}
|
|
125
125
|
/>
|
|
@@ -138,7 +138,7 @@ describe('AnnotationHistory', () => {
|
|
|
138
138
|
|
|
139
139
|
renderWithProviders(
|
|
140
140
|
<AnnotationHistory
|
|
141
|
-
rUri={
|
|
141
|
+
rUri={testRId}
|
|
142
142
|
Link={MockLink}
|
|
143
143
|
routes={mockRoutes}
|
|
144
144
|
/>
|
|
@@ -169,7 +169,7 @@ describe('AnnotationHistory', () => {
|
|
|
169
169
|
|
|
170
170
|
renderWithProviders(
|
|
171
171
|
<AnnotationHistory
|
|
172
|
-
rUri={
|
|
172
|
+
rUri={testRId}
|
|
173
173
|
Link={MockLink}
|
|
174
174
|
routes={mockRoutes}
|
|
175
175
|
/>
|
|
@@ -194,7 +194,7 @@ describe('AnnotationHistory', () => {
|
|
|
194
194
|
|
|
195
195
|
renderWithProviders(
|
|
196
196
|
<AnnotationHistory
|
|
197
|
-
rUri={
|
|
197
|
+
rUri={testRId}
|
|
198
198
|
hoveredAnnotationId={annotationUri}
|
|
199
199
|
Link={MockLink}
|
|
200
200
|
routes={mockRoutes}
|
|
@@ -215,7 +215,7 @@ describe('AnnotationHistory', () => {
|
|
|
215
215
|
|
|
216
216
|
renderWithProviders(
|
|
217
217
|
<AnnotationHistory
|
|
218
|
-
rUri={
|
|
218
|
+
rUri={testRId}
|
|
219
219
|
hoveredAnnotationId="http://localhost/annotations/ann-1"
|
|
220
220
|
Link={MockLink}
|
|
221
221
|
routes={mockRoutes}
|
|
@@ -234,7 +234,7 @@ describe('AnnotationHistory', () => {
|
|
|
234
234
|
|
|
235
235
|
renderWithProviders(
|
|
236
236
|
<AnnotationHistory
|
|
237
|
-
rUri={
|
|
237
|
+
rUri={testRId}
|
|
238
238
|
Link={MockLink}
|
|
239
239
|
routes={mockRoutes}
|
|
240
240
|
/>
|
|
@@ -255,7 +255,7 @@ describe('AnnotationHistory', () => {
|
|
|
255
255
|
|
|
256
256
|
renderWithProviders(
|
|
257
257
|
<AnnotationHistory
|
|
258
|
-
rUri={
|
|
258
|
+
rUri={testRId}
|
|
259
259
|
onEventClick={onEventClick}
|
|
260
260
|
onEventHover={onEventHover}
|
|
261
261
|
Link={MockLink}
|
|
@@ -276,7 +276,7 @@ describe('AnnotationHistory', () => {
|
|
|
276
276
|
|
|
277
277
|
renderWithProviders(
|
|
278
278
|
<AnnotationHistory
|
|
279
|
-
rUri={
|
|
279
|
+
rUri={testRId}
|
|
280
280
|
Link={MockLink}
|
|
281
281
|
routes={mockRoutes}
|
|
282
282
|
/>
|
|
@@ -298,7 +298,7 @@ describe('AnnotationHistory', () => {
|
|
|
298
298
|
|
|
299
299
|
renderWithProviders(
|
|
300
300
|
<AnnotationHistory
|
|
301
|
-
rUri={
|
|
301
|
+
rUri={testRId}
|
|
302
302
|
Link={MockLink}
|
|
303
303
|
routes={mockRoutes}
|
|
304
304
|
/>
|
|
@@ -318,7 +318,7 @@ describe('AnnotationHistory', () => {
|
|
|
318
318
|
|
|
319
319
|
renderWithProviders(
|
|
320
320
|
<AnnotationHistory
|
|
321
|
-
rUri={
|
|
321
|
+
rUri={testRId}
|
|
322
322
|
Link={MockLink}
|
|
323
323
|
routes={mockRoutes}
|
|
324
324
|
/>
|
|
@@ -336,7 +336,7 @@ describe('AnnotationHistory', () => {
|
|
|
336
336
|
|
|
337
337
|
const { container } = renderWithProviders(
|
|
338
338
|
<AnnotationHistory
|
|
339
|
-
rUri={
|
|
339
|
+
rUri={testRId}
|
|
340
340
|
Link={MockLink}
|
|
341
341
|
routes={mockRoutes}
|
|
342
342
|
/>
|
|
@@ -27,7 +27,7 @@ vi.mock('@semiont/api-client', async () => {
|
|
|
27
27
|
return 'unsupported';
|
|
28
28
|
}),
|
|
29
29
|
isPdfMimeType: vi.fn((mimeType: string) => mimeType === 'application/pdf'),
|
|
30
|
-
|
|
30
|
+
resourceId: vi.fn((id: string) => id),
|
|
31
31
|
getExactText: vi.fn(() => 'exact text'),
|
|
32
32
|
getTextPositionSelector: vi.fn(() => ({ start: 0, end: 10 })),
|
|
33
33
|
getTargetSelector: vi.fn(() => ({ type: 'TextPositionSelector', start: 0, end: 10 })),
|
|
@@ -200,7 +200,7 @@ describe('BrowseView Component', () => {
|
|
|
200
200
|
const defaultProps = {
|
|
201
201
|
content: '# Test Content\n\nThis is test markdown content.',
|
|
202
202
|
mimeType: 'text/markdown',
|
|
203
|
-
resourceUri: '
|
|
203
|
+
resourceUri: 'test-resource',
|
|
204
204
|
annotations: {
|
|
205
205
|
highlights: [],
|
|
206
206
|
references: [],
|
|
@@ -55,7 +55,7 @@ function makeStoredEvent(overrides: Partial<StoredEvent['event']> = {}): StoredE
|
|
|
55
55
|
id: 'evt-1',
|
|
56
56
|
type: 'resource.created',
|
|
57
57
|
timestamp: '2026-03-06T12:00:00Z',
|
|
58
|
-
resourceId: '
|
|
58
|
+
resourceId: 'res-1',
|
|
59
59
|
userId: 'user-1',
|
|
60
60
|
version: 1,
|
|
61
61
|
payload: { name: 'Test', format: 'text/plain', contentChecksum: 'abc', creationMethod: 'upload' },
|
|
@@ -31,7 +31,7 @@ vi.mock('../../../hooks/useObservableBrowse', () => ({
|
|
|
31
31
|
|
|
32
32
|
const mockResource: SemiontResource & { content: string } = {
|
|
33
33
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
|
34
|
-
'@id': '
|
|
34
|
+
'@id': 'test-123',
|
|
35
35
|
name: 'Test Document',
|
|
36
36
|
created: '2024-01-01T00:00:00Z',
|
|
37
37
|
entityTypes: [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { Ref } from 'react';
|
|
4
4
|
import type { components } from '@semiont/core';
|
|
5
5
|
import { getAnnotationExactText } from '@semiont/api-client';
|
|
6
6
|
import { useEventBus } from '../../../contexts/EventBusContext';
|
|
@@ -20,6 +20,7 @@ interface AssessmentEntryProps {
|
|
|
20
20
|
assessment: Annotation;
|
|
21
21
|
isFocused: boolean;
|
|
22
22
|
isHovered?: boolean;
|
|
23
|
+
ref?: Ref<HTMLDivElement>;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
function formatRelativeTime(isoString: string): string {
|
|
@@ -67,15 +68,12 @@ function getAssessmentText(annotation: Annotation): string | null {
|
|
|
67
68
|
return null;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
export
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
ref
|
|
78
|
-
) {
|
|
71
|
+
export function AssessmentEntry({
|
|
72
|
+
assessment,
|
|
73
|
+
isFocused,
|
|
74
|
+
isHovered = false,
|
|
75
|
+
ref,
|
|
76
|
+
}: AssessmentEntryProps) {
|
|
79
77
|
const eventBus = useEventBus();
|
|
80
78
|
const hoverProps = useHoverEmitter(assessment.id);
|
|
81
79
|
|
|
@@ -113,4 +111,4 @@ export const AssessmentEntry = forwardRef<HTMLDivElement, AssessmentEntryProps>(
|
|
|
113
111
|
</div>
|
|
114
112
|
</div>
|
|
115
113
|
);
|
|
116
|
-
}
|
|
114
|
+
}
|
|
@@ -141,7 +141,7 @@ export function AssessmentPanel({
|
|
|
141
141
|
? [{ type: 'TextualBody' as const, value: newAssessmentText, purpose: 'assessing' as const }]
|
|
142
142
|
: [];
|
|
143
143
|
|
|
144
|
-
eventBus.get('mark:
|
|
144
|
+
eventBus.get('mark:submit').next({
|
|
145
145
|
motivation: 'assessing',
|
|
146
146
|
selector: pendingAnnotation.selector,
|
|
147
147
|
body,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect, useRef,
|
|
3
|
+
import { useState, useEffect, useRef, useImperativeHandle, type Ref } from 'react';
|
|
4
4
|
import { useTranslations } from '../../../contexts/TranslationContext';
|
|
5
5
|
import type { components } from '@semiont/core';
|
|
6
6
|
import { getAnnotationExactText, getCommentText } from '@semiont/api-client';
|
|
@@ -14,6 +14,7 @@ interface CommentEntryProps {
|
|
|
14
14
|
isFocused: boolean;
|
|
15
15
|
isHovered?: boolean;
|
|
16
16
|
annotateMode?: boolean;
|
|
17
|
+
ref?: Ref<HTMLDivElement>;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
function formatRelativeTime(isoString: string): string {
|
|
@@ -33,16 +34,13 @@ function formatRelativeTime(isoString: string): string {
|
|
|
33
34
|
return date.toLocaleDateString();
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
ref
|
|
45
|
-
) {
|
|
37
|
+
export function CommentEntry({
|
|
38
|
+
comment,
|
|
39
|
+
isFocused,
|
|
40
|
+
isHovered = false,
|
|
41
|
+
annotateMode = true,
|
|
42
|
+
ref,
|
|
43
|
+
}: CommentEntryProps) {
|
|
46
44
|
const t = useTranslations('CommentsPanel');
|
|
47
45
|
const eventBus = useEventBus();
|
|
48
46
|
const hoverProps = useHoverEmitter(comment.id);
|
|
@@ -156,4 +154,4 @@ export const CommentEntry = forwardRef<HTMLDivElement, CommentEntryProps>(
|
|
|
156
154
|
)}
|
|
157
155
|
</div>
|
|
158
156
|
);
|
|
159
|
-
}
|
|
157
|
+
}
|
|
@@ -167,7 +167,7 @@ export function CommentsPanel({
|
|
|
167
167
|
|
|
168
168
|
const handleSaveNewComment = () => {
|
|
169
169
|
if (newCommentText.trim() && pendingAnnotation) {
|
|
170
|
-
eventBus.get('mark:
|
|
170
|
+
eventBus.get('mark:submit').next({
|
|
171
171
|
motivation: 'commenting',
|
|
172
172
|
selector: pendingAnnotation.selector,
|
|
173
173
|
body: [{ type: 'TextualBody', value: newCommentText, purpose: 'commenting' }],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { Ref } from 'react';
|
|
4
4
|
import type { components } from '@semiont/core';
|
|
5
5
|
import { getAnnotationExactText } from '@semiont/api-client';
|
|
6
6
|
import { useEventBus } from '../../../contexts/EventBusContext';
|
|
@@ -12,6 +12,7 @@ interface HighlightEntryProps {
|
|
|
12
12
|
highlight: Annotation;
|
|
13
13
|
isFocused: boolean;
|
|
14
14
|
isHovered?: boolean;
|
|
15
|
+
ref?: Ref<HTMLDivElement>;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
function formatRelativeTime(isoString: string): string {
|
|
@@ -31,15 +32,12 @@ function formatRelativeTime(isoString: string): string {
|
|
|
31
32
|
return date.toLocaleDateString();
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
},
|
|
41
|
-
ref
|
|
42
|
-
) {
|
|
35
|
+
export function HighlightEntry({
|
|
36
|
+
highlight,
|
|
37
|
+
isFocused,
|
|
38
|
+
isHovered = false,
|
|
39
|
+
ref,
|
|
40
|
+
}: HighlightEntryProps) {
|
|
43
41
|
const eventBus = useEventBus();
|
|
44
42
|
const hoverProps = useHoverEmitter(highlight.id);
|
|
45
43
|
|
|
@@ -69,4 +67,4 @@ export const HighlightEntry = forwardRef<HTMLDivElement, HighlightEntryProps>(
|
|
|
69
67
|
</div>
|
|
70
68
|
</div>
|
|
71
69
|
);
|
|
72
|
-
}
|
|
70
|
+
}
|
|
@@ -129,10 +129,10 @@ export function HighlightPanel({
|
|
|
129
129
|
});
|
|
130
130
|
|
|
131
131
|
// Highlights auto-create: when pendingAnnotation arrives with highlighting motivation,
|
|
132
|
-
// immediately emit mark:
|
|
132
|
+
// immediately emit mark:submit event
|
|
133
133
|
useEffect(() => {
|
|
134
134
|
if (pendingAnnotation && pendingAnnotation.motivation === 'highlighting') {
|
|
135
|
-
eventBus.get('mark:
|
|
135
|
+
eventBus.get('mark:submit').next({
|
|
136
136
|
motivation: 'highlighting',
|
|
137
137
|
selector: pendingAnnotation.selector,
|
|
138
138
|
body: [],
|