mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Fix repeated Turbo dialog streams
Repeated streams reopened a detached template dialog instead of the existing DOM dialog.
This commit is contained in:
+8
@@ -114,6 +114,12 @@ describe('AttributeHelpTextModalService', () => {
|
||||
});
|
||||
|
||||
it('should handle Turbo Stream dialog response and update dialog', async () => {
|
||||
const showModalSpy = vi.spyOn(HTMLDialogElement.prototype, 'showModal') as unknown as Mock<() => void>;
|
||||
|
||||
showModalSpy.mockImplementation(function showModal(this:HTMLDialogElement) {
|
||||
this.open = true;
|
||||
});
|
||||
|
||||
expect(document.querySelector('dialog#test3')).toBeFalsy();
|
||||
|
||||
await modalService.show('3');
|
||||
@@ -128,6 +134,7 @@ describe('AttributeHelpTextModalService', () => {
|
||||
await modalService.show('3');
|
||||
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(2);
|
||||
expect(showModalSpy.mock.contexts.at(-1)).toBe(dialog);
|
||||
|
||||
let mutation = await waitForElementMutation(dialog);
|
||||
|
||||
@@ -138,6 +145,7 @@ describe('AttributeHelpTextModalService', () => {
|
||||
await modalService.show('3');
|
||||
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(3);
|
||||
expect(showModalSpy.mock.contexts.at(-1)).toBe(dialog);
|
||||
|
||||
mutation = await waitForElementMutation(dialog);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Idiomorph } from 'idiomorph';
|
||||
export function registerDialogStreamAction() {
|
||||
StreamActions.closeDialog = function closeDialogStreamAction(this:StreamElement) {
|
||||
const dialog = document.querySelector(this.target)!;
|
||||
const additionalData = JSON.parse(this.getAttribute('additional') || '{}') as unknown;
|
||||
const additionalData = JSON.parse(this.getAttribute('additional') ?? '{}') as unknown;
|
||||
|
||||
// dispatching with submitted: true to indicate that the behavior of a successful submission should
|
||||
// be triggered (i.e. reloading the ui)
|
||||
@@ -16,10 +16,12 @@ export function registerDialogStreamAction() {
|
||||
const content = this.templateElement.content;
|
||||
const dialog = content.querySelector('dialog')!;
|
||||
const existingElement = document.getElementById(dialog.id);
|
||||
let dialogToShow = dialog;
|
||||
|
||||
if (existingElement && existingElement instanceof HTMLDialogElement) {
|
||||
if (existingElement instanceof HTMLDialogElement) {
|
||||
// a dialog with this id already exists: update (morph) its contents.
|
||||
Idiomorph.morph(existingElement, dialog.innerHTML, { morphStyle: 'innerHTML' });
|
||||
dialogToShow = existingElement;
|
||||
} else {
|
||||
// no dialog with this id exists: append <dialog-helper> to the body.
|
||||
document.body.append(content);
|
||||
@@ -39,13 +41,13 @@ export function registerDialogStreamAction() {
|
||||
}
|
||||
|
||||
// Auto-show the modal
|
||||
dialog.showModal();
|
||||
dialogToShow.showModal();
|
||||
|
||||
// Hack to fix the width calculation of nested elements
|
||||
// such as the CKEditor toolbar.
|
||||
setTimeout(() => {
|
||||
const width = dialog.offsetWidth;
|
||||
dialog.style.width = `${width + 1}px`;
|
||||
const width = dialogToShow.offsetWidth;
|
||||
dialogToShow.style.width = `${width + 1}px`;
|
||||
}, 250);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user