@semiont/react-ui 0.5.5 → 0.5.6

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 (87) hide show
  1. package/README.md +59 -55
  2. package/dist/{PdfAnnotationCanvas.client-CN3C3S55.js → PdfAnnotationCanvas.client-NIMALXNZ.js} +7 -27
  3. package/dist/PdfAnnotationCanvas.client-NIMALXNZ.js.map +1 -0
  4. package/dist/index.css +6 -0
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.d.ts +243 -99
  7. package/dist/index.js +539 -405
  8. package/dist/index.js.map +1 -1
  9. package/package.json +16 -12
  10. package/src/components/Button/__tests__/Button.test.tsx +0 -2
  11. package/src/components/CodeMirrorRenderer.tsx +2 -0
  12. package/src/components/ErrorBoundary.tsx +0 -9
  13. package/src/components/ProtectedErrorBoundary.tsx +6 -2
  14. package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +0 -1
  15. package/src/components/__tests__/ErrorBoundary.test.tsx +20 -13
  16. package/src/components/__tests__/LiveRegion.hooks.test.tsx +1 -1
  17. package/src/components/__tests__/ProtectedErrorBoundary.test.tsx +2 -1
  18. package/src/components/__tests__/ResizeHandle.test.tsx +0 -1
  19. package/src/components/__tests__/SessionExpiryBanner.test.tsx +0 -1
  20. package/src/components/__tests__/StatusDisplay.test.tsx +0 -1
  21. package/src/components/__tests__/Toast.test.tsx +2 -3
  22. package/src/components/__tests__/Toolbar.test.tsx +0 -1
  23. package/src/components/annotation/annotations.css +14 -0
  24. package/src/components/annotation-popups/__tests__/JsonLdView.test.tsx +3 -5
  25. package/src/components/annotation-popups/__tests__/SharedPopupElements.test.tsx +0 -1
  26. package/src/components/branding/__tests__/SemiontBranding.test.tsx +1 -2
  27. package/src/components/layout/__tests__/LeftSidebar.test.tsx +5 -6
  28. package/src/components/layout/__tests__/PageLayout.test.tsx +1 -3
  29. package/src/components/layout/__tests__/SkipLinks.a11y.test.tsx +8 -8
  30. package/src/components/layout/__tests__/UnifiedHeader.test.tsx +12 -1
  31. package/src/components/modals/__tests__/KeyboardShortcutsHelpModal.test.tsx +0 -1
  32. package/src/components/modals/__tests__/PermissionDeniedModal.test.tsx +3 -4
  33. package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +0 -1
  34. package/src/components/modals/__tests__/SearchModal.basic.test.tsx +1 -1
  35. package/src/components/modals/__tests__/SearchModal.keyboard.test.tsx +0 -5
  36. package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +0 -1
  37. package/src/components/modals/__tests__/SearchModal.visual.test.tsx +2 -2
  38. package/src/components/modals/__tests__/SessionExpiredModal.test.tsx +0 -1
  39. package/src/components/navigation/NavigationMenu.tsx +1 -1
  40. package/src/components/navigation/__tests__/Footer.a11y.test.tsx +4 -0
  41. package/src/components/navigation/__tests__/Footer.test.tsx +3 -6
  42. package/src/components/navigation/__tests__/NavigationMenu.a11y.test.tsx +1 -1
  43. package/src/components/navigation/__tests__/NavigationMenu.test.tsx +7 -9
  44. package/src/components/navigation/__tests__/ObservableLink.test.tsx +0 -1
  45. package/src/components/navigation/__tests__/SimpleNavigation.test.tsx +1 -2
  46. package/src/components/navigation/__tests__/SortableResourceTab.test.tsx +0 -1
  47. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +6 -4
  48. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +10 -19
  49. package/src/components/resource/__tests__/BrowseView.test.tsx +8 -6
  50. package/src/components/resource/__tests__/HistoryEvent.test.tsx +0 -4
  51. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +4 -6
  52. package/src/components/resource/panels/ReferencesPanel.tsx +1 -1
  53. package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +3 -4
  54. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +7 -6
  55. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +14 -10
  56. package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +0 -1
  57. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +30 -17
  58. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +6 -5
  59. package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +4 -5
  60. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +19 -13
  61. package/src/components/resource/panels/__tests__/JsonLdPanel.test.tsx +1 -3
  62. package/src/components/resource/panels/__tests__/PanelHeader.test.tsx +0 -1
  63. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +5 -5
  64. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +40 -7
  65. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +3 -3
  66. package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +30 -32
  67. package/src/components/resource/panels/__tests__/TagEntry.test.tsx +5 -5
  68. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +6 -5
  69. package/src/components/settings/__tests__/SettingsPanel.test.tsx +0 -1
  70. package/src/components/viewers/__tests__/ImageViewer.test.tsx +0 -1
  71. package/src/features/auth/__tests__/SignInForm.a11y.test.tsx +2 -0
  72. package/src/features/auth/__tests__/SignUpForm.a11y.test.tsx +11 -12
  73. package/src/features/auth/__tests__/SignUpForm.test.tsx +3 -3
  74. package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -0
  75. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +2 -1
  76. package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +0 -1
  77. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +33 -35
  78. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +12 -11
  79. package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +204 -11
  80. package/src/features/resource-discovery/state/discover-state-unit.ts +70 -11
  81. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +2 -2
  82. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +3 -2
  83. package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +0 -1
  84. package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +5 -2
  85. package/src/integrations/__tests__/css-modules-helper.test.tsx +2 -3
  86. package/src/integrations/__tests__/styled-components-theme.test.ts +1 -3
  87. package/dist/PdfAnnotationCanvas.client-CN3C3S55.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
