feat(k8s): 统一 YAML 查看编辑并补齐 Pod/导出能力
- 抽取 YamlCodeMirror/YamlEditorToolbar,修复弹窗滚动与固定高度布局 - 对齐集群导出精简规则(Service/Ingress/Workload/PVC 注解等) - Deployment/Pod/Service/Ingress 分资源配置:Pod 只读,支持单文件下载 - 修复 Deployment Pod YAML 弹窗未渲染,补全 PodsTab 与详情页 YAML 入口 - 命名空间列表页新增导出 YAML(tar.gz),与集群导出 API 一致
This commit is contained in:
1 parent
eeba677850
commit
fd7b04b9d6
15 files changed
+651
-150
No files matched your search
@@ -31,6 +31,8 @@ type ResourceType =
|
||||
|
||||
// 支持可视化编辑/新建的资源类型 // Logan.Li
|
||||
const VISUAL_RESOURCE_TYPES: ResourceType[] = ['services', 'ingresses', 'configmaps', 'secrets', 'pvcs'];
|
||||
/** 支持命名空间 YAML 批量导出(对齐集群导出)// Logan.Li */
|
||||
const EXPORT_YAML_TYPES: ResourceType[] = ['deployments', 'services', 'ingresses', 'configmaps', 'secrets'];
|
||||
|
||||
const VisualActions = ({ name, opts }: { name: string; opts: { onYaml?: (n: string) => void; onEdit?: (n: string) => void } }) => (
|
||||
<div className="flex items-center gap-0.5">
|
||||
@@ -71,10 +73,8 @@ const RESOURCE_CONFIG: Record<ResourceType, {
|
||||
</TableCell>
|
||||
<TableCell className="text-xs text-slate-500 max-w-[200px] truncate">{d.image || '-'}</TableCell>
|
||||
<TableCell onClick={(e) => e.stopPropagation()}>
|
||||
<div className="flex items-center gap-0.5">
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-slate-400 hover:text-blue-400" title="查看YAML"
|
||||
onClick={() => opts.onYaml?.(d.name)}><FileCode className="h-3.5 w-3.5" /></Button>
|
||||
</div>
|
||||
<Button variant="ghost" size="sm" className="h-7 px-2 text-xs text-blue-400 hover:text-blue-300 hover:bg-blue-500/10" title="查看 YAML"
|
||||
onClick={() => opts.onYaml?.(d.name)}><FileCode className="h-3.5 w-3.5 mr-1" />YAML</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
),
|
||||
@@ -318,7 +318,7 @@ export default function NamespaceResourcePage() {
|
||||
const { clusterCode, namespace } = useParams<{ clusterCode: string; namespace: string }>();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { toast: _toast } = useToast();
|
||||
const { toast } = useToast();
|
||||
const type = useMemo<ResourceType>(() => {
|
||||
const segments = location.pathname.split('/');
|
||||
const last = segments[segments.length - 1];
|
||||
@@ -417,6 +417,15 @@ export default function NamespaceResourcePage() {
|
||||
const handleCreate = () => setVisualItem({ resource: type, name: '', isCreate: true });
|
||||
const handleExportCSV = () => kubernetesApi.exportAsCSV(`${type}-${clusterCode}-${namespace}.csv`, filtered);
|
||||
const handleExportJSON = () => kubernetesApi.exportAsJSON(`${type}-${clusterCode}-${namespace}.json`, filtered);
|
||||
const handleExportYaml = async () => {
|
||||
if (!clusterCode || !namespace) return;
|
||||
try {
|
||||
await kubernetesApi.exportNamespaceResources(clusterCode, namespace);
|
||||
toast({ title: '导出完成', description: `${namespace} 资源 YAML 已开始下载` });
|
||||
} catch (e) {
|
||||
toast({ title: '导出失败', description: (e as Error)?.message || String(e), variant: 'destructive' });
|
||||
}
|
||||
};
|
||||
|
||||
if (!config) return <div className="text-slate-400 p-8 text-center">未知资源类型: {type}</div>;
|
||||
|
||||
@@ -430,7 +439,6 @@ export default function NamespaceResourcePage() {
|
||||
name={yamlItem.name}
|
||||
onClose={() => setYamlItem(null)}
|
||||
onSaved={loadData}
|
||||
cleanBeforeEdit={true}
|
||||
autoEdit={yamlItem.editMode === true}
|
||||
/>
|
||||
)}
|
||||
@@ -482,6 +490,11 @@ export default function NamespaceResourcePage() {
|
||||
<Button variant="outline" size="sm" className="h-9 border-slate-700 text-slate-400 text-xs" onClick={handleExportJSON} title="导出JSON">
|
||||
<Download className="h-3 w-3 mr-1" />JSON
|
||||
</Button>
|
||||
{EXPORT_YAML_TYPES.includes(type) && (
|
||||
<Button variant="outline" size="sm" className="h-9 border-slate-700 text-slate-400 text-xs" onClick={handleExportYaml} title="导出命名空间 YAML(tar.gz)">
|
||||
<Download className="h-3 w-3 mr-1" />导出YAML
|
||||
</Button>
|
||||
)}
|
||||
{VISUAL_RESOURCE_TYPES.includes(type) && (
|
||||
<>
|
||||
<Button variant="outline" size="sm" className="h-9 border-slate-700 text-slate-400 text-xs" onClick={() => setShowYamlImport(true)}>
|
||||
|
||||
Reference in new issue
Block a user