diff --git a/djangocms_versioning/admin.py b/djangocms_versioning/admin.py index 0641bcb3..77b1748b 100644 --- a/djangocms_versioning/admin.py +++ b/djangocms_versioning/admin.py @@ -8,6 +8,7 @@ from cms.models import PageContent from cms.utils import get_language_from_request from cms.utils.conf import get_cms_setting +from cms.utils.helpers import is_editable_model from cms.utils.urlutils import add_url_parameters, static_with_version from django.conf import settings from django.contrib import admin, messages @@ -464,10 +465,26 @@ def _get_edit_link(self, obj, request, disabled=False): f"admin:{version._meta.app_label}_{version._meta.model_name}_edit_redirect", args=(version.pk,), ) + # Only show if no draft exists + if version.state == PUBLISHED: + pks_for_grouper = version.versionable.for_content_grouping_values( + obj + ).values_list("pk", flat=True) + drafts = Version.objects.filter( + object_id__in=pks_for_grouper, + content_type=version.content_type, + state=DRAFT, + ) + if drafts.exists(): + return "" + icon = "edit-new" + else: + icon = "edit" + return self.admin_action_button( url, - icon="pencil", - title=_("Edit"), + icon=icon, + title=_("Edit") if icon == "edit" else _("New Draft"), name="edit", disabled=disabled, action="post", @@ -747,7 +764,7 @@ def _get_edit_link(self, obj, request, disabled=False): return "" icon = "edit-new" else: - icon = "pencil" + icon = "edit" # Don't open in the sideframe if the item is not sideframe compatible keepsideframe = obj.versionable.content_model_is_sideframe_editable @@ -759,7 +776,7 @@ def _get_edit_link(self, obj, request, disabled=False): return self.admin_action_button( edit_url, icon=icon, - title=_("Edit") if icon == "pencil" else _("New Draft"), + title=_("Edit") if icon == "edit" else _("New Draft"), name="edit", action="post", disabled=disabled, @@ -822,6 +839,32 @@ def _get_unlock_link(self, obj, request): disabled=not obj.check_unlock.as_bool(request.user), ) + def _get_settings_link(self, obj, request): + """ + Generate a settings button for the Versioning Admin + """ + + # If the content object is not registered for frontend editing no action should be present + # Also, the content object must be registered with the admin site + content_model = obj.versionable.content_model + if not is_editable_model(content_model): + return "" + + try: + settings_url = reverse( + f"admin:{content_model._meta.app_label}_{content_model._meta.model_name}_change", + args=(obj.content.pk,) + ) + except Resolver404: + return "" + + return self.admin_action_button( + settings_url, + icon="settings", + title=_("Settings"), + name="settings", + ) + def get_actions_list(self): """Returns all action links as a list""" return self.get_state_actions() @@ -848,6 +891,7 @@ def get_state_actions(self): self._get_revert_link, self._get_discard_link, self._get_unlock_link, + self._get_settings_link, ] @admin.action( @@ -945,6 +989,7 @@ def publish_view(self, request, object_id): request, self.model._meta, object_id ) + requested_redirect = request.GET.get("next", None) if conf.ON_PUBLISH_REDIRECT in ("preview", "published"): redirect_url=get_preview_url(version.content) else: @@ -952,12 +997,12 @@ def publish_view(self, request, object_id): if not version.can_be_published(): self.message_user(request, _("Version cannot be published"), messages.ERROR) - return redirect(redirect_url) + return redirect(requested_redirect or redirect_url) try: version.check_publish(request.user) except ConditionFailed as e: self.message_user(request, force_str(e), messages.ERROR) - return redirect(redirect_url) + return redirect(requested_redirect or redirect_url) # Publish the version version.publish(request.user) @@ -970,7 +1015,7 @@ def publish_view(self, request, object_id): if hasattr(version.content, "get_absolute_url"): redirect_url = version.content.get_absolute_url() or redirect_url - return redirect(redirect_url) + return redirect(requested_redirect or redirect_url) def unpublish_view(self, request, object_id): """Unpublishes the specified version and redirects back to the @@ -1085,7 +1130,7 @@ def edit_redirect_view(self, request, object_id): return redirect(version_list_url(version.content)) # Redirect - return redirect(get_editable_url(target.content)) + return redirect(get_editable_url(target.content, request.GET.get("force_admin"))) def revert_view(self, request, object_id): """Reverts to the specified version i.e. creates a draft from it.""" diff --git a/djangocms_versioning/cms_config.py b/djangocms_versioning/cms_config.py index e2894084..39dbc70a 100644 --- a/djangocms_versioning/cms_config.py +++ b/djangocms_versioning/cms_config.py @@ -268,6 +268,8 @@ def on_page_content_archive(version): class VersioningCMSPageAdminMixin(VersioningAdminMixin): + change_form_template = "admin/djangocms_versioning/page/change_form.html" + def get_readonly_fields(self, request, obj=None): fields = super().get_readonly_fields(request, obj) if obj: @@ -281,15 +283,6 @@ def get_readonly_fields(self, request, obj=None): fields.remove(f_name) return fields - def get_form(self, request, obj=None, **kwargs): - form = super().get_form(request, obj, **kwargs) - if obj: - version = Version.objects.get_for_content(obj) - if not version.check_modify.as_bool(request.user): - for f_name in ["slug", "overwrite_url"]: - form.declared_fields[f_name].widget.attrs["readonly"] = True - return form - def get_queryset(self, request): urls = ("cms_pagecontent_get_tree",) queryset = super().get_queryset(request) diff --git a/djangocms_versioning/cms_toolbars.py b/djangocms_versioning/cms_toolbars.py index 84f03e28..007cac53 100644 --- a/djangocms_versioning/cms_toolbars.py +++ b/djangocms_versioning/cms_toolbars.py @@ -292,6 +292,9 @@ def get_page_content(self, language=None): if not language: language = self.current_lang + toolbar_obj = self.toolbar.get_object() + if toolbar_obj and toolbar_obj.language == language: + return self.toolbar.get_object() return get_latest_admin_viewable_content(self.page, language=language) def populate(self): diff --git a/djangocms_versioning/helpers.py b/djangocms_versioning/helpers.py index 8d2213d8..76636e14 100644 --- a/djangocms_versioning/helpers.py +++ b/djangocms_versioning/helpers.py @@ -233,11 +233,11 @@ def is_content_editable(placeholder, user): return version.state == DRAFT -def get_editable_url(content_obj): +def get_editable_url(content_obj, force_admin=False): """If the object is editable the cms editable view should be used, with the toolbar. - This method is provides the URL for it. + This method provides the URL for it. """ - if is_editable_model(content_obj.__class__): + if is_editable_model(content_obj.__class__) and not force_admin: language = getattr(content_obj, "language", None) url = get_object_edit_url(content_obj, language) # Or else, the standard edit view should be used diff --git a/djangocms_versioning/static/djangocms_versioning/css/object-tools.css b/djangocms_versioning/static/djangocms_versioning/css/object-tools.css new file mode 100644 index 00000000..6b7b671e --- /dev/null +++ b/djangocms_versioning/static/djangocms_versioning/css/object-tools.css @@ -0,0 +1,8 @@ +.object-tools a.accent { + background-color: var(--accent) !important; +} +.object-tools a.accent:hover, +.object-tools a.accent:active, +.object-tools a.accent:hover:active { + background-color: color-mix(in srgb, var(--accent) 90%, var(--dca-black)) !important; +} diff --git a/djangocms_versioning/static/djangocms_versioning/js/object-tools.js b/djangocms_versioning/static/djangocms_versioning/js/object-tools.js new file mode 100644 index 00000000..ca7e1e44 --- /dev/null +++ b/djangocms_versioning/static/djangocms_versioning/js/object-tools.js @@ -0,0 +1,13 @@ +(function($) { + $(document).ready(function() { + $('.cms-form-post-method').on('click', function(e) { + e.preventDefault(); + var csrf_token = document.querySelector('form input[name="csrfmiddlewaretoken"]').value; + var url = this.href; + var $form = $('
'); + var $csrf = $(``); + $form.append($csrf); + $form.appendTo('body').submit(); + }); + }); +})(django.jQuery); diff --git a/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html b/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html new file mode 100644 index 00000000..92d00d0e --- /dev/null +++ b/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html @@ -0,0 +1,100 @@ +{% extends "admin/cms/page/change_form.html" %} +{% load static admin_urls admin_modify djangocms_versioning i18n cms_admin %} + +{% block extrahead %} + {{ block.super }} + +{% endblock %} +{% block extrastyle %} + {{ block.super }} + +{% endblock %} + +{% block content_title %} + {% if title %}