diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 9c08dfb59f..74589de99c 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -3638,6 +3638,10 @@ "resolved": "src/packages/performance-profiling", "link": true }, + "node_modules/@umbraco-backoffice/preview": { + "resolved": "src/packages/preview", + "link": true + }, "node_modules/@umbraco-backoffice/property-editors": { "resolved": "src/packages/property-editors", "link": true @@ -17084,6 +17088,9 @@ "src/packages/performance-profiling": { "name": "@umbraco-backoffice/performance-profiling" }, + "src/packages/preview": { + "name": "@umbraco-backoffice/preview" + }, "src/packages/property-editors": { "name": "@umbraco-backoffice/property-editors" }, diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index b22f6f4e74..f91e42d9ba 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -85,6 +85,7 @@ "./picker-input": "./dist-cms/packages/core/picker-input/index.js", "./picker-data-source": "./dist-cms/packages/core/picker-data-source/index.js", "./picker": "./dist-cms/packages/core/picker/index.js", + "./preview": "./dist-cms/packages/preview/index.js", "./property-action": "./dist-cms/packages/core/property-action/index.js", "./property-editor-data-source": "./dist-cms/packages/core/property-editor-data-source/index.js", "./property-editor": "./dist-cms/packages/core/property-editor/index.js", diff --git a/src/Umbraco.Web.UI.Client/src/apps/preview/index.ts b/src/Umbraco.Web.UI.Client/src/apps/preview/index.ts new file mode 100644 index 0000000000..d90c7995f9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/apps/preview/index.ts @@ -0,0 +1 @@ +export * from './preview.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/apps/preview/preview.element.ts b/src/Umbraco.Web.UI.Client/src/apps/preview/preview.element.ts index b2d0db0da7..e9bce3c441 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/preview/preview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/preview/preview.element.ts @@ -1,8 +1,14 @@ -import { manifests as previewApps } from './apps/manifests.js'; -import { UmbPreviewContext } from './preview.context.js'; import { css, customElement, html, nothing, state, when } from '@umbraco-cms/backoffice/external/lit'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { + umbExtensionsRegistry, + UmbBackofficeEntryPointExtensionInitializer, +} from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbPreviewContext } from '@umbraco-cms/backoffice/preview'; +import { UmbServerExtensionRegistrator } from '@umbraco-cms/backoffice/extension-api'; +import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth'; + +const CORE_PACKAGES = [import('../../packages/preview/umbraco-package.js')]; /** * @element umb-preview @@ -11,23 +17,40 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; export class UmbPreviewElement extends UmbLitElement { #context = new UmbPreviewContext(this); - constructor() { - super(); - - if (previewApps?.length) { - umbExtensionsRegistry.registerMany(previewApps); - } - - this.observe(this.#context.iframeReady, (iframeReady) => (this._iframeReady = iframeReady)); - this.observe(this.#context.previewUrl, (previewUrl) => (this._previewUrl = previewUrl)); - } - @state() private _iframeReady?: boolean; @state() private _previewUrl?: string; + constructor() { + super(); + + new UmbBackofficeEntryPointExtensionInitializer(this, umbExtensionsRegistry); + + this.observe(this.#context.iframeReady, (iframeReady) => (this._iframeReady = iframeReady)); + this.observe(this.#context.previewUrl, (previewUrl) => (this._previewUrl = previewUrl)); + } + + override async firstUpdated() { + await this.#extensionsAfterAuth(); + + // Extensions are loaded in parallel and don't need to block the preview frame + CORE_PACKAGES.forEach(async (packageImport) => { + const { extensions } = await packageImport; + umbExtensionsRegistry.registerMany(extensions); + }); + } + + async #extensionsAfterAuth() { + const authContext = await this.getContext(UMB_AUTH_CONTEXT, { preventTimeout: true }); + if (!authContext) { + throw new Error('UmbPreviewElement requires the UMB_AUTH_CONTEXT to be set.'); + } + await this.observe(authContext.isAuthorized).asPromise(); + await new UmbServerExtensionRegistrator(this, umbExtensionsRegistry).registerPrivateExtensions(); + } + #onIFrameLoad(event: Event & { target: HTMLIFrameElement }) { this.#context.iframeLoaded(event.target); } @@ -36,7 +59,7 @@ export class UmbPreviewElement extends UmbLitElement { if (!this._previewUrl) return nothing; return html` ${when(!this._iframeReady, () => html`
`)} -
+