92 lines
13 KiB
Markdown
92 lines
13 KiB
Markdown
## Context
|
||
|
||
`main` 7911dc7 (после #66/#67). Оболочка: `web/src/shell/Layout.tsx` рисует `AppBar` (`shell/AppBar.tsx`: название,
|
||
`ProjectPicker`, `Segmented` разделов со ссылками, `DataStatus`, `ThemeSwitch`, `Menu` «Ещё» со «Сменить токен») и
|
||
`<main className="page …">`. Прокрутка страниц — у окна (`window.scrollY`): на этом держатся восстановление прокрутки
|
||
доски (`BoardCanvas`), липкая шапка доски (`.sticky`, `top: 0`, высота — в `--head-h`), липкая полоса дат, ящик
|
||
«Проблемы» и полоса горизонтальной прокрутки `.hscroll` (`bottom: 0`). Верхняя панель не липкая (решение 15 #65),
|
||
поэтому уезжает.
|
||
|
||
Доска: `.lane:nth-child(even of .lane){background:var(--lane-alt)}`; колонки дат `.dcol` (`.past` — 5% `--p-crit`,
|
||
`.today` — 7% действия) рисуются в DOM до дорожек, поэтому непрозрачный фон чётной дорожки закрывает их подсветку.
|
||
Карточка (`board/components/Card.tsx`) показывает «до {дата}» без признака просрочки; признак есть только в карточке
|
||
задачи (`issues/card.ts` `isOverdue`, бейдж «просрочено») и в списке (красная дата).
|
||
|
||
## Goals / Non-Goals
|
||
|
||
**Goals:** навигация и «Обновить из Jira» всегда на экране; доска шире не теряет (свёртка); просрочка видна на доске.
|
||
|
||
**Non-Goals:** см. proposal.
|
||
|
||
## Decisions
|
||
|
||
1. **Каркас.** `Layout` рисует `<div class="shell">` с `Sidebar` и `<main class="page …">`. `.shell` — grid
|
||
`grid-template-columns: var(--sidebar-w) minmax(0, 1fr)`; панель `position: sticky; top: 0; height: 100dvh;
|
||
overflow-y: auto`. Прокрутка остаётся у окна — восстановление прокрутки, липкие шапка доски, полоса дат, ящик и
|
||
`.hscroll` работают без изменений. Ширина: развёрнутая 240 px, свёрнутая 64 px (`--sidebar-w`).
|
||
2. **Состав развёрнутой панели** (сверху вниз): строка «Хаб Jira» + кнопка-иконка «Свернуть панель»
|
||
(`aria-expanded`); `ProjectPicker` на всю ширину; `<nav aria-label="Разделы">` — ссылки «Доска связей» и «Задачи»
|
||
со значками, высота 40 px, текущая — фон `--color-bg-selected`, текст действия, `aria-current="page"`; разделитель
|
||
с автоматическим отступом; блок данных `DataStatus` в колонку (агент, «данные на …», кнопка «Обновить из Jira» на
|
||
всю ширину, строка события под кнопкой с переносом — абсолютное позиционирование события из R-7 #65 больше не
|
||
нужно); строка: `ThemeSwitch` слева, `Menu` «Ещё» справа, меню открывается вверх.
|
||
3. **Свёрнутая панель.** Только значки: кнопка «Развернуть панель», метка текущего проекта мелким текстом (до 6
|
||
символов, полный текст в `title`; щелчок разворачивает панель), значки разделов (`aria-label` = название раздела,
|
||
`title`), «Обновить из Jira» — `IconButton` с крутящимся значком при пакете и точкой агента в углу, событие пакета —
|
||
в `title` и в скрытом `role="status"`, тема, меню. Ключ `localStorage` `jira-hub-sidebar`: `collapsed` — свёрнута,
|
||
иначе развёрнута; чтение и запись — в `try/catch`.
|
||
4. **Узкий экран (<640 px).** Панели в потоке нет: сверху липкая строка 56 px — кнопка «Меню» (`IconMenu`,
|
||
`aria-expanded`), «Хаб Jira», справа `IconButton` «Обновить из Jira». «Меню» открывает ту же развёрнутую панель
|
||
поверх страницы (фиксирована слева, ширина `min(300px, 85vw)`, подложка `--color-overlay`); закрывается выбором
|
||
раздела, Escape, щелчком по подложке; фокус при открытии — на первую ссылку раздела, при закрытии — на «Меню».
|
||
Свёртка на узком экране не действует. Режим определяется `matchMedia("(max-width: 639px)")` с подпиской на смену.
|
||
5. **Шапка доски** остаётся липкой с `top: 0` (теперь это верх окна); правило `@media (max-width:640px){.sticky{position:static}}`
|
||
не трогаем, только `top` у `.sticky`, `.dates-bar` и `.drawer` на узком экране сдвигается на высоту строки 56 px
|
||
через `--topbar-h` (0 на широких).
|
||
6. **Меню вверх.** `Menu` получает проп `up?: boolean` → класс `dd--up` (`.dd--up > .dd-menu { top: auto; bottom: calc(100% + 4px) }`).
|
||
7. **Иконки.** Новые в `ui/icons.tsx`: `IconBoard` (граф из трёх узлов), `IconList` (строки), `IconMenu` (три
|
||
линии), `IconSidebar` (прямоугольник с полосой слева).
|
||
8. **`AppBar` удаляется**, `Segmented` больше не нужен оболочке (остаётся в `ui` для списка задач). `.appbar …` в
|
||
`shell.css` и `projects.css` заменяются стилями `.sidebar`.
|
||
9. **Дорожки без чередования.** Правило `.lane:nth-child(even of .lane)` и токен `--lane-alt` удаляются в обеих темах;
|
||
развёрнутые дорожки прозрачны (фон — поверхность `.wrap`), разделитель — верхняя граница; свёрнутая дорожка
|
||
остаётся на `--color-bg-track`.
|
||
10. **Просрочка на карточке доски.** `Card` получает проп `today: string` (ISO, из `BoardPage`, где он уже есть для
|
||
`computeVisible`) и считает `late = !closed && !!n.due && n.due < today`; у `.due` класс `late` — цвет
|
||
`--color-status-error`, `title="просрочено"`, скрытый текст «, просрочено» (`.visually-hidden`). Карточка в слое
|
||
измерения тоже получает `today`, размер не меняется (скрытый текст вне потока). Сравнение в `cardPropsEqual`
|
||
дополняется `today`. Модель доски и эталоны не меняются.
|
||
11. **Тесты.** Vitest: `Sidebar` (разделы и `aria-current`, свёртка и ключ `jira-hub-sidebar`, «Сменить токен»,
|
||
узкий режим: «Меню» открывает и Escape закрывает, выбор раздела закрывает), `Card` (просрочка: незакрытая с
|
||
прошедшим сроком — `late`, закрытая и будущая — нет), тест токенов (нет `--lane-alt`). Playwright: существующие
|
||
сценарии с новыми селекторами; новый — панель видна после прокрутки доски вниз и свёртка переживает перезагрузку;
|
||
`screens.spec` — снимки свёрнутой панели и открытого меню на 390.
|
||
|
||
## Risks / Trade-offs
|
||
|
||
- [Панель 240 px сужает доску на ноутбуке] → свёртка в 64 px, выбор запоминается.
|
||
- [Две копии меню на узком экране (строка и панель)] → нет: на узком экране панель одна, она же выезжает; в строке
|
||
только «Меню» и «Обновить из Jira».
|
||
- [e2e и юнит-тесты, завязанные на `.appbar`] → правятся в той же задаче, что и разметка.
|
||
|
||
## Decisions made without discussion
|
||
|
||
Владелец 22.10.2026: «в графе связей идёт чередование строк по цвету. оно мешает. его или сделать менее заметным или
|
||
убрать вообще, тк не видно просроченные задачи, и закрепить хэдер, а лучше сделать его сайдбаром». Ранее (#65)
|
||
отдал UX на усмотрение агента. Всё ниже — решения агента.
|
||
|
||
| # | Дата | Решение | Обоснование | Цена ошибки |
|
||
|---|---|---|---|---|
|
||
| 1 | 22.10.2026 | Боковая панель, а не липкая верхняя (решения 1–2) | владелец предпочёл «лучше сайдбар»; вертикальный список разделов растёт без переноса строк | средняя: вернуть верхнюю панель — новая вёрстка оболочки |
|
||
| 2 | 22.10.2026 | Чередование убрано совсем, не ослаблено (решение 9) | любой непрозрачный фон дорожки снова закроет колонки дат; разделителя-линии достаточно | низкая: вернуть правило и токен |
|
||
| 3 | 22.10.2026 | Просрочка на карточке доски цветом ошибки + «просрочено» в подсказке (решение 10) | «не видно просроченные» — вне режима «по датам» просрочку на доске не было видно вовсе | низкая: класс и проп |
|
||
| 4 | 22.10.2026 | Свёртка панели в полосу 64 px с запоминанием (решение 3) | доске нужна ширина; раз в спринт граф — тогда удобно свернуть | низкая |
|
||
| 5 | 22.10.2026 | На узком экране — строка с «Меню» и выезжающая панель (решение 4) | закреплённая панель 4–5 строк (M-12 #65) съела бы экран | низкая: узкий экран — только «без поломок» |
|
||
| 6 | 22.10.2026 | Развёрнута по умолчанию, ширина 240 px | на 1920 место есть; название проекта видно целиком | низкая |
|
||
| 7 | 22.10.2026 | R-1: панель без `overflow-y:auto` (вопреки решению 1) | прокрутка панели обрезала бы меню «Ещё» свёрнутой панели, выходящее за 64 px | низкая: на окне ниже ~470 px низ панели обрезан (M-5) |
|
||
| 8 | 22.10.2026 | R-2: в выезжающей панели «Закрыть меню» вместо «Свернуть панель» | свёртка внутри выезжающей панели бессмысленна (решение 4) | нет |
|
||
| 9 | 22.10.2026 | R-3: e2e M-3 переходит по разделам обычным щелчком, не `dispatchEvent` | панель закреплена, щелчок больше не прокручивает доску; тест заодно проверяет закрепление | нет |
|
||
| 10 | 22.10.2026 | R-4 (C-1): `.shell>.page{width:100%}` и `.page` — контейнер (`container: page/inline-size`); пороги раскладки страниц (фильтры списка, прокрутка таблицы, колонка ящика «Проблемы») — запросами к контейнеру с порогами «прежний порог окна минус поля страницы 48 px» | рядом панель 240/64 px: ширина страницы больше не равна ширине окна, и пороги по окну давали таблицу шире страницы | низкая: пороги — числа в CSS |
|
||
| 11 | 22.10.2026 | R-5 (I-1): на узком экране событие пакета — строкой под закреплённой строкой (`aria-hidden`, озвучивает `role=status` кнопки) | на телефоне подсказок нет, результат «Обновить из Jira» был не виден | низкая: строка занимает 1–2 строки по высоте, пока есть событие |
|
||
|