diff --git a/contracts/admin.py b/contracts/admin.py index 3f93aeb673053e8e25d0ce1320fcb287237f0b62..a5474b072572315009a6e7951f313b3fedb9333b 100644 --- a/contracts/admin.py +++ b/contracts/admin.py @@ -1,6 +1,8 @@ from dal_admin_filters import AutocompleteFilter from django.contrib import admin from django.utils.html import format_html +from import_export import resources +from rangefilter.filters import DateRangeFilter from shared.admin import MarkdownxGuardedModelAdmin @@ -21,6 +23,11 @@ from .models import ( ) +class ContractResource(resources.ModelResource): + class Meta: + model = Contract + + class IndexHiddenModelAdmin(MarkdownxGuardedModelAdmin): def has_module_permission(self, request): return False @@ -31,8 +38,8 @@ class IndexHiddenModelAdmin(MarkdownxGuardedModelAdmin): class ContractAuthorPlaceholderFilter(AutocompleteFilter): title = "Autor" - field_name = "author" - autocomplete_url = "" + field_name = "created_by" + autocomplete_url = "users:select2_djhacker_user_autocomplete" # END Autocompletes @@ -175,10 +182,23 @@ class ContractAdmin(MarkdownxGuardedModelAdmin): super().save_model(request, obj, form, change) list_filter = ( - ContracteePlaceholderFilter, - SigneePlaceholderFilter, + "types", + "approval_state", + "legal_state", + "public_state", + "paper_form_state", + ContractAuthorPlaceholderFilter, + "issues", + ("all_parties_sign_date", DateRangeFilter), + ("valid_start_date", DateRangeFilter), + ("valid_end_date", DateRangeFilter), ) + list_display = ( + "name", + "approval_state", + "public_state", + ) # END Contracts @@ -209,6 +229,9 @@ class SigneeAdmin(MarkdownxGuardedModelAdmin): readonly_fields = ("load_ares_data_button",) + list_filter = ("entity_type",) + list_display = ("name", "entity_type") + inlines = (SigneeRepresentativeInline,) def load_ares_data_button(self, obj): diff --git a/contracts/migrations/0010_alter_contractee_address_country_and_more.py b/contracts/migrations/0010_alter_contractee_address_country_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..0848e91104082359695d27e41baef63a9b284113 --- /dev/null +++ b/contracts/migrations/0010_alter_contractee_address_country_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.4 on 2023-03-10 19:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0009_alter_contractee_address_country_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='contractee', + name='address_country', + field=models.CharField(default='Česká Republika', max_length=256, verbose_name='Země'), + ), + migrations.AlterField( + model_name='signee', + name='address_country', + field=models.CharField(default='Česká Republika', max_length=256, verbose_name='Země'), + ), + ] diff --git a/contracts/models.py b/contracts/models.py index e780429ffd42ac56862df54b801eff45cebfe128..509ed7daaf5aced4a101b16520c85ce5c074d621 100644 --- a/contracts/models.py +++ b/contracts/models.py @@ -98,6 +98,8 @@ class Signee(models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Jiná smluvní strana" verbose_name_plural = "Ostatní smluvní strany" @@ -145,6 +147,8 @@ class SigneeRepresentative(RepresentativeMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Zástupce" verbose_name_plural = "Zástupci" @@ -203,6 +207,8 @@ class Contractee(models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Naše smluvní strana" verbose_name_plural = "Naše smluvní strany" @@ -244,6 +250,8 @@ class ContracteeRepresentative(RepresentativeMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Zástupce" verbose_name_plural = "Zástupci" @@ -255,6 +263,8 @@ class ContractType(NameStrMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Typ smlouvy" verbose_name_plural = "Typy smlouvy" @@ -266,6 +276,8 @@ class ContractIssue(NameStrMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Problém se smlouvou" verbose_name_plural = "Problémy se smlouvami" @@ -282,11 +294,13 @@ class ContractFilingArea(NameStrMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Spisovna" verbose_name_plural = "Spisovny" -class Contract(models.Model): +class Contract(NameStrMixin, models.Model): # BEGIN Automatically set fields created_by = models.ForeignKey( @@ -482,6 +496,8 @@ class Contract(models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Smlouva" verbose_name_plural = "Smlouvy" @@ -493,20 +509,6 @@ class Contract(models.Model): is_public=True, ).all() - def __str__(self) -> str: - result = "" - - if self.approval_state == Contract.ApprovalStates.YES: - result += "SCHVÁLENÁ - " - elif self.approval_state == Contract.ApprovalStates.NO: - result += "NESCHVÁLENÁ - " - else: - result += "KE ZPRACOVÁNÍ - " - - result += self.name - - return result - class ContractFile(NameStrMixin, models.Model): name = models.CharField( @@ -533,6 +535,8 @@ class ContractFile(NameStrMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Soubor" verbose_name_plural = "Soubory" @@ -557,6 +561,8 @@ class ContracteeSignature(models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Podpis naší smluvní strany" verbose_name_plural = "Podpisy našich smluvních stran" @@ -597,6 +603,8 @@ class SigneeSignature(models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Podpis jiné smluvní strany" verbose_name_plural = "Podpisy ostatních smluvních stran" @@ -636,5 +644,7 @@ class ContractIntent(NameStrMixin, models.Model): ) class Meta: + app_label = "contracts" + verbose_name = "Záměr" verbose_name_plural = "Záměry" diff --git a/registry/settings/base.py b/registry/settings/base.py index c25e824f3e3f343c86b77dc2f7b0c4cb4f2c9b3f..333f1295adbd8915a4b3d015f9eccde2e3dd59f0 100644 --- a/registry/settings/base.py +++ b/registry/settings/base.py @@ -48,19 +48,23 @@ INSTALLED_APPS = [ "dal", "dal_select2", "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", + "import_export", + "rangefilter", "guardian", "markdownx", "pirates", "webpack_loader", "contracts", "oidc", - "shared", "users", ] @@ -81,7 +85,9 @@ ROOT_URLCONF = "registry.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], + "DIRS": [ + os.path.join(BASE_DIR, "registry") + ], "APP_DIRS": True, "OPTIONS": { "context_processors": [ @@ -179,6 +185,11 @@ WEBPACK_LOADER = { } +## Media files + +MEDIA_URL = "media/" + + ## Server USE_X_FORWARDED_HOST = True @@ -188,6 +199,12 @@ X_FRAME_OPTIONS = "SAMEORIGIN" SILENCED_SYSTEM_CHECKS = ["security.W019"] +## Admin + +ADMIN_INDEX_AUTO_CREATE_APP_GROUP = True +ADMIN_INDEX_SHOW_REMAINING_APPS = True + + ## App-specific DEFAULT_CONTRACTEE_NAME = env.str("DEFAULT_CONTRACTEE_NAME") diff --git a/registry/templates/admin/base.html b/registry/templates/admin/base.html new file mode 100644 index 0000000000000000000000000000000000000000..103f27d5a47f2943608c2b206ded2e578beb3297 --- /dev/null +++ b/registry/templates/admin/base.html @@ -0,0 +1,10 @@ +{% 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/urls.py b/registry/urls.py index 2a4013ea030f2d6cb57293fdf8f0bea69cdcca38..fbd47f4f0586ae05794842d95ab96b929a8cf413 100644 --- a/registry/urls.py +++ b/registry/urls.py @@ -13,13 +13,26 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ + +from django.conf import settings from django.contrib import admin -from django.urls import include, path +from django.urls import include, path, re_path +from django.views.static import serve from pirates.urls import urlpatterns as pirates_urlpatterns urlpatterns = [ path("", include("contracts.urls")), + path("", include("users.urls")), path("markdownx/", include("markdownx.urls")), path("oidc/", include("oidc.urls")), path("admin/", admin.site.urls), ] + pirates_urlpatterns + +if settings.DEBUG: + urlpatterns.append( + re_path( + r"^media/(?P<path>.*)$", + serve, + {"document_root": settings.MEDIA_ROOT} + ), + ) diff --git a/requirements/base.txt b/requirements/base.txt index f743df87fab2d83d52426933b63df0889d4fdfbb..9fd8bfa52a579ef340992f7d117b5ac379d74d29 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,8 +1,11 @@ dal-admin-filters==1.1.0 django==4.1.4 +django-admin-index==2.0.2 django-admin-interface==0.24.2 +django-admin-rangefilter==0.9.0 django-autocomplete-light==3.9.4 django-database-url==1.0.3 +django-import-export==3.1.0 djhacker==0.2.3 psycopg2-binary==2.9.5 django-webpack-loader==1.8.0 diff --git a/static_src/admin/admin_index_custom.css b/static_src/admin/admin_index_custom.css new file mode 100644 index 0000000000000000000000000000000000000000..4216cd1ad126fb39036d1687abf0f3fcf4b29577 --- /dev/null +++ b/static_src/admin/admin_index_custom.css @@ -0,0 +1,4 @@ +:root { + --djai-tab-bg: #ff0080; + --djai-tab-bg--hover: #a91b60; +} diff --git a/users/admin.py b/users/admin.py index 8c38f3f3dad51e4585f3984282c2a4bec5349c1e..d2e7cac9cda39bc9169098b90e87182b9559c76e 100644 --- a/users/admin.py +++ b/users/admin.py @@ -1,3 +1,7 @@ from django.contrib import admin -# Register your models here. +from shared.admin import MarkdownxGuardedModelAdmin + +from .models import User + +admin.site.register(User, MarkdownxGuardedModelAdmin) diff --git a/users/apps.py b/users/apps.py index 88f7b1798e7f1150a0e4e86781d9533d9573db3d..abeee2f0c63140b6b17c3c95beb9aa8c2cf92a04 100644 --- a/users/apps.py +++ b/users/apps.py @@ -4,3 +4,4 @@ from django.apps import AppConfig class UsersConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "users" + verbose_name = "Uživatelé" diff --git a/users/migrations/0002_alter_user_options.py b/users/migrations/0002_alter_user_options.py new file mode 100644 index 0000000000000000000000000000000000000000..2de062f1b4382f8323c5e4ed0eac1e32cf4d7442 --- /dev/null +++ b/users/migrations/0002_alter_user_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.4 on 2023-03-10 20:07 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='user', + options={}, + ), + ] diff --git a/users/models.py b/users/models.py index 11e82baf8f2eae2b3caf8dcbdd10dce9d39caef4..6334f7199c12eed982f8859e6ce109b424be1f9c 100644 --- a/users/models.py +++ b/users/models.py @@ -13,3 +13,8 @@ class User(pirates_models.AbstractUser): first_name += " " return f"{first_name}{self.last_name}" + + class Meta: + app_label = "users" + verbose_name = "Uživatel" + verbose_name_plural = "Uživatelé" diff --git a/users/urls.py b/users/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..cc5e95051fe7f770a6b77c339789047d50adf9bc --- /dev/null +++ b/users/urls.py @@ -0,0 +1,14 @@ +import dal.autocomplete + +from django.urls import path + +from . import views, models + +app_name = "users" +urlpatterns = [ + path( + "autocomplete", + dal.autocomplete.Select2QuerySetView.as_view(model=models.User), + name="select2_djhacker_user_autocomplete", + ), +]