@semiont/react-ui 0.5.24 → 0.5.25

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 (151) hide show
  1. package/dist/{PdfAnnotationCanvas.client-V7Q3BEEQ.js → PdfAnnotationCanvas.client-EHQWF6BR.js} +45 -10
  2. package/dist/PdfAnnotationCanvas.client-EHQWF6BR.js.map +1 -0
  3. package/dist/{ar-JRTKCMTF.js → ar-CULRHLNG.js} +20 -6
  4. package/dist/ar-CULRHLNG.js.map +1 -0
  5. package/dist/{bn-LO6EDSCC.js → bn-HYR7CEL2.js} +20 -6
  6. package/dist/bn-HYR7CEL2.js.map +1 -0
  7. package/dist/{chunk-5Y5JDCKC.js → chunk-NH6L2GIL.js} +20 -6
  8. package/dist/chunk-NH6L2GIL.js.map +1 -0
  9. package/dist/{chunk-4QMTEPQ3.js → chunk-TG2XQEC4.js} +31 -31
  10. package/dist/{cs-LCHHOR4O.js → cs-YBRWY7NH.js} +20 -6
  11. package/dist/cs-YBRWY7NH.js.map +1 -0
  12. package/dist/{da-TARGPMJR.js → da-PHDEOBV3.js} +20 -6
  13. package/dist/da-PHDEOBV3.js.map +1 -0
  14. package/dist/{de-SBH4QBPJ.js → de-O4UCCVLJ.js} +20 -6
  15. package/dist/de-O4UCCVLJ.js.map +1 -0
  16. package/dist/{el-2D2OLGWB.js → el-MVGO6WZV.js} +20 -6
  17. package/dist/el-MVGO6WZV.js.map +1 -0
  18. package/dist/{en-QFIEG3CA.js → en-2KQILFKQ.js} +4 -2
  19. package/dist/{es-U6YK2LX6.js → es-USSLXQY7.js} +20 -6
  20. package/dist/es-USSLXQY7.js.map +1 -0
  21. package/dist/{fa-S7SZE37M.js → fa-WMAREFWY.js} +20 -6
  22. package/dist/fa-WMAREFWY.js.map +1 -0
  23. package/dist/{fi-CBL3NIXN.js → fi-B3NBNOTS.js} +20 -6
  24. package/dist/fi-B3NBNOTS.js.map +1 -0
  25. package/dist/{fr-EABUHV6S.js → fr-TXYK5T5W.js} +20 -6
  26. package/dist/fr-TXYK5T5W.js.map +1 -0
  27. package/dist/{he-THWD244Y.js → he-JCJACW5D.js} +20 -6
  28. package/dist/he-JCJACW5D.js.map +1 -0
  29. package/dist/{hi-GHGFZJ44.js → hi-VOQLZNJU.js} +20 -6
  30. package/dist/hi-VOQLZNJU.js.map +1 -0
  31. package/dist/{id-POZOUMDW.js → id-BFN5RZNZ.js} +20 -6
  32. package/dist/id-BFN5RZNZ.js.map +1 -0
  33. package/dist/index.css +0 -36
  34. package/dist/index.css.map +1 -1
  35. package/dist/index.d.ts +85 -24
  36. package/dist/index.js +1763 -1690
  37. package/dist/index.js.map +1 -1
  38. package/dist/{it-KDYJADSH.js → it-TWWDHKKM.js} +20 -6
  39. package/dist/it-TWWDHKKM.js.map +1 -0
  40. package/dist/{ja-Z5Z6ZF3P.js → ja-YRQLEBFM.js} +20 -6
  41. package/dist/ja-YRQLEBFM.js.map +1 -0
  42. package/dist/{ko-7X3XUXRN.js → ko-PG6B3CRB.js} +20 -6
  43. package/dist/ko-PG6B3CRB.js.map +1 -0
  44. package/dist/{ms-BTWEIW43.js → ms-7EZECVKM.js} +20 -6
  45. package/dist/ms-7EZECVKM.js.map +1 -0
  46. package/dist/{nl-IS2CGF5I.js → nl-HP753YAP.js} +20 -6
  47. package/dist/nl-HP753YAP.js.map +1 -0
  48. package/dist/{no-AAMEVA26.js → no-JUD5WX3N.js} +20 -6
  49. package/dist/no-JUD5WX3N.js.map +1 -0
  50. package/dist/{pl-PVXUQYFT.js → pl-RVUL4CBM.js} +20 -6
  51. package/dist/pl-RVUL4CBM.js.map +1 -0
  52. package/dist/{pt-3ITQ76TL.js → pt-RPOVD4QM.js} +20 -6
  53. package/dist/pt-RPOVD4QM.js.map +1 -0
  54. package/dist/{ro-FRB4IIVS.js → ro-DMYWQTRD.js} +20 -6
  55. package/dist/ro-DMYWQTRD.js.map +1 -0
  56. package/dist/{sv-DS3RO24M.js → sv-DMZ4FGXD.js} +20 -6
  57. package/dist/sv-DMZ4FGXD.js.map +1 -0
  58. package/dist/test-utils.js +2 -2
  59. package/dist/{th-AX66MWWB.js → th-4HVBJBQ2.js} +20 -6
  60. package/dist/th-4HVBJBQ2.js.map +1 -0
  61. package/dist/{tr-7KTB67TT.js → tr-6BDPU5ML.js} +20 -6
  62. package/dist/tr-6BDPU5ML.js.map +1 -0
  63. package/dist/{uk-SMQS2MAQ.js → uk-TBZBT2TL.js} +20 -6
  64. package/dist/uk-TBZBT2TL.js.map +1 -0
  65. package/dist/{vi-D3JXL2EZ.js → vi-UMKZKZL3.js} +20 -6
  66. package/dist/vi-UMKZKZL3.js.map +1 -0
  67. package/dist/{zh-S754AWFS.js → zh-YBJWJJYB.js} +20 -6
  68. package/dist/zh-YBJWJJYB.js.map +1 -0
  69. package/package.json +8 -8
  70. package/src/components/AssistProgress.tsx +42 -30
  71. package/src/components/EntityFoundLog.tsx +38 -0
  72. package/src/components/__tests__/AssistProgress.test.tsx +86 -28
  73. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +112 -12
  74. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +247 -1
  75. package/src/components/resource/AnnotateView.tsx +14 -7
  76. package/src/components/resource/BrowseView.tsx +2 -7
  77. package/src/components/resource/DownloadFileLink.tsx +49 -0
  78. package/src/components/resource/__tests__/AnnotateView.focus.test.tsx +58 -0
  79. package/src/components/resource/__tests__/download-link.test.tsx +129 -0
  80. package/src/components/resource/panels/AssistSection.css +0 -43
  81. package/src/components/resource/panels/AssistSection.tsx +11 -2
  82. package/src/components/resource/panels/AssistShell.tsx +5 -1
  83. package/src/components/resource/panels/ReferencesPanel.tsx +12 -13
  84. package/src/components/resource/panels/TaggingPanel.tsx +21 -1
  85. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +2 -2
  86. package/src/components/resource/panels/__tests__/AssistShell.test.tsx +9 -4
  87. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +1 -1
  88. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +26 -0
  89. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +32 -3
  90. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +17 -6
  91. package/translations/ar.json +17 -5
  92. package/translations/bn.json +17 -5
  93. package/translations/cs.json +17 -5
  94. package/translations/da.json +17 -5
  95. package/translations/de.json +17 -5
  96. package/translations/el.json +17 -5
  97. package/translations/en.json +17 -5
  98. package/translations/es.json +17 -5
  99. package/translations/fa.json +17 -5
  100. package/translations/fi.json +17 -5
  101. package/translations/fr.json +17 -5
  102. package/translations/he.json +17 -5
  103. package/translations/hi.json +17 -5
  104. package/translations/id.json +17 -5
  105. package/translations/it.json +17 -5
  106. package/translations/ja.json +17 -5
  107. package/translations/ko.json +17 -5
  108. package/translations/ms.json +17 -5
  109. package/translations/nl.json +17 -5
  110. package/translations/no.json +17 -5
  111. package/translations/pl.json +17 -5
  112. package/translations/pt.json +17 -5
  113. package/translations/ro.json +17 -5
  114. package/translations/sv.json +17 -5
  115. package/translations/th.json +17 -5
  116. package/translations/tr.json +17 -5
  117. package/translations/uk.json +17 -5
  118. package/translations/vi.json +17 -5
  119. package/translations/zh.json +17 -5
  120. package/dist/PdfAnnotationCanvas.client-V7Q3BEEQ.js.map +0 -1
  121. package/dist/ar-JRTKCMTF.js.map +0 -1
  122. package/dist/bn-LO6EDSCC.js.map +0 -1
  123. package/dist/chunk-5Y5JDCKC.js.map +0 -1
  124. package/dist/cs-LCHHOR4O.js.map +0 -1
  125. package/dist/da-TARGPMJR.js.map +0 -1
  126. package/dist/de-SBH4QBPJ.js.map +0 -1
  127. package/dist/el-2D2OLGWB.js.map +0 -1
  128. package/dist/es-U6YK2LX6.js.map +0 -1
  129. package/dist/fa-S7SZE37M.js.map +0 -1
  130. package/dist/fi-CBL3NIXN.js.map +0 -1
  131. package/dist/fr-EABUHV6S.js.map +0 -1
  132. package/dist/he-THWD244Y.js.map +0 -1
  133. package/dist/hi-GHGFZJ44.js.map +0 -1
  134. package/dist/id-POZOUMDW.js.map +0 -1
  135. package/dist/it-KDYJADSH.js.map +0 -1
  136. package/dist/ja-Z5Z6ZF3P.js.map +0 -1
  137. package/dist/ko-7X3XUXRN.js.map +0 -1
  138. package/dist/ms-BTWEIW43.js.map +0 -1
  139. package/dist/nl-IS2CGF5I.js.map +0 -1
  140. package/dist/no-AAMEVA26.js.map +0 -1
  141. package/dist/pl-PVXUQYFT.js.map +0 -1
  142. package/dist/pt-3ITQ76TL.js.map +0 -1
  143. package/dist/ro-FRB4IIVS.js.map +0 -1
  144. package/dist/sv-DS3RO24M.js.map +0 -1
  145. package/dist/th-AX66MWWB.js.map +0 -1
  146. package/dist/tr-7KTB67TT.js.map +0 -1
  147. package/dist/uk-SMQS2MAQ.js.map +0 -1
  148. package/dist/vi-D3JXL2EZ.js.map +0 -1
  149. package/dist/zh-S754AWFS.js.map +0 -1
  150. /package/dist/{chunk-4QMTEPQ3.js.map → chunk-TG2XQEC4.js.map} +0 -0
  151. /package/dist/{en-QFIEG3CA.js.map → en-2KQILFKQ.js.map} +0 -0
