@semiont/react-ui 0.2.34-build.91 → 0.2.34-build.92
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/{EventBusContext-BmzEcGHZ.d.mts → EventBusContext-DMI4uwYk.d.mts} +2 -2
- package/dist/{PdfAnnotationCanvas.client-VLNA5O5M.mjs → PdfAnnotationCanvas.client-HNYRKFDS.mjs} +10 -9
- package/dist/PdfAnnotationCanvas.client-HNYRKFDS.mjs.map +1 -0
- package/dist/{ar-4ZEORRW2.mjs → ar-MDB7HC5S.mjs} +45 -49
- package/dist/ar-MDB7HC5S.mjs.map +1 -0
- package/dist/{bn-SEDE5BQJ.mjs → bn-3SAV2ZEM.mjs} +45 -49
- package/dist/bn-3SAV2ZEM.mjs.map +1 -0
- package/dist/{chunk-C63BARI7.mjs → chunk-3FIQXKQF.mjs} +31 -31
- package/dist/{chunk-D7NBW4RV.mjs → chunk-JH7BXE2P.mjs} +45 -49
- package/dist/chunk-JH7BXE2P.mjs.map +1 -0
- package/dist/{chunk-M7SZRRIE.mjs → chunk-MWQ5CNKW.mjs} +13 -13
- package/dist/chunk-MWQ5CNKW.mjs.map +1 -0
- package/dist/{chunk-ULIET3MW.mjs → chunk-YI5IX5ZA.mjs} +1 -1
- package/dist/{chunk-ULIET3MW.mjs.map → chunk-YI5IX5ZA.mjs.map} +1 -1
- package/dist/{cs-7W4WF5WD.mjs → cs-AWCETEUV.mjs} +45 -49
- package/dist/cs-AWCETEUV.mjs.map +1 -0
- package/dist/{da-75XGBCBK.mjs → da-UZZHXYLC.mjs} +45 -49
- package/dist/da-UZZHXYLC.mjs.map +1 -0
- package/dist/{de-ODJVFLHM.mjs → de-LQFWN6S5.mjs} +45 -49
- package/dist/de-LQFWN6S5.mjs.map +1 -0
- package/dist/{el-C4PM4WB3.mjs → el-IWOETBJ7.mjs} +45 -49
- package/dist/el-IWOETBJ7.mjs.map +1 -0
- package/dist/{en-KJCJQ4OO.mjs → en-XWEPVTB4.mjs} +2 -6
- package/dist/{es-WD33R7QL.mjs → es-726NTS53.mjs} +45 -49
- package/dist/es-726NTS53.mjs.map +1 -0
- package/dist/{fa-2BP6V56P.mjs → fa-BVEJZT5S.mjs} +45 -49
- package/dist/fa-BVEJZT5S.mjs.map +1 -0
- package/dist/{fi-USRRW24J.mjs → fi-JBNCGGA6.mjs} +45 -49
- package/dist/fi-JBNCGGA6.mjs.map +1 -0
- package/dist/{fr-EC5S6WVF.mjs → fr-OLH7PNGI.mjs} +45 -49
- package/dist/fr-OLH7PNGI.mjs.map +1 -0
- package/dist/{he-7TBVIKAA.mjs → he-KOJQ4HMA.mjs} +45 -49
- package/dist/he-KOJQ4HMA.mjs.map +1 -0
- package/dist/{hi-FO4VIZLA.mjs → hi-BKJFZXAY.mjs} +45 -49
- package/dist/hi-BKJFZXAY.mjs.map +1 -0
- package/dist/{id-7U7GGVWY.mjs → id-DPLHJVNP.mjs} +45 -49
- package/dist/id-DPLHJVNP.mjs.map +1 -0
- package/dist/index.css +80 -80
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +215 -201
- package/dist/index.mjs +810 -748
- package/dist/index.mjs.map +1 -1
- package/dist/{it-Y4OPL6I2.mjs → it-JXHAM7NL.mjs} +45 -49
- package/dist/it-JXHAM7NL.mjs.map +1 -0
- package/dist/{ja-PK7SQL55.mjs → ja-DQRAO3PU.mjs} +45 -49
- package/dist/ja-DQRAO3PU.mjs.map +1 -0
- package/dist/{ko-L25PXMYD.mjs → ko-6IFCOP6F.mjs} +45 -49
- package/dist/ko-6IFCOP6F.mjs.map +1 -0
- package/dist/{ms-STH777QM.mjs → ms-KF5S2TLL.mjs} +45 -49
- package/dist/ms-KF5S2TLL.mjs.map +1 -0
- package/dist/{nl-Y7LECDDR.mjs → nl-2GUUZLQM.mjs} +45 -49
- package/dist/nl-2GUUZLQM.mjs.map +1 -0
- package/dist/{no-KEKCEWU6.mjs → no-2IBCZGEF.mjs} +45 -49
- package/dist/no-2IBCZGEF.mjs.map +1 -0
- package/dist/{pl-7A7OC75O.mjs → pl-ZEUBJ7YU.mjs} +45 -49
- package/dist/pl-ZEUBJ7YU.mjs.map +1 -0
- package/dist/{pt-35HTM7RA.mjs → pt-WLAFIZWQ.mjs} +45 -49
- package/dist/pt-WLAFIZWQ.mjs.map +1 -0
- package/dist/{ro-VAWL5KQA.mjs → ro-K56IXFGU.mjs} +45 -49
- package/dist/ro-K56IXFGU.mjs.map +1 -0
- package/dist/{sv-7ZK5EQEB.mjs → sv-VFJLMJRY.mjs} +45 -49
- package/dist/sv-VFJLMJRY.mjs.map +1 -0
- package/dist/test-utils.d.mts +2 -2
- package/dist/test-utils.mjs +3 -3
- package/dist/{th-UDWZ4X34.mjs → th-RICLQ2GW.mjs} +45 -49
- package/dist/th-RICLQ2GW.mjs.map +1 -0
- package/dist/{tr-4WMPK3UX.mjs → tr-SALXWE2M.mjs} +45 -49
- package/dist/tr-SALXWE2M.mjs.map +1 -0
- package/dist/{uk-SSLASQYJ.mjs → uk-3U3T3O2E.mjs} +45 -49
- package/dist/uk-3U3T3O2E.mjs.map +1 -0
- package/dist/{vi-IF42Z5PU.mjs → vi-LIVNZXOB.mjs} +45 -49
- package/dist/vi-LIVNZXOB.mjs.map +1 -0
- package/dist/{zh-HRQTNTAI.mjs → zh-KDUAZPX3.mjs} +45 -49
- package/dist/zh-KDUAZPX3.mjs.map +1 -0
- package/package.json +1 -1
- package/src/components/AnnotateReferencesProgressWidget.tsx +113 -0
- package/src/components/CodeMirrorRenderer.tsx +9 -27
- package/src/components/Toolbar.tsx +2 -2
- package/src/components/annotation/AnnotateToolbar.tsx +9 -9
- package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +17 -17
- package/src/components/image-annotation/AnnotationOverlay.tsx +13 -11
- package/src/components/image-annotation/SvgDrawingCanvas.tsx +8 -4
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +11 -9
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +1 -1
- package/src/components/resource/AnnotateView.tsx +17 -12
- package/src/components/resource/BrowseView.tsx +19 -50
- package/src/components/resource/ResourceViewer.tsx +28 -24
- package/src/components/resource/__tests__/BrowseView.test.tsx +27 -27
- package/src/components/resource/panels/AssessmentEntry.tsx +1 -1
- package/src/components/resource/panels/AssessmentPanel.tsx +16 -16
- package/src/components/resource/panels/{DetectSection.css → AssistSection.css} +79 -79
- package/src/components/resource/panels/{DetectSection.tsx → AssistSection.tsx} +46 -46
- package/src/components/resource/panels/CommentEntry.tsx +1 -1
- package/src/components/resource/panels/CommentsPanel.tsx +16 -16
- package/src/components/resource/panels/HighlightEntry.tsx +1 -1
- package/src/components/resource/panels/HighlightPanel.tsx +14 -14
- package/src/components/resource/panels/ReferenceEntry.tsx +5 -5
- package/src/components/resource/panels/ReferencesPanel.tsx +90 -103
- package/src/components/resource/panels/ResourceInfoPanel.tsx +2 -2
- package/src/components/resource/panels/TagEntry.tsx +1 -1
- package/src/components/resource/panels/TaggingPanel.tsx +53 -53
- package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +12 -20
- package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +12 -12
- package/src/components/resource/panels/__tests__/{DetectSection.test.tsx → AssistSection.test.tsx} +109 -108
- package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +8 -8
- package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +3 -3
- package/src/components/resource/panels/__tests__/{HighlightPanel.detectionProgress.test.tsx → HighlightPanel.annotationProgress.test.tsx} +56 -56
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +98 -95
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +3 -3
- package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +16 -16
- package/src/components/settings/SettingsPanel.tsx +29 -1
- package/src/features/resource-compose/components/ResourceComposePage.tsx +3 -0
- package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +36 -26
- package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +26 -16
- package/src/features/resource-viewer/__tests__/{DetectionProgressDismissal.test.tsx → AnnotationProgressDismissal.test.tsx} +48 -38
- package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +59 -49
- package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +55 -33
- package/src/features/resource-viewer/__tests__/GenerationFlowIntegration.test.tsx +24 -16
- package/src/features/resource-viewer/__tests__/ResolutionFlowIntegration.test.tsx +41 -31
- package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +10 -10
- package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +196 -0
- package/src/features/resource-viewer/__tests__/{detection-progress-flow.test.tsx → annotation-progress-flow.test.tsx} +51 -28
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +56 -45
- package/src/styles/core/buttons.css +3 -3
- package/src/styles/core/forms.css +2 -2
- package/src/styles/index.css +1 -1
- package/src/styles/motivations/motivation-assessment.css +9 -9
- package/src/styles/motivations/motivation-comment.css +9 -9
- package/src/styles/motivations/motivation-highlight.css +9 -9
- package/src/styles/motivations/motivation-reference.css +9 -9
- package/src/styles/motivations/motivation-tag.css +9 -9
- package/src/styles/utilities/focus-extended.css +6 -6
- package/translations/ar.json +44 -44
- package/translations/bn.json +44 -44
- package/translations/cs.json +44 -44
- package/translations/da.json +44 -44
- package/translations/de.json +44 -44
- package/translations/el.json +44 -44
- package/translations/en.json +44 -44
- package/translations/es.json +44 -44
- package/translations/fa.json +44 -44
- package/translations/fi.json +44 -44
- package/translations/fr.json +44 -44
- package/translations/he.json +44 -44
- package/translations/hi.json +44 -44
- package/translations/id.json +44 -44
- package/translations/it.json +44 -44
- package/translations/ja.json +44 -44
- package/translations/ko.json +44 -44
- package/translations/ms.json +44 -44
- package/translations/nl.json +44 -44
- package/translations/no.json +44 -44
- package/translations/pl.json +44 -44
- package/translations/pt.json +44 -44
- package/translations/ro.json +44 -44
- package/translations/sv.json +44 -44
- package/translations/th.json +44 -44
- package/translations/tr.json +44 -44
- package/translations/uk.json +44 -44
- package/translations/vi.json +44 -44
- package/translations/zh.json +44 -44
- package/dist/PdfAnnotationCanvas.client-VLNA5O5M.mjs.map +0 -1
- package/dist/ar-4ZEORRW2.mjs.map +0 -1
- package/dist/bn-SEDE5BQJ.mjs.map +0 -1
- package/dist/chunk-D7NBW4RV.mjs.map +0 -1
- package/dist/chunk-M7SZRRIE.mjs.map +0 -1
- package/dist/cs-7W4WF5WD.mjs.map +0 -1
- package/dist/da-75XGBCBK.mjs.map +0 -1
- package/dist/de-ODJVFLHM.mjs.map +0 -1
- package/dist/el-C4PM4WB3.mjs.map +0 -1
- package/dist/es-WD33R7QL.mjs.map +0 -1
- package/dist/fa-2BP6V56P.mjs.map +0 -1
- package/dist/fi-USRRW24J.mjs.map +0 -1
- package/dist/fr-EC5S6WVF.mjs.map +0 -1
- package/dist/he-7TBVIKAA.mjs.map +0 -1
- package/dist/hi-FO4VIZLA.mjs.map +0 -1
- package/dist/id-7U7GGVWY.mjs.map +0 -1
- package/dist/it-Y4OPL6I2.mjs.map +0 -1
- package/dist/ja-PK7SQL55.mjs.map +0 -1
- package/dist/ko-L25PXMYD.mjs.map +0 -1
- package/dist/ms-STH777QM.mjs.map +0 -1
- package/dist/nl-Y7LECDDR.mjs.map +0 -1
- package/dist/no-KEKCEWU6.mjs.map +0 -1
- package/dist/pl-7A7OC75O.mjs.map +0 -1
- package/dist/pt-35HTM7RA.mjs.map +0 -1
- package/dist/ro-VAWL5KQA.mjs.map +0 -1
- package/dist/sv-7ZK5EQEB.mjs.map +0 -1
- package/dist/th-UDWZ4X34.mjs.map +0 -1
- package/dist/tr-4WMPK3UX.mjs.map +0 -1
- package/dist/uk-SSLASQYJ.mjs.map +0 -1
- package/dist/vi-IF42Z5PU.mjs.map +0 -1
- package/dist/zh-HRQTNTAI.mjs.map +0 -1
- package/src/components/DetectionProgressWidget.tsx +0 -113
- /package/dist/{chunk-C63BARI7.mjs.map → chunk-3FIQXKQF.mjs.map} +0 -0
- /package/dist/{en-KJCJQ4OO.mjs.map → en-XWEPVTB4.mjs.map} +0 -0
|
@@ -5,12 +5,13 @@ import { useTranslations } from '../../../contexts/TranslationContext';
|
|
|
5
5
|
import { useEventBus } from '../../../contexts/EventBusContext';
|
|
6
6
|
import { useEventSubscriptions } from '../../../contexts/useEventSubscription';
|
|
7
7
|
import type { RouteBuilder, LinkComponentProps } from '../../../contexts/RoutingContext';
|
|
8
|
-
import {
|
|
8
|
+
import { AnnotateReferencesProgressWidget } from '../../AnnotateReferencesProgressWidget';
|
|
9
9
|
import { ReferenceEntry } from './ReferenceEntry';
|
|
10
10
|
import type { components, paths, Selector } from '@semiont/core';
|
|
11
11
|
import { getTextPositionSelector, getTargetSelector } from '@semiont/api-client';
|
|
12
12
|
import { PanelHeader } from './PanelHeader';
|
|
13
13
|
import './ReferencesPanel.css';
|
|
14
|
+
import type { AnnotationProgress } from '@semiont/core';
|
|
14
15
|
|
|
15
16
|
type Annotation = components['schemas']['Annotation'];
|
|
16
17
|
type Motivation = components['schemas']['Motivation'];
|
|
@@ -40,16 +41,11 @@ function getSelectorDisplayText(selector: Selector | Selector[]): string | null
|
|
|
40
41
|
return null;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
interface DetectionLog {
|
|
44
|
-
entityType: string;
|
|
45
|
-
foundCount: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
44
|
interface Props {
|
|
49
45
|
// Generic panel props
|
|
50
46
|
annotations?: Annotation[];
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
isAssisting: boolean;
|
|
48
|
+
progress: AnnotationProgress | null;
|
|
53
49
|
annotateMode?: boolean;
|
|
54
50
|
Link: React.ComponentType<LinkComponentProps>;
|
|
55
51
|
routes: RouteBuilder;
|
|
@@ -66,17 +62,17 @@ interface Props {
|
|
|
66
62
|
}
|
|
67
63
|
|
|
68
64
|
/**
|
|
69
|
-
* Panel for managing reference annotations with entity type
|
|
65
|
+
* Panel for managing reference annotations with entity type annotation
|
|
70
66
|
*
|
|
71
|
-
* @emits
|
|
72
|
-
* @emits
|
|
73
|
-
* @emits
|
|
74
|
-
* @subscribes
|
|
67
|
+
* @emits annotate:detect-request - Start reference annotation. Payload: { motivation: 'linking', options: { entityTypes: string[], includeDescriptiveReferences: boolean } }
|
|
68
|
+
* @emits annotate:create - Create new reference annotation. Payload: { motivation: 'linking', selector: Selector | Selector[], body: Body[] }
|
|
69
|
+
* @emits annotate:cancel-pending - Cancel pending reference annotation. Payload: undefined
|
|
70
|
+
* @subscribes attend:click - Annotation clicked. Payload: { annotationId: string }
|
|
75
71
|
*/
|
|
76
72
|
export function ReferencesPanel({
|
|
77
73
|
annotations = [],
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
isAssisting,
|
|
75
|
+
progress,
|
|
80
76
|
annotateMode = true,
|
|
81
77
|
Link,
|
|
82
78
|
routes,
|
|
@@ -89,28 +85,27 @@ export function ReferencesPanel({
|
|
|
89
85
|
onScrollCompleted,
|
|
90
86
|
hoveredAnnotationId,
|
|
91
87
|
}: Props) {
|
|
92
|
-
const t = useTranslations('
|
|
93
|
-
const tRef = useTranslations('ReferencesPanel');
|
|
88
|
+
const t = useTranslations('ReferencesPanel');
|
|
94
89
|
const eventBus = useEventBus();
|
|
95
90
|
const [selectedEntityTypes, setSelectedEntityTypes] = useState<string[]>([]);
|
|
96
|
-
const [
|
|
91
|
+
const [lastAnnotationLog, setLastDetectionLog] = useState<Array<{ entityType: string; foundCount: number }> | null>(null);
|
|
97
92
|
const [pendingEntityTypes, setPendingEntityTypes] = useState<string[]>([]);
|
|
98
93
|
const [includeDescriptiveReferences, setIncludeDescriptiveReferences] = useState(false);
|
|
99
94
|
const [focusedAnnotationId, setFocusedAnnotationId] = useState<string | null>(null);
|
|
100
95
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
101
96
|
|
|
102
97
|
// Collapsible detection section state - load from localStorage, default expanded
|
|
103
|
-
const [
|
|
98
|
+
const [isAssistExpanded, setIsDetectExpanded] = useState(() => {
|
|
104
99
|
if (typeof window === 'undefined') return true;
|
|
105
|
-
const stored = localStorage.getItem('
|
|
100
|
+
const stored = localStorage.getItem('assist-section-expanded-reference');
|
|
106
101
|
return stored ? stored === 'true' : true;
|
|
107
102
|
});
|
|
108
103
|
|
|
109
104
|
// Persist detection section expanded state to localStorage
|
|
110
105
|
useEffect(() => {
|
|
111
106
|
if (typeof window === 'undefined') return;
|
|
112
|
-
localStorage.setItem('
|
|
113
|
-
}, [
|
|
107
|
+
localStorage.setItem('assist-section-expanded-reference', String(isAssistExpanded));
|
|
108
|
+
}, [isAssistExpanded]);
|
|
114
109
|
|
|
115
110
|
// Direct ref management - replace useAnnotationPanel hook
|
|
116
111
|
const entryRefs = useRef<Map<string, HTMLDivElement>>(new Map());
|
|
@@ -201,13 +196,13 @@ export function ReferencesPanel({
|
|
|
201
196
|
}, []);
|
|
202
197
|
|
|
203
198
|
useEventSubscriptions({
|
|
204
|
-
'
|
|
199
|
+
'attend:click': handleAnnotationClick,
|
|
205
200
|
});
|
|
206
201
|
|
|
207
|
-
// Clear log when starting new
|
|
208
|
-
const
|
|
202
|
+
// Clear log when starting new annotation
|
|
203
|
+
const handleAssist = () => {
|
|
209
204
|
setLastDetectionLog(null);
|
|
210
|
-
eventBus.get('
|
|
205
|
+
eventBus.get('annotate:assist-request').next({
|
|
211
206
|
motivation: 'linking',
|
|
212
207
|
options: {
|
|
213
208
|
entityTypes: selectedEntityTypes,
|
|
@@ -221,23 +216,23 @@ export function ReferencesPanel({
|
|
|
221
216
|
const hasSavedLogRef = useRef(false);
|
|
222
217
|
|
|
223
218
|
// Save detection log when detection completes
|
|
224
|
-
// Only depends on
|
|
225
|
-
// Trade-off: If completedEntityTypes changes while
|
|
226
|
-
// This is acceptable because in practice, completedEntityTypes only changes when
|
|
219
|
+
// Only depends on isAssisting boolean to avoid infinite loops from array reference changes
|
|
220
|
+
// Trade-off: If completedEntityTypes changes while isAssisting stays false, we won't update
|
|
221
|
+
// This is acceptable because in practice, completedEntityTypes only changes when annotation finishes
|
|
227
222
|
useEffect(() => {
|
|
228
|
-
// When
|
|
229
|
-
if (
|
|
223
|
+
// When annotation starts, reset the flag
|
|
224
|
+
if (isAssisting) {
|
|
230
225
|
hasSavedLogRef.current = false;
|
|
231
226
|
return;
|
|
232
227
|
}
|
|
233
228
|
|
|
234
|
-
// When
|
|
235
|
-
if (!
|
|
229
|
+
// When annotation is complete and we haven't saved yet, save the log
|
|
230
|
+
if (!isAssisting && !hasSavedLogRef.current && progress?.completedEntityTypes) {
|
|
236
231
|
hasSavedLogRef.current = true;
|
|
237
|
-
setLastDetectionLog(
|
|
232
|
+
setLastDetectionLog(progress.completedEntityTypes);
|
|
238
233
|
setSelectedEntityTypes([]);
|
|
239
234
|
}
|
|
240
|
-
}, [
|
|
235
|
+
}, [isAssisting, progress?.completedEntityTypes]); // Both dependencies needed to annotation completion
|
|
241
236
|
|
|
242
237
|
const togglePendingEntityType = (type: string) => {
|
|
243
238
|
setPendingEntityTypes(prev =>
|
|
@@ -250,7 +245,7 @@ export function ReferencesPanel({
|
|
|
250
245
|
const handleCreateReference = () => {
|
|
251
246
|
if (pendingAnnotation) {
|
|
252
247
|
const entityType = pendingEntityTypes.join(',') || undefined;
|
|
253
|
-
eventBus.get('
|
|
248
|
+
eventBus.get('annotate:create').next({
|
|
254
249
|
motivation: 'linking',
|
|
255
250
|
selector: pendingAnnotation.selector,
|
|
256
251
|
body: entityType ? [{ type: 'TextualBody', value: entityType, purpose: 'tagging' }] : [],
|
|
@@ -265,7 +260,7 @@ export function ReferencesPanel({
|
|
|
265
260
|
|
|
266
261
|
const handleEscape = (e: KeyboardEvent) => {
|
|
267
262
|
if (e.key === 'Escape') {
|
|
268
|
-
eventBus.get('
|
|
263
|
+
eventBus.get('annotate:cancel-pending').next(undefined);
|
|
269
264
|
setPendingEntityTypes([]);
|
|
270
265
|
}
|
|
271
266
|
};
|
|
@@ -276,7 +271,7 @@ export function ReferencesPanel({
|
|
|
276
271
|
|
|
277
272
|
return (
|
|
278
273
|
<div className="semiont-panel">
|
|
279
|
-
<PanelHeader annotationType="reference" count={annotations.length} title={
|
|
274
|
+
<PanelHeader annotationType="reference" count={annotations.length} title={t('title')} />
|
|
280
275
|
|
|
281
276
|
{/* New reference creation - shown when there's a pending annotation with linking motivation */}
|
|
282
277
|
{pendingAnnotation && pendingAnnotation.motivation === 'linking' && (
|
|
@@ -288,7 +283,7 @@ export function ReferencesPanel({
|
|
|
288
283
|
return `"${displayText.substring(0, 100)}${displayText.length > 100 ? '...' : ''}"`;
|
|
289
284
|
}
|
|
290
285
|
// Generic labels for PDF/image annotations without text
|
|
291
|
-
return
|
|
286
|
+
return t('fragmentSelected');
|
|
292
287
|
})()}
|
|
293
288
|
</div>
|
|
294
289
|
|
|
@@ -296,7 +291,7 @@ export function ReferencesPanel({
|
|
|
296
291
|
{allEntityTypes.length > 0 && (
|
|
297
292
|
<div className="semiont-form-field">
|
|
298
293
|
<p className="semiont-form-field__label">
|
|
299
|
-
{
|
|
294
|
+
{t('entityTypesOptional')}
|
|
300
295
|
</p>
|
|
301
296
|
<div className="semiont-tag-selector">
|
|
302
297
|
{allEntityTypes.map((type: string) => (
|
|
@@ -317,20 +312,20 @@ export function ReferencesPanel({
|
|
|
317
312
|
<div className="semiont-annotation-prompt__actions">
|
|
318
313
|
<button
|
|
319
314
|
onClick={() => {
|
|
320
|
-
eventBus.get('
|
|
315
|
+
eventBus.get('annotate:cancel-pending').next(undefined);
|
|
321
316
|
setPendingEntityTypes([]);
|
|
322
317
|
}}
|
|
323
318
|
className="semiont-button semiont-button--secondary"
|
|
324
319
|
data-type="reference"
|
|
325
320
|
>
|
|
326
|
-
{
|
|
321
|
+
{t('cancel')}
|
|
327
322
|
</button>
|
|
328
323
|
<button
|
|
329
324
|
onClick={handleCreateReference}
|
|
330
325
|
className="semiont-button semiont-button--primary"
|
|
331
326
|
data-type="reference"
|
|
332
327
|
>
|
|
333
|
-
🔗 {
|
|
328
|
+
🔗 {t('createReference')}
|
|
334
329
|
</button>
|
|
335
330
|
</div>
|
|
336
331
|
</div>
|
|
@@ -339,32 +334,47 @@ export function ReferencesPanel({
|
|
|
339
334
|
|
|
340
335
|
{/* Scrollable content area */}
|
|
341
336
|
<div ref={containerRef} className="semiont-panel__content">
|
|
342
|
-
{/*
|
|
337
|
+
{/* Assist Section - only in Annotate mode and for text resources */}
|
|
343
338
|
{annotateMode && (
|
|
344
339
|
<div className="semiont-panel__section">
|
|
345
340
|
<button
|
|
346
|
-
onClick={() => setIsDetectExpanded(!
|
|
341
|
+
onClick={() => setIsDetectExpanded(!isAssistExpanded)}
|
|
347
342
|
className="semiont-panel__section-title semiont-panel__section-title--collapsible"
|
|
348
|
-
aria-expanded={
|
|
343
|
+
aria-expanded={isAssistExpanded}
|
|
349
344
|
type="button"
|
|
350
345
|
>
|
|
351
|
-
<span>{t('
|
|
352
|
-
<span className="semiont-panel__section-chevron" data-expanded={
|
|
346
|
+
<span>{t('annotateReferences')}</span>
|
|
347
|
+
<span className="semiont-panel__section-chevron" data-expanded={isAssistExpanded}>
|
|
353
348
|
›
|
|
354
349
|
</span>
|
|
355
350
|
</button>
|
|
356
|
-
{
|
|
351
|
+
{isAssistExpanded && (
|
|
357
352
|
<>
|
|
358
|
-
{/* Show annotation UI
|
|
359
|
-
{!
|
|
360
|
-
<div className="semiont-
|
|
353
|
+
{/* Show annotation UI when not actively assisting */}
|
|
354
|
+
{!isAssisting && (
|
|
355
|
+
<div className="semiont-assist-widget" data-type="reference">
|
|
361
356
|
<>
|
|
357
|
+
{/* Completed annotation log - shown after completion */}
|
|
358
|
+
{lastAnnotationLog && lastAnnotationLog.length > 0 && (
|
|
359
|
+
<div className="semiont-assist-widget__log">
|
|
360
|
+
<div className="semiont-assist-widget__log-items">
|
|
361
|
+
{lastAnnotationLog.map((item, index) => (
|
|
362
|
+
<div key={index} className="semiont-assist-widget__log-item">
|
|
363
|
+
<span className="semiont-assist-widget__log-check">✓</span>
|
|
364
|
+
<span className="semiont-assist-widget__log-type">{item.entityType}:</span>
|
|
365
|
+
<span>{t('found', { count: item.foundCount })}</span>
|
|
366
|
+
</div>
|
|
367
|
+
))}
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
)}
|
|
371
|
+
|
|
362
372
|
{/* Entity Types Selection */}
|
|
363
|
-
<div className="semiont-
|
|
364
|
-
<p className="semiont-
|
|
373
|
+
<div className="semiont-assist-widget__entity-types">
|
|
374
|
+
<p className="semiont-assist-widget__label">
|
|
365
375
|
{t('selectEntityTypes')}
|
|
366
376
|
</p>
|
|
367
|
-
<div className="semiont-
|
|
377
|
+
<div className="semiont-assist-widget__chips">
|
|
368
378
|
{allEntityTypes.length > 0 ? (
|
|
369
379
|
allEntityTypes.map((type: string) => (
|
|
370
380
|
<button
|
|
@@ -385,7 +395,7 @@ export function ReferencesPanel({
|
|
|
385
395
|
</button>
|
|
386
396
|
))
|
|
387
397
|
) : (
|
|
388
|
-
<p className="semiont-
|
|
398
|
+
<p className="semiont-assist-widget__no-types">
|
|
389
399
|
{t('noEntityTypes')}
|
|
390
400
|
</p>
|
|
391
401
|
)}
|
|
@@ -394,73 +404,50 @@ export function ReferencesPanel({
|
|
|
394
404
|
|
|
395
405
|
{/* Selected Count */}
|
|
396
406
|
{selectedEntityTypes.length > 0 && (
|
|
397
|
-
<p className="semiont-
|
|
407
|
+
<p className="semiont-assist-widget__count">
|
|
398
408
|
{t('typesSelected', { count: selectedEntityTypes.length })}
|
|
399
409
|
</p>
|
|
400
410
|
)}
|
|
401
411
|
|
|
402
412
|
{/* Include Descriptive References Checkbox */}
|
|
403
|
-
<div className="semiont-
|
|
404
|
-
<label className="semiont-
|
|
413
|
+
<div className="semiont-assist-widget__checkbox-group">
|
|
414
|
+
<label className="semiont-assist-widget__checkbox-label">
|
|
405
415
|
<input
|
|
406
416
|
type="checkbox"
|
|
407
417
|
checked={includeDescriptiveReferences}
|
|
408
418
|
onChange={(e) => setIncludeDescriptiveReferences(e.target.checked)}
|
|
409
|
-
className="semiont-
|
|
419
|
+
className="semiont-assist-widget__checkbox"
|
|
410
420
|
/>
|
|
411
|
-
<span>{
|
|
421
|
+
<span>{t('includeDescriptiveReferences')}</span>
|
|
412
422
|
</label>
|
|
413
|
-
<p className="semiont-
|
|
414
|
-
{
|
|
423
|
+
<p className="semiont-assist-widget__checkbox-hint">
|
|
424
|
+
{t('descriptiveReferencesTooltip')}
|
|
415
425
|
</p>
|
|
416
426
|
</div>
|
|
417
427
|
|
|
418
|
-
{/* Start
|
|
428
|
+
{/* Start Assist Button */}
|
|
419
429
|
<button
|
|
420
|
-
onClick={
|
|
430
|
+
onClick={handleAssist}
|
|
421
431
|
disabled={selectedEntityTypes.length === 0}
|
|
422
|
-
title={t('
|
|
432
|
+
title={t('annotate')}
|
|
423
433
|
className="semiont-button"
|
|
424
|
-
data-variant="
|
|
434
|
+
data-variant="assist"
|
|
425
435
|
data-type="reference"
|
|
426
436
|
>
|
|
427
437
|
<span className="semiont-button-icon">✨</span>
|
|
428
|
-
<span>{t('
|
|
438
|
+
<span>{t('annotate')}</span>
|
|
429
439
|
</button>
|
|
430
440
|
</>
|
|
431
441
|
</div>
|
|
432
442
|
)}
|
|
433
443
|
|
|
434
|
-
{/*
|
|
435
|
-
{
|
|
436
|
-
<
|
|
437
|
-
progress={
|
|
444
|
+
{/* Annotation Progress - shown when active */}
|
|
445
|
+
{isAssisting && progress && (
|
|
446
|
+
<AnnotateReferencesProgressWidget
|
|
447
|
+
progress={progress}
|
|
438
448
|
annotationType="reference"
|
|
439
449
|
/>
|
|
440
450
|
)}
|
|
441
|
-
|
|
442
|
-
{/* Completed detection log - shown after completion */}
|
|
443
|
-
{!detectionProgress && lastDetectionLog && lastDetectionLog.length > 0 && (
|
|
444
|
-
<div className="semiont-detect-widget__log">
|
|
445
|
-
<div className="semiont-detect-widget__log-items">
|
|
446
|
-
{lastDetectionLog.map((item, index) => (
|
|
447
|
-
<div key={index} className="semiont-detect-widget__log-item">
|
|
448
|
-
<span className="semiont-detect-widget__log-check">✓</span>
|
|
449
|
-
<span className="semiont-detect-widget__log-type">{item.entityType}:</span>
|
|
450
|
-
<span>{t('found', { count: item.foundCount })}</span>
|
|
451
|
-
</div>
|
|
452
|
-
))}
|
|
453
|
-
</div>
|
|
454
|
-
<button
|
|
455
|
-
onClick={() => setLastDetectionLog(null)}
|
|
456
|
-
className="semiont-button"
|
|
457
|
-
data-variant="detect"
|
|
458
|
-
data-type="reference"
|
|
459
|
-
>
|
|
460
|
-
{t('more')}
|
|
461
|
-
</button>
|
|
462
|
-
</div>
|
|
463
|
-
)}
|
|
464
451
|
</>
|
|
465
452
|
)}
|
|
466
453
|
</div>
|
|
@@ -470,14 +457,14 @@ export function ReferencesPanel({
|
|
|
470
457
|
<div>
|
|
471
458
|
<div className="semiont-panel__divider">
|
|
472
459
|
<h3 className="semiont-panel__subtitle">
|
|
473
|
-
{
|
|
460
|
+
{t('outgoingReferences')} ({sortedAnnotations.length})
|
|
474
461
|
</h3>
|
|
475
462
|
</div>
|
|
476
463
|
|
|
477
464
|
<div className="semiont-panel__list">
|
|
478
465
|
{sortedAnnotations.length === 0 ? (
|
|
479
466
|
<p className="semiont-panel__empty-message">
|
|
480
|
-
{
|
|
467
|
+
{t('noReferences')}
|
|
481
468
|
</p>
|
|
482
469
|
) : (
|
|
483
470
|
sortedAnnotations.map((reference) => (
|
|
@@ -500,9 +487,9 @@ export function ReferencesPanel({
|
|
|
500
487
|
<div>
|
|
501
488
|
<div className="semiont-panel__divider">
|
|
502
489
|
<h3 className="semiont-panel__subtitle">
|
|
503
|
-
{
|
|
490
|
+
{t('incomingReferences')} ({referencedBy.length})
|
|
504
491
|
{referencedByLoading && (
|
|
505
|
-
<span className="semiont-panel__loading-indicator">({
|
|
492
|
+
<span className="semiont-panel__loading-indicator">({t('loading')})</span>
|
|
506
493
|
)}
|
|
507
494
|
</h3>
|
|
508
495
|
</div>
|
|
@@ -517,18 +504,18 @@ export function ReferencesPanel({
|
|
|
517
504
|
<div key={ref.id} className="semiont-reference-item semiont-reference-item--incoming">
|
|
518
505
|
<div className="semiont-reference-item__header">
|
|
519
506
|
<span className="semiont-reference-item__title">
|
|
520
|
-
{ref.resourceName ||
|
|
507
|
+
{ref.resourceName || t('untitledResource')}
|
|
521
508
|
</span>
|
|
522
509
|
<Link
|
|
523
510
|
href={routes.resourceDetail(resourceId)}
|
|
524
511
|
className="semiont-reference-item__link"
|
|
525
|
-
title={
|
|
512
|
+
title={t('open')}
|
|
526
513
|
>
|
|
527
514
|
🔗
|
|
528
515
|
</Link>
|
|
529
516
|
</div>
|
|
530
517
|
<span className="semiont-reference-item__excerpt">
|
|
531
|
-
"{ref.target.selector?.exact ||
|
|
518
|
+
"{ref.target.selector?.exact || t('noText')}"
|
|
532
519
|
</span>
|
|
533
520
|
</div>
|
|
534
521
|
);
|
|
@@ -536,7 +523,7 @@ export function ReferencesPanel({
|
|
|
536
523
|
</div>
|
|
537
524
|
) : (
|
|
538
525
|
<p className="semiont-panel__empty-message semiont-panel__empty-message--small">
|
|
539
|
-
{referencedByLoading ?
|
|
526
|
+
{referencedByLoading ? t('loadingEllipsis') : t('noIncomingReferences')}
|
|
540
527
|
</p>
|
|
541
528
|
)}
|
|
542
529
|
</div>
|
|
@@ -16,7 +16,7 @@ interface Props {
|
|
|
16
16
|
/**
|
|
17
17
|
* Panel for displaying resource metadata and management actions
|
|
18
18
|
*
|
|
19
|
-
* @emits
|
|
19
|
+
* @emits generate:clone - Clone this resource. Payload: undefined
|
|
20
20
|
* @emits resource:unarchive - Unarchive this resource. Payload: undefined
|
|
21
21
|
* @emits resource:archive - Archive this resource. Payload: undefined
|
|
22
22
|
*/
|
|
@@ -97,7 +97,7 @@ export function ResourceInfoPanel({
|
|
|
97
97
|
{/* Clone Action */}
|
|
98
98
|
<div className="semiont-resource-info-panel__action-section">
|
|
99
99
|
<button
|
|
100
|
-
onClick={() => eventBus.get('
|
|
100
|
+
onClick={() => eventBus.get('generate:clone').next(undefined)}
|
|
101
101
|
className="semiont-resource-button semiont-resource-button--secondary"
|
|
102
102
|
>
|
|
103
103
|
🔗 {t('clone')}
|
|
@@ -37,7 +37,7 @@ export const TagEntry = forwardRef<HTMLDivElement, TagEntryProps>(
|
|
|
37
37
|
<div
|
|
38
38
|
ref={ref}
|
|
39
39
|
onClick={() => {
|
|
40
|
-
eventBus.get('
|
|
40
|
+
eventBus.get('attend:click').next({ annotationId: tag.id, motivation: tag.motivation });
|
|
41
41
|
}}
|
|
42
42
|
{...hoverProps}
|
|
43
43
|
className={`semiont-annotation-entry${isHovered ? ' semiont-annotation-pulse' : ''}`}
|