Skip to Content
Руководство для разработчиковDaemon UIWebShell Sidebar — Руководство по кастомизации

WebShell Sidebar — Руководство по кастомизации

WebShellSidebar — это панель списка сессий и навигации, отрисовываемая внутри компонента App web-shell. Этот документ сопоставляет каждую визуальную область с её текущей возможностью кастомизации и указывает области без внешней точки внедрения.

Включение sidebar

Sidebar отключён по умолчанию. Передайте проп sidebar для включения:

import { WebShellWithProviders } from '@qwen-code/web-shell'; <WebShellWithProviders baseUrl="http://localhost:4170" sidebar={true} // simple enable // or with fine-grained options: // sidebar={{ enabled: true, defaultCollapsed: false, ... }} />;

Обзор структуры

┌─────────────────────────────────────┐ │ ① Branding (topRow) │ ✅ customizable ├─────────────────────────────────────┤ │ ② Primary navigation │ ✅ customizable │ [+ New task] [🧩 Plugins] │ │ [📅 Scheduled] [🎯 Goals] │ │ [custom render...] │ ├─────────────────────────────────────┤ │ ③ Project header │ ✅ show/hide │ 📁 Projects ▼ [🔍] [+] │ │ Session list entries... │ │ 📦 Archived sessions │ ├─────────────────────────────────────┤ │ ④ Footer action bar │ ✅ customizable │ [⚙ Settings] v0.19 [☀] [▦] [◧] │ ├─────────────────────────────────────┤ │ ⑤ Resize handle │ ❌ not customizable └─────────────────────────────────────┘

Настраиваемые области

① Branding — branding

interface WebShellSidebarBranding { render?: () => ReactNode; // replace the entire branding row hideWhenCompact?: boolean; // hide when sidebar is collapsed (default: true) }
ЗначениеЭффект
undefined (по умолчанию)Логотип Qwen + текст “Qwen Code”
falseСтрока брендинга полностью скрыта
{ render: () => <MyHeader /> }Полная замена на пользовательский контент
{ hideWhenCompact: false }Показывать брендинг в свёрнутом режиме icon-rail
sidebar={{ branding: { render: () => ( <div style={{ display: 'flex', gap: 8 }}> <img src="/my-logo.svg" alt="" width={24} /> <span>My App</span> </div> ), }, }}

② Primary Navigation — primaryNav

type WebShellSidebarPrimaryNavItem = | 'newTask' // ✏️ New Task button | 'plugins' // 🧩 Plugins button | 'scheduledTasks' // 📅 Scheduled Tasks button | 'goals'; // 🎯 Goals button interface WebShellSidebarPrimaryNavOptions { items?: readonly WebShellSidebarPrimaryNavItem[]; // which built-in buttons to show (default: all) render?: () => ReactNode; // additional custom content after built-in buttons }

Область основной навигации содержит встроенные кнопки, управляемые через items:

