Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion application/single_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.261.266"
VERSION = "0.261.267"
IS_DEVELOPMENT = is_development_env_enabled()

# Opt-out for deployments where App Service Easy Auth is active but the platform
Expand Down
3 changes: 3 additions & 0 deletions application/single_app/route_backend_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions application/v2_ui/src/lib/userSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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',
Expand Down
37 changes: 32 additions & 5 deletions application/v2_ui/src/pages/AdminSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Check warning on line 29 in application/v2_ui/src/pages/AdminSettingsPage.tsx

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
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';
Expand Down Expand Up @@ -222,6 +223,10 @@
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.
Expand Down Expand Up @@ -1274,9 +1279,28 @@
<div className="flex min-h-0 flex-1">
<aside
aria-label="Settings categories"
className="hidden w-56 shrink-0 overflow-y-auto border-r border-edge p-3 lg:block"
className={clsx(
'hidden shrink-0 overflow-y-auto border-r border-edge transition-[width] motion-reduce:transition-none lg:block',

Check warning on line 1283 in application/v2_ui/src/pages/AdminSettingsPage.tsx

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.
railCollapsed ? 'w-16 px-2 py-3' : 'w-56 p-3',
)}
>
<div className="space-y-0.5">
<button
type="button"
onClick={() => updateUserSettings({ v2AdminRailCollapsed: !railCollapsed })}
aria-label={railCollapsed ? 'Expand settings categories' : 'Collapse settings categories'}
aria-expanded={!railCollapsed}
aria-controls="admin-settings-category-list"
title={railCollapsed ? 'Expand settings categories' : 'Collapse settings categories'}
className={clsx(
'mb-2 flex w-full items-center gap-2 rounded-lg py-1.5 text-xs text-text-3 transition-colors hover:bg-surface-2 hover:text-text-1',
railCollapsed ? 'justify-center px-2' : 'px-3',
)}
>
{railCollapsed ? <PanelLeftOpen size={15} aria-hidden="true" /> : (

Check warning on line 1299 in application/v2_ui/src/pages/AdminSettingsPage.tsx

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.
<><PanelLeftClose size={15} aria-hidden="true" /><span>Collapse</span></>

Check warning on line 1300 in application/v2_ui/src/pages/AdminSettingsPage.tsx

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Moderate - Changed line contains obfuscation, dynamic loading, or hidden payload marker. Recommendation%3A Confirm the changed code is not hiding behavior, decoding payloads, or bypassing normal review.
)}
</button>
<div id="admin-settings-category-list" className="space-y-0.5">
{categories.map((category) => {
const active = activeGroup === category.id;
return (
Expand All @@ -1285,9 +1309,11 @@
type="button"
disabled={delegationDirty}
aria-pressed={active}
title={railCollapsed ? category.label : undefined}
onClick={() => setActiveGroup(category.id)}
className={clsx(
'flex w-full items-center gap-2.5 rounded-lg px-3 py-2.5 text-left text-sm transition-colors',
'flex w-full items-center gap-2.5 rounded-lg py-2.5 text-left text-sm transition-colors',
railCollapsed ? 'justify-center px-2' : 'px-3',
'disabled:cursor-not-allowed disabled:opacity-60',
active
? 'bg-accent-soft font-semibold text-accent'
Expand All @@ -1299,7 +1325,8 @@
aria-hidden="true"
className={clsx('shrink-0', active ? 'text-accent' : 'text-text-3')}
/>
<span className="min-w-0 flex-1">{category.label}</span>
{/* Collapsed, the label stays as the button's accessible name. */}
<span className={railCollapsed ? 'sr-only' : 'min-w-0 flex-1'}>{category.label}</span>
</button>
);
})}
Expand Down
17 changes: 17 additions & 0 deletions docs/admin/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,23 @@

This layout was implemented in **0.261.258**.

### Collapsing the category list

The category list on the left can shrink to a strip of icons, giving its width to the
settings cards. That matters most at larger text sizes, where the list grows with the
text, and on mid-sized screens, where the extra width can leave room for the **On this
page** list. Select **Collapse** at the top of the list to shrink it, and the expand
icon in the same place to bring the labels back.

Collapsed, each icon still switches category, shows its category name as a tooltip,

Check warning on line 84 in docs/admin/index.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.
and is announced by name to screen readers. The choice is saved with your user
preferences, so it applies wherever you sign in, and it is kept separately from the
workspace section rail and the main navigation, so collapsing one leaves the others
alone. On narrower windows the page offers a category drop-down instead of the list,
whichever way the list was left.

The collapsible category list was added in **0.261.267**.

## Settings groups

| Group | What it controls | Tabs | Link |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ packages, settings, routes, or browser asset sources are required.
container. At 76rem and above it becomes a grid of the cards and a 15rem index; the
whole frame stays within 112rem so an ultra-wide monitor does not stretch it. The
search bar aligns with the content instead of floating in the middle. The category
rail shows each group's icon from the navigation definition.
rail shows each group's icon from the navigation definition, and can be collapsed to
those icons; see [V2 Admin Settings Rail Collapse](V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md).

### Section presentation

Expand Down
98 changes: 98 additions & 0 deletions docs/explanation/features/V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# V2 Admin Settings Rail Collapse

## Overview

The V2 workspace pages let people collapse their section rail to icons to give the
content more room. V2 Admin Settings now does the same for its **Settings categories**
rail. A control at the top of the rail shrinks it from 14rem to a 4rem strip of category
icons, the settings cards take the freed width, and the choice is remembered per
administrator.

The admin page shares its width with up to three navigation columns: the application
shell's rail, the categories rail, and, on wide screens, the **On this page** index. The
categories rail is sized in `rem`, so it grows with the text size and reaches 448px at
the largest size. Collapsing it returns that room to the cards, and on mid-sized screens
can make room for the index, whose container query responds to the wider pane on its own.

## Implemented in version: **0.261.267**

The application version is maintained in `application/single_app/config.py`.

**Dependencies:** the React/TypeScript V2 UI, local `lucide-react` icons
(`PanelLeftClose`, `PanelLeftOpen`), and the `/api/user/settings` preference store. No new
packages, routes, admin settings, or browser asset sources are required.

## Technical specifications

### Behaviour

| State | Rail | Category entries | Control |
| --- | --- | --- | --- |
| Expanded (default) | `w-56` | Icon and label | `PanelLeftClose` with **Collapse** |
| Collapsed | `w-16` | Icon only; the label stays as screen-reader text and a `title` tooltip | `PanelLeftOpen` |

Check warning on line 32 in docs/explanation/features/V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.

- The control is named "Collapse settings categories" or "Expand settings categories",
and carries `aria-expanded` and `aria-controls="admin-settings-category-list"`.
- Category entries keep `aria-pressed` on the active category and stay locked while Call
agent changes are unsaved. The collapse control is not locked, because it does not

Check warning on line 37 in docs/explanation/features/V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.
change the category.
- The width change animates, except when the browser asks for reduced motion.
- The rail is still drawn only at the `lg` breakpoint and above. Narrower windows use the
existing **Settings category** select whatever the preference says.

### Persistence

| Key | Contents |
| --- | --- |
| `v2AdminRailCollapsed` | `true` when the categories rail shows icons only. Absent, or any other value, means expanded. |

The key is whitelisted in `allowed_keys` in `route_backend_users.py` and declared in
`WRITABLE_USER_SETTING_KEYS` in `userSettings.ts`. The route drops an unlisted key without
reporting it, so both are required. Writes go through `useUserSettingsStore.update`, which
debounces them and rolls the value back if the save fails.

The key is deliberately separate from `v2WorkspaceRailCollapsed`, the workspace section
rail, and `v2RailCollapsed`, the application shell's rail. Making room on the admin page
should not rearrange the workspace pages or the shell.

### File structure

| File | Change |
| --- | --- |
| `application/v2_ui/src/pages/AdminSettingsPage.tsx` | Collapse control, collapsed rail and entries. |
| `application/v2_ui/src/lib/userSettings.ts` | `v2AdminRailCollapsed` type and writable key. |
| `application/single_app/route_backend_users.py` | `v2AdminRailCollapsed` added to `allowed_keys`. |
| `ui_tests/fixtures/v2_admin_settings.py` | `open(preferences=...)` seeds saved user preferences. |

## Usage

Open **Admin Settings** in V2 and select **Collapse** at the top of the category list.
Select the expand icon in the same place to bring the labels back. Hover an icon to see
its category name. See the
[administration guide](../../admin/index.md#collapsing-the-category-list).

## Testing and validation

- `functional_tests/test_v2_admin_settings_rail_collapse.py` pins the contracts: the page
reads and writes `v2AdminRailCollapsed`, and neither other rail key, before its
non-admin return; the control's accessibility attributes; screen-reader labels and
tooltips on collapsed entries; the control staying usable while categories are locked;

Check warning on line 79 in docs/explanation/features/V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.
and the key being in both the route whitelist and the client's writable keys.
- `ui_tests/test_v2_admin_settings_rail_collapse.py` drives the built SPA with intercepted
APIs: the rail goes from 224px to 64px and the cards gain the width, the save carries
only the admin rail key, the choice survives a reload and can be undone, collapsed icons
still switch categories, the control works from the keyboard and keeps focus, the
collapsed rail fits at 200% text, and the select replaces the rail on narrow screens, in
light and dark.
- `functional_tests/test_v2_settings_and_workspace_tags.py` keeps checking that every key
the client writes is whitelisted.

### Known limitations

- Until the user's preferences load, the rail draws expanded, the same as the workspace
rail.
- The classic Admin Settings page is unchanged.

Related: [V2 Admin Settings Layout and Hierarchy](V2_ADMIN_SETTINGS_LAYOUT_AND_HIERARCHY.md),
and [V2 Documents Explorer](V2_DOCUMENTS_EXPLORER.md), which introduced the collapsible
workspace rail.
9 changes: 9 additions & 0 deletions docs/explanation/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

For feature-focused and fix-focused drill-downs by version, see [Features by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/features) and [Fixes by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/fixes).

### **(v0.261.267)**

#### User Interface Enhancements

* **Collapsible Category List in V2 Admin Settings**
* The category list on the left of V2 Admin Settings can now collapse to a strip of icons, as the workspace section rail does, giving its width to the settings cards. **Collapse** sits at the top of the list. Collapsed, each icon still switches category, shows its name as a tooltip, and is announced by name to screen readers.

Check warning on line 10 in docs/explanation/release_notes.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains AI, plugin, agent, or workspace boundary marker. Recommendation%3A Check whether prompts, chat history, uploaded documents, embeddings, citations, settings, or identity can cross a new boundary.
* The choice is remembered per administrator in a new `v2AdminRailCollapsed` user preference, kept separate from the workspace section rail and the main navigation so collapsing one leaves the others alone. Narrower windows keep the category drop-down.
* (Ref: `AdminSettingsPage.tsx`, `userSettings.ts`, `route_backend_users.py`, `test_v2_admin_settings_rail_collapse.py`, `ui_tests/test_v2_admin_settings_rail_collapse.py`, [V2 Admin Settings Rail Collapse](features/V2_ADMIN_SETTINGS_RAIL_COLLAPSE.md))

### **(v0.261.265)**

#### User Interface Enhancements
Expand Down
Loading
Loading