319 lines
9.9 KiB
TypeScript
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;
|