Allow Action controller to trigger a redirect

- Migrate site switcher to use Stimulus approach via w-action
- Closes #10035
pull/8345/head
Aadi jindal 2023-02-07 09:11:01 +05:30 zatwierdzone przez LB (Ben Johnston)
rodzic 37192f847b
commit ed58c692ca
8 zmienionych plików z 104 dodań i 28 usunięć

Wyświetl plik

@ -151,7 +151,6 @@ module.exports = {
'docs/_static/**',
'wagtail/contrib/modeladmin/static_src/wagtailmodeladmin/js/prepopulate.js',
'wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js',
'wagtail/contrib/settings/static_src/wagtailsettings/js/site-switcher.js',
'wagtail/documents/static_src/wagtaildocs/js/add-multiple.js',
'wagtail/embeds/static_src/wagtailembeds/js/embed-chooser-modal.js',
'wagtail/images/static_src/wagtailimages/js/add-multiple.js',

Wyświetl plik

@ -115,6 +115,7 @@ Changelog
* Maintenance: Migrate initDismissibles behaviour to a Stimulus controller `w-disimissible` (Loveth Omokaro)
* Maintenance: Replace jQuery autosize v3 with Stimulus `w-autosize` controller using autosize npm package v6 (Suyash Srivastava)
* Maintenance: Update `w-action` controller to support a click method (Suyash Srivastava)
* Maintenance: Migrate the site settings switcher select from jQuery to a refined version of the `w-action` controller usage (Aadi jindal, LB (Ben) Johnston)
4.2.2 (03.04.2023)

Wyświetl plik

@ -3,9 +3,23 @@ import { ActionController } from './ActionController';
describe('ActionController', () => {
let app;
const oldWindowLocation = window.location;
beforeAll(() => {
delete window.location;
window.location = Object.defineProperties(
{},
{
...Object.getOwnPropertyDescriptors(oldWindowLocation),
assign: { configurable: true, value: jest.fn() },
},
);
});
afterEach(() => {
app?.stop();
jest.clearAllMocks();
});
describe('post method', () => {
@ -70,4 +84,62 @@ describe('ActionController', () => {
expect(clickMock).toHaveBeenCalled();
});
});
describe('redirect method', () => {
beforeEach(() => {
document.body.innerHTML = `
<select name="url" data-controller="w-action" data-action="change->w-action#redirect">
<option value="http://localhost/place?option=1">1</option>
<option value="http://localhost/place?option=2" selected>2</option>
</select>
`;
app = Application.start();
app.register('w-action', ActionController);
});
it('should have a redirect method that falls back to any element value', () => {
const select = document.querySelector('select');
expect(window.location.href).toEqual('http://localhost/');
expect(window.location.assign).not.toHaveBeenCalled();
select.dispatchEvent(new CustomEvent('change'));
expect(window.location.assign).toHaveBeenCalledWith(
'http://localhost/place?option=2',
);
});
it('should allow redirection via the custom event detail', () => {
const select = document.querySelector('select');
expect(window.location.href).toEqual('http://localhost/');
expect(window.location.assign).not.toHaveBeenCalled();
select.dispatchEvent(
new CustomEvent('change', { detail: { url: '/its/in/the/detail/' } }),
);
expect(window.location.assign).toHaveBeenCalledWith(
'/its/in/the/detail/',
);
});
it('should allow redirection via the Stimulus param approach', () => {
const select = document.querySelector('select');
expect(window.location.href).toEqual('http://localhost/');
expect(window.location.assign).not.toHaveBeenCalled();
select.dataset.wActionUrlParam = '/check/out/the/param/';
select.dispatchEvent(
new CustomEvent('change', { detail: { url: '/its/in/the/detail/' } }),
);
expect(window.location.assign).toHaveBeenCalledWith(
'/check/out/the/param/',
);
});
});
});

Wyświetl plik

@ -25,6 +25,15 @@ import { WAGTAIL_CONFIG } from '../config/wagtailConfig';
* >
* Enable
* </button>
*
* @example - triggering a dynamic redirect
* // note: a link is preferred normally
* <form>
* <select name="url" data-controller="w-action" data-action="change->w-action#redirect">
* <option value="/path/to/1">1</option>
* <option value="/path/to/2">2</option>
* </select>
* </form>
*/
export class ActionController extends Controller<
HTMLButtonElement | HTMLInputElement
@ -70,4 +79,16 @@ export class ActionController extends Controller<
document.body.appendChild(formElement);
formElement.submit();
}
/**
* Trigger a redirect based on the custom event's detail, the Stimulus param
* or finally check the controlled element for a value to use.
*/
redirect(
event: CustomEvent<{ url?: string }> & { params?: { url?: string } },
) {
const url = event?.params?.url || event?.detail?.url || this.element.value;
if (!url) return;
window.location.assign(url);
}
}

Wyświetl plik

@ -186,11 +186,6 @@ module.exports = function exports(env, argv) {
to: 'wagtail/users/static/',
globOptions: { ignore: ['**/{app,scss}/**', '*.{css,txt}'] },
},
{
from: 'wagtail/contrib/settings/static_src/',
to: 'wagtail/contrib/settings/static/',
globOptions: { ignore: ['**/{app,scss}/**', '*.{css,txt}'] },
},
{
from: 'wagtail/contrib/modeladmin/static_src/',
to: 'wagtail/contrib/modeladmin/static/',

Wyświetl plik

@ -162,6 +162,7 @@ Those improvements were implemented by Albina Starykova as part of an [Outreachy
* Migrate initDismissibles behaviour to a Stimulus controller `w-disimissible` (Loveth Omokaro)
* Replace jQuery autosize v3 with Stimulus `w-autosize` controller using autosize npm package v6 (Suyash Srivastava)
* Update `w-action` controller to support a click method (Suyash Srivastava)
* Migrate the site settings switcher select from jQuery to a refined version of the `w-action` controller usage (Aadi jindal, LB (Ben) Johnston)
## Upgrade considerations

Wyświetl plik

@ -2,20 +2,19 @@ from django import forms
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from wagtail.admin.staticfiles import versioned_static
from wagtail.models import Site
class SiteSwitchForm(forms.Form):
site = forms.ChoiceField(choices=[])
@property
def media(self):
return forms.Media(
js=[
versioned_static("wagtailsettings/js/site-switcher.js"),
]
)
site = forms.ChoiceField(
choices=[],
widget=forms.Select(
attrs={
"data-controller": "w-action",
"data-action": "change->w-action#redirect",
}
),
)
def __init__(self, current_site, model, **kwargs):
initial_data = {"site": self.get_change_url(current_site, model)}

Wyświetl plik

@ -1,12 +0,0 @@
$(function () {
var $switcher = $('form#settings-site-switch select');
if (!$switcher.length) return;
var initial = $switcher.val();
$switcher.on('change', function () {
var url = $switcher.val();
if (url !== initial) {
window.location = url;
}
});
});