66 lines
6.5 KiB
Markdown
66 lines
6.5 KiB
Markdown
# Боковая панель и доска без чередования — план
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** заменить верхнюю панель приложения закреплённой боковой (со свёрткой и выезжающим вариантом на узком экране), убрать чередование дорожек доски и показать просрочку на карточке доски.
|
||
|
||
**Architecture:** `Layout` рисует grid `.shell` из `Sidebar` и `main.page`; прокрутка остаётся у окна. `Sidebar` собирает существующие `ProjectPicker`, `DataStatus`, `ThemeSwitch`, `Menu`; режим (развёрнута / свёрнута / узкий экран) — локальное состояние + `localStorage` + `matchMedia`. Доска: CSS и проп `today` у `Card`.
|
||
|
||
**Tech Stack:** React 19 + TS, Vitest + Testing Library, Playwright.
|
||
|
||
**Spec:** `openspec/changes/sidebar/` (proposal, design, specs/web-app/spec.md)
|
||
|
||
## Global Constraints
|
||
|
||
- Литералы цвета — только в `web/src/styles/tokens.css` (тест `tokens.test.ts`).
|
||
- Ключ свёртки `jira-hub-sidebar`, значение `collapsed`; без записи — развёрнута; доступ к `localStorage` в `try/catch`.
|
||
- Ширины: развёрнутая 240 px, свёрнутая 64 px; узкий экран — `(max-width: 639px)`, строка 56 px, выезжающая панель `min(300px, 85vw)`.
|
||
- Подписи: «Хаб Jira», «Свернуть панель», «Развернуть панель», «Меню», «Разделы», «Доска связей», «Задачи», «Обновить из Jira», «просрочено».
|
||
- Модель доски, golden-эталоны, API, ключи `graph-*` не меняются.
|
||
|
||
## Review Focus
|
||
|
||
- Прокрутка доски у окна: восстановление прокрутки, липкая шапка, полоса дат, ящик «Проблемы», `.hscroll` — после смены каркаса (e2e `board.spec` сценарии прокрутки).
|
||
- Окно карточки и окна диалогов поверх панели (z-index), фокус возвращается после закрытия.
|
||
- Узкий экран: выезжающая панель не оставляет горизонтальной прокрутки и закрывается при переходе по ссылке.
|
||
- Свёрнутая панель: «Обновить из Jira» показывает ход пакета (значок крутится, текст события в `title`/`role=status`).
|
||
- Просрочка: граница — срок сегодня не просрочен; закрытая задача не просрочена.
|
||
|
||
---
|
||
|
||
### Task 1: Доска — без чередования, просрочка на карточке
|
||
|
||
**Files:** `web/src/board/board.css`, `web/src/styles/tokens.css`, `web/src/styles/tokens.test.ts`, `web/src/board/components/Card.tsx`, `web/src/board/components/BoardCanvas.tsx` (передача `today`), `web/src/board/BoardPage.tsx`, `web/src/styles/base.css` (`.visually-hidden`, если нет), тест `web/src/board/components/Card.test.tsx`.
|
||
|
||
- [ ] Тест `Card`: `today="2026-10-22"`, `due="2026-10-20"`, не закрыта → `.due.late`, `title="просрочено"`, текст «просрочено» в DOM; `closed` → без `late`; `due="2026-10-22"` → без `late`.
|
||
- [ ] Тест токенов: в `tokens.css` нет `--lane-alt`.
|
||
- [ ] Реализация (design 9, 10); `cardPropsEqual` сравнивает `today`.
|
||
- [ ] `npx vitest run` зелёный, коммит.
|
||
|
||
### Task 2: Боковая панель (широкий экран)
|
||
|
||
**Files:** create `web/src/shell/Sidebar.tsx`, `web/src/shell/sidebarPref.ts`, `web/src/shell/Sidebar.test.tsx`; modify `Layout.tsx`, `DataStatus.tsx` (проп `compact`), `shell.css`, `projects/projects.css`, `ui/Menu.tsx` (`up`), `ui/ui.css`, `ui/icons.tsx`; delete `AppBar.tsx`, `AppBar.test.tsx` (перенести его проверки в `Sidebar.test.tsx`).
|
||
|
||
**Interfaces:** `readSidebar(): boolean` (true — свёрнута), `saveSidebar(collapsed: boolean): void`; `Sidebar({ section, project }: { section: Section | null; project: string | null })`; `Section` переезжает в `Sidebar.tsx`.
|
||
|
||
- [ ] Тесты: ссылки «Доска связей»/«Задачи» с `aria-current`; «Свернуть панель» → `localStorage['jira-hub-sidebar']==='collapsed'`, ссылки с `aria-label`, повторный рендер — свёрнута; «Сменить токен» очищает токен; в свёрнутой — кнопка «Обновить из Jira» и `role=status`.
|
||
- [ ] Реализация (design 1–3, 6–8).
|
||
- [ ] `npx vitest run` и `npm run lint` зелёные, коммит.
|
||
|
||
### Task 3: Узкий экран
|
||
|
||
**Files:** `Sidebar.tsx`, `Layout.tsx`, `shell.css`, `board/board.css` (`--topbar-h` у `.drawer`), `Sidebar.test.tsx`.
|
||
|
||
- [ ] Тесты (matchMedia замокан на узкий): видна кнопка «Меню», панели нет; «Меню» → панель открыта (`aria-expanded=true`), фокус на первой ссылке; Escape → закрыта, фокус на «Меню»; щелчок по разделу → закрыта.
|
||
- [ ] Реализация (design 4, 5).
|
||
- [ ] vitest зелёный, коммит.
|
||
|
||
### Task 4: e2e, снимки, документация
|
||
|
||
**Files:** `web/e2e/*.spec.ts`, `web/e2e/hub.ts`, `web/e2e/screens.spec.ts`, `ARCHITECTURE.md`.
|
||
|
||
- [ ] Поправить селекторы `.appbar`/сегментов на панель; новый e2e: после прокрутки доски вниз ссылка «Задачи» в панели видна в окне (`toBeInViewport`); свёртка переживает перезагрузку; на 390 «Меню» → «Задачи» → список, `scrollWidth <= innerWidth`.
|
||
- [ ] `screens.spec`: добавить снимки `board-collapsed` (1920) и `menu` (390).
|
||
- [ ] ARCHITECTURE.md: оболочка — боковая панель.
|
||
- [ ] `make check`, `npm run e2e`, `SCREENS=1 npx playwright test e2e/screens.spec.ts` зелёные; коммит, push.
|