web: sort components into folders, implement pagination for table
This commit is contained in:
221
web/src/elements/sidebar/Sidebar.ts
Normal file
221
web/src/elements/sidebar/Sidebar.ts
Normal file
@ -0,0 +1,221 @@
|
||||
import { css, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
||||
// @ts-ignore
|
||||
import PageStyle from "@patternfly/patternfly/components/Page/page.css";
|
||||
// @ts-ignore
|
||||
import NavStyle from "@patternfly/patternfly/components/Nav/nav.css";
|
||||
// @ts-ignore
|
||||
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
||||
|
||||
import { User } from "../../api/user";
|
||||
|
||||
export interface SidebarItem {
|
||||
name: string;
|
||||
path?: string[];
|
||||
children?: SidebarItem[];
|
||||
condition?: (sb: Sidebar) => boolean;
|
||||
}
|
||||
|
||||
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: "Overview",
|
||||
path: ["/administration/overview/"],
|
||||
},
|
||||
{
|
||||
name: "System Tasks",
|
||||
path: ["/administration/tasks/"],
|
||||
},
|
||||
{
|
||||
name: "Applications",
|
||||
path: ["/administration/applications/"],
|
||||
},
|
||||
{
|
||||
name: "Sources",
|
||||
path: ["/administration/sources/"],
|
||||
},
|
||||
{
|
||||
name: "Providers",
|
||||
path: ["/administration/providers/"],
|
||||
},
|
||||
{
|
||||
name: "User Management",
|
||||
children: [
|
||||
{
|
||||
name: "User",
|
||||
path: ["/administration/users/"],
|
||||
},
|
||||
{
|
||||
name: "Groups",
|
||||
path: ["/administration/groups/"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Outposts",
|
||||
children: [
|
||||
{
|
||||
name: "Outposts",
|
||||
path: ["/administration/outposts/"],
|
||||
},
|
||||
{
|
||||
name: "Service Connections",
|
||||
path: ["/administration/outposts/service_connections/"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Policies",
|
||||
children: [
|
||||
{
|
||||
name: "Policies",
|
||||
path: ["/administration/policies/"],
|
||||
},
|
||||
{
|
||||
name: "Bindings",
|
||||
path: ["/administration/policies/bindings/"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Property Mappings",
|
||||
path: ["/administration/property-mappings/"],
|
||||
},
|
||||
{
|
||||
name: "Flows",
|
||||
children: [
|
||||
{
|
||||
name: "Flows",
|
||||
path: ["/administration/flows/"],
|
||||
},
|
||||
{
|
||||
name: "Stages",
|
||||
path: ["/administration/stages/"],
|
||||
},
|
||||
{
|
||||
name: "Prompts",
|
||||
path: ["/administration/stages/prompts/"],
|
||||
},
|
||||
{
|
||||
name: "Invitations",
|
||||
path: ["/administration/stages/invitations/"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Certificates",
|
||||
path: ["/administration/crypto/certificates/"],
|
||||
},
|
||||
{
|
||||
name: "Tokens",
|
||||
path: ["/administration/tokens/"],
|
||||
},
|
||||
],
|
||||
condition: (sb: Sidebar) => {
|
||||
return sb.user?.is_superuser!;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@customElement("pb-sidebar")
|
||||
export class Sidebar extends LitElement {
|
||||
@property()
|
||||
activePath: string;
|
||||
|
||||
@property()
|
||||
user?: User;
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
GlobalsStyle,
|
||||
PageStyle,
|
||||
NavStyle,
|
||||
css`
|
||||
.pf-c-nav__link {
|
||||
--pf-c-nav__link--PaddingTop: 0.5rem;
|
||||
--pf-c-nav__link--PaddingRight: 0.5rem;
|
||||
--pf-c-nav__link--PaddingBottom: 0.5rem;
|
||||
}
|
||||
.pf-c-nav__subnav {
|
||||
--pf-c-nav__subnav--PaddingBottom: 0px;
|
||||
}
|
||||
|
||||
.pf-c-nav__item-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
User.me().then((u) => (this.user = u));
|
||||
this.activePath = window.location.hash.slice(1, Infinity);
|
||||
window.addEventListener("hashchange", (e) => {
|
||||
this.activePath = window.location.hash.slice(1, Infinity);
|
||||
});
|
||||
}
|
||||
|
||||
renderItem(item: SidebarItem): TemplateResult {
|
||||
if (item.condition) {
|
||||
const result = item.condition(this);
|
||||
if (!result) {
|
||||
return html``;
|
||||
}
|
||||
}
|
||||
return html` <li
|
||||
class="pf-c-nav__item ${item.children ? "pf-m-expandable pf-m-expanded" : ""}"
|
||||
>
|
||||
${item.path
|
||||
? html`<a
|
||||
href="#${item.path}"
|
||||
class="pf-c-nav__link ${item.path.some((v) => v === this.activePath)
|
||||
? "pf-m-current"
|
||||
: ""}"
|
||||
>
|
||||
${item.name}
|
||||
</a>`
|
||||
: html`<a class="pf-c-nav__link" aria-expanded="true"
|
||||
>${item.name}
|
||||
<span class="pf-c-nav__toggle">
|
||||
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||
</span>
|
||||
</a>
|
||||
<section class="pf-c-nav__subnav">
|
||||
<ul class="pf-c-nav__simple-list">
|
||||
${item.children?.map((i) => this.renderItem(i))}
|
||||
</ul>
|
||||
</section>`}
|
||||
</li>`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<div class="pf-c-page__sidebar-body">
|
||||
<nav class="pf-c-nav" aria-label="Global">
|
||||
<ul class="pf-c-nav__list">
|
||||
<li class="pf-c-nav__item">
|
||||
<pb-sidebar-brand></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>
|
||||
</nav>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
56
web/src/elements/sidebar/SidebarBrand.ts
Normal file
56
web/src/elements/sidebar/SidebarBrand.ts
Normal file
@ -0,0 +1,56 @@
|
||||
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";
|
||||
import { Config } from "../../api/config";
|
||||
|
||||
@customElement("pb-sidebar-brand")
|
||||
export class SidebarBrand extends LitElement {
|
||||
@property()
|
||||
config?: Config;
|
||||
|
||||
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;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
Config.get().then((c) => (this.config = c));
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.config) {
|
||||
return html``;
|
||||
}
|
||||
return html` <a href="" class="pf-c-page__header-brand-link">
|
||||
<div class="pf-c-brand pb-brand">
|
||||
<img src="${this.config?.branding_logo}" alt="passbook icon" loading="lazy" />
|
||||
${this.config?.branding_title
|
||||
? html`<span>${this.config.branding_title}</span>`
|
||||
: ""}
|
||||
</div>
|
||||
</a>`;
|
||||
}
|
||||
}
|
||||
61
web/src/elements/sidebar/SidebarUser.ts
Normal file
61
web/src/elements/sidebar/SidebarUser.ts
Normal file
@ -0,0 +1,61 @@
|
||||
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="/flows/-/default/invalidation/" class="pf-c-nav__link user-logout" id="logout">
|
||||
<i class="fas fa-sign-out-alt" aria-hidden="true"></i>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user