重构消息通知弹窗

This commit is contained in:
dengqichen 2025-11-28 09:26:33 +08:00
parent d14f80ce51
commit 730bb94926

View File

@ -179,7 +179,7 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
key={task.taskId}
className="group p-3 border border-border rounded-lg hover:bg-muted/50 transition-colors"
>
{/* 主要信息行 */}
{/* 第一行:应用信息 + 操作按钮 */}
<div className="flex items-center justify-between gap-3">
<div className="flex items-center gap-2 min-w-0 flex-1">
<span className="font-medium text-foreground truncate">
@ -191,6 +191,15 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
<Badge variant="secondary" className="shrink-0 text-xs">
{task.environmentName}
</Badge>
<Badge
variant="outline"
className="shrink-0 text-xs bg-blue-50 text-blue-700 border-blue-200"
>
{task.approvalMode === 'ANY' && '任一通过'}
{task.approvalMode === 'SINGLE' && '单人审批'}
{task.approvalMode === 'MULTI' && '会签'}
{task.approvalMode === 'OR' && '或签'}
</Badge>
</div>
{/* 操作按钮 */}
@ -223,28 +232,18 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
</div>
</div>
{/* 次要信息行 */}
<div className="mt-1.5 flex items-center justify-between text-xs text-muted-foreground">
<div className="flex items-center gap-3 min-w-0">
{(task.approvalTitle || task.approvalContent) && (
<span className="truncate">
{task.approvalTitle}{task.approvalTitle && task.approvalContent && ' - '}{task.approvalContent}
</span>
)}
{task.deployRemark && (
<span className="flex items-center gap-1 truncate">
{/* 第二行:任务名称 + 备注 */}
<div className="mt-1.5 flex items-center gap-2 text-xs text-muted-foreground">
<FileText className="h-3 w-3 shrink-0" />
{task.deployRemark}
<span className="truncate">
{task.taskName}
{task.deployRemark && ` · ${task.deployRemark}`}
</span>
)}
</div>
<div className="flex items-center gap-2 shrink-0">
{task.pendingDuration && (
<span className="flex items-center gap-1">
<Clock className="h-3 w-3" />
{formatDuration(task.pendingDuration)}
</span>
)}
{/* 第三行:元信息(左)+ 等待时长(右) */}
<div className="mt-1 flex items-center justify-between text-xs text-muted-foreground">
<div className="flex items-center gap-3">
<span className="flex items-center gap-1">
<User className="h-3 w-3" />
{task.deployBy}
@ -254,6 +253,10 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
{formatTime(task.deployStartTime)}
</span>
</div>
<span className="flex items-center gap-1 text-orange-600 shrink-0">
<Clock className="h-3 w-3" />
{formatDuration(task.pendingDuration || 0)}
</span>
</div>
</div>
))}
@ -265,87 +268,87 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
{/* 审批确认对话框 */}
<AlertDialog open={approvalDialogOpen} onOpenChange={setApprovalDialogOpen}>
<AlertDialogContent className="max-w-lg">
<AlertDialogHeader className="space-y-3">
<div className="flex items-center justify-center">
<AlertDialogContent className="max-w-md">
<AlertDialogHeader>
<div className="flex items-center justify-center mb-2">
<div className={
approvalResult === ApprovalResult.APPROVED
? "w-16 h-16 rounded-full bg-gradient-to-br from-green-500 to-green-600 flex items-center justify-center shadow-lg shadow-green-500/30"
: "w-16 h-16 rounded-full bg-gradient-to-br from-red-500 to-red-600 flex items-center justify-center shadow-lg shadow-red-500/30"
? "w-12 h-12 rounded-full bg-green-500 flex items-center justify-center"
: "w-12 h-12 rounded-full bg-red-500 flex items-center justify-center"
}>
{approvalResult === ApprovalResult.APPROVED ? (
<CheckCircle className="h-8 w-8 text-white" />
<CheckCircle className="h-6 w-6 text-white" />
) : (
<XCircle className="h-8 w-8 text-white" />
<XCircle className="h-6 w-6 text-white" />
)}
</div>
</div>
<AlertDialogTitle className="text-center text-xl font-bold">
<AlertDialogTitle className="text-center text-base font-medium">
{approvalResult === ApprovalResult.APPROVED ? '确认通过审批' : '确认拒绝审批'}
</AlertDialogTitle>
</AlertDialogHeader>
<div className="space-y-4 px-6 py-2">
{selectedTask && (
<>
<div className="text-center text-sm text-gray-600 px-4">
<p className="text-center text-sm text-muted-foreground">
<span className={
approvalResult === ApprovalResult.APPROVED
? "font-semibold text-green-600 mx-1"
: "font-semibold text-red-600 mx-1"
? "font-medium text-green-600 mx-1"
: "font-medium text-red-600 mx-1"
}>
{approvalResult === ApprovalResult.APPROVED ? '通过' : '拒绝'}
</span>
</div>
<div className="p-4 bg-gradient-to-br from-gray-50 to-gray-100/50 border border-gray-200 rounded-xl space-y-3 text-sm shadow-sm">
<div className="flex items-center gap-3">
<span className="text-gray-500 min-w-[64px] font-medium">ID</span>
<span className="font-mono font-bold text-orange-600">#{selectedTask.deployRecordId}</span>
</div>
<div className="h-px bg-gray-200" />
<div className="flex items-center gap-3">
<span className="text-gray-500 min-w-[64px] font-medium"></span>
<span className="font-semibold text-gray-900">{selectedTask.applicationName}</span>
</div>
<div className="flex items-center gap-3">
<span className="text-gray-500 min-w-[64px] font-medium"></span>
<span className="font-semibold text-gray-900">{selectedTask.environmentName}</span>
</div>
<div className="flex items-center gap-3">
<span className="text-gray-500 min-w-[64px] font-medium"></span>
</p>
</AlertDialogHeader>
{selectedTask && (
<div className="space-y-4">
{/* 部署信息 - 两行布局 */}
<div className="p-3 bg-muted/50 border border-border rounded-lg text-sm">
<div className="grid grid-cols-2 gap-x-6 gap-y-2">
{/* 第一行 */}
<div className="flex items-center gap-2">
<div className="w-6 h-6 rounded-full bg-blue-100 flex items-center justify-center">
<User className="h-3.5 w-3.5 text-blue-600" />
<span className="text-muted-foreground w-12">ID</span>
<span className="font-mono text-orange-600">#{selectedTask.deployRecordId}</span>
</div>
<span className="font-semibold text-gray-900">{selectedTask.deployBy}</span>
<div className="flex items-center gap-2">
<span className="text-muted-foreground w-12"></span>
<span className="font-medium">{selectedTask.applicationName}</span>
</div>
{/* 第二行 */}
<div className="flex items-center gap-2">
<span className="text-muted-foreground w-12"></span>
<span className="font-medium">{selectedTask.environmentName}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-muted-foreground w-12"></span>
<User className="h-3.5 w-3.5 text-muted-foreground" />
<span className="font-medium">{selectedTask.deployBy}</span>
</div>
</div>
</div>
<div className="space-y-2.5">
<label className="text-sm font-semibold text-gray-900 flex items-center gap-2">
<div className="w-1 h-4 bg-orange-500 rounded-full" />
{/* 审批意见 */}
<div className="space-y-2">
<label className="text-sm font-medium flex items-center gap-2">
{selectedTask.requireComment && (
<span className="text-xs px-2 py-0.5 bg-red-100 text-red-700 rounded-md font-medium"></span>
<Badge variant="destructive" className="text-xs h-5"></Badge>
)}
</label>
<Textarea
placeholder={selectedTask.requireComment ? "请填写审批意见..." : "请填写审批意见(可选)..."}
value={approvalComment}
onChange={(e) => setApprovalComment(e.target.value)}
rows={4}
className="resize-none border-gray-300 focus:border-orange-400 focus:ring-orange-400/20 rounded-lg"
rows={3}
className="resize-none"
/>
</div>
</>
)}
</div>
<AlertDialogFooter className="gap-3 sm:gap-3">
)}
<AlertDialogFooter className="gap-2 sm:gap-2">
<AlertDialogCancel
onClick={() => setApprovalDialogOpen(false)}
className="flex-1 h-11 border-2 border-gray-300 hover:bg-gray-50 font-semibold"
className="flex-1"
>
</AlertDialogCancel>
@ -354,8 +357,8 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
disabled={submitting}
className={
approvalResult === ApprovalResult.APPROVED
? "flex-1 h-11 bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 text-white shadow-lg shadow-green-500/30 font-semibold"
: "flex-1 h-11 bg-gradient-to-r from-red-500 to-red-600 hover:from-red-600 hover:to-red-700 text-white shadow-lg shadow-red-500/30 font-semibold"
? "flex-1 bg-green-600 hover:bg-green-700 text-white"
: "flex-1 bg-red-600 hover:bg-red-700 text-white"
}
>
{submitting ? (