Learn head: responsive row/col (title full width, 3 equal buttons below on mobile)

This commit is contained in:
2026-10-03 00:31:58 +03:00
parent f5ad352e20
commit bad3776bc1
8 changed files with 61 additions and 59 deletions

View File

@@ -455,13 +455,13 @@ code.code { padding: 0.125rem 0.5rem; border-radius: var(--radius-xs); font-fami
.mini-count { font-size: 0.72rem; margin-left: 0.15rem; color: var(--c-text-muted); }
.defense-cell-timer { font-variant-numeric: tabular-nums; }
.lab-head-actions { display: flex; gap: 0.2rem; }
.mini-btn {
.btn btn-secondary btn-sm p-2 {
display: inline-flex; align-items: center; justify-content: center;
min-width: 1.5rem; height: 1.5rem; padding: 0 0.3rem; cursor: pointer;
border: 1px solid var(--c-border); border-radius: var(--radius-sm);
background: var(--c-surface); color: var(--c-text); text-decoration: none; font-size: 0.85rem;
}
.mini-btn:hover { background: var(--c-bg); }
.btn btn-secondary btn-sm p-2:hover { background: var(--c-bg); }
.js-pub-eye .eye-closed { display: none; }
.js-pub-eye.is-empty .eye-open { display: none; }
.js-pub-eye.is-empty .eye-closed { display: inline-block; }
@@ -470,7 +470,7 @@ code.code { padding: 0.125rem 0.5rem; border-radius: var(--radius-xs); font-fami
/* Увеличенный диалог (оценка + комментарии) */
dialog.dlg.dlg-lg { width: min(72rem, calc(100vw - 2rem)); }
dialog.dlg.dlg-lg .dlg-body { max-height: 88vh; min-height: 62vh; }
.mini-btn svg, .cell-btn svg { width: 1rem; height: 1rem; }
.btn btn-secondary btn-sm p-2 svg, .cell-btn svg { width: 1rem; height: 1rem; }
.chip { display: inline-block; margin: 2px 4px 2px 0; padding: 2px 8px; border-radius: var(--radius-sm); font-size: 11.5px; line-height: 1.5; }
.chip-pos { background: #2e6b3a; color: #fff; }
@@ -611,7 +611,7 @@ th.th-filterable { padding-bottom: 0.35rem; }
font-size: 1rem; line-height: 1; padding: 0.15rem 0; border-radius: var(--radius-sm);
}
.drag-handle:hover { background: var(--c-bg); color: var(--c-text); }
.mini-btn.danger:hover { color: var(--c-accent); border-color: #dcb9be; background: var(--c-accent-soft); }
.btn btn-secondary btn-sm p-2.danger:hover { color: var(--c-accent); border-color: #dcb9be; background: var(--c-accent-soft); }
.drag-handle:active { cursor: grabbing; }
.dragging { opacity: 0.45; }
.drop-before { box-shadow: 0 -3px 0 0 var(--c-text); }

View File

@@ -279,7 +279,7 @@ function attachPublishToggles() {
cb.disabled = false;
if (res && res.ok) {
showToast((desired ? 'Опубликовано: ' : 'Скрыто: ') + res.count + ' из ' + res.total);
var eye = document.querySelector('.mini-btn.js-pub-eye[data-lab="' + labId + '"]');
var eye = document.querySelector('.btn btn-secondary btn-sm p-2.js-pub-eye[data-lab="' + labId + '"]');
if (eye) {
eye.setAttribute('data-count', String(res.count || 0));
eye.setAttribute('data-total', String(res.total || 0));
@@ -302,7 +302,7 @@ function attachPublishToggles() {
/* Перерисовка «глазика» публикации по атрибутам data-count/data-total/data-all. */
function updateEyeCounts() {
document.querySelectorAll('.mini-btn.js-pub-eye').forEach(function (eye) {
document.querySelectorAll('.btn btn-secondary btn-sm p-2.js-pub-eye').forEach(function (eye) {
var total = parseInt(eye.getAttribute('data-total') || '0', 10);
var count = parseInt(eye.getAttribute('data-count') || '0', 10);
var all = eye.getAttribute('data-all') === 'true';

View File

@@ -16,8 +16,6 @@
</p>
</div>
<div class="actions">
<a class="btn btn-secondary" th:href="@{/admin/groups/{id}/submissions.zip(id=${group.id})}"
title="ZIP со всеми последними решениями группы по всем лабораторным">Скачать работы</a>
<a class="btn btn-secondary" th:href="@{/admin/groups/{id}/credentials(id=${group.id}, format='xlsx')}">Скачать пароли</a>
<button class="btn" type="button" data-modal="modal-add-student">+ Студент</button>
</div>
@@ -46,7 +44,7 @@
<a th:href="@{/admin/labs/{id}(id=${lab.id})}" th:text="|ЛР ${lab.number}|">ЛР</a>
<span class="lab-col-title" th:text="${lab.title}">—</span>
<div class="lab-head-actions">
<button class="mini-btn" type="button"
<button class="btn btn-secondary btn-sm p-2" type="button"
th:attr="data-url=@{/admin/groups/{id}/assign-modal(id=${group.id}, labId=${lab.id})},data-lab-name=|ЛР ${lab.number}|" data-action="assign"
title="Выдача вариантов: уровни, варианты, автокраспределение по группе">
<i class="cell-ico ico bi bi-list" aria-hidden="true"></i>
@@ -57,7 +55,7 @@
<input type="hidden" name="labId" th:value="${lab.id}">
<input class="js-pub-published" type="hidden" name="published"
th:value="${all} ? 'false' : 'true'">
<button class="mini-btn js-pub-eye" type="submit"
<button class="btn btn-secondary btn-sm p-2 js-pub-eye" type="submit"
th:attr="data-lab=${lab.id},data-count=${pc},data-total=${pub != null ? pub.total : 0},data-all=${all}"
th:classappend="${all} ? 'is-all' : (${pc > 0} ? 'is-partial' : 'is-empty')"
th:title="${pub == null} ? '' : (${all} ? 'Оценки опубликованы всей группе — нажмите, чтобы скрыть у всех' : (${pc > 0} ? 'Опубликовано ' + ${pc} + ' из ' + ${pub.total} + ' — нажмите, чтобы опубликовать всем' : 'Показать оценки и комментарии всей группе'))">
@@ -66,7 +64,7 @@
<span class="mini-count js-pub-count" th:classappend="(${all} or ${pc == 0}) ? 'is-hidden' : ''" th:text="${pc}"></span>
</button>
</form>
<a class="mini-btn"
<a class="btn btn-secondary btn-sm p-2"
th:href="'/admin/groups/' + ${group.id} + '/submissions.zip?labId=' + ${lab.id}"
th:title="|Скачать решения по ЛР ${lab.number}|">⤓<span class="mini-count" th:text="${labSubmissionCounts[lab.id] ?: 0}">0</span></a>
</div>

View File

@@ -31,7 +31,7 @@
<div class="flex items-center gap-2 mb-2">
<h2 class="section-title m-0">Условие лабораторной</h2>
<button class="mini-btn" type="button" data-action="lab-edit"
<button class="btn btn-secondary btn-sm p-2" type="button" data-action="lab-edit"
title="Редактировать параметры лабораторной" aria-label="Редактировать параметры лабораторной">
<i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i>
</button>
@@ -80,7 +80,7 @@
<div class="flex flex-wrap items-center justify-between gap-2 mb-4">
<h3 class="section-title m-0" th:text="${level.title}">Уровень</h3>
<div class="flex items-center gap-2">
<button class="mini-btn" type="button" th:attr="data-modal=|modal-level-rename-${level.id}|"
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-level-rename-${level.id}|"
title="Переименовать уровень" aria-label="Переименовать уровень">
<i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i>
</button>
@@ -88,7 +88,7 @@
th:action="@{/admin/labs/{labId}/levels/{levelId}/delete(labId=${lab.id}, levelId=${level.id})}"
method="post" data-confirm="Удалить уровень? Варианты на уровне должны быть пустыми.">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<button class="mini-btn danger" type="submit" title="Удалить уровень"
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить уровень"
aria-label="Удалить уровень">
<i class="cell-ico ico bi bi-trash" aria-hidden="true"></i>
</button>
@@ -106,7 +106,7 @@
th:text="' · ' + ${v.title}"></span>
</div>
<div class="flex gap-2">
<button class="mini-btn" type="button" th:attr="data-modal=|modal-variant-edit-${v.id}|"
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-variant-edit-${v.id}|"
title="Редактировать вариант" aria-label="Редактировать вариант">
<i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i>
</button>
@@ -114,7 +114,7 @@
th:action="@{/admin/labs/{labId}/variants/{variantId}/delete(labId=${lab.id}, variantId=${v.id})}"
method="post" data-confirm="Удалить вариант вместе с его условием?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<button class="mini-btn danger" type="submit" title="Удалить вариант"
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить вариант"
aria-label="Удалить вариант">
<i class="cell-ico ico bi bi-trash" aria-hidden="true"></i>
</button>

View File

@@ -46,21 +46,21 @@
</h1>
<div th:if="${currentUser != null and currentUser.admin}" class="flex flex-wrap gap-2 mb-4">
<button class="mini-btn" type="button" data-action="article-edit" title="Править статью" aria-label="Править статью"><i class="ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" data-action="article-edit" title="Править статью" aria-label="Править статью"><i class="ico bi bi-pencil" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/articles/toggle-published}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${article.id}">
<input type="hidden" name="published" th:value="${!article.published}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<a class="btn btn-secondary"
th:href="@{/learn/{c}(c=${article.chapterSlug})}">К главе</a>
<form class="inline-form" th:action="@{/admin/content/articles/{id}/delete(id=${article.id})}" method="post" data-confirm="Удалить статью?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="back" th:value="${backParent}">
<button class="mini-btn danger" type="submit" title="Удалить статью" aria-label="Удалить статью"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить статью" aria-label="Удалить статью"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>

View File

@@ -16,19 +16,19 @@
<div th:if="${currentUser != null and currentUser.admin}" class="flex flex-wrap gap-2 mb-4">
<button class="btn btn-primary" type="button" data-modal="modal-new-section">+ Раздел</button>
<button class="mini-btn" type="button" data-modal="modal-rename-chapter" title="Переименовать главу" aria-label="Переименовать главу"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" data-modal="modal-rename-chapter" title="Переименовать главу" aria-label="Переименовать главу"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/chapters/toggle-published}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${chapter.id}">
<input type="hidden" name="published" th:value="${!chapter.published}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn" type="submit" th:if="${chapter.published}" title="Скрыть главу" aria-label="Скрыть главу"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${chapter.published}" title="Опубликовать главу" aria-label="Опубликовать главу"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${chapter.published}" title="Скрыть главу" aria-label="Скрыть главу"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${chapter.published}" title="Опубликовать главу" aria-label="Опубликовать главу"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<form class="inline-form" th:action="@{/admin/content/chapters/{id}/delete(id=${chapter.id})}" method="post" data-confirm="Удалить главу со всеми разделами и статьями?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="back" th:value="${backParent}">
<button class="mini-btn danger" type="submit" title="Удалить главу со всеми разделами и статьями" aria-label="Удалить главу со всеми разделами и статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить главу со всеми разделами и статьями" aria-label="Удалить главу со всеми разделами и статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>
@@ -60,20 +60,20 @@
th:text="${section.title}">Раздел</a>
<span th:if="${!section.published}" class="badge badge-warn">скрыто</span>
<div th:if="${currentUser != null and currentUser.admin}" class="sort-actions">
<button class="mini-btn" type="button" th:attr="data-modal=|modal-rename-section-${section.id}|" title="Переименовать раздел" aria-label="Переименовать раздел"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-rename-section-${section.id}|" title="Переименовать раздел" aria-label="Переименовать раздел"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/sections/toggle-published}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${section.id}">
<input type="hidden" name="published" th:value="${!section.published}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn" type="submit" th:if="${section.published}" title="Скрыть раздел" aria-label="Скрыть раздел"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${section.published}" title="Опубликовать раздел" aria-label="Опубликовать раздел"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${section.published}" title="Скрыть раздел" aria-label="Скрыть раздел"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${section.published}" title="Опубликовать раздел" aria-label="Опубликовать раздел"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<button class="mini-btn" type="button" th:attr="data-modal=|modal-move-${section.id}|" title="Перенести статьи и удалить" aria-label="Перенести статьи и удалить"><i class="cell-ico ico bi bi-arrow-left-right" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-move-${section.id}|" title="Перенести статьи и удалить" aria-label="Перенести статьи и удалить"><i class="cell-ico ico bi bi-arrow-left-right" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/sections/{id}/delete(id=${section.id})}" method="post" data-confirm="Удалить раздел вместе со статьями?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn danger" type="submit" title="Удалить раздел вместе со статьями" aria-label="Удалить раздел вместе со статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить раздел вместе со статьями" aria-label="Удалить раздел вместе со статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>
</div>
@@ -89,15 +89,15 @@
th:text="${article.title}">Статья</a>
<span th:if="${!article.published}" class="badge badge-warn">скрыто</span>
<div th:if="${currentUser != null and currentUser.admin}" class="sort-actions">
<a class="mini-btn" title="Править статью" aria-label="Править статью"
<a class="btn btn-secondary btn-sm p-2" title="Править статью" aria-label="Править статью"
th:href="@{/learn/{c}/{s}/{a}(c=${chapter.slug}, s=${section.slug}, a=${article.slug}, edit=1)}"><i class="ico bi bi-pencil" aria-hidden="true"></i></a>
<form class="inline-form" th:action="@{/admin/content/articles/toggle-published}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${article.id}">
<input type="hidden" name="published" th:value="${!article.published}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
</div>
</li>

View File

@@ -3,12 +3,16 @@
<head><title>Материалы — LMS</title></head>
<body>
<div id="content" th:attr="data-csrf=${csrfToken},data-sort-scope='full'">
<div class="flex items-center justify-between gap-4 mb-6">
<h1 class="page-title">Учебные материалы</h1>
<div th:if="${currentUser != null and currentUser.admin}" class="flex gap-2">
<button class="btn btn-primary" type="button" data-modal="modal-new-article">+ Статья</button>
<button class="btn btn-secondary" type="button" data-modal="modal-import">Импорт zip</button>
<button class="btn btn-secondary" type="button" data-modal="modal-new-chapter">+ Глава</button>
<div class="row g-3 align-items-center mb-4">
<div class="col-12 col-md">
<h1 class="page-title m-0">Учебные материалы</h1>
</div>
<div class="col-12 col-md-auto" th:if="${currentUser != null and currentUser.admin}">
<div class="row row-cols-3 row-cols-md-auto g-2">
<div class="col"><button class="btn btn-secondary w-100" type="button" data-modal="modal-import">Импорт</button></div>
<div class="col"><button class="btn primary w-100" type="button" data-modal="modal-new-chapter">+ Глава</button></div>
<div class="col"><button class="btn btn-primary w-100" type="button" data-modal="modal-new-article">+ Статья</button></div>
</div>
</div>
</div>
<div th:if="${currentUser != null and currentUser.admin}" id="sort-status" class="sort-status" hidden>
@@ -32,13 +36,13 @@
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${chapter.id}">
<input type="hidden" name="published" th:value="${!chapter.published}">
<button class="mini-btn" type="submit" th:if="${chapter.published}" title="Скрыть главу" aria-label="Скрыть главу"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${chapter.published}" title="Опубликовать главу" aria-label="Опубликовать главу"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${chapter.published}" title="Скрыть главу" aria-label="Скрыть главу"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${chapter.published}" title="Опубликовать главу" aria-label="Опубликовать главу"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<button class="mini-btn" type="button" th:attr="data-modal=|modal-rename-chapter-${chapter.id}|" title="Переименовать главу" aria-label="Переименовать главу"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-rename-chapter-${chapter.id}|" title="Переименовать главу" aria-label="Переименовать главу"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/chapters/{id}/delete(id=${chapter.id})}" method="post" data-confirm="Удалить главу со всеми разделами и статьями?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<button class="mini-btn danger" type="submit" title="Удалить главу со всеми разделами и статьями" aria-label="Удалить главу со всеми разделами и статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить главу со всеми разделами и статьями" aria-label="Удалить главу со всеми разделами и статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>
</div>
@@ -65,14 +69,14 @@
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${section.id}">
<input type="hidden" name="published" th:value="${!section.published}">
<button class="mini-btn" type="submit" th:if="${section.published}" title="Скрыть раздел" aria-label="Скрыть раздел"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${section.published}" title="Опубликовать раздел" aria-label="Опубликовать раздел"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${section.published}" title="Скрыть раздел" aria-label="Скрыть раздел"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${section.published}" title="Опубликовать раздел" aria-label="Опубликовать раздел"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<button class="mini-btn" type="button" th:attr="data-modal=|modal-rename-section-${section.id}|" title="Переименовать раздел" aria-label="Переименовать раздел"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="mini-btn" type="button" th:attr="data-modal=|modal-move-${section.id}|" title="Перенести статьи в другой раздел" aria-label="Перенести статьи в другой раздел"><i class="cell-ico ico bi bi-arrow-left-right" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-rename-section-${section.id}|" title="Переименовать раздел" aria-label="Переименовать раздел"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" th:attr="data-modal=|modal-move-${section.id}|" title="Перенести статьи в другой раздел" aria-label="Перенести статьи в другой раздел"><i class="cell-ico ico bi bi-arrow-left-right" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/sections/{id}/delete(id=${section.id})}" method="post" data-confirm="Удалить раздел со всеми статьями?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<button class="mini-btn danger" type="submit" title="Удалить раздел со всеми статьями" aria-label="Удалить раздел со всеми статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить раздел со всеми статьями" aria-label="Удалить раздел со всеми статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>
</div>
@@ -92,14 +96,14 @@
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${article.id}">
<input type="hidden" name="published" th:value="${!article.published}">
<button class="mini-btn" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<a class="mini-btn" title="Править статью" aria-label="Править статью"
<a class="btn btn-secondary btn-sm p-2" title="Править статью" aria-label="Править статью"
th:href="@{/learn/{c}/{s}/{a}(c=${chapter.slug}, s=${section.slug}, a=${article.slug}, edit=1)}"><i class="ico bi bi-pencil" aria-hidden="true"></i></a>
<form class="inline-form" th:action="@{/admin/content/articles/{id}/delete(id=${article.id})}" method="post" data-confirm="Удалить статью?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<button class="mini-btn danger" type="submit" title="Удалить статью" aria-label="Удалить статью"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить статью" aria-label="Удалить статью"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>
</li>

View File

@@ -18,20 +18,20 @@
<div th:if="${currentUser != null and currentUser.admin}" class="flex flex-wrap gap-2 mb-4">
<button class="btn btn-primary" type="button" data-modal="modal-new-article">+ Статья</button>
<button class="mini-btn" type="button" data-modal="modal-rename-section" title="Переименовать раздел" aria-label="Переименовать раздел"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" data-modal="modal-rename-section" title="Переименовать раздел" aria-label="Переименовать раздел"><i class="cell-ico ico bi bi-pencil" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/sections/toggle-published}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${section.id}">
<input type="hidden" name="published" th:value="${!section.published}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn" type="submit" th:if="${section.published}" title="Скрыть раздел" aria-label="Скрыть раздел"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${section.published}" title="Опубликовать раздел" aria-label="Опубликовать раздел"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${section.published}" title="Скрыть раздел" aria-label="Скрыть раздел"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${section.published}" title="Опубликовать раздел" aria-label="Опубликовать раздел"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<button class="mini-btn" type="button" data-modal="modal-move-section" title="Перенести статьи и удалить" aria-label="Перенести статьи и удалить"><i class="cell-ico ico bi bi-arrow-left-right" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="button" data-modal="modal-move-section" title="Перенести статьи и удалить" aria-label="Перенести статьи и удалить"><i class="cell-ico ico bi bi-arrow-left-right" aria-hidden="true"></i></button>
<form class="inline-form" th:action="@{/admin/content/sections/{id}/delete(id=${section.id})}" method="post" data-confirm="Удалить раздел вместе со статьями?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="back" th:value="${backParent}">
<button class="mini-btn danger" type="submit" title="Удалить раздел вместе со статьями" aria-label="Удалить раздел вместе со статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
<button class="btn btn-danger btn-sm p-2" type="submit" title="Удалить раздел вместе со статьями" aria-label="Удалить раздел вместе со статьями"><i class="cell-ico ico bi bi-trash" aria-hidden="true"></i></button>
</form>
</div>
@@ -56,15 +56,15 @@
<span th:if="${!article.published}" class="badge badge-warn ml-1">скрыто</span>
</td>
<td class="text-right actions-cell">
<a class="mini-btn" title="Править статью" aria-label="Править статью"
<a class="btn btn-secondary btn-sm p-2" title="Править статью" aria-label="Править статью"
th:href="@{/learn/{c}/{s}/{a}(c=${chapter.slug}, s=${section.slug}, a=${article.slug}, edit=1)}"><i class="ico bi bi-pencil" aria-hidden="true"></i></a>
<form class="inline-form" th:action="@{/admin/content/articles/toggle-published}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<input type="hidden" name="id" th:value="${article.id}">
<input type="hidden" name="published" th:value="${!article.published}">
<input type="hidden" name="back" th:value="${back}">
<button class="mini-btn" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="mini-btn" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:if="${article.published}" title="Скрыть статью" aria-label="Скрыть статью"><i class="cell-ico ico bi bi-eye" aria-hidden="true"></i></button>
<button class="btn btn-secondary btn-sm p-2" type="submit" th:unless="${article.published}" title="Опубликовать статью" aria-label="Опубликовать статью"><i class="cell-ico ico bi bi-eye-slash" aria-hidden="true"></i></button>
</form>
<form class="inline-form" th:action="@{/admin/content/articles/{id}/delete(id=${article.id})}" method="post" data-confirm="Удалить статью?">
<input type="hidden" name="_csrf" th:value="${csrfToken}">