@manta-eu/react 0.1.10 → 0.2.1

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 (324) hide show
  1. package/dist/components/channel-icon/index.d.ts +1 -0
  2. package/dist/components/channel-icon/index.d.ts.map +1 -1
  3. package/dist/components/channel-icon/index.js +1 -1
  4. package/dist/components/channel-icon/index.js.map +1 -1
  5. package/dist/components/chat-view/ChatTurnErrorNotice.d.ts.map +1 -1
  6. package/dist/components/chat-view/ChatTurnErrorNotice.js +3 -1
  7. package/dist/components/chat-view/ChatTurnErrorNotice.js.map +1 -1
  8. package/dist/components/layouts/ConnectedCustomApp.d.ts +13 -0
  9. package/dist/components/layouts/ConnectedCustomApp.d.ts.map +1 -0
  10. package/dist/components/layouts/ConnectedCustomApp.js +37 -0
  11. package/dist/components/layouts/ConnectedCustomApp.js.map +1 -0
  12. package/dist/components/layouts/Sidebar.d.ts.map +1 -1
  13. package/dist/components/layouts/Sidebar.js +6 -3
  14. package/dist/components/layouts/Sidebar.js.map +1 -1
  15. package/dist/components/planning/ActioningView.d.ts +1 -2
  16. package/dist/components/planning/ActioningView.d.ts.map +1 -1
  17. package/dist/components/planning/ActioningView.js +19 -44
  18. package/dist/components/planning/ActioningView.js.map +1 -1
  19. package/dist/components/planning/ManualActionCard.d.ts +4 -0
  20. package/dist/components/planning/ManualActionCard.d.ts.map +1 -1
  21. package/dist/components/planning/ManualActionCard.js +7 -5
  22. package/dist/components/planning/ManualActionCard.js.map +1 -1
  23. package/dist/components/planning/ManualActionList.d.ts +4 -0
  24. package/dist/components/planning/ManualActionList.d.ts.map +1 -1
  25. package/dist/components/planning/ManualActionList.js +8 -2
  26. package/dist/components/planning/ManualActionList.js.map +1 -1
  27. package/dist/components/planning/actioning-view-utils.d.ts +9 -0
  28. package/dist/components/planning/actioning-view-utils.d.ts.map +1 -1
  29. package/dist/components/planning/actioning-view-utils.js +19 -1
  30. package/dist/components/planning/actioning-view-utils.js.map +1 -1
  31. package/dist/components/table-skeleton/index.d.ts +2 -0
  32. package/dist/components/table-skeleton/index.d.ts.map +1 -1
  33. package/dist/components/table-skeleton/index.js +2 -1
  34. package/dist/components/table-skeleton/index.js.map +1 -1
  35. package/dist/components/tooltip/index.d.ts +7 -0
  36. package/dist/components/tooltip/index.d.ts.map +1 -1
  37. package/dist/components/tooltip/index.js +10 -1
  38. package/dist/components/tooltip/index.js.map +1 -1
  39. package/dist/globals.css +19 -6
  40. package/dist/graph/createNodeRouter.js +3 -3
  41. package/dist/graph/createNodeRouter.js.map +1 -1
  42. package/dist/graph/entity-link.d.ts +14 -0
  43. package/dist/graph/entity-link.d.ts.map +1 -0
  44. package/dist/graph/entity-link.js +12 -0
  45. package/dist/graph/entity-link.js.map +1 -0
  46. package/dist/graph/graph-list-utils.d.ts +1 -0
  47. package/dist/graph/graph-list-utils.d.ts.map +1 -1
  48. package/dist/graph/graph-list-utils.js +1 -0
  49. package/dist/graph/graph-list-utils.js.map +1 -1
  50. package/dist/graph/graph-model.d.ts.map +1 -1
  51. package/dist/graph/graph-model.js +14 -5
  52. package/dist/graph/graph-model.js.map +1 -1
  53. package/dist/graph/nodes/BrandAssetAnalysisView.d.ts.map +1 -1
  54. package/dist/graph/nodes/BrandAssetAnalysisView.js +2 -1
  55. package/dist/graph/nodes/BrandAssetAnalysisView.js.map +1 -1
  56. package/dist/graph/nodes/BrandFontSuggestionView.d.ts +3 -0
  57. package/dist/graph/nodes/BrandFontSuggestionView.d.ts.map +1 -0
  58. package/dist/graph/nodes/{BrandFontFamilyView.js → BrandFontSuggestionView.js} +22 -13
  59. package/dist/graph/nodes/BrandFontSuggestionView.js.map +1 -0
  60. package/dist/graph/nodes/BrandGuidelinesView.js +1 -1
  61. package/dist/graph/nodes/BrandGuidelinesView.js.map +1 -1
  62. package/dist/graph/nodes/NodePropertyTable.d.ts +4 -2
  63. package/dist/graph/nodes/NodePropertyTable.d.ts.map +1 -1
  64. package/dist/graph/nodes/NodePropertyTable.js +12 -59
  65. package/dist/graph/nodes/NodePropertyTable.js.map +1 -1
  66. package/dist/graph/nodes/brand-font.d.ts +8 -0
  67. package/dist/graph/nodes/brand-font.d.ts.map +1 -1
  68. package/dist/graph/nodes/brand-font.js +6 -0
  69. package/dist/graph/nodes/brand-font.js.map +1 -1
  70. package/dist/graph/nodes/brand-shared.d.ts +0 -3
  71. package/dist/graph/nodes/brand-shared.d.ts.map +1 -1
  72. package/dist/graph/nodes/brand-shared.js +1 -4
  73. package/dist/graph/nodes/brand-shared.js.map +1 -1
  74. package/dist/graph/nodes/node-property-row.d.ts +30 -0
  75. package/dist/graph/nodes/node-property-row.d.ts.map +1 -0
  76. package/dist/graph/nodes/node-property-row.js +35 -0
  77. package/dist/graph/nodes/node-property-row.js.map +1 -0
  78. package/dist/graph/property-formatters.d.ts +1 -0
  79. package/dist/graph/property-formatters.d.ts.map +1 -1
  80. package/dist/graph/property-formatters.js +4 -1
  81. package/dist/graph/property-formatters.js.map +1 -1
  82. package/dist/graph/special-nodes/AttributeList.d.ts +27 -0
  83. package/dist/graph/special-nodes/AttributeList.d.ts.map +1 -0
  84. package/dist/graph/special-nodes/AttributeList.js +57 -0
  85. package/dist/graph/special-nodes/AttributeList.js.map +1 -0
  86. package/dist/graph/special-nodes/EntityPreview.d.ts +5 -0
  87. package/dist/graph/special-nodes/EntityPreview.d.ts.map +1 -0
  88. package/dist/graph/special-nodes/EntityPreview.js +19 -0
  89. package/dist/graph/special-nodes/EntityPreview.js.map +1 -0
  90. package/dist/graph/special-nodes/EntityValueChip.d.ts +11 -0
  91. package/dist/graph/special-nodes/EntityValueChip.d.ts.map +1 -0
  92. package/dist/graph/special-nodes/EntityValueChip.js +40 -0
  93. package/dist/graph/special-nodes/EntityValueChip.js.map +1 -0
  94. package/dist/graph/special-nodes/GenericView.d.ts +2 -1
  95. package/dist/graph/special-nodes/GenericView.d.ts.map +1 -1
  96. package/dist/graph/special-nodes/GenericView.js +23 -69
  97. package/dist/graph/special-nodes/GenericView.js.map +1 -1
  98. package/dist/graph/special-nodes/card-facts.d.ts +52 -0
  99. package/dist/graph/special-nodes/card-facts.d.ts.map +1 -0
  100. package/dist/graph/special-nodes/card-facts.js +189 -0
  101. package/dist/graph/special-nodes/card-facts.js.map +1 -0
  102. package/dist/graph/special-nodes/property-icons.d.ts +9 -0
  103. package/dist/graph/special-nodes/property-icons.d.ts.map +1 -0
  104. package/dist/graph/special-nodes/property-icons.js +39 -0
  105. package/dist/graph/special-nodes/property-icons.js.map +1 -0
  106. package/dist/graph/status-utils.d.ts +16 -0
  107. package/dist/graph/status-utils.d.ts.map +1 -1
  108. package/dist/graph/status-utils.js +35 -0
  109. package/dist/graph/status-utils.js.map +1 -1
  110. package/dist/graph/types.d.ts +5 -0
  111. package/dist/graph/types.d.ts.map +1 -1
  112. package/dist/hooks/use-approve-anyway.d.ts +12 -0
  113. package/dist/hooks/use-approve-anyway.d.ts.map +1 -0
  114. package/dist/hooks/use-approve-anyway.js +81 -0
  115. package/dist/hooks/use-approve-anyway.js.map +1 -0
  116. package/dist/hooks/use-connection-problems.d.ts.map +1 -1
  117. package/dist/hooks/useAuth.d.ts +2 -2
  118. package/dist/hooks/useAuth.d.ts.map +1 -1
  119. package/dist/hooks/useAuth.js +2 -2
  120. package/dist/hooks/useAuth.js.map +1 -1
  121. package/dist/hooks/useOnboardingState.js +1 -1
  122. package/dist/hooks/useOnboardingState.js.map +1 -1
  123. package/dist/hooks/useValidateActionPlan.d.ts.map +1 -1
  124. package/dist/ldo-ui.d.ts +2 -1
  125. package/dist/ldo-ui.d.ts.map +1 -1
  126. package/dist/ldo-ui.js +1 -0
  127. package/dist/ldo-ui.js.map +1 -1
  128. package/dist/lib/datastore-route-table.d.ts +2 -1
  129. package/dist/lib/datastore-route-table.d.ts.map +1 -1
  130. package/dist/lib/datastore-route-table.js +2 -1
  131. package/dist/lib/datastore-route-table.js.map +1 -1
  132. package/dist/lib/manual-actions.d.ts +2 -1
  133. package/dist/lib/manual-actions.d.ts.map +1 -1
  134. package/dist/lib/manual-actions.js +3 -2
  135. package/dist/lib/manual-actions.js.map +1 -1
  136. package/dist/providers/ActiveChatProvider.js +3 -1
  137. package/dist/providers/ActiveChatProvider.js.map +1 -1
  138. package/dist/providers/AuthContext.d.ts +2 -1
  139. package/dist/providers/AuthContext.d.ts.map +1 -1
  140. package/dist/providers/AuthContext.js.map +1 -1
  141. package/dist/providers/ChatManagerProvider.d.ts.map +1 -1
  142. package/dist/providers/ChatManagerProvider.js +22 -9
  143. package/dist/providers/ChatManagerProvider.js.map +1 -1
  144. package/dist/providers/chat-socket-auth.d.ts +7 -2
  145. package/dist/providers/chat-socket-auth.d.ts.map +1 -1
  146. package/dist/providers/chat-socket-auth.js +87 -16
  147. package/dist/providers/chat-socket-auth.js.map +1 -1
  148. package/dist/providers/index.d.ts.map +1 -1
  149. package/dist/providers/index.js +8 -1
  150. package/dist/providers/index.js.map +1 -1
  151. package/dist/routes/activity/detail/ActivityChanges.d.ts +2 -0
  152. package/dist/routes/activity/detail/ActivityChanges.d.ts.map +1 -1
  153. package/dist/routes/activity/detail/ActivityChanges.js +8 -7
  154. package/dist/routes/activity/detail/ActivityChanges.js.map +1 -1
  155. package/dist/routes/activity/detail/ActivityDetail.d.ts +1 -0
  156. package/dist/routes/activity/detail/ActivityDetail.d.ts.map +1 -1
  157. package/dist/routes/activity/detail/ActivityDetail.js +5 -4
  158. package/dist/routes/activity/detail/ActivityDetail.js.map +1 -1
  159. package/dist/routes/activity/detail/ActivityStepsRail.d.ts +1 -0
  160. package/dist/routes/activity/detail/ActivityStepsRail.d.ts.map +1 -1
  161. package/dist/routes/activity/detail/ActivityStepsRail.js +3 -2
  162. package/dist/routes/activity/detail/ActivityStepsRail.js.map +1 -1
  163. package/dist/routes/activity/detail/ActivityTimeline.js +2 -2
  164. package/dist/routes/activity/detail/ActivityTimeline.js.map +1 -1
  165. package/dist/routes/activity/detail/NoChangesMessage.d.ts +6 -0
  166. package/dist/routes/activity/detail/NoChangesMessage.d.ts.map +1 -0
  167. package/dist/routes/activity/detail/NoChangesMessage.js +10 -0
  168. package/dist/routes/activity/detail/NoChangesMessage.js.map +1 -0
  169. package/dist/routes/data-explorer/components/RawTriples.js +1 -1
  170. package/dist/routes/data-explorer/components/RawTriples.js.map +1 -1
  171. package/dist/routes/data-explorer/components/RecentTypes.js +1 -1
  172. package/dist/routes/data-explorer/components/RecentTypes.js.map +1 -1
  173. package/dist/routes/data-explorer/components/class-detail/Instances.js +1 -1
  174. package/dist/routes/data-explorer/components/class-detail/Instances.js.map +1 -1
  175. package/dist/routes/data-explorer/components/namespace-detail/NamespaceClassRow.js +1 -1
  176. package/dist/routes/data-explorer/components/namespace-detail/NamespaceClassRow.js.map +1 -1
  177. package/dist/routes/data-explorer/components/ontology-coverage/CoverageTermColumns.js +1 -1
  178. package/dist/routes/data-explorer/components/ontology-coverage/CoverageTermColumns.js.map +1 -1
  179. package/dist/routes/data-explorer/components/ontology-coverage/UnobservedRuleVocabulary.js +1 -1
  180. package/dist/routes/data-explorer/components/ontology-coverage/UnobservedRuleVocabulary.js.map +1 -1
  181. package/dist/routes/data-explorer/components/record-detail/ChatPreview.js +2 -2
  182. package/dist/routes/data-explorer/components/record-detail/ChatPreview.js.map +1 -1
  183. package/dist/routes/data-explorer/declared-namespaces.d.ts +3 -0
  184. package/dist/routes/data-explorer/declared-namespaces.d.ts.map +1 -1
  185. package/dist/routes/data-explorer/declared-namespaces.js +21 -13
  186. package/dist/routes/data-explorer/declared-namespaces.js.map +1 -1
  187. package/dist/routes/data-explorer/namespaces.d.ts +1 -0
  188. package/dist/routes/data-explorer/namespaces.d.ts.map +1 -1
  189. package/dist/routes/data-explorer/namespaces.js +7 -6
  190. package/dist/routes/data-explorer/namespaces.js.map +1 -1
  191. package/dist/routes/datastores/components/DeleteDatastoreDialog.d.ts +10 -0
  192. package/dist/routes/datastores/components/DeleteDatastoreDialog.d.ts.map +1 -0
  193. package/dist/routes/datastores/components/DeleteDatastoreDialog.js +20 -0
  194. package/dist/routes/datastores/components/DeleteDatastoreDialog.js.map +1 -0
  195. package/dist/routes/datastores/flatten.d.ts +1 -0
  196. package/dist/routes/datastores/flatten.d.ts.map +1 -1
  197. package/dist/routes/datastores/flatten.js +17 -0
  198. package/dist/routes/datastores/flatten.js.map +1 -1
  199. package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts +3 -1
  200. package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts.map +1 -1
  201. package/dist/routes/datastores/hooks/useDatastoreColumns.js +14 -6
  202. package/dist/routes/datastores/hooks/useDatastoreColumns.js.map +1 -1
  203. package/dist/routes/datastores/index.d.ts.map +1 -1
  204. package/dist/routes/datastores/index.js +31 -5
  205. package/dist/routes/datastores/index.js.map +1 -1
  206. package/dist/routes/integrations/components/ProviderGroup.js +2 -2
  207. package/dist/routes/integrations/components/ProviderGroup.js.map +1 -1
  208. package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.d.ts.map +1 -1
  209. package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.js +13 -6
  210. package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.js.map +1 -1
  211. package/dist/routes/integrations/components/connect-forms/data-connection-fields.d.ts +3 -0
  212. package/dist/routes/integrations/components/connect-forms/data-connection-fields.d.ts.map +1 -1
  213. package/dist/routes/integrations/components/connect-forms/data-connection-fields.js +9 -2
  214. package/dist/routes/integrations/components/connect-forms/data-connection-fields.js.map +1 -1
  215. package/dist/routes/plans/components/ActionPlanPage.d.ts.map +1 -1
  216. package/dist/routes/plans/components/ActionPlanPage.js +4 -7
  217. package/dist/routes/plans/components/ActionPlanPage.js.map +1 -1
  218. package/dist/routes/plans/components/PlanDetailRouteContent.d.ts.map +1 -1
  219. package/dist/routes/plans/components/PlanDetailRouteContent.js +2 -1
  220. package/dist/routes/plans/components/PlanDetailRouteContent.js.map +1 -1
  221. package/package.json +12 -7
  222. package/src/app-subpaths.json +1 -0
  223. package/src/components/channel-icon/index.tsx +1 -1
  224. package/src/components/chat-view/ChatTurnErrorNotice.tsx +3 -1
  225. package/src/components/layouts/ConnectedCustomApp.tsx +63 -0
  226. package/src/components/layouts/Sidebar.tsx +9 -3
  227. package/src/components/planning/ActioningView.tsx +62 -70
  228. package/src/components/planning/ManualActionCard.tsx +66 -14
  229. package/src/components/planning/ManualActionList.tsx +30 -11
  230. package/src/components/planning/actioning-view-utils.ts +27 -1
  231. package/src/components/table-skeleton/index.tsx +7 -1
  232. package/src/components/tooltip/index.tsx +35 -2
  233. package/src/graph/createNodeRouter.tsx +3 -3
  234. package/src/graph/entity-link.tsx +20 -0
  235. package/src/graph/graph-list-utils.ts +2 -0
  236. package/src/graph/graph-model.ts +15 -6
  237. package/src/graph/nodes/BrandAssetAnalysisView.tsx +3 -1
  238. package/src/graph/nodes/{BrandFontFamilyView.tsx → BrandFontSuggestionView.tsx} +41 -27
  239. package/src/graph/nodes/BrandGuidelinesView.tsx +1 -1
  240. package/src/graph/nodes/NodePropertyTable.tsx +32 -143
  241. package/src/graph/nodes/brand-font.ts +17 -0
  242. package/src/graph/nodes/brand-shared.tsx +1 -4
  243. package/src/graph/nodes/node-property-row.tsx +154 -0
  244. package/src/graph/property-formatters.ts +5 -1
  245. package/src/graph/special-nodes/AttributeList.tsx +177 -0
  246. package/src/graph/special-nodes/EntityPreview.tsx +27 -0
  247. package/src/graph/special-nodes/EntityValueChip.tsx +85 -0
  248. package/src/graph/special-nodes/GenericView.tsx +49 -139
  249. package/src/graph/special-nodes/card-facts.ts +278 -0
  250. package/src/graph/special-nodes/property-icons.ts +59 -0
  251. package/src/graph/status-utils.ts +40 -0
  252. package/src/graph/types.ts +4 -0
  253. package/src/hooks/use-approve-anyway.ts +100 -0
  254. package/src/hooks/useAuth.ts +3 -3
  255. package/src/hooks/useOnboardingState.ts +1 -1
  256. package/src/ldo-ui.ts +8 -0
  257. package/src/lib/datastore-route-table.ts +4 -2
  258. package/src/lib/manual-actions.ts +3 -2
  259. package/src/providers/ActiveChatProvider.tsx +3 -1
  260. package/src/providers/AuthContext.ts +3 -1
  261. package/src/providers/ChatManagerProvider.tsx +19 -9
  262. package/src/providers/chat-socket-auth.ts +95 -16
  263. package/src/providers/index.tsx +16 -1
  264. package/src/routes/activity/detail/ActivityChanges.tsx +21 -5
  265. package/src/routes/activity/detail/ActivityDetail.tsx +24 -5
  266. package/src/routes/activity/detail/ActivityStepsRail.tsx +4 -2
  267. package/src/routes/activity/detail/ActivityTimeline.tsx +2 -2
  268. package/src/routes/activity/detail/NoChangesMessage.tsx +20 -0
  269. package/src/routes/data-explorer/components/RawTriples.tsx +1 -1
  270. package/src/routes/data-explorer/components/RecentTypes.tsx +1 -1
  271. package/src/routes/data-explorer/components/class-detail/Instances.tsx +1 -1
  272. package/src/routes/data-explorer/components/namespace-detail/NamespaceClassRow.tsx +1 -1
  273. package/src/routes/data-explorer/components/ontology-coverage/CoverageTermColumns.tsx +1 -1
  274. package/src/routes/data-explorer/components/ontology-coverage/UnobservedRuleVocabulary.tsx +1 -1
  275. package/src/routes/data-explorer/components/record-detail/ChatPreview.tsx +2 -2
  276. package/src/routes/data-explorer/declared-namespaces.ts +21 -13
  277. package/src/routes/data-explorer/namespaces.ts +7 -6
  278. package/src/routes/datastores/components/DeleteDatastoreDialog.tsx +78 -0
  279. package/src/routes/datastores/flatten.ts +15 -0
  280. package/src/routes/datastores/hooks/useDatastoreColumns.tsx +88 -49
  281. package/src/routes/datastores/index.tsx +41 -2
  282. package/src/routes/integrations/components/ProviderGroup.tsx +2 -2
  283. package/src/routes/integrations/components/connect-forms/DataConnectionConnectForm.tsx +38 -12
  284. package/src/routes/integrations/components/connect-forms/data-connection-fields.ts +11 -2
  285. package/src/routes/plans/components/ActionPlanPage.tsx +9 -8
  286. package/src/routes/plans/components/PlanDetailRouteContent.tsx +4 -3
  287. package/dist/components/planning/ExecutionActivityRow.d.ts +0 -9
  288. package/dist/components/planning/ExecutionActivityRow.d.ts.map +0 -1
  289. package/dist/components/planning/ExecutionActivityRow.js +0 -53
  290. package/dist/components/planning/ExecutionActivityRow.js.map +0 -1
  291. package/dist/components/planning/ExecutionSectionItem.d.ts +0 -20
  292. package/dist/components/planning/ExecutionSectionItem.d.ts.map +0 -1
  293. package/dist/components/planning/ExecutionSectionItem.js +0 -66
  294. package/dist/components/planning/ExecutionSectionItem.js.map +0 -1
  295. package/dist/components/planning/ExecutionSections.d.ts +0 -16
  296. package/dist/components/planning/ExecutionSections.d.ts.map +0 -1
  297. package/dist/components/planning/ExecutionSections.js +0 -32
  298. package/dist/components/planning/ExecutionSections.js.map +0 -1
  299. package/dist/components/planning/action-plan-icons.d.ts +0 -3
  300. package/dist/components/planning/action-plan-icons.d.ts.map +0 -1
  301. package/dist/components/planning/action-plan-icons.js +0 -25
  302. package/dist/components/planning/action-plan-icons.js.map +0 -1
  303. package/dist/components/planning/execution-section-model.d.ts +0 -24
  304. package/dist/components/planning/execution-section-model.d.ts.map +0 -1
  305. package/dist/components/planning/execution-section-model.js +0 -150
  306. package/dist/components/planning/execution-section-model.js.map +0 -1
  307. package/dist/graph/nodes/BrandFontFamilyView.d.ts +0 -3
  308. package/dist/graph/nodes/BrandFontFamilyView.d.ts.map +0 -1
  309. package/dist/graph/nodes/BrandFontFamilyView.js.map +0 -1
  310. package/dist/graph/nodes/BrandFontUploadButton.d.ts +0 -6
  311. package/dist/graph/nodes/BrandFontUploadButton.d.ts.map +0 -1
  312. package/dist/graph/nodes/BrandFontUploadButton.js +0 -69
  313. package/dist/graph/nodes/BrandFontUploadButton.js.map +0 -1
  314. package/dist/routes/data-explorer/components/TruncateTooltip.d.ts +0 -7
  315. package/dist/routes/data-explorer/components/TruncateTooltip.d.ts.map +0 -1
  316. package/dist/routes/data-explorer/components/TruncateTooltip.js +0 -9
  317. package/dist/routes/data-explorer/components/TruncateTooltip.js.map +0 -1
  318. package/src/components/planning/ExecutionActivityRow.tsx +0 -89
  319. package/src/components/planning/ExecutionSectionItem.tsx +0 -184
  320. package/src/components/planning/ExecutionSections.tsx +0 -97
  321. package/src/components/planning/action-plan-icons.tsx +0 -27
  322. package/src/components/planning/execution-section-model.ts +0 -190
  323. package/src/graph/nodes/BrandFontUploadButton.tsx +0 -95
  324. package/src/routes/data-explorer/components/TruncateTooltip.tsx +0 -25
