diff --git a/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts b/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts index 3c83664382..4d21f5ae7a 100644 --- a/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts +++ b/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts @@ -75,23 +75,26 @@ export interface components { instance?: string; errors?: { [key: string]: unknown }; }; + InstallSetupUserConfiguration: { + name: string; + email: string; + password: string; + subscribeToNewsletter: boolean; + }; InstallSetupDatabaseConfiguration: { id?: string; server?: string | null; password?: string | null; username?: string | null; - databaseName?: string | null; - databaseType?: string | null; + name?: string | null; + providerName?: string | null; useIntegratedAuthentication?: boolean | null; connectionString?: string | null; }; InstallSetupRequest: { - name: string; - email: string; - password: string; - subscribeToNewsletter: boolean; + user: components["schemas"]["InstallSetupUserConfiguration"]; telemetryLevel: components["schemas"]["ConsentLevel"]; - database: components["schemas"]["InstallSetupDatabaseConfiguration"]; + database?: components["schemas"]["InstallSetupDatabaseConfiguration"]; }; InstallValidateDatabaseRequest: { database: components["schemas"]["InstallSetupDatabaseConfiguration"]; diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-context.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-context.ts index fa94721ad9..f54b0cef5a 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-context.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-context.ts @@ -1,28 +1,24 @@ -import { BehaviorSubject, Observable, ReplaySubject, Subject } from 'rxjs'; +import { BehaviorSubject, ReplaySubject } from 'rxjs'; import { getInstallSettings, postInstallSetup } from '../core/api/fetcher'; import { PostInstallRequest, UmbracoInstaller } from '../core/models'; export class UmbInstallerContext { - private _data: BehaviorSubject = new BehaviorSubject({ - name: '', - email: '', - password: '', - subscribeToNewsletter: false, + private _data = new BehaviorSubject({ + user: { name: '', email: '', password: '', subscribeToNewsletter: false }, telemetryLevel: 'Basic', - database: {}, }); - public readonly data: Observable = this._data.asObservable(); + public readonly data = this._data.asObservable(); - private _settings: Subject = new ReplaySubject(); - public readonly settings: Observable = this._settings.asObservable(); + private _settings = new ReplaySubject(); + public readonly settings = this._settings.asObservable(); constructor() { this.loadIntallerSettings(); } public appendData(data: any) { - this._data.next({ ...this._data.getValue(), ...data }); + this._data.next({ ...this.getData(), ...data }); } public getData() { @@ -30,11 +26,8 @@ export class UmbInstallerContext { } public requestInstall() { - return new Promise((resolve, reject) => { - postInstallSetup(this._data.getValue()).then(resolve, ({ data }) => { - reject(data); - }); - }); + // TODO: The post install will probably return a user in the future, so we have to set that context somewhere to let the client know that it is authenticated + return postInstallSetup(this.getData()); } private loadIntallerSettings() { diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts index 131ed51968..4bb21d3f46 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts @@ -115,8 +115,8 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { this.storeDataSubscription?.unsubscribe(); this.storeDataSubscription = installerStore.data.subscribe((data) => { - this.databaseFormData = data.database; - this._options.forEach((x, i) => (x.selected = data.database.databaseType === x.value || i === 0)); + this.databaseFormData = data.database ?? {}; + this._options.forEach((x, i) => (x.selected = data.database?.id === x.value || i === 0)); }); }); } @@ -148,22 +148,22 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { if (!isValid) return; const formData = new FormData(form); + const id = formData.get('id') as string; const username = formData.get('username') as string; const password = formData.get('password') as string; const server = formData.get('server') as string; - const databaseName = formData.get('databaseName') as string; - const databaseType = formData.get('databaseType') as string; + const name = formData.get('name') as string; const useIntegratedAuthentication = formData.has('useIntegratedAuthentication'); const database = { ...this._installerStore.getData().database, + id, username, password, server, - databaseName, - databaseType, + name, useIntegratedAuthentication, - }; + } as UmbracoPerformInstallDatabaseConfiguration; this._installerStore.appendData({ database }); this._installerStore.requestInstall().then(this._handleFulfilled.bind(this), this._handleRejected.bind(this)); @@ -182,7 +182,8 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { } private get selectedDatabase() { - const id = this._installerStore.getData().database.databaseType; + const id = this._installerStore.getData().database?.id; + console.log('selected id', id, this._databases); return this._databases.find((x) => x.id === id) ?? this._databases[0]; } @@ -229,9 +230,9 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { Database Name Database type diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-installing.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-installing.element.ts index 235c1b2b0a..37ebf2509c 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-installing.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-installing.element.ts @@ -25,7 +25,7 @@ export class UmbInstallerInstalling extends LitElement { if (this._installProgress >= 100) { // Redirect to backoffice - history.pushState(null, '', '/backoffice/backoffice'); + history.replaceState(null, '', '/'); return; } diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-user.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-user.element.ts index 18fdcb9b9c..e53bd64683 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-user.element.ts @@ -70,12 +70,12 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { this.consumeContext('umbInstallerContext', (installerStore: UmbInstallerContext) => { this._installerStore = installerStore; this.installerStoreSubscription?.unsubscribe(); - this.installerStoreSubscription = installerStore.data.subscribe((data) => { + this.installerStoreSubscription = installerStore.data.subscribe(({ user }) => { this._userFormData = { - name: data.name, - password: data.password, - email: data.email, - subscribeToNewsletter: data.subscribeToNewsletter, + name: user.name, + password: user.password, + email: user.email, + subscribeToNewsletter: user.subscribeToNewsletter, }; }); }); @@ -86,14 +86,6 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { this.installerStoreSubscription?.unsubscribe(); } - private _handleChange(e: InputEvent) { - const target = e.target as HTMLInputElement; - - const value: { [key: string]: string | boolean } = {}; - value[target.name] = target.checked ?? target.value; // handle boolean and text inputs - this._installerStore.appendData(value); - } - private _handleSubmit = (e: SubmitEvent) => { e.preventDefault(); @@ -109,7 +101,7 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { const email = formData.get('email'); const subscribeToNewsletter = formData.has('subscribeToNewsletter'); - this._installerStore.appendData({ name, password, email, subscribeToNewsletter }); + this._installerStore.appendData({ user: { name, password, email, subscribeToNewsletter } }); this.dispatchEvent(new CustomEvent('next', { bubbles: true, composed: true })); }; @@ -124,7 +116,6 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { type="text" id="name" .value=${this._userFormData.name} - @input=${this._handleChange} name="name" required required-message="Name is required"> @@ -136,7 +127,6 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { type="email" id="email" .value=${this._userFormData.email} - @input=${this._handleChange} name="email" required required-message="Email is required"> @@ -148,7 +138,6 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { id="password" name="password" .value=${this._userFormData.password} - @input=${this._handleChange} required required-message="Password is required"> @@ -157,7 +146,6 @@ export class UmbInstallerUser extends UmbContextConsumerMixin(LitElement) { Keep me updated on Umbraco Versions, Security Bulletins and Community News diff --git a/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts index e06c3e59e5..558fe436e8 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts @@ -75,7 +75,7 @@ export const handlers = [ rest.post('/umbraco/backoffice/install/setup', async (req, res, ctx) => { await new Promise((resolve) => setTimeout(resolve, (Math.random() + 1) * 1000)); // simulate a delay of 1-2 seconds - if (req.body.database.databaseName === 'fail') { + if (req.body.database?.name === 'fail') { return res( // Respond with a 200 status code ctx.status(400), @@ -83,7 +83,7 @@ export const handlers = [ type: 'validation', status: 400, errors: { - databaseName: ['Database name is invalid'], + name: ['Database name is invalid'], }, }) );