mirror of
https://github.com/wagtail/wagtail.git
synced 2024-12-01 11:41:20 +01:00
[feat] Add bulk action for move
This commit is contained in:
parent
3ef56faac9
commit
46bebde476
@ -0,0 +1,20 @@
|
||||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n wagtailadmin_tags %}
|
||||
{% block titletag %}{% blocktrans with title=page_to_move.specific_deferred.get_admin_display_title %}Select a new parent page for {{ title }}{% endblocktrans %}{% endblock %}
|
||||
{% block content %}
|
||||
<header class="nice-padding">
|
||||
<h1>
|
||||
{% icon name="doc-empty-inverse" class_name="header-title-icon" %}
|
||||
{% blocktrans count counter=num_pages %}
|
||||
Select a new parent page for <span>1 page</span>
|
||||
{% plural %}
|
||||
Select a new parent page for <span>{{ counter }} pages</span>
|
||||
{% endblocktrans %}
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
<div class="nice-padding">
|
||||
{% include "wagtailadmin/pages/listing/_list_move.html" with pages=child_pages parent_page=viewed_page %}
|
||||
{% paginate child_pages base_url=pagination_base_url %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -0,0 +1,22 @@
|
||||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block titletag %}{% blocktrans count counter=num_pages %}Move 1 page{% plural %}Move {{ counter }} pages {% endblocktrans %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% trans "Move" as move_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=move_str icon="doc-empty-inverse" %}
|
||||
<div class="nice-padding">
|
||||
{% for page_to_move in pages_to_move %}
|
||||
{% if page_to_move.is_leaf %}
|
||||
<p>{% blocktrans with title=destination.get_admin_display_title subtitle=page_to_move.get_admin_display_title %}Are you sure you want to move the page {{subtitle}} into '{{ title }}'?{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
<p>{% blocktrans with title=destination.get_admin_display_title subtitle=page_to_move.get_admin_display_title %}Are you sure you want to move the page {{subtitle}} and all of its children into '{{ title }}'?{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<form action="{{ submit_url }}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{% trans 'Yes, move these pages' %}" class="button">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
@ -18,6 +18,7 @@
|
||||
{% if parent_page %}
|
||||
{% page_permissions parent_page as parent_page_perms %}
|
||||
<tr class="index {% if not parent_page.live %} unpublished{% endif %} {% block parent_page_row_classname %}{% endblock %}">
|
||||
{% if is_moving %}<td></td>{% endif %}
|
||||
<td class="title" {% if show_ordering_column %}colspan="2"{% endif %}>
|
||||
{% block parent_page_title %}
|
||||
{% endblock %}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
{% block pre_parent_page_headers %}
|
||||
<tr class="table-headers">
|
||||
<th></th>
|
||||
<th class="title">Title</th>
|
||||
{% if show_parent %}
|
||||
<th class="parent">{% trans 'Parent' %}</th>
|
||||
|
@ -6,6 +6,6 @@ Navigation controls for the page listing in 'move' mode
|
||||
|
||||
<td class="{% if page.can_descend %}children{% endif %}">
|
||||
{% if page.can_descend %}
|
||||
<a href="{% url 'wagtailadmin_pages:move_choose_destination' page_to_move.id page.id %}" class="icon text-replace icon-arrow-right navigate-pages" title="{% blocktrans with title=page.get_admin_display_title %}Explore subpages of '{{ title }}'{% endblocktrans %}">{% trans 'Explore' %}</a>
|
||||
<a href="{% if page_to_move %}{% url 'wagtailadmin_pages:move_choose_destination' page_to_move.id page.id %}{% else %}{% url 'wagtailadmin_bulk_move' parent_page_id page.id %}{{page_ids}}{% endif %}" class="icon text-replace icon-arrow-right navigate-pages" title="{% blocktrans with title=page.get_admin_display_title %}Explore subpages of '{{ title }}'{% endblocktrans %}">{% trans 'Explore' %}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
@ -6,7 +6,7 @@ Expects a variable 'page', the page instance.
|
||||
|
||||
<div class="title-wrapper">
|
||||
{% if page.can_choose %}
|
||||
<a href="{% url 'wagtailadmin_pages:move_confirm' page_to_move.id page.id %}">{{ page.specific.get_admin_display_title }}{% block pages_listing_link_title_extra %}{% endblock pages_listing_link_title_extra %}</a>
|
||||
<a href="{% if page_to_move %}{% url 'wagtailadmin_pages:move_confirm' page_to_move.id page.id %}{% else %}{% url 'wagtailadmin_bulk_move_confirm' parent_page_id page.id %}{{page_ids}}{% endif %}">{{ page.specific.get_admin_display_title }}{% block pages_listing_link_title_extra %}{% endblock pages_listing_link_title_extra %}</a>
|
||||
{% else %}
|
||||
{{ page.get_admin_display_title }}{% block pages_listing_title_extra %}{% endblock pages_listing_title_extra %}
|
||||
{% endif %}
|
||||
|
@ -40,6 +40,9 @@ urlpatterns = [
|
||||
path('pages/<int:parent_page_id>/multiple/delete/', bulk_actions.delete, name='wagtailadmin_bulk_delete'),
|
||||
path('pages/<int:parent_page_id>/multiple/unpublish/', bulk_actions.unpublish, name='wagtailadmin_bulk_unpublish'),
|
||||
path('pages/<int:parent_page_id>/multiple/publish/', bulk_actions.publish, name='wagtailadmin_bulk_publish'),
|
||||
path('pages/<int:parent_page_id>/multiple/move/', bulk_actions.move, name='wagtailadmin_bulk_move'),
|
||||
path('pages/<int:parent_page_id>/multiple/move/<int:dest_page_id>/', bulk_actions.move, name='wagtailadmin_bulk_move'),
|
||||
path('pages/<int:parent_page_id>/multiple/move/<int:dest_page_id>/confirm/', bulk_actions.move_confirm, name='wagtailadmin_bulk_move_confirm'),
|
||||
|
||||
path('pages/', include(wagtailadmin_pages_urls, namespace='wagtailadmin_pages')),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
from .delete import delete
|
||||
from .move import move, move_confirm
|
||||
from .publish import publish
|
||||
from .unpublish import unpublish
|
||||
|
||||
|
||||
__all__ = ['delete', 'publish', 'unpublish']
|
||||
__all__ = ['delete', 'move', 'move_confirm', 'publish', 'unpublish']
|
||||
|
109
wagtail/admin/views/bulk_actions/move.py
Normal file
109
wagtail/admin/views/bulk_actions/move.py
Normal file
@ -0,0 +1,109 @@
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.paginator import Paginator
|
||||
from django.shortcuts import get_list_or_404, get_object_or_404, redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from wagtail.admin import messages
|
||||
from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
|
||||
from wagtail.core import hooks
|
||||
from wagtail.core.models import Page
|
||||
|
||||
|
||||
def move(request, parent_page_id, dest_page_id=None):
|
||||
next_url = get_valid_next_url_from_request(request)
|
||||
if not next_url:
|
||||
next_url = reverse('wagtailadmin_explore', args=[parent_page_id])
|
||||
|
||||
page_ids = list(map(int, request.GET.getlist('id')))
|
||||
child_pages = set()
|
||||
if dest_page_id:
|
||||
viewed_page = get_object_or_404(Page, id=dest_page_id)
|
||||
else:
|
||||
viewed_page = Page.get_first_root_node()
|
||||
|
||||
for _page in get_list_or_404(Page, id__in=page_ids):
|
||||
page_to_move = _page.specific
|
||||
page_perms = page_to_move.permissions_for_user(request.user)
|
||||
if not page_perms.can_move():
|
||||
raise PermissionDenied
|
||||
viewed_page.can_choose = page_perms.can_move_to(viewed_page)
|
||||
for target in viewed_page.get_children():
|
||||
target.can_choose = page_perms.can_move_to(target)
|
||||
|
||||
target.can_descend = (
|
||||
not(target == page_to_move
|
||||
or target.is_child_of(page_to_move))
|
||||
and target.get_children_count()
|
||||
)
|
||||
|
||||
child_pages.add(target)
|
||||
|
||||
child_pages = list(child_pages)
|
||||
paginator = Paginator(child_pages, per_page=50)
|
||||
child_pages = paginator.get_page(request.GET.get('p'))
|
||||
print(len(child_pages))
|
||||
|
||||
if request.method == 'GET':
|
||||
args = [parent_page_id]
|
||||
if dest_page_id:
|
||||
args.append(dest_page_id)
|
||||
return TemplateResponse(request, 'wagtailadmin/pages/bulk_actions/bulk_move_choose_destination.html', {
|
||||
'num_pages': len(page_ids),
|
||||
'viewed_page': viewed_page,
|
||||
'child_pages': child_pages,
|
||||
'parent_page_id': parent_page_id,
|
||||
'page_ids': '?id=' + '&id='.join(request.GET.getlist('id')),
|
||||
'is_moving': True
|
||||
})
|
||||
|
||||
|
||||
def move_confirm(request, parent_page_id, dest_page_id):
|
||||
next_url = get_valid_next_url_from_request(request)
|
||||
if not next_url:
|
||||
next_url = reverse('wagtailadmin_explore', args=[parent_page_id])
|
||||
|
||||
destination = get_object_or_404(Page, id=dest_page_id).specific_deferred
|
||||
|
||||
page_ids = list(map(int, request.GET.getlist('id')))
|
||||
pages_to_move = []
|
||||
for _page in get_list_or_404(Page, id__in=page_ids):
|
||||
page_to_move = _page.specific
|
||||
page_perms = page_to_move.permissions_for_user(request.user)
|
||||
if not page_perms.can_move():
|
||||
raise PermissionDenied
|
||||
if not page_perms.can_move_to(destination):
|
||||
raise PermissionDenied
|
||||
if not Page._slug_is_available(page_to_move.slug, destination, page=page_to_move):
|
||||
messages.error(
|
||||
request,
|
||||
_("The slug '{0}' is already in use at the selected parent page. Make sure the slug is unique and try again").format(page_to_move.slug)
|
||||
)
|
||||
return redirect('wagtailadmin_pages:move_choose_destination', page_to_move.id, dest_page_id)
|
||||
for fn in hooks.get_hooks('before_move_page'):
|
||||
result = fn(request, page_to_move, destination)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
pages_to_move.append(page_to_move)
|
||||
|
||||
if request.method == 'GET':
|
||||
return TemplateResponse(request, 'wagtailadmin/pages/bulk_actions/confirm_bulk_move.html', {
|
||||
'num_pages': len(page_ids),
|
||||
'pages_to_move': pages_to_move,
|
||||
'destination': destination,
|
||||
'submit_url': reverse('wagtailadmin_bulk_move_confirm', args=[parent_page_id, dest_page_id])
|
||||
+ '?' + urlencode([('id', page_id) for page_id in page_ids]),
|
||||
})
|
||||
else:
|
||||
for page_to_move in pages_to_move:
|
||||
page_to_move.move(destination, pos='last-child', user=request.user)
|
||||
|
||||
for fn in hooks.get_hooks('after_move_page'):
|
||||
result = fn(request, page_to_move)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
messages.success(request, _(f"{len(page_ids)} pages moved."))
|
||||
return redirect(next_url)
|
@ -189,7 +189,7 @@ def bulk_action_choices(page, is_parent=False, next_url=None):
|
||||
if page:
|
||||
yield PageListingButton(
|
||||
_('Move'),
|
||||
reverse('wagtailadmin_bulk_delete', args=[page.id]) + '?' + urlencode({'next': next_url}),
|
||||
reverse('wagtailadmin_bulk_move', args=[page.id]) + '?' + urlencode({'next': next_url}),
|
||||
attrs={'aria-label': _("Move pages")},
|
||||
priority=10
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user