web: bug - licenseStatus is not defined on initial render (#10894)

* web: bug / licenseStatus is not defined on initial render

- Test if the licenseStatus is available before rendering the banner
- The banner is rendered correctly when the status becomes available.

The loading sequence is such that if the user reloads the page, the
first attempt to render the license banner fails because the
licenseStatus field is not yet populated; the result is an ugly
`licenseStatus is undefined` on the console.

Because the licenseStatus is a live context, when it is updated
any objects that subscribe to it are scheduled for a re-render.
This is why the system appears to behave correctly now.

While this is invisible to the user, it's still undesirable behavior.

Returning `nothing` requires that we remove the type declarations
as return values from the renderers. Typescript's inferers do
just fine.

* fix some other small things

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Ken Sternberg
2024-08-13 13:39:13 -07:00
committed by GitHub
parent ed49017f2d
commit 5a2ed5bf30
3 changed files with 10 additions and 7 deletions

View File

@ -214,7 +214,7 @@ def outpost_post_save(model_class: str, model_pk: Any):
if not hasattr(instance, field_name): if not hasattr(instance, field_name):
continue continue
LOGGER.debug("triggering outpost update from from field", field=field.name) LOGGER.debug("triggering outpost update from field", field=field.name)
# Because the Outpost Model has an M2M to Provider, # Because the Outpost Model has an M2M to Provider,
# we have to iterate over the entire QS # we have to iterate over the entire QS
for reverse in getattr(instance, field_name).all(): for reverse in getattr(instance, field_name).all():

View File

@ -97,7 +97,7 @@ export class AdminOverviewPage extends AdminOverviewBase {
const name = this.user?.user.name ?? this.user?.user.username; const name = this.user?.user.name ?? this.user?.user.username;
return html`<ak-page-header icon="" header="" description=${msg("General system status")}> return html`<ak-page-header icon="" header="" description=${msg("General system status")}>
<span slot="header"> ${msg(str`Welcome, ${name}.`)} </span> <span slot="header"> ${msg(str`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

@ -2,7 +2,7 @@ import { AKElement } from "@goauthentik/elements/Base";
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider"; import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, html, nothing } from "lit"; import { html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css"; import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
@ -14,7 +14,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
@property() @property()
interface: "admin" | "user" | "flow" | "" = ""; interface: "admin" | "user" | "flow" | "" = "";
static get styles(): CSSResult[] { static get styles() {
return [PFBanner]; return [PFBanner];
} }
@ -37,6 +37,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
return nothing; return nothing;
} }
break; break;
case LicenseSummaryStatusEnum.Unlicensed:
case LicenseSummaryStatusEnum.Valid: case LicenseSummaryStatusEnum.Valid:
return nothing; return nothing;
case LicenseSummaryStatusEnum.ReadOnly: case LicenseSummaryStatusEnum.ReadOnly:
@ -78,7 +79,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
</div>`; </div>`;
} }
renderFlagBanner(): TemplateResult { renderFlagBanner() {
return html` return html`
${this.licenseSummary.licenseFlags.includes(LicenseFlagsEnum.Trial) ${this.licenseSummary.licenseFlags.includes(LicenseFlagsEnum.Trial)
? html`<div class="pf-c-banner pf-m-sticky pf-m-gold"> ? html`<div class="pf-c-banner pf-m-sticky pf-m-gold">
@ -93,8 +94,10 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
`; `;
} }
render(): TemplateResult { render() {
return html`${this.renderFlagBanner()}${this.renderStatusBanner()}`; return this.licenseSummary
? html`${this.renderFlagBanner()}${this.renderStatusBanner()}`
: nothing;
} }
} }