static: add elements for sidebar brand and sidebar user

This commit is contained in:
Jens Langhammer 2020-11-22 19:37:09 +01:00
parent 3c311ca527
commit 07773ed934
7 changed files with 247 additions and 139 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,4 +4,11 @@ export interface User {
name: string; name: string;
is_superuser: boolean; is_superuser: boolean;
email: boolean; email: boolean;
avatar: string;
}
export function me(): Promise<User> {
return fetch("/api/v2beta/core/users/me/")
.then((r) => r.json())
.then((r) => <User>r);
} }

View File

@ -12,16 +12,31 @@ import PageStyle from "@patternfly/patternfly/components/Page/page.css";
import NavStyle from "@patternfly/patternfly/components/Nav/nav.css"; import NavStyle from "@patternfly/patternfly/components/Nav/nav.css";
// @ts-ignore // @ts-ignore
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css"; import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
import { User } from "../api/user";
import { me, User } from "../api/user";
export interface SidebarItem { export interface SidebarItem {
name: string; name: string;
path?: string; path?: string;
children?: SidebarItem[]; children?: SidebarItem[];
condition?: (sb: SideBar) => boolean; condition?: (sb: Sidebar) => boolean;
} }
export const SIDEBAR_ITEMS: SidebarItem[] = [ export const SIDEBAR_ITEMS: SidebarItem[] = [
{
name: "Library",
path: "/-/overview/",
},
{
name: "Monitor",
path: "/audit/audit/",
condition: (sb: Sidebar) => {
return sb.user?.is_superuser!;
},
},
{
name: "Administration",
children: [
{ {
name: "General", name: "General",
children: [ children: [
@ -110,31 +125,15 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [
name: "Tokens", name: "Tokens",
path: "administration/tokens", path: "administration/tokens",
}, },
]; ],
condition: (sb: Sidebar) => {
export const ROOT_ITEMS: SidebarItem[] = [
{
name: "Library",
path: "/-/overview/",
},
{
name: "Monitor",
path: "/audit/audit/",
condition: (sb: SideBar) => {
return sb.user?.is_superuser!;
},
},
{
name: "Administration",
children: SIDEBAR_ITEMS,
condition: (sb: SideBar) => {
return sb.user?.is_superuser!; return sb.user?.is_superuser!;
}, },
}, },
]; ];
@customElement("pb-sidebar") @customElement("pb-sidebar")
export class SideBar extends LitElement { export class Sidebar extends LitElement {
@property() @property()
activePath: string; activePath: string;
@ -161,21 +160,11 @@ export class SideBar extends LitElement {
.pf-c-nav__subnav { .pf-c-nav__subnav {
--pf-c-nav__subnav--PaddingBottom: 0px; --pf-c-nav__subnav--PaddingBottom: 0px;
} }
.pb-brand {
font-family: "DIN 1451 Std"; .pf-c-nav__item-bottom {
line-height: 60px; position: absolute;
font-size: 3rem; bottom: 0;
color: var(--pf-c-nav__link--m-current--Color);
display: flex;
flex-direction: row;
justify-content: center;
width: 100%; width: 100%;
margin: 0 1rem;
margin-bottom: 1.5rem;
}
.pb-brand img {
max-height: 60px;
margin-right: 8px;
} }
`, `,
]; ];
@ -183,28 +172,13 @@ export class SideBar extends LitElement {
constructor() { constructor() {
super(); super();
fetch("/api/v2beta/core/users/me/") me().then((u) => (this.user = u));
.then((r) => r.json())
.then((r) => (this.user = <User>r));
this.activePath = window.location.hash.slice(1, Infinity); this.activePath = window.location.hash.slice(1, Infinity);
window.addEventListener("hashchange", (e) => { window.addEventListener("hashchange", (e) => {
this.activePath = window.location.hash.slice(1, Infinity); this.activePath = window.location.hash.slice(1, Infinity);
}); });
} }
renderBrand(): TemplateResult {
return html`<li class="pf-c-nav__item">
<a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand pb-brand">
<img src="${this.brandLogo}" alt="passbook icon" />
${this.brandTitle
? html`<span>${this.brandTitle}</span>`
: ""}
</div>
</a>
</li>`;
}
renderItem(item: SidebarItem): TemplateResult { renderItem(item: SidebarItem): TemplateResult {
if (item.condition) { if (item.condition) {
const result = item.condition(this); const result = item.condition(this);
@ -247,8 +221,16 @@ export class SideBar extends LitElement {
return html`<div class="pf-c-page__sidebar-body"> return html`<div class="pf-c-page__sidebar-body">
<nav class="pf-c-nav" aria-label="Global"> <nav class="pf-c-nav" aria-label="Global">
<ul class="pf-c-nav__list"> <ul class="pf-c-nav__list">
${this.renderBrand()} <li class="pf-c-nav__item">
${ROOT_ITEMS.map((i) => this.renderItem(i))} <pb-sidebar-brand
.brandLogo=${this.brandLogo}
.brandTitle=${this.brandTitle}
></pb-sidebar-brand>
</li>
${SIDEBAR_ITEMS.map((i) => this.renderItem(i))}
<li class="pf-c-nav__item pf-c-nav__item-bottom">
<pb-sidebar-user .user=${this.user}></pb-sidebar-user>
</li>
</ul> </ul>
</nav> </nav>
</div>`; </div>`;

View File

@ -0,0 +1,48 @@
import { css, customElement, html, LitElement, property } from "lit-element";
// @ts-ignore
import PageStyle from "@patternfly/patternfly/components/Page/page.css";
// @ts-ignore
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
@customElement("pb-sidebar-brand")
export class SidebarBrand extends LitElement {
@property()
brandLogo?: string;
@property()
brandTitle?: string;
static get styles() {
return [
GlobalsStyle,
PageStyle,
css`
.pf-c-brand {
font-family: "DIN 1451 Std";
line-height: 60px;
font-size: 3rem;
color: var(--pf-c-nav__link--m-current--Color);
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
margin: 0 1rem;
margin-bottom: 1.5rem;
}
.pf-c-brand img {
max-height: 60px;
margin-right: 8px;
}
`,
];
}
render() {
return html` <a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand pb-brand">
<img src="${this.brandLogo}" alt="passbook icon" />
${this.brandTitle ? html`<span>${this.brandTitle}</span>` : ""}
</div>
</a>`;
}
}

View File

@ -0,0 +1,69 @@
import { css, customElement, html, LitElement, property } from "lit-element";
// @ts-ignore
import NavStyle from "@patternfly/patternfly/components/Nav/nav.css";
// @ts-ignore
import fa from "@fortawesome/fontawesome-free/css/all.css";
// @ts-ignore
import AvatarStyle from "@patternfly/patternfly/components/Avatar/avatar.css";
import { User } from "../api/user";
@customElement("pb-sidebar-user")
export class SidebarUser extends LitElement {
@property()
user?: User;
static get styles() {
return [
fa,
NavStyle,
AvatarStyle,
css`
:host {
display: flex;
width: 100%;
flex-direction: row;
justify-content: space-between;
}
.pf-c-nav__link {
align-items: center;
}
.user-avatar {
display: flex;
flex-direction: row;
}
.user-avatar > span {
line-height: var(--pf-c-avatar--Height);
padding-left: var(--pf-global--spacer--sm);
font-size: var(--pf-global--FontSize--lg);
}
.user-logout {
flex-shrink: 3;
max-width: 75px;
}
`,
];
}
render() {
if (!this.user) {
return html``;
}
return html`
<a
href="/-/user/"
class="pf-c-nav__link user-avatar"
id="user-settings"
>
<img class="pf-c-avatar" src="${this.user?.avatar}" alt="" />
<span>${this.user?.username}</span>
</a>
<a
href="/-/default/invalidation/"
class="pf-c-nav__link user-logout"
id="logout"
>
<i class="fas fa-sign-out-alt" aria-hidden="true"></i>
</a>
`;
}
}

View File

@ -2,6 +2,8 @@ import "./legacy.js";
import "./elements/ActionButton"; import "./elements/ActionButton";
import "./elements/Sidebar"; import "./elements/Sidebar";
import "./elements/SidebarBrand";
import "./elements/SidebarUser";
import "./elements/CodeMirror"; import "./elements/CodeMirror";
import "./elements/Dropdown"; import "./elements/Dropdown";
import "./elements/FetchFillSlot"; import "./elements/FetchFillSlot";