UserGroupDeleteModal.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import React, {
  2. FC, useCallback, useState, useMemo,
  3. } from 'react';
  4. import { TFunctionResult } from 'i18next';
  5. import { useTranslation } from 'react-i18next';
  6. import {
  7. Modal, ModalHeader, ModalBody, ModalFooter,
  8. } from 'reactstrap';
  9. import AppContainer from '~/client/services/AppContainer';
  10. import { IUserGroupHasId } from '~/interfaces/user';
  11. import { CustomWindow } from '~/interfaces/global';
  12. import Xss from '~/services/xss';
  13. /**
  14. * Delete User Group Select component
  15. *
  16. * @export
  17. * @class GrantSelector
  18. * @extends {React.Component}
  19. */
  20. type Props = {
  21. appContainer: AppContainer,
  22. userGroups: IUserGroupHasId[],
  23. deleteUserGroup?: IUserGroupHasId,
  24. onDelete?: (deleteGroupId: string, actionName: string, transferToUserGroupId: string) => Promise<void> | void,
  25. isShow: boolean,
  26. onShow?: (group: IUserGroupHasId) => Promise<void> | void,
  27. onHide?: () => Promise<void> | void,
  28. };
  29. type AvailableOption = {
  30. id: number,
  31. actionForPages: string,
  32. iconClass: string,
  33. styleClass: string,
  34. label: TFunctionResult,
  35. };
  36. // actionName master constants
  37. const actionForPages = {
  38. public: 'public',
  39. delete: 'delete',
  40. transfer: 'transfer',
  41. };
  42. const UserGroupDeleteModal: FC<Props> = (props: Props) => {
  43. const xss: Xss = (window as CustomWindow).xss;
  44. const { t } = useTranslation();
  45. const availableOptions = useMemo<AvailableOption[]>(() => {
  46. return [
  47. {
  48. id: 1,
  49. actionForPages: actionForPages.public,
  50. iconClass: 'icon-people',
  51. styleClass: '',
  52. label: t('admin:user_group_management.delete_modal.publish_pages'),
  53. },
  54. {
  55. id: 2,
  56. actionForPages: actionForPages.delete,
  57. iconClass: 'icon-trash',
  58. styleClass: 'text-danger',
  59. label: t('admin:user_group_management.delete_modal.delete_pages'),
  60. },
  61. {
  62. id: 3,
  63. actionForPages: actionForPages.transfer,
  64. iconClass: 'icon-options',
  65. styleClass: '',
  66. label: t('admin:user_group_management.delete_modal.transfer_pages'),
  67. },
  68. ];
  69. }, []);
  70. /*
  71. * State
  72. */
  73. const [actionName, setActionName] = useState<string>('');
  74. const [transferToUserGroupId, setTransferToUserGroupId] = useState<string>('');
  75. /*
  76. * Function
  77. */
  78. const resetStates = useCallback(() => {
  79. setActionName('');
  80. setTransferToUserGroupId('');
  81. }, []);
  82. const onHide = useCallback(() => {
  83. if (props.onHide == null) {
  84. return;
  85. }
  86. resetStates();
  87. props.onHide();
  88. }, [props.onHide]);
  89. const handleActionChange = useCallback((e) => {
  90. const actionName = e.target.value;
  91. setActionName(actionName);
  92. }, [setActionName]);
  93. const handleGroupChange = useCallback((e) => {
  94. const transferToUserGroupId = e.target.value;
  95. setTransferToUserGroupId(transferToUserGroupId);
  96. }, []);
  97. const handleSubmit = useCallback((e) => {
  98. if (props.onDelete == null || props.deleteUserGroup == null) {
  99. return;
  100. }
  101. e.preventDefault();
  102. props.onDelete(
  103. props.deleteUserGroup._id,
  104. actionName,
  105. transferToUserGroupId,
  106. );
  107. }, [props.onDelete, props.deleteUserGroup, actionName, transferToUserGroupId]);
  108. const renderPageActionSelector = useCallback(() => {
  109. const options = availableOptions.map((opt) => {
  110. const dataContent = `<i class="icon icon-fw ${opt.iconClass} ${opt.styleClass}"></i> <span class="action-name ${opt.styleClass}">${opt.label}</span>`;
  111. return <option key={opt.id} value={opt.actionForPages} data-content={dataContent}>{opt.label}</option>;
  112. });
  113. return (
  114. <select
  115. name="actionName"
  116. className="form-control"
  117. placeholder="select"
  118. value={actionName}
  119. onChange={handleActionChange}
  120. >
  121. <option value="" disabled>{t('admin:user_group_management.delete_modal.dropdown_desc')}</option>
  122. {options}
  123. </select>
  124. );
  125. }, [handleActionChange, actionName, availableOptions]);
  126. const renderGroupSelector = useCallback(() => {
  127. const { deleteUserGroup } = props;
  128. if (deleteUserGroup == null) {
  129. return;
  130. }
  131. const groups = props.userGroups.filter((group) => {
  132. return group._id !== deleteUserGroup._id;
  133. });
  134. const options = groups.map((group) => {
  135. const dataContent = `<i class="icon icon-fw icon-organization"></i> ${xss.process(group.name)}`;
  136. return <option key={group._id} value={group._id} data-content={dataContent}>{xss.process(group.name)}</option>;
  137. });
  138. const defaultOptionText = groups.length === 0 ? t('admin:user_group_management.delete_modal.no_groups')
  139. : t('admin:user_group_management.delete_modal.select_group');
  140. return (
  141. <select
  142. name="transferToUserGroupId"
  143. className={`form-control ${actionName === actionForPages.transfer ? '' : 'd-none'}`}
  144. value={transferToUserGroupId}
  145. onChange={handleGroupChange}
  146. >
  147. <option value="" disabled>{defaultOptionText}</option>
  148. {options}
  149. </select>
  150. );
  151. }, [actionName, transferToUserGroupId, props.userGroups, props.deleteUserGroup]);
  152. const validateForm = useCallback(() => {
  153. let isValid = true;
  154. if (actionName === '') {
  155. isValid = false;
  156. }
  157. else if (actionName === actionForPages.transfer) {
  158. isValid = transferToUserGroupId !== '';
  159. }
  160. return isValid;
  161. }, [actionName, transferToUserGroupId]);
  162. return (
  163. <Modal className="modal-md" isOpen={props.isShow} toggle={onHide}>
  164. <ModalHeader tag="h4" toggle={onHide} className="bg-danger text-light">
  165. <i className="icon icon-fire"></i> {t('admin:user_group_management.delete_modal.header')}
  166. </ModalHeader>
  167. <ModalBody>
  168. <div>
  169. <span className="font-weight-bold">{t('admin:user_group_management.group_name')}</span> : &quot;{props?.deleteUserGroup?.name || ''}&quot;
  170. </div>
  171. <div className="text-danger mt-5">
  172. {t('admin:user_group_management.delete_modal.desc')}
  173. </div>
  174. </ModalBody>
  175. <ModalFooter>
  176. <form className="d-flex justify-content-between w-100" onSubmit={handleSubmit}>
  177. <div className="d-flex form-group mb-0">
  178. {renderPageActionSelector()}
  179. {renderGroupSelector()}
  180. </div>
  181. <button type="submit" value="" className="btn btn-sm btn-danger text-nowrap" disabled={!validateForm()}>
  182. <i className="icon icon-fire"></i> {t('Delete')}
  183. </button>
  184. </form>
  185. </ModalFooter>
  186. </Modal>
  187. );
  188. };
  189. export default UserGroupDeleteModal;