@semiont/react-ui 0.2.33-build.79 → 0.2.33-build.81
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-CJjL_cCf.d.mts +462 -0
- package/dist/{PdfAnnotationCanvas.client-ADC4FFSE.mjs → PdfAnnotationCanvas.client-RAJRPQLU.mjs} +42 -27
- package/dist/PdfAnnotationCanvas.client-RAJRPQLU.mjs.map +1 -0
- package/dist/{ar-EMHEHPCJ.mjs → ar-4ZEORRW2.mjs} +7 -4
- package/dist/ar-4ZEORRW2.mjs.map +1 -0
- package/dist/{bn-OVCI4F6X.mjs → bn-SEDE5BQJ.mjs} +7 -4
- package/dist/bn-SEDE5BQJ.mjs.map +1 -0
- package/dist/{chunk-LIHZTECW.mjs → chunk-D7NBW4RV.mjs} +7 -4
- package/dist/chunk-D7NBW4RV.mjs.map +1 -0
- package/dist/{chunk-JZIO2A3B.mjs → chunk-QB52Q7EQ.mjs} +206 -146
- package/dist/chunk-QB52Q7EQ.mjs.map +1 -0
- package/dist/{cs-FAN66Q2F.mjs → cs-7W4WF5WD.mjs} +7 -4
- package/dist/cs-7W4WF5WD.mjs.map +1 -0
- package/dist/{da-YBBIHI2O.mjs → da-75XGBCBK.mjs} +7 -4
- package/dist/da-75XGBCBK.mjs.map +1 -0
- package/dist/{de-MAYU33LB.mjs → de-ODJVFLHM.mjs} +7 -4
- package/dist/de-ODJVFLHM.mjs.map +1 -0
- package/dist/{el-MKGSWN4O.mjs → el-C4PM4WB3.mjs} +7 -4
- package/dist/el-C4PM4WB3.mjs.map +1 -0
- package/dist/{en-DDLIXJCU.mjs → en-KJCJQ4OO.mjs} +2 -2
- package/dist/{es-52LHUWJD.mjs → es-WD33R7QL.mjs} +7 -4
- package/dist/es-WD33R7QL.mjs.map +1 -0
- package/dist/{fa-FJICRANB.mjs → fa-2BP6V56P.mjs} +7 -4
- package/dist/fa-2BP6V56P.mjs.map +1 -0
- package/dist/{fi-O455XFCR.mjs → fi-USRRW24J.mjs} +7 -4
- package/dist/fi-USRRW24J.mjs.map +1 -0
- package/dist/{fr-TXIXHOOE.mjs → fr-EC5S6WVF.mjs} +7 -4
- package/dist/fr-EC5S6WVF.mjs.map +1 -0
- package/dist/{he-JBSOX5IN.mjs → he-7TBVIKAA.mjs} +7 -4
- package/dist/he-7TBVIKAA.mjs.map +1 -0
- package/dist/{hi-KGHI3XVT.mjs → hi-FO4VIZLA.mjs} +7 -4
- package/dist/hi-FO4VIZLA.mjs.map +1 -0
- package/dist/{id-5OCPPZLO.mjs → id-7U7GGVWY.mjs} +7 -4
- package/dist/id-7U7GGVWY.mjs.map +1 -0
- package/dist/index.css +123 -85
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +715 -574
- package/dist/index.mjs +3898 -3575
- package/dist/index.mjs.map +1 -1
- package/dist/{it-PNBBZSM2.mjs → it-Y4OPL6I2.mjs} +7 -4
- package/dist/it-Y4OPL6I2.mjs.map +1 -0
- package/dist/{ja-LDD7R3TJ.mjs → ja-PK7SQL55.mjs} +7 -4
- package/dist/ja-PK7SQL55.mjs.map +1 -0
- package/dist/{ko-F47ZDEY3.mjs → ko-L25PXMYD.mjs} +7 -4
- package/dist/ko-L25PXMYD.mjs.map +1 -0
- package/dist/{ms-Z7LMXJWL.mjs → ms-STH777QM.mjs} +7 -4
- package/dist/ms-STH777QM.mjs.map +1 -0
- package/dist/{nl-6SJFBPJ3.mjs → nl-Y7LECDDR.mjs} +7 -4
- package/dist/nl-Y7LECDDR.mjs.map +1 -0
- package/dist/{no-YXPBPSGF.mjs → no-KEKCEWU6.mjs} +7 -4
- package/dist/no-KEKCEWU6.mjs.map +1 -0
- package/dist/{pl-P4AZ2QME.mjs → pl-7A7OC75O.mjs} +7 -4
- package/dist/pl-7A7OC75O.mjs.map +1 -0
- package/dist/{pt-LHWUS6U6.mjs → pt-35HTM7RA.mjs} +7 -4
- package/dist/pt-35HTM7RA.mjs.map +1 -0
- package/dist/{ro-EA5J2ZON.mjs → ro-VAWL5KQA.mjs} +7 -4
- package/dist/ro-VAWL5KQA.mjs.map +1 -0
- package/dist/{sv-DATBS3UQ.mjs → sv-7ZK5EQEB.mjs} +7 -4
- package/dist/sv-7ZK5EQEB.mjs.map +1 -0
- package/dist/test-utils.d.mts +18 -8
- package/dist/test-utils.mjs +36 -14
- package/dist/test-utils.mjs.map +1 -1
- package/dist/{th-WTFJRWPT.mjs → th-UDWZ4X34.mjs} +7 -4
- package/dist/th-UDWZ4X34.mjs.map +1 -0
- package/dist/{tr-IKO3RXOX.mjs → tr-4WMPK3UX.mjs} +7 -4
- package/dist/tr-4WMPK3UX.mjs.map +1 -0
- package/dist/{uk-CF6CTTRK.mjs → uk-SSLASQYJ.mjs} +7 -4
- package/dist/uk-SSLASQYJ.mjs.map +1 -0
- package/dist/{vi-AJLTXPZQ.mjs → vi-IF42Z5PU.mjs} +7 -4
- package/dist/vi-IF42Z5PU.mjs.map +1 -0
- package/dist/{zh-U3ORHHYH.mjs → zh-HRQTNTAI.mjs} +7 -4
- package/dist/zh-HRQTNTAI.mjs.map +1 -0
- package/package.json +3 -1
- package/src/components/CodeMirrorRenderer.tsx +66 -93
- package/src/components/DetectionProgressWidget.tsx +16 -5
- package/src/components/ResizeHandle.tsx +10 -4
- package/src/components/SessionExpiryBanner.tsx +2 -3
- package/src/components/SessionTimer.tsx +3 -3
- package/src/components/Toolbar.tsx +18 -9
- package/src/components/__tests__/SessionTimer.test.tsx +33 -33
- package/src/components/annotation/AnnotateToolbar.tsx +17 -15
- package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +165 -63
- package/src/components/annotation/annotation-entries.css +10 -0
- package/src/components/annotation-popups/JsonLdView.tsx +8 -2
- package/src/components/image-annotation/AnnotationOverlay.tsx +42 -22
- package/src/components/image-annotation/SvgDrawingCanvas.tsx +27 -30
- package/src/components/layout/__tests__/LeftSidebar.test.tsx +12 -33
- package/src/components/layout/__tests__/PageLayout.test.tsx +37 -32
- package/src/components/layout/__tests__/UnifiedHeader.test.tsx +21 -40
- package/src/components/modals/ResourceSearchModal.tsx +2 -2
- package/src/components/modals/SearchModal.tsx +1 -1
- package/src/components/navigation/CollapsibleResourceNavigation.tsx +14 -9
- package/src/components/navigation/NavigationTabs.css +36 -24
- package/src/components/navigation/ObservableLink.tsx +91 -0
- package/src/components/navigation/SimpleNavigation.tsx +20 -16
- package/src/components/navigation/SortableResourceTab.tsx +11 -5
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +51 -26
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +28 -22
- package/src/components/resource/AnnotateView.tsx +64 -134
- package/src/components/resource/BrowseView.tsx +86 -166
- package/src/components/resource/HistoryEvent.tsx +13 -7
- package/src/components/resource/ResourceViewer.tsx +122 -264
- package/src/components/resource/__tests__/BrowseView.test.tsx +631 -0
- package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +231 -0
- package/src/components/resource/panels/AssessmentEntry.tsx +25 -33
- package/src/components/resource/panels/AssessmentPanel.tsx +106 -28
- package/src/components/resource/panels/CommentEntry.tsx +38 -32
- package/src/components/resource/panels/CommentsPanel.tsx +121 -28
- package/src/components/resource/panels/DetectSection.css +36 -1
- package/src/components/resource/panels/DetectSection.tsx +49 -15
- package/src/components/resource/panels/HighlightEntry.tsx +25 -33
- package/src/components/resource/panels/HighlightPanel.tsx +100 -25
- package/src/components/resource/panels/ReferenceEntry.tsx +61 -75
- package/src/components/resource/panels/ReferencesPanel.tsx +134 -42
- package/src/components/resource/panels/ResourceInfoPanel.tsx +47 -48
- package/src/components/resource/panels/TagEntry.tsx +25 -33
- package/src/components/resource/panels/TaggingPanel.tsx +118 -30
- package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +30 -92
- package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +129 -110
- package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +86 -78
- package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +144 -149
- package/src/components/resource/panels/__tests__/DetectSection.test.tsx +480 -0
- package/src/components/resource/panels/__tests__/HighlightPanel.detectionProgress.test.tsx +362 -0
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +226 -111
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +117 -61
- package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +128 -106
- package/src/components/settings/SettingsPanel.tsx +15 -12
- package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +1 -46
- package/src/features/admin-devops/components/AdminDevOpsPage.tsx +0 -9
- package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +0 -3
- package/src/features/admin-security/components/AdminSecurityPage.tsx +0 -9
- package/src/features/admin-users/__tests__/AdminUsersPage.test.tsx +0 -3
- package/src/features/admin-users/components/AdminUsersPage.tsx +0 -9
- package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +0 -3
- package/src/features/moderate-entity-tags/components/EntityTagsPage.tsx +1 -9
- package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +0 -32
- package/src/features/moderate-recent/components/RecentDocumentsPage.tsx +1 -9
- package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +0 -32
- package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -9
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +51 -54
- package/src/features/resource-compose/components/ResourceComposePage.tsx +3 -13
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +39 -45
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +9 -13
- package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +234 -0
- package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +234 -0
- package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +388 -0
- package/src/features/resource-viewer/__tests__/DetectionProgressDismissal.test.tsx +318 -0
- package/src/features/resource-viewer/__tests__/GenerationFlowIntegration.test.tsx +503 -0
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +139 -93
- package/src/features/resource-viewer/__tests__/detection-progress-flow.test.tsx +322 -0
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +341 -524
- package/translations/ar.json +6 -3
- package/translations/bn.json +6 -3
- package/translations/cs.json +6 -3
- package/translations/da.json +6 -3
- package/translations/de.json +6 -3
- package/translations/el.json +6 -3
- package/translations/en.json +6 -3
- package/translations/es.json +6 -3
- package/translations/fa.json +6 -3
- package/translations/fi.json +6 -3
- package/translations/fr.json +6 -3
- package/translations/he.json +6 -3
- package/translations/hi.json +6 -3
- package/translations/id.json +6 -3
- package/translations/it.json +6 -3
- package/translations/ja.json +6 -3
- package/translations/ko.json +6 -3
- package/translations/ms.json +6 -3
- package/translations/nl.json +6 -3
- package/translations/no.json +6 -3
- package/translations/pl.json +6 -3
- package/translations/pt.json +6 -3
- package/translations/ro.json +6 -3
- package/translations/sv.json +6 -3
- package/translations/th.json +6 -3
- package/translations/tr.json +6 -3
- package/translations/uk.json +6 -3
- package/translations/vi.json +6 -3
- package/translations/zh.json +6 -3
- package/dist/PdfAnnotationCanvas.client-ADC4FFSE.mjs.map +0 -1
- package/dist/TranslationManager-Co_5fSxl.d.mts +0 -118
- package/dist/ar-EMHEHPCJ.mjs.map +0 -1
- package/dist/bn-OVCI4F6X.mjs.map +0 -1
- package/dist/chunk-JZIO2A3B.mjs.map +0 -1
- package/dist/chunk-LIHZTECW.mjs.map +0 -1
- package/dist/cs-FAN66Q2F.mjs.map +0 -1
- package/dist/da-YBBIHI2O.mjs.map +0 -1
- package/dist/de-MAYU33LB.mjs.map +0 -1
- package/dist/el-MKGSWN4O.mjs.map +0 -1
- package/dist/es-52LHUWJD.mjs.map +0 -1
- package/dist/fa-FJICRANB.mjs.map +0 -1
- package/dist/fi-O455XFCR.mjs.map +0 -1
- package/dist/fr-TXIXHOOE.mjs.map +0 -1
- package/dist/he-JBSOX5IN.mjs.map +0 -1
- package/dist/hi-KGHI3XVT.mjs.map +0 -1
- package/dist/id-5OCPPZLO.mjs.map +0 -1
- package/dist/it-PNBBZSM2.mjs.map +0 -1
- package/dist/ja-LDD7R3TJ.mjs.map +0 -1
- package/dist/ko-F47ZDEY3.mjs.map +0 -1
- package/dist/ms-Z7LMXJWL.mjs.map +0 -1
- package/dist/nl-6SJFBPJ3.mjs.map +0 -1
- package/dist/no-YXPBPSGF.mjs.map +0 -1
- package/dist/pl-P4AZ2QME.mjs.map +0 -1
- package/dist/pt-LHWUS6U6.mjs.map +0 -1
- package/dist/ro-EA5J2ZON.mjs.map +0 -1
- package/dist/sv-DATBS3UQ.mjs.map +0 -1
- package/dist/th-WTFJRWPT.mjs.map +0 -1
- package/dist/tr-IKO3RXOX.mjs.map +0 -1
- package/dist/uk-CF6CTTRK.mjs.map +0 -1
- package/dist/vi-AJLTXPZQ.mjs.map +0 -1
- package/dist/zh-U3ORHHYH.mjs.map +0 -1
- /package/dist/{en-DDLIXJCU.mjs.map → en-KJCJQ4OO.mjs.map} +0 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import mitt from 'mitt';
|
|
4
|
+
import { ResourceEvent } from '@semiont/core';
|
|
5
|
+
import { GenerationProgress as GenerationProgress$1, Selector, components, ResourceUri, GenerationContext } from '@semiont/api-client';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Open Resources Manager Interface
|
|
9
|
+
*
|
|
10
|
+
* Manages a list of open resources (documents/files) with persistence.
|
|
11
|
+
* This interface allows apps to provide their own implementation of resource management
|
|
12
|
+
* (localStorage, sessionStorage, database, etc.) while components remain framework-agnostic.
|
|
13
|
+
*
|
|
14
|
+
* Components accept this manager as a prop instead of consuming from Context.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* // In app (e.g., frontend/src/hooks/useOpenResourcesManager.ts)
|
|
19
|
+
* export function useOpenResourcesManager(): OpenResourcesManager {
|
|
20
|
+
* const [openResources, setOpenResources] = useState<OpenResource[]>([]);
|
|
21
|
+
*
|
|
22
|
+
* // Implementation details...
|
|
23
|
+
*
|
|
24
|
+
* return {
|
|
25
|
+
* openResources,
|
|
26
|
+
* addResource,
|
|
27
|
+
* removeResource,
|
|
28
|
+
* updateResourceName,
|
|
29
|
+
* reorderResources
|
|
30
|
+
* };
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* // Pass to components as props
|
|
34
|
+
* <KnowledgeNavigation openResourcesManager={openResourcesManager} />
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
interface OpenResource {
|
|
38
|
+
/** Unique identifier for the resource */
|
|
39
|
+
id: string;
|
|
40
|
+
/** Display name of the resource */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Timestamp when the resource was opened */
|
|
43
|
+
openedAt: number;
|
|
44
|
+
/** Order/position for manual sorting (optional for backward compatibility) */
|
|
45
|
+
order?: number;
|
|
46
|
+
/** Media type for icon display (e.g., 'application/pdf', 'text/plain') */
|
|
47
|
+
mediaType?: string;
|
|
48
|
+
}
|
|
49
|
+
interface OpenResourcesManager {
|
|
50
|
+
/** List of currently open resources */
|
|
51
|
+
openResources: OpenResource[];
|
|
52
|
+
/**
|
|
53
|
+
* Add a new resource to the open list or update if already exists
|
|
54
|
+
* @param id - Unique resource identifier
|
|
55
|
+
* @param name - Display name of the resource
|
|
56
|
+
* @param mediaType - Optional media type for icon display
|
|
57
|
+
*/
|
|
58
|
+
addResource: (id: string, name: string, mediaType?: string) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Remove a resource from the open list
|
|
61
|
+
* @param id - Resource identifier to remove
|
|
62
|
+
*/
|
|
63
|
+
removeResource: (id: string) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Update the display name of an open resource
|
|
66
|
+
* @param id - Resource identifier
|
|
67
|
+
* @param name - New display name
|
|
68
|
+
*/
|
|
69
|
+
updateResourceName: (id: string, name: string) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Reorder resources by moving from one index to another
|
|
72
|
+
* @param oldIndex - Current position index
|
|
73
|
+
* @param newIndex - Desired position index
|
|
74
|
+
*/
|
|
75
|
+
reorderResources: (oldIndex: number, newIndex: number) => void;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Session management interface for handling authentication state and session expiry
|
|
80
|
+
* Apps implement this interface and pass it to SessionProvider
|
|
81
|
+
*/
|
|
82
|
+
interface SessionState {
|
|
83
|
+
/** Whether the user is currently authenticated */
|
|
84
|
+
isAuthenticated: boolean;
|
|
85
|
+
/** When the session expires (null if not authenticated) */
|
|
86
|
+
expiresAt: Date | null;
|
|
87
|
+
/** Time in milliseconds until session expires (null if not authenticated) */
|
|
88
|
+
timeUntilExpiry: number | null;
|
|
89
|
+
/** Whether the session is expiring soon (< 5 minutes) */
|
|
90
|
+
isExpiringSoon: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface SessionManager extends SessionState {
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Translation management interface
|
|
97
|
+
* Apps implement this to provide translations using their preferred i18n library
|
|
98
|
+
*/
|
|
99
|
+
interface TranslationManager {
|
|
100
|
+
/**
|
|
101
|
+
* Translate a key within a namespace
|
|
102
|
+
* @param namespace - Translation namespace (e.g., 'Toolbar', 'ResourceViewer')
|
|
103
|
+
* @param key - Translation key within the namespace
|
|
104
|
+
* @param params - Optional parameters for interpolation
|
|
105
|
+
* @returns Translated string
|
|
106
|
+
*/
|
|
107
|
+
t: (namespace: string, key: string, params?: Record<string, any>) => string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Progress type definitions for detection and generation flows
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Common detection progress fields shared across all motivation types.
|
|
116
|
+
*
|
|
117
|
+
* The five motivations have different SSE progress shapes
|
|
118
|
+
* (ReferenceDetectionProgress uses entity-type steps; the others use percentage).
|
|
119
|
+
* This local type captures the subset of fields used by the detection UI
|
|
120
|
+
* (DetectionProgressWidget, useDetectionFlow).
|
|
121
|
+
*/
|
|
122
|
+
interface DetectionProgress {
|
|
123
|
+
status: string;
|
|
124
|
+
message?: string;
|
|
125
|
+
/** Reference detection: currently scanning entity type */
|
|
126
|
+
currentEntityType?: string;
|
|
127
|
+
/** Reference detection: completed entity types with counts (frontend-only) */
|
|
128
|
+
completedEntityTypes?: Array<{
|
|
129
|
+
entityType: string;
|
|
130
|
+
foundCount: number;
|
|
131
|
+
}>;
|
|
132
|
+
/** Percentage-based motivations (highlight, assessment, comment, tag) */
|
|
133
|
+
percentage?: number;
|
|
134
|
+
/** Category-based motivations (tag) */
|
|
135
|
+
currentCategory?: string;
|
|
136
|
+
processedCategories?: number;
|
|
137
|
+
totalCategories?: number;
|
|
138
|
+
/** Request parameters for display in progress UI (frontend-only, added by annotation-registry) */
|
|
139
|
+
requestParams?: Array<{
|
|
140
|
+
label: string;
|
|
141
|
+
value: string;
|
|
142
|
+
}>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Generation progress type (no extensions needed, re-export API type)
|
|
146
|
+
*/
|
|
147
|
+
type GenerationProgress = GenerationProgress$1;
|
|
148
|
+
|
|
149
|
+
type Annotation = components['schemas']['Annotation'];
|
|
150
|
+
type Motivation = components['schemas']['Motivation'];
|
|
151
|
+
interface SelectionData {
|
|
152
|
+
exact: string;
|
|
153
|
+
start: number;
|
|
154
|
+
end: number;
|
|
155
|
+
svgSelector?: string;
|
|
156
|
+
fragmentSelector?: string;
|
|
157
|
+
conformsTo?: string;
|
|
158
|
+
prefix?: string;
|
|
159
|
+
suffix?: string;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Unified event map for all application events
|
|
163
|
+
*
|
|
164
|
+
* Consolidates events from:
|
|
165
|
+
* - MakeMeaningEventBus (document/annotation operations)
|
|
166
|
+
* - NavigationEventBus (navigation and sidebar UI)
|
|
167
|
+
* - GlobalSettingsEventBus (app-wide settings)
|
|
168
|
+
*/
|
|
169
|
+
type EventMap = {
|
|
170
|
+
'make-meaning:event': ResourceEvent;
|
|
171
|
+
'detection:started': Extract<ResourceEvent, {
|
|
172
|
+
type: 'job.started';
|
|
173
|
+
}>;
|
|
174
|
+
'detection:entity-found': Extract<ResourceEvent, {
|
|
175
|
+
type: 'annotation.added';
|
|
176
|
+
}>;
|
|
177
|
+
'detection:completed': Extract<ResourceEvent, {
|
|
178
|
+
type: 'job.completed';
|
|
179
|
+
}>;
|
|
180
|
+
'detection:failed': Extract<ResourceEvent, {
|
|
181
|
+
type: 'job.failed';
|
|
182
|
+
}>;
|
|
183
|
+
'detection:progress': DetectionProgress;
|
|
184
|
+
'annotation:added': Extract<ResourceEvent, {
|
|
185
|
+
type: 'annotation.added';
|
|
186
|
+
}>;
|
|
187
|
+
'annotation:removed': Extract<ResourceEvent, {
|
|
188
|
+
type: 'annotation.removed';
|
|
189
|
+
}>;
|
|
190
|
+
'annotation:updated': Extract<ResourceEvent, {
|
|
191
|
+
type: 'annotation.body.updated';
|
|
192
|
+
}>;
|
|
193
|
+
'entity-tag:added': Extract<ResourceEvent, {
|
|
194
|
+
type: 'entitytag.added';
|
|
195
|
+
}>;
|
|
196
|
+
'entity-tag:removed': Extract<ResourceEvent, {
|
|
197
|
+
type: 'entitytag.removed';
|
|
198
|
+
}>;
|
|
199
|
+
'resource:archived': Extract<ResourceEvent, {
|
|
200
|
+
type: 'resource.archived';
|
|
201
|
+
}>;
|
|
202
|
+
'resource:unarchived': Extract<ResourceEvent, {
|
|
203
|
+
type: 'resource.unarchived';
|
|
204
|
+
}>;
|
|
205
|
+
'selection:comment-requested': SelectionData;
|
|
206
|
+
'selection:tag-requested': SelectionData;
|
|
207
|
+
'selection:assessment-requested': SelectionData;
|
|
208
|
+
'selection:reference-requested': SelectionData;
|
|
209
|
+
'annotation:requested': {
|
|
210
|
+
selector: Selector | Selector[];
|
|
211
|
+
motivation: Motivation;
|
|
212
|
+
};
|
|
213
|
+
'annotation:cancel-pending': void;
|
|
214
|
+
'annotation:hover': {
|
|
215
|
+
annotationId: string | null;
|
|
216
|
+
};
|
|
217
|
+
'annotation:click': {
|
|
218
|
+
annotationId: string;
|
|
219
|
+
motivation: Motivation;
|
|
220
|
+
};
|
|
221
|
+
'annotation:focus': {
|
|
222
|
+
annotationId: string | null;
|
|
223
|
+
};
|
|
224
|
+
'annotation:sparkle': {
|
|
225
|
+
annotationId: string;
|
|
226
|
+
};
|
|
227
|
+
'panel:toggle': {
|
|
228
|
+
panel: string;
|
|
229
|
+
};
|
|
230
|
+
'panel:open': {
|
|
231
|
+
panel: string;
|
|
232
|
+
scrollToAnnotationId?: string;
|
|
233
|
+
motivation?: string;
|
|
234
|
+
};
|
|
235
|
+
'panel:close': void;
|
|
236
|
+
'view:mode-toggled': void;
|
|
237
|
+
'toolbar:selection-changed': {
|
|
238
|
+
motivation: string | null;
|
|
239
|
+
};
|
|
240
|
+
'toolbar:click-changed': {
|
|
241
|
+
action: string;
|
|
242
|
+
};
|
|
243
|
+
'toolbar:shape-changed': {
|
|
244
|
+
shape: string;
|
|
245
|
+
};
|
|
246
|
+
'navigation:sidebar-toggle': void;
|
|
247
|
+
'navigation:resource-close': {
|
|
248
|
+
resourceId: string;
|
|
249
|
+
};
|
|
250
|
+
'navigation:resource-reorder': {
|
|
251
|
+
oldIndex: number;
|
|
252
|
+
newIndex: number;
|
|
253
|
+
};
|
|
254
|
+
'navigation:link-clicked': {
|
|
255
|
+
href: string;
|
|
256
|
+
label?: string;
|
|
257
|
+
};
|
|
258
|
+
'navigation:router-push': {
|
|
259
|
+
path: string;
|
|
260
|
+
reason?: string;
|
|
261
|
+
};
|
|
262
|
+
'navigation:external-navigate': {
|
|
263
|
+
url: string;
|
|
264
|
+
resourceId?: string;
|
|
265
|
+
cancelFallback: () => void;
|
|
266
|
+
};
|
|
267
|
+
'navigation:reference-navigate': {
|
|
268
|
+
documentId: string;
|
|
269
|
+
};
|
|
270
|
+
'navigation:entity-type-clicked': {
|
|
271
|
+
entityType: string;
|
|
272
|
+
};
|
|
273
|
+
'settings:theme-changed': {
|
|
274
|
+
theme: 'light' | 'dark' | 'system';
|
|
275
|
+
};
|
|
276
|
+
'settings:line-numbers-toggled': void;
|
|
277
|
+
'settings:locale-changed': {
|
|
278
|
+
locale: string;
|
|
279
|
+
};
|
|
280
|
+
'resource:archive': void;
|
|
281
|
+
'resource:unarchive': void;
|
|
282
|
+
'resource:clone': void;
|
|
283
|
+
'job:cancel-requested': {
|
|
284
|
+
jobType: 'detection' | 'generation';
|
|
285
|
+
};
|
|
286
|
+
'annotation:create': {
|
|
287
|
+
motivation: Motivation;
|
|
288
|
+
selector: Selector | Selector[];
|
|
289
|
+
body: components['schemas']['AnnotationBody'][];
|
|
290
|
+
};
|
|
291
|
+
'annotation:created': {
|
|
292
|
+
annotation: Annotation;
|
|
293
|
+
};
|
|
294
|
+
'annotation:create-failed': {
|
|
295
|
+
error: Error;
|
|
296
|
+
};
|
|
297
|
+
'annotation:delete': {
|
|
298
|
+
annotationId: string;
|
|
299
|
+
};
|
|
300
|
+
'annotation:deleted': {
|
|
301
|
+
annotationId: string;
|
|
302
|
+
};
|
|
303
|
+
'annotation:delete-failed': {
|
|
304
|
+
error: Error;
|
|
305
|
+
};
|
|
306
|
+
'annotation:update-body': {
|
|
307
|
+
annotationUri: string;
|
|
308
|
+
resourceId: string;
|
|
309
|
+
operations: Array<{
|
|
310
|
+
op: 'add' | 'remove' | 'replace';
|
|
311
|
+
item?: components['schemas']['AnnotationBody'];
|
|
312
|
+
oldItem?: components['schemas']['AnnotationBody'];
|
|
313
|
+
newItem?: components['schemas']['AnnotationBody'];
|
|
314
|
+
}>;
|
|
315
|
+
};
|
|
316
|
+
'annotation:body-updated': {
|
|
317
|
+
annotationUri: string;
|
|
318
|
+
};
|
|
319
|
+
'annotation:body-update-failed': {
|
|
320
|
+
error: Error;
|
|
321
|
+
};
|
|
322
|
+
'detection:start': {
|
|
323
|
+
motivation: Motivation;
|
|
324
|
+
options: {
|
|
325
|
+
instructions?: string;
|
|
326
|
+
/** Comment tone */
|
|
327
|
+
tone?: 'scholarly' | 'explanatory' | 'conversational' | 'technical' | 'analytical' | 'critical' | 'balanced' | 'constructive';
|
|
328
|
+
density?: number;
|
|
329
|
+
entityTypes?: string[];
|
|
330
|
+
includeDescriptiveReferences?: boolean;
|
|
331
|
+
schemaId?: string;
|
|
332
|
+
categories?: string[];
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
'detection:complete': {
|
|
336
|
+
motivation?: Motivation;
|
|
337
|
+
resourceUri?: ResourceUri;
|
|
338
|
+
progress?: DetectionProgress;
|
|
339
|
+
};
|
|
340
|
+
'detection:cancelled': void;
|
|
341
|
+
'detection:dismiss-progress': void;
|
|
342
|
+
'generation:start': {
|
|
343
|
+
annotationUri: string;
|
|
344
|
+
resourceUri: string;
|
|
345
|
+
options: {
|
|
346
|
+
title: string;
|
|
347
|
+
prompt?: string;
|
|
348
|
+
language?: string;
|
|
349
|
+
temperature?: number;
|
|
350
|
+
maxTokens?: number;
|
|
351
|
+
context: GenerationContext;
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
'generation:progress': GenerationProgress;
|
|
355
|
+
'generation:complete': {
|
|
356
|
+
annotationUri: string;
|
|
357
|
+
progress: GenerationProgress;
|
|
358
|
+
};
|
|
359
|
+
'generation:failed': {
|
|
360
|
+
error: Error;
|
|
361
|
+
};
|
|
362
|
+
'generation:modal-open': {
|
|
363
|
+
annotationUri: string;
|
|
364
|
+
resourceUri: string;
|
|
365
|
+
defaultTitle: string;
|
|
366
|
+
};
|
|
367
|
+
'reference:create-manual': {
|
|
368
|
+
annotationUri: string;
|
|
369
|
+
title: string;
|
|
370
|
+
entityTypes: string[];
|
|
371
|
+
};
|
|
372
|
+
'reference:link': {
|
|
373
|
+
annotationUri: string;
|
|
374
|
+
searchTerm: string;
|
|
375
|
+
};
|
|
376
|
+
'resolution:search-requested': {
|
|
377
|
+
referenceId: string;
|
|
378
|
+
searchTerm: string;
|
|
379
|
+
};
|
|
380
|
+
'context:retrieval-requested': {
|
|
381
|
+
annotationUri: string;
|
|
382
|
+
resourceUri: string;
|
|
383
|
+
};
|
|
384
|
+
'context:retrieval-complete': {
|
|
385
|
+
annotationUri: string;
|
|
386
|
+
context: GenerationContext;
|
|
387
|
+
};
|
|
388
|
+
'context:retrieval-failed': {
|
|
389
|
+
annotationUri: string;
|
|
390
|
+
error: Error;
|
|
391
|
+
};
|
|
392
|
+
};
|
|
393
|
+
type EventBus = ReturnType<typeof mitt<EventMap>> & {
|
|
394
|
+
busId: string;
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* Reset the global event bus - FOR TESTING ONLY.
|
|
398
|
+
*
|
|
399
|
+
* Call this in test setup (beforeEach) to ensure test isolation.
|
|
400
|
+
* Each test gets a fresh event bus with no lingering subscriptions.
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* beforeEach(() => {
|
|
405
|
+
* resetEventBusForTesting();
|
|
406
|
+
* });
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
declare function resetEventBusForTesting(): void;
|
|
410
|
+
interface EventBusProviderProps {
|
|
411
|
+
children: ReactNode;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Unified event bus provider for all application events
|
|
415
|
+
*
|
|
416
|
+
* Consolidates three previous event buses:
|
|
417
|
+
* - MakeMeaningEventBus (document/annotation operations)
|
|
418
|
+
* - NavigationEventBus (navigation and sidebar UI)
|
|
419
|
+
* - GlobalSettingsEventBus (app-wide settings)
|
|
420
|
+
*
|
|
421
|
+
* Benefits:
|
|
422
|
+
* - Single import: useEventBus()
|
|
423
|
+
* - No decision fatigue about which bus to use
|
|
424
|
+
* - Easier cross-domain coordination
|
|
425
|
+
* - Simpler provider hierarchy
|
|
426
|
+
*
|
|
427
|
+
* NOTE: This provider uses a global singleton event bus to ensure all components
|
|
428
|
+
* share the same instance. Multiple providers in the tree will all reference the
|
|
429
|
+
* same global bus.
|
|
430
|
+
*
|
|
431
|
+
* Operation handlers (API calls triggered by events) are set up separately via
|
|
432
|
+
* the useResolutionFlow hook, which should be called at the resource page level.
|
|
433
|
+
*/
|
|
434
|
+
declare function EventBusProvider({ children, }: EventBusProviderProps): react_jsx_runtime.JSX.Element;
|
|
435
|
+
/**
|
|
436
|
+
* Hook to access the unified event bus
|
|
437
|
+
*
|
|
438
|
+
* Use this everywhere instead of:
|
|
439
|
+
* - useMakeMeaningEvents()
|
|
440
|
+
* - useNavigationEvents()
|
|
441
|
+
* - useGlobalSettingsEvents()
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* const eventBus = useEventBus();
|
|
446
|
+
*
|
|
447
|
+
* // Emit any event
|
|
448
|
+
* eventBus.emit('annotation:hover', { annotationId: '123' });
|
|
449
|
+
* eventBus.emit('navigation:sidebar-toggle', undefined);
|
|
450
|
+
* eventBus.emit('settings:theme-changed', { theme: 'dark' });
|
|
451
|
+
*
|
|
452
|
+
* // Subscribe to any event
|
|
453
|
+
* useEffect(() => {
|
|
454
|
+
* const handler = ({ annotationId }) => console.log(annotationId);
|
|
455
|
+
* eventBus.on('annotation:hover', handler);
|
|
456
|
+
* return () => eventBus.off('annotation:hover', handler);
|
|
457
|
+
* }, []);
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
declare function useEventBus(): EventBus;
|
|
461
|
+
|
|
462
|
+
export { type DetectionProgress as D, type EventBus as E, type GenerationProgress as G, type OpenResourcesManager as O, type SessionManager as S, type TranslationManager as T, type EventMap as a, type OpenResource as b, type SessionState as c, type EventBusProviderProps as d, EventBusProvider as e, resetEventBusForTesting as r, useEventBus as u };
|
package/dist/{PdfAnnotationCanvas.client-ADC4FFSE.mjs → PdfAnnotationCanvas.client-RAJRPQLU.mjs}
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import "./chunk-3JTO27MH.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/pdf-annotation/PdfAnnotationCanvas.tsx
|
|
6
|
-
import { useRef, useState, useCallback, useEffect } from "react";
|
|
6
|
+
import { useRef, useState, useCallback, useEffect, useMemo } from "react";
|
|
7
7
|
import { getTargetSelector } from "@semiont/api-client";
|
|
8
8
|
|
|
9
9
|
// src/lib/pdf-coordinates.ts
|
|
@@ -151,14 +151,14 @@ function PdfAnnotationCanvas({
|
|
|
151
151
|
existingAnnotations = [],
|
|
152
152
|
drawingMode,
|
|
153
153
|
selectedMotivation,
|
|
154
|
-
|
|
155
|
-
onAnnotationClick,
|
|
156
|
-
onAnnotationHover,
|
|
154
|
+
eventBus,
|
|
157
155
|
hoveredAnnotationId,
|
|
158
156
|
selectedAnnotationId
|
|
159
157
|
}) {
|
|
160
|
-
const
|
|
161
|
-
|
|
158
|
+
const pdfUrl = useMemo(() => {
|
|
159
|
+
const resourceId = resourceUri.split("/").pop();
|
|
160
|
+
return `/api/resources/${resourceId}`;
|
|
161
|
+
}, [resourceUri]);
|
|
162
162
|
const [pdfDoc, setPdfDoc] = useState(null);
|
|
163
163
|
const [numPages, setNumPages] = useState(0);
|
|
164
164
|
const [pageNumber, setPageNumber] = useState(1);
|
|
@@ -172,6 +172,7 @@ function PdfAnnotationCanvas({
|
|
|
172
172
|
const [selection, setSelection] = useState(null);
|
|
173
173
|
const containerRef = useRef(null);
|
|
174
174
|
const imageRef = useRef(null);
|
|
175
|
+
const currentHover = useRef(null);
|
|
175
176
|
useEffect(() => {
|
|
176
177
|
let cancelled = false;
|
|
177
178
|
async function loadPdf() {
|
|
@@ -274,7 +275,7 @@ function PdfAnnotationCanvas({
|
|
|
274
275
|
});
|
|
275
276
|
}, [isDrawing, selection]);
|
|
276
277
|
const handleMouseUp = useCallback(() => {
|
|
277
|
-
if (!isDrawing || !selection || !pageDimensions || !displayDimensions || !
|
|
278
|
+
if (!isDrawing || !selection || !pageDimensions || !displayDimensions || !eventBus) {
|
|
278
279
|
setIsDrawing(false);
|
|
279
280
|
setSelection(null);
|
|
280
281
|
return;
|
|
@@ -284,23 +285,23 @@ function PdfAnnotationCanvas({
|
|
|
284
285
|
);
|
|
285
286
|
const MIN_DRAG_DISTANCE = 10;
|
|
286
287
|
if (dragDistance < MIN_DRAG_DISTANCE) {
|
|
287
|
-
if (
|
|
288
|
+
if (existingAnnotations.length > 0) {
|
|
288
289
|
const clickedAnnotation = pageAnnotations.find((ann) => {
|
|
289
290
|
const fragmentSel = getFragmentSelector(ann.target);
|
|
290
291
|
if (!fragmentSel) return false;
|
|
291
292
|
const pdfCoord2 = parseFragmentSelector(fragmentSel.value);
|
|
292
293
|
if (!pdfCoord2) return false;
|
|
293
|
-
const
|
|
294
|
+
const rect = pdfToCanvasCoordinates(pdfCoord2, pageDimensions.height, 1);
|
|
294
295
|
const scaleX2 = displayDimensions.width / pageDimensions.width;
|
|
295
296
|
const scaleY2 = displayDimensions.height / pageDimensions.height;
|
|
296
|
-
const displayX =
|
|
297
|
-
const displayY =
|
|
298
|
-
const displayWidth =
|
|
299
|
-
const displayHeight =
|
|
297
|
+
const displayX = rect.x * scaleX2;
|
|
298
|
+
const displayY = rect.y * scaleY2;
|
|
299
|
+
const displayWidth = rect.width * scaleX2;
|
|
300
|
+
const displayHeight = rect.height * scaleY2;
|
|
300
301
|
return selection.endX >= displayX && selection.endX <= displayX + displayWidth && selection.endY >= displayY && selection.endY <= displayY + displayHeight;
|
|
301
302
|
});
|
|
302
303
|
if (clickedAnnotation) {
|
|
303
|
-
|
|
304
|
+
eventBus?.emit("annotation:click", { annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
|
|
304
305
|
setIsDrawing(false);
|
|
305
306
|
setSelection(null);
|
|
306
307
|
return;
|
|
@@ -327,16 +328,18 @@ function PdfAnnotationCanvas({
|
|
|
327
328
|
// Use scale 1.0 since we already scaled to native coords
|
|
328
329
|
);
|
|
329
330
|
const fragmentSelector = createFragmentSelector(pdfCoord);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
331
|
+
if (selectedMotivation) {
|
|
332
|
+
eventBus.emit("annotation:requested", {
|
|
333
|
+
selector: {
|
|
334
|
+
type: "FragmentSelector",
|
|
335
|
+
conformsTo: "http://tools.ietf.org/rfc/rfc3778",
|
|
336
|
+
value: fragmentSelector
|
|
337
|
+
},
|
|
338
|
+
motivation: selectedMotivation
|
|
339
|
+
});
|
|
340
|
+
}
|
|
338
341
|
setIsDrawing(false);
|
|
339
|
-
}, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions,
|
|
342
|
+
}, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions, selectedMotivation, existingAnnotations]);
|
|
340
343
|
const getFragmentSelector = (target) => {
|
|
341
344
|
const selector = getTargetSelector(target);
|
|
342
345
|
if (!selector) return null;
|
|
@@ -351,6 +354,18 @@ function PdfAnnotationCanvas({
|
|
|
351
354
|
const page = getPageFromFragment(fragmentSel.value);
|
|
352
355
|
return page === pageNumber;
|
|
353
356
|
});
|
|
357
|
+
const handleMouseEnter = (annotationId) => {
|
|
358
|
+
if (currentHover.current !== annotationId) {
|
|
359
|
+
currentHover.current = annotationId;
|
|
360
|
+
eventBus?.emit("annotation:hover", { annotationId });
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
const handleMouseLeave = () => {
|
|
364
|
+
if (currentHover.current !== null) {
|
|
365
|
+
currentHover.current = null;
|
|
366
|
+
eventBus?.emit("annotation:hover", { annotationId: null });
|
|
367
|
+
}
|
|
368
|
+
};
|
|
354
369
|
const { stroke, fill } = getMotivationColor(selectedMotivation ?? null);
|
|
355
370
|
if (error) {
|
|
356
371
|
return /* @__PURE__ */ jsx("div", { className: "semiont-pdf-annotation-canvas__error", children: error });
|
|
@@ -431,9 +446,9 @@ function PdfAnnotationCanvas({
|
|
|
431
446
|
cursor: "pointer",
|
|
432
447
|
opacity: isSelected ? 1 : isHovered ? 0.9 : 0.7
|
|
433
448
|
},
|
|
434
|
-
onClick: () =>
|
|
435
|
-
onMouseEnter: () =>
|
|
436
|
-
onMouseLeave:
|
|
449
|
+
onClick: () => eventBus?.emit("annotation:click", { annotationId: ann.id, motivation: ann.motivation }),
|
|
450
|
+
onMouseEnter: () => handleMouseEnter(ann.id),
|
|
451
|
+
onMouseLeave: handleMouseLeave
|
|
437
452
|
},
|
|
438
453
|
ann.id
|
|
439
454
|
);
|
|
@@ -495,4 +510,4 @@ function PdfAnnotationCanvas({
|
|
|
495
510
|
export {
|
|
496
511
|
PdfAnnotationCanvas
|
|
497
512
|
};
|
|
498
|
-
//# sourceMappingURL=PdfAnnotationCanvas.client-
|
|
513
|
+
//# sourceMappingURL=PdfAnnotationCanvas.client-RAJRPQLU.mjs.map
|