web: resetting the form is not working yet...
I vehemently dislike the object-oriented "reset" command; every wizard should start with an absolutely fresh copy of the data upon entry. Refactoring the wizard to re-build its content from the inside is the correct way to go, but I don't have a good mental image of how to make the ModalButton and the component it invokes interact cleanly, which frustrates the hell out of me.
This commit is contained in:
parent
217505d0c9
commit
c889801bb3
|
@ -1,6 +1,7 @@
|
||||||
import { type AkWizardMain } from "@goauthentik/app/components/ak-wizard-main/ak-wizard-main";
|
import { type AkWizardMain } from "@goauthentik/app/components/ak-wizard-main/ak-wizard-main";
|
||||||
import { merge } from "@goauthentik/common/merge";
|
import { merge } from "@goauthentik/common/merge";
|
||||||
import "@goauthentik/components/ak-wizard-main";
|
import "@goauthentik/components/ak-wizard-main";
|
||||||
|
import { CloseWizard } from "@goauthentik/components/ak-wizard-main/commonWizardButtons";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||||
|
|
||||||
|
@ -15,8 +16,14 @@ import PFRadio from "@patternfly/patternfly/components/Radio/radio.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
import applicationWizardContext from "./ak-application-wizard-context-name";
|
import applicationWizardContext from "./ak-application-wizard-context-name";
|
||||||
import { steps } from "./steps";
|
import { newSteps } from "./steps";
|
||||||
import { OneOfProvider, WizardState, WizardStateEvent } from "./types";
|
import { OneOfProvider, WizardState, WizardStateUpdate } from "./types";
|
||||||
|
|
||||||
|
const freshWizardState = () => ({
|
||||||
|
providerModel: "",
|
||||||
|
app: {},
|
||||||
|
provider: {},
|
||||||
|
});
|
||||||
|
|
||||||
@customElement("ak-application-wizard")
|
@customElement("ak-application-wizard")
|
||||||
export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
|
@ -25,11 +32,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
wizardState: WizardState = {
|
wizardState: WizardState = freshWizardState();
|
||||||
providerModel: "",
|
|
||||||
app: {},
|
|
||||||
provider: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providing a context at the root element
|
* Providing a context at the root element
|
||||||
|
@ -40,7 +43,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
});
|
});
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
steps = steps;
|
steps = newSteps();
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
prompt = msg("Create");
|
prompt = msg("Create");
|
||||||
|
@ -49,15 +52,15 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
|
|
||||||
wizardRef: Ref<AkWizardMain> = createRef();
|
wizardRef: Ref<AkWizardMain> = createRef();
|
||||||
|
|
||||||
get step() {
|
|
||||||
return this.wizardRef.value?.currentStep ?? -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.handleUpdate = this.handleUpdate.bind(this);
|
this.handleUpdate = this.handleUpdate.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get step() {
|
||||||
|
return this.wizardRef.value?.currentStep ?? -1;
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
new ContextRoot().attach(this.parentElement!);
|
new ContextRoot().attach(this.parentElement!);
|
||||||
|
@ -88,11 +91,25 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
throw new Error("Could not find Authentication Method page?");
|
throw new Error("Could not find Authentication Method page?");
|
||||||
}
|
}
|
||||||
method.disabled = false;
|
method.disabled = false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And this is where all the special cases go...
|
// And this is where all the special cases go...
|
||||||
handleUpdate(event: CustomEvent<WizardStateEvent>) {
|
handleUpdate(event: CustomEvent<WizardStateUpdate>) {
|
||||||
|
if (event.detail.status === "submitted") {
|
||||||
|
const submitStep = this.steps.find(({ id }) => id === "submit");
|
||||||
|
if (!submitStep) {
|
||||||
|
throw new Error("Could not find submit step?");
|
||||||
|
}
|
||||||
|
submitStep.buttons = [CloseWizard];
|
||||||
|
this.steps = [...this.steps];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const update = event.detail.update;
|
const update = event.detail.update;
|
||||||
|
if (!update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.maybeProviderSwap(update.providerModel)) {
|
if (this.maybeProviderSwap(update.providerModel)) {
|
||||||
this.steps = [...this.steps];
|
this.steps = [...this.steps];
|
||||||
|
@ -100,7 +117,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
|
|
||||||
if (event.detail.status === "valid" && this.steps[this.step + 1]) {
|
if (event.detail.status === "valid" && this.steps[this.step + 1]) {
|
||||||
this.steps[this.step + 1].disabled = false;
|
this.steps[this.step + 1].disabled = false;
|
||||||
this.steps = [...this.steps];
|
this.steps = [...this.steps];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.wizardState = merge(this.wizardState, update) as WizardState;
|
this.wizardState = merge(this.wizardState, update) as WizardState;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import type { ModelRequest } from "@goauthentik/api";
|
||||||
|
|
||||||
import BasePanel from "../BasePanel";
|
import BasePanel from "../BasePanel";
|
||||||
import providerModelsList from "../auth-method-choice/ak-application-wizard-authentication-method-choice.choices";
|
import providerModelsList from "../auth-method-choice/ak-application-wizard-authentication-method-choice.choices";
|
||||||
|
import { type WizardStateUpdate } from "../types";
|
||||||
|
|
||||||
function cleanApplication(app: Partial<ApplicationRequest>): ApplicationRequest {
|
function cleanApplication(app: Partial<ApplicationRequest>): ApplicationRequest {
|
||||||
return {
|
return {
|
||||||
|
@ -100,6 +101,7 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
||||||
const network = new CoreApi(DEFAULT_CONFIG).coreTransactionalApplicationsUpdate({
|
const network = new CoreApi(DEFAULT_CONFIG).coreTransactionalApplicationsUpdate({
|
||||||
transactionApplicationRequest: data,
|
transactionApplicationRequest: data,
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise.allSettled([network, timeout]).then(([network_resolution]) => {
|
Promise.allSettled([network, timeout]).then(([network_resolution]) => {
|
||||||
if (network_resolution.status === "rejected") {
|
if (network_resolution.status === "rejected") {
|
||||||
this.commitState = errorState;
|
this.commitState = errorState;
|
||||||
|
@ -112,9 +114,9 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
||||||
this.errors = network_resolution.value.logs;
|
this.errors = network_resolution.value.logs;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.response = network_resolution.value;
|
this.response = network_resolution.value;
|
||||||
this.dispatchCustomEvent(EVENT_REFRESH);
|
this.dispatchCustomEvent(EVENT_REFRESH);
|
||||||
|
this.dispatchWizardUpdate({ status: "submitted"});
|
||||||
this.commitState = doneState;
|
this.commitState = doneState;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,11 +14,11 @@ import "./commit/ak-application-wizard-commit-application";
|
||||||
import "./methods/ak-application-wizard-authentication-method";
|
import "./methods/ak-application-wizard-authentication-method";
|
||||||
|
|
||||||
type NamedStep = WizardStep & {
|
type NamedStep = WizardStep & {
|
||||||
id: string,
|
id: string;
|
||||||
valid: boolean,
|
valid: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const steps: NamedStep[] = [
|
export const newSteps = (): NamedStep[] => [
|
||||||
{
|
{
|
||||||
id: "application",
|
id: "application",
|
||||||
label: "Application Details",
|
label: "Application Details",
|
||||||
|
|
|
@ -25,6 +25,6 @@ export interface WizardState {
|
||||||
type StatusType = "invalid" | "valid" | "submitted" | "failed";
|
type StatusType = "invalid" | "valid" | "submitted" | "failed";
|
||||||
|
|
||||||
export type WizardStateUpdate = {
|
export type WizardStateUpdate = {
|
||||||
update: Partial<WizardState>,
|
update?: Partial<WizardState>,
|
||||||
status?: StatusType,
|
status?: StatusType,
|
||||||
};
|
};
|
||||||
|
|
|
@ -154,11 +154,6 @@ export class AkWizardMain extends CustomListenerElement(AKElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case "next": {
|
case "next": {
|
||||||
console.log(this.nextStep,
|
|
||||||
this.steps[this.nextStep],
|
|
||||||
!this.steps[this.nextStep].disabled,
|
|
||||||
this.validated);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.nextStep &&
|
this.nextStep &&
|
||||||
this.steps[this.nextStep] &&
|
this.steps[this.nextStep] &&
|
||||||
|
@ -170,6 +165,7 @@ export class AkWizardMain extends CustomListenerElement(AKElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case "close": {
|
case "close": {
|
||||||
|
this.currentStep = 0;
|
||||||
this.frame.open = false;
|
this.frame.open = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue