Reduced state held and fixed reset (#4213)
This commit is contained in:
parent
6277c0bc06
commit
45b2a8da62
3 changed files with 55 additions and 52 deletions
|
@ -251,7 +251,7 @@ describe("Realm roles test", () => {
|
||||||
keyValue.fillKeyValue({ key: "one", value: "1" }).validateRows(2);
|
keyValue.fillKeyValue({ key: "one", value: "1" }).validateRows(2);
|
||||||
keyValue.save();
|
keyValue.save();
|
||||||
masthead.checkNotificationMessage("The role has been saved", true);
|
masthead.checkNotificationMessage("The role has been saved", true);
|
||||||
keyValue.validateRows(1);
|
keyValue.validateRows(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should add attribute multiple", () => {
|
it("should add attribute multiple", () => {
|
||||||
|
@ -262,14 +262,14 @@ describe("Realm roles test", () => {
|
||||||
.fillKeyValue({ key: "two", value: "2" }, 1)
|
.fillKeyValue({ key: "two", value: "2" }, 1)
|
||||||
.fillKeyValue({ key: "three", value: "3" }, 2)
|
.fillKeyValue({ key: "three", value: "3" }, 2)
|
||||||
.save()
|
.save()
|
||||||
.validateRows(3);
|
.validateRows(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should delete attribute", () => {
|
it("should delete attribute", () => {
|
||||||
listingPage.itemExist(editRoleName).goToItemDetails(editRoleName);
|
listingPage.itemExist(editRoleName).goToItemDetails(editRoleName);
|
||||||
createRealmRolePage.goToAttributesTab();
|
createRealmRolePage.goToAttributesTab();
|
||||||
|
|
||||||
keyValue.deleteRow(1).save().validateRows(2);
|
keyValue.deleteRow(1).save().validateRows(3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,12 +5,12 @@ import {
|
||||||
PageSection,
|
PageSection,
|
||||||
ValidatedOptions,
|
ValidatedOptions,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import type { SubmitHandler, UseFormMethods } from "react-hook-form";
|
import { SubmitHandler, useWatch, UseFormMethods } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, To } from "react-router-dom-v5-compat";
|
import { Link, To } from "react-router-dom-v5-compat";
|
||||||
|
|
||||||
import { FormAccess } from "../form-access/FormAccess";
|
import { FormAccess } from "../form-access/FormAccess";
|
||||||
import type { AttributeForm } from "../key-value-form/AttributeForm";
|
import { AttributeForm } from "../key-value-form/AttributeForm";
|
||||||
import { KeycloakTextArea } from "../keycloak-text-area/KeycloakTextArea";
|
import { KeycloakTextArea } from "../keycloak-text-area/KeycloakTextArea";
|
||||||
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
||||||
import { ViewHeader } from "../view-header/ViewHeader";
|
import { ViewHeader } from "../view-header/ViewHeader";
|
||||||
|
@ -24,7 +24,7 @@ export type RoleFormProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RoleForm = ({
|
export const RoleForm = ({
|
||||||
form: { handleSubmit, errors, register, getValues },
|
form: { register, control, handleSubmit, errors },
|
||||||
onSubmit,
|
onSubmit,
|
||||||
cancelLink,
|
cancelLink,
|
||||||
role,
|
role,
|
||||||
|
@ -32,6 +32,12 @@ export const RoleForm = ({
|
||||||
}: RoleFormProps) => {
|
}: RoleFormProps) => {
|
||||||
const { t } = useTranslation("roles");
|
const { t } = useTranslation("roles");
|
||||||
|
|
||||||
|
const roleName = useWatch<string | undefined>({
|
||||||
|
control,
|
||||||
|
defaultValue: undefined,
|
||||||
|
name: "name",
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!editMode && <ViewHeader titleKey={t("createRole")} />}
|
{!editMode && <ViewHeader titleKey={t("createRole")} />}
|
||||||
|
@ -86,7 +92,7 @@ export const RoleForm = ({
|
||||||
? ValidatedOptions.error
|
? ValidatedOptions.error
|
||||||
: ValidatedOptions.default
|
: ValidatedOptions.default
|
||||||
}
|
}
|
||||||
isDisabled={getValues().name?.includes("default-roles")}
|
isDisabled={roleName?.includes("default-roles")}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<ActionGroup>
|
<ActionGroup>
|
||||||
|
|
|
@ -8,9 +8,8 @@ import {
|
||||||
Tab,
|
Tab,
|
||||||
TabTitleText,
|
TabTitleText,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { omit } from "lodash-es";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { SubmitHandler, useForm } from "react-hook-form";
|
import { 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-v5-compat";
|
import { useLocation, useMatch, useNavigate } from "react-router-dom-v5-compat";
|
||||||
|
|
||||||
|
@ -30,6 +29,7 @@ import {
|
||||||
import {
|
import {
|
||||||
arrayToKeyValue,
|
arrayToKeyValue,
|
||||||
keyValueToArray,
|
keyValueToArray,
|
||||||
|
KeyValueType,
|
||||||
} from "../components/key-value-form/key-value-convert";
|
} from "../components/key-value-form/key-value-convert";
|
||||||
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||||
import { PermissionsTab } from "../components/permission-tab/PermissionTab";
|
import { PermissionsTab } from "../components/permission-tab/PermissionTab";
|
||||||
|
@ -54,11 +54,10 @@ export default function RealmRoleTabs() {
|
||||||
const form = useForm<AttributeForm>({
|
const form = useForm<AttributeForm>({
|
||||||
mode: "onChange",
|
mode: "onChange",
|
||||||
});
|
});
|
||||||
const { setValue, reset } = form;
|
const { control, reset, setValue } = form;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { adminClient } = useAdminClient();
|
const { adminClient } = useAdminClient();
|
||||||
const [role, setRole] = useState<AttributeForm>();
|
|
||||||
|
|
||||||
const { id, clientId } = useParams<ClientRoleParams>();
|
const { id, clientId } = useParams<ClientRoleParams>();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
@ -66,12 +65,11 @@ export default function RealmRoleTabs() {
|
||||||
const { realm: realmName } = useRealm();
|
const { realm: realmName } = useRealm();
|
||||||
|
|
||||||
const [key, setKey] = useState(0);
|
const [key, setKey] = useState(0);
|
||||||
|
const [attributes, setAttributes] = useState<KeyValueType[] | undefined>();
|
||||||
|
|
||||||
const { profileInfo } = useServerInfo();
|
const { profileInfo } = useServerInfo();
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => setKey(key + 1);
|
||||||
setKey(key + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
|
|
||||||
|
@ -84,6 +82,18 @@ export default function RealmRoleTabs() {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const roleName = useWatch<string | undefined>({
|
||||||
|
control,
|
||||||
|
defaultValue: undefined,
|
||||||
|
name: "name",
|
||||||
|
});
|
||||||
|
|
||||||
|
const composites = useWatch<boolean>({
|
||||||
|
control,
|
||||||
|
defaultValue: false,
|
||||||
|
name: "composite",
|
||||||
|
});
|
||||||
|
|
||||||
const [realm, setRealm] = useState<RealmRepresentation>();
|
const [realm, setRealm] = useState<RealmRepresentation>();
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
@ -103,36 +113,20 @@ export default function RealmRoleTabs() {
|
||||||
const convertedRole = convert(role);
|
const convertedRole = convert(role);
|
||||||
|
|
||||||
reset(convertedRole);
|
reset(convertedRole);
|
||||||
|
setAttributes(convertedRole.attributes);
|
||||||
setRealm(realm);
|
setRealm(realm);
|
||||||
setRole(convertedRole);
|
|
||||||
},
|
},
|
||||||
[key]
|
[key]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSubmit: SubmitHandler<AttributeForm> = async (formValues) => {
|
const onSubmit: SubmitHandler<AttributeForm> = async (formValues) => {
|
||||||
try {
|
try {
|
||||||
if (
|
|
||||||
formValues.attributes &&
|
|
||||||
formValues.attributes[formValues.attributes.length - 1]?.key === ""
|
|
||||||
) {
|
|
||||||
setValue(
|
|
||||||
"attributes",
|
|
||||||
formValues.attributes.slice(0, formValues.attributes.length - 1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { attributes, ...rest } = formValues;
|
const { attributes, ...rest } = formValues;
|
||||||
let roleRepresentation: RoleRepresentation = rest;
|
const roleRepresentation: RoleRepresentation = rest;
|
||||||
|
|
||||||
roleRepresentation.name = roleRepresentation.name?.trim();
|
roleRepresentation.name = roleRepresentation.name?.trim();
|
||||||
|
roleRepresentation.attributes = keyValueToArray(attributes);
|
||||||
|
|
||||||
if (attributes) {
|
|
||||||
roleRepresentation.attributes = keyValueToArray(attributes);
|
|
||||||
}
|
|
||||||
roleRepresentation = {
|
|
||||||
...omit(role!, "attributes"),
|
|
||||||
...roleRepresentation,
|
|
||||||
};
|
|
||||||
if (!clientId) {
|
if (!clientId) {
|
||||||
await adminClient.roles.updateById({ id }, roleRepresentation);
|
await adminClient.roles.updateById({ id }, roleRepresentation);
|
||||||
} else {
|
} else {
|
||||||
|
@ -142,7 +136,7 @@ export default function RealmRoleTabs() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setRole(convert(roleRepresentation));
|
setAttributes(attributes);
|
||||||
addAlert(t("roleSaveSuccess"), AlertVariant.success);
|
addAlert(t("roleSaveSuccess"), AlertVariant.success);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addError("roles:roleSaveError", error);
|
addError("roles:roleSaveError", error);
|
||||||
|
@ -201,7 +195,7 @@ export default function RealmRoleTabs() {
|
||||||
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
|
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
|
||||||
titleKey: "roles:roleDeleteConfirm",
|
titleKey: "roles:roleDeleteConfirm",
|
||||||
messageKey: t("roles:roleDeleteConfirmDialog", {
|
messageKey: t("roles:roleDeleteConfirmDialog", {
|
||||||
selectedRoleName: role?.name || t("createRole"),
|
selectedRoleName: roleName || t("createRole"),
|
||||||
}),
|
}),
|
||||||
continueButtonLabel: "common:delete",
|
continueButtonLabel: "common:delete",
|
||||||
continueButtonVariant: ButtonVariant.danger,
|
continueButtonVariant: ButtonVariant.danger,
|
||||||
|
@ -212,7 +206,7 @@ export default function RealmRoleTabs() {
|
||||||
} else {
|
} else {
|
||||||
await adminClient.clients.delRole({
|
await adminClient.clients.delRole({
|
||||||
id: clientId,
|
id: clientId,
|
||||||
roleName: role!.name!,
|
roleName: roleName!,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
addAlert(t("roleDeletedSuccess"), AlertVariant.success);
|
addAlert(t("roleDeletedSuccess"), AlertVariant.success);
|
||||||
|
@ -266,14 +260,14 @@ export default function RealmRoleTabs() {
|
||||||
] = useConfirmDialog({
|
] = useConfirmDialog({
|
||||||
titleKey: t("roles:removeAllAssociatedRoles") + "?",
|
titleKey: t("roles:removeAllAssociatedRoles") + "?",
|
||||||
messageKey: t("roles:removeAllAssociatedRolesConfirmDialog", {
|
messageKey: t("roles:removeAllAssociatedRolesConfirmDialog", {
|
||||||
name: role?.name || t("createRole"),
|
name: roleName || t("createRole"),
|
||||||
}),
|
}),
|
||||||
continueButtonLabel: "common:delete",
|
continueButtonLabel: "common:delete",
|
||||||
continueButtonVariant: ButtonVariant.danger,
|
continueButtonVariant: ButtonVariant.danger,
|
||||||
onConfirm: async () => {
|
onConfirm: async () => {
|
||||||
try {
|
try {
|
||||||
const additionalRoles = await adminClient.roles.getCompositeRoles({
|
const additionalRoles = await adminClient.roles.getCompositeRoles({
|
||||||
id: role!.id!,
|
id,
|
||||||
});
|
});
|
||||||
await adminClient.roles.delCompositeRoles({ id }, additionalRoles);
|
await adminClient.roles.delCompositeRoles({ id }, additionalRoles);
|
||||||
addAlert(
|
addAlert(
|
||||||
|
@ -296,7 +290,7 @@ export default function RealmRoleTabs() {
|
||||||
const addComposites = async (composites: RoleRepresentation[]) => {
|
const addComposites = async (composites: RoleRepresentation[]) => {
|
||||||
try {
|
try {
|
||||||
await adminClient.roles.createComposite(
|
await adminClient.roles.createComposite(
|
||||||
{ roleId: role?.id!, realm: realm!.realm },
|
{ roleId: id, realm: realm!.realm },
|
||||||
composites
|
composites
|
||||||
);
|
);
|
||||||
refresh();
|
refresh();
|
||||||
|
@ -307,9 +301,10 @@ export default function RealmRoleTabs() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDefaultRole = (name: string) => realm?.defaultRole!.name === name;
|
const isDefaultRole = (name: string | undefined) =>
|
||||||
|
realm?.defaultRole!.name === name;
|
||||||
|
|
||||||
if (!realm || !role) {
|
if (!realm) {
|
||||||
return <KeycloakSpinner />;
|
return <KeycloakSpinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,17 +316,17 @@ export default function RealmRoleTabs() {
|
||||||
<AddRoleMappingModal
|
<AddRoleMappingModal
|
||||||
id={id}
|
id={id}
|
||||||
type="roles"
|
type="roles"
|
||||||
name={role.name}
|
name={roleName}
|
||||||
onAssign={(rows) => addComposites(rows.map((r) => r.role))}
|
onAssign={(rows) => addComposites(rows.map((r) => r.role))}
|
||||||
onClose={() => setOpen(false)}
|
onClose={() => setOpen(false)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<ViewHeader
|
<ViewHeader
|
||||||
titleKey={role.name!}
|
titleKey={roleName!}
|
||||||
badges={[
|
badges={[
|
||||||
{
|
{
|
||||||
id: "composite-role-badge",
|
id: "composite-role-badge",
|
||||||
text: role.composite ? t("composite") : "",
|
text: composites ? t("composite") : "",
|
||||||
readonly: true,
|
readonly: true,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
@ -354,25 +349,25 @@ export default function RealmRoleTabs() {
|
||||||
? toClient({ realm: realmName, clientId, tab: "roles" })
|
? toClient({ realm: realmName, clientId, tab: "roles" })
|
||||||
: toRealmRoles({ realm: realmName })
|
: toRealmRoles({ realm: realmName })
|
||||||
}
|
}
|
||||||
editMode={true}
|
editMode
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
{role.composite && (
|
{composites && (
|
||||||
<Tab
|
<Tab
|
||||||
data-testid="associatedRolesTab"
|
data-testid="associatedRolesTab"
|
||||||
title={<TabTitleText>{t("associatedRolesText")}</TabTitleText>}
|
title={<TabTitleText>{t("associatedRolesText")}</TabTitleText>}
|
||||||
{...associatedRolesTab}
|
{...associatedRolesTab}
|
||||||
>
|
>
|
||||||
<RoleMapping
|
<RoleMapping
|
||||||
name={role.name!}
|
name={roleName!}
|
||||||
id={role.id!}
|
id={id}
|
||||||
type="roles"
|
type="roles"
|
||||||
isManager
|
isManager
|
||||||
save={(rows) => addComposites(rows.map((r) => r.role))}
|
save={(rows) => addComposites(rows.map((r) => r.role))}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
)}
|
)}
|
||||||
{!isDefaultRole(role.name!) && (
|
{!isDefaultRole(roleName) && (
|
||||||
<Tab
|
<Tab
|
||||||
data-testid="attributesTab"
|
data-testid="attributesTab"
|
||||||
className="kc-attributes-tab"
|
className="kc-attributes-tab"
|
||||||
|
@ -382,11 +377,13 @@ export default function RealmRoleTabs() {
|
||||||
<AttributesForm
|
<AttributesForm
|
||||||
form={form}
|
form={form}
|
||||||
save={onSubmit}
|
save={onSubmit}
|
||||||
reset={() => reset(role)}
|
reset={() =>
|
||||||
|
setValue("attributes", attributes, { shouldDirty: false })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
)}
|
)}
|
||||||
{!isDefaultRole(role.name!) && (
|
{!isDefaultRole(roleName) && (
|
||||||
<Tab
|
<Tab
|
||||||
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
|
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
|
||||||
{...usersInRoleTab}
|
{...usersInRoleTab}
|
||||||
|
@ -401,7 +398,7 @@ export default function RealmRoleTabs() {
|
||||||
title={<TabTitleText>{t("common:permissions")}</TabTitleText>}
|
title={<TabTitleText>{t("common:permissions")}</TabTitleText>}
|
||||||
{...permissionsTab}
|
{...permissionsTab}
|
||||||
>
|
>
|
||||||
<PermissionsTab id={role.id} type="roles" />
|
<PermissionsTab id={id} type="roles" />
|
||||||
</Tab>
|
</Tab>
|
||||||
)}
|
)}
|
||||||
</RoutableTabs>
|
</RoutableTabs>
|
||||||
|
|
Loading…
Reference in a new issue