Skip to content

Commit 2a459b4

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/image-cropper-config-improvements
2 parents 0c2788d + dd1d4fe commit 2a459b4

File tree

132 files changed

+2104
-1218
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+2104
-1218
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"./extension-registry": "./dist-cms/packages/core/extension-registry/index.js",
4242
"./icon": "./dist-cms/packages/core/icon-registry/index.js",
4343
"./id": "./dist-cms/packages/core/id/index.js",
44+
"./imaging": "./dist-cms/packages/core/imaging/index.js",
4445
"./language": "./dist-cms/packages/language/index.js",
4546
"./lit-element": "./dist-cms/packages/core/lit-element/index.js",
4647
"./localization": "./dist-cms/packages/core/localization/index.js",

src/apps/app/app.element.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ export class UmbAppElement extends UmbLitElement {
9999
component: () => import('../upgrader/upgrader.element.js'),
100100
guards: [this.#isAuthorizedGuard()],
101101
},
102+
{
103+
path: 'preview',
104+
component: () => import('../preview/preview.element.js'),
105+
guards: [this.#isAuthorizedGuard()],
106+
},
102107
{
103108
path: 'logout',
104109
resolve: () => {

src/apps/backoffice/components/backoffice-header-logo.element.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
6161
flex-direction: column;
6262
align-items: center;
6363
gap: var(--uui-size-space-3);
64+
min-width: var(--uui-size-100);
6465
}
6566
`,
6667
];

src/apps/preview/apps/manifests.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { ManifestPreviewAppProvider } from '@umbraco-cms/backoffice/extension-registry';
2+
3+
export const manifests: Array<ManifestPreviewAppProvider> = [
4+
{
5+
type: 'previewApp',
6+
alias: 'Umb.PreviewApps.Device',
7+
name: 'Preview: Device Switcher',
8+
element: () => import('./preview-device.element.js'),
9+
weight: 400,
10+
},
11+
{
12+
type: 'previewApp',
13+
alias: 'Umb.PreviewApps.Culture',
14+
name: 'Preview: Culture Switcher',
15+
element: () => import('./preview-culture.element.js'),
16+
weight: 300,
17+
},
18+
{
19+
type: 'previewApp',
20+
alias: 'Umb.PreviewApps.OpenWebsite',
21+
name: 'Preview: Open Website Button',
22+
element: () => import('./preview-open-website.element.js'),
23+
weight: 200,
24+
},
25+
{
26+
type: 'previewApp',
27+
alias: 'Umb.PreviewApps.Exit',
28+
name: 'Preview: Exit Button',
29+
element: () => import('./preview-exit.element.js'),
30+
weight: 100,
31+
},
32+
];
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { UMB_PREVIEW_CONTEXT } from '../preview.context.js';
2+
import { css, customElement, html, nothing, repeat, state } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
4+
import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language';
5+
import type { UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language';
6+
7+
const elementName = 'umb-preview-culture';
8+
9+
@customElement(elementName)
10+
export class UmbPreviewCultureElement extends UmbLitElement {
11+
#languageRepository = new UmbLanguageCollectionRepository(this);
12+
13+
@state()
14+
private _culture?: UmbLanguageDetailModel;
15+
16+
@state()
17+
private _cultures: Array<UmbLanguageDetailModel> = [];
18+
19+
connectedCallback() {
20+
super.connectedCallback();
21+
this.#getCultures();
22+
}
23+
24+
async #getCultures() {
25+
const { data: langauges } = await this.#languageRepository.requestCollection({ skip: 0, take: 100 });
26+
this._cultures = langauges?.items ?? [];
27+
28+
const searchParams = new URLSearchParams(window.location.search);
29+
const culture = searchParams.get('culture');
30+
31+
if (culture && culture !== this._culture?.unique) {
32+
this._culture = this._cultures.find((c) => c.unique === culture);
33+
}
34+
}
35+
36+
async #onClick(culture: UmbLanguageDetailModel) {
37+
if (this._culture === culture) return;
38+
this._culture = culture;
39+
40+
const previewContext = await this.getContext(UMB_PREVIEW_CONTEXT);
41+
previewContext.updateIFrame({ culture: culture.unique });
42+
}
43+
44+
render() {
45+
if (this._cultures.length <= 1) return nothing;
46+
return html`
47+
<uui-button look="primary" popovertarget="cultures-popover">
48+
<div>
49+
<uui-icon name="icon-globe"></uui-icon>
50+
<span>${this._culture?.name ?? this.localize.term('treeHeaders_languages')}</span>
51+
</div>
52+
</uui-button>
53+
<uui-popover-container id="cultures-popover" placement="top-end">
54+
<umb-popover-layout>
55+
${repeat(
56+
this._cultures,
57+
(item) => item.unique,
58+
(item) => html`
59+
<uui-menu-item
60+
label=${item.name}
61+
?active=${item.unique === this._culture?.unique}
62+
@click=${() => this.#onClick(item)}>
63+
<uui-icon slot="icon" name="icon-globe"></uui-icon>
64+
</uui-menu-item>
65+
`,
66+
)}
67+
</umb-popover-layout>
68+
</uui-popover-container>
69+
`;
70+
}
71+
72+
static styles = [
73+
css`
74+
:host {
75+
display: flex;
76+
border-left: 1px solid var(--uui-color-header-contrast);
77+
--uui-button-font-weight: 400;
78+
--uui-button-padding-left-factor: 3;
79+
--uui-button-padding-right-factor: 3;
80+
}
81+
82+
uui-button > div {
83+
display: flex;
84+
align-items: center;
85+
gap: 5px;
86+
}
87+
88+
umb-popover-layout {
89+
--uui-color-surface: var(--uui-color-header-surface);
90+
--uui-color-border: var(--uui-color-header-surface);
91+
color: var(--uui-color-header-contrast);
92+
}
93+
`,
94+
];
95+
}
96+
97+
export { UmbPreviewCultureElement as element };
98+
99+
declare global {
100+
interface HTMLElementTagNameMap {
101+
[elementName]: UmbPreviewCultureElement;
102+
}
103+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import { UMB_PREVIEW_CONTEXT } from '../preview.context.js';
2+
import { css, customElement, html, property, repeat } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
4+
5+
export interface UmbPreviewDevice {
6+
alias: string;
7+
label: string;
8+
css: string;
9+
icon: string;
10+
dimensions: { height: string; width: string };
11+
}
12+
13+
const elementName = 'umb-preview-device';
14+
15+
@customElement(elementName)
16+
export class UmbPreviewDeviceElement extends UmbLitElement {
17+
#devices: Array<UmbPreviewDevice> = [
18+
{
19+
alias: 'fullsize',
20+
label: 'Fit browser',
21+
css: 'fullsize',
22+
icon: 'icon-application-window-alt',
23+
dimensions: { height: '100%', width: '100%' },
24+
},
25+
{
26+
alias: 'desktop',
27+
label: 'Desktop',
28+
css: 'desktop shadow',
29+
icon: 'icon-display',
30+
dimensions: { height: '1080px', width: '1920px' },
31+
},
32+
{
33+
alias: 'laptop',
34+
label: 'Laptop',
35+
css: 'laptop shadow',
36+
icon: 'icon-laptop',
37+
dimensions: { height: '768px', width: '1366px' },
38+
},
39+
{
40+
alias: 'ipad-portrait',
41+
label: 'Tablet portrait',
42+
css: 'ipad-portrait shadow',
43+
icon: 'icon-ipad',
44+
dimensions: { height: '929px', width: '769px' },
45+
},
46+
{
47+
alias: 'ipad-landscape',
48+
label: 'Tablet landscape',
49+
css: 'ipad-landscape shadow flip',
50+
icon: 'icon-ipad',
51+
dimensions: { height: '675px', width: '1024px' },
52+
},
53+
{
54+
alias: 'smartphone-portrait',
55+
label: 'Smartphone portrait',
56+
css: 'smartphone-portrait shadow',
57+
icon: 'icon-iphone',
58+
dimensions: { height: '640px', width: '360px' },
59+
},
60+
{
61+
alias: 'smartphone-landscape',
62+
label: 'Smartphone landscape',
63+
css: 'smartphone-landscape shadow flip',
64+
icon: 'icon-iphone',
65+
dimensions: { height: '360px', width: '640px' },
66+
},
67+
];
68+
69+
@property({ attribute: false, type: Object })
70+
device = this.#devices[0];
71+
72+
connectedCallback() {
73+
super.connectedCallback();
74+
this.#changeDevice(this.device);
75+
}
76+
77+
async #changeDevice(device: UmbPreviewDevice) {
78+
if (device === this.device) return;
79+
80+
this.device = device;
81+
82+
const previewContext = await this.getContext(UMB_PREVIEW_CONTEXT);
83+
84+
previewContext?.updateIFrame({
85+
className: device.css,
86+
height: device.dimensions.height,
87+
width: device.dimensions.width,
88+
});
89+
}
90+
91+
render() {
92+
return html`
93+
<uui-button look="primary" popovertarget="devices-popover">
94+
<div>
95+
<uui-icon name=${this.device.icon} class=${this.device.css.includes('flip') ? 'flip' : ''}></uui-icon>
96+
<span>${this.device.label}</span>
97+
</div>
98+
</uui-button>
99+
<uui-popover-container id="devices-popover" placement="top-end">
100+
<umb-popover-layout>
101+
${repeat(
102+
this.#devices,
103+
(item) => item.alias,
104+
(item) => html`
105+
<uui-menu-item
106+
label=${item.label}
107+
?active=${item === this.device}
108+
@click=${() => this.#changeDevice(item)}>
109+
<uui-icon slot="icon" name=${item.icon} class=${item.css.includes('flip') ? 'flip' : ''}></uui-icon>
110+
</uui-menu-item>
111+
`,
112+
)}
113+
</umb-popover-layout>
114+
</uui-popover-container>
115+
`;
116+
}
117+
118+
static styles = [
119+
css`
120+
:host {
121+
display: flex;
122+
border-left: 1px solid var(--uui-color-header-contrast);
123+
--uui-button-font-weight: 400;
124+
--uui-button-padding-left-factor: 3;
125+
--uui-button-padding-right-factor: 3;
126+
}
127+
128+
uui-button > div {
129+
display: flex;
130+
align-items: center;
131+
gap: 5px;
132+
}
133+
134+
umb-popover-layout {
135+
--uui-color-surface: var(--uui-color-header-surface);
136+
--uui-color-border: var(--uui-color-header-surface);
137+
color: var(--uui-color-header-contrast);
138+
}
139+
`,
140+
];
141+
}
142+
143+
export { UmbPreviewDeviceElement as element };
144+
145+
declare global {
146+
interface HTMLElementTagNameMap {
147+
[elementName]: UmbPreviewDeviceElement;
148+
}
149+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { UMB_PREVIEW_CONTEXT } from '../preview.context.js';
2+
import { css, customElement, html } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
4+
5+
const elementName = 'umb-preview-exit';
6+
@customElement(elementName)
7+
export class UmbPreviewExitElement extends UmbLitElement {
8+
async #onClick() {
9+
const previewContext = await this.getContext(UMB_PREVIEW_CONTEXT);
10+
previewContext.exitPreview(0);
11+
}
12+
13+
render() {
14+
return html`
15+
<uui-button look="primary" @click=${this.#onClick}>
16+
<div>
17+
<uui-icon name="icon-power"></uui-icon>
18+
<span>${this.localize.term('preview_endLabel')}</span>
19+
</div>
20+
</uui-button>
21+
`;
22+
}
23+
24+
static styles = [
25+
css`
26+
:host {
27+
display: flex;
28+
border-left: 1px solid var(--uui-color-header-contrast);
29+
--uui-button-font-weight: 400;
30+
--uui-button-padding-left-factor: 3;
31+
--uui-button-padding-right-factor: 3;
32+
}
33+
34+
uui-button > div {
35+
display: flex;
36+
align-items: center;
37+
gap: 5px;
38+
}
39+
`,
40+
];
41+
}
42+
43+
export { UmbPreviewExitElement as element };
44+
45+
declare global {
46+
interface HTMLElementTagNameMap {
47+
[elementName]: UmbPreviewExitElement;
48+
}
49+
}

0 commit comments

Comments
 (0)