Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5e24b78
Use batch_editing branch of mapentity
PartyNell Dec 2, 2025
f0f6e56
Add actions button on blades list view
PartyNell Dec 2, 2025
809d08c
Remove custom code for multiple path deletion
PartyNell Dec 3, 2025
c386303
fix quality
PartyNell Dec 3, 2025
25155e9
Use datatable select tool for merge paths JS
PartyNell Dec 3, 2025
1013d8d
Make Topology.geom_need_update editable=False
PartyNell Dec 3, 2025
06cd168
Add protection on Multi action to check if the selected items are in …
PartyNell Dec 4, 2025
cc0ca4c
Remove topology field from Blade multi update form
PartyNell Dec 4, 2025
281fb5a
Remove published field in multi update form if the user do not have p…
PartyNell Dec 4, 2025
379731e
Change get execution order to execute pks verification first
PartyNell Dec 5, 2025
a167152
Restrict multi actions for paths depends on draft permission
PartyNell Dec 5, 2025
944ec06
change get_success_url to get_redirect_url in BelongStructureMixin
PartyNell Dec 8, 2025
5aeb074
Delete Actions button on report list view
PartyNell Dec 9, 2025
cd5adca
Make traductions
PartyNell Dec 12, 2025
ddb289f
Translate french traductions
PartyNell Dec 12, 2025
200d2be
Remove structure field in multi action form if the user isn't superuser
PartyNell Dec 12, 2025
c99467d
Add structure restrictions for blades
PartyNell Dec 12, 2025
4917a88
reduce button size
PartyNell Dec 12, 2025
d7cff02
Makes tests
PartyNell Dec 12, 2025
ecdbeb3
Make tests
PartyNell Dec 12, 2025
1a77515
Make Path action buttom rounded
PartyNell Dec 15, 2025
07714ce
Change warning message for multi action when a selected items isn't i…
PartyNell Dec 15, 2025
c8367e4
Change traduction
PartyNell Dec 15, 2025
518a0af
Add changelog entry
PartyNell Dec 15, 2025
4f4f87d
Alter field geom_need_update on topology (make migration)
PartyNell Dec 15, 2025
48b0759
Fix deps
PartyNell Dec 15, 2025
85e126c
Fix coverage
PartyNell Dec 15, 2025
dde4690
fix cypress tests
PartyNell Dec 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions cypress/integration/nav_create_path.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('Create path', () => {

cy.loginByCSRF(username, password)
.then((resp) => {
expect(resp.status).to.eq(200)
expect(resp.status).to.eq(200);
});
cy.mockTiles();
});
Expand Down Expand Up @@ -53,17 +53,17 @@ describe('Create path', () => {
it('Path action delete multiple without path', () => {
cy.visit('/path/list');
cy.get("button.btn-primary[data-toggle='dropdown']").click();
cy.get("a[href='#delete']").click();
cy.get("#btn-delete").click();
cy.url().should('include', '/path/list/');
cy.get("a[title='Path number 1']").should('have.length', 2);
cy.get("a[title='Path number 2']").should('have.length', 2);
})
it('Path action delete multiple path', () => {
cy.visit('/path/list');
cy.get("input[name='path[]'][value='1']").click();
cy.get("input[name='path[]'][value='2']").click();
cy.get('a[data-pk="1"]').closest('tr').find('input.dt-select-checkbox').check();
cy.get('a[data-pk="2"]').closest('tr').find('input.dt-select-checkbox').check();
cy.get("button.btn-primary[data-toggle='dropdown']").click();
cy.get("a[href='#delete']").click();
cy.get("#btn-delete").click();
cy.get("input[type='submit']").click();
cy.url().should('include', '/path/list/');
cy.get("a[title='Path number 1']").should('have.length', 1);
Expand All @@ -72,8 +72,8 @@ describe('Create path', () => {
// Two path
it('Path action merge multiple path', () => {
cy.visit('/path/list');
cy.get("input[name='path[]'][value='3']").click();
cy.get("input[name='path[]'][value='4']").click();
cy.get('a[data-pk="3"]').closest('tr').find('input.dt-select-checkbox').check();
cy.get('a[data-pk="4"]').closest('tr').find('input.dt-select-checkbox').check();
cy.get("button.btn-primary[data-toggle='dropdown']").click();
cy.get("a[href='#confirm-merge']").click();
cy.get("button").contains('Merge').click();
Expand Down
2 changes: 1 addition & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Cypress.Commands.add('loginByCSRF', (username, password) => {
.then((body) => {
// we can use Cypress.$ to parse the string body
// thus enabling us to query into it easily
const $html = Cypress.$(body)
const $html = Cypress.$(body);
cy.request({
method: 'POST',
url: '/login/?next=/',
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ CHANGELOG

* Fix ``label_en`` content on sensitivity module parser

**New features**
* Add bulk deletion/edition on list views (refs #5107).

2.121.1 (2025-11-17)
----------------------------

Expand Down
11 changes: 7 additions & 4 deletions geotrek/common/locale/de/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-22 09:48+0000\n"
"POT-Creation-Date: 2025-12-15 08:21+0000\n"
"PO-Revision-Date: 2025-10-22 09:01+0000\n"
"Last-Translator: Anonymous <[email protected]>\n"
"Language-Team: German <https://weblate.makina-corpus.net/projects/geotrek-admin/common/de/>\n"
Expand Down Expand Up @@ -110,9 +110,6 @@ msgstr ""
msgid "Merge"
msgstr ""

msgid "Action"
msgstr ""

msgid "Insertion date"
msgstr ""

Expand Down Expand Up @@ -159,6 +156,9 @@ msgstr ""
msgid "External id"
msgstr ""

msgid "Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
msgstr ""

msgid "Attachment license"
msgstr ""

Expand Down Expand Up @@ -559,6 +559,9 @@ msgstr ""
msgid "User"
msgstr ""

msgid "Action"
msgstr ""

msgid "Full history"
msgstr ""

Expand Down
11 changes: 7 additions & 4 deletions geotrek/common/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-22 09:48+0000\n"
"POT-Creation-Date: 2025-12-15 08:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down Expand Up @@ -110,9 +110,6 @@ msgstr ""
msgid "Merge"
msgstr ""

msgid "Action"
msgstr ""

msgid "Insertion date"
msgstr ""

Expand Down Expand Up @@ -159,6 +156,9 @@ msgstr ""
msgid "External id"
msgstr ""

msgid "Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
msgstr ""

msgid "Attachment license"
msgstr ""

Expand Down Expand Up @@ -559,6 +559,9 @@ msgstr ""
msgid "User"
msgstr ""

msgid "Action"
msgstr ""

msgid "Full history"
msgstr ""

Expand Down
11 changes: 7 additions & 4 deletions geotrek/common/locale/es/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-22 09:48+0000\n"
"POT-Creation-Date: 2025-12-15 08:21+0000\n"
"PO-Revision-Date: 2025-10-22 09:00+0000\n"
"Last-Translator: Anonymous <[email protected]>\n"
"Language-Team: Spanish <https://weblate.makina-corpus.net/projects/geotrek-admin/common/es/>\n"
Expand Down Expand Up @@ -111,9 +111,6 @@ msgstr ""
msgid "Merge"
msgstr ""

msgid "Action"
msgstr ""

msgid "Insertion date"
msgstr "Fecha de inserción"

Expand Down Expand Up @@ -160,6 +157,9 @@ msgstr ""
msgid "External id"
msgstr ""

msgid "Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
msgstr ""

msgid "Attachment license"
msgstr ""

Expand Down Expand Up @@ -560,6 +560,9 @@ msgstr ""
msgid "User"
msgstr ""

msgid "Action"
msgstr ""

msgid "Full history"
msgstr ""

Expand Down
11 changes: 7 additions & 4 deletions geotrek/common/locale/fr/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-22 09:48+0000\n"
"POT-Creation-Date: 2025-12-15 08:21+0000\n"
"PO-Revision-Date: 2025-10-22 09:00+0000\n"
"Last-Translator: Emmanuelle Helly <[email protected]>\n"
"Language-Team: French <https://weblate.makina-corpus.net/projects/geotrek-admin/common/fr/>\n"
Expand Down Expand Up @@ -110,9 +110,6 @@ msgstr "Le Parc national est un territoire naturel, ouvert à tous, mais soumis
msgid "Merge"
msgstr "Fusionner"

msgid "Action"
msgstr "Action"

msgid "Insertion date"
msgstr "Date d'insertion"

Expand Down Expand Up @@ -159,6 +156,9 @@ msgstr "Fournisseur"
msgid "External id"
msgstr "ID externe"

msgid "Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
msgstr "L’accès est restreint car tous les éléments sélectionnés n’appartiennent pas à votre structure. Utilisez le filtre par structure pour sélectionner uniquement les éléments autorisés."

msgid "Attachment license"
msgstr "Licence pièce-jointes"

Expand Down Expand Up @@ -559,6 +559,9 @@ msgstr "Date"
msgid "User"
msgstr "Utilisateur"

msgid "Action"
msgstr "Action"

msgid "Full history"
msgstr "Historique complet"

Expand Down
11 changes: 7 additions & 4 deletions geotrek/common/locale/it/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-22 09:48+0000\n"
"POT-Creation-Date: 2025-12-15 08:21+0000\n"
"PO-Revision-Date: 2025-10-22 09:00+0000\n"
"Last-Translator: Anonymous <[email protected]>\n"
"Language-Team: Italian <https://weblate.makina-corpus.net/projects/geotrek-admin/common/it/>\n"
Expand Down Expand Up @@ -110,9 +110,6 @@ msgstr ""
msgid "Merge"
msgstr ""

msgid "Action"
msgstr ""

msgid "Insertion date"
msgstr "Data di inserimento"

Expand Down Expand Up @@ -159,6 +156,9 @@ msgstr ""
msgid "External id"
msgstr ""

msgid "Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
msgstr ""

msgid "Attachment license"
msgstr ""

Expand Down Expand Up @@ -559,6 +559,9 @@ msgstr ""
msgid "User"
msgstr ""

msgid "Action"
msgstr ""

msgid "Full history"
msgstr ""

Expand Down
11 changes: 7 additions & 4 deletions geotrek/common/locale/nl/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-22 09:48+0000\n"
"POT-Creation-Date: 2025-12-15 08:21+0000\n"
"PO-Revision-Date: 2025-10-22 09:01+0000\n"
"Last-Translator: Anonymous <[email protected]>\n"
"Language-Team: Dutch <https://weblate.makina-corpus.net/projects/geotrek-admin/common/nl/>\n"
Expand Down Expand Up @@ -110,9 +110,6 @@ msgstr ""
msgid "Merge"
msgstr ""

msgid "Action"
msgstr ""

msgid "Insertion date"
msgstr ""

Expand Down Expand Up @@ -159,6 +156,9 @@ msgstr ""
msgid "External id"
msgstr ""

msgid "Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
msgstr ""

msgid "Attachment license"
msgstr ""

Expand Down Expand Up @@ -559,6 +559,9 @@ msgstr ""
msgid "User"
msgstr ""

msgid "Action"
msgstr ""

msgid "Full history"
msgstr ""

Expand Down
14 changes: 0 additions & 14 deletions geotrek/common/mixins/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,6 @@
from geotrek.common.utils import classproperty, logger


class CheckBoxActionMixin:
@property
def checkbox(self):
return f'<input type="checkbox" name="{self._meta.model_name}[]" value="{self.pk}" />'

@classproperty
def checkbox_verbose_name(cls):
return _("Action")

@property
def checkbox_display(self):
return self.checkbox


class TimeStampedModelMixin(models.Model):
# Computed values (managed at DB-level with triggers)
date_insert = models.DateTimeField(
Expand Down
69 changes: 67 additions & 2 deletions geotrek/common/mixins/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
from io import BytesIO

from django.conf import settings
from django.http import HttpResponse, HttpResponseNotFound
from django.contrib import messages
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.functional import classproperty
from django.utils.translation import gettext_lazy as _
from django.views import static
from mapentity import views as mapentity_views
from mapentity.helpers import suffix_for
from mapentity.helpers import suffix_for, user_has_perm
from pdfimpose.schema.saddle import impose
from pymupdf import Document

Expand Down Expand Up @@ -232,3 +234,66 @@ def get_context_data(self, **kwargs):
obj._meta.get_field(field).verbose_name for field in completeness_fields
]
return context


class BelongStructureMixin:
"""
Check if the selected items are in the same structure than the user, except for super-user
This mixin is for views that handle action on multiple items (ex: MultiDelete, MultiUpdate)
"""

def get(self, request, *args, **kwargs):
# check pks definition first to avoid get_queryset error
response = super().get(request, *args, **kwargs)

if isinstance(response, HttpResponseRedirect):
return response

# check permissions
queryset = self.get_queryset()
user_structure = self.request.user.profile.structure
superuser = self.request.user.is_superuser

filtered_queryset = queryset.filter(structure__exact=user_structure)

if not superuser and filtered_queryset.count() != queryset.count():
messages.warning(
self.request,
_(
"Access is restricted because not all selected items belong to your structure. Use the structure filter to select only authorized items."
),
)
return HttpResponseRedirect(self.get_redirect_url())

return response

def get_editable_fields(self):
superuser = self.request.user.is_superuser
editable_fields = super().get_editable_fields()

if not superuser:
editable_fields.remove("structure")

return editable_fields


class PublishedFieldMixin:
"""
Check if the user can modify "published" field and remove it from the multi update form
This mixin is for MultiUpdate views with a "published" field
"""

def get_editable_fields(self):
publish_permission = (
f"{self.model._meta.app_label}.publish_{self.model._meta.model_name}"
)
editable_fields = super().get_editable_fields()

if not user_has_perm(self.request.user, publish_permission):
editable_fields = [
field
for field in list(editable_fields)
if not field.startswith("published")
]

return editable_fields
Loading