schon/engine/vibes_auth/admin.py
Egor fureunoir Gorbunov b1da9b90e2 Features: 1) Add new message "You cannot jump over your head!" in admin interface localization; 2) Update line references across various locales; 3) Improve formatting of multiline text in translation files;
Fixes: 1) Fix inconsistencies in string concatenation for English translations; 2) Correct missing or misplaced message references in locale files;

Extra: Resolve spacing and encoding inconsistencies in translation files.
2025-11-12 15:56:00 +03:00

194 lines
5.7 KiB
Python

from typing import Any
from django.contrib import admin
from django.contrib.auth.admin import (
GroupAdmin as BaseGroupAdmin,
)
from django.contrib.auth.admin import (
UserAdmin as BaseUserAdmin,
)
from django.contrib.auth.models import Group as BaseGroup
from django.contrib.auth.models import Permission
from django.core.exceptions import PermissionDenied
from django.db.models import Prefetch, QuerySet
from django.http import HttpRequest
from django.utils.translation import gettext_lazy as _
from rest_framework_simplejwt.token_blacklist.admin import (
BlacklistedTokenAdmin as BaseBlacklistedTokenAdmin,
)
from rest_framework_simplejwt.token_blacklist.admin import (
OutstandingTokenAdmin as BaseOutstandingTokenAdmin,
)
from rest_framework_simplejwt.token_blacklist.models import (
BlacklistedToken as BaseBlacklistedToken,
)
from rest_framework_simplejwt.token_blacklist.models import (
OutstandingToken as BaseOutstandingToken,
)
from engine.core.admin import ActivationActionsMixin
from engine.core.models import Order
from engine.payments.models import Balance
from engine.vibes_auth.forms import UserForm
from engine.vibes_auth.models import (
BlacklistedToken,
Group,
OutstandingToken,
User,
ChatMessage,
ChatThread,
ThreadStatus,
)
class BalanceInline(admin.TabularInline): # type: ignore [type-arg]
model = Balance
can_delete = False
extra = 0
verbose_name = _("balance")
verbose_name_plural = _("balance")
is_navtab = True
icon = "fa-solid fa-wallet"
class OrderInline(admin.TabularInline): # type: ignore [type-arg]
model = Order
extra = 0
verbose_name = _("order")
verbose_name_plural = _("orders")
is_navtab = True
icon = "fa-solid fa-cart-shopping"
class UserAdmin(ActivationActionsMixin, BaseUserAdmin): # type: ignore [misc, type-arg]
inlines = (BalanceInline, OrderInline)
fieldsets = (
(None, {"fields": ("email", "password")}),
(
_("personal info"),
{"fields": ("first_name", "last_name", "phone_number", "avatar")},
),
(
_("permissions"),
{
"fields": (
"is_active",
"is_verified",
"is_subscribed",
"is_staff",
"is_superuser",
"groups",
"user_permissions",
)
},
),
(_("important dates"), {"fields": ("last_login", "date_joined")}),
(_("additional info"), {"fields": ("language", "attributes")}),
)
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": ("email", "password1", "password2"),
},
),
)
list_display = ("email", "phone_number", "is_verified", "is_active", "is_staff")
search_fields = ("email", "phone_number")
list_filter = (
"is_verified",
"is_active",
"is_staff",
"is_superuser",
"is_subscribed",
)
ordering = ("email",)
readonly_fields = ("password",)
form = UserForm
def get_queryset(self, request: HttpRequest) -> QuerySet[User]:
qs = super().get_queryset(request)
return qs.prefetch_related("groups", "payments_balance", "orders").prefetch_related(
Prefetch(
"user_permissions",
queryset=Permission.objects.select_related("content_type"),
)
)
def save_model(self, request: HttpRequest, obj: Any, form: UserForm, change: Any) -> None:
if form.cleaned_data.get("attributes") is None:
obj.attributes = None
if form.cleaned_data.get("is_superuser", False) and not request.user.is_superuser:
raise PermissionDenied(_("You cannot jump over your head!"))
super().save_model(request, obj, form, change)
# noinspection PyUnusedLocal
@admin.register(ChatThread)
class ChatThreadAdmin(admin.ModelAdmin):
list_display = (
"uuid",
"user",
"email",
"assigned_to",
"status",
"last_message_at",
"is_active",
"created",
"modified",
)
list_filter = (
"status",
"is_active",
("assigned_to", admin.EmptyFieldListFilter),
)
search_fields = ("uuid", "email", "user__email", "user__username")
autocomplete_fields = ("user", "assigned_to")
actions = (
"close_threads",
"open_threads",
"delete_selected",
)
readonly_fields = ("created", "modified")
@admin.action(description=_("Close selected threads"))
def close_threads(self, request, queryset): # type: ignore[no-untyped-def]
queryset.update(status=ThreadStatus.CLOSED)
@admin.action(description=_("Open selected threads"))
def open_threads(self, request, queryset): # type: ignore[no-untyped-def]
queryset.update(status=ThreadStatus.OPEN)
@admin.register(ChatMessage)
class ChatMessageAdmin(admin.ModelAdmin):
list_display = ("uuid", "thread", "sender_type", "sender_user", "sent_at")
list_filter = ("sender_type",)
search_fields = ("uuid", "thread__uuid", "sender_user__email")
autocomplete_fields = ("thread", "sender_user")
readonly_fields = ("created", "modified")
class GroupAdmin(BaseGroupAdmin):
pass
class BlacklistedTokenAdmin(BaseBlacklistedTokenAdmin):
pass
class OutstandingTokenAdmin(BaseOutstandingTokenAdmin):
pass
admin.site.register(User, UserAdmin)
admin.site.unregister(BaseGroup)
admin.site.register(Group, GroupAdmin)
admin.site.unregister(BaseBlacklistedToken)
admin.site.register(BlacklistedToken, BlacklistedTokenAdmin)
admin.site.unregister(BaseOutstandingToken)
admin.site.register(OutstandingToken, OutstandingTokenAdmin)