From 044a0620afeb697c4abff6d32c9ea62cf820c7a4 Mon Sep 17 00:00:00 2001 From: Teffen Ellis Date: Mon, 14 Jul 2025 16:45:24 +0200 Subject: [PATCH] web: Unify usage of "valid". --- .../admin/admin-settings/AdminSettingsFooterLinks.ts | 2 +- .../stories/AdminSettingsFooterLinks.stories.ts | 2 +- .../stories/AdminSettingsFooterLinks.test.ts | 10 +++++----- web/src/admin/outposts/ServiceConnectionWizard.ts | 2 +- web/src/admin/policies/PolicyWizard.ts | 2 +- .../admin/property-mappings/PropertyMappingWizard.ts | 2 +- web/src/admin/providers/ProviderWizard.ts | 2 +- .../providers/oauth2/OAuth2ProviderRedirectURI.ts | 2 +- web/src/admin/sources/SourceWizard.ts | 2 +- web/src/admin/stages/StageWizard.ts | 2 +- web/src/elements/AkControlElement.ts | 2 +- web/src/elements/ak-array-input.ts | 11 ++++++----- web/src/elements/stories/ak-array-input.stories.ts | 2 +- web/src/elements/tests/ak-array-input.test.ts | 4 ++-- web/src/elements/utils/inputs.ts | 6 ++++++ web/src/elements/wizard/ActionWizardPage.ts | 4 ++-- web/src/elements/wizard/FormWizardPage.ts | 2 +- web/src/elements/wizard/TypeCreateWizardPage.ts | 2 +- web/src/elements/wizard/Wizard.ts | 4 ++-- web/src/elements/wizard/WizardPage.ts | 2 +- .../stages/identification/RememberMeController.ts | 2 +- 21 files changed, 38 insertions(+), 31 deletions(-) diff --git a/web/src/admin/admin-settings/AdminSettingsFooterLinks.ts b/web/src/admin/admin-settings/AdminSettingsFooterLinks.ts index 8515905d14..d4f813b07d 100644 --- a/web/src/admin/admin-settings/AdminSettingsFooterLinks.ts +++ b/web/src/admin/admin-settings/AdminSettingsFooterLinks.ts @@ -51,7 +51,7 @@ export class FooterLinkInput extends AkControlElement { ) as unknown as FooterLink; } - get isValid() { + get valid() { const href = this.json()?.href ?? ""; return hasLegalScheme(href) && URL.canParse(href); } diff --git a/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.stories.ts b/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.stories.ts index aa615f8600..58154a6b74 100644 --- a/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.stories.ts +++ b/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.stories.ts @@ -34,7 +34,7 @@ const metadata: Meta = { return; } const target = event.target as FooterLinkInput; - messages!.innerText = `${JSON.stringify(target.json(), null, 2)}\n\nValid: ${target.isValid ? "Yes" : "No"}`; + messages!.innerText = `${JSON.stringify(target.json(), null, 2)}\n\nValid: ${target.valid ? "Yes" : "No"}`; }); }, 250); diff --git a/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.test.ts b/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.test.ts index 9b29d0b68d..0acb62884d 100644 --- a/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.test.ts +++ b/web/src/admin/admin-settings/stories/AdminSettingsFooterLinks.test.ts @@ -20,7 +20,7 @@ describe("ak-admin-settings-footer-link", () => { it("should render an empty control", async () => { render(html``); const link = await $("ak-admin-settings-footer-link"); - await expect(await link.getProperty("isValid")).toStrictEqual(false); + await expect(await link.getProperty("valid")).toStrictEqual(false); await expect(await link.getProperty("toJson")).toEqual({ name: "", href: "" }); }); @@ -28,7 +28,7 @@ describe("ak-admin-settings-footer-link", () => { render(html``); const link = await $("ak-admin-settings-footer-link"); await link.$('input[name="name"]').setValue("foo"); - await expect(await link.getProperty("isValid")).toStrictEqual(false); + await expect(await link.getProperty("valid")).toStrictEqual(false); await expect(await link.getProperty("toJson")).toEqual({ name: "foo", href: "" }); }); @@ -36,7 +36,7 @@ describe("ak-admin-settings-footer-link", () => { render(html``); const link = await $("ak-admin-settings-footer-link"); await link.$('input[name="href"]').setValue("https://foo.com"); - await expect(await link.getProperty("isValid")).toStrictEqual(true); + await expect(await link.getProperty("valid")).toStrictEqual(true); await expect(await link.getProperty("toJson")).toEqual({ name: "", href: "https://foo.com", @@ -48,7 +48,7 @@ describe("ak-admin-settings-footer-link", () => { const link = await $("ak-admin-settings-footer-link"); await link.$('input[name="name"]').setValue("foo"); await link.$('input[name="href"]').setValue("https://foo.com"); - await expect(await link.getProperty("isValid")).toStrictEqual(true); + await expect(await link.getProperty("valid")).toStrictEqual(true); await expect(await link.getProperty("toJson")).toEqual({ name: "foo", href: "https://foo.com", @@ -64,6 +64,6 @@ describe("ak-admin-settings-footer-link", () => { name: "foo", href: "never://foo.com", }); - await expect(await link.getProperty("isValid")).toStrictEqual(false); + await expect(await link.getProperty("valid")).toStrictEqual(false); }); }); diff --git a/web/src/admin/outposts/ServiceConnectionWizard.ts b/web/src/admin/outposts/ServiceConnectionWizard.ts index 84de565f1b..f2814cabaf 100644 --- a/web/src/admin/outposts/ServiceConnectionWizard.ts +++ b/web/src/admin/outposts/ServiceConnectionWizard.ts @@ -55,7 +55,7 @@ export class ServiceConnectionWizard extends AKElement { "initial", `type-${ev.detail.component}-${ev.detail.modelName}`, ]; - this.wizard.isValid = true; + this.wizard.valid = true; }} > diff --git a/web/src/admin/policies/PolicyWizard.ts b/web/src/admin/policies/PolicyWizard.ts index bb15315eb9..6d6122a5fe 100644 --- a/web/src/admin/policies/PolicyWizard.ts +++ b/web/src/admin/policies/PolicyWizard.ts @@ -66,7 +66,7 @@ export class PolicyWizard extends AKElement { this.wizard.steps.splice(idx, 0, `type-${component}-${modelName}`); - this.wizard.isValid = true; + this.wizard.valid = true; }; render(): TemplateResult { diff --git a/web/src/admin/property-mappings/PropertyMappingWizard.ts b/web/src/admin/property-mappings/PropertyMappingWizard.ts index 04f3d8dafa..a54e14c2fa 100644 --- a/web/src/admin/property-mappings/PropertyMappingWizard.ts +++ b/web/src/admin/property-mappings/PropertyMappingWizard.ts @@ -65,7 +65,7 @@ export class PropertyMappingWizard extends AKElement { "initial", `type-${ev.detail.component}-${ev.detail.modelName}`, ]; - this.wizard.isValid = true; + this.wizard.valid = true; }} > diff --git a/web/src/admin/providers/ProviderWizard.ts b/web/src/admin/providers/ProviderWizard.ts index 8542394a12..4857faa60c 100644 --- a/web/src/admin/providers/ProviderWizard.ts +++ b/web/src/admin/providers/ProviderWizard.ts @@ -68,7 +68,7 @@ export class ProviderWizard extends AKElement { @select=${(ev: CustomEvent) => { if (!this.wizard) return; this.wizard.steps = ["initial", `type-${ev.detail.component}`]; - this.wizard.isValid = true; + this.wizard.valid = true; }} > diff --git a/web/src/admin/providers/oauth2/OAuth2ProviderRedirectURI.ts b/web/src/admin/providers/oauth2/OAuth2ProviderRedirectURI.ts index db1b59d465..bda44e1c6a 100644 --- a/web/src/admin/providers/oauth2/OAuth2ProviderRedirectURI.ts +++ b/web/src/admin/providers/oauth2/OAuth2ProviderRedirectURI.ts @@ -48,7 +48,7 @@ export class OAuth2ProviderRedirectURI extends AkControlElement { ) as unknown as RedirectURI; } - get isValid() { + get valid() { return true; } diff --git a/web/src/admin/sources/SourceWizard.ts b/web/src/admin/sources/SourceWizard.ts index f7c206d92e..959c082d70 100644 --- a/web/src/admin/sources/SourceWizard.ts +++ b/web/src/admin/sources/SourceWizard.ts @@ -57,7 +57,7 @@ export class SourceWizard extends AKElement { "initial", `type-${ev.detail.component}-${ev.detail.modelName}`, ]; - this.wizard.isValid = true; + this.wizard.valid = true; }} > diff --git a/web/src/admin/stages/StageWizard.ts b/web/src/admin/stages/StageWizard.ts index 27e17024cb..916c520cd3 100644 --- a/web/src/admin/stages/StageWizard.ts +++ b/web/src/admin/stages/StageWizard.ts @@ -93,7 +93,7 @@ export class StageWizard extends AKElement { 0, `type-${ev.detail.component}-${ev.detail.modelName}`, ); - this.wizard.isValid = true; + this.wizard.valid = true; }} > diff --git a/web/src/elements/AkControlElement.ts b/web/src/elements/AkControlElement.ts index 424ada4822..ad4cf5e7db 100644 --- a/web/src/elements/AkControlElement.ts +++ b/web/src/elements/AkControlElement.ts @@ -22,7 +22,7 @@ export class AkControlElement extends AKElement { return this.json(); } - get isValid(): boolean { + get valid(): boolean { return true; } } diff --git a/web/src/elements/ak-array-input.ts b/web/src/elements/ak-array-input.ts index 5b5c12c634..548262e2c3 100644 --- a/web/src/elements/ak-array-input.ts +++ b/web/src/elements/ak-array-input.ts @@ -96,15 +96,16 @@ export class ArrayInput extends AkControlElement implements IArrayInput< return this.items; } - get isValid() { + get valid() { if (!this.validate) { return true; } - const oneIsValid = (g: HTMLDivElement) => - g.querySelector>("[name]")?.isValid ?? true; - const allAreValid = Array.from(this.inputGroups ?? []).every(oneIsValid); - return allAreValid && (this.validator ? this.validator(this.items) : true); + const valid = Array.from(this.inputGroups || []).every((inputGroup) => { + return inputGroup.querySelector("[name]")?.valid ?? true; + }); + + return valid && (this.validator?.(this.items) ?? true); } itemsFromDom(): T[] { diff --git a/web/src/elements/stories/ak-array-input.stories.ts b/web/src/elements/stories/ak-array-input.stories.ts index 0fb95d98ad..1ffe6ebabc 100644 --- a/web/src/elements/stories/ak-array-input.stories.ts +++ b/web/src/elements/stories/ak-array-input.stories.ts @@ -40,7 +40,7 @@ const metadata: Meta> = { return; } const target = event.target as FooterLinkInput; - messages!.innerText = `${JSON.stringify(target.json(), null, 2)}\n\nValid: ${target.isValid ? "Yes" : "No"}`; + messages!.innerText = `${JSON.stringify(target.json(), null, 2)}\n\nValid: ${target.valid ? "Yes" : "No"}`; }); }, 250); diff --git a/web/src/elements/tests/ak-array-input.test.ts b/web/src/elements/tests/ak-array-input.test.ts index 325dfc0643..f334fe114c 100644 --- a/web/src/elements/tests/ak-array-input.test.ts +++ b/web/src/elements/tests/ak-array-input.test.ts @@ -42,7 +42,7 @@ describe("ak-array-input", () => { await component(); const link = await $("ak-array-input"); await browser.pause(500); - await expect(await link.getProperty("isValid")).toStrictEqual(true); + await expect(await link.getProperty("valid")).toStrictEqual(true); await expect(await link.getProperty("toJson")).toEqual([]); }); @@ -50,7 +50,7 @@ describe("ak-array-input", () => { await component(sampleItems); const link = await $("ak-array-input"); await browser.pause(500); - await expect(await link.getProperty("isValid")).toStrictEqual(true); + await expect(await link.getProperty("valid")).toStrictEqual(true); await expect(await link.getProperty("toJson")).toEqual(sampleItems); }); }); diff --git a/web/src/elements/utils/inputs.ts b/web/src/elements/utils/inputs.ts index 991a1195c1..576fd7f365 100644 --- a/web/src/elements/utils/inputs.ts +++ b/web/src/elements/utils/inputs.ts @@ -15,6 +15,12 @@ export function isNamedElement(element: Element): element is NamedElement { return "name" in element.attributes; } +declare global { + interface HTMLElementTagNameMap { + "[name]": NamedElement; + } +} + /** * Create a map of files provided by input elements within the given iterable. */ diff --git a/web/src/elements/wizard/ActionWizardPage.ts b/web/src/elements/wizard/ActionWizardPage.ts index 79904ea3b0..0de2f25cf4 100644 --- a/web/src/elements/wizard/ActionWizardPage.ts +++ b/web/src/elements/wizard/ActionWizardPage.ts @@ -55,7 +55,7 @@ export class ActionWizardPage extends WizardPage { await this.run(); // Ensure wizard is closable, even when run() failed - this.host.isValid = true; + this.host.valid = true; }; sidebarLabel = () => msg("Apply changes"); @@ -91,7 +91,7 @@ export class ActionWizardPage extends WizardPage { } } - this.host.isValid = true; + this.host.valid = true; this.dispatchEvent( new CustomEvent(EVENT_REFRESH, { diff --git a/web/src/elements/wizard/FormWizardPage.ts b/web/src/elements/wizard/FormWizardPage.ts index eb9636ef07..189a7fd442 100644 --- a/web/src/elements/wizard/FormWizardPage.ts +++ b/web/src/elements/wizard/FormWizardPage.ts @@ -15,7 +15,7 @@ export class FormWizardPage extends WizardPage { }; activeCallback = async () => { - this.host.isValid = true; + this.host.valid = true; this.activePageCallback(this); }; diff --git a/web/src/elements/wizard/TypeCreateWizardPage.ts b/web/src/elements/wizard/TypeCreateWizardPage.ts index 53b574360c..6b79bcb433 100644 --- a/web/src/elements/wizard/TypeCreateWizardPage.ts +++ b/web/src/elements/wizard/TypeCreateWizardPage.ts @@ -70,7 +70,7 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) { activeCallback = (): void => { const form = this.formRef.value; - this.host.isValid = form?.checkValidity() ?? false; + this.host.valid = form?.checkValidity() ?? false; if (this.selectedType) { this.selectDispatch(this.selectedType); diff --git a/web/src/elements/wizard/Wizard.ts b/web/src/elements/wizard/Wizard.ts index 6565bd282e..0364ec68ea 100644 --- a/web/src/elements/wizard/Wizard.ts +++ b/web/src/elements/wizard/Wizard.ts @@ -64,7 +64,7 @@ export class Wizard extends ModalButton { * Whether the wizard is valid and can proceed to the next step. */ @property({ type: Boolean }) - isValid = false; + valid = false; /** * Actions to display at the end of the wizard. @@ -328,7 +328,7 @@ export class Wizard extends ModalButton {