@solidxai/core-ui 0.1.19 → 0.1.20-beta.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 (282) hide show
  1. package/dist/components/common/Link.d.ts.map +1 -1
  2. package/dist/components/common/Link.js +2 -1
  3. package/dist/components/common/Link.js.map +1 -1
  4. package/dist/components/common/Link.tsx +2 -1
  5. package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts +1 -0
  6. package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts.map +1 -1
  7. package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js +109 -23
  8. package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js.map +1 -1
  9. package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.tsx +155 -34
  10. package/dist/components/core/chatter/SolidChatter.js +2 -2
  11. package/dist/components/core/chatter/SolidChatter.js.map +1 -1
  12. package/dist/components/core/chatter/SolidChatter.tsx +2 -2
  13. package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.js +20 -19
  14. package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.js.map +1 -1
  15. package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.tsx +16 -16
  16. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.d.ts.map +1 -1
  17. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.js +3 -10
  18. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.js.map +1 -1
  19. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.tsx +3 -8
  20. package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.d.ts.map +1 -1
  21. package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.js +36 -9
  22. package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.js.map +1 -1
  23. package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.tsx +78 -7
  24. package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.d.ts +1 -0
  25. package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.d.ts.map +1 -1
  26. package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.js +1 -1
  27. package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.js.map +1 -1
  28. package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.tsx +1 -1
  29. package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.d.ts +4 -0
  30. package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.d.ts.map +1 -0
  31. package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.js +131 -0
  32. package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.js.map +1 -0
  33. package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.tsx +151 -0
  34. package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.d.ts +4 -0
  35. package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.d.ts.map +1 -0
  36. package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.js +13 -0
  37. package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.js.map +1 -0
  38. package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.tsx +20 -0
  39. package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
  40. package/dist/components/core/form/SolidFormView.js +4 -0
  41. package/dist/components/core/form/SolidFormView.js.map +1 -1
  42. package/dist/components/core/form/SolidFormView.tsx +4 -0
  43. package/dist/components/core/kanban/SolidKanbanView.d.ts.map +1 -1
  44. package/dist/components/core/kanban/SolidKanbanView.js +50 -15
  45. package/dist/components/core/kanban/SolidKanbanView.js.map +1 -1
  46. package/dist/components/core/kanban/SolidKanbanView.tsx +22 -3
  47. package/dist/components/core/list/SolidListView.d.ts.map +1 -1
  48. package/dist/components/core/list/SolidListView.js +16 -3
  49. package/dist/components/core/list/SolidListView.js.map +1 -1
  50. package/dist/components/core/list/SolidListView.tsx +16 -2
  51. package/dist/components/core/list/columns/SolidMediaMultipleColumn.d.ts.map +1 -1
  52. package/dist/components/core/list/columns/SolidMediaMultipleColumn.js +4 -1
  53. package/dist/components/core/list/columns/SolidMediaMultipleColumn.js.map +1 -1
  54. package/dist/components/core/list/columns/SolidMediaMultipleColumn.tsx +4 -1
  55. package/dist/components/core/module/ModulePackageDialog.css +102 -0
  56. package/dist/components/core/module/ModulePackageDialog.d.ts +2 -1
  57. package/dist/components/core/module/ModulePackageDialog.d.ts.map +1 -1
  58. package/dist/components/core/module/ModulePackageDialog.js +216 -68
  59. package/dist/components/core/module/ModulePackageDialog.js.map +1 -1
  60. package/dist/components/core/module/ModulePackageDialog.tsx +356 -76
  61. package/dist/components/core/solid-agent/SolidAgentChat.d.ts.map +1 -1
  62. package/dist/components/core/solid-agent/SolidAgentChat.js +9 -3
  63. package/dist/components/core/solid-agent/SolidAgentChat.js.map +1 -1
  64. package/dist/components/core/solid-agent/SolidAgentChat.tsx +9 -4
  65. package/dist/components/core/solid-agent/SolidAgentMarkdown.d.ts.map +1 -1
  66. package/dist/components/core/solid-agent/SolidAgentMarkdown.js +25 -6
  67. package/dist/components/core/solid-agent/SolidAgentMarkdown.js.map +1 -1
  68. package/dist/components/core/solid-agent/SolidAgentMarkdown.tsx +15 -1
  69. package/dist/components/core/solid-agent/client/agentRuntime.d.ts +5 -0
  70. package/dist/components/core/solid-agent/client/agentRuntime.d.ts.map +1 -1
  71. package/dist/components/core/solid-agent/client/agentRuntime.js +77 -20
  72. package/dist/components/core/solid-agent/client/agentRuntime.js.map +1 -1
  73. package/dist/components/core/solid-agent/client/agentRuntime.ts +29 -1
  74. package/dist/components/core/solid-agent/client/agentSocket.d.ts +5 -1
  75. package/dist/components/core/solid-agent/client/agentSocket.d.ts.map +1 -1
  76. package/dist/components/core/solid-agent/client/agentSocket.js +27 -4
  77. package/dist/components/core/solid-agent/client/agentSocket.js.map +1 -1
  78. package/dist/components/core/solid-agent/client/agentSocket.ts +14 -3
  79. package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.js +2 -2
  80. package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.js.map +1 -1
  81. package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx +5 -5
  82. package/dist/components/core/solid-agent/embed/agentEmbedProtocol.d.ts +2 -0
  83. package/dist/components/core/solid-agent/embed/agentEmbedProtocol.d.ts.map +1 -1
  84. package/dist/components/core/solid-agent/embed/agentEmbedProtocol.js +2 -2
  85. package/dist/components/core/solid-agent/embed/agentEmbedProtocol.js.map +1 -1
  86. package/dist/components/core/solid-agent/embed/agentEmbedProtocol.ts +4 -4
  87. package/dist/components/core/solid-agent/thread/AgentThread.d.ts.map +1 -1
  88. package/dist/components/core/solid-agent/thread/AgentThread.js +61 -26
  89. package/dist/components/core/solid-agent/thread/AgentThread.js.map +1 -1
  90. package/dist/components/core/solid-agent/thread/AgentThread.tsx +74 -40
  91. package/dist/components/core/solid-agent/thread/SolidAgentChatItem.d.ts +2 -1
  92. package/dist/components/core/solid-agent/thread/SolidAgentChatItem.d.ts.map +1 -1
  93. package/dist/components/core/solid-agent/thread/SolidAgentChatItem.js +2 -1
  94. package/dist/components/core/solid-agent/thread/SolidAgentChatItem.js.map +1 -1
  95. package/dist/components/core/solid-agent/thread/SolidAgentChatItem.tsx +3 -1
  96. package/dist/components/core/solid-agent/types.d.ts +3 -0
  97. package/dist/components/core/solid-agent/types.d.ts.map +1 -1
  98. package/dist/components/core/solid-agent/types.js +0 -9
  99. package/dist/components/core/solid-agent/types.js.map +1 -1
  100. package/dist/components/core/solid-agent/types.ts +4 -2
  101. package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.d.ts +1 -1
  102. package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.d.ts.map +1 -1
  103. package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.js +5 -2
  104. package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.js.map +1 -1
  105. package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.tsx +11 -5
  106. package/dist/components/core/solid-agent/widgets/DefaultErrorChatWidget.js +3 -0
  107. package/dist/components/core/solid-agent/widgets/DefaultErrorChatWidget.js.map +1 -1
  108. package/dist/components/core/solid-agent/widgets/DefaultErrorChatWidget.tsx +4 -0
  109. package/dist/components/core/solid-agent/widgets/DefaultNoticeChatWidget.js +3 -0
  110. package/dist/components/core/solid-agent/widgets/DefaultNoticeChatWidget.js.map +1 -1
  111. package/dist/components/core/solid-agent/widgets/DefaultNoticeChatWidget.tsx +4 -0
  112. package/dist/components/core/solid-agent/widgets/DefaultThinkingChatWidget.js +3 -0
  113. package/dist/components/core/solid-agent/widgets/DefaultThinkingChatWidget.js.map +1 -1
  114. package/dist/components/core/solid-agent/widgets/DefaultThinkingChatWidget.tsx +4 -0
  115. package/dist/components/core/solid-agent/widgets/DefaultToolCallChatWidget.js +3 -0
  116. package/dist/components/core/solid-agent/widgets/DefaultToolCallChatWidget.js.map +1 -1
  117. package/dist/components/core/solid-agent/widgets/DefaultToolCallChatWidget.tsx +4 -0
  118. package/dist/components/core/solid-agent/widgets/DefaultUnknownChatWidget.js +3 -0
  119. package/dist/components/core/solid-agent/widgets/DefaultUnknownChatWidget.js.map +1 -1
  120. package/dist/components/core/solid-agent/widgets/DefaultUnknownChatWidget.tsx +4 -0
  121. package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.js +3 -0
  122. package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.js.map +1 -1
  123. package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.tsx +4 -0
  124. package/dist/components/core/solid-agent/widgets/SolidChecklistChatWidget.js +3 -0
  125. package/dist/components/core/solid-agent/widgets/SolidChecklistChatWidget.js.map +1 -1
  126. package/dist/components/core/solid-agent/widgets/SolidChecklistChatWidget.tsx +4 -0
  127. package/dist/components/core/solid-agent/widgets/SolidCodeChatWidget.js +3 -0
  128. package/dist/components/core/solid-agent/widgets/SolidCodeChatWidget.js.map +1 -1
  129. package/dist/components/core/solid-agent/widgets/SolidCodeChatWidget.tsx +4 -0
  130. package/dist/components/core/solid-agent/widgets/SolidDiffListChatWidget.js +3 -0
  131. package/dist/components/core/solid-agent/widgets/SolidDiffListChatWidget.js.map +1 -1
  132. package/dist/components/core/solid-agent/widgets/SolidDiffListChatWidget.tsx +4 -0
  133. package/dist/components/core/solid-agent/widgets/SolidGalleryChatWidget.js +19 -0
  134. package/dist/components/core/solid-agent/widgets/SolidGalleryChatWidget.js.map +1 -1
  135. package/dist/components/core/solid-agent/widgets/SolidGalleryChatWidget.tsx +20 -0
  136. package/dist/components/core/solid-agent/widgets/SolidJsonChatWidget.js +3 -0
  137. package/dist/components/core/solid-agent/widgets/SolidJsonChatWidget.js.map +1 -1
  138. package/dist/components/core/solid-agent/widgets/SolidJsonChatWidget.tsx +4 -0
  139. package/dist/components/core/solid-agent/widgets/SolidLinkCardChatWidget.js +3 -0
  140. package/dist/components/core/solid-agent/widgets/SolidLinkCardChatWidget.js.map +1 -1
  141. package/dist/components/core/solid-agent/widgets/SolidLinkCardChatWidget.tsx +4 -0
  142. package/dist/components/core/solid-agent/widgets/SolidMarkdownChatWidget.js +3 -0
  143. package/dist/components/core/solid-agent/widgets/SolidMarkdownChatWidget.js.map +1 -1
  144. package/dist/components/core/solid-agent/widgets/SolidMarkdownChatWidget.tsx +4 -0
  145. package/dist/components/core/solid-agent/widgets/SolidProgressChatWidget.js +3 -0
  146. package/dist/components/core/solid-agent/widgets/SolidProgressChatWidget.js.map +1 -1
  147. package/dist/components/core/solid-agent/widgets/SolidProgressChatWidget.tsx +4 -0
  148. package/dist/components/core/solid-agent/widgets/SolidQuestionChatWidget.js +3 -0
  149. package/dist/components/core/solid-agent/widgets/SolidQuestionChatWidget.js.map +1 -1
  150. package/dist/components/core/solid-agent/widgets/SolidQuestionChatWidget.tsx +4 -0
  151. package/dist/components/core/solid-agent/widgets/SolidStatusChatWidget.js +3 -0
  152. package/dist/components/core/solid-agent/widgets/SolidStatusChatWidget.js.map +1 -1
  153. package/dist/components/core/solid-agent/widgets/SolidStatusChatWidget.tsx +4 -0
  154. package/dist/components/core/solid-agent/widgets/SolidTableChatWidget.js +3 -0
  155. package/dist/components/core/solid-agent/widgets/SolidTableChatWidget.js.map +1 -1
  156. package/dist/components/core/solid-agent/widgets/SolidTableChatWidget.tsx +4 -0
  157. package/dist/components/core/solid-agent/widgets/SolidToolActivityChatWidget.js +3 -0
  158. package/dist/components/core/solid-agent/widgets/SolidToolActivityChatWidget.js.map +1 -1
  159. package/dist/components/core/solid-agent/widgets/SolidToolActivityChatWidget.tsx +4 -0
  160. package/dist/components/core/solid-agent/widgets/solidChatWidgets.module.css +9 -1
  161. package/dist/components/core/users/CreateUser.d.ts.map +1 -1
  162. package/dist/components/core/users/CreateUser.js +23 -8
  163. package/dist/components/core/users/CreateUser.js.map +1 -1
  164. package/dist/components/core/users/CreateUser.tsx +10 -6
  165. package/dist/components/layout/AdminHeaderActions.d.ts.map +1 -1
  166. package/dist/components/layout/AdminHeaderActions.js +1 -29
  167. package/dist/components/layout/AdminHeaderActions.js.map +1 -1
  168. package/dist/components/layout/AdminHeaderActions.tsx +0 -42
  169. package/dist/components/layout/AdminTopHeader.js +2 -2
  170. package/dist/components/layout/AdminTopHeader.js.map +1 -1
  171. package/dist/components/layout/AdminTopHeader.tsx +2 -2
  172. package/dist/components/layout/AppSidebar.d.ts.map +1 -1
  173. package/dist/components/layout/AppSidebar.js +21 -5
  174. package/dist/components/layout/AppSidebar.js.map +1 -1
  175. package/dist/components/layout/AppSidebar.tsx +24 -6
  176. package/dist/components/layout/SolidAiStudioLayout.d.ts +0 -1
  177. package/dist/components/layout/SolidAiStudioLayout.d.ts.map +1 -1
  178. package/dist/components/layout/SolidAiStudioLayout.js +8 -161
  179. package/dist/components/layout/SolidAiStudioLayout.js.map +1 -1
  180. package/dist/components/layout/SolidAiStudioLayout.tsx +6 -136
  181. package/dist/components/layout/user-profile-menu.js +10 -10
  182. package/dist/components/layout/user-profile-menu.js.map +1 -1
  183. package/dist/components/layout/user-profile-menu.tsx +3 -3
  184. package/dist/components/shad-cn-ui/SolidLightbox.d.ts +2 -1
  185. package/dist/components/shad-cn-ui/SolidLightbox.d.ts.map +1 -1
  186. package/dist/components/shad-cn-ui/SolidLightbox.js +11 -4
  187. package/dist/components/shad-cn-ui/SolidLightbox.js.map +1 -1
  188. package/dist/components/shad-cn-ui/SolidLightbox.tsx +14 -1
  189. package/dist/helpers/modelViewPersistence.d.ts +2 -0
  190. package/dist/helpers/modelViewPersistence.d.ts.map +1 -1
  191. package/dist/helpers/modelViewPersistence.js +72 -0
  192. package/dist/helpers/modelViewPersistence.js.map +1 -1
  193. package/dist/helpers/modelViewPersistence.ts +79 -0
  194. package/dist/helpers/registry.d.ts +6 -2
  195. package/dist/helpers/registry.d.ts.map +1 -1
  196. package/dist/helpers/registry.js +68 -3
  197. package/dist/helpers/registry.js.map +1 -1
  198. package/dist/helpers/registry.ts +62 -4
  199. package/dist/hooks/useModelsDevModels.d.ts +43 -0
  200. package/dist/hooks/useModelsDevModels.d.ts.map +1 -0
  201. package/dist/hooks/useModelsDevModels.js +81 -0
  202. package/dist/hooks/useModelsDevModels.js.map +1 -0
  203. package/dist/hooks/useModelsDevModels.ts +106 -0
  204. package/dist/hooks/useRouter.d.ts.map +1 -1
  205. package/dist/hooks/useRouter.js +3 -2
  206. package/dist/hooks/useRouter.js.map +1 -1
  207. package/dist/hooks/useRouter.ts +3 -2
  208. package/dist/index.d.ts +2 -2
  209. package/dist/index.d.ts.map +1 -1
  210. package/dist/index.js +1 -1
  211. package/dist/index.js.map +1 -1
  212. package/dist/index.ts +4 -1
  213. package/dist/modules/solidUiModule.d.ts +3 -2
  214. package/dist/modules/solidUiModule.d.ts.map +1 -1
  215. package/dist/modules/solidUiModule.js +1 -1
  216. package/dist/modules/solidUiModule.js.map +1 -1
  217. package/dist/modules/solidUiModule.ts +5 -1
  218. package/dist/redux/api/moduleApi.d.ts +12 -2
  219. package/dist/redux/api/moduleApi.d.ts.map +1 -1
  220. package/dist/redux/api/moduleApi.js +33 -3
  221. package/dist/redux/api/moduleApi.js.map +1 -1
  222. package/dist/redux/api/moduleApi.ts +17 -2
  223. package/dist/redux/api/solidChatterMessageApi.d.ts +3 -1
  224. package/dist/redux/api/solidChatterMessageApi.d.ts.map +1 -1
  225. package/dist/redux/api/solidChatterMessageApi.js +9 -1
  226. package/dist/redux/api/solidChatterMessageApi.js.map +1 -1
  227. package/dist/redux/api/solidChatterMessageApi.ts +9 -1
  228. package/dist/redux/store/defaultStoreConfig.d.ts +9 -1
  229. package/dist/redux/store/defaultStoreConfig.d.ts.map +1 -1
  230. package/dist/resources/globals.css +30 -0
  231. package/dist/resources/solid-custom.css +10 -6
  232. package/dist/resources/solid-tailwind-generated.css +1 -1
  233. package/dist/routes/AppEventListener.d.ts.map +1 -1
  234. package/dist/routes/AppEventListener.js +3 -3
  235. package/dist/routes/AppEventListener.js.map +1 -1
  236. package/dist/routes/AppEventListener.tsx +2 -3
  237. package/dist/routes/pages/admin/core/AgentHubTagsField.css +21 -0
  238. package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts +17 -0
  239. package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts.map +1 -0
  240. package/dist/routes/pages/admin/core/AgentHubTagsField.js +171 -0
  241. package/dist/routes/pages/admin/core/AgentHubTagsField.js.map +1 -0
  242. package/dist/routes/pages/admin/core/AgentHubTagsField.tsx +125 -0
  243. package/dist/routes/pages/admin/core/AgentPersonaHistory.css +130 -0
  244. package/dist/routes/pages/admin/core/AgentPersonaHistory.d.ts +7 -0
  245. package/dist/routes/pages/admin/core/AgentPersonaHistory.d.ts.map +1 -0
  246. package/dist/routes/pages/admin/core/AgentPersonaHistory.js +228 -0
  247. package/dist/routes/pages/admin/core/AgentPersonaHistory.js.map +1 -0
  248. package/dist/routes/pages/admin/core/AgentPersonaHistory.tsx +234 -0
  249. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.css +13 -14
  250. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.d.ts.map +1 -1
  251. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js +218 -165
  252. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js.map +1 -1
  253. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.tsx +221 -127
  254. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.d.ts.map +1 -1
  255. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js +14 -69
  256. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js.map +1 -1
  257. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.tsx +15 -83
  258. package/dist/routes/pages/admin/core/AgentToolActivationDialog.d.ts +11 -0
  259. package/dist/routes/pages/admin/core/AgentToolActivationDialog.d.ts.map +1 -0
  260. package/dist/routes/pages/admin/core/AgentToolActivationDialog.js +166 -0
  261. package/dist/routes/pages/admin/core/AgentToolActivationDialog.js.map +1 -0
  262. package/dist/routes/pages/admin/core/AgentToolActivationDialog.tsx +140 -0
  263. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.css +26 -0
  264. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.d.ts.map +1 -1
  265. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js +94 -71
  266. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js.map +1 -1
  267. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.tsx +60 -52
  268. package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.d.ts +2 -0
  269. package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.d.ts.map +1 -0
  270. package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.js +108 -0
  271. package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.js.map +1 -0
  272. package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.tsx +96 -0
  273. package/dist/routes/solidRoutes.d.ts.map +1 -1
  274. package/dist/routes/solidRoutes.js +2 -0
  275. package/dist/routes/solidRoutes.js.map +1 -1
  276. package/dist/routes/solidRoutes.tsx +2 -0
  277. package/dist/types/extension-registry.d.ts +12 -0
  278. package/dist/types/extension-registry.d.ts.map +1 -1
  279. package/dist/types/extension-registry.js.map +1 -1
  280. package/dist/types/extension-registry.ts +15 -0
  281. package/dist/types/solid-core.d.ts +2 -0
  282. package/package.json +2 -1