  • Все кнопки показываются по умолчанию, если items не задан
  • Показываются только перечисленные кнопки, если items задан
  • Пользовательский контент можно добавить через render() после встроенных кнопок
ЗначениеЭффект
undefined (по умолчанию)Все встроенные кнопки показаны
{ items: ['plugins'] }Только кнопка Plugins
{ items: ['plugins', 'scheduledTasks'] }Plugins + Scheduled Tasks
{ items: [], render: () => ... }Скрыть все встроенные, только свой контент
sidebar={{ primaryNav: { items: ['plugins', 'scheduledTasks'], // hide newTask and goals render: () => ( <button onClick={() => console.log('custom action')}> 🔗 Data Sync </button> ), }, }}
type WebShellSidebarFooterItem = | 'settings' // ⚙ Settings panel | 'version' // version label (e.g. "v0.19.10") | 'theme' // ☀/🌙 light/dark toggle | 'sessionsOverview' // ▦ session overview panel (large screens only) | 'splitView' // ◧ split view (large screens only) | 'daemonStatus' // 📊 daemon status panel | 'collapse'; // ◁/▷ collapse/expand toggle interface WebShellSidebarFooterOptions { items?: readonly WebShellSidebarFooterItem[]; // which built-in items to show (default: all) render?: () => ReactNode; // custom content rendered on the left side, before built-in items }
ЗначениеЭффект
undefined (по умолчанию)Все элементы показаны
falseFooter полностью скрыт
{ items: ['settings', 'theme', 'collapse'] }Показаны только указанные элементы

Footer автоматически адаптируется к узкой ширине: подписи скрываются, а версия убирается ниже определённых порогов.

sidebar={{ footer: { items: ['theme', 'collapse'] }, // minimal footer }}

Пользовательский контент через render() отображается в левой части footer, перед встроенными элементами:

sidebar={{ footer: { items: ['collapse'], render: () => ( <button onClick={() => openHelpCenter()}> ❓ Help </button> ), }, }}

Примечание: 'scheduledTasks' и 'goals' перенесены в область основной навигации (②) и показываются по умолчанию. Они управляются через primaryNav.items, а не через footer.items.

Другие параметры верхнего уровня

interface WebShellSidebarOptions { enabled?: boolean; // show/hide sidebar (default: true when passed) defaultCollapsed?: boolean; // initial collapsed state (persisted in localStorage) showCompactToggle?: boolean; // show the collapse button in the chat area (default: true) branding?: false | WebShellSidebarBranding; primaryNav?: WebShellSidebarPrimaryNavOptions; hideProjectHeader?: boolean; // hide "Projects" header row (default: false = shown) sessionActions?: WebShellSidebarSessionActionsOptions; footer?: false | WebShellSidebarFooterOptions; }

③ Project Header — hideProjectHeader

Управляет видимостью строки заголовка “Projects” (строка с кнопкой сворачивания, иконкой поиска и кнопкой добавления рабочего пространства). По умолчанию false (показывается).

sidebar={{ hideProjectHeader: true, // hide the "项目 ▼ [🔍] [+]" row }}

При скрытии записи списка сессий и архивные сессии продолжают отображаться — удаляется строка заголовка с кнопками действий и панель поиска сессий.

Действия над строками сессий — sessionActions

type WebShellSidebarSessionActionItem = | 'details' // 📝 Details (dropdown sub-menu) | 'rename' // ✏️ Rename (dropdown menu) | 'group' // 📁 Group/Move to folder (dropdown menu) | 'export' // 📤 Export chat history (dropdown menu) | 'delete' // 🗑 Delete session (dropdown menu) | 'pin' // 📌 Pin/Unpin (inline button) | 'archive'; // 📦 Archive (inline button) /** Subset with working inline (hover-button) handlers. */ type WebShellSidebarSessionInlineActionItem = | 'pin' | 'archive' | 'rename' | 'export' | 'delete'; interface WebShellSidebarSessionActionsOptions { items?: readonly WebShellSidebarSessionActionItem[]; // which actions to show (default: all) inlineItems?: readonly WebShellSidebarSessionInlineActionItem[]; // which items appear as inline buttons (default: ['pin', 'archive']) }

Управляет тем, какие кнопки действий отображаются в строках сессий:

  • items: Главный переключатель всех действий (и inline, и dropdown). Если элемента нет в items, он скрыт везде.
  • inlineItems: Управляет тем, какие элементы отображаются как inline-кнопки (при наведении). По умолчанию ['pin', 'archive']. Можно использовать только элементы с работающими inline-обработчиками: 'pin', 'archive', 'rename', 'export', 'delete'. 'details' и 'group' доступны только через dropdown.

Приоритет видимости: И items, И встроенное условие элемента, И inlineItems должны все сработать, чтобы inline-кнопка отобразилась. Например, delete как inline требует, чтобы 'delete' был и в items, и в inlineItems.

ЗначениеЭффект
undefined (по умолчанию)Все действия показаны, pin + archive как inline
{ inlineItems: ['pin', 'delete'] }Pin + delete как inline-кнопки
{ inlineItems: [] }Никаких inline-кнопок
{ inlineItems: ['archive', 'export'] }Archive + export как inline-кнопки

Триггер dropdown (⋮) автоматически скрывается, когда ни один dropdown-элемент не включён. Inline-кнопки (pin, archive) показываются только когда и их условие capability, и items их включают.

sidebar={{ sessionActions: { items: ['details', 'rename', 'export', 'delete', 'pin'], // which actions to show (master control) inlineItems: ['pin', 'delete'], // pin + delete as inline buttons }, }}

Области без кастомизации

Projects / Workspaces (внутри списка сессий)

Когда список сессий виден, следующие подобласти отрисовываются, но не настраиваются индивидуально:

АспектДетали
Источник данныхХук useSessions() → daemon API (эндпоинт /sessions)
Сортировка списка сессийПо времени создания, по убыванию
Отрисовка строки сессииВнутренний renderSessionRow useCallback — не инъектируется
Поиск / фильтрацияВстроенная панель поиска с клиентским текстовым сопоставлением
Группы сессийКомпонент SessionGroupSection с 6 предустановленными цветами + custom hex
Секции рабочих пространствWorkspaceSection для каждого daemon рабочего пространства, не заменяема
Диалог добавления рабочего пространстваВстроенный AddWorkspaceDialog

⑤ Resize handle

  • Ручка перетаскивания на правом краю для изменения ширины sidebar
  • Ширина сохраняется в localStorage
  • Не настраивается

Пропы поведения в runtime

Эти WebShellProps влияют на поведение sidebar косвенно:

ПропЭффект
onNewSessionПереопределить обработчик новой сессии
onLoadSessionПереопределить логику загрузки сессии
onSessionIdChangeРеагировать на переключение сессий
splitSessionIdsУправлять сессиями split-view внешне
theme / onThemeChangeУправлять / отслеживать тему
language / onLanguageChangeУправлять / отслеживать язык UI

Свёрнутое и мобильное состояния

СостояниеПоведение
ExpandedПолный sidebar с текстовыми подписями
CollapsedРежим icon-rail (только логотип, иконка пера, иконки действий)
MobileDrawer выезжает слева с backdrop overlay

Состояние сворачивания сохраняется в localStorage под ключом qwen-code-web-shell-sidebar-collapsed.

Расположения исходников

КомпонентФайл
WebShellSidebarpackages/web-shell/client/components/sidebar/WebShellSidebar.tsx
SessionGroupSectionpackages/web-shell/client/components/sidebar/SessionGroupSection.tsx
WorkspaceSectionpackages/web-shell/client/components/sidebar/WorkspaceSection.tsx
Sidebar stylespackages/web-shell/client/components/sidebar/WebShellSidebar.module.css
App integrationpackages/web-shell/client/App.tsx (search WebShellSidebar)
Entry point (dev)packages/web-shell/client/main.tsx (sidebar: true)
Last updated on