Persist PageTree expand state via control-plane view-state and align chevron/DOM with restored expansion; keep Sidex-style shallow page-tree scan and drop the unused recursive scanner that only added cargo noise. Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi into a module package, and retire Hermes/ACP/OpenHub recycle + root harness evidence from the index while gitignoring recycle and local diag dumps. Archive superseded design/bugs docs under old/, point architecture at ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor regressions so the working tree can stay clean.
192 lines
10 KiB
Rust
192 lines
10 KiB
Rust
//! MNOTE 首页组件(Wolai 风格)
|
|
|
|
use super::{
|
|
document::{DocumentPane, DocumentPaneViewModel},
|
|
layout::PageLayout,
|
|
};
|
|
use leptos::prelude::*;
|
|
|
|
/// MNOTE 首页。
|
|
#[component]
|
|
pub fn HomePage(
|
|
/// 侧栏页面树 HTML(可选)
|
|
#[prop(optional)]
|
|
sidebar_tree_html: Option<String>,
|
|
/// 工作区名称(可选)
|
|
#[prop(optional)]
|
|
workspace_name: Option<String>,
|
|
/// 工作区 id(可选)
|
|
#[prop(optional)]
|
|
workspace_id: Option<String>,
|
|
/// workspace shell 侧栏 sections HTML(可选)
|
|
#[prop(optional)]
|
|
workspace_sidebar_html: Option<String>,
|
|
/// 顶栏页面祖先链 HTML(可选)
|
|
#[prop(optional)]
|
|
breadcrumb_html: Option<String>,
|
|
/// 当前选中的页面 id(可选)
|
|
#[prop(optional)]
|
|
active_page_id: Option<String>,
|
|
/// 当前选中的页面标题(可选)
|
|
#[prop(optional)]
|
|
active_page_title: Option<String>,
|
|
/// 导航页主体 HTML(可选)
|
|
#[prop(optional)]
|
|
navigation_html: String,
|
|
/// 是否显示管理员授权入口
|
|
#[prop(optional)]
|
|
show_admin_access_policy: bool,
|
|
/// 是否启用树实时流
|
|
#[prop(optional, default = true)]
|
|
enable_tree_live: bool,
|
|
/// 密码箱导航 SSR href(含 local_folder 上下文)
|
|
#[prop(optional)]
|
|
vault_nav_href: Option<String>,
|
|
) -> impl IntoView {
|
|
let active_page_id = active_page_id.unwrap_or_default();
|
|
let active_page_title = active_page_title
|
|
.map(|value| value.trim().to_string())
|
|
.filter(|value| !value.is_empty())
|
|
.unwrap_or_else(|| "个人".to_string());
|
|
let has_active_page = !active_page_id.trim().is_empty();
|
|
let navigation_html = Some(navigation_html)
|
|
.map(|value| value.trim().to_string())
|
|
.filter(|value| !value.is_empty());
|
|
let workspace_id = workspace_id
|
|
.map(|value| value.trim().to_string())
|
|
.filter(|value| !value.is_empty());
|
|
let active_href = workspace_id
|
|
.as_deref()
|
|
.map(|workspace_id| format!("/documents/{active_page_id}?workspaceId={workspace_id}"))
|
|
.unwrap_or_else(|| format!("/documents/{active_page_id}"));
|
|
view! {
|
|
<PageLayout current_nav="home" sidebar_tree_html={sidebar_tree_html.unwrap_or_default()} workspace_name={workspace_name.unwrap_or_default()} workspace_sidebar_html={workspace_sidebar_html.unwrap_or_default()} topbar_title={active_page_title.clone()} breadcrumb_html={breadcrumb_html.unwrap_or_default()} show_admin_access_policy={show_admin_access_policy} enable_tree_live={enable_tree_live} vault_nav_href={vault_nav_href.unwrap_or_default()}>
|
|
{move || if has_active_page {
|
|
view! {
|
|
<main class="document-shell document-shell--workspace-entry" data-root-active-page-id={active_page_id.clone()} data-editor-host="leptos_tiptap_island">
|
|
<header class="document-shell-header">
|
|
<div class="document-page-icon" aria-hidden="true">"⌂"</div>
|
|
<h1>{active_page_title.clone()}</h1>
|
|
<div class="document-shell-meta" aria-label="页面元信息">
|
|
<span><span aria-hidden="true">"◌"</span>"个人空间"</span>
|
|
<span><span aria-hidden="true">"▣"</span>"工作区首页"</span>
|
|
</div>
|
|
</header>
|
|
<section class="mnote-workspace-active-state" data-testid="mnote-workspace-active-page-state">
|
|
<a class="mnote-workspace-active-link" href={active_href.clone()}>"打开当前页面"</a>
|
|
</section>
|
|
</main>
|
|
}.into_any()
|
|
} else if let Some(navigation_html) = navigation_html.clone() {
|
|
view! {
|
|
<main
|
|
class="document-workspace mnote-navigation-page-workspace"
|
|
data-testid="mnote-document-workspace"
|
|
data-has-secondary-pane="false"
|
|
data-workspace-id={workspace_id.clone().unwrap_or_default()}
|
|
>
|
|
<section class="document-main-editor-group" data-testid="mnote-main-editor-tab-host" data-pane-role="primary">
|
|
<div class="mnote-main-tab-strip" data-mnote-main-tab-strip="true" data-pane-role="primary" role="tablist" aria-label="主编辑区标签页">
|
|
<button
|
|
type="button"
|
|
class="mnote-main-tab is-active"
|
|
data-mnote-main-tab="page"
|
|
data-mnote-tab-kind="page"
|
|
data-pane-role="primary"
|
|
data-workspace-id={workspace_id.clone().unwrap_or_default()}
|
|
role="tab"
|
|
aria-selected="true"
|
|
tabindex="0"
|
|
>
|
|
<span class="mnote-main-tab-badge" aria-hidden="true"></span>
|
|
<span class="mnote-main-tab-title">"主页"</span>
|
|
</button>
|
|
</div>
|
|
<div class="mnote-main-tab-panels">
|
|
<div
|
|
data-mnote-page-tab-panel="true"
|
|
data-pane-role="primary"
|
|
>
|
|
<div
|
|
class="mnote-navigation-page-host"
|
|
data-mnote-navigation-page-placeholder="true"
|
|
data-pane-role="primary"
|
|
>
|
|
<div inner_html={navigation_html}></div>
|
|
</div>
|
|
</div>
|
|
<section
|
|
class="mnote-resource-tab-host"
|
|
data-mnote-resource-tab-host="true"
|
|
data-pane-role="primary"
|
|
data-testid="mnote-resource-tab-host"
|
|
hidden=true
|
|
>
|
|
<div class="mnote-resource-tab-panel-root" data-mnote-resource-tab-panel-root="true" data-pane-role="primary"></div>
|
|
</section>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
}.into_any()
|
|
} else {
|
|
let empty_primary_model = DocumentPaneViewModel {
|
|
pane_role: "primary",
|
|
title: "文件夹".to_string(),
|
|
document_id: String::new(),
|
|
workspace_id: workspace_id.clone().unwrap_or_default(),
|
|
page_wide_layout: false,
|
|
page_small_text: false,
|
|
page_layout_density: "normal".to_string(),
|
|
page_font: "default".to_string(),
|
|
page_show_heading_numbers: false,
|
|
has_page_subtree: false,
|
|
primary_legacy_ids: true,
|
|
visible: true,
|
|
hide_title_header: true,
|
|
};
|
|
view! {
|
|
<main
|
|
class="document-workspace mnote-workspace-empty-editor-host"
|
|
data-testid="mnote-document-workspace"
|
|
data-has-secondary-pane="false"
|
|
data-workspace-id={workspace_id.clone().unwrap_or_default()}
|
|
>
|
|
<section class="document-main-editor-group" data-testid="mnote-main-editor-tab-host" data-pane-role="primary">
|
|
<div class="mnote-main-tab-strip" data-mnote-main-tab-strip="true" data-pane-role="primary" role="tablist" aria-label="主编辑区标签页">
|
|
<button
|
|
type="button"
|
|
class="mnote-main-tab is-active"
|
|
data-mnote-main-tab="page"
|
|
data-mnote-tab-kind="page"
|
|
data-pane-role="primary"
|
|
data-workspace-id={workspace_id.clone().unwrap_or_default()}
|
|
role="tab"
|
|
aria-selected="true"
|
|
tabindex="0"
|
|
>
|
|
<span class="mnote-main-tab-badge" aria-hidden="true"></span>
|
|
<span class="mnote-main-tab-title">"文件夹"</span>
|
|
</button>
|
|
</div>
|
|
<div class="mnote-main-tab-panels">
|
|
<div data-mnote-page-tab-panel="true" data-pane-role="primary">
|
|
<DocumentPane model={empty_primary_model} />
|
|
</div>
|
|
<section
|
|
class="mnote-resource-tab-host"
|
|
data-mnote-resource-tab-host="true"
|
|
data-pane-role="primary"
|
|
data-testid="mnote-resource-tab-host"
|
|
hidden=true
|
|
>
|
|
<div class="mnote-resource-tab-panel-root" data-mnote-resource-tab-panel-root="true" data-pane-role="primary"></div>
|
|
</section>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
}.into_any()
|
|
}}
|
|
</PageLayout>
|
|
}
|
|
}
|