style(ui): 「系统管理」视觉层按 06-工作台UI规范 重做(用户反馈毛坯房)
- 管理项 行 → 卡片网格(§4.5 .data-card:r12 / 16px 18px / 轻投影 / hover 上浮 2px + 蓝边 + 蓝影) - 弹窗 → §4.7(mask rgba(0,0,0,.35);面板 r14 / 22px 26px / 520px / 0 8px 30px / 进场动画) - 按钮 §4.1 .btn-sm 量级 + hover;计数右对齐 + tabular-nums(§5);字号阶梯 15/13/17 - 卡片补图标;prefers-reduced-motion 降级 - 色彩仍用 dsh 官方 token --dsw-*(嵌在 dsh 面板内须跟随主题,规范硬色值是给门户静态页的) - 版本 0.3.0 → 0.3.1,已铺发
This commit is contained in:
1 parent
281c0816fa
commit
4190848c4a
2 files changed
+41
-19
No files matched your search
@@ -338,7 +338,21 @@ window.__ModuleLoader__.load({
|
||||
".bp-row:hover{border-color:var(--dsw-alias-brand-primary, #2f6fed);box-shadow:0 4px 12px rgba(47,111,237,.15)}",
|
||||
".bp-btn{transition:border-color .18s cubic-bezier(.16,1,.3,1),color .18s cubic-bezier(.16,1,.3,1)}",
|
||||
".bp-btn:hover:not(:disabled){border-color:var(--dsw-alias-brand-primary, #2f6fed);color:var(--dsw-alias-brand-primary, #2f6fed)}",
|
||||
".bp-row input[type=checkbox]{cursor:pointer;margin:0}"
|
||||
".bp-row input[type=checkbox]{cursor:pointer;margin:0}",
|
||||
|
||||
// 2026-09-13 ·「系统管理」视觉层(对齐 06-工作台UI规范:§4.5 卡片 hover 上浮 / §4.7 弹窗 / §4.1 按钮)
|
||||
".pa-card{transition:border-color .15s cubic-bezier(.16,1,.3,1),box-shadow .15s cubic-bezier(.16,1,.3,1),transform .15s cubic-bezier(.16,1,.3,1)}",
|
||||
".pa-card:hover{border-color:var(--dsw-alias-brand-primary,#2f6fed);box-shadow:0 4px 12px rgba(47,111,237,.15);transform:translateY(-2px)}",
|
||||
".pa-card:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#2f6fed);outline-offset:2px}",
|
||||
".pa-card:hover .pa-go{color:var(--dsw-alias-brand-primary,#2f6fed);opacity:1}",
|
||||
".pa-go{opacity:.45;transition:color .15s,opacity .15s}",
|
||||
".pa-btn{transition:border-color .15s cubic-bezier(.16,1,.3,1),color .15s cubic-bezier(.16,1,.3,1),background .15s cubic-bezier(.16,1,.3,1)}",
|
||||
".pa-btn:hover:not(:disabled){border-color:var(--dsw-alias-brand-primary,#2f6fed);color:var(--dsw-alias-brand-primary,#2f6fed);background:rgba(47,111,237,.06)}",
|
||||
".pa-row{transition:background .15s}",
|
||||
".pa-row:hover{background:rgba(47,111,237,.06)}",
|
||||
".pa-modal{box-shadow:0 8px 30px rgba(0,0,0,.28);animation:paIn .18s cubic-bezier(.16,1,.3,1)}",
|
||||
"@keyframes paIn{from{opacity:0;transform:translateY(6px) scale(.985)}to{opacity:1;transform:none}}",
|
||||
"@media (prefers-reduced-motion: reduce){.pa-card,.pa-modal{animation:none;transition:none}.pa-card:hover{transform:none}}"
|
||||
].join("");
|
||||
document.head.appendChild(el);
|
||||
return function () { el.remove(); };
|
||||
@@ -1079,25 +1093,32 @@ window.__ModuleLoader__.load({
|
||||
|
||||
// ── 管理项清单:每项点开都是「弹窗内管理」(用户 2026-09-13 要求)
|
||||
var ITEMS = [
|
||||
{ id: "users", title: t("pa.usersTitle"), desc: t("pa.pending") + " " + nPending + " · " + t("pa.disabled") + " " + nDisabled, badge: userList.length },
|
||||
{ id: "plugins", title: t("pa.pool"), desc: t("pa.poolCount"), badge: pool.length },
|
||||
{ id: "runtime", title: t("pa.runtime"), desc: t("pa.items"), badge: rt.length },
|
||||
{ id: "storage", title: t("pa.storage"), desc: t("pa.storageUsers"), badge: stUsers.length },
|
||||
{ id: "instance", title: t("pa.inst"), desc: inst + (brk ? " · " + t("pa.breakerOpen") : ""), badge: s.status && s.status.instance ? s.status.instance.port : "—" },
|
||||
{ id: "users", icon: "👥", title: t("pa.usersTitle"), desc: t("pa.pending") + " " + nPending + " · " + t("pa.disabled") + " " + nDisabled, badge: userList.length },
|
||||
{ id: "plugins", icon: "🧩", title: t("pa.pool"), desc: t("pa.poolCount"), badge: pool.length },
|
||||
{ id: "runtime", icon: "📦", title: t("pa.runtime"), desc: t("pa.items"), badge: rt.length },
|
||||
{ id: "storage", icon: "💾", title: t("pa.storage"), desc: t("pa.storageUsers"), badge: stUsers.length },
|
||||
{ id: "instance", icon: "🖥️", title: t("pa.inst"), desc: inst + (brk ? " · " + t("pa.breakerOpen") : ""), badge: s.status && s.status.instance ? s.status.instance.port : "—" },
|
||||
];
|
||||
|
||||
function itemRow(it) {
|
||||
// 卡片(06-工作台UI规范 §4.5 .data-card:r12 / 16px 18px / shadow / hover 上浮 + 蓝边 + 蓝影)
|
||||
function itemCard(it) {
|
||||
return jsxRuntime.jsx("div", {
|
||||
key: it.id, role: "button", tabIndex: 0,
|
||||
key: it.id, role: "button", tabIndex: 0, className: "pa-card",
|
||||
onClick: function () { setNote(""); setModal(it.id); },
|
||||
onKeyDown: function (e) { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setModal(it.id); } },
|
||||
style: { display: "flex", alignItems: "center", gap: "10px", padding: "10px 12px", border: "1px solid " + T.border, borderRadius: "10px", background: T.field, cursor: "pointer" },
|
||||
style: {
|
||||
border: "1px solid " + T.border, borderRadius: "12px", background: T.field,
|
||||
padding: "16px 18px", cursor: "pointer", display: "flex", flexDirection: "column",
|
||||
gap: "6px", minHeight: "104px", boxShadow: "0 1px 3px rgba(0,0,0,.08)"
|
||||
},
|
||||
children: [
|
||||
jsxRuntime.jsx("div", { key: "t", style: { flex: "1 1 auto", minWidth: 0 }, children: [
|
||||
jsxRuntime.jsx("div", { key: "a", style: { fontSize: "14px", fontWeight: 500, color: T.text }, children: it.title }),
|
||||
jsxRuntime.jsx("div", { key: "b", style: { fontSize: "12px", color: T.dim, marginTop: "2px" }, children: it.desc }) ] }),
|
||||
jsxRuntime.jsx("div", { key: "n", style: { fontSize: "13px", color: T.sub, fontVariantNumeric: "tabular-nums" }, children: it.badge }),
|
||||
jsxRuntime.jsx("div", { key: "c", style: { color: T.dim, fontSize: "14px" }, children: "›" })
|
||||
jsxRuntime.jsx("div", { key: "top", style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
||||
jsxRuntime.jsx("span", { key: "i", style: { fontSize: "16px", lineHeight: 1 }, children: it.icon }),
|
||||
jsxRuntime.jsx("span", { key: "t", style: { fontSize: "15px", fontWeight: 500, color: T.text }, children: it.title }),
|
||||
jsxRuntime.jsx("span", { key: "g", className: "pa-go", style: { marginLeft: "auto", fontSize: "14px", color: T.dim }, children: "›" })
|
||||
] }),
|
||||
jsxRuntime.jsx("div", { key: "d", style: { fontSize: "13px", color: T.dim, lineHeight: 1.6 }, children: it.desc }),
|
||||
jsxRuntime.jsx("div", { key: "n", style: { marginTop: "auto", fontSize: "17px", fontWeight: 500, color: T.text, textAlign: "right", fontVariantNumeric: "tabular-nums" }, children: it.badge })
|
||||
]
|
||||
});
|
||||
}
|
||||
@@ -1159,17 +1180,18 @@ window.__ModuleLoader__.load({
|
||||
var rows = [
|
||||
jsxRuntime.jsx("div", { key: "hd", style: { fontSize: "15px", fontWeight: 500, color: T.text }, children: t("pa.label") }),
|
||||
jsxRuntime.jsx("div", { key: "sub", style: { fontSize: "12px", color: T.dim }, children: t("pa.readonlyHint") }),
|
||||
jsxRuntime.jsx("div", { key: "items", style: { display: "flex", flexDirection: "column", gap: "8px" }, children: ITEMS.map(itemRow) }),
|
||||
jsxRuntime.jsx("div", { key: "items", style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(158px, 1fr))", gap: "12px" }, children: ITEMS.map(itemCard) }),
|
||||
];
|
||||
if (modal) {
|
||||
var it = ITEMS.filter(function (x) { return x.id === modal; })[0] || { title: modal };
|
||||
rows.push(jsxRuntime.jsx("div", {
|
||||
key: "overlay",
|
||||
onClick: function () { setModal(null); },
|
||||
style: { position: "fixed", inset: 0, zIndex: 9999, background: "rgba(0,0,0,.4)", display: "flex", alignItems: "center", justifyContent: "center", padding: "24px" },
|
||||
children: jsxRuntime.jsx("div", {
|
||||
style: { position: "fixed", inset: 0, zIndex: 9999, background: "rgba(0,0,0,.35)", display: "flex", alignItems: "center", justifyContent: "center", padding: "24px" },
|
||||
className: "pa-modal",
|
||||
children: jsxRuntime.jsx("div", {
|
||||
onClick: function (e) { e.stopPropagation(); },
|
||||
style: { background: T.text === "" ? "#fff" : ("var(--dsw-alias-bg-layer-1, #ffffff)"), border: "1px solid " + T.border, borderRadius: "12px", width: "100%", maxWidth: "760px", maxHeight: "78vh", overflow: "auto", padding: "16px", boxShadow: "0 8px 32px rgba(0,0,0,.2)" },
|
||||
style: { background: T.text === "" ? "#fff" : ("var(--dsw-alias-bg-layer-1, #ffffff)"), border: "1px solid " + T.border, borderRadius: "14px", width: "520px", maxWidth: "92vw", maxHeight: "80vh", overflow: "auto", padding: "22px 26px" },
|
||||
children: [
|
||||
jsxRuntime.jsx("div", { key: "mh", style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "10px" }, children: [
|
||||
jsxRuntime.jsx("div", { key: "t", style: { fontSize: "15px", fontWeight: 500, color: T.text }, children: it.title }),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dsh-local/business-plugins",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"description": "功能管理(原「功能插件」)section for dsh web profile — v0.2.8(2026-09-13):**所有弹窗改页内弹窗** —— 弃用 window.confirm,改为 fixed 遮罩 + 居中面板 + 点遮罩/✕ 关闭(视觉与交互对齐 MCN 工作台 dsh-plugin-mcn 的 modalTitle/modalText/modalBtns 三段结构);**超限时弹窗内红底警告块**(标题 + 说明 + 内存数字),确认按钮转危险色,未点确认不发请求。v0.2.7(档案 75 维度 B 落地 · 2026-09-13):卡片新增「预估内存 ≈ N MiB」徽章(按实测成本分色:≥60 红 / ≥30 黄)、卡片加高(minHeight 112 + padding 14/16)便于四层信息排布;**列表上方新增「内存预估」状态条** —— 实心段=当前已启用插件预估占用、半透明段=本次勾选增量、超单实例上限(384 MiB)整条转红并给文字警告,确认弹窗也带上内存预估。口径 = 空载基线 285 MiB + 逐插件实测加载成本(隔离 cgroup 的 rss 增量),**是预估值不是实时读数**。候选池列表 + 搜索/状态徽章 + 批量启用/禁用 + 确认弹窗 + 重启后自动刷新。v0.2.4(档案 67):对齐 06-工作台UI规范 —— **信息层次反转**(主视觉改为插件用途说明,插件名/版本退为副行小字;中文说明由候选池入库时优先取官方目录)、字号阶梯 14/13/12、徽章与按钮改规范量级、空态改「标题 + 说明」、新增列表行 hover 反馈。v0.2.2:分区名由「功能插件」改为「功能管理」。v0.2.0:配色改用官方 --dsw-* design token(跟随 dsh 主题);文案走官方 locale(zh/en)。",
|
||||
"type": "module",
|
||||
"main": "lib/index.js",
|
||||
|
||||
Reference in new issue
Block a user