make context aware about Router

This commit is contained in:
Niels Lyngsø
2023-05-15 21:40:10 +02:00
parent d7be696321
commit 418bb2285f
5 changed files with 47 additions and 24 deletions

View File

@@ -1,3 +1,5 @@
// eslint-disable-next-line local-rules/no-external-imports
import type { IRouterSlot } from 'router-slot/model';
import type {
UUIDialogElement,
UUIModalDialogElement,
@@ -5,6 +7,7 @@ import type {
UUIModalSidebarSize,
} from '@umbraco-ui/uui';
import { BehaviorSubject } from 'rxjs';
import { UmbRouterSlotElement } from '@umbraco-cms/internal/router';
import { UmbModalConfig, UmbModalType } from './modal.context';
import { UmbModalToken } from './token/modal-token';
import { UmbId } from '@umbraco-cms/backoffice/id';
@@ -45,18 +48,18 @@ export class UmbModalHandlerClass<ModalData extends object = object, ModalResult
#host: UmbControllerHostElement;
public modalElement: UUIModalDialogElement | UUIModalSidebarElement;
#modalRouterElement: UmbRouterSlotElement = new UmbRouterSlotElement();
#innerElement = new BehaviorSubject<HTMLElement | undefined>(undefined);
public readonly innerElement = this.#innerElement.asObservable();
#modalElement?: UUIModalSidebarElement | UUIDialogElement;
public key: string;
public type: UmbModalType = 'dialog';
public size: UUIModalSidebarSize = 'small';
constructor(
host: UmbControllerHostElement,
router: IRouterSlot | null,
modalAlias: string | UmbModalToken<ModalData, ModalResult>,
data?: ModalData,
config?: UmbModalConfig
@@ -79,6 +82,10 @@ export class UmbModalHandlerClass<ModalData extends object = object, ModalResult
});
this.modalElement = this.#createContainerElement();
this.modalElement.appendChild(this.#modalRouterElement);
if (router) {
this.#modalRouterElement.parent = router;
}
this.#observeModal(modalAlias.toString(), data);
}
@@ -88,7 +95,6 @@ export class UmbModalHandlerClass<ModalData extends object = object, ModalResult
#createSidebarElement() {
const sidebarElement = document.createElement('uui-modal-sidebar');
this.#modalElement = sidebarElement;
sidebarElement.size = this.size;
return sidebarElement;
}
@@ -96,7 +102,6 @@ export class UmbModalHandlerClass<ModalData extends object = object, ModalResult
#createDialogElement() {
const modalDialogElement = document.createElement('uui-modal-dialog');
const dialogElement: UUIDialogElement = document.createElement('uui-dialog');
this.#modalElement = dialogElement;
modalDialogElement.appendChild(dialogElement);
return modalDialogElement;
}
@@ -151,14 +156,14 @@ export class UmbModalHandlerClass<ModalData extends object = object, ModalResult
}
#appendInnerElement(element: HTMLElement) {
this.#modalElement?.appendChild(element);
this.#modalRouterElement.appendChild(element);
this.#innerElement.next(element);
}
#removeInnerElement() {
const innerElement = this.#innerElement.getValue();
if (innerElement) {
this.#modalElement?.removeChild(innerElement);
this.#modalRouterElement.removeChild(innerElement);
this.#innerElement.next(undefined);
}
}

View File

@@ -1,3 +1,5 @@
// eslint-disable-next-line local-rules/no-external-imports
import type { IRouterSlot } from 'router-slot/model';
import { UmbModalHandler } from './modal-handler';
import { UmbModalConfig, UmbModalContext } from './modal.context';
import { UmbModalToken } from './token/modal-token';
@@ -107,13 +109,13 @@ export class UmbModalRouteRegistration<UmbModalTokenData extends object = object
this.#modalHandler = undefined;
};
routeSetup(modalContext: UmbModalContext, params: Params) {
routeSetup(router: IRouterSlot, modalContext: UmbModalContext, params: Params) {
// If already open, don't do anything:
if (this.active) return;
const modalData = this.#onSetupCallback ? this.#onSetupCallback(params) : undefined;
if (modalData !== false) {
this.#modalHandler = modalContext.open(this.#modalAlias, modalData, this.modalConfig);
this.#modalHandler = modalContext.open(this.#modalAlias, modalData, this.modalConfig, router);
this.#modalHandler.onSubmit().then(this.#onSubmit, this.#onReject);
return this.#modalHandler;
}

View File

@@ -1,3 +1,5 @@
// eslint-disable-next-line local-rules/no-external-imports
import type { IRouterSlot } from 'router-slot/model';
// TODO: remove this import when the search hack is removed
import '../../src/backoffice/search/search-modal/search-modal.element';
@@ -30,7 +32,7 @@ export class UmbModalContext {
// TODO: Remove this when the modal system is more flexible
public search() {
const modalHandler = new UmbModalHandlerClass(this.host, 'Umb.Modal.Search') as unknown as UmbModalHandler<
const modalHandler = new UmbModalHandlerClass(this.host, null, 'Umb.Modal.Search') as unknown as UmbModalHandler<
any,
any
>;
@@ -78,12 +80,16 @@ export class UmbModalContext {
public open<ModalData extends object = object, ModalResult = unknown>(
modalAlias: string | UmbModalToken<ModalData, ModalResult>,
data?: ModalData,
config?: UmbModalConfig
config?: UmbModalConfig,
router: IRouterSlot | null = null
) {
const modalHandler = new UmbModalHandlerClass(this.host, modalAlias, data, config) as unknown as UmbModalHandler<
ModalData,
ModalResult
>;
const modalHandler = new UmbModalHandlerClass(
this.host,
router,
modalAlias,
data,
config
) as unknown as UmbModalHandler<ModalData, ModalResult>;
modalHandler.modalElement.addEventListener('close-end', () => this.#onCloseEnd(modalHandler));

View File

@@ -1,5 +1,5 @@
// eslint-disable-next-line local-rules/no-external-imports
import type { IRoutingInfo } from 'router-slot/model';
import type { IRoutingInfo, IRouterSlot } from 'router-slot/model';
import type { UmbRoute } from './route.interface';
import { generateRoutePathBuilder } from './generate-route-path-builder.function';
import {
@@ -13,13 +13,17 @@ import { UMB_MODAL_CONTEXT_TOKEN, UmbModalRouteRegistration } from '@umbraco-cms
const EmptyDiv = document.createElement('div');
export class UmbRouteContext {
#mainRouter: IRouterSlot;
#modalRouter: IRouterSlot;
#modalRegistrations: UmbModalRouteRegistration[] = [];
#modalContext?: typeof UMB_MODAL_CONTEXT_TOKEN.TYPE;
#contextRoutes: UmbRoute[] = [];
#routerBasePath?: string;
#activeModalPath?: string;
constructor(host: UmbControllerHostElement, private _onGotModals: (contextRoutes: any) => void) {
constructor(host: UmbControllerHostElement, mainRouter: IRouterSlot, modalRouter: IRouterSlot) {
this.#mainRouter = mainRouter;
this.#modalRouter = modalRouter;
new UmbContextProviderController(host, UMB_ROUTE_CONTEXT_TOKEN, this);
new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (context) => {
this.#modalContext = context;
@@ -29,7 +33,6 @@ export class UmbRouteContext {
public registerModal(registration: UmbModalRouteRegistration) {
this.#modalRegistrations.push(registration);
console.log('registerModal', registration);
this.#generateNewUrlBuilder(registration);
this.#generateContextRoutes();
return registration;
@@ -48,7 +51,7 @@ export class UmbRouteContext {
component: EmptyDiv,
setup: (component, info) => {
if (!this.#modalContext) return;
const modalHandler = modalRegistration.routeSetup(this.#modalContext, info.match.params);
const modalHandler = modalRegistration.routeSetup(this.#modalRouter, this.#modalContext, info.match.params);
if (modalHandler) {
modalHandler.onSubmit().then(
() => {
@@ -81,7 +84,8 @@ export class UmbRouteContext {
});
// TODO: Should we await one frame, to ensure we don't call back too much?.
this._onGotModals(this.#contextRoutes);
this.#modalRouter.routes = this.#contextRoutes;
this.#modalRouter.render();
}
public _internal_routerGotBasePath(routerBasePath: string) {

View File

@@ -1,5 +1,7 @@
// eslint-disable-next-line local-rules/no-external-imports
import { RouterSlot } from 'router-slot/router-slot';
// eslint-disable-next-line local-rules/no-external-imports
import type { IRouterSlot } from 'router-slot/model';
import { css, html, PropertyValueMap } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { UmbLitElement } from '../lit-element';
@@ -28,6 +30,14 @@ export class UmbRouterSlotElement extends UmbLitElement {
this.#router.routes = value || [];
}
@property()
public get parent(): IRouterSlot | null | undefined {
return this.#router.parent;
}
public set parent(parent: IRouterSlot | null | undefined) {
this.#router.parent = parent;
}
private _routerPath?: string;
public get absoluteRouterPath() {
return this._routerPath;
@@ -42,11 +52,7 @@ export class UmbRouterSlotElement extends UmbLitElement {
return this._routerPath + '/' + this._activeLocalPath;
}
#routeContext = new UmbRouteContext(this, (contextRoutes) => {
this.#modalRouter.routes = contextRoutes;
// Force a render?
this.#modalRouter.render();
});
#routeContext = new UmbRouteContext(this, this.#router, this.#modalRouter);
constructor() {
super();