@semiont/react-ui 0.4.20 → 0.4.22

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.
Files changed (125) hide show
  1. package/README.md +8 -5
  2. package/dist/{PdfAnnotationCanvas.client-CHDCGQBR.mjs → PdfAnnotationCanvas.client-5QESNO5H.mjs} +13 -16
  3. package/dist/PdfAnnotationCanvas.client-5QESNO5H.mjs.map +1 -0
  4. package/dist/TranslationManager-9Xj3MIWQ.d.mts +16 -0
  5. package/dist/chunk-4NOUO3W6.mjs +7788 -0
  6. package/dist/chunk-4NOUO3W6.mjs.map +1 -0
  7. package/dist/index.d.mts +212 -1206
  8. package/dist/index.mjs +3332 -13712
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/test-utils.d.mts +48 -21
  11. package/dist/test-utils.mjs +2505 -87
  12. package/dist/test-utils.mjs.map +1 -1
  13. package/package.json +2 -2
  14. package/src/components/AnnotateReferencesProgressWidget.tsx +21 -28
  15. package/src/components/CodeMirrorRenderer.tsx +12 -12
  16. package/src/components/LiveRegion.tsx +1 -2
  17. package/src/components/StatusDisplay.tsx +42 -16
  18. package/src/components/Toolbar.tsx +4 -4
  19. package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +34 -20
  20. package/src/components/__tests__/StatusDisplay.test.tsx +50 -65
  21. package/src/components/__tests__/Toolbar.test.tsx +4 -4
  22. package/src/components/annotation/AnnotateToolbar.tsx +8 -9
  23. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +31 -77
  24. package/src/components/annotation-popups/JsonLdView.tsx +1 -2
  25. package/src/components/annotation-popups/__tests__/JsonLdView.test.tsx +1 -2
  26. package/src/components/image-annotation/AnnotationOverlay.tsx +15 -18
  27. package/src/components/image-annotation/SvgDrawingCanvas.tsx +12 -17
  28. package/src/components/modals/ConfigureGenerationStep.tsx +1 -2
  29. package/src/components/modals/PermissionDeniedModal.tsx +11 -11
  30. package/src/components/modals/ReferenceWizardModal.tsx +14 -18
  31. package/src/components/modals/ResourceSearchModal.tsx +12 -8
  32. package/src/components/modals/SearchModal.tsx +11 -6
  33. package/src/components/modals/SearchResultsStep.tsx +1 -3
  34. package/src/components/modals/SessionExpiredModal.tsx +11 -11
  35. package/src/components/modals/__tests__/PermissionDeniedModal.test.tsx +7 -7
  36. package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +10 -8
  37. package/src/components/modals/__tests__/SearchModal.accessibility.test.tsx +6 -2
  38. package/src/components/modals/__tests__/SearchModal.basic.test.tsx +6 -2
  39. package/src/components/modals/__tests__/SearchModal.keyboard.test.tsx +6 -2
  40. package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +10 -7
  41. package/src/components/modals/__tests__/SearchModal.visual.test.tsx +6 -2
  42. package/src/components/modals/__tests__/SessionExpiredModal.test.tsx +5 -5
  43. package/src/components/navigation/CollapsibleResourceNavigation.tsx +10 -10
  44. package/src/components/navigation/ObservableLink.tsx +6 -6
  45. package/src/components/navigation/SimpleNavigation.tsx +4 -4
  46. package/src/components/navigation/__tests__/ObservableLink.test.tsx +4 -4
  47. package/src/components/navigation/__tests__/SimpleNavigation.test.tsx +4 -4
  48. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +15 -18
  49. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +1 -2
  50. package/src/components/resource/AnnotateView.tsx +8 -10
  51. package/src/components/resource/AnnotationHistory.tsx +9 -12
  52. package/src/components/resource/BrowseView.tsx +11 -8
  53. package/src/components/resource/ResourceViewer.tsx +22 -34
  54. package/src/components/resource/__tests__/AnnotationHistory.test.tsx +54 -192
  55. package/src/components/resource/__tests__/BrowseView.test.tsx +38 -87
  56. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +41 -31
  57. package/src/components/resource/__tests__/event-formatting.test.ts +6 -2
  58. package/src/components/resource/event-formatting.ts +2 -3
  59. package/src/components/resource/panels/AssessmentEntry.tsx +7 -8
  60. package/src/components/resource/panels/AssessmentPanel.tsx +21 -17
  61. package/src/components/resource/panels/AssistSection.tsx +15 -21
  62. package/src/components/resource/panels/CollaborationPanel.tsx +29 -7
  63. package/src/components/resource/panels/CommentEntry.tsx +7 -8
  64. package/src/components/resource/panels/CommentsPanel.tsx +11 -13
  65. package/src/components/resource/panels/HighlightEntry.tsx +7 -8
  66. package/src/components/resource/panels/HighlightPanel.tsx +12 -13
  67. package/src/components/resource/panels/ReferenceEntry.tsx +13 -15
  68. package/src/components/resource/panels/ReferencesPanel.tsx +17 -19
  69. package/src/components/resource/panels/ResourceInfoPanel.tsx +8 -7
  70. package/src/components/resource/panels/StatisticsPanel.tsx +2 -3
  71. package/src/components/resource/panels/TagEntry.tsx +7 -8
  72. package/src/components/resource/panels/TaggingPanel.tsx +14 -23
  73. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +4 -3
  74. package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +4 -4
  75. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +22 -57
  76. package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +51 -20
  77. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +4 -4
  78. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +22 -61
  79. package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +4 -4
  80. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +1 -2
  81. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +7 -8
  82. package/src/components/resource/panels/__tests__/ReferencesPanel.observable-flow.test.tsx +153 -0
  83. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +51 -106
  84. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +28 -53
  85. package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +3 -3
  86. package/src/components/resource/panels/__tests__/TagEntry.test.tsx +4 -4
  87. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +19 -52
  88. package/src/components/settings/SettingsPanel.tsx +9 -9
  89. package/src/components/settings/__tests__/SettingsPanel.test.tsx +15 -15
  90. package/src/features/admin-devops/components/AdminDevOpsPage.tsx +1 -2
  91. package/src/features/admin-exchange/components/AdminExchangePage.tsx +1 -1
  92. package/src/features/admin-exchange/components/ImportCard.tsx +2 -7
  93. package/src/features/admin-security/components/AdminSecurityPage.tsx +1 -2
  94. package/src/features/admin-users/components/AdminUsersPage.tsx +1 -1
  95. package/src/features/moderate-entity-tags/components/EntityTagsPage.tsx +1 -2
  96. package/src/features/moderate-recent/components/RecentDocumentsPage.tsx +1 -2
  97. package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -1
  98. package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +1 -1
  99. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +5 -3
  100. package/src/features/resource-compose/components/ResourceComposePage.tsx +6 -22
  101. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +4 -3
  102. package/src/features/resource-discovery/components/ResourceCard.tsx +1 -2
  103. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +3 -4
  104. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +37 -45
  105. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +129 -197
  106. package/dist/KnowledgeBaseSessionContext-BNNunwzO.d.mts +0 -175
  107. package/dist/PdfAnnotationCanvas.client-CHDCGQBR.mjs.map +0 -1
  108. package/dist/chunk-OZICDVH7.mjs +0 -62
  109. package/dist/chunk-OZICDVH7.mjs.map +0 -1
  110. package/dist/chunk-R4CCMFJH.mjs +0 -877
  111. package/dist/chunk-R4CCMFJH.mjs.map +0 -1
  112. package/dist/chunk-VN5NY4SN.mjs +0 -200
  113. package/dist/chunk-VN5NY4SN.mjs.map +0 -1
  114. package/src/components/modals/ProposeEntitiesModal.tsx +0 -179
  115. package/src/components/modals/__tests__/ProposeEntitiesModal.test.tsx +0 -129
  116. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +0 -323
  117. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +0 -245
  118. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +0 -303
  119. package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +0 -150
  120. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +0 -243
  121. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +0 -383
  122. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +0 -299
  123. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +0 -186
  124. package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +0 -429
  125. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +0 -348
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/react-ui",
3
- "version": "0.4.20",
3
+ "version": "0.4.22",
4
4
  "description": "React components and hooks for Semiont",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",
