From f4903b0d1da6fa4c19d0ee0555b92b67846d4290 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <git@imaniti.org>
Date: Sun, 12 Mar 2023 22:29:35 +0100
Subject: [PATCH] finish admin theme, working on simple button navigation

---
 contracts/admin.py                      | 20 ++++++++++++++-
 registry/settings/base.py               |  5 ++--
 registry/templates/admin/base.html      | 10 --------
 registry/templates/admin/base_site.html | 34 +++++++++++++++++++++++++
 registry/templates/admin/index.html     | 16 ++++++++++++
 requirements/base.txt                   |  1 +
 users/models.py                         | 16 ++++++++++++
 7 files changed, 89 insertions(+), 13 deletions(-)
 delete mode 100644 registry/templates/admin/base.html
 create mode 100644 registry/templates/admin/base_site.html
 create mode 100644 registry/templates/admin/index.html

diff --git a/contracts/admin.py b/contracts/admin.py
index a5474b0..f528005 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -1,3 +1,5 @@
+from admin_extra_buttons.api import ExtraButtonsMixin, button
+from admin_extra_buttons.utils import HttpResponseRedirectToReferrer
 from dal_admin_filters import AutocompleteFilter
 from django.contrib import admin
 from django.utils.html import format_html
@@ -73,7 +75,7 @@ class ContractIntentInline(admin.TabularInline):
     extra = 0
 
 
-class ContractAdmin(MarkdownxGuardedModelAdmin):
+class ContractAdmin(ExtraButtonsMixin, MarkdownxGuardedModelAdmin):
     form = ContractAdminForm
 
     readonly_fields = ("created_by",)
@@ -85,6 +87,22 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
         ContractIntentInline,
     )
 
+    @button(
+        permission="contracts.approve",
+        label="Schválit",
+        change_form=True,
+        html_attrs={
+            "style": "background-color:var(--admin-interface-save-button-background-color);"
+                "color:var(--admin-interface-save-button-text-color)"
+        }
+    )
+    def approve(self, request):
+        
+        
+        self.message_user(request, "Smlouva schválena.")
+        
+        return HttpResponseRedirectToReferrer(request)
+
     def get_fieldsets(self, request, obj=None):
         fieldsets = [
             (
diff --git a/registry/settings/base.py b/registry/settings/base.py
index 333f129..7849f65 100644
--- a/registry/settings/base.py
+++ b/registry/settings/base.py
@@ -50,19 +50,20 @@ INSTALLED_APPS = [
     "dal_admin_filters",
     "django_admin_index",
     "ordered_model",
-    "shared",
     "django.contrib.admin",
     "django.contrib.auth",
     "django.contrib.contenttypes",
     "django.contrib.sessions",
     "django.contrib.messages",
     "django.contrib.staticfiles",
+    "admin_extra_buttons",
     "import_export",
     "rangefilter",
     "guardian",
     "markdownx",
     "pirates",
     "webpack_loader",
+    "shared",
     "contracts",
     "oidc",
     "users",
@@ -86,7 +87,7 @@ TEMPLATES = [
     {
         "BACKEND": "django.template.backends.django.DjangoTemplates",
         "DIRS": [
-            os.path.join(BASE_DIR, "registry")
+            os.path.join(BASE_DIR, "registry", "templates")
         ],
         "APP_DIRS": True,
         "OPTIONS": {
diff --git a/registry/templates/admin/base.html b/registry/templates/admin/base.html
deleted file mode 100644
index 103f27d..0000000
--- a/registry/templates/admin/base.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends 'admin/base.html' %}
-
-{% block extrastyle %}{{ block.super }}
-<style>
-    :root {
-        --djai-tab-bg: #ff0080;
-        --djai-tab-bg--hover: #a91b60;
-    }
-</style>
-{% endblock %} 
diff --git a/registry/templates/admin/base_site.html b/registry/templates/admin/base_site.html
new file mode 100644
index 0000000..20560f9
--- /dev/null
+++ b/registry/templates/admin/base_site.html
@@ -0,0 +1,34 @@
+{% extends 'admin/base_site.html' %}
+
+{% block extrastyle %}{{ block.super }}
+<style>
+    :root {
+        --djai-tab-bg: #000 !important;
+        --djai-tab-bg--active: #424242 !important;
+        --djai-tab-bg--hover: #424242 !important;
+        --djai-dropdown-bg: #424242 !important;
+        --djai-dropdown-bg--active: #5e5e5e !important;
+        --djai-dropdown-bg--hover: #5e5e5e !important;
+    }
+    
+    .index-action-buttons {
+        display: flex;
+        flex-direction: row;
+        row-gap: 10px;
+    }
+    
+    .index-action-buttons button,
+    .index-action-buttons [aria-role="button"],
+    .index-action-buttons button:visited,
+    .index-action-buttons [aria-role="button"]:visited,
+    .index-action-buttons button:hover,
+    .index-action-buttons [aria-role="button"]:hover {
+        padding: 10px 15px;
+        margin-bottom: 15px;
+        background-color: var(--admin-interface-module-background-color) !important;
+        color: var(--admin-interface-module-text-color) !important;
+        border-radius: var(--admin-interface-module-border-radius) !important;
+        text-decoration: none !important;
+    }
+</style>
+{% endblock %} 
diff --git a/registry/templates/admin/index.html b/registry/templates/admin/index.html
new file mode 100644
index 0000000..be5f8f5
--- /dev/null
+++ b/registry/templates/admin/index.html
@@ -0,0 +1,16 @@
+{% extends "admin/index.html" %}
+
+{% block content %}
+
+{% if request.user.can_approve_contracts %}
+    <div class="index-action-buttons">
+        <a
+            href="contracts/contract/?approval_state__exact=no"
+            aria-role="button"
+        >Smlouvy ke schválení ({{ request.user.contracts_to_approve_count }})</a>
+    </div>
+{% endif %}
+
+{{ block.super }}
+
+{% endblock %}
diff --git a/requirements/base.txt b/requirements/base.txt
index 9fd8bfa..ade0d47 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -1,5 +1,6 @@
 dal-admin-filters==1.1.0
 django==4.1.4
+django-admin-extra-buttons==1.5.6
 django-admin-index==2.0.2
 django-admin-interface==0.24.2
 django-admin-rangefilter==0.9.0
diff --git a/users/models.py b/users/models.py
index 6334f71..52074a4 100644
--- a/users/models.py
+++ b/users/models.py
@@ -14,6 +14,22 @@ class User(pirates_models.AbstractUser):
 
         return f"{first_name}{self.last_name}"
 
+    @property
+    def can_approve_contracts(self) -> bool:
+        # TODO: Do we need the superuser check?
+        return self.is_superuser or self.has_perm("contracts.approve")
+
+    @property
+    def contracts_to_approve_count(self) -> int:
+        if not self.can_approve_contracts:
+            return 0
+
+        from contracts.models import Contract
+
+        return Contract.objects.filter(
+            approval_state=Contract.ApprovalStates.NO
+        ).count()
+
     class Meta:
         app_label = "users"
         verbose_name = "Uživatel"
-- 
GitLab