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:
parent
7fe7dfc529
commit
080b6a7981
4 changed files with 43 additions and 34 deletions
|
@ -23,7 +23,7 @@ export const ClientRoleRoute: AppRouteObject = {
|
||||||
element: <RealmRoleTabs />,
|
element: <RealmRoleTabs />,
|
||||||
breadcrumb: (t) => t("roles:roleDetails"),
|
breadcrumb: (t) => t("roles:roleDetails"),
|
||||||
handle: {
|
handle: {
|
||||||
access: "view-realm",
|
access: "view-clients",
|
||||||
},
|
},
|
||||||
} satisfies AppRouteObject;
|
} satisfies AppRouteObject;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { FilterIcon } from "@patternfly/react-icons";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useAccess } from "../../context/access/Access";
|
||||||
import useLocaleSort from "../../utils/useLocaleSort";
|
import useLocaleSort from "../../utils/useLocaleSort";
|
||||||
import { ListEmptyState } from "../list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../list-empty-state/ListEmptyState";
|
||||||
import { KeycloakDataTable } from "../table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../table-toolbar/KeycloakDataTable";
|
||||||
|
@ -40,10 +41,14 @@ export const AddRoleMappingModal = ({
|
||||||
onClose,
|
onClose,
|
||||||
}: AddRoleMappingModalProps) => {
|
}: AddRoleMappingModalProps) => {
|
||||||
const { t } = useTranslation(type);
|
const { t } = useTranslation(type);
|
||||||
|
const { hasAccess } = useAccess();
|
||||||
|
const canViewRealmRoles = hasAccess("view-realm");
|
||||||
|
|
||||||
const [searchToggle, setSearchToggle] = useState(false);
|
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 [selectedRows, setSelectedRows] = useState<Row[]>([]);
|
||||||
const [key, setKey] = useState(0);
|
const [key, setKey] = useState(0);
|
||||||
const refresh = () => setKey(key + 1);
|
const refresh = () => setKey(key + 1);
|
||||||
|
@ -137,34 +142,36 @@ export const AddRoleMappingModal = ({
|
||||||
searchPlaceholderKey="clients:searchByRoleName"
|
searchPlaceholderKey="clients:searchByRoleName"
|
||||||
isPaginated={!(filterType === "roles" && type !== "roles")}
|
isPaginated={!(filterType === "roles" && type !== "roles")}
|
||||||
searchTypeComponent={
|
searchTypeComponent={
|
||||||
<ToolbarItem>
|
canViewRealmRoles && (
|
||||||
<Dropdown
|
<ToolbarItem>
|
||||||
onSelect={() => {
|
<Dropdown
|
||||||
setFilterType(filterType === "roles" ? "clients" : "roles");
|
onSelect={() => {
|
||||||
setSearchToggle(false);
|
setFilterType(filterType === "roles" ? "clients" : "roles");
|
||||||
refresh();
|
setSearchToggle(false);
|
||||||
}}
|
refresh();
|
||||||
data-testid="filter-type-dropdown"
|
}}
|
||||||
toggle={
|
data-testid="filter-type-dropdown"
|
||||||
<DropdownToggle
|
toggle={
|
||||||
onToggle={setSearchToggle}
|
<DropdownToggle
|
||||||
icon={<FilterIcon />}
|
onToggle={setSearchToggle}
|
||||||
>
|
icon={<FilterIcon />}
|
||||||
{filterType === "roles"
|
>
|
||||||
? t("common:filterByRoles")
|
{filterType === "roles"
|
||||||
: t("common:filterByClients")}
|
? t("common:filterByRoles")
|
||||||
</DropdownToggle>
|
: t("common:filterByClients")}
|
||||||
}
|
</DropdownToggle>
|
||||||
isOpen={searchToggle}
|
}
|
||||||
dropdownItems={[
|
isOpen={searchToggle}
|
||||||
<DropdownItem key="filter-type" data-testid={filterType}>
|
dropdownItems={[
|
||||||
{filterType === "roles"
|
<DropdownItem key="filter-type" data-testid={filterType}>
|
||||||
? t("common:filterByClients")
|
{filterType === "roles"
|
||||||
: t("common:filterByRoles")}
|
? t("common:filterByClients")
|
||||||
</DropdownItem>,
|
: t("common:filterByRoles")}
|
||||||
]}
|
</DropdownItem>,
|
||||||
/>
|
]}
|
||||||
</ToolbarItem>
|
/>
|
||||||
|
</ToolbarItem>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
canSelectAll
|
canSelectAll
|
||||||
isRadio={isRadio}
|
isRadio={isRadio}
|
||||||
|
|
|
@ -33,7 +33,6 @@ const RoleDetailLink = ({
|
||||||
}: RoleDetailLinkProps) => {
|
}: RoleDetailLinkProps) => {
|
||||||
const { t } = useTranslation(messageBundle);
|
const { t } = useTranslation(messageBundle);
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
|
|
||||||
return role.name !== defaultRoleName ? (
|
return role.name !== defaultRoleName ? (
|
||||||
<Link to={toDetail(role.id!)}>{role.name}</Link>
|
<Link to={toDetail(role.id!)}>{role.name}</Link>
|
||||||
) : (
|
) : (
|
||||||
|
@ -107,7 +106,7 @@ export const RolesList = ({
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
setSelectedRole(undefined);
|
setSelectedRole(undefined);
|
||||||
addAlert(t("roleDeletedSuccess"), AlertVariant.success);
|
addAlert(t("roles:roleDeletedSuccess"), AlertVariant.success);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addError("roles:roleDeleteError", error);
|
addError("roles:roleDeleteError", error);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +144,10 @@ export const RolesList = ({
|
||||||
title: t("common:delete"),
|
title: t("common:delete"),
|
||||||
onRowClick: (role) => {
|
onRowClick: (role) => {
|
||||||
setSelectedRole(role);
|
setSelectedRole(role);
|
||||||
if (role.name === realm!.defaultRole!.name) {
|
if (
|
||||||
|
realm!.defaultRole &&
|
||||||
|
role.name === realm!.defaultRole!.name
|
||||||
|
) {
|
||||||
addAlert(
|
addAlert(
|
||||||
t("defaultRoleDeleteError"),
|
t("defaultRoleDeleteError"),
|
||||||
AlertVariant.danger
|
AlertVariant.danger
|
||||||
|
|
|
@ -300,7 +300,7 @@ export default function RealmRoleTabs() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDefaultRole = (name: string | undefined) =>
|
const isDefaultRole = (name: string | undefined) =>
|
||||||
realm?.defaultRole!.name === name;
|
realm?.defaultRole && realm.defaultRole!.name === name;
|
||||||
|
|
||||||
if (!realm) {
|
if (!realm) {
|
||||||
return <KeycloakSpinner />;
|
return <KeycloakSpinner />;
|
||||||
|
|
Loading…
Reference in a new issue