kopia lustrzana https://github.com/wagtail/wagtail
[feat] Add 'Select all pages in listing' support
rodzic
e524ccb995
commit
403cd5eb29
|
@ -64,6 +64,12 @@ ul.listing {
|
|||
opacity: 0.5;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.num-pages-in-listing {
|
||||
color: $color-teal;
|
||||
text-transform: none;
|
||||
padding: 0 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +101,7 @@ ul.listing {
|
|||
}
|
||||
|
||||
.bulk-actions-choices,
|
||||
.bulk-actions-choices ul {
|
||||
.bulk-actions-choices > ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
/* global wagtailConfig */
|
||||
/* global $ */
|
||||
|
||||
const BULK_ACTION_PAGE_CHECKBOX_INPUT = 'bulk-action-checkbox';
|
||||
const BULK_ACTION_SELECT_ALL_CHECKBOX_TH = 'bulk-actions-filter-checkbox';
|
||||
const BULK_ACTION_FILTERS_CLASS = `${BULK_ACTION_SELECT_ALL_CHECKBOX_TH} .c-dropdown__item a`;
|
||||
const BULK_ACTION_CHOICES_DIV = 'bulk-actions-choices';
|
||||
const BULK_ACTION_NUM_PAGES_SPAN = 'num-pages';
|
||||
const BULK_ACTION_NUM_PAGES_IN_LISTING_SPAN = 'num-pages-in-listing';
|
||||
const BULK_ACTION_NUM_PAGES_IN_LISTING = 'num-pages-in-listing';
|
||||
const TABLE_HEADERS_TR = 'table-headers';
|
||||
let parentPageId;
|
||||
|
||||
const checkedState = {
|
||||
checkedPages: new Set(),
|
||||
numPages: 0,
|
||||
listingPageIds: [],
|
||||
selectAllInListing: false
|
||||
};
|
||||
|
||||
/* Event listener for the `Select All` checkbox */
|
||||
|
@ -25,6 +29,7 @@ function SelectBulkActionsFilter(e) {
|
|||
|
||||
/* Event listener for individual page checkbox */
|
||||
function SelectBulkActionsCheckboxes(e) {
|
||||
if (checkedState.selectAllInListing) checkedState.selectAllInListing = false;
|
||||
const prevLength = checkedState.checkedPages.size;
|
||||
if (e.target.checked) checkedState.checkedPages.add(+e.target.dataset.pageId);
|
||||
else {
|
||||
|
@ -58,36 +63,48 @@ function SelectBulkActionsCheckboxes(e) {
|
|||
|
||||
if (checkedState.checkedPages.size > 0) {
|
||||
/* Update text on number of pages */
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_SPAN}`).textContent =
|
||||
`${checkedState.checkedPages.size === checkedState.numPages ? 'All ' : ''} ${checkedState.checkedPages.size}`;
|
||||
let numPagesSelected = '';
|
||||
if (checkedState.checkedPages.size === checkedState.numPages) {
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_IN_LISTING}`).classList.remove('u-hidden');
|
||||
if (checkedState.numPages === 1) {
|
||||
numPagesSelected = wagtailConfig.STRINGS.NUM_PAGES_SELECTED_SINGULAR;
|
||||
} else {
|
||||
numPagesSelected = wagtailConfig.STRINGS.NUM_PAGES_SELECTED_ALL.replace('{0}', checkedState.checkedPages.size);
|
||||
}
|
||||
} else {
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_IN_LISTING}`).classList.add('u-hidden');
|
||||
if (checkedState.checkedPages.size === 1) {
|
||||
numPagesSelected = wagtailConfig.STRINGS.NUM_PAGES_SELECTED_SINGULAR;
|
||||
} else {
|
||||
numPagesSelected = wagtailConfig.STRINGS.NUM_PAGES_SELECTED_PLURAL.replace(
|
||||
'{0}', checkedState.checkedPages.size
|
||||
);
|
||||
}
|
||||
}
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_SPAN}`).textContent = numPagesSelected;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Gets the value of given name from the query string in url */
|
||||
function getParameterByName(name) {
|
||||
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
|
||||
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
|
||||
/* Updates the content of BULK_ACTION_NUM_PAGES_IN_LISTING_SPAN with the new count of pages */
|
||||
function updateNumPagesInListing(filterQueryString) {
|
||||
// eslint-disable-next-line no-undef
|
||||
$.ajax({
|
||||
url: parentPageId ? `/admin/pages/${parentPageId}/filter-count/` : '/admin/pages/filter-count/',
|
||||
data: { filters: filterQueryString },
|
||||
success: (response) => {
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_IN_LISTING_SPAN}`).textContent = response.count;
|
||||
},
|
||||
});
|
||||
function fetchAllPageIdsInListing(e) {
|
||||
if (checkedState.listingPageIds.length === 0) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
url: '?fetchPageIds=1',
|
||||
success: (response) => {
|
||||
checkedState.listingPageIds = response.page_ids;
|
||||
},
|
||||
});
|
||||
}
|
||||
checkedState.selectAllInListing = true;
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_SPAN}`).
|
||||
textContent = wagtailConfig.STRINGS.NUM_PAGES_SELECTED_ALL_IN_LISTING;
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_IN_LISTING}`).classList.add('u-hidden');
|
||||
}
|
||||
|
||||
/* Event listener for filter dropdown options */
|
||||
function FilterEventListener(e) {
|
||||
e.preventDefault();
|
||||
const filter = e.target.dataset.filter || '';
|
||||
updateNumPagesInListing(filter);
|
||||
const changeEvent = new Event('change');
|
||||
if (filter.length) {
|
||||
/* split the filter string into [key,value] pairs and check for the values in the
|
||||
|
@ -121,7 +138,7 @@ function BulkActionEventListeners(e) {
|
|||
e.preventDefault();
|
||||
const url = e.target.getAttribute('href');
|
||||
let queryString = '';
|
||||
checkedState.checkedPages.forEach(pageId => {
|
||||
(checkedState.selectAllInListing ? checkedState.listingPageIds : checkedState.checkedPages).forEach(pageId => {
|
||||
queryString += `&id=${pageId}`;
|
||||
});
|
||||
window.location.href = url + queryString;
|
||||
|
@ -129,7 +146,7 @@ function BulkActionEventListeners(e) {
|
|||
|
||||
|
||||
/* Adds all event listeners */
|
||||
(function AddBulkActionEventListeners() {
|
||||
function addBulkActionListeners() {
|
||||
document.querySelectorAll(`.${BULK_ACTION_PAGE_CHECKBOX_INPUT}`)
|
||||
.forEach(el => {
|
||||
checkedState.numPages++;
|
||||
|
@ -142,6 +159,7 @@ function BulkActionEventListeners(e) {
|
|||
document.querySelectorAll(`.${BULK_ACTION_CHOICES_DIV} > ul > li > a`).forEach(
|
||||
elem => elem.addEventListener('click', BulkActionEventListeners)
|
||||
);
|
||||
parentPageId = document.querySelector(`.${BULK_ACTION_SELECT_ALL_CHECKBOX_TH}`).dataset.parentId;
|
||||
updateNumPagesInListing(getParameterByName('filters'));
|
||||
})()
|
||||
document.querySelector(`.${BULK_ACTION_NUM_PAGES_IN_LISTING}`).addEventListener('click', fetchAllPageIdsInListing);
|
||||
}
|
||||
|
||||
addBulkActionListeners();
|
||||
|
|
|
@ -107,6 +107,11 @@ def get_js_translation_strings():
|
|||
# counting from -1 and use modulo 7 to get an array index
|
||||
'WEEKDAYS': [str(WEEKDAYS[d % 7]) for d in range(-1, 6)],
|
||||
'WEEKDAYS_SHORT': [str(WEEKDAYS_ABBR[d % 7]) for d in range(-1, 6)],
|
||||
|
||||
'NUM_PAGES_SELECTED_SINGULAR': _('1 page selected'),
|
||||
'NUM_PAGES_SELECTED_PLURAL': _("{0} pages selected"),
|
||||
'NUM_PAGES_SELECTED_ALL': _("All {0} pages on this screen selected"),
|
||||
'NUM_PAGES_SELECTED_ALL_IN_LISTING': _("All pages in listing selected"),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,13 +37,8 @@ ordering: the current sort parameter
|
|||
<input type="checkbox" aria-label="Bulk action checkbox" />
|
||||
{% bulk_action_filters %}
|
||||
<div class="bulk-actions-choices u-hidden">
|
||||
<span>
|
||||
{% blocktrans count counter=pages|length %}
|
||||
<span class="num-pages">1 page</span> on this page selected. Select all <span class="num-pages-in-listing">0</span> in listing |
|
||||
{% plural %}
|
||||
<span class="num-pages">All {{counter}} pages</span> on this page selected. Select all <span class="num-pages-in-listing">0</span> in listing |
|
||||
{% endblocktrans %}
|
||||
</span>
|
||||
<span class="num-pages"></span>
|
||||
<a class="num-pages-in-listing u-hidden" href='#'>{{ select_all_page_text }}</a>
|
||||
<ul>{% page_bulk_action_choices %}</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,6 @@ from abc import ABC, abstractproperty
|
|||
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_list_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.views.generic.base import TemplateView
|
||||
|
||||
from wagtail.admin import messages
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
from django.conf import settings
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Count
|
||||
from django.http.response import JsonResponse
|
||||
from django.shortcuts import 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.auth import user_has_any_page_permission, user_passes_test
|
||||
from wagtail.admin.navigation import get_explorable_root_page
|
||||
|
@ -39,6 +41,12 @@ def index(request, parent_page_id=None):
|
|||
& user_perms.explorable_pages()
|
||||
)
|
||||
|
||||
fetch_page_ids = request.GET.get('fetchPageIds', '0')
|
||||
if fetch_page_ids == '1':
|
||||
return JsonResponse({
|
||||
'page_ids': list(pages.values_list('id', flat=True))
|
||||
})
|
||||
|
||||
# Get page ordering
|
||||
ordering = request.GET.get('ordering', '-latest_revision_created_at')
|
||||
if ordering not in [
|
||||
|
@ -103,7 +111,8 @@ def index(request, parent_page_id=None):
|
|||
'do_paginate': do_paginate,
|
||||
'locale': None,
|
||||
'translations': [],
|
||||
'show_ordering_column': 'ordering' in request.GET.dict()
|
||||
'show_ordering_column': 'ordering' in request.GET.dict(),
|
||||
'select_all_page_text': _("Select all pages in listing")
|
||||
}
|
||||
|
||||
if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and not parent_page.is_root():
|
||||
|
|
Ładowanie…
Reference in New Issue