diff --git a/.github/workflows/publish-to-live-pypi.yml b/.github/workflows/publish-to-live-pypi.yml new file mode 100644 index 00000000..0776261d --- /dev/null +++ b/.github/workflows/publish-to-live-pypi.yml @@ -0,0 +1,41 @@ +name: Publish Python 🐍 distributions 📦 to pypi + +on: + release: + types: + - published + +jobs: + build-n-publish: + name: Build and publish Python 🐍 distributions 📦 to pypi + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/djangocms-moderation + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install pypa/build + run: >- + python -m + pip install + build + --user + - name: Build a binary wheel and a source tarball + run: >- + python -m + build + --sdist + --wheel + --outdir dist/ + . + + - name: Publish distribution 📦 to PyPI + if: startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml new file mode 100644 index 00000000..ae0fd790 --- /dev/null +++ b/.github/workflows/publish-to-test-pypi.yml @@ -0,0 +1,43 @@ +name: Publish Python 🐍 distributions 📦 to TestPyPI + +on: + push: + branches: + - master + +jobs: + build-n-publish: + name: Build and publish Python 🐍 distributions 📦 to TestPyPI + runs-on: ubuntu-latest + environment: + name: test + url: https://test.pypi.org/p/djangocms-moderation + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install pypa/build + run: >- + python -m + pip install + build + --user + - name: Build a binary wheel and a source tarball + run: >- + python -m + build + --sdist + --wheel + --outdir dist/ + . + + - name: Publish distribution 📦 to Test PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + skip_existing: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 606c3c76..c489abb2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,4 +42,4 @@ jobs: run: coverage run ./tests/settings.py - name: Upload Coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 59db67e9..e99f5e66 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,19 +9,19 @@ ci: repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.19.0 hooks: - id: pyupgrade args: ["--py310-plus"] - repo: https://github.com/adamchainz/django-upgrade - rev: '1.19.0' + rev: '1.22.1' hooks: - id: django-upgrade args: [--target-version, "4.0"] - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 @@ -31,7 +31,7 @@ repos: - id: yesqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: check-merge-conflict - id: debug-statements diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f1e63062..1d7eabb0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,10 @@ Changelog Unreleased ========== +fix: Add data-popup attr to a tag in burger menu item +fix: Replace SortableAdminMixin by SortableAdminBase for WorkflowAdmin +fix: Restore "In Collection" button in the toolbar +fix: Update README.rst and add overview of settings 2.2.1 (2024-07-02) ================== diff --git a/README.rst b/README.rst index e2d425b2..93572458 100644 --- a/README.rst +++ b/README.rst @@ -23,8 +23,8 @@ Run:: Add the following to your project's ``INSTALLED_APPS``: - - ``'djangocms_moderation'`` - - ``'adminsortable2'`` +- ``'djangocms_moderation'`` +- ``'adminsortable2'`` Run:: @@ -32,6 +32,69 @@ Run:: to perform the application's database migrations. +Configuration +============= + +The following settings can be added to your project's settings file to configure django CMS Moderation's behavior: + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Setting + - Description + * - ``CMS_MODERATION_DEFAULT_COMPLIANCE_NUMBER_BACKEND`` + - Default backend class for generating compliance numbers. + Default is ``djangocms_moderation.backends.uuid4_backend``. + * - ``CMS_MODERATION_COMPLIANCE_NUMBER_BACKENDS`` + - List of available compliance number backend classes. + By default, three backends are configured: ``uuid4_backend``, + ``sequential_number_backend``, and + ``sequential_number_with_identifier_prefix_backend``. + * - ``CMS_MODERATION_ENABLE_WORKFLOW_OVERRIDE`` + - Enable/disable workflow override functionality. Defaults to ``False``. + * - ``CMS_MODERATION_DEFAULT_CONFIRMATION_PAGE_TEMPLATE`` + - Default template for confirmation pages. Defaults to + ``djangocms_moderation/moderation_confirmation.html`` + * - ``CMS_MODERATION_CONFIRMATION_PAGE_TEMPLATES`` + - List of available confirmation page templates. Only includes the + default template by default. + * - ``CMS_MODERATION_COLLECTION_COMMENTS_ENABLED`` + - Enable/disable comments on collections. Defaults to ``True``. + * - ``CMS_MODERATION_REQUEST_COMMENTS_ENABLED`` + - Enable/disable comments on requests. Defaults to ``True``. + * - ``CMS_MODERATION_COLLECTION_NAME_LENGTH_LIMIT`` + - Maximum length for collection names. Defaults to ``24``. + * - ``EMAIL_NOTIFICATIONS_FAIL_SILENTLY`` + - Control email notification error handling. Defaults to ``False``. + +Example Configuration +--------------------- + +Add these settings to your project's settings file: + +.. code-block:: python + + # Custom compliance number backend + CMS_MODERATION_DEFAULT_COMPLIANCE_NUMBER_BACKEND = 'myapp.backends.CustomComplianceNumberBackend' + + # Enable workflow override + CMS_MODERATION_ENABLE_WORKFLOW_OVERRIDE = True + + # Custom confirmation template + CMS_MODERATION_DEFAULT_CONFIRMATION_PAGE_TEMPLATE = 'custom_confirmation.html' + + # Enable comments + CMS_MODERATION_COLLECTION_COMMENTS_ENABLED = True + CMS_MODERATION_REQUEST_COMMENTS_ENABLED = True + + # Set collection name length limit + CMS_MODERATION_COLLECTION_NAME_LENGTH_LIMIT = 100 + + # Control email notification errors + EMAIL_NOTIFICATIONS_FAIL_SILENTLY = False + +============= Documentation ============= diff --git a/djangocms_moderation/cms_toolbars.py b/djangocms_moderation/cms_toolbars.py index 7679807a..a99a7b66 100644 --- a/djangocms_moderation/cms_toolbars.py +++ b/djangocms_moderation/cms_toolbars.py @@ -54,7 +54,7 @@ def _add_moderation_buttons(self): if not helpers.is_registered_for_moderation(self.toolbar.obj): return - if self._is_versioned() and self.toolbar.edit_mode_active: + if self._is_versioned() and (self.toolbar.edit_mode_active or self.toolbar.preview_mode_active): moderation_request = helpers.get_active_moderation_request(self.toolbar.obj) if moderation_request: title, url = helpers.get_moderation_button_title_and_url( diff --git a/djangocms_moderation/monkeypatch.py b/djangocms_moderation/monkeypatch.py index a439850e..a1ad0f06 100644 --- a/djangocms_moderation/monkeypatch.py +++ b/djangocms_moderation/monkeypatch.py @@ -120,6 +120,17 @@ def inner(self, obj, request): return inner +def _check_registered_for_moderation(message): + """ + Fail check if object is registered for moderation + """ + def inner(version, user): + if is_registered_for_moderation(version.content): + raise ConditionFailed(message) + + return inner + + admin.VersionAdmin._get_publish_link = _get_publish_link( admin.VersionAdmin._get_publish_link ) @@ -152,5 +163,8 @@ def inner(self, obj, request): _("Cannot edit a version in an active moderation collection") ) ] +models.Version.check_publish += [ + _check_registered_for_moderation(_("Content cannot be published directly. Use the moderation process.")) +] fields.PlaceholderRelationField.default_checks += [_is_placeholder_review_unlocked] diff --git a/djangocms_moderation/static/djangocms_moderation/js/burger.js b/djangocms_moderation/static/djangocms_moderation/js/burger.js index 3fbcdf9e..93efd262 100644 --- a/djangocms_moderation/static/djangocms_moderation/js/burger.js +++ b/djangocms_moderation/static/djangocms_moderation/js/burger.js @@ -147,6 +147,7 @@ let li_anchor = document.createElement('a'); const itemId = $(item).attr('id'); const itemTarget = $(item).attr('target'); + const itemDataPopup = $(item).attr('data-popup'); li_anchor.setAttribute('class', 'cms-actions-dropdown-menu-item-anchor'); li_anchor.setAttribute('href', $(item).attr('href')); @@ -158,6 +159,10 @@ if (itemTarget !== undefined) { li_anchor.setAttribute('target', itemTarget); } + // Copy the data-popup attribute if it is set + if (itemDataPopup !== undefined) { + li_anchor.setAttribute('data-popup', itemDataPopup); + } if ($(item).hasClass('cms-form-get-method')) { // Ensure the fake-form selector is propagated to the new anchor diff --git a/docs/requirements.txt b/docs/requirements.txt index 1e5785d8..f8a8a421 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -118,7 +118,7 @@ tabulate==0.9.0 # via docstrfmt toml==0.10.2 # via docstrfmt -tornado==6.4.1 +tornado==6.4.2 # via livereload typing-extensions==4.9.0 # via diff --git a/package-lock.json b/package-lock.json index 0af53185..e8609650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2179,9 +2179,9 @@ "dev": true }, "elliptic": { - "version": "6.5.7", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", - "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", + "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", "dev": true, "requires": { "bn.js": "^4.11.9", diff --git a/tests/test_admin.py b/tests/test_admin.py index 32dbd321..2c44b403 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -440,3 +440,11 @@ def test_workflow_admin_renders_correctly(self): # django-admin-sortable2 injected its inputs self.assertContains(result, '') self.assertContains(result, '