split sections and tools from header element
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
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 { getUserSections } from '../core/api/fetcher';
|
||||
import { UmbExtensionManifest } 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) {
|
||||
static styles: CSSResultGroup = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
#tabs {
|
||||
color: var(--uui-look-primary-contrast);
|
||||
height: 60px;
|
||||
font-size: 16px;
|
||||
--uui-tab-text: var(--uui-look-primary-contrast);
|
||||
--uui-tab-text-hover: var(--uui-look-primary-contrast-hover);
|
||||
--uui-tab-text-active: var(--uui-interface-active);
|
||||
--uui-tab-background: var(--uui-look-primary-surface);
|
||||
}
|
||||
|
||||
#dropdown {
|
||||
background-color: white;
|
||||
border-radius: var(--uui-border-radius);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
box-shadow: var(--uui-shadow-depth-3);
|
||||
min-width: 200px;
|
||||
color: black; /* Change to variable */
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@state()
|
||||
private _open = false;
|
||||
|
||||
@state()
|
||||
private _allowedSection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
private _sections: Array<UmbExtensionManifest> = [];
|
||||
|
||||
@state()
|
||||
private _visibleSections: Array<UmbExtensionManifest> = [];
|
||||
|
||||
@state()
|
||||
private _extraSections: Array<UmbExtensionManifest> = [];
|
||||
|
||||
@state()
|
||||
private _currentSectionAlias = '';
|
||||
|
||||
private _router?: UmbRouter;
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _sectionSubscription?: Subscription;
|
||||
private _currentSectionSubscription?: Subscription;
|
||||
private _locationSubscription?: Subscription;
|
||||
private _location? : UmbRouteLocation;
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbRouter', (_instance: UmbRouter) => {
|
||||
this._router = _instance;
|
||||
this._useLocation();
|
||||
});
|
||||
|
||||
this.consumeContext('umbSectionContext', (_instance: UmbSectionContext) => {
|
||||
this._sectionContext = _instance;
|
||||
this._useCurrentSection();
|
||||
this._useSections();
|
||||
});
|
||||
}
|
||||
|
||||
private _handleMore(e: MouseEvent) {
|
||||
e.stopPropagation();
|
||||
this._open = !this._open;
|
||||
}
|
||||
|
||||
private _handleTabClick(e: PointerEvent, section: UmbExtensionManifest) {
|
||||
const tab = e.currentTarget as any;
|
||||
|
||||
// TODO: we need to be able to prevent the tab from setting the active state
|
||||
if (tab.id === 'moreTab') {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: this could maybe be handled by an anchor tag
|
||||
this._router?.push(`/section/${section.meta.pathname}`);
|
||||
this._sectionContext?.setCurrent(section.alias);
|
||||
}
|
||||
|
||||
private _handleLabelClick(e: PointerEvent) {
|
||||
const label = (e.target as any).label;
|
||||
|
||||
// TODO: set current section
|
||||
//this._sectionContext?.setCurrent(section.alias);
|
||||
|
||||
const moreTab = this.shadowRoot?.getElementById('moreTab');
|
||||
moreTab?.setAttribute('active', 'true');
|
||||
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
private _useLocation () {
|
||||
this._locationSubscription?.unsubscribe();
|
||||
|
||||
this._locationSubscription = this._router?.location
|
||||
.subscribe((location: UmbRouteLocation) => {
|
||||
this._location = location;
|
||||
});
|
||||
}
|
||||
|
||||
private _useCurrentSection () {
|
||||
this._currentSectionSubscription?.unsubscribe();
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._locationSubscription?.unsubscribe();
|
||||
this._sectionSubscription?.unsubscribe();
|
||||
this._currentSectionSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-tab-group id="tabs">
|
||||
${this._visibleSections.map(
|
||||
(section) => html`
|
||||
<uui-tab
|
||||
?active="${this._currentSectionAlias === section.alias}"
|
||||
label="${section.name}"
|
||||
@click="${(e: PointerEvent) => this._handleTabClick(e, section)}"></uui-tab>
|
||||
`
|
||||
)}
|
||||
${this._renderExtraSections()}
|
||||
</uui-tab-group>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderExtraSections() {
|
||||
return when(
|
||||
this._extraSections.length > 0,
|
||||
() => html`
|
||||
<uui-tab id="moreTab" @click="${this._handleTabClick}">
|
||||
<uui-popover .open=${this._open} placement="bottom-start" @close="${() => (this._open = false)}">
|
||||
<uui-button slot="trigger" look="primary" label="More" @click="${this._handleMore}" compact>
|
||||
<uui-symbol-more></uui-symbol-more>
|
||||
</uui-button>
|
||||
|
||||
<div slot="popover" id="dropdown">
|
||||
${this._extraSections.map(
|
||||
(section) => html`
|
||||
<uui-menu-item
|
||||
?active="${this._currentSectionAlias === section.alias}"
|
||||
label="${section.name}"
|
||||
@click-label="${this._handleLabelClick}"></uui-menu-item>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</uui-popover>
|
||||
</uui-tab>
|
||||
`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-backoffice-header-sections': UmbBackofficeHeaderSections;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
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 {
|
||||
static styles: CSSResultGroup = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
#tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--uui-size-space-2);
|
||||
}
|
||||
|
||||
.tool {
|
||||
font-size: 18px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div id="tools">
|
||||
<uui-button class="tool" look="primary" label="Search" compact>
|
||||
<uui-icon name="search"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button class="tool" look="primary" label="Help" compact>
|
||||
<uui-icon name="favorite"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button look="primary" style="font-size: 14px;" label="User" compact>
|
||||
<uui-avatar name="Mads Rasmussen"></uui-avatar>
|
||||
</uui-button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-backoffice-header-tools': UmbBackofficeHeaderTools;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,19 @@
|
||||
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 { getUserSections } from '../core/api/fetcher';
|
||||
import { UmbExtensionManifest, UmbManifestSectionMeta } from '../core/extension';
|
||||
import { UmbRouteLocation, UmbRouter } from '../core/router';
|
||||
import { UmbSectionContext } from '../section.context';
|
||||
import { UmbContextConsumerMixin } from '../core/context';
|
||||
|
||||
// TODO: umb or not umb in file name?
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
|
||||
import './backoffice-header-sections.element';
|
||||
import './backoffice-header-tools.element';
|
||||
@customElement('umb-backoffice-header')
|
||||
export class UmbBackofficeHeader extends UmbContextConsumerMixin(LitElement) {
|
||||
export class UmbBackofficeHeader extends LitElement {
|
||||
static styles: CSSResultGroup = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#appHeader {
|
||||
background-color: var(--uui-look-primary-surface);
|
||||
display: flex;
|
||||
@@ -41,181 +35,10 @@ export class UmbBackofficeHeader extends UmbContextConsumerMixin(LitElement) {
|
||||
|
||||
#sections {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--uui-size-space-2);
|
||||
}
|
||||
|
||||
#tabs {
|
||||
color: var(--uui-look-primary-contrast);
|
||||
height: 60px;
|
||||
font-size: 16px;
|
||||
--uui-tab-text: var(--uui-look-primary-contrast);
|
||||
--uui-tab-text-hover: var(--uui-look-primary-contrast-hover);
|
||||
--uui-tab-text-active: var(--uui-interface-active);
|
||||
--uui-tab-background: var(--uui-look-primary-surface);
|
||||
}
|
||||
|
||||
#tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--uui-size-space-2);
|
||||
}
|
||||
|
||||
.tool {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#dropdown {
|
||||
background-color: white;
|
||||
border-radius: var(--uui-border-radius);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
box-shadow: var(--uui-shadow-depth-3);
|
||||
min-width: 200px;
|
||||
color: black; /* Change to variable */
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@state()
|
||||
private _open = false;
|
||||
|
||||
@state()
|
||||
private _allowedSection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
private _sections: Array<UmbExtensionManifest> = [];
|
||||
|
||||
@state()
|
||||
private _visibleSections: Array<UmbExtensionManifest> = [];
|
||||
|
||||
@state()
|
||||
private _extraSections: Array<UmbExtensionManifest> = [];
|
||||
|
||||
@state()
|
||||
private _currentSectionAlias = '';
|
||||
|
||||
private _router?: UmbRouter;
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _sectionSubscription?: Subscription;
|
||||
private _currentSectionSubscription?: Subscription;
|
||||
private _locationSubscription?: Subscription;
|
||||
private _location? : UmbRouteLocation;
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbRouter', (_instance: UmbRouter) => {
|
||||
this._router = _instance;
|
||||
this._useLocation();
|
||||
});
|
||||
|
||||
this.consumeContext('umbSectionContext', (_instance: UmbSectionContext) => {
|
||||
this._sectionContext = _instance;
|
||||
this._useCurrentSection();
|
||||
this._useSections();
|
||||
});
|
||||
}
|
||||
|
||||
private _handleMore(e: MouseEvent) {
|
||||
e.stopPropagation();
|
||||
this._open = !this._open;
|
||||
}
|
||||
|
||||
private _handleTabClick(e: PointerEvent, section: UmbExtensionManifest) {
|
||||
const tab = e.currentTarget as any;
|
||||
|
||||
// TODO: we need to be able to prevent the tab from setting the active state
|
||||
if (tab.id === 'moreTab') {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: this could maybe be handled by an anchor tag
|
||||
this._router?.push(`/section/${section.meta.pathname}`);
|
||||
this._sectionContext?.setCurrent(section.alias);
|
||||
}
|
||||
|
||||
private _handleLabelClick(e: PointerEvent) {
|
||||
const label = (e.target as any).label;
|
||||
|
||||
// TODO: set current section
|
||||
//this._sectionContext?.setCurrent(section.alias);
|
||||
|
||||
const moreTab = this.shadowRoot?.getElementById('moreTab');
|
||||
moreTab?.setAttribute('active', 'true');
|
||||
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
private _useLocation () {
|
||||
this._locationSubscription?.unsubscribe();
|
||||
|
||||
this._locationSubscription = this._router?.location
|
||||
.subscribe((location: UmbRouteLocation) => {
|
||||
this._location = location;
|
||||
});
|
||||
}
|
||||
|
||||
private _useCurrentSection () {
|
||||
this._currentSectionSubscription?.unsubscribe();
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._locationSubscription?.unsubscribe();
|
||||
this._sectionSubscription?.unsubscribe();
|
||||
this._currentSectionSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
private _renderExtraSections() {
|
||||
return when(
|
||||
this._extraSections.length > 0,
|
||||
() => html`
|
||||
<uui-tab id="moreTab" @click="${this._handleTabClick}">
|
||||
<uui-popover .open=${this._open} placement="bottom-start" @close="${() => (this._open = false)}">
|
||||
<uui-button slot="trigger" look="primary" label="More" @click="${this._handleMore}" compact>
|
||||
<uui-symbol-more></uui-symbol-more>
|
||||
</uui-button>
|
||||
|
||||
<div slot="popover" id="dropdown">
|
||||
${this._extraSections.map(
|
||||
(section) => html`
|
||||
<uui-menu-item
|
||||
?active="${this._currentSectionAlias === section.alias}"
|
||||
label="${section.name}"
|
||||
@click-label="${this._handleLabelClick}"></uui-menu-item>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</uui-popover>
|
||||
</uui-tab>
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div id="appHeader">
|
||||
@@ -223,31 +46,8 @@ export class UmbBackofficeHeader extends UmbContextConsumerMixin(LitElement) {
|
||||
<img src="/umbraco_logomark_white.svg" alt="Umbraco" />
|
||||
</uui-button>
|
||||
|
||||
<div id="sections">
|
||||
<uui-tab-group id="tabs">
|
||||
${this._visibleSections.map(
|
||||
(section) => html`
|
||||
<uui-tab
|
||||
?active="${this._currentSectionAlias === section.alias}"
|
||||
label="${section.name}"
|
||||
@click="${(e: PointerEvent) => this._handleTabClick(e, section)}"></uui-tab>
|
||||
`
|
||||
)}
|
||||
${this._renderExtraSections()}
|
||||
</uui-tab-group>
|
||||
</div>
|
||||
|
||||
<div id="tools">
|
||||
<uui-button class="tool" look="primary" label="Search" compact>
|
||||
<uui-icon name="search"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button class="tool" look="primary" label="Help" compact>
|
||||
<uui-icon name="favorite"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button look="primary" style="font-size: 14px;" label="User" compact>
|
||||
<uui-avatar name="Mads Rasmussen"></uui-avatar>
|
||||
</uui-button>
|
||||
</div>
|
||||
<umb-backoffice-header-sections id="sections"></umb-backoffice-header-sections>
|
||||
<umb-backoffice-header-tools></umb-backoffice-header-tools>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import './backoffice-header.element';
|
||||
import './backoffice-sidebar.element';
|
||||
import './backoffice-main.element';
|
||||
|
||||
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
import './backoffice-header.element';
|
||||
import './backoffice-sidebar.element';
|
||||
import './backoffice-main.element';
|
||||
|
||||
@defineElement('umb-backoffice')
|
||||
export class UmbBackoffice extends LitElement {
|
||||
static styles = [
|
||||
|
||||
Reference in New Issue
Block a user