@semiont/react-ui 0.5.26 → 0.5.27

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 (249) hide show
  1. package/README.md +28 -4
  2. package/dist/{PdfAnnotationCanvas.client-6ZSF6ZTJ.js → PdfAnnotationCanvas.client-EVUPTUWZ.js} +5 -5
  3. package/dist/PdfAnnotationCanvas.client-EVUPTUWZ.js.map +1 -0
  4. package/dist/{PdfAnnotationCanvas.client-JCJMXWWJ.css → PdfAnnotationCanvas.client-TGDPPGXJ.css} +6 -1
  5. package/dist/PdfAnnotationCanvas.client-TGDPPGXJ.css.map +1 -0
  6. package/dist/{ar-YTUUGK2O.js → ar-OU3DQGC6.js} +53 -7
  7. package/dist/ar-OU3DQGC6.js.map +1 -0
  8. package/dist/{bn-ASGNGPMD.js → bn-PHWCR6AZ.js} +53 -7
  9. package/dist/bn-PHWCR6AZ.js.map +1 -0
  10. package/dist/{chunk-OBQOZCJE.js → chunk-5VDTWRXJ.js} +31 -31
  11. package/dist/{chunk-L3WKRWP3.js → chunk-PCRRBU7H.js} +53 -7
  12. package/dist/chunk-PCRRBU7H.js.map +1 -0
  13. package/dist/{cs-WMYVAOZY.js → cs-NEXYZ62I.js} +53 -7
  14. package/dist/cs-NEXYZ62I.js.map +1 -0
  15. package/dist/{da-FSHHN4D6.js → da-FAT43YCU.js} +53 -7
  16. package/dist/da-FAT43YCU.js.map +1 -0
  17. package/dist/{de-FJFO3TPT.js → de-KRQ3WBCU.js} +53 -7
  18. package/dist/de-KRQ3WBCU.js.map +1 -0
  19. package/dist/{el-XOH4QIAG.js → el-Q4IU3EKC.js} +53 -7
  20. package/dist/el-Q4IU3EKC.js.map +1 -0
  21. package/dist/{en-3FCBW3YD.js → en-2KADE7N4.js} +4 -2
  22. package/dist/{es-HDX4QI7E.js → es-2IO3R2MK.js} +53 -7
  23. package/dist/es-2IO3R2MK.js.map +1 -0
  24. package/dist/{fa-DJ6WTFTJ.js → fa-Q5GOQFXX.js} +53 -7
  25. package/dist/fa-Q5GOQFXX.js.map +1 -0
  26. package/dist/{fi-4S7H7W7U.js → fi-R6NMRWBE.js} +53 -7
  27. package/dist/fi-R6NMRWBE.js.map +1 -0
  28. package/dist/{fr-6UJSYHXC.js → fr-QY4D5E6J.js} +53 -7
  29. package/dist/fr-QY4D5E6J.js.map +1 -0
  30. package/dist/{he-ZZJOHJX2.js → he-X6Y77XHY.js} +53 -7
  31. package/dist/he-X6Y77XHY.js.map +1 -0
  32. package/dist/{hi-HZJTAW7U.js → hi-XL7IOEQM.js} +53 -7
  33. package/dist/hi-XL7IOEQM.js.map +1 -0
  34. package/dist/{id-E3I6ILEM.js → id-QZ4ZZS67.js} +53 -7
  35. package/dist/id-QZ4ZZS67.js.map +1 -0
  36. package/dist/index.css +105 -454
  37. package/dist/index.css.map +1 -1
  38. package/dist/index.d.ts +155 -54
  39. package/dist/index.js +1798 -1637
  40. package/dist/index.js.map +1 -1
  41. package/dist/integrations/css-modules-helper.js +1 -3
  42. package/dist/integrations/css-modules-helper.js.map +1 -1
  43. package/dist/{it-ULAPAD7U.js → it-ME2Q7OB6.js} +53 -7
  44. package/dist/it-ME2Q7OB6.js.map +1 -0
  45. package/dist/{ja-SAHZQ4CZ.js → ja-HX7QASRI.js} +53 -7
  46. package/dist/ja-HX7QASRI.js.map +1 -0
  47. package/dist/{ko-DFU2ADQ4.js → ko-EQO5AHAV.js} +53 -7
  48. package/dist/ko-EQO5AHAV.js.map +1 -0
  49. package/dist/{ms-NWL76XNT.js → ms-UILFSF3I.js} +53 -7
  50. package/dist/ms-UILFSF3I.js.map +1 -0
  51. package/dist/{nl-ATCM76WN.js → nl-NNI45PMK.js} +53 -7
  52. package/dist/nl-NNI45PMK.js.map +1 -0
  53. package/dist/{no-UIAQ5RJF.js → no-MAL5F6P6.js} +53 -7
  54. package/dist/no-MAL5F6P6.js.map +1 -0
  55. package/dist/{pl-NOECQDXD.js → pl-4RMY6JAJ.js} +53 -7
  56. package/dist/pl-4RMY6JAJ.js.map +1 -0
  57. package/dist/{pt-SVWIIUPC.js → pt-VQH2X3QQ.js} +53 -7
  58. package/dist/pt-VQH2X3QQ.js.map +1 -0
  59. package/dist/{ro-NR2DRTZG.js → ro-XXCQO2OG.js} +53 -7
  60. package/dist/ro-XXCQO2OG.js.map +1 -0
  61. package/dist/{sv-STVJ37JP.js → sv-7Z6EJ6U4.js} +53 -7
  62. package/dist/sv-7Z6EJ6U4.js.map +1 -0
  63. package/dist/test-utils.css +1 -1
  64. package/dist/test-utils.css.map +1 -1
  65. package/dist/test-utils.d.ts +1 -1
  66. package/dist/test-utils.js +2 -2
  67. package/dist/test-utils.js.map +1 -1
  68. package/dist/{th-UWQR4K54.js → th-L3DXXYVQ.js} +53 -7
  69. package/dist/th-L3DXXYVQ.js.map +1 -0
  70. package/dist/{tr-WNXZSD27.js → tr-P3DFVLFJ.js} +53 -7
  71. package/dist/tr-P3DFVLFJ.js.map +1 -0
  72. package/dist/{uk-SJRMB47Y.js → uk-7C5D3PXS.js} +53 -7
  73. package/dist/uk-7C5D3PXS.js.map +1 -0
  74. package/dist/{vi-TMRQFES2.js → vi-ZLTLEO7P.js} +53 -7
  75. package/dist/vi-ZLTLEO7P.js.map +1 -0
  76. package/dist/{zh-QOL3LYEM.js → zh-5FHVWDIN.js} +53 -7
  77. package/dist/zh-5FHVWDIN.js.map +1 -0
  78. package/package.json +7 -7
  79. package/src/components/AssistProgress.tsx +144 -134
  80. package/src/components/{EntityFoundLog.tsx → ItemFoundLog.tsx} +12 -7
  81. package/src/components/ProtectedErrorBoundary.css +3 -1
  82. package/src/components/StatusDisplay.css +1 -1
  83. package/src/components/Toast.css +3 -1
  84. package/src/components/__tests__/AssistProgress.test.tsx +216 -148
  85. package/src/components/annotation/annotation-entries.css +0 -4
  86. package/src/components/annotation/references.css +0 -4
  87. package/src/components/image-annotation/AnnotationOverlay.tsx +6 -6
  88. package/src/components/image-annotation/SvgDrawingCanvas.tsx +1 -1
  89. package/src/components/image-annotation/__tests__/AnnotationOverlay.click.test.tsx +7 -9
  90. package/src/components/image-annotation/__tests__/SvgDrawingCanvas.click.test.tsx +1 -2
  91. package/src/components/layout/Header.css +0 -4
  92. package/src/components/layout/LeftSidebar.css +0 -4
  93. package/src/components/modals/ConfigureGenerationStep.tsx +109 -48
  94. package/src/components/modals/ConfigureSearchStep.tsx +23 -40
  95. package/src/components/modals/ReferenceWizardModal.tsx +55 -16
  96. package/src/components/modals/ResourceGenerateModal.tsx +24 -8
  97. package/src/components/modals/ResourceSearchModal.tsx +1 -1
  98. package/src/components/modals/SearchModal.css +0 -12
  99. package/src/components/modals/SearchModal.tsx +1 -1
  100. package/src/components/modals/SearchResultsStep.tsx +2 -20
  101. package/src/components/modals/WizardFooter.tsx +63 -0
  102. package/src/components/modals/__tests__/ConfigureGenerationStep.test.tsx +255 -0
  103. package/src/components/modals/__tests__/ConfigureSearchStep.test.tsx +72 -0
  104. package/src/components/modals/__tests__/ReferenceWizardModal.test.tsx +256 -0
  105. package/src/components/modals/__tests__/ResourceGenerateModal.test.tsx +1 -0
  106. package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +6 -2
  107. package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +6 -2
  108. package/src/components/modals/__tests__/WizardFooter.test.tsx +235 -0
  109. package/src/components/modals/modals.css +16 -42
  110. package/src/components/navigation/NavigationTabs.css +0 -20
  111. package/src/components/pdf-annotation/PdfAnnotationCanvas.css +21 -2
  112. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +2 -2
  113. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +3 -5
  114. package/src/components/resource/AnnotateView.tsx +16 -5
  115. package/src/components/resource/AnnotationHistory.tsx +2 -0
  116. package/src/components/resource/BrowseView.tsx +15 -4
  117. package/src/components/resource/ResourceViewer.tsx +23 -24
  118. package/src/components/resource/__tests__/AnnotateView.focus.test.tsx +50 -0
  119. package/src/components/resource/__tests__/AnnotationHistory.test.tsx +2 -0
  120. package/src/components/resource/__tests__/BrowseView.test.tsx +29 -3
  121. package/src/components/resource/__tests__/ResourceViewer.embeddable.test.tsx +47 -3
  122. package/src/components/resource/event-formatting.ts +0 -3
  123. package/src/components/resource/panels/AssessmentEntry.tsx +1 -1
  124. package/src/components/resource/panels/AssessmentPanel.css +5 -6
  125. package/src/components/resource/panels/AssistSection.css +68 -271
  126. package/src/components/resource/panels/AssistSection.tsx +4 -4
  127. package/src/components/resource/panels/AssistShell.tsx +12 -4
  128. package/src/components/resource/panels/CollaborationPanel.css +47 -22
  129. package/src/components/resource/panels/CollaborationPanel.tsx +93 -2
  130. package/src/components/resource/panels/CommentEntry.tsx +1 -1
  131. package/src/components/resource/panels/CommentsPanel.css +0 -16
  132. package/src/components/resource/panels/HighlightEntry.tsx +1 -1
  133. package/src/components/resource/panels/HighlightPanel.css +0 -7
  134. package/src/components/resource/panels/JsonLdPanel.css +0 -4
  135. package/src/components/resource/panels/ReferenceEntry.tsx +1 -1
  136. package/src/components/resource/panels/ReferencesPanel.css +0 -12
  137. package/src/components/resource/panels/ReferencesPanel.tsx +12 -20
  138. package/src/components/resource/panels/ResourceInfoPanel.css +0 -32
  139. package/src/components/resource/panels/ResourceInfoPanel.tsx +1 -1
  140. package/src/components/resource/panels/StatisticsPanel.css +0 -20
  141. package/src/components/resource/panels/TagEntry.tsx +1 -1
  142. package/src/components/resource/panels/TaggingPanel.css +0 -4
  143. package/src/components/resource/panels/TaggingPanel.tsx +2 -10
  144. package/src/components/resource/panels/UnifiedAnnotationsPanel.css +0 -4
  145. package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +0 -1
  146. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +48 -50
  147. package/src/components/resource/panels/__tests__/AssistShell.test.tsx +11 -6
  148. package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +89 -0
  149. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +1 -2
  150. package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +0 -1
  151. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +44 -36
  152. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +0 -1
  153. package/src/components/resource/panels/__tests__/ReferencesPanel.headless.test.tsx +1 -1
  154. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +34 -53
  155. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +37 -1
  156. package/src/components/resource/panels/__tests__/TagEntry.test.tsx +0 -1
  157. package/src/components/settings/SettingsPanel.css +0 -4
  158. package/src/features/auth/auth.css +2 -26
  159. package/src/features/resource-compose/state/__tests__/compose-page-state-unit.test.ts +25 -1
  160. package/src/features/resource-compose/state/compose-page-state-unit.ts +11 -2
  161. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +55 -0
  162. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +29 -0
  163. package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +53 -3
  164. package/src/features/resource-discovery/state/discover-state-unit.ts +29 -8
  165. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +41 -20
  166. package/src/features/resource-viewer/hooks/__tests__/useResourceViewedReport.test.tsx +63 -0
  167. package/src/features/resource-viewer/hooks/useResourceViewedReport.ts +33 -0
  168. package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +2 -2
  169. package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +1 -1
  170. package/src/styles/core/buttons.css +3 -1
  171. package/src/styles/core/forms.css +0 -21
  172. package/src/styles/core/indicators.css +0 -4
  173. package/src/styles/core/inputs.css +0 -4
  174. package/src/styles/core/progress.css +2 -34
  175. package/src/styles/core/sliders.css +0 -4
  176. package/src/styles/core/toggles.css +0 -4
  177. package/src/styles/features/resource-discovery.css +13 -0
  178. package/src/styles/features/resource-viewer.css +0 -20
  179. package/src/styles/motivations/motivation-assessment.css +2 -2
  180. package/src/styles/panels/history-panel.css +0 -40
  181. package/src/styles/panels/user-panel.css +0 -3
  182. package/src/styles/patterns/panel-helpers.css +0 -27
  183. package/src/styles/patterns/panel-sections.css +0 -59
  184. package/src/styles/patterns/panels-base.css +0 -32
  185. package/translations/ar.json +49 -5
  186. package/translations/bn.json +49 -5
  187. package/translations/cs.json +49 -5
  188. package/translations/da.json +49 -5
  189. package/translations/de.json +49 -5
  190. package/translations/el.json +49 -5
  191. package/translations/en.json +49 -5
  192. package/translations/es.json +49 -5
  193. package/translations/fa.json +49 -5
  194. package/translations/fi.json +49 -5
  195. package/translations/fr.json +49 -5
  196. package/translations/he.json +49 -5
  197. package/translations/hi.json +49 -5
  198. package/translations/id.json +49 -5
  199. package/translations/it.json +49 -5
  200. package/translations/ja.json +49 -5
  201. package/translations/ko.json +49 -5
  202. package/translations/ms.json +49 -5
  203. package/translations/nl.json +49 -5
  204. package/translations/no.json +49 -5
  205. package/translations/pl.json +49 -5
  206. package/translations/pt.json +49 -5
  207. package/translations/ro.json +49 -5
  208. package/translations/sv.json +49 -5
  209. package/translations/th.json +49 -5
  210. package/translations/tr.json +49 -5
  211. package/translations/uk.json +49 -5
  212. package/translations/vi.json +49 -5
  213. package/translations/zh.json +49 -5
  214. package/dist/PdfAnnotationCanvas.client-6ZSF6ZTJ.js.map +0 -1
  215. package/dist/PdfAnnotationCanvas.client-JCJMXWWJ.css.map +0 -1
  216. package/dist/ar-YTUUGK2O.js.map +0 -1
  217. package/dist/bn-ASGNGPMD.js.map +0 -1
  218. package/dist/chunk-L3WKRWP3.js.map +0 -1
  219. package/dist/chunk-XUDKYAVC.js +0 -21
  220. package/dist/chunk-XUDKYAVC.js.map +0 -1
  221. package/dist/cs-WMYVAOZY.js.map +0 -1
  222. package/dist/da-FSHHN4D6.js.map +0 -1
  223. package/dist/de-FJFO3TPT.js.map +0 -1
  224. package/dist/el-XOH4QIAG.js.map +0 -1
  225. package/dist/es-HDX4QI7E.js.map +0 -1
  226. package/dist/fa-DJ6WTFTJ.js.map +0 -1
  227. package/dist/fi-4S7H7W7U.js.map +0 -1
  228. package/dist/fr-6UJSYHXC.js.map +0 -1
  229. package/dist/he-ZZJOHJX2.js.map +0 -1
  230. package/dist/hi-HZJTAW7U.js.map +0 -1
  231. package/dist/id-E3I6ILEM.js.map +0 -1
  232. package/dist/it-ULAPAD7U.js.map +0 -1
  233. package/dist/ja-SAHZQ4CZ.js.map +0 -1
  234. package/dist/ko-DFU2ADQ4.js.map +0 -1
  235. package/dist/ms-NWL76XNT.js.map +0 -1
  236. package/dist/nl-ATCM76WN.js.map +0 -1
  237. package/dist/no-UIAQ5RJF.js.map +0 -1
  238. package/dist/pl-NOECQDXD.js.map +0 -1
  239. package/dist/pt-SVWIIUPC.js.map +0 -1
  240. package/dist/ro-NR2DRTZG.js.map +0 -1
  241. package/dist/sv-STVJ37JP.js.map +0 -1
  242. package/dist/th-UWQR4K54.js.map +0 -1
  243. package/dist/tr-WNXZSD27.js.map +0 -1
  244. package/dist/uk-SJRMB47Y.js.map +0 -1
  245. package/dist/vi-TMRQFES2.js.map +0 -1
  246. package/dist/zh-QOL3LYEM.js.map +0 -1
  247. package/src/integrations/tailwind-plugin.cjs +0 -224
  248. /package/dist/{chunk-OBQOZCJE.js.map → chunk-5VDTWRXJ.js.map} +0 -0
  249. /package/dist/{en-3FCBW3YD.js.map → en-2KADE7N4.js.map} +0 -0
