web/user: refactor loading of data in userinterface
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
0767107730
commit
33f547c870
|
@ -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>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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>`;
|
||||||
}),
|
|
||||||
)}`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue