admin-dashboard-web/src/Pages/AllUsers/index.js

413 lines
13 KiB
JavaScript

import {
Button,
Popconfirm,
Popover,
Select,
Space,
Table,
Typography,
notification,
} from "antd";
import {
Constants,
FormatDatetime,
getConnectionStatusItem,
hasOnePermission,
hasPermission,
myFetch,
wsConnectionCustomEventName,
} from "../../utils";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { UserAddOutlined } from "@ant-design/icons";
import CreateUserModal from "./CreateUserModal";
import { useTranslation } from "react-i18next";
import { MyAvatar } from "../../Components/MyAvatar";
import { useUsersContext } from "../../Contexts/UsersContext";
import { useAppContext } from "../../Contexts/AppContext";
import { useWebSocketContext } from "../../Contexts/WebSocketContext";
import { SentMessagesCommands } from "../../Handlers/WebSocketMessageHandler";
export default function AllUsers() {
const webSocketContext = useWebSocketContext();
const appContext = useAppContext();
const usersContext = useUsersContext();
const { t } = useTranslation();
const [selectedRoleId, setSelectedRoleId] = useState("");
const [notificationApi, notificationContextHolder] =
notification.useNotification();
const [isCreateUserModalOpen, setIsCreateUserModalOpen] = useState(false);
const getTableContent = () => {
let items = [
{
title: t("allUsers.column.avatar"),
dataIndex: "avatar",
key: "avatar",
},
{
title: t("allUsers.column.username"),
dataIndex: "username",
key: "username",
},
{
title: t("allUsers.column.role"),
dataIndex: "role",
key: "role",
},
{
title: t("allUsers.column.connectionStatus"),
dataIndex: "connectionStatus",
key: "connectionStatus",
},
{
title: t("allUsers.column.lastOnline"),
dataIndex: "lastOnline",
key: "lastOnline",
},
];
if (
hasOnePermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.ACTION.CHANGE_ROLE,
Constants.PERMISSIONS.ALL_USERS.ACTION.DELETE_USER,
Constants.PERMISSIONS.ALL_USERS.ACTION.DEACTIVATE_USER
)
) {
items.push({
title: t("allUsers.column.action.title"),
key: "action",
render: (_, record) => (
<Space size="middle">
{hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.ACTION.CHANGE_ROLE
) &&
(usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).SortingOrder <
usersContext.roles.find((role) => role.Id === record._roleId)
.SortingOrder ||
usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).Master) && (
<Popconfirm
title={t(
"allUsers.column.action.roleChange.popconfirm.title"
)}
cancelText={t("common.button.cancel")}
okText={t(
"allUsers.column.action.roleChange.popconfirm.okText"
)}
onConfirm={() => onRoleChangeConfirm(record.key)}
okButtonProps={{
disabled:
selectedRoleId ===
usersContext.users.find((user) => user.Id === record.key)
.RoleId,
}}
description={
<Select
style={{ width: 250 }}
getPopupContainer={(node) => node.parentNode}
defaultValue={
usersContext.users.find(
(user) => user.Id === record.key
).RoleId
}
value={selectedRoleId}
onChange={(e) => setSelectedRoleId(e)}
>
{usersContext.roles.map((role) => {
if (
usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).Master ||
usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).SortingOrder < role.SortingOrder
) {
return (
<Select.Option key={role.Id}>
{role.DisplayName}
</Select.Option>
);
}
return null;
})}
</Select>
}
>
<Link
to="#"
onClick={() => {
setSelectedRoleId(
usersContext.users.find(
(user) => user.Id === record.key
).RoleId
);
}}
>
{t("allUsers.column.action.changeRole")}
</Link>
</Popconfirm>
)}
{hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.ACTION.DELETE_USER
) &&
(usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).SortingOrder <
usersContext.roles.find((role) => role.Id === record._roleId)
.SortingOrder ||
usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).Master) && (
<Popconfirm
placement="top"
cancelText={t("common.button.cancel")}
okText={t("allUsers.column.action.delete.popconfirm.okText")}
title={t("allUsers.column.action.delete.popconfirm.title")}
onConfirm={() => onUserDeletionConfirm(record.key)}
>
<Link to="#">{t("allUsers.column.action.delete.link")}</Link>
</Popconfirm>
)}
{!usersContext.users.find((user) => user.Id === record.key)
.Deactivated
? hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.ACTION.USER_DEACTIVATION
) &&
(usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).SortingOrder <
usersContext.roles.find((role) => role.Id === record._roleId)
.SortingOrder ||
usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).Master) && (
<Popconfirm
placement="top"
okText={t(
"allUsers.column.action.deactivate.popconfirm.okText"
)}
cancelText={t("common.button.cancel")}
title={t(
"allUsers.column.action.deactivate.popconfirm.title"
)}
onConfirm={() =>
onUserDeactivationConfirm(record.key, true)
}
>
<Link to="#">
{t("allUsers.column.action.deactivate.link")}
</Link>
</Popconfirm>
)
: hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.ACTION.USER_DEACTIVATION
) &&
(usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).SortingOrder <
usersContext.roles.find((role) => role.Id === record._roleId)
.SortingOrder ||
usersContext.roles.find(
(role) => role.Id === usersContext.roleId
).Master) && (
<Popconfirm
placement="top"
okText={t(
"allUsers.column.action.activate.popconfirm.okText"
)}
title={t(
"allUsers.column.action.activate.popconfirm.title"
)}
cancelText={t("common.button.cancel")}
onConfirm={() =>
onUserDeactivationConfirm(record.key, false)
}
>
<Link to="#">
{t("allUsers.column.action.activate.link")}
</Link>
</Popconfirm>
)}
</Space>
),
});
}
return items;
};
const activatedUsers = usersContext.users.filter(
(user) => user.Deactivated === false
);
const deactivatedUsers = usersContext.users.filter(
(user) => user.Deactivated === true
);
const getTableItems = (users) => {
let items = [];
users.sort(
(a, b) =>
usersContext.roles.find((r) => r.Id === a.RoleId).SortingOrder -
usersContext.roles.find((r) => r.Id === b.RoleId).SortingOrder
);
users.forEach((user) => {
items.push({
key: user.Id,
avatar: (
<Popover
placement="right"
trigger="hover"
content={<MyAvatar avatar={user.Avatar} avatarWidth={256} />}
>
<>
<MyAvatar avatar={user.Avatar} />
</>
</Popover>
),
role: usersContext.roles.find((role) => role.Id === user.RoleId)
.DisplayName,
_roleId: user.RoleId, // used as reference for user deletion
connectionStatus: getConnectionStatusItem(user.ConnectionStatus),
username: user.Username,
lastOnline: FormatDatetime(user.LastOnline),
});
});
return items;
};
const onRoleChangeConfirm = (targetUserId) => {
const existsRole = usersContext.roles.find(
(role) => role.Id === selectedRoleId
);
if (existsRole === undefined) {
notificationApi["error"]({
message: t("allUsers.roleChangeError.notification.message"),
description: t("allUsers.roleChangeError.notification.description"),
});
return;
}
webSocketContext.SendSocketMessage(
SentMessagesCommands.AllUsersUpdateUserRole,
{
UserId: targetUserId,
RoleId: selectedRoleId,
}
);
};
const onUserDeletionConfirm = (userId) => {
webSocketContext.SendSocketMessage(
SentMessagesCommands.AllUsersDeleteUser,
{
UserId: userId,
}
);
};
const onUserDeactivationConfirm = (userId, deactivate) => {
webSocketContext.SendSocketMessage(
SentMessagesCommands.AllUsersUserDeactivation,
{
UserId: userId,
Deactivation: deactivate,
}
);
};
useEffect(() => {
const usersRequest = () =>
myFetch("/users", "GET").then((data) => {
usersContext.setRoleId(data.RoleId);
usersContext.setUsers(data.Users);
usersContext.setRoles(data.Roles);
});
usersRequest();
const handleUsersRequest = () => usersRequest();
document.addEventListener(wsConnectionCustomEventName, handleUsersRequest);
return () =>
document.removeEventListener(
wsConnectionCustomEventName,
handleUsersRequest
);
}, []);
return (
<>
{notificationContextHolder}
<div
style={{
display: "flex",
justifyContent: "space-between",
}}
>
<Typography.Title level={4}>
{t("allUsers.header.allUsers")} ({activatedUsers.length})
</Typography.Title>
{hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.CREATE_NEW_USER
) && (
<Button
icon={<UserAddOutlined />}
onClick={() => setIsCreateUserModalOpen(true)}
>
{t("allUsers.button.createNewUser")}
</Button>
)}
</div>
<Table
scroll={{ x: "max-content" }}
columns={getTableContent()}
dataSource={getTableItems(activatedUsers)}
/>
{hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.ALL_USERS.ACTION.USER_DEACTIVATION
) &&
deactivatedUsers.length > 0 && (
<>
<Typography.Title level={4}>
{t("allUsers.header.deactivatedUsers")} ({deactivatedUsers.length}
)
</Typography.Title>
<Table
scroll={{ x: "max-content" }}
columns={getTableContent()}
dataSource={getTableItems(deactivatedUsers)}
/>
</>
)}
<CreateUserModal
isModalOpen={isCreateUserModalOpen}
setIsModalOpen={setIsCreateUserModalOpen}
/>
</>
);
}