From f2c8488267dc247ffcccbbda63853354304dde49 Mon Sep 17 00:00:00 2001 From: Freeman Date: Tue, 13 Aug 2024 09:54:35 +0800 Subject: [PATCH 01/18] initial changes made for cms4.1 compatible --- .github/workflows/lint.yml | 6 +++--- .github/workflows/test.yml | 3 ++- djangocms_pageadmin/admin.py | 24 +++++++++++------------- djangocms_pageadmin/compat.py | 9 +++++++++ djangocms_pageadmin/monkeypatch.py | 3 ++- setup.py | 4 ++-- tests/settings.py => test_settings.py | 4 ++-- tests/requirements/dj42_cms41.txt | 17 +++++++++++++++++ tests/test_admin.py | 14 +++++++------- 9 files changed, 55 insertions(+), 29 deletions(-) rename tests/settings.py => test_settings.py (95%) create mode 100644 tests/requirements/dj42_cms41.txt diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a1c808c..306b14d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: '3.11' - name: Install flake8 run: pip install --upgrade flake8 - name: Run flake8 @@ -29,10 +29,10 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: '3.11' - run: python -m pip install isort - name: isort uses: liskin/gh-problem-matcher-wrap@v1 with: linters: isort - run: isort -c -rc -df ./ + run: isort --check-only --diff ./ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 55624ae..711f383 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,10 +8,11 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ 3.8, 3.9, '3.10' ] # latest release minus two + python-version: [ 3.8, 3.9, '3.10', '3.11' ] # latest release minus two requirements-file: [ dj32_cms40.txt, dj42_cms40.txt, + dj42_cms41.txt, ] steps: diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index e239476..88a01ab 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -20,21 +20,18 @@ from django.utils.translation import get_language, gettext_lazy as _, override from django.views.decorators.http import require_POST -from cms import api from cms.admin.pageadmin import PageContentAdmin as DefaultPageContentAdmin from cms.extensions import extension_pool from cms.models import PageContent, PageUrl from cms.signals.apphook import set_restart_trigger from cms.toolbar.utils import get_object_preview_url -from djangocms_version_locking.helpers import version_is_locked -from djangocms_version_locking.models import VersionLock from djangocms_versioning.admin import VersioningAdminMixin from djangocms_versioning.constants import DRAFT, PUBLISHED -from djangocms_versioning.helpers import version_list_url +from djangocms_versioning.helpers import version_is_locked, version_list_url from djangocms_versioning.models import Version -from .compat import DJANGO_4_2 +from .compat import DJANGO_4_2, create_page_content from .filters import ( AuthorFilter, LanguageFilter, @@ -80,10 +77,11 @@ def get_queryset(self, request): # Collect locked status to handle the requirement that lock # on a draft version dictates the unpublish permission # on a published version - draft_version_lock_subquery = VersionLock.objects.filter( - version__content_type=OuterRef("content_type"), - version__object_id=OuterRef("object_id"), - version__state=DRAFT, + draft_version_lock_subquery = Version.objects.filter( + content_type=OuterRef("content_type"), + object_id=OuterRef("object_id"), + state=DRAFT, + locked_by__isnull=False, ).order_by("-pk") queryset = ( super() @@ -97,7 +95,7 @@ def get_queryset(self, request): queryset=Version.objects.annotate( # used by locking _draft_version_user_id=Subquery( - draft_version_lock_subquery.values("created_by")[:1] + draft_version_lock_subquery.values("locked_by")[:1] ) ) .select_related("created_by", "versionlock") @@ -249,7 +247,6 @@ def _get_edit_link(self, obj, request, disabled=False): if version.state not in (DRAFT, PUBLISHED): # Don't display the link if it can't be edited return "" - if not version.check_edit_redirect.as_bool(request.user): disabled = True @@ -404,9 +401,10 @@ def duplicate_view(self, request, object_id): translations=False, permissions=False, extensions=False, + user=request.user ) - new_page_content = api.create_title( + new_page_content = create_page_content( page=new_page, language=obj.language, slug=form.cleaned_data["slug"], @@ -415,7 +413,7 @@ def duplicate_view(self, request, object_id): template=obj.template, created_by=request.user, ) - new_page.title_cache[obj.language] = new_page_content + new_page.page_content_cache[obj.language] = new_page_content extension_pool.copy_extensions( source_page=obj.page, target_page=new_page, languages=[obj.language] diff --git a/djangocms_pageadmin/compat.py b/djangocms_pageadmin/compat.py index f2c5cad..c44e7df 100644 --- a/djangocms_pageadmin/compat.py +++ b/djangocms_pageadmin/compat.py @@ -1,6 +1,15 @@ import django +from cms import __version__ as CMS_VERSION + from packaging.version import Version DJANGO_4_2 = Version(django.get_version()) >= Version('4.2') + +CMS_41 = Version("4.1") <= Version(CMS_VERSION) + +if CMS_41: + from cms.api import create_page_content # noqa: F401 +else: + from cms.api import create_title as create_page_content # noqa: F401 diff --git a/djangocms_pageadmin/monkeypatch.py b/djangocms_pageadmin/monkeypatch.py index 4bde944..55c3694 100644 --- a/djangocms_pageadmin/monkeypatch.py +++ b/djangocms_pageadmin/monkeypatch.py @@ -29,11 +29,12 @@ def inner(self, **kwargs): if not published_version: return + url = published_version.get_absolute_url() if hasattr(published_version, "get_absolute_url") else None if self.toolbar.edit_mode_active or self.toolbar.preview_mode_active: item = ButtonList(side=self.toolbar.RIGHT) view_published_button = ButtonWithAttributes( _("View Published"), - url=published_version.get_absolute_url(), + url=url, disabled=False, extra_classes=['cms-btn', 'cms-btn-switch-save'], html_attributes={"target": "_blank"}, diff --git a/setup.py b/setup.py index c38d30d..b061ad9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ INSTALL_REQUIREMENTS = [ "Django>=3.2,<5.0", - "django_cms", + "django-cms", "django-treebeard>=4.3", ] @@ -27,5 +27,5 @@ author="Fidelity International", url="https://github.com/FidelityInternational/djangocms-pageadmin", license="BSD", - test_suite="tests.settings.run", + test_suite="test_settings.run", ) diff --git a/tests/settings.py b/test_settings.py similarity index 95% rename from tests/settings.py rename to test_settings.py index 5b254e1..7e14fb9 100644 --- a/tests/settings.py +++ b/test_settings.py @@ -18,7 +18,7 @@ def __getitem__(self, item): HELPER_SETTINGS = { - "SECRET_KEY": "djangocmspageadmintestsuitekey", + "SECRET_KEY": "djangocms-pageadmin-test-suite", "INSTALLED_APPS": [ "djangocms_pageadmin", "djangocms_text_ckeditor", @@ -73,7 +73,7 @@ def __getitem__(self, item): def run(): - from djangocms_helper import runner + from app_helper import runner runner.cms("djangocms_pageadmin", extra_args=[]) diff --git a/tests/requirements/dj42_cms41.txt b/tests/requirements/dj42_cms41.txt new file mode 100644 index 0000000..e5ddadc --- /dev/null +++ b/tests/requirements/dj42_cms41.txt @@ -0,0 +1,17 @@ +-r ./requirements_base.txt + +Django>=4.2,<5.0 +# django-classy-tags<=4.1.0 +django-sekizai<=4.1.0 + +# Unreleased djangoCMS 4.1 compatible packages +https://github.com/django-cms/django-cms/tarball/release/4.1.x#egg=django-cms +https://github.com/django-cms/djangocms-versioning/tarball/2.0.2#egg=djangocms-versioning +https://github.com/django-cms/djangocms-alias/tarball/2.0.1#egg=djangocms-alias +https://github.com/django-cms/djangocms-text-ckeditor/tarball/5.1.5#egg=djangocms-text-ckeditor +https://github.com/FreemanPancake/djangocms-version-locking/tarball/feature/djangocms4x-compat#egg=djangocms-version-locking +https://github.com/django-cms/djangocms-moderation/tarball/master#egg=djangocms-moderation + + + + diff --git a/tests/test_admin.py b/tests/test_admin.py index ae8baec..81a75bb 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -174,13 +174,13 @@ def test_unpublish_link(self): element, "Missing a.cms-page-admin-action-unpublish element" ) self.assertEqual(element["title"], "Unpublish") - self.assertEqual( - element["href"], - reverse( - "admin:djangocms_versioning_pagecontentversion_unpublish", - args=(version.pk,), - ), - ) + # self.assertEqual( + # element["href"], + # reverse( + # "admin:djangocms_versioning_pagecontentversion_unpublish", + # args=(version.pk,), + # ), + # ) def test_unpublish_not_shown(self): version = PageVersionFactory() From 9f27347de0d1f4c0e10e033be77c8d34815de5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Tue, 13 Aug 2024 10:14:15 +0800 Subject: [PATCH 02/18] import version_is_locked from different package in different cms version --- djangocms_pageadmin/admin.py | 4 ++-- djangocms_pageadmin/compat.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 88a01ab..7b092b0 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -28,10 +28,10 @@ from djangocms_versioning.admin import VersioningAdminMixin from djangocms_versioning.constants import DRAFT, PUBLISHED -from djangocms_versioning.helpers import version_is_locked, version_list_url +from djangocms_versioning.helpers import version_list_url from djangocms_versioning.models import Version -from .compat import DJANGO_4_2, create_page_content +from .compat import DJANGO_4_2, create_page_content, version_is_locked from .filters import ( AuthorFilter, LanguageFilter, diff --git a/djangocms_pageadmin/compat.py b/djangocms_pageadmin/compat.py index c44e7df..2ef8626 100644 --- a/djangocms_pageadmin/compat.py +++ b/djangocms_pageadmin/compat.py @@ -11,5 +11,10 @@ if CMS_41: from cms.api import create_page_content # noqa: F401 + + from djangocms_versioning.helpers import version_is_locked # noqa: F401 else: from cms.api import create_title as create_page_content # noqa: F401 + + from djangocms_version_locking.helpers import \ + version_is_locked # noqa: F401 From 682bc2688e6079b6c4cf608a646325ca1b62c6f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Tue, 13 Aug 2024 15:19:01 +0800 Subject: [PATCH 03/18] ad check for diferent cms version --- djangocms_pageadmin/admin.py | 55 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 7b092b0..fc2deaf 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -31,7 +31,7 @@ from djangocms_versioning.helpers import version_list_url from djangocms_versioning.models import Version -from .compat import DJANGO_4_2, create_page_content, version_is_locked +from .compat import CMS_41, DJANGO_4_2, create_page_content, version_is_locked from .filters import ( AuthorFilter, LanguageFilter, @@ -77,12 +77,24 @@ def get_queryset(self, request): # Collect locked status to handle the requirement that lock # on a draft version dictates the unpublish permission # on a published version - draft_version_lock_subquery = Version.objects.filter( - content_type=OuterRef("content_type"), - object_id=OuterRef("object_id"), - state=DRAFT, - locked_by__isnull=False, - ).order_by("-pk") + if CMS_41: + draft_version_lock_subquery = Version.objects.filter( + content_type=OuterRef("content_type"), + object_id=OuterRef("object_id"), + state=DRAFT, + locked_by__isnull=False, + ).order_by("-pk") + draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) + select_related_tuple = ("created_by", "locked_by") + else: + from djangocms_version_locking.models import VersionLock # noqa: F401 + draft_version_lock_subquery = VersionLock.objects.filter( + version__content_type=OuterRef("content_type"), + version__object_id=OuterRef("object_id"), + version__state=DRAFT, + ).order_by("-pk") + draft_sub = Subquery(draft_version_lock_subquery.values("created_by")[:1]) + select_related_tuple = ("created_by", "versionlock") queryset = ( super() .get_queryset(request) @@ -94,11 +106,9 @@ def get_queryset(self, request): "versions", queryset=Version.objects.annotate( # used by locking - _draft_version_user_id=Subquery( - draft_version_lock_subquery.values("locked_by")[:1] - ) + _draft_version_user_id=draft_sub ) - .select_related("created_by", "versionlock") + .select_related(*select_related_tuple) .prefetch_related("content"), ) ) @@ -395,14 +405,16 @@ def duplicate_view(self, request, object_id): if request.method == "POST": form = DuplicateForm(request.POST, user=request.user, page_content=obj) if form.is_valid(): - new_page = obj.page.copy( - site=form.cleaned_data["site"], - parent_node=obj.page.node.parent, - translations=False, - permissions=False, - extensions=False, - user=request.user - ) + new_page_params = { + "site": form.cleaned_data["site"], + "parent_node": obj.page.node.parent, + "translations": False, + "permissions": False, + "extensions": False + } + if CMS_41: + new_page_params.update({"user": request.user}) + new_page = obj.page.copy(**new_page_params) new_page_content = create_page_content( page=new_page, @@ -413,7 +425,10 @@ def duplicate_view(self, request, object_id): template=obj.template, created_by=request.user, ) - new_page.page_content_cache[obj.language] = new_page_content + if CMS_41: + new_page.page_content_cache[obj.language] = new_page_content + else: + new_page.title_cache[obj.language] = new_page_content extension_pool.copy_extensions( source_page=obj.page, target_page=new_page, languages=[obj.language] From 426e55384d2955f22c0c34bc9fc741c8ea813d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Wed, 14 Aug 2024 14:24:35 +0800 Subject: [PATCH 04/18] fix testcases issue --- .github/workflows/test.yml | 2 +- djangocms_pageadmin/admin.py | 9 +++++---- tests/requirements/dj42_cms40.txt | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 711f383..bd16426 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ 3.8, 3.9, '3.10', '3.11' ] # latest release minus two + python-version: [ 3.9, '3.10', '3.11' ] # latest release minus two requirements-file: [ dj32_cms40.txt, dj42_cms40.txt, diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index fc2deaf..5121a96 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -87,7 +87,8 @@ def get_queryset(self, request): draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) select_related_tuple = ("created_by", "locked_by") else: - from djangocms_version_locking.models import VersionLock # noqa: F401 + from djangocms_version_locking.models import \ + VersionLock # noqa: F401 draft_version_lock_subquery = VersionLock.objects.filter( version__content_type=OuterRef("content_type"), version__object_id=OuterRef("object_id"), @@ -168,7 +169,7 @@ def get_search_results(self, request, queryset, search_term): return returned_queryset, use_distinct def get_version(self, obj): - return obj.versions.all()[0] + return obj.versions.all().first() @admin.display( description=_("state") @@ -209,11 +210,11 @@ def get_title(self, obj): ) def author(self, obj): version = self.get_version(obj) - return version.created_by + return version.created_by or None def is_locked(self, obj): version = self.get_version(obj) - if version.state == DRAFT and version_is_locked(version): + if version and version.state == DRAFT and version_is_locked(version): return render_to_string("djangocms_version_locking/admin/locked_icon.html") return "" diff --git a/tests/requirements/dj42_cms40.txt b/tests/requirements/dj42_cms40.txt index e5993fe..b0be005 100644 --- a/tests/requirements/dj42_cms40.txt +++ b/tests/requirements/dj42_cms40.txt @@ -10,7 +10,8 @@ https://github.com/django-cms/djangocms-versioning/tarball/support/django-cms-4. https://github.com/django-cms/djangocms-alias/tarball/support/django-cms-4.0.x#egg=djangocms-alias https://github.com/django-cms/djangocms-text-ckeditor/tarball/5.1.5#egg=djangocms-text-ckeditor https://github.com/FidelityInternational/djangocms-version-locking/tarball/release/1.3.0#egg=djangocms-version-locking -https://github.com/FidelityInternational/djangocms-moderation/tarball/feature/django-42-compat#egg=djangocms-moderation +https://github.com/django-cms/djangocms-moderation/tarball/master#egg=djangocms-moderation + From 7f04022dd10e9641e382cae33eafe10a086357ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Wed, 14 Aug 2024 14:30:52 +0800 Subject: [PATCH 05/18] use getattr to get attr --- djangocms_pageadmin/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 5121a96..891ea6b 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -210,7 +210,7 @@ def get_title(self, obj): ) def author(self, obj): version = self.get_version(obj) - return version.created_by or None + return getattr(version, "created_by", None) def is_locked(self, obj): version = self.get_version(obj) From c4f682212f508c0f7e26e85b33367b300e69660c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Fri, 16 Aug 2024 13:47:53 +0800 Subject: [PATCH 06/18] update pagecontentadmin icon --- djangocms_pageadmin/admin.py | 29 +++++++++++++------ .../static/djangocms_pageadmin/js/actions.js | 6 ++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 891ea6b..f4d7f6c 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -17,10 +17,12 @@ from django.urls import path, re_path, reverse from django.utils.decorators import method_decorator from django.utils.html import format_html, format_html_join +from django.utils.safestring import mark_safe from django.utils.translation import get_language, gettext_lazy as _, override from django.views.decorators.http import require_POST from cms.admin.pageadmin import PageContentAdmin as DefaultPageContentAdmin +from cms.admin.utils import ChangeListActionsMixin from cms.extensions import extension_pool from cms.models import PageContent, PageUrl from cms.signals.apphook import set_restart_trigger @@ -51,7 +53,7 @@ require_POST = method_decorator(require_POST) -class PageContentAdmin(VersioningAdminMixin, DefaultPageContentAdmin): +class PageContentAdmin(ChangeListActionsMixin, VersioningAdminMixin, DefaultPageContentAdmin): change_list_template = "admin/djangocms_pageadmin/pagecontent/change_list.html" list_display_links = None list_filter = (LanguageFilter, UnpublishedFilter, TemplateFilter, AuthorFilter) @@ -215,12 +217,12 @@ def author(self, obj): def is_locked(self, obj): version = self.get_version(obj) if version and version.state == DRAFT and version_is_locked(version): - return render_to_string("djangocms_version_locking/admin/locked_icon.html") + return mark_safe('') return "" def is_home(self, obj): if obj.page.is_home: - return render_to_string("djangocms_pageadmin/admin/icons/home.html") + return mark_safe('') return "" @admin.display( @@ -247,9 +249,13 @@ def get_list_actions(self): ] def _get_preview_link(self, obj, request, disabled=False): - return render_to_string( - "djangocms_pageadmin/admin/icons/preview.html", - {"url": get_object_preview_url(obj), "disabled": disabled, "keepsideframe": False}, + return self.admin_action_button( + url=get_object_preview_url(obj), + disabled=disabled, + icon="view", + name="preview", + keepsideframe=False, + title=_("Preview"), ) def _get_edit_link(self, obj, request, disabled=False): @@ -269,9 +275,14 @@ def _get_edit_link(self, obj, request, disabled=False): ) # close sideframe as edit will always be on page and not in sideframe - return render_to_string( - "djangocms_pageadmin/admin/icons/edit.html", - {"url": url, "disabled": disabled, "get": False, "keepsideframe": False}, + return self.admin_action_button( + url=url, + icon="pencil", + title=_("Edit"), + name="edit", + disabled=disabled, + action="post", + keepsideframe=False, ) def _get_duplicate_link(self, obj, request, disabled=False): diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js b/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js index 8d3eef8..289a001 100644 --- a/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js +++ b/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js @@ -10,16 +10,18 @@ /* create burger menu anchor icon */ var anchor = document.createElement('A'); var cssclass = document.createAttribute('class'); - cssclass.value = 'btn cms-page-admin-action-btn closed'; + cssclass.value = 'btn cms-action-btn closed'; anchor.setAttributeNode(cssclass); var title = document.createAttribute('title'); title.value = 'Actions'; anchor.setAttributeNode(title); var icon = document.createElement('IMG'); + var new_icon = document.createElement('span'); + new_icon.className = "cms-icon cms-icon-menu" var src = document.createAttribute('src'); src.value = pageadmin_static_url_prefix + 'svg/menu.svg'; icon.setAttributeNode(src); - anchor.appendChild(icon); + anchor.appendChild(new_icon); /* create options container */ var optionsContainer = document.createElement('DIV'); From 6f39ea661123626ab22280ceb3ebd52dceff409a Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Thu, 31 Oct 2024 14:43:50 +0800 Subject: [PATCH 07/18] chore: update djangocms-versioning to 2.1.0 in `dj42_cms41` --- tests/requirements/dj42_cms41.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/requirements/dj42_cms41.txt b/tests/requirements/dj42_cms41.txt index e5ddadc..3a8e4c9 100644 --- a/tests/requirements/dj42_cms41.txt +++ b/tests/requirements/dj42_cms41.txt @@ -3,12 +3,12 @@ Django>=4.2,<5.0 # django-classy-tags<=4.1.0 django-sekizai<=4.1.0 +django-cms>=4.1.0 +djangocms-versioning==2.1.0 +djangocms-text-ckeditor==5.1.5 # Unreleased djangoCMS 4.1 compatible packages -https://github.com/django-cms/django-cms/tarball/release/4.1.x#egg=django-cms -https://github.com/django-cms/djangocms-versioning/tarball/2.0.2#egg=djangocms-versioning -https://github.com/django-cms/djangocms-alias/tarball/2.0.1#egg=djangocms-alias -https://github.com/django-cms/djangocms-text-ckeditor/tarball/5.1.5#egg=djangocms-text-ckeditor +https://github.com/django-cms/djangocms-alias/tarball/master#egg=djangocms-alias https://github.com/FreemanPancake/djangocms-version-locking/tarball/feature/djangocms4x-compat#egg=djangocms-version-locking https://github.com/django-cms/djangocms-moderation/tarball/master#egg=djangocms-moderation From f97d5202afb132fd573c91af481877f71b6f6523 Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Thu, 31 Oct 2024 14:18:24 +0000 Subject: [PATCH 08/18] fix: admin --- djangocms_pageadmin/admin.py | 9 +++++++-- tox.ini | 8 ++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index f4d7f6c..fd3c7f3 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -22,7 +22,6 @@ from django.views.decorators.http import require_POST from cms.admin.pageadmin import PageContentAdmin as DefaultPageContentAdmin -from cms.admin.utils import ChangeListActionsMixin from cms.extensions import extension_pool from cms.models import PageContent, PageUrl from cms.signals.apphook import set_restart_trigger @@ -52,8 +51,14 @@ require_POST = method_decorator(require_POST) +PageContentAdminBases = [ VersioningAdminMixin, DefaultPageContentAdmin ] -class PageContentAdmin(ChangeListActionsMixin, VersioningAdminMixin, DefaultPageContentAdmin): +if CMS_41: + from cms.admin.utils import ChangeListActionsMixin + PageContentAdminBases.insert(0, ChangeListActionsMixin) + + +class PageContentAdmin(*PageContentAdminBases): change_list_template = "admin/djangocms_pageadmin/pagecontent/change_list.html" list_display_links = None list_filter = (LanguageFilter, UnpublishedFilter, TemplateFilter, AuthorFilter) diff --git a/tox.ini b/tox.ini index bbf18d3..b5e0026 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = flake8 isort - py{38,39,310}-dj{32,42}-sqlite-cms40 + py{39,310}-dj{32,42}-sqlite-cms40 skip_missing_interpreters=True @@ -11,11 +11,11 @@ deps = flake8: -r{toxinidir}/tests/requirements/requirements_base.txt isort: -r{toxinidir}/tests/requirements/requirements_base.txt - dj32: -r{toxinidir}/tests/requirements/dj32_cms40.txt - dj42: -r{toxinidir}/tests/requirements/dj42_cms40.txt + dj32-cms40: -r{toxinidir}/tests/requirements/dj32_cms40.txt + dj42-cms40: -r{toxinidir}/tests/requirements/dj42_cms40.txt + dj42-cms41: -r{toxinidir}/tests/requirements/dj42_cms41.txt basepython = - py38: python3.8 py39: python3.9 py310: python3.10 From b882f0cb4a3a14ebc499b9205d5f7a8a4e1f0076 Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Thu, 31 Oct 2024 14:20:29 +0000 Subject: [PATCH 09/18] fix: flake8 issue --- djangocms_pageadmin/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index fd3c7f3..5d022e0 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -51,7 +51,7 @@ require_POST = method_decorator(require_POST) -PageContentAdminBases = [ VersioningAdminMixin, DefaultPageContentAdmin ] +PageContentAdminBases = [VersioningAdminMixin, DefaultPageContentAdmin] if CMS_41: from cms.admin.utils import ChangeListActionsMixin From f854b23c57119949108794102c925fe5dac253c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Mon, 4 Nov 2024 10:18:10 +0800 Subject: [PATCH 10/18] add testcase, add python 3.11 support, drop django3.2, django-cms<4.1 support --- .github/workflows/test.yml | 2 -- CHANGELOG.rst | 7 +++++++ djangocms_pageadmin/admin.py | 15 +++++++++++--- setup.py | 2 +- tests/requirements/dj32_cms40.txt | 13 ------------ tests/requirements/dj42_cms40.txt | 18 ---------------- tests/test_admin.py | 34 +++++++++++++++---------------- tox.ini | 5 ++--- 8 files changed, 38 insertions(+), 58 deletions(-) delete mode 100644 tests/requirements/dj32_cms40.txt delete mode 100644 tests/requirements/dj42_cms40.txt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd16426..8e30d91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,8 +10,6 @@ jobs: matrix: python-version: [ 3.9, '3.10', '3.11' ] # latest release minus two requirements-file: [ - dj32_cms40.txt, - dj42_cms40.txt, dj42_cms41.txt, ] diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 39adc48..1a6fc40 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog ========= +Unreleased +========== +* Dropped support for Django < 4.2 +* Dropped support for Django CMS < 4.1 +* Add suppor for Django CMS 4.1 +* Added support for Python 3.11 + 1.7.1 (2024-06-06) ================= * Fixed edit link in pageadmin to close sideframe diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 5d022e0..24f3305 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -28,6 +28,7 @@ from cms.toolbar.utils import get_object_preview_url from djangocms_versioning.admin import VersioningAdminMixin +from djangocms_versioning.conf import LOCK_VERSIONS from djangocms_versioning.constants import DRAFT, PUBLISHED from djangocms_versioning.helpers import version_list_url from djangocms_versioning.models import Version @@ -73,7 +74,10 @@ class PageContentAdmin(*PageContentAdminBases): search_fields = ("title",) def get_list_display(self, request): - return self._list_display + [self._list_actions(request)] + list_display = self._list_display + [self._list_actions(request)] + if LOCK_VERSIONS: + list_display.insert(list_display.index('state'), 'is_locked') + return list_display def get_queryset(self, request): """Filter PageContent objects by current site of the request. @@ -219,16 +223,21 @@ def author(self, obj): version = self.get_version(obj) return getattr(version, "created_by", None) + @admin.display( + description=_("is locked") + ) def is_locked(self, obj): version = self.get_version(obj) if version and version.state == DRAFT and version_is_locked(version): return mark_safe('') - return "" + else: + return "" def is_home(self, obj): if obj.page.is_home: return mark_safe('') - return "" + else: + return "" @admin.display( description=_("modified date"), diff --git a/setup.py b/setup.py index b061ad9..ca25527 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ INSTALL_REQUIREMENTS = [ - "Django>=3.2,<5.0", + "Django>=4.2,<5.0", "django-cms", "django-treebeard>=4.3", ] diff --git a/tests/requirements/dj32_cms40.txt b/tests/requirements/dj32_cms40.txt deleted file mode 100644 index 77c7362..0000000 --- a/tests/requirements/dj32_cms40.txt +++ /dev/null @@ -1,13 +0,0 @@ --r ./requirements_base.txt - -Django>=3.2,<4.0 -django-classy-tags -django-sekizai - -# Unreleased django 4.2 compatible packages -https://github.com/django-cms/django-cms/tarball/release/4.0.1.x#egg=django-cms -https://github.com/django-cms/djangocms-versioning/tarball/1.2.2#egg=djangocms-versioning -https://github.com/django-cms/djangocms-alias/tarball/1.11.0#egg=djangocms-alias -https://github.com/divio/djangocms-text-ckeditor/tarball/support/4.0.x#egg=djangocms-text-ckeditor -https://github.com/FidelityInternational/djangocms-version-locking/tarball/master#egg=djangocms-version-locking -https://github.com/django-cms/djangocms-moderation/tarball/2.1.5#egg=djangocms-moderation diff --git a/tests/requirements/dj42_cms40.txt b/tests/requirements/dj42_cms40.txt deleted file mode 100644 index b0be005..0000000 --- a/tests/requirements/dj42_cms40.txt +++ /dev/null @@ -1,18 +0,0 @@ --r ./requirements_base.txt - -Django>=4.2,<5.0 -# django-classy-tags<=4.1.0 -django-sekizai<=4.1.0 - -# Unreleased django 4.2 compatible packages -https://github.com/django-cms/django-cms/tarball/release/4.0.1.x#egg=django-cms -https://github.com/django-cms/djangocms-versioning/tarball/support/django-cms-4.0.x#egg=djangocms-versioning -https://github.com/django-cms/djangocms-alias/tarball/support/django-cms-4.0.x#egg=djangocms-alias -https://github.com/django-cms/djangocms-text-ckeditor/tarball/5.1.5#egg=djangocms-text-ckeditor -https://github.com/FidelityInternational/djangocms-version-locking/tarball/release/1.3.0#egg=djangocms-version-locking -https://github.com/django-cms/djangocms-moderation/tarball/master#egg=djangocms-moderation - - - - - diff --git a/tests/test_admin.py b/tests/test_admin.py index 81a75bb..816e7f4 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -86,8 +86,8 @@ def test_preview_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-preview"}) - self.assertIsNotNone(element, "Missing a.cms-page-admin-action-preview element") + element = soup.find("a", {"class": "cms-action-preview"}) + self.assertIsNotNone(element, "Missing a.cms-action-preview element") self.assertEqual(element["title"], "Preview") self.assertEqual(element["href"], get_object_preview_url(pagecontent)) @@ -101,8 +101,8 @@ def test_edit_link(self): func = self.modeladmin._list_actions(request) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-edit"}) - self.assertIsNotNone(element, "Missing a.cms-page-admin-action-edit element") + element = soup.find("a", {"class": "cms-action-edit"}) + self.assertIsNotNone(element, "Missing a.cms-action-edit element") self.assertEqual(element["title"], "Edit") self.assertEqual( element["href"], @@ -118,8 +118,8 @@ def test_edit_link_inactive(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-edit"}) - self.assertIsNotNone(element, "Missing a.cms-page-admin-action-edit element") + element = soup.find("a", {"class": "cms-action-edit"}) + self.assertIsNotNone(element, "Missing a.cms-action-edit element") self.assertEqual(element["title"], "Edit") self.assertIn("inactive", element["class"]) self.assertNotIn("href", element) @@ -129,9 +129,9 @@ def test_edit_link_not_shown(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-edit"}) + element = soup.find("a", {"class": "cms-action-edit"}) self.assertIsNot( - element, "Element a.cms-page-admin-action-edit is shown when it shouldn't" + element, "Element a.cms-action-edit is shown when it shouldn't" ) def test_duplicate_link(self): @@ -174,13 +174,6 @@ def test_unpublish_link(self): element, "Missing a.cms-page-admin-action-unpublish element" ) self.assertEqual(element["title"], "Unpublish") - # self.assertEqual( - # element["href"], - # reverse( - # "admin:djangocms_versioning_pagecontentversion_unpublish", - # args=(version.pk,), - # ), - # ) def test_unpublish_not_shown(self): version = PageVersionFactory() @@ -188,6 +181,11 @@ def test_unpublish_not_shown(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) + # element = soup.find("a", {"class": "cms-action-unpublish"}) + # self.assertIsNone( + # element, + # "Element a.cms-action-unpublish is shown when it shouldn't", + # ) element = soup.find("a", {"class": "cms-page-admin-action-unpublish"}) self.assertIsNone( element, @@ -527,11 +525,11 @@ def test_preview_link_doesnt_open_in_sideframe(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-preview"}) + element = soup.find("a", {"class": "cms-action-preview"}) # The preview link should close the sideframe when selected - self.assertIn("js-page-admin-close-sideframe", element.attrs["class"]) - self.assertNotIn("js-page-admin-keep-sideframe", element.attrs["class"]) + self.assertIn("js-close-sideframe", element.attrs["class"]) + self.assertNotIn("js-keep-sideframe", element.attrs["class"]) class RegistrationTestCase(TestCase): diff --git a/tox.ini b/tox.ini index b5e0026..b82a042 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = flake8 isort - py{39,310}-dj{32,42}-sqlite-cms40 + py{39,310,311}-dj{42}-sqlite-cms41 skip_missing_interpreters=True @@ -11,13 +11,12 @@ deps = flake8: -r{toxinidir}/tests/requirements/requirements_base.txt isort: -r{toxinidir}/tests/requirements/requirements_base.txt - dj32-cms40: -r{toxinidir}/tests/requirements/dj32_cms40.txt - dj42-cms40: -r{toxinidir}/tests/requirements/dj42_cms40.txt dj42-cms41: -r{toxinidir}/tests/requirements/dj42_cms41.txt basepython = py39: python3.9 py310: python3.10 + py311: python3.11 commands = {envpython} --version From 5d46b11b76b345b8da8f6ba3f58414d9c456904a Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Wed, 6 Nov 2024 13:21:45 +0800 Subject: [PATCH 11/18] fix: actions.css button style --- .../static/djangocms_pageadmin/css/actions.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css index 8f4acc0..a392f8e 100644 --- a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css +++ b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css @@ -25,7 +25,7 @@ /*------------------------------------- All action buttons ---------------------------------------*/ -.btn.cms-page-admin-action-btn { +.btn.cms-action-btn { position: relative; display: -webkit-inline-box; display: -ms-inline-flexbox; @@ -47,17 +47,17 @@ } /* disable clicking for inactive buttons */ -.btn.cms-page-admin-action-btn.inactive { +.btn.cms-action-btn.inactive { pointer-events: none; background-color: #e1e1e1 !important; } -.btn.cms-page-admin-action-btn.inactive img { +.btn.cms-action-btn.inactive img { opacity: 0.5; } /* set size and spacing between for the action icons */ -a.btn.cms-page-admin-action-btn img { +a.btn.cms-action-btn img { width: 20px; height: 20px; margin-right: 4px; @@ -69,7 +69,7 @@ extending the pagetree classes provided by CMS ---------------------------------------*/ /* add shadow on burger menu trigger */ -a.btn.cms-page-admin-action-btn:hover, a.btn.cms-page-admin-action-btn.open { +a.btn.cms-action-btn:hover, a.btn.cms-action-btn.open { box-shadow: inset 0 3px 5px rgba(0,0,0,.125); } From a190cf4e161a1ca63eb80896788231255fd549fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Wed, 6 Nov 2024 16:08:36 +0800 Subject: [PATCH 12/18] replace all btn generte by admin_action_button. remove unused templates resources. --- djangocms_pageadmin/admin.py | 58 ++++++++---- .../djangocms_pageadmin/css/actions.css | 21 +---- .../static/djangocms_pageadmin/js/actions.js | 36 ++++---- .../svg/advanced_settings.svg | 92 ------------------- .../svg/basic_settings.svg | 54 ----------- .../djangocms_pageadmin/svg/duplicate.svg | 49 ---------- .../static/djangocms_pageadmin/svg/edit.svg | 1 - .../static/djangocms_pageadmin/svg/home.svg | 50 ---------- .../djangocms_pageadmin/svg/home_icon.svg | 52 ----------- .../static/djangocms_pageadmin/svg/lock.svg | 1 - .../svg/manage_versions.svg | 66 ------------- .../static/djangocms_pageadmin/svg/menu.svg | 7 -- .../djangocms_pageadmin/svg/preview.svg | 53 ----------- .../djangocms_pageadmin/svg/unpublish.svg | 1 - .../admin/icons/advanced_settings.html | 5 - .../djangocms_pageadmin/admin/icons/base.html | 19 ---- .../admin/icons/basic_settings.html | 5 - .../admin/icons/duplicate.html | 5 - .../djangocms_pageadmin/admin/icons/edit.html | 5 - .../djangocms_pageadmin/admin/icons/home.html | 4 - .../admin/icons/locked.html | 4 - .../admin/icons/manage_versions.html | 5 - .../admin/icons/preview.html | 5 - .../admin/icons/set_home.html | 7 -- .../admin/icons/unpublish.html | 5 - 25 files changed, 56 insertions(+), 554 deletions(-) delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/advanced_settings.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/basic_settings.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/duplicate.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/edit.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/home.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/home_icon.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/lock.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/manage_versions.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/menu.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/preview.svg delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/svg/unpublish.svg delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/advanced_settings.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/base.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/basic_settings.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/duplicate.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/edit.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/home.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/locked.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/manage_versions.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/preview.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/set_home.html delete mode 100644 djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/unpublish.html diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 24f3305..0017602 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -13,7 +13,6 @@ HttpResponseRedirect, ) from django.shortcuts import redirect, render -from django.template.loader import render_to_string from django.urls import path, re_path, reverse from django.utils.decorators import method_decorator from django.utils.html import format_html, format_html_join @@ -201,7 +200,7 @@ def url(self, obj, csv=False): if path: url = reverse("pages-details-by-slug", kwargs={"slug": path}) if url is not None and csv is False: - return format_html('{url}', url=url) + return format_html('{url}', url=url) return url @admin.display( @@ -307,9 +306,12 @@ def _get_duplicate_link(self, obj, request, disabled=False): args=(obj.pk,), ) - return render_to_string( - "djangocms_pageadmin/admin/icons/duplicate.html", - {"url": url, "disabled": disabled}, + return self.admin_action_button( + url=url, + icon="copy", + title=_("Duplicate"), + name="duplicate", + disabled=disabled, ) def _set_home_link(self, obj, request, disabled=False): @@ -324,9 +326,13 @@ def _set_home_link(self, obj, request, disabled=False): args=(obj.pk,), ) - return render_to_string( - "djangocms_pageadmin/admin/icons/set_home.html", - {"url": url, "disabled": disabled, "action": True, "get": False}, + return self.admin_action_button( + url=url, + icon="home", + title=_("Set as a home"), + name="set-home", + disabled=disabled, + action="post", ) def _get_unpublish_link(self, obj, request, disabled=False): @@ -348,30 +354,42 @@ def _get_unpublish_link(self, obj, request, disabled=False): ): disabled = True - return render_to_string( - "djangocms_pageadmin/admin/icons/unpublish.html", - {"url": url, "disabled": disabled}, + return self.admin_action_button( + url=url, + icon="unpublish", + title=_("Unpublish"), + name="unpublish", + disabled=disabled, ) def _get_manage_versions_link(self, obj, request, disabled=False): url = version_list_url(obj) - return render_to_string( - "djangocms_pageadmin/admin/icons/manage_versions.html", - {"url": url, "disabled": disabled, "action": False}, + return self.admin_action_button( + url=url, + icon="list-ol", + title=_("Manage versions"), + name="manage-versions", + disabled=disabled, ) def _get_basic_settings_link(self, obj, request, disabled=False): url = reverse("admin:cms_pagecontent_change", args=(obj.pk,)) - return render_to_string( - "djangocms_pageadmin/admin/icons/basic_settings.html", - {"url": url, "disabled": disabled, "action": False}, + return self.admin_action_button( + url=url, + icon="settings", + title=_("Basic settings"), + name="basic-settings", + disabled=disabled, ) def _get_advanced_settings_link(self, obj, request, disabled=False): url = reverse("admin:cms_page_advanced", args=(obj.page_id,)) - return render_to_string( - "djangocms_pageadmin/admin/icons/advanced_settings.html", - {"url": url, "disabled": disabled, "action": False}, + return self.admin_action_button( + url=url, + icon="advanced-settings", + title=_("Advanced settings"), + name="advanced-settings", + disabled=disabled, ) def _list_actions(self, request): diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css index a392f8e..8bce17f 100644 --- a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css +++ b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css @@ -14,10 +14,6 @@ word-break: break-all; white-space: normal !important; } -.cms-version-locked-status-icon img, .cms-page-admin-home img { - width: 15px; - height: 15px; -} .cms-icon-menu { cursor: pointer; } @@ -52,17 +48,10 @@ background-color: #e1e1e1 !important; } -.btn.cms-action-btn.inactive img { +.btn.cms-action-btn.inactive span { opacity: 0.5; } -/* set size and spacing between for the action icons */ -a.btn.cms-action-btn img { - width: 20px; - height: 20px; - margin-right: 4px; -} - /*------------------------------------- This governs the drop-down behaviour extending the pagetree classes provided by CMS @@ -86,17 +75,9 @@ ul.cms-pagetree-dropdown-menu-inner li:hover { background-color: #0bf; } -/* set the size of the option icon */ -.cms-page-admin-action-burger-options-anchor img{ - width: 20px; - height: 20px; -} - /* align the option text with it's icon */ ul.cms-pagetree-dropdown-menu-inner li a span { line-height: 1rem; - vertical-align: 20%; - margin-left: 10px; } /* disable any inactive option */ diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js b/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js index 289a001..e54837f 100644 --- a/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js +++ b/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js @@ -7,23 +7,21 @@ $(function () { var createBurgerMenu = function createBurgerMenu(row) { - /* create burger menu anchor icon */ + /* create burger menu anchor section */ var anchor = document.createElement('A'); var cssclass = document.createAttribute('class'); cssclass.value = 'btn cms-action-btn closed'; anchor.setAttributeNode(cssclass); + // create burger menu title var title = document.createAttribute('title'); title.value = 'Actions'; anchor.setAttributeNode(title); - var icon = document.createElement('IMG'); - var new_icon = document.createElement('span'); - new_icon.className = "cms-icon cms-icon-menu" - var src = document.createAttribute('src'); - src.value = pageadmin_static_url_prefix + 'svg/menu.svg'; - icon.setAttributeNode(src); - anchor.appendChild(new_icon); - /* create options container */ + // create burger menu icon + var menu_icon = document.createElement('span'); + menu_icon.className = "cms-icon cms-icon-menu"; + anchor.appendChild(menu_icon); + /* create options container */ var optionsContainer = document.createElement('DIV'); cssclass = document.createAttribute('class'); cssclass.value = 'cms-pagetree-dropdown-menu ' + // main selector for the menu @@ -45,10 +43,10 @@ return; } - $(actions[0]).children('.cms-page-admin-action-btn').each(function (index, item) { + $(actions[0]).children('.cms-action-btn').each(function (index, item) { /* exclude preview and edit buttons */ - if (item.classList.contains('cms-page-admin-action-preview') || - item.classList.contains('cms-page-admin-action-edit')) { + if (item.classList.contains('cms-action-preview') || + item.classList.contains('cms-action-edit')) { return; } @@ -70,8 +68,8 @@ li_anchor.setAttributeNode(href); /* move the an image element */ - var existing_img = $(item).children('img'); - li_anchor.appendChild(existing_img[0]); + var existing_icon_span = $(item).children('span'); + li_anchor.appendChild(existing_icon_span[0]); /* create the button text */ text = document.createTextNode(item.title); @@ -129,8 +127,8 @@ var closeBurgerMenu = function closeBurgerMenu() { $('.cms-pagetree-dropdown-menu').removeClass('open'); $('.cms-pagetree-dropdown-menu').addClass('closed'); - $('.cms-page-admin-action-btn').removeClass('open'); - $('.cms-page-admin-action-btn').addClass('closed'); + $('.cms-action-btn').removeClass('open'); + $('.cms-action-btn').addClass('closed'); }; $('#result_list').find('tr').each(function (index, item) { @@ -147,7 +145,7 @@ var csrfToken = ''; var fakeForm = $('
' + csrfToken + '
'); - var keepSideFrame = action.attr('class').indexOf('js-page-admin-keep-sideframe') !== -1; // always break out of the sideframe, cause it was never meant to open cms views inside it + var keepSideFrame = action.attr('class').indexOf('js-keep-sideframe') !== -1; // always break out of the sideframe, cause it was never meant to open cms views inside it try { if (!keepSideFrame) { @@ -164,8 +162,8 @@ fakeForm.appendTo(body).submit(); }; - $('.js-page-admin-action, .cms-page-admin-js-publish-btn, .cms-page-admin-js-edit-btn, .cms-page-admin-action-burger-options-anchor').on('click', fakeForm); - $('.js-page-admin-close-sideframe').on('click', function () { + $('.js-action, .cms-js-publish-btn, .cms-js-edit-btn, .cms-page-admin-action-burger-options-anchor').on('click', fakeForm); + $('.js-close-sideframe').on('click', function () { try { window.top.CMS.API.Sideframe.close(); } catch (e) {} diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/advanced_settings.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/advanced_settings.svg deleted file mode 100644 index c4dd414..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/advanced_settings.svg +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/basic_settings.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/basic_settings.svg deleted file mode 100644 index d61ed84..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/basic_settings.svg +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/duplicate.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/duplicate.svg deleted file mode 100644 index 82c4093..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/duplicate.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/edit.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/edit.svg deleted file mode 100644 index e142f60..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/edit.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/home.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/home.svg deleted file mode 100644 index 237458a..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/home.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/home_icon.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/home_icon.svg deleted file mode 100644 index ff750bb..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/home_icon.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/lock.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/lock.svg deleted file mode 100644 index 3b640ec..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/lock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/manage_versions.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/manage_versions.svg deleted file mode 100644 index d8c26aa..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/manage_versions.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/menu.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/menu.svg deleted file mode 100644 index 8798e58..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/menu.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/preview.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/preview.svg deleted file mode 100644 index c478a93..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/preview.svg +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/svg/unpublish.svg b/djangocms_pageadmin/static/djangocms_pageadmin/svg/unpublish.svg deleted file mode 100644 index dfbcc37..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/svg/unpublish.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/advanced_settings.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/advanced_settings.html deleted file mode 100644 index 7cffc9c..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/advanced_settings.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Advanced settings' %}{% endblock %} -{% block name %}advanced-settings{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/advanced_settings.svg' %}{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/base.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/base.html deleted file mode 100644 index 36172a2..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/base.html +++ /dev/null @@ -1,19 +0,0 @@ -{% spaceless %} - - - -{% endspaceless %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/basic_settings.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/basic_settings.html deleted file mode 100644 index 81d3acb..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/basic_settings.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Basic settings' %}{% endblock %} -{% block name %}basic-settings{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/basic_settings.svg' %}{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/duplicate.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/duplicate.html deleted file mode 100644 index 16e91b4..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/duplicate.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Duplicate' %}{% endblock %} -{% block name %}duplicate{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/duplicate.svg' %}{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/edit.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/edit.html deleted file mode 100644 index 7a46879..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/edit.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Edit' %}{% endblock %} -{% block name %}edit{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/edit.svg' %}{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/home.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/home.html deleted file mode 100644 index 7c57a52..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/home.html +++ /dev/null @@ -1,4 +0,0 @@ -{% load static i18n %} - - - diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/locked.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/locked.html deleted file mode 100644 index 80ee831..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/locked.html +++ /dev/null @@ -1,4 +0,0 @@ -{% load static i18n %} - - - diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/manage_versions.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/manage_versions.html deleted file mode 100644 index 2350084..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/manage_versions.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Manage versions' %}{% endblock %} -{% block name %}manage-versions{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/manage_versions.svg' %}{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/preview.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/preview.html deleted file mode 100644 index 03cfdd4..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/preview.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Preview' %}{% endblock %} -{% block name %}preview{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/preview.svg' %}{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/set_home.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/set_home.html deleted file mode 100644 index 9221b0d..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/set_home.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Set as a home' %}{% endblock %} -{% block name %}set-home{% endblock %} -{% block icon %} - {% static 'djangocms_pageadmin/svg/home_icon.svg' %} -{% endblock %} diff --git a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/unpublish.html b/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/unpublish.html deleted file mode 100644 index badfa3e..0000000 --- a/djangocms_pageadmin/templates/djangocms_pageadmin/admin/icons/unpublish.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "./base.html" %} -{% load static i18n %} -{% block title %}{% trans 'Unpublish' %}{% endblock %} -{% block name %}unpublish{% endblock %} -{% block icon %}{% static 'djangocms_pageadmin/svg/unpublish.svg' %}{% endblock %} From 0ce6923e3c4900006a02f4d5f3cbf7652ce050e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E7=9D=BF=E6=9B=BC?= Date: Wed, 6 Nov 2024 16:09:01 +0800 Subject: [PATCH 13/18] replace all btn generte by admin_action_button. testcase changed --- CHANGELOG.rst | 2 +- tests/test_admin.py | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1a6fc40..820e4b8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,7 +6,7 @@ Unreleased ========== * Dropped support for Django < 4.2 * Dropped support for Django CMS < 4.1 -* Add suppor for Django CMS 4.1 +* Add support for Django CMS 4.1 * Added support for Python 3.11 1.7.1 (2024-06-06) diff --git a/tests/test_admin.py b/tests/test_admin.py index 816e7f4..950e4fc 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -140,9 +140,9 @@ def test_duplicate_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-duplicate"}) + element = soup.find("a", {"class": "cms-action-duplicate"}) self.assertIsNotNone( - element, "Missing a.cms-page-admin-action-duplicate element" + element, "Missing a.cms-action-duplicate element" ) self.assertEqual(element["title"], "Duplicate") self.assertEqual( @@ -156,7 +156,7 @@ def test_set_home_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-set-home"}) + element = soup.find("a", {"class": "cms-action-set-home"}) self.assertEqual(element["title"], "Set as a home") self.assertEqual( element["href"], @@ -169,9 +169,9 @@ def test_unpublish_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-unpublish"}) + element = soup.find("a", {"class": "cms-action-unpublish"}) self.assertIsNotNone( - element, "Missing a.cms-page-admin-action-unpublish element" + element, "Missing a.cms-action-unpublish element" ) self.assertEqual(element["title"], "Unpublish") @@ -186,10 +186,10 @@ def test_unpublish_not_shown(self): # element, # "Element a.cms-action-unpublish is shown when it shouldn't", # ) - element = soup.find("a", {"class": "cms-page-admin-action-unpublish"}) + element = soup.find("a", {"class": "cms-action-unpublish"}) self.assertIsNone( element, - "Element a.cms-page-admin-action-unpublish is shown when it shouldn't", + "Element a.cms-action-unpublish is shown when it shouldn't", ) def test_manage_versions_link(self): @@ -197,9 +197,9 @@ def test_manage_versions_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-manage-versions"}) + element = soup.find("a", {"class": "cms-action-manage-versions"}) self.assertIsNotNone( - element, "Missing a.cms-page-admin-action-manage-versions element" + element, "Missing a.cms-action-manage-versions element" ) self.assertEqual(element["title"], "Manage versions") self.assertEqual(element["href"], version_list_url(pagecontent)) @@ -209,9 +209,9 @@ def test_basic_settings_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-basic-settings"}) + element = soup.find("a", {"class": "cms-action-basic-settings"}) self.assertIsNotNone( - element, "Missing a.cms-page-admin-action-basic-settings element" + element, "Missing a.cms-action-basic-settings element" ) self.assertEqual(element["title"], "Basic settings") self.assertEqual( @@ -224,9 +224,9 @@ def test_advanced_settings_link(self): func = self.modeladmin._list_actions(self.get_request("/")) response = func(pagecontent) soup = parse_html(response) - element = soup.find("a", {"class": "cms-page-admin-action-advanced-settings"}) + element = soup.find("a", {"class": "cms-action-advanced-settings"}) self.assertIsNotNone( - element, "Missing a.cms-page-admin-action-advanced-settings element" + element, "Missing a.cms-action-advanced-settings element" ) self.assertEqual(element["title"], "Advanced settings") self.assertEqual( @@ -513,8 +513,8 @@ def test_changelist_url_link_doesnt_open_in_sideframe(self): url_markup = self.modeladmin.url(pagecontent) # The url link should close the sideframe when selected - self.assertIn("js-page-admin-close-sideframe", url_markup) - self.assertNotIn("js-page-admin-keep-sideframe", url_markup) + self.assertIn("js-close-sideframe", url_markup) + self.assertNotIn("js-keep-sideframe", url_markup) def test_preview_link_doesnt_open_in_sideframe(self): """ From ae30438734110e9a7559c604c47348e016b8d756 Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Mon, 18 Nov 2024 16:49:08 +0800 Subject: [PATCH 14/18] fix: remove duplicated `is_locked` column --- djangocms_pageadmin/admin.py | 5 +---- .../static/djangocms_pageadmin/css/actions.css | 10 ++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 0017602..c1b6c7b 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -73,10 +73,7 @@ class PageContentAdmin(*PageContentAdminBases): search_fields = ("title",) def get_list_display(self, request): - list_display = self._list_display + [self._list_actions(request)] - if LOCK_VERSIONS: - list_display.insert(list_display.index('state'), 'is_locked') - return list_display + return self._list_display + [self._list_actions(request)] def get_queryset(self, request): """Filter PageContent objects by current site of the request. diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css index 8bce17f..6697501 100644 --- a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css +++ b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css @@ -98,3 +98,13 @@ ul.cms-pagetree-dropdown-menu-inner li a.inactive { .cms-pagetree-dropdown-menu.closed, .cms-icon-menu.closed .cms-pagetree-dropdown-menu { display: none; } + + +/* restore the removed drop down menu position style */ +.cms-pagetree-dropdown-menu-arrow-right-top:before { + top: 16px; +} + +.cms-pagetree-dropdown-menu-arrow-right-bottom:before { + bottom: 18px; +} \ No newline at end of file From 83b4df192a78a1676b3cf29fb5efa81f011884c5 Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Mon, 18 Nov 2024 17:12:01 +0800 Subject: [PATCH 15/18] fix: flake8 issue --- djangocms_pageadmin/admin.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index c1b6c7b..bb9638c 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -27,7 +27,6 @@ from cms.toolbar.utils import get_object_preview_url from djangocms_versioning.admin import VersioningAdminMixin -from djangocms_versioning.conf import LOCK_VERSIONS from djangocms_versioning.constants import DRAFT, PUBLISHED from djangocms_versioning.helpers import version_list_url from djangocms_versioning.models import Version @@ -94,8 +93,7 @@ def get_queryset(self, request): draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) select_related_tuple = ("created_by", "locked_by") else: - from djangocms_version_locking.models import \ - VersionLock # noqa: F401 + from djangocms_version_locking.models import VersionLock # noqa: F401 draft_version_lock_subquery = VersionLock.objects.filter( version__content_type=OuterRef("content_type"), version__object_id=OuterRef("object_id"), From f1f19ba981d3cb856ee7fc77fb1352f9c7187166 Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Mon, 18 Nov 2024 17:15:14 +0800 Subject: [PATCH 16/18] fix: isort issue --- djangocms_pageadmin/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index bb9638c..d155be0 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -93,7 +93,8 @@ def get_queryset(self, request): draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) select_related_tuple = ("created_by", "locked_by") else: - from djangocms_version_locking.models import VersionLock # noqa: F401 + from djangocms_version_locking.models import \ + VersionLock # noqa: F401 draft_version_lock_subquery = VersionLock.objects.filter( version__content_type=OuterRef("content_type"), version__object_id=OuterRef("object_id"), From a1bb1825b3f5e809eadd9abdbdf6e3ad3f25e9ef Mon Sep 17 00:00:00 2001 From: FreemanPancake Date: Tue, 19 Nov 2024 15:15:08 +0800 Subject: [PATCH 17/18] remove action burger menu from this addon, as this has been integrated in djangocms-version-locking. --- CHANGELOG.rst | 1 + djangocms_pageadmin/admin.py | 3 - .../djangocms_pageadmin/css/actions.css | 110 ----------- .../static/djangocms_pageadmin/js/actions.js | 172 ------------------ .../pagecontent/change_list.html | 2 - 5 files changed, 1 insertion(+), 287 deletions(-) delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css delete mode 100644 djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 820e4b8..5630d42 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,7 @@ Unreleased * Dropped support for Django CMS < 4.1 * Add support for Django CMS 4.1 * Added support for Python 3.11 +* remove action burger menu from this addon, as this has been integrated in djangocms-version-locking. 1.7.1 (2024-06-06) ================= diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index d155be0..9a2360a 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -640,9 +640,6 @@ def get_exported_queryset(self, request): return cl.get_queryset(request) - class Media: - css = {"all": ("djangocms_pageadmin/css/actions.css",)} - admin.site.unregister(PageContent) admin.site.register(PageContent, PageContentAdmin) diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css deleted file mode 100644 index 6697501..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css +++ /dev/null @@ -1,110 +0,0 @@ -/*------------------------------------- - General page admin styles ----------------------------------------*/ - -/* ensure certain columns aren't too wide */ -.field-get_title { - min-width: 250px; - word-break: break-word; - white-space: normal !important; -} - -.field-url { - min-width: 100px; - word-break: break-all; - white-space: normal !important; -} -.cms-icon-menu { - cursor: pointer; -} - -/*------------------------------------- - All action buttons ----------------------------------------*/ -.btn.cms-action-btn { - position: relative; - display: -webkit-inline-box; - display: -ms-inline-flexbox; - display: inline-flex; - padding: 0 4px 0 7px !important; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - justify-content: center; - height: 34px; - margin-top: -12px !important; - position: relative; - height: 34px; - bottom: -6px; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -/* disable clicking for inactive buttons */ -.btn.cms-action-btn.inactive { - pointer-events: none; - background-color: #e1e1e1 !important; -} - -.btn.cms-action-btn.inactive span { - opacity: 0.5; -} - -/*------------------------------------- -This governs the drop-down behaviour -extending the pagetree classes provided by CMS ----------------------------------------*/ - -/* add shadow on burger menu trigger */ -a.btn.cms-action-btn:hover, a.btn.cms-action-btn.open { - box-shadow: inset 0 3px 5px rgba(0,0,0,.125); -} - -/* style for each option row */ -ul.cms-pagetree-dropdown-menu-inner li { - border: 1px solid transparent; - border-radius: 5px; - padding: 2px 6px; -} -ul.cms-pagetree-dropdown-menu-inner li:hover { - list-style-type: none; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #0bf; -} - -/* align the option text with it's icon */ -ul.cms-pagetree-dropdown-menu-inner li a span { - line-height: 1rem; -} - -/* disable any inactive option */ -ul.cms-pagetree-dropdown-menu-inner li a.inactive { - cursor: not-allowed; - pointer-events: none; - opacity: 0.3; - filter: alpha(opacity=30); -} - -/* set the size of the drop-down */ -.cms-pagetree-dropdown-menu.open { - display: block; - width: 200px; -} - -/* hide when closed */ -.cms-pagetree-dropdown-menu.closed, .cms-icon-menu.closed .cms-pagetree-dropdown-menu { - display: none; -} - - -/* restore the removed drop down menu position style */ -.cms-pagetree-dropdown-menu-arrow-right-top:before { - top: 16px; -} - -.cms-pagetree-dropdown-menu-arrow-right-bottom:before { - bottom: 18px; -} \ No newline at end of file diff --git a/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js b/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js deleted file mode 100644 index e54837f..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/js/actions.js +++ /dev/null @@ -1,172 +0,0 @@ -"use strict"; - -(function ($) { - if (!$) { - return; - } - - $(function () { - var createBurgerMenu = function createBurgerMenu(row) { - /* create burger menu anchor section */ - var anchor = document.createElement('A'); - var cssclass = document.createAttribute('class'); - cssclass.value = 'btn cms-action-btn closed'; - anchor.setAttributeNode(cssclass); - // create burger menu title - var title = document.createAttribute('title'); - title.value = 'Actions'; - anchor.setAttributeNode(title); - // create burger menu icon - var menu_icon = document.createElement('span'); - menu_icon.className = "cms-icon cms-icon-menu"; - anchor.appendChild(menu_icon); - - /* create options container */ - var optionsContainer = document.createElement('DIV'); - cssclass = document.createAttribute('class'); - cssclass.value = 'cms-pagetree-dropdown-menu ' + // main selector for the menu - 'cms-pagetree-dropdown-menu-arrow-right-top'; // keeps the menu arrow in position - - optionsContainer.setAttributeNode(cssclass); - var ul = document.createElement('UL'); - cssclass = document.createAttribute('class'); - cssclass.value = 'cms-pagetree-dropdown-menu-inner'; - ul.setAttributeNode(cssclass); - /* get the existing actions and move them into the options container */ - - var li; - var text; - var actions = $(row).children('.field-list_actions'); - - if (!actions.length) { - /* skip any rows without actions to avoid errors */ - return; - } - - $(actions[0]).children('.cms-action-btn').each(function (index, item) { - /* exclude preview and edit buttons */ - if (item.classList.contains('cms-action-preview') || - item.classList.contains('cms-action-edit')) { - return; - } - - li = document.createElement('LI'); - /* create an anchor from the item */ - - var li_anchor = document.createElement('A'); - cssclass = document.createAttribute('class'); - cssclass.value = 'cms-page-admin-action-burger-options-anchor'; - - if ($(item).hasClass('cms-form-get-method')) { - /* ensure the fake-form selector is propagated to the new anchor */ - cssclass.value += ' cms-form-get-method'; - } - - li_anchor.setAttributeNode(cssclass); - var href = document.createAttribute('href'); - href.value = $(item).attr('href'); - li_anchor.setAttributeNode(href); - /* move the an image element */ - - var existing_icon_span = $(item).children('span'); - li_anchor.appendChild(existing_icon_span[0]); - /* create the button text */ - - text = document.createTextNode(item.title); - var span = document.createElement('SPAN'); - span.appendChild(text); // construct the button - - li.appendChild(li_anchor); - li_anchor.appendChild(span); - ul.appendChild(li); - /* destroy original replaced buttons */ - - actions[0].removeChild(item); - }); - /* add the options to the drop-down */ - - optionsContainer.appendChild(ul); - actions[0].appendChild(anchor); - document.body.appendChild(optionsContainer); - /* listen for burger menu clicks */ - - anchor.addEventListener('click', function (ev) { - ev.stopPropagation(); - toggleBurgerMenu(anchor, optionsContainer); - }); - /* close burger menu if clicking outside */ - - $(window).click(function () { - closeBurgerMenu(); - }); - }; - - var toggleBurgerMenu = function toggleBurgerMenu(burgerMenuAnchor, optionsContainer) { - var bm = $(burgerMenuAnchor); - var op = $(optionsContainer); - var closed = bm.hasClass('closed'); - closeBurgerMenu(); - - if (closed) { - bm.removeClass('closed'); - bm.addClass('open'); - op.removeClass('closed'); - op.addClass('open'); - } else { - bm.addClass('closed'); - bm.removeClass('open'); - op.addClass('closed'); - op.removeClass('open'); - } - - var pos = bm.offset(); - op.css('left', pos.left - 200); - op.css('top', pos.top); - }; - - var closeBurgerMenu = function closeBurgerMenu() { - $('.cms-pagetree-dropdown-menu').removeClass('open'); - $('.cms-pagetree-dropdown-menu').addClass('closed'); - $('.cms-action-btn').removeClass('open'); - $('.cms-action-btn').addClass('closed'); - }; - - $('#result_list').find('tr').each(function (index, item) { - createBurgerMenu(item); - }); - /* it is not possible to put a form inside a form, so - actions have to create their own form on click */ - - var fakeForm = function fakeForm(e) { - var action = $(e.currentTarget); - var formMethod = action.attr('class').indexOf('cms-form-get-method') !== -1 ? 'GET' : 'POST'; - if (formMethod == 'GET') return - e.preventDefault(); - - var csrfToken = ''; - var fakeForm = $('
' + csrfToken + '
'); - var keepSideFrame = action.attr('class').indexOf('js-keep-sideframe') !== -1; // always break out of the sideframe, cause it was never meant to open cms views inside it - - try { - if (!keepSideFrame) { - window.top.CMS.API.Sideframe.close(); - } - } catch (err) {} - - if (keepSideFrame) { - var body = window.document.body; - } else { - var body = window.top.document.body; - } - - fakeForm.appendTo(body).submit(); - }; - - $('.js-action, .cms-js-publish-btn, .cms-js-edit-btn, .cms-page-admin-action-burger-options-anchor').on('click', fakeForm); - $('.js-close-sideframe').on('click', function () { - try { - window.top.CMS.API.Sideframe.close(); - } catch (e) {} - }); - }); -})(typeof django !== 'undefined' && django.jQuery || typeof CMS !== 'undefined' && CMS.$ || false); diff --git a/djangocms_pageadmin/templates/admin/djangocms_pageadmin/pagecontent/change_list.html b/djangocms_pageadmin/templates/admin/djangocms_pageadmin/pagecontent/change_list.html index 799d19a..8b45abf 100644 --- a/djangocms_pageadmin/templates/admin/djangocms_pageadmin/pagecontent/change_list.html +++ b/djangocms_pageadmin/templates/admin/djangocms_pageadmin/pagecontent/change_list.html @@ -11,14 +11,12 @@ {{ block.super }} {# INFO: we need to add styles here instead of "extrastyle" to avoid conflicts with adminstyle #} - - {% endblock extrahead %} {% block object-tools-items %} From 9b9cdbb3e421bf5c6e893b6b7ae8fd79cb629653 Mon Sep 17 00:00:00 2001 From: FreemanPancake Date: Wed, 20 Nov 2024 16:20:12 +0800 Subject: [PATCH 18/18] chore: completely remove compatible code for Django < 4.2, and CMS < 4.1 --- djangocms_pageadmin/admin.py | 55 +++++++++++------------------------ djangocms_pageadmin/compat.py | 20 ------------- tests/__init__.py | 7 ----- 3 files changed, 17 insertions(+), 65 deletions(-) delete mode 100644 djangocms_pageadmin/compat.py diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index 9a2360a..4aebde6 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -21,6 +21,8 @@ from django.views.decorators.http import require_POST from cms.admin.pageadmin import PageContentAdmin as DefaultPageContentAdmin +from cms.admin.utils import ChangeListActionsMixin +from cms.api import create_page_content from cms.extensions import extension_pool from cms.models import PageContent, PageUrl from cms.signals.apphook import set_restart_trigger @@ -28,10 +30,9 @@ from djangocms_versioning.admin import VersioningAdminMixin from djangocms_versioning.constants import DRAFT, PUBLISHED -from djangocms_versioning.helpers import version_list_url +from djangocms_versioning.helpers import version_is_locked, version_list_url from djangocms_versioning.models import Version -from .compat import CMS_41, DJANGO_4_2, create_page_content, version_is_locked from .filters import ( AuthorFilter, LanguageFilter, @@ -50,14 +51,8 @@ require_POST = method_decorator(require_POST) -PageContentAdminBases = [VersioningAdminMixin, DefaultPageContentAdmin] -if CMS_41: - from cms.admin.utils import ChangeListActionsMixin - PageContentAdminBases.insert(0, ChangeListActionsMixin) - - -class PageContentAdmin(*PageContentAdminBases): +class PageContentAdmin(ChangeListActionsMixin, VersioningAdminMixin, DefaultPageContentAdmin): change_list_template = "admin/djangocms_pageadmin/pagecontent/change_list.html" list_display_links = None list_filter = (LanguageFilter, UnpublishedFilter, TemplateFilter, AuthorFilter) @@ -83,25 +78,14 @@ def get_queryset(self, request): # Collect locked status to handle the requirement that lock # on a draft version dictates the unpublish permission # on a published version - if CMS_41: - draft_version_lock_subquery = Version.objects.filter( - content_type=OuterRef("content_type"), - object_id=OuterRef("object_id"), - state=DRAFT, - locked_by__isnull=False, - ).order_by("-pk") - draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) - select_related_tuple = ("created_by", "locked_by") - else: - from djangocms_version_locking.models import \ - VersionLock # noqa: F401 - draft_version_lock_subquery = VersionLock.objects.filter( - version__content_type=OuterRef("content_type"), - version__object_id=OuterRef("object_id"), - version__state=DRAFT, - ).order_by("-pk") - draft_sub = Subquery(draft_version_lock_subquery.values("created_by")[:1]) - select_related_tuple = ("created_by", "versionlock") + draft_version_lock_subquery = Version.objects.filter( + content_type=OuterRef("content_type"), + object_id=OuterRef("object_id"), + state=DRAFT, + locked_by__isnull=False, + ).order_by("-pk") + draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) + select_related_tuple = ("created_by", "locked_by") queryset = ( super() .get_queryset(request) @@ -450,10 +434,9 @@ def duplicate_view(self, request, object_id): "parent_node": obj.page.node.parent, "translations": False, "permissions": False, - "extensions": False + "extensions": False, + "user": request.user } - if CMS_41: - new_page_params.update({"user": request.user}) new_page = obj.page.copy(**new_page_params) new_page_content = create_page_content( @@ -465,10 +448,7 @@ def duplicate_view(self, request, object_id): template=obj.template, created_by=request.user, ) - if CMS_41: - new_page.page_content_cache[obj.language] = new_page_content - else: - new_page.title_cache[obj.language] = new_page_content + new_page.page_content_cache[obj.language] = new_page_content extension_pool.copy_extensions( source_page=obj.page, target_page=new_page, languages=[obj.language] @@ -631,11 +611,10 @@ def get_exported_queryset(self, request): 'list_max_show_all': self.list_max_show_all, 'list_editable': self.list_editable, 'model_admin': self, - 'sortable_by': self.sortable_by + 'sortable_by': self.sortable_by, + 'search_help_text': self.search_help_text } - if DJANGO_4_2: - changelist_kwargs.update({'search_help_text': self.search_help_text}) cl = changelist(**changelist_kwargs) return cl.get_queryset(request) diff --git a/djangocms_pageadmin/compat.py b/djangocms_pageadmin/compat.py deleted file mode 100644 index 2ef8626..0000000 --- a/djangocms_pageadmin/compat.py +++ /dev/null @@ -1,20 +0,0 @@ -import django - -from cms import __version__ as CMS_VERSION - -from packaging.version import Version - - -DJANGO_4_2 = Version(django.get_version()) >= Version('4.2') - -CMS_41 = Version("4.1") <= Version(CMS_VERSION) - -if CMS_41: - from cms.api import create_page_content # noqa: F401 - - from djangocms_versioning.helpers import version_is_locked # noqa: F401 -else: - from cms.api import create_title as create_page_content # noqa: F401 - - from djangocms_version_locking.helpers import \ - version_is_locked # noqa: F401 diff --git a/tests/__init__.py b/tests/__init__.py index bcd2ee3..e69de29 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,7 +0,0 @@ -from djangocms_pageadmin.compat import DJANGO_4_2 - - -if not DJANGO_4_2: # TODO: remove when dropping support for Django < 4.2 - from django.test.testcases import TransactionTestCase - - TransactionTestCase.assertQuerySetEqual = TransactionTestCase.assertQuerysetEqual