From 178417fe670243c282753284bb27bd54739848cc Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 4 Feb 2021 09:54:00 +0100 Subject: [PATCH] web: start implementing provider list --- swagger.yaml | 24 ++++ web/src/api/Providers.ts | 12 +- web/src/elements/router/Route.ts | 1 + web/src/interfaces/AdminInterface.ts | 2 +- web/src/pages/providers/ProviderListPage.ts | 128 ++++++++++++++++++++ web/src/pages/providers/ProviderViewPage.ts | 26 ++++ web/src/routes.ts | 8 +- 7 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 web/src/pages/providers/ProviderListPage.ts create mode 100644 web/src/pages/providers/ProviderViewPage.ts diff --git a/swagger.yaml b/swagger.yaml index 75b17b84a..01f2a69d2 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -8758,6 +8758,14 @@ definitions: enum: - global - per_provider + assigned_application_slug: + title: Assigned application slug + type: string + readOnly: true + assigned_application_name: + title: Assigned application name + type: string + readOnly: true verbose_name: title: Verbose name type: string @@ -8819,6 +8827,14 @@ definitions: description: User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used. type: string + assigned_application_slug: + title: Assigned application slug + type: string + readOnly: true + assigned_application_name: + title: Assigned application name + type: string + readOnly: true verbose_name: title: Verbose name type: string @@ -8919,6 +8935,14 @@ definitions: type: string format: uuid x-nullable: true + assigned_application_slug: + title: Assigned application slug + type: string + readOnly: true + assigned_application_name: + title: Assigned application name + type: string + readOnly: true verbose_name: title: Verbose name type: string diff --git a/web/src/api/Providers.ts b/web/src/api/Providers.ts index b2bee21e1..42f5e553f 100644 --- a/web/src/api/Providers.ts +++ b/web/src/api/Providers.ts @@ -4,6 +4,10 @@ export class Provider { pk: number; name: string; authorization_flow: string; + + assigned_application_slug?: string; + assigned_application_name?: string; + verbose_name: string; verbose_name_plural: string; @@ -11,11 +15,15 @@ export class Provider { throw Error(); } - static get(slug: string): Promise { - return DefaultClient.fetch(["providers", "all", slug]); + static get(id: number): Promise { + return DefaultClient.fetch(["providers", "all", id]); } static list(filter?: QueryArguments): Promise> { return DefaultClient.fetch>(["providers", "all"], filter); } + + static adminUrl(rest: string): string { + return `/administration/providers/${rest}`; + } } diff --git a/web/src/elements/router/Route.ts b/web/src/elements/router/Route.ts index f2275a5d0..2dcfba313 100644 --- a/web/src/elements/router/Route.ts +++ b/web/src/elements/router/Route.ts @@ -1,6 +1,7 @@ import { html, TemplateResult } from "lit-html"; export const SLUG_REGEX = "[-a-zA-Z0-9_]+"; +export const ID_REGEX = "\d+"; export class Route { url: RegExp; diff --git a/web/src/interfaces/AdminInterface.ts b/web/src/interfaces/AdminInterface.ts index 20bba8d46..d370e04d8 100644 --- a/web/src/interfaces/AdminInterface.ts +++ b/web/src/interfaces/AdminInterface.ts @@ -26,7 +26,7 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [ new SidebarItem("Sources", "/administration/sources/").activeWhen( `^/sources/(?${SLUG_REGEX})$`, ), - new SidebarItem("Providers", "/administration/providers/"), + new SidebarItem("Providers", "/providers"), new SidebarItem("Outposts", "/administration/outposts/"), new SidebarItem("Outpost Service Connections", "/administration/outposts/service_connections/"), ).when((): Promise => { diff --git a/web/src/pages/providers/ProviderListPage.ts b/web/src/pages/providers/ProviderListPage.ts new file mode 100644 index 000000000..d70f24ecf --- /dev/null +++ b/web/src/pages/providers/ProviderListPage.ts @@ -0,0 +1,128 @@ +import { gettext } from "django"; +import { customElement, html, property, TemplateResult } from "lit-element"; +import { Provider } from "../../api/Providers"; +import { PBResponse } from "../../api/Client"; +import { TablePage } from "../../elements/table/TablePage"; + +import "../../elements/buttons/ModalButton"; +import "../../elements/buttons/SpinnerButton"; +import { TableColumn } from "../../elements/table/Table"; + +@customElement("ak-provider-list") +export class ProviderListPage extends TablePage { + searchEnabled(): boolean { + return true; + } + pageTitle(): string { + return gettext("Provider"); + } + pageDescription(): string { + return gettext("Provide support for protocols like SAML and OAuth to assigned applications."); + } + pageIcon(): string { + return gettext("pf-icon pf-icon-integration"); + } + + @property() + order = "name"; + + apiEndpoint(page: number): Promise> { + return Provider.list({ + ordering: this.order, + page: page, + search: this.search || "", + }); + } + + columns(): TableColumn[] { + return [ + new TableColumn("Name", "name"), + new TableColumn("Application"), + new TableColumn("Type", "type"), + new TableColumn(""), + ]; + } + + row(item: Provider): TemplateResult[] { + return [ + html` + ${item.name} + `, + item.assigned_application_name ? + html` + ${gettext("Assigned to application ")} + ${item.assigned_application_name}` : + html` + ${gettext("Warning: Provider not assigned to any application.")}`, + html`${item.verbose_name}`, + html` + + + Edit + +
+
  + + + Delete + +
+
+ `, + ]; + } + + renderToolbar(): TemplateResult { + return html` + + + + + ${super.renderToolbar()}`; + } + +} diff --git a/web/src/pages/providers/ProviderViewPage.ts b/web/src/pages/providers/ProviderViewPage.ts new file mode 100644 index 000000000..b7993a6a7 --- /dev/null +++ b/web/src/pages/providers/ProviderViewPage.ts @@ -0,0 +1,26 @@ +import { gettext } from "django"; +import { customElement, html, LitElement, property, TemplateResult } from "lit-element"; +import { Provider } from "../../api/Providers"; +import { PBResponse } from "../../api/Client"; +import { TablePage } from "../../elements/table/TablePage"; + +import "../../elements/buttons/ModalButton"; +import "../../elements/buttons/SpinnerButton"; +import { TableColumn } from "../../elements/table/Table"; + +@customElement("ak-provider-view") +export class ProviderViewPage extends LitElement { + @property() + set args(value: { [key: string]: number }) { + this.providerID = value.id; + } + + @property() + set providerID(value: number) { + Provider.get(value).then((app) => (this.provider = app)); + } + + @property({ attribute: false }) + provider?: Provider; + +} diff --git a/web/src/routes.ts b/web/src/routes.ts index 2c3f1d9b9..b09c81951 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { Route, SLUG_REGEX } from "./elements/router/Route"; +import { Route, SLUG_REGEX, ID_REGEX } from "./elements/router/Route"; import "./pages/LibraryPage"; import "./pages/admin-overview/AdminOverviewPage"; @@ -10,6 +10,8 @@ import "./pages/flows/FlowViewPage"; import "./pages/events/EventListPage"; import "./pages/events/TransportListPage"; import "./pages/events/RuleListPage"; +import "./pages/providers/ProviderListPage"; +import "./pages/providers/ProviderViewPage"; import "./pages/property-mappings/PropertyMappingListPage"; export const ROUTES: Route[] = [ @@ -18,6 +20,10 @@ export const ROUTES: Route[] = [ new Route(new RegExp("^#.*")).redirect("/library"), new Route(new RegExp("^/library$"), html``), new Route(new RegExp("^/administration/overview$"), html``), + new Route(new RegExp("^/providers$"), html``), + new Route(new RegExp(`^/providers/(?${ID_REGEX})$`)).then((args) => { + return html``; + }), new Route(new RegExp("^/applications$"), html``), new Route(new RegExp(`^/applications/(?${SLUG_REGEX})$`)).then((args) => { return html``;