feat: 创建 ChatArea 组件(含 MessageRenderer、ExecutionStepsDisplay 子组件)
This commit is contained in:
117
src/views/AgentChat/components/ChatArea/ExecutionStepsDisplay.js
Normal file
117
src/views/AgentChat/components/ChatArea/ExecutionStepsDisplay.js
Normal file
@@ -0,0 +1,117 @@
|
||||
// src/views/AgentChat/components/ChatArea/ExecutionStepsDisplay.js
|
||||
// 执行步骤显示组件
|
||||
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionItem,
|
||||
AccordionButton,
|
||||
AccordionPanel,
|
||||
AccordionIcon,
|
||||
Card,
|
||||
CardBody,
|
||||
Badge,
|
||||
HStack,
|
||||
VStack,
|
||||
Flex,
|
||||
Text,
|
||||
} from '@chakra-ui/react';
|
||||
import { Activity } from 'lucide-react';
|
||||
|
||||
/**
|
||||
* ExecutionStepsDisplay - 执行步骤显示组件
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {Array} props.steps - 执行步骤列表
|
||||
* @param {Object} props.plan - 执行计划(可选)
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const ExecutionStepsDisplay = ({ steps, plan }) => {
|
||||
return (
|
||||
<Accordion allowToggle>
|
||||
<AccordionItem
|
||||
border="1px solid"
|
||||
borderColor="rgba(255, 255, 255, 0.1)"
|
||||
borderRadius="lg"
|
||||
bg="rgba(255, 255, 255, 0.03)"
|
||||
backdropFilter="blur(10px)"
|
||||
_hover={{
|
||||
bg: 'rgba(255, 255, 255, 0.05)',
|
||||
borderColor: 'rgba(255, 255, 255, 0.2)',
|
||||
}}
|
||||
>
|
||||
<AccordionButton px={4} py={2}>
|
||||
<HStack flex={1} spacing={2}>
|
||||
<Activity className="w-4 h-4" color="#C084FC" />
|
||||
<Text color="gray.300" fontSize="sm">
|
||||
执行详情
|
||||
</Text>
|
||||
<Badge
|
||||
bgGradient="linear(to-r, purple.500, pink.500)"
|
||||
color="white"
|
||||
variant="subtle"
|
||||
boxShadow="0 2px 8px rgba(139, 92, 246, 0.3)"
|
||||
>
|
||||
{steps.length} 步骤
|
||||
</Badge>
|
||||
</HStack>
|
||||
<AccordionIcon color="gray.400" />
|
||||
</AccordionButton>
|
||||
<AccordionPanel pb={4}>
|
||||
<VStack spacing={2} align="stretch">
|
||||
{steps.map((result, idx) => (
|
||||
<motion.div
|
||||
key={idx}
|
||||
initial={{ opacity: 0, x: -10 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: idx * 0.05 }}
|
||||
>
|
||||
<Card
|
||||
bg="rgba(255, 255, 255, 0.03)"
|
||||
backdropFilter="blur(10px)"
|
||||
border="1px solid"
|
||||
borderColor="rgba(255, 255, 255, 0.1)"
|
||||
>
|
||||
<CardBody p={3}>
|
||||
<Flex align="start" justify="space-between" gap={2}>
|
||||
<Text fontSize="xs" fontWeight="medium" color="gray.300">
|
||||
步骤 {idx + 1}: {result.tool_name}
|
||||
</Text>
|
||||
<Badge
|
||||
bgGradient={
|
||||
result.status === 'success'
|
||||
? 'linear(to-r, green.500, teal.500)'
|
||||
: 'linear(to-r, red.500, orange.500)'
|
||||
}
|
||||
color="white"
|
||||
variant="subtle"
|
||||
boxShadow={
|
||||
result.status === 'success'
|
||||
? '0 2px 8px rgba(16, 185, 129, 0.3)'
|
||||
: '0 2px 8px rgba(239, 68, 68, 0.3)'
|
||||
}
|
||||
>
|
||||
{result.status}
|
||||
</Badge>
|
||||
</Flex>
|
||||
<Text fontSize="xs" color="gray.500" mt={1}>
|
||||
{result.execution_time?.toFixed(2)}s
|
||||
</Text>
|
||||
{result.error && (
|
||||
<Text fontSize="xs" color="red.400" mt={1}>
|
||||
⚠️ {result.error}
|
||||
</Text>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</VStack>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExecutionStepsDisplay;
|
||||
Reference in New Issue
Block a user