feat(sql-console): 表头 sticky + 数据行截断 + 点击展开详情

This commit is contained in:
xfy 2026-07-06 10:46:27 +08:00
parent b0833eebf7
commit 59edc7c4e4

View File

@ -62,8 +62,8 @@ fn render_cell(value: &serde_json::Value) -> Element {
/// 渲染展开详情区中的「列名: 完整值」单行。
///
/// 与 `render_cell` 不同:值不做截断,长文本由外层 `<pre>` 的
/// `whitespace-pre-wrap break-all` + `max-h-80 overflow-y-auto` 承载。
/// 与 `render_cell` 不同:值不做截断,长文本换行由外层展开区容器
/// `whitespace-pre-wrap break-all` + `max-h-80 overflow-y-auto`承载。
fn render_expanded_value(col: &str, value: &serde_json::Value) -> Element {
use serde_json::Value;
let display = match value {
@ -101,12 +101,64 @@ pub struct SqlResultTableProps {
#[cfg_attr(not(target_arch = "wasm32"), allow(unused_mut))]
pub fn SqlResultTable(props: SqlResultTableProps) -> Element {
let mut expanded_row: Signal<Option<usize>> = use_signal(|| None);
let cols_len = props.result.columns.len();
// colspan = 列数 + 行头箭头列
let expand_colspan = cols_len + 1;
rsx! {
div { class: "{ADMIN_TABLE_CLASS}",
div { class: "overflow-auto max-h-[70vh]",
table { class: "w-full text-sm border-collapse",
// 占位:后续 task 填充 thead / tbody
thead {
tr { class: "border-b border-[var(--color-paper-border)] sticky top-0 bg-[var(--color-paper-entry)] z-10",
th { class: "w-8 px-2 py-2", "" }
for col in props.result.columns.iter() {
th {
class: "px-4 py-2 text-left font-medium whitespace-nowrap text-[var(--color-paper-secondary)]",
"{col}"
}
}
}
}
tbody {
for (row_idx, row) in props.result.rows.iter().enumerate() {
// 数据行:点击切换展开
tr {
class: "border-b border-[var(--color-paper-border)] last:border-0 hover:bg-[var(--color-paper-accent-soft)] transition-colors cursor-pointer",
onclick: move |_| {
let cur = expanded_row();
if cur == Some(row_idx) {
expanded_row.set(None);
} else {
expanded_row.set(Some(row_idx));
}
},
td { class: "px-2 py-2 text-center text-[var(--color-paper-tertiary)] text-xs select-none",
if expanded_row() == Some(row_idx) { "" } else { "" }
}
for cell in row.iter() {
td {
class: "px-4 py-2 align-top",
{render_cell(cell)}
}
}
}
// 展开详情行(跨列)
if expanded_row() == Some(row_idx) {
tr {
td { colspan: "{expand_colspan}",
class: "px-4 py-3 bg-[var(--color-paper-theme)]",
div {
class: "{EXPAND_MAX_HEIGHT_CLASS} overflow-y-auto space-y-0.5 whitespace-pre-wrap break-all",
for (ci, col) in props.result.columns.iter().enumerate() {
{render_expanded_value(col, row.get(ci).unwrap_or(&serde_json::Value::Null))}
}
}
}
}
}
}
}
}
}
}