feat(ui): unified sidebar with collapsible sections and enhanced UX (#659)

* feat(ui): add unified sidebar component

Add new unified-sidebar component for layout improvements.
- Export UnifiedSidebar from layout components
- Update root route to use new sidebar structure

* refactor(ui): consolidate unified-sidebar into sidebar folder

Merge the unified-sidebar implementation into the standard sidebar
folder structure. The unified sidebar becomes the canonical sidebar
with improved features including collapsible sections, scroll
indicators, and enhanced mobile support.

- Delete old sidebar.tsx
- Move unified-sidebar components to sidebar/components
- Rename UnifiedSidebar to Sidebar
- Update all imports in __root.tsx
- Remove redundant unified-sidebar folder

* fix(ui): address PR review comments and fix E2E tests for unified sidebar

- Add try/catch for getElectronAPI() in sidebar-footer with window.open fallback
- Use formatShortcut() for OS-aware hotkey display in sidebar-header
- Remove unnecessary optional chaining on project.icon
- Remove redundant ternary in sidebar-navigation className
- Update E2E tests to use new project-dropdown-trigger data-testid

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Stefan de Vogelaere
2026-01-23 02:06:10 +01:00
committed by GitHub
parent afb6e14811
commit 01859f3a9a
12 changed files with 1099 additions and 456 deletions

View File

@@ -14,7 +14,6 @@ import {
authenticateForTests,
handleLoginScreenIfPresent,
waitForNetworkIdle,
sanitizeForTestId,
} from '../utils';
const TEST_TEMP_DIR = createTempDirPath('project-creation-test');
@@ -78,10 +77,10 @@ test.describe('Project Creation', () => {
}
// Wait for project to be set as current and visible on the page
// The project name appears in the project switcher button
// Use ends-with selector since data-testid format is: project-switcher-{id}-{sanitizedName}
const sanitizedProjectName = sanitizeForTestId(projectName);
await expect(page.locator(`[data-testid$="-${sanitizedProjectName}"]`)).toBeVisible({
// The project name appears in the project dropdown trigger
await expect(
page.locator('[data-testid="project-dropdown-trigger"]').getByText(projectName)
).toBeVisible({
timeout: 15000,
});

View File

@@ -18,7 +18,6 @@ import {
authenticateForTests,
handleLoginScreenIfPresent,
waitForNetworkIdle,
sanitizeForTestId,
} from '../utils';
// Create unique temp dir for this test run
@@ -169,11 +168,11 @@ test.describe('Open Project', () => {
}
// Wait for a project to be set as current and visible on the page
// The project name appears in the project switcher button
// Use ends-with selector since data-testid format is: project-switcher-{id}-{sanitizedName}
// The project name appears in the project dropdown trigger
if (targetProjectName) {
const sanitizedName = sanitizeForTestId(targetProjectName);
await expect(page.locator(`[data-testid$="-${sanitizedName}"]`)).toBeVisible({
await expect(
page.locator('[data-testid="project-dropdown-trigger"]').getByText(targetProjectName)
).toBeVisible({
timeout: 15000,
});
}