2026-07-10 14:31:56 +08:00

98 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useMemo, useState } from "react";
import { AdminFilterResetButton, AdminFilterSelect, AdminListToolbar, AdminSearchBox } from "@/shared/ui/AdminListLayout.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import { TimeText } from "@/shared/ui/TimeText.jsx";
import { OpsStatusBadge } from "./OpsStatusBadge.jsx";
export function AppsView({ apps }) {
const [keyword, setKeyword] = useState("");
const [status, setStatus] = useState("");
// 应用主数据总量很小(个位数),筛选全部在前端完成,不回源。
const items = useMemo(() => {
const normalizedKeyword = keyword.trim().toLowerCase();
return apps.filter((item) => {
const code = String(item.app_code ?? item.appCode ?? "").toLowerCase();
const name = String(item.app_name ?? item.appName ?? "").toLowerCase();
if (normalizedKeyword && !code.includes(normalizedKeyword) && !name.includes(normalizedKeyword)) {
return false;
}
if (status && String(item.status || "").toLowerCase() !== status) {
return false;
}
return true;
});
}, [apps, keyword, status]);
return (
<div className="ops-view">
<AdminListToolbar
filters={
<>
<AdminSearchBox label="应用" placeholder="应用编码 / 名称" value={keyword} onChange={setKeyword} />
<AdminFilterSelect
label="状态"
options={[
["", "全部状态"],
["active", "已启用"],
["disabled", "已停用"]
]}
value={status}
onChange={setStatus}
/>
<AdminFilterResetButton
disabled={!keyword && !status}
onClick={() => {
setKeyword("");
setStatus("");
}}
/>
</>
}
/>
<DataTable
columns={appColumns}
emptyLabel="暂无应用"
items={items}
minWidth="880px"
rowKey={(item) => item.app_code ?? item.appCode}
title="应用列表"
total={items.length}
/>
</div>
);
}
const appColumns = [
{ key: "app_code", label: "应用编码", render: (item) => item.app_code ?? item.appCode, width: "minmax(100px, 0.8fr)" },
{ key: "app_name", label: "应用名称", render: (item) => item.app_name ?? item.appName },
{ key: "platform", label: "平台", render: (item) => item.platform || "-", width: "minmax(80px, 0.6fr)" },
{ key: "package_name", label: "包名", render: (item) => item.package_name ?? item.packageName ?? "-", width: "minmax(180px, 1.4fr)" },
{
key: "status",
label: "状态",
render: (item) =>
String(item.status || "").toLowerCase() === "active" ? (
<OpsStatusBadge label="已启用" tone="succeeded" />
) : (
<OpsStatusBadge label={item.status || "-"} />
),
width: "minmax(112px, 0.6fr)"
},
{
key: "source",
label: "来源",
// fixed 来源是 admin-server 为外部幸运礼物接入硬编码补齐的白名单 Appyumi/aslan
// 不在 app registry 主数据里,运营需要知道它们没有包名/平台等完整信息。
render: (item) =>
item.source === "fixed" ? <OpsStatusBadge label="外部接入" tone="warning" /> : <OpsStatusBadge label="主数据" tone="succeeded" />,
width: "minmax(124px, 0.7fr)"
},
{
key: "updated_at_ms",
label: "更新时间",
render: (item) => (item.source === "fixed" ? "-" : <TimeText value={item.updated_at_ms ?? item.updatedAtMs} />),
width: "minmax(150px, 1fr)"
}
];