feat: model

This commit is contained in:
scarqin
2024-12-24 14:28:10 +08:00
parent b05874fb0a
commit a9b7fc525a
2 changed files with 46 additions and 32 deletions
@@ -1,7 +1,17 @@
'use client'
import { useFetch } from '@common/hooks/http'
import { addEdge, NodeTypes, ReactFlow, useEdgesState, useNodesState } from '@xyflow/react'
import {
addEdge,
Connection,
Edge,
Node,
NodeTypes,
PanOnScrollMode,
ReactFlow,
useEdgesState,
useNodesState
} from '@xyflow/react'
import '@xyflow/react/dist/style.css'
import { useCallback, useEffect, useState } from 'react'
import { KeyStatusNode } from './components/KeyStatusNode'
@@ -23,6 +33,18 @@ interface ApiResponse {
success: string
}
interface NodeData {
title?: string
status?: string
defaultModel?: string
logo?: string
keys?: Array<{
id: string
status: string
priority: number
}>
}
const calculateNodePositions = (models: ModelData[], startY = LAYOUT.NODE_START_Y, gap = LAYOUT.NODE_GAP) => {
return models.reduce(
(acc, model, index) => {
@@ -48,8 +70,8 @@ const nodeTypes: NodeTypes = {
const AIFlowChart = () => {
const [modelData, setModelData] = useState<ModelData[]>([])
const [nodes, setNodes, onNodesChange] = useNodesState([])
const [edges, setEdges, onEdgesChange] = useEdgesState([])
const [nodes, setNodes, onNodesChange] = useNodesState<Node>([])
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([])
const { fetchData } = useFetch()
useEffect(() => {
@@ -68,7 +90,7 @@ const AIFlowChart = () => {
const newNodes = [
{
id: 'service',
id: 'apiService',
type: 'serviceCard',
position: { x: LAYOUT.SERVICE_NODE_X, y: LAYOUT.NODE_START_Y },
data: {}
@@ -123,10 +145,10 @@ const AIFlowChart = () => {
setEdges(newEdges)
}, [modelData])
const onConnect = useCallback((params: any) => setEdges((eds) => addEdge(params, eds)), [setEdges])
const onConnect = useCallback((params: Connection) => setEdges((eds) => addEdge(params, eds)), [setEdges])
const onNodeDrag = useCallback(
(_: any, node: any) => {
const onNodeDrag: any = useCallback(
(_: MouseEvent, node: Node<any>) => {
if (node.type !== 'modelCard') return
setNodes((nds) => {
@@ -147,8 +169,8 @@ const AIFlowChart = () => {
[setNodes]
)
const onNodeDragStop = useCallback(
(_: any, node: any) => {
const onNodeDragStop: any = useCallback(
(_, node: Node<any>) => {
if (node.type !== 'modelCard') return
setNodes((nds) => {
@@ -174,7 +196,7 @@ const AIFlowChart = () => {
)
return (
<div className="w-full h-full">
<div className="overflow-y-auto w-full h-full" style={{ height: '100vh' }}>
<ReactFlow
nodes={nodes}
edges={edges}
@@ -184,8 +206,13 @@ const AIFlowChart = () => {
onNodeDrag={onNodeDrag}
onNodeDragStop={onNodeDragStop}
nodeTypes={nodeTypes}
fitView
attributionPosition="bottom-left"
maxZoom={1}
minZoom={1}
zoomOnScroll={false}
zoomOnPinch={false}
zoomOnDoubleClick={false}
panOnScroll={true}
panOnScrollMode={PanOnScrollMode.Vertical}
/>
</div>
)
@@ -1,6 +1,5 @@
import { Icon } from '@iconify/react'
import { Handle, Position } from '@xyflow/react'
import { Avatar } from 'antd'
import { t } from 'i18next'
import React from 'react'
import { ModelStatus } from './types'
@@ -29,25 +28,13 @@ export const ModelCardNode: React.FC<{ data: ModelCardNodeData }> = ({ data }) =
<div>
<div className="flex justify-between items-center">
<div className="flex gap-2 items-center">
<Avatar
shape="square"
size={50}
className={`rounded-[12px] border-none ${logo ? 'bg-[linear-gradient(135deg,white,#f0f0f0)]' : 'bg-theme'}`}
src={
logo ? (
<img
src={logo}
alt="Logo"
style={{ maxWidth: '200px', width: '45px', height: '45px', objectFit: 'unset' }}
/>
) : undefined
}
// TODO use https://www.npmjs.com/package/@icon-park/react
icon={logo ? '' : <iconpark-icon name="auto-generate-api"></iconpark-icon>}
>
{' '}
</Avatar>
<span className="text-base text-gray-900">{title}</span>
<div className="flex flex-1 overflow-hidden items-center gap-[4px]">
<span
className=" flex items-center h-[22px] ai-setting-svg-container"
dangerouslySetInnerHTML={{ __html: logo }}
></span>
</div>
<span className="text-base text-gray-900 max-w-[180px] truncate">{title}</span>
<Icon
icon={status === 'enable' ? 'mdi:check-circle' : 'mdi:close-circle'}
className={`text-xl ${status === 'enable' ? 'text-green-500' : 'text-red-500'}`}