fix(web): ui
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState, useRef, useMemo, useCallback, type FC } from 'react';
|
||||
import { Row, Col, Button, Dropdown, Tooltip, App } from 'antd'
|
||||
import { Button, Dropdown, Tooltip, App, Flex } from 'antd'
|
||||
import type { MenuProps } from 'antd';
|
||||
import { EllipsisOutlined, RightOutlined, DownOutlined } from '@ant-design/icons';
|
||||
import { RightOutlined, DownOutlined } from '@ant-design/icons';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -78,6 +78,7 @@ const KnowledgeBaseManagement: FC = () => {
|
||||
if (permissionId !== 'share') {
|
||||
items.push({
|
||||
key: '1',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit_bold.svg')]" />,
|
||||
label: t('knowledgeBase.edit'),
|
||||
onClick: () => {
|
||||
handleEdit(item);
|
||||
@@ -87,6 +88,7 @@ const KnowledgeBaseManagement: FC = () => {
|
||||
|
||||
items.push({
|
||||
key: '2',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete_red_big.svg')]" />,
|
||||
label: t('knowledgeBase.delete'),
|
||||
onClick: () => {
|
||||
handleDelete(item);
|
||||
@@ -560,21 +562,23 @@ const KnowledgeBaseManagement: FC = () => {
|
||||
{data.length === 0 && !loading ? (
|
||||
<Empty size={200} />
|
||||
) : (
|
||||
<Row gutter={[16, 16]} className="rb:mb-2" style={{ margin: 0 }}>
|
||||
<div style={{ columns: '3 280px', columnGap: 12, marginBottom: 8 }}>
|
||||
{data.map((item) => {
|
||||
const modelInfo = modelMenus[item.id];
|
||||
const hasModelInfo = modelInfo && modelInfo.menu.length > 1;
|
||||
return (
|
||||
<Col xs={12} sm={12} md={12} lg={8} xl={8} key={item.id} >
|
||||
<div key={item.id} className="rb:break-inside-avoid rb:mb-3">
|
||||
<RbCard
|
||||
title={item.name}
|
||||
headerType="borderless"
|
||||
headerClassName="rb:py-3!"
|
||||
className='rb:min-h-[200px]'
|
||||
extra={
|
||||
<div onClick={(e) => e.stopPropagation()}>
|
||||
<Dropdown menu={{ items: getOptMenuItems(item) }} >
|
||||
<EllipsisOutlined className="rb:cursor-pointer" />
|
||||
<Dropdown
|
||||
menu={{ items: getOptMenuItems(item) }}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<div onClick={(e) => e.stopPropagation()} className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
}
|
||||
@@ -583,24 +587,23 @@ const KnowledgeBaseManagement: FC = () => {
|
||||
<div className="rb:flex rb:text-[#5B6167] rb:h-5 rb:line-clamp-1 rb:text-sm rb:leading-5 rb:mb-3">
|
||||
{/* <div className="rb:font-medium rb:w-20">{t('knowledgeBase.description')} </div> */}
|
||||
<Tooltip title={item.description}>
|
||||
<div className='rb:flex-1 rb:text-left rb:leading-5 rb:text-gray-800 rb:break-words rb:line-clamp-2'>{(item.description && item.description != '') ? item.description : t('knowledgeBase.noDescription')}</div>
|
||||
<div className='rb:flex-1 rb:text-left rb:leading-5 rb:text-gray-800 rb:wrap-break-word rb:line-clamp-2'>{(item.description && item.description != '') ? item.description : t('knowledgeBase.noDescription')}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className='rb:min-h-[60px] rb:py-2.5 rb:px-3 rb:bg-[#F6F6F6] rb:rounded-lg rb:mb-3'>
|
||||
{item.descriptionItems?.map((description: Record<string, unknown>) => (
|
||||
<Flex vertical gap={4} className='rb:min-h-15 rb:py-2.5! rb:px-3! rb:bg-[#F6F6F6] rb:rounded-lg rb:mb-3'>
|
||||
{item.descriptionItems?.map((description: Record<string, unknown>) => (
|
||||
<div
|
||||
key={description.key as string}
|
||||
className="rb:flex rb:gap-4 rb:justify-start rb:text-[#5B6167] rb:text-[14px] rb:leading-[20px]"
|
||||
key={description.key as string}
|
||||
className="rb:grid rb:grid-cols-2 rb:text-[#5B6167] rb:text-[14px] rb:leading-5"
|
||||
>
|
||||
<div className={clsx('rb:whitespace-nowrap rb:w-20',{"rb:text-gray-800 rb:font-medium" : (description.key as string) === 'permission_id'})}>{(description.label as string)}</div>
|
||||
<div className={clsx('rb:flex-inline rb:text-left rb:py-[1px] rb:rounded rb:font-medium',{
|
||||
"rb:text-[#155eef] rb:font-medium": (description.key as string) === 'permission_id' && (description.children as string) === t('knowledgeBase.private'),
|
||||
"rb:text-[#FF8A4C] rb:font-medium": (description.key as string) === 'permission_id' && (description.children as string) === t('knowledgeBase.share'),
|
||||
})}>{(description.children as string)}</div>
|
||||
<div className={clsx('rb:whitespace-nowrap rb:w-20', {"rb:text-gray-800 rb:font-medium" : (description.key as string) === 'permission_id'})}>{(description.label as string)}</div>
|
||||
<div className={clsx('rb:flex-inline rb:text-left rb:py-px rb:rounded',{
|
||||
"rb:text-[#155eef] rb:font-medium": (description.key as string) === 'permission_id' && (description.children as string) === t('knowledgeBase.private'),
|
||||
"rb:text-[#FF8A4C] rb:font-medium": (description.key as string) === 'permission_id' && (description.children as string) === t('knowledgeBase.share'),
|
||||
})}>{(description.children as string)}</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
</div>
|
||||
))}
|
||||
</Flex>
|
||||
{hasModelInfo && (
|
||||
<div onClick={(e) => e.stopPropagation()}>
|
||||
<div
|
||||
@@ -633,9 +636,9 @@ const KnowledgeBaseManagement: FC = () => {
|
||||
)}
|
||||
</div>
|
||||
</RbCard>
|
||||
</Col>
|
||||
</div>
|
||||
)})}
|
||||
</Row>
|
||||
</div>
|
||||
)}
|
||||
</InfiniteScroll>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 14:10:15
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-25 13:38:59
|
||||
* @Last Modified time: 2026-03-27 15:03:09
|
||||
*/
|
||||
import { type FC, useState, useRef } from 'react';
|
||||
import type { MenuInfo } from 'rc-menu/lib/interface';
|
||||
@@ -150,13 +150,13 @@ const Ontology: FC = () => {
|
||||
items: [
|
||||
{
|
||||
key: 'edit',
|
||||
icon: <div className="rb:size-6 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit_bold.svg')]" />,
|
||||
label: t('common.edit'),
|
||||
onClick: (e: MenuInfo) => handleEdit(item, e),
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
icon: <div className="rb:size-6 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete_red_big.svg')]" />,
|
||||
label: t('common.delete'),
|
||||
onClick: (e: MenuInfo) => handleDelete(item, e),
|
||||
},
|
||||
@@ -164,7 +164,7 @@ const Ontology: FC = () => {
|
||||
}}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<div onClick={(e) => e.stopPropagation()} className="rb:cursor-pointer rb:size-6 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
<div onClick={(e) => e.stopPropagation()} className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 17:44:15
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-26 14:31:50
|
||||
* @Last Modified time: 2026-03-27 15:14:58
|
||||
*/
|
||||
/**
|
||||
* Prompt Editor Component
|
||||
@@ -278,7 +278,7 @@ const Prompt: FC = () => {
|
||||
className="rb:h-[calc(100vh-193px)] rb:bg-white! rb:border-none! rb:p-0! rb:text-[#212332] rb:leading-5"
|
||||
onChange={(value) => form.setFieldValue('current_prompt', value)}
|
||||
/>
|
||||
: <Empty url={analysisEmptyIcon} title={t(`prompt.promptPlaceholder`)} isNeedSubTitle={false} size={[270, 170]} className="rb:h-[calc(100vh-193px)] rb:w-70 rb:mx-auto! rb:text-center! rb:text-[12px]! rb:leading-4!" />
|
||||
: <Empty url={analysisEmptyIcon} title={t(`prompt.promptPlaceholder`)} isNeedSubTitle={false} size={[270, 170]} className="rb:h-[calc(100vh-193px)] rb:mx-auto! rb:text-center! rb:text-[12px]! rb:leading-4!" />
|
||||
}
|
||||
</Form.Item>
|
||||
</RbCard>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 17:44:04
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-26 14:36:33
|
||||
* @Last Modified time: 2026-03-27 15:52:44
|
||||
*/
|
||||
/**
|
||||
* Prompt History Component
|
||||
@@ -12,8 +12,7 @@
|
||||
import React, { useRef, type MouseEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Tooltip, App, Flex, Form, Dropdown } from 'antd';
|
||||
import { DashOutlined } from '@ant-design/icons';
|
||||
import { Space, App, Flex, Form } from 'antd';
|
||||
|
||||
import type { HistoryQuery, HistoryItem, PromptDetailRef } from '../types';
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
@@ -104,26 +103,30 @@ const History: React.FC = () => {
|
||||
renderItem={(item) => (
|
||||
<RbCard
|
||||
className="rb:cursor-pointer rb:relative"
|
||||
title={<Tooltip title={item.title}>{item.title}</Tooltip>}
|
||||
headerClassName='rb:h-[38px]! rb:pt-3!'
|
||||
title={item.title}
|
||||
headerClassName='rb:min-h-[46px]!'
|
||||
headerType="borderless"
|
||||
bodyClassName="rb:px-3! rb:py-0!"
|
||||
>
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{ key: 'detail', label: t('common.viewDetail') },
|
||||
{ key: 'edit', label: t('common.edit') },
|
||||
{ key: 'delete', label: t('common.delete') },
|
||||
],
|
||||
onClick: ({key}) => handleClick(key, item)
|
||||
}}
|
||||
>
|
||||
<DashOutlined className="rb:absolute rb:right-6 rb:top-3.25 rb:hover:bg-[#F6F6F6] rb:p-1 rb:rounded-md" />
|
||||
</Dropdown>
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167] rb:leading-4.5 rb:mb-2">{formatDateTime(item.created_at, 'YYYY/MM/DD HH:mm')}</div>
|
||||
<div className="rb:h-35.5 rb:leading-5 rb:overflow-hidden rb:px-3 rb:py-2.5 rb:bg-[#F6F6F6] rb:rounded-lg rb:hover:shadow-[0px_2px_8px_0px_rgba(23,23,25,0.16)]">
|
||||
<div className="rb:h-35.5 rb:leading-5 rb:overflow-hidden rb:px-3 rb:py-2.5 rb:bg-[#F6F6F6] rb:rounded-lg">
|
||||
<Markdown content={item.prompt} className="rb:h-31! rb:overflow-hidden! rb:line-clamp-6! rb:break-word! rb:text-ellipsis!" />
|
||||
</div>
|
||||
|
||||
<Flex align="center" justify="space-between" className="rb:py-3!">
|
||||
<div className="rb:text-[12px] rb:text-[#5B6167] rb:leading-4.5">{formatDateTime(item.created_at, 'YYYY/MM/DD HH:mm')}</div>
|
||||
|
||||
<Space size={8}>
|
||||
<div className="rb:size-4.5 rb:bg-cover rb:bg-[url('src/assets/images/prompt/eye.svg')] rb:hover:bg-[url('src/assets/images/prompt/eye_bg.svg')]"
|
||||
onClick={() => handleClick('detail', item)}
|
||||
></div>
|
||||
<div className="rb:size-4.5 rb:bg-cover rb:bg-[url('src/assets/images/prompt/edit.svg')] rb:hover:bg-[url('src/assets/images/prompt/edit_bg.svg')]"
|
||||
onClick={() => handleClick('edit', item)}
|
||||
></div>
|
||||
<div className="rb:size-4.5 rb:bg-cover rb:bg-[url('src/assets/images/prompt/delete.svg')] rb:hover:bg-[url('src/assets/images/prompt/delete_hover.svg')]"
|
||||
onClick={() => handleClick('delete', item)}
|
||||
></div>
|
||||
</Space>
|
||||
</Flex>
|
||||
</RbCard>
|
||||
)}
|
||||
heightClass="rb:h-[calc(100vh-126px)]!"
|
||||
|
||||
@@ -88,14 +88,14 @@ const Custom = forwardRef<CustomRef, { getStatusTag: (status: string) => ReactNo
|
||||
items: [
|
||||
{
|
||||
key: 'edit',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit_bold.svg')]" />,
|
||||
label: t('common.edit'),
|
||||
onClick: () => handleEdit(item),
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
className: 'rb:text-[#FF5D34]!',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete_red.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete_red_big.svg')]" />,
|
||||
label: t('common.delete'),
|
||||
onClick: () => handleDeleteService(item),
|
||||
},
|
||||
@@ -103,7 +103,7 @@ const Custom = forwardRef<CustomRef, { getStatusTag: (status: string) => ReactNo
|
||||
}}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<div className="rb:cursor-pointer rb:size-6 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
<div className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ const Inner: React.FC<{ getStatusTag: (status: string) => ReactNode; keyword?: s
|
||||
</Space>
|
||||
<Flex align="center" justify="center" className="rb:size-5.5 rb:hover:bg-[#F6F6F6] rb:rounded-md">
|
||||
<div
|
||||
className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit.svg')]"
|
||||
className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit_bold.svg')]"
|
||||
onClick={() => handleEdit(item)}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
@@ -104,20 +104,20 @@ const Mcp = forwardRef<McpRef, { getStatusTag: (status: string) => ReactNode; ke
|
||||
items: [
|
||||
{
|
||||
key: 'edit',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/edit_bold.svg')]" />,
|
||||
label: t('common.edit'),
|
||||
onClick: () => handleEdit(item),
|
||||
},
|
||||
{
|
||||
key: 'link',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/conversation/link.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/link.svg')]" />,
|
||||
label: t('tool.testLink'),
|
||||
onClick: () => handleTestConnection(item),
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
className: 'rb:text-[#FF5D34]!',
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete_red.svg')]" />,
|
||||
icon: <div className="rb:size-4 rb:bg-cover rb:cursor-pointer rb:bg-[url('@/assets/images/common/delete_red_big.svg')]" />,
|
||||
label: t('common.delete'),
|
||||
onClick: () => handleDeleteService(item),
|
||||
},
|
||||
@@ -125,7 +125,7 @@ const Mcp = forwardRef<McpRef, { getStatusTag: (status: string) => ReactNode; ke
|
||||
}}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<div className="rb:cursor-pointer rb:size-6 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
<div className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-03-16 15:00:07
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-25 12:09:39
|
||||
* @Last Modified time: 2026-03-27 15:23:14
|
||||
*/
|
||||
import { type FC, useRef, useState, useEffect } from 'react'
|
||||
import { Flex, Dropdown, type MenuProps, Slider } from 'antd'
|
||||
@@ -128,7 +128,7 @@ const AudioPlayer: FC<AudioPlayerProps> = ({ src, fileName, fileSize }) => {
|
||||
></div>
|
||||
|
||||
<Dropdown menu={mainMenu} trigger={['click']} placement="bottomRight">
|
||||
<div className="rb:cursor-pointer rb:size-6 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
<div className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]"></div>
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -70,7 +70,7 @@ const NodeLibrary: FC<{ collapsed: boolean; handleToggle: () => void }> = ({ col
|
||||
key={nodeIndex}
|
||||
align="center"
|
||||
gap={8}
|
||||
className="rb:rounded-xl rb:p-2! rb-border rb:cursor-pointer rb:hover:border rb:hover:border-[#171719]!"
|
||||
className="rb:rounded-xl rb:p-2! rb:border rb:border-[#EBEBEB] rb:cursor-pointer rb:hover:border rb:hover:border-[#171719]!"
|
||||
draggable
|
||||
onDragStart={(e) => {
|
||||
e.dataTransfer.setData('application/reactflow', node.type);
|
||||
|
||||
@@ -95,7 +95,7 @@ const VariableList: FC<VariableListProps> = ({
|
||||
<Divider size="small" />
|
||||
<Flex gap={10} vertical>
|
||||
{config.sys?.map((vo, index) =>
|
||||
<Flex align="center" justify="space-between" key={index} className="rb:py-2! rb:pl-2.5! rb:pr-2! rb:text-[12px] rb:bg-[#F6F6F6] rb-border rb:rounded-md">
|
||||
<Flex align="center" justify="space-between" key={index} className="rb:py-2! rb:pl-2.5! rb:pr-2! rb:text-[12px] rb:bg-[#F6F6F6] rb:border rb:border-[#EBEBEB] rb:rounded-md">
|
||||
<span className="rb:font-medium">sys.{vo.name}</span>
|
||||
<span className="rb:py-px rb:px-2 rb:bg-[#FBFDFF] rb-border rb:rounded-sm">{vo.type}</span>
|
||||
</Flex>
|
||||
|
||||
Reference in New Issue
Block a user