@@ -2,6 +2,11 @@
2
2
  import "./chunk-O23TLLXW.js";
3
3
 
4
4
  // translations/zh.json
5
+ var AssistProgress = {
6
+ close: "\u5173\u95ED",
7
+ paramsTitle: "\u8BF7\u6C42\u53C2\u6570\uFF1A",
8
+ processing: "\u5F53\u524D\uFF1A{{label}}"
9
+ };
5
10
  var Toolbar = {
6
11
  annotations: "\u6CE8\u91CA",
7
12
  history: "\u5386\u53F2",
@@ -108,7 +113,9 @@ var CommentsPanel = {
108
113
  densityDense: "\u5BC6\u96C6",
109
114
  fragmentSelected: "\u5DF2\u9009\u62E9\u7247\u6BB5",
110
115
  imageRegionSelected: "\u5DF2\u9009\u62E9\u56FE\u50CF\u533A\u57DF",
111
- closeProgress: "\u5173\u95ED"
116
+ complete: "\u6CE8\u91CA\u5B8C\u6210\uFF01",
117
+ failed: "\u6CE8\u91CA\u5931\u8D25",
118
+ densityPerWords: "\u6BCF 2000 \u8BCD {{density}} \u4E2A"
112
119
  };
113
120
  var HighlightPanel = {
114
121
  title: "\u9AD8\u4EAE",
@@ -123,7 +130,9 @@ var HighlightPanel = {
123
130
  densityLabel: "\u5BC6\u5EA6",
124
131
  densitySparse: "\u7A00\u758F",
125
132
  densityDense: "\u5BC6\u96C6",
126
- closeProgress: "\u5173\u95ED"
133
+ complete: "\u6CE8\u91CA\u5B8C\u6210\uFF01",
134
+ failed: "\u6CE8\u91CA\u5931\u8D25",
135
+ densityPerWords: "\u6BCF 2000 \u8BCD {{density}} \u4E2A"
127
136
  };
128
137
  var AssessmentPanel = {
129
138
  title: "\u8BC4\u4F30",
@@ -148,7 +157,9 @@ var AssessmentPanel = {
148
157
  densityDense: "\u5BC6\u96C6",
149
158
  fragmentSelected: "\u5DF2\u9009\u62E9\u7247\u6BB5",
150
159
  imageRegionSelected: "\u5DF2\u9009\u62E9\u56FE\u50CF\u533A\u57DF",
151
- closeProgress: "\u5173\u95ED"
160
+ complete: "\u6CE8\u91CA\u5B8C\u6210\uFF01",
161
+ failed: "\u6CE8\u91CA\u5931\u8D25",
162
+ densityPerWords: "\u6BCF 2000 \u8BCD {{density}} \u4E2A"
152
163
  };
153
164
  var TaggingPanel = {
154
165
  title: "\u6807\u7B7E",
@@ -167,7 +178,9 @@ var TaggingPanel = {
167
178
  selectCategory: "\u9009\u62E9\u5206\u7C7B",
168
179
  chooseCategory: "\u9009\u62E9\u4E00\u4E2A\u5206\u7C7B...",
169
180
  fragmentSelected: "\u5DF2\u9009\u62E9\u7247\u6BB5",
170
- imageRegionSelected: "\u5DF2\u9009\u62E9\u56FE\u50CF\u533A\u57DF"
181
+ imageRegionSelected: "\u5DF2\u9009\u62E9\u56FE\u50CF\u533A\u57DF",
182
+ complete: "\u6CE8\u91CA\u5B8C\u6210\uFF01",
183
+ failed: "\u6CE8\u91CA\u5931\u8D25"
171
184
  };
172
185
  var UnifiedAnnotationsPanel = {
173
186
  title: "\u6CE8\u91CA",
@@ -223,7 +236,6 @@ var ReferencesPanel = {
223
236
  complete: "\u6CE8\u91CA\u5B8C\u6210\uFF01",
224
237
  failed: "\u6CE8\u91CA\u5931\u8D25",
225
238
  current: "\u5F53\u524D\uFF1A{{entityType}}",
226
- closeProgress: "\u5173\u95ED",
227
239
  loading: "\u52A0\u8F7D\u4E2D...",
228
240
  loadingEllipsis: "\u52A0\u8F7D\u4E2D...",
229
241
  untitledResource: "\u65E0\u6807\u9898\u8D44\u6E90",
@@ -408,6 +420,7 @@ var ReferenceWizard = {
408
420
  search: "\u641C\u7D22"
409
421
  };
410
422
  var zh_default = {
423
+ AssistProgress,
411
424
  Toolbar,
412
425
  ResourceInfoPanel,
413
426
  CollaborationPanel,
@@ -433,6 +446,7 @@ export {
433
446
  AnnotateView,
434
447
  AnnotationHistory,
435
448
  AssessmentPanel,
449
+ AssistProgress,
436
450
  CollaborationPanel,
437
451
  CollapsibleResourceNavigation,
438
452
  CommentsPanel,
@@ -450,4 +464,4 @@ export {
450
464
  UnifiedAnnotationsPanel,
451
465
  zh_default as default
452
466
  };
453
- //# sourceMappingURL=zh-S754AWFS.js.map
467
+ //# sourceMappingURL=zh-YBJWJJYB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../translations/zh.json"],"sourcesContent":["{\n \"AssistProgress\": {\n \"close\": \"关闭\",\n \"paramsTitle\": \"请求参数:\",\n \"processing\": \"当前:{{label}}\"\n },\n \"Toolbar\": {\n \"annotations\": \"注释\",\n \"history\": \"历史\",\n \"resourceInfo\": \"资源信息\",\n \"collaboration\": \"协作\",\n \"userAccount\": \"用户帐户\",\n \"settings\": \"设置\",\n \"knowledgeBase\": \"知识库\"\n },\n \"ResourceInfoPanel\": {\n \"title\": \"资源信息\",\n \"locale\": \"区域设置\",\n \"notSpecified\": \"未指定\",\n \"entityTypeTags\": \"实体类型标签\",\n \"representation\": \"表示形式\",\n \"mediaType\": \"媒体类型\",\n \"byteSize\": \"大小\",\n \"storageUri\": \"存储\",\n \"clone\": \"克隆\",\n \"cloneDescription\": \"为此资源生成可共享的克隆链接\",\n \"generate\": \"生成\",\n \"generateDescription\": \"根据此资源的上下文生成新资源\",\n \"archive\": \"归档\",\n \"archiveDescription\": \"将此资源移至已归档状态\",\n \"unarchive\": \"取消归档\",\n \"unarchiveDescription\": \"将此资源恢复为活跃状态\",\n \"provenance\": \"来源\",\n \"createdAt\": \"创建时间\",\n \"modifiedAt\": \"修改时间\",\n \"attributedTo\": \"归属于\",\n \"derivedFrom\": \"派生自\"\n },\n \"CollaborationPanel\": {\n \"title\": \"协作\",\n \"connectionStatus\": \"连接状态\",\n \"live\": \"实时\",\n \"disconnected\": \"已断开\",\n \"events\": \"{{count}} 个事件\",\n \"lastSync\": \"上次同步:\",\n \"noActivity\": \"暂无活动\",\n \"justNow\": \"刚刚\",\n \"secondsAgo\": \"{{count}} 秒前\",\n \"minuteAgo\": \"1 分钟前\",\n \"minutesAgo\": \"{{count}} 分钟前\",\n \"hourAgo\": \"1 小时前\",\n \"hoursAgo\": \"{{count}} 小时前\",\n \"realtimeActive\": \"实时更新已激活\",\n \"reconnecting\": \"正在重新连接服务器...\",\n \"sharing\": \"共享\",\n \"collaborationComingSoon\": \"协作功能即将推出\"\n },\n \"AnnotationHistory\": {\n \"history\": \"历史\",\n \"loading\": \"加载中...\",\n \"user\": \"用户\",\n \"viewOriginal\": \"查看原文\",\n \"viewAnnotation\": \"查看注释:{{content}}\",\n \"resourceCreated\": \"已创建资源\",\n \"resourceCloned\": \"已克隆\",\n \"resourceArchived\": \"已归档\",\n \"resourceUnarchived\": \"已取消归档\",\n \"highlightAdded\": \"已添加高亮\",\n \"highlightRemoved\": \"已移除高亮\",\n \"referenceCreated\": \"已创建引用\",\n \"referenceResolved\": \"已解析引用\",\n \"referenceDeleted\": \"已删除引用\",\n \"entitytagAdded\": \"已添加标签\",\n \"entitytagRemoved\": \"已移除标签\",\n \"assessmentAdded\": \"已添加评估\",\n \"assessmentRemoved\": \"已移除评估\",\n \"annotationAdded\": \"已添加注释\",\n \"annotationRemoved\": \"已移除注释\",\n \"annotationBodyUpdated\": \"已更新注释\",\n \"jobEvent\": \"任务事件\",\n \"embeddingComputed\": \"嵌入计算完成\",\n \"justNow\": \"刚刚\",\n \"minutesAgo\": \"{{count}}分钟前\",\n \"hoursAgo\": \"{{count}}小时前\",\n \"daysAgo\": \"{{count}}天前\",\n \"failed\": \"无法加载历史。\",\n \"retry\": \"重试\"\n },\n \"CommentsPanel\": {\n \"title\": \"评论\",\n \"noComments\": \"暂无评论。选择文本并点击评论来添加。\",\n \"commentPlaceholder\": \"在此输入您的评论...\",\n \"save\": \"保存\",\n \"cancel\": \"取消\",\n \"edit\": \"编辑\",\n \"annotateComments\": \"注释评论\",\n \"instructions\": \"说明\",\n \"optional\": \"(可选)\",\n \"instructionsPlaceholder\": \"例如,关注技术术语...\",\n \"annotate\": \"注释\",\n \"annotating\": \"正在注释...\",\n \"toneLabel\": \"语气\",\n \"toneOptional\": \"(可选)\",\n \"toneScholarly\": \"学术\",\n \"toneExplanatory\": \"解释性\",\n \"toneConversational\": \"对话式\",\n \"toneTechnical\": \"技术性\",\n \"densityLabel\": \"密度\",\n \"densitySparse\": \"稀疏\",\n \"densityDense\": \"密集\",\n \"fragmentSelected\": \"已选择片段\",\n \"imageRegionSelected\": \"已选择图像区域\",\n \"complete\": \"注释完成!\",\n \"failed\": \"注释失败\",\n \"densityPerWords\": \"每 2000 词 {{density}} 个\"\n },\n \"HighlightPanel\": {\n \"title\": \"高亮\",\n \"noHighlights\": \"暂无高亮。使用 AI 注释查找重要段落。\",\n \"annotateHighlights\": \"注释高亮\",\n \"instructions\": \"说明\",\n \"optional\": \"(可选)\",\n \"instructionsPlaceholder\": \"例如,关注关键技术概念...\",\n \"annotate\": \"注释\",\n \"annotating\": \"正在注释...\",\n \"cancel\": \"取消\",\n \"densityLabel\": \"密度\",\n \"densitySparse\": \"稀疏\",\n \"densityDense\": \"密集\",\n \"complete\": \"注释完成!\",\n \"failed\": \"注释失败\",\n \"densityPerWords\": \"每 2000 词 {{density}} 个\"\n },\n \"AssessmentPanel\": {\n \"title\": \"评估\",\n \"noAssessments\": \"暂无评估。使用 AI 注释评价段落。\",\n \"assessmentPlaceholder\": \"在此输入您的评估...\",\n \"save\": \"保存\",\n \"cancel\": \"取消\",\n \"annotateAssessments\": \"注释评估\",\n \"instructions\": \"说明\",\n \"optional\": \"(可选)\",\n \"instructionsPlaceholder\": \"例如,评估声明的准确性和证据...\",\n \"annotate\": \"注释\",\n \"annotating\": \"正在注释...\",\n \"toneLabel\": \"语气\",\n \"toneOptional\": \"(可选)\",\n \"toneAnalytical\": \"分析性\",\n \"toneCritical\": \"批判性\",\n \"toneBalanced\": \"平衡\",\n \"toneConstructive\": \"建设性\",\n \"densityLabel\": \"密度\",\n \"densitySparse\": \"稀疏\",\n \"densityDense\": \"密集\",\n \"fragmentSelected\": \"已选择片段\",\n \"imageRegionSelected\": \"已选择图像区域\",\n \"complete\": \"注释完成!\",\n \"failed\": \"注释失败\",\n \"densityPerWords\": \"每 2000 词 {{density}} 个\"\n },\n \"TaggingPanel\": {\n \"title\": \"标签\",\n \"noTags\": \"暂无标签。使用 AI 注释识别结构角色。\",\n \"noSchemas\": \"此知识库尚未注册任何标签模式。KB 管理员必须先注册至少一个结构分析模式(例如通过 `register-tag-schemas` 技能),然后才能使用标签功能。\",\n \"annotateTags\": \"注释标签\",\n \"selectSchema\": \"选择框架\",\n \"selectCategories\": \"选择分类\",\n \"annotate\": \"注释\",\n \"annotating\": \"正在注释...\",\n \"cancel\": \"取消\",\n \"selectAll\": \"全选\",\n \"deselectAll\": \"取消全选\",\n \"categoriesSelected\": \"{count, plural, =0 {未选择分类} =1 {已选择 1 个分类} other {已选择 # 个分类}}\",\n \"createTagForSelection\": \"为选择内容创建标签\",\n \"selectCategory\": \"选择分类\",\n \"chooseCategory\": \"选择一个分类...\",\n \"fragmentSelected\": \"已选择片段\",\n \"imageRegionSelected\": \"已选择图像区域\",\n \"complete\": \"注释完成!\",\n \"failed\": \"注释失败\"\n },\n \"UnifiedAnnotationsPanel\": {\n \"title\": \"注释\",\n \"statistics\": \"统计\",\n \"highlight\": \"高亮\",\n \"reference\": \"引用\",\n \"assessment\": \"评估\",\n \"comment\": \"评论\",\n \"tag\": \"标签\",\n \"annotationsFailed\": \"无法加载注释。\",\n \"retry\": \"重试\"\n },\n \"StatisticsPanel\": {\n \"title\": \"统计\",\n \"highlights\": \"高亮\",\n \"comments\": \"评论\",\n \"assessments\": \"评估\",\n \"tags\": \"标签\",\n \"references\": \"引用\",\n \"stub\": \"存根\",\n \"resolved\": \"已解析\",\n \"entityTypes\": \"实体类型\"\n },\n \"ReferencesPanel\": {\n \"title\": \"引用\",\n \"noReferences\": \"暂无引用。选择文本以创建对其他资源的引用。\",\n \"outgoingReferences\": \"外部引用\",\n \"incomingReferences\": \"传入引用\",\n \"noIncomingReferences\": \"无传入引用\",\n \"stub\": \"存根引用(未链接)\",\n \"resolved\": \"已解析引用(已链接)\",\n \"open\": \"打开\",\n \"unlink\": \"取消链接\",\n \"resolve\": \"解析引用\",\n \"cancel\": \"取消\",\n \"createReference\": \"创建引用\",\n \"entityTypesOptional\": \"实体类型(可选)\",\n \"fragmentSelected\": \"已选择片段\",\n \"imageRegionSelected\": \"已选择图像区域\",\n \"annotateReferences\": \"注释引用\",\n \"selectEntityTypes\": \"实体类型:\",\n \"select\": \"选择\",\n \"deselect\": \"取消选择\",\n \"noEntityTypes\": \"没有可用的实体类型\",\n \"typesSelected\": \"{count, plural, =1 {已选择 1 个类型} other {已选择 # 个类型}}\",\n \"annotate\": \"注释\",\n \"annotating\": \"正在注释...\",\n \"includeDescriptiveReferences\": \"包含描述性引用\",\n \"descriptiveReferencesTooltip\": \"同时查找诸如「首席执行官」、「科技巨头」、「物理学家」等短语(除名称外)\",\n \"annotationProgressTitle\": \"正在注释实体引用\",\n \"cancelAnnotation\": \"取消注释\",\n \"found\": \"找到 {{count}} 个\",\n \"complete\": \"注释完成!\",\n \"failed\": \"注释失败\",\n \"current\": \"当前:{{entityType}}\",\n \"loading\": \"加载中...\",\n \"loadingEllipsis\": \"加载中...\",\n \"untitledResource\": \"无标题资源\",\n \"noText\": \"无文本\",\n \"incomingReferencesFailed\": \"无法加载传入引用。\",\n \"retry\": \"重试\",\n \"entityTypesFailed\": \"无法加载实体类型。\"\n },\n \"KeyboardShortcuts\": {\n \"title\": \"键盘快捷键\",\n \"closeDialog\": \"关闭对话框\",\n \"or\": \"或\",\n \"navigationTitle\": \"导航\",\n \"navOpenSearch\": \"打开全局搜索\",\n \"navOpenSearchAlt\": \"打开全局搜索(备选方式)\",\n \"navCreateResource\": \"创建新资源\",\n \"navCloseOverlays\": \"关闭所有覆盖层(双击)\",\n \"navShowHelp\": \"显示键盘快捷键帮助\",\n \"sidebarTitle\": \"知识侧边栏\",\n \"sidebarCollapse\": \"折叠侧边栏\",\n \"sidebarExpand\": \"展开侧边栏\",\n \"sidebarPickup\": \"拾取资源标签页(聚焦时)\",\n \"sidebarMove\": \"移动资源标签页(拖动时)\",\n \"sidebarDrop\": \"放下资源标签页(拖动时)\",\n \"sidebarCancel\": \"取消拖动操作\",\n \"annotationsTitle\": \"资源注释\",\n \"annotHighlight\": \"从注释创建高亮(直接)\",\n \"annotReference\": \"打开注释的引用弹窗\",\n \"annotDelete\": \"删除聚焦的注释\",\n \"annotNavigate\": \"浏览注释\",\n \"annotNavigateBack\": \"向后浏览注释\",\n \"listsTitle\": \"列表与网格\",\n \"listsFilterNav\": \"浏览实体类型筛选器\",\n \"listsGridNav\": \"浏览资源网格\",\n \"listsJumpFirst\": \"跳转到第一项\",\n \"listsJumpLast\": \"跳转到最后一项\",\n \"searchModalTitle\": \"在搜索模态框中\",\n \"searchNav\": \"浏览搜索结果\",\n \"searchSelect\": \"选择结果\",\n \"searchClose\": \"关闭搜索\",\n \"modalTitle\": \"模态框控制\",\n \"modalClose\": \"关闭活动模态框\",\n \"modalNavForward\": \"向前浏览按钮\",\n \"modalNavBackward\": \"向后浏览按钮\",\n \"modalActivate\": \"激活聚焦的按钮\",\n \"accessibilityTitle\": \"无障碍\",\n \"a11ySkipLinks\": \"导航到跳转链接(在页面顶部时)\",\n \"a11yFollowLink\": \"跟随跳转链接\",\n \"macNote\": \"使用 Mac 键盘快捷键。Command 是 Command 键。\",\n \"windowsNote\": \"使用 Windows/Linux 键盘快捷键。Ctrl 是 Ctrl 键。\",\n \"footerHint\": \"随时按 {{key}} 显示此帮助\",\n \"close\": \"关闭\"\n },\n \"AnnotateToolbar\": {\n \"modeGroup\": \"模式\",\n \"browse\": \"浏览\",\n \"annotate\": \"注释\",\n \"selectionGroup\": \"动机\",\n \"clickGroup\": \"点击\",\n \"shapeGroup\": \"形状\",\n \"none\": \"无\",\n \"linking\": \"引用\",\n \"highlighting\": \"高亮\",\n \"assessing\": \"评估\",\n \"commenting\": \"评论\",\n \"tagging\": \"标签\",\n \"detail\": \"详情\",\n \"follow\": \"跟随\",\n \"deleting\": \"删除\",\n \"jsonld\": \"JSON-LD\",\n \"rectangle\": \"矩形\",\n \"circle\": \"圆形\",\n \"polygon\": \"多边形\"\n },\n \"CollapsibleResourceNavigation\": {\n \"title\": \"导航\",\n \"collapseSidebar\": \"折叠侧边栏\",\n \"expandSidebar\": \"展开侧边栏\",\n \"dragToReorder\": \"拖动以重新排序\",\n \"dragToReorderDoc\": \"拖动以重新排序 {{name}}\",\n \"closeResource\": \"关闭资源\",\n \"dragInstructions\": \"要重新排序资源:使用 Tab 导航到资源。按 Alt+上箭头向上移动或 Alt+下箭头向下移动。对于拖放操作:按空格键拾取项目。使用方向键移动它。再次按空格键放下。\"\n },\n \"ResourceViewer\": {\n \"deleteConfirmationTitle\": \"删除注释\",\n \"deleteConfirmationMessage\": \"您确定要删除此注释吗?此操作无法撤消。\",\n \"deleteConfirmationCancel\": \"取消\",\n \"deleteConfirmationDelete\": \"删除\"\n },\n \"Settings\": {\n \"title\": \"设置\",\n \"lineNumbers\": \"行号\",\n \"lineNumbersVisible\": \"显示\",\n \"lineNumbersHidden\": \"隐藏\",\n \"theme\": \"主题\",\n \"themeLight\": \"浅色\",\n \"themeDark\": \"深色\",\n \"themeSystem\": \"系统\",\n \"themeSystemActive\": \"系统({{mode}})\",\n \"themeModeActive\": \"使用{{mode}}模式\",\n \"language\": \"语言\",\n \"languageHint\": \"在主导航中更改语言\",\n \"languageChanging\": \"正在更改语言...\",\n \"hoverDelay\": \"悬停延迟\",\n \"hoverDelayFast\": \"快速\",\n \"hoverDelaySlow\": \"慢速\",\n \"hoverDelayDescription\": \"悬停效果出现前延迟 {{delay}}ms\"\n },\n \"AnnotateView\": {},\n \"ResourceGenerate\": {\n \"gatherTitle\": \"配置收集\",\n \"reviewTitle\": \"查看上下文\",\n \"configureTitle\": \"配置生成\",\n \"next\": \"下一步\",\n \"back\": \"返回\",\n \"cancel\": \"取消\",\n \"gatherIntro\": \"选择要包含在收集的上下文中的内容。\",\n \"includeContent\": \"包含资源内容\",\n \"includeSummary\": \"包含摘要\",\n \"gatherDepth\": \"深度\",\n \"gatherMaxResources\": \"最大资源数\",\n \"gatherButton\": \"收集\",\n \"excludeLabel\": \"从召回中排除\",\n \"loadingContext\": \"正在收集上下文...\",\n \"failedContext\": \"收集上下文失败\",\n \"sourceContextLabel\": \"资源\",\n \"connectionsLabel\": \"连接\",\n \"citedByLabel\": \"被引用\",\n \"resourceTitle\": \"新资源标题\",\n \"resourceTitlePlaceholder\": \"生成资源的标题...\",\n \"additionalInstructions\": \"附加说明\",\n \"additionalInstructionsPlaceholder\": \"生成的可选指导...\",\n \"language\": \"语言\",\n \"languageHelp\": \"生成资源的语言\",\n \"creativity\": \"创造力\",\n \"creativityFocused\": \"专注\",\n \"creativityCreative\": \"创造性\",\n \"maxLength\": \"最大长度\",\n \"maxLengthHelp\": \"最大令牌数\",\n \"generate\": \"生成\",\n \"progressTitle\": \"正在生成资源\",\n \"progressCancel\": \"取消生成\",\n \"progressInProgress\": \"正在生成…\",\n \"progressComplete\": \"生成完成!\",\n \"progressFailed\": \"生成失败\"\n },\n \"ReferenceWizard\": {\n \"gatherTitle\": \"已收集的上下文\",\n \"configureGenerationTitle\": \"配置生成\",\n \"configureSearchTitle\": \"配置搜索\",\n \"searchResultsTitle\": \"搜索结果\",\n \"sourceContextLabel\": \"资源中的注释上下文\",\n \"connectionsLabel\": \"对等注释\",\n \"citedByLabel\": \"资源被引用\",\n \"userHintLabel\": \"提示\",\n \"userHintPlaceholder\": \"描述此注释所指的内容...\",\n \"loadingContext\": \"正在收集上下文...\",\n \"failedContext\": \"收集上下文失败\",\n \"cancel\": \"取消\",\n \"generate\": \"生成\",\n \"compose\": \"编写\",\n \"resolutionStrategyLabel\": \"解析策略\",\n \"back\": \"返回\",\n \"link\": \"链接\",\n \"score\": \"评分\",\n \"noResults\": \"未找到结果\",\n \"resourceTitle\": \"资源标题\",\n \"resourceTitlePlaceholder\": \"输入资源标题...\",\n \"additionalInstructions\": \"附加说明\",\n \"additionalInstructionsPlaceholder\": \"输入附加说明...\",\n \"language\": \"语言\",\n \"languageHelp\": \"生成内容的语言\",\n \"creativity\": \"创造力\",\n \"creativityFocused\": \"专注\",\n \"creativityCreative\": \"创造性\",\n \"maxLength\": \"最大长度\",\n \"maxLengthHelp\": \"最大令牌数\",\n \"maxResults\": \"最大结果数\",\n \"semanticScoring\": \"语义评分\",\n \"semanticScoringHelp\": \"使用 AI 按语义相关性对结果进行评分\",\n \"searching\": \"搜索中...\",\n \"search\": \"搜索\"\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/react-ui",
3
- "version": "0.5.24",
3
+ "version": "0.5.25",
4
4
  "engines": {
5
5
  "node": ">=24.0.0"
6
6
  },
@@ -94,8 +94,8 @@
94
94
  "@headlessui/react": "^2.2.10",
95
95
  "@testing-library/jest-dom": "^6.1.5",
96
96
  "@testing-library/react": "^16.1.0",
97
- "@types/react": "^19.2.16",
98
- "@types/react-dom": "^19",
97
+ "@types/react": "^19.2.18",
98
+ "@types/react-dom": "^19.2.4",
99
99
  "@vitest/coverage-v8": "^4.1.8",
100
100
  "autoprefixer": "^10.5.4",
101
101
  "axe-core": "^4.12.1",
@@ -104,7 +104,7 @@
104
104
  "jest-axe": "^10.0.0",
105
105
  "jsdom": "^29.1.1",
106
106
  "postcss-import": "^16.1.1",
107
- "rollup": "^4.61.0",
107
+ "rollup": "^4.62.3",
108
108
  "rollup-plugin-dts": "^6.4.1",
109
109
  "styled-components": "^6.4.3",
110
110
  "tsup": "^8.0.1",
@@ -122,10 +122,10 @@
122
122
  "directory": "packages/react-ui"
123
123
  },
124
124
  "dependencies": {
125
- "@semiont/core": "0.5.24",
126
- "@semiont/http-transport": "0.5.24",
127
- "@semiont/sdk": "0.5.24",
128
- "pdfjs-dist": "^6.1.200",
125
+ "@semiont/core": "0.5.25",
126
+ "@semiont/http-transport": "0.5.25",
127
+ "@semiont/sdk": "0.5.25",
128
+ "pdfjs-dist": "^6.2.108",
129
129
  "react-error-boundary": "^6.1.2",
130
130
  "react-markdown": "^10.1.0",
131
131
  "remark-gfm": "^4.0.1",
@@ -1,26 +1,38 @@
1
1
  'use client';
2
2
 
3
3
  import type { components } from '@semiont/core';
4
+ import { EntityFoundLog } from './EntityFoundLog';
4
5
 
5
6
  type JobProgress = components['schemas']['JobProgress'];
6
7
 
8
+ /**
9
+ * Every string this component renders. Required by default and with NO
10
+ * English fallbacks (ASSIST-SURFACE-WARTS Lane A): a `tr.x || 'X'` default
11
+ * turns a forgotten key into English text in a Japanese UI, silently and
12
+ * only at runtime. Required keys make the same mistake a type error at the
13
+ * call site. Only genuinely conditional copy is optional.
14
+ */
7
15
  export interface AssistProgressTranslations {
8
16
  /** Header title (e.g. "Annotating Entity References" / "Generating Resource"). Omit for the headerless inline style. */
9
17
  title?: string;
10
18
  /** Cancel-button title attribute. */
11
- cancel?: string;
19
+ cancel: string;
12
20
  /** Default in-progress status message (used when the job sends no `message`). */
13
- inProgress?: string;
21
+ inProgress: string;
14
22
  /** Status copy for the terminal 'complete' stage. */
15
- complete?: string;
23
+ complete: string;
16
24
  /** Fallback status copy for the terminal 'error' stage. */
17
- failed?: string;
18
- /** Completed entity-type log line (reference flow). */
25
+ failed: string;
26
+ /** Request-parameters block heading. */
27
+ paramsTitle: string;
28
+ /** Current-work detail line — the generic form, used by every flow. */
29
+ processing: (label: string) => string;
30
+ /** Completed entity-type log line (reference flow only). */
19
31
  found?: (count: number) => string;
20
- /** Current-work detail line (reference flow). */
32
+ /** Current-work detail line, reference-flow wording; falls back to `processing`. */
21
33
  current?: (label: string) => string;
22
34
  /** Dismiss-button label. */
23
- close?: string;
35
+ close: string;
24
36
  }
25
37
 
26
38
  export interface AssistProgressProps {
@@ -37,7 +49,7 @@ export interface AssistProgressProps {
37
49
  onDismiss?: () => void;
38
50
  /** Render the percentage bar (tag flow's visual; percentage itself comes from `progress`). */
39
51
  showPercentBar?: boolean;
40
- translations?: AssistProgressTranslations;
52
+ translations: AssistProgressTranslations;
41
53
  }
42
54
 
43
55
  /**
@@ -55,9 +67,12 @@ export function AssistProgress({
55
67
  onCancel,
56
68
  onDismiss,
57
69
  showPercentBar = false,
58
- translations: tr = {},
70
+ translations: tr,
59
71
  }: AssistProgressProps) {
60
72
  const terminal = progress.stage === 'complete' || progress.stage === 'error';
73
+ // The reference flow words this line its own way; everyone else gets the
74
+ // generic one. Both are translated — there is no untranslated branch.
75
+ const currentLabel = tr.current ?? tr.processing;
61
76
 
62
77
  return (
63
78
  <div className="semiont-annotation-progress" data-status={progress.stage} data-type={dataType}>
@@ -72,8 +87,8 @@ export function AssistProgress({
72
87
  <button
73
88
  onClick={onCancel}
74
89
  className="semiont-annotation-cancel"
75
- title={tr.cancel || 'Cancel'}
76
- aria-label={tr.cancel || 'Cancel'}
90
+ title={tr.cancel}
91
+ aria-label={tr.cancel}
77
92
  type="button"
78
93
  >
79
94
 
@@ -85,7 +100,7 @@ export function AssistProgress({
85
100
  {/* Request parameters */}
86
101
  {progress.requestParams && progress.requestParams.length > 0 && (
87
102
  <div className="semiont-annotation-progress__params" data-type={dataType}>
88
- <div className="semiont-annotation-progress__params-title">Request Parameters:</div>
103
+ <div className="semiont-annotation-progress__params-title">{tr.paramsTitle}</div>
89
104
  {progress.requestParams.map((param, idx) => (
90
105
  <div key={idx} className="semiont-annotation-progress__param">
91
106
  <span className="semiont-annotation-progress__param-label">{param.label}:</span> <span>{param.value}</span>
@@ -95,16 +110,8 @@ export function AssistProgress({
95
110
  )}
96
111
 
97
112
  {/* Completed entity-type log (reference flow) */}
98
- {tr.found && progress.completedEntityTypes && progress.completedEntityTypes.length > 0 && (
99
- <div className="semiont-annotation-log">
100
- {progress.completedEntityTypes.map((item, index) => (
101
- <div key={index} className="semiont-annotation-log-item">
102
- <span className="semiont-annotation-check">✓</span>
103
- <span className="semiont-annotation-entity-type">{item.entityType}:</span>
104
- <span>{tr.found!(item.foundCount)}</span>
105
- </div>
106
- ))}
107
- </div>
113
+ {tr.found && progress.completedEntityTypes && (
114
+ <EntityFoundLog entries={progress.completedEntityTypes} formatFound={tr.found} />
108
115
  )}
109
116
 
110
117
  {/* Status line with stage branching */}
@@ -112,20 +119,25 @@ export function AssistProgress({
112
119
  {progress.stage === 'complete' ? (
113
120
  <div className="semiont-annotation-progress__message">
114
121
  <span className="semiont-annotation-progress__icon">✅</span>
115
- {/* JobProgress.message is required but may be '' never blank a terminal line. */}
116
- <span>{tr.complete || progress.message || 'Complete'}</span>
122
+ {/* Same precedence as 'error' below: the job's own message carries
123
+ detail no static string can ("Created 14 highlights"), and
124
+ `tr.complete` covers the required-but-possibly-'' case so a
125
+ terminal line is never blank. NOTE: job messages are composed
126
+ backend-side and are not localized — a real gap, but a backend
127
+ one; see ASSIST-SURFACE-WARTS watch-items. */}
128
+ <span>{progress.message || tr.complete}</span>
117
129
  </div>
118
130
  ) : progress.stage === 'error' ? (
119
131
  <div className="semiont-annotation-progress__message">
120
132
  <span className="semiont-annotation-progress__icon">❌</span>
121
- <span>{progress.message || tr.failed || 'Failed'}</span>
133
+ <span>{progress.message || tr.failed}</span>
122
134
  </div>
123
135
  ) : (
124
136
  <div className="semiont-annotation-progress__message">
125
137
  <span className="semiont-annotation-progress__icon">✨</span>
126
138
  <span>
127
139
  {progress.message
128
- || (progress.currentEntityType && tr.current ? tr.current(progress.currentEntityType) : tr.inProgress)}
140
+ || (progress.currentEntityType ? currentLabel(progress.currentEntityType) : tr.inProgress)}
129
141
  </span>
130
142
  </div>
131
143
  )}
@@ -133,12 +145,12 @@ export function AssistProgress({
133
145
  {/* Current-work detail while running */}
134
146
  {!terminal && progress.currentEntityType && (
135
147
  <div className="semiont-annotation-progress__details">
136
- {tr.current ? tr.current(progress.currentEntityType) : `Processing: ${progress.currentEntityType}`}
148
+ {currentLabel(progress.currentEntityType)}
137
149
  </div>
138
150
  )}
139
151
  {!terminal && progress.currentCategory && (
140
152
  <div className="semiont-annotation-progress__details">
141
- Processing: {progress.currentCategory}
153
+ {tr.processing(progress.currentCategory)}
142
154
  {progress.processedCategories !== undefined && progress.totalCategories !== undefined && (
143
155
  <> ({progress.processedCategories}/{progress.totalCategories})</>
144
156
  )}
@@ -150,8 +162,8 @@ export function AssistProgress({
150
162
  <button
151
163
  onClick={onDismiss}
152
164
  className="semiont-annotation-progress__close"
153
- aria-label={tr.close || 'Dismiss'}
154
- title={tr.close || 'Dismiss'}
165
+ aria-label={tr.close}
166
+ title={tr.close}
155
167
  type="button"
156
168
  >
157
169
  ×
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+
3
+ export interface EntityFoundEntry {
4
+ entityType: string;
5
+ foundCount: number;
6
+ }
7
+
8
+ export interface EntityFoundLogProps {
9
+ entries: EntityFoundEntry[];
10
+ /** Formats the per-entity count line, e.g. `(n) => t('found', { count: n })`. */
11
+ formatFound: (count: number) => string;
12
+ }
13
+
14
+ /**
15
+ * "✓ Person: 5 found" — the completed entity-type log.
16
+ *
17
+ * One markup for one concept (ASSIST-SURFACE-WARTS Lane B). This was two
18
+ * class families a single panel apart: the live progress display used
19
+ * `semiont-annotation-log*` while ReferencesPanel's post-run form log used
20
+ * `semiont-assist-widget__log*`, with the same rows rendered by hand in both.
21
+ * Presentational and provider-free, like AssistProgress — the caller brings
22
+ * the formatter.
23
+ */
24
+ export function EntityFoundLog({ entries, formatFound }: EntityFoundLogProps) {
25
+ if (entries.length === 0) return null;
26
+
27
+ return (
28
+ <div className="semiont-annotation-log">
29
+ {entries.map((item, index) => (
30
+ <div key={index} className="semiont-annotation-log-item">
31
+ <span className="semiont-annotation-check">✓</span>
32
+ <span className="semiont-annotation-entity-type">{item.entityType}:</span>
33
+ <span>{formatFound(item.foundCount)}</span>
34
+ </div>
35
+ ))}
36
+ </div>
37
+ );
38
+ }
@@ -7,13 +7,19 @@
7
7
  * cancel/dismiss arrive as callbacks the caller wires (job.cancelRequest /
8
8
  * mark.dismissProgress). Feature blocks are data-presence-driven so each call
9
9
  * site keeps its current visuals by passing what it always had.
10
+ *
11
+ * i18n contract (ASSIST-SURFACE-WARTS Lane A): every string this component
12
+ * renders comes from `translations`. There are NO English fallbacks — a
13
+ * missing key must be a type error at the call site, not a silent English
14
+ * leak in a Japanese UI. Tests use key-echo strings ('tr.complete') so an
15
+ * assertion failing means "rendered something other than what was passed".
10
16
  */
11
17
  import { describe, it, expect, vi } from 'vitest';
12
18
  import { render, screen } from '@testing-library/react';
13
19
  import userEvent from '@testing-library/user-event';
14
20
  import '@testing-library/jest-dom';
15
21
  import type { components } from '@semiont/core';
16
- import { AssistProgress } from '../AssistProgress';
22
+ import { AssistProgress, type AssistProgressTranslations } from '../AssistProgress';
17
23
 
18
24
  type JobProgress = components['schemas']['JobProgress'];
19
25
 
@@ -21,13 +27,26 @@ const running = (over: Partial<JobProgress> = {}): JobProgress => ({
21
27
  stage: 'analyzing', percentage: 40, message: 'working on it', ...over,
22
28
  });
23
29
 
30
+ /** Every required key, echoing its own name; override per test. */
31
+ const T = (over: Partial<AssistProgressTranslations> = {}): AssistProgressTranslations => ({
32
+ cancel: 'tr.cancel',
33
+ inProgress: 'tr.inProgress',
34
+ complete: 'tr.complete',
35
+ failed: 'tr.failed',
36
+ close: 'tr.close',
37
+ paramsTitle: 'tr.paramsTitle',
38
+ processing: (label: string) => `tr.processing(${label})`,
39
+ ...over,
40
+ });
41
+
24
42
  describe('AssistProgress', () => {
25
43
  it('renders provider-free: message, params, and data hooks', () => {
26
44
  const { container } = render(
27
45
  <AssistProgress
28
46
  progress={running({ requestParams: [{ label: 'Density', value: '5' }] })}
29
47
  dataType="comment"
30
- />,
48
+ translations={T()}
49
+ />,
31
50
  );
32
51
  expect(screen.getByText('working on it')).toBeInTheDocument();
33
52
  expect(screen.getByText(/Density/)).toBeInTheDocument();
@@ -37,12 +56,24 @@ describe('AssistProgress', () => {
37
56
  expect(root).toHaveAttribute('data-status', 'analyzing');
38
57
  });
39
58
 
59
+ it('renders the request-parameters title from translations, never a literal', () => {
60
+ render(
61
+ <AssistProgress
62
+ progress={running({ requestParams: [{ label: 'Density', value: '5' }] })}
63
+ dataType="comment"
64
+ translations={T()}
65
+ />,
66
+ );
67
+ expect(screen.getByText('tr.paramsTitle')).toBeInTheDocument();
68
+ expect(screen.queryByText('Request Parameters:')).not.toBeInTheDocument();
69
+ });
70
+
40
71
  it('renders a title header only when given one', () => {
41
72
  const { rerender } = render(
42
- <AssistProgress progress={running()} dataType="reference" translations={{ title: 'Annotating Entity References' }} />,
73
+ <AssistProgress progress={running()} dataType="reference" translations={T({ title: 'Annotating Entity References' })} />,
43
74
  );
44
75
  expect(screen.getByText('Annotating Entity References')).toBeInTheDocument();
45
- rerender(<AssistProgress progress={running()} dataType="comment" />);
76
+ rerender(<AssistProgress progress={running()} dataType="comment" translations={T()} />);
46
77
  expect(screen.queryByText('Annotating Entity References')).not.toBeInTheDocument();
47
78
  });
48
79
 
@@ -50,7 +81,7 @@ describe('AssistProgress', () => {
50
81
  // Cancel lives in the title header — both flows that offer cancel
51
82
  // (reference detection, generation) render the titled profile.
52
83
  const onCancel = vi.fn();
53
- const tr = { title: 'Generating Resource', cancel: 'Cancel Job' };
84
+ const tr = T({ title: 'Generating Resource', cancel: 'Cancel Job' });
54
85
  const { rerender } = render(
55
86
  <AssistProgress progress={running()} dataType="generation" onCancel={onCancel} translations={tr} />,
56
87
  );
@@ -68,13 +99,20 @@ describe('AssistProgress', () => {
68
99
  expect(screen.queryByTitle('Cancel Job')).not.toBeInTheDocument();
69
100
  });
70
101
 
71
- it('stage branching: complete shows + complete copy, error shows + message', () => {
102
+ it('stage branching: both terminal stages prefer the job message, then the translated copy', () => {
103
+ // The job composes detail no static string can ("Created 14 highlights"),
104
+ // so it wins on BOTH terminal stages; the translated copy covers the
105
+ // required-but-empty message case (pinned below).
72
106
  const { rerender } = render(
73
- <AssistProgress progress={running({ stage: 'complete' })} dataType="reference" translations={{ complete: 'All done!' }} />,
107
+ <AssistProgress progress={running({ stage: 'complete' })} dataType="reference" translations={T({ complete: 'All done!' })} />,
108
+ );
109
+ expect(screen.getByText('working on it')).toBeInTheDocument();
110
+ rerender(
111
+ <AssistProgress progress={running({ stage: 'complete', message: '' })} dataType="reference" translations={T({ complete: 'All done!' })} />,
74
112
  );
75
113
  expect(screen.getByText('All done!')).toBeInTheDocument();
76
114
  rerender(
77
- <AssistProgress progress={running({ stage: 'error', message: 'it broke' })} dataType="reference" translations={{ failed: 'Failed' }} />,
115
+ <AssistProgress progress={running({ stage: 'error', message: 'it broke' })} dataType="reference" translations={T({ failed: 'Failed' })} />,
78
116
  );
79
117
  expect(screen.getByText('it broke')).toBeInTheDocument();
80
118
  });
@@ -83,7 +121,7 @@ describe('AssistProgress', () => {
83
121
  render(
84
122
  <AssistProgress
85
123
  progress={running({ completedEntityTypes: [{ entityType: 'Person', foundCount: 3 }] })}
86
- dataType="reference" translations={{ found: (n) => `Found ${n}` }}
124
+ dataType="reference" translations={T({ found: (n) => `Found ${n}` })}
87
125
  />,
88
126
  );
89
127
  expect(screen.getByText('Person:')).toBeInTheDocument();
@@ -94,55 +132,75 @@ describe('AssistProgress', () => {
94
132
  const { rerender } = render(
95
133
  <AssistProgress
96
134
  progress={running({ currentEntityType: 'Location' })}
97
- dataType="reference" translations={{ current: (l) => `Processing: ${l}` }}
135
+ dataType="reference" translations={T({ current: (l) => `Current: ${l}` })}
98
136
  />,
99
137
  );
100
- expect(screen.getByText('Processing: Location')).toBeInTheDocument();
138
+ expect(screen.getByText('Current: Location')).toBeInTheDocument();
101
139
  rerender(
102
140
  <AssistProgress
103
141
  progress={running({ currentCategory: 'Rule', processedCategories: 2, totalCategories: 5 })}
104
- dataType="tag" />,
142
+ dataType="tag" translations={T()}
143
+ />,
105
144
  );
106
145
  expect(screen.getByText(/Rule/)).toBeInTheDocument();
107
146
  expect(screen.getByText(/2\/5/)).toBeInTheDocument();
108
147
  });
109
148
 
149
+ it('falls back to the generic processing formatter — never the English literal', () => {
150
+ // The reference flow passes its own `current` wording; every other flow
151
+ // (tag categories, and any flow without one) uses `processing`. Neither
152
+ // path may render a hardcoded "Processing: ".
153
+ const { rerender } = render(
154
+ <AssistProgress progress={running({ currentEntityType: 'Location' })} dataType="reference" translations={T()} />,
155
+ );
156
+ expect(screen.getByText('tr.processing(Location)')).toBeInTheDocument();
157
+ rerender(
158
+ <AssistProgress progress={running({ currentCategory: 'Rule' })} dataType="tag" translations={T()} />,
159
+ );
160
+ expect(screen.getByText(/tr\.processing\(Rule\)/)).toBeInTheDocument();
161
+ expect(screen.queryByText(/^Processing: /)).not.toBeInTheDocument();
162
+ });
163
+
110
164
  it('renders the percentage bar only when opted in', () => {
111
165
  const { container, rerender } = render(
112
- <AssistProgress progress={running({ percentage: 40 })} dataType="tag" showPercentBar />,
166
+ <AssistProgress progress={running({ percentage: 40 })} dataType="tag" showPercentBar translations={T()} />,
113
167
  );
114
168
  const fill = container.querySelector('.semiont-progress-bar__fill');
115
169
  expect(fill).toBeInTheDocument();
116
170
  expect(fill).toHaveStyle({ width: '40%' });
117
171
  rerender(
118
- <AssistProgress progress={running({ percentage: 40 })} dataType="reference" />,
172
+ <AssistProgress progress={running({ percentage: 40 })} dataType="reference" translations={T()} />,
119
173
  );
120
174
  expect(container.querySelector('.semiont-progress-bar__fill')).not.toBeInTheDocument();
121
175
  });
122
176
 
123
- it('cancel and dismiss carry accessible names, with safe fallbacks when untranslated', () => {
124
- // ✕ / × glyphs alone are meaningless to screen readers; the controls must
125
- // have an accessible name even when a caller forgets the translations.
177
+ it('cancel and dismiss take their accessible names from translations', () => {
178
+ // ✕ / × glyphs alone are meaningless to screen readers, and an English
179
+ // fallback is meaningless to a non-English reader. The labels are
180
+ // required keys, so there is nothing to fall back TO.
126
181
  render(
127
182
  <AssistProgress progress={running()} dataType="generation"
128
183
  onCancel={vi.fn()} onDismiss={vi.fn()}
129
- translations={{ title: 'Generating' }} />,
184
+ translations={T({ title: 'Generating' })} />,
130
185
  );
131
- expect(screen.getByLabelText('Cancel')).toBeInTheDocument();
132
- expect(screen.getByLabelText('Dismiss')).toBeInTheDocument();
186
+ expect(screen.getByLabelText('tr.cancel')).toBeInTheDocument();
187
+ expect(screen.getByLabelText('tr.close')).toBeInTheDocument();
188
+ expect(screen.queryByLabelText('Cancel')).not.toBeInTheDocument();
189
+ expect(screen.queryByLabelText('Dismiss')).not.toBeInTheDocument();
133
190
  });
134
191
 
135
- it('terminal stages never render a blank status line', () => {
192
+ it('terminal stages never render a blank status line, and never an English one', () => {
136
193
  // JobProgress.message is required but can be '' — a terminal display with
137
- // no text at all is worse than a generic word.
194
+ // no text at all is worse than a generic word, but that word must be the
195
+ // caller's translated one.
138
196
  const { rerender } = render(
139
- <AssistProgress progress={running({ stage: 'complete', message: '' })} dataType="reference" />,
197
+ <AssistProgress progress={running({ stage: 'complete', message: '' })} dataType="reference" translations={T()} />,
140
198
  );
141
- expect(screen.getByText('Complete')).toBeInTheDocument();
199
+ expect(screen.getByText('tr.complete')).toBeInTheDocument();
142
200
  rerender(
143
- <AssistProgress progress={running({ stage: 'error', message: '' })} dataType="reference" />,
201
+ <AssistProgress progress={running({ stage: 'error', message: '' })} dataType="reference" translations={T()} />,
144
202
  );
145
- expect(screen.getByText('Failed')).toBeInTheDocument();
203
+ expect(screen.getByText('tr.failed')).toBeInTheDocument();
146
204
  });
147
205
 
148
206
  it('renders dismiss whenever the caller offers it (WHEN is the caller\'s policy)', async () => {
@@ -151,12 +209,12 @@ describe('AssistProgress', () => {
151
209
  // "callback present → affordance rendered".
152
210
  const onDismiss = vi.fn();
153
211
  const { rerender } = render(
154
- <AssistProgress progress={running()} dataType="highlight" translations={{ close: 'Close' }} />,
212
+ <AssistProgress progress={running()} dataType="highlight" translations={T({ close: 'Close' })} />,
155
213
  );
156
214
  expect(screen.queryByLabelText('Close')).not.toBeInTheDocument();
157
215
  rerender(
158
216
  <AssistProgress progress={running()} dataType="highlight"
159
- onDismiss={onDismiss} translations={{ close: 'Close' }} />,
217
+ onDismiss={onDismiss} translations={T({ close: 'Close' })} />,
160
218
  );
161
219
  await userEvent.click(screen.getByLabelText('Close'));
162
220
  expect(onDismiss).toHaveBeenCalledOnce();