fix: polish group matrix headers and cell alignment
- shorten intermediate attestation header to «Пр. атт.» - vertically center row cell contents and left-align values - use normal header color/weight for average, password and actions - align attestation action buttons to equal height - add a divider before the actions column
This commit is contained in:
@@ -43,6 +43,15 @@ object AttestationPresentation {
|
||||
|
||||
fun kindLabel(kind: String): String = KIND_LABELS[kind] ?: kind
|
||||
|
||||
/** Короткая подпись для шапки узкого столбца. */
|
||||
fun shortKindLabel(kind: String): String =
|
||||
when (kind) {
|
||||
"intermediate" -> "Пр. атт."
|
||||
"pass" -> "Зачёт"
|
||||
"exam" -> "Экзамен"
|
||||
else -> kind
|
||||
}
|
||||
|
||||
/** Понимает и «2», и старые значения вроде «2 семестр»; вне 1–8 — 1. */
|
||||
fun semesterNumber(raw: String): Int {
|
||||
val digits = raw.filter { it.isDigit() }
|
||||
|
||||
@@ -69,6 +69,7 @@ data class GroupAttestation(
|
||||
val id: String = "",
|
||||
val kind: String = "",
|
||||
val kindLabel: String = "",
|
||||
val shortLabel: String = "",
|
||||
val semester: Int = 1,
|
||||
val published: Boolean = false,
|
||||
val options: List<AttestationOption> = emptyList(),
|
||||
|
||||
@@ -18,6 +18,7 @@ object GroupAttestationViews {
|
||||
id = column.id,
|
||||
kind = column.kind,
|
||||
kindLabel = AttestationPresentation.kindLabel(column.kind),
|
||||
shortLabel = AttestationPresentation.shortKindLabel(column.kind),
|
||||
semester = AttestationPresentation.semesterNumber(column.semester),
|
||||
published = column.published,
|
||||
options =
|
||||
|
||||
@@ -546,17 +546,22 @@ dialog.dlg.dlg-lg .dlg-body { max-height: 88vh; min-height: 62vh; }
|
||||
.scroll-x { overflow-x: auto; }
|
||||
.matrix { border-collapse: separate; border-spacing: 0; }
|
||||
.matrix th {
|
||||
vertical-align: top; padding: 0.75rem 1rem; text-align: left;
|
||||
vertical-align: middle; padding: 0.75rem 1rem; text-align: left;
|
||||
font-size: 0.75rem; font-weight: 500; color: var(--c-text-muted);
|
||||
background: var(--c-surface); white-space: nowrap;
|
||||
}
|
||||
.matrix td { vertical-align: top; padding: 1rem; }
|
||||
.matrix td { vertical-align: middle; padding: 1rem; }
|
||||
/* Непрозрачный фон обязателен: закреплённый столбец не должен просвечивать при прокрутке. */
|
||||
.matrix tbody tr:hover td { background: var(--c-row-hover); }
|
||||
.matrix tbody tr:hover td.matrix-sticky { background: var(--c-row-hover); }
|
||||
.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 td.cell-lab { min-width: 9.5rem; border-left: 1px solid var(--c-border); }
|
||||
#group-table th.password-col,
|
||||
#group-table th.average-col,
|
||||
#group-table th.actions-head { color: var(--c-text); font-weight: 400; }
|
||||
#group-table th.actions-head,
|
||||
#group-table td.actions-cell { border-left: 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 { 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); }
|
||||
@@ -564,14 +569,19 @@ dialog.dlg.dlg-lg .dlg-body { max-height: 88vh; min-height: 62vh; }
|
||||
.attestation-title { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; width: 100%; max-width: 9rem; text-align: left; }
|
||||
.attestation-kind { font-weight: 400; color: var(--c-text); white-space: normal; text-align: left; }
|
||||
.attestation-col .lab-col-head, .attestation-col .lab-col-title { text-align: left; }
|
||||
.js-attestation-form { display: flex; justify-content: center; width: 100%; }
|
||||
.attestation-col .lab-head-actions .btn {
|
||||
width: 1.7rem; height: 1.7rem; min-height: 1.7rem; padding: 0;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.attestation-col .lab-head-actions .ico { font-size: 0.95rem; line-height: 1; }
|
||||
.js-attestation-form { display: flex; justify-content: flex-start; 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;
|
||||
text-align: left; text-align-last: left; cursor: pointer;
|
||||
background-image:
|
||||
linear-gradient(45deg, transparent 50%, currentColor 50%),
|
||||
linear-gradient(135deg, currentColor 50%, transparent 50%);
|
||||
|
||||
@@ -73,11 +73,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text-center average-col" title="Средний балл по выставленным оценкам">Средний балл</th>
|
||||
<th class="average-col" title="Средний балл по выставленным оценкам">Средний балл</th>
|
||||
<th th:each="att : ${attestations}" class="text-center attestation-col" data-nosort>
|
||||
<div class="lab-col-head">
|
||||
<div class="attestation-title">
|
||||
<span class="attestation-kind" th:text="${att.kindLabel}">Аттестация</span>
|
||||
<span class="attestation-kind" th:text="${att.shortLabel}">Пр. атт.</span>
|
||||
</div>
|
||||
<span class="lab-col-title" th:text="'Семестр ' + ${att.semester}">Семестр 1</span>
|
||||
<div class="lab-head-actions">
|
||||
@@ -105,8 +105,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<th data-nosort>Пароль</th>
|
||||
<th class="text-right" data-nosort>Действия</th>
|
||||
<th class="password-col" data-nosort>Пароль</th>
|
||||
<th class="text-right actions-head" data-nosort>Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -155,9 +155,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center average-cell"
|
||||
<td class="average-cell"
|
||||
th:text="${row.averageScore != null ? row.averageScore : '—'}">—</td>
|
||||
<td th:each="att : ${attestations}" class="text-center attestation-cell">
|
||||
<td th:each="att : ${attestations}" class="attestation-cell">
|
||||
<form class="inline-form js-attestation-form" method="post"
|
||||
th:action="@{/admin/groups/{id}/attestation-results(id=${group.id})}">
|
||||
<input type="hidden" name="_csrf" th:value="${csrfToken}">
|
||||
@@ -172,7 +172,7 @@
|
||||
</select>
|
||||
</form>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<td class="password-cell">
|
||||
<span th:if="${row.mustChangePassword}" class="badge badge-warn">временный</span>
|
||||
<span th:unless="${row.mustChangePassword}" class="badge badge-ok">изменён</span>
|
||||
</td>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<!-- v=37: сброс кэша стилей после изменения геометрии; при изменении 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/app.css(v='42')}">
|
||||
<link rel="stylesheet" th:href="@{/css/app.css(v='44')}">
|
||||
<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>
|
||||
<script th:src="@{/js/highlight.min.js(v='36')}" defer></script>
|
||||
|
||||
Reference in New Issue
Block a user