Skip to content

Commit cf0d4c2

Browse files
committed
fix #397: Django popup when using list action
fix #397: Django popup when using list action
1 parent 3d23456 commit cf0d4c2

File tree

7 files changed

+66
-7
lines changed

7 files changed

+66
-7
lines changed

.github/workflows/publish.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,17 @@ jobs:
3434
run: |
3535
npm run build
3636
npm run build -- --debug
37-
- name: Patch templates
37+
- name: Patch Django templates and JavaScript files
3838
run: |
39+
mkdir -p adminsortable2/static/adminsortable2/js
3940
mkdir -p adminsortable2/templates/adminsortable2/edit_inline
40-
DJANGO_VERSIONS=("4.2" "5.0" "5.1" "5.2")
41+
DJANGO_VERSIONS=("4.2" "5.0" "5.1" "5.2" "6.0")
4142
for django_version in ${DJANGO_VERSIONS[@]}; do
4243
echo $django_version
44+
curl --silent --output adminsortable2/static/adminsortable2/js/actions-$django_version.js https://raw.githubusercontent.com/django/django/stable/$django_version.x/django/contrib/admin/static/admin/js/actions.js
4345
curl --silent --output adminsortable2/templates/adminsortable2/edit_inline/stacked-django-$django_version.html https://raw.githubusercontent.com/django/django/stable/$django_version.x/django/contrib/admin/templates/admin/edit_inline/stacked.html
4446
curl --silent --output adminsortable2/templates/adminsortable2/edit_inline/tabular-django-$django_version.html https://raw.githubusercontent.com/django/django/stable/$django_version.x/django/contrib/admin/templates/admin/edit_inline/tabular.html
47+
patch -p0 adminsortable2/static/adminsortable2/js/actions-$django_version.js patches/actions-django-5.2.patch
4548
patch -p0 adminsortable2/templates/adminsortable2/edit_inline/stacked-django-$django_version.html patches/stacked-django-4.0.patch
4649
patch -p0 adminsortable2/templates/adminsortable2/edit_inline/tabular-django-$django_version.html patches/tabular-django-4.0.patch
4750
done

