web: migrate Stage List to web

This commit is contained in:
Jens Langhammer 2021-02-19 19:29:17 +01:00
parent a76cbf8b70
commit 93478a55d7
17 changed files with 172 additions and 216 deletions

View file

@ -1,143 +0,0 @@
{% extends "administration/base.html" %}
{% load i18n %}
{% load authentik_utils %}
{% block content %}
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>
<i class="pf-icon pf-icon-plugged"></i>
{% trans 'Stages' %}
</h1>
<p>{% trans "Stages are single steps of a Flow that a user is guided through." %}</p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/toolbar_search.html' %}
<div class="pf-c-toolbar__bulk-select">
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<ak-modal-button href="{% url 'authentik_admin:stage-create' %}?type={{ type }}">
<button slot="trigger" class="pf-c-dropdown__menu-item">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</button>
<div slot="modal"></div>
</ak-modal-button>
</li>
{% endfor %}
</ul>
</ak-dropdown>
<button role="ak-refresh" class="pf-c-button pf-m-primary">
{% trans 'Refresh' %}
</button>
</div>
{% include 'partials/pagination.html' %}
</div>
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
<tr role="row">
<th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th role="columnheader" scope="col">{% trans 'Flows' %}</th>
<th role="cell"></th>
</tr>
</thead>
<tbody role="rowgroup">
{% for stage in object_list %}
<tr role="row">
<th role="columnheader">
<div>
<div>{{ stage.name }}</div>
<small>{{ stage|verbose_name }}</small>
</div>
</th>
<td role="cell">
<ul>
{% for flow in stage.flow_set.all %}
<li>{{ flow.slug }}</li>
{% empty %}
<li>-</li>
{% endfor %}
</ul>
</td>
<td>
<ak-modal-button href="{% url 'authentik_admin:stage-update' pk=stage.stage_uuid %}">
<ak-spinner-button slot="trigger" class="pf-m-secondary">
{% trans 'Edit' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
<ak-modal-button href="{% url 'authentik_admin:stage-delete' pk=stage.stage_uuid %}">
<ak-spinner-button slot="trigger" class="pf-m-danger">
{% trans 'Delete' %}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pf-c-pagination pf-m-bottom">
{% include 'partials/pagination.html' %}
</div>
{% else %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/toolbar_search.html' %}
</div>
</div>
<div class="pf-c-empty-state">
<div class="pf-c-empty-state__content">
<i class="pf-icon pf-icon-plugged pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Stages.' %}
</h1>
<div class="pf-c-empty-state__body">
{% if request.GET.search != "" %}
{% trans "Your search query doesn't match any stages." %}
{% else %}
{% trans 'Currently no stages exist. Click the button below to create one.' %}
{% endif %}
</div>
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<ak-modal-button href="{% url 'authentik_admin:stage-create' %}?type={{ type }}">
<button slot="trigger" class="pf-c-dropdown__menu-item">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</button>
<div slot="modal"></div>
</ak-modal-button>
</li>
{% endfor %}
</ul>
</ak-dropdown>
</div>
</div>
{% endif %}
</div>
</section>
{% endblock %}

View file

@ -125,7 +125,6 @@ urlpatterns = [
name="provider-delete", name="provider-delete",
), ),
# Stages # Stages
path("stages/", stages.StageListView.as_view(), name="stages"),
path("stages/create/", stages.StageCreateView.as_view(), name="stage-create"), path("stages/create/", stages.StageCreateView.as_view(), name="stage-create"),
path( path(
"stages/<uuid:pk>/update/", "stages/<uuid:pk>/update/",

View file

@ -4,38 +4,18 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin as DjangoPermissionRequiredMixin, PermissionRequiredMixin as DjangoPermissionRequiredMixin,
) )
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin from guardian.mixins import PermissionRequiredMixin
from authentik.admin.views.utils import ( from authentik.admin.views.utils import (
BackSuccessUrlMixin, BackSuccessUrlMixin,
DeleteMessageView, DeleteMessageView,
InheritanceCreateView, InheritanceCreateView,
InheritanceListView,
InheritanceUpdateView, InheritanceUpdateView,
SearchListMixin,
UserPaginateListMixin,
) )
from authentik.flows.models import Stage from authentik.flows.models import Stage
class StageListView(
LoginRequiredMixin,
PermissionListMixin,
UserPaginateListMixin,
SearchListMixin,
InheritanceListView,
):
"""Show list of all stages"""
model = Stage
template_name = "administration/stage/list.html"
permission_required = "authentik_flows.view_stage"
ordering = "name"
search_fields = ["name"]
class StageCreateView( class StageCreateView(
SuccessMessageMixin, SuccessMessageMixin,
BackSuccessUrlMixin, BackSuccessUrlMixin,
@ -49,7 +29,7 @@ class StageCreateView(
template_name = "generic/create.html" template_name = "generic/create.html"
permission_required = "authentik_flows.add_stage" permission_required = "authentik_flows.add_stage"
success_url = reverse_lazy("authentik_admin:stages") success_url = "/"
success_message = _("Successfully created Stage") success_message = _("Successfully created Stage")
@ -65,7 +45,7 @@ class StageUpdateView(
model = Stage model = Stage
permission_required = "authentik_flows.update_application" permission_required = "authentik_flows.update_application"
template_name = "generic/update.html" template_name = "generic/update.html"
success_url = reverse_lazy("authentik_admin:stages") success_url = "/"
success_message = _("Successfully updated Stage") success_message = _("Successfully updated Stage")
@ -75,5 +55,5 @@ class StageDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessage
model = Stage model = Stage
template_name = "generic/delete.html" template_name = "generic/delete.html"
permission_required = "authentik_flows.delete_stage" permission_required = "authentik_flows.delete_stage"
success_url = reverse_lazy("authentik_admin:stages") success_url = "/"
success_message = _("Successfully deleted Stage") success_message = _("Successfully deleted Stage")

View file

@ -8,8 +8,8 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.viewsets import ReadOnlyModelViewSet
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
from authentik.flows.api.flows import FlowSerializer
from authentik.flows.models import Stage from authentik.flows.models import Stage
from authentik.flows.planner import cache_key
from authentik.lib.templatetags.authentik_utils import verbose_name from authentik.lib.templatetags.authentik_utils import verbose_name
from authentik.lib.utils.reflection import all_subclasses from authentik.lib.utils.reflection import all_subclasses
@ -18,6 +18,7 @@ class StageSerializer(ModelSerializer, MetaNameSerializer):
"""Stage Serializer""" """Stage Serializer"""
object_type = SerializerMethodField() object_type = SerializerMethodField()
flow_set = FlowSerializer(many=True)
def get_object_type(self, obj: Stage) -> str: def get_object_type(self, obj: Stage) -> str:
"""Get object type so that we know which API Endpoint to use to get the full object""" """Get object type so that we know which API Endpoint to use to get the full object"""
@ -26,13 +27,20 @@ class StageSerializer(ModelSerializer, MetaNameSerializer):
class Meta: class Meta:
model = Stage model = Stage
fields = ["pk", "name", "object_type", "verbose_name", "verbose_name_plural"] fields = [
"pk",
"name",
"object_type",
"verbose_name",
"verbose_name_plural",
"flow_set",
]
class StageViewSet(ReadOnlyModelViewSet): class StageViewSet(ReadOnlyModelViewSet):
"""Stage Viewset""" """Stage Viewset"""
queryset = Stage.objects.all() queryset = Stage.objects.all().select_related("flow_set")
serializer_class = StageSerializer serializer_class = StageSerializer
search_fields = ["name"] search_fields = ["name"]
filterset_fields = ["name"] filterset_fields = ["name"]

View file

@ -1,4 +1,4 @@
import { DefaultClient, AKResponse, QueryArguments } from "./Client"; import { DefaultClient, AKResponse, QueryArguments, BaseInheritanceModel } from "./Client";
import { TypeCreate } from "./Providers"; import { TypeCreate } from "./Providers";
export enum FlowDesignation { export enum FlowDesignation {
@ -49,16 +49,26 @@ export class Flow {
} }
} }
export class Stage { export class Stage implements BaseInheritanceModel {
pk: string; pk: string;
name: string; name: string;
__type__: string; object_type: string;
verbose_name: string; verbose_name: string;
verbose_name_plural: string;
flow_set: Flow[];
constructor() { constructor() {
throw Error(); throw Error();
} }
static get(slug: string): Promise<Stage> {
return DefaultClient.fetch<Stage>(["stages", "all", slug]);
}
static list(filter?: QueryArguments): Promise<AKResponse<Stage>> {
return DefaultClient.fetch<AKResponse<Stage>>(["stages", "all"], filter);
}
static getTypes(): Promise<TypeCreate[]> { static getTypes(): Promise<TypeCreate[]> {
return DefaultClient.fetch<TypeCreate[]>(["stages", "all", "types"]); return DefaultClient.fetch<TypeCreate[]>(["stages", "all", "types"]);
} }

View file

@ -20,37 +20,37 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);
}), }),
new SidebarItem("Resources").children( new SidebarItem("Resources").children(
new SidebarItem("Applications", "/applications").activeWhen( new SidebarItem("Applications", "/core/applications").activeWhen(
`^/applications/(?<slug>${SLUG_REGEX})$` `^/core/applications/(?<slug>${SLUG_REGEX})$`
), ),
new SidebarItem("Sources", "/sources").activeWhen( new SidebarItem("Sources", "/core/sources").activeWhen(
`^/sources/(?<slug>${SLUG_REGEX})$`, `^/core/sources/(?<slug>${SLUG_REGEX})$`,
), ),
new SidebarItem("Providers", "/providers"), new SidebarItem("Providers", "/core/providers"),
new SidebarItem("Outposts", "/outposts"), new SidebarItem("Outposts", "/outpost/outposts"),
new SidebarItem("Outpost Service Connections", "/outpost-service-connections"), new SidebarItem("Outpost Service Connections", "/outpost/service-connections"),
).when((): Promise<boolean> => { ).when((): Promise<boolean> => {
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);
}), }),
new SidebarItem("Customisation").children( new SidebarItem("Customisation").children(
new SidebarItem("Policies", "/policies"), new SidebarItem("Policies", "/policy/policies"),
new SidebarItem("Property Mappings", "/property-mappings"), new SidebarItem("Property Mappings", "/core/property-mappings"),
).when((): Promise<boolean> => { ).when((): Promise<boolean> => {
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);
}), }),
new SidebarItem("Flows").children( new SidebarItem("Flows").children(
new SidebarItem("Flows", "/flows").activeWhen(`^/flows/(?<slug>${SLUG_REGEX})$`), new SidebarItem("Flows", "/flow/flows").activeWhen(`^/flow/flows/(?<slug>${SLUG_REGEX})$`),
new SidebarItem("Stages", "/administration/stages/"), new SidebarItem("Stages", "/flow/stages"),
new SidebarItem("Prompts", "/administration/stages_prompts/"), new SidebarItem("Prompts", "/administration/stages_prompts/"),
new SidebarItem("Invitations", "/administration/stages/invitations/"), new SidebarItem("Invitations", "/administration/stages/invitations/"),
).when((): Promise<boolean> => { ).when((): Promise<boolean> => {
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);
}), }),
new SidebarItem("Identity & Cryptography").children( new SidebarItem("Identity & Cryptography").children(
new SidebarItem("User", "/users"), new SidebarItem("User", "/identity/users"),
new SidebarItem("Groups", "/groups"), new SidebarItem("Groups", "/identity/groups"),
new SidebarItem("Certificates", "/crypto/certificates"), new SidebarItem("Certificates", "/crypto/certificates"),
new SidebarItem("Tokens", "/tokens"), new SidebarItem("Tokens", "/core/tokens"),
).when((): Promise<boolean> => { ).when((): Promise<boolean> => {
return User.me().then(u => u.is_superuser); return User.me().then(u => u.is_superuser);
}), }),

