mirror of
https://github.com/goauthentik/authentik
synced 2026-05-08 08:02:26 +02:00
Compare commits
4 Commits
blueprint_
...
router-com
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d84cc49e4 | ||
|
|
36007c5d1c | ||
|
|
27c846545b | ||
|
|
d68515f9ff |
@@ -93,6 +93,8 @@ export class DebugPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default DebugPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-admin-debug-page": DebugPage;
|
||||
|
||||
@@ -2,201 +2,118 @@ import "#admin/admin-overview/AdminOverviewPage";
|
||||
|
||||
import { globalAK } from "#common/global";
|
||||
|
||||
import { ID_REGEX, Route, SLUG_REGEX, UUID_REGEX } from "#elements/router/Route";
|
||||
import {
|
||||
ID_REGEX as id,
|
||||
Route,
|
||||
SLUG_REGEX as slug,
|
||||
UUID_REGEX as uuid,
|
||||
} from "#elements/router/Route";
|
||||
import { collateRoutes, RouteEntry } from "#elements/router/shared";
|
||||
|
||||
import { html } from "lit";
|
||||
|
||||
// prettier-ignore
|
||||
const routePairs: RouteEntry[] = collateRoutes([
|
||||
["admin/settings", () => import("./admin-settings/AdminSettingsPage")],
|
||||
|
||||
["administration", [
|
||||
["dashboard/users", () => import("./admin-overview/DashboardUserPage")],
|
||||
["system-tasks", () => import("./admin-overview/SystemTasksPage")],
|
||||
]],
|
||||
|
||||
["blueprints/instances", () => import("./blueprints/BlueprintListPage")],
|
||||
|
||||
["core", [
|
||||
["providers", () => import("./providers/ProviderListPage")],
|
||||
[`providers/(?<providerID>${id})`, () => import("./providers/ProviderViewPage")],
|
||||
|
||||
["applications", () => import("./applications/ApplicationListPage")],
|
||||
[`applications/(?<applicationSlug>${slug})`, () => import("./applications/ApplicationViewPage")],
|
||||
|
||||
["sources", () => import("./sources/SourceListPage")],
|
||||
[`sources/(?<sourceSlug>${slug})`, () => import("./sources/SourceViewPage")],
|
||||
|
||||
["property-mappings", () => import("./property-mappings/PropertyMappingListPage")],
|
||||
|
||||
["tokens", () => import("./tokens/TokenListPage")],
|
||||
["brands", () => import("./brands/BrandListPage")],
|
||||
]],
|
||||
|
||||
["crypto/certificates", () => import("./crypto/CertificateKeyPairListPage")],
|
||||
|
||||
["debug", () => import("./DebugPage")],
|
||||
|
||||
["endpoints", [
|
||||
["devices", () => import("./endpoints/devices/DeviceListPage")],
|
||||
[`devices/(?<deviceID>${uuid})`, () => import("./endpoints/devices/DeviceViewPage")],
|
||||
|
||||
["connectors", () => import("./endpoints/connectors/ConnectorsListPage")],
|
||||
[`connectors/(?<connectorID>${uuid})`,() => import("./endpoints/connectors/ConnectorViewPage")],
|
||||
|
||||
["groups", () => import("./endpoints/DeviceAccessGroupsListPage")],
|
||||
]],
|
||||
|
||||
["enterprise/licenses", () => import("./enterprise/EnterpriseLicenseListPage")],
|
||||
|
||||
["events", [
|
||||
["log", () => import("./events/EventListPage")],
|
||||
[`log/(?<eventID>${uuid})`, () => import("./events/EventViewPage")],
|
||||
|
||||
["transports", () => import("./events/TransportListPage")],
|
||||
|
||||
["rules", () => import("./events/RuleListPage")],
|
||||
|
||||
["exports", () => import("./events/DataExportListPage")],
|
||||
|
||||
["lifecycle-rules", () => import("./lifecycle/LifecycleRuleListPage")],
|
||||
["lifecycle-reviews", () => import("./lifecycle/ReviewListPage")],
|
||||
]],
|
||||
|
||||
["files", () => import("./files/FileListPage")],
|
||||
|
||||
["flow", [
|
||||
["flows", () => import("./flows/FlowListPage")],
|
||||
[`flows/(?<flowSlug>${slug})`, () => import("./flows/FlowViewPage")],
|
||||
|
||||
["stages", () => import("./stages/StageListPage")],
|
||||
["stages/invitations", () => import("./stages/invitation/InvitationListPage")],
|
||||
["stages/prompts", () => import("./stages/prompt/PromptListPage")],
|
||||
]],
|
||||
|
||||
["identity", [
|
||||
["groups", () => import("./groups/GroupListPage")],
|
||||
[`groups/(?<groupID>${uuid})`, () => import("./groups/GroupViewPage")],
|
||||
|
||||
["users", () => import("./users/UserListPage")],
|
||||
[`users/(?<userID>${id})`, () => import("./users/UserViewPage")],
|
||||
|
||||
["roles", () => import("./roles/RoleListPage")],
|
||||
[`roles/(?<roleID>${uuid})`, () => import("./roles/RoleViewPage")],
|
||||
["initial-permissions", () => import("./rbac/InitialPermissionsListPage")],
|
||||
]],
|
||||
|
||||
["outpost", [
|
||||
["outposts", () => import("./outposts/OutpostListPage")],
|
||||
["integrations", () => import("./outposts/ServiceConnectionListPage")],
|
||||
]],
|
||||
|
||||
["policy", [
|
||||
["policies", () => import("./policies/PolicyListPage")],
|
||||
["reputation", () => import("./policies/reputation/ReputationListPage")],
|
||||
]],
|
||||
]);
|
||||
|
||||
export const ROUTES: Route[] = [
|
||||
// Prevent infinite Shell loops
|
||||
new Route(new RegExp("^/$")).redirect("/administration/overview"),
|
||||
new Route(new RegExp("^#.*")).redirect("/administration/overview"),
|
||||
new Route(new RegExp("^/library$")).redirect("/if/user/", true),
|
||||
new Route({ pattern: new RegExp("^/$") }).redirect("/administration/overview"),
|
||||
new Route({ pattern: new RegExp("^#.*") }).redirect("/administration/overview"),
|
||||
new Route({ pattern: "/library" }).redirect("/if/user/", true),
|
||||
// statically imported since this is the default route
|
||||
new Route(new RegExp("^/administration/overview$"), async () => {
|
||||
return html`<ak-admin-overview></ak-admin-overview>`;
|
||||
}),
|
||||
new Route(new RegExp("^/administration/dashboard/users$"), async () => {
|
||||
await import("#admin/admin-overview/DashboardUserPage");
|
||||
return html`<ak-admin-dashboard-users></ak-admin-dashboard-users>`;
|
||||
}),
|
||||
new Route(new RegExp("^/administration/system-tasks$"), async () => {
|
||||
await import("#admin/admin-overview/SystemTasksPage");
|
||||
return html`<ak-system-tasks></ak-system-tasks>`;
|
||||
}),
|
||||
new Route(new RegExp("^/core/providers$"), async () => {
|
||||
await import("#admin/providers/ProviderListPage");
|
||||
return html`<ak-provider-list></ak-provider-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/core/providers/(?<id>${ID_REGEX})$`), async (args) => {
|
||||
await import("#admin/providers/ProviderViewPage");
|
||||
return html`<ak-provider-view .providerID=${parseInt(args.id, 10)}></ak-provider-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/core/applications$"), async () => {
|
||||
await import("#admin/applications/ApplicationListPage");
|
||||
return html`<ak-application-list></ak-application-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/core/applications/(?<slug>${SLUG_REGEX})$`), async (args) => {
|
||||
await import("#admin/applications/ApplicationViewPage");
|
||||
return html`<ak-application-view .applicationSlug=${args.slug}></ak-application-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/endpoints/devices$"), async () => {
|
||||
await import("#admin/endpoints/devices/DeviceListPage");
|
||||
return html`<ak-endpoints-device-list></ak-endpoints-device-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/endpoints/devices/(?<uuid>${UUID_REGEX})$`), async (args) => {
|
||||
await import("#admin/endpoints/devices/DeviceViewPage");
|
||||
return html`<ak-endpoints-device-view .deviceId=${args.uuid}></ak-endpoints-device-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/endpoints/connectors$"), async () => {
|
||||
await import("#admin/endpoints/connectors/ConnectorsListPage");
|
||||
return html`<ak-endpoints-connectors-list></ak-endpoints-connectors-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/endpoints/connectors/(?<uuid>${UUID_REGEX})$`), async (args) => {
|
||||
await import("#admin/endpoints/connectors/ConnectorViewPage");
|
||||
return html`<ak-endpoints-connector-view
|
||||
.connectorID=${args.uuid}
|
||||
></ak-endpoints-connector-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/endpoints/groups$"), async () => {
|
||||
await import("#admin/endpoints/DeviceAccessGroupsListPage");
|
||||
return html`<ak-endpoints-device-access-groups-list></ak-endpoints-device-access-groups-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/core/sources$"), async () => {
|
||||
await import("#admin/sources/SourceListPage");
|
||||
return html`<ak-source-list></ak-source-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/core/sources/(?<slug>${SLUG_REGEX})$`), async (args) => {
|
||||
await import("#admin/sources/SourceViewPage");
|
||||
return html`<ak-source-view .sourceSlug=${args.slug}></ak-source-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/core/property-mappings$"), async () => {
|
||||
await import("#admin/property-mappings/PropertyMappingListPage");
|
||||
return html`<ak-property-mapping-list></ak-property-mapping-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/core/tokens$"), async () => {
|
||||
await import("#admin/tokens/TokenListPage");
|
||||
return html`<ak-token-list></ak-token-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/core/brands"), async () => {
|
||||
await import("#admin/brands/BrandListPage");
|
||||
return html`<ak-brand-list></ak-brand-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/policy/policies$"), async () => {
|
||||
await import("#admin/policies/PolicyListPage");
|
||||
return html`<ak-policy-list></ak-policy-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/policy/reputation$"), async () => {
|
||||
await import("#admin/policies/reputation/ReputationListPage");
|
||||
return html`<ak-policy-reputation-list></ak-policy-reputation-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/identity/groups$"), async () => {
|
||||
await import("#admin/groups/GroupListPage");
|
||||
return html`<ak-group-list></ak-group-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/identity/groups/(?<uuid>${UUID_REGEX})$`), async (args) => {
|
||||
await import("#admin/groups/GroupViewPage");
|
||||
return html`<ak-group-view .groupId=${args.uuid}></ak-group-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/identity/users$"), async () => {
|
||||
await import("#admin/users/UserListPage");
|
||||
return html`<ak-user-list></ak-user-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/identity/users/(?<id>${ID_REGEX})$`), async (args) => {
|
||||
await import("#admin/users/UserViewPage");
|
||||
return html`<ak-user-view .userId=${parseInt(args.id, 10)}></ak-user-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/identity/roles$"), async () => {
|
||||
await import("#admin/roles/RoleListPage");
|
||||
return html`<ak-role-list></ak-role-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/identity/initial-permissions$"), async () => {
|
||||
await import("#admin/rbac/InitialPermissionsListPage");
|
||||
return html`<ak-initial-permissions-list></ak-initial-permissions-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/identity/roles/(?<id>${UUID_REGEX})$`), async (args) => {
|
||||
await import("#admin/roles/RoleViewPage");
|
||||
return html`<ak-role-view roleId=${args.id}></ak-role-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/flow/stages/invitations$"), async () => {
|
||||
await import("#admin/stages/invitation/InvitationListPage");
|
||||
return html`<ak-stage-invitation-list></ak-stage-invitation-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/flow/stages/prompts$"), async () => {
|
||||
await import("#admin/stages/prompt/PromptListPage");
|
||||
return html`<ak-stage-prompt-list></ak-stage-prompt-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/flow/stages$"), async () => {
|
||||
await import("#admin/stages/StageListPage");
|
||||
return html`<ak-stage-list></ak-stage-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/flow/flows$"), async () => {
|
||||
await import("#admin/flows/FlowListPage");
|
||||
return html`<ak-flow-list></ak-flow-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/flow/flows/(?<slug>${SLUG_REGEX})$`), async (args) => {
|
||||
await import("#admin/flows/FlowViewPage");
|
||||
return html`<ak-flow-view .flowSlug=${args.slug} exportparts="main, tabs"></ak-flow-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/events/log$"), async () => {
|
||||
await import("#admin/events/EventListPage");
|
||||
return html`<ak-event-list></ak-event-list>`;
|
||||
}),
|
||||
new Route(new RegExp(`^/events/log/(?<id>${UUID_REGEX})$`), async (args) => {
|
||||
await import("#admin/events/EventViewPage");
|
||||
return html`<ak-event-view .eventID=${args.id}></ak-event-view>`;
|
||||
}),
|
||||
new Route(new RegExp("^/events/transports$"), async () => {
|
||||
await import("#admin/events/TransportListPage");
|
||||
return html`<ak-event-transport-list></ak-event-transport-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/events/rules$"), async () => {
|
||||
await import("#admin/events/RuleListPage");
|
||||
return html`<ak-event-rule-list></ak-event-rule-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/events/exports"), async () => {
|
||||
await import("./events/DataExportListPage");
|
||||
return html`<ak-data-export-list></ak-data-export-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/events/lifecycle-rules$"), async () => {
|
||||
await import("#admin/lifecycle/LifecycleRuleListPage");
|
||||
return html`<ak-lifecycle-rule-list></ak-lifecycle-rule-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/events/lifecycle-reviews"), async () => {
|
||||
await import("#admin/lifecycle/ReviewListPage");
|
||||
return html`<ak-review-list></ak-review-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/outpost/outposts$"), async () => {
|
||||
await import("#admin/outposts/OutpostListPage");
|
||||
return html`<ak-outpost-list></ak-outpost-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/outpost/integrations$"), async () => {
|
||||
await import("#admin/outposts/ServiceConnectionListPage");
|
||||
return html`<ak-outpost-service-connection-list></ak-outpost-service-connection-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/crypto/certificates$"), async () => {
|
||||
await import("#admin/crypto/CertificateKeyPairListPage");
|
||||
return html`<ak-crypto-certificate-list></ak-crypto-certificate-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/admin/settings$"), async () => {
|
||||
await import("#admin/admin-settings/AdminSettingsPage");
|
||||
return html`<ak-admin-settings></ak-admin-settings>`;
|
||||
}),
|
||||
new Route(new RegExp("^/files$"), async () => {
|
||||
await import("#admin/files/FileListPage");
|
||||
return html`<ak-files-list></ak-files-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/blueprints/instances$"), async () => {
|
||||
await import("#admin/blueprints/BlueprintListPage");
|
||||
return html`<ak-blueprint-list></ak-blueprint-list>`;
|
||||
}),
|
||||
new Route(new RegExp("^/debug$"), async () => {
|
||||
await import("#admin/DebugPage");
|
||||
return html`<ak-admin-debug-page></ak-admin-debug-page>`;
|
||||
}),
|
||||
new Route(new RegExp("^/enterprise/licenses$"), async () => {
|
||||
await import("#admin/enterprise/EnterpriseLicenseListPage");
|
||||
return html`<ak-enterprise-license-list></ak-enterprise-license-list>`;
|
||||
new Route({
|
||||
pattern: "/administration/overview",
|
||||
handler: () => html`<ak-admin-overview></ak-admin-overview>`,
|
||||
}),
|
||||
...routePairs.map(([pattern, loader, handler]) => new Route({ pattern, loader, handler })),
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -93,6 +93,8 @@ export class DashboardUserPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default DashboardUserPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-admin-dashboard-users": DashboardUserPage;
|
||||
|
||||
@@ -74,6 +74,8 @@ export class SystemTasksPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default SystemTasksPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-system-tasks": SystemTasksPage;
|
||||
|
||||
@@ -91,6 +91,8 @@ export class AdminSettingsPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default AdminSettingsPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-admin-settings": AdminSettingsPage;
|
||||
|
||||
@@ -206,6 +206,8 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
}
|
||||
}
|
||||
|
||||
export default ApplicationListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-application-list": ApplicationListPage;
|
||||
|
||||
@@ -438,6 +438,8 @@ export class ApplicationViewPage extends WithLicenseSummary(AKElement) {
|
||||
}
|
||||
}
|
||||
|
||||
export default ApplicationViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-application-view": ApplicationViewPage;
|
||||
|
||||
@@ -213,6 +213,8 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
||||
}
|
||||
}
|
||||
|
||||
export default BlueprintListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-blueprint-list": BlueprintListPage;
|
||||
|
||||
@@ -110,6 +110,8 @@ export class BrandListPage extends TablePage<Brand> {
|
||||
}
|
||||
}
|
||||
|
||||
export default BrandListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-brand-list": BrandListPage;
|
||||
|
||||
@@ -213,6 +213,8 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
||||
}
|
||||
}
|
||||
|
||||
export default CertificateKeyPairListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-crypto-certificate-list": CertificateKeyPairListPage;
|
||||
|
||||
@@ -99,6 +99,8 @@ export class DeviceAccessGroupsListPage extends TablePage<DeviceAccessGroup> {
|
||||
}
|
||||
}
|
||||
|
||||
export default DeviceAccessGroupsListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-endpoints-device-access-groups-list": DeviceAccessGroupsListPage;
|
||||
|
||||
@@ -19,7 +19,11 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
|
||||
@customElement("ak-endpoints-connector-view")
|
||||
export class ConnectorViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
@property({ type: String, attribute: "connector-id" })
|
||||
get connectorID() {
|
||||
return this.connector?.connectorUuid || "";
|
||||
}
|
||||
|
||||
set connectorID(value: string) {
|
||||
new EndpointsApi(DEFAULT_CONFIG)
|
||||
.endpointsConnectorsRetrieve({
|
||||
@@ -61,6 +65,8 @@ export class ConnectorViewPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default ConnectorViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-endpoints-connector-view": ConnectorViewPage;
|
||||
|
||||
@@ -95,6 +95,8 @@ export class ConnectorsListPage extends TablePage<Connector> {
|
||||
}
|
||||
}
|
||||
|
||||
export default ConnectorsListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-endpoints-connectors-list": ConnectorsListPage;
|
||||
|
||||
@@ -171,6 +171,8 @@ export class DeviceListPage extends TablePage<EndpointDevice> {
|
||||
}
|
||||
}
|
||||
|
||||
export default DeviceListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-endpoints-device-list": DeviceListPage;
|
||||
|
||||
@@ -34,8 +34,8 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-endpoints-device-view")
|
||||
export class DeviceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
public deviceId?: string;
|
||||
@property({ type: String, attribute: "device-id" })
|
||||
public deviceID?: string;
|
||||
|
||||
@state()
|
||||
protected device?: EndpointDeviceDetails;
|
||||
@@ -57,8 +57,8 @@ export class DeviceViewPage extends AKElement {
|
||||
}
|
||||
|
||||
public override willUpdate(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has("deviceId") && this.deviceId) {
|
||||
this.fetchDevice(this.deviceId);
|
||||
if (changedProperties.has("deviceID") && this.deviceID) {
|
||||
this.fetchDevice(this.deviceID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,6 +329,8 @@ export class DeviceViewPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default DeviceViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-endpoints-device-view": DeviceViewPage;
|
||||
|
||||
@@ -289,6 +289,8 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
||||
}
|
||||
}
|
||||
|
||||
export default EnterpriseLicenseListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-enterprise-license-list": EnterpriseLicenseListPage;
|
||||
|
||||
@@ -135,6 +135,8 @@ export class DataExportListPage extends TablePage<DataExport> {
|
||||
}
|
||||
}
|
||||
|
||||
export default DataExportListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-data-export-list": DataExportListPage;
|
||||
|
||||
@@ -131,6 +131,8 @@ export class EventListPage extends WithLicenseSummary(TablePage<Event>) {
|
||||
}
|
||||
}
|
||||
|
||||
export default EventListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-event-list": EventListPage;
|
||||
|
||||
@@ -145,6 +145,8 @@ export class EventViewPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default EventViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-event-view": EventViewPage;
|
||||
|
||||
@@ -16,12 +16,16 @@ export class EventVolumeChart extends EventChart {
|
||||
@property({ attribute: "with-map", type: Boolean })
|
||||
withMap = false;
|
||||
|
||||
_query?: EventsEventsListRequest;
|
||||
#query?: EventsEventsListRequest;
|
||||
|
||||
@property({ attribute: false })
|
||||
get query() {
|
||||
return this.#query;
|
||||
}
|
||||
|
||||
set query(value: EventsEventsListRequest | undefined) {
|
||||
if (JSON.stringify(value) === JSON.stringify(this._query)) return;
|
||||
this._query = value;
|
||||
if (JSON.stringify(value) === JSON.stringify(this.#query)) return;
|
||||
this.#query = value;
|
||||
this.refreshHandler();
|
||||
}
|
||||
|
||||
@@ -41,7 +45,7 @@ export class EventVolumeChart extends EventChart {
|
||||
apiRequest(): Promise<EventVolume[]> {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({
|
||||
historyDays: 7,
|
||||
...this._query,
|
||||
...this.#query,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,8 @@ Bindings to groups/users are checked against the user of the event.`,
|
||||
}
|
||||
}
|
||||
|
||||
export default RuleListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-event-rule-list": RuleListPage;
|
||||
|
||||
@@ -144,6 +144,8 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
||||
}
|
||||
}
|
||||
|
||||
export default TransportListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-event-transport-list": TransportListPage;
|
||||
|
||||
@@ -161,6 +161,8 @@ export class FileListPage extends WithCapabilitiesConfig(TablePage<FileItem>) {
|
||||
}
|
||||
}
|
||||
|
||||
export default FileListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-files-list": FileListPage;
|
||||
|
||||
@@ -182,6 +182,8 @@ export class FlowListPage extends TablePage<Flow> {
|
||||
}
|
||||
}
|
||||
|
||||
export default FlowListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-flow-list": FlowListPage;
|
||||
|
||||
@@ -324,6 +324,8 @@ export class FlowViewPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default FlowViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-flow-view": FlowViewPage;
|
||||
|
||||
@@ -106,6 +106,8 @@ export class GroupListPage extends TablePage<Group> {
|
||||
}
|
||||
}
|
||||
|
||||
export default GroupListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-group-list": GroupListPage;
|
||||
|
||||
@@ -45,8 +45,12 @@ import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css";
|
||||
|
||||
@customElement("ak-group-view")
|
||||
export class GroupViewPage extends WithLicenseSummary(AKElement) {
|
||||
@property({ type: String })
|
||||
set groupId(id: string) {
|
||||
@property({ type: String, attribute: "group-id" })
|
||||
public get groupID() {
|
||||
return this.group?.pk || "";
|
||||
}
|
||||
|
||||
public set groupID(id: string) {
|
||||
new CoreApi(DEFAULT_CONFIG)
|
||||
.coreGroupsRetrieve({
|
||||
groupUuid: id,
|
||||
@@ -77,7 +81,7 @@ export class GroupViewPage extends WithLicenseSummary(AKElement) {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
if (!this.group?.pk) return;
|
||||
this.groupId = this.group?.pk;
|
||||
this.groupID = this.group?.pk;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -325,6 +329,8 @@ export class GroupViewPage extends WithLicenseSummary(AKElement) {
|
||||
}
|
||||
}
|
||||
|
||||
export default GroupViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-group-view": GroupViewPage;
|
||||
|
||||
@@ -141,6 +141,8 @@ export class LifecycleRuleListPage extends TablePage<LifecycleRule> {
|
||||
}
|
||||
}
|
||||
|
||||
export default LifecycleRuleListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-lifecycle-rule-list": LifecycleRuleListPage;
|
||||
|
||||
@@ -84,6 +84,8 @@ export class ReviewListPage extends TablePage<LifecycleIteration> {
|
||||
}
|
||||
}
|
||||
|
||||
export default ReviewListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-review-list": ReviewListPage;
|
||||
|
||||
@@ -242,6 +242,8 @@ export class OutpostListPage extends TablePage<Outpost> {
|
||||
}
|
||||
}
|
||||
|
||||
export default OutpostListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-outpost-list": OutpostListPage;
|
||||
|
||||
@@ -167,6 +167,8 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
|
||||
}
|
||||
}
|
||||
|
||||
export default OutpostServiceConnectionListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-outpost-service-connection-list": OutpostServiceConnectionListPage;
|
||||
|
||||
@@ -146,6 +146,8 @@ export class PolicyListPage extends TablePage<Policy> {
|
||||
}
|
||||
}
|
||||
|
||||
export default PolicyListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-policy-list": PolicyListPage;
|
||||
|
||||
@@ -97,6 +97,8 @@ export class ReputationListPage extends TablePage<Reputation> {
|
||||
}
|
||||
}
|
||||
|
||||
export default ReputationListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-policy-reputation-list": ReputationListPage;
|
||||
|
||||
@@ -156,6 +156,8 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
||||
}
|
||||
}
|
||||
|
||||
export default PropertyMappingListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-property-mapping-list": PropertyMappingListPage;
|
||||
|
||||
@@ -142,6 +142,8 @@ export class ProviderListPage extends TablePage<Provider> {
|
||||
}
|
||||
}
|
||||
|
||||
export default ProviderListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-provider-list": ProviderListPage;
|
||||
|
||||
@@ -29,11 +29,15 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
|
||||
@customElement("ak-provider-view")
|
||||
export class ProviderViewPage extends AKElement {
|
||||
@property({ type: Number })
|
||||
set providerID(value: number) {
|
||||
@property({ type: Number, attribute: "provider-id" })
|
||||
public get providerID() {
|
||||
return this.provider?.pk || "";
|
||||
}
|
||||
|
||||
public set providerID(value: number | string) {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
.providersAllRetrieve({
|
||||
id: value,
|
||||
id: typeof value === "string" ? parseInt(value, 10) : value,
|
||||
})
|
||||
.then((prov) => (this.provider = prov));
|
||||
}
|
||||
@@ -104,6 +108,8 @@ export class ProviderViewPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default ProviderViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-provider-view": ProviderViewPage;
|
||||
|
||||
@@ -65,7 +65,11 @@ export function TypeToLabel(type?: ClientTypeEnum): string {
|
||||
@customElement("ak-provider-oauth2-view")
|
||||
export class OAuth2ProviderViewPage extends AKElement {
|
||||
@property({ type: Number })
|
||||
set providerID(value: number) {
|
||||
public get providerID() {
|
||||
return this.provider?.pk ?? -1;
|
||||
}
|
||||
|
||||
public set providerID(value: number) {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
.providersOauth2Retrieve({
|
||||
id: value,
|
||||
|
||||
@@ -110,11 +110,7 @@ export class InitialPermissionsListPage extends TablePage<InitialPermissions> {
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"initial-permissions-list": InitialPermissionsListPage;
|
||||
}
|
||||
}
|
||||
export default InitialPermissionsListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
|
||||
@@ -146,6 +146,8 @@ export class RoleListPage extends TablePage<Role> {
|
||||
}
|
||||
}
|
||||
|
||||
export default RoleListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-role-list": RoleListPage;
|
||||
|
||||
@@ -38,11 +38,15 @@ import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
|
||||
|
||||
@customElement("ak-role-view")
|
||||
export class RoleViewPage extends WithLicenseSummary(AKElement) {
|
||||
@property({ type: String })
|
||||
set roleId(id: string) {
|
||||
@property({ type: String, attribute: "role-id" })
|
||||
public get roleID() {
|
||||
return this.targetRole?.pk || "";
|
||||
}
|
||||
|
||||
public set roleID(uuid: string) {
|
||||
new RbacApi(DEFAULT_CONFIG)
|
||||
.rbacRolesRetrieve({
|
||||
uuid: id,
|
||||
uuid,
|
||||
})
|
||||
.then((role) => {
|
||||
this.targetRole = role;
|
||||
@@ -75,7 +79,7 @@ export class RoleViewPage extends WithLicenseSummary(AKElement) {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
if (!this.targetRole?.pk) return;
|
||||
this.roleId = this.targetRole?.pk;
|
||||
this.roleID = this.targetRole?.pk;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -182,6 +186,8 @@ export class RoleViewPage extends WithLicenseSummary(AKElement) {
|
||||
}
|
||||
}
|
||||
|
||||
export default RoleViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-role-view": RoleViewPage;
|
||||
|
||||
@@ -124,6 +124,8 @@ export class SourceListPage extends TablePage<Source> {
|
||||
}
|
||||
}
|
||||
|
||||
export default SourceListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-source-list": SourceListPage;
|
||||
|
||||
@@ -11,66 +11,67 @@ import "#elements/buttons/SpinnerButton/ak-spinner-button";
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
import { StrictUnsafe } from "#elements/utils/unsafe";
|
||||
|
||||
import { setPageDetails } from "#components/ak-page-navbar";
|
||||
|
||||
import { Source, SourcesApi } from "@goauthentik/api";
|
||||
|
||||
import { html, PropertyValues, TemplateResult } from "lit";
|
||||
import { html, PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
function resolveSourceViewComponentName(component: string) {
|
||||
switch (component) {
|
||||
case "ak-source-kerberos-form":
|
||||
return "ak-source-kerberos-view";
|
||||
case "ak-source-ldap-form":
|
||||
return "ak-source-ldap-view";
|
||||
case "ak-source-oauth-form":
|
||||
return "ak-source-oauth-view";
|
||||
case "ak-source-saml-form":
|
||||
return "ak-source-saml-view";
|
||||
case "ak-source-plex-form":
|
||||
return "ak-source-plex-view";
|
||||
case "ak-source-scim-form":
|
||||
return "ak-source-scim-view";
|
||||
case "ak-source-telegram-form":
|
||||
return "ak-source-telegram-view";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement("ak-source-view")
|
||||
export class SourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesAllRetrieve({
|
||||
slug: slug,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesAllRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
source?: Source;
|
||||
|
||||
render(): TemplateResult {
|
||||
render(): SlottedTemplateResult {
|
||||
if (!this.source) {
|
||||
return html`<ak-empty-state loading full-height></ak-empty-state>`;
|
||||
}
|
||||
switch (this.source?.component) {
|
||||
case "ak-source-kerberos-form":
|
||||
return html`<ak-source-kerberos-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-kerberos-view>`;
|
||||
case "ak-source-ldap-form":
|
||||
return html`<ak-source-ldap-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-ldap-view>`;
|
||||
case "ak-source-oauth-form":
|
||||
return html`<ak-source-oauth-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-oauth-view>`;
|
||||
case "ak-source-saml-form":
|
||||
return html`<ak-source-saml-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-saml-view>`;
|
||||
case "ak-source-plex-form":
|
||||
return html`<ak-source-plex-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-plex-view>`;
|
||||
case "ak-source-scim-form":
|
||||
return html`<ak-source-scim-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-scim-view>`;
|
||||
case "ak-source-telegram-form":
|
||||
return html`<ak-source-telegram-view
|
||||
sourceSlug=${this.source.slug}
|
||||
></ak-source-telegram-view>`;
|
||||
default:
|
||||
return html`<p>Invalid source type ${this.source.component}</p>`;
|
||||
|
||||
const sourceViewComponentName = resolveSourceViewComponentName(this.source.component);
|
||||
|
||||
if (!sourceViewComponentName) {
|
||||
return html`<p>Invalid source type ${this.source.component}</p>`;
|
||||
}
|
||||
|
||||
return StrictUnsafe(sourceViewComponentName, {
|
||||
sourceSlug: this.source.slug,
|
||||
});
|
||||
}
|
||||
|
||||
updated(changed: PropertyValues<this>) {
|
||||
@@ -83,6 +84,8 @@ export class SourceViewPage extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default SourceViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-source-view": SourceViewPage;
|
||||
|
||||
@@ -41,15 +41,15 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-source-kerberos-view")
|
||||
export class KerberosSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesKerberosRetrieve({
|
||||
slug: slug,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesKerberosRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -37,15 +37,15 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-source-ldap-view")
|
||||
export class LDAPSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesLdapRetrieve({
|
||||
slug: slug,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesLdapRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -79,15 +79,15 @@ export function ProviderToLabel(provider?: ProviderTypeEnum): string {
|
||||
|
||||
@customElement("ak-source-oauth-view")
|
||||
export class OAuthSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(value: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesOauthRetrieve({
|
||||
slug: value,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesOauthRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -34,15 +34,15 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-source-plex-view")
|
||||
export class PlexSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(value: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesPlexRetrieve({
|
||||
slug: value,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesPlexRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -36,15 +36,15 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-source-saml-view")
|
||||
export class SAMLSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesSamlRetrieve({
|
||||
slug: slug,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesSamlRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -36,15 +36,15 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-source-scim-view")
|
||||
export class SCIMSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(value: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesScimRetrieve({
|
||||
slug: value,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesScimRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -30,15 +30,15 @@ import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-source-telegram-view")
|
||||
export class TelegramSourceViewPage extends AKElement {
|
||||
@property({ type: String })
|
||||
set sourceSlug(value: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesTelegramRetrieve({
|
||||
slug: value,
|
||||
})
|
||||
.then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
@property({ type: String, attribute: "source-slug" })
|
||||
public get sourceSlug() {
|
||||
return this.source?.slug || "";
|
||||
}
|
||||
|
||||
public set sourceSlug(slug: string) {
|
||||
new SourcesApi(DEFAULT_CONFIG).sourcesTelegramRetrieve({ slug }).then((source) => {
|
||||
this.source = source;
|
||||
});
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -126,6 +126,8 @@ export class StageListPage extends TablePage<Stage> {
|
||||
}
|
||||
}
|
||||
|
||||
export default StageListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-stage-list": StageListPage;
|
||||
|
||||
@@ -184,6 +184,8 @@ export class InvitationListPage extends TablePage<Invitation> {
|
||||
}
|
||||
}
|
||||
|
||||
export default InvitationListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-stage-invitation-list": InvitationListPage;
|
||||
|
||||
@@ -108,6 +108,8 @@ export class PromptListPage extends TablePage<Prompt> {
|
||||
}
|
||||
}
|
||||
|
||||
export default PromptListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-stage-prompt-list": PromptListPage;
|
||||
|
||||
@@ -141,6 +141,8 @@ export class TokenListPage extends TablePage<Token> {
|
||||
}
|
||||
}
|
||||
|
||||
export default TokenListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-token-list": TokenListPage;
|
||||
|
||||
@@ -429,6 +429,8 @@ export class UserListPage extends WithBrandConfig(
|
||||
}
|
||||
}
|
||||
|
||||
export default UserListPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-user-list": UserListPage;
|
||||
|
||||
@@ -66,11 +66,15 @@ import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css";
|
||||
|
||||
@customElement("ak-user-view")
|
||||
export class UserViewPage extends WithBrandConfig(WithCapabilitiesConfig(WithSession(AKElement))) {
|
||||
@property({ type: Number })
|
||||
set userId(id: number) {
|
||||
@property({ type: Number, attribute: "user-id" })
|
||||
public get userID() {
|
||||
return this.user?.pk || "";
|
||||
}
|
||||
|
||||
public set userID(id: string | number) {
|
||||
new CoreApi(DEFAULT_CONFIG)
|
||||
.coreUsersRetrieve({
|
||||
id: id,
|
||||
id: typeof id === "string" ? parseInt(id, 10) : id,
|
||||
})
|
||||
.then((user) => {
|
||||
this.user = user;
|
||||
@@ -517,6 +521,8 @@ export class UserViewPage extends WithBrandConfig(WithCapabilitiesConfig(WithSes
|
||||
}
|
||||
}
|
||||
|
||||
export default UserViewPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-user-view": UserViewPage;
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
import "#elements/EmptyState";
|
||||
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
import { assertDefaultExport, ImportCallback } from "#common/modules/types";
|
||||
|
||||
import { html, nothing, TemplateResult } from "lit";
|
||||
import { RouteHandler, RouteInit, RouteLoader, RouteParameters } from "#elements/router/shared";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
import { StrictUnsafe } from "#elements/utils/unsafe";
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { until } from "lit/directives/until.js";
|
||||
|
||||
export const SLUG_REGEX = "[-a-zA-Z0-9_]+";
|
||||
export const ID_REGEX = "\\d+";
|
||||
export const UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
||||
|
||||
export interface RouteArgs {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export class Route {
|
||||
url: RegExp;
|
||||
public readonly pattern: RegExp;
|
||||
|
||||
private element?: TemplateResult;
|
||||
private callback?: (args: RouteArgs) => Promise<SlottedTemplateResult>;
|
||||
#loader: RouteLoader | ImportCallback<object> | null;
|
||||
#handler: RouteHandler | null = null;
|
||||
|
||||
constructor(url: RegExp, callback?: (args: RouteArgs) => Promise<TemplateResult>) {
|
||||
this.url = url;
|
||||
this.callback = callback;
|
||||
constructor({ pattern, loader, handler }: RouteInit) {
|
||||
this.pattern = typeof pattern === "string" ? new RegExp(`^${pattern}$`) : pattern;
|
||||
|
||||
this.#loader = loader || null;
|
||||
this.#handler = handler || null;
|
||||
}
|
||||
|
||||
redirect(to: string, raw = false): Route {
|
||||
this.callback = async () => {
|
||||
public redirect(to: string, raw = false): Route {
|
||||
this.#handler = async () => {
|
||||
console.debug(`authentik/router: redirecting ${to}`);
|
||||
if (!raw) {
|
||||
window.location.hash = `#${to}`;
|
||||
@@ -37,32 +39,42 @@ export class Route {
|
||||
return this;
|
||||
}
|
||||
|
||||
then(render: (args: RouteArgs) => TemplateResult): Route {
|
||||
this.callback = async (args) => {
|
||||
return render(args);
|
||||
public render(params: RouteParameters): SlottedTemplateResult {
|
||||
const invoke = (mod?: unknown) => {
|
||||
if (this.#handler) {
|
||||
return this.#handler(params);
|
||||
}
|
||||
|
||||
if (!mod) {
|
||||
throw new TypeError(
|
||||
"Route moduled did not provide a callback or load a module with a default export",
|
||||
);
|
||||
}
|
||||
|
||||
assertDefaultExport<CustomElementConstructor>(mod);
|
||||
|
||||
const tagName = window.customElements.getName(mod.default);
|
||||
|
||||
if (!tagName) {
|
||||
throw new TypeError(
|
||||
"Route provided a module that did not register a custom element",
|
||||
);
|
||||
}
|
||||
|
||||
return StrictUnsafe(tagName, params);
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
thenAsync(render: (args: RouteArgs) => Promise<TemplateResult>): Route {
|
||||
this.callback = render;
|
||||
return this;
|
||||
}
|
||||
|
||||
render(args: RouteArgs): TemplateResult {
|
||||
if (this.callback) {
|
||||
return html`${until(
|
||||
this.callback(args),
|
||||
if (this.#loader) {
|
||||
return until(
|
||||
this.#loader().then(invoke),
|
||||
html`<ak-empty-state loading></ak-empty-state>`,
|
||||
)}`;
|
||||
);
|
||||
}
|
||||
if (this.element) {
|
||||
return this.element;
|
||||
}
|
||||
throw new Error("Route does not have callback or element");
|
||||
|
||||
return invoke();
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<Route url=${this.url} callback=${this.callback ? "true" : "false"}>`;
|
||||
public toString(): string {
|
||||
return `<Route url=${this.pattern} callback=${this.#handler ? "true" : "false"}>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,21 @@ import { ROUTE_SEPARATOR } from "#common/constants";
|
||||
|
||||
import { Route } from "#elements/router/Route";
|
||||
import { RouteParameterRecord } from "#elements/router/shared";
|
||||
|
||||
import { TemplateResult } from "lit";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
|
||||
export class RouteMatch {
|
||||
route: Route;
|
||||
arguments: { [key: string]: string };
|
||||
params: Record<string, string>;
|
||||
fullURL: string;
|
||||
|
||||
constructor(route: Route, fullUrl: string) {
|
||||
constructor(route: Route, fullURL: string) {
|
||||
this.route = route;
|
||||
this.arguments = {};
|
||||
this.fullURL = fullUrl;
|
||||
this.params = {};
|
||||
this.fullURL = fullURL;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return this.route.render(this.arguments);
|
||||
render(): SlottedTemplateResult {
|
||||
return this.route.render(this.params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,18 +25,18 @@ export class RouteMatch {
|
||||
*
|
||||
* @returns The sanitized URL for logging/tracing.
|
||||
*/
|
||||
sanitizedURL() {
|
||||
sanitizedURL(): string {
|
||||
let cleanedURL = this.fullURL;
|
||||
for (const match of Object.keys(this.arguments)) {
|
||||
const value = this.arguments[match];
|
||||
cleanedURL = cleanedURL?.replace(value, `:${match}`);
|
||||
for (const match of Object.keys(this.params)) {
|
||||
const value = this.params[match];
|
||||
cleanedURL = cleanedURL.replace(value, `:${match}`);
|
||||
}
|
||||
return cleanedURL;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<RouteMatch url=${this.sanitizedURL()} route=${this.route} arguments=${JSON.stringify(
|
||||
this.arguments,
|
||||
return `<RouteMatch url=${this.sanitizedURL()} route=${this.route} params=${JSON.stringify(
|
||||
this.params,
|
||||
)}>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { AKElement } from "#elements/Base";
|
||||
import { RouteChangeEvent } from "#elements/router/events";
|
||||
import { Route } from "#elements/router/Route";
|
||||
import { RouteMatch } from "#elements/router/RouteMatch";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
import { ifPreviousValue, onlyBinding } from "#elements/utils/properties";
|
||||
|
||||
import { ConsoleLogger } from "#logger/browser";
|
||||
@@ -21,7 +22,7 @@ import {
|
||||
} from "@sentry/browser";
|
||||
import { BaseTransportOptions, Client, ClientOptions } from "@sentry/core";
|
||||
|
||||
import { html, PropertyValues, TemplateResult } from "lit";
|
||||
import { html, PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
// Polyfill for hashchange.newURL,
|
||||
@@ -167,11 +168,11 @@ export class RouterOutlet extends AKElement {
|
||||
let matchedRoute: RouteMatch | null = null;
|
||||
|
||||
for (const route of this.routes) {
|
||||
const match = route.url.exec(activeUrl);
|
||||
const match = route.pattern.exec(activeUrl);
|
||||
|
||||
if (match !== null) {
|
||||
matchedRoute = new RouteMatch(route, activeUrl);
|
||||
matchedRoute.arguments = match.groups || {};
|
||||
matchedRoute.params = match.groups || {};
|
||||
|
||||
this.#logger.debug(matchedRoute);
|
||||
|
||||
@@ -181,13 +182,15 @@ export class RouterOutlet extends AKElement {
|
||||
|
||||
if (!matchedRoute) {
|
||||
this.#logger.info(`Route "${activeUrl}" not defined`);
|
||||
const route = new Route(RegExp(""), async () => {
|
||||
return html`<div class="pf-c-page__main">
|
||||
<ak-router-404 url=${activeUrl}></ak-router-404>
|
||||
</div>`;
|
||||
const route = new Route({
|
||||
pattern: /.*/,
|
||||
handler: () =>
|
||||
html`<div class="pf-c-page__main">
|
||||
<ak-router-404 url=${activeUrl}></ak-router-404>
|
||||
</div>`,
|
||||
});
|
||||
matchedRoute = new RouteMatch(route, activeUrl);
|
||||
matchedRoute.arguments = route.url.exec(activeUrl)?.groups || {};
|
||||
matchedRoute.params = route.pattern.exec(activeUrl)?.groups || {};
|
||||
}
|
||||
this.current = matchedRoute;
|
||||
|
||||
@@ -214,8 +217,8 @@ export class RouterOutlet extends AKElement {
|
||||
}
|
||||
}
|
||||
|
||||
render(): TemplateResult | undefined {
|
||||
return this.current?.render();
|
||||
protected override render(): SlottedTemplateResult {
|
||||
return this.current?.render() || null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,39 @@
|
||||
* @file Common types for routing.
|
||||
*/
|
||||
|
||||
import { DefaultImportCallback, ImportCallback } from "#common/modules/types";
|
||||
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
|
||||
export type PrimitiveRouteParameter = string | number | boolean | null | undefined;
|
||||
export type RouteParameterRecord = { [key: string]: PrimitiveRouteParameter };
|
||||
|
||||
export type RouteParameters = Record<string, string>;
|
||||
|
||||
export type RouteLoader = DefaultImportCallback<CustomElementConstructor>;
|
||||
|
||||
export type RouteHandler<P extends object = RouteParameters> = (
|
||||
parameters: P,
|
||||
) => SlottedTemplateResult;
|
||||
|
||||
export interface RouteInit<P extends object = RouteParameters> {
|
||||
pattern: RegExp | string;
|
||||
loader?: RouteLoader | ImportCallback<object>;
|
||||
handler?: RouteHandler<P>;
|
||||
}
|
||||
|
||||
export type RouteEntry =
|
||||
| [pattern: RegExp | string, loader: ImportCallback<object>, handler: RouteHandler]
|
||||
| [pattern: RegExp | string, loader: RouteLoader, handler?: RouteHandler];
|
||||
type RouteGroup = [prefix: string, children: NestedRouteEntry[]];
|
||||
type NestedRouteEntry = RouteEntry | RouteGroup;
|
||||
|
||||
export function collateRoutes(entries: NestedRouteEntry[], prefix = ""): RouteEntry[] {
|
||||
return entries.flatMap((entry) => {
|
||||
const [segment, second] = entry;
|
||||
if (Array.isArray(second)) {
|
||||
return collateRoutes(second, `${prefix}/${segment}`);
|
||||
}
|
||||
return [[`${prefix}/${segment}`, ...entry.slice(1)] as RouteEntry];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import { html } from "lit";
|
||||
|
||||
export const ROUTES: Route[] = [
|
||||
// Prevent infinite Shell loops
|
||||
new Route(new RegExp("^/$")).redirect("/library"),
|
||||
new Route(new RegExp("^#.*")).redirect("/library"),
|
||||
new Route(new RegExp("^/library$"), async () => html`<ak-library></ak-library>`),
|
||||
new Route(new RegExp("^/settings$"), async () => {
|
||||
await import("#user/user-settings/UserSettingsPage");
|
||||
return html`<ak-user-settings></ak-user-settings>`;
|
||||
new Route({ pattern: new RegExp("^/$") }).redirect("/library"),
|
||||
new Route({ pattern: new RegExp("^#.*") }).redirect("/library"),
|
||||
new Route({ pattern: "/library", handler: () => html`<ak-library></ak-library>` }),
|
||||
new Route({
|
||||
pattern: "/settings",
|
||||
loader: () => import("#user/user-settings/UserSettingsPage"),
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -189,6 +189,8 @@ export class UserSettingsPage extends WithSession(AKElement) {
|
||||
}
|
||||
}
|
||||
|
||||
export default UserSettingsPage;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-user-settings": UserSettingsPage;
|
||||
|
||||
Reference in New Issue
Block a user