Fix filetree SSR tab selection
This commit is contained in:
@@ -484,6 +484,11 @@ pub async fn root_entry(
|
|||||||
&workspace_projection,
|
&workspace_projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
Some(file_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 workspace_name = workspace_projection.workspace_name.clone();
|
||||||
let active_page_id = selected_active_page_id.unwrap_or_default();
|
let active_page_id = selected_active_page_id.unwrap_or_default();
|
||||||
@@ -663,6 +668,7 @@ pub async fn trash_entry(
|
|||||||
&workspace_projection,
|
&workspace_projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
Some(file_tree_html.as_str()),
|
Some(file_tree_html.as_str()),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
let trash_workbench_html = render_local_trash_workbench_html(
|
let trash_workbench_html = render_local_trash_workbench_html(
|
||||||
&workspace_id,
|
&workspace_id,
|
||||||
@@ -725,6 +731,7 @@ pub async fn trash_entry(
|
|||||||
&workspace_projection,
|
&workspace_projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
Some(file_tree_html.as_str()),
|
Some(file_tree_html.as_str()),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
let dataset = load_sidebar_dataset(state.config(), &context, &workspace_id)
|
let dataset = load_sidebar_dataset(state.config(), &context, &workspace_id)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ pub async fn mindmap_object_shell(
|
|||||||
&workspace_projection,
|
&workspace_projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
Some(file_tree_html.as_str()),
|
Some(file_tree_html.as_str()),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
Some(workspace_name),
|
Some(workspace_name),
|
||||||
@@ -107,6 +108,7 @@ pub async fn mindmap_object_shell(
|
|||||||
&workspace_projection,
|
&workspace_projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
Some(file_tree_html.as_str()),
|
Some(file_tree_html.as_str()),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
Some(workspace_name),
|
Some(workspace_name),
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ pub struct DocumentShellQuery {
|
|||||||
pub workspace_id: Option<String>,
|
pub workspace_id: Option<String>,
|
||||||
pub source_kind: Option<String>,
|
pub source_kind: Option<String>,
|
||||||
pub root_uri: Option<String>,
|
pub root_uri: Option<String>,
|
||||||
|
pub tree_view: Option<String>,
|
||||||
pub secondary_document_id: Option<String>,
|
pub secondary_document_id: Option<String>,
|
||||||
pub secondary_source_kind: Option<String>,
|
pub secondary_source_kind: Option<String>,
|
||||||
pub secondary_root_uri: Option<String>,
|
pub secondary_root_uri: Option<String>,
|
||||||
@@ -142,6 +143,11 @@ pub async fn document_page_shell(
|
|||||||
.map(str::trim)
|
.map(str::trim)
|
||||||
.filter(|value| !value.is_empty())
|
.filter(|value| !value.is_empty())
|
||||||
== Some("local_folder");
|
== 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 (sidebar_tree_html, file_tree_html) = if is_local_folder {
|
||||||
let root_uri = query.root_uri.as_deref().unwrap_or_default();
|
let root_uri = query.root_uri.as_deref().unwrap_or_default();
|
||||||
(
|
(
|
||||||
@@ -168,6 +174,11 @@ pub async fn document_page_shell(
|
|||||||
&workspace_projection,
|
&workspace_projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
Some(file_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 workspace_name = workspace_projection.workspace_name.clone();
|
||||||
let page_subtree_json =
|
let page_subtree_json =
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ pub fn PageLayout(
|
|||||||
&projection,
|
&projection,
|
||||||
Some(sidebar_tree_html.as_str()),
|
Some(sidebar_tree_html.as_str()),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let tree_live_bootstrap = serde_json::json!({
|
let tree_live_bootstrap = serde_json::json!({
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ mod tests {
|
|||||||
Some("doc_root"),
|
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-testid=\"wolai-sidebar-row\""));
|
||||||
assert!(html.contains("data-node-id=\"doc_root\""));
|
assert!(html.contains("data-node-id=\"doc_root\""));
|
||||||
@@ -370,6 +370,7 @@ mod tests {
|
|||||||
&projection,
|
&projection,
|
||||||
Some(r#"<ul data-rust-page-renderer="initial_v1"></ul>"#),
|
Some(r#"<ul data-rust-page-renderer="initial_v1"></ul>"#),
|
||||||
Some(r#"<ul data-rust-filetree-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""#));
|
assert!(html.contains(r#"data-mnote-sidebar-tree-tab="page""#));
|
||||||
@@ -381,6 +382,37 @@ mod tests {
|
|||||||
assert!(!html.contains("wolai-file-tree-section"));
|
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]
|
#[test]
|
||||||
fn workspace_shell_sidebar_html_outputs_empty_state() {
|
fn workspace_shell_sidebar_html_outputs_empty_state() {
|
||||||
let dataset = json!({
|
let dataset = json!({
|
||||||
@@ -389,7 +421,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
let projection =
|
let projection =
|
||||||
build_workspace_shell_projection(&dataset, "ws_demo", None, "开发用户 的工作区");
|
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("data-testid=\"wolai-sidebar-empty-state\""));
|
||||||
assert!(!html.contains("暂无页面"));
|
assert!(!html.contains("暂无页面"));
|
||||||
@@ -409,7 +441,8 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
"开发用户 的工作区",
|
"开发用户 的工作区",
|
||||||
);
|
);
|
||||||
let degraded_html = render_workspace_shell_sidebar_html(°raded_projection, None, None);
|
let degraded_html =
|
||||||
|
render_workspace_shell_sidebar_html(°raded_projection, None, None, None);
|
||||||
|
|
||||||
assert!(degraded_projection.degraded);
|
assert!(degraded_projection.degraded);
|
||||||
assert!(degraded_html.contains("data-mnote-workspace-shell-degraded=\"true\""));
|
assert!(degraded_html.contains("data-mnote-workspace-shell-degraded=\"true\""));
|
||||||
@@ -423,7 +456,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
let dev_projection =
|
let dev_projection =
|
||||||
build_workspace_shell_projection(&dev_dataset, "ws_demo", None, "开发用户 的工作区");
|
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_projection.dev_fixture);
|
||||||
assert!(dev_html.contains("data-mnote-dev-fixture=\"true\""));
|
assert!(dev_html.contains("data-mnote-dev-fixture=\"true\""));
|
||||||
@@ -435,6 +468,7 @@ pub fn render_workspace_shell_sidebar_html(
|
|||||||
projection: &WorkspaceShellProjection,
|
projection: &WorkspaceShellProjection,
|
||||||
sidebar_tree_html: Option<&str>,
|
sidebar_tree_html: Option<&str>,
|
||||||
file_tree_html: Option<&str>,
|
file_tree_html: Option<&str>,
|
||||||
|
initial_tree_mode: Option<&str>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let starred_rows = if projection.starred_items.is_empty() {
|
let starred_rows = if projection.starred_items.is_empty() {
|
||||||
String::new()
|
String::new()
|
||||||
@@ -481,6 +515,40 @@ pub fn render_workspace_shell_sidebar_html(
|
|||||||
} else {
|
} else {
|
||||||
String::new()
|
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
|
let bottom_entries = projection
|
||||||
.bottom_entries
|
.bottom_entries
|
||||||
.iter()
|
.iter()
|
||||||
@@ -526,7 +594,7 @@ pub fn render_workspace_shell_sidebar_html(
|
|||||||
);
|
);
|
||||||
|
|
||||||
format!(
|
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("star", "wolai-section-icon"),
|
||||||
render_symbol("folder_open", "wolai-folder-icon"),
|
render_symbol("folder_open", "wolai-folder-icon"),
|
||||||
escape_html(&projection.workspace_id),
|
escape_html(&projection.workspace_id),
|
||||||
|
|||||||
Reference in New Issue
Block a user