import { useEffect, useState } from 'react'; import { Info, Save, Loader2 } from 'lucide-react'; import { toast } from 'sonner'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { apiClient } from '@/lib/api'; interface Props { pipelineId: number; } export default function BasicInfoPanel({ pipelineId }: Props) { const queryClient = useQueryClient(); const { data: detail } = useQuery({ queryKey: ['pipeline', pipelineId], queryFn: () => apiClient.getPipeline(pipelineId), }); const p = detail?.pipeline; // 编辑权限:「管理」等级及以上才能保存 const canEdit = (detail?.accessLevel ?? 4) >= 3; const [form, setForm] = useState({ name: '', description: '', sourceRepo: '', sourceBranch: '', deployType: 'host', env: 'staging', notifyWebhookURL: '' }); useEffect(() => { if (p) { setForm({ name: p.name || '', description: p.description || '', sourceRepo: p.sourceRepo || '', sourceBranch: p.sourceBranch || 'main', deployType: p.deployType || 'host', env: p.env || 'staging', notifyWebhookURL: p.notifyWebhookURL || '', }); } }, [p?.id, p?.updatedAt]); const saveMutation = useMutation({ mutationFn: (body: any) => apiClient.updatePipeline(pipelineId, body), onSuccess: () => { toast.success('基本信息已保存'); queryClient.invalidateQueries({ queryKey: ['pipeline', pipelineId] }); queryClient.invalidateQueries({ queryKey: ['pipelines'] }); }, onError: (err: Error) => toast.error('保存失败', { description: err.message }), }); const set = (k: string, v: string) => setForm((f) => ({ ...f, [k]: v })); const inputStyle = { background: 'var(--panel-bg-secondary)', borderColor: 'var(--border-color-light)', color: 'var(--text-primary)' }; return (

基本信息

{p?.type === 'jenkins' && ( Jenkins 导入 )}
{p && 更新于 {new Date(p.updatedAt).toLocaleString('zh-CN', { hour12: false })}} {canEdit && ( )}
set('name', e.target.value)} className="w-full px-3 py-2 text-[13px] rounded-md border outline-none" style={inputStyle} />
set('sourceBranch', e.target.value)} className="w-full px-3 py-2 text-[13px] rounded-md border outline-none" style={inputStyle} />
set('description', e.target.value)} className="w-full px-3 py-2 text-[13px] rounded-md border outline-none" style={inputStyle} />
set('sourceRepo', e.target.value)} placeholder="https://gitee.com/org/repo.git" className="w-full px-3 py-2 text-[13px] rounded-md border outline-none font-mono" style={inputStyle} />

发布通知

流水线成功/失败后回调该 Webhook(也在「Webhook 配置」中统一管理)

set('notifyWebhookURL', e.target.value)} placeholder="https://open.feishu.cn/open-apis/bot/v2/hook/xxx" className="w-full px-3 py-2 text-[13px] rounded-md border outline-none font-mono" style={inputStyle} />
); }