Browse Source

Fix: Add parsing animations to the agent log and optimize some page styles (#9040)

### What problem does this PR solve?

Add parsing animations to the agent log and optimize some page styles
#3221

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
tags/v0.20.0
chanx 3 months ago
parent
commit
6aaad85cc6
No account linked to committer's email address

+ 1
- 1
web/src/locales/en.ts View File

}, },
operator: 'Operator', operator: 'Operator',
value: 'Value', value: 'Value',
useTemplate: 'Use this template',
useTemplate: 'Use',
wenCai: 'WenCai', wenCai: 'WenCai',
queryType: 'Query type', queryType: 'Query type',
wenCaiDescription: wenCaiDescription:

+ 1
- 1
web/src/locales/zh-traditional.ts View File

}, },
operator: '操作符', operator: '操作符',
value: '值', value: '值',
useTemplate: '使用該模板',
useTemplate: '使用',
wenCai: '問財', wenCai: '問財',
queryType: '查詢類型', queryType: '查詢類型',
wenCaiDescription: wenCaiDescription:

+ 1
- 1
web/src/locales/zh.ts View File

}, },
operator: '操作符', operator: '操作符',
value: '值', value: '值',
useTemplate: '使用该模板',
useTemplate: '使用',
wenCai: '问财', wenCai: '问财',
queryType: '查询类型', queryType: '查询类型',
wenCaiDescription: wenCaiDescription:

+ 11
- 5
web/src/pages/agent/form/begin-form/query-table.tsx View File

