web: housekeeping, optimizations and small fixes (#12450)

* web/user: fix incorrect font in RAC endpoint popup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix navbar button colour in light mode

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add about modal

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix sidebar overlapping page header

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix wizard hint alignment

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add loading state to about modal

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add version context

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* stub out init functions on loading interface

saves 4 HTTP requests on each full page load 🎉

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix z-index for panels

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove redundant api request

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L.
2024-12-22 17:01:46 +01:00
committed by GitHub
parent 02bd699917
commit dc3559c7e9
16 changed files with 288 additions and 67 deletions

View File

@ -0,0 +1,117 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { VERSION } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import "@goauthentik/elements/EmptyState";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import { msg } from "@lit/localize";
import { TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import PFAbout from "@patternfly/patternfly/components/AboutModalBox/about-modal-box.css";
import { AdminApi, CapabilitiesEnum, LicenseSummaryStatusEnum } from "@goauthentik/api";
@customElement("ak-about-modal")
export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton)) {
static get styles() {
return super.styles.concat(
PFAbout,
css`
.pf-c-about-modal-box__hero {
background-image: url("/static/dist/assets/images/flow_background.jpg");
}
`,
);
}
async getAboutEntries(): Promise<[string, string | TemplateResult][]> {
const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
let build: string | TemplateResult = msg("Release");
if (globalAK().config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
build = msg("Development");
} else if (version.buildHash !== "") {
build = html`<a
rel="noopener noreferrer"
href="https://github.com/goauthentik/authentik/commit/${version.buildHash}"
target="_blank"
>${version.buildHash}</a
>`;
}
return [
[msg("Version"), version.versionCurrent],
[msg("UI Version"), VERSION],
[msg("Build"), build],
[msg("Python version"), status.runtime.pythonVersion],
[msg("Platform"), status.runtime.platform],
[msg("Kernel"), status.runtime.uname],
[
msg("OpenSSL"),
`${status.runtime.opensslVersion} ${status.runtime.opensslFipsEnabled ? "FIPS" : ""}`,
],
];
}
renderModal() {
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
product += ` ${msg("Enterprise")}`;
}
return html`<div
class="pf-c-backdrop"
@click=${(e: PointerEvent) => {
e.stopPropagation();
}}
>
<div class="pf-l-bullseye">
<div class="pf-c-about-modal-box" role="dialog" aria-modal="true">
<div class="pf-c-about-modal-box__brand">
<img
class="pf-c-about-modal-box__brand-image"
src=${this.brand?.brandingFavicon ?? DefaultBrand.brandingFavicon}
alt="authentik Logo"
/>
</div>
<div class="pf-c-about-modal-box__close">
<button
class="pf-c-button pf-m-plain"
type="button"
@click=${() => {
this.open = false;
}}
>
<i class="fas fa-times" aria-hidden="true"></i>
</button>
</div>
<div class="pf-c-about-modal-box__header">
<h1 class="pf-c-title pf-m-4xl">${product}</h1>
</div>
<div class="pf-c-about-modal-box__hero"></div>
<div class="pf-c-about-modal-box__content">
<div class="pf-c-about-modal-box__body">
<div class="pf-c-content">
${until(
this.getAboutEntries().then((entries) => {
return html`<dl>
${entries.map(([label, value]) => {
return html`<dt>${label}</dt>
<dd>${value}</dd>`;
})}
</dl>`;
}),
html`<ak-empty-state loading></ak-empty-state>`,
)}
</div>
</div>
<p class="pf-c-about-modal-box__strapline"></p>
</div>
</div>
</div>
</div>`;
}
}

View File

@ -1,5 +1,6 @@
import "@goauthentik/admin/AdminInterface/AboutModal";
import type { AboutModal } from "@goauthentik/admin/AdminInterface/AboutModal";
import { ROUTES } from "@goauthentik/admin/Routes";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import {
EVENT_API_DRAWER_TOGGLE,
EVENT_NOTIFICATION_DRAWER_TOGGLE,
@ -20,7 +21,7 @@ import "@goauthentik/elements/sidebar/Sidebar";
import "@goauthentik/elements/sidebar/SidebarItem";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { customElement, property, query, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -28,7 +29,7 @@ import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AdminApi, SessionUser, UiThemeEnum, Version } from "@goauthentik/api";
import { SessionUser, UiThemeEnum, Version } from "@goauthentik/api";
import "./AdminSidebar";
@ -48,6 +49,9 @@ export class AdminInterface extends EnterpriseAwareInterface {
@state()
user?: SessionUser;
@query("ak-about-modal")
aboutModal?: AboutModal;
static get styles(): CSSResult[] {
return [
PFBase,
@ -77,6 +81,9 @@ export class AdminInterface extends EnterpriseAwareInterface {
ak-admin-sidebar {
grid-area: nav;
}
.pf-c-drawer__panel {
z-index: var(--pf-global--ZIndex--xl);
}
`,
];
}
@ -100,7 +107,6 @@ export class AdminInterface extends EnterpriseAwareInterface {
async firstUpdated(): Promise<void> {
configureSentry(true);
this.version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
this.user = await me();
const canAccessAdmin =
this.user.user.isSuperuser ||
@ -159,6 +165,7 @@ export class AdminInterface extends EnterpriseAwareInterface {
: "display-none"}"
?hidden=${!this.apiDrawerOpen}
></ak-api-drawer>
<ak-about-modal></ak-about-modal>
</div>
</div>
</div></div

View File

@ -7,6 +7,7 @@ import {
CapabilitiesEnum,
WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider";
import { WithVersion } from "@goauthentik/elements/Interface/versionProvider";
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route";
import { getRootStyle } from "@goauthentik/elements/utils/getRootStyle";
import { spread } from "@open-wc/lit-helpers";
@ -16,25 +17,19 @@ import { TemplateResult, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { map } from "lit/directives/map.js";
import { AdminApi, CoreApi, UiThemeEnum, Version } from "@goauthentik/api";
import { CoreApi, UiThemeEnum } from "@goauthentik/api";
import type { SessionUser, UserSelf } from "@goauthentik/api";
@customElement("ak-admin-sidebar")
export class AkAdminSidebar extends WithCapabilitiesConfig(AKElement) {
export class AkAdminSidebar extends WithCapabilitiesConfig(WithVersion(AKElement)) {
@property({ type: Boolean, reflect: true })
open = true;
@state()
version: Version["versionCurrent"] | null = null;
@state()
impersonation: UserSelf["username"] | null = null;
constructor() {
super();
new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve().then((version) => {
this.version = version.versionCurrent;
});
me().then((user: SessionUser) => {
this.impersonation = user.original ? user.user.username : null;
});
@ -175,12 +170,10 @@ export class AkAdminSidebar extends WithCapabilitiesConfig(AKElement) {
}
renderNewVersionMessage() {
return this.version && this.version !== VERSION
return this.version && this.version.versionCurrent !== VERSION
? html`
<ak-sidebar-item ?highlight=${true}>
<span slot="label"
>${msg("A newer version of the frontend is available.")}</span
>
<span slot="label">${msg("A newer version of the UI is available.")}</span>
</ak-sidebar-item>
`
: nothing;