From dadbd21b0977092719e9a02a111333807cf47ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 00:12:35 +0100 Subject: [PATCH 01/45] add modal layout --- .../modal-layout-user-settings.element.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts new file mode 100644 index 0000000000..e469869741 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts @@ -0,0 +1,62 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, CSSResultGroup, html, LitElement } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbModalHandler } from '@umbraco-cms/services'; + +@customElement('umb-modal-layout-user-settings') +export class UmbModalLayoutUserSettingsElement extends LitElement { + static styles: CSSResultGroup = [ + UUITextStyles, + css` + :host { + display: block; + } + :host, + umb-editor-entity-layout { + width: 100%; + height: 100%; + } + #main { + padding: var(--uui-size-space-5); + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } + `, + ]; + + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + private _close() { + this.modalHandler?.close(); + } + + render() { + return html` + +
+ + Your profile + Edit + Logout + + + External login providers + Edit your Umbraco ID profile + Change your Umbraco ID password + +
+
+ Close +
+
+ `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-modal-layout-user-settings': UmbModalLayoutUserSettingsElement; + } +} From fe17aac8c9aca056587d271811ad4e3d88e75b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 00:12:56 +0100 Subject: [PATCH 02/45] add modal layout to modal service and user icon --- .../backoffice-header-tools.element.ts | 19 +++++++++++++++++-- .../src/core/services/modal/modal.service.ts | 11 +++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts index 0958b10c39..19adf9a7a8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts @@ -1,9 +1,11 @@ +import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UmbModalService } from '@umbraco-cms/services'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; @customElement('umb-backoffice-header-tools') -export class UmbBackofficeHeaderTools extends LitElement { +export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(LitElement) { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -19,6 +21,19 @@ export class UmbBackofficeHeaderTools extends LitElement { `, ]; + constructor() { + super(); + this.consumeContext('umbModalService', (modalService: UmbModalService) => { + this._modalService = modalService; + }); + } + + private _handleUserClick() { + this._modalService?.userSettings(); + } + + private _modalService?: UmbModalService; + render() { return html`
@@ -28,7 +43,7 @@ export class UmbBackofficeHeaderTools extends LitElement { - +
diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts index f8027a2cdf..3e9c966980 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts @@ -2,6 +2,7 @@ import './layouts/confirm/modal-layout-confirm.element'; import './layouts/content-picker/modal-layout-content-picker.element'; import './layouts/property-editor-ui-picker/modal-layout-property-editor-ui-picker.element'; +import './layouts/modal-layout-user-settings.element'; import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; import { BehaviorSubject, Observable } from 'rxjs'; @@ -68,6 +69,16 @@ export class UmbModalService { return this.open('umb-modal-layout-icon-picker', { data, type: 'sidebar', size: 'small' }); } + /** + * Opens the user settings sidebar modal + * @public + * @return {*} {UmbModalHandler} + * @memberof UmbModalService + */ + public userSettings(): UmbModalHandler { + return this.open('umb-modal-layout-user-settings', { type: 'sidebar', size: 'small' }); + } + /** * Opens a modal or sidebar modal * @public From f000ec0085565a880392bc9a86cf3ca11c9c5932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 00:14:59 +0100 Subject: [PATCH 03/45] rename to user dialog --- ...tings.element.ts => modal-layout-user-dialog.element.ts} | 6 +++--- .../src/core/services/modal/modal.service.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/{modal-layout-user-settings.element.ts => modal-layout-user-dialog.element.ts} (88%) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts similarity index 88% rename from src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts rename to src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index e469869741..ab1bcef066 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-settings.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -3,8 +3,8 @@ import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UmbModalHandler } from '@umbraco-cms/services'; -@customElement('umb-modal-layout-user-settings') -export class UmbModalLayoutUserSettingsElement extends LitElement { +@customElement('umb-modal-layout-user-dialog') +export class UmbModalLayoutUserDialogElement extends LitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -57,6 +57,6 @@ export class UmbModalLayoutUserSettingsElement extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-modal-layout-user-settings': UmbModalLayoutUserSettingsElement; + 'umb-modal-layout-user-dialog': UmbModalLayoutUserDialogElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts index 3e9c966980..e8a7d645dd 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts @@ -2,7 +2,7 @@ import './layouts/confirm/modal-layout-confirm.element'; import './layouts/content-picker/modal-layout-content-picker.element'; import './layouts/property-editor-ui-picker/modal-layout-property-editor-ui-picker.element'; -import './layouts/modal-layout-user-settings.element'; +import './layouts/modal-layout-user-dialog.element'; import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; import { BehaviorSubject, Observable } from 'rxjs'; @@ -76,7 +76,7 @@ export class UmbModalService { * @memberof UmbModalService */ public userSettings(): UmbModalHandler { - return this.open('umb-modal-layout-user-settings', { type: 'sidebar', size: 'small' }); + return this.open('umb-modal-layout-user-dialog', { type: 'sidebar', size: 'small' }); } /** From 1a7c37df6799f4110eea31b737bab521f70c5522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 22:18:23 +0100 Subject: [PATCH 04/45] add faked current user to user store --- .../src/core/stores/user/user.store.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts index d562b3fdd8..0d4a9a082b 100644 --- a/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts @@ -1,6 +1,5 @@ -import { BehaviorSubject, map, Observable } from 'rxjs'; -import { v4 as uuidv4 } from 'uuid'; -import type { UserDetails, UserEntity } from '../../models'; +import { BehaviorSubject, map, Observable, ReplaySubject, Subject } from 'rxjs'; +import type { UserDetails } from '../../models'; import { UmbEntityStore } from '../entity.store'; import { UmbDataStoreBase } from '../store'; @@ -16,9 +15,20 @@ export class UmbUserStore extends UmbDataStoreBase { private _totalUsers: BehaviorSubject = new BehaviorSubject(0); public readonly totalUsers: Observable = this._totalUsers.asObservable(); + private _currentUser: Subject = new ReplaySubject(); + public readonly currentUser: Observable = this._currentUser.asObservable(); + constructor(entityStore: UmbEntityStore) { super(); this._entityStore = entityStore; + + //TODO: Temp code to get the first user as the current user. Replace when login is implemented. + const subscription = this.getAll().subscribe((response) => { + if (response.length > 0) { + this._currentUser.next(response[0]); + subscription.unsubscribe(); + } + }); } getAll(): Observable> { From 24f5c32b24f10ed00dbb51098bc14b72b9feaa65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 22:18:38 +0100 Subject: [PATCH 05/45] add current user to header avatar --- .../backoffice-header-tools.element.ts | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts index 19adf9a7a8..f2f8a37a82 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts @@ -1,11 +1,14 @@ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UserDetails } from '@umbraco-cms/models'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbModalService } from '@umbraco-cms/services'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbUserStore } from 'src/core/stores/user/user.store'; @customElement('umb-backoffice-header-tools') -export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(LitElement) { +export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -23,8 +26,18 @@ export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(LitElement constructor() { super(); - this.consumeContext('umbModalService', (modalService: UmbModalService) => { - this._modalService = modalService; + this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { + this._userStore = instances['umbUserStore']; + this._modalService = instances['umbModalService']; + this._observeCurrentUser(); + }); + } + + private async _observeCurrentUser() { + if (!this._userStore) return; + + this.observe(this._userStore.currentUser, (currentUser) => { + this._currentUser = currentUser; }); } @@ -32,6 +45,10 @@ export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(LitElement this._modalService?.userSettings(); } + @state() + private _currentUser?: UserDetails; + + private _userStore?: UmbUserStore; private _modalService?: UmbModalService; render() { @@ -44,7 +61,7 @@ export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(LitElement - + `; From 586e947c8af45bbfe71b5103d51466c046be9340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 22:25:38 +0100 Subject: [PATCH 06/45] added redirecting to current user edit page --- .../modal-layout-user-dialog.element.ts | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index ab1bcef066..9fb582943e 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -1,10 +1,14 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; import { UmbModalHandler } from '@umbraco-cms/services'; +import type { UserDetails } from '@umbraco-cms/models'; +import { UmbUserStore } from 'src/core/stores/user/user.store'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; +import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; @customElement('umb-modal-layout-user-dialog') -export class UmbModalLayoutUserDialogElement extends LitElement { +export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -28,17 +32,44 @@ export class UmbModalLayoutUserDialogElement extends LitElement { @property({ attribute: false }) modalHandler?: UmbModalHandler; + @state() + private _currentUser?: UserDetails; + + private _userStore?: UmbUserStore; + + constructor() { + super(); + this.consumeAllContexts(['umbUserStore'], (instances) => { + this._userStore = instances['umbUserStore']; + this._observeCurrentUser(); + }); + } + + private async _observeCurrentUser() { + if (!this._userStore) return; + + this.observe(this._userStore.currentUser, (currentUser) => { + this._currentUser = currentUser; + }); + } + private _close() { this.modalHandler?.close(); } + private _edit() { + if (!this._currentUser) return; + history.pushState(null, '', '/section/users/view/users/user/' + this._currentUser.key); //TODO Change to a tag with href and make dynamic + this._close(); + } + render() { return html` - +
Your profile - Edit + Edit Logout From 9177a5b54d5c83d996add83a66460bdf7c593304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Wed, 23 Nov 2022 23:25:37 +0100 Subject: [PATCH 07/45] user editor: hide status and delete button on current user --- .../backoffice-header-tools.element.ts | 12 +-- .../editors/user/editor-user.element.ts | 90 ++++++++++++------- 2 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts index f2f8a37a82..dfc275d0f5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts @@ -24,6 +24,12 @@ export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(UmbObserve `, ]; + @state() + private _currentUser?: UserDetails; + + private _userStore?: UmbUserStore; + private _modalService?: UmbModalService; + constructor() { super(); this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { @@ -45,12 +51,6 @@ export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(UmbObserve this._modalService?.userSettings(); } - @state() - private _currentUser?: UserDetails; - - private _userStore?: UmbUserStore; - private _modalService?: UmbModalService; - render() { return html`
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index e6984408d8..8017ef3597 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -14,9 +14,12 @@ import type { ManifestEditorAction, ManifestWithLoader, UserDetails } from '@umb import '../../property-editor-uis/content-picker/property-editor-ui-content-picker.element'; import '../shared/editor-entity-layout/editor-entity-layout.element'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; @customElement('umb-editor-user') -export class UmbEditorUserElement extends UmbContextProviderMixin(UmbContextConsumerMixin(LitElement)) { +export class UmbEditorUserElement extends UmbContextProviderMixin( + UmbContextConsumerMixin(UmbObserverMixin(LitElement)) +) { static styles = [ UUITextStyles, css` @@ -91,6 +94,9 @@ export class UmbEditorUserElement extends UmbContextProviderMixin(UmbContextCons @state() private _user?: UserDetails | null; + @state() + private _currentUser?: UserDetails | null; + @state() private _userName = ''; @@ -107,10 +113,44 @@ export class UmbEditorUserElement extends UmbContextProviderMixin(UmbContextCons constructor() { super(); - + this.consumeAllContexts(['umbUserStore'], (instances) => { + this._userStore = instances['umbUserStore']; + this._observeCurrentUser(); + this._observeUser(); + }); this._registerEditorActions(); } + private async _observeCurrentUser() { + if (!this._userStore) return; + + this.observe(this._userStore.currentUser, (currentUser) => { + this._currentUser = currentUser; + }); + } + + private async _observeUser() { + if (!this._userStore) return; + + this.observe(this._userStore.getByKey(this.entityKey), (user) => { + this._user = user; + if (!this._user) return; + + if (!this._userContext) { + this._userContext = new UmbUserContext(this._user); + this.provideContext('umbUserContext', this._userContext); + } else { + this._userContext.update(this._user); + } + + this._userNameSubscription = this._userContext.data.subscribe((user) => { + if (user && user.name !== this._userName) { + this._userName = user.name; + } + }); + }); + } + private _registerEditorActions() { const manifests: Array> = [ { @@ -139,28 +179,6 @@ export class UmbEditorUserElement extends UmbContextProviderMixin(UmbContextCons }); } - private _observeUser() { - this._usersSubscription?.unsubscribe(); - - this._usersSubscription = this._userStore?.getByKey(this.entityKey).subscribe((user) => { - this._user = user; - if (!this._user) return; - - if (!this._userContext) { - this._userContext = new UmbUserContext(this._user); - this.provideContext('umbUserContext', this._userContext); - } else { - this._userContext.update(this._user); - } - - this._userNameSubscription = this._userContext.data.subscribe((user) => { - if (user && user.name !== this._userName) { - this._userName = user.name; - } - }); - }); - } - disconnectedCallback(): void { super.disconnectedCallback(); @@ -183,6 +201,19 @@ export class UmbEditorUserElement extends UmbContextProviderMixin(UmbContextCons history.pushState(null, '', '/section/users/view/users/overview'); } + private _renderActionButtons() { + return html` ${this._user?.status !== 'invited' + ? html` + + ` + : nothing} + `; + } + private renderLeftColumn() { if (!this._user) return nothing; @@ -246,16 +277,7 @@ export class UmbEditorUserElement extends UmbContextProviderMixin(UmbContextCons
- ${this._user?.status !== 'invited' - ? html` - - ` - : nothing} - + ${this._currentUser?.key !== this._user.key ? this._renderActionButtons() : nothing}
Status: From ecf667d577b3c9dab41fe2f22fc831d7b205382d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Thu, 24 Nov 2022 00:07:27 +0100 Subject: [PATCH 08/45] added change password dialog --- .../backoffice-header-tools.element.ts | 8 +- .../modal-layout-change-password.element.ts | 91 +++++++++++++++++++ .../modal-layout-user-dialog.element.ts | 14 ++- .../src/core/services/modal/modal.service.ts | 11 +++ 4 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts index dfc275d0f5..0c336cf22d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts @@ -1,10 +1,10 @@ -import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; -import { UserDetails } from '@umbraco-cms/models'; -import { UmbObserverMixin } from '@umbraco-cms/observable-api'; -import { UmbModalService } from '@umbraco-cms/services'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; +import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import type { UserDetails } from '@umbraco-cms/models'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; +import { UmbModalService } from '@umbraco-cms/services'; import { UmbUserStore } from 'src/core/stores/user/user.store'; @customElement('umb-backoffice-header-tools') diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts new file mode 100644 index 0000000000..4a7fbe4cdb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts @@ -0,0 +1,91 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, CSSResultGroup, html, LitElement } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; +import type { UserDetails } from '@umbraco-cms/models'; +import { UmbUserStore } from 'src/core/stores/user/user.store'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; +import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; + +@customElement('umb-modal-layout-change-password') +export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { + static styles: CSSResultGroup = [ + UUITextStyles, + css` + :host { + display: block; + } + :host, + umb-editor-entity-layout { + width: 100%; + height: 100%; + } + #main { + padding: var(--uui-size-space-5); + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } + `, + ]; + + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + private _close() { + this.modalHandler?.close(); + } + + private _handleSubmit(e: Event) { + e.preventDefault(); + console.log('IMPLEMENT SUBMIT'); + this._close(); + } + + render() { + return html` + + +
+ + Old password + + +
+ + New password + + + + Confirm password + + + + + +
+
+
+ `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-modal-layout-change-password': UmbModalLayoutChangePasswordElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index 9fb582943e..ceb30eab14 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -1,7 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbModalHandler } from '@umbraco-cms/services'; +import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; import type { UserDetails } from '@umbraco-cms/models'; import { UmbUserStore } from 'src/core/stores/user/user.store'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; @@ -36,11 +36,13 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb private _currentUser?: UserDetails; private _userStore?: UmbUserStore; + private _modalService?: UmbModalService; constructor() { super(); - this.consumeAllContexts(['umbUserStore'], (instances) => { + this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { this._userStore = instances['umbUserStore']; + this._modalService = instances['umbModalService']; this._observeCurrentUser(); }); } @@ -63,6 +65,11 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb this._close(); } + private _changePassword() { + if (!this._modalService) return; + this._modalService.changePassword(); + } + render() { return html` @@ -70,7 +77,7 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb Your profile Edit - Logout + Change password External login providers @@ -80,6 +87,7 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb
Close + Logout
`; diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts index e8a7d645dd..f7e1397884 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts @@ -3,6 +3,7 @@ import './layouts/confirm/modal-layout-confirm.element'; import './layouts/content-picker/modal-layout-content-picker.element'; import './layouts/property-editor-ui-picker/modal-layout-property-editor-ui-picker.element'; import './layouts/modal-layout-user-dialog.element'; +import './layouts/modal-layout-change-password.element'; import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; import { BehaviorSubject, Observable } from 'rxjs'; @@ -79,6 +80,16 @@ export class UmbModalService { return this.open('umb-modal-layout-user-dialog', { type: 'sidebar', size: 'small' }); } + /** + * Opens the user settings sidebar modal + * @public + * @return {*} {UmbModalHandler} + * @memberof UmbModalService + */ + public changePassword(): UmbModalHandler { + return this.open('umb-modal-layout-change-password', { type: 'dialog' }); + } + /** * Opens a modal or sidebar modal * @public From 5d15b87f0852f6c89cc214f6ff203ff0531eee64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Thu, 24 Nov 2022 21:51:53 +0100 Subject: [PATCH 09/45] change password: validation and no old password on admin --- .../editors/user/editor-user.element.ts | 19 ++++++-- .../modal-layout-change-password.element.ts | 46 +++++++++++++------ 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index 8017ef3597..a7020a3877 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -15,6 +15,7 @@ import '../../property-editor-uis/content-picker/property-editor-ui-content-pick import '../shared/editor-entity-layout/editor-entity-layout.element'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; +import { UmbModalService } from '@umbraco-cms/services'; @customElement('umb-editor-user') export class UmbEditorUserElement extends UmbContextProviderMixin( @@ -103,9 +104,10 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( @property({ type: String }) entityKey = ''; - protected _userStore?: UmbUserStore; - protected _usersSubscription?: Subscription; + private _userStore?: UmbUserStore; + private _usersSubscription?: Subscription; private _userContext?: UmbUserContext; + private _modalService?: UmbModalService; private _userNameSubscription?: Subscription; @@ -113,8 +115,10 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( constructor() { super(); - this.consumeAllContexts(['umbUserStore'], (instances) => { + this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { this._userStore = instances['umbUserStore']; + this._modalService = instances['umbModalService']; + this._observeCurrentUser(); this._observeUser(); }); @@ -201,7 +205,14 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( history.pushState(null, '', '/section/users/view/users/overview'); } + private _changePassword() { + this._modalService?.changePassword(); + } + private _renderActionButtons() { + if (this._currentUser?.key === this._user?.key) + return html` `; + return html` ${this._user?.status !== 'invited' ? html`
- ${this._currentUser?.key !== this._user.key ? this._renderActionButtons() : nothing} + ${this._renderActionButtons()}
Status: diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts index 4a7fbe4cdb..62695985a4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts @@ -1,5 +1,5 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, CSSResultGroup, html, LitElement } from 'lit'; +import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; import type { UserDetails } from '@umbraco-cms/models'; @@ -32,30 +32,50 @@ export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin @property({ attribute: false }) modalHandler?: UmbModalHandler; + @state() + private _requireOldPassword = false; //TODO: Implement check to see if current user is an admin. + private _close() { this.modalHandler?.close(); } - private _handleSubmit(e: Event) { + private _handleSubmit(e: SubmitEvent) { e.preventDefault(); - console.log('IMPLEMENT SUBMIT'); + + const form = e.target as HTMLFormElement; + if (!form) return; + + const isValid = form.checkValidity(); + if (!isValid) return; + + const formData = new FormData(form); + + const oldPassword = formData.get('oldPassword') as string; + const newPassword = formData.get('newPassword') as string; + const confirmPassword = formData.get('confirmPassword') as string; + console.log('IMPLEMENT SUBMIT', { oldPassword, newPassword, confirmPassword }); this._close(); } + private _renderOldPasswordInput() { + return html` + + Old password + + + `; + } + render() { return html` - +
- - Old password - - -
+ ${this._requireOldPassword ? this._renderOldPasswordInput() : nothing} New password Date: Fri, 25 Nov 2022 10:02:14 +0100 Subject: [PATCH 10/45] change password styling --- .../modal-layout-change-password.element.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts index 62695985a4..4223e2df85 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts @@ -14,17 +14,15 @@ export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin css` :host { display: block; + width: 400px; } - :host, - umb-editor-entity-layout { + uui-input-password { width: 100%; - height: 100%; } - #main { - padding: var(--uui-size-space-5); + #actions { display: flex; - flex-direction: column; - gap: var(--uui-size-space-3); + justify-content: flex-end; + margin-top: var(--uui-size-layout-2); } `, ]; @@ -95,8 +93,10 @@ export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin required-message="Confirm password is required"> - - +
+ + +
From 021081da9bd6774fd6a2a21eebf57ceea12770c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Fri, 25 Nov 2022 11:04:36 +0100 Subject: [PATCH 11/45] external login provider extension point and test extension --- .../src/backoffice/backoffice.element.ts | 2 + ...ternal-login-provider-extension.element.ts | 44 +++++++++++++++++++ .../external-login-provider-test.element.ts | 24 ++++++++++ .../external-login-providers/manifests.ts | 16 +++++++ .../registry/extension.registry.ts | 2 + .../external-login-provider.models.ts | 11 +++++ .../src/core/extensions-registry/models.ts | 8 +++- .../modal-layout-user-dialog.element.ts | 27 +++++++++++- 8 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-extension.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/core/extensions-registry/external-login-provider.models.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index e4969b2511..70ffa658fc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -31,6 +31,7 @@ import { manifests as propertyEditorUIManifests } from './property-editor-uis/ma import { manifests as treeManifests } from './trees/manifests'; import { manifests as editorManifests } from './editors/manifests'; import { manifests as propertyActionManifests } from './property-actions/manifests'; +import { manifests as externalLoginProviderManifests } from './external-login-providers/manifests'; import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import type { ManifestTypes, ManifestWithLoader } from '@umbraco-cms/models'; @@ -64,6 +65,7 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this._registerExtensions(propertyEditorModelManifests); this._registerExtensions(propertyEditorUIManifests); this._registerExtensions(propertyActionManifests); + this._registerExtensions(externalLoginProviderManifests); this._umbIconRegistry.attach(this); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-extension.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-extension.element.ts new file mode 100644 index 0000000000..db338650e1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-extension.element.ts @@ -0,0 +1,44 @@ +import { CSSResultGroup, html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { createExtensionElement } from '@umbraco-cms/extensions-api'; +import type { ManifestExternalLoginProvider } from '@umbraco-cms/models'; + +@customElement('umb-external-login-provider-extension') +export class UmbExternalLoginProviderExtensionElement extends LitElement { + static styles: CSSResultGroup = [UUITextStyles]; + + private _externalLoginProvider?: ManifestExternalLoginProvider; + + @property({ type: Object }) + public get externalLoginProvider(): ManifestExternalLoginProvider | undefined { + return this._externalLoginProvider; + } + public set externalLoginProvider(value: ManifestExternalLoginProvider | undefined) { + this._externalLoginProvider = value; + this._createElement(); + } + + @state() + private _element?: any; + + private async _createElement() { + if (!this.externalLoginProvider) return; + + try { + this._element = (await createExtensionElement(this.externalLoginProvider)) as any | undefined; + } catch (error) { + // TODO: loading JS failed so we should do some nice UI. (This does only happen if extension has a js prop, otherwise we concluded that no source was needed resolved the load.) + } + } + + render() { + return html`${this._element}`; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-external-login-provider-extension': UmbExternalLoginProviderExtensionElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts new file mode 100644 index 0000000000..af85d3cc4f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts @@ -0,0 +1,24 @@ +import { css, html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; + +@customElement('umb-external-login-provider-test') +export class UmbExternalLoginProviderTestElement extends UmbContextProviderMixin( + UmbContextConsumerMixin(UmbObserverMixin(LitElement)) +) { + static styles = [UUITextStyles, css``]; + + render() { + return html`
MY CUSTOM EXTENSION LETS GOO
`; + } +} + +export default UmbExternalLoginProviderTestElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-external-login-provider-test': UmbExternalLoginProviderTestElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts new file mode 100644 index 0000000000..affde880c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts @@ -0,0 +1,16 @@ +import type { ManifestExternalLoginProvider, ManifestWithLoader } from '@umbraco-cms/models'; + +export const manifests: Array> = [ + { + type: 'externalLoginProvider', + alias: 'Umb.ExternalLoginProvider.Test', + name: 'Test External Login Provider', + elementName: 'umb-external-login-provider-test', + loader: () => import('./external-login-provider-test.element'), + weight: 600, + meta: { + label: 'Test External Login Provider', + pathname: 'test/test/test', + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-api/registry/extension.registry.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-api/registry/extension.registry.ts index 8da2169429..eac7d95c11 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-api/registry/extension.registry.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-api/registry/extension.registry.ts @@ -15,6 +15,7 @@ import type { ManifestEditorAction, ManifestCustom, ManifestPackageView, + ManifestExternalLoginProvider, } from '../../models'; import { createExtensionElement } from '../create-extension-element.function'; @@ -67,6 +68,7 @@ export class UmbExtensionRegistry { extensionsOfType(type: 'packageView'): Observable>; extensionsOfType(type: 'entrypoint'): Observable>; extensionsOfType(type: 'custom'): Observable>; + extensionsOfType(type: 'externalLoginProvider'): Observable>; extensionsOfType(type: string): Observable>; extensionsOfType(type: string): Observable> { return this.extensions.pipe( diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/external-login-provider.models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/external-login-provider.models.ts new file mode 100644 index 0000000000..ebc0588bc9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/external-login-provider.models.ts @@ -0,0 +1,11 @@ +import type { ManifestElement } from './models'; + +export interface ManifestExternalLoginProvider extends ManifestElement { + type: 'externalLoginProvider'; + meta: MetaExternalLoginProvider; +} + +export interface MetaExternalLoginProvider { + label: string; + pathname: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts index f2193cc413..df15da06d4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts @@ -9,6 +9,7 @@ import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './pr import type { ManifestDashboard } from './dashboard.models'; import type { ManifestPropertyAction } from './property-action.models'; import type { ManifestPackageView } from './package-view.models'; +import type { ManifestExternalLoginProvider } from './external-login-provider.models'; export * from './section.models'; export * from './section-view.models'; @@ -21,6 +22,7 @@ export * from './property-editor.models'; export * from './dashboard.models'; export * from './property-action.models'; export * from './package-view.models'; +export * from './external-login-provider.models'; export type ManifestTypes = | ManifestSection @@ -36,7 +38,8 @@ export type ManifestTypes = | ManifestPropertyAction | ManifestPackageView | ManifestEntrypoint - | ManifestCustom; + | ManifestCustom + | ManifestExternalLoginProvider; export type ManifestStandardTypes = | 'section' @@ -51,7 +54,8 @@ export type ManifestStandardTypes = | 'dashboard' | 'propertyAction' | 'packageView' - | 'entrypoint'; + | 'entrypoint' + | 'externalLoginProvider'; export type ManifestElementType = | ManifestSection diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index ceb30eab14..107f69f32e 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -2,10 +2,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; -import type { UserDetails } from '@umbraco-cms/models'; +import type { ManifestExternalLoginProvider, UserDetails } from '@umbraco-cms/models'; import { UmbUserStore } from 'src/core/stores/user/user.store'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; +import '../../../../backoffice/external-login-providers/external-login-provider-extension.element'; @customElement('umb-modal-layout-user-dialog') export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -35,6 +37,9 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb @state() private _currentUser?: UserDetails; + @state() + private _externalLoginProviders: Array = []; + private _userStore?: UmbUserStore; private _modalService?: UmbModalService; @@ -45,6 +50,8 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb this._modalService = instances['umbModalService']; this._observeCurrentUser(); }); + + this._observeExternalLoginProviders(); } private async _observeCurrentUser() { @@ -55,6 +62,16 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb }); } + private _observeExternalLoginProviders() { + this.observe( + umbExtensionsRegistry.extensionsOfType('externalLoginProvider'), + (loginProvider) => { + this._externalLoginProviders = loginProvider; + console.log('loginProvider', loginProvider); + } + ); + } + private _close() { this.modalHandler?.close(); } @@ -84,6 +101,14 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb Edit your Umbraco ID profile Change your Umbraco ID password + +
+ ${this._externalLoginProviders.map( + (provider) => + html`` + )} +
Close From 60691e872ef1c8bfa4bde006778ded6a74800a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Fri, 25 Nov 2022 11:28:47 +0100 Subject: [PATCH 12/45] external login provider styling --- .../external-login-provider-test.element.ts | 24 +++++++++++++++++-- .../modal-layout-user-dialog.element.ts | 17 ++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts index af85d3cc4f..8d502d2e98 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test.element.ts @@ -8,10 +8,30 @@ import { UmbObserverMixin } from '@umbraco-cms/observable-api'; export class UmbExternalLoginProviderTestElement extends UmbContextProviderMixin( UmbContextConsumerMixin(UmbObserverMixin(LitElement)) ) { - static styles = [UUITextStyles, css``]; + static styles = [ + UUITextStyles, + css` + :host { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + padding: var(--uui-size-space-5); + border: 1px solid var(--uui-color-border); + background: var(--uui-color-surface-alt); + border-radius: var(--uui-border-radius); + } + p { + margin: 0; + } + `, + ]; render() { - return html`
MY CUSTOM EXTENSION LETS GOO
`; + return html` + Custom External Login Provider +

This is an example of a custom external login provider using the external login provider extension point

+ + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index 107f69f32e..4b22d1685d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -28,6 +28,11 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb flex-direction: column; gap: var(--uui-size-space-3); } + #umbraco-id-buttons { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } `, ]; @@ -98,17 +103,17 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb External login providers - Edit your Umbraco ID profile - Change your Umbraco ID password - - -
+
+ Edit your Umbraco ID profile + Change your Umbraco ID password +
+
${this._externalLoginProviders.map( (provider) => html`` )} -
+
Close From 8557c366bb158796b6e87398022d1fc5a569fdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Fri, 25 Nov 2022 11:34:39 +0100 Subject: [PATCH 13/45] more external login provider examples --- .../external-login-provider-test2.element.ts | 57 +++++++++++++++++++ .../external-login-providers/manifests.ts | 14 ++++- .../modal-layout-user-dialog.element.ts | 4 ++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test2.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test2.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test2.element.ts new file mode 100644 index 0000000000..955ad87749 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/external-login-provider-test2.element.ts @@ -0,0 +1,57 @@ +import { css, html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; + +@customElement('umb-external-login-provider-test2') +export class UmbExternalLoginProviderTest2Element extends UmbContextProviderMixin( + UmbContextConsumerMixin(UmbObserverMixin(LitElement)) +) { + static styles = [ + UUITextStyles, + css` + :host { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + padding: var(--uui-size-space-5); + border: 1px solid var(--uui-color-border); + background: var(--uui-color-surface-alt); + border-radius: var(--uui-border-radius); + } + p { + margin: 0; + } + uui-input { + width: 100%; + } + `, + ]; + + render() { + return html` + Another Custom External Login Provider +

This is an example of another custom external login provider

+ + Email + + + + `; + } +} + +export default UmbExternalLoginProviderTest2Element; + +declare global { + interface HTMLElementTagNameMap { + 'umb-external-login-provider-test2': UmbExternalLoginProviderTest2Element; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts index affde880c2..5812b461c8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts @@ -7,10 +7,22 @@ export const manifests: Array> name: 'Test External Login Provider', elementName: 'umb-external-login-provider-test', loader: () => import('./external-login-provider-test.element'), - weight: 600, + weight: 2, meta: { label: 'Test External Login Provider', pathname: 'test/test/test', }, }, + { + type: 'externalLoginProvider', + alias: 'Umb.ExternalLoginProvider.Test2', + name: 'Test External Login Provider 2', + elementName: 'umb-external-login-provider-test2', + loader: () => import('./external-login-provider-test2.element'), + weight: 1, + meta: { + label: 'Test External Login Provider 2', + pathname: 'test/test/test', + }, + }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index 4b22d1685d..c74d824953 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -33,6 +33,10 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb flex-direction: column; gap: var(--uui-size-space-3); } + umb-external-login-provider-extension:not(:last-child) { + margin-bottom: var(--uui-size-space-3); + display: block; + } `, ]; From bce31c40c67b0c96f4e47050568bf13c55706972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Fri, 25 Nov 2022 12:13:14 +0100 Subject: [PATCH 14/45] user dashboard extension point at test extension --- .../src/backoffice/backoffice.element.ts | 2 + .../backoffice/user-dashboards/manifests.ts | 16 +++++++ .../user-dashboard-extension.element.ts | 44 +++++++++++++++++++ .../user-dashboard-test.element.ts | 44 +++++++++++++++++++ .../src/core/extensions-registry/models.ts | 8 +++- .../user-dashboard.models.ts | 11 +++++ .../modal-layout-user-dialog.element.ts | 27 +++++++++--- 7 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-extension.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-test.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index 70ffa658fc..ec29944136 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -32,6 +32,7 @@ import { manifests as treeManifests } from './trees/manifests'; import { manifests as editorManifests } from './editors/manifests'; import { manifests as propertyActionManifests } from './property-actions/manifests'; import { manifests as externalLoginProviderManifests } from './external-login-providers/manifests'; +import { manifests as userDashboards } from './user-dashboards/manifests'; import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import type { ManifestTypes, ManifestWithLoader } from '@umbraco-cms/models'; @@ -66,6 +67,7 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this._registerExtensions(propertyEditorUIManifests); this._registerExtensions(propertyActionManifests); this._registerExtensions(externalLoginProviderManifests); + this._registerExtensions(userDashboards); this._umbIconRegistry.attach(this); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts new file mode 100644 index 0000000000..d3bc69a31c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts @@ -0,0 +1,16 @@ +import type { ManifestExternalLoginProvider, ManifestWithLoader } from '@umbraco-cms/models'; + +export const manifests: Array> = [ + { + type: 'userDashboard', + alias: 'Umb.UserDashboard.Test', + name: 'Test User Dashboard', + elementName: 'umb-user-dashboard-test', + loader: () => import('./user-dashboard-test.element'), + weight: 2, + meta: { + label: 'Test User Dashboard', + pathname: 'test/test/test', + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-extension.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-extension.element.ts new file mode 100644 index 0000000000..85ad951331 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-extension.element.ts @@ -0,0 +1,44 @@ +import { CSSResultGroup, html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { createExtensionElement } from '@umbraco-cms/extensions-api'; +import type { ManifestUserDashboard } from '@umbraco-cms/models'; + +@customElement('umb-user-dashboard-extension') +export class UmbUserDashboardExtensionElement extends LitElement { + static styles: CSSResultGroup = [UUITextStyles]; + + private _userDashboard?: ManifestUserDashboard; + + @property({ type: Object }) + public get userDashboard(): ManifestUserDashboard | undefined { + return this._userDashboard; + } + public set userDashboard(value: ManifestUserDashboard | undefined) { + this._userDashboard = value; + this._createElement(); + } + + @state() + private _element?: any; + + private async _createElement() { + if (!this.userDashboard) return; + + try { + this._element = (await createExtensionElement(this.userDashboard)) as any | undefined; + } catch (error) { + // TODO: loading JS failed so we should do some nice UI. (This does only happen if extension has a js prop, otherwise we concluded that no source was needed resolved the load.) + } + } + + render() { + return html`${this._element}`; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-dashboard-extension': UmbUserDashboardExtensionElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-test.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-test.element.ts new file mode 100644 index 0000000000..ede0abf1ff --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/user-dashboard-test.element.ts @@ -0,0 +1,44 @@ +import { css, html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; + +@customElement('umb-user-dashboard-test') +export class UmbUserDashboardTestElement extends UmbContextProviderMixin( + UmbContextConsumerMixin(UmbObserverMixin(LitElement)) +) { + static styles = [ + UUITextStyles, + css` + :host { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + padding: var(--uui-size-space-5); + border: 1px solid var(--uui-color-border); + background: var(--uui-color-positive); + color: var(--uui-color-positive-contrast); + border-radius: var(--uui-border-radius); + } + p { + margin: 0; + } + `, + ]; + + render() { + return html` + Custom User Dashboard +

This is an example of a custom user dashboard using the user dashboard extension point

+ `; + } +} + +export default UmbUserDashboardTestElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-dashboard-test': UmbUserDashboardTestElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts index df15da06d4..076f86078a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts @@ -10,6 +10,7 @@ import type { ManifestDashboard } from './dashboard.models'; import type { ManifestPropertyAction } from './property-action.models'; import type { ManifestPackageView } from './package-view.models'; import type { ManifestExternalLoginProvider } from './external-login-provider.models'; +import { ManifestUserDashboard } from './user-dashboard.models'; export * from './section.models'; export * from './section-view.models'; @@ -23,6 +24,7 @@ export * from './dashboard.models'; export * from './property-action.models'; export * from './package-view.models'; export * from './external-login-provider.models'; +export * from './user-dashboard.models'; export type ManifestTypes = | ManifestSection @@ -39,7 +41,8 @@ export type ManifestTypes = | ManifestPackageView | ManifestEntrypoint | ManifestCustom - | ManifestExternalLoginProvider; + | ManifestExternalLoginProvider + | ManifestUserDashboard; export type ManifestStandardTypes = | 'section' @@ -55,7 +58,8 @@ export type ManifestStandardTypes = | 'propertyAction' | 'packageView' | 'entrypoint' - | 'externalLoginProvider'; + | 'externalLoginProvider' + | 'userDashboard'; export type ManifestElementType = | ManifestSection diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts new file mode 100644 index 0000000000..a9fd823c55 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts @@ -0,0 +1,11 @@ +import type { ManifestElement } from './models'; + +export interface ManifestUserDashboard extends ManifestElement { + type: 'userDashboard'; + meta: MetaUserDashboard; +} + +export interface MetaUserDashboard { + label: string; + pathname: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index c74d824953..8918cb3214 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -2,12 +2,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; -import type { ManifestExternalLoginProvider, UserDetails } from '@umbraco-cms/models'; +import type { ManifestExternalLoginProvider, ManifestUserDashboard, UserDetails } from '@umbraco-cms/models'; import { UmbUserStore } from 'src/core/stores/user/user.store'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import '../../../../backoffice/external-login-providers/external-login-provider-extension.element'; +import '../../../../backoffice/user-dashboards/user-dashboard-extension.element'; @customElement('umb-modal-layout-user-dialog') export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -49,6 +50,9 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb @state() private _externalLoginProviders: Array = []; + @state() + private _userDashboards: Array = []; + private _userStore?: UmbUserStore; private _modalService?: UmbModalService; @@ -61,6 +65,7 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb }); this._observeExternalLoginProviders(); + this._observeUserDashboards(); } private async _observeCurrentUser() { @@ -76,11 +81,17 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb umbExtensionsRegistry.extensionsOfType('externalLoginProvider'), (loginProvider) => { this._externalLoginProviders = loginProvider; - console.log('loginProvider', loginProvider); } ); } + private _observeUserDashboards() { + this.observe(umbExtensionsRegistry.extensionsOfType('userDashboard'), (userDashboard) => { + this._userDashboards = userDashboard; + console.log(this._userDashboards); + }); + } + private _close() { this.modalHandler?.close(); } @@ -107,17 +118,19 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb External login providers -
- Edit your Umbraco ID profile - Change your Umbraco ID password -
-
${this._externalLoginProviders.map( (provider) => html`` )}
+ + User Dashboards + ${this._userDashboards.map( + (provider) => + html`` + )} +
Close From 17d0876716aad4a799f2bb050eb2a9428e90b107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Fri, 25 Nov 2022 15:39:56 +0100 Subject: [PATCH 15/45] fix styling --- .../modal/layouts/modal-layout-user-dialog.element.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index 8918cb3214..d75c9c6c32 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -124,13 +124,12 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb .externalLoginProvider=${provider}>` )} - - User Dashboards +
${this._userDashboards.map( (provider) => html`` )} - +
Close From ffcb9d4c2f49fa9ad73990f671d083017f959321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 09:40:07 +0100 Subject: [PATCH 16/45] add history service --- .../src/backoffice/backoffice.element.ts | 2 ++ .../core/services/history/history.service.ts | 32 +++++++++++++++++++ .../src/core/services/history/index.ts | 1 + 3 files changed, 35 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts create mode 100644 src/Umbraco.Web.UI.Client/src/core/services/history/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index ec29944136..1ae4f5c181 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -36,6 +36,7 @@ import { manifests as userDashboards } from './user-dashboards/manifests'; import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import type { ManifestTypes, ManifestWithLoader } from '@umbraco-cms/models'; +import { UmbHistoryService } from 'src/core/services/history'; @defineElement('umb-backoffice') export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProviderMixin(LitElement)) { @@ -78,6 +79,7 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this.provideContext('umbUserStore', new UmbUserStore(this._umbEntityStore)); this.provideContext('umbUserGroupStore', new UmbUserGroupStore(this._umbEntityStore)); this.provideContext('umbNotificationService', new UmbNotificationService()); + this.provideContext('umbHistoryService', new UmbHistoryService()); this.provideContext('umbModalService', new UmbModalService()); this.provideContext('umbSectionStore', new UmbSectionStore()); } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts new file mode 100644 index 0000000000..fac73ae8d7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts @@ -0,0 +1,32 @@ +import { BehaviorSubject, Observable } from 'rxjs'; + +export type UmbModelType = 'dialog' | 'sidebar'; + +export type UmbHistoryItem = { + path: string; + icon?: string; +}; + +export class UmbHistoryService { + private _history: BehaviorSubject> = new BehaviorSubject(>[]); + public readonly history: Observable> = this._history.asObservable(); + + /** + * Pushes a new history item to the history array + * @public + * @param {UmbHistoryItem} historyItem + * @memberof UmbHistoryService + */ + public push(historyItem: UmbHistoryItem): void { + this._history.next([...this._history.getValue(), historyItem]); + } + + /** + * Clears the history array + * @public + * @memberof UmbHistoryService + */ + public clear() { + this._history.next([]); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/index.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/index.ts new file mode 100644 index 0000000000..76f55618be --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/services/history/index.ts @@ -0,0 +1 @@ +export * from './history.service'; From 1be01a7599504b03f6949177a5f8e8fe440dd13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 09:43:26 +0100 Subject: [PATCH 17/45] fix user dashboard manifest --- .../src/backoffice/user-dashboards/manifests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts index d3bc69a31c..9259cad147 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts @@ -1,6 +1,6 @@ -import type { ManifestExternalLoginProvider, ManifestWithLoader } from '@umbraco-cms/models'; +import type { ManifestUserDashboard, ManifestWithLoader } from '@umbraco-cms/models'; -export const manifests: Array> = [ +export const manifests: Array> = [ { type: 'userDashboard', alias: 'Umb.UserDashboard.Test', From e6c163e59be06f7a92f6dd90b64b3d921d1b4681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 10:40:24 +0100 Subject: [PATCH 18/45] render history items --- .../core/services/history/history.service.ts | 15 +++- .../modal-layout-user-dialog.element.ts | 89 ++++++++++++++++--- 2 files changed, 93 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts index fac73ae8d7..380a12e166 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts @@ -4,11 +4,24 @@ export type UmbModelType = 'dialog' | 'sidebar'; export type UmbHistoryItem = { path: string; + label: string | Array; icon?: string; }; export class UmbHistoryService { - private _history: BehaviorSubject> = new BehaviorSubject(>[]); + private _history: BehaviorSubject> = new BehaviorSubject(>[ + { label: 'Users grid', path: 'section/users/view/users/overview/grid' }, + { label: ['User', 'Nat Linnane'], path: 'section/users/view/users/user/50f184d4-71f3-4a43-b8be-7a36340fbd0d' }, + { + label: ['User Group', 'Administrator'], + path: 'section/users/view/users/userGroup/10000000-0000-0000-0000-000000000000', + }, + { label: 'About us', path: 'section/content/document/74e4008a-ea4f-4793-b924-15e02fd380d2/view/content' }, + { + label: ['Blog', 'Look at this nice history page!'], + path: 'section/content/document/74e4008a-ea4f-4793-b924-15e02fd380d2/view/content', + }, + ]); public readonly history: Observable> = this._history.asObservable(); /** diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index d75c9c6c32..2ba707912d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -1,6 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, CSSResultGroup, html, LitElement } from 'lit'; +import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; +import { UmbHistoryItem, UmbHistoryService } from '../../history'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; import type { ManifestExternalLoginProvider, ManifestUserDashboard, UserDetails } from '@umbraco-cms/models'; import { UmbUserStore } from 'src/core/stores/user/user.store'; @@ -38,6 +39,33 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb margin-bottom: var(--uui-size-space-3); display: block; } + #recent-history { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } + #recent-history-items { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-2); + } + .history-item { + color: inherit; + text-decoration: none; + } + .history-item-name-separator { + margin: 0 var(--uui-size-space-1); + } + .history-item-path, + .history-item-name-separator { + opacity: 0.4; + } + .history-item-name, + .history-item-path { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } `, ]; @@ -53,29 +81,27 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb @state() private _userDashboards: Array = []; + @state() + private _history: Array = []; + private _userStore?: UmbUserStore; private _modalService?: UmbModalService; + private _historyService?: UmbHistoryService; constructor() { super(); - this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { + this.consumeAllContexts(['umbUserStore', 'umbModalService', 'umbHistoryService'], (instances) => { this._userStore = instances['umbUserStore']; this._modalService = instances['umbModalService']; + this._historyService = instances['umbHistoryService']; this._observeCurrentUser(); + this._observeHistory(); }); this._observeExternalLoginProviders(); this._observeUserDashboards(); } - private async _observeCurrentUser() { - if (!this._userStore) return; - - this.observe(this._userStore.currentUser, (currentUser) => { - this._currentUser = currentUser; - }); - } - private _observeExternalLoginProviders() { this.observe( umbExtensionsRegistry.extensionsOfType('externalLoginProvider'), @@ -85,6 +111,21 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb ); } + private async _observeCurrentUser() { + if (!this._userStore) return; + + this.observe(this._userStore.currentUser, (currentUser) => { + this._currentUser = currentUser; + }); + } + private async _observeHistory() { + if (!this._historyService) return; + + this.observe>(this._historyService.history, (history) => { + this._history = history; + }); + } + private _observeUserDashboards() { this.observe(umbExtensionsRegistry.extensionsOfType('userDashboard'), (userDashboard) => { this._userDashboards = userDashboard; @@ -107,6 +148,30 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb this._modalService.changePassword(); } + private _renderHistoryItem(item: UmbHistoryItem) { + if (typeof item.label === 'string') { + return html` +
${item.label}
+
`; + } + if (Array.isArray(item.label)) { + console.log('hallo', item); + + return html` + +
+ ${item.label.map((name, index) => { + return html`${name}${index < item.label.length - 1 ? '>' : nothing}`; + })} +
+
+ `; + } + + return nothing; + } + render() { return html` @@ -130,6 +195,10 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb html`` )}
+
+ Recent History +
${this._history.map((item) => html`${this._renderHistoryItem(item)}`)}
+
Close From 9b7a7bb326590962f8969bad8d853850f5121d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 10:43:43 +0100 Subject: [PATCH 19/45] make history service static --- .../src/backoffice/backoffice.element.ts | 3 --- .../src/core/services/history/history.service.ts | 4 +++- .../layouts/modal-layout-user-dialog.element.ts | 12 ++++-------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index 1ae4f5c181..a5dde252d9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -36,8 +36,6 @@ import { manifests as userDashboards } from './user-dashboards/manifests'; import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import type { ManifestTypes, ManifestWithLoader } from '@umbraco-cms/models'; -import { UmbHistoryService } from 'src/core/services/history'; - @defineElement('umb-backoffice') export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProviderMixin(LitElement)) { static styles = [ @@ -79,7 +77,6 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this.provideContext('umbUserStore', new UmbUserStore(this._umbEntityStore)); this.provideContext('umbUserGroupStore', new UmbUserGroupStore(this._umbEntityStore)); this.provideContext('umbNotificationService', new UmbNotificationService()); - this.provideContext('umbHistoryService', new UmbHistoryService()); this.provideContext('umbModalService', new UmbModalService()); this.provideContext('umbSectionStore', new UmbSectionStore()); } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts index 380a12e166..1c346626be 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts @@ -8,7 +8,7 @@ export type UmbHistoryItem = { icon?: string; }; -export class UmbHistoryService { +class UmbHistoryService { private _history: BehaviorSubject> = new BehaviorSubject(>[ { label: 'Users grid', path: 'section/users/view/users/overview/grid' }, { label: ['User', 'Nat Linnane'], path: 'section/users/view/users/user/50f184d4-71f3-4a43-b8be-7a36340fbd0d' }, @@ -43,3 +43,5 @@ export class UmbHistoryService { this._history.next([]); } } + +export const umbHistoryService = new UmbHistoryService(); diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index 2ba707912d..86edf87f9a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -1,7 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbHistoryItem, UmbHistoryService } from '../../history'; +import { UmbHistoryItem, umbHistoryService } from '../../history'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; import type { ManifestExternalLoginProvider, ManifestUserDashboard, UserDetails } from '@umbraco-cms/models'; import { UmbUserStore } from 'src/core/stores/user/user.store'; @@ -86,19 +86,17 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb private _userStore?: UmbUserStore; private _modalService?: UmbModalService; - private _historyService?: UmbHistoryService; constructor() { super(); - this.consumeAllContexts(['umbUserStore', 'umbModalService', 'umbHistoryService'], (instances) => { + this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { this._userStore = instances['umbUserStore']; this._modalService = instances['umbModalService']; - this._historyService = instances['umbHistoryService']; this._observeCurrentUser(); - this._observeHistory(); }); this._observeExternalLoginProviders(); + this._observeHistory(); this._observeUserDashboards(); } @@ -119,9 +117,7 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb }); } private async _observeHistory() { - if (!this._historyService) return; - - this.observe>(this._historyService.history, (history) => { + this.observe>(umbHistoryService.history, (history) => { this._history = history; }); } From 9e8d825fae000cda11fd43bcf00c4eb88c813f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 10:49:11 +0100 Subject: [PATCH 20/45] remove path --- .../modal/layouts/modal-layout-user-dialog.element.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index 86edf87f9a..b4d145f22e 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -56,12 +56,11 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb .history-item-name-separator { margin: 0 var(--uui-size-space-1); } - .history-item-path, + .history-item-name-separator { opacity: 0.4; } - .history-item-name, - .history-item-path { + .history-item-name { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; From 9b73c7a359d8f668c8b7c2ad77ba29925a050437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 11:05:43 +0100 Subject: [PATCH 21/45] prevent duplicates in history --- .../core/services/history/history.service.ts | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts index 1c346626be..f1037e3816 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts @@ -9,19 +9,7 @@ export type UmbHistoryItem = { }; class UmbHistoryService { - private _history: BehaviorSubject> = new BehaviorSubject(>[ - { label: 'Users grid', path: 'section/users/view/users/overview/grid' }, - { label: ['User', 'Nat Linnane'], path: 'section/users/view/users/user/50f184d4-71f3-4a43-b8be-7a36340fbd0d' }, - { - label: ['User Group', 'Administrator'], - path: 'section/users/view/users/userGroup/10000000-0000-0000-0000-000000000000', - }, - { label: 'About us', path: 'section/content/document/74e4008a-ea4f-4793-b924-15e02fd380d2/view/content' }, - { - label: ['Blog', 'Look at this nice history page!'], - path: 'section/content/document/74e4008a-ea4f-4793-b924-15e02fd380d2/view/content', - }, - ]); + private _history: BehaviorSubject> = new BehaviorSubject(>[]); public readonly history: Observable> = this._history.asObservable(); /** @@ -31,7 +19,18 @@ class UmbHistoryService { * @memberof UmbHistoryService */ public push(historyItem: UmbHistoryItem): void { - this._history.next([...this._history.getValue(), historyItem]); + const history = this._history.getValue(); + const lastItem = history[history.length - 1]; + + // This prevents duplicate entries in the history array. + if (!lastItem || lastItem.path !== historyItem.path) { + this._history.next([...this._history.getValue(), historyItem]); + } else { + //Update existing item + const newHistory = this._history.getValue(); + newHistory[history.length - 1] = historyItem; + this._history.next(newHistory); + } } /** From 94cd54293f269ce1f2f5fb6a3f8c7df06c35884d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 11:05:52 +0100 Subject: [PATCH 22/45] implement recent history --- .../src/backoffice/editors/user/editor-user.element.ts | 4 ++++ .../list-view-layouts/grid/editor-view-users-grid.element.ts | 2 ++ .../table/editor-view-users-table.element.ts | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index a7020a3877..3fd2a81d29 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -16,6 +16,7 @@ import '../shared/editor-entity-layout/editor-entity-layout.element'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbModalService } from '@umbraco-cms/services'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-user') export class UmbEditorUserElement extends UmbContextProviderMixin( @@ -115,6 +116,7 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( constructor() { super(); + this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { this._userStore = instances['umbUserStore']; this._modalService = instances['umbModalService']; @@ -140,6 +142,8 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( this._user = user; if (!this._user) return; + umbHistoryService.push({ label: ['Users', user.name], path: 'section/users/view/users/user/' + user.key }); + if (!this._userContext) { this._userContext = new UmbUserContext(this._user); this.provideContext('umbUserContext', this._userContext); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts index 5193831ec3..22e80bf7e3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts @@ -9,6 +9,7 @@ import { UmbUserStore } from '../../../../../../../core/stores/user/user.store'; import { getTagLookAndColor } from '../../../../user-extensions'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import type { UserDetails, UserEntity } from '@umbraco-cms/models'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-view-users-grid') export class UmbEditorViewUsersGridElement extends UmbContextConsumerMixin(LitElement) { @@ -53,6 +54,7 @@ export class UmbEditorViewUsersGridElement extends UmbContextConsumerMixin(LitEl connectedCallback(): void { super.connectedCallback(); + umbHistoryService.push({ label: 'Users grid', path: 'section/users/view/users/overview/grid' }); this.consumeContext('umbUserStore', (userStore: UmbUserStore) => { this._userStore = userStore; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts index 9592318b80..e131786a79 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts @@ -18,6 +18,7 @@ import type { UserDetails } from '@umbraco-cms/models'; import './column-layouts/name/user-table-name-column-layout.element'; import './column-layouts/status/user-table-status-column-layout.element'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-view-users-table') export class UmbEditorViewUsersTableElement extends UmbContextConsumerMixin(LitElement) { @@ -75,6 +76,7 @@ export class UmbEditorViewUsersTableElement extends UmbContextConsumerMixin(LitE connectedCallback(): void { super.connectedCallback(); + umbHistoryService.push({ label: 'Users list', path: 'section/users/view/users/overview/list' }); this.consumeContext('umbUserStore', (userStore: UmbUserStore) => { this._userStore = userStore; From a2c60cee659230181e51f9accb4e95d30bef1cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Mon, 28 Nov 2022 11:26:58 +0100 Subject: [PATCH 23/45] packages and settings history --- .../dashboard-examine-management.element.ts | 12 ++++++++++++ .../views/section-view-examine-indexers.ts | 5 +++++ .../dashboard-models-builder.element.ts | 9 +++++++++ .../dashboard-published-status.element.ts | 5 +++++ .../telemetry/dashboard-telemetry.element.ts | 5 +++++ .../created/section-view-packages-created.element.ts | 6 ++++++ .../section-view-packages-installed.element.ts | 6 ++++++ .../views/repo/section-view-packages-repo.element.ts | 8 ++++++++ .../user-groups/editor-view-user-groups.element.ts | 12 ++++++------ 9 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts index f3b68b97a1..c086ee997c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts @@ -6,6 +6,7 @@ import { UmbDashboardExamineIndexElement } from './views/section-view-examine-in import { UmbDashboardExamineSearcherElement } from './views/section-view-examine-searchers'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-examine-management') export class UmbDashboardExamineManagementElement extends UmbContextConsumerMixin(LitElement) { @@ -48,6 +49,17 @@ export class UmbDashboardExamineManagementElement extends UmbContextConsumerMixi @state() private _currentPath?: string; + /** + * + */ + constructor() { + super(); + umbHistoryService.push({ + label: ['Settings', 'Examine Management'], + path: 'section/settings/dashboard/examine-management', + }); + } + private _onRouteChange() { this._currentPath = path(); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts index 188c5f0a73..8e70c340ae 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts @@ -10,6 +10,7 @@ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import './section-view-examine-searchers'; import { ApiError, ProblemDetails, Index, SearchResource } from '@umbraco-cms/backend-api'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-examine-index') export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(LitElement) { @@ -95,6 +96,10 @@ export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(Lit try { const index = await SearchResource.getSearchIndexByIndexName({ indexName: this.indexName }); this._indexData = index; + umbHistoryService.push({ + label: ['Settings', 'Examine Management', this._indexData.name], + path: 'section/settings/dashboard/examine-management/index/ExternalIndex/' + this._indexData.name, + }); } catch (e) { if (e instanceof ApiError) { const error = e as ProblemDetails; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts index ee13ac50d5..ead297d2d4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts @@ -1,11 +1,20 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-models-builder') export class UmbDashboardModelsBuilderElement extends LitElement { static styles = [UUITextStyles, css``]; + constructor() { + super(); + umbHistoryService.push({ + label: ['Settings', 'Models Builder'], + path: 'section/settings/dashboard/models-builder', + }); + } + render() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts index 6d0d24b0be..41d33c6989 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts @@ -9,6 +9,7 @@ import { UmbNotificationDefaultData } from '../../../core/services/notification/ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import { ApiError, ProblemDetails, PublishedCacheResource } from '@umbraco-cms/backend-api'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-published-status') export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(LitElement) { @@ -44,6 +45,10 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( constructor() { super(); + umbHistoryService.push({ + label: ['Settings', 'Published Status'], + path: 'section/settings/dashboard/published-status', + }); this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => { this._notificationService = instances['umbNotificationService']; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts index d9c7f30e58..81012c0319 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts @@ -3,6 +3,7 @@ import { css, html, LitElement } from 'lit'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { customElement, state } from 'lit/decorators.js'; import { ApiError, ProblemDetails, Telemetry, TelemetryLevel, TelemetryResource } from '@umbraco-cms/backend-api'; +import { umbHistoryService } from 'src/core/services/history'; export type SettingOption = 'Minimal' | 'Basic' | 'Detailed'; @@ -28,6 +29,10 @@ export class UmbDashboardTelemetryElement extends LitElement { constructor() { super(); + umbHistoryService.push({ + label: ['Settings', 'Telemetry Data'], + path: 'section/settings/dashboard/telemetry', + }); } connectedCallback(): void { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts index eb846fe01b..25f672a05e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts @@ -1,6 +1,7 @@ import { html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { IRoute, IRoutingInfo } from 'router-slot'; +import { umbHistoryService } from 'src/core/services/history'; import { UmbEditorEntityElement } from '../../../../editors/shared/editor-entity/editor-entity.element'; @customElement('umb-section-view-packages-created') @@ -26,6 +27,11 @@ export class UmbSectionViewPackagesCreatedElement extends LitElement { }, ]; + constructor() { + super(); + umbHistoryService.push({ label: ['Packages', 'Created'], path: 'section/packages/view/created/overview' }); + } + render() { return html``; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts index 42a9355f04..0eafecd484 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts @@ -1,6 +1,7 @@ import { html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { IRoute, IRoutingInfo } from 'router-slot'; +import { umbHistoryService } from 'src/core/services/history'; import { UmbEditorEntityElement } from '../../../../editors/shared/editor-entity/editor-entity.element'; @customElement('umb-section-view-packages-installed') @@ -26,6 +27,11 @@ export class UmbSectionViewPackagesInstalledElement extends LitElement { }, ]; + constructor() { + super(); + umbHistoryService.push({ label: ['Packages', 'Installed'], path: 'section/packages/view/installed/overview' }); + } + render() { return html``; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts index 74e3136a3f..a0dfec9e88 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts @@ -1,8 +1,16 @@ import { html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-section-view-packages-repo') export class UmbSectionViewPackagesRepoElement extends LitElement { + /** + * + */ + constructor() { + super(); + umbHistoryService.push({ label: 'Packages', path: 'section/packages/view/packages' }); + } render() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts index ed79c0b9c5..b11e5f80d3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts @@ -15,6 +15,7 @@ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import type { UserGroupDetails } from '@umbraco-cms/models'; import './user-group-table-name-column-layout.element'; +import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-view-user-groups') export class UmbEditorViewUserGroupsElement extends UmbContextConsumerMixin(LitElement) { @@ -70,19 +71,18 @@ export class UmbEditorViewUserGroupsElement extends UmbContextConsumerMixin(LitE connectedCallback(): void { super.connectedCallback(); + umbHistoryService.push({ label: 'User groups', path: 'section/users/view/user-groups' }); - this.consumeContext('umbUserGroupStore', (userStore: UmbUserGroupStore) => { - this._userGroupStore = userStore; - this._observeUsers(); + this.consumeContext('umbUserGroupStore', (userGroupStore: UmbUserGroupStore) => { + this._userGroupStore = userGroupStore; + this._observeUserGroups(); }); } - private _observeUsers() { + private _observeUserGroups() { this._userGroupsSubscription?.unsubscribe(); this._userGroupsSubscription = this._userGroupStore?.getAll().subscribe((userGroups) => { this._userGroups = userGroups; - console.log('user groups', userGroups); - this._createTableItems(this._userGroups); }); } From 57ee922b27f32771b02c9a1742133634634a3044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= Date: Thu, 1 Dec 2022 14:13:00 +0100 Subject: [PATCH 24/45] recent history redesign --- .../dashboard-examine-management.element.ts | 2 +- .../views/section-view-examine-indexers.ts | 2 +- .../dashboard-models-builder.element.ts | 2 +- .../dashboard-published-status.element.ts | 2 +- .../telemetry/dashboard-telemetry.element.ts | 2 +- .../editors/user/editor-user.element.ts | 2 +- .../section-view-packages-created.element.ts | 2 +- ...section-view-packages-installed.element.ts | 2 +- .../modal-layout-user-dialog.element.ts | 77 +++++++++++-------- 9 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts index c086ee997c..44575ee75c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts @@ -55,7 +55,7 @@ export class UmbDashboardExamineManagementElement extends UmbContextConsumerMixi constructor() { super(); umbHistoryService.push({ - label: ['Settings', 'Examine Management'], + label: ['Examine Management', 'Settings'], path: 'section/settings/dashboard/examine-management', }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts index 8e70c340ae..e54b79ac41 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/views/section-view-examine-indexers.ts @@ -97,7 +97,7 @@ export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(Lit const index = await SearchResource.getSearchIndexByIndexName({ indexName: this.indexName }); this._indexData = index; umbHistoryService.push({ - label: ['Settings', 'Examine Management', this._indexData.name], + label: [this._indexData.name, 'Settings', 'Examine Management'], path: 'section/settings/dashboard/examine-management/index/ExternalIndex/' + this._indexData.name, }); } catch (e) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts index ead297d2d4..85c5e6dfee 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts @@ -10,7 +10,7 @@ export class UmbDashboardModelsBuilderElement extends LitElement { constructor() { super(); umbHistoryService.push({ - label: ['Settings', 'Models Builder'], + label: ['Models Builder', 'Settings'], path: 'section/settings/dashboard/models-builder', }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts index 41d33c6989..f0cd601678 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts @@ -46,7 +46,7 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( constructor() { super(); umbHistoryService.push({ - label: ['Settings', 'Published Status'], + label: ['Published Status', 'Settings'], path: 'section/settings/dashboard/published-status', }); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts index 81012c0319..e3d4773eca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts @@ -30,7 +30,7 @@ export class UmbDashboardTelemetryElement extends LitElement { constructor() { super(); umbHistoryService.push({ - label: ['Settings', 'Telemetry Data'], + label: ['Telemetry Data', 'Settings'], path: 'section/settings/dashboard/telemetry', }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index 3fd2a81d29..b1169522b6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -142,7 +142,7 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( this._user = user; if (!this._user) return; - umbHistoryService.push({ label: ['Users', user.name], path: 'section/users/view/users/user/' + user.key }); + umbHistoryService.push({ label: [user.name, 'Users'], path: 'section/users/view/users/user/' + user.key }); if (!this._userContext) { this._userContext = new UmbUserContext(this._user); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts index 25f672a05e..546986cd3b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts @@ -29,7 +29,7 @@ export class UmbSectionViewPackagesCreatedElement extends LitElement { constructor() { super(); - umbHistoryService.push({ label: ['Packages', 'Created'], path: 'section/packages/view/created/overview' }); + umbHistoryService.push({ label: ['Created', 'Packages'], path: 'section/packages/view/created/overview' }); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts index 0eafecd484..6e886faa3f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts @@ -29,7 +29,7 @@ export class UmbSectionViewPackagesInstalledElement extends LitElement { constructor() { super(); - umbHistoryService.push({ label: ['Packages', 'Installed'], path: 'section/packages/view/installed/overview' }); + umbHistoryService.push({ label: ['Installed', 'Packages'], path: 'section/packages/view/installed/overview' }); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index b4d145f22e..bc7bdcdd1d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -47,20 +47,31 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb #recent-history-items { display: flex; flex-direction: column; - gap: var(--uui-size-space-2); + gap: var(--uui-size-space-4); } .history-item { - color: inherit; + display: grid; + grid-template-columns: 32px 1fr; + grid-template-rows: 1fr; + color: var(--uui-color-interactive); text-decoration: none; } - .history-item-name-separator { - margin: 0 var(--uui-size-space-1); + .history-item uui-icon { + margin-top: 2px; } - - .history-item-name-separator { - opacity: 0.4; + .history-item:hover { + color: var(--uui-color-interactive-emphasis); } - .history-item-name { + .history-item > div { + color: inherit; + text-decoration: none; + display: flex; + flex-direction: column; + line-height: 1.4em; + } + .history-item > div > span { + font-size: var(--uui-size-4); + opacity: 0.5; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; @@ -144,27 +155,25 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb } private _renderHistoryItem(item: UmbHistoryItem) { - if (typeof item.label === 'string') { - return html` -
${item.label}
-
`; - } - if (Array.isArray(item.label)) { - console.log('hallo', item); - - return html` - -
- ${item.label.map((name, index) => { - return html`${name}${index < item.label.length - 1 ? '>' : nothing}`; - })} -
-
- `; - } - - return nothing; + return html` + + +
+ ${Array.isArray(item.label) ? item.label[0] : item.label} + + ${Array.isArray(item.label) + ? item.label.map((label, index) => { + if (index === 0) return; + return html` + ${label} + ${index !== item.label.length - 1 ? html`${'>'}` : nothing} + `; + }) + : nothing} + +
+
+ `; } render() { @@ -190,10 +199,12 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb html`` )}
-
- Recent History -
${this._history.map((item) => html`${this._renderHistoryItem(item)}`)}
-
+ + Recent History +
+ ${this._history.reverse().map((item) => html` ${this._renderHistoryItem(item)} `)} +
+
Close From 8b90943c5166dbcbc491699583ffdb072f5f44ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 2 Dec 2022 16:29:28 +0100 Subject: [PATCH 25/45] admin access to user editor actions --- .../editors/user/editor-user.element.ts | 41 +++++++++++++------ .../src/core/mocks/data/users.data.ts | 1 + 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index b1169522b6..ebced964b1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -1,5 +1,5 @@ import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; -import { css, html, LitElement, nothing } from 'lit'; +import { css, html, LitElement, nothing, TemplateResult } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { Subscription } from 'rxjs'; @@ -214,19 +214,34 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( } private _renderActionButtons() { - if (this._currentUser?.key === this._user?.key) - return html` `; + const adminUserGroupKey = '10000000-0000-0000-0000-000000000000'; + const buttons: TemplateResult[] = []; - return html` ${this._user?.status !== 'invited' - ? html` - - ` - : nothing} - `; + if (this._currentUser?.userGroup !== adminUserGroupKey) return nothing; + + if (this._user?.status !== 'invited') + buttons.push( + html` + + ` + ); + + if (this._currentUser?.key !== this._user?.key) + buttons.push(html` `); + + buttons.push( + html` ` + ); + + return buttons; } private renderLeftColumn() { diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts index 571f81e118..b28d78200a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts @@ -44,6 +44,7 @@ export const data: Array = [ updateDate: '8/27/2022', createDate: '9/19/2022', failedLoginAttempts: 52, + userGroup: '10000000-0000-0000-0000-000000000000', }, { key: '7c9c5510-a7b6-43fd-a2d1-51de0009eabf', From dff8e5445a7ff2dd889343acf888d89aad899e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 2 Dec 2022 16:49:00 +0100 Subject: [PATCH 26/45] change password modal reacts to admin state --- .../editors/user/editor-user.element.ts | 17 ++++++++++++----- .../modal-layout-change-password.element.ts | 10 +++++++--- .../src/core/services/modal/modal.service.ts | 5 +++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index ebced964b1..06e3982f7d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -210,14 +210,21 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( } private _changePassword() { - this._modalService?.changePassword(); + this._modalService?.changePassword({ requireOldPassword: this._isCurrentUserAdmin === false }); + } + + private get _isCurrentUserAdmin(): boolean { + //TODO: Find a way to figure out if current user is in the admin group + const adminUserGroupKey = '10000000-0000-0000-0000-000000000000'; + return this._currentUser?.userGroup === adminUserGroupKey; } private _renderActionButtons() { - const adminUserGroupKey = '10000000-0000-0000-0000-000000000000'; + if (!this._user) return; + const buttons: TemplateResult[] = []; - if (this._currentUser?.userGroup !== adminUserGroupKey) return nothing; + if (this._isCurrentUserAdmin === false) return nothing; if (this._user?.status !== 'invited') buttons.push( @@ -225,8 +232,8 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( + color="${this._user.status === 'disabled' ? 'positive' : 'warning'}" + label="${this._user.status === 'disabled' ? 'Enable' : 'Disable'}"> ` ); diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts index 4223e2df85..47728db7a8 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts @@ -7,6 +7,10 @@ import { UmbUserStore } from 'src/core/stores/user/user.store'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +export interface UmbModalChangePasswordData { + requireOldPassword: boolean; +} + @customElement('umb-modal-layout-change-password') export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { static styles: CSSResultGroup = [ @@ -30,8 +34,8 @@ export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin @property({ attribute: false }) modalHandler?: UmbModalHandler; - @state() - private _requireOldPassword = false; //TODO: Implement check to see if current user is an admin. + @property() + data?: UmbModalChangePasswordData; private _close() { this.modalHandler?.close(); @@ -73,7 +77,7 @@ export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin
- ${this._requireOldPassword ? this._renderOldPasswordInput() : nothing} + ${this.data?.requireOldPassword ? this._renderOldPasswordInput() : nothing} New password Date: Mon, 5 Dec 2022 16:53:44 +0100 Subject: [PATCH 27/45] current user is not a static service --- .../backoffice-header-tools.element.ts | 8 ++--- .../editors/user/editor-user.element.ts | 3 +- .../current-user/current-user.service.ts | 30 +++++++++++++++++++ .../src/core/services/current-user/index.ts | 1 + .../modal-layout-user-dialog.element.ts | 22 ++++++++------ .../src/core/stores/user/user.store.ts | 13 +------- 6 files changed, 49 insertions(+), 28 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts create mode 100644 src/Umbraco.Web.UI.Client/src/core/services/current-user/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts index 0c336cf22d..2e639b0d2a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/backoffice-header-tools.element.ts @@ -5,7 +5,7 @@ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import type { UserDetails } from '@umbraco-cms/models'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbModalService } from '@umbraco-cms/services'; -import { UmbUserStore } from 'src/core/stores/user/user.store'; +import { umbCurrentUserService } from 'src/core/services/current-user'; @customElement('umb-backoffice-header-tools') export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -27,22 +27,18 @@ export class UmbBackofficeHeaderTools extends UmbContextConsumerMixin(UmbObserve @state() private _currentUser?: UserDetails; - private _userStore?: UmbUserStore; private _modalService?: UmbModalService; constructor() { super(); this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { - this._userStore = instances['umbUserStore']; this._modalService = instances['umbModalService']; this._observeCurrentUser(); }); } private async _observeCurrentUser() { - if (!this._userStore) return; - - this.observe(this._userStore.currentUser, (currentUser) => { + this.observe(umbCurrentUserService.currentUser, (currentUser) => { this._currentUser = currentUser; }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index 06e3982f7d..c74fd54aca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -17,6 +17,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbModalService } from '@umbraco-cms/services'; import { umbHistoryService } from 'src/core/services/history'; +import { umbCurrentUserService } from 'src/core/services/current-user'; @customElement('umb-editor-user') export class UmbEditorUserElement extends UmbContextProviderMixin( @@ -130,7 +131,7 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( private async _observeCurrentUser() { if (!this._userStore) return; - this.observe(this._userStore.currentUser, (currentUser) => { + this.observe(umbCurrentUserService.currentUser, (currentUser) => { this._currentUser = currentUser; }); } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts new file mode 100644 index 0000000000..217b873a18 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts @@ -0,0 +1,30 @@ +import { BehaviorSubject, Observable } from 'rxjs'; +import { umbUsersData } from '../../mocks/data/users.data'; +import type { UserDetails } from '@umbraco-cms/models'; +import { umbracoPath } from '@umbraco-cms/utils'; + +class UmbCurrentUserService { + private _currentUser = new BehaviorSubject(umbUsersData.getItems('user')[0]); //TODO: Temp solution to set the first user as the current logged in user + public readonly currentUser: Observable = this._currentUser.asObservable(); + + /** + * logs out the user + * @public + * @memberof UmbCurrentUserService + */ + public logout(): void { + fetch(umbracoPath('/user/logout').toString()) + .then((res) => res.json()) + .then((data) => { + console.log('User Logged out', data); + }); + } + + public get isAdmin(): boolean { + //TODO: Find a way to figure out if current user is in the admin group + const adminUserGroupKey = '10000000-0000-0000-0000-000000000000'; + return this._currentUser.getValue()?.userGroup === adminUserGroupKey; + } +} + +export const umbCurrentUserService = new UmbCurrentUserService(); diff --git a/src/Umbraco.Web.UI.Client/src/core/services/current-user/index.ts b/src/Umbraco.Web.UI.Client/src/core/services/current-user/index.ts new file mode 100644 index 0000000000..f895dd41e2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/services/current-user/index.ts @@ -0,0 +1 @@ +export * from './current-user.service'; diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts index bc7bdcdd1d..c2be231872 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts @@ -2,6 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbHistoryItem, umbHistoryService } from '../../history'; +import { umbCurrentUserService } from '../../current-user'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; import type { ManifestExternalLoginProvider, ManifestUserDashboard, UserDetails } from '@umbraco-cms/models'; import { UmbUserStore } from 'src/core/stores/user/user.store'; @@ -94,17 +95,15 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb @state() private _history: Array = []; - private _userStore?: UmbUserStore; private _modalService?: UmbModalService; constructor() { super(); - this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { - this._userStore = instances['umbUserStore']; + this.consumeAllContexts(['umbModalService'], (instances) => { this._modalService = instances['umbModalService']; - this._observeCurrentUser(); }); + this._observeCurrentUser(); this._observeExternalLoginProviders(); this._observeHistory(); this._observeUserDashboards(); @@ -120,9 +119,7 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb } private async _observeCurrentUser() { - if (!this._userStore) return; - - this.observe(this._userStore.currentUser, (currentUser) => { + this.observe(umbCurrentUserService.currentUser, (currentUser) => { this._currentUser = currentUser; }); } @@ -144,14 +141,17 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb } private _edit() { + console.log('Hello', this._currentUser); if (!this._currentUser) return; + history.pushState(null, '', '/section/users/view/users/user/' + this._currentUser.key); //TODO Change to a tag with href and make dynamic this._close(); } private _changePassword() { if (!this._modalService) return; - this._modalService.changePassword(); + + this._modalService.changePassword({ requireOldPassword: umbCurrentUserService.isAdmin }); } private _renderHistoryItem(item: UmbHistoryItem) { @@ -176,6 +176,10 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb `; } + private _logout() { + umbCurrentUserService.logout(); + } + render() { return html` @@ -208,7 +212,7 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb
Close - Logout + Logout
`; diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts index 0d4a9a082b..80e6f80442 100644 --- a/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/user/user.store.ts @@ -1,4 +1,4 @@ -import { BehaviorSubject, map, Observable, ReplaySubject, Subject } from 'rxjs'; +import { BehaviorSubject, map, Observable } from 'rxjs'; import type { UserDetails } from '../../models'; import { UmbEntityStore } from '../entity.store'; import { UmbDataStoreBase } from '../store'; @@ -15,20 +15,9 @@ export class UmbUserStore extends UmbDataStoreBase { private _totalUsers: BehaviorSubject = new BehaviorSubject(0); public readonly totalUsers: Observable = this._totalUsers.asObservable(); - private _currentUser: Subject = new ReplaySubject(); - public readonly currentUser: Observable = this._currentUser.asObservable(); - constructor(entityStore: UmbEntityStore) { super(); this._entityStore = entityStore; - - //TODO: Temp code to get the first user as the current user. Replace when login is implemented. - const subscription = this.getAll().subscribe((response) => { - if (response.length > 0) { - this._currentUser.next(response[0]); - subscription.unsubscribe(); - } - }); } getAll(): Observable> { From e5c0803748386dc73715a7b7f397064d35e6dfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 12 Dec 2022 14:25:47 +0100 Subject: [PATCH 28/45] cleanup --- src/Umbraco.Web.UI.Client/package-lock.json | 37 +++++++++++++++---- .../modal-layout-change-password.element.ts | 8 ++-- .../modal-layout-user-dialog.element.ts | 1 - 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index ae23887df5..c006cadd7e 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -3946,6 +3946,15 @@ "@babel/core": "^7.4.0-0" } }, + "node_modules/@storybook/builder-webpack4/node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@storybook/builder-webpack4/node_modules/@storybook/addons": { "version": "6.5.14", "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.14.tgz", @@ -4734,6 +4743,14 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/@storybook/builder-webpack4/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/@storybook/builder-webpack4/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4746,14 +4763,6 @@ "node": ">=8" } }, - "node_modules/@storybook/builder-webpack4/node_modules/semver": { - "version": "5.7.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/@storybook/builder-webpack4/node_modules/tapable": { "version": "1.1.3", "dev": true, @@ -31529,6 +31538,14 @@ "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@storybook/addons": { @@ -32098,6 +32115,10 @@ "ajv-keywords": "^3.4.1" } }, + "semver": { + "version": "5.7.1", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts index 47728db7a8..49e16be8d1 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-change-password.element.ts @@ -1,9 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; -import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbUserStore } from 'src/core/stores/user/user.store'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbModalHandler } from '@umbraco-cms/services'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; @@ -62,7 +60,7 @@ export class UmbModalLayoutChangePasswordElement extends UmbContextConsumerMixin private _renderOldPasswordInput() { return html` - Old password + Old password Date: Tue, 13 Dec 2022 13:49:55 +0100 Subject: [PATCH 29/45] rename to current user --- ...alog.element.ts => modal-layout-current-user.element.ts} | 6 +++--- .../src/core/services/modal/modal.service.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/{modal-layout-user-dialog.element.ts => modal-layout-current-user.element.ts} (96%) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts similarity index 96% rename from src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts rename to src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts index f7276123bb..280090c6ae 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-user-dialog.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts @@ -11,8 +11,8 @@ import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import '../../../../backoffice/external-login-providers/external-login-provider-extension.element'; import '../../../../backoffice/user-dashboards/user-dashboard-extension.element'; -@customElement('umb-modal-layout-user-dialog') -export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { +@customElement('umb-modal-layout-current-user') +export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -220,6 +220,6 @@ export class UmbModalLayoutUserDialogElement extends UmbContextConsumerMixin(Umb declare global { interface HTMLElementTagNameMap { - 'umb-modal-layout-user-dialog': UmbModalLayoutUserDialogElement; + 'umb-modal-layout-current-user': UmbModalLayoutCurrentUserElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts index 2be3bf7c5c..ffab298efd 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/modal.service.ts @@ -2,7 +2,7 @@ import './layouts/confirm/modal-layout-confirm.element'; import './layouts/content-picker/modal-layout-content-picker.element'; import './layouts/property-editor-ui-picker/modal-layout-property-editor-ui-picker.element'; -import './layouts/modal-layout-user-dialog.element'; +import './layouts/modal-layout-current-user.element'; import './layouts/modal-layout-change-password.element'; import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; @@ -78,7 +78,7 @@ export class UmbModalService { * @memberof UmbModalService */ public userSettings(): UmbModalHandler { - return this.open('umb-modal-layout-user-dialog', { type: 'sidebar', size: 'small' }); + return this.open('umb-modal-layout-current-user', { type: 'sidebar', size: 'small' }); } /** From 5502052c7d3e77f2e8c37fb8d790533f29d6d9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 14 Dec 2022 13:19:01 +0100 Subject: [PATCH 30/45] implement current user modal for user header app --- .../header-app-current-user.element.ts | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/header-apps/header-app-current-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/header-apps/header-app-current-user.element.ts index 88731d20cd..61c636b63f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/header-apps/header-app-current-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/header-apps/header-app-current-user.element.ts @@ -1,9 +1,15 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UmbObserverMixin } from '@umbraco-cms/observable-api'; +import type { UserDetails } from '@umbraco-cms/models'; +import { UmbModalService } from '@umbraco-cms/services'; +import { umbCurrentUserService } from 'src/core/services/current-user'; @customElement('umb-header-app-current-user') -export class UmbHeaderAppCurrentUser extends LitElement { +export class UmbHeaderAppCurrentUser extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { + static styles: CSSResultGroup = [ UUITextStyles, css` @@ -13,12 +19,34 @@ export class UmbHeaderAppCurrentUser extends LitElement { `, ]; - // TODO: Get current user information. + @state() + private _currentUser?: UserDetails; + + private _modalService?: UmbModalService; + + constructor() { + super(); + this.consumeAllContexts(['umbUserStore', 'umbModalService'], (instances) => { + this._modalService = instances['umbModalService']; + this._observeCurrentUser(); + }); + } + + private async _observeCurrentUser() { + this.observe(umbCurrentUserService.currentUser, (currentUser) => { + this._currentUser = currentUser; + }); + } + + private _handleUserClick() { + this._modalService?.userSettings(); + } + render() { return html` - - + + `; } From 818d06c651223c0a01a8506e7a21010739925a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 13:12:47 +0100 Subject: [PATCH 31/45] action and tabs slot for body-layout --- .../body-layout/body-layout.element.ts | 63 ++++++++++++++++--- .../editor-content/editor-content.element.ts | 1 - .../editor-entity-layout.element.ts | 54 +++------------- 3 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts index 32d31aee54..fa872657a7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts @@ -1,6 +1,6 @@ -import { css, html, LitElement } from 'lit'; +import { css, html, LitElement, nothing } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; @customElement('umb-body-layout') export class UmbBodyLayout extends LitElement { @@ -16,15 +16,27 @@ export class UmbBodyLayout extends LitElement { } #header { - background-color: var(--uui-color-surface); + display: flex; + align-items: center; + justify-content: space-between; width: 100%; + min-height: 60px; + + background-color: var(--uui-color-surface); border-bottom: 1px solid var(--uui-color-border); box-sizing: border-box; - /* padding: 0 var(--uui-size-6); */ + } + + #headline { + display: block; + margin: 0 var(--uui-size-layout-1); + } + + #tabs { + margin-left: auto; } #main { - /* padding: 0 var(--uui-size-6); */ display: flex; flex: 1; flex-direction: column; @@ -33,28 +45,61 @@ export class UmbBodyLayout extends LitElement { #footer { display: flex; align-items: center; - height: 70px; + justify-content: space-between; width: 100%; - /*padding: 0 var(--uui-size-6);*/ + height: 54px; /* TODO: missing var(--uui-size-18);*/ border-top: 1px solid var(--uui-color-border); background-color: var(--uui-color-surface); box-sizing: border-box; } + + #actions { + display: flex; + gap: 6px; + margin: 0 var(--uui-size-layout-1); + margin-left: auto; + } `, ]; + + connectedCallback() { + super.connectedCallback(); + this.shadowRoot?.removeEventListener('slotchange', this._slotChanged); + this.shadowRoot?.addEventListener('slotchange', this._slotChanged); + } + + private _slotChanged = (e: Event) => { + (e.target as any).style.display = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0 ? '' : 'none'; + }; + + /** + * Alias of the editor. The Layout will render the editor views that are registered for this editor alias. + * @public + * @type {string} + * @attr + * @default '' + */ + @property() + public headline = ''; + render() { return html` + + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-content/editor-content.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-content/editor-content.element.ts index 34c3ca3fa1..0041e9046a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-content/editor-content.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-content/editor-content.element.ts @@ -61,7 +61,6 @@ export class UmbEditorContentElement extends UmbContextProviderMixin( #footer { margin: 0 var(--uui-size-layout-1); - flex:1 1 auto; } `, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-entity-layout/editor-entity-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-entity-layout/editor-entity-layout.element.ts index 6b4f567f1b..7ff23cf616 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-entity-layout/editor-entity-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/shared/editor-entity-layout/editor-entity-layout.element.ts @@ -37,36 +37,6 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(UmbObserverMi height: 100%; } - #header { - display: flex; - align-items: center; - min-height: 60px; - } - - #headline { - display: block; - flex: 1 1 auto; - margin: 0 var(--uui-size-layout-1); - } - - #tabs { - margin-left: auto; - } - - #footer { - display: flex; - height: 100%; - align-items: center; - flex: 1 1 auto; - } - - #actions { - display: flex; - margin-left: auto; - gap: 6px; - margin: 0 var(--uui-size-layout-1); - } - uui-input { width: 100%; } @@ -162,7 +132,7 @@ export class UmbEditorEntityLayout extends UmbContextConsumerMixin(UmbObserverMi return html` ${this._editorViews?.length > 0 ? html` - + ${this._editorViews.map( (view: ManifestEditorView) => html` - + + ${this._renderTabs()} - + + extension.meta.editors.includes(this.alias)}> + + `; } From 457269269f0238dbb3bef222c9640473fbd256af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 13:13:34 +0100 Subject: [PATCH 32/45] clean + disconnect --- .../components/body-layout/body-layout.element.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts index fa872657a7..aad18332ed 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts @@ -1,6 +1,6 @@ import { css, html, LitElement, nothing } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property, state } from 'lit/decorators.js'; +import { customElement, property } from 'lit/decorators.js'; @customElement('umb-body-layout') export class UmbBodyLayout extends LitElement { @@ -69,6 +69,11 @@ export class UmbBodyLayout extends LitElement { this.shadowRoot?.addEventListener('slotchange', this._slotChanged); } + disconnectedCallback() { + super.disconnectedCallback(); + this.shadowRoot?.removeEventListener('slotchange', this._slotChanged); + } + private _slotChanged = (e: Event) => { (e.target as any).style.display = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0 ? '' : 'none'; }; From 27bb971c5b12dd60c7828d461b1209509b882b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 13:35:46 +0100 Subject: [PATCH 33/45] REMOVE ManifestWithLoader --- .../src/backoffice/editors/user/editor-user.element.ts | 2 +- .../src/backoffice/external-login-providers/manifests.ts | 4 ++-- .../src/backoffice/user-dashboards/manifests.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index 42749dea57..7bd6ffaa96 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -157,7 +157,7 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( private _registerEditorActions() { - const manifests: Array> = [ + const manifests: Array = [ { type: 'editorAction', alias: 'Umb.EditorAction.User.Save', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts index 5812b461c8..bc744b5978 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/external-login-providers/manifests.ts @@ -1,6 +1,6 @@ -import type { ManifestExternalLoginProvider, ManifestWithLoader } from '@umbraco-cms/models'; +import type { ManifestExternalLoginProvider } from '@umbraco-cms/models'; -export const manifests: Array> = [ +export const manifests: Array = [ { type: 'externalLoginProvider', alias: 'Umb.ExternalLoginProvider.Test', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts index 9259cad147..f6cfd8da4b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts @@ -1,6 +1,6 @@ -import type { ManifestUserDashboard, ManifestWithLoader } from '@umbraco-cms/models'; +import type { ManifestUserDashboard } from '@umbraco-cms/models'; -export const manifests: Array> = [ +export const manifests: Array = [ { type: 'userDashboard', alias: 'Umb.UserDashboard.Test', From 1df12214420e3462cc9422a2a095a34926a8677b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 15 Dec 2022 14:16:10 +0100 Subject: [PATCH 34/45] update property description --- .../public/mockServiceWorker.js | 2 +- .../body-layout/body-layout.element.ts | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/public/mockServiceWorker.js b/src/Umbraco.Web.UI.Client/public/mockServiceWorker.js index 4ed73191bd..70f0a2b994 100644 --- a/src/Umbraco.Web.UI.Client/public/mockServiceWorker.js +++ b/src/Umbraco.Web.UI.Client/public/mockServiceWorker.js @@ -2,7 +2,7 @@ /* tslint:disable */ /** - * Mock Service Worker (0.49.1). + * Mock Service Worker (0.49.2). * @see https://github.com/mswjs/msw * - Please do NOT modify this file. * - Please do NOT serve this file on production. diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts index aad18332ed..b15ac3fa35 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/components/body-layout/body-layout.element.ts @@ -18,7 +18,7 @@ export class UmbBodyLayout extends LitElement { #header { display: flex; align-items: center; - justify-content: space-between; + justify-content: space-between; width: 100%; min-height: 60px; @@ -45,7 +45,7 @@ export class UmbBodyLayout extends LitElement { #footer { display: flex; align-items: center; - justify-content: space-between; + justify-content: space-between; width: 100%; height: 54px; /* TODO: missing var(--uui-size-18);*/ border-top: 1px solid var(--uui-color-border); @@ -62,7 +62,6 @@ export class UmbBodyLayout extends LitElement { `, ]; - connectedCallback() { super.connectedCallback(); this.shadowRoot?.removeEventListener('slotchange', this._slotChanged); @@ -75,11 +74,12 @@ export class UmbBodyLayout extends LitElement { } private _slotChanged = (e: Event) => { - (e.target as any).style.display = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0 ? '' : 'none'; + (e.target as any).style.display = + (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0 ? '' : 'none'; }; /** - * Alias of the editor. The Layout will render the editor views that are registered for this editor alias. + * Renders a headline in the header. * @public * @type {string} * @attr @@ -92,7 +92,7 @@ export class UmbBodyLayout extends LitElement { return html` @@ -100,11 +100,9 @@ export class UmbBodyLayout extends LitElement { - - `; } } From b7be34fe4e37300e18215ea26543b7c841b9a6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 14:21:31 +0100 Subject: [PATCH 35/45] export models --- .../src/core/extensions-registry/models.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts index 13939b8681..5d96d75a53 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts @@ -1,3 +1,5 @@ + +import type { ManifestHeaderApp } from './header-app.models'; import type { ManifestSection } from './section.models'; import type { ManifestSectionView } from './section-view.models'; import type { ManifestTree } from './tree.models'; @@ -9,7 +11,7 @@ import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './pr import type { ManifestDashboard } from './dashboard.models'; import type { ManifestPropertyAction } from './property-action.models'; import type { ManifestPackageView } from './package-view.models'; -import type { ManifestHeaderApp } from './header-app.models'; +import type { ManifestExternalLoginProvider } from './external-login-provider.models'; export * from './header-app.models'; export * from './section.models'; @@ -23,6 +25,7 @@ export * from './property-editor.models'; export * from './dashboard.models'; export * from './property-action.models'; export * from './package-view.models'; +export * from './external-login-provider.models'; export type ManifestTypes = | ManifestHeaderApp @@ -38,6 +41,7 @@ export type ManifestTypes = | ManifestDashboard | ManifestPropertyAction | ManifestPackageView + | ManifestExternalLoginProvider | ManifestEntrypoint | ManifestCustom; @@ -55,7 +59,8 @@ export type ManifestStandardTypes = | 'dashboard' | 'propertyAction' | 'packageView' - | 'entrypoint'; + | 'entrypoint' + | 'externalLoginProvider'; export type ManifestElementType = | ManifestSection @@ -68,7 +73,8 @@ export type ManifestElementType = | ManifestDashboard | ManifestEditorView | ManifestEditorAction - | ManifestPackageView; + | ManifestPackageView + | ManifestExternalLoginProvider; export interface ManifestBase { type: string; From d512584267cc6cb1103b71ad299aa8270d0188be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 14:24:09 +0100 Subject: [PATCH 36/45] user-dashboard --- .../src/backoffice/user-dashboards/manifests.ts | 2 +- .../src/core/extensions-registry/models.ts | 5 +++++ .../src/core/extensions-registry/user-dashboard.models.ts | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts index f6cfd8da4b..fed04c4737 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/user-dashboards/manifests.ts @@ -2,7 +2,7 @@ import type { ManifestUserDashboard } from '@umbraco-cms/models'; export const manifests: Array = [ { - type: 'userDashboard', + type: 'user-dashboard', alias: 'Umb.UserDashboard.Test', name: 'Test User Dashboard', elementName: 'umb-user-dashboard-test', diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts index 5d96d75a53..b528670d23 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/models.ts @@ -9,6 +9,7 @@ import type { ManifestEditorAction } from './editor-action.models'; import type { ManifestEditorView } from './editor-view.models'; import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './property-editor.models'; import type { ManifestDashboard } from './dashboard.models'; +import type { ManifestUserDashboard } from './user-dashboard.models'; import type { ManifestPropertyAction } from './property-action.models'; import type { ManifestPackageView } from './package-view.models'; import type { ManifestExternalLoginProvider } from './external-login-provider.models'; @@ -23,6 +24,7 @@ export * from './editor-action.models'; export * from './editor-view.models'; export * from './property-editor.models'; export * from './dashboard.models'; +export * from './user-dashboard.models'; export * from './property-action.models'; export * from './package-view.models'; export * from './external-login-provider.models'; @@ -39,6 +41,7 @@ export type ManifestTypes = | ManifestPropertyEditorUI | ManifestPropertyEditorModel | ManifestDashboard + | ManifestUserDashboard | ManifestPropertyAction | ManifestPackageView | ManifestExternalLoginProvider @@ -57,6 +60,7 @@ export type ManifestStandardTypes = | 'propertyEditorUI' | 'propertyEditorModel' | 'dashboard' + | 'user-dashboard' | 'propertyAction' | 'packageView' | 'entrypoint' @@ -71,6 +75,7 @@ export type ManifestElementType = | ManifestPropertyAction | ManifestPropertyEditorUI | ManifestDashboard + | ManifestUserDashboard | ManifestEditorView | ManifestEditorAction | ManifestPackageView diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts index a9fd823c55..166df0e24a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/user-dashboard.models.ts @@ -1,7 +1,7 @@ import type { ManifestElement } from './models'; export interface ManifestUserDashboard extends ManifestElement { - type: 'userDashboard'; + type: 'user-dashboard'; meta: MetaUserDashboard; } From 388e5400971b9a4317a877d6e271c8c8502bdaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 14:27:06 +0100 Subject: [PATCH 37/45] adapt to new store --- .../src/core/services/current-user/current-user.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts index 0091c47626..53782a9580 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/current-user/current-user.service.ts @@ -4,7 +4,7 @@ import type { UserDetails } from '@umbraco-cms/models'; import { umbracoPath } from '@umbraco-cms/utils'; class UmbCurrentUserService { - private _currentUser = new BehaviorSubject(umbUsersData.getItems('user')[0]); //TODO: Temp solution to set the first user as the current logged in user + private _currentUser = new BehaviorSubject(umbUsersData.getAll()[0]); //TODO: Temp solution to set the first user as the current logged in user public readonly currentUser: Observable = this._currentUser.asObservable(); /** From 30a636e5bb4f6842dd847699250827dd4149bc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 14:35:37 +0100 Subject: [PATCH 38/45] add todo comment --- .../src/core/services/history/history.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts index f1037e3816..f43f060b75 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts @@ -43,4 +43,5 @@ class UmbHistoryService { } } +// TODO: Do not make singletons or static classes. export const umbHistoryService = new UmbHistoryService(); From baa43d7f2971da2e1f5b5f0a619535925fe094ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 14:51:24 +0100 Subject: [PATCH 39/45] refactor history into current user history store --- .../src/backoffice/backoffice.element.ts | 2 ++ .../dashboard-examine-management.element.ts | 5 ----- .../dashboard-published-status.element.ts | 5 ----- .../telemetry/dashboard-telemetry.element.ts | 5 ----- .../editors/user/editor-user.element.ts | 4 +--- .../section-view-packages-created.element.ts | 6 ------ ...section-view-packages-installed.element.ts | 6 ------ .../section-view-packages-repo.element.ts | 9 +------- .../editor-view-user-groups.element.ts | 2 -- .../grid/editor-view-users-grid.element.ts | 2 -- .../table/editor-view-users-table.element.ts | 2 -- .../src/core/services/history/index.ts | 1 - .../modal-layout-current-user.element.ts | 21 +++++++++++-------- .../current-user-history.store.ts} | 16 +++++++------- 14 files changed, 23 insertions(+), 63 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/core/services/history/index.ts rename src/Umbraco.Web.UI.Client/src/core/{services/history/history.service.ts => stores/current-user-history/current-user-history.store.ts} (65%) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index 90a3e2097c..26652b6021 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -32,6 +32,7 @@ import { UmbSectionStore } from '../core/stores/section.store'; import { UmbUserStore } from '../core/stores/user/user.store'; import { UmbIconStore } from '../core/stores/icon/icon.store'; import { UmbUserGroupStore } from '../core/stores/user/user-group.store'; +import { UmbCurrentUserHistoryStore } from '../core/stores/current-user-history/current-user-history.store'; import { manifests as sectionManifests } from './sections/manifests'; import { manifests as propertyEditorModelManifests } from './property-editor-models/manifests'; import { manifests as propertyEditorUIManifests } from './property-editor-uis/manifests'; @@ -89,6 +90,7 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this.provideContext('umbNotificationService', new UmbNotificationService()); this.provideContext('umbModalService', new UmbModalService()); this.provideContext('umbSectionStore', new UmbSectionStore()); + this.provideContext('UmbCurrentUserHistoryStore', new UmbCurrentUserHistoryStore()); } private _registerExtensions(manifests: Array | Array) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts index 72b98ff2e4..a81006ceaf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/examine-management/dashboard-examine-management.element.ts @@ -6,7 +6,6 @@ import { UmbDashboardExamineIndexElement } from './views/section-view-examine-in import { UmbDashboardExamineSearcherElement } from './views/section-view-examine-searchers'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-examine-management') export class UmbDashboardExamineManagementElement extends UmbContextConsumerMixin(LitElement) { @@ -54,10 +53,6 @@ export class UmbDashboardExamineManagementElement extends UmbContextConsumerMixi */ constructor() { super(); - umbHistoryService.push({ - label: ['Examine Management', 'Settings'], - path: 'section/settings/dashboard/examine-management', - }); } private _onRouteChange() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts index f0cd601678..6d0d24b0be 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/published-status/dashboard-published-status.element.ts @@ -9,7 +9,6 @@ import { UmbNotificationDefaultData } from '../../../core/services/notification/ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import { ApiError, ProblemDetails, PublishedCacheResource } from '@umbraco-cms/backend-api'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-published-status') export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(LitElement) { @@ -45,10 +44,6 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( constructor() { super(); - umbHistoryService.push({ - label: ['Published Status', 'Settings'], - path: 'section/settings/dashboard/published-status', - }); this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => { this._notificationService = instances['umbNotificationService']; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts index 1ab8d58e1b..544b2b1fa2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/dashboards/telemetry/dashboard-telemetry.element.ts @@ -4,7 +4,6 @@ import { css, html, LitElement } from 'lit'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { customElement, state } from 'lit/decorators.js'; import { ApiError, ProblemDetails, Telemetry, TelemetryLevel, TelemetryResource } from '@umbraco-cms/backend-api'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-dashboard-telemetry') export class UmbDashboardTelemetryElement extends LitElement { @@ -31,10 +30,6 @@ export class UmbDashboardTelemetryElement extends LitElement { constructor() { super(); - umbHistoryService.push({ - label: ['Telemetry Data', 'Settings'], - path: 'section/settings/dashboard/telemetry', - }); } async connectedCallback() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index 7bd6ffaa96..087008c6ab 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -15,7 +15,7 @@ import type { ManifestEditorAction, UserDetails } from '@umbraco-cms/models'; import '../../property-editor-uis/content-picker/property-editor-ui-content-picker.element'; import '@umbraco-cms/components/input-user-group/input-user-group.element'; -import { umbHistoryService } from 'src/core/services/history'; +import { umbHistoryService } from '@umbraco-cms/stores/current-user-history'; import { umbCurrentUserService } from 'src/core/services/current-user'; import { UmbModalService } from '@umbraco-cms/services'; import '../shared/editor-entity-layout/editor-entity-layout.element'; @@ -132,8 +132,6 @@ export class UmbEditorUserElement extends UmbContextProviderMixin( this._user = user; if (!this._user) return; - umbHistoryService.push({ label: [user.name, 'Users'], path: 'section/users/view/users/user/' + user.key }); - if (!this._userContext) { this._userContext = new UmbUserContext(this._user); this.provideContext('umbUserContext', this._userContext); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts index c5f2271d96..2972eb91cf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/created/section-view-packages-created.element.ts @@ -1,7 +1,6 @@ import { html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { IRoute, IRoutingInfo } from 'router-slot'; -import { umbHistoryService } from 'src/core/services/history'; import { UmbEditorEntityElement } from '../../../../editors/shared/editor-entity/editor-entity.element'; @customElement('umb-section-view-packages-created') @@ -27,11 +26,6 @@ export class UmbSectionViewPackagesCreatedElement extends LitElement { }, ]; - constructor() { - super(); - umbHistoryService.push({ label: ['Created', 'Packages'], path: 'section/packages/view/created/overview' }); - } - render() { return html``; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts index 48d2871deb..2123f9f3d3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/installed/section-view-packages-installed.element.ts @@ -1,7 +1,6 @@ import { html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { IRoute, IRoutingInfo } from 'router-slot'; -import { umbHistoryService } from 'src/core/services/history'; import { UmbEditorEntityElement } from '../../../../editors/shared/editor-entity/editor-entity.element'; @customElement('umb-section-view-packages-installed') @@ -27,11 +26,6 @@ export class UmbSectionViewPackagesInstalledElement extends LitElement { }, ]; - constructor() { - super(); - umbHistoryService.push({ label: ['Installed', 'Packages'], path: 'section/packages/view/installed/overview' }); - } - render() { return html``; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts index a0dfec9e88..bd20977861 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/packages/views/repo/section-view-packages-repo.element.ts @@ -1,16 +1,9 @@ import { html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-section-view-packages-repo') export class UmbSectionViewPackagesRepoElement extends LitElement { - /** - * - */ - constructor() { - super(); - umbHistoryService.push({ label: 'Packages', path: 'section/packages/view/packages' }); - } + render() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts index 47199491c9..94230de07c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/user-groups/editor-view-user-groups.element.ts @@ -17,7 +17,6 @@ import './user-group-table-name-column-layout.element'; import './user-group-table-sections-column-layout.element'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbUserGroupStore } from '@umbraco-cms/stores/user/user-group.store'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-view-user-groups') export class UmbEditorViewUserGroupsElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -72,7 +71,6 @@ export class UmbEditorViewUserGroupsElement extends UmbContextConsumerMixin(UmbO connectedCallback(): void { super.connectedCallback(); - umbHistoryService.push({ label: 'User groups', path: 'section/users/view/user-groups' }); this.consumeContext('umbUserGroupStore', (userGroupStore: UmbUserGroupStore) => { this._userGroupStore = userGroupStore; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts index 6049825761..82031b2c87 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/grid/editor-view-users-grid.element.ts @@ -9,7 +9,6 @@ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import type { UserDetails, UserEntity, UserGroupDetails, UserGroupEntity } from '@umbraco-cms/models'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbUserGroupStore } from 'src/core/stores/user/user-group.store'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-view-users-grid') export class UmbEditorViewUsersGridElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -55,7 +54,6 @@ export class UmbEditorViewUsersGridElement extends UmbContextConsumerMixin(UmbOb constructor() { super(); - umbHistoryService.push({ label: 'Users grid', path: 'section/users/view/users/overview/grid' }); this.consumeAllContexts(['umbUserGroupStore', 'umbUsersContext'], (instances) => { this._userGroupStore = instances['umbUserGroupStore']; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts index b30e5bddfa..fbd623cd52 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/users/views/users/list-view-layouts/table/editor-view-users-table.element.ts @@ -18,7 +18,6 @@ import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import './column-layouts/name/user-table-name-column-layout.element'; import './column-layouts/status/user-table-status-column-layout.element'; import { UmbUserGroupStore } from 'src/core/stores/user/user-group.store'; -import { umbHistoryService } from 'src/core/services/history'; @customElement('umb-editor-view-users-table') export class UmbEditorViewUsersTableElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -77,7 +76,6 @@ export class UmbEditorViewUsersTableElement extends UmbContextConsumerMixin(UmbO constructor() { super(); - umbHistoryService.push({ label: 'Users list', path: 'section/users/view/users/overview/list' }); this.consumeAllContexts(['umbUserGroupStore', 'umbUsersContext'], (instances) => { this._userGroupStore = instances['umbUserGroupStore']; diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/index.ts b/src/Umbraco.Web.UI.Client/src/core/services/history/index.ts deleted file mode 100644 index 76f55618be..0000000000 --- a/src/Umbraco.Web.UI.Client/src/core/services/history/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './history.service'; diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts index 280090c6ae..b53e07ef98 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts @@ -1,7 +1,6 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbHistoryItem, umbHistoryService } from '../../history'; import { umbCurrentUserService } from '../../current-user'; import { UmbModalHandler, UmbModalService } from '@umbraco-cms/services'; import type { ManifestExternalLoginProvider, ManifestUserDashboard, UserDetails } from '@umbraco-cms/models'; @@ -10,6 +9,7 @@ import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry'; import '../../../../backoffice/external-login-providers/external-login-provider-extension.element'; import '../../../../backoffice/user-dashboards/user-dashboard-extension.element'; +import { UmbCurrentUserHistoryStore, UmbCurrentUserHistoryItem } from '@umbraco-cms/stores/current-user-history/current-user-history.store'; @customElement('umb-modal-layout-current-user') export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -92,14 +92,16 @@ export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(Um private _userDashboards: Array = []; @state() - private _history: Array = []; + private _history: Array = []; private _modalService?: UmbModalService; + private _currentUserHistoryStore?: UmbCurrentUserHistoryStore; constructor() { super(); - this.consumeAllContexts(['umbModalService'], (instances) => { + this.consumeAllContexts(['umbModalService', 'umbCurrentUserHistoryStore'], (instances) => { this._modalService = instances['umbModalService']; + this._currentUserHistoryStore = instances['umbCurrentUserHistoryStore']; }); this._observeCurrentUser(); @@ -123,15 +125,16 @@ export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(Um }); } private async _observeHistory() { - this.observe>(umbHistoryService.history, (history) => { - this._history = history; - }); + if(this._currentUserHistoryStore) { + this.observe>(this._currentUserHistoryStore.history, (history) => { + this._history = history; + }); + } } private _observeUserDashboards() { - this.observe(umbExtensionsRegistry.extensionsOfType('userDashboard'), (userDashboard) => { + this.observe(umbExtensionsRegistry.extensionsOfType('user-dashboard'), (userDashboard) => { this._userDashboards = userDashboard; - console.log(this._userDashboards); }); } @@ -153,7 +156,7 @@ export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(Um this._modalService.changePassword({ requireOldPassword: umbCurrentUserService.isAdmin }); } - private _renderHistoryItem(item: UmbHistoryItem) { + private _renderHistoryItem(item: UmbCurrentUserHistoryItem) { return html` diff --git a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts b/src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts rename to src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts index f43f060b75..cc7bdf101c 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/history/history.service.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts @@ -2,23 +2,24 @@ import { BehaviorSubject, Observable } from 'rxjs'; export type UmbModelType = 'dialog' | 'sidebar'; -export type UmbHistoryItem = { +export type UmbCurrentUserHistoryItem = { path: string; label: string | Array; icon?: string; }; -class UmbHistoryService { - private _history: BehaviorSubject> = new BehaviorSubject(>[]); - public readonly history: Observable> = this._history.asObservable(); +export class UmbCurrentUserHistoryStore { + + private _history: BehaviorSubject> = new BehaviorSubject(>[]); + public readonly history: Observable> = this._history.asObservable(); /** * Pushes a new history item to the history array * @public - * @param {UmbHistoryItem} historyItem + * @param {UmbCurrentUserHistoryItem} historyItem * @memberof UmbHistoryService */ - public push(historyItem: UmbHistoryItem): void { + public push(historyItem: UmbCurrentUserHistoryItem): void { const history = this._history.getValue(); const lastItem = history[history.length - 1]; @@ -42,6 +43,3 @@ class UmbHistoryService { this._history.next([]); } } - -// TODO: Do not make singletons or static classes. -export const umbHistoryService = new UmbHistoryService(); From d012372b1c1f2a0f45b9dfbfd169b7057ad8fc5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 15:36:48 +0100 Subject: [PATCH 40/45] current user history --- .../src/backoffice/backoffice.element.ts | 2 +- .../modal-layout-current-user.element.ts | 5 ++--- .../current-user-history.store.ts | 20 ++++++++++++++++++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index 26652b6021..7bedd2dab7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -90,7 +90,7 @@ export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProv this.provideContext('umbNotificationService', new UmbNotificationService()); this.provideContext('umbModalService', new UmbModalService()); this.provideContext('umbSectionStore', new UmbSectionStore()); - this.provideContext('UmbCurrentUserHistoryStore', new UmbCurrentUserHistoryStore()); + this.provideContext('umbCurrentUserHistoryStore', new UmbCurrentUserHistoryStore()); } private _registerExtensions(manifests: Array | Array) { diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts index b53e07ef98..4f932cb1a2 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/modal-layout-current-user.element.ts @@ -102,11 +102,11 @@ export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(Um this.consumeAllContexts(['umbModalService', 'umbCurrentUserHistoryStore'], (instances) => { this._modalService = instances['umbModalService']; this._currentUserHistoryStore = instances['umbCurrentUserHistoryStore']; + this._observeHistory(); }); this._observeCurrentUser(); this._observeExternalLoginProviders(); - this._observeHistory(); this._observeUserDashboards(); } @@ -126,7 +126,7 @@ export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(Um } private async _observeHistory() { if(this._currentUserHistoryStore) { - this.observe>(this._currentUserHistoryStore.history, (history) => { + this.observe>(this._currentUserHistoryStore.getLatestHistory(), (history) => { this._history = history; }); } @@ -143,7 +143,6 @@ export class UmbModalLayoutCurrentUserElement extends UmbContextConsumerMixin(Um } private _edit() { - console.log('Hello', this._currentUser); if (!this._currentUser) return; history.pushState(null, '', '/section/users/view/users/user/' + this._currentUser.key); //TODO Change to a tag with href and make dynamic diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts index cc7bdf101c..5865ae010c 100644 --- a/src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/current-user-history/current-user-history.store.ts @@ -1,4 +1,4 @@ -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, map, Observable } from 'rxjs'; export type UmbModelType = 'dialog' | 'sidebar'; @@ -13,6 +13,23 @@ export class UmbCurrentUserHistoryStore { private _history: BehaviorSubject> = new BehaviorSubject(>[]); public readonly history: Observable> = this._history.asObservable(); + constructor() { + (window as any).navigation.addEventListener('navigate', (event: any) => { + const url = new URL(event.destination.url); + const historyItem = {path: url.pathname, label: event.destination.url.split('/').pop()}; + this.push(historyItem); + }); + } + + + public getLatestHistory(): Observable> { + return this._history.pipe(map((historyItem) => + { + return historyItem.slice(-10); + } + )); + } + /** * Pushes a new history item to the history array * @public @@ -32,6 +49,7 @@ export class UmbCurrentUserHistoryStore { newHistory[history.length - 1] = historyItem; this._history.next(newHistory); } + } /** From b06a5386bee4193813c18e7a2114b70e969a21d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Dec 2022 15:45:30 +0100 Subject: [PATCH 41/45] remove import --- .../src/backoffice/editors/user/editor-user.element.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts index 087008c6ab..ffe939c570 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/user/editor-user.element.ts @@ -15,7 +15,6 @@ import type { ManifestEditorAction, UserDetails } from '@umbraco-cms/models'; import '../../property-editor-uis/content-picker/property-editor-ui-content-picker.element'; import '@umbraco-cms/components/input-user-group/input-user-group.element'; -import { umbHistoryService } from '@umbraco-cms/stores/current-user-history'; import { umbCurrentUserService } from 'src/core/services/current-user'; import { UmbModalService } from '@umbraco-cms/services'; import '../shared/editor-entity-layout/editor-entity-layout.element'; From 22cc940017c849445e70362e397e63fc321e2240 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:09:40 +0000 Subject: [PATCH 42/45] Bump lit from 2.4.1 to 2.5.0 Bumps [lit](https://github.com/lit/lit/tree/HEAD/packages/lit) from 2.4.1 to 2.5.0. - [Release notes](https://github.com/lit/lit/releases) - [Changelog](https://github.com/lit/lit/blob/main/packages/lit/CHANGELOG.md) - [Commits](https://github.com/lit/lit/commits/lit@2.5.0/packages/lit) --- updated-dependencies: - dependency-name: lit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Umbraco.Web.UI.Client/package-lock.json | 46 ++++++++++----------- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 7c7225aa98..0b19170e1e 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -16,7 +16,7 @@ "@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", "@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", "element-internals-polyfill": "^1.1.17", - "lit": "^2.4.1", + "lit": "^2.5.0", "lodash": "^4.17.21", "openapi-typescript-fetch": "^1.1.3", "router-slot": "^1.5.5", @@ -2523,9 +2523,9 @@ "dev": true }, "node_modules/@lit/reactive-element": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz", - "integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.5.0.tgz", + "integrity": "sha512-fQh9FDK0LPTwDk+0HhSZEtb8K0LTN1wXerwpGrWA+a8tWulYRDLI4vQDWp4GOIsewn0572KYV/oZ3+492D7osA==" }, "node_modules/@mdn/browser-compat-data": { "version": "4.2.1", @@ -20143,13 +20143,13 @@ "dev": true }, "node_modules/lit": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.4.1.tgz", - "integrity": "sha512-qohSgLiyN1cFnJG26dIiY03S4F49857A0AHQfnS0zYtnUVnD2MFvx+UT52rtXsIuNFQrnUupX+zyGSATlk1f/A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.5.0.tgz", + "integrity": "sha512-DtnUP6vR3l4Q8nRPPNBD+UxbAhwJPeky+OVbi3pdgMqm0g57xFSl1Sj64D1rIB+nVNdiVVg8YxB0hqKjvdadZA==", "dependencies": { - "@lit/reactive-element": "^1.4.0", + "@lit/reactive-element": "^1.5.0", "lit-element": "^3.2.0", - "lit-html": "^2.4.0" + "lit-html": "^2.5.0" } }, "node_modules/lit-element": { @@ -20162,9 +20162,9 @@ } }, "node_modules/lit-html": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.4.0.tgz", - "integrity": "sha512-G6qXu4JNUpY6aaF2VMfaszhO9hlWw0hOTRFDmuMheg/nDYGB+2RztUSOyrzALAbr8Nh0Y7qjhYkReh3rPnplVg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.5.0.tgz", + "integrity": "sha512-bLHosg1XL3JRUcKdSVI0sLCs0y1wWrj2sqqAN3cZ7bDDPNgmDHH29RV48x6Wz3ZmkxIupaE+z7uXSZ/pXWAO1g==", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -33055,9 +33055,9 @@ "dev": true }, "@lit/reactive-element": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz", - "integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.5.0.tgz", + "integrity": "sha512-fQh9FDK0LPTwDk+0HhSZEtb8K0LTN1wXerwpGrWA+a8tWulYRDLI4vQDWp4GOIsewn0572KYV/oZ3+492D7osA==" }, "@mdn/browser-compat-data": { "version": "4.2.1", @@ -46454,13 +46454,13 @@ "dev": true }, "lit": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.4.1.tgz", - "integrity": "sha512-qohSgLiyN1cFnJG26dIiY03S4F49857A0AHQfnS0zYtnUVnD2MFvx+UT52rtXsIuNFQrnUupX+zyGSATlk1f/A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.5.0.tgz", + "integrity": "sha512-DtnUP6vR3l4Q8nRPPNBD+UxbAhwJPeky+OVbi3pdgMqm0g57xFSl1Sj64D1rIB+nVNdiVVg8YxB0hqKjvdadZA==", "requires": { - "@lit/reactive-element": "^1.4.0", + "@lit/reactive-element": "^1.5.0", "lit-element": "^3.2.0", - "lit-html": "^2.4.0" + "lit-html": "^2.5.0" } }, "lit-element": { @@ -46473,9 +46473,9 @@ } }, "lit-html": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.4.0.tgz", - "integrity": "sha512-G6qXu4JNUpY6aaF2VMfaszhO9hlWw0hOTRFDmuMheg/nDYGB+2RztUSOyrzALAbr8Nh0Y7qjhYkReh3rPnplVg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.5.0.tgz", + "integrity": "sha512-bLHosg1XL3JRUcKdSVI0sLCs0y1wWrj2sqqAN3cZ7bDDPNgmDHH29RV48x6Wz3ZmkxIupaE+z7uXSZ/pXWAO1g==", "requires": { "@types/trusted-types": "^2.0.2" } diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 134f2221e8..d84c40f4ad 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -60,7 +60,7 @@ "@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", "@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", "element-internals-polyfill": "^1.1.17", - "lit": "^2.4.1", + "lit": "^2.5.0", "lodash": "^4.17.21", "openapi-typescript-fetch": "^1.1.3", "router-slot": "^1.5.5", From 6bac0f20910b70273be8163086f8c661920af587 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:08:52 +0000 Subject: [PATCH 43/45] Bump lit-html from 2.4.0 to 2.5.0 Bumps [lit-html](https://github.com/lit/lit/tree/HEAD/packages/lit-html) from 2.4.0 to 2.5.0. - [Release notes](https://github.com/lit/lit/releases) - [Changelog](https://github.com/lit/lit/blob/main/packages/lit-html/CHANGELOG.md) - [Commits](https://github.com/lit/lit/commits/lit-html@2.5.0/packages/lit-html) --- updated-dependencies: - dependency-name: lit-html dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Umbraco.Web.UI.Client/package-lock.json | 2 +- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 0b19170e1e..5e4d637dcc 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -54,7 +54,7 @@ "eslint-plugin-lit-a11y": "^2.3.0", "eslint-plugin-local-rules": "^1.3.2", "eslint-plugin-storybook": "^0.6.8", - "lit-html": "^2.4.0", + "lit-html": "^2.5.0", "msw": "^0.49.2", "msw-storybook-addon": "^1.6.3", "openapi-typescript-codegen": "^0.23.0", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index d84c40f4ad..6d1bf255ad 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -98,7 +98,7 @@ "eslint-plugin-lit-a11y": "^2.3.0", "eslint-plugin-local-rules": "^1.3.2", "eslint-plugin-storybook": "^0.6.8", - "lit-html": "^2.4.0", + "lit-html": "^2.5.0", "msw": "^0.49.2", "msw-storybook-addon": "^1.6.3", "openapi-typescript-codegen": "^0.23.0", From 79d55258c416793253117ac22497abd8c85146f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:06:50 +0000 Subject: [PATCH 44/45] Bump eslint-plugin-lit from 1.7.0 to 1.7.1 Bumps [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) from 1.7.0 to 1.7.1. - [Release notes](https://github.com/43081j/eslint-plugin-lit/releases) - [Commits](https://github.com/43081j/eslint-plugin-lit/compare/v1.7.0...v1.7.1) --- updated-dependencies: - dependency-name: eslint-plugin-lit dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- src/Umbraco.Web.UI.Client/package-lock.json | 14 +++++++------- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 5e4d637dcc..b916c4f49a 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -50,7 +50,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-lit": "^1.7.0", + "eslint-plugin-lit": "^1.7.1", "eslint-plugin-lit-a11y": "^2.3.0", "eslint-plugin-local-rules": "^1.3.2", "eslint-plugin-storybook": "^0.6.8", @@ -15571,9 +15571,9 @@ "dev": true }, "node_modules/eslint-plugin-lit": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.7.0.tgz", - "integrity": "sha512-V9cflbK3qn91BKZsqjfU0KX2bXv36VtVAty9k7D+SauR1mvmEaZpmEDT74H1PDdsuFQG+0fmoU/ufhPYlAhJxA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.7.1.tgz", + "integrity": "sha512-25rB2FPesP/b1aadT18tNKV3POkSey4IQmSgKd238Pv163S0RO5J67Nzim8L7xq0KE9jGPjfgyOivyXZ0vN4vQ==", "dev": true, "dependencies": { "parse5": "^6.0.1", @@ -43065,9 +43065,9 @@ } }, "eslint-plugin-lit": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.7.0.tgz", - "integrity": "sha512-V9cflbK3qn91BKZsqjfU0KX2bXv36VtVAty9k7D+SauR1mvmEaZpmEDT74H1PDdsuFQG+0fmoU/ufhPYlAhJxA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.7.1.tgz", + "integrity": "sha512-25rB2FPesP/b1aadT18tNKV3POkSey4IQmSgKd238Pv163S0RO5J67Nzim8L7xq0KE9jGPjfgyOivyXZ0vN4vQ==", "dev": true, "requires": { "parse5": "^6.0.1", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 6d1bf255ad..9d28d79902 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -94,7 +94,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-lit": "^1.7.0", + "eslint-plugin-lit": "^1.7.1", "eslint-plugin-lit-a11y": "^2.3.0", "eslint-plugin-local-rules": "^1.3.2", "eslint-plugin-storybook": "^0.6.8", From d176677de0d4fdd954ab2335339415791a2d0f21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:07:58 +0000 Subject: [PATCH 45/45] Bump vite-plugin-static-copy from 0.12.0 to 0.13.0 Bumps [vite-plugin-static-copy](https://github.com/sapphi-red/vite-plugin-static-copy) from 0.12.0 to 0.13.0. - [Release notes](https://github.com/sapphi-red/vite-plugin-static-copy/releases) - [Commits](https://github.com/sapphi-red/vite-plugin-static-copy/compare/v0.12.0...v0.13.0) --- updated-dependencies: - dependency-name: vite-plugin-static-copy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Umbraco.Web.UI.Client/package-lock.json | 34 ++++++++++----------- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index b916c4f49a..8f5c2e6745 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -64,7 +64,7 @@ "tiny-glob": "^0.2.9", "typescript": "^4.9.4", "vite": "^3.2.4", - "vite-plugin-static-copy": "^0.12.0", + "vite-plugin-static-copy": "^0.13.0", "vite-tsconfig-paths": "^4.0.1", "web-component-analyzer": "^2.0.0-next.4" }, @@ -29358,27 +29358,27 @@ } }, "node_modules/vite-plugin-static-copy": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.12.0.tgz", - "integrity": "sha512-5a8hCjYJdf/rl8s7ct/YWt97gXdGPGNSOoJtkY5IYhbnSq04X1gTt5GpFHKfAxhHoed1Grfw3Ed13t7AjJi7gw==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.13.0.tgz", + "integrity": "sha512-cln+fvKMgwNBjxQ59QVblmExZrc9gGEdRmfqcPOOGpxT5KInfpkGMvmK4L+kCAeHHSSGNU1bM7BA9PQgaAJc6g==", "dev": true, "dependencies": { "chokidar": "^3.5.3", "fast-glob": "^3.2.11", - "fs-extra": "^10.1.0", + "fs-extra": "^11.1.0", "picocolors": "^1.0.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^3.0.0" + "vite": "^3.0.0 || ^4.0.0" } }, "node_modules/vite-plugin-static-copy/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", + "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -29386,7 +29386,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.14" } }, "node_modules/vite-plugin-static-copy/node_modules/picocolors": { @@ -53659,21 +53659,21 @@ } }, "vite-plugin-static-copy": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.12.0.tgz", - "integrity": "sha512-5a8hCjYJdf/rl8s7ct/YWt97gXdGPGNSOoJtkY5IYhbnSq04X1gTt5GpFHKfAxhHoed1Grfw3Ed13t7AjJi7gw==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.13.0.tgz", + "integrity": "sha512-cln+fvKMgwNBjxQ59QVblmExZrc9gGEdRmfqcPOOGpxT5KInfpkGMvmK4L+kCAeHHSSGNU1bM7BA9PQgaAJc6g==", "dev": true, "requires": { "chokidar": "^3.5.3", "fast-glob": "^3.2.11", - "fs-extra": "^10.1.0", + "fs-extra": "^11.1.0", "picocolors": "^1.0.0" }, "dependencies": { "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", + "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", "dev": true, "requires": { "graceful-fs": "^4.2.0", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 9d28d79902..b8cebd009e 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -108,7 +108,7 @@ "tiny-glob": "^0.2.9", "typescript": "^4.9.4", "vite": "^3.2.4", - "vite-plugin-static-copy": "^0.12.0", + "vite-plugin-static-copy": "^0.13.0", "vite-tsconfig-paths": "^4.0.1", "web-component-analyzer": "^2.0.0-next.4" },