selected-layout-stay: отбор остаётся на кандидатах; отобранные — layout на всю высоту (резюме под кнопками, редактор+оригинал в рост, публикация внизу)

This commit is contained in:
kpa39l
2026-09-15 18:17:07 +00:00
parent 51a13de28c
commit 8d26c97e6b
8 changed files with 283 additions and 97 deletions
+2 -2
View File
@@ -50,7 +50,7 @@
<div class="row g-0">
<!-- ЛЕВАЯ ПАНЕЛЬ: список + группировка + массовые операции -->
<div class="col-md-4">
<div class="border rounded p-2 d-flex flex-column" style="max-height: 82vh; background:#fff;">
<div class="border rounded p-2 d-flex flex-column" style="max-height: calc(100vh - 160px); background:#fff;">
<div class="d-flex flex-wrap align-items-center mb-1 gap-1">
<span class="me-1 text-muted small">Группировка:</span>
{% for val, label in [('source', 'источник'), ('date', 'дата'), ('status', 'статус')] %}
@@ -119,7 +119,7 @@
<!-- ПРАВАЯ ПАНЕЛЬ: детали выбранного -->
<div class="col-md-8">
<div class="border rounded p-3 bg-white d-flex flex-column" style="height: 82vh;">
<div class="border rounded p-3 bg-white d-flex flex-column" style="height: calc(100vh - 160px);">
{% if selected %}
<div class="d-flex justify-content-between align-items-start flex-shrink-0">
<h5 class="mb-0">#{{ selected.id }} {{ selected.source_name or '?' }}</h5>
+99 -90
View File
@@ -43,7 +43,7 @@
<div class="row g-0">
<!-- ЛЕВАЯ ПАНЕЛЬ: список отобранных -->
<div class="col-md-4">
<div class="border rounded p-2 d-flex flex-column" style="max-height: 82vh; background:#fff;">
<div class="border rounded p-2 d-flex flex-column" style="max-height: calc(100vh - 160px); background:#fff;">
<div class="d-flex flex-wrap align-items-center mb-1 gap-1">
<span class="me-1 text-muted small">Группировка:</span>
{% for val, label in [('source', 'источник'), ('date', 'дата'), ('status', 'статус')] %}
@@ -111,103 +111,112 @@
</div>
<!-- ПРАВАЯ ПАНЕЛЬ: детали отобранного + подготовка своего поста -->
<div class="col-md-8">
<div class="border rounded p-3 bg-white d-flex flex-column" style="height: 82vh;">
{% if selected %}
<div class="d-flex justify-content-between align-items-start flex-shrink-0">
<h5 class="mb-0">#{{ selected.id }} {{ selected.source_name or '?' }}</h5>
<small class="text-muted">{{ (selected.published_at or selected.fetched_at) | dt }}</small>
</div>
<div class="mb-2">
{% if selected.direction %}<span class="badge bg-secondary">{{ selected.direction }}</span>{% endif %}
{% if selected.relevance %}<span class="badge bg-{{ 'success' if selected.relevance=='critical' else 'info' }}">{{ selected.relevance }}</span>{% endif %}
{% if selected.interest %}<span class="badge bg-warning text-dark">interest {{ selected.interest }}</span>{% endif %}
{% if selected.is_own %}<span class="badge bg-warning text-dark">⭐ СВОЙ</span>{% endif %}
{% if selected.fwd_from_channel_id %}<span class="badge bg-light text-dark">↩︎ форвард</span>{% endif %}
<small class="text-muted ms-2">👁 {{ selected.views }} 💬 {{ selected.reactions_total }}</small>
{% if selected.url %}<a class="btn btn-sm btn-outline-secondary ms-2" href="{{ selected.url }}" target="_blank">Исходник</a>{% endif %}
</div>
<div class="mb-3 flex-shrink-0">
{% set hid %}<input type="hidden" name="group_by" value="{{ group_by }}"><input type="hidden" name="direction" value="{{ direction }}"><input type="hidden" name="own" value="{{ own }}"><input type="hidden" name="q" value="{{ q }}"><input type="hidden" name="src" value="selected">{% endset %}
<div class="d-flex flex-wrap gap-2 mb-2">
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reclassify">
{{ hid }}
<button class="btn btn-info" type="submit" title="Прогнать через модель (qwen3:8b): направление, релевантность, интерес, резюме">🤖 Обработать моделью</button>
</form>
{% endif %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/rewrite">
{{ hid }}
<button class="btn btn-outline-primary" type="submit" title="Сгенерировать черновик своего поста через модель — затем отредактируйте в поле справа">✍️ Переписать</button>
</form>
{% endif %}
{% if selected.status != 'rejected' and selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reject">
{{ hid }}
<button class="btn btn-outline-danger" type="submit">🚫 Отклонить</button>
</form>
{% endif %}
<div class="col-md-8">
<div class="border rounded p-3 bg-white d-flex flex-column" style="height: calc(100vh - 160px);">
{% if selected %}
<div class="d-flex justify-content-between align-items-start flex-shrink-0">
<h5 class="mb-0">#{{ selected.id }} {{ selected.source_name or '?' }}</h5>
<small class="text-muted">{{ (selected.published_at or selected.fetched_at) | dt }}</small>
</div>
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/approve" id="approve-form">
{{ hid }}
<label class="form-label small text-muted mb-0 d-block">💬 Мой комментарий (будет первым в канале):</label>
<textarea class="form-control form-control-sm mt-1" name="comment" rows="2"
placeholder="Комментарий/анонс…">{{ selected.comment or '' }}</textarea>
<div class="mt-2 d-flex flex-wrap gap-2">
<button class="btn btn-success" type="submit" title="Опубликовать в канал: комментарий (если есть) первым, затем ваш текст (поле справа)/пересказ, картинка, ссылка">✅ Опубликовать</button>
<button class="btn btn-sm btn-outline-secondary" type="submit"
formaction="/posts/{{ selected.id }}/comment"
title="Сохранить комментарий в черновик (не публикует). Он подтянется при следующей публикации">💾 Сохранить комментарий</button>
</div>
</form>
{% endif %}
</div>
<!-- подготовка своего поста: редактор + оригинал рядом -->
<hr class="flex-shrink-0">
<div class="row g-2 flex-shrink-0">
<div class="col-md-6">
<h6 class="text-muted">✍️ Мой пост (редактируйте/сохраните — пойдёт в канал от вашего имени)</h6>
<form method="post" action="/posts/{{ selected.id }}/rewrite-save" class="row g-1">
<div class="mb-2 flex-shrink-0">
{% if selected.direction %}<span class="badge bg-secondary">{{ selected.direction }}</span>{% endif %}
{% if selected.relevance %}<span class="badge bg-{{ 'success' if selected.relevance=='critical' else 'info' }}{{ 'border' if selected.relevance=='critical' else '' }}">{{ selected.relevance }}</span>{% endif %}
{% if selected.interest %}<span class="badge bg-warning text-dark">interest {{ selected.interest }}</span>{% endif %}
{% if selected.is_own %}<span class="badge bg-warning text-dark">⭐ СВОЙ</span>{% endif %}
{% if selected.fwd_from_channel_id %}<span class="badge bg-light text-dark">↩︎ форвард</span>{% endif %}
<small class="text-muted ms-2">👁 {{ selected.views }} 💬 {{ selected.reactions_total }}</small>
{% if selected.url %}<a class="btn btn-sm btn-outline-secondary ms-2" href="{{ selected.url }}" target="_blank">Исходник</a>{% endif %}
</div>
{% set hid %}<input type="hidden" name="group_by" value="{{ group_by }}"><input type="hidden" name="direction" value="{{ direction }}"><input type="hidden" name="own" value="{{ own }}"><input type="hidden" name="q" value="{{ q }}"><input type="hidden" name="src" value="selected">{% endset %}
<!-- Кнопки действий -->
<div class="d-flex flex-wrap gap-2 mb-2 flex-shrink-0">
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reclassify">
{{ hid }}
<textarea class="form-control form-control-sm" name="rewritten_text" rows="8">{{ selected.rewritten_text or '' }}</textarea>
<div class="col-auto mt-1">
<button class="btn btn-sm btn-outline-primary" type="submit">💾 Сохранить</button>
<button class="btn btn-info" type="submit" title="Прогнать через модель (qwen3:8b): направление, релевантность, интерес, резюме">🤖 Обработать моделью</button>
</form>
{% endif %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/rewrite">
{{ hid }}
<button class="btn btn-outline-primary" type="submit" title="Сгенерировать черновик своего поста через модель — затем отредактируйте в поле справа">✍️ Переписать</button>
</form>
{% endif %}
{% if selected.status != 'rejected' and selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reject">
{{ hid }}
<button class="btn btn-outline-danger" type="submit">🚫 Отклонить</button>
</form>
{% endif %}
</div>
<!-- Резюме — сразу под кнопками -->
{% 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 %}
<hr class="flex-shrink-0 my-2">
<!-- подготовка своего поста: редактор + оригинал рядом, на всю оставшуюся высоту -->
<div class="row g-2 flex-grow-1" style="min-height:0;">
<div class="col-md-6 d-flex flex-column" style="min-height:0;">
<h6 class="text-muted">✍️ Мой пост (редактируйте/сохраните — пойдёт в канал от вашего имени)</h6>
<form method="post" action="/posts/{{ selected.id }}/rewrite-save" class="row g-1 d-flex flex-column flex-grow-1" style="min-height:0;">
{{ hid }}
<textarea class="form-control form-control-sm flex-grow-1" name="rewritten_text" rows="8" style="flex-grow:1; min-height:140px; resize:vertical;">{{ selected.rewritten_text or '' }}</textarea>
<div class="col-auto mt-1">
<button class="btn btn-sm btn-outline-primary" type="submit">💾 Сохранить</button>
</div>
</form>
</div>
<div class="col-md-6 d-flex flex-column" style="min-height:0;">
<h6 class="text-muted">Оригинальный пост</h6>
<div class="border rounded p-2 bg-light small overflow-auto flex-grow-1" style="min-height:0;">
{% if selected.text %}
<div class="post-text">{{ selected.text | markdown }}</div>
{% 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'] %}
<a href="{{ media_src }}" target="_blank" title="Открыть полноразмер">
<img src="{{ media_src }}" class="img-fluid rounded mt-2 d-block" style="max-height:50vh" alt="медиа поста">
</a>
{% elif media_ext in ['mp4','webm','mov'] %}
<video src="{{ media_src }}" controls class="mt-2 d-block" style="max-height:50vh"></video>
{% else %}
<a class="btn btn-sm btn-outline-secondary mt-2" href="{{ media_src }}" target="_blank">📎 Медиафайл</a>
{% endif %}
{% endif %}
</div>
</div>
</div>
<hr class="flex-shrink-0 my-2">
<!-- Комментарий + публикация — в самом низу -->
{% if selected.status != 'published' %}
<div class="flex-shrink-0 pt-2 border-top">
<form method="post" action="/posts/{{ selected.id }}/approve" id="approve-form">
{{ hid }}
<label class="form-label small text-muted mb-0 d-block">💬 Мой комментарий (будет первым в канале):</label>
<textarea class="form-control form-control-sm mt-1" name="comment" rows="2"
placeholder="Комментарий/анонс…">{{ selected.comment or '' }}</textarea>
<div class="mt-2 d-flex flex-wrap gap-2">
<button class="btn btn-success" type="submit" title="Опубликовать в канал: комментарий (если есть) первым, затем ваш текст (поле справа)/пересказ, картинка, ссылка">✅ Опубликовать</button>
<button class="btn btn-sm btn-outline-secondary" type="submit"
formaction="/posts/{{ selected.id }}/comment"
title="Сохранить комментарий в черновик (не публикует). Он подтянется при следующей публикации">💾 Сохранить комментарий</button>
</div>
</form>
</div>
<div class="col-md-6">
<h6 class="text-muted">Оригинальный пост</h6>
<div class="border rounded p-2 bg-light small overflow-auto" style="max-height:300px;">
{% if selected.text %}
<div class="post-text">{{ selected.text | markdown }}</div>
{% 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'] %}
<a href="{{ media_src }}" target="_blank" title="Открыть полноразмер">
<img src="{{ media_src }}" class="img-fluid rounded mt-2 d-block" style="max-height:320px" alt="медиа поста">
</a>
{% elif media_ext in ['mp4','webm','mov'] %}
<video src="{{ media_src }}" controls class="mt-2 d-block" style="max-height:320px"></video>
{% else %}
<a class="btn btn-sm btn-outline-secondary mt-2" href="{{ media_src }}" target="_blank">📎 Медиафайл</a>
{% endif %}
{% endif %}
{% if selected.summary %}<div class="mt-2"><span class="badge bg-light text-dark">резюме</span> {{ selected.summary }}</div>{% endif %}
</div>
</div>
</div>
{% endif %}
{% else %}
<div class="alert alert-info py-3">Выберите отобранный пост слева</div>
{% endif %}
{% else %}
<div class="alert alert-info py-3">Выберите отобранный пост слева</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>