Build out Positions CRUD and rework the Roles page

Positions had list/create/edit already stubbed as list-only; give it real
forms, with a check mirroring the management_position_implies_staff_position
constraint so a bad combination reads as a form error, not a 500. Roles now
groups by role (excluding the MEMBER everyone holds automatically, which was
just noise), grants via a modal instead of a separate page, and its member
picker is a small typeahead combobox instead of a long native <select>.
This commit is contained in:
2026-08-03 18:45:28 +02:00
parent 9b0af5800a
commit ce35348b31
13 changed files with 500 additions and 82 deletions

View File

@@ -2213,9 +2213,15 @@
}
}
}
.absolute {
position: absolute;
}
.fixed {
position: fixed;
}
.relative {
position: relative;
}
.static {
position: static;
}
@@ -2250,6 +2256,12 @@
}
}
}
.top-1 {
top: var(--spacing);
}
.left-1 {
left: var(--spacing);
}
.file-input {
@layer daisyui.l1.l2.l3 {
cursor: pointer;
@@ -2620,6 +2632,9 @@
.z-10 {
z-index: 10;
}
.col-span-full {
grid-column: 1 / -1;
}
.hero {
@layer daisyui.l1.l2.l3 {
display: grid;
@@ -3060,6 +3075,9 @@
.table {
display: table;
}
.aspect-square {
aspect-ratio: 1 / 1;
}
.h-12 {
height: calc(var(--spacing) * 12);
}
@@ -3075,6 +3093,9 @@
.h-screen {
height: 100vh;
}
.max-h-60 {
max-height: calc(var(--spacing) * 60);
}
.min-h-6 {
min-height: calc(var(--spacing) * 6);
}
@@ -3156,12 +3177,18 @@
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.flex-col {
flex-direction: column;
}
.flex-row {
flex-direction: row;
}
.flex-nowrap {
flex-wrap: nowrap;
}
.flex-wrap {
flex-wrap: wrap;
}
@@ -3434,6 +3461,9 @@
.object-contain {
object-fit: contain;
}
.object-cover {
object-fit: cover;
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
@@ -3564,6 +3594,9 @@
.whitespace-nowrap {
white-space: nowrap;
}
.whitespace-pre-line {
white-space: pre-line;
}
.alert-error {
@layer daisyui.l1.l2 {
color: var(--color-error-content);
@@ -3717,6 +3750,10 @@
outline-style: var(--tw-outline-style);
outline-width: 1px;
}
.blur {
--tw-blur: blur(8px);
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
@@ -3799,6 +3836,13 @@
--btn-soft-bg: initial;
}
}
.btn-xs {
@layer daisyui.l1.l2 {
--fontsize: 0.6875rem;
--btn-p: 0.5rem;
--size: calc(var(--size-field, 0.25rem) * 6);
}
}
.badge-accent {
@layer daisyui.l1.l2 {
--badge-color: var(--color-accent);
@@ -3881,6 +3925,11 @@
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
.md\:grid-cols-3 {
@media (width >= 48rem) {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
.md\:grid-cols-4 {
@media (width >= 48rem) {
grid-template-columns: repeat(4, minmax(0, 1fr));