From dbbabdcca4cb479d684b34d369d383456e543a45 Mon Sep 17 00:00:00 2001 From: asp_ly Date: Thu, 26 Dec 2024 22:44:51 +0800 Subject: [PATCH] 1 --- .../List/components/DeploymentConfigModal.tsx | 66 ++++---- .../pages/Deploy/Deployment/List/index.tsx | 151 ++++++++---------- 2 files changed, 100 insertions(+), 117 deletions(-) diff --git a/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx b/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx index a147b7bf..65f67737 100644 --- a/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx +++ b/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx @@ -1,4 +1,4 @@ -import React, {useEffect, useState} from 'react'; +import React, {useEffect, useState, useCallback} from 'react'; import {Modal, Form, Select, message, Switch, InputNumber} from 'antd'; import type {DeploymentConfig, DeployConfigTemplate} from '../types'; import {createDeploymentConfig, updateDeploymentConfig, getDeployConfigTemplates} from '../service'; @@ -8,11 +8,12 @@ import {BetaSchemaForm} from '@ant-design/pro-form'; import {convertJsonSchemaToColumns} from '@/utils/jsonSchemaUtils'; import './styles.less'; import {Editor} from '@/components/Editor'; +import type {JsonNode} from '@/types/common'; const {Option} = Select; interface DeploymentConfigModalProps { - visible: boolean; + open: boolean; onCancel: () => void; onSuccess: () => void; initialValues?: DeploymentConfig; @@ -20,7 +21,7 @@ interface DeploymentConfigModalProps { } const DeploymentConfigModal: React.FC = ({ - visible, + open, onCancel, onSuccess, initialValues, @@ -31,39 +32,40 @@ const DeploymentConfigModal: React.FC = ({ const [templates, setTemplates] = useState([]); const [selectedTemplate, setSelectedTemplate] = useState(); const [buildVariables, setBuildVariables] = useState>({}); + const [loading, setLoading] = useState(false); const isEdit = !!initialValues?.id; // 获取应用列表 - const fetchApplications = async () => { + const fetchApplications = useCallback(async () => { try { const data = await getApplicationList(); setApplications(data); } catch (error) { message.error('获取应用列表失败'); } - }; + }, []); // 获取配置模板 - const fetchTemplates = async () => { + const fetchTemplates = useCallback(async () => { try { const data = await getDeployConfigTemplates(); setTemplates(data); } catch (error) { message.error('获取配置模板失败'); } - }; + }, []); // 在模态框显示时获取数据 useEffect(() => { - if (visible) { + if (open) { fetchApplications(); fetchTemplates(); } - }, [visible]); + }, [open, fetchApplications, fetchTemplates]); // 初始化表单数据 useEffect(() => { - if (!visible) return; + if (!open) return; if (initialValues) { form.setFieldsValue(initialValues); @@ -82,9 +84,9 @@ const DeploymentConfigModal: React.FC = ({ setSelectedTemplate(undefined); setBuildVariables({}); } - }, [visible, initialValues, envId, form, templates]); + }, [open, initialValues, envId, form, templates]); - const handleAppChange = (appId: number) => { + const handleAppChange = useCallback((appId: number) => { const app = applications.find(a => a.id === appId); if (app) { const template = templates.find(t => t.languageType === app.language); @@ -94,10 +96,11 @@ const DeploymentConfigModal: React.FC = ({ form.setFieldValue('templateCode', template.code); } } - }; + }, [applications, templates, form]); const handleSubmit = async () => { try { + setLoading(true); const values = await form.validateFields(); const submitData = { ...values, @@ -116,13 +119,19 @@ const DeploymentConfigModal: React.FC = ({ form.resetFields(); onSuccess(); } catch (error) { - message.error(`${isEdit ? '更新' : '创建'}失败`); + if (error instanceof Error) { + message.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); + } else { + message.error(`${isEdit ? '更新' : '创建'}失败`); + } + } finally { + setLoading(false); } }; // 渲染表单项 const renderFormItems = () => { - if (!selectedTemplate?.buildVariablesSchema) return null; + if (!selectedTemplate?.buildVariablesSchema?.properties) return null; const { properties } = selectedTemplate.buildVariablesSchema; @@ -142,10 +151,10 @@ const DeploymentConfigModal: React.FC = ({ defaultLanguage={property.editorConfig.language || 'shell'} theme={property.editorConfig.theme || 'vs-dark'} value={buildVariables[key] || property.default || ''} - onChange={(value) => setBuildVariables({ - ...buildVariables, + onChange={(value: string) => setBuildVariables(prev => ({ + ...prev, [key]: value || '' - })} + }))} options={{ minimap: { enabled: property.editorConfig.minimap ?? false }, fontSize: property.editorConfig.fontSize || 14, @@ -186,15 +195,15 @@ const DeploymentConfigModal: React.FC = ({ columns={convertJsonSchemaToColumns({ type: 'object', properties: Object.fromEntries( - Object.entries(properties).filter(([_, prop]) => !prop.editorConfig) + Object.entries(properties || {}).filter(([_, prop]) => !prop.editorConfig) ), required: selectedTemplate.buildVariablesSchema.required || [] })} initialValues={buildVariables} - onValuesChange={(_, values) => setBuildVariables({ - ...buildVariables, + onValuesChange={(_, values) => setBuildVariables(prev => ({ + ...prev, ...values - })} + }))} /> ); @@ -203,7 +212,7 @@ const DeploymentConfigModal: React.FC = ({ return ( { form.resetFields(); onCancel(); @@ -212,6 +221,8 @@ const DeploymentConfigModal: React.FC = ({ width={800} className="deployment-config-modal" maskClosable={false} + confirmLoading={loading} + destroyOnClose >
= ({ name="enabled" label="状态" valuePropName="checked" + tooltip="是否启用该配置" > @@ -258,15 +270,9 @@ const DeploymentConfigModal: React.FC = ({ - +
diff --git a/frontend/src/pages/Deploy/Deployment/List/index.tsx b/frontend/src/pages/Deploy/Deployment/List/index.tsx index 68480160..d7008be8 100644 --- a/frontend/src/pages/Deploy/Deployment/List/index.tsx +++ b/frontend/src/pages/Deploy/Deployment/List/index.tsx @@ -1,6 +1,6 @@ import React, {useState, useEffect} from 'react'; import {PageContainer} from '@ant-design/pro-layout'; -import {Button, message, Popconfirm, Select} from 'antd'; +import {Button, message, Popconfirm, Select, Space} from 'antd'; import {PlusOutlined, EditOutlined, DeleteOutlined} from '@ant-design/icons'; import {getDeploymentConfigPage, deleteDeploymentConfig} from './service'; import {getEnvironmentList} from '../../Environment/List/service'; @@ -65,12 +65,15 @@ const DeploymentConfigList: React.FC = () => { actionRef.current?.reload(); }; - const renderResourceInfo = (resources?: { cpu?: string; memory?: string }) => { - if (!resources?.cpu && !resources?.memory) return '-'; - const items = []; - if (resources.cpu) items.push(`CPU: ${resources.cpu}`); - if (resources.memory) items.push(`内存: ${resources.memory}`); - return items.join(' / '); + const handleModalClose = () => { + setModalVisible(false); + setCurrentConfig(undefined); + }; + + const handleSuccess = () => { + setModalVisible(false); + setCurrentConfig(undefined); + actionRef.current?.reload(); }; const columns: ProColumns[] = [ @@ -105,74 +108,49 @@ const DeploymentConfigList: React.FC = () => { }, ], }, - { - title: '部署配置', - children: [ - { - title: '副本数', - dataIndex: ['deployConfig', 'replicas'], - width: 100, - align: 'center', - }, - { - title: '容器端口', - dataIndex: ['deployConfig', 'containerPort'], - width: 100, - align: 'center', - }, - ], - }, { title: '状态', dataIndex: 'enabled', width: 100, - align: 'center', valueEnum: { true: {text: '启用', status: 'Success'}, false: {text: '禁用', status: 'Default'}, }, }, - { - title: '排序', - dataIndex: 'sort', - width: 80, - align: 'center', - sorter: true, - }, { title: '操作', width: 180, key: 'action', valueType: 'option', fixed: 'right', - align: 'center', - render: (_, record) => { - const buttons = [ + render: (_, record) => [ + , + handleDelete(record.id)} + > , - handleDelete(record.id)} - > - - - ]; - return
{buttons}
; - }, + + + 删除 + + +
+ ], }, ]; @@ -202,6 +180,31 @@ const DeploymentConfigList: React.FC = () => { actionRef={actionRef} scroll={{x: 'max-content'}} cardBordered + rowKey="id" + search={false} + options={{ + setting: false, + density: false, + fullScreen: false, + reload: false, + }} + toolbar={{ + actions: [ + + ], + }} + pagination={{ + pageSize: 10, + showQuickJumper: true, + }} request={async (params) => { if (!selectedEnvId) { return { @@ -223,39 +226,13 @@ const DeploymentConfigList: React.FC = () => { total: data.totalElements || 0, }; }} - rowKey="id" - search={false} - options={{ - setting: { - listsHeight: 400, - }, - }} - pagination={{ - pageSize: 10, - showQuickJumper: true, - }} - dateFormatter="string" - toolBarRender={() => [ - , - ]} /> - {selectedEnvId && ( + {modalVisible && selectedEnvId && ( setModalVisible(false)} - onSuccess={() => { - setModalVisible(false); - actionRef.current?.reload(); - }} + open={modalVisible} + onCancel={handleModalClose} + onSuccess={handleSuccess} initialValues={currentConfig} envId={selectedEnvId} />