From bc8b0a8d5322e94aad50d23e12fe59253f14c117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=A2=E5=A5=8B=E7=8C=AB?= Date: Mon, 10 Nov 2025 11:26:36 +0800 Subject: [PATCH] feat(agent): add permission mode display component for empty session state (#11204) Replace empty state text with a visual permission mode display card that shows: - Permission mode icon with unique colors for each mode (default, plan, acceptEdits, bypassPermissions) - Permission mode title and description - Clickable to navigate directly to tooling settings tab Replace loading text with Ant Design Spin component for better UX. --- .../home/Messages/AgentSessionMessages.tsx | 16 ++-- .../home/Messages/PermissionModeDisplay.tsx | 82 +++++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 src/renderer/src/pages/home/Messages/PermissionModeDisplay.tsx diff --git a/src/renderer/src/pages/home/Messages/AgentSessionMessages.tsx b/src/renderer/src/pages/home/Messages/AgentSessionMessages.tsx index 90b284d6c4..611216919a 100644 --- a/src/renderer/src/pages/home/Messages/AgentSessionMessages.tsx +++ b/src/renderer/src/pages/home/Messages/AgentSessionMessages.tsx @@ -5,11 +5,13 @@ import { useTopicMessages } from '@renderer/hooks/useMessageOperations' import { getGroupedMessages } from '@renderer/services/MessagesService' import { type Topic, TopicType } from '@renderer/types' import { buildAgentSessionTopicId } from '@renderer/utils/agentSession' +import { Spin } from 'antd' import { memo, useMemo } from 'react' import styled from 'styled-components' import MessageGroup from './MessageGroup' import NarrowLayout from './NarrowLayout' +import PermissionModeDisplay from './PermissionModeDisplay' import { MessagesContainer, ScrollContainer } from './shared' const logger = loggerService.withContext('AgentSessionMessages') @@ -67,8 +69,12 @@ const AgentSessionMessages: React.FC = ({ agentId, sessionId }) => { groupedMessages.map(([key, groupMessages]) => ( )) + ) : session ? ( + ) : ( - {session ? 'No messages yet.' : 'Loading session...'} + + + )} @@ -77,10 +83,10 @@ const AgentSessionMessages: React.FC = ({ agentId, sessionId }) => { ) } -const EmptyState = styled.div` - color: var(--color-text-3); - font-size: 12px; - text-align: center; +const LoadingState = styled.div` + display: flex; + justify-content: center; + align-items: center; padding: 20px 0; ` diff --git a/src/renderer/src/pages/home/Messages/PermissionModeDisplay.tsx b/src/renderer/src/pages/home/Messages/PermissionModeDisplay.tsx new file mode 100644 index 0000000000..c8ad773484 --- /dev/null +++ b/src/renderer/src/pages/home/Messages/PermissionModeDisplay.tsx @@ -0,0 +1,82 @@ +import { permissionModeCards } from '@renderer/config/agent' +import SessionSettingsPopup from '@renderer/pages/settings/AgentSettings/SessionSettingsPopup' +import type { GetAgentSessionResponse, PermissionMode } from '@renderer/types' +import { FileEdit, Lightbulb, Shield, ShieldOff } from 'lucide-react' +import type { FC } from 'react' +import { useMemo } from 'react' +import { useTranslation } from 'react-i18next' + +interface Props { + session: GetAgentSessionResponse + agentId: string +} + +const getPermissionModeConfig = (mode: PermissionMode) => { + switch (mode) { + case 'default': + return { + icon: + } + case 'plan': + return { + icon: + } + case 'acceptEdits': + return { + icon: + } + case 'bypassPermissions': + return { + icon: + } + default: + return { + icon: + } + } +} + +const PermissionModeDisplay: FC = ({ session, agentId }) => { + const { t } = useTranslation() + + const permissionMode = session?.configuration?.permission_mode ?? 'default' + + const modeCard = useMemo(() => { + return permissionModeCards.find((card) => card.mode === permissionMode) + }, [permissionMode]) + + const modeConfig = useMemo(() => getPermissionModeConfig(permissionMode), [permissionMode]) + + const handleClick = () => { + SessionSettingsPopup.show({ + agentId, + sessionId: session.id, + tab: 'tooling' + }) + } + + if (!modeCard) { + return null + } + + return ( +
+
+
{modeConfig.icon}
+
+
+ {t(modeCard.titleKey, modeCard.titleFallback)} +
+
+ {t(modeCard.descriptionKey, modeCard.descriptionFallback)}{' '} + {t(modeCard.behaviorKey, modeCard.behaviorFallback)} +
+
+
+
+ ) +} + +export default PermissionModeDisplay