Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
af4e46b
Preview Device: refactored config
leekelleher Oct 21, 2025
9cdd0ca
Preview element CSS refinement
leekelleher Oct 21, 2025
54bda16
Preview element: load in private extensions
leekelleher Oct 21, 2025
073bae5
Added "Preview Environments" preview-app
leekelleher Oct 21, 2025
eaa1cf6
Aligned preview-app design
leekelleher Oct 21, 2025
ccfa03d
Created "Preview" package
leekelleher Oct 21, 2025
32470bc
Relocated "Preview Apps" and Context to the new package
leekelleher Oct 21, 2025
12a29e1
Deprecated `UmbDocumentPreviewRepository` (for v19)
leekelleher Oct 21, 2025
fae914d
Removed Preview Sessions event listeners
leekelleher Oct 21, 2025
d70817a
Changed localization from "End" to "Exit"
leekelleher Oct 21, 2025
87f61ae
Merge remote-tracking branch 'origin/v17/dev' into v17/feature/previe…
iOvergaard Oct 23, 2025
328b008
chore: consumes context only when needed
iOvergaard Oct 23, 2025
f2ef40d
feat: uses the UmbPreviewRepository instead
iOvergaard Oct 23, 2025
b0aebde
feat: adds localization to errors and ensures the function does not r…
iOvergaard Oct 23, 2025
a2a5e1a
feat: prevents creating a new repository for every click
iOvergaard Oct 23, 2025
ee49a99
feat: prevents potential memory leak by adding a signal to the events…
iOvergaard Oct 23, 2025
2410163
feat: adds a custom interface to prevent typescript errors
iOvergaard Oct 23, 2025
95e1602
feat: ensures new string states are checked properly
iOvergaard Oct 23, 2025
e13319a
docs: adds comment to avoid confusion
iOvergaard Oct 24, 2025
0665d14
feat: sets up scaling once per iframe load rather than on each update
iOvergaard Oct 24, 2025
a5f877a
fix: ensures that you can go back to the default segment again
iOvergaard Oct 24, 2025
19f5f01
feat: closes popovers when clicking on the iframe (losing blur) and i…
iOvergaard Oct 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Umbraco.Web.UI.Client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/Umbraco.Web.UI.Client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions src/Umbraco.Web.UI.Client/src/apps/preview/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './preview.element.js';
68 changes: 47 additions & 21 deletions src/Umbraco.Web.UI.Client/src/apps/preview/preview.element.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -11,22 +17,39 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
export class UmbPreviewElement extends UmbLitElement {
#context = new UmbPreviewContext(this);

@state()
private _iframeReady?: boolean;

@state()
private _previewUrl?: string;

constructor() {
super();

if (previewApps?.length) {
umbExtensionsRegistry.registerMany(previewApps);
}
new UmbBackofficeEntryPointExtensionInitializer(this, umbExtensionsRegistry);

this.observe(this.#context.iframeReady, (iframeReady) => (this._iframeReady = iframeReady));
this.observe(this.#context.previewUrl, (previewUrl) => (this._previewUrl = previewUrl));
}

@state()
private _iframeReady?: boolean;
override async firstUpdated() {
await this.#extensionsAfterAuth();

@state()
private _previewUrl?: string;
// 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);
Expand All @@ -36,7 +59,7 @@ export class UmbPreviewElement extends UmbLitElement {
if (!this._previewUrl) return nothing;
return html`
${when(!this._iframeReady, () => html`<div id="loading"><uui-loader-circle></uui-loader-circle></div>`)}
<div id="wrapper">
<div id="wrapper" class="fullsize">
<div id="container">
<iframe
src=${this._previewUrl}
Expand All @@ -47,9 +70,9 @@ export class UmbPreviewElement extends UmbLitElement {
</div>
<div id="menu">
<h4>Preview Mode</h4>
<uui-button-group>
<umb-extension-slot id="apps" type="previewApp"></umb-extension-slot>
</uui-button-group>
<div id="apps">
<umb-extension-slot type="previewApp"></umb-extension-slot>
</div>
</div>
`;
}
Expand All @@ -62,10 +85,7 @@ export class UmbPreviewElement extends UmbLitElement {
align-items: center;

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
inset: 0;

padding-bottom: 40px;
}
Expand All @@ -82,7 +102,9 @@ export class UmbPreviewElement extends UmbLitElement {
bottom: 0;

font-size: 6rem;
backdrop-filter: blur(5px);
backdrop-filter: blur(var(--uui-size-1, 3px));

z-index: 1;
}

#wrapper {
Expand All @@ -97,7 +119,7 @@ export class UmbPreviewElement extends UmbLitElement {
overflow: hidden;
}

#wrapper.shadow {
#wrapper:not(.fullsize) {
margin: 10px auto;
background-color: white;
border-radius: 3px;
Expand All @@ -123,6 +145,8 @@ export class UmbPreviewElement extends UmbLitElement {
left: 0;
right: 0;

z-index: 1;

background-color: var(--uui-color-header-surface);
height: 40px;

Expand All @@ -136,7 +160,9 @@ export class UmbPreviewElement extends UmbLitElement {
padding: 0 15px;
}

#menu > uui-button-group {
#apps {
display: inline-flex;
align-items: stretch;
height: 100%;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Umbraco.Web.UI.Client/src/assets/lang/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2737,8 +2737,8 @@ export default {
'You can edit and delete Document Blueprints from the "Document Blueprints" tree in the Settings section. Expand the Document Type which the Document Blueprint is based on and click it to edit or delete it.',
},
preview: {
endLabel: 'End',
endTitle: 'End preview mode',
endLabel: 'Exit',
endTitle: 'Exit preview mode',
openWebsiteLabel: 'Preview website',
openWebsiteTitle: 'Open website in preview mode',
returnToPreviewHeadline: 'Preview website?',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
import type { DocumentUrlInfoModel } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';

/** @deprecated This has been deprecated, please use `UmbPreviewRepository` instead. To be removed in Umbraco 19. [LK] */
export class UmbDocumentPreviewRepository extends UmbRepositoryBase {
constructor(host: UmbControllerHost) {
super(host);
Expand All @@ -24,6 +25,12 @@ export class UmbDocumentPreviewRepository extends UmbRepositoryBase {
culture?: string,
segment?: string,
): Promise<DocumentUrlInfoModel> {
new UmbDeprecation({
removeInVersion: '19.0.0',
deprecated: '`UmbDocumentPreviewRepository.getPreviewUrl()`',
solution: 'Use `UmbPreviewRepository.getPreviewUrl()` instead',
}).warn();

const { data, error } = await tryExecute(
this,
DocumentService.getDocumentByIdPreviewUrl({
Expand Down Expand Up @@ -62,6 +69,12 @@ export class UmbDocumentPreviewRepository extends UmbRepositoryBase {
* @memberof UmbDocumentPreviewRepository
*/
async exit(): Promise<void> {
new UmbDeprecation({
removeInVersion: '19.0.0',
deprecated: '`UmbDocumentPreviewRepository.exit()`',
solution: 'Use `UmbPreviewRepository.exit()` instead',
}).warn();

await tryExecute(this, PreviewService.deletePreview(), { disableNotifications: true });
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
UMB_USER_PERMISSION_DOCUMENT_CREATE,
UMB_USER_PERMISSION_DOCUMENT_UPDATE,
} from '../constants.js';
import { UmbDocumentPreviewRepository } from '../repository/preview/index.js';
import { UmbDocumentValidationRepository } from '../repository/validation/index.js';
import { UMB_DOCUMENT_CONFIGURATION_CONTEXT } from '../index.js';
import { UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, UMB_DOCUMENT_WORKSPACE_ALIAS } from './constants.js';
Expand All @@ -41,6 +40,7 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
import type { UmbVariantPropertyGuardRule } from '@umbraco-cms/backoffice/property';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
import { UmbPreviewRepository } from '@umbraco-cms/backoffice/preview';

type ContentModel = UmbDocumentDetailModel;
type ContentTypeModel = UmbDocumentTypeDetailModel;
Expand Down Expand Up @@ -337,7 +337,7 @@ export class UmbDocumentWorkspaceContext
}

// Get the preview URL from the server.
const previewRepository = new UmbDocumentPreviewRepository(this);
const previewRepository = new UmbPreviewRepository(this);
const previewUrlData = await previewRepository.getPreviewUrl(
unique,
urlProviderAlias,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './preview.context.js';
export * from './preview.context-token.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { UmbPreviewContext } from './preview.context.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';

export const UMB_PREVIEW_CONTEXT = new UmbContextToken<UmbPreviewContext>('UmbPreviewContext');
Loading
Loading