@@ -1,10 +1,13 @@
1
1
  import React from "react";
2
- import { ArrowLeft, Plus, RefreshCw, X } from "lucide-react";
2
+ import { ArrowLeft, RefreshCw } from "lucide-react";
3
3
  import { useDispatch } from "react-redux";
4
4
  import { useNavigate, useParams } from "react-router-dom";
5
5
  import { createSolidEntityApi } from "../../../../redux/api/solidEntityApi";
6
6
  import { showToast } from "../../../../redux/features/toastSlice";
7
+ import { solidPatch } from "../../../../http/solidHttp";
7
8
  import { AgentRegistryAuditPanel } from "./AgentRegistryAuditPanel";
9
+ import { AgentHubTagsField, agentHubTagsFrom, agentHubTagsPayload, type AgentHubTag } from "./AgentHubTagsField";
10
+ import { AgentToolActivationDialog } from "./AgentToolActivationDialog";
8
11
  import { AgentToolSessionsPanel } from "../../../../components/core/extension/solid-core/agentToolRegistry/AgentToolSessionsPanel";
9
12
  import { AgentRegistryCardWidget } from "../../../../components/core/extension/solid-core/agentRegistry/card/AgentRegistryCardWidget";
10
13
  import { SolidButton, SolidCodeEditor, SolidDialog, SolidDialogBody, SolidIconPicker, SolidInput, SolidTabGroup } from "../../../../components/shad-cn-ui";
