diff --git a/web/src/admin/applications/wizard/ApplicationWizardCss.ts b/web/src/admin/applications/wizard/BasePanel.css.ts
similarity index 100%
rename from web/src/admin/applications/wizard/ApplicationWizardCss.ts
rename to web/src/admin/applications/wizard/BasePanel.css.ts
diff --git a/web/src/admin/applications/wizard/ApplicationWizardPageBase.ts b/web/src/admin/applications/wizard/BasePanel.ts
similarity index 88%
rename from web/src/admin/applications/wizard/ApplicationWizardPageBase.ts
rename to web/src/admin/applications/wizard/BasePanel.ts
index 19db5ecbb..f469a029d 100644
--- a/web/src/admin/applications/wizard/ApplicationWizardPageBase.ts
+++ b/web/src/admin/applications/wizard/BasePanel.ts
@@ -4,9 +4,10 @@ import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { consume } from "@lit-labs/context";
import { query, state } from "@lit/reactive-element/decorators.js";
-import { styles as AwadStyles } from "./ApplicationWizardCss";
-import type { WizardState } from "./ak-application-wizard-context";
+import { styles as AwadStyles } from "./BasePanel.css";
+
import { applicationWizardContext } from "./ak-application-wizard-context-name";
+import type { WizardState } from "./types";
export class ApplicationWizardPageBase extends CustomEmitterElement(AKElement) {
static get styles() {
diff --git a/web/src/admin/applications/wizard/TypeApplicationWizardPage.ts b/web/src/admin/applications/wizard/TypeApplicationWizardPage.ts
deleted file mode 100644
index ff55cb67c..000000000
--- a/web/src/admin/applications/wizard/TypeApplicationWizardPage.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import { WizardPage } from "@goauthentik/elements/wizard/WizardPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { CSSResult, TemplateResult, html } from "lit";
-
-import PFButton from "@patternfly/patternfly/components/Button/button.css";
-import PFForm from "@patternfly/patternfly/components/Form/form.css";
-import PFRadio from "@patternfly/patternfly/components/Radio/radio.css";
-import PFBase from "@patternfly/patternfly/patternfly-base.css";
-
-import { TypeCreate } from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type")
-export class TypeApplicationWizardPage extends WizardPage {
- applicationTypes: TypeCreate[] = [
- {
- component: "ak-application-wizard-type-oauth",
- name: msg("OAuth2/OIDC"),
- description: msg("Modern applications, APIs and Single-page applications."),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-saml",
- name: msg("SAML"),
- description: msg(
- "XML-based SSO standard. Use this if your application only supports SAML.",
- ),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-proxy",
- name: msg("Proxy"),
- description: msg("Legacy applications which don't natively support SSO."),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-ldap",
- name: msg("LDAP"),
- description: msg(
- "Provide an LDAP interface for applications and users to authenticate against.",
- ),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-link",
- name: msg("Link"),
- description: msg(
- "Provide an LDAP interface for applications and users to authenticate against.",
- ),
- modelName: "",
- },
- ];
-
- sidebarLabel = () => msg("Authentication method");
-
- static get styles(): CSSResult[] {
- return [PFBase, PFButton, PFForm, PFRadio];
- }
-
- render(): TemplateResult {
- return html`
`;
- }
-}
diff --git a/web/src/admin/applications/wizard/ak-application-wizard-context.ts b/web/src/admin/applications/wizard/ak-application-wizard-context.ts
deleted file mode 100644
index 0dba5171b..000000000
--- a/web/src/admin/applications/wizard/ak-application-wizard-context.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
-
-import { provide } from "@lit-labs/context";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { property } from "@lit/reactive-element/decorators/property.js";
-import { LitElement, html } from "lit";
-
-import {
- Application,
- LDAPProvider,
- OAuth2Provider,
- ProxyProvider,
- RadiusProvider,
- SAMLProvider,
- SCIMProvider,
-} from "@goauthentik/api";
-
-import applicationWizardContext from "./ak-application-wizard-context-name";
-
-// my-context.ts
-
-type OneOfProvider =
- | Partial
- | Partial
- | Partial
- | Partial
- | Partial
- | Partial;
-
-export interface WizardState {
- step: number;
- providerType: string;
- application: Partial;
- provider: OneOfProvider;
-}
-
-type WizardStateEvent = WizardState & { target?: HTMLInputElement };
-
-@customElement("ak-application-wizard-context")
-export class AkApplicationWizardContext extends CustomListenerElement(LitElement) {
- /**
- * Providing a context at the root element
- */
- @provide({ context: applicationWizardContext })
- @property({ attribute: false })
- wizardState: WizardState = {
- step: 0,
- providerType: "",
- application: {},
- provider: {},
- };
-
- constructor() {
- super();
- this.handleUpdate = this.handleUpdate.bind(this);
- }
-
- connectedCallback() {
- super.connectedCallback();
- this.addCustomListener("ak-wizard-update", this.handleUpdate);
- }
-
- disconnectedCallback() {
- this.removeCustomListener("ak-wizard-update", this.handleUpdate);
- super.disconnectedCallback();
- }
-
- handleUpdate(event: CustomEvent) {
- delete event.detail.target;
- this.wizardState = event.detail;
- }
-
- render() {
- return html``;
- }
-}
-
-export default AkApplicationWizardContext;
diff --git a/web/src/admin/applications/wizard/ak-application-wizard.ts b/web/src/admin/applications/wizard/ak-application-wizard.ts
index b2ac9575a..d5c3beb26 100644
--- a/web/src/admin/applications/wizard/ak-application-wizard.ts
+++ b/web/src/admin/applications/wizard/ak-application-wizard.ts
@@ -11,12 +11,15 @@ import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFRadio from "@patternfly/patternfly/components/Radio/radio.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
-import { steps } from "./ApplicationWizardSteps";
import applicationWizardContext from "./ak-application-wizard-context-name";
+import { steps } from "./steps";
import { WizardState, WizardStateEvent } from "./types";
// my-context.ts
+// All this thing is doing is recording the input the user makes to the forms. It should NOT be
+// triggering re-renders; that's the wizard frame's jobs.
+
@customElement("ak-application-wizard")
export class ApplicationWizard extends CustomListenerElement(AKElement) {
static get styles(): CSSResult[] {
@@ -38,19 +41,8 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
@state()
steps = steps;
- @property({ type: Boolean })
- open = false;
-
@property()
- createText = msg("Create");
-
- @property({ type: Boolean })
- showButton = true;
-
- @property({ attribute: false })
- finalHandler: () => Promise = () => {
- return Promise.resolve();
- };
+ prompt = msg("Create");
constructor() {
super();
@@ -83,8 +75,6 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
method.disabled = false;
this.steps = newSteps;
}
-
- console.log(newWizardState);
this.wizardState = newWizardState;
}
@@ -94,12 +84,8 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
.steps=${this.steps}
header=${msg("New application")}
description=${msg("Create a new application.")}
+ prompt=${this.prompt}
>
- ${this.showButton
- ? html``
- : html``}
`;
}
diff --git a/web/src/admin/applications/wizard/application/ak-application-wizard-application-details.ts b/web/src/admin/applications/wizard/application/ak-application-wizard-application-details.ts
index 27e1346b9..4ecdba6c1 100644
--- a/web/src/admin/applications/wizard/application/ak-application-wizard-application-details.ts
+++ b/web/src/admin/applications/wizard/application/ak-application-wizard-application-details.ts
@@ -12,10 +12,10 @@ import { customElement } from "@lit/reactive-element/decorators/custom-element.j
import { TemplateResult, html } from "lit";
import { ifDefined } from "lit/directives/if-defined.js";
-import ApplicationWizardPageBase from "../ApplicationWizardPageBase";
+import BasePanel from "../BasePanel";
@customElement("ak-application-wizard-application-details")
-export class ApplicationWizardApplicationDetails extends ApplicationWizardPageBase {
+export class ApplicationWizardApplicationDetails extends BasePanel {
handleChange(ev: Event) {
if (!ev.target) {
console.warn(`Received event with no target: ${ev}`);
diff --git a/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts b/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts
index 65c3cce6a..5b64efacb 100644
--- a/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts
+++ b/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts
@@ -12,11 +12,11 @@ import { map } from "lit/directives/map.js";
import type { TypeCreate } from "@goauthentik/api";
-import ApplicationWizardPageBase from "../ApplicationWizardPageBase";
+import BasePanel from "../BasePanel";
import providerTypesList from "./ak-application-wizard-authentication-method-choice.choices";
@customElement("ak-application-wizard-authentication-method-choice")
-export class ApplicationWizardAuthenticationMethodChoice extends ApplicationWizardPageBase {
+export class ApplicationWizardAuthenticationMethodChoice extends BasePanel {
constructor() {
super();
this.handleChoice = this.handleChoice.bind(this);
diff --git a/web/src/admin/applications/wizard/design.md b/web/src/admin/applications/wizard/design.md
deleted file mode 100644
index 17d44e025..000000000
--- a/web/src/admin/applications/wizard/design.md
+++ /dev/null
@@ -1,20 +0,0 @@
-The design of the wizard is actually very simple. There is an orchestrator in the Context object;
-it takes messages from the current page and grants permissions to proceed based on the content of
-the Context object after a message.
-
-The fields of the Context object are:
-
-```Javascript
-{
- step: number // The page currently being visited
- providerType: The provider type chosen in step 2. Dictates which view to show in step 3
- application: // The data collected from the ApplicationDetails page
- provider: // the data collected from the ProviderDetails page.
-
-
-```
-
-The orchestrator leans on the per-page forms to tell it when a page is "valid enough to proceed".
-
-When it reaches the last page, the transaction is triggered. If there are errors, the user is
-invited to "go back to the page where the error occurred" and try again.
diff --git a/web/src/admin/applications/wizard/link/TypeLinkApplicationWizardPage.ts b/web/src/admin/applications/wizard/link/TypeLinkApplicationWizardPage.ts
deleted file mode 100644
index c91133a45..000000000
--- a/web/src/admin/applications/wizard/link/TypeLinkApplicationWizardPage.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { KeyUnknown } from "@goauthentik/elements/forms/Form";
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardFormPage } from "@goauthentik/elements/wizard/WizardFormPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { TemplateResult, html } from "lit";
-
-@customElement("ak-application-wizard-type-link")
-export class TypeLinkApplicationWizardPage extends WizardFormPage {
- sidebarLabel = () => msg("Application Link");
-
- nextDataCallback = async (data: KeyUnknown): Promise => {
- this.host.state["link"] = data.link;
- return true;
- };
-
- renderForm(): TemplateResult {
- return html`
-
- `;
- }
-}
diff --git a/web/src/admin/applications/wizard/ApplicationWizardProviderPageBase.ts b/web/src/admin/applications/wizard/methods/BaseProviderPanel.ts
similarity index 77%
rename from web/src/admin/applications/wizard/ApplicationWizardProviderPageBase.ts
rename to web/src/admin/applications/wizard/methods/BaseProviderPanel.ts
index b5db2e215..2558a3b6d 100644
--- a/web/src/admin/applications/wizard/ApplicationWizardProviderPageBase.ts
+++ b/web/src/admin/applications/wizard/methods/BaseProviderPanel.ts
@@ -1,6 +1,6 @@
-import ApplicationWizardPageBase from "./ApplicationWizardPageBase";
+import BasePanel from "../BasePanel";
-export class ApplicationWizardProviderPageBase extends ApplicationWizardPageBase {
+export class ApplicationWizardProviderPageBase extends BasePanel {
handleChange(ev: InputEvent) {
if (!ev.target) {
console.warn(`Received event with no target: ${ev}`);
diff --git a/web/src/admin/applications/wizard/auth-method/ak-application-wizard-authentication-method.ts b/web/src/admin/applications/wizard/methods/ak-application-wizard-authentication-method.ts
similarity index 59%
rename from web/src/admin/applications/wizard/auth-method/ak-application-wizard-authentication-method.ts
rename to web/src/admin/applications/wizard/methods/ak-application-wizard-authentication-method.ts
index ab727ba07..b63741326 100644
--- a/web/src/admin/applications/wizard/auth-method/ak-application-wizard-authentication-method.ts
+++ b/web/src/admin/applications/wizard/methods/ak-application-wizard-authentication-method.ts
@@ -1,16 +1,16 @@
import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import ApplicationWizardPageBase from "../ApplicationWizardPageBase";
+import BasePanel from "../BasePanel";
import { providerRendererList } from "../auth-method-choice/ak-application-wizard-authentication-method-choice.choices";
-import "../ldap/ak-application-wizard-authentication-by-ldap";
-import "../oauth/ak-application-wizard-authentication-by-oauth";
-import "../proxy/ak-application-wizard-authentication-for-reverse-proxy";
-import "../proxy/ak-application-wizard-authentication-for-single-forward-proxy";
+import "./ldap/ak-application-wizard-authentication-by-ldap";
+import "./oauth/ak-application-wizard-authentication-by-oauth";
+import "./proxy/ak-application-wizard-authentication-for-reverse-proxy";
+import "./proxy/ak-application-wizard-authentication-for-single-forward-proxy";
// prettier-ignore
@customElement("ak-application-wizard-authentication-method")
-export class ApplicationWizardApplicationDetails extends ApplicationWizardPageBase {
+export class ApplicationWizardApplicationDetails extends BasePanel {
render() {
const handler = providerRendererList.get(this.wizard.providerType);
if (!handler) {
diff --git a/web/src/admin/applications/wizard/ldap/LDAPOptionsAndHelp.ts b/web/src/admin/applications/wizard/methods/ldap/LDAPOptionsAndHelp.ts
similarity index 100%
rename from web/src/admin/applications/wizard/ldap/LDAPOptionsAndHelp.ts
rename to web/src/admin/applications/wizard/methods/ldap/LDAPOptionsAndHelp.ts
diff --git a/web/src/admin/applications/wizard/ldap/ak-application-wizard-authentication-by-ldap.ts b/web/src/admin/applications/wizard/methods/ldap/ak-application-wizard-authentication-by-ldap.ts
similarity index 97%
rename from web/src/admin/applications/wizard/ldap/ak-application-wizard-authentication-by-ldap.ts
rename to web/src/admin/applications/wizard/methods/ldap/ak-application-wizard-authentication-by-ldap.ts
index c9e0d8d0a..7b9aa4d3f 100644
--- a/web/src/admin/applications/wizard/ldap/ak-application-wizard-authentication-by-ldap.ts
+++ b/web/src/admin/applications/wizard/methods/ldap/ak-application-wizard-authentication-by-ldap.ts
@@ -18,7 +18,7 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { FlowsInstancesListDesignationEnum } from "@goauthentik/api";
import type { LDAPProvider } from "@goauthentik/api";
-import ApplicationWizardProviderPageBase from "../ApplicationWizardProviderPageBase";
+import BaseProviderPanel from "../BaseProviderPanel";
import {
bindModeOptions,
cryptoCertificateHelp,
@@ -31,7 +31,7 @@ import {
} from "./LDAPOptionsAndHelp";
@customElement("ak-application-wizard-authentication-by-ldap")
-export class ApplicationWizardApplicationDetails extends ApplicationWizardProviderPageBase {
+export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
render() {
const provider = this.wizard.provider as LDAPProvider | undefined;
diff --git a/web/src/admin/applications/wizard/oauth/ak-application-wizard-authentication-by-oauth.ts b/web/src/admin/applications/wizard/methods/oauth/ak-application-wizard-authentication-by-oauth.ts
similarity index 98%
rename from web/src/admin/applications/wizard/oauth/ak-application-wizard-authentication-by-oauth.ts
rename to web/src/admin/applications/wizard/methods/oauth/ak-application-wizard-authentication-by-oauth.ts
index 02bd54ac5..cf6ceb9de 100644
--- a/web/src/admin/applications/wizard/oauth/ak-application-wizard-authentication-by-oauth.ts
+++ b/web/src/admin/applications/wizard/methods/oauth/ak-application-wizard-authentication-by-oauth.ts
@@ -33,10 +33,10 @@ import type {
PaginatedScopeMappingList,
} from "@goauthentik/api";
-import ApplicationWizardProviderPageBase from "../ApplicationWizardProviderPageBase";
+import BaseProviderPanel from "../BaseProviderPanel";
@customElement("ak-application-wizard-authentication-by-oauth")
-export class ApplicationWizardAuthenticationByOauth extends ApplicationWizardProviderPageBase {
+export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
@state()
showClientSecret = false;
diff --git a/web/src/admin/applications/wizard/proxy/AuthenticationByProxyPage.ts b/web/src/admin/applications/wizard/methods/proxy/AuthenticationByProxyPage.ts
similarity index 98%
rename from web/src/admin/applications/wizard/proxy/AuthenticationByProxyPage.ts
rename to web/src/admin/applications/wizard/methods/proxy/AuthenticationByProxyPage.ts
index 1f7ecdf2e..c3ac7f44f 100644
--- a/web/src/admin/applications/wizard/proxy/AuthenticationByProxyPage.ts
+++ b/web/src/admin/applications/wizard/methods/proxy/AuthenticationByProxyPage.ts
@@ -21,11 +21,11 @@ import {
SourcesApi,
} from "@goauthentik/api";
-import ApplicationWizardProviderPageBase from "../ApplicationWizardProviderPageBase";
+import BaseProviderPanel from "../BaseProviderPanel";
type MaybeTemplateResult = TemplateResult | typeof nothing;
-export class AkTypeProxyApplicationWizardPage extends ApplicationWizardProviderPageBase {
+export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
constructor() {
super();
new PropertymappingsApi(DEFAULT_CONFIG)
diff --git a/web/src/admin/applications/wizard/proxy/ak-application-wizard-authentication-for-reverse-proxy.ts b/web/src/admin/applications/wizard/methods/proxy/ak-application-wizard-authentication-for-reverse-proxy.ts
similarity index 100%
rename from web/src/admin/applications/wizard/proxy/ak-application-wizard-authentication-for-reverse-proxy.ts
rename to web/src/admin/applications/wizard/methods/proxy/ak-application-wizard-authentication-for-reverse-proxy.ts
diff --git a/web/src/admin/applications/wizard/proxy/ak-application-wizard-authentication-for-single-forward-proxy.ts b/web/src/admin/applications/wizard/methods/proxy/ak-application-wizard-authentication-for-single-forward-proxy.ts
similarity index 100%
rename from web/src/admin/applications/wizard/proxy/ak-application-wizard-authentication-for-single-forward-proxy.ts
rename to web/src/admin/applications/wizard/methods/proxy/ak-application-wizard-authentication-for-single-forward-proxy.ts
diff --git a/web/src/admin/applications/wizard/saml/SamlProviderOptions.ts b/web/src/admin/applications/wizard/methods/saml/SamlProviderOptions.ts
similarity index 100%
rename from web/src/admin/applications/wizard/saml/SamlProviderOptions.ts
rename to web/src/admin/applications/wizard/methods/saml/SamlProviderOptions.ts
diff --git a/web/src/admin/applications/wizard/saml/ak-application-wizard-authentication-by-saml-configuration.ts b/web/src/admin/applications/wizard/methods/saml/ak-application-wizard-authentication-by-saml-configuration.ts
similarity index 98%
rename from web/src/admin/applications/wizard/saml/ak-application-wizard-authentication-by-saml-configuration.ts
rename to web/src/admin/applications/wizard/methods/saml/ak-application-wizard-authentication-by-saml-configuration.ts
index 2313749c3..f25c995ef 100644
--- a/web/src/admin/applications/wizard/saml/ak-application-wizard-authentication-by-saml-configuration.ts
+++ b/web/src/admin/applications/wizard/methods/saml/ak-application-wizard-authentication-by-saml-configuration.ts
@@ -21,7 +21,7 @@ import {
SAMLProvider,
} from "@goauthentik/api";
-import ApplicationWizardProviderPageBase from "../ApplicationWizardProviderPageBase";
+import BaseProviderPanel from "../BaseProviderPanel";
import {
digestAlgorithmOptions,
signatureAlgorithmOptions,
@@ -29,7 +29,7 @@ import {
} from "./SamlProviderOptions";
@customElement("ak-application-wizard-authentication-by-saml-configuration")
-export class ApplicationWizardProviderSamlConfiguration extends ApplicationWizardProviderPageBase {
+export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPanel {
propertyMappings?: PaginatedSAMLPropertyMappingList;
constructor() {
diff --git a/web/src/admin/applications/wizard/saml/ak-application-wizard-authentication-by-saml-import.ts b/web/src/admin/applications/wizard/methods/saml/ak-application-wizard-authentication-by-saml-import.ts
similarity index 89%
rename from web/src/admin/applications/wizard/saml/ak-application-wizard-authentication-by-saml-import.ts
rename to web/src/admin/applications/wizard/methods/saml/ak-application-wizard-authentication-by-saml-import.ts
index 49d03ef7f..dda096a67 100644
--- a/web/src/admin/applications/wizard/saml/ak-application-wizard-authentication-by-saml-import.ts
+++ b/web/src/admin/applications/wizard/methods/saml/ak-application-wizard-authentication-by-saml-import.ts
@@ -9,10 +9,10 @@ import { html } from "lit";
import { FlowsInstancesListDesignationEnum } from "@goauthentik/api";
-import ApplicationWizardProviderPageBase from "../ApplicationWizardProviderPageBase";
+import BaseProviderPanel from "../BaseProviderPanel";
@customElement("ak-application-wizard-authentication-by-saml-import")
-export class ApplicationWizardProviderSamlImport extends ApplicationWizardProviderPageBase {
+export class ApplicationWizardProviderSamlImport extends BaseProviderPanel {
render() {
return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/oauth/TypeOAuthApplicationWizardPage.ts b/web/src/admin/applications/wizard/oauth/TypeOAuthApplicationWizardPage.ts
deleted file mode 100644
index bb19272e9..000000000
--- a/web/src/admin/applications/wizard/oauth/TypeOAuthApplicationWizardPage.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardPage } from "@goauthentik/elements/wizard/WizardPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { CSSResult, TemplateResult, html } from "lit";
-
-import PFButton from "@patternfly/patternfly/components/Button/button.css";
-import PFForm from "@patternfly/patternfly/components/Form/form.css";
-import PFRadio from "@patternfly/patternfly/components/Radio/radio.css";
-import PFBase from "@patternfly/patternfly/patternfly-base.css";
-
-import { TypeCreate } from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type-oauth")
-export class TypeOAuthApplicationWizardPage extends WizardPage {
- applicationTypes: TypeCreate[] = [
- {
- component: "ak-application-wizard-type-oauth-code",
- name: msg("Web application"),
- description: msg(
- "Applications which handle the authentication server-side (for example, Python, Go, Rust, Java, PHP)",
- ),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-oauth-implicit",
- name: msg("Single-page applications"),
- description: msg(
- "Single-page applications which handle authentication in the browser (for example, Javascript, Angular, React, Vue)",
- ),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-oauth-implicit",
- name: msg("Native application"),
- description: msg(
- "Applications which redirect users to a non-web callback (for example, Android, iOS)",
- ),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-oauth-api",
- name: msg("API"),
- description: msg(
- "Authentication without user interaction, or machine-to-machine authentication.",
- ),
- modelName: "",
- },
- ];
-
- static get styles(): CSSResult[] {
- return [PFBase, PFButton, PFForm, PFRadio];
- }
-
- sidebarLabel = () => msg("Application type");
-
- render(): TemplateResult {
- return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/oauth/TypeOAuthCodeApplicationWizardPage.ts b/web/src/admin/applications/wizard/oauth/TypeOAuthCodeApplicationWizardPage.ts
deleted file mode 100644
index 458def24b..000000000
--- a/web/src/admin/applications/wizard/oauth/TypeOAuthCodeApplicationWizardPage.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import "@goauthentik/admin/common/ak-flow-search/ak-flow-search-no-default";
-import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
-import { KeyUnknown } from "@goauthentik/elements/forms/Form";
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import "@goauthentik/elements/forms/SearchSelect";
-import { WizardFormPage } from "@goauthentik/elements/wizard/WizardFormPage";
-import "@goauthentik/elements/wizard/WizardFormPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { TemplateResult, html } from "lit";
-
-import {
- ClientTypeEnum,
- FlowsInstancesListDesignationEnum,
- OAuth2ProviderRequest,
- ProvidersApi,
-} from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type-oauth-code")
-export class TypeOAuthCodeApplicationWizardPage extends WizardFormPage {
- sidebarLabel = () => msg("Method details");
-
- nextDataCallback = async (data: KeyUnknown): Promise => {
- this.host.addActionBefore(msg("Create provider"), async (): Promise => {
- const req: OAuth2ProviderRequest = {
- name: this.host.state["name"] as string,
- clientType: ClientTypeEnum.Confidential,
- authorizationFlow: data.authorizationFlow as string,
- };
- const provider = await new ProvidersApi(DEFAULT_CONFIG).providersOauth2Create({
- oAuth2ProviderRequest: req,
- });
- this.host.state["provider"] = provider;
- return true;
- });
- return true;
- };
-
- renderForm(): TemplateResult {
- return html``;
- }
-}
diff --git a/web/src/admin/applications/wizard/oauth/TypeOAuthImplicitApplicationWizardPage.ts b/web/src/admin/applications/wizard/oauth/TypeOAuthImplicitApplicationWizardPage.ts
deleted file mode 100644
index c1fa0f3cf..000000000
--- a/web/src/admin/applications/wizard/oauth/TypeOAuthImplicitApplicationWizardPage.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardFormPage } from "@goauthentik/elements/wizard/WizardFormPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { TemplateResult, html } from "lit";
-
-@customElement("ak-application-wizard-type-oauth-implicit")
-export class TypeOAuthImplicitApplicationWizardPage extends WizardFormPage {
- sidebarLabel = () => msg("Method details");
-
- render(): TemplateResult {
- return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/proxy/TypeProxyApplicationWizardPage.ts b/web/src/admin/applications/wizard/proxy/TypeProxyApplicationWizardPage.ts
deleted file mode 100644
index 43db7c56c..000000000
--- a/web/src/admin/applications/wizard/proxy/TypeProxyApplicationWizardPage.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
-import { KeyUnknown } from "@goauthentik/elements/forms/Form";
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardFormPage } from "@goauthentik/elements/wizard/WizardFormPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { TemplateResult, html } from "lit";
-
-import {
- FlowDesignationEnum,
- FlowsApi,
- ProvidersApi,
- ProxyProviderRequest,
-} from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type-proxy")
-export class TypeProxyApplicationWizardPage extends WizardFormPage {
- sidebarLabel = () => msg("Proxy details");
-
- nextDataCallback = async (data: KeyUnknown): Promise => {
- let name = this.host.state["name"] as string;
- // Check if a provider with the name already exists
- const providers = await new ProvidersApi(DEFAULT_CONFIG).providersAllList({
- search: name,
- });
- if (providers.results.filter((provider) => provider.name == name)) {
- name += "-1";
- }
- this.host.addActionBefore(msg("Create provider"), async (): Promise => {
- // Get all flows and default to the implicit authorization
- const flows = await new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
- designation: FlowDesignationEnum.Authorization,
- ordering: "slug",
- });
- const req: ProxyProviderRequest = {
- name: name,
- authorizationFlow: flows.results[0].pk,
- externalHost: data.externalHost as string,
- };
- const provider = await new ProvidersApi(DEFAULT_CONFIG).providersProxyCreate({
- proxyProviderRequest: req,
- });
- this.host.state["provider"] = provider;
- return true;
- });
- return true;
- };
-
- renderForm(): TemplateResult {
- return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/saml/TypeSAMLApplicationWizardPage.ts b/web/src/admin/applications/wizard/saml/TypeSAMLApplicationWizardPage.ts
deleted file mode 100644
index 2ef4d6972..000000000
--- a/web/src/admin/applications/wizard/saml/TypeSAMLApplicationWizardPage.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardPage } from "@goauthentik/elements/wizard/WizardPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { CSSResult, TemplateResult, html } from "lit";
-
-import PFButton from "@patternfly/patternfly/components/Button/button.css";
-import PFForm from "@patternfly/patternfly/components/Form/form.css";
-import PFRadio from "@patternfly/patternfly/components/Radio/radio.css";
-import PFBase from "@patternfly/patternfly/patternfly-base.css";
-
-import { TypeCreate } from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type-saml")
-export class TypeOAuthApplicationWizardPage extends WizardPage {
- applicationTypes: TypeCreate[] = [
- {
- component: "ak-application-wizard-type-saml-import",
- name: msg("Import SAML Metadata"),
- description: msg(
- "Import the metadata document of the applicaation you want to configure.",
- ),
- modelName: "",
- },
- {
- component: "ak-application-wizard-type-saml-config",
- name: msg("Manual configuration"),
- description: msg("Manually configure SAML"),
- modelName: "",
- },
- ];
-
- static get styles(): CSSResult[] {
- return [PFBase, PFButton, PFForm, PFRadio];
- }
-
- sidebarLabel = () => msg("Application type");
-
- render(): TemplateResult {
- return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/saml/TypeSAMLConfigApplicationWizardPage.ts b/web/src/admin/applications/wizard/saml/TypeSAMLConfigApplicationWizardPage.ts
deleted file mode 100644
index ad269ac63..000000000
--- a/web/src/admin/applications/wizard/saml/TypeSAMLConfigApplicationWizardPage.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
-import { KeyUnknown } from "@goauthentik/elements/forms/Form";
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardFormPage } from "@goauthentik/elements/wizard/WizardFormPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { TemplateResult, html } from "lit";
-
-import { FlowDesignationEnum, FlowsApi, ProvidersApi, SAMLProviderRequest } from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type-saml-config")
-export class TypeSAMLApplicationWizardPage extends WizardFormPage {
- sidebarLabel = () => msg("SAML details");
-
- nextDataCallback = async (data: KeyUnknown): Promise => {
- let name = this.host.state["name"] as string;
- // Check if a provider with the name already exists
- const providers = await new ProvidersApi(DEFAULT_CONFIG).providersAllList({
- search: name,
- });
- if (providers.results.filter((provider) => provider.name == name)) {
- name += "-1";
- }
- this.host.addActionBefore(msg("Create provider"), async (): Promise => {
- // Get all flows and default to the implicit authorization
- const flows = await new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
- designation: FlowDesignationEnum.Authorization,
- ordering: "slug",
- });
- const req: SAMLProviderRequest = {
- name: name,
- authorizationFlow: flows.results[0].pk,
- acsUrl: data.acsUrl as string,
- };
- const provider = await new ProvidersApi(DEFAULT_CONFIG).providersSamlCreate({
- sAMLProviderRequest: req,
- });
- this.host.state["provider"] = provider;
- return true;
- });
- return true;
- };
-
- renderForm(): TemplateResult {
- return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/saml/TypeSAMLImportApplicationWizardPage.ts b/web/src/admin/applications/wizard/saml/TypeSAMLImportApplicationWizardPage.ts
deleted file mode 100644
index c3ddfda79..000000000
--- a/web/src/admin/applications/wizard/saml/TypeSAMLImportApplicationWizardPage.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
-import { KeyUnknown } from "@goauthentik/elements/forms/Form";
-import "@goauthentik/elements/forms/HorizontalFormElement";
-import { WizardFormPage } from "@goauthentik/elements/wizard/WizardFormPage";
-
-import { msg } from "@lit/localize";
-import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
-import { TemplateResult, html } from "lit";
-
-import {
- FlowDesignationEnum,
- FlowsApi,
- ProvidersApi,
- ProvidersSamlImportMetadataCreateRequest,
-} from "@goauthentik/api";
-
-@customElement("ak-application-wizard-type-saml-import")
-export class TypeSAMLImportApplicationWizardPage extends WizardFormPage {
- sidebarLabel = () => msg("Import SAML metadata");
-
- nextDataCallback = async (data: KeyUnknown): Promise => {
- let name = this.host.state["name"] as string;
- // Check if a provider with the name already exists
- const providers = await new ProvidersApi(DEFAULT_CONFIG).providersAllList({
- search: name,
- });
- if (providers.results.filter((provider) => provider.name == name)) {
- name += "-1";
- }
- this.host.addActionBefore(msg("Create provider"), async (): Promise => {
- // Get all flows and default to the implicit authorization
- const flows = await new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
- designation: FlowDesignationEnum.Authorization,
- ordering: "slug",
- });
- const req: ProvidersSamlImportMetadataCreateRequest = {
- name: name,
- authorizationFlow: flows.results[0].slug,
- file: data["metadata"] as Blob,
- };
- const provider = await new ProvidersApi(
- DEFAULT_CONFIG,
- ).providersSamlImportMetadataCreate(req);
- this.host.state["provider"] = provider;
- return true;
- });
- return true;
- };
-
- renderForm(): TemplateResult {
- return html` `;
- }
-}
diff --git a/web/src/admin/applications/wizard/ApplicationWizardSteps.ts b/web/src/admin/applications/wizard/steps.ts
similarity index 70%
rename from web/src/admin/applications/wizard/ApplicationWizardSteps.ts
rename to web/src/admin/applications/wizard/steps.ts
index 2c720165b..1b7a5a072 100644
--- a/web/src/admin/applications/wizard/ApplicationWizardSteps.ts
+++ b/web/src/admin/applications/wizard/steps.ts
@@ -1,16 +1,15 @@
-import { WizardStep, makeWizardId } from "@goauthentik/components/ak-wizard-main";
+import { WizardStep } from "@goauthentik/components/ak-wizard-main";
import { msg } from "@lit/localize";
import { html } from "lit";
import "./application/ak-application-wizard-application-details";
import "./auth-method-choice/ak-application-wizard-authentication-method-choice";
-import "./auth-method/ak-application-wizard-authentication-method";
+import "./methods/ak-application-wizard-authentication-method";
export const steps: WizardStep[] = [
{
- id: makeWizardId("application"),
- nextStep: makeWizardId("auth-method-choice"),
+ id: "application",
label: "Application Details",
renderer: () =>
html``,
@@ -19,9 +18,7 @@ export const steps: WizardStep[] = [
valid: true,
},
{
- id: makeWizardId("auth-method-choice"),
- backStep: makeWizardId("application"),
- nextStep: makeWizardId("auth-method"),
+ id: "auth-method-choice",
label: "Authentication Method",
renderer: () =>
html``,
@@ -31,8 +28,7 @@ export const steps: WizardStep[] = [
valid: true,
},
{
- id: makeWizardId("auth-method"),
- backStep: makeWizardId("auth-method-choice"),
+ id: "auth-method",
label: "Authentication Details",
renderer: () =>
html``,
diff --git a/web/src/admin/applications/wizard/stories/ak-application-context-display-for-test.ts b/web/src/admin/applications/wizard/stories/ak-application-context-display-for-test.ts
index 3f8e0ce26..6abd7563e 100644
--- a/web/src/admin/applications/wizard/stories/ak-application-context-display-for-test.ts
+++ b/web/src/admin/applications/wizard/stories/ak-application-context-display-for-test.ts
@@ -3,8 +3,8 @@ import { customElement } from "@lit/reactive-element/decorators/custom-element.j
import { state } from "@lit/reactive-element/decorators/state.js";
import { LitElement, html } from "lit";
-import type { WizardState } from "../ak-application-wizard-context";
import applicationWizardContext from "../ak-application-wizard-context-name";
+import type { WizardState } from "../types";
@customElement("ak-application-context-display-for-test")
export class ApplicationContextDisplayForTest extends LitElement {
diff --git a/web/src/components/ak-wizard-main/ak-wizard-frame.ts b/web/src/components/ak-wizard-main/ak-wizard-frame.ts
index 6368a9010..712e9c777 100644
--- a/web/src/components/ak-wizard-main/ak-wizard-frame.ts
+++ b/web/src/components/ak-wizard-main/ak-wizard-frame.ts
@@ -63,6 +63,20 @@ export class AkWizardFrame extends CustomEmitterElement(ModalButton) {
this.open = false;
}
+ get maxStep() {
+ return this.steps.length - 1;
+ }
+
+ get nextStep() {
+ const idx = this.steps.findIndex((step) => step === this.currentStep);
+ return idx < this.maxStep ? this.steps[idx + 1] : undefined;
+ }
+
+ get backStep() {
+ const idx = this.steps.findIndex((step) => step === this.currentStep);
+ return idx > 0 ? this.steps[idx - 1] : undefined;
+ }
+
renderModalInner() {
// prettier-ignore
return html`
@@ -134,32 +148,30 @@ export class AkWizardFrame extends CustomEmitterElement(ModalButton) {
renderFooter() {
return html`
`;
}
- renderFooterNextButton() {
+ renderFooterNextButton(nextStep: WizardStep) {
return html`
`;
}
- renderFooterBackButton() {
+ renderFooterBackButton(backStep: WizardStep) {
return html`
diff --git a/web/src/components/ak-wizard-main/ak-wizard-main.ts b/web/src/components/ak-wizard-main/ak-wizard-main.ts
index 80f1c15d0..f4be5734a 100644
--- a/web/src/components/ak-wizard-main/ak-wizard-main.ts
+++ b/web/src/components/ak-wizard-main/ak-wizard-main.ts
@@ -20,8 +20,11 @@ import type { WizardStep } from "./types";
*
* @element ak-wizard-main
*
- * This is the entry point for the wizard.
- *
+ * This is the entry point for the wizard. Its tasks are:
+ * - keep the collection of steps
+ * - maintain the open/close status of the modal
+ * - listens for navigation events
+ * - if a navigation event is valid, switch to the panel requested
*/
@customElement("ak-wizard-main")
diff --git a/web/src/components/ak-wizard-main/index.ts b/web/src/components/ak-wizard-main/index.ts
index 30bb39ff1..572b3befe 100644
--- a/web/src/components/ak-wizard-main/index.ts
+++ b/web/src/components/ak-wizard-main/index.ts
@@ -1,5 +1,4 @@
import "./ak-wizard-main";
-import type { WizardStep, WizardStepId } from "./types";
-import { makeWizardId } from "./types";
+import type { WizardStep } from "./types";
-export { WizardStepId, WizardStep, makeWizardId };
+export { WizardStep };
diff --git a/web/src/components/ak-wizard-main/stories/ak-wizard-main.stories.ts b/web/src/components/ak-wizard-main/stories/ak-wizard-main.stories.ts
index 235f55faf..e35f9de5e 100644
--- a/web/src/components/ak-wizard-main/stories/ak-wizard-main.stories.ts
+++ b/web/src/components/ak-wizard-main/stories/ak-wizard-main.stories.ts
@@ -6,7 +6,6 @@ import { TemplateResult, html } from "lit";
import "../ak-wizard-main";
import AkWizard from "../ak-wizard-main";
import type { WizardStep } from "../types";
-import { makeWizardId } from "../types";
const metadata: Meta
= {
title: "Components / Wizard / Basic",
@@ -38,22 +37,20 @@ const container = (testItem: TemplateResult) =>
const dummySteps: WizardStep[] = [
{
- id: makeWizardId("0"),
+ id: "0",
label: "Test Step1",
renderer: () => html`This space intentionally left blank today
`,
disabled: false,
valid: true,
- nextStep: makeWizardId("1"),
nextButtonLabel: "Next",
backButtonLabel: undefined,
},
{
- id: makeWizardId("1"),
+ id: "1",
label: "Test Step 2",
renderer: () => html`This space also intentionally left blank
`,
disabled: false,
valid: true,
- backStep: makeWizardId("0"),
nextButtonLabel: undefined,
backButtonLabel: "Back",
},
diff --git a/web/src/components/ak-wizard-main/types.ts b/web/src/components/ak-wizard-main/types.ts
index a1911fb0d..f295a77f4 100644
--- a/web/src/components/ak-wizard-main/types.ts
+++ b/web/src/components/ak-wizard-main/types.ts
@@ -1,15 +1,7 @@
import { TemplateResult } from "lit";
-type PhantomType = { _type: Type } & Data;
-
-export type WizardStepId = PhantomType<"WizardId", string>;
-
-export const makeWizardId = (id: string): WizardStepId => id as WizardStepId;
-
export interface WizardStep {
- id: WizardStepId;
- nextStep?: WizardStepId;
- backStep?: WizardStepId;
+ id: string;
label: string;
valid: boolean;
renderer: () => TemplateResult;