0
0
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:
Shohan 2021-06-06 13:16:33 +05:30 committed by Matt Westcott
parent 3ef56faac9
commit 46bebde476
10 changed files with 161 additions and 4 deletions

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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>

View File

@ -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>

View File

@ -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 %}

View File

@ -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')),

View File

@ -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']

View 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)

View File

@ -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
)