use ui-shared (#27908)

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2024-03-22 16:56:17 +01:00 committed by GitHub
parent 4fb2f73b2c
commit e9a1a6b982
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 96 additions and 275 deletions

View file

@ -320,7 +320,7 @@ describe("Clients test", () => {
createClientPage
.fillClientData("")
.selectClientType("openid-connect")
.selectClientType("OpenID Connect")
.cancel();
cy.url().should("not.include", "/add-client");
@ -360,7 +360,7 @@ describe("Clients test", () => {
createClientPage
.fillClientData("test_client")
.selectClientType("openid-connect")
.selectClientType("OpenID Connect")
.continue()
.back()
.checkGeneralSettingsStepActive();
@ -373,7 +373,7 @@ describe("Clients test", () => {
createClientPage
.fillClientData("")
.selectClientType("openid-connect")
.selectClientType("OpenID Connect")
.continue()
.checkClientIdRequiredMessage();
@ -398,7 +398,7 @@ describe("Clients test", () => {
commonPage.tableToolbarUtils().clickPrimaryButton();
createClientPage
.selectClientType("openid-connect")
.selectClientType("OpenID Connect")
.fillClientData(itemId)
.continue()
.switchClientAuthentication()
@ -765,7 +765,7 @@ describe("Clients test", () => {
client = "client_" + uuid();
commonPage.tableToolbarUtils().createClient();
createClientPage
.selectClientType("openid-connect")
.selectClientType("OpenID Connect")
.fillClientData(client)
.continue();

View file

@ -127,7 +127,7 @@ describe("User Fed LDAP mapper tests", () => {
sidebarPage.goToClients();
listingPage.goToCreateItem();
createClientPage
.selectClientType("openid-connect")
.selectClientType("OpenID Connect")
.fillClientData(clientName)
.continue()
.continue()

View file

@ -1,8 +1,8 @@
import Select from "../../../../forms/Select";
import CommonPage from "../../../CommonPage";
export default class CreateClientPage extends CommonPage {
#clientTypeDrpDwn = ".pf-c-select__toggle";
#clientTypeList = ".pf-c-select__toggle + ul";
#clientTypeDrpDwn = "#protocol";
#clientIdInput = "#clientId";
#clientIdError = "#clientId + div";
#clientNameInput = "#name";
@ -31,13 +31,15 @@ export default class CreateClientPage extends CommonPage {
#firstWebOriginsInput = "webOrigins0";
#adminUrlInput = "adminUrl";
#loginThemeDrpDwn = "#loginTheme";
#loginThemeList = 'ul[aria-label="Login theme"]';
#consentRequiredSwitch = '[for="kc-consent-switch"] > .pf-c-switch__toggle';
#consentRequiredSwitchInput = "#kc-consent-switch";
#displayClientOnScreenSwitch = '[for="kc-display-on-client-switch"]';
#displayClientOnScreenSwitchInput = "#kc-display-on-client-switch";
#clientConsentScreenText = "#kc-consent-screen-text";
#loginThemeDrpDwn = "#login_theme";
#loginThemeList = 'ul[class="pf-c-select__menu"]';
#consentRequiredSwitch = '[for="consentRequired"] .pf-c-switch__toggle';
#consentRequiredSwitchInput = "#consentRequired";
#displayClientOnScreenSwitch =
'[for="attributes.display🍺on🍺consent🍺screen"].pf-c-switch';
#displayClientOnScreenSwitchInput =
"#attributes\\.display🍺on🍺consent🍺screen";
#clientConsentScreenText = "attributes.consent🍺screen🍺text";
#frontChannelLogoutSwitch =
'[for="kc-frontchannelLogout-switch"] > .pf-c-switch__toggle';
@ -60,8 +62,7 @@ export default class CreateClientPage extends CommonPage {
//#region General Settings
selectClientType(clientType: string) {
cy.get(this.#clientTypeDrpDwn).click();
cy.get(this.#clientTypeList).findByTestId(`option-${clientType}`).click();
Select.selectItem(cy.get(this.#clientTypeDrpDwn), clientType);
return this;
}
@ -238,11 +239,11 @@ export default class CreateClientPage extends CommonPage {
}
checkLoginSettingsElements() {
cy.get(this.#clientConsentScreenText).scrollIntoView();
cy.findByTestId(this.#clientConsentScreenText).scrollIntoView();
cy.get(this.#loginThemeDrpDwn).should("not.be.disabled");
cy.get(this.#consentRequiredSwitchInput).should("not.be.disabled");
cy.get(this.#displayClientOnScreenSwitchInput).should("be.disabled");
cy.get(this.#clientConsentScreenText).should("be.disabled");
cy.findByTestId(this.#clientConsentScreenText).should("be.disabled");
cy.get(this.#loginThemeDrpDwn).click();
cy.get(this.#loginThemeList).findByText("base").should("exist");
@ -251,13 +252,13 @@ export default class CreateClientPage extends CommonPage {
cy.get(this.#consentRequiredSwitch).click();
cy.get(this.#displayClientOnScreenSwitchInput).should("not.be.disabled");
cy.get(this.#clientConsentScreenText).should("be.disabled");
cy.findByTestId(this.#clientConsentScreenText).should("be.disabled");
cy.get(this.#displayClientOnScreenSwitch).click();
cy.get(this.#clientConsentScreenText).should("not.be.disabled");
cy.findByTestId(this.#clientConsentScreenText).should("not.be.disabled");
cy.get(this.#displayClientOnScreenSwitch).click();
cy.get(this.#clientConsentScreenText).should("be.disabled");
cy.findByTestId(this.#clientConsentScreenText).should("be.disabled");
cy.get(this.#consentRequiredSwitch).click();
cy.get(this.#displayClientOnScreenSwitchInput).should("be.disabled");

View file

@ -26,10 +26,10 @@ export default class SettingsTab extends PageObject {
"#saml🍺server🍺signature🍺keyinfo🍺xmlSigKeyInfoKeyNameTransformer";
#canonicalization = "#saml_signature_canonicalization_method";
#loginTheme = "#loginTheme";
#consentSwitch = "#kc-consent-switch";
#displayClientSwitch = "#kc-display-on-client-switch";
#consentScreenText = "#kc-consent-screen-text";
#loginTheme = "#login_theme";
#consentSwitch = "#consentRequired";
#displayClientSwitch = "attributes.display🍺on🍺consent🍺screen";
#consentScreenText = "attributes.consent🍺screen🍺text";
#saveBtn = "settings-save";
#revertBtn = "settingsRevert";
@ -124,7 +124,7 @@ export default class SettingsTab extends PageObject {
}
public clickDisplayClientSwitch() {
cy.get(this.#displayClientSwitch).parent().click();
cy.findByTestId(this.#displayClientSwitch).parent().click();
return this;
}
@ -202,13 +202,14 @@ export default class SettingsTab extends PageObject {
}
public assertLoginSettings() {
cy.get(this.#displayClientSwitch).should("be.disabled");
cy.get(this.#consentScreenText).should("be.disabled");
cy.findByTestId(this.#displayClientSwitch).should("be.disabled");
cy.findByTestId(this.#consentScreenText).should("be.disabled");
this.clickConsentSwitch();
cy.get(this.#displayClientSwitch).should("not.be.disabled");
cy.findByTestId(this.#displayClientSwitch).should("not.be.disabled");
this.clickDisplayClientSwitch();
cy.get(this.#consentScreenText).should("not.be.disabled");
cy.get(this.#consentScreenText).click().type("Consent Screen Text");
cy.findByTestId(this.#consentScreenText).should("not.be.disabled");
cy.findByTestId(this.#consentScreenText).click();
cy.findByTestId(this.#consentScreenText).type("Consent Screen Text");
return this;
}

View file

@ -1,3 +1,4 @@
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import {
Checkbox,
FormGroup,
@ -8,13 +9,12 @@ import {
} from "@patternfly/react-core";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { FormAccess } from "../../components/form/FormAccess";
import { convertAttributeNameToForm } from "../../util";
import { FormFields } from "../ClientDetails";
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
import { FormFields } from "../ClientDetails";
type CapabilityConfigProps = {
unWrap?: boolean;
@ -276,66 +276,20 @@ export const CapabilityConfig = ({
)}
{protocol === "saml" && (
<>
<FormGroup
labelIcon={
<HelpItem
helpText={t("encryptAssertionsHelp")}
fieldLabelId="encryptAssertions"
/>
}
<DefaultSwitchControl
name={convertAttributeNameToForm<FormFields>(
"attributes.saml.encrypt",
)}
label={t("encryptAssertions")}
fieldId="kc-encrypt"
hasNoPaddingTop
>
<Controller
name={convertAttributeNameToForm<FormFields>(
"attributes.saml.encrypt",
)}
control={control}
defaultValue={false}
render={({ field }) => (
<Switch
data-testid="encrypt"
id="kc-encrypt"
label={t("on")}
labelOff={t("off")}
isChecked={field.value}
onChange={field.onChange}
aria-label={t("encryptAssertions")}
/>
)}
/>
</FormGroup>
<FormGroup
labelIcon={
<HelpItem
helpText={t("clientSignatureHelp")}
fieldLabelId="clientSignature"
/>
}
labelIcon={t("encryptAssertionsHelp")}
/>
<DefaultSwitchControl
name={convertAttributeNameToForm<FormFields>(
"attributes.saml.client.signature",
)}
label={t("clientSignature")}
fieldId="kc-client-signature"
hasNoPaddingTop
>
<Controller
name={convertAttributeNameToForm<FormFields>(
"attributes.saml.client.signature",
)}
control={control}
defaultValue={false}
render={({ field }) => (
<Switch
data-testid="client-signature"
id="kc-client-signature"
label={t("on")}
labelOff={t("off")}
isChecked={field.value}
onChange={field.onChange}
aria-label={t("clientSignature")}
/>
)}
/>
</FormGroup>
labelIcon={t("clientSignatureHelp")}
/>
</>
)}
</FormAccess>

View file

@ -1,70 +1,28 @@
import {
FormGroup,
Select,
SelectOption,
SelectVariant,
} from "@patternfly/react-core";
import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { SelectControl } from "ui-shared";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { useLoginProviders } from "../../context/server-info/ServerInfoProvider";
import { ClientDescription } from "../ClientDescription";
import { getProtocolName } from "../utils";
export const GeneralSettings = () => {
const { t } = useTranslation();
const {
control,
formState: { errors },
} = useFormContext();
const providers = useLoginProviders();
const [open, isOpen] = useState(false);
return (
<FormAccess isHorizontal role="manage-clients">
<FormGroup
<SelectControl
name="protocol"
label={t("clientType")}
fieldId="kc-type"
validated={errors.protocol ? "error" : "default"}
labelIcon={
<HelpItem helpText={t("clientTypeHelp")} fieldLabelId="clientType" />
}
>
<Controller
name="protocol"
defaultValue=""
control={control}
render={({ field }) => (
<Select
id="kc-type"
onToggle={isOpen}
onSelect={(_, value) => {
field.onChange(value.toString());
isOpen(false);
}}
selections={field.value}
variant={SelectVariant.single}
aria-label={t("selectEncryptionType")}
isOpen={open}
>
{providers.map((option) => (
<SelectOption
selected={option === field.value}
key={option}
value={option}
data-testid={`option-${option}`}
>
{getProtocolName(t, option)}
</SelectOption>
))}
</Select>
)}
/>
</FormGroup>
labelIcon={t("clientTypeHelp")}
controller={{
defaultValue: "",
}}
options={providers.map((option) => ({
key: option,
value: getProtocolName(t, option),
}))}
/>
<ClientDescription hasConfigureAccess />
</FormAccess>
);

View file

@ -1,26 +1,16 @@
import {
FormGroup,
Select,
SelectOption,
SelectVariant,
Switch,
} from "@patternfly/react-core";
import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { SelectControl, TextAreaControl } from "ui-shared";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { KeycloakTextArea } from "../../components/keycloak-text-area/KeycloakTextArea";
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
import { convertAttributeNameToForm } from "../../util";
import { FormFields } from "../ClientDetails";
export const LoginSettingsPanel = ({ access }: { access?: boolean }) => {
const { t } = useTranslation();
const { register, control, watch } = useFormContext<FormFields>();
const { watch } = useFormContext<FormFields>();
const [loginThemeOpen, setLoginThemeOpen] = useState(false);
const loginThemes = useServerInfo().themes!["login"];
const consentRequired = watch("consentRequired");
const displayOnConsentScreen: string = watch(
@ -31,123 +21,40 @@ export const LoginSettingsPanel = ({ access }: { access?: boolean }) => {
return (
<FormAccess isHorizontal fineGrainedAccess={access} role="manage-clients">
<FormGroup
<SelectControl
name="attributes.login_theme"
label={t("loginTheme")}
labelIcon={
<HelpItem helpText={t("loginThemeHelp")} fieldLabelId="loginTheme" />
}
fieldId="loginTheme"
>
<Controller
name="attributes.login_theme"
defaultValue=""
control={control}
render={({ field }) => (
<Select
toggleId="loginTheme"
onToggle={setLoginThemeOpen}
onSelect={(_, value) => {
field.onChange(value.toString());
setLoginThemeOpen(false);
}}
selections={field.value || t("choose")}
variant={SelectVariant.single}
aria-label={t("loginTheme")}
isOpen={loginThemeOpen}
>
{[
<SelectOption key="empty" value="">
{t("choose")}
</SelectOption>,
...loginThemes.map((theme) => (
<SelectOption
selected={theme.name === field.value}
key={theme.name}
value={theme.name}
/>
)),
]}
</Select>
)}
/>
</FormGroup>
<FormGroup
labelIcon={t("loginThemeHelp")}
controller={{
defaultValue: "",
}}
options={[
{ key: "", value: t("choose") },
...loginThemes.map(({ name }) => ({ key: name, value: name })),
]}
/>
<DefaultSwitchControl
name="consentRequired"
label={t("consentRequired")}
labelIcon={
<HelpItem
helpText={t("consentRequiredHelp")}
fieldLabelId="consentRequired"
/>
}
fieldId="kc-consent"
hasNoPaddingTop
>
<Controller
name="consentRequired"
defaultValue={false}
control={control}
render={({ field }) => (
<Switch
id="kc-consent-switch"
label={t("on")}
labelOff={t("off")}
isChecked={field.value}
onChange={field.onChange}
aria-label={t("consentRequired")}
/>
)}
/>
</FormGroup>
<FormGroup
labelIcon={t("consentRequiredHelp")}
/>
<DefaultSwitchControl
name={convertAttributeNameToForm<FormFields>(
"attributes.display.on.consent.screen",
)}
label={t("displayOnClient")}
labelIcon={
<HelpItem
helpText={t("displayOnClientHelp")}
fieldLabelId="displayOnClient"
/>
}
fieldId="kc-display-on-client"
hasNoPaddingTop
>
<Controller
name={convertAttributeNameToForm<FormFields>(
"attributes.display.on.consent.screen",
)}
defaultValue={false}
control={control}
render={({ field }) => (
<Switch
id="kc-display-on-client-switch"
label={t("on")}
labelOff={t("off")}
isChecked={field.value === "true"}
onChange={(value) => field.onChange("" + value)}
isDisabled={!consentRequired}
aria-label={t("displayOnClient")}
/>
)}
/>
</FormGroup>
<FormGroup
labelIcon={t("displayOnClientHelp")}
isDisabled={!consentRequired}
stringify
/>
<TextAreaControl
name={convertAttributeNameToForm<FormFields>(
"attributes.consent.screen.text",
)}
label={t("consentScreenText")}
labelIcon={
<HelpItem
helpText={t("consentScreenTextHelp")}
fieldLabelId="consentScreenText"
/>
}
fieldId="kc-consent-screen-text"
>
<KeycloakTextArea
id="kc-consent-screen-text"
{...register(
convertAttributeNameToForm<FormFields>(
"attributes.consent.screen.text",
),
)}
isDisabled={!(consentRequired && displayOnConsentScreen === "true")}
/>
</FormGroup>
labelIcon={t("consentScreenTextHelp")}
isDisabled={!(consentRequired && displayOnConsentScreen === "true")}
/>
</FormAccess>
);
};