重构消息通知弹窗

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