@@ -73,7 +73,6 @@
73
73
  "test:split:coverage": "npm run test:coverage"
74
74
  },
75
75
  "peerDependencies": {
76
- "@tanstack/react-query": "^5.0.0",
77
76
  "react": "^18.0.0 || ^19.0.0",
78
77
  "react-dom": "^18.0.0 || ^19.0.0"
79
78
  },
@@ -105,6 +104,7 @@
105
104
  "dependencies": {
106
105
  "@semiont/api-client": "*",
107
106
  "@semiont/core": "*",
107
+ "@semiont/sdk": "*",
108
108
  "react-error-boundary": "^4.1.2"
109
109
  }
110
110
  }
@@ -1,19 +1,15 @@
1
1
  'use client';
2
2
 
3
3
  import { useTranslations } from '../contexts/TranslationContext';
4
- import { useEventBus } from '../contexts/EventBusContext';
5
- import type { MarkProgress } from '@semiont/core';
4
+ import { useSemiont } from '../session/SemiontProvider';
5
+ import { useObservable } from '../hooks/useObservable';
6
6
  import type { components } from '@semiont/core';
7
7
 
8
8
  type Motivation = components['schemas']['Motivation'];
9
-
10
- // Extended MarkProgress with optional request parameters
11
- interface EnrichedMarkProgress extends MarkProgress {
12
- requestParams?: Array<{ label: string; value: string }>;
13
- }
9
+ type JobProgress = components['schemas']['JobProgress'];
14
10
 