{ {
accessorKey: 'key', accessorKey: 'key',
header: 'key', header: 'key',
meta: { cellClassName: 'max-w-16' },
meta: { cellClassName: 'max-w-30' },
cell: ({ row }) => { cell: ({ row }) => {
const key: string = row.getValue('key'); const key: string = row.getValue('key');
return ( return (
{ {
accessorKey: 'name', accessorKey: 'name',
header: t('flow.name'), header: t('flow.name'),
meta: { cellClassName: 'max-w-20' },
meta: { cellClassName: 'max-w-30' },
cell: ({ row }) => { cell: ({ row }) => {
const name: string = row.getValue('name'); const name: string = row.getValue('name');
return ( return (


return ( return (
<div> <div>
<Button variant={'ghost'} onClick={() => showModal(idx, record)}>
<Button
className="bg-transparent text-foreground hover:bg-muted-foreground hover:text-foreground"
onClick={() => showModal(idx, record)}
>
<Pencil /> <Pencil />
</Button> </Button>
<Button variant={'ghost'} onClick={() => deleteRecord(idx)}>
<Button
className="bg-transparent text-foreground hover:bg-muted-foreground hover:text-foreground"
onClick={() => deleteRecord(idx)}
>
<Trash2 /> <Trash2 />
</Button> </Button>
</div> </div>
return ( return (
<div className="w-full"> <div className="w-full">
<div className="rounded-md border"> <div className="rounded-md border">
<Table>
<Table rootClassName="rounded-md">
<TableHeader> <TableHeader>
{table.getHeaderGroups().map((headerGroup) => ( {table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}> <TableRow key={headerGroup.id}>

+ 25
- 2
web/src/pages/agent/log-sheet/index.tsx View File

import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { ITraceData } from '@/interfaces/database/agent'; import { ITraceData } from '@/interfaces/database/agent';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { t } from 'i18next';
import { get } from 'lodash'; import { get } from 'lodash';
import { BellElectric, NotebookText } from 'lucide-react';
import { NotebookText } from 'lucide-react';
import { useCallback, useEffect, useMemo } from 'react'; import { useCallback, useEffect, useMemo } from 'react';
import JsonView from 'react18-json-view'; import JsonView from 'react18-json-view';
import 'react18-json-view/src/style.css'; import 'react18-json-view/src/style.css';
import { Operator } from '../constant';
import { useCacheChatLog } from '../hooks/use-cache-chat-log'; import { useCacheChatLog } from '../hooks/use-cache-chat-log';
import OperatorIcon from '../operator-icon';
import useGraphStore from '../store'; import useGraphStore from '../store';


type LogSheetProps = IModalProps<any> & type LogSheetProps = IModalProps<any> &


const getNodeName = useCallback( const getNodeName = useCallback(
(nodeId: string) => { (nodeId: string) => {
if ('begin' === nodeId) return t('flow.begin');
return getNode(nodeId)?.data.name; return getNode(nodeId)?.data.name;
}, },
[getNode], [getNode],
<Timeline> <Timeline>
{startedNodeList.map((x, idx) => { {startedNodeList.map((x, idx) => {
const nodeDataList = filterFinishedNodeList(x.data.component_id); const nodeDataList = filterFinishedNodeList(x.data.component_id);
const finishNodeIds = nodeDataList.map(
(x: INodeData) => x.component_id,
);
const inputs = getInputsOrOutputs(nodeDataList, 'inputs'); const inputs = getInputsOrOutputs(nodeDataList, 'inputs');
const outputs = getInputsOrOutputs(nodeDataList, 'outputs'); const outputs = getInputsOrOutputs(nodeDataList, 'outputs');
const nodeLabel = getNode(x.data.component_id)?.data.label;
return ( return (
<TimelineItem <TimelineItem
key={idx} key={idx}
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5 top-6 bg-background-checked" /> <TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5 top-6 bg-background-checked" />


<TimelineIndicator className="bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7"> <TimelineIndicator className="bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7">
<BellElectric className="size-5" />
<div className='relative after:content-[""] after:absolute after:inset-0 after:z-10 after:bg-transparent after:transition-all after:duration-300'>
<div className="absolute inset-0 z-10 flex items-center justify-center ">
<div
className={cn('rounded-full w-6 h-6', {
' border-muted-foreground border-2 border-t-transparent animate-spin ':
!finishNodeIds.includes(x.data.component_id),
})}
></div>
</div>
<div className="size-6 flex items-center justify-center">
<OperatorIcon
className="size-5"
name={nodeLabel as Operator}
></OperatorIcon>
</div>
</div>
</TimelineIndicator> </TimelineIndicator>
</TimelineHeader> </TimelineHeader>
<TimelineContent className="text-foreground rounded-lg border mb-5"> <TimelineContent className="text-foreground rounded-lg border mb-5">

+ 26
- 18
web/src/pages/agents/agent-templates.tsx View File

import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { CreateAgentDialog } from './create-agent-dialog'; import { CreateAgentDialog } from './create-agent-dialog';
import { TemplateCard } from './template-card'; import { TemplateCard } from './template-card';
import { SideBar } from './template-sidebar';


export default function AgentTemplates() { export default function AgentTemplates() {
const { navigateToAgentList } = useNavigatePage(); const { navigateToAgentList } = useNavigatePage();
</BreadcrumbList> </BreadcrumbList>
</Breadcrumb> </Breadcrumb>
</PageHeader> </PageHeader>
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-8 max-h-[94vh] overflow-auto px-8">
{list?.map((x) => {
return (
<TemplateCard
key={x.id}
data={x}
showModal={showModal}
></TemplateCard>
);
})}
<div className="flex flex-1 h-dvh">
<SideBar change={handleSiderBarChange}></SideBar>

<main className="flex-1 bg-muted/50 h-dvh">
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[94vh] overflow-auto px-8 pt-8">
{templateList?.map((x, index) => {
return (
<TemplateCard
isCreate={index === 0}
key={x.id}
data={x}
showModal={showModal}
></TemplateCard>
);
})}
</div>
{creatingVisible && (
<CreateAgentDialog
loading={loading}
visible={creatingVisible}
hideModal={hideCreatingModal}
onOk={handleOk}
></CreateAgentDialog>
)}
</main>
</div> </div>
{creatingVisible && (
<CreateAgentDialog
loading={loading}
visible={creatingVisible}
hideModal={hideCreatingModal}
onOk={handleOk}
></CreateAgentDialog>
)}
</section> </section>
); );
} }

Loading…
Cancel
Save