@@ -87,7 +87,7 @@ export function CommentEntry({
87
87
  data-type="comment"
88
88
  data-focused={isFocused ? 'true' : 'false'}
89
89
  onClick={() => {
90
- session?.client.browse.click(comment.id, comment.motivation);
90
+ session?.client.browse.click(comment.id);
91
91
  }}
92
92
  {...hoverProps}
93
93
  >
@@ -31,10 +31,6 @@
31
31
  margin-bottom: var(--semiont-panel-header-margin-bottom);
32
32
  }
33
33
 
34
- [data-theme="dark"] .semiont-comments-panel__title {
35
- color: var(--semiont-text-primary);
36
- }
37
-
38
34
  .semiont-comments-panel__list {
39
35
  flex: 1;
40
36
  overflow-y: auto;
@@ -68,29 +64,17 @@
68
64
  color: var(--semiont-text-primary);
69
65
  }
70
66
 
71
- [data-theme="dark"] .semiont-comments-panel__comment-author {
72
- color: var(--semiont-text-primary);
73
- }
74
-
75
67
  .semiont-comments-panel__comment-time {
76
68
  font-size: var(--semiont-text-xs);
77
69
  color: var(--semiont-text-tertiary);
78
70
  }
79
71
 
80
- [data-theme="dark"] .semiont-comments-panel__comment-time {
81
- color: var(--semiont-text-tertiary);
82
- }
83
-
84
72
  .semiont-comments-panel__comment-text {
85
73
  font-size: var(--semiont-text-sm);
86
74
  color: var(--semiont-text-primary);
87
75
  line-height: 1.5;
88
76
  }
89
77
 
90
- [data-theme="dark"] .semiont-comments-panel__comment-text {
91
- color: var(--semiont-text-primary);
92
- }
93
-
94
78
  .semiont-comments-panel__input-area {
95
79
  padding: var(--semiont-panel-padding);
96
80
  border-top: 1px solid var(--semiont-color-gray-200);
@@ -51,7 +51,7 @@ export function HighlightEntry({
51
51
  data-type="highlight"
52
52
  data-focused={isFocused ? 'true' : 'false'}
53
53
  onClick={() => {
54
- session?.client.browse.click(highlight.id, highlight.motivation);
54
+ session?.client.browse.click(highlight.id);
55
55
  }}
56
56
  {...hoverProps}
57
57
  >
@@ -30,10 +30,6 @@
30
30
  letter-spacing: 0.05em;
31
31
  }
32
32
 
33
- [data-theme="dark"] .semiont-highlight-panel__label {
34
- color: var(--semiont-text-secondary);
35
- }
36
-
37
33
  .semiont-highlight-panel__colors {
38
34
  display: grid;
39
35
  grid-template-columns: repeat(5, 1fr);
@@ -58,6 +54,3 @@
58
54
  transform: scale(1.1);
59
55
  }
60
56
 
61
- [data-theme="dark"] .semiont-highlight-panel__color--selected {
62
- border-color: var(--semiont-text-primary);
63
- }
@@ -24,10 +24,6 @@
24
24
  color: var(--semiont-text-primary);
25
25
  }
26
26
 
27
- [data-theme="dark"] .semiont-jsonld-panel__title {
28
- color: var(--semiont-text-primary);
29
- }
30
-
31
27
  .semiont-jsonld-panel__editor {
32
28
  flex: 1;
33
29
  overflow: hidden;
@@ -117,7 +117,7 @@ export function ReferenceEntry({
117
117
  data-type="reference"
118
118
  data-focused={isFocused ? 'true' : 'false'}
119
119
  onClick={() => {
120
- session?.client.browse.click(reference.id, reference.motivation);
120
+ session?.client.browse.click(reference.id);
121
121
  }}
122
122
  {...hoverProps}
123
123
  >
@@ -37,30 +37,18 @@
37
37
  margin-bottom: var(--semiont-panel-header-margin-bottom);
38
38
  }
39
39
 
40
- [data-theme="dark"] .semiont-references-panel__title {
41
- color: var(--semiont-text-primary);
42
- }
43
-
44
40
  .semiont-references-panel__path {
45
41
  font-size: var(--semiont-text-sm);
46
42
  color: var(--semiont-text-tertiary);
47
43
  margin-top: var(--semiont-panel-padding-xs);
48
44
  }
49
45
 
50
- [data-theme="dark"] .semiont-references-panel__path {
51
- color: var(--semiont-text-tertiary);
52
- }
53
-
54
46
  .semiont-references-panel__count {
55
47
  font-size: var(--semiont-text-sm);
56
48
  color: var(--semiont-text-tertiary);
57
49
  margin-top: var(--semiont-panel-padding-xs);
58
50
  }
59
51
 
60
- [data-theme="dark"] .semiont-references-panel__count {
61
- color: var(--semiont-text-tertiary);
62
- }
63
-
64
52
  /* Reference Icon Group — status icon + hover-reveal unlink */
65
53
  .semiont-reference-icon-group {
66
54
  position: relative;
@@ -1,12 +1,13 @@
1
1
  'use client';
2
2
 
3
3
  import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
4
+ import { assistProgressTranslations } from '../../../lib/assist-progress-copy';
4
5
  import { useTranslations } from '../../../contexts/TranslationContext';
5
6
  import type { SemiontSession } from '@semiont/sdk';
6
7
  import { useSessionEventSubscriptions } from '../../../hooks/useSessionEventSubscriptions';
7
8
  import type { RouteBuilder, LinkComponentProps } from '../../../contexts/RoutingContext';
8
9
  import { AssistShell } from './AssistShell';
9
- import { EntityFoundLog } from '../../EntityFoundLog';
10
+ import { ItemFoundLog } from '../../ItemFoundLog';
10
11
  import { ReferenceEntry } from './ReferenceEntry';
11
12
  import type { components, Selector } from '@semiont/core';
12
13
  import { getTextPositionSelector, getTargetSelector } from '@semiont/core';
@@ -126,7 +127,7 @@ export function ReferencesPanel({
126
127
  // lives in one namespace so the same words aren't re-translated per panel.
127
128
  const ta = useTranslations('AssistProgress');
128
129
  const [selectedEntityTypes, setSelectedEntityTypes] = useState<string[]>([]);
129
- const [lastAnnotationLog, setLastDetectionLog] = useState<Array<{ entityType: string; foundCount: number }> | null>(null);
130
+ const [lastAnnotationLog, setLastDetectionLog] = useState<Array<{ value: string; foundCount: number }> | null>(null);
130
131
  const [pendingEntityTypes, setPendingEntityTypes] = useState<string[]>([]);
131
132
  const [includeDescriptiveReferences, setIncludeDescriptiveReferences] = useState(false);
132
133
  const [focusedAnnotationId, setFocusedAnnotationId] = useState<string | null>(null);
@@ -243,8 +244,8 @@ export function ReferencesPanel({
243
244
 
244
245
  // Save detection log when detection completes
245
246
  // Only depends on isAssisting boolean to avoid infinite loops from array reference changes
246
- // Trade-off: If completedEntityTypes changes while isAssisting stays false, we won't update
247
- // This is acceptable because in practice, completedEntityTypes only changes when annotation finishes
247
+ // Trade-off: If completedItems changes while isAssisting stays false, we won't update
248
+ // This is acceptable because in practice, completedItems only changes when annotation finishes
248
249
  useEffect(() => {
249
250
  // When annotation starts, reset the flag
250
251
  if (isAssisting) {
@@ -253,12 +254,12 @@ export function ReferencesPanel({
253
254
  }
254
255
 
255
256
  // When annotation is complete and we haven't saved yet, save the log
256
- if (!hasSavedLogRef.current && progress?.completedEntityTypes) {
257
+ if (!hasSavedLogRef.current && progress?.completedItems) {
257
258
  hasSavedLogRef.current = true;
258
- setLastDetectionLog(progress.completedEntityTypes);
259
+ setLastDetectionLog(progress.completedItems);
259
260
  setSelectedEntityTypes([]);
260
261
  }
261
- }, [isAssisting, progress?.completedEntityTypes]); // Both dependencies needed to annotation completion
262
+ }, [isAssisting, progress?.completedItems]); // Both dependencies needed to annotation completion
262
263
 
263
264
  const togglePendingEntityType = (type: string) => {
264
265
  setPendingEntityTypes(prev =>
@@ -371,24 +372,15 @@ export function ReferencesPanel({
371
372
  progressProps={{
372
373
  onCancel: () => session?.client.job.cancelRequest('annotation'),
373
374
  onDismiss: () => session?.client.mark.dismissProgress(),
374
- translations: {
375
- title: t('annotationProgressTitle'),
376
- cancel: t('cancelAnnotation'),
377
- inProgress: t('annotating'),
378
- complete: t('complete'),
379
- failed: t('failed'),
380
- found: (count) => t('found', { count }),
381
- current: (entityType) => t('current', { entityType }),
382
- paramsTitle: ta('paramsTitle'),
383
- processing: (label) => ta('processing', { label }),
384
- close: ta('close'),
385
- },
375
+ translations: assistProgressTranslations(ta, {
376
+ found: (count: number) => t('found', { count }),
377
+ }),
386
378
  }}
387
379
  form={
388
380
  <>
389
381
  {/* Completed annotation log - shown after completion */}
390
382
  {lastAnnotationLog && (
391
- <EntityFoundLog
383
+ <ItemFoundLog
392
384
  entries={lastAnnotationLog}
393
385
  formatFound={(count) => t('found', { count })}
394
386
  />
@@ -21,10 +21,6 @@
21
21
  color: var(--semiont-text-primary);
22
22
  }
23
23
 
24
- [data-theme="dark"] .semiont-resource-info-panel__title {
25
- color: var(--semiont-text-primary);
26
- }
27
-
28
24
  .semiont-resource-info-panel__section {
29
25
  margin-bottom: var(--semiont-panel-gap);
30
26
  }
@@ -40,28 +36,16 @@
40
36
  margin-bottom: var(--semiont-panel-gap-sm);
41
37
  }
42
38
 
43
- [data-theme="dark"] .semiont-resource-info-panel__heading {
44
- color: var(--semiont-text-primary);
45
- }
46
-
47
39
  .semiont-resource-info-panel__value {
48
40
  font-size: var(--semiont-text-sm);
49
41
  color: var(--semiont-text-primary);
50
42
  }
51
43
 
52
- [data-theme="dark"] .semiont-resource-info-panel__value {
53
- color: var(--semiont-text-primary);
54
- }
55
-
56
44
  .semiont-resource-info-panel__value--empty {
57
45
  color: var(--semiont-text-tertiary);
58
46
  font-style: italic;
59
47
  }
60
48
 
61
- [data-theme="dark"] .semiont-resource-info-panel__value--empty {
62
- color: var(--semiont-text-tertiary);
63
- }
64
-
65
49
  .semiont-resource-info-panel__metric {
66
50
  display: flex;
67
51
  align-items: center;
@@ -78,20 +62,12 @@
78
62
  font-size: var(--semiont-text-sm);
79
63
  }
80
64
 
81
- [data-theme="dark"] .semiont-resource-info-panel__metric-label {
82
- color: var(--semiont-text-tertiary);
83
- }
84
-
85
65
  .semiont-resource-info-panel__metric-value {
86
66
  color: var(--semiont-text-primary);
87
67
  font-size: var(--semiont-text-sm);
88
68
  font-weight: var(--semiont-font-medium);
89
69
  }
90
70
 
91
- [data-theme="dark"] .semiont-resource-info-panel__metric-value {
92
- color: var(--semiont-text-primary);
93
- }
94
-
95
71
  .semiont-resource-info-panel__tags {
96
72
  display: flex;
97
73
  flex-wrap: wrap;
@@ -142,10 +118,6 @@
142
118
  margin-right: var(--semiont-panel-gap-sm);
143
119
  }
144
120
 
145
- [data-theme="dark"] .semiont-resource-info-panel__label {
146
- color: var(--semiont-text-tertiary);
147
- }
148
-
149
121
  .semiont-resource-info-panel__tag-list {
150
122
  display: flex;
151
123
  flex-wrap: wrap;
@@ -169,10 +141,6 @@
169
141
  line-height: 1.5;
170
142
  }
171
143
 
172
- [data-theme="dark"] .semiont-resource-info-panel__description {
173
- color: var(--semiont-text-tertiary);
174
- }
175
-
176
144
  /* Resource Info Panel Buttons */
177
145
  .semiont-resource-button {
178
146
  width: 100%;
@@ -155,7 +155,7 @@ export function ResourceInfoPanel({
155
155
  <button
156
156
  key={id}
157
157
  className="semiont-resource-info-panel__link"
158
- onClick={() => session?.client.browse.navigateReference(makeResourceId(id))}
158
+ onClick={() => session?.client.browse.openResource(makeResourceId(id))}
159
159
  >
160
160
  {i > 0 && ', '}{id}
161
161
  </button>
@@ -57,10 +57,6 @@
57
57
  color: var(--semiont-text-secondary);
58
58
  }
59
59
 
60
- [data-theme="dark"] .semiont-statistics-panel__label {
61
- color: var(--semiont-text-secondary);
62
- }
63
-
64
60
  .semiont-statistics-panel__value {
65
61
  font-size: var(--semiont-text-lg);
66
62
  font-weight: var(--semiont-font-semibold);
@@ -68,10 +64,6 @@
68
64
  margin-left: auto;
69
65
  }
70
66
 
71
- [data-theme="dark"] .semiont-statistics-panel__value {
72
- color: var(--semiont-text-primary);
73
- }
74
-
75
67
  /* Sub-items (indented) */
76
68
  .semiont-statistics-panel__subitems {
77
69
  width: 100%;
@@ -93,20 +85,12 @@
93
85
  color: var(--semiont-text-tertiary);
94
86
  }
95
87
 
96
- [data-theme="dark"] .semiont-statistics-panel__sublabel {
97
- color: var(--semiont-text-tertiary);
98
- }
99
-
100
88
  .semiont-statistics-panel__subvalue {
101
89
  font-size: var(--semiont-text-sm);
102
90
  font-weight: var(--semiont-font-medium);
103
91
  color: var(--semiont-text-secondary);
104
92
  }
105
93
 
106
- [data-theme="dark"] .semiont-statistics-panel__subvalue {
107
- color: var(--semiont-text-secondary);
108
- }
109
-
110
94
  /* Entity Types */
111
95
  .semiont-statistics-panel__entity-types {
112
96
  display: flex;
@@ -140,8 +124,4 @@
140
124
  flex: 1;
141
125
  }
142
126
 
143
- [data-theme="dark"] .semiont-statistics-panel__entity-name {
144
- color: var(--semiont-text-primary);
145
- }
146
-
147
127
  /* Tags use .semiont-tag from core/tags.css */
@@ -52,7 +52,7 @@ export function TagEntry({
52
52
  <div
53
53
  ref={ref}
54
54
  onClick={() => {
55
- session?.client.browse.click(tag.id, tag.motivation);
55
+ session?.client.browse.click(tag.id);
56
56
  }}
57
57
  {...hoverProps}
58
58
  className={`semiont-annotation-entry${isHovered ? ' semiont-annotation-pulse' : ''}`}
@@ -30,10 +30,6 @@
30
30
  letter-spacing: 0.05em;
31
31
  }
32
32
 
33
- [data-theme="dark"] .semiont-tagging-panel__label {
34
- color: var(--semiont-text-secondary);
35
- }
36
-
37
33
  .semiont-tagging-panel__input {
38
34
  padding: var(--semiont-panel-padding-sm);
39
35
  background: var(--semiont-bg-secondary);
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
4
+ import { assistProgressTranslations } from '../../../lib/assist-progress-copy';
4
5
  import { isReady } from '@semiont/sdk';
5
6
  import { useTranslations } from '../../../contexts/TranslationContext';
6
7
  import { useObservable } from '../../../hooks/useObservable';
@@ -364,17 +365,8 @@ export function TaggingPanel({
364
365
  isAssisting={isAssisting}
365
366
  progress={progress}
366
367
  progressProps={{
367
- showPercentBar: true,
368
368
  onDismiss: handleDismissProgress,
369
- translations: {
370
- cancel: t('cancel'),
371
- inProgress: t('annotating'),
372
- complete: t('complete'),
373
- failed: t('failed'),
374
- paramsTitle: ta('paramsTitle'),
375
- processing: (label) => ta('processing', { label }),
376
- close: ta('close'),
377
- },
369
+ translations: assistProgressTranslations(ta),
378
370
  }}
379
371
  form={
380
372
  <>
@@ -18,10 +18,6 @@
18
18
  color: var(--semiont-text-primary);
19
19
  }
20
20
 
21
- [data-theme="dark"] .semiont-unified-panel__title {
22
- color: var(--semiont-text-primary);
23
- }
24
-
25
21
  .semiont-unified-panel__tabs {
26
22
  display: flex;
27
23
  gap: 0;
@@ -185,7 +185,6 @@ describe('AssessmentEntry', () => {
185
185
 
186
186
  expect(clickHandler).toHaveBeenCalledWith({
187
187
  annotationId: 'assessment-1',
188
- motivation: 'assessing',
189
188
  });
190
189
 
191
190
  subscription.unsubscribe();
@@ -21,7 +21,7 @@ import type { SemiontSession } from '@semiont/sdk';
21
21
  import { AssistSection } from '../AssistSection';
22
22
 
23
23
  // Mock translations
24
- const mockT = vi.fn((key: string) => {
24
+ const mockT = vi.fn((key: string, params?: Record<string, unknown>) => {
25
25
  const translations: Record<string, string> = {
26
26
  annotateHighlights: 'Annotate Highlights',
27
27
  annotateAssessments: 'Annotate Assessments',
@@ -45,7 +45,29 @@ const mockT = vi.fn((key: string) => {
45
45
  annotate: 'Annotate',
46
46
  annotating: 'Annotating...',
47
47
  };
48
- return translations[key] || key;
48
+ // P3: the coded status line. Interpolates `{{var}}` like production —
49
+ // a mock that ignored params would let copy that cannot interpolate in the
50
+ // app still pass here.
51
+ Object.assign(translations, {
52
+ codeLoading: 'Loading…',
53
+ codeAnalyzing: 'Marking…',
54
+ codeDetectingEntities: 'Marking…',
55
+ codeCompleteCreated: 'Created {{count}} {{kind}}',
56
+ kindHighlight: 'highlights',
57
+ subject: '{{kind}}: {{label}}',
58
+ subjectWithPosition: '{{kind}}: {{label}} ({{done}} of {{total}})',
59
+ subjectKindEntityType: 'Entity type',
60
+ subjectKindCategory: 'Category',
61
+ // CLEAN-PROGRESS D3: the widget's own strings now come from the
62
+ // AssistProgress namespace, not from each panel's.
63
+ cancel: 'Cancel',
64
+ inProgress: 'Annotating...',
65
+ });
66
+ let out = translations[key] || key;
67
+ for (const [k, v] of Object.entries((params ?? {}) as Record<string, unknown>)) {
68
+ out = out.replace(`{{${k}}}`, String(v));
69
+ }
70
+ return out;
49
71
  });
50
72
 
51
73
  vi.mock('../../../../contexts/TranslationContext', () => ({
@@ -71,41 +93,37 @@ describe('AssistSection', () => {
71
93
  });
72
94
 
73
95
  describe('Progress Display', () => {
74
- it('should render progress message when progress prop provided', () => {
96
+ it('should render the translated status line when progress prop provided', () => {
75
97
  renderWithProviders(
76
98
  <AssistSection
77
99
  session={session}
78
100
  annotationType="highlight"
79
101
  isAssisting={true}
80
102
  progress={{
81
- stage: 'analyzing',
82
103
  percentage: 30,
83
- message: 'Analyzing text for highlights...',
84
104
  }}
85
105
  />
86
106
  );
87
107
 
88
- expect(screen.getByText('Analyzing text for highlights...')).toBeInTheDocument();
108
+ expect(screen.getByText('Annotating...')).toBeInTheDocument();
89
109
  });
90
110
 
91
- it('should render progress message with sparkle icon', () => {
111
+ it('should render the status line with sparkle icon', () => {
92
112
  renderWithProviders(
93
113
  <AssistSection
94
114
  session={session}
95
115
  annotationType="highlight"
96
116
  isAssisting={true}
97
117
  progress={{
98
- stage: 'analyzing',
99
118
  percentage: 0,
100
- message: 'Processing...',
101
119
  }}
102
120
  />
103
121
  );
104
122
 
105
- // Check for icon and message
106
- const progressDiv = screen.getByText('Processing...').closest('.semiont-annotation-progress__message');
123
+ // Check for icon and status text
124
+ const progressDiv = screen.getByText('Annotating...').closest('.semiont-assist-progress__status');
107
125
  expect(progressDiv).toBeInTheDocument();
108
- expect(progressDiv?.querySelector('.semiont-annotation-progress__icon')).toBeInTheDocument();
126
+ expect(progressDiv?.querySelector('.semiont-assist-progress__icon')).toBeInTheDocument();
109
127
  });
110
128
 
111
129
  it('should render request parameters when provided', () => {
@@ -115,22 +133,25 @@ describe('AssistSection', () => {
115
133
  annotationType="highlight"
116
134
  isAssisting={true}
117
135
  progress={{
118
- stage: 'analyzing',
119
136
  percentage: 0,
120
- message: 'Analyzing...',
121
137
  requestParams: [
122
- { label: 'Instructions', value: 'Find important points' },
123
- { label: 'Density', value: '5' },
138
+ { label: 'instructions', value: 'Find important points' },
139
+ { label: 'density', value: '5' },
124
140
  ],
125
141
  }}
126
142
  />
127
143
  );
128
144
 
129
- expect(screen.getByText('paramsTitle')).toBeInTheDocument();
145
+ expect(screen.getByTestId('semiont-assist-params')).toBeInTheDocument();
130
146
  expect(screen.getByText('Find important points')).toBeInTheDocument();
131
- expect(screen.getByText(/Instructions:/)).toBeInTheDocument();
132
147
  expect(screen.getByText('5')).toBeInTheDocument();
133
- expect(screen.getByText(/Density:/)).toBeInTheDocument();
148
+ // The wire carries a CODE; the label the user reads is LOOKED UP. Under
149
+ // the test translator that lookup echoes the key, so seeing the key is
150
+ // the assertion that the label went through translation — and that the
151
+ // raw wire code ('instructions') never reaches the screen.
152
+ expect(screen.getByText(/paramInstructions:/)).toBeInTheDocument();
153
+ expect(screen.getByText(/paramDensity:/)).toBeInTheDocument();
154
+ expect(screen.queryByText(/^instructions:/)).toBeNull();
134
155
  });
135
156
 
136
157
  it('should hide form when progress is present', () => {
@@ -140,9 +161,7 @@ describe('AssistSection', () => {
140
161
  annotationType="highlight"
141
162
  isAssisting={true}
142
163
  progress={{
143
- stage: 'analyzing',
144
164
  percentage: 0,
145
- message: 'Analyzing...',
146
165
  }}
147
166
  />
148
167
  );
@@ -189,15 +208,14 @@ describe('AssistSection', () => {
189
208
  annotationType="highlight"
190
209
  isAssisting={false}
191
210
  progress={{
192
- stage: 'complete',
211
+ message: { code: 'complete-created', count: 3, kind: 'highlight' },
193
212
  percentage: 100,
194
- message: 'Complete! Created 14 highlights',
195
213
  }}
196
214
  />
197
215
  );
198
216
 
199
- // Progress should still be visible
200
- expect(screen.getByText('Complete! Created 14 highlights')).toBeInTheDocument();
217
+ // Progress should still be visible, with the translated terminal copy
218
+ expect(screen.getByText('Created 3 highlights')).toBeInTheDocument();
201
219
  // Form should NOT be visible
202
220
  expect(screen.queryByPlaceholderText('Enter custom instructions...')).not.toBeInTheDocument();
203
221
  });
@@ -455,42 +473,24 @@ describe('AssistSection', () => {
455
473
  });
456
474
 
457
475
  describe('Edge Cases', () => {
458
- it('should handle empty progress message', () => {
476
+ it('should handle progress without a message', () => {
459
477
  renderWithProviders(
460
478
  <AssistSection
461
479
  session={session}
462
480
  annotationType="highlight"
463
481
  isAssisting={true}
464
482
  progress={{
465
- stage: 'analyzing',
466
483
  percentage: 0,
467
- message: '',
468
484
  }}
469
485
  />
470
486
  );
471
487
 
472
- // Should render progress section even with empty message
473
- const progressDiv = document.querySelector('.semiont-annotation-progress');
488
+ // Renders the progress section with the translated status line — the
489
+ // wire carries a code (or nothing), never a sentence to fall back on.
490
+ const progressDiv = document.querySelector('.semiont-assist-progress');
474
491
  expect(progressDiv).toBeInTheDocument();
475
492
  });
476
493
 
477
- it('should handle progress without percentage', () => {
478
- renderWithProviders(
479
- <AssistSection
480
- session={session}
481
- annotationType="highlight"
482
- isAssisting={true}
483
- progress={{
484
- stage: 'analyzing',
485
- percentage: 0,
486
- message: 'Processing...',
487
- }}
488
- />
489
- );
490
-
491
- expect(screen.getByText('Processing...')).toBeInTheDocument();
492
- });
493
-
494
494
  it('should handle progress with empty requestParams array', () => {
495
495
  renderWithProviders(
496
496
  <AssistSection
@@ -498,15 +498,13 @@ describe('AssistSection', () => {
498
498
  annotationType="highlight"
499
499
  isAssisting={true}
500
500
  progress={{
501
- stage: 'analyzing',
502
501
  percentage: 0,
503
- message: 'Processing...',
504
502
  requestParams: [],
505
503
  }}
506
504
  />
507
505
  );
508
506
 
509
- expect(screen.queryByText('paramsTitle')).not.toBeInTheDocument();
507
+ expect(screen.queryByTestId('semiont-assist-params')).not.toBeInTheDocument();
510
508
  });
511
509
  });
512
510
  });