diff --git a/frontend/src/pages/Deploy/Environment/List/index.tsx b/frontend/src/pages/Deploy/Environment/List/index.tsx index a654c04e..993a7b89 100644 --- a/frontend/src/pages/Deploy/Environment/List/index.tsx +++ b/frontend/src/pages/Deploy/Environment/List/index.tsx @@ -1,274 +1,253 @@ -import React, { useState, useEffect } from 'react'; -import { PageContainer } from '@ant-design/pro-layout'; -import { Card, Row, Col, Typography, Button, message, Empty, Tooltip, Tag } from 'antd'; -import { PlusOutlined, RocketOutlined, CloudServerOutlined, SettingOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons'; -import { getEnvironmentList, deleteEnvironment } from './service'; -import type { Environment } from './types'; -import { BuildTypeEnum, DeployTypeEnum } from './types'; +import React, {useState, useEffect} from 'react'; +import {PageContainer} from '@ant-design/pro-layout'; +import {Card, Row, Col, Typography, Button, message, Empty, Tooltip, Tag} from 'antd'; +import {PlusOutlined, RocketOutlined, CloudServerOutlined, SettingOutlined, DeleteOutlined, EditOutlined} from '@ant-design/icons'; +import {getEnvironmentList, deleteEnvironment} from './service'; +import type {Environment} from './types'; +import {BuildTypeEnum, DeployTypeEnum} from './types'; import EnvironmentModal from './components/EnvironmentModal'; -const { Title, Text } = Typography; +const {Title, Text} = Typography; // 构建方式和部署方式的显示映射 const buildTypeMap = { - [BuildTypeEnum.JENKINS]: { - label: 'Jenkins构建', - color: '#1890ff', - icon: , - description: '使用Jenkins进行自动化构建和部署' - }, - [BuildTypeEnum.GITLAB_RUNNER]: { - label: 'GitLab Runner构建', - color: '#722ed1', - icon: , - description: '使用GitLab Runner进行CI/CD流程' - }, - [BuildTypeEnum.GITHUB_ACTION]: { - label: 'GitHub Action构建', - color: '#52c41a', - icon: , - description: '使用GitHub Action进行自动化工作流' - }, + [BuildTypeEnum.JENKINS]: { + label: 'Jenkins构建', + color: '#1890ff', + icon: , + description: '使用Jenkins进行自动化构建和部署' + }, + [BuildTypeEnum.GITLAB_RUNNER]: { + label: 'GitLab Runner构建', + color: '#722ed1', + icon: , + description: '使用GitLab Runner进行CI/CD流程' + }, + [BuildTypeEnum.GITHUB_ACTION]: { + label: 'GitHub Action构建', + color: '#52c41a', + icon: , + description: '使用GitHub Action进行自动化工作流' + }, }; const deployTypeMap = { - [DeployTypeEnum.K8S]: { - label: 'Kubernetes集群部署', - color: '#1890ff', - icon: , - description: '部署到Kubernetes容器编排平台' - }, - [DeployTypeEnum.DOCKER]: { - label: 'Docker容器部署', - color: '#13c2c2', - icon: , - description: '部署为Docker独立容器' - }, - [DeployTypeEnum.VM]: { - label: '虚拟机部署', - color: '#faad14', - icon: , - description: '部署到传统虚拟机环境' - }, + [DeployTypeEnum.K8S]: { + label: 'Kubernetes集群部署', + color: '#1890ff', + icon: , + description: '部署到Kubernetes容器编排平台' + }, + [DeployTypeEnum.DOCKER]: { + label: 'Docker容器部署', + color: '#13c2c2', + icon: , + description: '部署为Docker独立容器' + }, + [DeployTypeEnum.VM]: { + label: '虚拟机部署', + color: '#faad14', + icon: , + description: '部署到传统虚拟机环境' + }, }; const EnvironmentList: React.FC = () => { - const [environments, setEnvironments] = useState([]); - const [loading, setLoading] = useState(false); - const [modalVisible, setModalVisible] = useState(false); - const [currentEnvironment, setCurrentEnvironment] = useState(); + const [environments, setEnvironments] = useState([]); + const [loading, setLoading] = useState(false); + const [modalVisible, setModalVisible] = useState(false); + const [currentEnvironment, setCurrentEnvironment] = useState(); - const fetchEnvironments = async () => { - setLoading(true); - try { - const data = await getEnvironmentList(); - setEnvironments(data); - } catch (error) { - message.error('获取环境列表失败'); - } finally { - setLoading(false); - } - }; + const fetchEnvironments = async () => { + setLoading(true); + try { + const data = await getEnvironmentList(); + setEnvironments(data); + } catch (error) { + message.error('获取环境列表失败'); + } finally { + setLoading(false); + } + }; - useEffect(() => { - fetchEnvironments(); - }, []); + useEffect(() => { + fetchEnvironments(); + }, []); - const handleDelete = async (id: number) => { - try { - await deleteEnvironment(id); - message.success('删除成功'); - fetchEnvironments(); - } catch (error) { - message.error('删除失败'); - } - }; + const handleDelete = async (id: number) => { + try { + await deleteEnvironment(id); + message.success('删除成功'); + fetchEnvironments(); + } catch (error) { + message.error('删除失败'); + } + }; - const handleAdd = () => { - setCurrentEnvironment(undefined); - setModalVisible(true); - }; + const handleAdd = () => { + setCurrentEnvironment(undefined); + setModalVisible(true); + }; - const handleEdit = (environment: Environment) => { - setCurrentEnvironment(environment); - setModalVisible(true); - }; + const handleEdit = (environment: Environment) => { + setCurrentEnvironment(environment); + setModalVisible(true); + }; - const EnvironmentCard = ({ environment }: { environment: Environment }) => { - const buildType = buildTypeMap[environment.buildType]; - const deployType = deployTypeMap[environment.deployType]; + const EnvironmentCard = ({environment}: { environment: Environment }) => { + const buildType = buildTypeMap[environment.buildType]; + const deployType = deployTypeMap[environment.deployType]; + + return ( + + + , + + + + ]} + > +
+
+ + {environment.envName} + + + {buildType.icon} {buildType.label} + +
+ + + {environment.envDesc || '暂无描述'} + + +
+ 环境编码 +
+ {environment.envCode} +
+
+
+
+ ); + }; return ( - - - , - - - - ]} - > -
-
- - {environment.envName} - - - {buildType.icon} {buildType.label} - -
- - } + onClick={handleAdd} + style={{ + borderRadius: '8px', + padding: '0 24px', + height: '40px', + boxShadow: '0 2px 0 rgba(0,0,0,0.045)', + transition: 'all 0.3s ease', + }} + > + 新建环境 + + ], }} - > - {environment.envDesc || '暂无描述'} - - -
- 环境编码 -
- {environment.envCode} + > +
+ + {environments.length > 0 ? ( + environments.map((environment) => ( + + + + )) + ) : ( + + + + + + )} +
-
-
- - setModalVisible(false)} + onSuccess={() => { + setModalVisible(false); + fetchEnvironments(); }} - > - {deployType.icon} {deployType.label} - - - 排序: {environment.sort} -
-
- + initialValues={currentEnvironment} + /> + ); - }; - - return ( - } - onClick={handleAdd} - style={{ - borderRadius: '8px', - padding: '0 24px', - height: '40px', - boxShadow: '0 2px 0 rgba(0,0,0,0.045)', - transition: 'all 0.3s ease', - }} - > - 新建环境 - - ], - }} - > -
- - {environments.length > 0 ? ( - environments.map((environment) => ( - - - - )) - ) : ( - - - - - - )} - -
- - setModalVisible(false)} - onSuccess={() => { - setModalVisible(false); - fetchEnvironments(); - }} - initialValues={currentEnvironment} - /> -
- ); }; export default EnvironmentList; diff --git a/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx b/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx index 65bf8f70..d17d0dee 100644 --- a/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx +++ b/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx @@ -1,159 +1,149 @@ -import React, { useEffect, useState } from 'react'; -import { Modal, Form, Input, InputNumber, Radio, message, Select } from 'antd'; -import type { ProjectGroup } from '../types'; -import type { Environment } from '../../../Environment/List/types'; -import { createProjectGroup, updateProjectGroup } from '../service'; -import { getEnvironmentList } from '../../../Environment/List/service'; +import React, {useEffect, useState} from 'react'; +import {Modal, Form, Input, InputNumber, Radio, message, Select} from 'antd'; +import type {ProjectGroup} from '../types'; +import type {Environment} from '../../../Environment/List/types'; +import {createProjectGroup, updateProjectGroup} from '../service'; +import {getEnvironmentList} from '../../../Environment/List/service'; interface ProjectGroupModalProps { - visible: boolean; - onCancel: () => void; - onSuccess: () => void; - initialValues?: ProjectGroup; + visible: boolean; + onCancel: () => void; + onSuccess: () => void; + initialValues?: ProjectGroup; } const ProjectGroupModal: React.FC = ({ - visible, - onCancel, - onSuccess, - initialValues, -}) => { - const [form] = Form.useForm(); - const [environments, setEnvironments] = useState([]); - const isEdit = !!initialValues; + visible, + onCancel, + onSuccess, + initialValues, + }) => { + const [form] = Form.useForm(); + const [environments, setEnvironments] = useState([]); + const isEdit = !!initialValues; - // 获取环境列表 - useEffect(() => { - const fetchEnvironments = async () => { - try { - const data = await getEnvironmentList(); - setEnvironments(data); - } catch (error) { - message.error('获取环境列表失败'); - } + // 获取环境列表 + useEffect(() => { + const fetchEnvironments = async () => { + try { + const data = await getEnvironmentList(); + setEnvironments(data); + } catch (error) { + message.error('获取环境列表失败'); + } + }; + fetchEnvironments(); + }, []); + + useEffect(() => { + if (visible && initialValues) { + // 设置初始值,包括环境ID列表 + const envIds = initialValues.environments?.map(env => env.id) || []; + form.setFieldsValue({ + ...initialValues, + environments: envIds + }); + } + }, [visible, initialValues, form]); + + const handleSubmit = async () => { + try { + const values = await form.validateFields(); + // 转换环境ID数组为对象数组 + const environments = (values.environments || []).map((id: number) => ({id})); + const submitData = { + ...values, + environments + }; + + if (isEdit) { + await updateProjectGroup({...submitData, id: initialValues.id}); + message.success('更新成功'); + } else { + await createProjectGroup(submitData); + message.success('创建成功'); + } + onSuccess(); + onCancel(); + form.resetFields(); + } catch (error) { + message.error(isEdit ? '更新失败' : '创建失败'); + } }; - fetchEnvironments(); - }, []); - useEffect(() => { - if (visible && initialValues) { - // 设置初始值,包括环境ID列表 - const envIds = initialValues.environments?.map(env => env.id) || []; - form.setFieldsValue({ - ...initialValues, - environments: envIds - }); - } - }, [visible, initialValues, form]); + const handleCancel = () => { + form.resetFields(); + onCancel(); + }; - const handleSubmit = async () => { - try { - const values = await form.validateFields(); - // 转换环境ID数组为对象数组 - const environments = (values.environments || []).map((id: number) => ({ id })); - const submitData = { - ...values, - environments - }; - - if (isEdit) { - await updateProjectGroup({ ...submitData, id: initialValues.id }); - message.success('更新成功'); - } else { - await createProjectGroup(submitData); - message.success('创建成功'); - } - onSuccess(); - onCancel(); - form.resetFields(); - } catch (error) { - message.error(isEdit ? '更新失败' : '创建失败'); - } - }; - - const handleCancel = () => { - form.resetFields(); - onCancel(); - }; - - return ( - -
- - - + + + + - - - + + + - - - - - - - 启用 - 禁用 - - - - - ({ + label: env.envName, + value: env.id, + }))} + /> + + + + 启用 + 禁用 + + +
+
+ ); }; export default ProjectGroupModal; \ No newline at end of file diff --git a/frontend/src/pages/Deploy/ProjectGroup/List/index.less b/frontend/src/pages/Deploy/ProjectGroup/List/index.less deleted file mode 100644 index 31030915..00000000 --- a/frontend/src/pages/Deploy/ProjectGroup/List/index.less +++ /dev/null @@ -1,188 +0,0 @@ -.project-card { - &:hover { - transform: translateY(-4px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); - } - - .ant-card-body { - padding: 0; - } - - .project-content { - padding: 20px; - } - - // 项目组头部 - .project-header { - display: flex; - align-items: flex-start; - gap: 12px; - margin-bottom: 16px; - - .project-type { - margin: 0; - padding: 6px; - border-radius: 6px; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - } - - .title-section { - flex: 1; - min-width: 0; - - .project-name { - margin: 0; - font-size: 16px; - line-height: 1.4; - color: #1f1f1f; - } - - .project-code { - margin-top: 4px; - font-size: 13px; - color: #666; - font-family: 'monaco, monospace'; - } - } - } - - // 项目组描述 - .project-desc { - color: #666; - font-size: 13px; - line-height: 1.6; - margin-bottom: 16px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - - // 项目组统计 - .project-stats { - display: flex; - gap: 16px; - margin-bottom: 20px; - padding: 12px; - background: #fafafa; - border-radius: 6px; - - .stat-item { - display: flex; - align-items: center; - gap: 6px; - color: #666; - font-size: 13px; - - .anticon { - font-size: 14px; - color: #8c8c8c; - } - } - } - - // 环境列表 - .environments-section { - margin-bottom: 20px; - - .env-list { - display: flex; - flex-direction: column; - gap: 8px; - - .env-item { - padding: 12px; - background: #fafafa; - border-radius: 6px; - transition: all 0.3s ease; - - &:hover { - background: #f0f0f0; - } - - .env-main { - display: flex; - justify-content: space-between; - align-items: center; - gap: 12px; - - .env-info { - flex: 1; - min-width: 0; - - .env-name { - display: block; - font-size: 14px; - font-weight: 500; - color: #262626; - margin-bottom: 4px; - } - - .env-code { - display: block; - font-size: 12px; - color: #666; - font-family: 'monaco, monospace'; - } - } - - .env-tags { - display: flex; - gap: 4px; - flex-shrink: 0; - - .ant-tag { - margin: 0; - padding: 4px; - border: none; - border-radius: 4px; - display: flex; - align-items: center; - justify-content: center; - - .anticon { - font-size: 12px; - } - } - } - } - - .env-desc { - margin-top: 8px; - font-size: 12px; - color: #8c8c8c; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - } - } - - // 操作按钮 - .project-actions { - display: flex; - gap: 8px; - padding-top: 16px; - border-top: 1px dashed #f0f0f0; - - .ant-btn { - padding: 4px 12px; - height: 32px; - border-radius: 4px; - - &:hover { - transform: translateY(-1px); - background: #fafafa; - } - - &.ant-btn-dangerous:hover { - background: #fff1f0; - } - } - } -} \ No newline at end of file diff --git a/frontend/src/pages/Deploy/ProjectGroup/List/index.tsx b/frontend/src/pages/Deploy/ProjectGroup/List/index.tsx index 1b39acef..280773b5 100644 --- a/frontend/src/pages/Deploy/ProjectGroup/List/index.tsx +++ b/frontend/src/pages/Deploy/ProjectGroup/List/index.tsx @@ -1,342 +1,367 @@ -import React, { useState, useEffect } from 'react'; -import { PageContainer } from '@ant-design/pro-layout'; -import { Card, Row, Col, Typography, Button, message, Input, Select, Empty, Tooltip, Tag, Space } from 'antd'; -import { PlusOutlined, SearchOutlined, RocketOutlined, TeamOutlined, EnvironmentOutlined, EditOutlined, DeleteOutlined, ClockCircleOutlined, CloudServerOutlined, SettingOutlined } from '@ant-design/icons'; -import { getProjectGroupList, deleteProjectGroup } from './service'; -import type { ProjectGroup } from './types'; +import React, {useState, useEffect} from 'react'; +import {PageContainer} from '@ant-design/pro-layout'; +import {Card, Row, Col, Typography, Button, message, Popconfirm, Space, Tag, Input, Select, Tooltip, Statistic, Divider} from 'antd'; +import { + PlusOutlined, + EditOutlined, + DeleteOutlined, + TeamOutlined, + SearchOutlined, + EnvironmentOutlined, + RocketOutlined +} from '@ant-design/icons'; +import {getProjectGroupList, deleteProjectGroup} from './service'; +import type {ProjectGroup} from './types'; import ProjectGroupModal from './components/ProjectGroupModal'; -import { BuildTypeEnum, DeployTypeEnum } from '../../Environment/List/types'; -const { Title, Text } = Typography; -const { Search } = Input; +const {Title, Text} = Typography; +const {Search} = Input; const ProjectList: React.FC = () => { - const [projects, setProjects] = useState([]); - const [loading, setLoading] = useState(false); - const [modalVisible, setModalVisible] = useState(false); - const [currentProject, setCurrentProject] = useState(); - const [searchText, setSearchText] = useState(''); - const [projectType, setProjectType] = useState('ALL'); + const [projects, setProjects] = useState([]); + const [loading, setLoading] = useState(false); + const [modalVisible, setModalVisible] = useState(false); + const [currentProject, setCurrentProject] = useState(); + const [searchText, setSearchText] = useState(''); + const [projectType, setProjectType] = useState('ALL'); - const fetchProjects = async () => { - setLoading(true); - try { - const data = await getProjectGroupList(); - setProjects(data); - } catch (error) { - message.error('获取项目组列表失败'); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - fetchProjects(); - }, []); - - const handleDelete = async (id: number) => { - try { - await deleteProjectGroup(id); - message.success('删除成功'); - fetchProjects(); - } catch (error) { - message.error('删除失败'); - } - }; - - const handleAdd = () => { - setCurrentProject(undefined); - setModalVisible(true); - }; - - const handleEdit = (project: ProjectGroup) => { - setCurrentProject(project); - setModalVisible(true); - }; - - const getProjectTypeInfo = (code: string) => { - if (code.toUpperCase().includes('DEMO')) { - return { - type: 'DEMO', - label: '示例项目组', - color: '#1890ff', - icon: , - description: '用于演示和测试的项目组' - }; - } - if (code.toUpperCase().includes('PLATFORM')) { - return { - type: 'PLATFORM', - label: '平台项目组', - color: '#52c41a', - icon: , - description: '平台相关的核心项目组' - }; - } - return { - type: 'BUSINESS', - label: '业务项目组', - color: '#722ed1', - icon: , - description: '具体业务相关的项目组' + const fetchProjects = async () => { + setLoading(true); + try { + const data = await getProjectGroupList(); + setProjects(data); + } catch (error) { + message.error('获取项目组列表失败'); + } finally { + setLoading(false); + } }; - }; - const filteredProjects = projects.filter(project => { - const matchesSearch = searchText ? - project.projectGroupName.toLowerCase().includes(searchText.toLowerCase()) || - project.projectGroupCode.toLowerCase().includes(searchText.toLowerCase()) || - project.projectGroupDesc?.toLowerCase().includes(searchText.toLowerCase()) - : true; + useEffect(() => { + fetchProjects(); + }, []); - const matchesType = projectType === 'ALL' ? true : getProjectTypeInfo(project.projectGroupCode).type === projectType; + const handleDelete = async (id: number) => { + try { + await deleteProjectGroup(id); + message.success('删除成功'); + fetchProjects(); + } catch (error) { + message.error('删除失败'); + } + }; - return matchesSearch && matchesType; - }); + const handleAdd = () => { + setCurrentProject(undefined); + setModalVisible(true); + }; - const buildTypeMap = { - [BuildTypeEnum.JENKINS]: { - label: 'Jenkins构建', - color: '#1890ff', - icon: , - }, - [BuildTypeEnum.GITLAB_RUNNER]: { - label: 'GitLab Runner构建', - color: '#722ed1', - icon: , - }, - [BuildTypeEnum.GITHUB_ACTION]: { - label: 'GitHub Action构建', - color: '#52c41a', - icon: , - }, - }; + const handleEdit = (project: ProjectGroup) => { + setCurrentProject(project); + setModalVisible(true); + }; - const deployTypeMap = { - [DeployTypeEnum.K8S]: { - label: 'K8S', - color: '#1890ff', - icon: , - }, - [DeployTypeEnum.DOCKER]: { - label: 'Docker', - color: '#13c2c2', - icon: , - }, - [DeployTypeEnum.VM]: { - label: 'VM', - color: '#faad14', - icon: , - }, - }; + const getProjectTypeInfo = (code: string) => { + if (code.toUpperCase().includes('DEMO')) { + return { + type: 'DEMO', + label: '示例项目组', + color: '#1890ff', + icon: , + description: '用于演示和测试的项目组' + }; + } + if (code.toUpperCase().includes('PLATFORM')) { + return { + type: 'PLATFORM', + label: '平台项目组', + color: '#52c41a', + icon: , + description: '平台相关的核心项目组' + }; + } + return { + type: 'BUSINESS', + label: '业务项目组', + color: '#722ed1', + icon: , + description: '具体业务相关的项目组' + }; + }; - const ProjectCard = ({ project }: { project: ProjectGroup }) => { - const typeInfo = getProjectTypeInfo(project.projectGroupCode); + const filteredProjects = projects.filter(project => { + const matchesSearch = searchText ? ( + project.projectGroupName.toLowerCase().includes(searchText.toLowerCase()) || + project.projectGroupCode.toLowerCase().includes(searchText.toLowerCase()) || + project.projectGroupDesc?.toLowerCase().includes(searchText.toLowerCase()) + ) : true; + + const matchesType = projectType === 'ALL' ? true : + getProjectTypeInfo(project.projectGroupCode).type === projectType; + + return matchesSearch && matchesType; + }); + + const ProjectCard = ({project}: { project: ProjectGroup }) => { + const typeInfo = getProjectTypeInfo(project.projectGroupCode); + const Icon = typeInfo.icon; + + return ( + +
+
+
+ + {project.projectGroupName} + <Tag + color={typeInfo.color} + style={{ + margin: 0, + padding: '0 8px', + borderRadius: '4px', + fontSize: '12px' + }} + > + {typeInfo.label} + </Tag> + + + {project.projectGroupDesc || '暂无描述'} + +
+
+ {Icon} +
+
+ +
+
+ 项目组编码 +
+ {project.projectGroupCode} +
+
+ + + + 环境数量} + value={2} + prefix={} + valueStyle={{fontSize: '16px', color: typeInfo.color}} + /> + + + 项目个数} + value={5} + prefix={} + valueStyle={{fontSize: '16px', color: typeInfo.color}} + /> + + + 成员数量} + value={5} + prefix={} + valueStyle={{fontSize: '16px', color: typeInfo.color}} + /> + + + + + + + + handleDelete(project.id)} + > + + + + +
+
+
+ ); + }; return ( - -
- {/* 项目组标题和类型 */} -
- - {typeInfo.icon} - -
- - {project.projectGroupName} - -
- {project.projectGroupCode} -
-
-
- - {/* 项目组描述 */} -
- {project.projectGroupDesc || '暂无描述'} -
- - {/* 项目组统计信息 */} -
-
- - {project.environments?.length || 0} 个环境 -
-
- - 5 个成员 -
-
- - 2小时前更新 -
-
- - {/* 环境列表 */} - {project.environments && project.environments.length > 0 && ( -
-
- {project.environments.map(env => { - const buildType = buildTypeMap[env.buildType]; - const deployType = deployTypeMap[env.deployType]; - - return ( -
-
-
- {env.envName} - {env.envCode} -
-
- - {buildType.icon} - - - {deployType.icon} - -
-
- {env.envDesc && ( -
{env.envDesc}
- )} -
- ); - })} -
-
- )} - - {/* 操作按钮 */} -
- - - -
-
-
- ); - }; - - return ( - } - onClick={handleAdd} - style={{ - borderRadius: '8px', - padding: '0 24px', - height: '40px', - boxShadow: '0 2px 0 rgba(0,0,0,0.045)', - transition: 'all 0.3s ease', + } + onClick={handleAdd} + style={{ + borderRadius: '8px', + boxShadow: '0 2px 0 rgba(0,0,0,0.045)', + height: '40px', + padding: '0 24px', + }} + > + 新建项目组 + + ], }} - > - 新建项目组 - - ], - }} - > -
- - - 搜索} - size="large" - value={searchText} - onChange={e => setSearchText(e.target.value)} - style={{ width: '100%' }} - /> - - -