Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Version check #2270

Merged
merged 21 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fe42c77
feat: add methods and types to support version checking with local st…
iOvergaard Sep 11, 2024
0e2b801
feat: show a button in the backoffice logo area if a new version is a…
iOvergaard Sep 11, 2024
7ee0673
feat: add localization
iOvergaard Sep 11, 2024
a96da1f
feat: register new modal to show version info
iOvergaard Sep 11, 2024
1babead
feat: update last check only once
iOvergaard Sep 11, 2024
d61e84b
feat: open the new version modal when a new version is available
iOvergaard Sep 11, 2024
b7d63a7
Merge remote-tracking branch 'origin/main' into v14/feature/version-c…
iOvergaard Sep 11, 2024
b0d1a52
update package lock
iOvergaard Sep 11, 2024
43c7466
chore: make sonarcloud happy
iOvergaard Sep 11, 2024
195a2a1
feat: add mock handlers for server endpoints
iOvergaard Sep 11, 2024
25503c4
feat: make method internal
iOvergaard Sep 11, 2024
b9a375f
chore: sort methods
iOvergaard Sep 11, 2024
aeeea4c
chore: generate server api
iOvergaard Sep 12, 2024
95d2799
Merge branch 'main' into v14/feature/version-check
iOvergaard Sep 12, 2024
99491ee
chore: change text based on actual texts coming from Our
iOvergaard Sep 12, 2024
5314a65
Merge branch 'main' into v14/feature/version-check
iOvergaard Sep 12, 2024
29d8ade
Merge branch 'main' into v14/feature/version-check
iOvergaard Sep 12, 2024
b15cdf6
chore: update link to sonarcloud is happy
iOvergaard Sep 12, 2024
aaa6722
Tweaked "read more" button icon
leekelleher Sep 12, 2024
3c61a3c
Merge branch 'main' into v14/feature/version-check
iOvergaard Sep 13, 2024
edd106f
Merge branch 'main' into v14/feature/version-check
iOvergaard Sep 13, 2024
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/apps/backoffice/backoffice.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbExtensionManifestInitializer } from '@umbraco-cms/backoffice/extension-api';
import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth';
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
import { UmbSysinfoRepository } from '@umbraco-cms/backoffice/sysinfo';

export class UmbBackofficeContext extends UmbContextBase<UmbBackofficeContext> {
#activeSectionAlias = new UmbStringState(undefined);
Expand Down Expand Up @@ -76,6 +77,12 @@ export class UmbBackofficeContext extends UmbContextBase<UmbBackofficeContext> {
public setActiveSectionAlias(alias: string) {
this.#activeSectionAlias.setValue(alias);
}

public async serverUpgradeCheck(): Promise<boolean> {
const repository = new UmbSysinfoRepository(this);
const check = await repository.serverUpgradeCheck();
return !!check;
}
}

export const UMB_BACKOFFICE_CONTEXT = new UmbContextToken<UmbBackofficeContext>('UmbBackofficeContext');
31 changes: 29 additions & 2 deletions src/apps/backoffice/components/backoffice-header-logo.element.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { isCurrentUserAnAdmin } from '@umbraco-cms/backoffice/current-user';
import { UMB_BACKOFFICE_CONTEXT } from '../backoffice.context.js';
import { isCurrentUserAnAdmin } from '@umbraco-cms/backoffice/current-user';
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_SYSINFO_MODAL } from '@umbraco-cms/backoffice/sysinfo';
import { UMB_NEWVERSION_MODAL, UMB_SYSINFO_MODAL } from '@umbraco-cms/backoffice/sysinfo';

@customElement('umb-backoffice-header-logo')
export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
Expand All @@ -14,6 +14,11 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
@state()
private _isUserAdmin = false;

@state()
private _serverUpgradeCheck = false;

#backofficeContext?: typeof UMB_BACKOFFICE_CONTEXT.TYPE;

constructor() {
super();

Expand All @@ -26,13 +31,19 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
},
'_observeVersion',
);

this.#backofficeContext = context;
});

this.#isAdmin();
}

async #isAdmin() {
this._isUserAdmin = await isCurrentUserAnAdmin(this);

if (this._isUserAdmin) {
this._serverUpgradeCheck = this.#backofficeContext ? await this.#backofficeContext.serverUpgradeCheck() : false;
}
}

