wagtail icon indicating copy to clipboard operation
wagtail copied to clipboard

Migrate `preview-panel.js` to Stimulus `PreviewController`

Open laymonage opened this issue 2 years ago • 12 comments

I've been playing around with Stimulus by refactoring the preview panel and I must say I quite enjoyed it! I think Stimulus fits nicely with our JavaScript use case in the front-end.

~~Fixes #9360 and adds some more optimisation by debouncing the update. It's still in draft as I have yet to write tests and do more testing.~~

Fixes #11677.

After more than a year, it's now ready for review!

Please check the following:

  • [x] Do the tests still pass?[^1]
  • [x] Does the code comply with the style guide?
    • [x] Run make lint from the Wagtail root.
  • [x] For Python changes: Have you added tests to cover the new/fixed behaviour?
  • [ ] For front-end changes: Did you test on all of Wagtail’s supported environments?[^2]
    • [ ] Please list the exact browser and operating system versions you tested:
    • [ ] Please list which assistive technologies [^3] you tested:
  • [ ] For new features: Has the documentation been updated accordingly?

Please describe additional details for testing this change.

[^1]: Development Testing [^2]: Browser and device support [^3]: Accessibility Target

laymonage avatar Apr 19 '23 07:04 laymonage

Thanks for the comments @lb-, I believe I've addressed those. I think this is only missing unit tests before it's ready for review, will try to write them over the week.

laymonage avatar Jul 31 '23 16:07 laymonage

Thanks @laymonage - happy to do a full review when ready.

lb- avatar Jul 31 '23 21:07 lb-

@laymonage I needed the Promise handling of the debounce for a different PR so brought it over (hope that's ok), also refined types and added a full unit test suite.

I have adjusted the behaviour for the wait arg so if it's a non-number it will immediately run the code, this is super useful for a pattern where a Stimulus value may set a delay/wait but if it does not we just want the code to run straight away.

https://github.com/wagtail/wagtail/pull/10835

lb- avatar Aug 27 '23 10:08 lb-

No worries @lb-, thanks for making the debounce function feature-complete. I've reviewed that PR and will rebase this and drop the debounce commit once that's merged.

laymonage avatar Sep 12 '23 16:09 laymonage

For this, would it be possible to also put in place a deprecation of the globals?

WAGTAIL_CONFIG.WAGTAIL_AUTO_UPDATE_PREVIEW_INTERVAL and WAGTAIL_CONFIG.WAGTAIL_AUTO_UPDATE_PREVIEW.

Instead, we set these as data attributes within the HTML from the Django settings and avoid reading from the global.

See https://github.com/wagtail/wagtail/issues/9771#issuecomment-1780617295 for context.

Also, @laymonage would you like me to pick this one up also, rebase and finalise unit tests?

lb- avatar Oct 26 '23 08:10 lb-

Update on above - https://github.com/wagtail/wagtail/pull/11166 now includes the movement of the WAGTAIL_CONFIG.WAGTAIL_AUTO_UPDATE_PREVIEW_INTERVAL and WAGTAIL_CONFIG.WAGTAIL_AUTO_UPDATE_PREVIEW configs.

lb- avatar Nov 28 '23 09:11 lb-

Just rebased as-is for the most part, still need to add tests and make additional tweaks now that we have additional code for the checks side panel. No need to review yet.

laymonage avatar Feb 12 '24 18:02 laymonage

I rely somewhat on the previewpanel - will the way of sending form data to the preview page to update the preview still be available?

Also wondering about these queryselectors...

    const previewSidePanel = document.querySelector(
        '[data-side-panel="preview"]',
    );
    const previewPanel = previewSidePanel.querySelector('[data-preview-panel]');
    const iFrameWrapper = previewSidePanel.querySelector('.preview-panel__wrapper');
    const iFrameObserverFn = function(mutationsList, observer) {
          // do my thing after iframe is updated (thus previewable instance has been updated)
    };
    iFrameObserver.observe(iFrameWrapper, {childList: true});

Nigel2392 avatar Feb 21 '24 21:02 Nigel2392

@Nigel2392 yeah the server-side interactions won't change in this PR, the client still sends the form data to the preview URL and reloads the iframe if the server response says the data is valid. The data-preview-panel attribute will be removed in favour of data-controller="w-preview".

If what you want is just to detect when the iframe is replaced, I'll likely dispatch some events from the controller so that you can listen to them when the preview panel is doing its things e.g. sending the form data, reloading the iframe, and finished loading the iframe. So instead of using a mutation observer, you can just do something like

previewPanel = document.querySelector('[data-controller="w-preview"]');
previewPanel.addEventListener('w-preview:loaded', (event) => {
  // do your thing
});

laymonage avatar Feb 21 '24 22:02 laymonage

Manage this branch in Squash

Test this branch here: https://preview-panel-controller-ikr1l.squash.io

squash-labs[bot] avatar Jul 23 '24 16:07 squash-labs[bot]