Allow view client roles tab without view-realm access (#21142)

* Allow view client->roles tab with view-clients access.
Fixes #21047

* Fix role deleted success message.
This commit is contained in:
Stan Silvert 2023-06-23 07:04:37 -04:00 committed by GitHub
parent 7fe7dfc529
commit 080b6a7981
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 34 deletions

View file

@ -23,7 +23,7 @@ export const ClientRoleRoute: AppRouteObject = {
element: <RealmRoleTabs />,
breadcrumb: (t) => t("roles:roleDetails"),
handle: {
access: "view-realm",
access: "view-clients",
},
} satisfies AppRouteObject;

View file

@ -11,6 +11,7 @@ import { FilterIcon } from "@patternfly/react-icons";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useAccess } from "../../context/access/Access";
import useLocaleSort from "../../utils/useLocaleSort";
import { ListEmptyState } from "../list-empty-state/ListEmptyState";
import { KeycloakDataTable } from "../table-toolbar/KeycloakDataTable";
@ -40,10 +41,14 @@ export const AddRoleMappingModal = ({
onClose,
}: AddRoleMappingModalProps) => {
const { t } = useTranslation(type);
const { hasAccess } = useAccess();
const canViewRealmRoles = hasAccess("view-realm");
const [searchToggle, setSearchToggle] = useState(false);
const [filterType, setFilterType] = useState<FilterType>("roles");
const [filterType, setFilterType] = useState<FilterType>(
canViewRealmRoles ? "roles" : "clients"
);
const [selectedRows, setSelectedRows] = useState<Row[]>([]);
const [key, setKey] = useState(0);
const refresh = () => setKey(key + 1);
@ -137,34 +142,36 @@ export const AddRoleMappingModal = ({
searchPlaceholderKey="clients:searchByRoleName"
isPaginated={!(filterType === "roles" && type !== "roles")}
searchTypeComponent={
<ToolbarItem>
<Dropdown
onSelect={() => {
setFilterType(filterType === "roles" ? "clients" : "roles");
setSearchToggle(false);
refresh();
}}
data-testid="filter-type-dropdown"
toggle={
<DropdownToggle
onToggle={setSearchToggle}
icon={<FilterIcon />}
>
{filterType === "roles"
? t("common:filterByRoles")
: t("common:filterByClients")}
</DropdownToggle>
}
isOpen={searchToggle}
dropdownItems={[
<DropdownItem key="filter-type" data-testid={filterType}>
{filterType === "roles"
? t("common:filterByClients")
: t("common:filterByRoles")}
</DropdownItem>,
]}
/>
</ToolbarItem>
canViewRealmRoles && (
<ToolbarItem>
<Dropdown
onSelect={() => {
setFilterType(filterType === "roles" ? "clients" : "roles");
setSearchToggle(false);
refresh();
}}
data-testid="filter-type-dropdown"
toggle={
<DropdownToggle
onToggle={setSearchToggle}
icon={<FilterIcon />}
>
{filterType === "roles"
? t("common:filterByRoles")
: t("common:filterByClients")}
</DropdownToggle>
}
isOpen={searchToggle}
dropdownItems={[
<DropdownItem key="filter-type" data-testid={filterType}>
{filterType === "roles"
? t("common:filterByClients")
: t("common:filterByRoles")}
</DropdownItem>,
]}
/>
</ToolbarItem>
)
}
canSelectAll
isRadio={isRadio}

View file

@ -33,7 +33,6 @@ const RoleDetailLink = ({
}: RoleDetailLinkProps) => {
const { t } = useTranslation(messageBundle);
const { realm } = useRealm();
return role.name !== defaultRoleName ? (
<Link to={toDetail(role.id!)}>{role.name}</Link>
) : (
@ -107,7 +106,7 @@ export const RolesList = ({
]);
}
setSelectedRole(undefined);
addAlert(t("roleDeletedSuccess"), AlertVariant.success);
addAlert(t("roles:roleDeletedSuccess"), AlertVariant.success);
} catch (error) {
addError("roles:roleDeleteError", error);
}
@ -145,7 +144,10 @@ export const RolesList = ({
title: t("common:delete"),
onRowClick: (role) => {
setSelectedRole(role);
if (role.name === realm!.defaultRole!.name) {
if (
realm!.defaultRole &&
role.name === realm!.defaultRole!.name
) {
addAlert(
t("defaultRoleDeleteError"),
AlertVariant.danger

View file

@ -300,7 +300,7 @@ export default function RealmRoleTabs() {
};
const isDefaultRole = (name: string | undefined) =>
realm?.defaultRole!.name === name;
realm?.defaultRole && realm.defaultRole!.name === name;
if (!realm) {
return <KeycloakSpinner />;