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:
parent
c889801bb3
commit
b7ea6d163b
|
@ -55,6 +55,7 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.handleUpdate = this.handleUpdate.bind(this);
|
this.handleUpdate = this.handleUpdate.bind(this);
|
||||||
|
this.handleClosed = this.handleClosed.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get step() {
|
get step() {
|
||||||
|
@ -65,10 +66,12 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
new ContextRoot().attach(this.parentElement!);
|
new ContextRoot().attach(this.parentElement!);
|
||||||
this.addCustomListener("ak-application-wizard-update", this.handleUpdate);
|
this.addCustomListener("ak-application-wizard-update", this.handleUpdate);
|
||||||
|
this.addCustomListener("ak-wizard-closed", this.handleClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
this.removeCustomListener("ak-application-wizard-update", this.handleUpdate);
|
this.removeCustomListener("ak-application-wizard-update", this.handleUpdate);
|
||||||
|
this.removeCustomListener("ak-wizard-closed", this.handleClosed);
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +127,12 @@ export class ApplicationWizard extends CustomListenerElement(AKElement) {
|
||||||
this.wizardStateProvider.setValue(this.wizardState);
|
this.wizardStateProvider.setValue(this.wizardState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleClosed() {
|
||||||
|
this.steps = newSteps();
|
||||||
|
this.wizardState = freshWizardState();
|
||||||
|
this.wizardStateProvider.setValue(this.wizardState);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<ak-wizard-main
|
<ak-wizard-main
|
||||||
|
|
|
@ -26,7 +26,6 @@ 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 {
|
||||||
|
|
|
@ -14,15 +14,10 @@ export class ApplicationWizardProviderPageBase extends BasePanel {
|
||||||
[target.name]: value,
|
[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() {
|
validator() {
|
||||||
return this.form.reportValidity();
|
return this.form.reportValidity();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,13 +71,11 @@ export class AkWizardFrame extends CustomEmitterElement(ModalButton) {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModalInner() {
|
renderModalInner() {
|
||||||
// prettier-ignore
|
|
||||||
return html`<div class="pf-c-wizard">
|
return html`<div class="pf-c-wizard">
|
||||||
${this.renderHeader()}
|
${this.renderHeader()}
|
||||||
<div class="pf-c-wizard__outer-wrap">
|
<div class="pf-c-wizard__outer-wrap">
|
||||||
<div class="pf-c-wizard__inner-wrap">
|
<div class="pf-c-wizard__inner-wrap">
|
||||||
${this.renderNavigation()}
|
${this.renderNavigation()} ${this.renderMainSection()}
|
||||||
${this.renderMainSection()}
|
|
||||||
</div>
|
</div>
|
||||||
${this.renderFooter()}
|
${this.renderFooter()}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
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 { html } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators.js";
|
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")
|
@customElement("ak-wizard-main")
|
||||||
export class AkWizardMain extends CustomListenerElement(AKElement) {
|
export class AkWizardMain extends CustomEmitterElement(CustomListenerElement(AKElement)) {
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [PFBase, PFButton, PFRadio];
|
return [PFBase, PFButton, PFRadio];
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,7 @@ export class AkWizardMain extends CustomListenerElement(AKElement) {
|
||||||
case "close": {
|
case "close": {
|
||||||
this.currentStep = 0;
|
this.currentStep = 0;
|
||||||
this.frame.open = false;
|
this.frame.open = false;
|
||||||
|
this.dispatchCustomEvent('ak-wizard-closed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
|
|
||||||
import { WizardButton } from "./types";
|
import { WizardButton } from "./types";
|
||||||
|
|
||||||
export const NextStep: WizardButton = [msg("Next"), "next"];
|
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 CancelWizard: WizardButton = [msg("Cancel"), "close"];
|
||||||
|
|
||||||
export const CloseWizard: WizardButton = [msg("Close"), "close"];
|
export const CloseWizard: WizardButton = [msg("Close"), "close"];
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,10 @@ import { TemplateResult } from "lit";
|
||||||
|
|
||||||
export type WizardNavCommand = "next" | "back" | "close" | ["goto", number];
|
export type WizardNavCommand = "next" | "back" | "close" | ["goto", number];
|
||||||
|
|
||||||
|
|
||||||
// The label of the button, the command the button should execute, and if the button
|
// The label of the button, the command the button should execute, and if the button
|
||||||
// should be marked "disabled."
|
// should be marked "disabled."
|
||||||
export type WizardButton = [string, WizardNavCommand, boolean?];
|
export type WizardButton = [string, WizardNavCommand, boolean?];
|
||||||
|
|
||||||
|
|
||||||
export interface WizardStep {
|
export interface WizardStep {
|
||||||
// The name of the step, as shown in the navigation.
|
// The name of the step, as shown in the navigation.
|
||||||
label: string;
|
label: string;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { PFSize } from "@goauthentik/elements/Spinner";
|
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 { customElement, property } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFBackdrop from "@patternfly/patternfly/components/Backdrop/backdrop.css";
|
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>`;
|
return html`<slot name="modal"></slot>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +136,6 @@ export class ModalButton extends AKElement {
|
||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
return html` <slot name="trigger" @click=${() => this.onClick()}></slot>
|
return html` <slot name="trigger" @click=${() => this.onClick()}></slot>
|
||||||
${this.open ? this.renderModal() : ""}`;
|
${this.open ? this.renderModal() : nothing}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue