enterprise: add more info to enterprise forecast (#6292)

* add more info to enterprise forecast

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

* fix banner colour

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

* fix some layout

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

* fix layout for warning banner

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-07-18 23:24:44 +02:00 committed by GitHub
parent c1eef9278d
commit b6e8342466
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 71 deletions

View file

@ -64,6 +64,8 @@ class LicenseForecastSerializer(PassiveSerializer):
users = IntegerField(required=True) users = IntegerField(required=True)
external_users = IntegerField(required=True) external_users = IntegerField(required=True)
forecasted_users = IntegerField(required=True)
forecasted_external_users = IntegerField(required=True)
class LicenseViewSet(UsedByMixin, ModelViewSet): class LicenseViewSet(UsedByMixin, ModelViewSet):
@ -142,8 +144,10 @@ class LicenseViewSet(UsedByMixin, ModelViewSet):
forecast_for_months = 12 forecast_for_months = 12
response = LicenseForecastSerializer( response = LicenseForecastSerializer(
data={ data={
"users": users_in_last_month * forecast_for_months, "users": LicenseKey.get_default_user_count(),
"external_users": external_in_last_month * forecast_for_months, "external_users": LicenseKey.get_external_user_count(),
"forecasted_users": (users_in_last_month * forecast_for_months),
"forecasted_external_users": (external_in_last_month * forecast_for_months),
} }
) )
response.is_valid(raise_exception=True) response.is_valid(raise_exception=True)

View file

@ -31746,8 +31746,14 @@ components:
type: integer type: integer
external_users: external_users:
type: integer type: integer
forecasted_users:
type: integer
forecasted_external_users:
type: integer
required: required:
- external_users - external_users
- forecasted_external_users
- forecasted_users
- users - users
LicenseRequest: LicenseRequest:
type: object type: object

View file

@ -75,17 +75,7 @@ export class AdminInterface extends Interface {
.display-none { .display-none {
display: none; display: none;
} }
:host {
display: flex;
flex-direction: column;
height: 100%;
}
ak-locale-context {
display: flex;
flex-grow: 1;
}
.pf-c-page { .pf-c-page {
flex-grow: 1;
background-color: var(--pf-c-page--BackgroundColor) !important; background-color: var(--pf-c-page--BackgroundColor) !important;
} }
/* Global page background colour */ /* Global page background colour */
@ -130,8 +120,7 @@ export class AdminInterface extends Interface {
} }
render(): TemplateResult { render(): TemplateResult {
return html` <ak-locale-context return html` <ak-locale-context>
><ak-enterprise-status interface="admin"></ak-enterprise-status>
<div class="pf-c-page"> <div class="pf-c-page">
<ak-sidebar <ak-sidebar
class="pf-c-page__sidebar ${this.sidebarOpen class="pf-c-page__sidebar ${this.sidebarOpen

View file

@ -11,7 +11,7 @@ import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { TableColumn } from "@goauthentik/elements/table/Table"; import { TableColumn } from "@goauthentik/elements/table/Table";
import { TablePage } from "@goauthentik/elements/table/TablePage"; import { TablePage } from "@goauthentik/elements/table/TablePage";
import { msg } from "@lit/localize"; import { msg, str } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
@ -148,17 +148,23 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
class="pf-l-grid__item" class="pf-l-grid__item"
icon="pf-icon pf-icon-user" icon="pf-icon pf-icon-user"
header=${msg("Forecast default users")} header=${msg("Forecast default users")}
subtext=${msg("Estimated user count one year from now")} subtext=${msg(
str`Estimated user count one year from now based on ${this.forecast?.users} current users and ${this.forecast?.forecastedUsers} forecasted users.`,
)}
> >
~&nbsp;${this.forecast?.users} ~&nbsp;${(this.forecast?.users || 0) +
(this.forecast?.forecastedUsers || 0)}
</ak-aggregate-card> </ak-aggregate-card>
<ak-aggregate-card <ak-aggregate-card
class="pf-l-grid__item" class="pf-l-grid__item"
icon="pf-icon pf-icon-user" icon="pf-icon pf-icon-user"
header=${msg("Forecast external users")} header=${msg("Forecast external users")}
subtext=${msg("Estimated external user count one year from now")} subtext=${msg(
str`Estimated user count one year from now based on ${this.forecast?.externalUsers} current external users and ${this.forecast?.forecastedExternalUsers} forecasted external users.`,
)}
> >
~&nbsp;${this.forecast?.externalUsers} ~&nbsp;${(this.forecast?.externalUsers || 0) +
(this.forecast?.forecastedExternalUsers || 0)}
</ak-aggregate-card> </ak-aggregate-card>
<ak-aggregate-card <ak-aggregate-card
class="pf-l-grid__item" class="pf-l-grid__item"

View file

@ -63,7 +63,7 @@ export class PageHeader extends AKElement {
PFPage, PFPage,
PFContent, PFContent,
css` css`
:host { .bar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
min-height: 114px; min-height: 114px;
@ -126,7 +126,9 @@ export class PageHeader extends AKElement {
} }
render(): TemplateResult { render(): TemplateResult {
return html`<button return html` <ak-enterprise-status interface="admin"></ak-enterprise-status>
<div class="bar">
<button
class="sidebar-trigger pf-c-button pf-m-plain" class="sidebar-trigger pf-c-button pf-m-plain"
@click=${() => { @click=${() => {
this.dispatchEvent( this.dispatchEvent(
@ -175,6 +177,7 @@ export class PageHeader extends AKElement {
}} }}
> >
<i class="fas fa-bell"></i> <i class="fas fa-bell"></i>
</button> `; </button>
</div>`;
} }
} }

View file

@ -28,7 +28,7 @@ export class EnterpriseStatusBanner extends AKElement {
} }
renderBanner(): TemplateResult { renderBanner(): TemplateResult {
return html`<div class="pf-c-banner ${this.summary?.readOnly ? "pf-m-red" : "pf-m-orange"}"> return html`<div class="pf-c-banner ${this.summary?.readOnly ? "pf-m-red" : "pf-m-gold"}">
${msg("Warning: The current user count has exceeded the configured licenses.")} ${msg("Warning: The current user count has exceeded the configured licenses.")}
<a href="/if/admin/#/enterprise/licenses"> ${msg("Click here for more info.")} </a> <a href="/if/admin/#/enterprise/licenses"> ${msg("Click here for more info.")} </a>
</div>`; </div>`;

View file

@ -94,6 +94,12 @@ export class UserInterface extends Interface {
width: 100vw; width: 100vw;
position: absolute; position: absolute;
z-index: -1; z-index: -1;
top: 0;
left: 0;
}
ak-locale-context {
display: flex;
flex-direction: column;
} }
`, `,
]; ];