# selected-layout-stay ## Design ### 1. `web/app.py` — отбор остаётся на кандидатах `post_select()` (`POST /posts/{id}/select`), сейчас: ```python return RedirectResponse(url=_cand_back(group_by, direction, own, q, src="selected", selected=post_id), status_code=302) ``` Стало: ```python return RedirectResponse(url=_cand_back(group_by, direction, own, q, src="candidates"), status_code=302) ``` `candidates_bulk()` `action == "select"`, сейчас: ```python return RedirectResponse(url=_cand_back(group_by, direction, own, q, src="selected"), status_code=302) ``` Стало: ```python return RedirectResponse(url=back, status_code=302) ``` `back` = `/candidates?group_by=<...>&direction=&own=&q=` (src=candidates из скрытого поля формы bulk). ### 2. `web/templates/selected.html` — правая панель на всю высоту Высота панели: `style="height: calc(100vh - 160px);"` (было `82vh`). Левая панель: `max-height: calc(100vh - 160px)` (было `82vh`). Порядок блоков в правой панели (flex-колонка): 1. Заголовок `#{{ selected.id }} …` — `flex-shrink-0` (без изменений). 2. Бейджи — `mb-2`, `flex-shrink-0` (без изменений). 3. Блок кнопок (reclassify/rewrite/reject) — `flex-shrink-0` (текущий блок kнопок, формы без изменений). 4. **Резюме** — новый блок сразу под кнопками: ```html {% if selected.summary %}
резюме {{ selected.summary }}
{% endif %} ``` (из блока «Оригинальный пост» строка с summary удаляется). 5. `
`. 6. Редактор — `row g-2 flex-grow-1` со `style="min-height:0;"`: - колонка «Мой пост»: `d-flex flex-column` + `min-height:0`; форма — `d-flex flex-column flex-grow-1` + `min-height:0`; textarea — `flex-grow-1` + `style="min-height:140px; resize:vertical;"` (было `rows="8"`), кнопка «💾 Сохранить» под ним; - колонка «Оригинальный пост»: `d-flex flex-column` + `min-height:0`; контейнер текста/медиа — `flex-grow-1 overflow-auto` + `min-height:0` (было `max-height:300px`). 7. **Низ (flex-shrink-0)** — блок с `border-top pt-2 mt-2` и approve-формой: поле комментария (`rows="2"`), «✅ Опубликовать», «💾 Сохранить комментарий». Перенесено из середины (was: внутри блока кнопок, `mb-3`). `{{ hid }}` (скрытые поля контекста) — используется во всех формах (уже есть). ### 3. `web/templates/candidates.html` — высоты панелей - Левая панель: `max-height: 82vh` → `max-height: calc(100vh - 160px)`. - Правая панель: `height: 82vh` → `height: calc(100vh - 160px)`. Остальная вёрстка кандидатов без изменений. ## Верификация - `openspec validate selected-layout-stay` — чисто. - Smoke (curl/TestClient): login → POST `/posts/{id}/select` с `group_by=date` → `Location: /candidates?group_by=date` (БЕЗ `/selected`). - Smoke: POST `/candidates/bulk` action=select → `Location: /candidates?...`. - GET `/selected` — в HTML: `calc(100vh - 160px)`, блок «резюме» сразу после кнопок, approve-форма в конце панели. - Перезапуск: `sudo systemctl restart vesti-web`. - Ручная проверка пользователем.