web/user: refactor loading of data in userinterface

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer 2023-02-04 18:30:22 +01:00
parent 0767107730
commit 33f547c870
No known key found for this signature in database
3 changed files with 227 additions and 259 deletions

View File

@ -23,8 +23,7 @@ import "@goauthentik/elements/sidebar/SidebarItem";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import AKGlobal from "@goauthentik/common/styles/authentik.css"; import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -32,7 +31,7 @@ import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AdminApi, Version } from "@goauthentik/api"; import { AdminApi, SessionUser, Version } from "@goauthentik/api";
autoDetectLanguage(); autoDetectLanguage();
@ -49,7 +48,11 @@ export class AdminInterface extends AKElement {
ws: WebsocketClient; ws: WebsocketClient;
private version: Promise<Version>; @state()
version?: Version;
@state()
user?: SessionUser;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return [
@ -103,12 +106,14 @@ export class AdminInterface extends AKElement {
apiDrawerOpen: this.apiDrawerOpen, apiDrawerOpen: this.apiDrawerOpen,
}); });
}); });
this.version = new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve(); }
me().then((u) => {
if (!u.user.isSuperuser && u.user.pk > 0) { async firstUpdated(): Promise<void> {
this.version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
this.user = await me();
if (!this.user.user.isSuperuser && this.user.user.pk > 0) {
window.location.assign("/if/user"); window.location.assign("/if/user");
} }
});
} }
render(): TemplateResult { render(): TemplateResult {
@ -160,22 +165,17 @@ export class AdminInterface extends AKElement {
renderSidebarItems(): TemplateResult { renderSidebarItems(): TemplateResult {
return html` return html`
${until( ${this.version?.versionCurrent !== VERSION
this.version.then((version) => { ? html`
if (version.versionCurrent !== VERSION) { <ak-sidebar-item ?highlight=${true}>
return html`<ak-sidebar-item ?highlight=${true}>
<span slot="label" <span slot="label"
>${t`A newer version of the frontend is available.`}</span >${t`A newer version of the frontend is available.`}</span
> >
</ak-sidebar-item>`; </ak-sidebar-item>
} `
return html``; : html``}
}), ${this.user?.original
)} ? html`<ak-sidebar-item
${until(
me().then((u) => {
if (u.original) {
return html`<ak-sidebar-item
?highlight=${true} ?highlight=${true}
?isAbsoluteLink=${true} ?isAbsoluteLink=${true}
path=${`/-/impersonation/end/?back=${encodeURIComponent( path=${`/-/impersonation/end/?back=${encodeURIComponent(
@ -183,13 +183,10 @@ export class AdminInterface extends AKElement {
)}`} )}`}
> >
<span slot="label" <span slot="label"
>${t`You're currently impersonating ${u.user.username}. Click to stop.`}</span >${t`You're currently impersonating ${this.user.user.username}. Click to stop.`}</span
> >
</ak-sidebar-item>`; </ak-sidebar-item>`
} : html``}
return html``;
}),
)}
<ak-sidebar-item path="/if/user/" ?isAbsoluteLink=${true} ?highlight=${true}> <ak-sidebar-item path="/if/user/" ?isAbsoluteLink=${true} ?highlight=${true}>
<span slot="label">${t`User interface`}</span> <span slot="label">${t`User interface`}</span>
</ak-sidebar-item> </ak-sidebar-item>

View File

@ -17,8 +17,7 @@ import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement, state } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import AKGlobal from "@goauthentik/common/styles/authentik.css"; import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css";
@ -26,6 +25,8 @@ import PFList from "@patternfly/patternfly/components/List/list.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import { SessionUser } from "@goauthentik/api";
export function versionFamily(): string { export function versionFamily(): string {
const parts = VERSION.split("."); const parts = VERSION.split(".");
parts.pop(); parts.pop();
@ -59,19 +60,20 @@ export class AdminOverviewPage extends AKElement {
]; ];
} }
render(): TemplateResult { @state()
return html`<ak-page-header icon="" header="" description=${t`General system status`}> user?: SessionUser;
<span slot="header">
${until( async firstUpdated(): Promise<void> {
me().then((user) => { this.user = await me();
let name = user.user.username;
if (user.user.name !== "") {
name = user.user.name;
} }
return t`Welcome, ${name}.`;
}), render(): TemplateResult {
)} let name = this.user?.user.username;
</span> if (this.user?.user.name) {
name = this.user.user.name;
}
return html`<ak-page-header icon="" header="" description=${t`General system status`}>
<span slot="header"> ${t`Welcome, ${name}.`} </span>
</ak-page-header> </ak-page-header>
<section class="pf-c-page__main-section"> <section class="pf-c-page__main-section">
<div class="pf-l-grid pf-m-gutter"> <div class="pf-l-grid pf-m-gutter">

View File

@ -5,7 +5,7 @@ import {
EVENT_WS_MESSAGE, EVENT_WS_MESSAGE,
} from "@goauthentik/common/constants"; } from "@goauthentik/common/constants";
import { configureSentry } from "@goauthentik/common/sentry"; import { configureSentry } from "@goauthentik/common/sentry";
import { UserDisplay, uiConfig } from "@goauthentik/common/ui/config"; import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
import { autoDetectLanguage } from "@goauthentik/common/ui/locale"; import { autoDetectLanguage } from "@goauthentik/common/ui/locale";
import { me } from "@goauthentik/common/users"; import { me } from "@goauthentik/common/users";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
@ -24,8 +24,7 @@ import { ROUTES } from "@goauthentik/user/Routes";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import AKGlobal from "@goauthentik/common/styles/authentik.css"; import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css"; import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
@ -38,7 +37,7 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css"; import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
import { CurrentTenant, EventsApi } from "@goauthentik/api"; import { CurrentTenant, EventsApi, SessionUser } from "@goauthentik/api";
autoDetectLanguage(); autoDetectLanguage();
@ -58,6 +57,12 @@ export class UserInterface extends AKElement {
@property({ type: Number }) @property({ type: Number })
notificationsCount = 0; notificationsCount = 0;
@state()
me?: SessionUser;
@state()
config?: UIConfig;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return [
PFBase, PFBase,
@ -121,47 +126,55 @@ export class UserInterface extends AKElement {
window.addEventListener(EVENT_WS_MESSAGE, () => { window.addEventListener(EVENT_WS_MESSAGE, () => {
this.firstUpdated(); this.firstUpdated();
}); });
tenant().then((tenant) => (this.tenant = tenant));
configureSentry(true); configureSentry(true);
} }
firstUpdated(): void { async firstUpdated(): Promise<void> {
me().then((user) => { this.tenant = await tenant();
new EventsApi(DEFAULT_CONFIG) this.me = await me();
.eventsNotificationsList({ this.config = await uiConfig();
const notifications = await new EventsApi(DEFAULT_CONFIG).eventsNotificationsList({
seen: false, seen: false,
ordering: "-created", ordering: "-created",
pageSize: 1, pageSize: 1,
user: user.user.pk, user: this.me.user.pk,
})
.then((r) => {
this.notificationsCount = r.pagination.count;
});
}); });
this.notificationsCount = notifications.pagination.count;
} }
render(): TemplateResult { render(): TemplateResult {
return html`${until( if (!this.config || !this.me) {
uiConfig().then((config) => { return html``;
}
let userDisplay = "";
switch (this.config.navbar.userDisplay) {
case UserDisplay.username:
userDisplay = this.me.user.username;
break;
case UserDisplay.name:
userDisplay = this.me.user.name;
break;
case UserDisplay.email:
userDisplay = this.me.user.email || "";
break;
default:
userDisplay = this.me.user.username;
}
return html`<div class="pf-c-page"> return html`<div class="pf-c-page">
<div class="background-wrapper" style="${config.theme.background}"></div> <div class="background-wrapper" style="${this.config.theme.background}"></div>
<header class="pf-c-page__header"> <header class="pf-c-page__header">
<div class="pf-c-page__header-brand"> <div class="pf-c-page__header-brand">
<a href="#/" class="pf-c-page__header-brand-link"> <a href="#/" class="pf-c-page__header-brand-link">
<img <img
class="pf-c-brand" class="pf-c-brand"
src="${first( src="${first(this.tenant.brandingLogo, DefaultTenant.brandingLogo)}"
this.tenant.brandingLogo, alt="${(this.tenant.brandingTitle, DefaultTenant.brandingTitle)}"
DefaultTenant.brandingLogo,
)}"
alt="${(this.tenant.brandingTitle,
DefaultTenant.brandingTitle)}"
/> />
</a> </a>
</div> </div>
<div class="pf-c-page__header-tools"> <div class="pf-c-page__header-tools">
<div class="pf-c-page__header-tools-group"> <div class="pf-c-page__header-tools-group">
${config.enabledFeatures.apiDrawer ${this.config.enabledFeatures.apiDrawer
? html`<div ? html`<div
class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg" class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg"
> >
@ -179,7 +192,7 @@ export class UserInterface extends AKElement {
</button> </button>
</div>` </div>`
: html``} : html``}
${config.enabledFeatures.notificationDrawer ${this.config.enabledFeatures.notificationDrawer
? html`<div ? html`<div
class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg" class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg"
> >
@ -191,14 +204,13 @@ export class UserInterface extends AKElement {
this.notificationDrawerOpen = this.notificationDrawerOpen =
!this.notificationDrawerOpen; !this.notificationDrawerOpen;
updateURLParams({ updateURLParams({
notificationDrawerOpen: notificationDrawerOpen: this.notificationDrawerOpen,
this.notificationDrawerOpen,
}); });
}} }}
> >
<span <span
class="pf-c-notification-badge ${this class="pf-c-notification-badge ${this.notificationsCount >
.notificationsCount > 0 0
? "pf-m-unread" ? "pf-m-unread"
: ""}" : ""}"
> >
@ -210,43 +222,29 @@ export class UserInterface extends AKElement {
</button> </button>
</div> ` </div> `
: html``} : html``}
${config.enabledFeatures.settings ${this.config.enabledFeatures.settings
? html` <div class="pf-c-page__header-tools-item"> ? html` <div class="pf-c-page__header-tools-item">
<a <a class="pf-c-button pf-m-plain" type="button" href="#/settings">
class="pf-c-button pf-m-plain"
type="button"
href="#/settings"
>
<i class="fas fa-cog" aria-hidden="true"></i> <i class="fas fa-cog" aria-hidden="true"></i>
</a> </a>
</div>` </div>`
: html``} : html``}
<div class="pf-c-page__header-tools-item"> <div class="pf-c-page__header-tools-item">
<a <a href="/flows/-/default/invalidation/" class="pf-c-button pf-m-plain">
href="/flows/-/default/invalidation/"
class="pf-c-button pf-m-plain"
>
<i class="fas fa-sign-out-alt" aria-hidden="true"></i> <i class="fas fa-sign-out-alt" aria-hidden="true"></i>
</a> </a>
</div> </div>
${until( ${this.me.user.isSuperuser
me().then((u) => { ? html`<a
if (!u.user.isSuperuser) return html``;
return html`
<a
class="pf-c-button pf-m-primary pf-m-small pf-u-display-none pf-u-display-block-on-md" class="pf-c-button pf-m-primary pf-m-small pf-u-display-none pf-u-display-block-on-md"
href="/if/admin" href="/if/admin"
> >
${t`Admin interface`} ${t`Admin interface`}
</a> </a>`
`; : html``}
}),
)}
</div> </div>
${until( ${this.me.original
me().then((u) => { ? html`<div class="pf-c-page__header-tools">
if (u.original) {
return html`<div class="pf-c-page__header-tools">
<div class="pf-c-page__header-tools-group"> <div class="pf-c-page__header-tools-group">
<a <a
class="pf-c-button pf-m-warning pf-m-small" class="pf-c-button pf-m-warning pf-m-small"
@ -257,40 +255,14 @@ export class UserInterface extends AKElement {
${t`Stop impersonation`} ${t`Stop impersonation`}
</a> </a>
</div> </div>
</div>`; </div>`
} : html``}
return html``;
}),
)}
<div class="pf-c-page__header-tools-group"> <div class="pf-c-page__header-tools-group">
<div <div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-md">
class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-md" ${userDisplay}
>
${until(
me().then((me) => {
switch (config.navbar.userDisplay) {
case UserDisplay.username:
return me.user.username;
case UserDisplay.name:
return me.user.name;
case UserDisplay.email:
return me.user.email;
default:
return me.user.username;
}
}),
)}
</div> </div>
</div> </div>
${until( <img class="pf-c-avatar" src=${this.me.user.avatar} alt="${t`Avatar image`}" />
me().then((me) => {
return html`<img
class="pf-c-avatar"
src=${me.user.avatar}
alt="${t`Avatar image`}"
/>`;
}),
)}
</div> </div>
</header> </header>
<div class="pf-c-page__drawer"> <div class="pf-c-page__drawer">
@ -316,8 +288,7 @@ export class UserInterface extends AKElement {
</div> </div>
</div> </div>
<ak-notification-drawer <ak-notification-drawer
class="pf-c-drawer__panel pf-m-width-33 ${this class="pf-c-drawer__panel pf-m-width-33 ${this.notificationDrawerOpen
.notificationDrawerOpen
? "" ? ""
: "display-none"}" : "display-none"}"
?hidden=${!this.notificationDrawerOpen} ?hidden=${!this.notificationDrawerOpen}
@ -332,7 +303,5 @@ export class UserInterface extends AKElement {
</div> </div>
</div> </div>
</div>`; </div>`;
}),
)}`;
} }
} }