Fix learn dialog rendering, add lab publish/draft toggle, bump to v0.1.2

- learn/index.html: restructured dialogs inside section divs to fix scope
- learn/index.html: edit-article dialogs via flat articles list in modal blocks
- LearnController: sectionChoices for select options; secure article fetching
- ContentService: createArticlePlaced: new section adjacent to anchor section
- lab status: published = student-visible, draft = hidden
- lab toggle: click badge in labs list or button in lab header to switch status
- added badge-btn CSS class, removed inline styles
- removed all th:onclick with expressions → data-modal attributes
- footer v0.1.2
This commit is contained in:
2026-09-11 20:41:11 +03:00
parent 006951adae
commit caa48d3193
11 changed files with 219 additions and 131 deletions

View File

@@ -9,6 +9,10 @@
<h1 class="page-title" th:text="|ЛР ${lab.number}. ${lab.title}|">ЛР 1</h1>
<p class="text-sm text-muted">
Статус: <span class="badge" th:classappend="${lab.status == 'published'} ? 'badge-ok' : 'badge-warn'" th:text="${lab.status}">—</span>
<form class="inline-form" th:action="@{/admin/labs/{id}/toggle-status(id=${lab.id})}" method="post">
<input type="hidden" name="_csrf" th:value="${csrfToken}">
<button class="btn btn-secondary btn-sm ml-2" onclick="return confirm('Сменить статус лабораторной?')" type="submit">Сменить статус</button>
</form>
<span th:if="${lab.deadlineAt != null}"> · Срок: <span th:text="${lab.deadlineAt}"></span></span>
<span th:if="${lab.defenseAt != null}"> · Защита: <span th:text="${lab.defenseAt}"></span></span>
· Максимум: <span th:text="${lab.pointsMax}"></span> б.
@@ -47,14 +51,14 @@
</h3>
<div class="flex gap-2">
<button class="btn btn-secondary btn-sm" type="button"
th:onclick="openModal('modal-rename-level-'+${level.id})">Переименовать</button>
th:attr="data-modal=${'modal-rename-level-' + level.id}" onclick="openModalData(this)">Переименовать</button>
<form th:action="@{/admin/labs/{labId}/levels/{lid}/delete(labId=${lab.id}, lid=${level.id})}" method="post"
onsubmit="return confirm('Удалить уровень без вариантов?')">
<button class="btn btn-danger btn-sm" type="submit">Удалить</button>
<input type="hidden" name="_csrf" th:value="${csrfToken}">
</form>
<button class="btn btn-primary btn-sm" type="button"
th:onclick="openModal('modal-add-variant-'+${level.id})">+ Вариант</button>
th:attr="data-modal=${'modal-add-variant-' + level.id}" onclick="openModalData(this)">+ Вариант</button>
</div>
</div>
<table>
@@ -66,7 +70,7 @@
<td class="text-muted" th:text="${#strings.abbreviate(v.statementMd, 60)}">—</td>
<td class="text-center">
<button class="btn btn-secondary btn-sm" type="button"
th:onclick="openModal('modal-edit-variant-'+${v.id})">Править</button>
th:attr="data-modal=${'modal-edit-variant-' + v.id}" onclick="openModalData(this)">Править</button>
<form class="inline-form" th:action="@{/admin/labs/{labId}/variants/{vid}/delete(labId=${lab.id}, vid=${v.id})}" method="post"
onsubmit="return confirm('Удалить вариант?')">
<button class="btn btn-danger btn-sm" type="submit">Удалить</button>
@@ -189,7 +193,7 @@
<dialog th:each="level : ${lab.levels}" th:id="|modal-rename-level-${level.id}|" class="modal">
<div class="modal-header">
<h2 class="modal-title">Переименовать уровень</h2>
<button class="modal-close" type="button" th:onclick="closeModal('modal-rename-level-'+[[${level.id}]])">✕</button>
<button class="modal-close" type="button" th:attr="data-modal=${'modal-rename-level-' + level.id}" onclick="closeModalData(this)">✕</button>
</div>
<div class="modal-body">
<form class="form-stack" th:action="@{/admin/labs/{labId}/levels/save(labId=${lab.id})}" method="post">
@@ -206,7 +210,7 @@
<dialog th:each="level : ${lab.levels}" th:id="|modal-add-variant-${level.id}|" class="modal">
<div class="modal-header">
<h2 class="modal-title">Новый вариант — <span th:text="${level.title}">уровень</span></h2>
<button class="modal-close" type="button" th:onclick="closeModal('modal-add-variant-'+[[${level.id}]])">✕</button>
<button class="modal-close" type="button" th:attr="data-modal=${'modal-add-variant-' + level.id}" onclick="closeModalData(this)">✕</button>
</div>
<div class="modal-body">
<form class="form-stack" th:action="@{/admin/labs/{labId}/variants/save(labId=${lab.id})}" method="post">
@@ -227,7 +231,7 @@
<dialog th:each="v : ${level.variants}" th:id="|modal-edit-variant-${v.id}|" class="modal">
<div class="modal-header">
<h2 class="modal-title">Правка варианта</h2>
<button class="modal-close" type="button" th:onclick="closeModal('modal-edit-variant-'+[[${v.id}]])">✕</button>
<button class="modal-close" type="button" th:attr="data-modal=${'modal-edit-variant-' + v.id}" onclick="closeModalData(this)">✕</button>
</div>
<div class="modal-body">
<form class="form-stack" th:action="@{/admin/labs/{labId}/variants/save(labId=${lab.id})}" method="post">