Files
SMATEC-FRONTEND/src/pages/Manager/User/Permission/components/AssignGroup.tsx

319 lines
9.9 KiB
TypeScript

import TreeSelectedGroup from '@/components/shared/TreeSelectedGroup';
import { HTTPSTATUS } from '@/constants';
import {
apiAssignToGroup,
apiQueryMembers,
apiUnassignToGroup,
} from '@/services/master/GroupController';
import { apiChangeRoleUser } from '@/services/master/UserController';
import { DeleteOutlined } from '@ant-design/icons';
import { ActionType, ProList, ProListMetas } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import {
Button,
Flex,
message,
Modal,
Popconfirm,
Segmented,
Space,
Tag,
Tooltip,
Typography,
} from 'antd';
import { useRef, useState } from 'react';
const { Text } = Typography;
type AssignGroupProps = {
user: MasterModel.UserResponse | null;
};
const AssignGroup = ({ user }: AssignGroupProps) => {
const groupActionRef = useRef<ActionType>();
const intl = useIntl();
const [assignedGroups, setAssignedGroups] = useState<MasterModel.GroupNode[]>(
[],
);
const [messageApi, contextHolder] = message.useMessage();
const [userRole, setUserRole] = useState<string>(
user?.metadata?.user_type || 'users',
);
const [open, setOpen] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const [groupSelected, setGroupSelected] = useState<string | string[] | null>(
null,
);
const columns: ProListMetas<MasterModel.GroupNode> = {
title: {
dataIndex: 'name',
render: (_, item: MasterModel.GroupNode) => (
<Typography.Paragraph
style={{
marginBottom: 0,
marginLeft: 8,
verticalAlign: 'middle',
display: 'inline-block',
}}
copyable
>
{item?.name}
</Typography.Paragraph>
),
},
subTitle: {
render: (_, entity) => {
return (
<Space>
<Tooltip
title={intl.formatMessage({
id: 'master.groups.code',
defaultMessage: 'Mã đơn vị',
})}
>
<Tag color="blue">{entity?.metadata?.code || '-'}</Tag>
</Tooltip>
<Tooltip
title={intl.formatMessage({
id: 'master.groups.short_name',
defaultMessage: 'Tên viết tắt',
})}
>
<Tag color="green">{entity?.metadata?.short_name || '-'}</Tag>
</Tooltip>
</Space>
);
},
},
actions: {
render: (_, item: MasterModel.GroupNode) => {
return (
<Popconfirm
title={`${intl.formatMessage({
id: 'master.users.unassign.content',
defaultMessage: 'Are you sure unassign this group',
})} ${item?.name}?`}
onConfirm={async () => {
try {
const body: MasterModel.AssignMemberRequest = {
group_id: item.id,
type: 'users',
members: [user?.id || ''],
};
const success = await apiUnassignToGroup(body);
if (success.status === HTTPSTATUS.HTTP_NOCONTENT) {
messageApi.success(
intl.formatMessage({
id: 'master.users.unassign.success',
defaultMessage: 'Unassign group successfully',
}),
);
groupActionRef.current?.reload();
} else {
throw new Error('Unassign group failed');
}
} catch (error) {
console.error('Error when unassign group: ', error);
messageApi.error(
intl.formatMessage({
id: 'master.users.unassign.fail',
defaultMessage: 'Unassign group failed',
}),
);
}
}}
>
<Button type="primary" danger icon={<DeleteOutlined />} />
</Popconfirm>
);
},
},
};
const showModal = () => {
setOpen(true);
};
const handleAssignUserToGroup = async () => {
setConfirmLoading(true);
try {
const body: MasterModel.AssignMemberRequest = {
group_id: groupSelected as string,
type: userRole === 'admin' ? 'admin' : 'users',
members: [user?.id || ''],
};
const resp = await apiAssignToGroup(body);
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
messageApi.success(
intl.formatMessage({
id: 'master.users.assign.success',
defaultMessage: 'Assign group successfully',
}),
);
groupActionRef.current?.reload();
setOpen(false);
} else {
throw new Error('Assign group failed');
}
} catch (error) {
console.error('Error when assign group: ', error);
messageApi.error(
intl.formatMessage({
id: 'master.users.assign.fail',
defaultMessage: 'Assign group failed',
}),
);
} finally {
setConfirmLoading(false);
}
};
const handleCancel = () => {
setOpen(false);
};
return (
<>
{contextHolder}
<Modal
title={intl.formatMessage({
id: 'master.users.group_assign.button.title',
defaultMessage: 'Assign Groups',
})}
open={open}
onOk={handleAssignUserToGroup}
confirmLoading={confirmLoading}
onCancel={handleCancel}
>
<Flex vertical gap={5}>
<Text>
{intl.formatMessage({
id: 'master.users.group_assign.select.title',
defaultMessage: 'Select Group',
})}
:
</Text>
<TreeSelectedGroup
disabled
groupIds={assignedGroups.map((group) => group.id)}
onSelected={(value) => {
setGroupSelected(value);
}}
/>
</Flex>
</Modal>
<ProList<MasterModel.GroupNode>
headerTitle={intl.formatMessage({
id: 'master.users.group_assign.title',
defaultMessage: 'Assigned list',
})}
actionRef={groupActionRef}
metas={columns}
toolBarRender={() => [
user?.metadata?.user_type !== 'enduser' && (
<Segmented
key="role"
value={userRole}
onChange={(value) => {
Modal.confirm({
title: intl.formatMessage({
id: 'master.users.change_role.confirm.title',
defaultMessage: 'Xác nhận thay đổi vai trò',
}),
content:
userRole === 'admin'
? intl.formatMessage({
id: 'master.users.change_role.user.content',
defaultMessage:
'Bạn có chắc muốn thay đổi vai trò thành giám sát đơn vị không?',
})
: intl.formatMessage({
id: 'master.users.change_role.admin.content',
defaultMessage:
'Bạn có chắc muốn thay đổi vai trò thành quản lý đơn vị không?',
}),
onOk: async () => {
try {
const resp = await apiChangeRoleUser(
user?.id || '',
value as 'users' | 'admin',
);
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
messageApi.success(
intl.formatMessage({
id: 'master.users.change_role.user.success',
defaultMessage: 'Role change successful',
}),
);
groupActionRef.current?.reload();
setUserRole(value as string);
} else {
throw new Error('Change role failed');
}
} catch (error) {
console.error('Error when change role user: ', error);
messageApi.error(
intl.formatMessage({
id: 'master.users.change_role.user.fail',
defaultMessage: 'Role change failed',
}),
);
}
},
});
}}
options={[
{
label: intl.formatMessage({
id: 'master.users.role.user',
defaultMessage: 'Giám sát',
}),
value: 'users',
},
{
label: intl.formatMessage({
id: 'master.users.role.admin',
defaultMessage: 'Quản lý',
}),
value: 'admin',
},
]}
/>
),
<Button
key="assign"
type="primary"
onClick={() => {
showModal();
}}
>
{intl.formatMessage({
id: 'master.users.group_assign.button.title',
defaultMessage: 'Assign',
})}
</Button>,
]}
request={async () => {
if (user?.id) {
const resp = await apiQueryMembers(user.id);
if (resp?.groups) {
setAssignedGroups(resp.groups);
return Promise.resolve({
success: true,
data: resp?.groups,
total: resp?.groups?.length || 0,
});
}
}
return Promise.resolve({
success: false,
data: [],
total: 0,
});
}}
rowKey="id"
search={false}
/>
</>
);
};
export default AssignGroup;