diff --git a/com/templates/com/news_list.jinja b/com/templates/com/news_list.jinja
index 9a462607..49657e47 100644
--- a/com/templates/com/news_list.jinja
+++ b/com/templates/com/news_list.jinja
@@ -211,7 +211,7 @@
- {% trans %}Matmatronch{% endtrans %}
+ {% trans %}Matmatronch{% endtrans %}
diff --git a/core/schemas.py b/core/schemas.py
index 18a02833..325664e9 100644
--- a/core/schemas.py
+++ b/core/schemas.py
@@ -1,3 +1,4 @@
+from datetime import datetime
from pathlib import Path
from typing import Annotated, Any
@@ -8,12 +9,12 @@ from django.urls import reverse
from django.utils.text import slugify
from django.utils.translation import gettext as _
from haystack.query import SearchQuerySet
-from ninja import FilterSchema, ModelSchema, Schema, UploadedFile
-from pydantic import AliasChoices, Field
+from ninja import FilterLookup, FilterSchema, ModelSchema, Schema, UploadedFile
+from pydantic import AliasChoices, Field, field_validator
from pydantic_core.core_schema import ValidationInfo
from core.models import Group, QuickUploadImage, SithFile, User
-from core.utils import is_image
+from core.utils import get_last_promo, is_image
NonEmptyStr = Annotated[str, MinLen(1)]
@@ -109,7 +110,11 @@ class GroupSchema(ModelSchema):
class UserFilterSchema(FilterSchema):
- search: Annotated[str, MinLen(1)]
+ search: Annotated[str, MinLen(1)] | None = None
+ role: Annotated[str, FilterLookup("role__icontains")] | None = None
+ department: str | None = None
+ promo: int | None = None
+ date_of_birth: datetime | None = None
exclude: list[int] | None = Field(
None, validation_alias=AliasChoices("exclude", "exclude[]")
)
@@ -138,6 +143,13 @@ class UserFilterSchema(FilterSchema):
return Q()
return ~Q(id__in=value)
+ @field_validator("promo", mode="after")
+ @classmethod
+ def validate_promo(cls, value: int) -> int:
+ if not 0 < value <= get_last_promo():
+ raise ValueError(f"{value} is not a valid promo")
+ return value
+
class MarkdownSchema(Schema):
text: str
diff --git a/core/static/bundled/htmx-index.js b/core/static/bundled/htmx-index.js
index 474617ac..5880668d 100644
--- a/core/static/bundled/htmx-index.js
+++ b/core/static/bundled/htmx-index.js
@@ -1,11 +1,11 @@
import htmx from "htmx.org";
document.body.addEventListener("htmx:beforeRequest", (event) => {
- event.target.ariaBusy = true;
+ event.detail.target.ariaBusy = true;
});
-document.body.addEventListener("htmx:afterRequest", (event) => {
- event.originalTarget.ariaBusy = null;
+document.body.addEventListener("htmx:beforeSwap", (event) => {
+ event.detail.target.ariaBusy = null;
});
Object.assign(window, { htmx });
diff --git a/core/static/core/forms.scss b/core/static/core/forms.scss
index e1793a69..be876c9b 100644
--- a/core/static/core/forms.scss
+++ b/core/static/core/forms.scss
@@ -143,6 +143,15 @@ form {
line-height: 1;
white-space: nowrap;
+ .fields-centered {
+ padding: 10px 10px 0;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ gap: var(--nf-input-size) 10px;
+ justify-content: center;
+ }
+
.helptext {
margin-top: .25rem;
margin-bottom: .25rem;
diff --git a/core/static/user/user_edit.scss b/core/static/user/user_edit.scss
index 5b20fcee..20995da6 100644
--- a/core/static/user/user_edit.scss
+++ b/core/static/user/user_edit.scss
@@ -114,15 +114,6 @@
}
}
- &-fields {
- padding: 10px 10px 0;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- gap: var(--nf-input-size) 10px;
- justify-content: center;
- }
-
&-field {
display: flex;
flex-wrap: wrap;
diff --git a/core/templates/core/base/navbar.jinja b/core/templates/core/base/navbar.jinja
index 8d8ae447..fd1e6ddc 100644
--- a/core/templates/core/base/navbar.jinja
+++ b/core/templates/core/base/navbar.jinja
@@ -23,7 +23,7 @@