.github/workflows/tests.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,17 @@ jobs:
6060
- name: Build Client
6161
run: |
6262
npm run build
63-
- name: Patch templates
63+
- name: Patch Django templates and JavaScript files
6464
run: |
65+
mkdir -p adminsortable2/static/adminsortable2/js
6566
mkdir -p adminsortable2/templates/adminsortable2/edit_inline
66-
DJANGO_VERSIONS=("4.2" "5.0" "5.1" "5.2")
67+
DJANGO_VERSIONS=("4.2" "5.0" "5.1" "5.2" "6.0")
6768
for django_version in ${DJANGO_VERSIONS[@]}; do
6869
echo $django_version
70+
curl --silent --output adminsortable2/static/adminsortable2/js/actions-$django_version.js https://raw.githubusercontent.com/django/django/stable/$django_version.x/django/contrib/admin/static/admin/js/actions.js
6971
curl --silent --output adminsortable2/templates/adminsortable2/edit_inline/stacked-django-$django_version.html https://raw.githubusercontent.com/django/django/stable/$django_version.x/django/contrib/admin/templates/admin/edit_inline/stacked.html
7072
curl --silent --output adminsortable2/templates/adminsortable2/edit_inline/tabular-django-$django_version.html https://raw.githubusercontent.com/django/django/stable/$django_version.x/django/contrib/admin/templates/admin/edit_inline/tabular.html
73+
patch -p0 adminsortable2/static/adminsortable2/js/actions-$django_version.js patches/actions-django-5.2.patch
7174
patch -p0 adminsortable2/templates/adminsortable2/edit_inline/stacked-django-$django_version.html patches/stacked-django-4.0.patch
7275
patch -p0 adminsortable2/templates/adminsortable2/edit_inline/tabular-django-$django_version.html patches/tabular-django-4.0.patch
7376
done

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ dist
1818
node_modules/
1919
workdir/*
2020
htmlcov
21+
adminsortable2/static/adminsortable2/js/actions-*
2122
adminsortable2/static/adminsortable2/js/adminsortable2.*
2223
adminsortable2/templates/adminsortable2/edit_inline

adminsortable2/admin.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,16 @@ class MovePageActionForm(admin.helpers.ActionForm):
8181
class SortableAdminBase:
8282
@property
8383
def media(self):
84-
css = {'all': ['adminsortable2/css/sortable.css']}
85-
js = ['adminsortable2/js/adminsortable2{}.js'.format('' if settings.DEBUG else '.min')]
86-
return super().media + widgets.Media(css=css, js=js)
84+
media = super().media
85+
css = dict(media._css)
86+
css.setdefault('all', [])
87+
css['all'].append('adminsortable2/css/sortable.css')
88+
js = list(media._js)
89+
# replace actions.js with our patched version until https://code.djangoproject.com/ticket/36757 is fixed
90+
if 'admin/js/actions.js' in js:
91+
js[js.index('admin/js/actions.js')] = 'adminsortable2/js/actions-{0}.{1}.js'.format(*DJANGO_VERSION)
92+
js.append('adminsortable2/js/adminsortable2{}.js'.format('' if settings.DEBUG else '.min'))
93+
return widgets.Media(css=css, js=js)
8794

8895
def get_formset_kwargs(self, request, obj, inline, prefix):
8996
formset_params = super().get_formset_kwargs(request, obj, inline, prefix)

client/admin-sortable2.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ class ListSortable {
4848
this.firstOrder = parseInt(firstOrder);
4949
this.orderDirection = parseInt(lastOrder) > this.firstOrder ? 1 : -1;
5050
}
51+
this.tableBody.classList.add('ignore-list-changes');
5152
}
5253

5354
private async onEnd(evt: SortableEvent) {
55+
this.tableBody.classList.remove('ignore-list-changes');
5456
if (typeof evt.newIndex !== 'number' || typeof evt.oldIndex !== 'number'
5557
|| typeof this.firstOrder !== 'number'|| typeof this.orderDirection !== 'number'
5658
|| !(evt.item instanceof HTMLTableRowElement))

patches/actions-django-5.2.patch

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- django/contrib/admin/static/admin/js/actions.js
2+
+++ adminsortable2/static/adminsortable2/js/actions.js
3+
@@ -151,7 +151,7 @@
4+
updateCounter(actionCheckboxes, options);
5+
lastChecked = target;
6+
} else {
7+
- list_editable_changed = true;
8+
+ list_editable_changed = !target.classList.contains('ignore-list-changes');
9+
}
10+
});
11+
});

testapp/test_e2e_sortable.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import pytest
22
from time import sleep
33

4+
from django.urls import resolve
5+
46
from testapp.models import Book
57

68

@@ -219,3 +221,33 @@ def test_move_next_page(adminpage, slug, p, o, direction):
219221
assert book.my_order == 25 + index
220222
else:
221223
assert book.my_order == Book.objects.count() - 24 - index
224+
225+
226+
@pytest.mark.parametrize('slug, p, o', slugs)
227+
def test_drag_then_delete(adminpage, slug, p, o, direction, update_url):
228+
if o == 2:
229+
return
230+
table_locator = adminpage.locator('table#result_list')
231+
drag_handle = table_locator.locator('tbody tr:nth-child(9) div.drag.handle')
232+
with adminpage.expect_response(update_url) as response_info:
233+
drag_handle.drag_to(table_locator.locator('tbody tr:nth-child(3)'))
234+
while not (response := response_info.value):
235+
sleep(0.1)
236+
assert response.ok
237+
table_row = table_locator.locator('tbody tr:nth-child(2)')
238+
action_checkbox = table_row.locator('td.action-checkbox input[type="checkbox"]')
239+
detail_anchor = table_row.locator('th.field-title a[href]')
240+
change_url = detail_anchor.get_attribute('href')
241+
if '?' in change_url:
242+
change_url = change_url[:change_url.index('?')]
243+
book = Book.objects.get(id=resolve(change_url).kwargs['object_id'])
244+
action_checkbox.click()
245+
action_select = adminpage.locator('#changelist-form select[name="action"]')
246+
action_select.select_option('delete_selected')
247+
with adminpage.expect_response(adminpage.url) as response_info:
248+
adminpage.locator('#changelist-form button[name="index"]').click()
249+
assert response_info.value.ok
250+
html_response = response_info.value.text()
251+
assert f'<a href="{change_url}">{book.title}</a>' in html_response
252+
for chapter in book.chapter_set.all():
253+
assert f'<li>Chapter: {chapter}</li>' in html_response

0 commit comments

Comments
 (0)