View file

@ -36,7 +36,7 @@ export class AdminOverviewPage extends LitElement {
<ak-aggregate-card class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Apps with most usage" style="grid-column-end: span 2;grid-row-end: span 3;"> <ak-aggregate-card class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Apps with most usage" style="grid-column-end: span 2;grid-row-end: span 3;">
<ak-top-applications-table></ak-top-applications-table> <ak-top-applications-table></ak-top-applications-table>
</ak-aggregate-card> </ak-aggregate-card>
<ak-admin-status-card-provider class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-plugged" header="Providers" headerLink="#/providers/"> <ak-admin-status-card-provider class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-plugged" header="Providers" headerLink="#/core/providers/">
</ak-admin-status-card-provider> </ak-admin-status-card-provider>
<ak-admin-status-card-policy-unbound class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-infrastructure" header="Policies" headerLink="#/administration/policies/"> <ak-admin-status-card-policy-unbound class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-infrastructure" header="Policies" headerLink="#/administration/policies/">
</ak-admin-status-card-policy-unbound> </ak-admin-status-card-policy-unbound>

View file

@ -50,7 +50,7 @@ export class ApplicationListPage extends TablePage<Application> {
item.meta_icon ? item.meta_icon ?
html`<img class="app-icon pf-c-avatar" src="${item.meta_icon}" alt="${gettext("Application Icon")}">` : html`<img class="app-icon pf-c-avatar" src="${item.meta_icon}" alt="${gettext("Application Icon")}">` :
html`<i class="pf-icon pf-icon-arrow"></i>`, html`<i class="pf-icon pf-icon-arrow"></i>`,
html`<a href="#/applications/${item.slug}"> html`<a href="#/core/applications/${item.slug}">
<div> <div>
${item.name} ${item.name}
</div> </div>

View file

@ -80,7 +80,7 @@ export class ApplicationViewPage extends LitElement {
</dt> </dt>
<dd class="pf-c-description-list__description"> <dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text"> <div class="pf-c-description-list__text">
<a href="#/providers/${this.application.provider.pk}"> <a href="#/core/providers/${this.application.provider.pk}">
${this.application.provider.name} ${this.application.provider.name}
</a> </a>
</div> </div>

View file

@ -107,7 +107,7 @@ export class EventInfo extends LitElement {
<span>${until(Flow.list({ <span>${until(Flow.list({
flow_uuid: this.event.context.flow as string, flow_uuid: this.event.context.flow as string,
}).then(resp => { }).then(resp => {
return html`<a href="#/flows/${resp.results[0].slug}">${resp.results[0].name}</a>`; return html`<a href="#/flow/flows/${resp.results[0].slug}">${resp.results[0].name}</a>`;
}), html`<ak-spinner size=${SpinnerSize.Medium}></ak-spinner>`)} }), html`<ak-spinner size=${SpinnerSize.Medium}></ak-spinner>`)}
</span> </span>
</div> </div>

View file

@ -47,7 +47,7 @@ export class FlowListPage extends TablePage<Flow> {
row(item: Flow): TemplateResult[] { row(item: Flow): TemplateResult[] {
return [ return [
html`<a href="#/flows/${item.slug}"> html`<a href="#/flow/flows/${item.slug}">
<code>${item.slug}</code> <code>${item.slug}</code>
</a>`, </a>`,
html`${item.name}`, html`${item.name}`,

View file

@ -48,7 +48,7 @@ export class OutpostListPage extends TablePage<Outpost> {
return [ return [
html`${item.name}`, html`${item.name}`,
html`<ul>${item.providers_obj.map((p) => { html`<ul>${item.providers_obj.map((p) => {
return html`<li><a href="#/providers/${p.pk}">${p.name}</a></li>`; return html`<li><a href="#/core/providers/${p.pk}">${p.name}</a></li>`;
})}</ul>`, })}</ul>`,
html`<ak-outpost-health outpostId=${item.pk}></ak-outpost-health>`, html`<ak-outpost-health outpostId=${item.pk}></ak-outpost-health>`,
html` html`

View file

@ -47,13 +47,13 @@ export class ProviderListPage extends TablePage<Provider> {
row(item: Provider): TemplateResult[] { row(item: Provider): TemplateResult[] {
return [ return [
html`<a href="#/providers/${item.pk}"> html`<a href="#/core/providers/${item.pk}">
${item.name} ${item.name}
</a>`, </a>`,
item.assigned_application_name ? item.assigned_application_name ?
html`<i class="pf-icon pf-icon-ok"></i> html`<i class="pf-icon pf-icon-ok"></i>
${gettext("Assigned to application ")} ${gettext("Assigned to application ")}
<a href="#/applications/${item.assigned_application_slug}">${item.assigned_application_name}</a>` : <a href="#/core/applications/${item.assigned_application_slug}">${item.assigned_application_name}</a>` :
html`<i class="pf-icon pf-icon-warning-triangle"></i> html`<i class="pf-icon pf-icon-warning-triangle"></i>
${gettext("Warning: Provider not assigned to any application.")}`, ${gettext("Warning: Provider not assigned to any application.")}`,
html`${item.verbose_name}`, html`${item.verbose_name}`,

View file

@ -14,7 +14,7 @@ export class RelatedApplicationButton extends LitElement {
render(): TemplateResult { render(): TemplateResult {
if (this.provider?.assigned_application_slug) { if (this.provider?.assigned_application_slug) {
return html`<a href="#/applications/${this.provider.assigned_application_slug}"> return html`<a href="#/core/applications/${this.provider.assigned_application_slug}">
${this.provider.assigned_application_name} ${this.provider.assigned_application_name}
</a>`; </a>`;
} }

View file

@ -46,7 +46,7 @@ export class SourceListPage extends TablePage<Source> {
row(item: Source): TemplateResult[] { row(item: Source): TemplateResult[] {
return [ return [
html`<a href="#/sources/${item.slug}"> html`<a href="#/core/sources/${item.slug}">
<div>${item.name}</div> <div>${item.name}</div>
${item.enabled ? html`` : html`<small>${gettext("Disabled")}</small>`} ${item.enabled ? html`` : html`<small>${gettext("Disabled")}</small>`}
</a>`, </a>`,

View file

@ -0,0 +1,100 @@
import { gettext } from "django";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import "../../elements/buttons/ModalButton";
import "../../elements/buttons/SpinnerButton";
import "../../elements/buttons/Dropdown";
import { until } from "lit-html/directives/until";
import { Stage } from "../../api/Flows";
@customElement("ak-stage-list")
export class StageListPage extends TablePage<Stage> {
pageTitle(): string {
return "Stages";
}
pageDescription(): string | undefined {
return "Stages are single steps of a Flow that a user is guided through.";
}
pageIcon(): string {
return "pf-icon pf-icon-plugged";
}
searchEnabled(): boolean {
return true;
}
@property()
order = "name";
apiEndpoint(page: number): Promise<AKResponse<Stage>> {
return Stage.list({
ordering: this.order,
page: page,
search: this.search || "",
});
}
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn("Flows"),
new TableColumn(""),
];
}
row(item: Stage): TemplateResult[] {
return [
html`<div>
<div>${item.name}</div>
<small>${item.verbose_name}</small>
</div>`,
html`${item.flow_set.map((flow) => {
return html`<a href="#/flow/flows/${flow.slug}">
<code>${flow.slug}</code>
</a>`;
})}`,
html`
<ak-modal-button href="${Stage.adminUrl(`${item.pk}/update/`)}">
<ak-spinner-button slot="trigger" class="pf-m-secondary">
${gettext("Edit")}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
<ak-modal-button href="${Stage.adminUrl(`${item.pk}/delete/`)}">
<ak-spinner-button slot="trigger" class="pf-m-danger">
${gettext("Delete")}
</ak-spinner-button>
<div slot="modal"></div>
</ak-modal-button>
`,
];
}
renderToolbar(): TemplateResult {
return html`
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">${gettext("Create")}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
${until(Stage.getTypes().then((types) => {
return types.map((type) => {
return html`<li>
<ak-modal-button href="${type.link}">
<button slot="trigger" class="pf-c-dropdown__menu-item">${type.name}<br>
<small>${type.description}</small>
</button>
<div slot="modal"></div>
</ak-modal-button>
</li>`;
});
}), html`<ak-spinner></ak-spinner>`)}
</ul>
</ak-dropdown>
${super.renderToolbar()}`;
}
}

View file

@ -11,6 +11,7 @@ import "./pages/events/RuleListPage";
import "./pages/events/TransportListPage"; import "./pages/events/TransportListPage";
import "./pages/flows/FlowListPage"; import "./pages/flows/FlowListPage";
import "./pages/flows/FlowViewPage"; import "./pages/flows/FlowViewPage";
import "./pages/groups/GroupListPage";
import "./pages/LibraryPage"; import "./pages/LibraryPage";
import "./pages/outposts/OutpostListPage"; import "./pages/outposts/OutpostListPage";
import "./pages/outposts/OutpostServiceConnectionListPage"; import "./pages/outposts/OutpostServiceConnectionListPage";
@ -20,10 +21,10 @@ import "./pages/providers/ProviderListPage";
import "./pages/providers/ProviderViewPage"; import "./pages/providers/ProviderViewPage";
import "./pages/sources/SourcesListPage"; import "./pages/sources/SourcesListPage";
import "./pages/sources/SourceViewPage"; import "./pages/sources/SourceViewPage";
import "./pages/groups/GroupListPage"; import "./pages/stages/StageListPage";
import "./pages/users/UserListPage";
import "./pages/tokens/TokenListPage";
import "./pages/system-tasks/SystemTaskListPage"; import "./pages/system-tasks/SystemTaskListPage";
import "./pages/tokens/TokenListPage";
import "./pages/users/UserListPage";
export const ROUTES: Route[] = [ export const ROUTES: Route[] = [
// Prevent infinite Shell loops // Prevent infinite Shell loops
@ -32,24 +33,25 @@ export const ROUTES: Route[] = [
new Route(new RegExp("^/library$"), html`<ak-library></ak-library>`), new Route(new RegExp("^/library$"), html`<ak-library></ak-library>`),
new Route(new RegExp("^/administration/overview$"), html`<ak-admin-overview></ak-admin-overview>`), new Route(new RegExp("^/administration/overview$"), html`<ak-admin-overview></ak-admin-overview>`),
new Route(new RegExp("^/administration/system-tasks$"), html`<ak-system-task-list></ak-system-task-list>`), new Route(new RegExp("^/administration/system-tasks$"), html`<ak-system-task-list></ak-system-task-list>`),
new Route(new RegExp("^/providers$"), html`<ak-provider-list></ak-provider-list>`), new Route(new RegExp("^/core/providers$"), html`<ak-provider-list></ak-provider-list>`),
new Route(new RegExp(`^/providers/(?<id>${ID_REGEX})$`)).then((args) => { new Route(new RegExp(`^/core/providers/(?<id>${ID_REGEX})$`)).then((args) => {
return html`<ak-provider-view .providerID=${parseInt(args.id, 10)}></ak-provider-view>`; return html`<ak-provider-view .providerID=${parseInt(args.id, 10)}></ak-provider-view>`;
}), }),
new Route(new RegExp("^/applications$"), html`<ak-application-list></ak-application-list>`), new Route(new RegExp("^/core/applications$"), html`<ak-application-list></ak-application-list>`),
new Route(new RegExp(`^/applications/(?<slug>${SLUG_REGEX})$`)).then((args) => { new Route(new RegExp(`^/core/applications/(?<slug>${SLUG_REGEX})$`)).then((args) => {
return html`<ak-application-view .args=${args}></ak-application-view>`; return html`<ak-application-view .args=${args}></ak-application-view>`;
}), }),
new Route(new RegExp("^/sources$"), html`<ak-source-list></ak-source-list>`), new Route(new RegExp("^/core/sources$"), html`<ak-source-list></ak-source-list>`),
new Route(new RegExp(`^/sources/(?<slug>${SLUG_REGEX})$`)).then((args) => { new Route(new RegExp(`^/core/sources/(?<slug>${SLUG_REGEX})$`)).then((args) => {
return html`<ak-source-view .args=${args}></ak-source-view>`; return html`<ak-source-view .args=${args}></ak-source-view>`;
}), }),
new Route(new RegExp("^/policies$"), html`<ak-policy-list></ak-policy-list>`), new Route(new RegExp("^/policy/policies$"), html`<ak-policy-list></ak-policy-list>`),
new Route(new RegExp("^/groups$"), html`<ak-group-list></ak-group-list>`), new Route(new RegExp("^/identity/groups$"), html`<ak-group-list></ak-group-list>`),
new Route(new RegExp("^/users$"), html`<ak-user-list></ak-user-list>`), new Route(new RegExp("^/identity/users$"), html`<ak-user-list></ak-user-list>`),
new Route(new RegExp("^/flows$"), html`<ak-flow-list></ak-flow-list>`), new Route(new RegExp("^/core/tokens$"), html`<ak-token-list></ak-token-list>`),
new Route(new RegExp("^/tokens$"), html`<ak-token-list></ak-token-list>`), new Route(new RegExp("^/flow/stages$"), html`<ak-stage-list></ak-stage-list>`),
new Route(new RegExp(`^/flows/(?<slug>${SLUG_REGEX})$`)).then((args) => { new Route(new RegExp("^/flow/flows$"), html`<ak-flow-list></ak-flow-list>`),
new Route(new RegExp(`^/flow/flows/(?<slug>${SLUG_REGEX})$`)).then((args) => {
return html`<ak-flow-view .flowSlug=${args.slug}></ak-flow-view>`; return html`<ak-flow-view .flowSlug=${args.slug}></ak-flow-view>`;
}), }),
new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`), new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`),
@ -58,8 +60,8 @@ export const ROUTES: Route[] = [
}), }),
new Route(new RegExp("^/events/transports$"), html`<ak-event-transport-list></ak-event-transport-list>`), new Route(new RegExp("^/events/transports$"), html`<ak-event-transport-list></ak-event-transport-list>`),
new Route(new RegExp("^/events/rules$"), html`<ak-event-rule-list></ak-event-rule-list>`), new Route(new RegExp("^/events/rules$"), html`<ak-event-rule-list></ak-event-rule-list>`),
new Route(new RegExp("^/property-mappings$"), html`<ak-property-mapping-list></ak-property-mapping-list>`), new Route(new RegExp("^/core/property-mappings$"), html`<ak-property-mapping-list></ak-property-mapping-list>`),
new Route(new RegExp("^/outposts$"), html`<ak-outpost-list></ak-outpost-list>`), new Route(new RegExp("^/outpost/outposts$"), html`<ak-outpost-list></ak-outpost-list>`),
new Route(new RegExp("^/outpost-service-connections$"), html`<ak-outpost-service-connection-list></ak-outpost-service-connection-list>`), new Route(new RegExp("^/outpost/service-connections$"), html`<ak-outpost-service-connection-list></ak-outpost-service-connection-list>`),
new Route(new RegExp("^/crypto/certificates$"), html`<ak-crypto-certificatekeypair-list></ak-crypto-certificatekeypair-list>`), new Route(new RegExp("^/crypto/certificates$"), html`<ak-crypto-certificatekeypair-list></ak-crypto-certificatekeypair-list>`),
]; ];