@@ -0,0 +1,100 @@
1
+ import { useExecuteAgentActionAdditionMutation } from "@manta-eu/client";
2
+ import { isPresent } from "@manta-eu/lib/present";
3
+ import { isValidFullIri, namespaces } from "@manta-eu/rdf-lib/namespaces";
4
+ import { useQueryClient } from "@tanstack/react-query";
5
+ import { DataFactory } from "ldkit/rdf";
6
+ import { sparql } from "ldkit/sparql";
7
+ import { useCallback, useMemo, useRef, useState } from "react";
8
+ import { toast } from "sonner";
9
+ import type { ManualAction } from "./use-manual-actions";
10
+ import { useSparqlSelect } from "./use-sparql-construct";
11
+ import { buildActionDocument, mintSubjectIri } from "#lib/action-document";
12
+ import { useMantaClient } from "#providers/MantaClientProvider";
13
+ import { invalidateActionPlanQueries } from "#shared/query-keys";
14
+
15
+ const df = new DataFactory();
16
+ const assetAnalysis = `${namespaces.brand}AssetAnalysis`;
17
+ const assetDecision = `${namespaces.brand}AssetDecision`;
18
+ const decideAssetShape = `${namespaces.brand}DecideAssetShape`;
19
+
20
+ export type ApproveAnywayHandle = {
21
+ /** Sends the approval; `reviewKey` names the review it answers, so a later review of the same analysis asks again. */
22
+ approve: (analysisIri: string, reviewKey: string) => void;
23
+ approving: ReadonlySet<string>;
24
+ approved: ReadonlySet<string>;
25
+ };
26
+
27
+ /** Maps each manual action about a brand analysis to that analysis, the one a person can approve anyway. */
28
+ export function useApprovableAnalyses(actions: readonly ManualAction[]): Map<string, string> {
29
+ const aboutIris = useMemo(() => {
30
+ const iris = actions.flatMap(({ aboutIri }) => (isPresent(aboutIri) && isValidFullIri(aboutIri) ? [aboutIri] : []));
31
+ return [...new Set(iris)].sort();
32
+ }, [actions]);
33
+
34
+ const values = aboutIris.map((iri) => sparql`${df.namedNode(iri)}`).join(" ");
35
+ const query = isPresent(aboutIris)
36
+ ? `SELECT ?about WHERE { VALUES ?about { ${values} } ?about a ${sparql`${df.namedNode(assetAnalysis)}`} . }`
37
+ : "";
38
+
39
+ const { data } = useSparqlSelect({
40
+ query,
41
+ queryKey: ["ldo-ui", "approvable-analyses", aboutIris],
42
+ enabled: isPresent(aboutIris),
43
+ });
44
+
45
+ return useMemo(() => {
46
+ const analyses = new Set((data ?? []).flatMap((row) => row.get("about")?.value ?? []));
47
+ const approvable = new Map<string, string>();
48
+ for (const action of actions) {
49
+ if (isPresent(action.aboutIri) && analyses.has(action.aboutIri)) {
50
+ approvable.set(action.subjectIri, action.aboutIri);
51
+ }
52
+ }
53
+ return approvable;
54
+ }, [actions, data]);
55
+ }
56
+
57
+ /** Records a person's approval of an analysis that was not confirmed on-brand, so the rules publish it anyway. */
58
+ export function useApproveAnyway(planGraphIri: string): ApproveAnywayHandle {
59
+ const queryClient = useQueryClient();
60
+ const { mantaClient } = useMantaClient();
61
+ const { mutateAsync: startAddition } = useExecuteAgentActionAdditionMutation(mantaClient);
62
+ const inFlight = useRef(new Set<string>());
63
+ const [approving, setApproving] = useState<ReadonlySet<string>>(() => new Set());
64
+ const [approved, setApproved] = useState<ReadonlySet<string>>(() => new Set());
65
+
66
+ const approve = useCallback(
67
+ (analysisIri: string, reviewKey: string) => {
68
+ if (inFlight.current.has(analysisIri)) return;
69
+ inFlight.current.add(analysisIri);
70
+ setApproving(new Set(inFlight.current));
71
+ const subjectIri = mintSubjectIri(assetDecision);
72
+ const properties = buildActionDocument(
73
+ { subjectIri, rdfType: assetDecision },
74
+ {
75
+ [`${namespaces.brand}decisionOnAsset`]: { "@id": analysisIri },
76
+ [`${namespaces.brand}decision`]: "approved",
77
+ },
78
+ );
79
+ void startAddition({
80
+ input: { subjectIri, rdfType: assetDecision, actionShape: decideAssetShape, properties },
81
+ })
82
+ .then(({ executeActionAddition }) => {
83
+ if (!executeActionAddition.success) throw new Error(executeActionAddition.error ?? "The approval failed");
84
+ setApproved((previous) => new Set(previous).add(reviewKey));
85
+ toast.success("Approved. It is uploaded, and this review closes, when the plan next runs.");
86
+ void invalidateActionPlanQueries(queryClient, planGraphIri);
87
+ })
88
+ .catch((error: unknown) => {
89
+ toast.error(error instanceof Error ? error.message : "The approval failed");
90
+ })
91
+ .finally(() => {
92
+ inFlight.current.delete(analysisIri);
93
+ setApproving(new Set(inFlight.current));
94
+ });
95
+ },
96
+ [startAddition, queryClient, planGraphIri],
97
+ );
98
+
99
+ return { approve, approving, approved };
100
+ }
@@ -26,7 +26,7 @@ export type UseAuthResult = {
26
26
  isAuthenticated: boolean;
27
27
  isOperator: boolean;
28
28
  canManageTeam: boolean;
29
- canManageExternalApps: boolean;
29
+ canManageCustomApps: boolean;
30
30
  orgRoles: OrgRoleDefinition[];
31
31
  canManageIntegrations: boolean;
32
32
  canManageStreams: boolean;
@@ -79,7 +79,7 @@ export const contextResponseSchema = z.object({
79
79
  canManageStreams: z.boolean().optional().default(false),
80
80
  canManageSharedMemories: z.boolean().optional().default(false),
81
81
  canManageTeam: z.boolean().optional().default(false),
82
- canManageExternalApps: z.boolean().optional().default(false),
82
+ canManageCustomApps: z.boolean().optional().default(false),
83
83
  datastore: datastoreSchema.nullish(),
84
84
  }),
85
85
  datastores: z.array(datastoreSchema),
@@ -297,7 +297,7 @@ export function useAuth(): UseAuthResult {
297
297
  datastoreAccessGranted: contextData?.datastoreAccessGranted ?? true,
298
298
  isOperator: contextData?.user?.isOperator ?? false,
299
299
  canManageTeam: contextData?.user?.canManageTeam ?? false,
300
- canManageExternalApps: contextData?.user?.canManageExternalApps ?? false,
300
+ canManageCustomApps: contextData?.user?.canManageCustomApps ?? false,
301
301
  orgRoles: contextData?.orgRoles ?? [],
302
302
  canManageIntegrations: contextData?.user?.canManageIntegrations ?? false,
303
303
  canManageStreams: contextData?.user?.canManageStreams ?? false,
@@ -1,7 +1,7 @@
1
+ import { onboardingCompletedCookieName as onboardingCookieName } from "@manta-eu/client/shared/constants";
1
2
  import Cookies from "js-cookie";
2
3
  import { useCallback, useState } from "react";
3
4
 
4
- const onboardingCookieName = "manta-onboarding-completed";
5
5
  const onboardingCookieExpiryDays = 365;
6
6
 
7
7
  type OnboardingState = {
package/src/ldo-ui.ts CHANGED
@@ -268,6 +268,7 @@ export type {
268
268
  EntityView,
269
269
  EntityViewProps,
270
270
  LayoutDirection,
271
+ NodeRelation,
271
272
  OnNodeContextMenu,
272
273
  RDFNode,
273
274
  RDFNodeData,
@@ -275,6 +276,13 @@ export type {
275
276
  SampleInstance,
276
277
  } from "./graph/types";
277
278
  export { jsonLdToRdfGraph } from "./graph/jsonld-bridge";
279
+ export {
280
+ EntityLinkProvider,
281
+ useEntityLink,
282
+ type EntityLinkComponent,
283
+ type EntityLinkProps,
284
+ type EntityLinkProviderProps,
285
+ } from "./graph/entity-link";
278
286
  export { rdfGraphToNodesAndEdges, rdfGraphToSummaryNodesAndEdges } from "./graph/graph-model";
279
287
  export {
280
288
  applyDagreLayout,
@@ -17,7 +17,8 @@ export type RouteElements = {
17
17
  Integrations?: ReactNode;
18
18
  ShopifyConnect?: ReactNode;
19
19
  Team?: ReactNode;
20
- ExternalApps?: ReactNode;
20
+ CustomApps?: ReactNode;
21
+ CustomAppUsers?: ReactNode;
21
22
  DataExplorerLayout?: ReactNode;
22
23
  DataExplorerIndex?: ReactNode;
23
24
  DataExplorerRecent?: ReactNode;
@@ -45,7 +46,8 @@ export const globalRoutes: RouteDefinition[] = [
45
46
  { path: "/datastores", render: (e) => e.Datastores || notFoundElement(e) },
46
47
  // Global, not datastore-scoped: Shopify sends the merchant here before any datastore is known.
47
48
  { path: "/shopify/connect", render: (e) => e.ShopifyConnect || notFoundElement(e) },
48
- { path: "/custom-apps", render: (e) => e.ExternalApps || notFoundElement(e) },
49
+ { path: "/custom-apps", render: (e) => e.CustomApps || notFoundElement(e) },
50
+ { path: "/custom-apps/:clientId/users", render: (e) => e.CustomAppUsers || notFoundElement(e) },
49
51
  ];
50
52
 
51
53
  export const datastoreRoutes: RouteDefinition[] = [
@@ -16,6 +16,7 @@ export function getPendingManualActions(actions: readonly ManualAction[] | undef
16
16
  return (actions ?? []).filter(isPendingManualAction);
17
17
  }
18
18
 
19
- export function getResolvedManualActions(actions: readonly ManualAction[] | undefined): ManualAction[] {
20
- return (actions ?? []).filter(isResolvedManualAction);
19
+ /** Names the review an approval answers: the step, as of the analysis it currently reports. */
20
+ export function approvalReviewKey(action: Pick<ManualAction, "subjectIri" | "observedValue">): string {
21
+ return `${action.subjectIri}|${action.observedValue ?? ""}`;
21
22
  }
@@ -109,7 +109,9 @@ function ThinkChatSession(props: ThinkChatSessionProps) {
109
109
  sub: [{ agent: "ThinkChat", name: conversationId }],
110
110
  host,
111
111
  query: socketAuth.query,
112
- ...("cacheTtl" in socketAuth ? { cacheTtl: socketAuth.cacheTtl } : {}),
112
+ ...("enabled" in socketAuth
113
+ ? { enabled: socketAuth.enabled, shouldReconnectOnClose: socketAuth.shouldReconnectOnClose }
114
+ : {}),
113
115
  onClose: handleAgentClose,
114
116
  onMessage: handleAgentMessage,
115
117
  });
@@ -9,7 +9,7 @@ export type AuthContextValue = Pick<
9
9
  | "logout"
10
10
  | "isOperator"
11
11
  | "canManageTeam"
12
- | "canManageExternalApps"
12
+ | "canManageCustomApps"
13
13
  | "orgRoles"
14
14
  | "canManageIntegrations"
15
15
  | "canManageStreams"
@@ -18,6 +18,8 @@ export type AuthContextValue = Pick<
18
18
  | "allowedModels"
19
19
  > & {
20
20
  user: User;
21
+ // Only Manta's own web app may list the apps connected to someone; any other host's token is refused.
22
+ canDisconnectCustomApps?: boolean;
21
23
  };
22
24
 
23
25
  export const AuthContext = createContext<AuthContextValue | undefined>(undefined);
@@ -80,6 +80,7 @@ export function ChatManagerProvider(props: ChatManagerProviderProps) {
80
80
  const conversationSelectionRef = useRef(conversationSelection);
81
81
  const pathnameRef = useRef(location.pathname);
82
82
  const routedConversationIdRef = useRef(routedConversationId);
83
+ const pendingPlanNavigationRef = useRef<{ pathname: string } | undefined>(undefined);
83
84
 
84
85
  // Where navigate() was last sent, which react-router's deferred location has not reached yet.
85
86
  const requestedPathRef = useRef(location.pathname);
@@ -96,7 +97,9 @@ export function ChatManagerProvider(props: ChatManagerProviderProps) {
96
97
  basePath: chatManagerBasePath,
97
98
  host: mantaBaseUrl.host,
98
99
  query: socketAuth.query,
99
- ...("cacheTtl" in socketAuth ? { cacheTtl: socketAuth.cacheTtl } : {}),
100
+ ...("enabled" in socketAuth
101
+ ? { enabled: socketAuth.enabled, shouldReconnectOnClose: socketAuth.shouldReconnectOnClose }
102
+ : {}),
100
103
  });
101
104
 
102
105
  const listConversations = useCallback(
@@ -351,7 +354,11 @@ export function ChatManagerProvider(props: ChatManagerProviderProps) {
351
354
  );
352
355
 
353
356
  const selectContext = useCallback(
354
- (context: ChatContext): Promise<void> => transitionContext({ kind: "select", context }).then(() => undefined),
357
+ (context: ChatContext): Promise<void> => {
358
+ // The current page may synchronize its old context while an explicit plan selection is waiting.
359
+ if (pendingPlanNavigationRef.current?.pathname === pathnameRef.current) return Promise.resolve();
360
+ return transitionContext({ kind: "select", context }).then(() => undefined);
361
+ },
355
362
  [transitionContext],
356
363
  );
357
364
 
@@ -390,17 +397,20 @@ export function ChatManagerProvider(props: ChatManagerProviderProps) {
390
397
 
391
398
  const context = { kind: ChatContextKind.Plan, planGraphIri: planIri } as const;
392
399
  const source = activeConversationFromSelection(conversationSelectionRef.current);
393
- if (source) {
394
- try {
400
+ const navigation = { pathname: pathnameRef.current };
401
+ pendingPlanNavigationRef.current = navigation;
402
+ try {
403
+ if (source) {
395
404
  const transitioned = await reassignCurrentConversation(context);
396
405
  if (!transitioned) return;
397
- } catch {
398
- toast.error("Couldn't move this chat to the plan. Please try again.");
399
- return;
400
406
  }
401
- }
402
407
 
403
- void navigate(buildPlanHref(planIri), { state: { fromChat: true } });
408
+ void navigate(buildPlanHref(planIri), { state: { fromChat: true } });
409
+ } catch {
410
+ toast.error("Couldn't move this chat to the plan. Please try again.");
411
+ } finally {
412
+ if (pendingPlanNavigationRef.current === navigation) pendingPlanNavigationRef.current = undefined;
413
+ }
404
414
  },
405
415
  [navigate, onSelectPlan, reassignCurrentConversation],
406
416
  );
@@ -1,44 +1,123 @@
1
1
  import { chatTicketPath, chatTicketQueryParam } from "@manta-eu/client/shared/chat-manager";
2
2
  import { datastoreHeader, datastoreQueryParam } from "@manta-eu/client/shared/datastore-path";
3
3
  import { isPresent } from "@manta-eu/lib/present";
4
- import { useCallback, useEffect, useMemo } from "react";
4
+ import { isTerminalCloseEvent } from "agents/client";
5
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
6
  import { providerFetch } from "./manta-client-context";
6
7
  import { useMantaClient } from "./MantaClientProvider";
7
8
 
8
- // A reconnect always fetches a new ticket, and an expiring cache entry would replace a live socket.
9
- const ticketCacheTtlMs = 24 * 60 * 60 * 1000;
10
9
  const tokenRefreshCheckMs = 30_000;
10
+ const reconnectDelaysMs = [0, 1_000, 2_000, 5_000, 10_000];
11
+ const dropCountResetMs = 60_000;
12
+ const stableConnectionMs = 5_000;
13
+ // Any other 4xx is Manta refusing this person or datastore for good, so asking again cannot help.
14
+ const retriedRefusals = new Set([401, 408, 429]);
11
15
 
12
16
  export type ChatSocketAuth =
13
17
  | { query: Record<string, string>; credentials: "include" }
14
- | { query: () => Promise<Record<string, string>>; cacheTtl: number; credentials: "omit" };
18
+ | {
19
+ query: Record<string, string>;
20
+ enabled: boolean;
21
+ shouldReconnectOnClose: (event: CloseEvent) => boolean;
22
+ credentials: "omit";
23
+ };
24
+
25
+ type Ticketed = { datastoreKey: string; query: Record<string, string> };
15
26
 
16
27
  function ticketFrom(body: unknown): string | undefined {
17
28
  if (typeof body !== "object" || body === null || !("ticket" in body)) return undefined;
18
29
  return typeof body.ticket === "string" ? body.ticket : undefined;
19
30
  }
20
31
 
32
+ // partysocket clears shouldReconnect before a close it was asked for: an unmount, or a socket being replaced.
33
+ function isRequestedClose(event: CloseEvent): boolean {
34
+ const target: unknown = event.target;
35
+ return typeof target === "object" && target !== null && "shouldReconnect" in target && !target.shouldReconnect;
36
+ }
37
+
38
+ /**
39
+ * A ticket is spent on its first connect, and partysocket would reconnect to the same URL, so the socket never
40
+ * reconnects by itself: each connect waits for a new ticket, and a dropped socket asks for one.
41
+ */
21
42
  export function useChatSocketAuth(datastoreQuery: Record<string, string>): ChatSocketAuth {
22
43
  const client = useMantaClient();
23
44
  const { getAccessToken, mantaBaseUrl } = client;
24
45
  const authorizedFetch = providerFetch(client);
46
+ const authorizedFetchRef = useRef(authorizedFetch);
47
+ authorizedFetchRef.current = authorizedFetch;
48
+ const hasAccessToken = getAccessToken !== undefined;
49
+ const datastoreKey = JSON.stringify(datastoreQuery);
50
+ const datastoreQueryRef = useRef(datastoreQuery);
51
+ datastoreQueryRef.current = datastoreQuery;
52
+ const [ticketed, setTicketed] = useState<Ticketed>();
53
+ const [connectRequest, setConnectRequest] = useState(0);
54
+ const drops = useRef({ count: 0, lastAt: 0 });
55
+ const ticketedAt = useRef<number>(undefined);
25
56
 
26
- const ticketQuery = useCallback(async () => {
27
- const response = await authorizedFetch(new URL(`/${chatTicketPath}`, mantaBaseUrl), {
28
- method: "POST",
29
- headers: datastoreHeader(datastoreQuery[datastoreQueryParam]),
30
- });
31
- const ticket = response.ok ? ticketFrom(await response.json()) : undefined;
32
- if (!isPresent(ticket)) throw new Error(`Manta refused a chat ticket (${response.status})`);
33
- return { ...datastoreQuery, [chatTicketQueryParam]: ticket };
34
- }, [authorizedFetch, mantaBaseUrl, datastoreQuery]);
57
+ // A socket that stayed up starts the backoff over; one dropped at once, as a server refusing it would, does not.
58
+ const recordDrop = useCallback((socketClosed = false) => {
59
+ const now = Date.now();
60
+ const stayedUp = socketClosed && ticketedAt.current !== undefined && now - ticketedAt.current >= stableConnectionMs;
61
+ const fresh = stayedUp || now - drops.current.lastAt > dropCountResetMs;
62
+ drops.current = { count: fresh ? 1 : drops.current.count + 1, lastAt: now };
63
+ setConnectRequest((request) => request + 1);
64
+ }, []);
65
+
66
+ useEffect(() => {
67
+ if (!hasAccessToken) return;
68
+ setTicketed((held) => (held?.datastoreKey === datastoreKey ? held : undefined));
69
+ let cancelled = false;
70
+ const delay = reconnectDelaysMs[Math.min(Math.max(drops.current.count - 1, 0), reconnectDelaysMs.length - 1)];
71
+ const timer = setTimeout(() => {
72
+ const query = datastoreQueryRef.current;
73
+ authorizedFetchRef
74
+ .current(new URL(`/${chatTicketPath}`, mantaBaseUrl), {
75
+ method: "POST",
76
+ headers: datastoreHeader(query[datastoreQueryParam]),
77
+ })
78
+ .then(async (response) => {
79
+ if (response.status >= 400 && response.status < 500 && !retriedRefusals.has(response.status)) {
80
+ if (!cancelled) console.warn(`Manta refused a chat ticket (${response.status}); not asking again`);
81
+ return;
82
+ }
83
+ const ticket = response.ok ? ticketFrom(await response.json()) : undefined;
84
+ if (!isPresent(ticket)) throw new Error(`Manta refused a chat ticket (${response.status})`);
85
+ if (cancelled) return;
86
+ ticketedAt.current = Date.now();
87
+ setTicketed({ datastoreKey, query: { ...query, [chatTicketQueryParam]: ticket } });
88
+ })
89
+ .catch((error: unknown) => {
90
+ if (cancelled) return;
91
+ console.warn("Could not get a chat ticket", error);
92
+ recordDrop();
93
+ });
94
+ }, delay);
95
+ return () => {
96
+ cancelled = true;
97
+ clearTimeout(timer);
98
+ };
99
+ }, [hasAccessToken, mantaBaseUrl, datastoreKey, connectRequest, recordDrop]);
100
+
101
+ const shouldReconnectOnClose = useCallback(
102
+ (event: CloseEvent) => {
103
+ if (!isRequestedClose(event) && !isTerminalCloseEvent(event)) recordDrop(true);
104
+ return false;
105
+ },
106
+ [recordDrop],
107
+ );
35
108
 
109
+ const ticketQuery = ticketed?.datastoreKey === datastoreKey ? ticketed.query : undefined;
36
110
  return useMemo(
37
111
  () =>
38
- getAccessToken
39
- ? { query: ticketQuery, cacheTtl: ticketCacheTtlMs, credentials: "omit" as const }
112
+ hasAccessToken
113
+ ? {
114
+ query: ticketQuery ?? datastoreQuery,
115
+ enabled: ticketQuery !== undefined,
116
+ shouldReconnectOnClose,
117
+ credentials: "omit" as const,
118
+ }
40
119
  : { query: datastoreQuery, credentials: "include" as const },
41
- [getAccessToken, ticketQuery, datastoreQuery],
120
+ [hasAccessToken, ticketQuery, datastoreQuery, shouldReconnectOnClose],
42
121
  );
43
122
  }
44
123
 
@@ -1,9 +1,12 @@
1
1
  import { defaultDeployment } from "@manta-eu/auth/default-deployment";
2
2
  import type { AccessTokenSource } from "@manta-eu/client";
3
+ import { entityPath } from "@manta-eu/client/shared/explorer-paths";
3
4
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
5
  import { NuqsAdapter } from "nuqs/adapters/react-router/v7";
5
6
  import type { ReactNode } from "react";
6
7
  import { useState } from "react";
8
+ import { Link } from "react-router";
9
+ import { EntityLinkProvider, type EntityLinkProps } from "../graph/entity-link";
7
10
  import { ActiveDatastoreProvider, ActiveDatastoreRouter, useActiveDatastore } from "./ActiveDatastoreProvider";
8
11
  import { GenerateStructuredDataProvider } from "./GenerateStructuredDataProvider";
9
12
  import { KnowledgeGraphPollingProvider } from "./KnowledgeGraphPollingProvider";
@@ -89,6 +92,16 @@ function CoreProviders(props: ProvidersProps) {
89
92
  );
90
93
  }
91
94
 
95
+ function RecordEntityLink(props: EntityLinkProps) {
96
+ const { iri, className, children } = props;
97
+
98
+ return (
99
+ <Link to={entityPath(iri)} className={className} onClick={(event) => event.stopPropagation()}>
100
+ {children}
101
+ </Link>
102
+ );
103
+ }
104
+
92
105
  export function Providers(props: ProvidersProps) {
93
106
  const { children, ...coreProps } = props;
94
107
 
@@ -97,7 +110,9 @@ export function Providers(props: ProvidersProps) {
97
110
  <ThemeProvider>
98
111
  <CoreProviders {...coreProps}>
99
112
  <ActiveDatastoreRouter>
100
- <NuqsAdapter>{children}</NuqsAdapter>
113
+ <NuqsAdapter>
114
+ <EntityLinkProvider component={RecordEntityLink}>{children}</EntityLinkProvider>
115
+ </NuqsAdapter>
101
116
  </ActiveDatastoreRouter>
102
117
  </CoreProviders>
103
118
  </ThemeProvider>
@@ -8,6 +8,7 @@ import { useIntersectionObserver } from "usehooks-ts";
8
8
  import { DiffRow } from "../change-display";
9
9
  import { EntityNodeView, subsumesChangeRows } from "./EntityNodeView";
10
10
  import { LazyMount, viewportOverscan } from "./LazyMount";
11
+ import { NoChangesMessage } from "./NoChangesMessage";
11
12
  import { useEntityNodes, type ActivityChangeGroup, type EntityNode } from "#ldo-ui";
12
13
  import { cn } from "#lib/utils";
13
14
  import { entityPath } from "#routes/data-explorer/namespaces";
@@ -52,10 +53,11 @@ type ChangeGroupProps = {
52
53
  node?: EntityNode;
53
54
  nodesLoading: boolean;
54
55
  scrollRoot: HTMLElement | null;
56
+ showLinks: boolean;
55
57
  };
56
58
 
57
59
  function ChangeGroup(props: ChangeGroupProps) {
58
- const { group, selected, onJumpTo, node, nodesLoading, scrollRoot } = props;
60
+ const { group, selected, onJumpTo, node, nodesLoading, scrollRoot, showLinks } = props;
59
61
 
60
62
  // Answered from the change's own triples until the fetch lands, so the rows do not show then vanish.
61
63
  const typedCard = useMemo(
@@ -87,7 +89,7 @@ function ChangeGroup(props: ChangeGroupProps) {
87
89
  >
88
90
  {group.entityLabel}
89
91
  </button>
90
- {isFullIri(group.entityIri) && (
92
+ {showLinks && isFullIri(group.entityIri) && (
91
93
  <Link
92
94
  to={entityPath(group.entityIri)}
93
95
  aria-label={`Open ${group.entityLabel} in the data explorer`}
@@ -145,10 +147,11 @@ type ChangeBlockProps = {
145
147
  activeIri: string | null;
146
148
  onJumpTo: (entityIri: string) => void;
147
149
  scrollRoot: HTMLElement | null;
150
+ showLinks: boolean;
148
151
  };
149
152
 
150
153
  function ChangeBlock(props: ChangeBlockProps) {
151
- const { groups, activeIri, onJumpTo, scrollRoot } = props;
154
+ const { groups, activeIri, onJumpTo, scrollRoot, showLinks } = props;
152
155
 
153
156
  const { ref, isIntersecting } = useIntersectionObserver({
154
157
  root: scrollRoot,
@@ -173,6 +176,7 @@ function ChangeBlock(props: ChangeBlockProps) {
173
176
  .find(isPresent)}
174
177
  nodesLoading={isLoading}
175
178
  scrollRoot={scrollRoot}
179
+ showLinks={showLinks}
176
180
  />
177
181
  ))}
178
182
  </div>
@@ -188,10 +192,21 @@ export type ActivityChangesProps = {
188
192
  scrollTarget: { iri: string; nonce: number } | null;
189
193
  // Embedded runs in a short box, where the full-page scroll-room spacer would over-scroll.
190
194
  inline?: boolean;
195
+ running?: boolean;
196
+ showLinks?: boolean;
191
197
  };
192
198
 
193
199
  export function ActivityChanges(props: ActivityChangesProps) {
194
- const { groups, activeIri, onActivate, onJumpTo, scrollTarget, inline = false } = props;
200
+ const {
201
+ groups,
202
+ activeIri,
203
+ onActivate,
204
+ onJumpTo,
205
+ scrollTarget,
206
+ inline = false,
207
+ running = false,
208
+ showLinks = true,
209
+ } = props;
195
210
 
196
211
  const blocks = useMemo(
197
212
  () =>
@@ -260,7 +275,7 @@ export function ActivityChanges(props: ActivityChangesProps) {
260
275
  if (!isPresent(groups)) {
261
276
  return (
262
277
  <div className="rounded-xl border border-muted-border bg-card p-5">
263
- <p className="typography-small text-muted-foreground">No recorded changes.</p>
278
+ <NoChangesMessage running={running} />
264
279
  </div>
265
280
  );
266
281
  }
@@ -291,6 +306,7 @@ export function ActivityChanges(props: ActivityChangesProps) {
291
306
  activeIri={activeIri}
292
307
  onJumpTo={onJumpTo}
293
308
  scrollRoot={scrollRoot}
309
+ showLinks={showLinks}
294
310
  />
295
311
  ))}
296
312
 
@@ -41,10 +41,20 @@ export type ActivityDetailProps = {
41
41
  variant?: "page" | "embedded";
42
42
  // Embedded only — lead-in above the run, rendered after it loads.
43
43
  caption?: ReactNode;
44
+ // Off when the host has no route for the run page or the data explorer.
45
+ showLinks?: boolean;
44
46
  };
45
47
 
46
48
  export function ActivityDetail(props: ActivityDetailProps) {
47
- const { activityIri, leading, layout: controlledLayout, onLayoutChange, variant = "page", caption } = props;
49
+ const {
50
+ activityIri,
51
+ leading,
52
+ layout: controlledLayout,
53
+ onLayoutChange,
54
+ variant = "page",
55
+ caption,
56
+ showLinks = true,
57
+ } = props;
48
58
  const embedded = variant === "embedded";
49
59
 
50
60
  const [internalLayout, setInternalLayout] = useState<ActivityLayout>("timeline");
@@ -107,9 +117,13 @@ export function ActivityDetail(props: ActivityDetailProps) {
107
117
  />
108
118
  ) : null;
109
119
 
120
+ const isRunning = activity?.status === "running";
121
+
110
122
  const changes = (
111
123
  <ActivityChanges
112
124
  inline={embedded}
125
+ running={isRunning}
126
+ showLinks={showLinks}
113
127
  groups={groups}
114
128
  activeIri={activeIri}
115
129
  onActivate={activate}
@@ -140,7 +154,7 @@ export function ActivityDetail(props: ActivityDetailProps) {
140
154
  <div className="flex h-full min-h-0 flex-col gap-3">
141
155
  {isPresent(caption) && <p className="typography-small text-muted-foreground shrink-0">{caption}</p>}
142
156
  <div className="flex shrink-0 flex-wrap items-center gap-2">
143
- {isPresent(activityIri) ? (
157
+ {showLinks && isPresent(activityIri) ? (
144
158
  <Link
145
159
  to={buildActivityHref(activityIri)}
146
160
  title={`Open ${activity.planLabel} run detail`}
@@ -160,7 +174,7 @@ export function ActivityDetail(props: ActivityDetailProps) {
160
174
  <Banner label={activity.errorMessage} className="max-h-40 shrink-0 overflow-y-auto" />
161
175
  )}
162
176
 
163
- {isChangeSetLoading ? (
177
+ {isChangeSetLoading && !isRunning ? (
164
178
  <div className="flex items-center justify-center py-10">
165
179
  <Loader className="size-5" />
166
180
  </div>
@@ -234,7 +248,7 @@ export function ActivityDetail(props: ActivityDetailProps) {
234
248
  ) : layout === "steps" ? (
235
249
  <>
236
250
  <div className="min-h-0 flex-1 overflow-y-auto sm:hidden">
237
- <ActivityStepsRail groups={groups} activeIri={activeIri} onSelect={activate} />
251
+ <ActivityStepsRail groups={groups} activeIri={activeIri} onSelect={activate} running={isRunning} />
238
252
  <div className="border-t border-muted-border">
239
253
  <ActivityStepDetail group={activeGroup} />
240
254
  </div>
@@ -243,7 +257,12 @@ export function ActivityDetail(props: ActivityDetailProps) {
243
257
  <ResizablePanelGroup direction="horizontal" className="min-h-0 flex-1">
244
258
  <ResizablePanel defaultSize={26} minSize={18} maxSize={50} className="min-h-0">
245
259
  <div className="h-full overflow-y-auto">
246
- <ActivityStepsRail groups={groups} activeIri={activeIri} onSelect={activate} />
260
+ <ActivityStepsRail
261
+ groups={groups}
262
+ activeIri={activeIri}
263
+ onSelect={activate}
264
+ running={isRunning}
265
+ />
247
266
  </div>
248
267
  </ResizablePanel>
249
268
 
@@ -1,6 +1,7 @@
1
1
  import { humanCount } from "@manta-eu/lib/humanize";
2
2
  import { isPresent } from "@manta-eu/lib/present";
3
3
  import { formatStepTime } from "../format";
4
+ import { NoChangesMessage } from "./NoChangesMessage";
4
5
  import type { ActivityChangeGroup } from "#ldo-ui";
5
6
  import { cn } from "#lib/utils";
6
7
 
@@ -8,15 +9,16 @@ export type ActivityStepsRailProps = {
8
9
  groups: ActivityChangeGroup[];
9
10
  activeIri: string | null;
10
11
  onSelect: (entityIri: string) => void;
12
+ running?: boolean;
11
13
  };
12
14
 
13
15
  export function ActivityStepsRail(props: ActivityStepsRailProps) {
14
- const { groups, activeIri, onSelect } = props;
16
+ const { groups, activeIri, onSelect, running = false } = props;
15
17
 
16
18
  if (!isPresent(groups)) {
17
19
  return (
18
20
  <div className="p-4">
19
- <p className="typography-small text-muted-foreground">No recorded changes.</p>
21
+ <NoChangesMessage running={running} />
20
22
  </div>
21
23
  );
22
24
  }