Update UI and migrations, fix dockerfile
This commit is contained in:
@@ -69,13 +69,22 @@
|
||||
<span>{{ p.posted_at_fmt or p.created_at_fmt }}</span>
|
||||
</div>
|
||||
<div class="editor-title-row">
|
||||
<span class="pill {% if p.editorial_status == 'accepted' %}ok{% elif p.editorial_status == 'rejected' %}bad{% elif p.editorial_status == 'regenerating' %}warn{% endif %}">
|
||||
<span class="pill {% if p.editorial_status in ['accepted', 'published'] %}ok{% elif p.editorial_status in ['rejected', 'publish_failed'] %}bad{% elif p.editorial_status == 'regenerating' %}warn{% endif %}" title="{{ p.publication_error or p.tg_publication_url or '' }}">
|
||||
{{ p.editorial_status_label }}
|
||||
</span>
|
||||
<span class="pill">{{ p.review_category or "без категории" }}</span>
|
||||
<span class="muted">AI {{ p.qualification_score or "?" }}/10</span>
|
||||
</div>
|
||||
<div class="editor-text">{{ p.review_text }}</div>
|
||||
<div class="publication-badges">
|
||||
{% for pub in p.publication_platforms %}
|
||||
{% if pub.url %}
|
||||
<a class="pill {{ pub.class }}" href="{{ pub.url }}" target="_blank" title="{{ pub.error or pub.status_label }}">{{ pub.label }} · {{ pub.status_label }}</a>
|
||||
{% else %}
|
||||
<span class="pill {{ pub.class }}" title="{{ pub.error or pub.status_label }}">{{ pub.label }} · {{ pub.status_label }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="editor-text">{{ p.publication_preview_text }}</div>
|
||||
<details class="source-compare">
|
||||
<summary>Исходник и AI-заметки</summary>
|
||||
<div class="compare-grid">
|
||||
@@ -154,10 +163,11 @@
|
||||
<label><span>Категория</span>
|
||||
<select name="final_category">
|
||||
{% for category in categories %}
|
||||
<option value="{{ category }}" {% if p.review_category == category %}selected{% endif %}>{{ category }}</option>
|
||||
<option value="{{ category.name }}" data-tag="{{ category.tag }}" {% if p.review_category == category.name %}selected{% endif %}>{{ category.name }}</option>
|
||||
{% endfor %}
|
||||
{% if p.review_category and p.review_category not in categories %}
|
||||
<option value="{{ p.review_category }}" selected>{{ p.review_category }} · старая категория</option>
|
||||
{% set category_names = categories | map(attribute="name") | list %}
|
||||
{% if p.review_category and p.review_category not in category_names %}
|
||||
<option value="{{ p.review_category }}" data-tag="{{ p.review_category_tag }}" selected>{{ p.review_category }} · старая категория</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</label>
|
||||
@@ -165,6 +175,9 @@
|
||||
<input name="final_source_tag" value="{{ p.review_source_tag or p.source_tag or '' }}">
|
||||
</label>
|
||||
</div>
|
||||
<label><span>Предпросмотр публикации</span>
|
||||
<div class="publication-preview" data-publication-preview>{{ p.publication_preview_text }}</div>
|
||||
</label>
|
||||
<div class="hashtag-preview" data-hashtag-preview>#{{ p.review_category_tag or p.review_category or "category" }} #{{ p.review_source_tag or p.source_tag or "source" }}</div>
|
||||
<label><span>Заметка редактора</span>
|
||||
<textarea name="editor_notes" rows="3">{{ p.editor_notes or "" }}</textarea>
|
||||
@@ -253,9 +266,11 @@
|
||||
button.addEventListener("click", () => document.getElementById(button.dataset.closeDialog)?.close());
|
||||
});
|
||||
document.querySelectorAll(".edit-form").forEach((form) => {
|
||||
const textArea = form.querySelector('[name="final_text"]');
|
||||
const category = form.querySelector('[name="final_category"]');
|
||||
const source = form.querySelector('[name="final_source_tag"]');
|
||||
const preview = form.querySelector("[data-hashtag-preview]");
|
||||
const hashtagPreview = form.querySelector("[data-hashtag-preview]");
|
||||
const publicationPreview = form.querySelector("[data-publication-preview]");
|
||||
const normalize = (value, fallback) => {
|
||||
const tag = String(value || "").trim().replace(/^#+/, "").toLowerCase()
|
||||
.replace(/\s+/g, "_")
|
||||
@@ -265,9 +280,15 @@
|
||||
return tag || fallback;
|
||||
};
|
||||
const update = () => {
|
||||
if (!preview) return;
|
||||
preview.textContent = `#${normalize(category?.value, "category")} #${normalize(source?.value, "source")}`;
|
||||
const option = category?.selectedOptions?.[0];
|
||||
const tags = `#${normalize(option?.dataset?.tag || category?.value, "category")} #${normalize(source?.value, "source")}`;
|
||||
if (hashtagPreview) hashtagPreview.textContent = tags;
|
||||
if (publicationPreview) {
|
||||
const cleanText = String(textArea?.value || "").trim();
|
||||
publicationPreview.textContent = cleanText ? `${cleanText}\n\n${tags}` : tags;
|
||||
}
|
||||
};
|
||||
textArea?.addEventListener("input", update);
|
||||
category?.addEventListener("change", update);
|
||||
source?.addEventListener("input", update);
|
||||
update();
|
||||
|
||||
Reference in New Issue
Block a user