From 9d7f01a4ce8167d4effa8a9fa583de4f7211a5a1 Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 28 Jul 2026 16:19:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(mcp):=20=E4=BB=A4=E7=89=8C=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=B7=BB=E5=8A=A0=E9=AA=A8=E6=9E=B6=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TokenList 首次加载时(loading 且无数据)用 DelayedSkeleton 包裹的 骨架表格占位,4 行 7 列对齐真实表格列宽;加载完成后才区分空态/表格。 修复了首次加载时误显「暂无令牌」的问题。 --- src/pages/admin/mcp.rs | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/pages/admin/mcp.rs b/src/pages/admin/mcp.rs index fc43e01..f7ec1f3 100644 --- a/src/pages/admin/mcp.rs +++ b/src/pages/admin/mcp.rs @@ -25,6 +25,8 @@ use crate::components::forms::{FormSelect, INPUT_CLASS}; #[cfg(target_arch = "wasm32")] use crate::components::skeletons::atoms::SkeletonBox; #[cfg(target_arch = "wasm32")] +use crate::components::skeletons::delayed_skeleton::DelayedSkeleton; +#[cfg(target_arch = "wasm32")] use crate::components::ui::{ ADMIN_CARD_CLASS, ADMIN_TABLE_CLASS, BADGE_BASE, BTN_PRIMARY, BTN_PRIMARY_SM, BTN_TEXT_RED, }; @@ -158,6 +160,7 @@ fn TokenList() -> Element { let mut state: McpPageState = use_context(); let mut tokens = use_signal(|| Vec::::new()); let mut loaded_gen = use_signal(|| None::); + let mut loading = use_signal(|| true); let reload_gen = state.reload_gen; let mut toast = state.toast; @@ -172,6 +175,7 @@ fn TokenList() -> Element { Ok(list) => tokens.set(list), Err(e) => toast.set(Some((format!("加载失败:{e}"), true))), } + loading.set(false); }); } }); @@ -231,8 +235,39 @@ fn TokenList() -> Element { } } - // 表格 - if tokens().is_empty() { + // 表格区:首次加载(loading 且无数据)显示骨架屏,加载后无数据显示空态,否则显示表格。 + if loading() && tokens().is_empty() { + DelayedSkeleton { + div { class: "{ADMIN_TABLE_CLASS}", + table { class: "w-full text-sm", + thead { + tr { class: "bg-[var(--color-paper-theme)]/50", + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-10" } } + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-8" } } + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-8" } } + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-8" } } + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-12" } } + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-8" } } + th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-10 ml-auto" } } + } + } + tbody { + for _ in 0..4 { + tr { class: "border-b border-[var(--color-paper-border)] last:border-b-0", + td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-28" } } + td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-12" } } + td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-16" } } + td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-16" } } + td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-20" } } + td { class: "px-4 py-3", SkeletonBox { class: "h-5 w-10 rounded-full" } } + td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-24 ml-auto" } } + } + } + } + } + } + } + } else if tokens().is_empty() { p { class: "text-[var(--color-paper-secondary)] text-sm py-4 text-center", "暂无令牌。在下方新建一个。" }