optimize: UI update
This commit is contained in:
@@ -34,12 +34,12 @@ const ButtonCheckbox: FC<ButtonCheckboxProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={clsx("rb:flex rb:items-center rb:border rb:rounded-[8px] rb:px-[8px] rb:text-[12px] rb:h-[24px] rb:cursor-pointer rb:hover:bg-[#F0F3F8]", {
|
||||
<div className={clsx("rb:flex rb:items-center rb:border rb:rounded-lg rb:px-2 rb:text-[12px] rb:h-6 rb:cursor-pointer rb:hover:bg-[#F0F3F8]", {
|
||||
"rb:bg-[rgba(21,94,239,0.06)] rb:border-[#155EEF] rb:text-[#155EEF]": checked,
|
||||
"rb:border-[#DFE4ED] rb:text-[#212332]": !checked,
|
||||
})} onClick={handleChange}>
|
||||
{icon && !checked && <img src={icon} className="rb:w-[16px] rb:h-[16px] rb:mr-[4px]" />}
|
||||
{checkedIcon && checked && <img src={checkedIcon} className="rb:w-[16px] rb:h-[16px] rb:mr-[4px]" />}
|
||||
{icon && !checked && <img src={icon} className="rb:w-4 rb:h-4 rb:mr-1" />}
|
||||
{checkedIcon && checked && <img src={checkedIcon} className="rb:w-4 rb:h-4 rb:mr-1" />}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ interface ApiResponse<T> {
|
||||
items?: T[];
|
||||
}
|
||||
|
||||
interface CustomSelectProps {
|
||||
interface CustomSelectProps extends Omit<SelectProps, 'filterOption'> {
|
||||
url: string;
|
||||
params?: Record<string, unknown>;
|
||||
valueKey?: string;
|
||||
|
||||
@@ -29,7 +29,7 @@ interface PageScrollListProps {
|
||||
|
||||
const PageScrollList = forwardRef<PageScrollListRef, PageScrollListProps>(({
|
||||
renderItem,
|
||||
query = {},
|
||||
query,
|
||||
url,
|
||||
column = 4,
|
||||
className = '',
|
||||
@@ -51,11 +51,11 @@ const PageScrollList = forwardRef<PageScrollListRef, PageScrollListProps>(({
|
||||
request.get(url, {
|
||||
page: page,
|
||||
pagesize: PAGE_SIZE,
|
||||
...query,
|
||||
...(query||{}),
|
||||
})
|
||||
.then((res) => {
|
||||
const response = res as ApiResponse;
|
||||
const results = Array.isArray(response.items) ? response.items : Array.isArray(response.hosts) ? response.hosts : Array.isArray(response) ? response : [];
|
||||
const results = Array.isArray(response.items) ? response.items : Array.isArray(response) ? response : [];
|
||||
if (flag) {
|
||||
setData(results);
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,7 @@ const colors = {
|
||||
|
||||
const RbAlert: FC<RbAlertProps> = ({ color = 'blue', icon, className, children }) => {
|
||||
return (
|
||||
<div className={`${colors[color]} ${className} rb:p-[6px_9px] rb:flex rb:items-center rb:text-[12px] rb:font-regular rb:leading-[16px] rb:border-[1px] rb:rounded-[6px]`}>
|
||||
<div className={`${colors[color]} ${className} rb:p-[6px_9px] rb:flex rb:items-center rb:text-[12px] rb:font-regular rb:leading-4 rb:border rb:rounded-md`}>
|
||||
{icon && <span className="rb:text-[16px] rb:mr-[9px]">{icon}</span>}
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,7 @@ const RbCard: FC<RbCardProps> = ({
|
||||
title={typeof title === 'function' ? title() : title ?
|
||||
<div className="rb:flex rb:items-center">
|
||||
{avatarUrl
|
||||
? <img src={avatarUrl} className="rb:mr-[13px] rb:w-[48px] rb:h-[48px] rb:rounded-[8px]" />
|
||||
? <img src={avatarUrl} className="rb:mr-3.25 rb:w-12 rb:h-12 rb:rounded-lg" />
|
||||
: avatar ? avatar : null
|
||||
}
|
||||
<div className={
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type FC, type ReactNode } from 'react'
|
||||
|
||||
interface TagProps {
|
||||
export interface TagProps {
|
||||
color?: 'processing' | 'error' | 'success' | 'warning' | 'default',
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
@@ -16,7 +16,7 @@ const colors = {
|
||||
|
||||
const Tag: FC<TagProps> = ({ color = 'processing', children, className }) => {
|
||||
return (
|
||||
<span className={`rb:inline-block rb:px-[4px] rb:py-[2px] rb:rounded-[4px] rb:text-[12px] rb:font-regular! rb:leading-[16px] rb:border-[1px] ${colors[color]} ${className || ''}`}>
|
||||
<span className={`rb:inline-block rb:px-1 rb:py-0.5 rb:rounded-sm rb:text-[12px] rb:font-regular! rb:leading-4 rb:border ${colors[color]} ${className || ''}`}>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ const NoPermission = () => {
|
||||
return (
|
||||
<Empty
|
||||
url={noPermission}
|
||||
size={[240, 240]}
|
||||
title={t('empty.noPermission')}
|
||||
subTitle={t('empty.noPermissionDesc')}
|
||||
className="rb:h-[calc(100vh-84px)]"
|
||||
|
||||
@@ -8,6 +8,7 @@ const NotFound = () => {
|
||||
return (
|
||||
<Empty
|
||||
url={notFoundImg}
|
||||
size={[328, 146]}
|
||||
title={t('empty.notFound')}
|
||||
subTitle={t('empty.notFoundDesc')}
|
||||
className="rb:h-[calc(100vh-84px)]"
|
||||
|
||||
@@ -7,16 +7,17 @@ export interface Data {
|
||||
other_address: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
},
|
||||
memory_num: {
|
||||
total: number;
|
||||
counts: {
|
||||
dialogue: number;
|
||||
chunk: number;
|
||||
statement: number;
|
||||
entity: number;
|
||||
}
|
||||
},
|
||||
memory_num: {
|
||||
total: number;
|
||||
counts: {
|
||||
dialogue: number;
|
||||
chunk: number;
|
||||
statement: number;
|
||||
entity: number;
|
||||
}
|
||||
},
|
||||
name?: string;
|
||||
}
|
||||
export interface ConfigModalData {
|
||||
llm: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { type FC, useEffect, useState, useRef } from 'react'
|
||||
import React, { type FC, useEffect, useState, useRef, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Col } from 'antd'
|
||||
@@ -29,13 +29,9 @@ const RelationshipNetwork:FC = () => {
|
||||
const [categories, setCategories] = useState<{ name: string }[]>([])
|
||||
const [selectedNode, setSelectedNode] = useState<Node | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) return
|
||||
getEdgeData()
|
||||
}, [id])
|
||||
|
||||
// 关系网络
|
||||
const getEdgeData = () => {
|
||||
const getEdgeData = useCallback(() => {
|
||||
if (!id) return
|
||||
setSelectedNode(null)
|
||||
getMemorySearchEdges(id).then((res) => {
|
||||
@@ -45,20 +41,20 @@ const RelationshipNetwork:FC = () => {
|
||||
const categories: { name: string }[] = []
|
||||
|
||||
list.forEach(item => {
|
||||
if (item.edge) {
|
||||
if (item.edge && item.edge.target_id && item.edge.source_id) {
|
||||
links.push({
|
||||
...item.edge,
|
||||
target: item.edge?.target_id,
|
||||
source: item.edge?.source_id,
|
||||
target: item.edge.target_id,
|
||||
source: item.edge.source_id,
|
||||
})
|
||||
}
|
||||
if (item.sourceNode) {
|
||||
nodes.push(item.sourceNode)
|
||||
categories.push({name: item.sourceNode.entity_type})
|
||||
categories.push({name: item.sourceNode.entity_type || 'Unknown'})
|
||||
}
|
||||
if (item.targetNode) {
|
||||
nodes.push(item.targetNode)
|
||||
categories.push({name: item.targetNode.entity_type})
|
||||
categories.push({name: item.targetNode.entity_type || 'Unknown'})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -76,14 +72,58 @@ const RelationshipNetwork:FC = () => {
|
||||
setLinks(uniqueLinks)
|
||||
setCategories(uniqueCategories)
|
||||
|
||||
// Calculate node frequency based on appearance in links
|
||||
const nodeFrequency = new Map<string, number>()
|
||||
|
||||
// Count each node's appearance in links (both as source and target)
|
||||
uniqueLinks.forEach(link => {
|
||||
// Increment source node frequency (only if source exists and is a string)
|
||||
if (typeof link.source === 'string') {
|
||||
nodeFrequency.set(link.source, (nodeFrequency.get(link.source) || 0) + 1)
|
||||
}
|
||||
// Increment target node frequency (only if target exists and is a string)
|
||||
if (typeof link.target === 'string') {
|
||||
nodeFrequency.set(link.target, (nodeFrequency.get(link.target) || 0) + 1)
|
||||
}
|
||||
})
|
||||
|
||||
// Set minimum frequency to 1 for nodes not in any links
|
||||
uniqueNodes.forEach(node => {
|
||||
if (node.id && typeof node.id === 'string') {
|
||||
if (!nodeFrequency.has(node.id)) {
|
||||
nodeFrequency.set(node.id, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
uniqueNodes.map(item => {
|
||||
const index = uniqueCategories.findIndex((n) => n.name === item.entity_type)
|
||||
const index = uniqueCategories.findIndex((n) => n.name === (item.entity_type || 'Unknown'))
|
||||
item.category = index
|
||||
item.symbolSize = index < 10 ? 5 : index <100 ? 8 : 10
|
||||
|
||||
// Get frequency for the node, ensuring id is a string
|
||||
const frequency = (item.id && typeof item.id === 'string') ? (nodeFrequency.get(item.id) || 1) : 1
|
||||
|
||||
// Set symbolSize based on frequency
|
||||
// Adjust these thresholds based on expected frequency ranges
|
||||
if (frequency <= 1) {
|
||||
item.symbolSize = 5
|
||||
} else if (frequency <= 10) {
|
||||
item.symbolSize = 10
|
||||
} else if (frequency <= 15) {
|
||||
item.symbolSize = 15
|
||||
} else if (frequency <= 20) {
|
||||
item.symbolSize = 25
|
||||
} else {
|
||||
item.symbolSize = 35
|
||||
}
|
||||
})
|
||||
setNodes(uniqueNodes)
|
||||
})
|
||||
}
|
||||
}, [id])
|
||||
useEffect(() => {
|
||||
if (!id) return
|
||||
getEdgeData()
|
||||
}, [id])
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
@@ -95,7 +135,7 @@ const RelationshipNetwork:FC = () => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const resizeObserver = new ResizeObserver(handleResize)
|
||||
const chartElement = chartRef.current?.getEchartsInstance().getDom().parentElement
|
||||
if (chartElement) {
|
||||
@@ -106,6 +146,8 @@ const RelationshipNetwork:FC = () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [nodes])
|
||||
|
||||
console.log('nodes', nodes)
|
||||
return (
|
||||
<>
|
||||
{/* 关系网络 */}
|
||||
@@ -175,12 +217,10 @@ const RelationshipNetwork:FC = () => {
|
||||
if (params.dataType === 'node') {
|
||||
// 处理节点点击事件
|
||||
console.log('Node clicked:', params.data);
|
||||
setSelectedNode(params.data)
|
||||
if (selectedNode?.id === params.data.id) {
|
||||
setSelectedNode(null)
|
||||
} else {
|
||||
setSelectedNode(params.data)
|
||||
}
|
||||
// 使用函数式更新避免状态依赖问题
|
||||
setSelectedNode(prevSelected =>
|
||||
prevSelected?.id === params.data.id ? null : params.data
|
||||
)
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user