mirror of
https://gitverse.ru/kpa39l/vesti.git
synced 2026-09-29 09:55:03 +00:00
selected-layout-stay: отбор остаётся на кандидатах; отобранные — layout на всю высоту (резюме под кнопками, редактор+оригинал в рост, публикация внизу)
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
schema: spec-driven
|
||||
skip_specs: true
|
||||
created: 2026-09-15
|
||||
@@ -0,0 +1,92 @@
|
||||
# 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 %}
|
||||
<div class="flex-shrink-0 mb-2">
|
||||
<div class="border rounded bg-light p-2 small">
|
||||
<span class="badge bg-secondary">резюме</span> {{ selected.summary }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
(из блока «Оригинальный пост» строка с summary удаляется).
|
||||
|
||||
5. `<hr class="flex-shrink-0 my-2">`.
|
||||
|
||||
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`.
|
||||
- Ручная проверка пользователем.
|
||||
@@ -0,0 +1,68 @@
|
||||
# selected-layout-stay: отбор без ухода со страницы + удобный layout отобранных
|
||||
|
||||
## Why
|
||||
|
||||
Два замечания пользователя по веб-интерфейсу:
|
||||
|
||||
1. **«⭐ Отобрать» уводит со страницы кандидатов.** При отметке поста
|
||||
(single-кнопка или bulk) редирект идёт на `/selected` — поток отбора
|
||||
разрывается: после каждого отбора нужно возвращаться назад в очередь
|
||||
кандидатов. Пользователь: «При отметке поста на странице кандидатов не
|
||||
нужно открывать страницу отобранных — остаёмся на странице кандидатов».
|
||||
|
||||
2. **Layout страницы отобранных неудобный:**
|
||||
- поля «Мой пост» и «Оригинальный пост» высотой всего несколько строчек
|
||||
(textarea rows=8, оригинал max-height:300px) — не хватает места для
|
||||
работы с текстом;
|
||||
- резюме оригинального поста спрятано внизу блока оригинала — должно быть
|
||||
под блоком кнопок «Обработать моделью»;
|
||||
- поле комментария и кнопки публикации стоят в середине страницы — должны
|
||||
быть в самом низу;
|
||||
- внизу страницы остаётся пустое место (панели `height: 82vh`, контент не
|
||||
растягивается) — нужно использовать всё окно браузера по высоте.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Отбор остаётся на кандидатах (`web/app.py`)
|
||||
|
||||
- `post_select()` (`POST /posts/{id}/select`): редирект после отбора —
|
||||
`_cand_back(group_by, direction, own, q, src="candidates")` вместо
|
||||
`src="selected"` (пост ушёл из очереди, возвращаемся в кандидаты в той же
|
||||
группировке/фильтрах).
|
||||
- `candidates_bulk()` `action == "select"`: редирект на `back` (текущая
|
||||
группировка + фильтры, src=candidates из скрытого поля формы) вместо
|
||||
перехода в `/selected`.
|
||||
|
||||
### 2. Layout отобранных (`web/templates/selected.html`)
|
||||
|
||||
Правая панель перестраивается по вертикали (flex-колонка на всю высоту окна):
|
||||
|
||||
1. Заголовок поста + бейджи (как сейчас).
|
||||
2. Блок кнопок «🤖 Обработать моделью / ✍️ Переписать / 🚫 Отклонить».
|
||||
3. **Резюме** (`selected.summary`) — сразу под кнопками, отдельный блок.
|
||||
4. Разделитель.
|
||||
5. «Мой пост» (textarea) + «Оригинальный пост» (текст+медиа) — **растянуты на
|
||||
всю оставшуюся высоту** (flex-grow-1, min-height:0, оригинал — overflow-auto).
|
||||
6. **В самом низу**: поле «💬 Мой комментарий» + «✅ Опубликовать» /
|
||||
«💾 Сохранить комментарий» (border-top поверх).
|
||||
|
||||
Высота панелей: `82vh` → `calc(100vh - 160px)` (navbar 4.5rem + заголовок +
|
||||
форма фильтров) — страница использует всё окно, пустого места внизу нет.
|
||||
То же для левой панели (`max-height`) и для страницы кандидатов
|
||||
(`web/templates/candidates.html`), чтобы поведение было консистентным.
|
||||
|
||||
## Why Not
|
||||
|
||||
- Не менять переход после «✅ Опубликовать» (на опубликованные) — осознанное
|
||||
поведение, не просили.
|
||||
- Не добавлять «вернуться к следующему кандидату» автоматом — редирект в
|
||||
очередь с сохранением фильтров достаточен и предсказуем.
|
||||
|
||||
## Impact
|
||||
|
||||
- Файлы: `web/app.py` (2 точки редиректа), `web/templates/selected.html`
|
||||
(правая панель), `web/templates/candidates.html` (высоты панелей).
|
||||
- Данные: без изменений.
|
||||
- Сервис: `vesti-web` (:8400) — перезапуск.
|
||||
- Rollback: откатить коммит/вернуть редиректы на `src="selected"` и высоты
|
||||
`82vh`, перезапустить.
|
||||
@@ -0,0 +1,13 @@
|
||||
# selected-layout-stay
|
||||
|
||||
- [x] Создан OpenSpec change (proposal/design) — `skip_specs: true`
|
||||
- [x] `openspec validate selected-layout-stay` — чисто
|
||||
- [x] web/app.py `post_select()`: редирект на кандидаты (src="candidates") после отбора
|
||||
- [x] web/app.py `candidates_bulk()` action=select: редирект на `back` (кандидаты)
|
||||
- [x] web/templates/selected.html: правое поле — резюме под кнопками, редактор/оригинал flex-grow-1, комментарий+публикация внизу, высоты calc(100vh - 160px)
|
||||
- [x] web/templates/candidates.html: высоты панелей calc(100vh - 160px)
|
||||
- [x] Smoke-тесты (read-only, TestClient): GET /candidates и /selected рендерятся, новая высота, резюме-блок, approve-форма внизу; редиректы select — проверены по коду + редирект single select подтверждён (Location=/candidates)
|
||||
- [x] Перезапуск `sudo systemctl restart vesti-web` (HTTP 200)
|
||||
- [ ] Обновить STATUS.md / TODO.md
|
||||
- [ ] Бэкап (крон 2:45 делает сам, вручную НЕ запускать)
|
||||
- [ ] Финальный e2e (временный select + откат статуса) — требует подтверждения пользователя (правило: не мутировать БД без явного согласия)
|
||||
Reference in New Issue
Block a user