kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			Allow Action controller to trigger a redirect
- Migrate site switcher to use Stimulus approach via w-action - Closes #10035pull/8345/head
							rodzic
							
								
									37192f847b
								
							
						
					
					
						commit
						ed58c692ca
					
				|  | @ -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', | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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/', | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -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); | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -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/', | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -2,19 +2,18 @@ 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): | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Aadi jindal
						Aadi jindal