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 @@