import "@goauthentik/admin/enterprise/EnterpriseLicenseForm"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { uiConfig } from "@goauthentik/common/ui/config"; import { PFColor } from "@goauthentik/elements/Label"; import "@goauthentik/elements/Spinner"; import "@goauthentik/elements/buttons/SpinnerButton"; import "@goauthentik/elements/cards/AggregateCard"; import "@goauthentik/elements/forms/DeleteBulkForm"; import "@goauthentik/elements/forms/ModalForm"; import { PaginatedResponse } from "@goauthentik/elements/table/Table"; import { TableColumn } from "@goauthentik/elements/table/Table"; import { TablePage } from "@goauthentik/elements/table/TablePage"; import { msg, str } from "@lit/localize"; import { CSSResult, TemplateResult, css, html } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import PFBanner from "@patternfly/patternfly/components/Banner/banner.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFCard from "@patternfly/patternfly/components/Card/card.css"; import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import { EnterpriseApi, License, LicenseForecast, LicenseSummary } from "@goauthentik/api"; @customElement("ak-enterprise-license-list") export class EnterpriseLicenseListPage extends TablePage { checkbox = true; searchEnabled(): boolean { return true; } pageTitle(): string { return msg("Licenses"); } pageDescription(): string { return msg("Manage enterprise licenses"); } pageIcon(): string { return "pf-icon pf-icon-key"; } @property() order = "name"; @state() forecast?: LicenseForecast; @state() summary?: LicenseSummary; @state() installID?: string; static get styles(): CSSResult[] { return super.styles.concat( PFDescriptionList, PFGrid, PFBanner, PFFormControl, PFButton, PFCard, css` .pf-m-no-padding-bottom { padding-bottom: 0; } `, ); } async apiEndpoint(page: number): Promise> { this.forecast = await new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseForecastRetrieve(); this.summary = await new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseSummaryRetrieve(); this.installID = ( await new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseGetInstallIdRetrieve() ).installId; return new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseList({ ordering: this.order, page: page, pageSize: (await uiConfig()).pagination.perPage, search: this.search || "", }); } columns(): TableColumn[] { return [ new TableColumn(msg("Name"), "name"), new TableColumn(msg("Users")), new TableColumn(msg("Expiry date")), new TableColumn(msg("Actions")), ]; } // TODO: Make this more generic, maybe automatically get the plural name // of the object to use in the renderEmpty renderEmpty(inner?: TemplateResult): TemplateResult { return super.renderEmpty(html` ${inner ? inner : html`
${this.searchEnabled() ? this.renderEmptyClearSearch() : html``}
${this.renderObjectCreate()}
`} `); } renderToolbarSelected(): TemplateResult { const disabled = this.selectedElements.length < 1; return html` { return [ { key: msg("Name"), value: item.name }, { key: msg("Expiry"), value: item.expiry?.toLocaleString() }, ]; }} .usedBy=${(item: License) => { return new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseUsedByList({ licenseUuid: item.licenseUuid, }); }} .delete=${(item: License) => { return new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseDestroy({ licenseUuid: item.licenseUuid, }); }} > `; } renderSectionBefore(): TemplateResult { return html`
${msg("Enterprise is in preview.")} ${msg("Send us feedback!")}
${msg("Get a license")}
${this.installID ? html` ${msg("Go to Customer Portal")}` : html``}
~ ${(this.forecast?.users || 0) + (this.forecast?.forecastedUsers || 0)} ~ ${(this.forecast?.externalUsers || 0) + (this.forecast?.forecastedExternalUsers || 0)} ${this.summary?.hasLicense ? this.summary.latestValid.toLocaleString() : "-"}
`; } row(item: License): TemplateResult[] { let color = PFColor.Green; if (item.expiry) { const now = new Date(); const inAMonth = new Date(); inAMonth.setDate(inAMonth.getDate() + 30); if (item.expiry <= inAMonth) { color = PFColor.Orange; } if (item.expiry <= now) { color = PFColor.Red; } } return [ html`
${item.name}
`, html`
0 / ${item.users} 0 / ${item.externalUsers}
`, html` ${item.expiry?.toLocaleString()} `, html` ${msg("Update")} ${msg("Update License")} `, ]; } renderObjectCreate(): TemplateResult { return html` ${msg("Install")} ${msg("Install License")} `; } }