15
11
  interface AnnotateReferencesProgressWidgetProps {
16
- progress: MarkProgress | null;
12
+ progress: JobProgress | null;
17
13
  annotationType?: Motivation | 'reference';
18
14
  }
19
15
 
@@ -24,11 +20,11 @@ interface AnnotateReferencesProgressWidgetProps {
24
20
  */
25
21
  export function AnnotateReferencesProgressWidget({ progress, annotationType = 'reference' }: AnnotateReferencesProgressWidgetProps) {
26
22
  const t = useTranslations('ReferencesPanel');
27
- const eventBus = useEventBus();
23
+ const session = useObservable(useSemiont().activeSession$);
28
24
 
29
25
  const handleCancel = () => {
30
26
  // Emit event for job cancellation
31
- eventBus.get('job:cancel-requested').next({ jobType: 'annotation' });
27
+ session?.client.job.cancelRequest('annotation');
32
28
  };
33
29
 
34
30
  if (!progress) return null;
@@ -36,7 +32,7 @@ export function AnnotateReferencesProgressWidget({ progress, annotationType = 'r
36
32
  return (
37
33
  <div
38
34
  className="semiont-annotation-progress"
39
- data-status={progress.status}
35
+ data-status={progress.stage}
40
36
  data-type={annotationType}
41
37
  >
42
38
  {/* Header with pulsing sparkle */}
@@ -45,7 +41,7 @@ export function AnnotateReferencesProgressWidget({ progress, annotationType = 'r
45
41
  <span className="semiont-annotation-sparkle">✨</span>
46
42
  {t('annotationProgressTitle')}
47
43
  </h3>
48
- {progress.status !== 'complete' && (
44
+ {progress.stage !== 'complete' && (
49
45
  <button
50
46
  onClick={handleCancel}
51
47
  className="semiont-annotation-cancel"
@@ -57,19 +53,16 @@ export function AnnotateReferencesProgressWidget({ progress, annotationType = 'r
57
53
  </div>
58
54
 
59
55
  {/* Request Parameters */}
60
- {(() => {
61
- const enrichedProgress = progress as EnrichedMarkProgress;
62
- return enrichedProgress.requestParams && enrichedProgress.requestParams.length > 0 && (
63
- <div className="semiont-annotation-progress__params">
64
- <div className="semiont-annotation-progress__params-title">Request Parameters:</div>
65
- {enrichedProgress.requestParams.map((param, idx) => (
66
- <div key={idx} className="semiont-annotation-progress__param">
67
- <span className="semiont-annotation-progress__param-label">{param.label}:</span> {param.value}
68
- </div>
69
- ))}
70
- </div>
71
- );
72
- })()}
56
+ {progress.requestParams && progress.requestParams.length > 0 && (
57
+ <div className="semiont-annotation-progress__params">
58
+ <div className="semiont-annotation-progress__params-title">Request Parameters:</div>
59
+ {progress.requestParams.map((param, idx) => (
60
+ <div key={idx} className="semiont-annotation-progress__param">
61
+ <span className="semiont-annotation-progress__param-label">{param.label}:</span> {param.value}
62
+ </div>
63
+ ))}
64
+ </div>
65
+ )}
73
66
 
74
67
  {/* Completed entity types log */}
75
68
  {progress.completedEntityTypes && progress.completedEntityTypes.length > 0 && (
@@ -86,12 +79,12 @@ export function AnnotateReferencesProgressWidget({ progress, annotationType = 'r
86
79
 
87
80
  {/* Status display with pulsing animation */}
88
81
  <div className="semiont-annotation-progress__status">
89
- {progress.status === 'complete' ? (
82
+ {progress.stage === 'complete' ? (
90
83
  <div className="semiont-annotation-progress__message">
91
84
  <span className="semiont-annotation-progress__icon">✅</span>
92
85
  <span>{t('complete')}</span>
93
86
  </div>
94
- ) : progress.status === 'error' ? (
87
+ ) : progress.stage === 'error' ? (
95
88
  <div className="semiont-annotation-progress__message">
96
89
  <span className="semiont-annotation-progress__icon">❌</span>
97
90
  <span>{progress.message || t('failed')}</span>
@@ -102,7 +95,7 @@ export function AnnotateReferencesProgressWidget({ progress, annotationType = 'r
102
95
  <span>{progress.message || (progress.currentEntityType ? t('current', { entityType: progress.currentEntityType }) : t('annotating'))}</span>
103
96
  </div>
104
97
  )}
105
- {progress.currentEntityType && progress.status !== 'complete' && progress.status !== 'error' && (
98
+ {progress.currentEntityType && progress.stage !== 'complete' && progress.stage !== 'error' && (
106
99
  <div className="semiont-annotation-progress__details">
107
100
  Processing: {progress.currentEntityType}
108
101
  </div>
@@ -6,9 +6,9 @@ import { EditorState, RangeSetBuilder, StateField, StateEffect, Compartment } fr
6
6
  import { markdown } from '@codemirror/lang-markdown';
7
7
  import { ReferenceResolutionWidget, showWidgetPreview, hideWidgetPreview } from '../lib/codemirror-widgets';
8
8
  import { scrollAnnotationIntoView } from '../lib/scroll-utils';
9
- import { isReference } from '@semiont/api-client';
10
- import type { EventBus } from "@semiont/core";
11
- import { createHoverHandlers } from '../hooks/useBeckonFlow';
9
+ import { annotationId as toAnnotationId } from '@semiont/core';
10
+ import { isReference } from '@semiont/core';
11
+ import { createHoverHandlers, type SemiontSession } from '@semiont/sdk';
12
12
  import {
13
13
  convertSegmentPositions,
14
14
  computeAnnotationDecorations,
@@ -43,7 +43,7 @@ interface Props {
43
43
  sourceView?: boolean; // If true, show raw source (no markdown rendering)
44
44
  showLineNumbers?: boolean; // If true, show line numbers
45
45
  enableWidgets?: boolean; // If true, show inline widgets (reference previews, entity badges)
46
- eventBus?: EventBus;
46
+ session?: SemiontSession | null | undefined;
47
47
  getTargetResourceName?: (resourceId: string) => string | undefined;
48
48
  generatingReferenceId?: string | null; // ID of reference currently generating a document
49
49
  hoverDelayMs: number; // Hover delay in milliseconds for accessibility
@@ -179,7 +179,7 @@ export function CodeMirrorRenderer({
179
179
  sourceView = false,
180
180
  showLineNumbers = false,
181
181
  enableWidgets = false,
182
- eventBus,
182
+ session,
183
183
  getTargetResourceName,
184
184
  generatingReferenceId,
185
185
  hoverDelayMs
@@ -196,7 +196,7 @@ export function CodeMirrorRenderer({
196
196
  // Index segments by annotation ID for O(1) click lookups
197
197
  const segmentsByIdRef = useRef(new Map<string, TextSegment>());
198
198
  const lineNumbersCompartment = useRef(new Compartment());
199
- const eventBusRef = useRef(eventBus);
199
+ const sessionRef = useRef(session);
200
200
  const getTargetResourceNameRef = useRef(getTargetResourceName);
201
201
 
202
202
  // Update refs when they change
@@ -206,7 +206,7 @@ export function CodeMirrorRenderer({
206
206
  if (s.annotation) segmentsById.set(s.annotation.id, s);
207
207
  }
208
208
  segmentsByIdRef.current = segmentsById;
209
- eventBusRef.current = eventBus;
209
+ sessionRef.current = session;
210
210
  getTargetResourceNameRef.current = getTargetResourceName;
211
211
 
212
212
  // Initialize CodeMirror view once
@@ -238,7 +238,7 @@ export function CodeMirrorRenderer({
238
238
  EditorView.domEventHandlers({
239
239
  click: (event, _view) => {
240
240
  const target = event.target as HTMLElement;
241
- if (eventBusRef.current && handleAnnotationClick(target, segmentsByIdRef.current, eventBusRef.current)) {
241
+ if (sessionRef.current && handleAnnotationClick(target, segmentsByIdRef.current, sessionRef.current)) {
242
242
  event.preventDefault();
243
243
  return true;
244
244
  }
@@ -303,7 +303,7 @@ export function CodeMirrorRenderer({
303
303
  const container = view.dom;
304
304
 
305
305
  const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
306
- (annotationId) => eventBusRef.current?.get('beckon:hover').next({ annotationId }),
306
+ (id) => sessionRef.current?.client.beckon.hover(id),
307
307
  hoverDelayMs
308
308
  );
309
309
 
@@ -311,7 +311,7 @@ export function CodeMirrorRenderer({
311
311
  const target = e.target as HTMLElement;
312
312
  const annotationElement = target.closest('[data-annotation-id]');
313
313
  const annotationId = annotationElement?.getAttribute('data-annotation-id');
314
- if (annotationId) handleMouseEnter(annotationId);
314
+ if (annotationId) handleMouseEnter(toAnnotationId(annotationId));
315
315
  };
316
316
 
317
317
  const handleMouseOut = (e: MouseEvent) => {
@@ -329,8 +329,8 @@ export function CodeMirrorRenderer({
329
329
  e.preventDefault();
330
330
  e.stopPropagation();
331
331
 
332
- if (eventBusRef.current) {
333
- dispatchWidgetClick(result, eventBusRef.current);
332
+ if (sessionRef.current) {
333
+ dispatchWidgetClick(result, sessionRef.current);
334
334
  }
335
335
  };
336
336
 
@@ -1,10 +1,9 @@
1
1
  'use client';
2
2
 
3
3
  import React, { useState, createContext, useContext, useCallback } from 'react';
4
- import type { components } from '@semiont/core';
5
4
  import type { Annotator } from '../lib/annotation-registry';
6
5
 
7
- type Annotation = components['schemas']['Annotation'];
6
+ import type { Annotation } from '@semiont/core';
8
7
 
9
8
  interface LiveRegionContextType {
10
9
  announce: (message: string, priority?: 'polite' | 'assertive') => void;
@@ -1,6 +1,8 @@
1
1
  'use client';
2
2
 
3
- import { useHealth } from '../lib/api-hooks';
3
+ import { useEffect, useState } from 'react';
4
+ import { useSemiont } from '../session/SemiontProvider';
5
+ import { useObservable } from '../hooks/useObservable';
4
6
  import './StatusDisplay.css';
5
7
 
6
8
  interface StatusDisplayProps {
@@ -9,36 +11,61 @@ interface StatusDisplayProps {
9
11
  hasValidBackendToken?: boolean;
10
12
  }
11
13
 
14
+ interface StatusData {
15
+ status: string;
16
+ version: string;
17
+ }
18
+
12
19
  export function StatusDisplay({
13
20
  isFullyAuthenticated = false,
14
21
  isAuthenticated = false,
15
22
  hasValidBackendToken = false
16
23
  }: StatusDisplayProps) {
17
- const health = useHealth();
18
- const status = health.status.useQuery(30000); // Poll every 30 seconds
24
+ const semiont = useObservable(useSemiont().activeSession$)?.client;
25
+ const [data, setData] = useState<StatusData | null>(null);
26
+ const [loading, setLoading] = useState(true);
27
+ const [error, setError] = useState<Error | null>(null);
28
+
29
+ useEffect(() => {
30
+ if (!semiont) { setLoading(false); return; }
31
+
32
+ const fetchStatus = () => {
33
+ semiont.admin.status()
34
+ .then((result) => {
35
+ setData(result as StatusData);
36
+ setError(null);
37
+ setLoading(false);
38
+ })
39
+ .catch((err) => {
40
+ setError(err instanceof Error ? err : new Error(String(err)));
41
+ setLoading(false);
42
+ });
43
+ };
44
+
45
+ fetchStatus();
46
+ const interval = setInterval(fetchStatus, 30000);
47
+ return () => clearInterval(interval);
48
+ }, [semiont]);
19
49
 
20
50
  const getStatusContent = () => {
21
- // Check for users who are logged in but missing backend token (old sessions)
22
51
  if (isAuthenticated && !hasValidBackendToken) {
23
52
  return '🚀 Frontend Status: Ready • Backend: Please sign out and sign in again to reconnect';
24
53
  }
25
54
 
26
- // If user is not authenticated at all, show appropriate message
27
55
  if (!isFullyAuthenticated) {
28
56
  return '🚀 Frontend Status: Ready • Backend: Authentication required';
29
57
  }
30
58
 
31
- if (status.data) {
32
- return `🚀 Frontend Status: Ready • Backend: ${status.data.status} (v${status.data.version})`;
59
+ if (data) {
60
+ return `🚀 Frontend Status: Ready • Backend: ${data.status} (v${data.version})`;
33
61
  }
34
62
 
35
- if (status.isLoading) {
63
+ if (loading) {
36
64
  return '🚀 Frontend Status: Ready • Backend: Connecting...';
37
65
  }
38
66
 
39
- if (status.error) {
40
- // Check if this is an auth error that might be fixed by re-login
41
- const errorMessage = status.error instanceof Error ? status.error.message : String(status.error);
67
+ if (error) {
68
+ const errorMessage = error.message;
42
69
  if (errorMessage.includes('401') || errorMessage.includes('Unauthorized')) {
43
70
  return '🚀 Frontend Status: Ready • Backend: Please sign out and sign in again';
44
71
  }
@@ -49,7 +76,6 @@ export function StatusDisplay({
49
76
  };
50
77
 
51
78
  const getStatusType = (): 'warning' | 'info' | 'success' | 'loading' | 'error' => {
52
- // Check for users who need to re-authenticate
53
79
  if (isAuthenticated && !hasValidBackendToken) {
54
80
  return 'warning';
55
81
  }
@@ -58,11 +84,11 @@ export function StatusDisplay({
58
84
  return 'info';
59
85
  }
60
86
 
61
- if (status.data) {
87
+ if (data) {
62
88
  return 'success';
63
89
  }
64
90
 
65
- if (status.isLoading) {
91
+ if (loading) {
66
92
  return 'loading';
67
93
  }
68
94
 
@@ -85,7 +111,7 @@ export function StatusDisplay({
85
111
  <p className="semiont-status-hint">
86
112
  Sign in to view backend status
87
113
  </p>
88
- ) : status.error ? (
114
+ ) : error ? (
89
115
  <p className="semiont-status-hint semiont-status-error-hint" role="alert">
90
116
  <span className="sr-only">Error: </span>
91
117
  Check that the backend server is running and accessible
@@ -93,4 +119,4 @@ export function StatusDisplay({
93
119
  ) : null}
94
120
  </section>
95
121
  );
96
- }
122
+ }
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useTranslations } from '../contexts/TranslationContext';
4
- import { useEventBus } from '../contexts/EventBusContext';
4
+ import { useSemiont } from '../session/SemiontProvider';
5
5
  import './toolbar/Toolbar.css';
6
6
 
7
7
  type ToolbarContext = 'document' | 'simple';
@@ -17,7 +17,7 @@ interface Props<T extends string = string> {
17
17
  /**
18
18
  * Toolbar component for panel navigation
19
19
  *
20
- * @emits browse:panel-toggle - Toggle panel visibility. Payload: { panel: string }
20
+ * @emits panel:toggle - Toggle panel visibility. Payload: { panel: string }
21
21
  */
22
22
  export function Toolbar<T extends string = string>({
23
23
  context,
@@ -25,10 +25,10 @@ export function Toolbar<T extends string = string>({
25
25
  isArchived = false
26
26
  }: Props<T>) {
27
27
  const t = useTranslations('Toolbar');
28
- const eventBus = useEventBus();
28
+ const semiont = useSemiont();
29
29
 
30
30
  const handlePanelToggle = (panel: string) => {
31
- eventBus.get('browse:panel-toggle').next({ panel });
31
+ semiont.emit('panel:toggle', { panel });
32
32
  };
33
33
 
34
34
  return (
@@ -4,7 +4,9 @@ import { screen, fireEvent } from '@testing-library/react';
4
4
  import '@testing-library/jest-dom';
5
5
  import { renderWithProviders } from '../../test-utils';
6
6
  import { AnnotateReferencesProgressWidget } from '../AnnotateReferencesProgressWidget';
7
- import type { MarkProgress } from '@semiont/core';
7
+ import type { components } from '@semiont/core';
8
+
9
+ type JobProgress = components['schemas']['JobProgress'];
8
10
 
9
11
  describe('AnnotateReferencesProgressWidget', () => {
10
12
  it('returns null when progress is null', () => {
@@ -15,9 +17,10 @@ describe('AnnotateReferencesProgressWidget', () => {
15
17
  expect(container.firstChild).toBeNull();
16
18
  });
17
19
 
18
- it('renders progress with status message', () => {
19
- const progress: MarkProgress = {
20
- status: 'in-progress',
20
+ it('renders progress with stage message', () => {
21
+ const progress: JobProgress = {
22
+ stage: 'in-progress',
23
+ percentage: 50,
21
24
  message: 'Processing entities...',
22
25
  };
23
26
 
@@ -29,8 +32,9 @@ describe('AnnotateReferencesProgressWidget', () => {
29
32
  });
30
33
 
31
34
  it('shows cancel button when not complete', () => {
32
- const progress: MarkProgress = {
33
- status: 'in-progress',
35
+ const progress: JobProgress = {
36
+ stage: 'in-progress',
37
+ percentage: 30,
34
38
  message: 'Working...',
35
39
  };
36
40
 
@@ -43,8 +47,10 @@ describe('AnnotateReferencesProgressWidget', () => {
43
47
  });
44
48
 
45
49
  it('hides cancel button when complete', () => {
46
- const progress: MarkProgress = {
47
- status: 'complete',
50
+ const progress: JobProgress = {
51
+ stage: 'complete',
52
+ percentage: 100,
53
+ message: '',
48
54
  };
49
55
 
50
56
  renderWithProviders(
@@ -56,8 +62,9 @@ describe('AnnotateReferencesProgressWidget', () => {
56
62
 
57
63
  it('emits job:cancel-requested on cancel click', () => {
58
64
  const handler = vi.fn();
59
- const progress: MarkProgress = {
60
- status: 'in-progress',
65
+ const progress: JobProgress = {
66
+ stage: 'in-progress',
67
+ percentage: 40,
61
68
  message: 'Working...',
62
69
  };
63
70
 
@@ -77,8 +84,10 @@ describe('AnnotateReferencesProgressWidget', () => {
77
84
  });
78
85
 
79
86
  it('renders completed entity types', () => {
80
- const progress: MarkProgress = {
81
- status: 'in-progress',
87
+ const progress: JobProgress = {
88
+ stage: 'in-progress',
89
+ percentage: 60,
90
+ message: '',
82
91
  completedEntityTypes: [
83
92
  { entityType: 'Person', foundCount: 5 },
84
93
  { entityType: 'Organization', foundCount: 3 },
@@ -96,9 +105,11 @@ describe('AnnotateReferencesProgressWidget', () => {
96
105
  expect(foundLabels).toHaveLength(2);
97
106
  });
98
107
 
99
- it('shows complete icon for complete status', () => {
100
- const progress: MarkProgress = {
101
- status: 'complete',
108
+ it('shows complete icon for complete stage', () => {
109
+ const progress: JobProgress = {
110
+ stage: 'complete',
111
+ percentage: 100,
112
+ message: '',
102
113
  };
103
114
 
104
115
  const { container } = renderWithProviders(
@@ -109,9 +120,10 @@ describe('AnnotateReferencesProgressWidget', () => {
109
120
  expect(screen.getByText('ReferencesPanel.complete')).toBeInTheDocument();
110
121
  });
111
122
 
112
- it('shows error message for error status', () => {
113
- const progress: MarkProgress = {
114
- status: 'error',
123
+ it('shows error message for error stage', () => {
124
+ const progress: JobProgress = {
125
+ stage: 'error',
126
+ percentage: 0,
115
127
  message: 'Something went wrong',
116
128
  };
117
129
 
@@ -124,8 +136,10 @@ describe('AnnotateReferencesProgressWidget', () => {
124
136
  });
125
137
 
126
138
  it('shows current entity type processing details', () => {
127
- const progress: MarkProgress = {
128
- status: 'in-progress',
139
+ const progress: JobProgress = {
140
+ stage: 'in-progress',
141
+ percentage: 50,
142
+ message: '',
129
143
  currentEntityType: 'Location',
130
144
  };
131
145