diff --git a/frontend/src/pages/Deploy/Team/List/components/ActionButtonsCell.tsx b/frontend/src/pages/Deploy/Team/List/components/ActionButtonsCell.tsx new file mode 100644 index 00000000..8a26a60c --- /dev/null +++ b/frontend/src/pages/Deploy/Team/List/components/ActionButtonsCell.tsx @@ -0,0 +1,159 @@ +import React, { useState } from 'react'; +import { Button } from '@/components/ui/button'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip'; +import { + Settings, + Bell, + Package, + MoreHorizontal, + Edit, + Trash2 +} from 'lucide-react'; + +interface ActionButtonsCellProps { + environmentId: number; + environmentName?: string; + onConfig: (environmentId: number) => void; + onNotification: (config: any) => void; + onAppManage: (environmentId: number) => void; + onDelete: (config: any) => void; + config: any; +} + +export const ActionButtonsCell: React.FC = ({ + environmentId, + environmentName, + onConfig, + onNotification, + onAppManage, + onDelete, + config +}) => { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + + const handleConfig = () => { + onConfig(environmentId); + }; + + const handleNotification = () => { + onNotification(config); + }; + + const handleAppManage = () => { + onAppManage(environmentId); + }; + + const handleDelete = () => { + onDelete(config); + }; + + return ( +
+ {/* 主要操作按钮 */} + + + + + + +
环境配置
+
+
+
+ + + + + + + +
通知设置
+
+
+
+ + + + + + + +
应用管理
+
+
+
+ + {/* 更多操作下拉菜单 */} + + + + + + + + + +
更多操作
+
+
+
+ + + + + 编辑配置 + + + + + + + 删除配置 + + +
+
+ ); +}; diff --git a/frontend/src/pages/Deploy/Team/List/components/ApplicationCountCell.tsx b/frontend/src/pages/Deploy/Team/List/components/ApplicationCountCell.tsx new file mode 100644 index 00000000..2564c0db --- /dev/null +++ b/frontend/src/pages/Deploy/Team/List/components/ApplicationCountCell.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { Badge } from '@/components/ui/badge'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip'; +import { Package, PackageOpen } from 'lucide-react'; + +interface ApplicationCountCellProps { + applicationCount?: number; +} + +export const ApplicationCountCell: React.FC = ({ + applicationCount = 0 +}) => { + const count = applicationCount || 0; + + const config = count === 0 + ? { + icon: , + label: '0个应用', + variant: 'secondary' as const, + description: '该环境尚未配置任何应用', + color: 'text-muted-foreground' + } + : count <= 5 + ? { + icon: , + label: `${count}个应用`, + variant: 'success' as const, + description: `已配置${count}个应用`, + color: 'text-green-600' + } + : { + icon: , + label: `${count}个应用`, + variant: 'default' as const, + description: `已配置${count}个应用,应用较多`, + color: 'text-blue-600' + }; + + return ( + + + +
+ {config.icon} + + {config.label} + +
+
+ +
+ {config.description} +
+
+
+
+ ); +}; diff --git a/frontend/src/pages/Deploy/Team/List/components/ApproversCell.tsx b/frontend/src/pages/Deploy/Team/List/components/ApproversCell.tsx new file mode 100644 index 00000000..82951045 --- /dev/null +++ b/frontend/src/pages/Deploy/Team/List/components/ApproversCell.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { Badge } from '@/components/ui/badge'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip'; +import { Users, CheckCircle } from 'lucide-react'; + +interface User { + id: number; + realName?: string; + username?: string; +} + +interface ApproversCellProps { + approvalRequired?: boolean; + approverUserIds?: number[]; + users?: User[]; +} + +export const ApproversCell: React.FC = ({ + approvalRequired, + approverUserIds, + users = [] +}) => { + // 不需要审批 + if (!approvalRequired) { + return ( +
+ + 无需审批 +
+ ); + } + + // 需要审批但没有设置审批人 + if (!approverUserIds || approverUserIds.length === 0) { + return ( +
+ + 未设置审批人 +
+ ); + } + + // 获取有效的审批人 + const validApprovers = approverUserIds + .map(id => users.find(u => u.id === id)) + .filter(Boolean) as User[]; + + if (validApprovers.length === 0) { + return ( +
+ + 审批人无效 +
+ ); + } + + const displayApprovers = validApprovers.slice(0, 2); + const remainingCount = validApprovers.length - 2; + + return ( + + + +
+
+ {displayApprovers.map((user) => ( + + {user.realName || user.username} + + ))} + {remainingCount > 0 && ( + + +{remainingCount} + + )} +
+
+
+ {remainingCount > 0 && ( + +
+
全部审批人:
+
+ {validApprovers.map((user) => ( + + {user.realName || user.username} + + ))} +
+
+
+ )} +
+
+ ); +}; diff --git a/frontend/src/pages/Deploy/Team/List/components/CodeReviewCell.tsx b/frontend/src/pages/Deploy/Team/List/components/CodeReviewCell.tsx new file mode 100644 index 00000000..7f38ffa0 --- /dev/null +++ b/frontend/src/pages/Deploy/Team/List/components/CodeReviewCell.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Badge } from '@/components/ui/badge'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip'; +import { GitBranch, GitPullRequest, ShieldCheck } from 'lucide-react'; + +interface CodeReviewCellProps { + requireCodeReview?: boolean; +} + +export const CodeReviewCell: React.FC = ({ + requireCodeReview +}) => { + const config = requireCodeReview + ? { + icon: , + label: '需要', + variant: 'default' as const, + description: '部署前需要进行代码审查', + color: 'text-blue-600' + } + : { + icon: , + label: '不需要', + variant: 'secondary' as const, + description: '部署时不需要代码审查', + color: 'text-gray-500' + }; + + return ( + + + +
+ +
+ {config.icon} + {config.label} +
+
+
+
+ +
+ {config.description} +
+
+
+
+ ); +}; diff --git a/frontend/src/pages/Deploy/Team/List/components/NotificationChannelCell.tsx b/frontend/src/pages/Deploy/Team/List/components/NotificationChannelCell.tsx new file mode 100644 index 00000000..43bcde14 --- /dev/null +++ b/frontend/src/pages/Deploy/Team/List/components/NotificationChannelCell.tsx @@ -0,0 +1,151 @@ +import React from 'react'; +import { Badge } from '@/components/ui/badge'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip'; +import { + Bell, + MessageSquare, + Mail, + AlertTriangle, + CheckCircle, + XCircle +} from 'lucide-react'; +import type { NotificationConfig } from '../types'; + +interface NotificationChannelCellProps { + notificationConfig?: NotificationConfig | null; +} + +// 通知渠道类型映射 +const getChannelIcon = (channelType?: string) => { + switch (channelType) { + case 'WEWORK': + return ; + case 'EMAIL': + return ; + case 'DINGTALK': + return ; + default: + return ; + } +}; + +// 通知类型配置 +const notificationTypes = [ + { + key: 'deployNotificationEnabled', + label: '部署', + variant: 'success' as const, + description: '部署状态变更时发送通知' + }, + { + key: 'buildNotificationEnabled', + label: '构建', + variant: 'default' as const, + description: '构建状态变更时发送通知' + }, + { + key: 'buildFailureFileEnabled', + label: '失败文件', + variant: 'destructive' as const, + description: '构建失败文件时发送通知' + } +]; + +export const NotificationChannelCell: React.FC = ({ + notificationConfig +}) => { + // 未配置状态 + if (!notificationConfig) { + return ( +
+ + 未配置 +
+ ); + } + + const { + notificationChannelName, + deployNotificationEnabled, + buildNotificationEnabled, + buildFailureFileEnabled, + updateTime, + updateBy + } = notificationConfig; + + // 计算启用的通知类型 + const enabledNotifications = notificationTypes.filter(type => + notificationConfig[type.key as keyof NotificationConfig] + ); + + // 渠道名称显示 + const channelName = notificationChannelName || '未知渠道'; + + // 状态判断 + const hasEnabledNotifications = enabledNotifications.length > 0; + + return ( + + + +
+ {getChannelIcon(notificationConfig.channelType)} + + {channelName} + + {hasEnabledNotifications ? ( +
+ {enabledNotifications.map((notification) => ( +
+ ))} +
+ ) : ( + 未启用 + )} +
+ + + +
+ {/* 启用的通知类型 */} + {hasEnabledNotifications ? ( +
+
启用的通知类型:
+
+ {enabledNotifications.map((notification) => ( + + {notification.label} + + ))} +
+
+ ) : ( +
未启用任何通知
+ )} +
+
+ + + ); +}; diff --git a/frontend/src/pages/Deploy/Team/List/components/TeamEnvironmentManageDialog.tsx b/frontend/src/pages/Deploy/Team/List/components/TeamEnvironmentManageDialog.tsx index c87e9083..633d139d 100644 --- a/frontend/src/pages/Deploy/Team/List/components/TeamEnvironmentManageDialog.tsx +++ b/frontend/src/pages/Deploy/Team/List/components/TeamEnvironmentManageDialog.tsx @@ -27,6 +27,11 @@ import { getTeamEnvironmentConfigs, deleteTeamEnvironmentConfig } from '../servi import { TeamEnvironmentConfigDialog } from './TeamEnvironmentConfigDialog'; import { TeamApplicationManageDialog } from './TeamApplicationManageDialog'; import { NotificationConfigDialog } from './NotificationConfigDialog'; +import { NotificationChannelCell } from './NotificationChannelCell'; +import { ApproversCell } from './ApproversCell'; +import { CodeReviewCell } from './CodeReviewCell'; +import { ApplicationCountCell } from './ApplicationCountCell'; +import { ActionButtonsCell } from './ActionButtonsCell'; interface User { id: number; @@ -196,112 +201,42 @@ export const TeamEnvironmentManageDialog: React.FC< {config.environmentName} - {config.approvalRequired && config.approverUserIds && config.approverUserIds.length > 0 ? ( -
- {config.approverUserIds.map((userId) => { - const user = users.find(u => u.id === userId); - return user ? ( - - {user.realName || user.username} - - ) : null; - })} -
- ) : ( - - 无需审批 - - )} +
- {config.notificationConfig ? ( -
- {config.notificationConfig.deployNotificationEnabled && ( - - 部署通知 - - )} - {config.notificationConfig.buildNotificationEnabled && ( - - 构建通知 - - )} - {!config.notificationConfig.deployNotificationEnabled && - !config.notificationConfig.buildNotificationEnabled && ( - - 未启用 - - )} -
- ) : ( - - 未配置 - - )} +
- - {config.applicationCount || 0} 个应用 - + - - {config.requireCodeReview ? '需要' : '不需要'} - + {config.remark || '-'} - -
- - - - -
+ + ))} diff --git a/frontend/src/pages/Deploy/Team/List/types.ts b/frontend/src/pages/Deploy/Team/List/types.ts index f9d0587d..83c4bcb4 100644 --- a/frontend/src/pages/Deploy/Team/List/types.ts +++ b/frontend/src/pages/Deploy/Team/List/types.ts @@ -55,7 +55,11 @@ export interface NotificationConfig { notificationChannelId?: number; deployNotificationEnabled?: boolean; buildNotificationEnabled?: boolean; + buildFailureFileEnabled?: boolean; notificationChannelName?: string; // 关联数据 + channelType?: string; // 渠道类型:WEWORK, EMAIL, DINGTALK等 + updateTime?: string; // 更新时间 + updateBy?: string; // 更新人 } /**