2
  import type { MockedFunction } from 'vitest';
3
3
  import React from 'react';
4
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
4
+ import { render, screen, waitFor } from '@testing-library/react';
5
5
  import userEvent from '@testing-library/user-event';
6
6
  import '@testing-library/jest-dom';
7
7
  import { CommentsPanel } from '../CommentsPanel';
8
- import type { components, EventBus } from '@semiont/core';
8
+ import type { EventBus } from '@semiont/core';
9
9
  import { createTestSemiontWrapper } from '../../../../test-utils';
10
10
 
11
- import type { Annotation } from '@semiont/core';
11
+ import type { Annotation, AnnotationId } from '@semiont/core';
12
12
 
13
13
  // Composition-based event tracker
14
14
  interface TrackedEvent {
@@ -68,7 +68,7 @@ vi.mock('@semiont/core', async () => {
68
68
 
69
69
  // Mock CommentEntry component to simplify testing
70
70
  vi.mock('../CommentEntry', () => ({
71
- CommentEntry: ({ comment, onClick, onCommentRef, onCommentHover }: any) => (
71
+ CommentEntry: ({ comment, onClick, onCommentHover }: any) => (
72
72
  <div
73
73
  data-testid={`comment-${comment.id}`}
74
74
  onClick={() => onClick()}
@@ -91,10 +91,11 @@ const mockGetTargetSelector = getTargetSelector as MockedFunction<typeof getTarg
91
91
  // Test data fixtures
92
92
  const createMockComment = (id: string, start: number, end: number): Annotation => ({
93
93
  '@context': 'http://www.w3.org/ns/anno.jsonld',
94
- id,
94
+ id: id as AnnotationId,
95
95
  type: 'Annotation',
96
96
  motivation: 'commenting',
97
97
  creator: {
98
+ '@type': 'Person',
98
99
  name: `user${id}@example.com`,
99
100
  },
100
101
  created: `2024-01-0${id.slice(-1)}T10:00:00Z`,
@@ -1,12 +1,10 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import React from 'react';
3
- import { screen, fireEvent } from '@testing-library/react';
2
+ import { screen } from '@testing-library/react';
4
3
  import '@testing-library/jest-dom';
5
4
  import { renderWithProviders } from '../../../../test-utils';
6
5
  import userEvent from '@testing-library/user-event';
7
- import type { components } from '@semiont/core';
8
6
 
9
- import type { Annotation } from '@semiont/core';
7
+ import type { Annotation, AnnotationId } from '@semiont/core';
10
8
 
11
9
  // Mock @semiont/api-client
12
10
  vi.mock('@semiont/core', async () => {
@@ -25,10 +23,11 @@ const mockGetAnnotationExactText = getAnnotationExactText as MockedFunction<type
25
23
 
26
24
  const createMockHighlight = (overrides?: Partial<Annotation>): Annotation => ({
27
25
  '@context': 'http://www.w3.org/ns/anno.jsonld',
28
- id: 'highlight-1',
26
+ id: 'highlight-1' as AnnotationId,
29
27
  type: 'Annotation',
30
28
  motivation: 'highlighting',
31
29
  creator: {
30
+ '@type': 'Person',
32
31
  name: 'alice@example.com',
33
32
  },
34
33
  created: '2024-06-15T12:00:00Z',
@@ -16,9 +16,8 @@ import React from 'react';
16
16
  import { screen } from '@testing-library/react';
17
17
  import { renderWithProviders } from '../../../../test-utils';
18
18
  import { HighlightPanel } from '../HighlightPanel';
19
- import type { components } from '@semiont/core';
20
19
 
21
- import type { Annotation } from '@semiont/core';
20
+ import type { Annotation, AnnotationId } from '@semiont/core';
22
21
 
23
22
  // Mock translations - simulates useTranslations('HighlightPanel')
24
23
  // The mock receives keys like 'title', 'noHighlights', etc. and returns translated strings
@@ -55,7 +54,9 @@ describe('HighlightPanel + AssistSection Integration', () => {
55
54
 
56
55
  mockAnnotations = [
57
56
  {
58
- id: 'highlight-1',
57
+ '@context': 'http://www.w3.org/ns/anno.jsonld',
58
+ type: 'Annotation',
59
+ id: 'highlight-1' as AnnotationId,
59
60
  motivation: 'highlighting',
60
61
  target: {
61
62
  source: 'resource-1',
@@ -78,7 +79,7 @@ describe('HighlightPanel + AssistSection Integration', () => {
78
79
  pendingAnnotation={null}
79
80
  isAssisting={true}
80
81
  progress={{
81
- status: 'analyzing',
82
+ stage: 'analyzing',
82
83
  percentage: 30,
83
84
  message: 'Analyzing text for highlights...',
84
85
  }}
@@ -129,7 +130,7 @@ describe('HighlightPanel + AssistSection Integration', () => {
129
130
  pendingAnnotation={null}
130
131
  isAssisting={false}
131
132
  progress={{
132
- status: 'complete',
133
+ stage: 'complete',
133
134
  percentage: 100,
134
135
  message: 'Complete! Created 14 highlights',
135
136
  }}
@@ -150,7 +151,8 @@ describe('HighlightPanel + AssistSection Integration', () => {
150
151
  pendingAnnotation={null}
151
152
  isAssisting={true}
152
153
  progress={{
153
- status: 'analyzing',
154
+ stage: 'analyzing',
155
+ percentage: 0,
154
156
  message: 'Analyzing...',
155
157
  requestParams: [
156
158
  { label: 'Instructions', value: 'Find important points' },
@@ -203,7 +205,8 @@ describe('HighlightPanel + AssistSection Integration', () => {
203
205
  pendingAnnotation={null}
204
206
  isAssisting={true}
205
207
  progress={{
206
- status: 'analyzing',
208
+ stage: 'analyzing',
209
+ percentage: 0,
207
210
  message: 'Analyzing...',
208
211
  }}
209
212
  annotateMode={true}
@@ -219,7 +222,8 @@ describe('HighlightPanel + AssistSection Integration', () => {
219
222
  pendingAnnotation={null}
220
223
  isAssisting={true}
221
224
  progress={{
222
- status: 'analyzing',
225
+ stage: 'analyzing',
226
+ percentage: 0,
223
227
  message: 'Analyzing...',
224
228
  }}
225
229
  annotateMode={false}
@@ -254,7 +258,8 @@ describe('HighlightPanel + AssistSection Integration', () => {
254
258
  pendingAnnotation={null}
255
259
  isAssisting={false}
256
260
  progress={{
257
- status: 'complete',
261
+ stage: 'complete',
262
+ percentage: 100,
258
263
  message: 'Done!',
259
264
  }}
260
265
  annotateMode={true}
@@ -274,7 +279,7 @@ describe('HighlightPanel + AssistSection Integration', () => {
274
279
  pendingAnnotation={null}
275
280
  isAssisting={true}
276
281
  progress={{
277
- status: 'started',
282
+ stage: 'started',
278
283
  percentage: 0,
279
284
  message: 'Starting...',
280
285
  }}
@@ -291,7 +296,7 @@ describe('HighlightPanel + AssistSection Integration', () => {
291
296
  pendingAnnotation={null}
292
297
  isAssisting={true}
293
298
  progress={{
294
- status: 'analyzing',
299
+ stage: 'analyzing',
295
300
  percentage: 50,
296
301
  message: 'Analyzing...',
297
302
  }}
@@ -309,7 +314,7 @@ describe('HighlightPanel + AssistSection Integration', () => {
309
314
  pendingAnnotation={null}
310
315
  isAssisting={false}
311
316
  progress={{
312
- status: 'complete',
317
+ stage: 'complete',
313
318
  percentage: 100,
314
319
  message: 'Complete!',
315
320
  }}
@@ -330,7 +335,8 @@ describe('HighlightPanel + AssistSection Integration', () => {
330
335
  pendingAnnotation={null}
331
336
  isAssisting={true}
332
337
  progress={{
333
- status: 'analyzing',
338
+ stage: 'analyzing',
339
+ percentage: 0,
334
340
  message: 'Analyzing...',
335
341
  }}
336
342
  annotateMode={true}
@@ -1,5 +1,4 @@
1
1
  import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
- import React from 'react';
3
2
  import { render, screen, waitFor } from '@testing-library/react';
4
3
  import userEvent from '@testing-library/user-event';
5
4
  import '@testing-library/jest-dom';
@@ -12,7 +11,7 @@ type SemiontResource = components['schemas']['ResourceDescriptor'];
12
11
  vi.mock('@codemirror/view', () => {
13
12
  class MockEditorView {
14
13
  destroy = vi.fn();
15
- constructor(config: any) {
14
+ constructor() {
16
15
  // Store config if needed for assertions
17
16
  }
18
17
  static editable = { of: vi.fn() };
@@ -55,7 +54,6 @@ vi.mock('../../../lib/codemirror-json-theme', () => ({
55
54
  // Mock useLineNumbers hook (must be before import)
56
55
  vi.mock('@/hooks/useLineNumbers');
57
56
 
58
- import { EditorView } from '@codemirror/view';
59
57
  import { useLineNumbers } from '@/hooks/useLineNumbers';
60
58
 
61
59
  // Test data fixtures
@@ -1,5 +1,4 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import React from 'react';
3
2
  import { screen } from '@testing-library/react';
4
3
  import '@testing-library/jest-dom';
5
4
  import { renderWithProviders } from '../../../../test-utils';
@@ -1,14 +1,12 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import React from 'react';
3
2
  import { screen } from '@testing-library/react';
4
3
  import '@testing-library/jest-dom';
5
4
  import { renderWithProviders } from '../../../../test-utils';
6
5
  import userEvent from '@testing-library/user-event';
7
- import type { components } from '@semiont/core';
8
6
  import { BindNamespace } from '@semiont/sdk';
9
7
  import type { RouteBuilder } from '../../../../contexts/RoutingContext';
10
8
 
11
- import type { Annotation } from '@semiont/core';
9
+ import type { Annotation, AnnotationId } from '@semiont/core';
12
10
 
13
11
  // Stable mock functions defined outside vi.mock to avoid re-render loops
14
12
  const mockGetAnnotationExactText = vi.fn();
@@ -54,7 +52,7 @@ import { ReferenceEntry } from '../ReferenceEntry';
54
52
 
55
53
  const createMockReference = (overrides?: Partial<Annotation>): Annotation => ({
56
54
  '@context': 'http://www.w3.org/ns/anno.jsonld',
57
- id: 'ref-1',
55
+ id: 'ref-1' as AnnotationId,
58
56
  type: 'Annotation',
59
57
  motivation: 'linking',
60
58
  created: '2024-06-15T12:00:00Z',
@@ -75,7 +73,9 @@ const createMockReference = (overrides?: Partial<Annotation>): Annotation => ({
75
73
 
76
74
  const mockRoutes: RouteBuilder = {
77
75
  resourceDetail: vi.fn((id: string) => `/resources/${id}`),
78
- resourceList: vi.fn(() => '/resources'),
76
+ userProfile: vi.fn((id: string) => `/users/${id}`),
77
+ search: vi.fn((query: string) => `/search?q=${query}`),
78
+ home: vi.fn(() => '/'),
79
79
  };
80
80
 
81
81
  describe('ReferenceEntry', () => {
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
2
  import React from 'react';
3
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
+ import { render, screen, waitFor } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
5
  import '@testing-library/jest-dom';
6
6
  import { ReferencesPanel } from '../ReferencesPanel';
@@ -316,7 +316,7 @@ describe('ReferencesPanel Component', () => {
316
316
  <ReferencesPanel
317
317
  {...defaultProps}
318
318
  isAssisting={true}
319
- progress={{ completedEntityTypes: [] }}
319
+ progress={{ stage: 'analyzing', percentage: 0, message: 'Detecting references...', completedEntityTypes: [] }}
320
320
  />
321
321
  );
322
322
 
@@ -326,6 +326,9 @@ describe('ReferencesPanel Component', () => {
326
326
  {...defaultProps}
327
327
  isAssisting={false}
328
328
  progress={{
329
+ stage: 'complete',
330
+ percentage: 100,
331
+ message: 'Annotation complete',
329
332
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
330
333
  }}
331
334
  />
@@ -366,7 +369,7 @@ describe('ReferencesPanel Component', () => {
366
369
  <ReferencesPanel
367
370
  {...defaultProps}
368
371
  isAssisting={true}
369
- progress={{ completedEntityTypes: [] }}
372
+ progress={{ stage: 'analyzing', percentage: 0, message: 'Detecting references...', completedEntityTypes: [] }}
370
373
  />
371
374
  );
372
375
 
@@ -375,6 +378,9 @@ describe('ReferencesPanel Component', () => {
375
378
 
376
379
  it('should pass progress data to widget', () => {
377
380
  const progress = {
381
+ stage: 'complete',
382
+ percentage: 100,
383
+ message: 'Annotation complete',
378
384
  completedEntityTypes: [
379
385
  { entityType: 'Person', foundCount: 5 },
380
386
  { entityType: 'Organization', foundCount: 3 },
@@ -399,7 +405,7 @@ describe('ReferencesPanel Component', () => {
399
405
  <ReferencesPanel
400
406
  {...defaultProps}
401
407
  isAssisting={true}
402
- progress={{ completedEntityTypes: [] }}
408
+ progress={{ stage: 'analyzing', percentage: 0, message: 'Detecting references...', completedEntityTypes: [] }}
403
409
  />
404
410
  );
405
411
 
@@ -412,7 +418,7 @@ describe('ReferencesPanel Component', () => {
412
418
  <ReferencesPanel
413
419
  {...defaultProps}
414
420
  isAssisting={true}
415
- progress={{ completedEntityTypes: [] }}
421
+ progress={{ stage: 'analyzing', percentage: 0, message: 'Detecting references...', completedEntityTypes: [] }}
416
422
  />
417
423
  );
418
424
 
@@ -428,6 +434,9 @@ describe('ReferencesPanel Component', () => {
428
434
  {...defaultProps}
429
435
  isAssisting={false}
430
436
  progress={{
437
+ stage: 'complete',
438
+ percentage: 100,
439
+ message: 'Annotation complete',
431
440
  completedEntityTypes: [
432
441
  { entityType: 'Person', foundCount: 5 },
433
442
  { entityType: 'Organization', foundCount: 3 },
@@ -455,6 +464,9 @@ describe('ReferencesPanel Component', () => {
455
464
  {...defaultProps}
456
465
  isAssisting={false}
457
466
  progress={{
467
+ stage: 'complete',
468
+ percentage: 100,
469
+ message: 'Annotation complete',
458
470
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
459
471
  }}
460
472
  />
@@ -472,6 +484,9 @@ describe('ReferencesPanel Component', () => {
472
484
  {...defaultProps}
473
485
  isAssisting={false}
474
486
  progress={{
487
+ stage: 'complete',
488
+ percentage: 100,
489
+ message: 'Annotation complete',
475
490
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
476
491
  }}
477
492
  />
@@ -489,6 +504,9 @@ describe('ReferencesPanel Component', () => {
489
504
  {...defaultProps}
490
505
  isAssisting={false}
491
506
  progress={{
507
+ stage: 'complete',
508
+ percentage: 100,
509
+ message: 'Annotation complete',
492
510
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
493
511
  }}
494
512
  />
@@ -509,6 +527,9 @@ describe('ReferencesPanel Component', () => {
509
527
  {...defaultProps}
510
528
  isAssisting={false}
511
529
  progress={{
530
+ stage: 'complete',
531
+ percentage: 100,
532
+ message: 'Annotation complete',
512
533
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
513
534
  }}
514
535
  />
@@ -529,6 +550,9 @@ describe('ReferencesPanel Component', () => {
529
550
  {...defaultProps}
530
551
  isAssisting={false}
531
552
  progress={{
553
+ stage: 'complete',
554
+ percentage: 100,
555
+ message: 'Annotation complete',
532
556
  completedEntityTypes: [],
533
557
  }}
534
558
  />
@@ -552,7 +576,7 @@ describe('ReferencesPanel Component', () => {
552
576
  <ReferencesPanel
553
577
  {...defaultProps}
554
578
  isAssisting={true}
555
- progress={{ completedEntityTypes: [] }}
579
+ progress={{ stage: 'analyzing', percentage: 0, message: 'Detecting references...', completedEntityTypes: [] }}
556
580
  />
557
581
  );
558
582
 
@@ -566,7 +590,7 @@ describe('ReferencesPanel Component', () => {
566
590
  <ReferencesPanel
567
591
  {...defaultProps}
568
592
  isAssisting={true}
569
- progress={{ completedEntityTypes: [] }}
593
+ progress={{ stage: 'analyzing', percentage: 0, message: 'Detecting references...', completedEntityTypes: [] }}
570
594
  />
571
595
  );
572
596
 
@@ -579,6 +603,9 @@ describe('ReferencesPanel Component', () => {
579
603
  {...defaultProps}
580
604
  isAssisting={false}
581
605
  progress={{
606
+ stage: 'complete',
607
+ percentage: 100,
608
+ message: 'Annotation complete',
582
609
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
583
610
  }}
584
611
  />
@@ -601,6 +628,9 @@ describe('ReferencesPanel Component', () => {
601
628
  {...defaultProps}
602
629
  isAssisting={false}
603
630
  progress={{
631
+ stage: 'complete',
632
+ percentage: 100,
633
+ message: 'Annotation complete',
604
634
  completedEntityTypes: [{ entityType: 'Person', foundCount: 5 }],
605
635
  }}
606
636
  />
@@ -692,6 +722,9 @@ describe('ReferencesPanel Component', () => {
692
722
  {...defaultProps}
693
723
  isAssisting={false}
694
724
  progress={{
725
+ stage: 'complete',
726
+ percentage: 100,
727
+ message: 'Annotation complete',
695
728
  completedEntityTypes: [{ entityType: 'Person', foundCount: 0 }],
696
729
  }}
697
730
  />
@@ -295,7 +295,7 @@ describe('ResourceInfoPanel Component', () => {
295
295
  renderWithEventBus(
296
296
  <ResourceInfoPanel
297
297
  {...defaultProps}
298
- wasAttributedTo={{ name: 'Alice', '@id': 'https://example.org/alice' }}
298
+ wasAttributedTo={{ '@type': 'Person', name: 'Alice', '@id': 'https://example.org/alice' }}
299
299
  />
300
300
  );
301
301
  expect(screen.getByText('Attributed to')).toBeInTheDocument();
@@ -307,8 +307,8 @@ describe('ResourceInfoPanel Component', () => {
307
307
  <ResourceInfoPanel
308
308
  {...defaultProps}
309
309
  wasAttributedTo={[
310
- { name: 'Alice' },
311
- { name: 'Bob' },
310
+ { '@type': 'Person', name: 'Alice' },
311
+ { '@type': 'Person', name: 'Bob' },
312
312
  ]}
313
313
  />
314
314
  );
@@ -1,11 +1,9 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import React from 'react';
3
2
  import { screen } from '@testing-library/react';
4
3
  import '@testing-library/jest-dom';
5
4
  import { renderWithProviders } from '../../../../test-utils';
6
- import type { components } from '@semiont/core';
7
5
 
8
- import type { Annotation } from '@semiont/core';
6
+ import type { Annotation, AnnotationId } from '@semiont/core';
9
7
 
10
8
  // Stable mock functions defined outside vi.mock to avoid re-render loops
11
9
  const mockIsBodyResolved = vi.fn();
@@ -27,7 +25,7 @@ import { StatisticsPanel } from '../StatisticsPanel';
27
25
 
28
26
  const createMockAnnotation = (overrides?: Partial<Annotation>): Annotation => ({
29
27
  '@context': 'http://www.w3.org/ns/anno.jsonld',
30
- id: 'http://example.com/annotations/1',
28
+ id: 'http://example.com/annotations/1' as AnnotationId,
31
29
  type: 'Annotation',
32
30
  motivation: 'linking',
33
31
  created: '2024-06-15T12:00:00Z',
@@ -73,7 +71,7 @@ describe('StatisticsPanel', () => {
73
71
  it('should render correct highlight count', () => {
74
72
  const props = {
75
73
  ...emptyProps,
76
- highlights: [createMockAnnotation({ id: 'h1' }), createMockAnnotation({ id: 'h2' }), createMockAnnotation({ id: 'h3' })],
74
+ highlights: [createMockAnnotation({ id: 'h1' as AnnotationId }), createMockAnnotation({ id: 'h2' as AnnotationId }), createMockAnnotation({ id: 'h3' as AnnotationId })],
77
75
  };
78
76
 
79
77
  renderWithProviders(<StatisticsPanel {...props} />);
@@ -85,7 +83,7 @@ describe('StatisticsPanel', () => {
85
83
  it('should render correct comment count', () => {
86
84
  const props = {
87
85
  ...emptyProps,
88
- comments: [createMockAnnotation({ id: 'c1' }), createMockAnnotation({ id: 'c2' })],
86
+ comments: [createMockAnnotation({ id: 'c1' as AnnotationId }), createMockAnnotation({ id: 'c2' as AnnotationId })],
89
87
  };
90
88
 
91
89
  renderWithProviders(<StatisticsPanel {...props} />);
@@ -97,7 +95,7 @@ describe('StatisticsPanel', () => {
97
95
  it('should render correct assessment count', () => {
98
96
  const props = {
99
97
  ...emptyProps,
100
- assessments: [createMockAnnotation({ id: 'a1' })],
98
+ assessments: [createMockAnnotation({ id: 'a1' as AnnotationId })],
101
99
  };
102
100
 
103
101
  renderWithProviders(<StatisticsPanel {...props} />);
@@ -110,10 +108,10 @@ describe('StatisticsPanel', () => {
110
108
  const props = {
111
109
  ...emptyProps,
112
110
  tags: [
113
- createMockAnnotation({ id: 't1' }),
114
- createMockAnnotation({ id: 't2' }),
115
- createMockAnnotation({ id: 't3' }),
116
- createMockAnnotation({ id: 't4' }),
111
+ createMockAnnotation({ id: 't1' as AnnotationId }),
112
+ createMockAnnotation({ id: 't2' as AnnotationId }),
113
+ createMockAnnotation({ id: 't3' as AnnotationId }),
114
+ createMockAnnotation({ id: 't4' as AnnotationId }),
117
115
  ],
118
116
  };
119
117
 
@@ -124,9 +122,9 @@ describe('StatisticsPanel', () => {
124
122
  });
125
123
 
126
124
  it('should render correct total reference count', () => {
127
- const refs = [createMockAnnotation({ id: 'r1' }), createMockAnnotation({ id: 'r2' })];
125
+ const refs = [createMockAnnotation({ id: 'r1' as AnnotationId }), createMockAnnotation({ id: 'r2' as AnnotationId })];
128
126
 
129
- const { container } = renderWithProviders(<StatisticsPanel {...emptyProps} references={refs} />);
127
+ renderWithProviders(<StatisticsPanel {...emptyProps} references={refs} />);
130
128
 
131
129
  expect(screen.getByText('StatisticsPanel.references')).toBeInTheDocument();
132
130
  // The references item has the total count as its direct .semiont-statistics-panel__value child
@@ -139,13 +137,13 @@ describe('StatisticsPanel', () => {
139
137
  describe('Reference sub-categories', () => {
140
138
  it('should show stub and resolved counts', () => {
141
139
  const refs = [
142
- createMockAnnotation({ id: 'r1' }),
143
- createMockAnnotation({ id: 'r2' }),
144
- createMockAnnotation({ id: 'r3' }),
140
+ createMockAnnotation({ id: 'r1' as AnnotationId }),
141
+ createMockAnnotation({ id: 'r2' as AnnotationId }),
142
+ createMockAnnotation({ id: 'r3' as AnnotationId }),
145
143
  ];
146
144
 
147
145
  // r1 resolved, r2 and r3 are stubs
148
- mockIsBodyResolved.mockImplementation((body: unknown) => {
146
+ mockIsBodyResolved.mockImplementation(() => {
149
147
  // We can distinguish by the call order
150
148
  return false;
151
149
  });
@@ -167,8 +165,8 @@ describe('StatisticsPanel', () => {
167
165
 
168
166
  it('should count all as resolved when isBodyResolved returns true', () => {
169
167
  const refs = [
170
- createMockAnnotation({ id: 'r1' }),
171
- createMockAnnotation({ id: 'r2' }),
168
+ createMockAnnotation({ id: 'r1' as AnnotationId }),
169
+ createMockAnnotation({ id: 'r2' as AnnotationId }),
172
170
  ];
173
171
 
174
172
  mockIsBodyResolved.mockReturnValue(true);
@@ -182,8 +180,8 @@ describe('StatisticsPanel', () => {
182
180
 
183
181
  it('should count all as stubs when isBodyResolved returns false', () => {
184
182
  const refs = [
185
- createMockAnnotation({ id: 'r1' }),
186
- createMockAnnotation({ id: 'r2' }),
183
+ createMockAnnotation({ id: 'r1' as AnnotationId }),
184
+ createMockAnnotation({ id: 'r2' as AnnotationId }),
187
185
  ];
188
186
 
189
187
  mockIsBodyResolved.mockReturnValue(false);
@@ -206,9 +204,9 @@ describe('StatisticsPanel', () => {
206
204
 
207
205
  it('should render entity types with counts', () => {
208
206
  const refs = [
209
- createMockAnnotation({ id: 'r1' }),
210
- createMockAnnotation({ id: 'r2' }),
211
- createMockAnnotation({ id: 'r3' }),
207
+ createMockAnnotation({ id: 'r1' as AnnotationId }),
208
+ createMockAnnotation({ id: 'r2' as AnnotationId }),
209
+ createMockAnnotation({ id: 'r3' as AnnotationId }),
212
210
  ];
213
211
 
214
212
  mockGetEntityTypes
@@ -226,9 +224,9 @@ describe('StatisticsPanel', () => {
226
224
 
227
225
  it('should sort entity types by count descending', () => {
228
226
  const refs = [
229
- createMockAnnotation({ id: 'r1' }),
230
- createMockAnnotation({ id: 'r2' }),
231
- createMockAnnotation({ id: 'r3' }),
227
+ createMockAnnotation({ id: 'r1' as AnnotationId }),
228
+ createMockAnnotation({ id: 'r2' as AnnotationId }),
229
+ createMockAnnotation({ id: 'r3' as AnnotationId }),
232
230
  ];
233
231
 
234
232
  // Person appears 3 times, Location 1 time
@@ -251,11 +249,11 @@ describe('StatisticsPanel', () => {
251
249
  describe('Mixed annotation counts', () => {
252
250
  it('should render all categories with their respective counts simultaneously', () => {
253
251
  const props = {
254
- highlights: [createMockAnnotation({ id: 'h1' })],
255
- comments: [createMockAnnotation({ id: 'c1' }), createMockAnnotation({ id: 'c2' })],
256
- assessments: [createMockAnnotation({ id: 'a1' }), createMockAnnotation({ id: 'a2' }), createMockAnnotation({ id: 'a3' })],
257
- references: [createMockAnnotation({ id: 'r1' })],
258
- tags: [createMockAnnotation({ id: 't1' }), createMockAnnotation({ id: 't2' })],
252
+ highlights: [createMockAnnotation({ id: 'h1' as AnnotationId })],
253
+ comments: [createMockAnnotation({ id: 'c1' as AnnotationId }), createMockAnnotation({ id: 'c2' as AnnotationId })],
254
+ assessments: [createMockAnnotation({ id: 'a1' as AnnotationId }), createMockAnnotation({ id: 'a2' as AnnotationId }), createMockAnnotation({ id: 'a3' as AnnotationId })],
255
+ references: [createMockAnnotation({ id: 'r1' as AnnotationId })],
256
+ tags: [createMockAnnotation({ id: 't1' as AnnotationId }), createMockAnnotation({ id: 't2' as AnnotationId })],
259
257
  };
260
258
 
261
259
  renderWithProviders(<StatisticsPanel {...props} />);
@@ -1,14 +1,13 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import React from 'react';
3
2
  import { render, screen } from '@testing-library/react';
4
3
  import '@testing-library/jest-dom';
5
4
  import { of } from 'rxjs';
6
5
  import { CacheObservable } from '@semiont/sdk';
7
6
  import { renderWithProviders, createTestSemiontWrapper } from '../../../../test-utils';
8
7
  import userEvent from '@testing-library/user-event';
9
- import type { components, TagSchema } from '@semiont/core';
8
+ import type { TagSchema } from '@semiont/core';
10
9
 
11
- import type { Annotation } from '@semiont/core';
10
+ import type { Annotation, AnnotationId } from '@semiont/core';
12
11
 
13
12
  // Mock @semiont/api-client
14
13
  vi.mock('@semiont/core', async () => {
@@ -37,10 +36,11 @@ const mockGetTagSchemaId = getTagSchemaId as MockedFunction<typeof getTagSchemaI
37
36
 
38
37
  const createMockTag = (overrides?: Partial<Annotation>): Annotation => ({
39
38
  '@context': 'http://www.w3.org/ns/anno.jsonld',
40
- id: 'tag-1',
39
+ id: 'tag-1' as AnnotationId,
41
40
  type: 'Annotation',
42
41
  motivation: 'tagging',
43
42
  creator: {
43
+ '@type': 'Person',
44
44
  name: 'tagger@example.com',
45
45
  },
46
46
  created: '2024-06-15T12:00:00Z',
@@ -71,7 +71,7 @@ describe('TagEntry', () => {
71
71
  vi.clearAllMocks();
72
72
  mockGetAnnotationExactText.mockReturnValue('Tagged text content');
73
73
  mockGetTagCategory.mockReturnValue('Entity');
74
- mockGetTagSchemaId.mockReturnValue(null);
74
+ mockGetTagSchemaId.mockReturnValue(undefined);
75
75
  });
76
76
 
77
77
  describe('Rendering', () => {