feat(mcp): 配置生成中 loading 替换为骨架屏
用 SkeletonBox 组合出 6 个配置片段的占位结构(标题行 + 代码块), 高度按真实 JSON/CLI 配置长短变化,比纯文本「生成配置中…」更直观。
This commit is contained in:
parent
070d06dacd
commit
ee1732214e
@ -23,6 +23,8 @@ use crate::api::mcp_tokens::{
|
|||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use crate::components::forms::{FormSelect, INPUT_CLASS};
|
use crate::components::forms::{FormSelect, INPUT_CLASS};
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
use crate::components::skeletons::atoms::SkeletonBox;
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
use crate::components::ui::{
|
use crate::components::ui::{
|
||||||
ADMIN_CARD_CLASS, ADMIN_TABLE_CLASS, BADGE_BASE, BTN_PRIMARY, BTN_PRIMARY_SM, BTN_TEXT_RED,
|
ADMIN_CARD_CLASS, ADMIN_TABLE_CLASS, BADGE_BASE, BTN_PRIMARY, BTN_PRIMARY_SM, BTN_TEXT_RED,
|
||||||
};
|
};
|
||||||
@ -47,6 +49,20 @@ const LIFETIME_OPTIONS: &[(TokenLifetime, &str)] = &[
|
|||||||
(TokenLifetime::Never, "永不过期"),
|
(TokenLifetime::Never, "永不过期"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// 配置骨架屏的尺寸变化:(标题宽度 px, 代码块高度 px)。
|
||||||
|
///
|
||||||
|
/// 按 6 个真实配置片段的长短差异给出不同占位尺寸,让骨架屏更像即将出现的真实内容
|
||||||
|
/// 而非千篇一律的等高块。
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
const CONFIG_SKELETON_SHAPES: &[(&str, &str)] = &[
|
||||||
|
("width: 260px;", "height: 168px;"), // Claude Code JSON
|
||||||
|
("width: 200px;", "height: 136px;"), // Cursor JSON
|
||||||
|
("width: 220px;", "height: 168px;"), // Cline JSON
|
||||||
|
("width: 320px;", "height: 152px;"), // Oh-My-Pi JSON
|
||||||
|
("width: 160px;", "height: 104px;"), // 通用 JSON
|
||||||
|
("width: 140px;", "height: 56px;"), // CLI 一行命令
|
||||||
|
];
|
||||||
|
|
||||||
/// 跨子组件共享的页面状态:刷新代际、一次性明文弹窗、配置用令牌、操作提示。
|
/// 跨子组件共享的页面状态:刷新代际、一次性明文弹窗、配置用令牌、操作提示。
|
||||||
///
|
///
|
||||||
/// `PartialEq` 由组件宏生成的 Props 结构体要求(`TokenRow` 以此为 prop)。
|
/// `PartialEq` 由组件宏生成的 Props 结构体要求(`TokenRow` 以此为 prop)。
|
||||||
@ -500,7 +516,23 @@ fn ConfigCard() -> Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if loading() {
|
if loading() {
|
||||||
p { class: "text-sm text-[var(--color-paper-tertiary)] py-4 text-center", "生成配置中…" }
|
div { class: "flex flex-col gap-4",
|
||||||
|
for i in 0..6 {
|
||||||
|
div { key: "{i}", class: "flex flex-col gap-2",
|
||||||
|
div { class: "flex items-center justify-between",
|
||||||
|
SkeletonBox {
|
||||||
|
class: "h-4 rounded",
|
||||||
|
style: CONFIG_SKELETON_SHAPES[i].0
|
||||||
|
}
|
||||||
|
SkeletonBox { class: "h-7 w-14 rounded-full" }
|
||||||
|
}
|
||||||
|
SkeletonBox {
|
||||||
|
class: "rounded-lg",
|
||||||
|
style: CONFIG_SKELETON_SHAPES[i].1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if let Some(c) = configs() {
|
} else if let Some(c) = configs() {
|
||||||
div { class: "flex flex-col gap-4",
|
div { class: "flex flex-col gap-4",
|
||||||
for snippet in c.snippets.iter() {
|
for snippet in c.snippets.iter() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user