From 152e980759ad602392515e8068569cc90c74eaf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Thu, 29 Aug 2024 10:29:36 +0800 Subject: [PATCH] make state indicator readonly, and add more function to alias action list --- djangocms_version_locking/cms_config.py | 11 ++- .../monkeypatch/admin.py | 37 ++++++++++ .../monkeypatch/djangocms_alias/__init__.py | 0 .../monkeypatch/djangocms_alias/admin.py | 67 +++++++++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 djangocms_version_locking/monkeypatch/admin.py create mode 100644 djangocms_version_locking/monkeypatch/djangocms_alias/__init__.py create mode 100644 djangocms_version_locking/monkeypatch/djangocms_alias/admin.py diff --git a/djangocms_version_locking/cms_config.py b/djangocms_version_locking/cms_config.py index e26f065..5abef7b 100644 --- a/djangocms_version_locking/cms_config.py +++ b/djangocms_version_locking/cms_config.py @@ -1,5 +1,5 @@ -from django.template.loader import render_to_string from django.utils.html import format_html +from django.utils.safestring import mark_safe from cms.app_base import CMSAppConfig, CMSAppExtension @@ -12,7 +12,7 @@ def add_alias_version_lock(obj, field): version = obj.versions.all()[0] lock_icon = "" if version.state == DRAFT and version_is_locked(version): - lock_icon = render_to_string("djangocms_version_locking/admin/locked_mixin_icon.html") + lock_icon = mark_safe('') return format_html( "{is_locked}{field_value}", is_locked=lock_icon, @@ -21,6 +21,13 @@ def add_alias_version_lock(obj, field): class VersionLockingCMSExtension(CMSAppExtension): + def __init__(self): + # The monkey patch is here to be sure that at module load time the Version class + # is registered and can be overriden without requiring a strict load order + # in the INSTALLED_APPS setting in a projects settings.py. This is why this patch + # Isn't loaded from: VersionLockingConfig.ready + from .monkeypatch import admin as monkeypatched_version_admin # noqa: F401 + from .monkeypatch.djangocms_alias import admin as monkeypatched_alias_admin # noqa: F401 def configure_app(self, cms_config): pass diff --git a/djangocms_version_locking/monkeypatch/admin.py b/djangocms_version_locking/monkeypatch/admin.py new file mode 100644 index 0000000..5769428 --- /dev/null +++ b/djangocms_version_locking/monkeypatch/admin.py @@ -0,0 +1,37 @@ +import json + +from django.template.loader import render_to_string +from django.utils.translation import gettext_lazy as _ + +from djangocms_versioning.admin import StateIndicatorMixin +from djangocms_versioning.constants import INDICATOR_DESCRIPTIONS +from djangocms_versioning.indicators import content_indicator, content_indicator_menu +from djangocms_versioning.helpers import get_latest_admin_viewable_content + +def _get_indicator_column(func): + ''' + Change the State Indicator to readonly, publish process will be take over by djangocms-moderation. + ''' + def inner(self, request): + def indicator(obj): + if self._extra_grouping_fields is not None: # Grouper Model + content_obj = get_latest_admin_viewable_content(obj, include_unpublished_archived=True, **{ + field: getattr(self, field) for field in self._extra_grouping_fields + }) + else: # Content Model + content_obj = obj + status = content_indicator(content_obj) + return render_to_string( + "admin/djangocms_versioning/indicator.html", + { + "state": status or "empty", + "description": INDICATOR_DESCRIPTIONS.get(status, _("Empty")), + "menu_template": "admin/cms/page/tree/indicator_menu.html", + } + ) + indicator.short_description = self.indicator_column_label + return indicator + return inner + + +StateIndicatorMixin.get_indicator_column = _get_indicator_column(StateIndicatorMixin.get_indicator_column) diff --git a/djangocms_version_locking/monkeypatch/djangocms_alias/__init__.py b/djangocms_version_locking/monkeypatch/djangocms_alias/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/djangocms_version_locking/monkeypatch/djangocms_alias/admin.py b/djangocms_version_locking/monkeypatch/djangocms_alias/admin.py new file mode 100644 index 0000000..97780cc --- /dev/null +++ b/djangocms_version_locking/monkeypatch/djangocms_alias/admin.py @@ -0,0 +1,67 @@ +from django.contrib import admin +from django.urls import reverse +from django.http import HttpRequest +from django.utils.translation import gettext_lazy as _ + +from djangocms_alias.admin import AliasAdmin as OriginalAliasAdmin +from djangocms_alias.models import Alias +from djangocms_versioning.helpers import get_latest_admin_viewable_content, proxy_model, version_list_url + + +class AliasAdmin(OriginalAliasAdmin): + def get_actions_list(self) -> list: + """Add alias edit link, manage version link""" + original_list = super().get_actions_list() + usage_link_index = original_list.index(self._get_alias_usage_link) + original_list.insert(usage_link_index-1, self._get_edit_link) + original_list.insert(usage_link_index-1, self._get_manage_versions_link) + + +def _get_content_obj(self, obj: Alias): + if self._extra_grouping_fields is not None: # Grouper Model + content_obj = get_latest_admin_viewable_content(obj, include_unpublished_archived=True, **{ + field: getattr(self, field) for field in self._extra_grouping_fields + }) + else: # Content Model + content_obj = obj + return content_obj + +def _get_manage_versions_link(self, obj: Alias, request: HttpRequest, disabled: bool = False): + url = version_list_url(self._get_content_obj(obj)) + return self.admin_action_button( + url, + icon="copy", + title=_("Manage versions"), + name="manage-versions", + disabled=disabled, + ) + +def _get_edit_link(self, obj: Alias, request: HttpRequest, disabled: bool = False): + version = proxy_model(obj, self._get_content_obj(obj)) + # if not version.check_edit_redirect.as_bool(request.user): + # # Don't display the link if it can't be edited + # return "" + if not version.check_edit_redirect.as_bool(request.user): + disabled = True + + url = reverse( + "admin:{app}_{model}_edit_redirect".format( + app=version._meta.app_label, model=version._meta.model_name + ), + args=(version.pk,), + ) + + # close sideframe as edit will always be on page and not in sideframe + return self.admin_action_button( + url=url, + icon="pencil", + title=_("Edit"), + name="edit", + disabled=disabled, + action="post", + keepsideframe=False, + ) + + +admin.site.unregister(Alias) +admin.site.register(Alias, AliasAdmin)