Port role form to new form controls (#27626)

Signed-off-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
Jon Koops 2024-03-07 15:08:36 +01:00 committed by GitHub
parent ea4155bbcd
commit 0adc842ac7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 129 additions and 155 deletions

View file

@ -94,7 +94,7 @@ export default class ProviderPage {
#rolesTab = "rolesTab"; #rolesTab = "rolesTab";
#createRoleBtn = "no-roles-for-this-client-empty-action"; #createRoleBtn = "no-roles-for-this-client-empty-action";
#roleSaveBtn = "save"; #roleSaveBtn = "save";
#roleNameField = "#kc-name"; #roleNameField = "name";
#groupName = "aa-uf-mappers-group"; #groupName = "aa-uf-mappers-group";
#clientName = "aa-uf-mappers-client"; #clientName = "aa-uf-mappers-client";
@ -310,7 +310,7 @@ export default class ProviderPage {
cy.wait(1000); cy.wait(1000);
cy.findByTestId(this.#createRoleBtn).click(); cy.findByTestId(this.#createRoleBtn).click();
cy.wait(1000); cy.wait(1000);
cy.get(this.#roleNameField).clear().type(roleName); cy.findByTestId(this.#roleNameField).clear().type(roleName);
cy.wait(1000); cy.wait(1000);
cy.findByTestId(this.#roleSaveBtn).click(); cy.findByTestId(this.#roleSaveBtn).click();
cy.wait(1000); cy.wait(1000);

View file

@ -1,16 +1,16 @@
class CreateRealmRolePage { class CreateRealmRolePage {
#realmRoleNameInput = "#kc-name"; #realmRoleNameInput = "name";
#realmRoleNameError = "#kc-name-helper"; #realmRoleNameError = "#name-helper";
#realmRoleDescriptionInput = "#kc-description"; #realmRoleDescriptionInput = "description";
#saveBtn = "save"; #saveBtn = "save";
#cancelBtn = "cancel"; #cancelBtn = "cancel";
//#region General Settings //#region General Settings
fillRealmRoleData(name: string, description = "") { fillRealmRoleData(name: string, description = "") {
cy.get(this.#realmRoleNameInput).clear(); cy.findByTestId(this.#realmRoleNameInput).clear();
if (name) { if (name) {
cy.get(this.#realmRoleNameInput).type(name); cy.findByTestId(this.#realmRoleNameInput).type(name);
} }
if (description !== "") { if (description !== "") {
@ -36,7 +36,7 @@ class CreateRealmRolePage {
} }
checkNameDisabled() { checkNameDisabled() {
cy.get(this.#realmRoleNameInput).should( cy.findByTestId(this.#realmRoleNameInput).should(
"have.attr", "have.attr",
"readonly", "readonly",
"readonly", "readonly",
@ -45,13 +45,16 @@ class CreateRealmRolePage {
} }
checkDescription(description: string) { checkDescription(description: string) {
cy.get(this.#realmRoleDescriptionInput).should("have.value", description); cy.findByTestId(this.#realmRoleDescriptionInput).should(
"have.value",
description,
);
return this; return this;
} }
updateDescription(description: string) { updateDescription(description: string) {
cy.get(this.#realmRoleDescriptionInput).clear(); cy.findByTestId(this.#realmRoleDescriptionInput).clear();
cy.get(this.#realmRoleDescriptionInput).type(description); cy.findByTestId(this.#realmRoleDescriptionInput).type(description);
return this; return this;
} }

View file

@ -1,6 +1,6 @@
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation"; import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
import { AlertVariant } from "@patternfly/react-core"; import { AlertVariant } from "@patternfly/react-core";
import { SubmitHandler, useForm } from "react-hook-form"; import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
@ -54,8 +54,8 @@ export default function CreateClientRole() {
}; };
return ( return (
<FormProvider {...form}>
<RoleForm <RoleForm
form={form}
onSubmit={onSubmit} onSubmit={onSubmit}
cancelLink={toClient({ cancelLink={toClient({
realm, realm,
@ -65,5 +65,6 @@ export default function CreateClientRole() {
role="manage-clients" role="manage-clients"
editMode={false} editMode={false}
/> />
</FormProvider>
); );
} }

View file

@ -1,22 +1,14 @@
import { import { ActionGroup, Button, PageSection } from "@patternfly/react-core";
ActionGroup, import { SubmitHandler, useFormContext, useWatch } from "react-hook-form";
Button,
FormGroup,
PageSection,
ValidatedOptions,
} from "@patternfly/react-core";
import { SubmitHandler, UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Link, To } from "react-router-dom"; import { Link, To } from "react-router-dom";
import { TextAreaControl, TextControl } from "ui-shared";
import { FormAccess } from "../form/FormAccess"; import { FormAccess } from "../form/FormAccess";
import { AttributeForm } from "../key-value-form/AttributeForm"; import { AttributeForm } from "../key-value-form/AttributeForm";
import { KeycloakTextArea } from "../keycloak-text-area/KeycloakTextArea";
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
import { ViewHeader } from "../view-header/ViewHeader"; import { ViewHeader } from "../view-header/ViewHeader";
export type RoleFormProps = { export type RoleFormProps = {
form: UseFormReturn<AttributeForm>;
onSubmit: SubmitHandler<AttributeForm>; onSubmit: SubmitHandler<AttributeForm>;
cancelLink: To; cancelLink: To;
role: "manage-realm" | "manage-clients"; role: "manage-realm" | "manage-clients";
@ -24,18 +16,13 @@ export type RoleFormProps = {
}; };
export const RoleForm = ({ export const RoleForm = ({
form: {
register,
control,
handleSubmit,
formState: { errors },
},
onSubmit, onSubmit,
cancelLink, cancelLink,
role, role,
editMode, editMode,
}: RoleFormProps) => { }: RoleFormProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { control, handleSubmit } = useFormContext<AttributeForm>();
const roleName = useWatch({ const roleName = useWatch({
control, control,
@ -53,54 +40,30 @@ export const RoleForm = ({
role={role} role={role}
className="pf-u-mt-lg" className="pf-u-mt-lg"
> >
<FormGroup <TextControl
name="name"
label={t("roleName")} label={t("roleName")}
fieldId="kc-name" rules={{
validated={ required: !editMode ? t("required") : undefined,
errors.name ? ValidatedOptions.error : ValidatedOptions.default validate(value) {
}
helperTextInvalid={t("required")}
isRequired={!editMode}
>
<KeycloakTextInput
id="kc-name"
isReadOnly={editMode}
{...register("name", {
required: !editMode,
validate: (value) => {
if (!value?.trim()) { if (!value?.trim()) {
return t("required").toString(); return t("required");
} }
}, },
})} }}
readOnly={editMode}
/> />
</FormGroup> <TextAreaControl
<FormGroup name="description"
label={t("description")} label={t("description")}
fieldId="kc-description" rules={{
validated={
errors.description
? ValidatedOptions.error
: ValidatedOptions.default
}
helperTextInvalid={errors.description?.message}
>
<KeycloakTextArea
id="kc-description"
validated={
errors.description
? ValidatedOptions.error
: ValidatedOptions.default
}
isDisabled={roleName?.includes("default-roles")}
{...register("description", {
maxLength: { maxLength: {
value: 255, value: 255,
message: t("maxLength", { length: 255 }), message: t("maxLength", { length: 255 }),
}, },
})} }}
isDisabled={roleName?.includes("default-roles") ?? false}
/> />
</FormGroup>
<ActionGroup> <ActionGroup>
<Button data-testid="save" type="submit" variant="primary"> <Button data-testid="save" type="submit" variant="primary">
{t("save")} {t("save")}

View file

@ -1,6 +1,6 @@
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation"; import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
import { AlertVariant } from "@patternfly/react-core"; import { AlertVariant } from "@patternfly/react-core";
import { SubmitHandler, useForm } from "react-hook-form"; import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
@ -45,12 +45,13 @@ export default function CreateRealmRole() {
}; };
return ( return (
<FormProvider {...form}>
<RoleForm <RoleForm
form={form}
onSubmit={onSubmit} onSubmit={onSubmit}
cancelLink={toRealmRoles({ realm })} cancelLink={toRealmRoles({ realm })}
role="manage-realm" role="manage-realm"
editMode={false} editMode={false}
/> />
</FormProvider>
); );
} }

View file

@ -9,7 +9,12 @@ import {
TabTitleText, TabTitleText,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { useState } from "react"; import { useState } from "react";
import { SubmitHandler, useForm, useWatch } from "react-hook-form"; import {
FormProvider,
SubmitHandler,
useForm,
useWatch,
} from "react-hook-form";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useLocation, useMatch, useNavigate } from "react-router-dom"; import { useLocation, useMatch, useNavigate } from "react-router-dom";
@ -333,13 +338,13 @@ export default function RealmRoleTabs() {
divider={false} divider={false}
/> />
<PageSection variant="light" className="pf-u-p-0"> <PageSection variant="light" className="pf-u-p-0">
<FormProvider {...form}>
<RoutableTabs isBox mountOnEnter defaultLocation={toTab("details")}> <RoutableTabs isBox mountOnEnter defaultLocation={toTab("details")}>
<Tab <Tab
title={<TabTitleText>{t("details")}</TabTitleText>} title={<TabTitleText>{t("details")}</TabTitleText>}
{...detailsTab} {...detailsTab}
> >
<RoleForm <RoleForm
form={form}
onSubmit={onSubmit} onSubmit={onSubmit}
role={clientRoleMatch ? "manage-clients" : "manage-realm"} role={clientRoleMatch ? "manage-clients" : "manage-realm"}
cancelLink={ cancelLink={
@ -398,6 +403,7 @@ export default function RealmRoleTabs() {
</Tab> </Tab>
)} )}
</RoutableTabs> </RoutableTabs>
</FormProvider>
</PageSection> </PageSection>
</> </>
); );