web: reify the data loop
I was very unhappy with the "update this dot-path" mechanism I was using earlier; it was hard for me to read and understand what was happening, and I wrote the darned thing. I decided instead to go with a hard substitution model; each phase of the wizard is responsible for updating the *entire* payload, mostly by creating a new payload and substituting the field value associated with the event. On the receiver, we have to do that *again* to handle the swapping of providers when the user chooses one and then another. It looks clunky, and it is, but it's *legible*; a junior dev could understand what it's doing, and that's the goal.
This commit is contained in:
parent
5e1854f74e
commit
09fedcacf0
|
@ -2,7 +2,7 @@ import { WizardPanel } from "@goauthentik/components/ak-wizard-main/types";
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { consume } from "@lit/context";
|
||||
import { consume } from "@lit-labs/context";
|
||||
import { query } from "@lit/reactive-element/decorators.js";
|
||||
|
||||
import { styles as AwadStyles } from "./BasePanel.css";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { createContext } from "@lit/context";
|
||||
import { createContext } from "@lit-labs/context";
|
||||
|
||||
import { ApplicationWizardState } from "./types";
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { merge } from "@goauthentik/common/merge";
|
||||
import { AkWizard } from "@goauthentik/components/ak-wizard-main/AkWizard";
|
||||
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { ContextProvider } from "@lit/context";
|
||||
import { ContextProvider } from "@lit-labs/context";
|
||||
import { msg } from "@lit/localize";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
|
||||
|
@ -97,7 +96,22 @@ export class ApplicationWizard extends CustomListenerElement(
|
|||
this.requestUpdate();
|
||||
}
|
||||
|
||||
this.wizardState = merge(this.wizardState, update) as ApplicationWizardState;
|
||||
// Being extremely explicit about how a wizard state gets built, so that we preserve as much
|
||||
// information as possible. This is much more predictable than using a generic merge.
|
||||
|
||||
this.wizardState = {
|
||||
...this.wizardState,
|
||||
app: {
|
||||
...this.wizardState.app ?? {},
|
||||
...update.app ?? {}
|
||||
},
|
||||
provider: {
|
||||
...this.wizardState.provider ?? {},
|
||||
...update.provider ?? {}
|
||||
},
|
||||
providerModel: update.providerModel
|
||||
}
|
||||
|
||||
this.wizardStateProvider.setValue(this.wizardState);
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ export class ApplicationWizardApplicationDetails extends BasePanel {
|
|||
const value = target.type === "checkbox" ? target.checked : target.value;
|
||||
this.dispatchWizardUpdate({
|
||||
update: {
|
||||
...this.wizard,
|
||||
app: {
|
||||
...this.wizard.app,
|
||||
[target.name]: value,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -25,7 +25,10 @@ export class ApplicationWizardAuthenticationMethodChoice extends BasePanel {
|
|||
handleChoice(ev: InputEvent) {
|
||||
const target = ev.target as HTMLInputElement;
|
||||
this.dispatchWizardUpdate({
|
||||
update: { providerModel: target.value },
|
||||
update: {
|
||||
...this.wizard,
|
||||
providerModel: target.value
|
||||
},
|
||||
status: this.validator() ? "valid" : "invalid",
|
||||
});
|
||||
}
|
||||
|
|
|
@ -133,7 +133,6 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
|||
if (body["provider"] !== undefined) {
|
||||
errs = [...errs, msg("In the Provider:"), ...spaceify(body["provider"])];
|
||||
}
|
||||
console.log(body, errs);
|
||||
return errs;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ export class ApplicationWizardProviderPageBase extends BasePanel {
|
|||
const value = target.type === "checkbox" ? target.checked : target.value;
|
||||
this.dispatchWizardUpdate({
|
||||
update: {
|
||||
...this.wizard,
|
||||
provider: {
|
||||
...this.wizard.provider,
|
||||
[target.name]: value,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { consume } from "@lit/context";
|
||||
import { consume } from "@lit-labs/context";
|
||||
import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
|
||||
import { state } from "@lit/reactive-element/decorators/state.js";
|
||||
import { LitElement, html } from "lit";
|
||||
|
|
|
@ -29,7 +29,7 @@ export interface ApplicationWizardState {
|
|||
type StatusType = "invalid" | "valid" | "submitted" | "failed";
|
||||
|
||||
export type ApplicationWizardStateUpdate = {
|
||||
update?: Partial<ApplicationWizardState>;
|
||||
update?: ApplicationWizardState;
|
||||
status?: StatusType;
|
||||
};
|
||||
|
||||
|
|
Reference in New Issue