mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
feat: update list after edit modal
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { BasicResponse } from '@common/const/const'
|
||||
import { useGlobalContext } from '@common/contexts/GlobalStateContext'
|
||||
import { useFetch } from '@common/hooks/http'
|
||||
import {
|
||||
CoordinateExtent,
|
||||
@@ -20,7 +21,6 @@ import { KeyStatusNode } from './components/KeyStatusNode'
|
||||
import { ModelCardNode } from './components/ModelCardNode'
|
||||
import { ServiceCardNode } from './components/NodeComponents'
|
||||
import { LAYOUT } from './constants'
|
||||
import { useAiSetting } from './contexts/AiSettingContext'
|
||||
import './styles.css'
|
||||
import { ModelData } from './types'
|
||||
|
||||
@@ -67,7 +67,7 @@ const AIFlowChart = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState<Node>([])
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([])
|
||||
const { fetchData } = useFetch()
|
||||
const { openConfigModal } = useAiSetting()
|
||||
const { aiConfigFlushed } = useGlobalContext()
|
||||
|
||||
useEffect(() => {
|
||||
fetchData<ApiResponse>('ai/providers/configured', {
|
||||
@@ -76,7 +76,7 @@ const AIFlowChart = () => {
|
||||
const mockApiResponse: ApiResponse = response as ApiResponse
|
||||
setModelData(mockApiResponse.data.providers)
|
||||
})
|
||||
}, [])
|
||||
}, [aiConfigFlushed])
|
||||
|
||||
useEffect(() => {
|
||||
if (!modelData.length) return
|
||||
@@ -104,8 +104,7 @@ const AIFlowChart = () => {
|
||||
status: model.status,
|
||||
defaultLlm: model.default_llm,
|
||||
logo: model.logo,
|
||||
id: model.id,
|
||||
openModal: openConfigModal
|
||||
id: model.id
|
||||
}
|
||||
})),
|
||||
...modelData.map((model) => ({
|
||||
@@ -220,7 +219,7 @@ const AIFlowChart = () => {
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="w-full h-full" style={{ height: 'calc(100vh - 64px)' }}>
|
||||
<div className="w-full" style={{ height: 'calc(-300px + 100vh)' }}>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Icon, { LoadingOutlined } from '@ant-design/icons'
|
||||
import WithPermission from '@common/components/aoplatform/WithPermission'
|
||||
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const'
|
||||
import { useGlobalContext } from '@common/contexts/GlobalStateContext'
|
||||
import { useFetch } from '@common/hooks/http'
|
||||
import { $t } from '@common/locales'
|
||||
import { App, Button, Card, Empty, Spin, Tag } from 'antd'
|
||||
@@ -8,70 +9,62 @@ import { memo, useEffect, useState } from 'react'
|
||||
import { useAiSetting } from './contexts/AiSettingContext'
|
||||
import { AiSettingListItem } from './types'
|
||||
|
||||
const CardBox = memo(
|
||||
({
|
||||
provider,
|
||||
openModal
|
||||
}: {
|
||||
provider: AiSettingListItem
|
||||
openModal: (provider: AiSettingListItem) => Promise<void>
|
||||
}) => {
|
||||
return (
|
||||
<Card
|
||||
title={
|
||||
<div className="flex w-full items-center justify-between gap-[4px]">
|
||||
<div className="flex flex-1 overflow-hidden items-center gap-[4px]">
|
||||
<span
|
||||
className=" flex items-center h-[22px] ai-setting-svg-container"
|
||||
dangerouslySetInnerHTML={{ __html: provider.logo }}
|
||||
></span>
|
||||
<span className="font-normal truncate">{provider.name}</span>
|
||||
</div>
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={provider.configured ? 'green' : undefined}
|
||||
className="h-[22px] px-[4px] text-center"
|
||||
>
|
||||
{provider.configured ? $t('已配置') : $t('未配置')}
|
||||
</Tag>
|
||||
</div>
|
||||
}
|
||||
className="shadow-[0_5px_10px_0_rgba(0,0,0,0.05)] rounded-[10px] overflow-visible h-[156px] m-0 flex flex-col "
|
||||
classNames={{ header: 'border-b-[0px] p-[20px] px-[24px]', body: 'pt-0 flex-1' }}
|
||||
>
|
||||
<div className="flex flex-col justify-between h-full gap-btnbase">
|
||||
<div className="flex items-center w-full h-[32px] flex-1">
|
||||
{provider.configured && (
|
||||
<>
|
||||
<label className="text-nowrap">{$t('默认')}:</label>
|
||||
<span className="overflow-hidden flex-1 truncate">{provider.defaultLlm}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<WithPermission access="system.settings.ai_provider.view">
|
||||
<Button
|
||||
block
|
||||
icon={<Icon icon="ic:outline-settings" width={18} height={18} />}
|
||||
onClick={() => openModal(provider)}
|
||||
classNames={{ icon: 'h-[18px]' }}
|
||||
>
|
||||
{$t('设置')}
|
||||
</Button>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
const CardBox = memo(({ provider }: { provider: AiSettingListItem }) => {
|
||||
const { openConfigModal } = useAiSetting()
|
||||
const { aiConfigFlushed, setAiConfigFlushed } = useGlobalContext()
|
||||
|
||||
const handleOpenModal = async (provider: AiSettingListItem) => {
|
||||
await openConfigModal(provider)
|
||||
setAiConfigFlushed(!aiConfigFlushed)
|
||||
}
|
||||
)
|
||||
const ModelCardArea = ({
|
||||
modelList,
|
||||
className,
|
||||
openModal
|
||||
}: {
|
||||
modelList: AiSettingListItem[]
|
||||
className?: string
|
||||
openModal?: (provider: AiSettingListItem) => Promise<void>
|
||||
}) => {
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={
|
||||
<div className="flex w-full items-center justify-between gap-[4px]">
|
||||
<div className="flex flex-1 overflow-hidden items-center gap-[4px]">
|
||||
<span
|
||||
className=" flex items-center h-[22px] ai-setting-svg-container"
|
||||
dangerouslySetInnerHTML={{ __html: provider.logo }}
|
||||
></span>
|
||||
<span className="font-normal truncate">{provider.name}</span>
|
||||
</div>
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={provider.configured ? 'green' : undefined}
|
||||
className="h-[22px] px-[4px] text-center"
|
||||
>
|
||||
{provider.configured ? $t('已配置') : $t('未配置')}
|
||||
</Tag>
|
||||
</div>
|
||||
}
|
||||
className="shadow-[0_5px_10px_0_rgba(0,0,0,0.05)] rounded-[10px] overflow-visible h-[156px] m-0 flex flex-col "
|
||||
classNames={{ header: 'border-b-[0px] p-[20px] px-[24px]', body: 'pt-0 flex-1' }}
|
||||
>
|
||||
<div className="flex flex-col justify-between h-full gap-btnbase">
|
||||
<div className="flex items-center w-full h-[32px] flex-1">
|
||||
{provider.configured && (
|
||||
<>
|
||||
<label className="text-nowrap">{$t('默认')}:</label>
|
||||
<span className="overflow-hidden flex-1 truncate">{provider.defaultLlm}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<WithPermission access="system.settings.ai_provider.view">
|
||||
<Button
|
||||
block
|
||||
icon={<Icon icon="ic:outline-settings" width={18} height={18} />}
|
||||
onClick={() => handleOpenModal(provider)}
|
||||
classNames={{ icon: 'h-[18px]' }}
|
||||
>
|
||||
{$t('设置')}
|
||||
</Button>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
})
|
||||
const ModelCardArea = ({ modelList, className }: { modelList: AiSettingListItem[]; className?: string }) => {
|
||||
return (
|
||||
<>
|
||||
{modelList.length > 0 ? (
|
||||
@@ -84,7 +77,7 @@ const ModelCardArea = ({
|
||||
}}
|
||||
>
|
||||
{modelList.map((provider: AiSettingListItem) => (
|
||||
<CardBox key={provider.id} provider={provider} openModal={openModal} />
|
||||
<CardBox key={provider.id} provider={provider} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
@@ -97,8 +90,8 @@ const ModelCardArea = ({
|
||||
const AIUnConfigure = () => {
|
||||
const [modelData, setModelData] = useState<AiSettingListItem[]>([])
|
||||
const { fetchData } = useFetch()
|
||||
const { openConfigModal } = useAiSetting()
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const { aiConfigFlushed } = useGlobalContext()
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
@@ -123,23 +116,20 @@ const AIUnConfigure = () => {
|
||||
}
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}, [])
|
||||
}, [aiConfigFlushed])
|
||||
|
||||
return (
|
||||
<Spin
|
||||
className="h-full"
|
||||
wrapperClassName="h-full pr-PAGE_INSIDE_X"
|
||||
indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />}
|
||||
spinning={modelData.length === 0}
|
||||
spinning={loading}
|
||||
>
|
||||
{modelData && modelData.length > 0 ? (
|
||||
<div>
|
||||
{modelData.filter((item) => !item.configured).length > 0 && (
|
||||
<>
|
||||
<ModelCardArea
|
||||
openModal={openConfigModal}
|
||||
modelList={modelData.filter((item) => !item.configured) || []}
|
||||
/>
|
||||
<ModelCardArea modelList={modelData.filter((item) => !item.configured) || []} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -80,6 +80,7 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
eoParams: { provider: entity?.id },
|
||||
eoBody: finalValue,
|
||||
eoTransformKeys: ['defaultLlm']
|
||||
// eoApiPrefix: 'http://uat.apikit.com:11204/mockApi/aoplatform/api/v1/'
|
||||
})
|
||||
.then((response) => {
|
||||
const { code, msg } = response
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { useGlobalContext } from '@common/contexts/GlobalStateContext'
|
||||
import { Icon } from '@iconify/react'
|
||||
import { Handle, Position } from '@xyflow/react'
|
||||
import { t } from 'i18next'
|
||||
import React from 'react'
|
||||
import { useAiSetting } from '../contexts/AiSettingContext'
|
||||
import { AiSettingListItem, ModelStatus } from '../types'
|
||||
|
||||
interface ModelCardData {
|
||||
@@ -14,11 +16,12 @@ interface ModelCardData {
|
||||
type ModelCardNodeData = ModelCardData & {
|
||||
id: string
|
||||
position: { x: number; y: number }
|
||||
openModal?: (entity: AiSettingListItem) => Promise<void>
|
||||
}
|
||||
|
||||
export const ModelCardNode: React.FC<{ data: ModelCardNodeData }> = ({ data }) => {
|
||||
const { title, status, defaultLlm, logo } = data
|
||||
const { openConfigModal } = useAiSetting()
|
||||
const { aiConfigFlushed, setAiConfigFlushed } = useGlobalContext()
|
||||
return (
|
||||
<div
|
||||
className="node-card bg-white rounded-lg shadow-sm p-4 min-w-[280px] group"
|
||||
@@ -47,7 +50,10 @@ export const ModelCardNode: React.FC<{ data: ModelCardNodeData }> = ({ data }) =
|
||||
<Icon
|
||||
icon="mdi:cog"
|
||||
className="text-xl text-gray-400 cursor-pointer hover:text-[--primary-color]"
|
||||
onClick={() => data.openModal?.({ id: data.id, defaultLlm: defaultLlm })}
|
||||
onClick={() => {
|
||||
openConfigModal({ id: data.id, defaultLlm: defaultLlm } as AiSettingListItem)
|
||||
setAiConfigFlushed(!aiConfigFlushed)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user