From 60617de0cbcca525841640d802f426b05d8fb548 Mon Sep 17 00:00:00 2001 From: kpa39l Date: Sun, 13 Sep 2026 20:57:48 +0000 Subject: [PATCH] =?UTF-8?q?candidates:=20=D1=84=D0=B8=D0=BA=D1=81=20=D1=81?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8B=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B8=20(422=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D1=81=D0=B0=D0=B1=D0=BC=D0=B8=D1=82=D0=B5=20bulk-=D1=84=D0=BE?= =?UTF-8?q?=D1=80=D0=BC=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Группировка вынесена из onchange-сабмита bulk-формы в GET-ссылки (/candidates?group_by=...&filters...&selected=...) - Чекбоксы bulk привязаны к форме атрибутом form='bulk-form' (без JS, HTML5) — устранены вложенные формы (невалидный HTML) - Выбор поста — ссылкой GET (selected=id) вместо POST /candidates/select - app.py: добавлен filters_qs (query-string фильтров для ссылок), импорт urllib.parse.quote; /candidates/select оставлен для обратной совместимости (сабмит старых форм) - Тест: смена группировки, bulk reject, выбор поста, фильтры — зелёные --- web/app.py | 11 +- web/templates/candidates.html | 242 +++++++++++++++++----------------- 2 files changed, 133 insertions(+), 120 deletions(-) diff --git a/web/app.py b/web/app.py index 4d3622f..be2c471 100644 --- a/web/app.py +++ b/web/app.py @@ -8,6 +8,7 @@ import secrets import sqlite3 from datetime import datetime from pathlib import Path +from urllib.parse import quote import markdown as md_lib from fastapi import FastAPI, Form, HTTPException, Request, Response @@ -250,9 +251,17 @@ def candidates(request: Request, direction: str = "", status: str = "", own: str continue break conn.close() + # строка параметров фильтров для ссылок (выбор поста, смена группировки) + qs = [] + for k, v in (("direction", direction), ("status", status), ("own", own), ("q", q)): + if v: + qs.append(f"{k}={quote(v)}") + if not selected: + selected = sel["id"] if sel else 0 + filters_qs = "&".join(qs) html = tpl.get_template("candidates.html").render( posts=grouped, counts=counts, status=status, direction=direction, own=own, - q=q, group_by=group_by, selected=sel, error=error, + q=q, group_by=group_by, selected=sel, error=error, filters_qs=filters_qs, directions=DIRECTIONS, STATUS_LABELS=STATUS_LABELS, STATUS_COLORS=STATUS_COLORS, ) return HTMLResponse(html) diff --git a/web/templates/candidates.html b/web/templates/candidates.html index 806b4d8..8bc288d 100644 --- a/web/templates/candidates.html +++ b/web/templates/candidates.html @@ -45,30 +45,24 @@ -
- - - - - +{% set selected_qs = '&selected=' ~ selected.id if selected else '' %} -
-
-
-
- Группировка: - - -
+
+
+
+
+ Группировка: + {% for val, label in [('source', 'по источнику'), ('date', 'по дате'), ('status', 'по статусу')] %} + {% if group_by == val %} + {{ label }} + {% else %} + {{ label }} + {% endif %} + {% endfor %} +
+
{% for g in posts %}
@@ -81,25 +75,17 @@
{% for p in g.posts %}
- - - - - - - - - - + + {{ (p.text or '')[:90] }} + + {{ p.source_name }} · {{ (p.published_at or p.fetched_at) | dt }} + {% if p.is_own %} · ⭐{% endif %} + {% if p.direction %}{{ p.direction }}{% endif %} + + +
{% endfor %}
@@ -108,86 +94,104 @@
Нет кандидатов по фильтру
{% endfor %}
-
-
-
- {% if selected %} -
-
#{{ selected.id }} {{ selected.source_name or '?' }}
- {{ (selected.published_at or selected.fetched_at) | dt }} +
+ + + + + +
+ +
-
- {% if selected.direction %}{{ selected.direction }}{% endif %} - {% if selected.relevance %}{{ selected.relevance }}{% endif %} - {% if selected.interest %}interest {{ selected.interest }}{% endif %} - {% if selected.is_own %}⭐ СВОЙ{% endif %} - {% if selected.fwd_from_channel_id %}↩︎ форвард{% endif %} - 👁 {{ selected.views }} 💬 {{ selected.reactions_total }} - {% if selected.url %}Исходник{% endif %} -
- -
- {% if selected.status != 'published' %} - - - - {% endif %} - {% if selected.status != 'rejected' %} -
- -
- {% endif %} - {% if selected.status != 'published' %} -
- -
-
- -
- {% endif %} -
- -
-
- - - -
- {% if selected.rewritten_text %} -
- - -
- {% endif %} -
- -
-
Оригинальный пост
- {% if selected.text %} -
{{ selected.text | markdown }}
- {% endif %} - {% if selected.media_path %} - {% set media_src = '/media/' ~ selected.media_path.split('/')[-1] %} - {% set media_ext = selected.media_path.lower().rsplit('.', 1)[-1] if '.' in selected.media_path else '' %} - {% if media_ext in ['jpg','jpeg','png','gif','webp'] %} - - медиа поста - - {% elif media_ext in ['mp4','webm','mov'] %} - - {% else %} - 📎 Медиафайл - {% endif %} - {% endif %} - {% if selected.summary %}
резюме {{ selected.summary }}
{% endif %} - - {% else %} -
Выберите кандидата слева
- {% endif %} -
+
- + +
+
+ {% if selected %} +
+
#{{ selected.id }} {{ selected.source_name or '?' }}
+ {{ (selected.published_at or selected.fetched_at) | dt }} +
+
+ {% if selected.direction %}{{ selected.direction }}{% endif %} + {% if selected.relevance %}{{ selected.relevance }}{% endif %} + {% if selected.interest %}interest {{ selected.interest }}{% endif %} + {% if selected.is_own %}⭐ СВОЙ{% endif %} + {% if selected.fwd_from_channel_id %}↩︎ форвард{% endif %} + 👁 {{ selected.views }} 💬 {{ selected.reactions_total }} + {% if selected.url %}Исходник{% endif %} +
+ +
+ {% if selected.status != 'published' %} +
+ +
+ {% endif %} + {% if selected.status != 'rejected' %} +
+ +
+ {% endif %} + {% if selected.status != 'published' %} +
+ +
+
+ +
+ {% endif %} +
+ +
+
+ + + +
+ {% if selected.rewritten_text %} +
+ + +
+ {% endif %} +
+ +
+
Оригинальный пост
+ {% if selected.text %} +
{{ selected.text | markdown }}
+ {% endif %} + {% if selected.media_path %} + {% set media_src = '/media/' ~ selected.media_path.split('/')[-1] %} + {% set media_ext = selected.media_path.lower().rsplit('.', 1)[-1] if '.' in selected.media_path else '' %} + {% if media_ext in ['jpg','jpeg','png','gif','webp'] %} + + медиа поста + + {% elif media_ext in ['mp4','webm','mov'] %} + + {% else %} + 📎 Медиафайл + {% endif %} + {% endif %} + {% if selected.summary %}
резюме {{ selected.summary }}
{% endif %} + + {% else %} +
Выберите кандидата слева
+ {% endif %} +
+
+
{% endblock %} \ No newline at end of file