add section context + filter dashboards based on section
This commit is contained in:
@@ -2,12 +2,14 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
import { UmbContextProviderMixin } from '../core/context';
|
||||
import { UmbContextProviderMixin, UmbContextConsumerMixin } from '../core/context';
|
||||
import { UmbNotificationService } from '../core/services/notification';
|
||||
import { UmbModalService } from '../core/services/modal';
|
||||
import { UmbDataTypeStore } from '../core/stores/data-type.store';
|
||||
import { UmbDocumentTypeStore } from '../core/stores/document-type.store';
|
||||
import { UmbNodeStore } from '../core/stores/node.store';
|
||||
import { UmbSectionContext } from './sections/section.context';
|
||||
import { UmbSectionStore } from '../core/stores/section.store';
|
||||
|
||||
import './components/backoffice-header.element';
|
||||
import './components/backoffice-main.element';
|
||||
@@ -15,12 +17,13 @@ import './components/backoffice-notification-container.element';
|
||||
import './components/backoffice-modal-container.element';
|
||||
import './components/editor-property-layout.element';
|
||||
import './components/node-property.element';
|
||||
import './components/section-layout.element';
|
||||
import './components/section-sidebar.element';
|
||||
import './components/section-main.element';
|
||||
import './sections/shared/section-layout.element';
|
||||
import './sections/shared/section-sidebar.element';
|
||||
import './sections/shared/section-main.element';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@defineElement('umb-backoffice')
|
||||
export default class UmbBackoffice extends UmbContextProviderMixin(LitElement) {
|
||||
export default class UmbBackoffice extends UmbContextConsumerMixin(UmbContextProviderMixin(LitElement)) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
@@ -36,6 +39,9 @@ export default class UmbBackoffice extends UmbContextProviderMixin(LitElement) {
|
||||
`,
|
||||
];
|
||||
|
||||
private _umbSectionStore?: UmbSectionStore;
|
||||
private _currentSectionSubscription?: Subscription;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -44,6 +50,17 @@ export default class UmbBackoffice extends UmbContextProviderMixin(LitElement) {
|
||||
this.provideContext('umbDocumentTypeStore', new UmbDocumentTypeStore());
|
||||
this.provideContext('umbNotificationService', new UmbNotificationService());
|
||||
this.provideContext('umbModalService', new UmbModalService());
|
||||
|
||||
// TODO: how do we want to handle context aware DI?
|
||||
this.consumeContext('umbExtensionRegistry', (extensionRegistry) => {
|
||||
this._umbSectionStore = new UmbSectionStore(extensionRegistry);
|
||||
this.provideContext('umbSectionStore', this._umbSectionStore);
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._currentSectionSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -3,14 +3,15 @@ import { css, CSSResultGroup, html, LitElement } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import { isPathActive, path } from 'router-slot';
|
||||
import { map, Subscription } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { getUserSections } from '../../core/api/fetcher';
|
||||
import { UmbContextConsumerMixin } from '../../core/context';
|
||||
import { UmbExtensionManifestSection, UmbExtensionRegistry } from '../../core/extension';
|
||||
import { UmbContextConsumerMixin, UmbContextProvider, UmbContextProviderMixin } from '../../core/context';
|
||||
import { UmbExtensionManifestSection } from '../../core/extension';
|
||||
import { UmbSectionStore } from '../../core/stores/section.store';
|
||||
import { UmbSectionContext } from '../sections/section.context';
|
||||
|
||||
@customElement('umb-backoffice-header-sections')
|
||||
export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElement) {
|
||||
export class UmbBackofficeHeaderSections extends UmbContextProviderMixin(UmbContextConsumerMixin(LitElement)) {
|
||||
static styles: CSSResultGroup = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
@@ -40,9 +41,6 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem
|
||||
@state()
|
||||
private _open = false;
|
||||
|
||||
@state()
|
||||
private _allowedSection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
private _sections: Array<UmbExtensionManifestSection> = [];
|
||||
|
||||
@@ -55,16 +53,18 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem
|
||||
@state()
|
||||
private _currentSectionAlias = '';
|
||||
|
||||
private _extensionRegistry?: UmbExtensionRegistry;
|
||||
private _sectionStore?: UmbSectionStore;
|
||||
|
||||
private _sectionSubscription?: Subscription;
|
||||
private _currentSectionSubscription?: Subscription;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbExtensionRegistry', (extensionRegistry: UmbExtensionRegistry) => {
|
||||
this._extensionRegistry = extensionRegistry;
|
||||
this.consumeContext('umbSectionStore', (sectionStore: UmbSectionStore) => {
|
||||
this._sectionStore = sectionStore;
|
||||
this._useSections();
|
||||
this._useCurrentSection();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,9 +77,11 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem
|
||||
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') {
|
||||
return;
|
||||
}
|
||||
if (tab.id === 'moreTab') return;
|
||||
|
||||
if (!tab.dataset.alias) return;
|
||||
|
||||
this._sectionStore?.setCurrent(tab.dataset.alias);
|
||||
}
|
||||
|
||||
private _handleLabelClick() {
|
||||
@@ -89,19 +91,21 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
private async _useSections() {
|
||||
private _useSections() {
|
||||
this._sectionSubscription?.unsubscribe();
|
||||
|
||||
const { data } = await getUserSections({});
|
||||
this._allowedSection = data.sections;
|
||||
this._sectionSubscription = this._sectionStore?.getAllowed().subscribe((allowedSections) => {
|
||||
this._sections = allowedSections;
|
||||
this._visibleSections = this._sections;
|
||||
});
|
||||
}
|
||||
|
||||
this._sectionSubscription = this._extensionRegistry
|
||||
?.extensionsOfType('section')
|
||||
.pipe(map((extensions) => extensions.sort((a, b) => b.meta.weight - a.meta.weight)))
|
||||
.subscribe((sections) => {
|
||||
this._sections = sections.filter((section) => this._allowedSection.includes(section.alias));
|
||||
this._visibleSections = this._sections;
|
||||
});
|
||||
private _useCurrentSection() {
|
||||
this._currentSectionSubscription?.unsubscribe();
|
||||
|
||||
this._currentSectionSubscription = this._sectionStore?.currentAlias.subscribe((currentSectionAlias) => {
|
||||
this._currentSectionAlias = currentSectionAlias;
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
@@ -109,15 +113,17 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem
|
||||
this._sectionSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
render() {
|
||||
private _renderSections() {
|
||||
return html`
|
||||
<uui-tab-group id="tabs">
|
||||
${this._visibleSections.map(
|
||||
(section: UmbExtensionManifestSection) => html`
|
||||
<uui-tab
|
||||
?active="${isPathActive(`/section/${section.meta.pathname}`, path())}"
|
||||
@click="${this._handleTabClick}"
|
||||
?active="${this._currentSectionAlias === section.alias}"
|
||||
href="${`/section/${section.meta.pathname}`}"
|
||||
label="${section.name}"></uui-tab>
|
||||
label="${section.name}"
|
||||
data-alias="${section.alias}"></uui-tab>
|
||||
`
|
||||
)}
|
||||
${this._renderExtraSections()}
|
||||
@@ -150,6 +156,10 @@ export class UmbBackofficeHeaderSections extends UmbContextConsumerMixin(LitElem
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` ${this._renderSections()} `;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -2,13 +2,16 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
import { map, Subscription } from 'rxjs';
|
||||
import { IRoutingInfo } from 'router-slot';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { UmbContextConsumerMixin } from '../../core/context';
|
||||
import { createExtensionElement, UmbExtensionManifestSection, UmbExtensionRegistry } from '../../core/extension';
|
||||
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '../../core/context';
|
||||
import { createExtensionElement, UmbExtensionManifestSection } from '../../core/extension';
|
||||
import { UmbSectionStore } from '../../core/stores/section.store';
|
||||
import { UmbSectionContext } from '../sections/section.context';
|
||||
|
||||
@defineElement('umb-backoffice-main')
|
||||
export class UmbBackofficeMain extends UmbContextConsumerMixin(LitElement) {
|
||||
export class UmbBackofficeMain extends UmbContextProviderMixin(UmbContextConsumerMixin(LitElement)) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
@@ -28,40 +31,61 @@ export class UmbBackofficeMain extends UmbContextConsumerMixin(LitElement) {
|
||||
@state()
|
||||
private _sections: Array<UmbExtensionManifestSection> = [];
|
||||
|
||||
private _extensionRegistry?: UmbExtensionRegistry;
|
||||
private _routePrefix = 'section/';
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _sectionStore?: UmbSectionStore;
|
||||
private _sectionSubscription?: Subscription;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbExtensionRegistry', (_instance: UmbExtensionRegistry) => {
|
||||
this._extensionRegistry = _instance;
|
||||
this.consumeContext('umbSectionStore', (_instance: UmbSectionStore) => {
|
||||
this._sectionStore = _instance;
|
||||
this._useSections();
|
||||
});
|
||||
}
|
||||
|
||||
private _useSections() {
|
||||
private async _useSections() {
|
||||
this._sectionSubscription?.unsubscribe();
|
||||
|
||||
this._sectionSubscription = this._extensionRegistry
|
||||
?.extensionsOfType('section')
|
||||
.pipe(map((extensions) => extensions.sort((a, b) => b.meta.weight - a.meta.weight)))
|
||||
.subscribe((sections) => {
|
||||
this._routes = [];
|
||||
this._sections = sections as Array<UmbExtensionManifestSection>;
|
||||
this._sectionSubscription = this._sectionStore?.getAllowed().subscribe((sections) => {
|
||||
if (!sections) return;
|
||||
this._sections = sections;
|
||||
this._createRoutes();
|
||||
});
|
||||
}
|
||||
|
||||
this._routes = this._sections.map((section) => {
|
||||
return {
|
||||
path: 'section/' + section.meta.pathname,
|
||||
component: () => createExtensionElement(section),
|
||||
};
|
||||
});
|
||||
private _createRoutes() {
|
||||
this._routes = [];
|
||||
this._routes = this._sections.map((section) => {
|
||||
return {
|
||||
path: this._routePrefix + section.meta.pathname,
|
||||
component: () => createExtensionElement(section),
|
||||
setup: this._onRouteSetup,
|
||||
};
|
||||
});
|
||||
|
||||
this._routes.push({
|
||||
path: '**',
|
||||
redirectTo: 'section/' + this._sections[0].meta.pathname,
|
||||
});
|
||||
});
|
||||
this._routes.push({
|
||||
path: '**',
|
||||
redirectTo: this._routePrefix + this._sections?.[0]?.meta.pathname,
|
||||
});
|
||||
}
|
||||
|
||||
private _onRouteSetup = (_component: HTMLElement, info: IRoutingInfo) => {
|
||||
const currentPath = info.match.route.path;
|
||||
const section = this._sections.find((s) => this._routePrefix + s.meta.pathname === currentPath);
|
||||
if (!section) return;
|
||||
this._sectionStore?.setCurrent(section.alias);
|
||||
this._provideSectionContext(section);
|
||||
};
|
||||
|
||||
private _provideSectionContext(section: UmbExtensionManifestSection) {
|
||||
if (!this._sectionContext) {
|
||||
this._sectionContext = new UmbSectionContext(section);
|
||||
this.provideContext('umbSectionContext', this._sectionContext);
|
||||
} else {
|
||||
this._sectionContext.update(section);
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { IRoutingInfo } from 'router-slot';
|
||||
import { map, Subscription } from 'rxjs';
|
||||
|
||||
import { UmbContextConsumerMixin } from '../../core/context';
|
||||
import { createExtensionElement, UmbExtensionManifestDashboard, UmbExtensionRegistry } from '../../core/extension';
|
||||
|
||||
@customElement('umb-section-dashboards')
|
||||
export class UmbSectionDashboards extends UmbContextConsumerMixin(LitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
background-color: var(--uui-color-surface);
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
#router-slot {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: var(--uui-size-space-5);
|
||||
display: block;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@state()
|
||||
private _dashboards: Array<UmbExtensionManifestDashboard> = [];
|
||||
|
||||
@state()
|
||||
private _current = '';
|
||||
|
||||
@state()
|
||||
private _routes: Array<any> = [];
|
||||
|
||||
private _extensionRegistry?: UmbExtensionRegistry;
|
||||
private _dashboardsSubscription?: Subscription;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbExtensionRegistry', (_instance: UmbExtensionRegistry) => {
|
||||
this._extensionRegistry = _instance;
|
||||
this._useDashboards();
|
||||
});
|
||||
}
|
||||
|
||||
private _useDashboards() {
|
||||
this._dashboardsSubscription?.unsubscribe();
|
||||
|
||||
this._dashboardsSubscription = this._extensionRegistry
|
||||
?.extensionsOfType('dashboard')
|
||||
.pipe(map((extensions) => extensions.sort((a, b) => b.meta.weight - a.meta.weight)))
|
||||
.subscribe((dashboards) => {
|
||||
this._dashboards = dashboards;
|
||||
this._routes = [];
|
||||
|
||||
this._routes = this._dashboards.map((dashboard) => {
|
||||
return {
|
||||
path: `${dashboard.meta.pathname}`,
|
||||
component: () => createExtensionElement(dashboard),
|
||||
setup: (_element: UmbExtensionManifestDashboard, info: IRoutingInfo) => {
|
||||
this._current = info.match.route.path;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
this._routes.push({
|
||||
path: '**',
|
||||
redirectTo: this._dashboards[0].meta.pathname,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private _handleTabClick(e: PointerEvent, dashboard: UmbExtensionManifestDashboard) {
|
||||
// TODO: generate URL from context/location. Or use Router-link concept?
|
||||
history.pushState(null, '', `/section/content/dashboard/${dashboard.meta.pathname}`);
|
||||
this._current = dashboard.name;
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._dashboardsSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-tab-group id="tabs">
|
||||
${this._dashboards.map(
|
||||
(dashboard: UmbExtensionManifestDashboard) => html`
|
||||
<uui-tab
|
||||
label=${dashboard.name}
|
||||
?active="${dashboard.meta.pathname === this._current}"
|
||||
@click="${(e: PointerEvent) => this._handleTabClick(e, dashboard)}"></uui-tab>
|
||||
`
|
||||
)}
|
||||
</uui-tab-group>
|
||||
<router-slot id="router-slot" .routes="${this._routes}"></router-slot>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbSectionDashboards;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-section-dashboards': UmbSectionDashboards;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export class UmbContentSection extends LitElement {
|
||||
private _routes: Array<IRoute> = [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: () => import('../../components/section-dashboards.element'),
|
||||
component: () => import('../shared/section-dashboards.element'),
|
||||
setup: () => {
|
||||
this._currentNodeId = undefined;
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@ export class UmbMediaSection extends LitElement {
|
||||
private _routes: Array<IRoute> = [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: () => import('../../components/section-dashboards.element'),
|
||||
component: () => import('../shared/section-dashboards.element'),
|
||||
setup: () => {
|
||||
this._currentNodeId = undefined;
|
||||
},
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { UmbExtensionManifestSection } from '../../core/extension';
|
||||
|
||||
export class UmbSectionContext {
|
||||
// TODO: figure out how fine grained we want to make our observables.
|
||||
private _data: BehaviorSubject<UmbExtensionManifestSection> = new BehaviorSubject({
|
||||
type: 'section',
|
||||
alias: '',
|
||||
name: '',
|
||||
meta: {
|
||||
pathname: '',
|
||||
weight: 0,
|
||||
},
|
||||
});
|
||||
public readonly data: Observable<UmbExtensionManifestSection> = this._data.asObservable();
|
||||
|
||||
constructor(section: UmbExtensionManifestSection) {
|
||||
if (!section) return;
|
||||
this._data.next(section);
|
||||
}
|
||||
|
||||
// TODO: figure out how we want to update data
|
||||
public update(data: Partial<UmbExtensionManifestSection>) {
|
||||
this._data.next({ ...this._data.getValue(), ...data });
|
||||
}
|
||||
|
||||
public getData() {
|
||||
return this._data.getValue();
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ export class UmbSettingsSection extends UmbContextConsumerMixin(LitElement) {
|
||||
private _routes: Array<IRoute> = [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: () => import('../../components/section-dashboards.element'),
|
||||
component: () => import('../shared/section-dashboards.element'),
|
||||
},
|
||||
{
|
||||
path: 'extensions',
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { IRoutingInfo } from 'router-slot';
|
||||
import { map, Subscription, first } from 'rxjs';
|
||||
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import { createExtensionElement, UmbExtensionManifestDashboard, UmbExtensionRegistry } from '../../../core/extension';
|
||||
import { UmbSectionContext } from '../section.context';
|
||||
|
||||
@customElement('umb-section-dashboards')
|
||||
export class UmbSectionDashboards extends UmbContextConsumerMixin(LitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
background-color: var(--uui-color-surface);
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
#router-slot {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: var(--uui-size-space-5);
|
||||
display: block;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@state()
|
||||
private _dashboards: Array<UmbExtensionManifestDashboard> = [];
|
||||
|
||||
@state()
|
||||
private _currentDashboardPathname = '';
|
||||
|
||||
@state()
|
||||
private _routes: Array<any> = [];
|
||||
|
||||
@state()
|
||||
private _currentSectionPathname = '';
|
||||
|
||||
private _currentSectionAlias = '';
|
||||
|
||||
private _extensionRegistry?: UmbExtensionRegistry;
|
||||
private _dashboardsSubscription?: Subscription;
|
||||
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _sectionContextSubscription?: Subscription;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// TODO: wait for more contexts
|
||||
this.consumeContext('umbExtensionRegistry', (_instance: UmbExtensionRegistry) => {
|
||||
this._extensionRegistry = _instance;
|
||||
});
|
||||
|
||||
this.consumeContext('umbSectionContext', (context: UmbSectionContext) => {
|
||||
this._sectionContext = context;
|
||||
this._useSectionContext();
|
||||
});
|
||||
}
|
||||
|
||||
private _useSectionContext() {
|
||||
this._sectionContextSubscription?.unsubscribe();
|
||||
|
||||
this._sectionContextSubscription = this._sectionContext?.data.pipe(first()).subscribe((section) => {
|
||||
this._currentSectionAlias = section.alias;
|
||||
this._currentSectionPathname = section.meta.pathname;
|
||||
this._useDashboards();
|
||||
});
|
||||
}
|
||||
|
||||
private _useDashboards() {
|
||||
if (!this._extensionRegistry || !this._currentSectionAlias) return;
|
||||
|
||||
this._dashboardsSubscription?.unsubscribe();
|
||||
|
||||
this._dashboardsSubscription = this._extensionRegistry
|
||||
?.extensionsOfType('dashboard')
|
||||
.pipe(
|
||||
map((extensions) =>
|
||||
extensions
|
||||
.filter((extension) => extension.meta.sections.includes(this._currentSectionAlias))
|
||||
.sort((a, b) => b.meta.weight - a.meta.weight)
|
||||
)
|
||||
)
|
||||
.subscribe((dashboards) => {
|
||||
if (!dashboards) return;
|
||||
this._dashboards = dashboards;
|
||||
this._createRoutes();
|
||||
});
|
||||
}
|
||||
|
||||
private _createRoutes() {
|
||||
this._routes = [];
|
||||
|
||||
this._routes = this._dashboards.map((dashboard) => {
|
||||
return {
|
||||
path: `${dashboard.meta.pathname}`,
|
||||
component: () => createExtensionElement(dashboard),
|
||||
setup: (_element: UmbExtensionManifestDashboard, info: IRoutingInfo) => {
|
||||
this._currentDashboardPathname = info.match.route.path;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
this._routes.push({
|
||||
path: '**',
|
||||
redirectTo: this._dashboards?.[0]?.meta.pathname,
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._dashboardsSubscription?.unsubscribe();
|
||||
this._sectionContextSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-tab-group id="tabs">
|
||||
${this._dashboards.map(
|
||||
(dashboard: UmbExtensionManifestDashboard) => html`
|
||||
<uui-tab
|
||||
href="${`/section/${this._currentSectionPathname}/dashboard/${dashboard.meta.pathname}`}"
|
||||
label=${dashboard.name}
|
||||
?active="${dashboard.meta.pathname === this._currentDashboardPathname}"></uui-tab>
|
||||
`
|
||||
)}
|
||||
</uui-tab-group>
|
||||
<router-slot id="router-slot" .routes="${this._routes}"></router-slot>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbSectionDashboards;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-section-dashboards': UmbSectionDashboards;
|
||||
}
|
||||
}
|
||||
30
src/Umbraco.Web.UI.Client/src/core/stores/section.store.ts
Normal file
30
src/Umbraco.Web.UI.Client/src/core/stores/section.store.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { map, Observable, ReplaySubject } from 'rxjs';
|
||||
import { UmbExtensionRegistry } from '../extension';
|
||||
|
||||
export class UmbSectionStore {
|
||||
private _extensionRegistry: UmbExtensionRegistry;
|
||||
|
||||
private _currentAlias: ReplaySubject<string> = new ReplaySubject(1);
|
||||
public readonly currentAlias: Observable<string> = this._currentAlias.asObservable();
|
||||
|
||||
// TODO: how do we want to handle DI in contexts?
|
||||
constructor(extensionRegistry: UmbExtensionRegistry) {
|
||||
this._extensionRegistry = extensionRegistry;
|
||||
}
|
||||
|
||||
public getAllowed() {
|
||||
// TODO: implemented allowed filtering
|
||||
/*
|
||||
const { data } = await getUserSections({});
|
||||
this._allowedSection = data.sections;
|
||||
*/
|
||||
|
||||
return this._extensionRegistry
|
||||
?.extensionsOfType('section')
|
||||
.pipe(map((extensions) => extensions.sort((a, b) => b.meta.weight - a.meta.weight)));
|
||||
}
|
||||
|
||||
public setCurrent(alias: string) {
|
||||
this._currentAlias.next(alias);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user