Fix filetree SSR tab selection

This commit is contained in:
lix-2026
2026-05-26 14:34:47 +08:00
parent 4744757883
commit f961c1e2a1
5 changed files with 94 additions and 5 deletions
@@ -484,6 +484,11 @@ pub async fn root_entry(
&workspace_projection,
Some(sidebar_tree_html.as_str()),
Some(file_tree_html.as_str()),
if requests_filetree_first {
Some("filetree")
} else {
None
},
);
let workspace_name = workspace_projection.workspace_name.clone();
let active_page_id = selected_active_page_id.unwrap_or_default();
@@ -663,6 +668,7 @@ pub async fn trash_entry(
&workspace_projection,
Some(sidebar_tree_html.as_str()),
Some(file_tree_html.as_str()),
None,
);
let trash_workbench_html = render_local_trash_workbench_html(
&workspace_id,
@@ -725,6 +731,7 @@ pub async fn trash_entry(
&workspace_projection,
Some(sidebar_tree_html.as_str()),
Some(file_tree_html.as_str()),
None,
);
let dataset = load_sidebar_dataset(state.config(), &context, &workspace_id)
.await
@@ -73,6 +73,7 @@ pub async fn mindmap_object_shell(
&workspace_projection,
Some(sidebar_tree_html.as_str()),
Some(file_tree_html.as_str()),
None,
);
(
Some(workspace_name),
@@ -107,6 +108,7 @@ pub async fn mindmap_object_shell(
&workspace_projection,
Some(sidebar_tree_html.as_str()),
Some(file_tree_html.as_str()),
None,
);
(
Some(workspace_name),
@@ -49,6 +49,7 @@ pub struct DocumentShellQuery {
pub workspace_id: Option<String>,
pub source_kind: Option<String>,
pub root_uri: Option<String>,
pub tree_view: Option<String>,
pub secondary_document_id: Option<String>,
pub secondary_source_kind: Option<String>,
pub secondary_root_uri: Option<String>,
@@ -142,6 +143,11 @@ pub async fn document_page_shell(
.map(str::trim)
.filter(|value| !value.is_empty())
== Some("local_folder");
let requests_filetree_first = query
.tree_view
.as_deref()
.map(str::trim)
.is_some_and(|value| value == "filetree");
let (sidebar_tree_html, file_tree_html) = if is_local_folder {
let root_uri = query.root_uri.as_deref().unwrap_or_default();
(
@@ -168,6 +174,11 @@ pub async fn document_page_shell(
&workspace_projection,
Some(sidebar_tree_html.as_str()),
Some(file_tree_html.as_str()),
if requests_filetree_first {
Some("filetree")
} else {
None
},
);
let workspace_name = workspace_projection.workspace_name.clone();
let page_subtree_json =
@@ -87,6 +87,7 @@ pub fn PageLayout(
&projection,
Some(sidebar_tree_html.as_str()),
None,
None,
)
});
let tree_live_bootstrap = serde_json::json!({
+73 -5
View File
@@ -336,7 +336,7 @@ mod tests {
Some("doc_root"),
"开发用户 的工作区",
);
let html = render_workspace_shell_sidebar_html(&projection, None, None);
let html = render_workspace_shell_sidebar_html(&projection, None, None, None);
assert!(html.contains("data-testid=\"wolai-sidebar-row\""));
assert!(html.contains("data-node-id=\"doc_root\""));
@@ -370,6 +370,7 @@ mod tests {
&projection,
Some(r#"<ul data-rust-page-renderer="initial_v1"></ul>"#),
Some(r#"<ul data-rust-filetree-renderer="initial_v1"></ul>"#),
None,
);
assert!(html.contains(r#"data-mnote-sidebar-tree-tab="page""#));
@@ -381,6 +382,37 @@ mod tests {
assert!(!html.contains("wolai-file-tree-section"));
}
#[test]
fn workspace_shell_sidebar_html_can_render_filetree_tab_initially_active() {
let dataset = json!({
"workspaces": [{ "id": "ws_demo", "name": "开发用户 的工作区" }],
"documents": [
{ "id": "doc_root", "workspace_id": "ws_demo", "title": "Root", "parent_id": null, "sort_order": 0 }
]
});
let projection = build_workspace_shell_projection(
&dataset,
"ws_demo",
Some("doc_root"),
"开发用户 的工作区",
);
let html = render_workspace_shell_sidebar_html(
&projection,
Some(r#"<ul data-rust-page-renderer="initial_v1"></ul>"#),
Some(r#"<ul data-rust-filetree-renderer="initial_v1"></ul>"#),
Some("filetree"),
);
assert!(html.contains(
r#"class="wolai-sidebar-tab wolai-sidebar-tab-muted" data-mnote-sidebar-tree-tab="page" aria-selected="false""#
));
assert!(html.contains(
r#"class="wolai-sidebar-tab wolai-sidebar-tab-active" data-mnote-sidebar-tree-tab="filetree" aria-selected="true""#
));
assert!(html.contains(r#"data-mnote-sidebar-tree-panel="page" hidden"#));
assert!(html.contains(r#"data-mnote-sidebar-tree-panel="filetree"><div"#));
}
#[test]
fn workspace_shell_sidebar_html_outputs_empty_state() {
let dataset = json!({
@@ -389,7 +421,7 @@ mod tests {
});
let projection =
build_workspace_shell_projection(&dataset, "ws_demo", None, "开发用户 的工作区");
let html = render_workspace_shell_sidebar_html(&projection, None, None);
let html = render_workspace_shell_sidebar_html(&projection, None, None, None);
assert!(!html.contains("data-testid=\"wolai-sidebar-empty-state\""));
assert!(!html.contains("暂无页面"));
@@ -409,7 +441,8 @@ mod tests {
None,
"开发用户 的工作区",
);
let degraded_html = render_workspace_shell_sidebar_html(&degraded_projection, None, None);
let degraded_html =
render_workspace_shell_sidebar_html(&degraded_projection, None, None, None);
assert!(degraded_projection.degraded);
assert!(degraded_html.contains("data-mnote-workspace-shell-degraded=\"true\""));
@@ -423,7 +456,7 @@ mod tests {
});
let dev_projection =
build_workspace_shell_projection(&dev_dataset, "ws_demo", None, "开发用户 的工作区");
let dev_html = render_workspace_shell_sidebar_html(&dev_projection, None, None);
let dev_html = render_workspace_shell_sidebar_html(&dev_projection, None, None, None);
assert!(dev_projection.dev_fixture);
assert!(dev_html.contains("data-mnote-dev-fixture=\"true\""));
@@ -435,6 +468,7 @@ pub fn render_workspace_shell_sidebar_html(
projection: &WorkspaceShellProjection,
sidebar_tree_html: Option<&str>,
file_tree_html: Option<&str>,
initial_tree_mode: Option<&str>,
) -> String {
let starred_rows = if projection.starred_items.is_empty() {
String::new()
@@ -481,6 +515,40 @@ pub fn render_workspace_shell_sidebar_html(
} else {
String::new()
};
let filetree_initially_active = initial_tree_mode
.map(str::trim)
.is_some_and(|value| value == "filetree")
&& !file_tree_content.trim().is_empty();
let page_tab_class = if filetree_initially_active {
"wolai-sidebar-tab wolai-sidebar-tab-muted"
} else {
"wolai-sidebar-tab wolai-sidebar-tab-active"
};
let page_aria_selected = if filetree_initially_active {
"false"
} else {
"true"
};
let filetree_tab_class = if filetree_initially_active {
"wolai-sidebar-tab wolai-sidebar-tab-active"
} else {
"wolai-sidebar-tab wolai-sidebar-tab-muted"
};
let filetree_aria_selected = if filetree_initially_active {
"true"
} else {
"false"
};
let page_panel_hidden = if filetree_initially_active {
" hidden"
} else {
""
};
let filetree_panel_hidden = if filetree_initially_active {
""
} else {
" hidden"
};
let bottom_entries = projection
.bottom_entries
.iter()
@@ -526,7 +594,7 @@ pub fn render_workspace_shell_sidebar_html(
);
format!(
r#"{status_markers}<section class="wolai-sidebar-section wolai-starred-section" aria-label="星标置顶"><div class="wolai-section-title">{}星标置顶<span class="wolai-section-caret">⌄</span></div>{starred_rows}</section><section class="wolai-sidebar-section wolai-my-pages-section" aria-label="页面树" data-testid="wolai-sidebar-page-tree-shell"><div class="wolai-sidebar-tabs" data-testid="wolai-sidebar-tree-tabs" role="tablist" aria-label="页面树和文件树"><button type="button" class="wolai-sidebar-tab wolai-sidebar-tab-active" data-mnote-sidebar-tree-tab="page" aria-selected="true" aria-controls="wolai-sidebar-page-tree-panel">我的页面</button><button type="button" class="wolai-sidebar-tab wolai-sidebar-tab-muted" data-mnote-sidebar-tree-tab="filetree" aria-selected="false" aria-controls="wolai-sidebar-file-tree-panel">{}Explorer</button><span class="wolai-section-caret">⌄</span><button type="button" class="wolai-section-add" data-testid="wolai-sidebar-create-page" data-mnote-action="create-page" data-workspace-id="{}" title="新建页面" aria-label="新建页面">+</button></div><div class="wolai-sidebar-tab-panels"><div id="wolai-sidebar-page-tree-panel" class="wolai-sidebar-tab-panel" data-mnote-sidebar-tree-panel="page">{my_pages}</div><div id="wolai-sidebar-file-tree-panel" class="wolai-sidebar-tab-panel" data-mnote-sidebar-tree-panel="filetree" hidden>{file_tree_content}</div></div></section><div class="wolai-sidebar-footer">{bottom_entries}</div>"#,
r#"{status_markers}<section class="wolai-sidebar-section wolai-starred-section" aria-label="星标置顶"><div class="wolai-section-title">{}星标置顶<span class="wolai-section-caret">⌄</span></div>{starred_rows}</section><section class="wolai-sidebar-section wolai-my-pages-section" aria-label="页面树" data-testid="wolai-sidebar-page-tree-shell"><div class="wolai-sidebar-tabs" data-testid="wolai-sidebar-tree-tabs" role="tablist" aria-label="页面树和文件树"><button type="button" class="{page_tab_class}" data-mnote-sidebar-tree-tab="page" aria-selected="{page_aria_selected}" aria-controls="wolai-sidebar-page-tree-panel">我的页面</button><button type="button" class="{filetree_tab_class}" data-mnote-sidebar-tree-tab="filetree" aria-selected="{filetree_aria_selected}" aria-controls="wolai-sidebar-file-tree-panel">{}Explorer</button><span class="wolai-section-caret">⌄</span><button type="button" class="wolai-section-add" data-testid="wolai-sidebar-create-page" data-mnote-action="create-page" data-workspace-id="{}" title="新建页面" aria-label="新建页面">+</button></div><div class="wolai-sidebar-tab-panels"><div id="wolai-sidebar-page-tree-panel" class="wolai-sidebar-tab-panel" data-mnote-sidebar-tree-panel="page"{page_panel_hidden}>{my_pages}</div><div id="wolai-sidebar-file-tree-panel" class="wolai-sidebar-tab-panel" data-mnote-sidebar-tree-panel="filetree"{filetree_panel_hidden}>{file_tree_content}</div></div></section><div class="wolai-sidebar-footer">{bottom_entries}</div>"#,
render_symbol("star", "wolai-section-icon"),
render_symbol("folder_open", "wolai-folder-icon"),
escape_html(&projection.workspace_id),