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..8e30d91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,10 +8,9 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ 3.8, 3.9, '3.10' ] # latest release minus two + python-version: [ 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/CHANGELOG.rst b/CHANGELOG.rst index 39adc48..5630d42 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog ========= +Unreleased +========== +* Dropped support for Django < 4.2 +* 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) ================= * Fixed edit link in pageadmin to close sideframe diff --git a/djangocms_pageadmin/admin.py b/djangocms_pageadmin/admin.py index e239476..4aebde6 100644 --- a/djangocms_pageadmin/admin.py +++ b/djangocms_pageadmin/admin.py @@ -13,28 +13,26 @@ 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 +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 import api 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 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 .filters import ( AuthorFilter, LanguageFilter, @@ -54,7 +52,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) @@ -80,11 +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 - 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") + draft_sub = Subquery(draft_version_lock_subquery.values("locked_by")[:1]) + select_related_tuple = ("created_by", "locked_by") queryset = ( super() .get_queryset(request) @@ -96,11 +97,9 @@ def get_queryset(self, request): "versions", queryset=Version.objects.annotate( # used by locking - _draft_version_user_id=Subquery( - draft_version_lock_subquery.values("created_by")[:1] - ) + _draft_version_user_id=draft_sub ) - .select_related("created_by", "versionlock") + .select_related(*select_related_tuple) .prefetch_related("content"), ) ) @@ -160,7 +159,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") @@ -181,7 +180,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( @@ -201,18 +200,23 @@ def get_title(self, obj): ) def author(self, obj): version = self.get_version(obj) - return version.created_by + return getattr(version, "created_by", None) + @admin.display( + description=_("is locked") + ) def is_locked(self, obj): version = self.get_version(obj) - if version.state == DRAFT and version_is_locked(version): - return render_to_string("djangocms_version_locking/admin/locked_icon.html") - return "" + if version and version.state == DRAFT and version_is_locked(version): + return mark_safe('') + else: + return "" def is_home(self, obj): if obj.page.is_home: - return render_to_string("djangocms_pageadmin/admin/icons/home.html") - return "" + return mark_safe('') + else: + return "" @admin.display( description=_("modified date"), @@ -238,9 +242,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): @@ -249,7 +257,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 @@ -261,9 +268,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): @@ -274,9 +286,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): @@ -291,9 +306,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): @@ -315,30 +334,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): @@ -398,15 +429,17 @@ 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, - ) - - new_page_content = api.create_title( + new_page_params = { + "site": form.cleaned_data["site"], + "parent_node": obj.page.node.parent, + "translations": False, + "permissions": False, + "extensions": False, + "user": request.user + } + new_page = obj.page.copy(**new_page_params) + + new_page_content = create_page_content( page=new_page, language=obj.language, slug=form.cleaned_data["slug"], @@ -415,7 +448,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] @@ -578,18 +611,14 @@ 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) - class Media: - css = {"all": ("djangocms_pageadmin/css/actions.css",)} - admin.site.unregister(PageContent) admin.site.register(PageContent, PageContentAdmin) diff --git a/djangocms_pageadmin/compat.py b/djangocms_pageadmin/compat.py deleted file mode 100644 index f2c5cad..0000000 --- a/djangocms_pageadmin/compat.py +++ /dev/null @@ -1,6 +0,0 @@ -import django - -from packaging.version import Version - - -DJANGO_4_2 = Version(django.get_version()) >= Version('4.2') 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/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css b/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css deleted file mode 100644 index 8f4acc0..0000000 --- a/djangocms_pageadmin/static/djangocms_pageadmin/css/actions.css +++ /dev/null @@ -1,119 +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-version-locked-status-icon img, .cms-page-admin-home img { - width: 15px; - height: 15px; -} -.cms-icon-menu { - cursor: pointer; -} - -/*------------------------------------- - All action buttons ----------------------------------------*/ -.btn.cms-page-admin-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-page-admin-action-btn.inactive { - pointer-events: none; - background-color: #e1e1e1 !important; -} - -.btn.cms-page-admin-action-btn.inactive img { - opacity: 0.5; -} - -/* set size and spacing between for the action icons */ -a.btn.cms-page-admin-action-btn img { - width: 20px; - height: 20px; - margin-right: 4px; -} - -/*------------------------------------- -This governs the drop-down behaviour -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 { - 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; -} - -/* 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 */ -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; -} 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 8d3eef8..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 icon */ - var anchor = document.createElement('A'); - var cssclass = document.createAttribute('class'); - cssclass.value = 'btn cms-page-admin-action-btn closed'; - anchor.setAttributeNode(cssclass); - var title = document.createAttribute('title'); - title.value = 'Actions'; - anchor.setAttributeNode(title); - var icon = document.createElement('IMG'); - var src = document.createAttribute('src'); - src.value = pageadmin_static_url_prefix + 'svg/menu.svg'; - icon.setAttributeNode(src); - anchor.appendChild(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-page-admin-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')) { - 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_img = $(item).children('img'); - li_anchor.appendChild(existing_img[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-page-admin-action-btn').removeClass('open'); - $('.cms-page-admin-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-page-admin-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-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 () { - try { - window.top.CMS.API.Sideframe.close(); - } catch (e) {} - }); - }); -})(typeof django !== 'undefined' && django.jQuery || typeof CMS !== 'undefined' && CMS.$ || false); 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/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 %} 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 %} diff --git a/setup.py b/setup.py index c38d30d..ca25527 100644 --- a/setup.py +++ b/setup.py @@ -4,8 +4,8 @@ INSTALL_REQUIREMENTS = [ - "Django>=3.2,<5.0", - "django_cms", + "Django>=4.2,<5.0", + "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/__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 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 e5993fe..0000000 --- a/tests/requirements/dj42_cms40.txt +++ /dev/null @@ -1,17 +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/FidelityInternational/djangocms-moderation/tarball/feature/django-42-compat#egg=djangocms-moderation - - - - diff --git a/tests/requirements/dj42_cms41.txt b/tests/requirements/dj42_cms41.txt new file mode 100644 index 0000000..3a8e4c9 --- /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 +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/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 + + + + diff --git a/tests/test_admin.py b/tests/test_admin.py index ae8baec..950e4fc 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): @@ -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,18 +169,11 @@ 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") - self.assertEqual( - element["href"], - reverse( - "admin:djangocms_versioning_pagecontentversion_unpublish", - args=(version.pk,), - ), - ) def test_unpublish_not_shown(self): version = PageVersionFactory() @@ -188,10 +181,15 @@ 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-page-admin-action-unpublish"}) + # 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-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): @@ -199,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)) @@ -211,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( @@ -226,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( @@ -515,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): """ @@ -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 bbf18d3..b82a042 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,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: -r{toxinidir}/tests/requirements/dj32_cms40.txt - dj42: -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 + py311: python3.11 commands = {envpython} --version