From 334f95bc7ea955b6c804bab0f1719cdecf2e2424 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 1 Jun 2022 13:17:25 +0200 Subject: [PATCH] add specialised types to dashboards and sections --- .../backoffice-header-sections.element.ts | 51 ++++++----- .../src/content/content-dashboards.element.ts | 86 ++++++++++--------- .../src/section.context.ts | 38 ++++---- 3 files changed, 92 insertions(+), 83 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice-header-sections.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice-header-sections.element.ts index e34c0ce43a..c4cd5bf3b5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice-header-sections.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice-header-sections.element.ts @@ -1,14 +1,14 @@ -import { Subscription } from 'rxjs'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { when } from 'lit/directives/when.js'; +import { Subscription } from 'rxjs'; import { getUserSections } from '../core/api/fetcher'; -import { UmbExtensionManifest } from '../core/extension'; +import { UmbContextConsumerMixin } from '../core/context'; +import { UmbExtensionManifestSection } from '../core/extension'; import { UmbRouteLocation, UmbRouter } from '../core/router'; import { UmbSectionContext } from '../section.context'; -import { UmbContextConsumerMixin } from '../core/context'; @customElement('umb-backoffice-header-sections') export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElement) { @@ -45,13 +45,13 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem private _allowedSection: Array = []; @state() - private _sections: Array = []; + private _sections: Array = []; @state() - private _visibleSections: Array = []; + private _visibleSections: Array = []; @state() - private _extraSections: Array = []; + private _extraSections: Array = []; @state() private _currentSectionAlias = ''; @@ -61,9 +61,9 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem private _sectionSubscription?: Subscription; private _currentSectionSubscription?: Subscription; private _locationSubscription?: Subscription; - private _location? : UmbRouteLocation; + private _location?: UmbRouteLocation; - constructor () { + constructor() { super(); this.consumeContext('umbRouter', (_instance: UmbRouter) => { @@ -83,8 +83,8 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem this._open = !this._open; } - private _handleTabClick(e: PointerEvent, section: UmbExtensionManifest) { - const tab = e.currentTarget as any; + private _handleTabClick(e: PointerEvent, section: UmbExtensionManifestSection) { + const tab = e.currentTarget as HTMLElement; // TODO: we need to be able to prevent the tab from setting the active state if (tab.id === 'moreTab') { @@ -108,38 +108,37 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem this._open = false; } - private _useLocation () { + private _useLocation() { this._locationSubscription?.unsubscribe(); - - this._locationSubscription = this._router?.location - .subscribe((location: UmbRouteLocation) => { + + this._locationSubscription = this._router?.location.subscribe((location: UmbRouteLocation) => { this._location = location; }); } - private _useCurrentSection () { + private _useCurrentSection() { this._currentSectionSubscription?.unsubscribe(); - this._currentSectionSubscription = this._sectionContext?.getCurrent() - .subscribe(section => { + this._currentSectionSubscription = this._sectionContext?.getCurrent().subscribe((section) => { this._currentSectionAlias = section.alias; }); } private async _useSections() { this._sectionSubscription?.unsubscribe(); - + const { data } = await getUserSections({}); this._allowedSection = data.sections; - this._sectionSubscription = this._sectionContext?.getSections() - .subscribe((sectionExtensions: any) => { - this._sections = sectionExtensions.filter((section: any) => this._allowedSection.includes(section.alias)); - this._visibleSections = this._sections; - const currentSectionAlias = this._sections.find(section => section.meta.pathname === this._location?.params?.section)?.alias; - if (!currentSectionAlias) return; - this._sectionContext?.setCurrent(currentSectionAlias); - }); + this._sectionSubscription = this._sectionContext?.getSections().subscribe((sectionExtensions) => { + this._sections = sectionExtensions.filter((section) => this._allowedSection.includes(section.alias)); + this._visibleSections = this._sections; + const currentSectionAlias = this._sections.find( + (section) => section.meta.pathname === this._location?.params?.section + )?.alias; + if (!currentSectionAlias) return; + this._sectionContext?.setCurrent(currentSectionAlias); + }); } disconnectedCallback(): void { diff --git a/src/Umbraco.Web.UI.Client/src/content/content-dashboards.element.ts b/src/Umbraco.Web.UI.Client/src/content/content-dashboards.element.ts index f14f71af3a..3cf8ef0f6e 100644 --- a/src/Umbraco.Web.UI.Client/src/content/content-dashboards.element.ts +++ b/src/Umbraco.Web.UI.Client/src/content/content-dashboards.element.ts @@ -2,8 +2,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { map, Subscription } from 'rxjs'; + import { UmbContextConsumerMixin } from '../core/context'; -import { UmbExtensionManifest, UmbExtensionRegistry } from '../core/extension'; +import { UmbExtensionManifest, UmbExtensionManifestDashboard, UmbExtensionRegistry } from '../core/extension'; import { UmbRouteLocation, UmbRouter } from '../core/router'; @customElement('umb-content-dashboards') @@ -18,7 +19,7 @@ export class UmbContentDashboards extends UmbContextConsumerMixin(LitElement) { ]; @state() - private _dashboards: Array = []; + private _dashboards: Array = []; @state() private _current = ''; @@ -47,49 +48,52 @@ export class UmbContentDashboards extends UmbContextConsumerMixin(LitElement) { }); } - private _useLocation () { + private _useLocation() { this._locationSubscription?.unsubscribe(); - this._router?.location - .subscribe((location: UmbRouteLocation) => { + this._router?.location.subscribe((location: UmbRouteLocation) => { this._location = location; }); } - private _useDashboards () { + private _useDashboards() { this._dashboardsSubscription?.unsubscribe(); this._dashboardsSubscription = this._extensionRegistry?.extensions - .pipe( - map((extensions: Array) => extensions - .filter(extension => extension.type === 'dashboard') - .sort((a: any, b: any) => b.meta.weight - a.meta.weight)) - ).subscribe(dashboards => { - // TODO: What do we want to use as path? - this._dashboards = dashboards; - const dashboardLocation = decodeURIComponent(this._location?.params?.dashboard); - const sectionLocation = this._location?.params?.section; + .pipe( + map((extensions) => + extensions + .filter((extension) => extension.type === 'dashboard') + .map((x) => x as UmbExtensionManifestDashboard) + .sort((a, b) => b.meta.weight - a.meta.weight) + ) + ) + .subscribe((dashboards) => { + // TODO: What do we want to use as path? + this._dashboards = dashboards; + const dashboardLocation = decodeURIComponent(this._location?.params?.dashboard); + const sectionLocation = this._location?.params?.section; - // TODO: Temp redirect solution - if (dashboardLocation === 'undefined') { - this._router?.push(`/section/${sectionLocation}/dashboard/${this._dashboards[0].meta.pathname}`); - this._setCurrent(this._dashboards[0]); - return; - } + // TODO: Temp redirect solution + if (dashboardLocation === 'undefined') { + this._router?.push(`/section/${sectionLocation}/dashboard/${this._dashboards[0].meta.pathname}`); + this._setCurrent(this._dashboards[0]); + return; + } - const dashboard = this._dashboards.find(dashboard => dashboard.meta.pathname === dashboardLocation); + const dashboard = this._dashboards.find((dashboard) => dashboard.meta.pathname === dashboardLocation); - if (!dashboard) { - this._router?.push(`/section/${sectionLocation}/dashboard/${this._dashboards[0].meta.pathname}`); - this._setCurrent(this._dashboards[0]); - return; - } + if (!dashboard) { + this._router?.push(`/section/${sectionLocation}/dashboard/${this._dashboards[0].meta.pathname}`); + this._setCurrent(this._dashboards[0]); + return; + } - this._setCurrent(dashboard); - }) + this._setCurrent(dashboard); + }); } - private _handleTabClick(e: PointerEvent, dashboard: UmbExtensionManifest) { + private _handleTabClick(_e: PointerEvent, dashboard: UmbExtensionManifestDashboard) { // TODO: this could maybe be handled by an anchor tag const section = this._location?.params?.section; this._router?.push(`/section/${section}/dashboard/${dashboard.meta.pathname}`); @@ -97,11 +101,11 @@ export class UmbContentDashboards extends UmbContextConsumerMixin(LitElement) { } // TODO: Temp outlet solution - private async _setCurrent (dashboard: UmbExtensionManifest) { + private async _setCurrent(dashboard: UmbExtensionManifest) { if (typeof dashboard.js === 'function') { await dashboard.js(); } - + if (dashboard.elementName) { const element = document.createElement(dashboard.elementName); this._outlet = element; @@ -119,15 +123,17 @@ export class UmbContentDashboards extends UmbContextConsumerMixin(LitElement) { render() { return html` - ${ this._dashboards.map(dashboard => html` - - `)} + ${this._dashboards.map( + (dashboard) => html` + + ` + )} - ${ this._outlet } - `; + ${this._outlet} + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/section.context.ts b/src/Umbraco.Web.UI.Client/src/section.context.ts index ff6be9e81f..f0f51ab36c 100644 --- a/src/Umbraco.Web.UI.Client/src/section.context.ts +++ b/src/Umbraco.Web.UI.Client/src/section.context.ts @@ -1,33 +1,37 @@ -import { firstValueFrom, map, Observable, ReplaySubject } from 'rxjs'; -import { UmbExtensionManifest, UmbExtensionRegistry } from './core/extension'; +import { firstValueFrom, map, ReplaySubject } from 'rxjs'; + +import { UmbExtensionManifestSection, UmbExtensionRegistry } from './core/extension'; export class UmbSectionContext { private _extensionRegistry!: UmbExtensionRegistry; - private _current: ReplaySubject = new ReplaySubject(1); - public readonly current: Observable = this._current.asObservable(); + private _current = new ReplaySubject(1); + public readonly current = this._current.asObservable(); constructor(_extensionRegistry: UmbExtensionRegistry) { this._extensionRegistry = _extensionRegistry; } - getSections () { - return this._extensionRegistry.extensions - .pipe( - map((extensions: Array) => extensions - .filter(extension => extension.type === 'section') - .sort((a: any, b: any) => b.meta.weight - a.meta.weight)) - ); + getSections() { + return this._extensionRegistry.extensions.pipe( + map((extensions) => + extensions + .filter((extension) => extension.type === 'section') + .map((extension) => extension as UmbExtensionManifestSection) + .sort((a, b) => b.meta.weight - a.meta.weight) + ) + ); } - getCurrent () { + getCurrent() { return this.current; } - async setCurrent (sectionAlias: string) { + async setCurrent(sectionAlias: string) { const sections = await firstValueFrom(this.getSections()); - const matchedSection = sections.find(section => section.alias === sectionAlias) as UmbExtensionManifest; - this._current.next(matchedSection); + const matchedSection = sections.find((section) => section.alias === sectionAlias); + if (matchedSection) { + this._current.next(matchedSection); + } } - -} \ No newline at end of file +}