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:
Ken Sternberg 2023-09-02 09:08:06 -07:00
parent 217505d0c9
commit c889801bb3
5 changed files with 39 additions and 24 deletions

View File

@ -1,6 +1,7 @@
import { type AkWizardMain } from "@goauthentik/app/components/ak-wizard-main/ak-wizard-main";
import { merge } from "@goauthentik/common/merge";
import "@goauthentik/components/ak-wizard-main";
import { CloseWizard } from "@goauthentik/components/ak-wizard-main/commonWizardButtons";
import { AKElement } from "@goauthentik/elements/Base";
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 applicationWizardContext from "./ak-application-wizard-context-name";
import { steps } from "./steps";
import { OneOfProvider, WizardState, WizardStateEvent } from "./types";
import { newSteps } from "./steps";
import { OneOfProvider, WizardState, WizardStateUpdate } from "./types";
const freshWizardState = () => ({
providerModel: "",
app: {},
provider: {},
});
@customElement("ak-application-wizard")
export class ApplicationWizard extends CustomListenerElement(AKElement) {
@ -25,11 +32,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
}
@state()
wizardState: WizardState = {
providerModel: "",
app: {},
provider: {},
};
wizardState: WizardState = freshWizardState();
/**
* Providing a context at the root element
@ -40,7 +43,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
});
@state()
steps = steps;
steps = newSteps();
@property()
prompt = msg("Create");
@ -49,15 +52,15 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
wizardRef: Ref<AkWizardMain> = createRef();
get step() {
return this.wizardRef.value?.currentStep ?? -1;
}
constructor() {
super();
this.handleUpdate = this.handleUpdate.bind(this);
}
get step() {
return this.wizardRef.value?.currentStep ?? -1;
}
connectedCallback() {
super.connectedCallback();
new ContextRoot().attach(this.parentElement!);
@ -88,11 +91,25 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
throw new Error("Could not find Authentication Method page?");
}
method.disabled = false;
return true;
}
// 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;
if (!update) {
return;
}
if (this.maybeProviderSwap(update.providerModel)) {
this.steps = [...this.steps];
@ -100,7 +117,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
if (event.detail.status === "valid" && this.steps[this.step + 1]) {
this.steps[this.step + 1].disabled = false;
this.steps = [...this.steps];
this.steps = [...this.steps];
}
this.wizardState = merge(this.wizardState, update) as WizardState;

View File

@ -26,6 +26,7 @@ import type { ModelRequest } from "@goauthentik/api";
import BasePanel from "../BasePanel";
import providerModelsList from "../auth-method-choice/ak-application-wizard-authentication-method-choice.choices";
import { type WizardStateUpdate } from "../types";
function cleanApplication(app: Partial<ApplicationRequest>): ApplicationRequest {
return {
@ -100,6 +101,7 @@ export class ApplicationWizardCommitApplication extends BasePanel {
const network = new CoreApi(DEFAULT_CONFIG).coreTransactionalApplicationsUpdate({
transactionApplicationRequest: data,
});
Promise.allSettled([network, timeout]).then(([network_resolution]) => {
if (network_resolution.status === "rejected") {
this.commitState = errorState;
@ -112,9 +114,9 @@ export class ApplicationWizardCommitApplication extends BasePanel {
this.errors = network_resolution.value.logs;
return;
}
this.response = network_resolution.value;
this.dispatchCustomEvent(EVENT_REFRESH);
this.dispatchWizardUpdate({ status: "submitted"});
this.commitState = doneState;
}
});

View File

@ -14,11 +14,11 @@ import "./commit/ak-application-wizard-commit-application";
import "./methods/ak-application-wizard-authentication-method";
type NamedStep = WizardStep & {
id: string,
valid: boolean,
id: string;
valid: boolean;
};
export const steps: NamedStep[] = [
export const newSteps = (): NamedStep[] => [
{
id: "application",
label: "Application Details",

View File

@ -25,6 +25,6 @@ export interface WizardState {
type StatusType = "invalid" | "valid" | "submitted" | "failed";
export type WizardStateUpdate = {
update: Partial<WizardState>,
update?: Partial<WizardState>,
status?: StatusType,
};

View File

@ -154,11 +154,6 @@ export class AkWizardMain extends CustomListenerElement(AKElement) {
return;
}
case "next": {
console.log(this.nextStep,
this.steps[this.nextStep],
!this.steps[this.nextStep].disabled,
this.validated);
if (
this.nextStep &&
this.steps[this.nextStep] &&
@ -170,6 +165,7 @@ export class AkWizardMain extends CustomListenerElement(AKElement) {
return;
}
case "close": {
this.currentStep = 0;
this.frame.open = false;
}
}