chore: align sqlite control plane architecture
- replace default Convex control-plane wording with Rust SQLite control-plane across architecture, AGENTS, Reasonix, and design docs - retire root Convex functions source and deploy script into recycle while keeping explicit cloud/compat/sync-replica boundaries - add control-plane migration guard/docs and keep CodeGraph refreshed after the SQLite control-plane cutover
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
//! MNOTE 通用页面布局组件(Wolai / Notion 风格)
|
||||
|
||||
use crate::ssr::pages::admin::AdminAccessPolicyPanel;
|
||||
use leptos::prelude::*;
|
||||
|
||||
const SIDEBAR_TREE_JS: &str = r##"
|
||||
@@ -1227,6 +1228,12 @@ const SIDEBAR_TREE_JS: &str = r##"
|
||||
if (existing && existing.parentElement) existing.parentElement.removeChild(existing);
|
||||
}
|
||||
|
||||
function closeAdminAccessPolicyDialog() {
|
||||
var existing = document.querySelector('[data-testid="mnote-admin-access-policy-modal"]');
|
||||
if (existing && existing.parentElement) existing.parentElement.removeChild(existing);
|
||||
document.documentElement.removeAttribute('data-mnote-admin-access-policy-modal-open');
|
||||
}
|
||||
|
||||
function accountMenuFallbackSession() {
|
||||
var body = document.body instanceof HTMLElement ? document.body : null;
|
||||
var actorId = body ? String(body.getAttribute('data-mnote-actor-id') || '').trim() : '';
|
||||
@@ -1263,10 +1270,6 @@ const SIDEBAR_TREE_JS: &str = r##"
|
||||
return String(session && session.actorType || '').trim() === 'admin';
|
||||
}
|
||||
|
||||
function accessPolicyHrefForSession(session) {
|
||||
return sessionIsAdmin(session) ? '/admin/access-policy' : '/user/access-policy';
|
||||
}
|
||||
|
||||
async function loadAccountInfo(menu) {
|
||||
try {
|
||||
var response = await fetch('/api/auth/session', {
|
||||
@@ -1346,6 +1349,43 @@ const SIDEBAR_TREE_JS: &str = r##"
|
||||
if (closeButton instanceof HTMLElement) closeButton.focus();
|
||||
}
|
||||
|
||||
function openAdminAccessPolicyDialog(trigger) {
|
||||
closeAdminAccessPolicyDialog();
|
||||
closeAccountMenu();
|
||||
if (!(trigger instanceof HTMLElement)) return;
|
||||
var role = trigger.getAttribute('data-access-policy-role') === 'admin' ? 'admin' : 'user';
|
||||
var template = document.querySelector('[data-testid="mnote-admin-access-policy-template-' + role + '"]');
|
||||
var dialog = document.createElement('div');
|
||||
dialog.className = 'mnote-admin-policy-modal';
|
||||
dialog.setAttribute('data-testid', 'mnote-admin-access-policy-modal');
|
||||
dialog.setAttribute('role', 'dialog');
|
||||
dialog.setAttribute('aria-modal', 'true');
|
||||
dialog.setAttribute('aria-labelledby', 'mnote-admin-policy-dialog-title');
|
||||
dialog.innerHTML =
|
||||
'<div class="mnote-admin-policy-modal__backdrop" data-admin-access-policy-close></div>' +
|
||||
'<section class="mnote-admin-policy-modal__panel">' +
|
||||
'<button type="button" class="mnote-admin-policy-modal__close" data-admin-access-policy-close aria-label="关闭授权管理"><span class="material-symbols-outlined" data-icon="close" aria-hidden="true"></span></button>' +
|
||||
'<div class="mnote-admin-policy-modal__content" data-testid="mnote-admin-access-policy-modal-content"></div>' +
|
||||
'</section>';
|
||||
var content = dialog.querySelector('[data-testid="mnote-admin-access-policy-modal-content"]');
|
||||
if (content) {
|
||||
content.innerHTML = template ? template.innerHTML : '<div class="mnote-admin-policy-empty">授权管理面板加载失败</div>';
|
||||
}
|
||||
if (typeof window.MNOTEInitAccessPolicyPanel === 'function') {
|
||||
window.MNOTEInitAccessPolicyPanel(dialog);
|
||||
}
|
||||
dialog.querySelectorAll('[data-admin-access-policy-close]').forEach(function(button) {
|
||||
button.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
closeAdminAccessPolicyDialog();
|
||||
});
|
||||
});
|
||||
document.body.appendChild(dialog);
|
||||
document.documentElement.setAttribute('data-mnote-admin-access-policy-modal-open', 'true');
|
||||
var closeButton = dialog.querySelector('.mnote-admin-policy-modal__close');
|
||||
if (closeButton instanceof HTMLElement) closeButton.focus();
|
||||
}
|
||||
|
||||
async function signOutAccount(trigger) {
|
||||
setCommandPending(trigger, true);
|
||||
try {
|
||||
@@ -1382,7 +1422,7 @@ const SIDEBAR_TREE_JS: &str = r##"
|
||||
menu.setAttribute('role', 'menu');
|
||||
menu.innerHTML =
|
||||
'<button type="button" class="mnote-workspace-source-menu__item mnote-account-menu__item" data-testid="mnote-account-profile" role="menuitem"><span class="material-symbols-outlined" data-icon="account_circle" aria-hidden="true"></span><span>个人信息</span></button>' +
|
||||
'<a class="mnote-workspace-source-menu__item mnote-account-menu__item" data-testid="mnote-account-access-policy" role="menuitem" href="/user/access-policy"><span class="material-symbols-outlined" data-icon="admin_panel_settings" aria-hidden="true"></span><span>授权管理</span></a>' +
|
||||
'<button type="button" class="mnote-workspace-source-menu__item mnote-account-menu__item" data-testid="mnote-account-access-policy" role="menuitem" hidden><span class="material-symbols-outlined" data-icon="admin_panel_settings" aria-hidden="true"></span><span>授权管理</span></button>' +
|
||||
'<button type="button" class="mnote-workspace-source-menu__item mnote-account-menu__logout" data-testid="mnote-account-sign-out" role="menuitem">退出登录</button>' +
|
||||
'<div class="mnote-account-menu__error" data-account-error hidden></div>';
|
||||
var sessionPromise = fetchAccountSession();
|
||||
@@ -1395,8 +1435,16 @@ const SIDEBAR_TREE_JS: &str = r##"
|
||||
}
|
||||
var accessPolicyLink = menu.querySelector('[data-testid="mnote-account-access-policy"]');
|
||||
sessionPromise.then(function(session) {
|
||||
if (accessPolicyLink instanceof HTMLElement) accessPolicyLink.setAttribute('href', accessPolicyHrefForSession(session));
|
||||
if (!(accessPolicyLink instanceof HTMLElement)) return;
|
||||
accessPolicyLink.hidden = false;
|
||||
accessPolicyLink.setAttribute('data-access-policy-role', sessionIsAdmin(session) ? 'admin' : 'user');
|
||||
});
|
||||
if (accessPolicyLink) {
|
||||
accessPolicyLink.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
openAdminAccessPolicyDialog(accessPolicyLink);
|
||||
});
|
||||
}
|
||||
var signOutButton = menu.querySelector('[data-testid="mnote-account-sign-out"]');
|
||||
if (signOutButton) {
|
||||
signOutButton.addEventListener('click', function(event) {
|
||||
@@ -9996,13 +10044,14 @@ pub fn PageLayout(
|
||||
/// 顶栏当前页面标题(可选)
|
||||
#[prop(optional)]
|
||||
topbar_title: Option<String>,
|
||||
/// 是否显示管理员授权入口
|
||||
/// 是否显示管理员授权能力
|
||||
#[prop(optional)]
|
||||
show_admin_access_policy: bool,
|
||||
/// 是否启用树实时流
|
||||
#[prop(optional, default = true)]
|
||||
enable_tree_live: bool,
|
||||
) -> impl IntoView {
|
||||
let _ = show_admin_access_policy;
|
||||
let sidebar_tree_html = sidebar_tree_html.unwrap_or_default();
|
||||
|
||||
let ws_name = workspace_name
|
||||
@@ -10042,6 +10091,12 @@ pub fn PageLayout(
|
||||
"views": ["page-tree", "file-tree"]
|
||||
})
|
||||
.to_string();
|
||||
let admin_access_policy_template = crate::ssr::render_view(leptos::view! {
|
||||
<AdminAccessPolicyPanel workspace_name={ws_name.clone()} is_admin=true boot_script=false />
|
||||
});
|
||||
let user_access_policy_template = crate::ssr::render_view(leptos::view! {
|
||||
<AdminAccessPolicyPanel workspace_name={ws_name.clone()} is_admin=false boot_script=false />
|
||||
});
|
||||
|
||||
view! {
|
||||
<div class="mnote-shell wolai-workspace-shell" data-mnote-web-owner="mnote-web" data-mnote-shell="workspace">
|
||||
@@ -10068,21 +10123,6 @@ pub fn PageLayout(
|
||||
<a href="/help" title="帮助" aria-label="帮助"><span class="material-symbols-outlined nav-icon" data-icon="help" aria-hidden="true"></span></a>
|
||||
<a href="/files" title="文件" aria-label="文件"><span class="material-symbols-outlined nav-icon" data-icon="inventory_2" aria-hidden="true"></span></a>
|
||||
<button type="button" title="打开本地文件夹" aria-label="打开本地文件夹" data-mnote-action="open-local-folder"><span class="material-symbols-outlined nav-icon" data-icon="folder_open" aria-hidden="true"></span></button>
|
||||
{if show_admin_access_policy {
|
||||
view! {
|
||||
<a
|
||||
href="/admin/access-policy"
|
||||
class:active={current_nav == "admin"}
|
||||
title="目录授权"
|
||||
aria-label="目录授权"
|
||||
data-testid="mnote-admin-access-policy-entry"
|
||||
>
|
||||
<span class="material-symbols-outlined nav-icon" data-icon="admin_panel_settings" aria-hidden="true"></span>
|
||||
</a>
|
||||
}.into_any()
|
||||
} else {
|
||||
view! {}.into_any()
|
||||
}}
|
||||
<button
|
||||
type="button"
|
||||
title="更多"
|
||||
@@ -10097,6 +10137,9 @@ pub fn PageLayout(
|
||||
</nav>
|
||||
<div class="wolai-sidebar-body" inner_html={sidebar_sections_html}></div>
|
||||
<script id="__MNOTE_TREE_LIVE_BOOTSTRAP__" type="application/json" inner_html={tree_live_bootstrap}></script>
|
||||
<div hidden data-testid="mnote-admin-access-policy-template-admin" inner_html={admin_access_policy_template}></div>
|
||||
<div hidden data-testid="mnote-admin-access-policy-template-user" inner_html={user_access_policy_template}></div>
|
||||
<script inner_html={crate::ssr::pages::admin::ADMIN_POLICY_SCRIPT.to_string()}></script>
|
||||
<script inner_html={SIDEBAR_TREE_JS.to_string()}></script>
|
||||
<script id="mnote-tree-live-controller" inner_html={TREE_LIVE_CONTROLLER_JS.to_string()}></script>
|
||||
</aside>
|
||||
|
||||
Reference in New Issue
Block a user