2022-08-03 12:12:07 +00:00
|
|
|
import { useState } from "react";
|
2021-03-24 14:07:49 +00:00
|
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
import {
|
|
|
|
AlertVariant,
|
|
|
|
Button,
|
|
|
|
Modal,
|
|
|
|
ModalVariant,
|
|
|
|
} from "@patternfly/react-core";
|
|
|
|
|
2021-08-26 08:39:35 +00:00
|
|
|
import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
2021-03-24 14:07:49 +00:00
|
|
|
import { useAdminClient } from "../context/auth/AdminClient";
|
|
|
|
import { useAlerts } from "../components/alert/Alerts";
|
|
|
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
|
|
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
|
|
|
import { emptyFormatter } from "../util";
|
2022-02-02 10:33:57 +00:00
|
|
|
import { differenceBy } from "lodash-es";
|
2021-03-24 14:07:49 +00:00
|
|
|
|
|
|
|
type MemberModalProps = {
|
|
|
|
groupId: string;
|
|
|
|
onClose: () => void;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const MemberModal = ({ groupId, onClose }: MemberModalProps) => {
|
|
|
|
const { t } = useTranslation("groups");
|
2022-07-14 13:02:28 +00:00
|
|
|
const { adminClient } = useAdminClient();
|
2021-07-28 12:01:42 +00:00
|
|
|
const { addAlert, addError } = useAlerts();
|
2021-03-24 14:07:49 +00:00
|
|
|
const [selectedRows, setSelectedRows] = useState<UserRepresentation[]>([]);
|
|
|
|
|
|
|
|
const loader = async (first?: number, max?: number, search?: string) => {
|
|
|
|
const members = await adminClient.groups.listMembers({ id: groupId });
|
|
|
|
const params: { [name: string]: string | number } = {
|
|
|
|
first: first!,
|
|
|
|
max: max! + members.length,
|
|
|
|
search: search || "",
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
const users = await adminClient.users.find({ ...params });
|
2022-02-02 10:33:57 +00:00
|
|
|
return differenceBy(users, members, "id").slice(0, max);
|
2021-03-24 14:07:49 +00:00
|
|
|
} catch (error) {
|
2021-07-28 12:01:42 +00:00
|
|
|
addError("groups:noUsersFoundError", error);
|
2021-03-24 14:07:49 +00:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Modal
|
|
|
|
variant={ModalVariant.large}
|
|
|
|
title={t("addMember")}
|
|
|
|
isOpen={true}
|
|
|
|
onClose={onClose}
|
|
|
|
actions={[
|
|
|
|
<Button
|
|
|
|
data-testid="add"
|
|
|
|
key="confirm"
|
|
|
|
variant="primary"
|
|
|
|
onClick={async () => {
|
|
|
|
try {
|
|
|
|
await Promise.all(
|
|
|
|
selectedRows.map((user) =>
|
|
|
|
adminClient.users.addToGroup({ id: user.id!, groupId })
|
|
|
|
)
|
|
|
|
);
|
|
|
|
onClose();
|
|
|
|
addAlert(
|
|
|
|
t("usersAdded", { count: selectedRows.length }),
|
|
|
|
AlertVariant.success
|
|
|
|
);
|
|
|
|
} catch (error) {
|
2021-07-28 12:01:42 +00:00
|
|
|
addError("groups:usersAddedError", error);
|
2021-03-24 14:07:49 +00:00
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{t("common:add")}
|
|
|
|
</Button>,
|
|
|
|
<Button
|
|
|
|
data-testid="cancel"
|
|
|
|
key="cancel"
|
2021-04-15 10:52:34 +00:00
|
|
|
variant="link"
|
2021-03-24 14:07:49 +00:00
|
|
|
onClick={onClose}
|
|
|
|
>
|
|
|
|
{t("common:cancel")}
|
|
|
|
</Button>,
|
|
|
|
]}
|
|
|
|
>
|
|
|
|
<KeycloakDataTable
|
|
|
|
loader={loader}
|
|
|
|
isPaginated
|
|
|
|
ariaLabelKey="users:title"
|
|
|
|
searchPlaceholderKey="users:searchForUser"
|
|
|
|
canSelectAll
|
|
|
|
onSelect={(rows) => setSelectedRows([...rows])}
|
|
|
|
emptyState={
|
|
|
|
<ListEmptyState
|
|
|
|
message={t("users:noUsersFound")}
|
|
|
|
instructions={t("users:emptyInstructions")}
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
columns={[
|
|
|
|
{
|
|
|
|
name: "username",
|
|
|
|
displayKey: "users:username",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "email",
|
|
|
|
displayKey: "users:email",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "lastName",
|
|
|
|
displayKey: "users:lastName",
|
|
|
|
cellFormatters: [emptyFormatter()],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "firstName",
|
|
|
|
displayKey: "users:firstName",
|
|
|
|
cellFormatters: [emptyFormatter()],
|
|
|
|
},
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
};
|