@@ -19,11 +22,12 @@ type ToolRecord = {
19
22
  name?: string;
20
23
  iconName?: string | null;
21
24
  description?: string;
22
- tags?: unknown;
25
+ tags?: AgentHubTag[];
23
26
  type?: string;
24
27
  status?: string | null;
25
28
  lastLoadError?: string | null;
26
29
  sourceCode?: string;
30
+ checksum?: string;
27
31
  agentTools?: AgentToolLink[] | AgentToolLink | null;
28
32
  };
29
33
 
@@ -38,17 +42,6 @@ function extractEntityRecord(response: unknown): Record<string, any> | undefined
38
42
  return candidate && typeof candidate === "object" ? candidate as Record<string, any> : undefined;
39
43
  }
40
44
 
41
- function parseTags(value: unknown): string[] {
42
- if (Array.isArray(value)) return value.map(String).map((tag) => tag.trim()).filter(Boolean);
43
- if (typeof value !== "string" || !value.trim()) return [];
44
- try {
45
- const parsed = JSON.parse(value);
46
- return Array.isArray(parsed) ? parsed.map(String).map((tag) => tag.trim()).filter(Boolean) : [];
47
- } catch {
48
- return value === "{}" ? [] : value.split(",").map((tag) => tag.trim()).filter(Boolean);
49
- }
50
- }
51
-
52
45
  async function sha256Hex(value: string): Promise<string> {
53
46
  const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value));
54
47
  return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
