fix: match attestation columns to lab result styling
- use the same header order and compact action row as lab columns - show attestation results as centered text-like selects instead of boxed inputs - keep column widths and separators aligned with lab columns - send the selected value with the inline attestation request
This commit is contained in:
@@ -557,13 +557,32 @@ dialog.dlg.dlg-lg .dlg-body { max-height: 88vh; min-height: 62vh; }
|
|||||||
.matrix tbody tr:last-child td { border-bottom: none; }
|
.matrix tbody tr:last-child td { border-bottom: none; }
|
||||||
.matrix th.lab-col { min-width: 9.5rem; border-left: 1px solid var(--c-border); }
|
.matrix th.lab-col { min-width: 9.5rem; border-left: 1px solid var(--c-border); }
|
||||||
.matrix td.cell-lab { min-width: 9.5rem; border-left: 1px solid var(--c-border); }
|
.matrix td.cell-lab { min-width: 9.5rem; border-left: 1px solid var(--c-border); }
|
||||||
.matrix th.attestation-col { min-width: 10rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); }
|
.matrix th.attestation-col { width: 11rem; min-width: 10rem; max-width: 11rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); }
|
||||||
.matrix td.attestation-cell { min-width: 10rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); }
|
.matrix td.attestation-cell { width: 11rem; min-width: 10rem; max-width: 11rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); }
|
||||||
.matrix th.average-col { min-width: 7rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); }
|
.matrix th.average-col { min-width: 7rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); }
|
||||||
.matrix td.average-cell { min-width: 7rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); font-weight: 600; }
|
.matrix td.average-cell { min-width: 7rem; border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border); font-weight: 600; }
|
||||||
.attestation-head { display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem; text-align: left; }
|
.attestation-title { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; width: 100%; max-width: 9rem; }
|
||||||
.attestation-kind { font-weight: 600; color: var(--c-text); }
|
.attestation-kind { font-weight: 600; color: var(--c-text); white-space: normal; }
|
||||||
.attestation-select { width: 100%; min-width: 8.5rem; font-size: 0.8125rem; }
|
.js-attestation-form { display: flex; justify-content: center; width: 100%; }
|
||||||
|
.attestation-select {
|
||||||
|
appearance: none; -webkit-appearance: none;
|
||||||
|
width: 9rem; max-width: 100%; min-width: 0; padding: 0.15rem 1.15rem 0.15rem 0.35rem;
|
||||||
|
border: 1px solid transparent; border-radius: var(--radius-sm);
|
||||||
|
background-color: transparent; color: var(--c-text);
|
||||||
|
font-size: 0.8125rem; font-weight: 600; font-variant-numeric: tabular-nums;
|
||||||
|
text-align: center; text-align-last: center; cursor: pointer;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, transparent 50%, currentColor 50%),
|
||||||
|
linear-gradient(135deg, currentColor 50%, transparent 50%);
|
||||||
|
background-position: calc(100% - 8px) 55%, calc(100% - 3px) 55%;
|
||||||
|
background-size: 5px 5px, 5px 5px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
.attestation-select:hover { color: var(--c-accent); text-decoration: underline; }
|
||||||
|
.attestation-select:focus { outline: none; border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); }
|
||||||
|
.attestation-select.none { color: var(--c-text-muted); font-weight: 400; }
|
||||||
|
.attestation-select:disabled { opacity: 0.6; cursor: wait; }
|
||||||
|
.attestation-select option { text-align: left; text-align-last: left; background: var(--c-surface); color: var(--c-text); }
|
||||||
.matrix td.student-cell { min-width: 12rem; }
|
.matrix td.student-cell { min-width: 12rem; }
|
||||||
.student-name { font-weight: 600; font-size: 0.84375rem; }
|
.student-name { font-weight: 600; font-size: 0.84375rem; }
|
||||||
.student-cell .font-mono { margin-top: 0.125rem; }
|
.student-cell .font-mono { margin-top: 0.125rem; }
|
||||||
|
|||||||
@@ -678,11 +678,12 @@ function submitAttestationForm(form) {
|
|||||||
if (form.dataset.saving === '1') return;
|
if (form.dataset.saving === '1') return;
|
||||||
form.dataset.saving = '1';
|
form.dataset.saving = '1';
|
||||||
var select = form.querySelector('select[name="value"]');
|
var select = form.querySelector('select[name="value"]');
|
||||||
|
var payload = new FormData(form);
|
||||||
if (select) select.disabled = true;
|
if (select) select.disabled = true;
|
||||||
|
|
||||||
fetch(form.action, {
|
fetch(form.action, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: new FormData(form),
|
body: payload,
|
||||||
headers: { 'X-Requested-With': 'fetch' }
|
headers: { 'X-Requested-With': 'fetch' }
|
||||||
})
|
})
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
|||||||
@@ -75,7 +75,12 @@
|
|||||||
</th>
|
</th>
|
||||||
<th class="text-center average-col" title="Средний балл по выставленным оценкам">Средний балл</th>
|
<th class="text-center average-col" title="Средний балл по выставленным оценкам">Средний балл</th>
|
||||||
<th th:each="att : ${attestations}" class="text-center attestation-col" data-nosort>
|
<th th:each="att : ${attestations}" class="text-center attestation-col" data-nosort>
|
||||||
<div class="attestation-head">
|
<div class="lab-col-head">
|
||||||
|
<div class="attestation-title">
|
||||||
|
<span class="attestation-kind" th:text="${att.kindLabel}">Аттестация</span>
|
||||||
|
<span class="badge badge-warn js-att-hidden" th:hidden="${att.published}">скрыто</span>
|
||||||
|
</div>
|
||||||
|
<span class="lab-col-title" th:text="'Семестр ' + ${att.semester}">Семестр 1</span>
|
||||||
<div class="lab-head-actions">
|
<div class="lab-head-actions">
|
||||||
<form class="inline-form js-att-pub-form" method="post"
|
<form class="inline-form js-att-pub-form" method="post"
|
||||||
th:action="@{/admin/groups/{gid}/attestations/{aid}/publication(gid=${group.id}, aid=${att.id})}">
|
th:action="@{/admin/groups/{gid}/attestations/{aid}/publication(gid=${group.id}, aid=${att.id})}">
|
||||||
@@ -99,9 +104,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<span class="attestation-kind" th:text="${att.kindLabel}">Аттестация</span>
|
|
||||||
<span class="lab-col-title" th:text="'Семестр ' + ${att.semester}">Семестр 1</span>
|
|
||||||
<span class="badge badge-warn js-att-hidden" th:hidden="${att.published}">скрыто</span>
|
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th data-nosort>Пароль</th>
|
<th data-nosort>Пароль</th>
|
||||||
@@ -162,8 +164,9 @@
|
|||||||
<input type="hidden" name="_csrf" th:value="${csrfToken}">
|
<input type="hidden" name="_csrf" th:value="${csrfToken}">
|
||||||
<input type="hidden" name="attestationId" th:value="${att.id}">
|
<input type="hidden" name="attestationId" th:value="${att.id}">
|
||||||
<input type="hidden" name="studentId" th:value="${row.studentId}">
|
<input type="hidden" name="studentId" th:value="${row.studentId}">
|
||||||
<select class="input attestation-select" name="value" data-auto-submit
|
<select class="attestation-select" name="value" data-auto-submit
|
||||||
th:attr="data-student-name=${row.fullName},data-attestation-label=${att.kindLabel}">
|
th:classappend="${row.attestations[att.id] == null} ? 'none' : ''"
|
||||||
|
th:title="${row.fullName} + ' — ' + ${att.kindLabel} + ' (' + 'Семестр ' + ${att.semester} + ')'">
|
||||||
<option value="" th:selected="${row.attestations[att.id] == null}">—</option>
|
<option value="" th:selected="${row.attestations[att.id] == null}">—</option>
|
||||||
<option th:each="opt : ${att.options}" th:value="${opt.value}" th:text="${opt.label}"
|
<option th:each="opt : ${att.options}" th:value="${opt.value}" th:text="${opt.label}"
|
||||||
th:selected="${row.attestations[att.id]?.value == opt.value}"></option>
|
th:selected="${row.attestations[att.id]?.value == opt.value}"></option>
|
||||||
@@ -431,7 +434,7 @@
|
|||||||
<div class="dlg-body" id="assign-modal-body"></div>
|
<div class="dlg-body" id="assign-modal-body"></div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script th:src="@{/js/admin-group.js(v='41')}" defer></script>
|
<script th:src="@{/js/admin-group.js(v='42')}" defer></script>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<!-- v=37: сброс кэша стилей после изменения геометрии; при изменении css поднимать версию -->
|
<!-- v=37: сброс кэша стилей после изменения геометрии; при изменении css поднимать версию -->
|
||||||
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
|
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
|
||||||
<link rel="stylesheet" th:href="@{/css/bootstrap-icons.min.css}">
|
<link rel="stylesheet" th:href="@{/css/bootstrap-icons.min.css}">
|
||||||
<link rel="stylesheet" th:href="@{/css/app.css(v='39')}">
|
<link rel="stylesheet" th:href="@{/css/app.css(v='41')}">
|
||||||
<link id="hljs-light" rel="stylesheet" th:href="@{/css/hljs-github.css(v='36')}">
|
<link id="hljs-light" rel="stylesheet" th:href="@{/css/hljs-github.css(v='36')}">
|
||||||
<link id="hljs-dark" rel="stylesheet" th:href="@{/css/hljs-github-dark.css(v='36')}" disabled>
|
<link id="hljs-dark" rel="stylesheet" th:href="@{/css/hljs-github-dark.css(v='36')}" disabled>
|
||||||
<script th:src="@{/js/highlight.min.js(v='36')}" defer></script>
|
<script th:src="@{/js/highlight.min.js(v='36')}" defer></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user