Closing redirecting modals fix (#19420)

* correct for fewer rejected promises

* move set new is new

* enable router slot to back out of a redirect

* hacky fix for redirect controller

* Update src/Umbraco.Web.UI.Client/src/packages/core/workspace/controllers/workspace-is-new-redirect.controller.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/Umbraco.Web.UI.Client/src/packages/core/workspace/controllers/workspace-is-new-redirect.controller.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Niels Lyngsø
2025-05-26 14:39:39 +02:00
committed by GitHub
parent 290334baaa
commit 5c7a25fdc7
7 changed files with 72 additions and 15 deletions

View File

@@ -918,6 +918,7 @@ export abstract class UmbContentDetailWorkspaceContextBase<
variantIdsIncludingInvariant,
);
this._data.setCurrent(newCurrentData);
this.setIsNew(false);
const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
if (!eventContext) {
@@ -928,7 +929,6 @@ export abstract class UmbContentDetailWorkspaceContextBase<
unique: parent.unique,
});
eventContext.dispatchEvent(event);
this.setIsNew(false);
}
async #update(variantIds: Array<UmbVariantId>, saveData: DetailModelType) {

View File

@@ -36,7 +36,11 @@ export class UmbItemRepositoryBase<ItemType extends { unique: string }>
*/
async requestItems(uniques: Array<string>) {
if (!uniques) throw new Error('Uniques are missing');
await this._init;
try {
await this._init;
} catch {
return {};
}
const { data, error: _error } = await this.#itemSource.getItems(uniques);
@@ -59,7 +63,11 @@ export class UmbItemRepositoryBase<ItemType extends { unique: string }>
* @memberof UmbItemRepositoryBase
*/
async items(uniques: Array<string>) {
await this._init;
try {
await this._init;
} catch {
return undefined;
}
return this._itemStore!.items(uniques);
}
}

View File

@@ -8,5 +8,5 @@ export interface UmbItemRepository<ItemType> extends UmbApi {
error?: UmbProblemDetails | undefined;
asObservable?: () => Observable<Array<ItemType>>;
}>;
items: (uniques: string[]) => Promise<Observable<Array<ItemType>>>;
items: (uniques: string[]) => Promise<Observable<Array<ItemType>> | undefined>;
}

View File

@@ -176,6 +176,8 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
* Tears down the element.
*/
override disconnectedCallback() {
this._setParent(null);
this._cancelNavigation?.();
this.detachListeners();
}
@@ -413,6 +415,11 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
return cancel();
}
}
// Check if the current route is still matching the browser URL.:
if (!window.location.href.includes(this.constructAbsolutePath(''))) {
// If the parent is active, we should not redirect.
return cancel();
}
handleRedirect(this, route);
return false;
}

View File

@@ -16,6 +16,13 @@ export const UmbWorkspaceIsNewRedirectControllerAlias = Symbol('IsNewRedirectCon
* @param router
*/
export class UmbWorkspaceIsNewRedirectController extends UmbControllerBase {
/**
* TODO: Figure out why we need this timeout. [NL]
* The problem this fixes it when save & publishing a document open in a modal, like from a collection.
* The redirect triggers something that ends up re-setting the path, making the modal path the one in the browser despite the modal is closed.
*/
timeout: any | undefined;
constructor(
host: UmbControllerHost,
workspaceContext: UmbSubmittableWorkspaceContextBase<unknown>,
@@ -25,21 +32,45 @@ export class UmbWorkspaceIsNewRedirectController extends UmbControllerBase {
// Navigate to edit route when language is created:
this.observe(workspaceContext.isNew, (isNew) => {
if (this.timeout) {
clearTimeout(this.timeout);
}
if (isNew === false) {
const unique = workspaceContext.getUnique();
if (router && unique) {
const routerPath = router.absoluteRouterPath;
if (routerPath) {
const newPath: string = umbUrlPatternToString(ensurePathEndsWithSlash(routerPath) + 'edit/:id', {
id: unique,
});
this.destroy();
window.history.replaceState(null, '', newPath);
this.timeout = setTimeout(() => {
const unique = workspaceContext.getUnique();
if (router && unique) {
const routerPath = router.absoluteRouterPath;
if (routerPath) {
const newPath: string = umbUrlPatternToString(ensurePathEndsWithSlash(routerPath) + 'edit/:id', {
id: unique,
});
this.destroy();
// get current url:
const currentUrl = window.location.href;
if (
router.localActiveViewPath === undefined ||
router.localActiveViewPath === '' ||
!currentUrl.includes(router.localActiveViewPath)
) {
return;
}
// Check that we are still part of the DOM and thereby relevant:
window.history.replaceState(null, '', newPath);
}
}
}
this.timeout = undefined;
}, 500);
}
});
// TODO: If workspace route changes cause of other reasons then this controller should be destroyed.
}
override destroy() {
super.destroy();
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
}
}

View File

@@ -373,6 +373,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
this.#entityContext.setUnique(data.unique);
this._data.setPersisted(data);
this._data.setCurrent(data);
this.setIsNew(false);
const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
if (!eventContext) throw new Error('Event context not found.');
@@ -381,7 +382,6 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
unique: parent.unique,
});
eventContext.dispatchEvent(event);
this.setIsNew(false);
}
protected async _update(currentData: DetailModelType) {

View File

@@ -162,6 +162,17 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
protected invalidSubmit(reason?: any): Promise<void> {
return Promise.reject(reason);
}
override destroy(): void {
this.#isNew.destroy();
this.routes.destroy();
super.destroy();
this.#submitPromise = undefined;
this.#submitResolve = undefined;
this.#submitReject = undefined;
this.#validationContexts.forEach((context) => context.destroy());
this.#validationContexts = [];
}
}
/*