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

View file

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

View file

@ -1,6 +1,6 @@
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
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 { useNavigate, useParams } from "react-router-dom";
@ -54,16 +54,17 @@ export default function CreateClientRole() {
};
return (
<RoleForm
form={form}
onSubmit={onSubmit}
cancelLink={toClient({
realm,
clientId: clientId!,
tab: "roles",
})}
role="manage-clients"
editMode={false}
/>
<FormProvider {...form}>
<RoleForm
onSubmit={onSubmit}
cancelLink={toClient({
realm,
clientId: clientId!,
tab: "roles",
})}
role="manage-clients"
editMode={false}
/>
</FormProvider>
);
}

View file

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

View file

@ -1,6 +1,6 @@
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
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 { useNavigate } from "react-router-dom";
@ -45,12 +45,13 @@ export default function CreateRealmRole() {
};
return (
<RoleForm
form={form}
onSubmit={onSubmit}
cancelLink={toRealmRoles({ realm })}
role="manage-realm"
editMode={false}
/>
<FormProvider {...form}>
<RoleForm
onSubmit={onSubmit}
cancelLink={toRealmRoles({ realm })}
role="manage-realm"
editMode={false}
/>
</FormProvider>
);
}

View file

@ -9,7 +9,12 @@ import {
TabTitleText,
} from "@patternfly/react-core";
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 { useLocation, useMatch, useNavigate } from "react-router-dom";
@ -333,71 +338,72 @@ export default function RealmRoleTabs() {
divider={false}
/>
<PageSection variant="light" className="pf-u-p-0">
<RoutableTabs isBox mountOnEnter defaultLocation={toTab("details")}>
<Tab
title={<TabTitleText>{t("details")}</TabTitleText>}
{...detailsTab}
>
<RoleForm
form={form}
onSubmit={onSubmit}
role={clientRoleMatch ? "manage-clients" : "manage-realm"}
cancelLink={
clientRoleMatch
? toClient({ realm: realmName, clientId, tab: "roles" })
: toRealmRoles({ realm: realmName })
}
editMode
/>
</Tab>
{composites && (
<FormProvider {...form}>
<RoutableTabs isBox mountOnEnter defaultLocation={toTab("details")}>
<Tab
data-testid="associatedRolesTab"
title={<TabTitleText>{t("associatedRolesText")}</TabTitleText>}
{...associatedRolesTab}
title={<TabTitleText>{t("details")}</TabTitleText>}
{...detailsTab}
>
<RoleMapping
name={roleName!}
id={id}
type="roles"
isManager
save={(rows) => addComposites(rows.map((r) => r.role))}
/>
</Tab>
)}
{!isDefaultRole(roleName) && (
<Tab
data-testid="attributesTab"
className="kc-attributes-tab"
title={<TabTitleText>{t("attributes")}</TabTitleText>}
{...attributesTab}
>
<AttributesForm
form={form}
save={onSubmit}
reset={() =>
setValue("attributes", attributes, { shouldDirty: false })
<RoleForm
onSubmit={onSubmit}
role={clientRoleMatch ? "manage-clients" : "manage-realm"}
cancelLink={
clientRoleMatch
? toClient({ realm: realmName, clientId, tab: "roles" })
: toRealmRoles({ realm: realmName })
}
editMode
/>
</Tab>
)}
{!isDefaultRole(roleName) && (
<Tab
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
{...usersInRoleTab}
>
<UsersInRoleTab data-cy="users-in-role-tab" />
</Tab>
)}
{isFeatureEnabled(Feature.AdminFineGrainedAuthz) && (
<Tab
title={<TabTitleText>{t("permissions")}</TabTitleText>}
{...permissionsTab}
>
<PermissionsTab id={id} type="roles" />
</Tab>
)}
</RoutableTabs>
{composites && (
<Tab
data-testid="associatedRolesTab"
title={<TabTitleText>{t("associatedRolesText")}</TabTitleText>}
{...associatedRolesTab}
>
<RoleMapping
name={roleName!}
id={id}
type="roles"
isManager
save={(rows) => addComposites(rows.map((r) => r.role))}
/>
</Tab>
)}
{!isDefaultRole(roleName) && (
<Tab
data-testid="attributesTab"
className="kc-attributes-tab"
title={<TabTitleText>{t("attributes")}</TabTitleText>}
{...attributesTab}
>
<AttributesForm
form={form}
save={onSubmit}
reset={() =>
setValue("attributes", attributes, { shouldDirty: false })
}
/>
</Tab>
)}
{!isDefaultRole(roleName) && (
<Tab
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
{...usersInRoleTab}
>
<UsersInRoleTab data-cy="users-in-role-tab" />
</Tab>
)}
{isFeatureEnabled(Feature.AdminFineGrainedAuthz) && (
<Tab
title={<TabTitleText>{t("permissions")}</TabTitleText>}
{...permissionsTab}
>
<PermissionsTab id={id} type="roles" />
</Tab>
)}
</RoutableTabs>
</FormProvider>
</PageSection>
</>
);