From 42c42428872743084819afd565f563b021878f4c Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Tue, 6 Oct 2026 16:38:17 -0400 Subject: [PATCH 1/2] Add a collapsible categories rail to V2 Admin Settings The Admin Settings categories rail can now collapse to icons, like the workspace section rail, giving its width to the settings cards. Collapsed entries keep their labels as tooltips and screen-reader text. The choice is remembered per admin in a new v2AdminRailCollapsed user preference, kept separate from the workspace and shell rails and allowlisted in /api/user/settings. Bumps the version to 0.261.266 and adds functional and Playwright UI coverage plus feature and admin guide documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- application/single_app/config.py | 2 +- application/single_app/route_backend_users.py | 3 + application/v2_ui/src/lib/userSettings.ts | 12 + .../v2_ui/src/pages/AdminSettingsPage.tsx | 37 +++- docs/admin/index.md | 17 ++ .../V2_ADMIN_SETTINGS_LAYOUT_AND_HIERARCHY.md | 3 +- .../V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md | 98 +++++++++ .../test_v2_admin_settings_rail_collapse.py | 151 +++++++++++++ ui_tests/fixtures/v2_admin_settings.py | 7 +- .../test_v2_admin_settings_rail_collapse.py | 205 ++++++++++++++++++ 10 files changed, 526 insertions(+), 9 deletions(-) create mode 100644 docs/explanation/features/V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md create mode 100644 functional_tests/test_v2_admin_settings_rail_collapse.py create mode 100644 ui_tests/test_v2_admin_settings_rail_collapse.py diff --git a/application/single_app/config.py b/application/single_app/config.py index 6bd64619f..1e040ce02 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -101,7 +101,7 @@ EXECUTOR_TYPE = 'thread' EXECUTOR_MAX_WORKERS = 30 SESSION_TYPE = 'filesystem' -VERSION = "0.261.265" +VERSION = "0.261.266" IS_DEVELOPMENT = is_development_env_enabled() # Opt-out for deployments where App Service Easy Auth is active but the platform diff --git a/application/single_app/route_backend_users.py b/application/single_app/route_backend_users.py index af83d7648..edd089156 100644 --- a/application/single_app/route_backend_users.py +++ b/application/single_app/route_backend_users.py @@ -557,6 +557,9 @@ def user_settings(): # Whether the personal workspace's own section rail is collapsed to # icons. Separate from v2RailCollapsed, which is the shell's rail. 'v2WorkspaceRailCollapsed', + # Whether the V2 Admin Settings categories rail is collapsed to icons. + # Separate from the shell and workspace rails so each keeps its own state. + 'v2AdminRailCollapsed', # V2 document explorer: how the workspace documents list is presented # (view mode, visible columns, page size, details pane) and the saved # filter combinations pinned in its navigation rail. diff --git a/application/v2_ui/src/lib/userSettings.ts b/application/v2_ui/src/lib/userSettings.ts index c4ba25e30..b7fa62b3c 100644 --- a/application/v2_ui/src/lib/userSettings.ts +++ b/application/v2_ui/src/lib/userSettings.ts @@ -73,6 +73,15 @@ export interface UserSettings { */ v2WorkspaceRailCollapsed?: boolean; + /** + * Whether the Admin Settings categories rail shows icons only. + * + * Its own key rather than `v2WorkspaceRailCollapsed` or `v2RailCollapsed`: making room for + * the settings cards should not also change how the workspace pages or the application + * shell are laid out. + */ + v2AdminRailCollapsed?: boolean; + /** * How the workspace documents explorer is presented, and the views pinned in its rail. * @@ -208,6 +217,9 @@ export const WRITABLE_USER_SETTING_KEYS = [ // Separate from v2RailCollapsed, which is the rail of the application shell: // collapsing one should not collapse the other. 'v2WorkspaceRailCollapsed', + // Whether the Admin Settings categories rail is showing icons only. Separate from the + // shell and workspace rails for the same reason they are separate from each other. + 'v2AdminRailCollapsed', // Workspace documents explorer: how the list is presented, and the saved filter // combinations pinned in its navigation rail. 'v2DocumentsPrefs', diff --git a/application/v2_ui/src/pages/AdminSettingsPage.tsx b/application/v2_ui/src/pages/AdminSettingsPage.tsx index 359f91189..4053d8de4 100644 --- a/application/v2_ui/src/pages/AdminSettingsPage.tsx +++ b/application/v2_ui/src/pages/AdminSettingsPage.tsx @@ -26,9 +26,10 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { clsx } from 'clsx'; -import { Loader2, Network, Search, ShieldAlert, TriangleAlert, type LucideIcon } from 'lucide-react'; +import { Loader2, Network, PanelLeftClose, PanelLeftOpen, Search, ShieldAlert, TriangleAlert, type LucideIcon } from 'lucide-react'; import { ApiError, api } from '../lib/apiClient'; import { useBootstrapStore } from '../stores/bootstrapStore'; +import { useUserSettingsStore } from '../stores/userSettingsStore'; import { PageHeader } from '../components/layout/PageHeader'; import { GlassButton, GlassPanel, Skeleton, Toggle } from '../components/ui/primitives'; import { AdminModal } from '../components/admin/AdminModal'; @@ -222,6 +223,10 @@ function buildCapabilityIndex( export function AdminSettingsPage() { const isAdmin = useBootstrapStore((state) => Boolean(state.data?.user?.is_admin)); const bootstrapVersion = useBootstrapStore((state) => state.data?.version); + // The categories rail's icons-only state is its own per-user preference, so making room + // here leaves the workspace and shell rails as they are. + const railCollapsed = useUserSettingsStore((state) => state.settings.v2AdminRailCollapsed === true); + const updateUserSettings = useUserSettingsStore((state) => state.update); /** * Re-read the bootstrap payload once a save lands. @@ -1274,9 +1279,28 @@ export function AdminSettingsPage() {