diff --git a/dashboard/src/components/layout/Layout.tsx b/dashboard/src/components/layout/Layout.tsx index 873a133f..8f0a23c8 100644 --- a/dashboard/src/components/layout/Layout.tsx +++ b/dashboard/src/components/layout/Layout.tsx @@ -130,7 +130,7 @@ export function Layout({ children }: LayoutProps) { key="settings-sidebar" className="relative z-40 hidden shrink-0 lg:block" initial={{ width: 0, opacity: 0 }} - animate={{ width: sidebarOpen ? 240 : 64, opacity: 1 }} + animate={{ width: sidebarOpen ? 224 : 64, opacity: 1 }} exit={{ width: 0, opacity: 0 }} transition={{ type: 'spring', diff --git a/dashboard/src/components/layout/Sidebar.tsx b/dashboard/src/components/layout/Sidebar.tsx index 0b09d8f6..0b716ea0 100644 --- a/dashboard/src/components/layout/Sidebar.tsx +++ b/dashboard/src/components/layout/Sidebar.tsx @@ -32,8 +32,8 @@ export function Sidebar({ 'fixed inset-y-0 left-0 z-50 isolate flex flex-col border-r transition-all duration-300 lg:relative lg:z-0 lg:h-full', inheritsPageBackground ? 'bg-transparent' : 'bg-card', // 移动端始终显示完整宽度,桌面端根据 sidebarOpen 切换 - 'w-60 lg:w-auto', - sidebarOpen ? 'lg:w-60' : 'lg:w-16', + 'w-56 lg:w-auto', + sidebarOpen ? 'lg:w-56' : 'lg:w-16', mobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0' )} > diff --git a/dashboard/src/index.css b/dashboard/src/index.css index eb6d145f..4d16efba 100644 --- a/dashboard/src/index.css +++ b/dashboard/src/index.css @@ -183,7 +183,7 @@ --layout-space-lg: 1.5rem; --layout-space-xl: 2rem; --layout-space-2xl: 3rem; - --layout-sidebar-width: 15rem; + --layout-sidebar-width: 14rem; --layout-header-height: 3.5rem; --layout-max-content-width: 1280px; diff --git a/src/A_memorix/host_service.py b/src/A_memorix/host_service.py index 5d744f41..5e915423 100644 --- a/src/A_memorix/host_service.py +++ b/src/A_memorix/host_service.py @@ -20,6 +20,8 @@ if TYPE_CHECKING: logger = get_logger("a_memorix.host_service") +_INTERNAL_CONFIG_FIELDS = {"field_docs", "_validate_any", "suppress_any_warning"} + def _get_config_manager(): from src.config.config import config_manager @@ -47,6 +49,18 @@ def _to_builtin_data(obj: Any) -> Any: return obj +def _strip_internal_config_fields(obj: Any) -> Any: + if isinstance(obj, dict): + return { + str(key): _strip_internal_config_fields(value) + for key, value in obj.items() + if str(key) not in _INTERNAL_CONFIG_FIELDS + } + if isinstance(obj, list): + return [_strip_internal_config_fields(value) for value in obj] + return obj + + def _backup_config_file(path: Path) -> Optional[Path]: if not path.exists(): return None @@ -309,13 +323,15 @@ class AMemorixHostService: web_config = payload.get("web") if isinstance(web_config, dict) and "import_config" in web_config: web_config["import"] = web_config.pop("import_config") - return _to_builtin_data(payload) if isinstance(payload, dict) else {} + payload = _to_builtin_data(payload) if isinstance(payload, dict) else {} + return _strip_internal_config_fields(payload) if isinstance(payload, dict) else {} @staticmethod def _runtime_dict_to_bot_config_dict(config: Dict[str, Any]) -> Dict[str, Any]: payload = _to_builtin_data(config) if not isinstance(payload, dict): return {} + payload = _strip_internal_config_fields(payload) web_config = payload.get("web") if isinstance(web_config, dict) and "import_config" in web_config and "import" not in web_config: web_config["import"] = web_config.pop("import_config")