web: Converted our toggle groups to a more streamlined implementation.

This commit is contained in:
Ken Sternberg 2023-08-03 13:39:58 -07:00
parent 7808b7b48a
commit 8042d9f276
4 changed files with 115 additions and 125 deletions

View File

@ -72,8 +72,6 @@ const metadata: Meta<AkApplicationWizardApplicationDetails> = {
status: 200, status: 200,
response: dummyHasJwks, response: dummyHasJwks,
}, },
], ],
}, },
}; };
@ -134,7 +132,6 @@ export const PageThreeLdap = () => {
); );
}; };
export const PageThreeOauth2 = () => { export const PageThreeOauth2 = () => {
return container( return container(
html`<ak-application-wizard-context> html`<ak-application-wizard-context>

View File

@ -112,55 +112,22 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
} }
renderModeSelector(): TemplateResult { renderModeSelector(): TemplateResult {
return html` <div class="pf-c-toggle-group__item"> return html` <ak-toggle-group
<button value=${this.policyGroupUser}
class="pf-c-toggle-group__button ${this.policyGroupUser === target.policy @ak-toggle=${(ev: CustomEvent<{ value: target }>) => {
? "pf-m-selected" this.policyGroupUser = ev.detail.value;
: ""}" }}
type="button" >
@click=${() => { <option value=${target.policy}>${msg("Policy")}</option>
this.policyGroupUser = target.policy; <option value=${target.group}>${msg("Group")}</option>
}} <option value=${target.user}>${msg("User")}</option>
> </ak-toggle-group>`;
<span class="pf-c-toggle-group__text">${msg("Policy")}</span>
</button>
</div>
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
<div class="pf-c-toggle-group__item">
<button
class="pf-c-toggle-group__button ${this.policyGroupUser === target.group
? "pf-m-selected"
: ""}"
type="button"
@click=${() => {
this.policyGroupUser = target.group;
}}
>
<span class="pf-c-toggle-group__text">${msg("Group")}</span>
</button>
</div>
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
<div class="pf-c-toggle-group__item">
<button
class="pf-c-toggle-group__button ${this.policyGroupUser === target.user
? "pf-m-selected"
: ""}"
type="button"
@click=${() => {
this.policyGroupUser = target.user;
}}
>
<span class="pf-c-toggle-group__text">${msg("User")}</span>
</button>
</div>`;
} }
renderForm(): TemplateResult { renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal"> return html`<form class="pf-c-form pf-m-horizontal">
<div class="pf-c-card pf-m-selectable pf-m-selected"> <div class="pf-c-card pf-m-selectable pf-m-selected">
<div class="pf-c-card__body"> <div class="pf-c-card__body">${this.renderModeSelector()}</div>
<div class="pf-c-toggle-group">${this.renderModeSelector()}</div>
</div>
<div class="pf-c-card__footer"> <div class="pf-c-card__footer">
<ak-form-element-horizontal <ak-form-element-horizontal
label=${msg("Policy")} label=${msg("Policy")}

View File

@ -1,6 +1,7 @@
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search"; import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-toggle-group";
import "@goauthentik/elements/forms/FormGroup"; import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm"; import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
@ -8,8 +9,7 @@ import "@goauthentik/elements/forms/SearchSelect";
import "@goauthentik/elements/utils/TimeDeltaHelp"; import "@goauthentik/elements/utils/TimeDeltaHelp";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, css } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { TemplateResult, html } from "lit";
import { customElement, state } from "lit/decorators.js"; import { customElement, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
@ -104,84 +104,25 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
} }
renderHttpBasic(): TemplateResult { renderHttpBasic(): TemplateResult {
return html`<ak-form-element-horizontal return html`<ak-text-input
label=${msg("HTTP-Basic Username Key")}
name="basicAuthUserAttribute" name="basicAuthUserAttribute"
label=${msg("HTTP-Basic Username Key")}
value="${ifDefined(this.instance?.basicAuthUserAttribute)}"
help=${msg(
"User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used.",
)}
> >
<input </ak-text-input>
type="text"
value="${ifDefined(this.instance?.basicAuthUserAttribute)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${msg(
"User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used.",
)}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("HTTP-Basic Password Key")}
name="basicAuthPasswordAttribute"
>
<input
type="text"
value="${ifDefined(this.instance?.basicAuthPasswordAttribute)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${msg(
"User/Group Attribute used for the password part of the HTTP-Basic Header.",
)}
</p>
</ak-form-element-horizontal>`;
}
renderModeSelector(): TemplateResult { <ak-text-input
return html` <div class="pf-c-toggle-group__item"> name="basicAuthPasswordAttribute"
<button label=${msg("HTTP-Basic Password Key")}
class="pf-c-toggle-group__button ${this.mode === ProxyMode.Proxy value="${ifDefined(this.instance?.basicAuthPasswordAttribute)}"
? "pf-m-selected" help=${msg(
: ""}" "User/Group Attribute used for the password part of the HTTP-Basic Header.",
type="button" )}
@click=${() => { >
this.mode = ProxyMode.Proxy; </ak-text-input>`;
}}
>
<span class="pf-c-toggle-group__text">${msg("Proxy")}</span>
</button>
</div>
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
<div class="pf-c-toggle-group__item">
<button
class="pf-c-toggle-group__button ${this.mode === ProxyMode.ForwardSingle
? "pf-m-selected"
: ""}"
type="button"
@click=${() => {
this.mode = ProxyMode.ForwardSingle;
}}
>
<span class="pf-c-toggle-group__text"
>${msg("Forward auth (single application)")}</span
>
</button>
</div>
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
<div class="pf-c-toggle-group__item">
<button
class="pf-c-toggle-group__button ${this.mode === ProxyMode.ForwardDomain
? "pf-m-selected"
: ""}"
type="button"
@click=${() => {
this.mode = ProxyMode.ForwardDomain;
}}
>
<span class="pf-c-toggle-group__text"
>${msg("Forward auth (domain level)")}</span
>
</button>
</div>`;
} }
renderSettings(): TemplateResult { renderSettings(): TemplateResult {
@ -363,7 +304,20 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
<div class="pf-c-card pf-m-selectable pf-m-selected"> <div class="pf-c-card pf-m-selectable pf-m-selected">
<div class="pf-c-card__body"> <div class="pf-c-card__body">
<div class="pf-c-toggle-group">${this.renderModeSelector()}</div> <ak-toggle-group
value=${this.mode}
@ak-toggle=${(ev: CustomEvent<{ value: ProxyMode }>) => {
this.mode = ev.detail.value;
}}
>
<option value=${ProxyMode.Proxy}>${msg("Proxy")}</option>
<option value=${ProxyMode.ForwardSingle}>
${msg("Forward auth (single application)")}
</option>
<option value=${ProxyMode.ForwardDomain}>
${msg("Forward auth (domain level)")}
</option>
</ak-toggle-group>
</div> </div>
<div class="pf-c-card__footer">${this.renderSettings()}</div> <div class="pf-c-card__footer">${this.renderSettings()}</div>
</div> </div>

View File

@ -0,0 +1,72 @@
import { AKElement } from "@goauthentik/elements/Base";
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";
type Pair = [string, string];
@customElement("ak-toggle-group")
export class AkToggleGroup extends CustomEmitterElement(AKElement) {
static get styles() {
return [
PFToggleGroup,
css`
.pf-c-toggle-group {
justify-content: center;
}
`,
];
}
@property({ type: String, reflect: true })
value = "";
get rawOptions(): HTMLOptionElement[] {
return Array.from(this.querySelectorAll("option") ?? []);
}
get options(): Pair[] {
return Array.from(this.rawOptions).map(
(option: HTMLOptionElement): Pair => [
option.getAttribute("value") ?? "",
option.textContent ?? "",
],
);
}
render() {
const last = this.options.length - 1;
const mkClass = (v: string) => ({
"pf-c-toggle-group__button": true,
"pf-m-selected": this.value === v,
});
const mkClick = (v: string) => () => {
this.dispatchCustomEvent("ak-toggle", { value: v });
};
return html` <div class="pf-c-toggle-group">
${this.options.map(
([key, label], idx) =>
html`<div class="pf-c-toggle-group__item">
<button
class="${classMap(mkClass(key))}"
type="button"
@click=${mkClick(key)}
>
<span class="pf-c-toggle-group__text">${label}</span>
</button>
</div>
${idx < last
? html`<div class="pf-c-divider pf-m-vertical" role="separator"></div>`
: nothing} `,
)}
</div>`;
}
}
export default AkToggleGroup;