web: reset

As I said, I greatly dislike having to be dependent upon "resets"; I prefer my
data to be de novo going into a "new" transaction.  That said, we work with
what we've got; I've created an event generated by the wizard that says the
modal just closed; anything wrapping and implementing the wizard can then
capture that event and reset the data.  I've also added a pair of functions
that create the two states (what step, what form data) anew, so that resetting
is as trivial as initializing (and is exactly the same, code-wise).
This commit is contained in:
Ken Sternberg 2023-09-02 10:16:17 -07:00
parent c889801bb3
commit b7ea6d163b
11 changed files with 25 additions and 25 deletions

View file

@ -55,6 +55,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
constructor() {
super();
this.handleUpdate = this.handleUpdate.bind(this);
this.handleClosed = this.handleClosed.bind(this);
}
get step() {
@ -65,10 +66,12 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
super.connectedCallback();
new ContextRoot().attach(this.parentElement!);
this.addCustomListener("ak-application-wizard-update", this.handleUpdate);
this.addCustomListener("ak-wizard-closed", this.handleClosed);
}
disconnectedCallback() {
this.removeCustomListener("ak-application-wizard-update", this.handleUpdate);
this.removeCustomListener("ak-wizard-closed", this.handleClosed);
super.disconnectedCallback();
}
@ -124,6 +127,12 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
this.wizardStateProvider.setValue(this.wizardState);
}
handleClosed() {
this.steps = newSteps();
this.wizardState = freshWizardState();
this.wizardStateProvider.setValue(this.wizardState);
}
render() {
return html`
<ak-wizard-main

View file

@ -38,7 +38,7 @@ export class ApplicationWizardApplicationDetails extends BasePanel {
validator() {
return this.form.reportValidity();
}
render(): TemplateResult {
return html` <form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
<ak-text-input

View file

@ -26,7 +26,6 @@ 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 {
@ -116,7 +115,7 @@ export class ApplicationWizardCommitApplication extends BasePanel {
}
this.response = network_resolution.value;
this.dispatchCustomEvent(EVENT_REFRESH);
this.dispatchWizardUpdate({ status: "submitted"});
this.dispatchWizardUpdate({ status: "submitted" });
this.commitState = doneState;
}
});

View file

@ -14,15 +14,10 @@ export class ApplicationWizardProviderPageBase extends BasePanel {
[target.name]: value,
},
},
status: this.form.checkValidity() ? "valid" : "invalid"
status: this.form.checkValidity() ? "valid" : "invalid",
});
}
shouldUpdate(changed: Map<string, any>) {
console.log("CHANGED:", JSON.stringify(Array.from(changed.entries()), null, 2));
return true;
}
validator() {
return this.form.reportValidity();
}

View file

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

View file

@ -71,13 +71,11 @@ export class AkWizardFrame extends CustomEmitterElement(ModalButton) {
}
renderModalInner() {
// prettier-ignore
return html`<div class="pf-c-wizard">
${this.renderHeader()}
<div class="pf-c-wizard__outer-wrap">
<div class="pf-c-wizard__inner-wrap">
${this.renderNavigation()}
${this.renderMainSection()}
${this.renderNavigation()} ${this.renderMainSection()}
</div>
${this.renderFooter()}
</div>

View file

@ -1,5 +1,5 @@
import { AKElement } from "@goauthentik/elements/Base";
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { CustomEmitterElement, CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { html } from "lit";
import { customElement, property, query, state } from "lit/decorators.js";
@ -45,7 +45,7 @@ const hasValidator = (v: any): v is Required<Pick<WizardPanel, "validator">> =>
*/
@customElement("ak-wizard-main")
export class AkWizardMain extends CustomListenerElement(AKElement) {
export class AkWizardMain extends CustomEmitterElement(CustomListenerElement(AKElement)) {
static get styles() {
return [PFBase, PFButton, PFRadio];
}
@ -167,6 +167,7 @@ export class AkWizardMain extends CustomListenerElement(AKElement) {
case "close": {
this.currentStep = 0;
this.frame.open = false;
this.dispatchCustomEvent('ak-wizard-closed');
}
}
}

View file

@ -1,4 +1,5 @@
import { msg } from "@lit/localize";
import { WizardButton } from "./types";
export const NextStep: WizardButton = [msg("Next"), "next"];
@ -10,4 +11,3 @@ export const SubmitStep: WizardButton = [msg("Submit"), "next"];
export const CancelWizard: WizardButton = [msg("Cancel"), "close"];
export const CloseWizard: WizardButton = [msg("Close"), "close"];

View file

@ -36,8 +36,8 @@ export class AkDemoWizard extends AKElement {
<ak-wizard-context .steps=${this.steps}>
<ak-wizard-frame
?open=${this.open}
header=${this.header}
canCancel
header=${this.header}
canCancel
description=${ifDefined(this.description)}
>
<button slot="trigger" class="pf-c-button pf-m-primary">Show Wizard</button>

View file

@ -2,15 +2,13 @@ import { TemplateResult } from "lit";
export type WizardNavCommand = "next" | "back" | "close" | ["goto", number];
// The label of the button, the command the button should execute, and if the button
// should be marked "disabled."
export type WizardButton = [string, WizardNavCommand, boolean?];
export interface WizardStep {
// The name of the step, as shown in the navigation.
label: string;
label: string;
// A function which returns the html for rendering the actual content of the step, its form and
// such.

View file

@ -1,7 +1,7 @@
import { AKElement } from "@goauthentik/elements/Base";
import { PFSize } from "@goauthentik/elements/Spinner";
import { CSSResult, TemplateResult, css, html } from "lit";
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFBackdrop from "@patternfly/patternfly/components/Backdrop/backdrop.css";
@ -100,7 +100,7 @@ export class ModalButton extends AKElement {
});
}
renderModalInner(): TemplateResult {
renderModalInner(): TemplateResult | typeof nothing {
return html`<slot name="modal"></slot>`;
}
@ -136,6 +136,6 @@ export class ModalButton extends AKElement {
render(): TemplateResult {
return html` <slot name="trigger" @click=${() => this.onClick()}></slot>
${this.open ? this.renderModal() : ""}`;
${this.open ? this.renderModal() : nothing}`;
}
}