mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-05-24 23:28:47 +08:00
### What problem does this PR solve? Feat: Render operator menu by category. #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
f9f75aa119
commit
ca865df87f
@ -1,3 +1,4 @@
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
@ -11,81 +12,97 @@ import {
|
||||
SidebarGroupLabel,
|
||||
SidebarHeader,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from '@/components/ui/sidebar';
|
||||
import { ChevronDown } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
Calendar,
|
||||
ChevronDown,
|
||||
Home,
|
||||
Inbox,
|
||||
Search,
|
||||
Settings,
|
||||
} from 'lucide-react';
|
||||
AgentOperatorList,
|
||||
Operator,
|
||||
componentMenuList,
|
||||
operatorMap,
|
||||
} from './constant';
|
||||
import OperatorIcon from './operator-icon';
|
||||
|
||||
// Menu items.
|
||||
const items = [
|
||||
{
|
||||
title: 'Home',
|
||||
url: '#',
|
||||
icon: Home,
|
||||
},
|
||||
{
|
||||
title: 'Inbox',
|
||||
url: '#',
|
||||
icon: Inbox,
|
||||
},
|
||||
{
|
||||
title: 'Calendar',
|
||||
url: '#',
|
||||
icon: Calendar,
|
||||
},
|
||||
{
|
||||
title: 'Search',
|
||||
url: '#',
|
||||
icon: Search,
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
url: '#',
|
||||
icon: Settings,
|
||||
},
|
||||
];
|
||||
function SideDown() {
|
||||
return (
|
||||
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
|
||||
);
|
||||
}
|
||||
|
||||
type OperatorItem = {
|
||||
name: Operator;
|
||||
};
|
||||
|
||||
function OperatorCard({ name }: OperatorItem) {
|
||||
return (
|
||||
<Card className="bg-colors-background-inverse-weak border-colors-outline-neutral-standard">
|
||||
<CardContent className="p-2 flex items-center gap-2">
|
||||
<OperatorIcon
|
||||
name={name}
|
||||
color={operatorMap[name].color}
|
||||
></OperatorIcon>
|
||||
{name}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
type OperatorCollapsibleProps = { operatorList: OperatorItem[]; title: string };
|
||||
|
||||
function OperatorCollapsible({
|
||||
operatorList,
|
||||
title,
|
||||
}: OperatorCollapsibleProps) {
|
||||
return (
|
||||
<Collapsible defaultOpen className="group/collapsible">
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel asChild className="mb-1">
|
||||
<CollapsibleTrigger>
|
||||
<span className="font-bold text-base">{title}</span>
|
||||
<SideDown />
|
||||
</CollapsibleTrigger>
|
||||
</SidebarGroupLabel>
|
||||
<CollapsibleContent className="px-2">
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu className="gap-2">
|
||||
{operatorList.map((item) => (
|
||||
<OperatorCard key={item.name} name={item.name}></OperatorCard>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</CollapsibleContent>
|
||||
</SidebarGroup>
|
||||
</Collapsible>
|
||||
);
|
||||
}
|
||||
|
||||
export function AgentSidebar() {
|
||||
const agentOperatorList = useMemo(() => {
|
||||
return componentMenuList.filter((x) =>
|
||||
AgentOperatorList.some((y) => y === x.name),
|
||||
);
|
||||
}, []);
|
||||
|
||||
const thirdOperatorList = useMemo(() => {
|
||||
return componentMenuList.filter(
|
||||
(x) => !AgentOperatorList.some((y) => y === x.name),
|
||||
);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Sidebar variant={'floating'} className="top-16">
|
||||
<SidebarHeader>
|
||||
<p className="font-bold text-2xl">All nodes</p>
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<Collapsible defaultOpen className="group/collapsible">
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel asChild>
|
||||
<CollapsibleTrigger>
|
||||
Help
|
||||
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
|
||||
</CollapsibleTrigger>
|
||||
</SidebarGroupLabel>
|
||||
<CollapsibleContent>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</CollapsibleContent>
|
||||
</SidebarGroup>
|
||||
</Collapsible>
|
||||
<SidebarGroup>yyy</SidebarGroup>
|
||||
<OperatorCollapsible
|
||||
title="Agent operator"
|
||||
operatorList={agentOperatorList}
|
||||
></OperatorCollapsible>
|
||||
<OperatorCollapsible
|
||||
title="Third-party tools"
|
||||
operatorList={thirdOperatorList}
|
||||
></OperatorCollapsible>
|
||||
</SidebarContent>
|
||||
</Sidebar>
|
||||
);
|
||||
|
2985
web/src/pages/agent/constant.tsx
Normal file
2985
web/src/pages/agent/constant.tsx
Normal file
File diff suppressed because it is too large
Load Diff
22
web/src/pages/agent/operator-icon/index.tsx
Normal file
22
web/src/pages/agent/operator-icon/index.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Operator, operatorIconMap } from '../constant';
|
||||
|
||||
interface IProps {
|
||||
name: Operator;
|
||||
fontSize?: number;
|
||||
width?: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const OperatorIcon = ({ name, fontSize, width, color }: IProps) => {
|
||||
const Icon = operatorIconMap[name] || React.Fragment;
|
||||
return (
|
||||
<Icon
|
||||
className={'text-2xl max-h-6 max-w-6 text-[rgb(59, 118, 244)]'}
|
||||
style={{ fontSize, color }}
|
||||
width={width}
|
||||
></Icon>
|
||||
);
|
||||
};
|
||||
|
||||
export default OperatorIcon;
|
Loading…
x
Reference in New Issue
Block a user