DevOS v1 + Phase 2: unified resource model, infra ops, website deployment, AI chat ops
- Monorepo: NestJS API (Fastify) + React web (antd/ProComponents) + shared packages - PostgreSQL/Prisma (unified resources, relations graph, audit, events, jobs) - Auth/RBAC/workspace isolation, credential vault (AES-256-GCM) - Servers/SSH, Docker discovery & lifecycle, Job Center - Websites & deployments (git provider credential clone, env, health verification) - Domains/DNS (Cloudflare adapter), certificates (TLS probe), monitoring - Automation (cron/event/webhook HMAC + notifications), AI Gateway, MCP (29 tools) - AI chat window (LLM function-calling + rules fallback, SSE streaming, approvals) - Notes: Vditor WYSIWYG markdown editor, non-blocking autosave - Tests: 35 unit/security tests; UI audit clean (desktop+mobile, deep links)
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* # 容器列表页(全工作区)
|
||||
*/
|
||||
import { useRef } from "react";
|
||||
import {
|
||||
PageContainer,
|
||||
ProTable,
|
||||
type ActionType,
|
||||
type ProColumns,
|
||||
} from "@ant-design/pro-components";
|
||||
import { App as AntApp, Popconfirm } from "antd";
|
||||
import { ReloadOutlined } from "@ant-design/icons";
|
||||
import { containerApi } from "../services/api";
|
||||
import type { ContainerView } from "@devos/types";
|
||||
import { StatusBadge } from "../components/shared";
|
||||
|
||||
export default function ContainersPage() {
|
||||
const { message } = AntApp.useApp();
|
||||
const actionRef = useRef<ActionType>(null);
|
||||
|
||||
const columns: ProColumns<ContainerView>[] = [
|
||||
{ title: "名称", dataIndex: "name" },
|
||||
{ title: "镜像", dataIndex: "image", ellipsis: true },
|
||||
{ title: "状态", dataIndex: "state", render: (_, r) => <StatusBadge status={r.state} /> },
|
||||
{ title: "容器 ID", dataIndex: "containerId", copyable: true },
|
||||
{
|
||||
title: "操作",
|
||||
valueType: "option",
|
||||
render: (_, record) => [
|
||||
<Popconfirm
|
||||
key="restart"
|
||||
title={`重启容器 ${record.name}?(HIGH 风险操作)`}
|
||||
onConfirm={async () => {
|
||||
try {
|
||||
await containerApi.restart(record.id);
|
||||
message.success("容器已重启");
|
||||
actionRef.current?.reload();
|
||||
} catch (e) {
|
||||
message.error(e instanceof Error ? e.message : "失败");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<a style={{ color: "#fa8c16" }}>
|
||||
<ReloadOutlined /> 重启
|
||||
</a>
|
||||
</Popconfirm>,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<ProTable<ContainerView>
|
||||
scroll={{ x: "max-content" }}
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
actionRef={actionRef}
|
||||
headerTitle="容器"
|
||||
search={false}
|
||||
pagination={{ pageSize: 20 }}
|
||||
request={async () => {
|
||||
const items = await containerApi.list();
|
||||
return { data: items, success: true, total: items.length };
|
||||
}}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user