diff --git a/frontend/src/components/ui/select.tsx b/frontend/src/components/ui/select.tsx index b830cd52..bc4fe280 100644 --- a/frontend/src/components/ui/select.tsx +++ b/frontend/src/components/ui/select.tsx @@ -183,6 +183,40 @@ const SelectSeparator = React.forwardRef< )) SelectSeparator.displayName = SelectPrimitive.Separator.displayName +// ClearableSelect - 支持清空功能的Select包装组件 +interface ClearableSelectProps { + value?: string | number | null; + onValueChange?: (value: string | null) => void; + placeholder?: string; + disabled?: boolean; + children: React.ReactNode; + defaultValue?: string; + open?: boolean; + onOpenChange?: (open: boolean) => void; +} + +const ClearableSelect = React.forwardRef< + React.ElementRef, + ClearableSelectProps +>(({ value, onValueChange, children, ...props }, ref) => { + const hasValue = value !== undefined && value !== null && value !== ''; + const selectProps = hasValue ? { value: value.toString() } : {}; + + return ( + + ); +}); +ClearableSelect.displayName = "ClearableSelect"; + export { Select, SelectGroup, @@ -194,4 +228,5 @@ export { SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, + ClearableSelect, } diff --git a/frontend/src/pages/Dashboard/components/EnvironmentTabs.tsx b/frontend/src/pages/Dashboard/components/EnvironmentTabs.tsx index 1121189d..8ea716ea 100644 --- a/frontend/src/pages/Dashboard/components/EnvironmentTabs.tsx +++ b/frontend/src/pages/Dashboard/components/EnvironmentTabs.tsx @@ -104,7 +104,7 @@ export const EnvironmentTabs: React.FC = React.memo(({ ) : ( -
+
{env.applications.map((app) => ( ( {/* 卡片骨架 */}
-
- {[1, 2, 3, 4, 5, 6].map((i) => ( +
+ {[1, 2, 3, 4].map((i) => (
))}
diff --git a/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx b/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx index 9e9d6685..14bbf3ba 100644 --- a/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx +++ b/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx @@ -10,6 +10,7 @@ import { DialogHeader, DialogTitle, DialogFooter, + DialogBody, } from "@/components/ui/dialog"; import {Button} from "@/components/ui/button"; import { @@ -142,8 +143,8 @@ const ApplicationModal: React.FC = ({ {isEdit ? '编辑' : '新建'}应用
- -
+ +
= ({ />
-
- +
+ diff --git a/frontend/src/pages/Deploy/NotificationChannel/List/components/NotificationChannelDialog.tsx b/frontend/src/pages/Deploy/NotificationChannel/List/components/NotificationChannelDialog.tsx index 08918276..b3572d32 100644 --- a/frontend/src/pages/Deploy/NotificationChannel/List/components/NotificationChannelDialog.tsx +++ b/frontend/src/pages/Deploy/NotificationChannel/List/components/NotificationChannelDialog.tsx @@ -8,6 +8,7 @@ import { DialogHeader, DialogTitle, DialogBody, + DialogFooter, DialogLoading, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; @@ -266,7 +267,7 @@ const NotificationChannelDialog: React.FC = ({ return ( - + {mode === 'edit' ? '编辑' : '创建'}通知渠道 @@ -277,7 +278,7 @@ const NotificationChannelDialog: React.FC = ({ {loading ? ( ) : ( - + {/* 渠道名称 */}
- - {/* Submit buttons at the bottom of form */} -
- - -
)} + + {!loading && ( + + + + + )}
); diff --git a/frontend/src/pages/Deploy/Team/List/components/NotificationConfigDialog.tsx b/frontend/src/pages/Deploy/Team/List/components/NotificationConfigDialog.tsx index 28f9640d..8fb28db1 100644 --- a/frontend/src/pages/Deploy/Team/List/components/NotificationConfigDialog.tsx +++ b/frontend/src/pages/Deploy/Team/List/components/NotificationConfigDialog.tsx @@ -22,7 +22,7 @@ import { FormMessage, } from '@/components/ui/form'; import { - Select, + ClearableSelect, SelectContent, SelectItem, SelectTrigger, @@ -51,9 +51,12 @@ const formSchema = z }) .refine( (data) => { - // 如果启用了部署通知或构建通知,则通知渠道必填 + // 如果启用了任意通知类型,则通知渠道必填 if ( - (data.notificationConfig?.deployNotificationEnabled ||data.notificationConfig?.buildNotificationEnabled) && !data.notificationConfig?.notificationChannelId + (data.notificationConfig?.deployNotificationEnabled || + data.notificationConfig?.buildNotificationEnabled || + data.notificationConfig?.buildFailureFileEnabled) && + !data.notificationConfig?.notificationChannelId ) { return false; } @@ -138,6 +141,7 @@ export const NotificationConfigDialog: React.FC< notificationChannelId: undefined, deployNotificationEnabled: false, buildNotificationEnabled: false, + buildFailureFileEnabled: false, }, }); } @@ -171,6 +175,9 @@ export const NotificationConfigDialog: React.FC< }, [open, teamId, environmentId]); const handleSubmit = async (data: FormData) => { + console.log('表单提交数据:', data); + console.log('当前配置:', currentConfig); + if (!configId || !currentConfig) { toast({ title: '错误', @@ -182,34 +189,31 @@ export const NotificationConfigDialog: React.FC< setSubmitting(true); try { - // 提交完整的环境配置,只更新通知部分 - const payload: any = { + // 构建通知配置对象 + let notificationConfig = undefined; + if (data.notificationConfig?.notificationChannelId) { + notificationConfig = { + id: data.notificationConfig.id, + notificationChannelId: data.notificationConfig.notificationChannelId, + deployNotificationEnabled: data.notificationConfig.deployNotificationEnabled ?? false, + buildNotificationEnabled: data.notificationConfig.buildNotificationEnabled ?? false, + buildFailureFileEnabled: data.notificationConfig.buildFailureFileEnabled ?? false, + }; + } + + // 构建完整的提交数据(保留原有配置,只更新通知部分) + const payload = { teamId: currentConfig.teamId, environmentId: currentConfig.environmentId, approvalRequired: currentConfig.approvalRequired, approverUserIds: currentConfig.approverUserIds || [], requireCodeReview: currentConfig.requireCodeReview, remark: currentConfig.remark, - // 更新通知配置 - notificationConfig: - data.notificationConfig && - (data.notificationConfig.deployNotificationEnabled || - data.notificationConfig.buildNotificationEnabled || - data.notificationConfig.buildFailureFileEnabled) - ? { - id: data.notificationConfig.id, - notificationChannelId: - data.notificationConfig.notificationChannelId, - deployNotificationEnabled: - data.notificationConfig.deployNotificationEnabled, - buildNotificationEnabled: - data.notificationConfig.buildNotificationEnabled, - buildFailureFileEnabled: - data.notificationConfig.buildFailureFileEnabled, - } - : undefined, + notificationConfig, }; + console.log('最终提交的 payload:', payload); + await updateTeamEnvironmentConfig(configId, payload); toast({ @@ -257,10 +261,10 @@ export const NotificationConfigDialog: React.FC< render={({ field }) => ( 通知渠道 - +
选择通知渠道后,启用下方的通知类型 @@ -342,7 +348,7 @@ export const NotificationConfigDialog: React.FC< )} /> - {/* 构建通知 */} + {/* 失败日志 */} = ({ visible, onClose, onSuccess, reco {isEdit ? '编辑流程' : '新建流程'} -
+ {/* 流程分类 */}
-
+