@@ -86,7 +79,7 @@ export function AgentToolRegistryEditorPage() {
86
79
  const entityApi = React.useMemo(() => createSolidEntityApi("agentToolRegistry"), []);
87
80
  const { useCreateSolidEntityMutation, useGetSolidEntityByIdQuery, useUpdateSolidEntityMutation } = entityApi;
88
81
  const { data: response, isLoading, isFetching, refetch } = useGetSolidEntityByIdQuery(
89
- { id, qs: "populate[0]=agentTools&populate[1]=agentTools.agentRegistry" },
82
+ { id, qs: "populate[0]=agentTools&populate[1]=agentTools.agentRegistry&populate[2]=tags" },
90
83
  { skip: !id || id === "new" },
91
84
  );
92
85
  const [createTool, { isLoading: isCreating }] = useCreateSolidEntityMutation();
@@ -98,44 +91,38 @@ export function AgentToolRegistryEditorPage() {
98
91
  const [description, setDescription] = React.useState("");
99
92
  const [type, setType] = React.useState("custom");
100
93
  const [sourceCode, setSourceCode] = React.useState("");
101
- const [tags, setTags] = React.useState<string[]>([]);
102
- const [tagDraft, setTagDraft] = React.useState("");
94
+ const [tags, setTags] = React.useState<AgentHubTag[]>([]);
95
+ const [creatingTag, setCreatingTag] = React.useState(false);
103
96
  const [fieldErrors, setFieldErrors] = React.useState<Record<string, string>>({});
104
97
  const [auditRefreshVersion, setAuditRefreshVersion] = React.useState(0);
105
98
  const [confirmRefresh, setConfirmRefresh] = React.useState(false);
99
+ const [activationOpen, setActivationOpen] = React.useState(false);
100
+ const [activationTool, setActivationTool] = React.useState<{ id: number; checksum: string; name: string } | null>(null);
101
+ const preparingActivation = React.useRef(false);
106
102
  const baseline = React.useRef("");
107
103
 
108
- const currentForm = () => JSON.stringify({ name, iconName, description, type, sourceCode, tags, tagDraft });
104
+ const currentForm = () => JSON.stringify({ name, iconName, description, type, sourceCode, tags });
109
105
 
110
106
  React.useEffect(() => {
111
- const nextTags = parseTags(record?.tags);
107
+ const nextTags = agentHubTagsFrom(record?.tags);
112
108
  setName(record?.name ?? "");
113
109
  setIconName(record?.iconName ?? "");
114
110
  setDescription(record?.description ?? "");
115
111
  setType(record?.type ?? "custom");
116
112
  setSourceCode(record?.sourceCode ?? "");
117
113
  setTags(nextTags);
118
- setTagDraft("");
119
- baseline.current = JSON.stringify({ name: record?.name ?? "", iconName: record?.iconName ?? "", description: record?.description ?? "", type: record?.type ?? "custom", sourceCode: record?.sourceCode ?? "", tags: nextTags, tagDraft: "" });
114
+ baseline.current = JSON.stringify({ name: record?.name ?? "", iconName: record?.iconName ?? "", description: record?.description ?? "", type: record?.type ?? "custom", sourceCode: record?.sourceCode ?? "", tags: nextTags });
120
115
  }, [record]);
121
116
 
122
117
  const isReadOnly = record?.type === "solidx";
123
118
  const isDirty = Boolean(record?.id) && currentForm() !== baseline.current;
124
119
  const requestRefresh = () => isDirty ? setConfirmRefresh(true) : void refetch();
125
120
 
126
- const addTag = () => {
127
- const next = tagDraft.trim();
128
- if (!next) return;
129
- if (!tags.some((tag) => tag.toLowerCase() === next.toLowerCase())) setTags((current) => [...current, next]);
130
- setTagDraft("");
131
- setFieldErrors((current) => ({ ...current, tags: "" }));
132
- };
133
-
134
- const save = async (nextStatus?: "active" | "inactive") => {
121
+ const save = async (nextStatus?: "inactive") => {
122
+ if (creatingTag) return;
135
123
  const nextErrors: Record<string, string> = {};
136
124
  if (!name.trim()) nextErrors.name = "Name is required.";
137
125
  if (!description.trim()) nextErrors.description = "Description is required.";
138
- if (tags.length === 0) nextErrors.tags = "At least one tag is required.";
139
126
  if (!type.trim()) nextErrors.type = "Tool type is required.";
140
127
  if (!sourceCode.trim()) nextErrors.sourceCode = "Tool source code is required.";
141
128
 
@@ -147,19 +134,18 @@ export function AgentToolRegistryEditorPage() {
147
134
  }
148
135
  const payload = {
149
136
  name: name.trim(), iconName: iconName || null, description: description.trim(), type,
150
- sourceCode, tags: JSON.stringify(tags),
151
- ...(type === "custom" ? { checksum: await sha256Hex(sourceCode) } : {}),
152
- // Status is required by the agentToolRegistry metadata, including partial
153
- // updates. Preserve the current lifecycle state for ordinary saves.
154
- status: nextStatus ?? (record?.status === "load_failed" ? "active" : record?.status ?? "active"),
155
- ...((nextStatus === "active" || (!nextStatus && record?.status === "load_failed")) ? { lastLoadError: null } : {}),
137
+ sourceCode, ...agentHubTagsPayload(tags),
138
+ ...(["custom", "thirdparty"].includes(type) ? { checksum: await sha256Hex(sourceCode) } : {}),
139
+ status: nextStatus ?? (record && (sourceCode !== record.sourceCode || name.trim() !== record.name || type !== record.type)
140
+ ? "inactive" : record?.status ?? "inactive"),
156
141
  };
157
142
  try {
158
143
  if (record?.id) {
159
- await updateTool({ id: record.id, data: payload }).unwrap();
144
+ const result = await updateTool({ id: record.id, data: payload }).unwrap();
160
145
  dispatch(showToast({ severity: "success", summary: nextStatus ? "Tool status updated" : "Saved", detail: nextStatus ? `Tool moved to ${nextStatus}. Restart linked agent processes to apply the change.` : "Tool updated successfully." }));
161
146
  setAuditRefreshVersion((version) => version + 1);
162
147
  refetch();
148
+ return (extractEntityRecord(result) ?? { ...record, ...payload }) as ToolRecord;
163
149
  } else {
164
150
  const result: any = await createTool(payload).unwrap();
165
151
  const createdId = result?.data?.id ?? result?.id;
@@ -170,7 +156,7 @@ export function AgentToolRegistryEditorPage() {
170
156
  const errorDetail = getSaveErrorMessage(error);
171
157
  const serverFieldErrors: Record<string, string> = {};
172
158
  if (/required|not be empty|cannot be empty|should not be empty/i.test(errorDetail)) {
173
- for (const field of ["name", "description", "tags", "type", "sourceCode"]) {
159
+ for (const field of ["name", "description", "type", "sourceCode"]) {
174
160
  if (!new RegExp(`\\b${field}\\b`, "i").test(errorDetail)) continue;
175
161
  const label = field === "sourceCode" ? "Tool source code" : field[0].toUpperCase() + field.slice(1);
176
162
  serverFieldErrors[field] = `${label} is required.`;
@@ -184,6 +170,23 @@ export function AgentToolRegistryEditorPage() {
184
170
  }
185
171
  };
186
172
 
173
+ const beginActivation = async () => {
174
+ if (isReadOnly) return;
175
+ if (!record || activationOpen || isSaving || preparingActivation.current) return;
176
+ preparingActivation.current = true;
177
+ try {
178
+ const saved = isDirty || record.status === "load_failed" ? await save("inactive") : record;
179
+ if (!saved?.id) return;
180
+ const checksum = await sha256Hex(saved.sourceCode ?? sourceCode);
181
+ setActivationTool({ id: saved.id, checksum, name: saved.name ?? name });
182
+ setActivationOpen(true);
183
+ } catch {
184
+ dispatch(showToast({ severity: "error", summary: "Activation failed", detail: "Could not prepare the saved tool source for checks." }));
185
+ } finally {
186
+ preparingActivation.current = false;
187
+ }
188
+ };
189
+
187
190
  const agents = React.useMemo(() => {
188
191
  const relatedTools = record?.agentTools;
189
192
  const links = Array.isArray(relatedTools) ? relatedTools : relatedTools ? [relatedTools] : [];
@@ -212,36 +215,33 @@ export function AgentToolRegistryEditorPage() {
212
215
  <div className="agent-tool-editor__field"><span>Icon</span><SolidIconPicker value={iconName} onChange={setIconName} /></div>
213
216
  <label className="agent-tool-editor__field"><span>Description <b>*</b></span><SolidInput value={description} aria-invalid={Boolean(fieldErrors.description)} aria-describedby={fieldErrors.description ? "agent-tool-description-error" : undefined} className={fieldErrors.description ? "agent-tool-editor__input--invalid" : undefined} onChange={(e) => { setDescription(e.target.value); setFieldErrors((current) => ({ ...current, description: "" })); }} />{fieldErrors.description && <small id="agent-tool-description-error" className="agent-tool-editor__field-error">{fieldErrors.description}</small>}</label>
214
217
  </div>
218
+ {!record?.id && <label className="agent-tool-editor__field"><span>Tool status</span><select value="inactive" disabled aria-label="Tool status"><option value="inactive">Inactive</option></select><small>New tools start inactive. Run configuration and initialization checks to activate.</small></label>}
215
219
  <label className="agent-tool-editor__field"><span>Tool type <b>*</b></span><select value={type} aria-invalid={Boolean(fieldErrors.type)} aria-describedby={fieldErrors.type ? "agent-tool-type-error" : undefined} className={fieldErrors.type ? "agent-tool-editor__input--invalid" : undefined} onChange={(e) => { setType(e.target.value); setFieldErrors((current) => ({ ...current, type: "" })); }}>
216
220
  {isReadOnly && <option value="solidx">SolidX</option>}<option value="thirdparty">Third Party</option><option value="custom">Custom</option>
217
221
  </select>{fieldErrors.type && <small id="agent-tool-type-error" className="agent-tool-editor__field-error">{fieldErrors.type}</small>}</label>
218
- <div className="agent-tool-editor__field"><span>Tags <b>*</b></span><div className={`agent-tool-editor__tag-input${fieldErrors.tags ? " agent-tool-editor__tag-input--invalid" : ""}`}>
219
- {tags.map((tag, index) => <span className="agent-tool-editor__tag" key={`${tag}-${index}`}>{tag}<button type="button" aria-label={`Remove ${tag}`} onClick={() => setTags((current) => { const next = current.filter((_, i) => i !== index); if (next.length) setFieldErrors((errors) => ({ ...errors, tags: "" })); return next; })}><X size={13} /></button></span>)}
220
- <input value={tagDraft} aria-label="Add a tag" placeholder="Type a tag and press Enter" onChange={(e) => setTagDraft(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addTag(); } }} />
221
- <SolidButton type="button" variant="secondary" size="small" onClick={addTag}><Plus size={14} /> Add</SolidButton>
222
- </div>{fieldErrors.tags && <small className="agent-tool-editor__field-error">{fieldErrors.tags}</small>}<small>Tags are saved as a JSON array.</small></div>
222
+ <AgentHubTagsField value={tags} onChange={setTags} disabled={isReadOnly || isCreating || isSaving} onBusyChange={setCreatingTag} />
223
223
  {record?.id && <section className="agent-tool-editor__workflow" aria-labelledby="agent-tool-lifecycle-title">
224
- <div className="agent-tool-editor__workflow-head"><div><h2 id="agent-tool-lifecycle-title">Tool lifecycle</h2><p>Activate or deactivate this tool for linked agents. Load failures are reported by AgentHub.</p></div></div>
225
- <div className="agent-tool-editor__workflow-stages" aria-label={`Current tool stage: ${(record.status ?? "active").replace(/[_-]+/g, " ")}`}>
224
+ <div className="agent-tool-editor__workflow-head"><div><h2 id="agent-tool-lifecycle-title">Tool lifecycle</h2><p>Configuration and initialization must pass before this tool can be activated.</p></div></div>
225
+ <div className="agent-tool-editor__workflow-stages" aria-label={`Current tool stage: ${(record.status ?? "inactive").replace(/[_-]+/g, " ")}`}>
226
226
  {([ ["active", "Active", "Enabled for loading into linked agents."], ["inactive", "Inactive", "Not loaded for linked agents."], ["load_failed", "Load failed", "AgentHub could not load this tool."] ] as const).map(([value, label, description], index) => {
227
- const currentStatus = record.status ?? "active";
227
+ const currentStatus = record.status ?? "inactive";
228
228
  const isCurrent = currentStatus === value;
229
229
  const canRetry = value === "load_failed" && isCurrent;
230
- const disabled = isCreating || isSaving || (!canRetry && (value === "load_failed" || isCurrent));
230
+ const disabled = isReadOnly || activationOpen || isCreating || isSaving || (!canRetry && (value === "load_failed" || isCurrent));
231
231
  return <React.Fragment key={value}>
232
232
  {index > 0 && <div className="agent-tool-editor__workflow-connector" aria-hidden="true" />}
233
233
  <button type="button" className={`agent-tool-editor__workflow-stage agent-tool-editor__workflow-stage--${value}${isCurrent ? " is-current" : ""}`}
234
234
  aria-current={isCurrent ? "step" : undefined} aria-pressed={isCurrent} disabled={disabled}
235
- onClick={() => void save(value === "load_failed" ? "active" : value)}>
235
+ onClick={() => value === "inactive" ? void save("inactive") : void beginActivation()}>
236
236
  <span className="agent-tool-editor__workflow-mark">{index + 1}</span>
237
- <span className="agent-tool-editor__workflow-copy"><strong>{label}</strong><small>{description}</small><small className="agent-tool-editor__workflow-cta">{canRetry ? "Click to retry loading" : isCurrent ? "Current stage" : value === "load_failed" ? "Set automatically by AgentHub" : "Click to move to this stage"}</small></span>
237
+ <span className="agent-tool-editor__workflow-copy"><strong>{label}</strong><small>{description}</small><small className="agent-tool-editor__workflow-cta">{canRetry ? "Run checks and retry activation" : isCurrent ? "Current stage" : value === "load_failed" ? "Set automatically by AgentHub" : value === "active" ? "Run checks to activate" : "Click to deactivate"}</small></span>
238
238
  {isCurrent && <span className="agent-tool-editor__workflow-current">Current</span>}
239
239
  </button>
240
240
  </React.Fragment>;
241
241
  })}
242
242
  </div>
243
- {record.status === "load_failed" && <small className="agent-tool-editor__workflow-hint">Fix the source or checksum first. Retrying saves the current tool configuration and clears the reported error; restart linked agent processes to load the updated tool.</small>}
244
- <small className="agent-tool-editor__workflow-hint">Changing stage saves the current tool configuration. Restart linked agent processes to apply the change.</small>
243
+ {record.status === "load_failed" && <small className="agent-tool-editor__workflow-hint">Fix the source or checksum, then run configuration and initialization checks before retrying activation.</small>}
244
+ <small className="agent-tool-editor__workflow-hint">Activation checks use the saved tool configuration. Restart linked agent processes to apply status changes.</small>
245
245
  </section>}
246
246
  </fieldset> },
247
247
  { value: "tool", label: "Tool", content: <div className="agent-tool-editor__tool">
@@ -260,12 +260,20 @@ export function AgentToolRegistryEditorPage() {
260
260
  return <main className="agent-tool-editor">
261
261
  <header className="agent-tool-editor__header"><div><div className="agent-tool-editor__heading-with-refresh"><h1>{record ? "Edit Tool" : "Create Tool"}</h1>{record?.id && <button type="button" className={`agent-tool-editor__refresh${isFetching ? " is-loading" : ""}`} aria-label="Refresh tool" title="Refresh tool" disabled={isFetching || isSaving} onClick={requestRefresh}><RefreshCw size={14} /></button>}</div></div><div className="agent-tool-editor__actions">
262
262
  <SolidButton variant="secondary" leftIcon={<ArrowLeft size={16} />} onClick={() => navigate(-1)}>Back</SolidButton>
263
- {!isReadOnly && <SolidButton loading={isCreating || isSaving} onClick={() => void save()}>Save Tool</SolidButton>}
263
+ {!isReadOnly && <SolidButton disabled={activationOpen || creatingTag} loading={isCreating || isSaving} onClick={() => void save()}>Save Tool</SolidButton>}
264
264
  </div></header>
265
265
  <SolidDialog open={confirmRefresh} onOpenChange={setConfirmRefresh} header="Discard unsaved changes?" style={{ width: "min(28rem, 94vw)" }}
266
266
  footer={<><SolidButton type="button" variant="secondary" onClick={() => setConfirmRefresh(false)}>Cancel</SolidButton><SolidButton type="button" disabled={isFetching} onClick={() => { setConfirmRefresh(false); void refetch(); }}>Refresh and discard</SolidButton></>}>
267
267
  <SolidDialogBody><p>You have unsaved changes. Refreshing will discard them and load the latest tool content.</p></SolidDialogBody>
268
268
  </SolidDialog>
269
+ {activationOpen && activationTool && <AgentToolActivationDialog open={activationOpen} onOpenChange={setActivationOpen}
270
+ toolId={activationTool.id} checksum={activationTool.checksum} toolName={activationTool.name}
271
+ onActivated={async () => {
272
+ await solidPatch(`/agent-tool-registry/${activationTool.id}`, { status: "active", checksum: activationTool.checksum });
273
+ setAuditRefreshVersion((version) => version + 1);
274
+ void refetch();
275
+ dispatch(showToast({ severity: "success", summary: "Tool activated", detail: "Configuration and initialization checks passed." }));
276
+ }} />}
269
277
  {isLoading ? <div className="agent-tool-editor__loading">Loading tool…</div> : record?.id ? (
270
278
  <AgentRegistryAuditPanel modelSingularName="agentToolRegistry" recordId={record.id} refreshVersion={auditRefreshVersion} modelUserKey={record.name}>
271
279
  <SolidTabGroup tabs={tabs} value={activeTab} onValueChange={setActiveTab} className="agent-tool-editor__tabs" listClassName="agent-tool-editor__tab-list" panelClassName="agent-tool-editor__tab-panel" />
@@ -0,0 +1,2 @@
1
+ export declare function ArchivedChatterMessagesPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=ArchivedChatterMessagesPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArchivedChatterMessagesPage.d.ts","sourceRoot":"","sources":["../../../../../src/routes/pages/admin/core/ArchivedChatterMessagesPage.tsx"],"names":[],"mappings":"AASA,wBAAgB,2BAA2B,4CAsF1C"}
@@ -0,0 +1,108 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
49
+ import React from 'react';
50
+ import qs from 'qs';
51
+ import { ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';
52
+ import { SolidButton } from '../../../../components/shad-cn-ui';
53
+ import { useGetArchivedChatterMessagesQuery, useLazyGetArchivedChatterMessageQuery } from '../../../../redux/api/solidChatterMessageApi';
54
+ var PAGE_SIZE = 25;
55
+ export function ArchivedChatterMessagesPage() {
56
+ var _this = this;
57
+ var _a, _b, _c, _d, _e;
58
+ var _f = React.useState({ entityName: '', entityId: '', messageType: '', messageSubType: '', user: '', from: '', to: '' }), filters = _f[0], setFilters = _f[1];
59
+ var _g = React.useState(0), offset = _g[0], setOffset = _g[1];
60
+ var _h = React.useState(null), selectedId = _h[0], setSelectedId = _h[1];
61
+ var queryString = React.useMemo(function () {
62
+ var query = { limit: PAGE_SIZE, offset: offset };
63
+ var where = {};
64
+ if (filters.entityName.trim())
65
+ where.coModelName = { $containsi: filters.entityName.trim() };
66
+ if (filters.entityId.trim() && Number.isFinite(Number(filters.entityId)))
67
+ where.coModelEntityId = { $eq: Number(filters.entityId) };
68
+ if (filters.messageType)
69
+ where.messageType = { $eq: filters.messageType };
70
+ if (filters.messageSubType.trim())
71
+ where.messageSubType = { $containsi: filters.messageSubType.trim() };
72
+ if (filters.user.trim())
73
+ where.user = { fullName: { $containsi: filters.user.trim() } };
74
+ if (filters.from || filters.to) {
75
+ where.createdAt = {};
76
+ if (filters.from)
77
+ where.createdAt.$gte = new Date(filters.from).toISOString();
78
+ if (filters.to)
79
+ where.createdAt.$lte = new Date(filters.to).toISOString();
80
+ }
81
+ if (Object.keys(where).length)
82
+ query.filters = where;
83
+ query.sort = ['createdAt:DESC'];
84
+ return qs.stringify(query, { encodeValuesOnly: true });
85
+ }, [filters, offset]);
86
+ var _j = useGetArchivedChatterMessagesQuery(queryString), data = _j.data, isLoading = _j.isLoading, isFetching = _j.isFetching, error = _j.error;
87
+ var _k = useLazyGetArchivedChatterMessageQuery(), fetchOne = _k[0], _l = _k[1], detailData = _l.data, detailLoading = _l.isFetching;
88
+ var records = (_a = data === null || data === void 0 ? void 0 : data.records) !== null && _a !== void 0 ? _a : [];
89
+ var meta = (_b = data === null || data === void 0 ? void 0 : data.meta) !== null && _b !== void 0 ? _b : {};
90
+ var openRecord = function (id) { return __awaiter(_this, void 0, void 0, function () {
91
+ return __generator(this, function (_a) {
92
+ switch (_a.label) {
93
+ case 0:
94
+ setSelectedId(id);
95
+ return [4 /*yield*/, fetchOne(id)];
96
+ case 1:
97
+ _a.sent();
98
+ return [2 /*return*/];
99
+ }
100
+ });
101
+ }); };
102
+ var selected = detailData === null || detailData === void 0 ? void 0 : detailData.record;
103
+ return _jsxs("main", { className: "mx-auto flex w-full max-w-7xl flex-col gap-5 p-6", children: [_jsxs("header", { children: [_jsx("h1", { className: "m-0 text-2xl font-semibold", children: "Archived Messages" }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Search chatter messages moved to the configured archive store." })] }), (data === null || data === void 0 ? void 0 : data.available) === false ? _jsxs("section", { className: "rounded-lg border p-6", role: "status", children: [_jsx("h2", { className: "m-0 text-lg font-semibold", children: "Chatter archival is not enabled" }), _jsx("p", { className: "mb-0 mt-2 text-sm text-muted-foreground", children: "Configure and register an IChatterMessageArchive provider in the consuming project to archive and browse messages." })] }) : _jsxs(_Fragment, { children: [_jsxs("section", { className: "grid grid-cols-1 gap-3 rounded-lg border p-4 sm:grid-cols-2 lg:grid-cols-7", "aria-label": "Archive filters", children: [_jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["Entity name", _jsx("input", { className: "rounded border px-3 py-2", value: filters.entityName, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { entityName: e.target.value })); }, placeholder: "e.g. customer" })] }), _jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["Entity ID", _jsx("input", { className: "rounded border px-3 py-2", inputMode: "numeric", value: filters.entityId, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { entityId: e.target.value })); }, placeholder: "Record ID" })] }), _jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["Message type", _jsxs("select", { className: "rounded border px-3 py-2", value: filters.messageType, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { messageType: e.target.value })); }, children: [_jsx("option", { value: "", children: "All types" }), _jsx("option", { value: "audit", children: "Audit" }), _jsx("option", { value: "custom", children: "Custom" })] })] }), _jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["Message subtype", _jsx("input", { className: "rounded border px-3 py-2", value: filters.messageSubType, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { messageSubType: e.target.value })); }, placeholder: "e.g. audit_update" })] }), _jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["Changed by", _jsx("input", { className: "rounded border px-3 py-2", value: filters.user, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { user: e.target.value })); }, placeholder: "User name" })] }), _jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["From", _jsx("input", { className: "rounded border px-3 py-2", type: "datetime-local", value: filters.from, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { from: e.target.value })); } })] }), _jsxs("label", { className: "flex flex-col gap-1 text-sm", children: ["To", _jsx("input", { className: "rounded border px-3 py-2", type: "datetime-local", value: filters.to, onChange: function (e) { setOffset(0); setFilters(__assign(__assign({}, filters), { to: e.target.value })); } })] })] }), error && _jsx("p", { role: "alert", className: "text-sm text-red-600", children: "Unable to load archived messages. Check provider availability and try again." }), _jsx("section", { className: "overflow-hidden rounded-lg border", children: isLoading ? _jsxs("div", { className: "flex items-center gap-2 p-8", children: [_jsx(Loader2, { className: "animate-spin", size: 18 }), "Loading archived messages\u2026"] }) : records.length === 0 ? _jsx("p", { className: "p-8 text-center text-sm text-muted-foreground", children: "No archived messages match these filters." }) : _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full border-collapse text-left text-sm", children: [_jsx("thead", { className: "bg-muted/50", children: _jsxs("tr", { children: [_jsx("th", { className: "p-3", children: "Date" }), _jsx("th", { className: "p-3", children: "Entity" }), _jsx("th", { className: "p-3", children: "Entity ID" }), _jsx("th", { className: "p-3", children: "Type" }), _jsx("th", { className: "p-3", children: "User" }), _jsx("th", { className: "p-3", children: "Message" })] }) }), _jsx("tbody", { children: records.map(function (message) {
104
+ var _a;
105
+ return _jsxs("tr", { className: "border-t hover:bg-muted/30", children: [_jsx("td", { className: "whitespace-nowrap p-3", children: message.createdAt ? new Date(message.createdAt).toLocaleString() : '—' }), _jsx("td", { className: "p-3", children: message.modelDisplayName || message.coModelName }), _jsx("td", { className: "p-3", children: message.coModelEntityId }), _jsx("td", { className: "p-3", children: message.messageSubType || message.messageType }), _jsx("td", { className: "p-3", children: ((_a = message.user) === null || _a === void 0 ? void 0 : _a.fullName) || 'System' }), _jsx("td", { className: "max-w-md p-3", children: _jsx("button", { type: "button", className: "text-left text-primary underline", onClick: function () { return openRecord(message.id); }, children: message.messageBody || 'View message' }) })] }, message.id);
106
+ }) })] }) }) }), _jsxs("footer", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-sm text-muted-foreground", children: [(_c = meta.totalRecords) !== null && _c !== void 0 ? _c : records.length, " archived messages", isFetching ? ' · Updating…' : ''] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(SolidButton, { variant: "outline", disabled: offset === 0 || isFetching, onClick: function () { return setOffset(Math.max(0, offset - PAGE_SIZE)); }, children: [_jsx(ChevronLeft, { size: 16 }), "Previous"] }), _jsxs(SolidButton, { variant: "outline", disabled: records.length < PAGE_SIZE || isFetching, onClick: function () { return setOffset(offset + PAGE_SIZE); }, children: ["Next", _jsx(ChevronRight, { size: 16 })] })] })] })] }), selectedId !== null && _jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4", role: "presentation", onClick: function () { return setSelectedId(null); }, children: _jsxs("section", { role: "dialog", "aria-modal": "true", "aria-label": "Archived chatter message", className: "max-h-[85vh] w-full max-w-3xl overflow-auto rounded-lg bg-background p-6 shadow-xl", onClick: function (e) { return e.stopPropagation(); }, children: [_jsxs("div", { className: "mb-4 flex items-start justify-between", children: [_jsxs("h2", { className: "m-0 text-xl font-semibold", children: ["Archived message #", selectedId] }), _jsx("button", { type: "button", className: "rounded px-2 py-1 hover:bg-muted", onClick: function () { return setSelectedId(null); }, children: "Close" })] }), detailLoading ? _jsx("p", { children: "Loading message\u2026" }) : selected ? _jsxs(_Fragment, { children: [_jsxs("dl", { className: "grid grid-cols-2 gap-3 text-sm", children: [_jsx("dt", { children: "Entity" }), _jsx("dd", { children: selected.modelDisplayName || selected.coModelName }), _jsx("dt", { children: "Entity ID" }), _jsx("dd", { children: selected.coModelEntityId }), _jsx("dt", { children: "Date" }), _jsx("dd", { children: selected.createdAt ? new Date(selected.createdAt).toLocaleString() : '—' }), _jsx("dt", { children: "User" }), _jsx("dd", { children: ((_d = selected.user) === null || _d === void 0 ? void 0 : _d.fullName) || 'System' }), _jsx("dt", { children: "Subtype" }), _jsx("dd", { children: selected.messageSubType })] }), _jsx("h3", { className: "mt-5 text-base font-semibold", children: "Message" }), _jsx("pre", { className: "whitespace-pre-wrap break-words rounded bg-muted p-3 text-sm", children: selected.messageBody || '' }), !!((_e = selected.chatterMessageDetails) === null || _e === void 0 ? void 0 : _e.length) && _jsxs(_Fragment, { children: [_jsx("h3", { className: "mt-5 text-base font-semibold", children: "Change details" }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-left text-sm", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "p-2", children: "Field" }), _jsx("th", { className: "p-2", children: "Previous" }), _jsx("th", { className: "p-2", children: "Current" })] }) }), _jsx("tbody", { children: selected.chatterMessageDetails.map(function (detail, index) { var _a, _b, _c, _d, _e; return _jsxs("tr", { className: "border-t", children: [_jsx("td", { className: "p-2", children: detail.fieldDisplayName || detail.fieldName }), _jsx("td", { className: "p-2", children: (_b = (_a = detail.oldValueDisplay) !== null && _a !== void 0 ? _a : detail.oldValue) !== null && _b !== void 0 ? _b : '—' }), _jsx("td", { className: "p-2", children: (_d = (_c = detail.newValueDisplay) !== null && _c !== void 0 ? _c : detail.newValue) !== null && _d !== void 0 ? _d : '—' })] }, (_e = detail.id) !== null && _e !== void 0 ? _e : index); }) })] }) })] })] }) : _jsx("p", { role: "alert", children: "Could not load this archived message." })] }) })] });
107
+ }
108
+ //# sourceMappingURL=ArchivedChatterMessagesPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArchivedChatterMessagesPage.js","sourceRoot":"","sources":["../../../../../src/routes/pages/admin/core/ArchivedChatterMessagesPage.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,kCAAkC,EAAE,qCAAqC,EAAE,MAAM,8CAA8C,CAAC;AAEzI,IAAM,SAAS,GAAG,EAAE,CAAC;AAGrB,MAAM,UAAU,2BAA2B;IAA3C,iBAsFC;;IArFO,IAAA,KAAwB,KAAK,CAAC,QAAQ,CAAU,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAjJ,OAAO,QAAA,EAAE,UAAU,QAA8H,CAAC;IACnJ,IAAA,KAAsB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAtC,MAAM,QAAA,EAAE,SAAS,QAAqB,CAAC;IACxC,IAAA,KAA8B,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,EAAhE,UAAU,QAAA,EAAE,aAAa,QAAuC,CAAC;IAExE,IAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;QAChC,IAAM,KAAK,GAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,QAAA,EAAE,CAAC;QAChD,IAAM,KAAK,GAAwB,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,WAAW,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7F,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAAE,KAAK,CAAC,eAAe,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpI,IAAI,OAAO,CAAC,WAAW;YAAE,KAAK,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;QAC1E,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,cAAc,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;QACxG,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,IAAI,GAAG,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;QACxF,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,EAAE;YAC9B,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;YACrB,IAAI,OAAO,CAAC,IAAI;gBAAE,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9E,IAAI,OAAO,CAAC,EAAE;gBAAE,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;SAC3E;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;YAAE,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACrD,KAAK,CAAC,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAChC,OAAO,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAEhB,IAAA,KAAyC,kCAAkC,CAAC,WAAW,CAAC,EAAtF,IAAI,UAAA,EAAE,SAAS,eAAA,EAAE,UAAU,gBAAA,EAAE,KAAK,WAAoD,CAAC;IACzF,IAAA,KAA8D,qCAAqC,EAAE,EAApG,QAAQ,QAAA,EAAE,UAA+C,EAAvC,UAAU,UAAA,EAAc,aAAa,gBAA6C,CAAC;IAC5G,IAAM,OAAO,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,mCAAI,EAAE,CAAC;IACpC,IAAM,IAAI,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,mCAAI,EAAE,CAAC;IAE9B,IAAM,UAAU,GAAG,UAAO,EAAU;;;;oBAClC,aAAa,CAAC,EAAE,CAAC,CAAC;oBAClB,qBAAM,QAAQ,CAAC,EAAE,CAAC,EAAA;;oBAAlB,SAAkB,CAAC;;;;SACpB,CAAC;IACF,IAAM,QAAQ,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,CAAC;IAEpC,OAAO,gBAAM,SAAS,EAAC,kDAAkD,aACvE,6BACE,aAAI,SAAS,EAAC,4BAA4B,kCAAuB,EACjE,YAAG,SAAS,EAAC,oCAAoC,+EAAmE,IAC7G,EAER,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,MAAK,KAAK,CAAC,CAAC,CAAC,mBAAS,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,QAAQ,aACnF,aAAI,SAAS,EAAC,2BAA2B,gDAAqC,EAC9E,YAAG,SAAS,EAAC,yCAAyC,mIAAuH,IACrK,CAAC,CAAC,CAAC,8BACX,mBAAS,SAAS,EAAC,4EAA4E,gBAAY,iBAAiB,aAC1H,iBAAO,SAAS,EAAC,6BAA6B,4BAAY,gBAAO,SAAS,EAAC,0BAA0B,EAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAC,eAAe,GAAG,IAAQ,EACjQ,iBAAO,SAAS,EAAC,6BAA6B,0BAAU,gBAAO,SAAS,EAAC,0BAA0B,EAAC,SAAS,EAAC,SAAS,EAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAC,WAAW,GAAG,IAAQ,EAC3Q,iBAAO,SAAS,EAAC,6BAA6B,6BAAa,kBAAQ,SAAS,EAAC,0BAA0B,EAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,aAAE,iBAAQ,KAAK,EAAC,EAAE,0BAAmB,EAAA,iBAAQ,KAAK,EAAC,OAAO,sBAAe,EAAA,iBAAQ,KAAK,EAAC,QAAQ,uBAAgB,IAAS,IAAQ,EAC7V,iBAAO,SAAS,EAAC,6BAA6B,gCAAgB,gBAAO,SAAS,EAAC,0BAA0B,EAAC,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAC,mBAAmB,GAAG,IAAQ,EACjR,iBAAO,SAAS,EAAC,6BAA6B,2BAAW,gBAAO,SAAS,EAAC,0BAA0B,EAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAC,WAAW,GAAG,IAAQ,EAChP,iBAAO,SAAS,EAAC,6BAA6B,qBAAK,gBAAO,SAAS,EAAC,0BAA0B,EAAC,IAAI,EAAC,gBAAgB,EAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,GAAI,IAAQ,EACxO,iBAAO,SAAS,EAAC,6BAA6B,mBAAG,gBAAO,SAAS,EAAC,0BAA0B,EAAC,IAAI,EAAC,gBAAgB,EAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAA,CAAC,IAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,uBAAM,OAAO,KAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAG,CAAC,CAAC,CAAC,GAAI,IAAQ,IAC1N,EAET,KAAK,IAAI,YAAG,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,sBAAsB,6FAAiF,EAC3I,kBAAS,SAAS,EAAC,mCAAmC,YACnD,SAAS,CAAC,CAAC,CAAC,eAAK,SAAS,EAAC,6BAA6B,aAAC,KAAC,OAAO,IAAC,SAAS,EAAC,cAAc,EAAC,IAAI,EAAE,EAAE,GAAI,uCAAgC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,YAAG,SAAS,EAAC,+CAA+C,0DAA8C,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,iBAAiB,YAC7S,iBAAO,SAAS,EAAC,0CAA0C,aACzD,gBAAO,SAAS,EAAC,aAAa,YAAC,yBAAI,aAAI,SAAS,EAAC,KAAK,qBAAU,EAAA,aAAI,SAAS,EAAC,KAAK,uBAAY,EAAA,aAAI,SAAS,EAAC,KAAK,0BAAe,EAAA,aAAI,SAAS,EAAC,KAAK,qBAAU,EAAA,aAAI,SAAS,EAAC,KAAK,qBAAU,EAAA,aAAI,SAAS,EAAC,KAAK,wBAAa,IAAK,GAAQ,EACxO,0BAAQ,OAAO,CAAC,GAAG,CAAC,UAAC,OAAY;;4CAAK,OAAA,cAAqB,SAAS,EAAC,4BAA4B,aAC/F,aAAI,SAAS,EAAC,uBAAuB,YAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,GAAG,GAAM,EACnH,aAAI,SAAS,EAAC,KAAK,YAAE,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,WAAW,GAAM,EAAA,aAAI,SAAS,EAAC,KAAK,YAAE,OAAO,CAAC,eAAe,GAAM,EAC5H,aAAI,SAAS,EAAC,KAAK,YAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,WAAW,GAAM,EAAA,aAAI,SAAS,EAAC,KAAK,YAAE,CAAA,MAAA,OAAO,CAAC,IAAI,0CAAE,QAAQ,KAAI,QAAQ,GAAM,EACrI,aAAI,SAAS,EAAC,cAAc,YAAC,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,kCAAkC,EAAC,OAAO,EAAE,cAAM,OAAA,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,EAAtB,CAAsB,YAAG,OAAO,CAAC,WAAW,IAAI,cAAc,GAAU,GAAK,KAJ/I,OAAO,CAAC,EAAE,CAKpD,CAAA;yCAAA,CAAC,GAAS,IACT,GACJ,GACE,EAEV,kBAAQ,SAAS,EAAC,mCAAmC,aACnD,gBAAM,SAAS,EAAC,+BAA+B,aAAE,MAAA,IAAI,CAAC,YAAY,mCAAI,OAAO,CAAC,MAAM,wBAAoB,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAQ,EAChJ,eAAK,SAAS,EAAC,YAAY,aAAC,MAAC,WAAW,IAAC,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAE,MAAM,KAAK,CAAC,IAAI,UAAU,EAAE,OAAO,EAAE,cAAM,OAAA,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EAA1C,CAA0C,aAAE,KAAC,WAAW,IAAC,IAAI,EAAE,EAAE,GAAI,gBAAsB,EAAA,MAAC,WAAW,IAAC,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,IAAI,UAAU,EAAE,OAAO,EAAE,cAAM,OAAA,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAA7B,CAA6B,qBAAM,KAAC,YAAY,IAAC,IAAI,EAAE,EAAE,GAAI,IAAc,IAAM,IACvX,IACR,EAEF,UAAU,KAAK,IAAI,IAAI,cAAK,SAAS,EAAC,qEAAqE,EAAC,IAAI,EAAC,cAAc,EAAC,OAAO,EAAE,cAAM,OAAA,aAAa,CAAC,IAAI,CAAC,EAAnB,CAAmB,YACjK,mBAAS,IAAI,EAAC,QAAQ,gBAAY,MAAM,gBAAY,0BAA0B,EAAC,SAAS,EAAC,oFAAoF,EAAC,OAAO,EAAE,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,eAAe,EAAE,EAAnB,CAAmB,aAC7M,eAAK,SAAS,EAAC,uCAAuC,aAAC,cAAI,SAAS,EAAC,2BAA2B,mCAAoB,UAAU,IAAM,EAAA,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,kCAAkC,EAAC,OAAO,EAAE,cAAM,OAAA,aAAa,CAAC,IAAI,CAAC,EAAnB,CAAmB,sBAAgB,IAAM,EAC9P,aAAa,CAAC,CAAC,CAAC,gDAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,8BACpD,cAAI,SAAS,EAAC,gCAAgC,aAAC,kCAAe,EAAA,uBAAK,QAAQ,CAAC,gBAAgB,IAAI,QAAQ,CAAC,WAAW,GAAM,EAAA,qCAAkB,EAAA,uBAAK,QAAQ,CAAC,eAAe,GAAM,EAAA,gCAAa,EAAA,uBAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,GAAG,GAAM,EAAA,gCAAa,EAAA,uBAAK,CAAA,MAAA,QAAQ,CAAC,IAAI,0CAAE,QAAQ,KAAI,QAAQ,GAAM,EAAA,mCAAgB,EAAA,uBAAK,QAAQ,CAAC,cAAc,GAAM,IAAK,EACjY,aAAI,SAAS,EAAC,8BAA8B,wBAAa,EAAA,cAAK,SAAS,EAAC,8DAA8D,YAAE,QAAQ,CAAC,WAAW,IAAI,EAAE,GAAO,EACxK,CAAC,CAAC,CAAA,MAAA,QAAQ,CAAC,qBAAqB,0CAAE,MAAM,CAAA,IAAI,8BAAE,aAAI,SAAS,EAAC,8BAA8B,+BAAoB,EAAA,cAAK,SAAS,EAAC,iBAAiB,YAAC,iBAAO,SAAS,EAAC,0BAA0B,aAAC,0BAAO,yBAAI,aAAI,SAAS,EAAC,KAAK,sBAAW,EAAA,aAAI,SAAS,EAAC,KAAK,yBAAc,EAAA,aAAI,SAAS,EAAC,KAAK,wBAAa,IAAK,GAAQ,EAAA,0BAAQ,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAC,MAAW,EAAE,KAAa,4BAAK,OAAA,cAAI,SAAS,EAAC,UAAU,aAA0B,aAAI,SAAS,EAAC,KAAK,YAAE,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,SAAS,GAAM,EAAA,aAAI,SAAS,EAAC,KAAK,YAAE,MAAA,MAAA,MAAM,CAAC,eAAe,mCAAI,MAAM,CAAC,QAAQ,mCAAI,GAAG,GAAM,EAAA,aAAI,SAAS,EAAC,KAAK,YAAE,MAAA,MAAA,MAAM,CAAC,eAAe,mCAAI,MAAM,CAAC,QAAQ,mCAAI,GAAG,GAAM,KAAhP,MAAA,MAAM,CAAC,EAAE,mCAAI,KAAK,CAAmO,CAAA,EAAA,CAAC,GAAS,IAAQ,GAAM,IAAG,IAC3qB,CAAC,CAAC,CAAC,YAAG,IAAI,EAAC,OAAO,sDAA0C,IACvD,GACN,IACD,CAAC;AACV,CAAC","sourcesContent":["import React from 'react';\nimport qs from 'qs';\nimport { ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';\nimport { SolidButton } from '../../../../components/shad-cn-ui';\nimport { useGetArchivedChatterMessagesQuery, useLazyGetArchivedChatterMessageQuery } from '../../../../redux/api/solidChatterMessageApi';\n\nconst PAGE_SIZE = 25;\ntype Filters = { entityName: string; entityId: string; messageType: string; messageSubType: string; user: string; from: string; to: string };\n\nexport function ArchivedChatterMessagesPage() {\n const [filters, setFilters] = React.useState<Filters>({ entityName: '', entityId: '', messageType: '', messageSubType: '', user: '', from: '', to: '' });\n const [offset, setOffset] = React.useState(0);\n const [selectedId, setSelectedId] = React.useState<number | null>(null);\n\n const queryString = React.useMemo(() => {\n const query: any = { limit: PAGE_SIZE, offset };\n const where: Record<string, any> = {};\n if (filters.entityName.trim()) where.coModelName = { $containsi: filters.entityName.trim() };\n if (filters.entityId.trim() && Number.isFinite(Number(filters.entityId))) where.coModelEntityId = { $eq: Number(filters.entityId) };\n if (filters.messageType) where.messageType = { $eq: filters.messageType };\n if (filters.messageSubType.trim()) where.messageSubType = { $containsi: filters.messageSubType.trim() };\n if (filters.user.trim()) where.user = { fullName: { $containsi: filters.user.trim() } };\n if (filters.from || filters.to) {\n where.createdAt = {};\n if (filters.from) where.createdAt.$gte = new Date(filters.from).toISOString();\n if (filters.to) where.createdAt.$lte = new Date(filters.to).toISOString();\n }\n if (Object.keys(where).length) query.filters = where;\n query.sort = ['createdAt:DESC'];\n return qs.stringify(query, { encodeValuesOnly: true });\n }, [filters, offset]);\n\n const { data, isLoading, isFetching, error } = useGetArchivedChatterMessagesQuery(queryString);\n const [fetchOne, { data: detailData, isFetching: detailLoading }] = useLazyGetArchivedChatterMessageQuery();\n const records = data?.records ?? [];\n const meta = data?.meta ?? {};\n\n const openRecord = async (id: number) => {\n setSelectedId(id);\n await fetchOne(id);\n };\n const selected = detailData?.record;\n\n return <main className=\"mx-auto flex w-full max-w-7xl flex-col gap-5 p-6\">\n <header>\n <h1 className=\"m-0 text-2xl font-semibold\">Archived Messages</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">Search chatter messages moved to the configured archive store.</p>\n </header>\n\n {data?.available === false ? <section className=\"rounded-lg border p-6\" role=\"status\">\n <h2 className=\"m-0 text-lg font-semibold\">Chatter archival is not enabled</h2>\n <p className=\"mb-0 mt-2 text-sm text-muted-foreground\">Configure and register an IChatterMessageArchive provider in the consuming project to archive and browse messages.</p>\n </section> : <>\n <section className=\"grid grid-cols-1 gap-3 rounded-lg border p-4 sm:grid-cols-2 lg:grid-cols-7\" aria-label=\"Archive filters\">\n <label className=\"flex flex-col gap-1 text-sm\">Entity name<input className=\"rounded border px-3 py-2\" value={filters.entityName} onChange={e => { setOffset(0); setFilters({ ...filters, entityName: e.target.value }); }} placeholder=\"e.g. customer\" /></label>\n <label className=\"flex flex-col gap-1 text-sm\">Entity ID<input className=\"rounded border px-3 py-2\" inputMode=\"numeric\" value={filters.entityId} onChange={e => { setOffset(0); setFilters({ ...filters, entityId: e.target.value }); }} placeholder=\"Record ID\" /></label>\n <label className=\"flex flex-col gap-1 text-sm\">Message type<select className=\"rounded border px-3 py-2\" value={filters.messageType} onChange={e => { setOffset(0); setFilters({ ...filters, messageType: e.target.value }); }}><option value=\"\">All types</option><option value=\"audit\">Audit</option><option value=\"custom\">Custom</option></select></label>\n <label className=\"flex flex-col gap-1 text-sm\">Message subtype<input className=\"rounded border px-3 py-2\" value={filters.messageSubType} onChange={e => { setOffset(0); setFilters({ ...filters, messageSubType: e.target.value }); }} placeholder=\"e.g. audit_update\" /></label>\n <label className=\"flex flex-col gap-1 text-sm\">Changed by<input className=\"rounded border px-3 py-2\" value={filters.user} onChange={e => { setOffset(0); setFilters({ ...filters, user: e.target.value }); }} placeholder=\"User name\" /></label>\n <label className=\"flex flex-col gap-1 text-sm\">From<input className=\"rounded border px-3 py-2\" type=\"datetime-local\" value={filters.from} onChange={e => { setOffset(0); setFilters({ ...filters, from: e.target.value }); }} /></label>\n <label className=\"flex flex-col gap-1 text-sm\">To<input className=\"rounded border px-3 py-2\" type=\"datetime-local\" value={filters.to} onChange={e => { setOffset(0); setFilters({ ...filters, to: e.target.value }); }} /></label>\n </section>\n\n {error && <p role=\"alert\" className=\"text-sm text-red-600\">Unable to load archived messages. Check provider availability and try again.</p>}\n <section className=\"overflow-hidden rounded-lg border\">\n {isLoading ? <div className=\"flex items-center gap-2 p-8\"><Loader2 className=\"animate-spin\" size={18} />Loading archived messages…</div> : records.length === 0 ? <p className=\"p-8 text-center text-sm text-muted-foreground\">No archived messages match these filters.</p> : <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse text-left text-sm\">\n <thead className=\"bg-muted/50\"><tr><th className=\"p-3\">Date</th><th className=\"p-3\">Entity</th><th className=\"p-3\">Entity ID</th><th className=\"p-3\">Type</th><th className=\"p-3\">User</th><th className=\"p-3\">Message</th></tr></thead>\n <tbody>{records.map((message: any) => <tr key={message.id} className=\"border-t hover:bg-muted/30\">\n <td className=\"whitespace-nowrap p-3\">{message.createdAt ? new Date(message.createdAt).toLocaleString() : '—'}</td>\n <td className=\"p-3\">{message.modelDisplayName || message.coModelName}</td><td className=\"p-3\">{message.coModelEntityId}</td>\n <td className=\"p-3\">{message.messageSubType || message.messageType}</td><td className=\"p-3\">{message.user?.fullName || 'System'}</td>\n <td className=\"max-w-md p-3\"><button type=\"button\" className=\"text-left text-primary underline\" onClick={() => openRecord(message.id)}>{message.messageBody || 'View message'}</button></td>\n </tr>)}</tbody>\n </table>\n </div>}\n </section>\n\n <footer className=\"flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">{meta.totalRecords ?? records.length} archived messages{isFetching ? ' · Updating…' : ''}</span>\n <div className=\"flex gap-2\"><SolidButton variant=\"outline\" disabled={offset === 0 || isFetching} onClick={() => setOffset(Math.max(0, offset - PAGE_SIZE))}><ChevronLeft size={16} />Previous</SolidButton><SolidButton variant=\"outline\" disabled={records.length < PAGE_SIZE || isFetching} onClick={() => setOffset(offset + PAGE_SIZE)}>Next<ChevronRight size={16} /></SolidButton></div>\n </footer>\n </>}\n\n {selectedId !== null && <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\" role=\"presentation\" onClick={() => setSelectedId(null)}>\n <section role=\"dialog\" aria-modal=\"true\" aria-label=\"Archived chatter message\" className=\"max-h-[85vh] w-full max-w-3xl overflow-auto rounded-lg bg-background p-6 shadow-xl\" onClick={e => e.stopPropagation()}>\n <div className=\"mb-4 flex items-start justify-between\"><h2 className=\"m-0 text-xl font-semibold\">Archived message #{selectedId}</h2><button type=\"button\" className=\"rounded px-2 py-1 hover:bg-muted\" onClick={() => setSelectedId(null)}>Close</button></div>\n {detailLoading ? <p>Loading message…</p> : selected ? <>\n <dl className=\"grid grid-cols-2 gap-3 text-sm\"><dt>Entity</dt><dd>{selected.modelDisplayName || selected.coModelName}</dd><dt>Entity ID</dt><dd>{selected.coModelEntityId}</dd><dt>Date</dt><dd>{selected.createdAt ? new Date(selected.createdAt).toLocaleString() : '—'}</dd><dt>User</dt><dd>{selected.user?.fullName || 'System'}</dd><dt>Subtype</dt><dd>{selected.messageSubType}</dd></dl>\n <h3 className=\"mt-5 text-base font-semibold\">Message</h3><pre className=\"whitespace-pre-wrap break-words rounded bg-muted p-3 text-sm\">{selected.messageBody || ''}</pre>\n {!!selected.chatterMessageDetails?.length && <><h3 className=\"mt-5 text-base font-semibold\">Change details</h3><div className=\"overflow-x-auto\"><table className=\"w-full text-left text-sm\"><thead><tr><th className=\"p-2\">Field</th><th className=\"p-2\">Previous</th><th className=\"p-2\">Current</th></tr></thead><tbody>{selected.chatterMessageDetails.map((detail: any, index: number) => <tr className=\"border-t\" key={detail.id ?? index}><td className=\"p-2\">{detail.fieldDisplayName || detail.fieldName}</td><td className=\"p-2\">{detail.oldValueDisplay ?? detail.oldValue ?? '—'}</td><td className=\"p-2\">{detail.newValueDisplay ?? detail.newValue ?? '—'}</td></tr>)}</tbody></table></div></>}\n </> : <p role=\"alert\">Could not load this archived message.</p>}\n </section>\n </div>}\n </main>;\n}\n"]}
@@ -0,0 +1,96 @@
1
+ import React from 'react';
2
+ import qs from 'qs';
3
+ import { ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';
4
+ import { SolidButton } from '../../../../components/shad-cn-ui';
5
+ import { useGetArchivedChatterMessagesQuery, useLazyGetArchivedChatterMessageQuery } from '../../../../redux/api/solidChatterMessageApi';
6
+
7
+ const PAGE_SIZE = 25;
8
+ type Filters = { entityName: string; entityId: string; messageType: string; messageSubType: string; user: string; from: string; to: string };
9
+
10
+ export function ArchivedChatterMessagesPage() {
11
+ const [filters, setFilters] = React.useState<Filters>({ entityName: '', entityId: '', messageType: '', messageSubType: '', user: '', from: '', to: '' });
12
+ const [offset, setOffset] = React.useState(0);
13
+ const [selectedId, setSelectedId] = React.useState<number | null>(null);
14
+
15
+ const queryString = React.useMemo(() => {
16
+ const query: any = { limit: PAGE_SIZE, offset };
17
+ const where: Record<string, any> = {};
18
+ if (filters.entityName.trim()) where.coModelName = { $containsi: filters.entityName.trim() };
19
+ if (filters.entityId.trim() && Number.isFinite(Number(filters.entityId))) where.coModelEntityId = { $eq: Number(filters.entityId) };
20
+ if (filters.messageType) where.messageType = { $eq: filters.messageType };
21
+ if (filters.messageSubType.trim()) where.messageSubType = { $containsi: filters.messageSubType.trim() };
22
+ if (filters.user.trim()) where.user = { fullName: { $containsi: filters.user.trim() } };
23
+ if (filters.from || filters.to) {
24
+ where.createdAt = {};
25
+ if (filters.from) where.createdAt.$gte = new Date(filters.from).toISOString();
26
+ if (filters.to) where.createdAt.$lte = new Date(filters.to).toISOString();
27
+ }
28
+ if (Object.keys(where).length) query.filters = where;
29
+ query.sort = ['createdAt:DESC'];
30
+ return qs.stringify(query, { encodeValuesOnly: true });
31
+ }, [filters, offset]);
32
+
33
+ const { data, isLoading, isFetching, error } = useGetArchivedChatterMessagesQuery(queryString);
34
+ const [fetchOne, { data: detailData, isFetching: detailLoading }] = useLazyGetArchivedChatterMessageQuery();
35
+ const records = data?.records ?? [];
36
+ const meta = data?.meta ?? {};
37
+
38
+ const openRecord = async (id: number) => {
39
+ setSelectedId(id);
40
+ await fetchOne(id);
41
+ };
42
+ const selected = detailData?.record;
43
+
44
+ return <main className="mx-auto flex w-full max-w-7xl flex-col gap-5 p-6">
45
+ <header>
46
+ <h1 className="m-0 text-2xl font-semibold">Archived Messages</h1>
47
+ <p className="mt-1 text-sm text-muted-foreground">Search chatter messages moved to the configured archive store.</p>
48
+ </header>
49
+
50
+ {data?.available === false ? <section className="rounded-lg border p-6" role="status">
51
+ <h2 className="m-0 text-lg font-semibold">Chatter archival is not enabled</h2>
52
+ <p className="mb-0 mt-2 text-sm text-muted-foreground">Configure and register an IChatterMessageArchive provider in the consuming project to archive and browse messages.</p>
53
+ </section> : <>
54
+ <section className="grid grid-cols-1 gap-3 rounded-lg border p-4 sm:grid-cols-2 lg:grid-cols-7" aria-label="Archive filters">
55
+ <label className="flex flex-col gap-1 text-sm">Entity name<input className="rounded border px-3 py-2" value={filters.entityName} onChange={e => { setOffset(0); setFilters({ ...filters, entityName: e.target.value }); }} placeholder="e.g. customer" /></label>
56
+ <label className="flex flex-col gap-1 text-sm">Entity ID<input className="rounded border px-3 py-2" inputMode="numeric" value={filters.entityId} onChange={e => { setOffset(0); setFilters({ ...filters, entityId: e.target.value }); }} placeholder="Record ID" /></label>
57
+ <label className="flex flex-col gap-1 text-sm">Message type<select className="rounded border px-3 py-2" value={filters.messageType} onChange={e => { setOffset(0); setFilters({ ...filters, messageType: e.target.value }); }}><option value="">All types</option><option value="audit">Audit</option><option value="custom">Custom</option></select></label>
58
+ <label className="flex flex-col gap-1 text-sm">Message subtype<input className="rounded border px-3 py-2" value={filters.messageSubType} onChange={e => { setOffset(0); setFilters({ ...filters, messageSubType: e.target.value }); }} placeholder="e.g. audit_update" /></label>
59
+ <label className="flex flex-col gap-1 text-sm">Changed by<input className="rounded border px-3 py-2" value={filters.user} onChange={e => { setOffset(0); setFilters({ ...filters, user: e.target.value }); }} placeholder="User name" /></label>
60
+ <label className="flex flex-col gap-1 text-sm">From<input className="rounded border px-3 py-2" type="datetime-local" value={filters.from} onChange={e => { setOffset(0); setFilters({ ...filters, from: e.target.value }); }} /></label>
61
+ <label className="flex flex-col gap-1 text-sm">To<input className="rounded border px-3 py-2" type="datetime-local" value={filters.to} onChange={e => { setOffset(0); setFilters({ ...filters, to: e.target.value }); }} /></label>
62
+ </section>
63
+
64
+ {error && <p role="alert" className="text-sm text-red-600">Unable to load archived messages. Check provider availability and try again.</p>}
65
+ <section className="overflow-hidden rounded-lg border">
66
+ {isLoading ? <div className="flex items-center gap-2 p-8"><Loader2 className="animate-spin" size={18} />Loading archived messages…</div> : records.length === 0 ? <p className="p-8 text-center text-sm text-muted-foreground">No archived messages match these filters.</p> : <div className="overflow-x-auto">
67
+ <table className="w-full border-collapse text-left text-sm">
68
+ <thead className="bg-muted/50"><tr><th className="p-3">Date</th><th className="p-3">Entity</th><th className="p-3">Entity ID</th><th className="p-3">Type</th><th className="p-3">User</th><th className="p-3">Message</th></tr></thead>
69
+ <tbody>{records.map((message: any) => <tr key={message.id} className="border-t hover:bg-muted/30">
70
+ <td className="whitespace-nowrap p-3">{message.createdAt ? new Date(message.createdAt).toLocaleString() : '—'}</td>
71
+ <td className="p-3">{message.modelDisplayName || message.coModelName}</td><td className="p-3">{message.coModelEntityId}</td>
72
+ <td className="p-3">{message.messageSubType || message.messageType}</td><td className="p-3">{message.user?.fullName || 'System'}</td>
73
+ <td className="max-w-md p-3"><button type="button" className="text-left text-primary underline" onClick={() => openRecord(message.id)}>{message.messageBody || 'View message'}</button></td>
74
+ </tr>)}</tbody>
75
+ </table>
76
+ </div>}
77
+ </section>
78
+
79
+ <footer className="flex items-center justify-between">
80
+ <span className="text-sm text-muted-foreground">{meta.totalRecords ?? records.length} archived messages{isFetching ? ' · Updating…' : ''}</span>
81
+ <div className="flex gap-2"><SolidButton variant="outline" disabled={offset === 0 || isFetching} onClick={() => setOffset(Math.max(0, offset - PAGE_SIZE))}><ChevronLeft size={16} />Previous</SolidButton><SolidButton variant="outline" disabled={records.length < PAGE_SIZE || isFetching} onClick={() => setOffset(offset + PAGE_SIZE)}>Next<ChevronRight size={16} /></SolidButton></div>
82
+ </footer>
83
+ </>}
84
+
85
+ {selectedId !== null && <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4" role="presentation" onClick={() => setSelectedId(null)}>
86
+ <section role="dialog" aria-modal="true" aria-label="Archived chatter message" className="max-h-[85vh] w-full max-w-3xl overflow-auto rounded-lg bg-background p-6 shadow-xl" onClick={e => e.stopPropagation()}>
87
+ <div className="mb-4 flex items-start justify-between"><h2 className="m-0 text-xl font-semibold">Archived message #{selectedId}</h2><button type="button" className="rounded px-2 py-1 hover:bg-muted" onClick={() => setSelectedId(null)}>Close</button></div>
88
+ {detailLoading ? <p>Loading message…</p> : selected ? <>
89
+ <dl className="grid grid-cols-2 gap-3 text-sm"><dt>Entity</dt><dd>{selected.modelDisplayName || selected.coModelName}</dd><dt>Entity ID</dt><dd>{selected.coModelEntityId}</dd><dt>Date</dt><dd>{selected.createdAt ? new Date(selected.createdAt).toLocaleString() : '—'}</dd><dt>User</dt><dd>{selected.user?.fullName || 'System'}</dd><dt>Subtype</dt><dd>{selected.messageSubType}</dd></dl>
90
+ <h3 className="mt-5 text-base font-semibold">Message</h3><pre className="whitespace-pre-wrap break-words rounded bg-muted p-3 text-sm">{selected.messageBody || ''}</pre>
91
+ {!!selected.chatterMessageDetails?.length && <><h3 className="mt-5 text-base font-semibold">Change details</h3><div className="overflow-x-auto"><table className="w-full text-left text-sm"><thead><tr><th className="p-2">Field</th><th className="p-2">Previous</th><th className="p-2">Current</th></tr></thead><tbody>{selected.chatterMessageDetails.map((detail: any, index: number) => <tr className="border-t" key={detail.id ?? index}><td className="p-2">{detail.fieldDisplayName || detail.fieldName}</td><td className="p-2">{detail.oldValueDisplay ?? detail.oldValue ?? '—'}</td><td className="p-2">{detail.newValueDisplay ?? detail.newValue ?? '—'}</td></tr>)}</tbody></table></div></>}
92
+ </> : <p role="alert">Could not load this archived message.</p>}
93
+ </section>
94
+ </div>}
95
+ </main>;
96
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"solidRoutes.d.ts","sourceRoot":"","sources":["../../src/routes/solidRoutes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAuCpD,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,SAAS,CAAC;AAQjE,wBAAgB,cAAc,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,EAAE,CA4G9E"}
1
+ {"version":3,"file":"solidRoutes.d.ts","sourceRoot":"","sources":["../../src/routes/solidRoutes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAwCpD,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,SAAS,CAAC;AAQjE,wBAAgB,cAAc,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,EAAE,CA6G9E"}
@@ -32,6 +32,7 @@ import { AgentToolRegistryEditorPage } from "./pages/admin/core/AgentToolRegistr
32
32
  import { AgentRegistryEditorPage } from "./pages/admin/core/AgentRegistryEditorPage";
33
33
  import { WorkflowExecutionDetailPage } from "./pages/admin/core/WorkflowExecutionDetailPage";
34
34
  import { MediaUploadPage } from "./pages/admin/core/MediaUploadPage";
35
+ import { ArchivedChatterMessagesPage } from "./pages/admin/core/ArchivedChatterMessagesPage";
35
36
  import { LoginPage } from "./pages/auth/LoginPage";
36
37
  import { RegisterPage } from "./pages/auth/RegisterPage";
37
38
  import { ForgotPasswordPage } from "./pages/auth/ForgotPasswordPage";
@@ -94,6 +95,7 @@ export function getSolidRoutes(options) {
94
95
  { path: "/admin/core/:moduleName/dashboard/:dashboardName", element: pick("dashboard", _jsx(DashboardPage, {})), handle: { title: "Dashboard", manageDocumentMeta: true } },
95
96
  { path: "/admin/core/:moduleName/:modelName/form/:id", element: pick("form", _jsx(FormPage, {})), handle: { title: "Form", manageDocumentMeta: true } },
96
97
  { path: "/admin/core/solid-core/media/upload", element: _jsx(MediaUploadPage, {}), handle: { title: "Upload Media", manageDocumentMeta: true } },
98
+ { path: "/admin/core/solid-core/chatter/archived", element: _jsx(ArchivedChatterMessagesPage, {}), handle: { title: "Archived Messages", manageDocumentMeta: true } },
97
99
  { path: "/admin/core/solid-core/workflow-definition/editor/:id", element: _jsx(WorkflowDefinitionEditorPage, {}), handle: { title: "Workflow Definition Editor", manageDocumentMeta: true } },
98
100
  { path: "/admin/core/solid-core/agent-skill-registry/editor/:id", element: _jsx(AgentSkillRegistryEditorPage, {}), handle: { title: "Agent Skill Registry Editor", manageDocumentMeta: true } },
99
101
  { path: "/admin/core/solid-core/agent-tool-registry/editor/:id", element: _jsx(AgentToolRegistryEditorPage, {}), handle: { title: "Agent Tool Registry Editor", manageDocumentMeta: true } },