feat(light-app): 应用管理页加类型分类筛选 + 修复深色顶栏标题高分屏内边距
- 应用管理工具栏新增「全部/新页跳转/iframe嵌套」分类切换,选中 iframe 嵌套时出现挂载菜单下拉,可按 mountLocation 进一步筛选(深色/浅蓝主题适配) - 深色顶栏 .header-center-title 内边距由固定 155px 改为 8.07vw,随视口 等比缩放以匹配 background cover,修复 4K 等高分屏两侧菜单贴近中间的问题 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
69c8c14c91
commit
9ed5420381
3 files changed
+68
-8
No files matched your search
@@ -133,6 +133,8 @@ export default function LightAppManagementPage() {
|
|||||||
const [form, setForm] = useState<FormState>(emptyForm);
|
const [form, setForm] = useState<FormState>(emptyForm);
|
||||||
const [activeParamPopover, setActiveParamPopover] = useState<string | null>(null);
|
const [activeParamPopover, setActiveParamPopover] = useState<string | null>(null);
|
||||||
const [viewMode, setViewMode] = useState<"table" | "cards">("table");
|
const [viewMode, setViewMode] = useState<"table" | "cards">("table");
|
||||||
|
const [categoryFilter, setCategoryFilter] = useState<"all" | LightAppType>("all");
|
||||||
|
const [mountFilter, setMountFilter] = useState<string>("");
|
||||||
|
|
||||||
const saving = actions.create.isPending || actions.update.isPending;
|
const saving = actions.create.isPending || actions.update.isPending;
|
||||||
|
|
||||||
@@ -220,7 +222,22 @@ export default function LightAppManagementPage() {
|
|||||||
toast.success("已复制地址");
|
toast.success("已复制地址");
|
||||||
};
|
};
|
||||||
|
|
||||||
const tableApps = useMemo(() => apps, [apps]);
|
const selectCategory = (cat: "all" | LightAppType) => {
|
||||||
|
setCategoryFilter(cat);
|
||||||
|
if (cat !== "iframe") setMountFilter("");
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableApps = useMemo(
|
||||||
|
() =>
|
||||||
|
apps.filter((app) => {
|
||||||
|
if (categoryFilter !== "all" && app.appType !== categoryFilter) return false;
|
||||||
|
if (categoryFilter === "iframe" && mountFilter && app.mountLocation !== mountFilter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
[apps, categoryFilter, mountFilter],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="light-app-management-page h-full overflow-y-auto bg-neutral-50 dark:bg-[#0C1836] dark:text-[#C5CFE0]">
|
<div className="light-app-management-page h-full overflow-y-auto bg-neutral-50 dark:bg-[#0C1836] dark:text-[#C5CFE0]">
|
||||||
@@ -252,7 +269,7 @@ export default function LightAppManagementPage() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="lam-toolbar flex flex-col items-center gap-3.5 rounded-[5px] bg-white p-3 shadow-[0_1px_3px_rgba(0,0,0,0.01)] md:flex-row">
|
<div className="lam-toolbar flex flex-col items-center gap-3.5 rounded-[5px] bg-white p-3 shadow-[0_1px_3px_rgba(0,0,0,0.01)] md:flex-row md:flex-wrap">
|
||||||
<div className="relative w-full flex-1">
|
<div className="relative w-full flex-1">
|
||||||
<Search className="absolute left-3.5 top-1/2 h-4 w-4 -translate-y-1/2 text-neutral-400" />
|
<Search className="absolute left-3.5 top-1/2 h-4 w-4 -translate-y-1/2 text-neutral-400" />
|
||||||
<input
|
<input
|
||||||
@@ -272,6 +289,41 @@ export default function LightAppManagementPage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="lam-cat-toggle flex shrink-0 items-center space-x-0.5 self-end rounded-[5px] border border-neutral-200/50 bg-neutral-100/60 p-0.5 md:self-auto">
|
||||||
|
{(
|
||||||
|
[
|
||||||
|
{ value: "all", label: "全部" },
|
||||||
|
{ value: "window_open", label: "新页跳转" },
|
||||||
|
{ value: "iframe", label: "iframe 嵌套" },
|
||||||
|
] as const
|
||||||
|
).map((c) => (
|
||||||
|
<button
|
||||||
|
key={c.value}
|
||||||
|
onClick={() => selectCategory(c.value)}
|
||||||
|
className={`lam-cat-toggle-btn cursor-pointer rounded-[5px] px-4 py-1.5 text-xs font-bold transition-all ${
|
||||||
|
categoryFilter === c.value
|
||||||
|
? "is-active bg-white text-[#F5222D] shadow-sm"
|
||||||
|
: "text-neutral-500 hover:text-neutral-700"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{c.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{categoryFilter === "iframe" && (
|
||||||
|
<div className="lam-mount-filter w-full shrink-0 animate-in fade-in self-end md:w-[180px] md:self-auto">
|
||||||
|
<Select
|
||||||
|
className="w-full"
|
||||||
|
value={mountFilter || undefined}
|
||||||
|
placeholder="按挂载菜单筛选"
|
||||||
|
clearable
|
||||||
|
options={MOUNT_OPTIONS}
|
||||||
|
onChange={(v) => setMountFilter((v as string) ?? "")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="lam-view-toggle flex shrink-0 items-center space-x-0.5 self-end rounded-[5px] border border-neutral-200/50 bg-neutral-100/60 p-0.5 md:self-auto">
|
<div className="lam-view-toggle flex shrink-0 items-center space-x-0.5 self-end rounded-[5px] border border-neutral-200/50 bg-neutral-100/60 p-0.5 md:self-auto">
|
||||||
<button
|
<button
|
||||||
onClick={() => setViewMode("table")}
|
onClick={() => setViewMode("table")}
|
||||||
|
|||||||
@@ -65,22 +65,26 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .light-app-management-page .lam-view-toggle {
|
.dark .light-app-management-page .lam-view-toggle,
|
||||||
|
.dark .light-app-management-page .lam-cat-toggle {
|
||||||
background: var(--color-bg-page);
|
background: var(--color-bg-page);
|
||||||
border-color: var(--color-border);
|
border-color: var(--color-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .light-app-management-page .lam-view-toggle-btn.is-active {
|
.dark .light-app-management-page .lam-view-toggle-btn.is-active,
|
||||||
|
.dark .light-app-management-page .lam-cat-toggle-btn.is-active {
|
||||||
background: var(--color-bg-card);
|
background: var(--color-bg-card);
|
||||||
color: var(--color-link);
|
color: var(--color-link);
|
||||||
box-shadow: var(--shadow-1);
|
box-shadow: var(--shadow-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .light-app-management-page .lam-view-toggle-btn:not(.is-active) {
|
.dark .light-app-management-page .lam-view-toggle-btn:not(.is-active),
|
||||||
|
.dark .light-app-management-page .lam-cat-toggle-btn:not(.is-active) {
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .light-app-management-page .lam-view-toggle-btn:not(.is-active):hover {
|
.dark .light-app-management-page .lam-view-toggle-btn:not(.is-active):hover,
|
||||||
|
.dark .light-app-management-page .lam-cat-toggle-btn:not(.is-active):hover {
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +596,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ── 视图切换激活态 ──────────────────────────────────────────────────── */
|
/* ── 视图切换激活态 ──────────────────────────────────────────────────── */
|
||||||
[data-theme="lightblue"] .light-app-management-page .lam-view-toggle-btn.is-active {
|
[data-theme="lightblue"] .light-app-management-page .lam-view-toggle-btn.is-active,
|
||||||
|
[data-theme="lightblue"] .light-app-management-page .lam-cat-toggle-btn.is-active {
|
||||||
color: #0062D9;
|
color: #0062D9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -950,7 +950,10 @@ html.dark .strategy-app-header {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0 155px;
|
/* 左右内边距随视口宽度等比缩放,与背景图基座的 background-size:cover 同步,
|
||||||
|
使两侧菜单在 1080p / 2K / 4K 下都贴齐发光基座边缘。
|
||||||
|
基准:1920 宽时 155px → 155/1920×100 ≈ 8.07vw。 */
|
||||||
|
padding: 0 8.07vw;
|
||||||
/* 文字略微上移,贴合基座视觉中心 */
|
/* 文字略微上移,贴合基座视觉中心 */
|
||||||
transform: translateY(-6px);
|
transform: translateY(-6px);
|
||||||
font-family: "Source Han Sans SC", "Noto Sans SC", "Noto Sans S Chinese",
|
font-family: "Source Han Sans SC", "Noto Sans SC", "Noto Sans S Chinese",
|
||||||
|
|||||||
Reference in new issue
Block a user