override render() {
Expand All @@ -50,6 +61,14 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
height="82"
loading="lazy" />
<span>${this._version}</span>

${this._serverUpgradeCheck
? html`<uui-button
@click=${this.#openNewVersion}
color="danger"
label=${this.localize.term('general_newVersionAvailable')}></uui-button>`
: ''}

<a href="https://umbraco.com" target="_blank" rel="noopener">Umbraco.com</a>

${this._isUserAdmin
Expand All @@ -72,6 +91,14 @@ export class UmbBackofficeHeaderLogoElement extends UmbLitElement {
.catch(() => {});
}

async #openNewVersion() {
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
modalManager
.open(this, UMB_NEWVERSION_MODAL)
.onSubmit()
.catch(() => {});
}

static override styles = [
UmbTextStyles,
css`
Expand Down
1 change: 1 addition & 0 deletions src/assets/lang/da-dk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ export default {
lastUpdated: 'Last Updated',
skipToMenu: 'Skip to menu',
skipToContent: 'Skip to content',
newVersionAvailable: 'Ny version tilgængelig',
},
colors: {
blue: 'Blå',
Expand Down
1 change: 1 addition & 0 deletions src/assets/lang/de-de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ export default {
header: 'Kopf',
systemField: 'System Feld',
lastUpdated: 'Zuletzt geändert',
newVersionAvailable: 'Neue Version verfügbar',
},
colors: {
blue: 'Blau',
Expand Down
1 change: 1 addition & 0 deletions src/assets/lang/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,7 @@ export default {
skipToMenu: 'Skip to menu',
skipToContent: 'Skip to content',
restore: 'Restore',
newVersionAvailable: 'New version available',
},
colors: {
blue: 'Blue',
Expand Down
1 change: 1 addition & 0 deletions src/assets/lang/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ export default {
media: 'Media',
revert: 'Revert',
validate: 'Validate',
newVersionAvailable: 'New version available',
},
colors: {
blue: 'Blue',
Expand Down
17 changes: 16 additions & 1 deletion src/external/backend-api/src/services.gen.ts

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/external/backend-api/src/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2149,6 +2149,7 @@ export type ServerConfigurationItemResponseModel = {

export type ServerConfigurationResponseModel = {
allowPasswordReset: boolean;
versionCheckPeriod: number;
};

export type ServerInformationResponseModel = {
Expand Down Expand Up @@ -2608,6 +2609,12 @@ export type UpdateWebhookRequestModel = {
events: Array<(string)>;
};

export type UpgradeCheckResponseModel = {
type: string;
comment: string;
url: string;
};

export type UpgradeSettingsResponseModel = {
currentState: string;
newState: string;
Expand Down Expand Up @@ -4667,6 +4674,8 @@ export type GetServerStatusResponse = ((ServerStatusResponseModel));

export type GetServerTroubleshootingResponse = ((ServerTroubleshootingResponseModel));

export type GetServerUpgradeCheckResponse = ((UpgradeCheckResponseModel));

export type GetItemStaticFileData = {
path?: Array<(string)>;
};
Expand Down
43 changes: 33 additions & 10 deletions src/mocks/handlers/server.handlers.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
const { rest } = window.MockServiceWorker;
import {
type ServerStatusResponseModel,
type ServerInformationResponseModel,
type ServerTroubleshootingResponseModel,
RuntimeLevelModel,
RuntimeModeModel,
type GetServerUpgradeCheckResponse,
type GetServerTroubleshootingResponse,
type GetServerInformationResponse,
type GetServerConfigurationResponse,
type GetServerStatusResponse,
} from '@umbraco-cms/backoffice/external/backend-api';
import { umbracoPath } from '@umbraco-cms/backoffice/utils';

export const serverRunningHandler = rest.get(umbracoPath('/server/status'), (_req, res, ctx) => {
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<ServerStatusResponseModel>({
ctx.json<GetServerStatusResponse>({
serverStatus: RuntimeLevelModel.RUN,
}),
);
Expand All @@ -22,7 +24,7 @@ export const serverMustInstallHandler = rest.get(umbracoPath('/server/status'),
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<ServerStatusResponseModel>({
ctx.json<GetServerStatusResponse>({
serverStatus: RuntimeLevelModel.INSTALL,
}),
);
Expand All @@ -32,20 +34,41 @@ export const serverMustUpgradeHandler = rest.get(umbracoPath('/server/status'),
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<ServerStatusResponseModel>({
ctx.json<GetServerStatusResponse>({
serverStatus: RuntimeLevelModel.UPGRADE,
}),
);
});

export const serverInformationHandlers = [
rest.get(umbracoPath('/server/configuration'), (_req, res, ctx) => {
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<GetServerConfigurationResponse>({
allowPasswordReset: true,
versionCheckPeriod: 7, // days
}),
);
}),
rest.get(umbracoPath('/server/upgrade-check'), (_req, res, ctx) => {
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<GetServerUpgradeCheckResponse>({
type: 'Minor',
comment: "14.2.0.0 is released. Upgrade today - it's free!",
url: 'https://our.umbraco.com/download/releases/1420',
}),
);
}),
rest.get(umbracoPath('/server/information'), (_req, res, ctx) => {
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<ServerInformationResponseModel>({
version: '14.0.0-preview004',
assemblyVersion: '14.0.0-preview004',
ctx.json<GetServerInformationResponse>({
version: '14.0.0',
assemblyVersion: '14.0.0',
baseUtcOffset: '01:00:00',
runtimeMode: RuntimeModeModel.BACKOFFICE_DEVELOPMENT,
}),
Expand All @@ -55,7 +78,7 @@ export const serverInformationHandlers = [
return res(
// Respond with a 200 status code
ctx.status(200),
ctx.json<ServerTroubleshootingResponseModel>({
ctx.json<GetServerTroubleshootingResponse>({
items: [
{ name: 'Umbraco base url', data: location.origin },
{ name: 'Mocked server', data: 'true' },
Expand Down
68 changes: 68 additions & 0 deletions src/packages/sysinfo/components/new-version.element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { UmbSysinfoRepository } from '../repository/sysinfo.repository.js';
import type { UmbServerUpgradeCheck } from '../types.js';
import { css, customElement, html, state, when } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';

@customElement('umb-new-version')
export class UmbNewVersionElement extends UmbModalBaseElement {
@state()
private _serverUpgradeCheck: UmbServerUpgradeCheck | null = null;

#sysinfoRepository = new UmbSysinfoRepository(this);

override async connectedCallback() {
super.connectedCallback();
this._serverUpgradeCheck = await this.#sysinfoRepository.serverUpgradeCheck();
}

override render() {
return html`
<uui-dialog>
<uui-dialog-layout headline=${this.localize.term('general_newVersionAvailable')}>
${when(
this._serverUpgradeCheck === null,
() => html`<uui-loader-bar></uui-loader-bar>`,
() => html` <div>${this._serverUpgradeCheck!.comment}</div> `,
)}

<uui-button
@click=${this._submitModal}
slot="actions"
look="secondary"
label=${this.localize.term('general_close')}></uui-button>

${this._serverUpgradeCheck?.url
? html` <uui-button
.href=${this._serverUpgradeCheck.url}
target="_blank"
slot="actions"
look="primary"
color="positive"
label=${this.localize.term('general_readMore')}>
<umb-localize key="general_readMore">Read more</umb-localize>
<umb-icon slot="extra" name="icon-out"></umb-icon>
</uui-button>`
: ''}
</uui-dialog-layout>
</uui-dialog>
`;
}

static override readonly styles = [
UmbTextStyles,
css`
umb-icon {
margin-left: var(--uui-size-2);
}
`,
];
}

export default UmbNewVersionElement;

declare global {
interface HTMLElementTagNameMap {
'umb-new-version': UmbNewVersionElement;
}
}
1 change: 1 addition & 0 deletions src/packages/sysinfo/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './modals/index.js';
export * from './repository/index.js';
export type * from './types.js';
22 changes: 15 additions & 7 deletions src/packages/sysinfo/manifests.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type { ManifestModal, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

const modalManifest: ManifestModal = {
type: 'modal',
alias: 'Umb.Modal.Sysinfo',
name: 'Sysinfo Modal',
js: () => import('./components/sysinfo.element.js'),
};
const modalManifests: Array<ManifestModal> = [
{
type: 'modal',
alias: 'Umb.Modal.Sysinfo',
name: 'Sysinfo Modal',
js: () => import('./components/sysinfo.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.NewVersion',
name: 'New Version Modal',
js: () => import('./components/new-version.element.js'),
},
];

export const manifests: Array<ManifestTypes> = [modalManifest];
export const manifests: Array<ManifestTypes> = [...modalManifests];
1 change: 1 addition & 0 deletions src/packages/sysinfo/modals/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './new-version-modal.token.js';
export * from './sysinfo-modal.token.js';
8 changes: 8 additions & 0 deletions src/packages/sysinfo/modals/new-version-modal.token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';

export const UMB_NEWVERSION_MODAL = new UmbModalToken('Umb.Modal.NewVersion', {
modal: {
type: 'dialog',
size: 'medium',
},
});
Loading
Loading