@solidxai/core-ui 0.1.20-beta.0 → 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.
- package/dist/components/common/Link.d.ts.map +1 -1
- package/dist/components/common/Link.js +2 -1
- package/dist/components/common/Link.js.map +1 -1
- package/dist/components/common/Link.tsx +2 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts +1 -0
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts.map +1 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js +109 -23
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js.map +1 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.tsx +155 -34
- package/dist/components/core/chatter/SolidChatter.js +2 -2
- package/dist/components/core/chatter/SolidChatter.js.map +1 -1
- package/dist/components/core/chatter/SolidChatter.tsx +2 -2
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.js +20 -19
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.js.map +1 -1
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.tsx +16 -16
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.js +36 -9
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.js.map +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ExportModulePackageRowAction.tsx +78 -7
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.d.ts +1 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.js +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.js.map +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/ModuleImportListHeaderAction.tsx +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.d.ts +4 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.js +131 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.js.map +1 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/RestoreModulePackageRowAction.tsx +151 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.d.ts +4 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.js +13 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.js.map +1 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/UpdateModulePackageRowAction.tsx +20 -0
- package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormView.js +4 -0
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/SolidFormView.tsx +4 -0
- package/dist/components/core/kanban/SolidKanbanView.d.ts.map +1 -1
- package/dist/components/core/kanban/SolidKanbanView.js +50 -15
- package/dist/components/core/kanban/SolidKanbanView.js.map +1 -1
- package/dist/components/core/kanban/SolidKanbanView.tsx +22 -3
- package/dist/components/core/list/SolidListView.d.ts.map +1 -1
- package/dist/components/core/list/SolidListView.js +16 -3
- package/dist/components/core/list/SolidListView.js.map +1 -1
- package/dist/components/core/list/SolidListView.tsx +16 -2
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.d.ts.map +1 -1
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.js +4 -1
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.js.map +1 -1
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.tsx +4 -1
- package/dist/components/core/module/ModulePackageDialog.css +102 -0
- package/dist/components/core/module/ModulePackageDialog.d.ts +2 -1
- package/dist/components/core/module/ModulePackageDialog.d.ts.map +1 -1
- package/dist/components/core/module/ModulePackageDialog.js +216 -68
- package/dist/components/core/module/ModulePackageDialog.js.map +1 -1
- package/dist/components/core/module/ModulePackageDialog.tsx +356 -76
- package/dist/components/core/solid-agent/SolidAgentChat.d.ts.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentChat.js +9 -3
- package/dist/components/core/solid-agent/SolidAgentChat.js.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentChat.tsx +9 -4
- package/dist/components/core/solid-agent/SolidAgentMarkdown.d.ts.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentMarkdown.js +25 -6
- package/dist/components/core/solid-agent/SolidAgentMarkdown.js.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentMarkdown.tsx +15 -1
- package/dist/components/core/solid-agent/client/agentRuntime.d.ts +5 -0
- package/dist/components/core/solid-agent/client/agentRuntime.d.ts.map +1 -1
- package/dist/components/core/solid-agent/client/agentRuntime.js +77 -20
- package/dist/components/core/solid-agent/client/agentRuntime.js.map +1 -1
- package/dist/components/core/solid-agent/client/agentRuntime.ts +29 -1
- package/dist/components/core/solid-agent/client/agentSocket.d.ts +5 -1
- package/dist/components/core/solid-agent/client/agentSocket.d.ts.map +1 -1
- package/dist/components/core/solid-agent/client/agentSocket.js +27 -4
- package/dist/components/core/solid-agent/client/agentSocket.js.map +1 -1
- package/dist/components/core/solid-agent/client/agentSocket.ts +14 -3
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.js +2 -2
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.js.map +1 -1
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx +5 -5
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.d.ts +2 -0
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.d.ts.map +1 -1
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.js +2 -2
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.js.map +1 -1
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.ts +4 -4
- package/dist/components/core/solid-agent/thread/AgentThread.d.ts.map +1 -1
- package/dist/components/core/solid-agent/thread/AgentThread.js +61 -26
- package/dist/components/core/solid-agent/thread/AgentThread.js.map +1 -1
- package/dist/components/core/solid-agent/thread/AgentThread.tsx +74 -40
- package/dist/components/core/solid-agent/thread/SolidAgentChatItem.d.ts +2 -1
- package/dist/components/core/solid-agent/thread/SolidAgentChatItem.d.ts.map +1 -1
- package/dist/components/core/solid-agent/thread/SolidAgentChatItem.js +2 -1
- package/dist/components/core/solid-agent/thread/SolidAgentChatItem.js.map +1 -1
- package/dist/components/core/solid-agent/thread/SolidAgentChatItem.tsx +3 -1
- package/dist/components/core/solid-agent/types.d.ts +3 -0
- package/dist/components/core/solid-agent/types.d.ts.map +1 -1
- package/dist/components/core/solid-agent/types.js +0 -9
- package/dist/components/core/solid-agent/types.js.map +1 -1
- package/dist/components/core/solid-agent/types.ts +4 -2
- package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.d.ts +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.d.ts.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.js +5 -2
- package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultAssistantMessageChatWidget.tsx +11 -5
- package/dist/components/core/solid-agent/widgets/DefaultErrorChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/DefaultErrorChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultErrorChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/DefaultNoticeChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/DefaultNoticeChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultNoticeChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/DefaultThinkingChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/DefaultThinkingChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultThinkingChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/DefaultToolCallChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/DefaultToolCallChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultToolCallChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/DefaultUnknownChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/DefaultUnknownChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultUnknownChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidChecklistChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidChecklistChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidChecklistChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidCodeChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidCodeChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidCodeChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidDiffListChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidDiffListChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidDiffListChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidGalleryChatWidget.js +19 -0
- package/dist/components/core/solid-agent/widgets/SolidGalleryChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidGalleryChatWidget.tsx +20 -0
- package/dist/components/core/solid-agent/widgets/SolidJsonChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidJsonChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidJsonChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidLinkCardChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidLinkCardChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidLinkCardChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidMarkdownChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidMarkdownChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidMarkdownChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidProgressChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidProgressChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidProgressChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidQuestionChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidQuestionChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidQuestionChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidStatusChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidStatusChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidStatusChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidTableChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidTableChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidTableChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/SolidToolActivityChatWidget.js +3 -0
- package/dist/components/core/solid-agent/widgets/SolidToolActivityChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/SolidToolActivityChatWidget.tsx +4 -0
- package/dist/components/core/solid-agent/widgets/solidChatWidgets.module.css +9 -1
- package/dist/components/core/users/CreateUser.d.ts.map +1 -1
- package/dist/components/core/users/CreateUser.js +23 -8
- package/dist/components/core/users/CreateUser.js.map +1 -1
- package/dist/components/core/users/CreateUser.tsx +10 -6
- package/dist/components/layout/AdminTopHeader.js +2 -2
- package/dist/components/layout/AdminTopHeader.js.map +1 -1
- package/dist/components/layout/AdminTopHeader.tsx +2 -2
- package/dist/components/layout/AppSidebar.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.js +21 -5
- package/dist/components/layout/AppSidebar.js.map +1 -1
- package/dist/components/layout/AppSidebar.tsx +24 -6
- package/dist/components/layout/SolidAiStudioLayout.d.ts.map +1 -1
- package/dist/components/layout/SolidAiStudioLayout.js +3 -4
- package/dist/components/layout/SolidAiStudioLayout.js.map +1 -1
- package/dist/components/layout/SolidAiStudioLayout.tsx +3 -4
- package/dist/components/layout/user-profile-menu.js +10 -10
- package/dist/components/layout/user-profile-menu.js.map +1 -1
- package/dist/components/layout/user-profile-menu.tsx +3 -3
- package/dist/components/shad-cn-ui/SolidLightbox.d.ts +2 -1
- package/dist/components/shad-cn-ui/SolidLightbox.d.ts.map +1 -1
- package/dist/components/shad-cn-ui/SolidLightbox.js +11 -4
- package/dist/components/shad-cn-ui/SolidLightbox.js.map +1 -1
- package/dist/components/shad-cn-ui/SolidLightbox.tsx +14 -1
- package/dist/helpers/modelViewPersistence.d.ts +2 -0
- package/dist/helpers/modelViewPersistence.d.ts.map +1 -1
- package/dist/helpers/modelViewPersistence.js +72 -0
- package/dist/helpers/modelViewPersistence.js.map +1 -1
- package/dist/helpers/modelViewPersistence.ts +79 -0
- package/dist/helpers/registry.d.ts +6 -2
- package/dist/helpers/registry.d.ts.map +1 -1
- package/dist/helpers/registry.js +68 -3
- package/dist/helpers/registry.js.map +1 -1
- package/dist/helpers/registry.ts +62 -4
- package/dist/hooks/useModelsDevModels.d.ts +43 -0
- package/dist/hooks/useModelsDevModels.d.ts.map +1 -0
- package/dist/hooks/useModelsDevModels.js +81 -0
- package/dist/hooks/useModelsDevModels.js.map +1 -0
- package/dist/hooks/useModelsDevModels.ts +106 -0
- package/dist/hooks/useRouter.d.ts.map +1 -1
- package/dist/hooks/useRouter.js +3 -2
- package/dist/hooks/useRouter.js.map +1 -1
- package/dist/hooks/useRouter.ts +3 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.ts +4 -1
- package/dist/modules/solidUiModule.d.ts +3 -2
- package/dist/modules/solidUiModule.d.ts.map +1 -1
- package/dist/modules/solidUiModule.js +1 -1
- package/dist/modules/solidUiModule.js.map +1 -1
- package/dist/modules/solidUiModule.ts +5 -1
- package/dist/redux/api/moduleApi.d.ts +12 -2
- package/dist/redux/api/moduleApi.d.ts.map +1 -1
- package/dist/redux/api/moduleApi.js +33 -3
- package/dist/redux/api/moduleApi.js.map +1 -1
- package/dist/redux/api/moduleApi.ts +17 -2
- package/dist/redux/api/solidChatterMessageApi.d.ts +3 -1
- package/dist/redux/api/solidChatterMessageApi.d.ts.map +1 -1
- package/dist/redux/api/solidChatterMessageApi.js +9 -1
- package/dist/redux/api/solidChatterMessageApi.js.map +1 -1
- package/dist/redux/api/solidChatterMessageApi.ts +9 -1
- package/dist/redux/store/defaultStoreConfig.d.ts +9 -1
- package/dist/redux/store/defaultStoreConfig.d.ts.map +1 -1
- package/dist/resources/globals.css +30 -0
- package/dist/resources/solid-custom.css +10 -6
- package/dist/resources/solid-tailwind-generated.css +1 -1
- package/dist/routes/AppEventListener.js +1 -1
- package/dist/routes/AppEventListener.js.map +1 -1
- package/dist/routes/AppEventListener.tsx +1 -1
- package/dist/routes/pages/admin/core/AgentPersonaHistory.css +130 -0
- package/dist/routes/pages/admin/core/AgentPersonaHistory.d.ts +7 -0
- package/dist/routes/pages/admin/core/AgentPersonaHistory.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/AgentPersonaHistory.js +228 -0
- package/dist/routes/pages/admin/core/AgentPersonaHistory.js.map +1 -0
- package/dist/routes/pages/admin/core/AgentPersonaHistory.tsx +234 -0
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.css +6 -14
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js +186 -146
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.tsx +170 -118
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.d.ts +2 -0
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.js +108 -0
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.js.map +1 -0
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.tsx +96 -0
- package/dist/routes/solidRoutes.d.ts.map +1 -1
- package/dist/routes/solidRoutes.js +2 -0
- package/dist/routes/solidRoutes.js.map +1 -1
- package/dist/routes/solidRoutes.tsx +2 -0
- package/dist/types/extension-registry.d.ts +12 -0
- package/dist/types/extension-registry.d.ts.map +1 -1
- package/dist/types/extension-registry.js.map +1 -1
- package/dist/types/extension-registry.ts +15 -0
- package/dist/types/solid-core.d.ts +2 -0
- package/package.json +2 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { ArrowLeft, ChevronDown, Ellipsis, ExternalLink, Eye, FlaskConical, Pencil, Plus, RefreshCw, Trash2 } from "lucide-react";
|
|
2
|
+
import { ArrowLeft, Ellipsis, ExternalLink, Eye, FlaskConical, Pencil, Plus, RefreshCw, Trash2 } from "lucide-react";
|
|
4
3
|
import { useDispatch } from "react-redux";
|
|
5
4
|
import { useNavigate, useParams } from "react-router-dom";
|
|
6
5
|
import { createSolidEntityApi } from "../../../../redux/api/solidEntityApi";
|
|
@@ -8,14 +7,15 @@ import { useGetSolidSettingsQuery } from "../../../../redux/api/solidSettingsApi
|
|
|
8
7
|
import { getSettingsMap } from "../../../../helpers/settingsPayload";
|
|
9
8
|
import { showToast } from "../../../../redux/features/toastSlice";
|
|
10
9
|
import { AgentRegistryAuditPanel } from "./AgentRegistryAuditPanel";
|
|
10
|
+
import { AgentPersonaHistory } from "./AgentPersonaHistory";
|
|
11
11
|
import { AgentHubTagsField, agentHubTagsFrom, agentHubTagsPayload, type AgentHubTag } from "./AgentHubTagsField";
|
|
12
12
|
import { AgentResourceCardWidget } from "../../../../components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget";
|
|
13
13
|
import { AgentSessionsPanel } from "../../../../components/core/extension/solid-core/agentToolRegistry/AgentToolSessionsPanel";
|
|
14
14
|
import { AgentProcessesPanel } from "../../../../components/core/extension/solid-core/agentToolRegistry/AgentProcessesPanel";
|
|
15
15
|
import type { SolidKanbanCardWidgetProps } from "../../../../types/solid-core";
|
|
16
16
|
import { SolidWorkflowStatusPill } from "../../../../components/core/form/SolidDraftPublishWorkflow";
|
|
17
|
-
import {
|
|
18
|
-
import { SolidButton, SolidCodeEditor, SolidDialog, SolidDialogBody, SolidDropdownMenu, SolidDropdownMenuContent, SolidDropdownMenuItem, SolidDropdownMenuTrigger, SolidIconPicker, SolidInput, SolidTabGroup } from "../../../../components/shad-cn-ui";
|
|
17
|
+
import { getModelsDevModels, useModelsDevCatalog } from "../../../../hooks/useModelsDevModels";
|
|
18
|
+
import { SolidAutocomplete, SolidButton, SolidCodeEditor, SolidDialog, SolidDialogBody, SolidDropdownMenu, SolidDropdownMenuContent, SolidDropdownMenuItem, SolidDropdownMenuTrigger, SolidIconPicker, SolidInput, SolidTabGroup } from "../../../../components/shad-cn-ui";
|
|
19
19
|
import { SolidAgentEmbedded } from "../../../../components/core/solid-agent/SolidAgentEmbedded";
|
|
20
20
|
import { SolidAgentMarkdown } from "../../../../components/core/solid-agent/SolidAgentMarkdown";
|
|
21
21
|
import { AgentEmbeddingPanel } from "../../../../components/core/solid-agent/embed/AgentEmbeddingPanel";
|
|
@@ -23,7 +23,7 @@ import "./AgentRegistryEditorPage.css";
|
|
|
23
23
|
|
|
24
24
|
type Item = { id: number; name?: string; title?: string; displayName?: string; description?: string; iconName?: string; key?: string; module?: { id?: number; displayName?: string }; [key: string]: any };
|
|
25
25
|
type Link = { id: number; agentSkillRegistry?: Item; agentToolRegistry?: Item; roleMetadata?: Item; secret?: Item; envVarName?: string; alwaysInclude?: boolean; requiresApproval?: boolean };
|
|
26
|
-
type Input = { name: string; description: string; dataType: string };
|
|
26
|
+
type Input = { name: string; description: string; dataType: string; defaultValue?: unknown; optional: boolean };
|
|
27
27
|
type Agent = Item & {
|
|
28
28
|
configVersion?: number;
|
|
29
29
|
systemPrompt?: string; requiredInputs?: string; reasoningModelKey?: string; fastModelKey?: string; status?: string;
|
|
@@ -31,110 +31,113 @@ type Agent = Item & {
|
|
|
31
31
|
agentSkills?: Link[]; agentTools?: Link[]; agentRoles?: Link[]; agentSecrets?: Link[];
|
|
32
32
|
tags?: AgentHubTag[];
|
|
33
33
|
};
|
|
34
|
-
type ProviderModelOption = { provider:
|
|
34
|
+
type ProviderModelOption = { provider: string; providerLabel: string; model: string; value: string; note?: string };
|
|
35
35
|
|
|
36
|
-
const PROVIDER_LABELS: Record<
|
|
36
|
+
const PROVIDER_LABELS: Record<string, string> = {
|
|
37
37
|
anthropic: "Anthropic",
|
|
38
38
|
openai: "OpenAI",
|
|
39
39
|
openrouter: "OpenRouter",
|
|
40
40
|
};
|
|
41
|
+
const BUILT_IN_PROVIDER_TYPES = ["openai", "anthropic"];
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
type AiProviderConfig = { type?: string; apiKey?: unknown; region?: string };
|
|
44
|
+
type AiModelConfig = { providerId?: string; model?: string };
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Build picker options from the AI settings: every provider with an API key, its models from
|
|
48
|
+
* models.dev, plus the models chosen in settings and any already-saved values for this agent.
|
|
49
|
+
*/
|
|
50
|
+
function buildModelOptions(
|
|
51
|
+
providers: Record<string, AiProviderConfig>,
|
|
52
|
+
settingsModels: Record<string, AiModelConfig | undefined>,
|
|
53
|
+
catalog: Parameters<typeof getModelsDevModels>[0],
|
|
54
|
+
savedValues: string[],
|
|
55
|
+
): ProviderModelOption[] {
|
|
56
|
+
const enabled = Object.entries(providers)
|
|
57
|
+
.filter(([, entry]) => typeof entry?.apiKey === "string" && entry.apiKey.trim().length > 0);
|
|
58
|
+
const options: ProviderModelOption[] = [];
|
|
59
|
+
const seen = new Set<string>();
|
|
60
|
+
const add = (provider: string, model: string, note?: string) => {
|
|
61
|
+
const value = `${provider}:${model}`;
|
|
62
|
+
if (!model || seen.has(value)) return;
|
|
63
|
+
seen.add(value);
|
|
64
|
+
options.push({ provider, providerLabel: PROVIDER_LABELS[provider] ?? provider, model, value, note });
|
|
65
|
+
};
|
|
66
|
+
for (const [provider, entry] of enabled) {
|
|
67
|
+
for (const [role, config] of Object.entries(settingsModels)) {
|
|
68
|
+
if (config?.providerId === provider && config.model) add(provider, config.model, `${role} model in AI settings`);
|
|
69
|
+
}
|
|
70
|
+
for (const value of savedValues) {
|
|
71
|
+
if (value.startsWith(`${provider}:`)) add(provider, value.slice(provider.length + 1), "currently saved");
|
|
72
|
+
}
|
|
73
|
+
const type = entry.type && BUILT_IN_PROVIDER_TYPES.includes(entry.type) ? entry.type : undefined;
|
|
74
|
+
for (const model of getModelsDevModels(catalog, [provider, type])) add(provider, model.id);
|
|
75
|
+
}
|
|
76
|
+
return options;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const OTHER_MODEL = "__other_model__";
|
|
80
|
+
|
|
81
|
+
function SearchableSelect({ value, options, placeholder, disabled, onChange }: {
|
|
43
82
|
value: string;
|
|
44
|
-
options:
|
|
83
|
+
options: { label: string; value: string }[];
|
|
45
84
|
placeholder: string;
|
|
85
|
+
disabled?: boolean;
|
|
46
86
|
onChange: (value: string) => void;
|
|
47
87
|
}) {
|
|
48
|
-
const rootRef = React.useRef<HTMLDivElement>(null);
|
|
49
|
-
const menuRef = React.useRef<HTMLDivElement>(null);
|
|
50
|
-
const [open, setOpen] = React.useState(false);
|
|
51
88
|
const [query, setQuery] = React.useState("");
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
`${PROVIDER_LABELS[option.provider]} ${option.model}`.toLowerCase().includes(query.trim().toLowerCase()));
|
|
57
|
-
const groups = (Object.keys(ALLOWED_MODELS_BY_PROVIDER) as AllowedModelProvider[])
|
|
58
|
-
.map((provider) => ({ provider, options: filtered.filter((option) => option.provider === provider) }))
|
|
59
|
-
.filter((group) => group.options.length > 0);
|
|
89
|
+
const selectedLabel = options.find((option) => option.value === value)?.label;
|
|
90
|
+
const selected = React.useMemo(() => selectedLabel ? { label: selectedLabel, value } : null, [selectedLabel, value]);
|
|
91
|
+
const suggestions = options.filter((option) =>
|
|
92
|
+
`${option.label} ${option.value}`.toLowerCase().includes(query.trim().toLowerCase()));
|
|
60
93
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
width: bounds.width,
|
|
76
|
-
maxHeight: availableHeight,
|
|
77
|
-
...(openAbove
|
|
78
|
-
? { bottom: window.innerHeight - bounds.top + gap }
|
|
79
|
-
: { top: bounds.bottom + gap }),
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
positionMenu();
|
|
83
|
-
window.addEventListener("resize", positionMenu);
|
|
84
|
-
window.addEventListener("scroll", positionMenu, true);
|
|
85
|
-
const handleOutsideClick = (event: MouseEvent) => {
|
|
86
|
-
const target = event.target as Node;
|
|
87
|
-
if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target)) setOpen(false);
|
|
88
|
-
};
|
|
89
|
-
document.addEventListener("mousedown", handleOutsideClick);
|
|
90
|
-
return () => {
|
|
91
|
-
window.removeEventListener("resize", positionMenu);
|
|
92
|
-
window.removeEventListener("scroll", positionMenu, true);
|
|
93
|
-
document.removeEventListener("mousedown", handleOutsideClick);
|
|
94
|
-
};
|
|
95
|
-
}, [open]);
|
|
94
|
+
return <SolidAutocomplete
|
|
95
|
+
className="solid-standard-autocomplete w-full"
|
|
96
|
+
value={selected}
|
|
97
|
+
suggestions={suggestions}
|
|
98
|
+
completeMethod={({ query: next }) => setQuery(next)}
|
|
99
|
+
onChange={(event) => onChange(event.value?.value ?? "")}
|
|
100
|
+
field="label"
|
|
101
|
+
placeholder={placeholder}
|
|
102
|
+
disabled={disabled}
|
|
103
|
+
dropdown
|
|
104
|
+
forceSelection
|
|
105
|
+
portal
|
|
106
|
+
/>;
|
|
107
|
+
}
|
|
96
108
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
onChange={(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}}
|
|
121
|
-
|
|
122
|
-
|
|
109
|
+
function ModelPicker({ value, options, providers, providerConfig, onChange }: {
|
|
110
|
+
value: string;
|
|
111
|
+
options: ProviderModelOption[];
|
|
112
|
+
providers: { label: string; value: string }[];
|
|
113
|
+
providerConfig: Record<string, AiProviderConfig>;
|
|
114
|
+
onChange: (value: string) => void;
|
|
115
|
+
}) {
|
|
116
|
+
const separator = value.indexOf(":");
|
|
117
|
+
const provider = separator < 0 ? "" : value.slice(0, separator);
|
|
118
|
+
const model = separator < 0 ? "" : value.slice(separator + 1);
|
|
119
|
+
const availableModels = options.filter((option) => option.provider === provider);
|
|
120
|
+
const [otherSelected, setOtherSelected] = React.useState(false);
|
|
121
|
+
const showOther = !!provider && (otherSelected || (!!model && !availableModels.some((option) => option.model === model)));
|
|
122
|
+
|
|
123
|
+
return <div className="agent-editor__stack">
|
|
124
|
+
<div className="agent-editor__field"><span>Provider *</span>
|
|
125
|
+
<SearchableSelect value={provider} options={providers} placeholder="Select provider"
|
|
126
|
+
onChange={(next) => { setOtherSelected(false); onChange(`${next}:`); }} />
|
|
127
|
+
{providerConfig[provider]?.type === "bedrock" && providerConfig[provider]?.region &&
|
|
128
|
+
<small><em>Region: {providerConfig[provider].region}</em></small>}
|
|
129
|
+
</div>
|
|
130
|
+
<div className="agent-editor__field"><span>Model *</span>
|
|
131
|
+
<SearchableSelect value={showOther ? OTHER_MODEL : model}
|
|
132
|
+
options={[...availableModels.map((option) => ({ label: option.model, value: option.model })), { label: "Other", value: OTHER_MODEL }]}
|
|
133
|
+
placeholder="Select model" disabled={!provider}
|
|
134
|
+
onChange={(next) => {
|
|
135
|
+
setOtherSelected(next === OTHER_MODEL);
|
|
136
|
+
onChange(`${provider}:${next === OTHER_MODEL ? "" : next}`);
|
|
137
|
+
}} />
|
|
138
|
+
{showOther && <SolidInput className="w-full" aria-label="Custom model ID" placeholder="Enter model ID" value={model}
|
|
139
|
+
onChange={(event) => onChange(`${provider}:${event.target.value}`)} />}
|
|
123
140
|
</div>
|
|
124
|
-
{open && createPortal(<div ref={menuRef} className="agent-editor__model-menu" style={menuStyle} role="listbox">
|
|
125
|
-
{!groups.length ? <div className="agent-editor__model-empty">{options.length ? "No matching models." : "No enabled providers. Add an API key in AI Settings."}</div>
|
|
126
|
-
: groups.map((group) => <section className="agent-editor__model-group" key={group.provider}>
|
|
127
|
-
<h3>{PROVIDER_LABELS[group.provider]}</h3>
|
|
128
|
-
{group.options.map((option) => {
|
|
129
|
-
flatIndex += 1;
|
|
130
|
-
const index = flatIndex;
|
|
131
|
-
return <button type="button" role="option" aria-selected={option.value === value} className={`agent-editor__model-option${index === activeIndex ? " is-active" : ""}`}
|
|
132
|
-
key={option.value} onMouseDown={(event) => event.preventDefault()} onMouseEnter={() => setActiveIndex(index)} onClick={() => choose(option)}>
|
|
133
|
-
<span>{option.model}</span><small>{option.provider}:{option.model}</small>
|
|
134
|
-
</button>;
|
|
135
|
-
})}
|
|
136
|
-
</section>)}
|
|
137
|
-
</div>, document.body)}
|
|
138
141
|
</div>;
|
|
139
142
|
}
|
|
140
143
|
|
|
@@ -217,17 +220,41 @@ function parseInputs(value: unknown): Input[] {
|
|
|
217
220
|
const parsed = typeof value === "string" ? JSON.parse(value) : value;
|
|
218
221
|
if (Array.isArray(parsed)) return parsed.map((input) => ({
|
|
219
222
|
name: String(input.name ?? input.variableName ?? ""), description: String(input.description ?? ""),
|
|
220
|
-
dataType: String(input.dataType ?? input.type ?? "string"),
|
|
223
|
+
dataType: String(input.dataType ?? input.type ?? "string"), defaultValue: input.defaultValue ?? null,
|
|
224
|
+
optional: input.optional === true,
|
|
221
225
|
}));
|
|
222
226
|
// Existing agent definitions may use a name-keyed object.
|
|
223
227
|
if (parsed && typeof parsed === "object") return Object.entries(parsed).map(([name, definition]: [string, any]) => ({
|
|
224
228
|
name, description: String(definition?.description ?? ""),
|
|
225
|
-
dataType: String(definition?.dataType ?? definition?.type ?? "string"),
|
|
229
|
+
dataType: String(definition?.dataType ?? definition?.type ?? "string"), defaultValue: definition?.defaultValue ?? null,
|
|
230
|
+
optional: definition?.optional === true,
|
|
226
231
|
}));
|
|
227
232
|
} catch { /* Keep malformed historical values from crashing the editor. */ }
|
|
228
233
|
return [];
|
|
229
234
|
}
|
|
230
235
|
|
|
236
|
+
function parseDefaultValue(raw: string, dataType: string): unknown {
|
|
237
|
+
if (dataType === "string" || dataType === "date" || dataType === "datetime") return raw;
|
|
238
|
+
if (dataType === "boolean") {
|
|
239
|
+
if (raw !== "true" && raw !== "false") throw new Error(`Default value must be true or false for ${dataType}.`);
|
|
240
|
+
return raw === "true";
|
|
241
|
+
}
|
|
242
|
+
if (dataType === "number" || dataType === "integer") {
|
|
243
|
+
const value = Number(raw);
|
|
244
|
+
if (!Number.isFinite(value) || (dataType === "integer" && !Number.isSafeInteger(value))) throw new Error(`Default value must be a valid ${dataType}.`);
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
const value = JSON.parse(raw);
|
|
248
|
+
if (dataType === "array" && !Array.isArray(value)) throw new Error("Default value must be a JSON array.");
|
|
249
|
+
if (dataType === "object" && (!value || typeof value !== "object" || Array.isArray(value))) throw new Error("Default value must be a JSON object.");
|
|
250
|
+
return value;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function formatDefaultValue(value: unknown): string {
|
|
254
|
+
if (value == null) return "";
|
|
255
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
256
|
+
}
|
|
257
|
+
|
|
231
258
|
function apiError(error: any): string {
|
|
232
259
|
const value = error?.data?.data?.message ?? error?.data?.message ?? error?.message;
|
|
233
260
|
return Array.isArray(value) ? value.join("; ") : typeof value === "string" ? value : "The save failed.";
|
|
@@ -269,12 +296,16 @@ function LinkPicker({ label, description, options, selected, onAdd, onRemove, cr
|
|
|
269
296
|
}) {
|
|
270
297
|
const [search, setSearch] = React.useState("");
|
|
271
298
|
const [open, setOpen] = React.useState(false);
|
|
299
|
+
const showAssociatedCount = label === "Skills" || label === "Tools";
|
|
272
300
|
const available = options.filter((item) => !selected.some((selectedItem) => selectedItem.id === item.id)
|
|
273
301
|
&& `${item.name ?? item.displayName ?? item.key ?? ""} ${item.description ?? ""}`.toLowerCase().includes(search.toLowerCase())).slice(0, 20);
|
|
274
302
|
return <section className="agent-editor__section">
|
|
275
303
|
<div className="agent-editor__section-head"><div><h2>{label}</h2><p>{description}</p></div>
|
|
276
304
|
{createUrl && <a href={createUrl} target="_blank" rel="noopener noreferrer" className="agent-editor__new-link">Create {label === "Skills" ? "skill" : "tool"} <ExternalLink size={14} /></a>}
|
|
277
305
|
</div>
|
|
306
|
+
{showAssociatedCount && <div className="agent-editor__linked-count" role="status">
|
|
307
|
+
{selected.length} {label.toLowerCase()} associated
|
|
308
|
+
</div>}
|
|
278
309
|
<div className="agent-editor__picker">
|
|
279
310
|
<SolidInput value={search} placeholder={`Search and add ${label.toLowerCase()}…`} aria-label={`Search ${label.toLowerCase()}`}
|
|
280
311
|
onFocus={() => setOpen(true)} onChange={(event) => { setSearch(event.target.value); setOpen(true); }} />
|
|
@@ -413,18 +444,26 @@ export function AgentRegistryEditorPage() {
|
|
|
413
444
|
}, [skills.refetch, tools.refetch]);
|
|
414
445
|
|
|
415
446
|
const configValue = getSettingsMap(settings).solidXGenAiCodeBuilderConfig;
|
|
416
|
-
let
|
|
447
|
+
let aiConfig: { providers?: Record<string, AiProviderConfig>; models?: { default?: AiModelConfig; main?: AiModelConfig; fast?: AiModelConfig } } = {};
|
|
417
448
|
try {
|
|
418
|
-
|
|
419
|
-
enabledProviders = config?.providers ?? {};
|
|
449
|
+
aiConfig = (typeof configValue === "string" ? JSON.parse(configValue) : configValue) ?? {};
|
|
420
450
|
} catch { /* Invalid configuration has no enabled providers. */ }
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
451
|
+
const { catalog: modelsCatalog } = useModelsDevCatalog();
|
|
452
|
+
const savedModelKeys = [record?.reasoningModelKey, record?.fastModelKey].filter((key): key is string => !!key);
|
|
453
|
+
const modelOptions = buildModelOptions(
|
|
454
|
+
aiConfig.providers ?? {},
|
|
455
|
+
{ Reasoning: aiConfig.models?.default ?? aiConfig.models?.main, Fast: aiConfig.models?.fast },
|
|
456
|
+
modelsCatalog,
|
|
457
|
+
savedModelKeys,
|
|
458
|
+
);
|
|
459
|
+
const providerOptions = Object.entries(aiConfig.providers ?? {})
|
|
460
|
+
.filter(([, entry]) => typeof entry?.apiKey === "string" && entry.apiKey.trim().length > 0)
|
|
461
|
+
.map(([provider]) => ({ label: modelsCatalog?.[provider]?.name ?? PROVIDER_LABELS[provider] ?? provider, value: provider }));
|
|
462
|
+
const isValidModelKey = (value: string) => {
|
|
463
|
+
const separator = value.indexOf(":");
|
|
464
|
+
return separator > 0 && providerOptions.some((provider) => provider.value === value.slice(0, separator)) &&
|
|
465
|
+
!!value.slice(separator + 1).trim();
|
|
466
|
+
};
|
|
428
467
|
const toggle = (setter: React.Dispatch<React.SetStateAction<number[]>>, value: number) =>
|
|
429
468
|
setter((current) => current.includes(value) ? current.filter((id) => id !== value) : [...current, value]);
|
|
430
469
|
|
|
@@ -454,8 +493,8 @@ export function AgentRegistryEditorPage() {
|
|
|
454
493
|
if (!name.trim()) next.name = "Name is required.";
|
|
455
494
|
if (!title.trim()) next.title = "Title is required.";
|
|
456
495
|
if (!systemPrompt.trim()) next.systemPrompt = "Persona instructions are required.";
|
|
457
|
-
if (!
|
|
458
|
-
if (!
|
|
496
|
+
if (!isValidModelKey(reasoningModelKey)) next.reasoningModelKey = "Choose an enabled reasoning provider and model.";
|
|
497
|
+
if (!isValidModelKey(fastModelKey)) next.fastModelKey = "Choose an enabled fast provider and model.";
|
|
459
498
|
if (inputs.some((input) => !input.name.trim() || !input.dataType)) next.inputs = "Each input needs a name and data type.";
|
|
460
499
|
if (new Set(inputs.map((input) => input.name.trim().toLowerCase())).size !== inputs.length) next.inputs = "Input names must be unique.";
|
|
461
500
|
if (stepLimit < 1 || turnStepLimit < 1 || costLimit < 0) next.limits = "Step limits must be positive and cost limit cannot be negative.";
|
|
@@ -465,9 +504,19 @@ export function AgentRegistryEditorPage() {
|
|
|
465
504
|
dispatch(showToast({ severity: "error", summary: "Missing information", detail: Object.values(next).join(" ") }));
|
|
466
505
|
return;
|
|
467
506
|
}
|
|
507
|
+
let normalizedInputs: Input[];
|
|
508
|
+
try {
|
|
509
|
+
normalizedInputs = inputs.map((input) => ({ ...input, name: input.name.trim(), description: input.description.trim(),
|
|
510
|
+
defaultValue: input.defaultValue === "" || input.defaultValue == null ? null : parseDefaultValue(String(input.defaultValue), input.dataType) }));
|
|
511
|
+
} catch (error) {
|
|
512
|
+
next.inputs = error instanceof Error ? error.message : "Check the default input values.";
|
|
513
|
+
setErrors(next);
|
|
514
|
+
setTab("basics");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
468
517
|
const payload = {
|
|
469
518
|
name: name.trim(), title: title.trim(), description: description.trim(), iconName,
|
|
470
|
-
requiredInputs: JSON.stringify(
|
|
519
|
+
requiredInputs: JSON.stringify(normalizedInputs),
|
|
471
520
|
reasoningModelKey, fastModelKey, systemPrompt, stepLimit: Number(stepLimit),
|
|
472
521
|
turnStepLimit: Number(turnStepLimit), costLimit: Number(costLimit),
|
|
473
522
|
...agentHubTagsPayload(tags),
|
|
@@ -546,25 +595,27 @@ export function AgentRegistryEditorPage() {
|
|
|
546
595
|
{field("Description", description, setDescription, "description")}<div className="agent-editor__field"><span>Icon</span><SolidIconPicker value={iconName} onChange={setIconName} /></div>
|
|
547
596
|
</div>
|
|
548
597
|
<AgentHubTagsField value={tags} onChange={setTags} disabled={creating || updating || isLoading || isFetching || isError} onBusyChange={setCreatingTag} />
|
|
549
|
-
<section className="agent-editor__section"><div className="agent-editor__section-head"><div><h2>
|
|
550
|
-
{inputs.length > 0 && <SolidButton type="button" variant="secondary" size="small" onClick={() => setInputs((current) => [...current, { name: "", description: "", dataType: "string" }])}><Plus size={15} /> Add input</SolidButton>}
|
|
598
|
+
<section className="agent-editor__section"><div className="agent-editor__section-head"><div><h2>Inputs</h2><p>Define the variables this agent can use. Mark inputs optional or provide a default value when people do not need to enter them.</p></div>
|
|
599
|
+
{inputs.length > 0 && <SolidButton type="button" variant="secondary" size="small" onClick={() => setInputs((current) => [...current, { name: "", description: "", dataType: "string", defaultValue: null, optional: false }])}><Plus size={15} /> Add input</SolidButton>}
|
|
551
600
|
</div>
|
|
552
|
-
{!inputs.length ? <div className="agent-editor__empty">This agent has no
|
|
601
|
+
{!inputs.length ? <div className="agent-editor__empty">This agent has no inputs. <button type="button" onClick={() => setInputs([{ name: "", description: "", dataType: "string", defaultValue: null, optional: false }])}><Plus size={15} /> Add an input variable</button></div>
|
|
553
602
|
: <div className="agent-editor__inputs">{inputs.map((input, index) => <div className="agent-editor__input-row" key={index}>
|
|
554
603
|
<SolidInput aria-label={`Input ${index + 1} name`} placeholder="Variable name" value={input.name} onChange={(event) => setInputs((current) => current.map((item, i) => i === index ? { ...item, name: event.target.value } : item))} />
|
|
555
604
|
<SolidInput aria-label={`Input ${index + 1} description`} placeholder="Description" value={input.description} onChange={(event) => setInputs((current) => current.map((item, i) => i === index ? { ...item, description: event.target.value } : item))} />
|
|
605
|
+
<SolidInput aria-label={`Input ${index + 1} default value`} placeholder="Default value" value={formatDefaultValue(input.defaultValue)} onChange={(event) => setInputs((current) => current.map((item, i) => i === index ? { ...item, defaultValue: event.target.value } : item))} />
|
|
556
606
|
<select aria-label={`Input ${index + 1} data type`} value={input.dataType} onChange={(event) => setInputs((current) => current.map((item, i) => i === index ? { ...item, dataType: event.target.value } : item))}>
|
|
557
607
|
{["string", "number", "integer", "boolean", "date", "datetime", "object", "array"].map((type) => <option key={type} value={type}>{type}</option>)}
|
|
558
608
|
</select>
|
|
609
|
+
<label className="agent-editor__input-optional"><input type="checkbox" checked={input.optional} onChange={(event) => setInputs((current) => current.map((item, i) => i === index ? { ...item, optional: event.target.checked } : item))} /> Optional</label>
|
|
559
610
|
<button type="button" aria-label={`Remove input ${index + 1}`} onClick={() => setInputs((current) => current.filter((_, i) => i !== index))}><Trash2 size={17} /></button>
|
|
560
611
|
</div>)}</div>}
|
|
561
612
|
{errors.inputs && <small className="agent-editor__error">{errors.inputs}</small>}</section>
|
|
562
|
-
<section className="agent-editor__section"><h2>Models</h2><p>Choose
|
|
613
|
+
<section className="agent-editor__section agent-editor__models"><h2>Models</h2><p>Choose a configured provider and model for each role. Select Other to enter a model ID manually.</p><div className="agent-editor__grid">
|
|
563
614
|
{([["Reasoning model", reasoningModelKey, setReasoningModelKey, "reasoningModelKey"], ["Fast model", fastModelKey, setFastModelKey, "fastModelKey"]] as const).map(([label, value, setter, key]) =>
|
|
564
|
-
<
|
|
565
|
-
{errors[key] && <small className="agent-editor__error">{errors[key]}</small>}</
|
|
615
|
+
<div className="agent-editor__field" key={key}><span>{label}</span><ModelPicker value={value} options={modelOptions} providers={providerOptions} providerConfig={aiConfig.providers ?? {}} onChange={setter} />
|
|
616
|
+
{errors[key] && <small className="agent-editor__error">{errors[key]}</small>}</div>)}
|
|
566
617
|
</div>{settingsError ? <p className="agent-editor__hint">Settings could not be loaded. Try refreshing this page.</p>
|
|
567
|
-
: !
|
|
618
|
+
: !providerOptions.length && <p className="agent-editor__hint">No enabled providers are available. Check the AI settings and your permission to view encrypted settings.</p>}</section>
|
|
568
619
|
<section className="agent-editor__section agent-editor__workflow" aria-labelledby="agent-lifecycle-title">
|
|
569
620
|
<div className="agent-editor__section-head"><div><h2 id="agent-lifecycle-title">Agent lifecycle</h2><p>Track this agent through its available stages. Select a stage to update its status.</p></div><div className="agent-editor__workflow-meta">{record?.configVersion != null && <span className="agent-editor__config-version" aria-label={`Configuration version ${record.configVersion}`}>Config v{record.configVersion}</span>}<SolidWorkflowStatusPill label={agentStatus} /></div></div>
|
|
570
621
|
<div className="agent-editor__workflow-stages" aria-label={`Current agent stage: ${agentStatus}`}>
|
|
@@ -585,7 +636,8 @@ export function AgentRegistryEditorPage() {
|
|
|
585
636
|
<small className="agent-editor__workflow-save-hint">Changing stage saves the current form and its linked skills, tools, roles, and secrets.</small>
|
|
586
637
|
</section>
|
|
587
638
|
</div> },
|
|
588
|
-
{ value: "persona", label: "Persona", content: <section className="agent-editor__section agent-editor__persona"><div className="agent-editor__section-head"><div><h2>System prompt *</h2><p>Describe the agent's role, behavior, and instructions in Markdown.</p></div
|
|
639
|
+
{ value: "persona", label: "Persona", content: <section className="agent-editor__section agent-editor__persona"><div className="agent-editor__section-head"><div><h2>System prompt *</h2><p>Describe the agent's role, behavior, and instructions in Markdown.</p></div>
|
|
640
|
+
{record?.id && <AgentPersonaHistory agentId={record.id} savedPrompt={record.systemPrompt ?? ""} refreshVersion={auditVersion} />}</div>
|
|
589
641
|
<SolidCodeEditor value={systemPrompt} onChange={(value) => { setSystemPrompt(value ?? ""); setErrors((current) => ({ ...current, systemPrompt: "" })); }} language="markdown" fontSize={11} height="max(34rem, calc(100dvh - 18rem))" />
|
|
590
642
|
{errors.systemPrompt && <small className="agent-editor__error">{errors.systemPrompt}</small>}</section> },
|
|
591
643
|
{ value: "skills", label: "Skills", content: <LinkPicker label="Skills" description="Skills available to this agent." options={skills.records} selected={linked(skillIds, skills.records, items(record?.agentSkills).map((link) => link.agentSkillRegistry).filter(Boolean))}
|
|
@@ -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"]}
|