/* eslint-disable */
// @ts-nocheck
import type KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
import { useAlerts } from "../../../shared/keycloak-ui-shared";
import {
AlertVariant,
Badge,
Button,
ButtonVariant,
Checkbox,
ToolbarItem,
} from "../../../shared/@patternfly/react-core";
import { cellWidth } from "../../../shared/@patternfly/react-table";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useAdminClient } from "../../admin-client";
import { emptyFormatter, upperCaseFormatter } from "../../util";
import { translationFormatter } from "../../utils/translationFormatter";
import { useConfirmDialog } from "../confirm-dialog/ConfirmDialog";
import { ListEmptyState } from "../../../shared/keycloak-ui-shared";
import { Action, KeycloakDataTable } from "../../../shared/keycloak-ui-shared";
import {
AddRoleButton,
AddRoleMappingModal,
FilterType,
} from "./AddRoleMappingModal";
import { deleteMapping, getMapping } from "./queries";
import { getAllEffectiveRoles } from "./resource";
import "./role-mapping.css";
export type CompositeRole = RoleRepresentation & {
parent: RoleRepresentation;
isInherited?: boolean;
};
export type Row = {
client?: ClientRepresentation;
role: RoleRepresentation | CompositeRole;
id?: string; // KeycloakDataTable expects an id for the row
};
export const mapRoles = (
assignedRoles: Row[],
effectiveRoles: Row[],
hide: boolean,
) => [
...(hide
? assignedRoles.map((row) => ({
id: row.role.id,
...row,
role: {
...row.role,
isInherited: false,
},
}))
: effectiveRoles.map((row) => ({
id: row.role.id,
...row,
role: {
...row.role,
isInherited:
assignedRoles.find((r) => r.role.id === row.role.id) === undefined,
},
}))),
];
export const ServiceRole = ({ role, client }: Row) => (
<>
{client?.clientId && (
{client.clientId}
)}
{role.name}
>
);
export type ResourcesKey = keyof KeycloakAdminClient;
type RoleMappingProps = {
name: string;
id: string;
type: ResourcesKey;
isManager?: boolean;
save: (rows: Row[]) => Promise;
groupsResource?: any;
};
export const RoleMapping = ({
name,
id,
type,
isManager = true,
save,
groupsResource,
}: RoleMappingProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const [key, setKey] = useState(0);
const refresh = () => setKey(key + 1);
const [hide, setHide] = useState(true);
const [showAssign, setShowAssign] = useState(false);
const [filterType, setFilterType] = useState("clients");
const [selected, setSelected] = useState([]);
const assignRoles = async (rows: Row[]) => {
await save(rows);
refresh();
};
const loader = async () => {
let allEffectiveRoles: Row[] = [];
if (!hide) {
const effectiveRoles = await getAllEffectiveRoles(adminClient, {
type,
id,
});
allEffectiveRoles = effectiveRoles.map((e) => ({
...(e.clientRole && e.client && e.clientId
? { client: { clientId: e.client, id: e.clientId } }
: {}),
role: { id: e.id, name: e.name, description: e.description },
}));
}
const roles = await getMapping(adminClient, type, id, groupsResource);
const realmRolesMapping =
roles.realmMappings?.map((role) => ({ role })) || [];
const clientMapping = Object.values(roles.clientMappings || {})
.map((client) =>
client.mappings.map((role: RoleRepresentation) => ({
client: { clientId: client.client, ...client },
role,
})),
)
.flat();
return [
...mapRoles(
[...clientMapping, ...realmRolesMapping],
allEffectiveRoles,
hide,
),
];
};
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
titleKey: "removeMappingTitle",
messageKey: t("removeMappingConfirm", { count: selected.length }),
continueButtonLabel: "remove",
continueButtonVariant: ButtonVariant.danger,
onCancel: () => {
setSelected([]);
refresh();
},
onConfirm: async () => {
try {
await Promise.all(deleteMapping(adminClient, type, id, selected));
addAlert(t("roleMappingUpdatedSuccess"), AlertVariant.success);
setSelected([]);
refresh();
} catch (error) {
addError("roleMappingUpdatedError", error);
}
},
});
return (
<>
{showAssign && (
setShowAssign(false)}
groupsResource={groupsResource}
/>
)}
setSelected(rows)}
searchPlaceholderKey="searchByName"
ariaLabelKey="roleList"
isRowDisabled={(value) =>
(value.role as CompositeRole).isInherited || false
}
toolbarItem={
<>
{
setHide(check);
refresh();
}}
/>
{isManager && (
<>
{
setFilterType(type);
setShowAssign(true);
}}
/>
>
)}
>
}
actions={
isManager
? [
{
title: t("unAssignRole"),
onRowClick: async (role) => {
setSelected([role]);
toggleDeleteDialog();
return false;
},
} as Action>[0]>,
]
: []
}
columns={[
{
name: "role.name",
displayKey: "name",
transforms: [cellWidth(30)],
cellRenderer: ServiceRole,
},
{
name: "role.isInherited",
displayKey: "inherent",
cellFormatters: [upperCaseFormatter(), emptyFormatter()],
},
{
name: "role.description",
displayKey: "description",
cellFormatters: [translationFormatter(t)],
},
]}
emptyState={
{
setHide(false);
refresh();
},
},
]}
>
{
setFilterType(type);
setShowAssign(true);
}}
/>
}
/>
>
);
};