Files
authentik/web/src/user/LibraryPage/ak-library.ts

120 lines
3.5 KiB
TypeScript

import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { me } from "@goauthentik/common/users";
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
import "@goauthentik/elements/EmptyState";
import { localized, msg } from "@lit/localize";
import { html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { Application, CoreApi } from "@goauthentik/api";
import "./ak-library-impl.js";
import type { PageUIConfig } from "./types.js";
/**
* List of Applications available
*
* Properties:
* apps: a list of the applications available to the user.
*
* Aggregates two functions:
* - Display the list of applications available to the user
* - Filter that list using the search bar
*
*/
const coreApi = () => new CoreApi(DEFAULT_CONFIG);
@localized()
@customElement("ak-library")
export class LibraryPage extends AKElement {
@state()
ready = false;
@state()
isAdmin = false;
/**
* The list of applications. This is the *complete* list; the constructor fetches as many pages
* as the server announces when page one is accessed, and then concatenates them all together.
*/
@state()
apps: Application[] = [];
@state()
uiConfig: PageUIConfig;
constructor() {
super();
const uiConfig = rootInterface()?.uiConfig;
if (!uiConfig) {
throw new Error("Could not retrieve uiConfig. Reason: unknown. Check logs.");
}
this.uiConfig = {
layout: uiConfig.layout.type,
background: uiConfig.theme.cardBackground,
searchEnabled: uiConfig.enabledFeatures.search,
};
Promise.all([this.fetchApplications(), me()]).then(([applications, meStatus]) => {
this.isAdmin = meStatus.user.isSuperuser;
this.apps = applications;
this.ready = true;
});
}
async fetchApplications(): Promise<Application[]> {
const applicationListParams = (page = 1) => ({
ordering: "name",
page,
pageSize: 100,
onlyWithLaunchUrl: true,
});
const applicationListFetch = await coreApi().coreApplicationsList(applicationListParams(1));
const pageCount = applicationListFetch.pagination.totalPages;
if (pageCount === 1) {
return applicationListFetch.results;
}
const applicationLaterPages = await Promise.allSettled(
Array.from({ length: pageCount - 1 }).map((_a, idx) =>
coreApi().coreApplicationsList(applicationListParams(idx + 2)),
),
);
return applicationLaterPages.reduce(
function (acc, result) {
if (result.status === "rejected") {
const reason = JSON.stringify(result.reason, null, 2);
throw new Error(`Could not retrieve list of applications. Reason: ${reason}`);
}
return [...acc, ...result.value.results];
},
[...applicationListFetch.results],
);
}
pageTitle(): string {
return msg("My Applications");
}
loading() {
return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}> </ak-empty-state>`;
}
running() {
return html`<ak-library-impl
?isadmin=${this.isAdmin}
.apps=${this.apps}
.uiConfig=${this.uiConfig}
></ak-library-impl>`;
}
render() {
return this.ready ? this.running() : this.loading();
}
}