| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- import type { FC } from 'react';
- import React, { useCallback, useState, useMemo } from 'react';
- import {
- getIdForRef, isPopulated, type IGrantedGroup, type IUserGroupHasId,
- } from '@growi/core';
- import { useTranslation } from 'next-i18next';
- import {
- Modal, ModalHeader, ModalBody, ModalFooter,
- } from 'reactstrap';
- import { PageActionOnGroupDelete } from '~/interfaces/user-group';
- /**
- * Delete User Group Select component
- *
- * @export
- * @class GrantSelector
- * @extends {React.Component}
- */
- type Props = {
- userGroups: IGrantedGroup[],
- deleteUserGroup?: IUserGroupHasId,
- onDelete?: (deleteGroupId: string, actionName: PageActionOnGroupDelete, transferToUserGroup: IGrantedGroup | null) => Promise<void> | void,
- isShow: boolean,
- onHide?: () => Promise<void> | void,
- };
- type AvailableOption = {
- id: number,
- actionForPages: PageActionOnGroupDelete,
- label: string,
- };
- export const UserGroupDeleteModal: FC<Props> = (props: Props) => {
- const { t } = useTranslation();
- const {
- onHide, onDelete, userGroups, deleteUserGroup,
- } = props;
- const availableOptions = useMemo<AvailableOption[]>(() => {
- return [
- {
- id: 1,
- actionForPages: PageActionOnGroupDelete.publicize,
- label: t('admin:user_group_management.delete_modal.publish_pages'),
- },
- {
- id: 2,
- actionForPages: PageActionOnGroupDelete.delete,
- label: t('admin:user_group_management.delete_modal.delete_pages'),
- },
- {
- id: 3,
- actionForPages: PageActionOnGroupDelete.transfer,
- label: t('admin:user_group_management.delete_modal.transfer_pages'),
- },
- ];
- }, [t]);
- /*
- * State
- */
- const [actionName, setActionName] = useState<PageActionOnGroupDelete | null>(null);
- const [transferToUserGroup, setTransferToUserGroup] = useState<IGrantedGroup | null>(null);
- /*
- * Function
- */
- const resetStates = useCallback(() => {
- setActionName(null);
- setTransferToUserGroup(null);
- }, []);
- const toggleHandler = useCallback(() => {
- if (onHide == null) {
- return;
- }
- resetStates();
- onHide();
- }, [onHide, resetStates]);
- const handleActionChange = useCallback((e) => {
- const actionName = e.target.value;
- setActionName(actionName);
- }, [setActionName]);
- const handleGroupChange = useCallback((e) => {
- const transferToUserGroupId = e.target.value;
- const selectedGroup = userGroups.find(group => getIdForRef(group.item) === transferToUserGroupId) ?? null;
- setTransferToUserGroup(selectedGroup);
- }, [userGroups]);
- const handleSubmit = useCallback((e) => {
- if (onDelete == null || deleteUserGroup == null || actionName == null) {
- return;
- }
- e.preventDefault();
- onDelete(
- deleteUserGroup._id,
- actionName,
- transferToUserGroup,
- );
- }, [onDelete, deleteUserGroup, actionName, transferToUserGroup]);
- const renderPageActionSelector = useCallback(() => {
- const options = availableOptions.map((opt) => {
- return <option key={opt.id} value={opt.actionForPages}>{opt.label}</option>;
- });
- // TODO: Use GROWI original dropdown.
- // refs: https://redmine.weseek.co.jp/issues/142614
- return (
- <select
- name="actionName"
- className="form-control"
- placeholder="select"
- value={actionName ?? ''}
- onChange={handleActionChange}
- >
- <option value="" disabled>{t('admin:user_group_management.delete_modal.dropdown_desc')}</option>
- {options}
- </select>
- );
- }, [availableOptions, actionName, handleActionChange, t]);
- const renderGroupSelector = useCallback(() => {
- if (deleteUserGroup == null) {
- return;
- }
- const groups = userGroups.filter((group) => {
- return getIdForRef(group.item) !== deleteUserGroup._id;
- });
- const options = groups.map((group) => {
- const groupId = getIdForRef(group.item);
- const groupName = isPopulated(group.item) ? group.item.name : null;
- return { id: groupId, name: groupName };
- }).filter(obj => obj.name != null)
- .map(obj => <option key={obj.id} value={obj.id}>{obj.name}</option>);
- const defaultOptionText = groups.length === 0 ? t('admin:user_group_management.delete_modal.no_groups')
- : t('admin:user_group_management.delete_modal.select_group');
- return (
- <select
- name="transferToUserGroup"
- className={`form-control ${actionName === PageActionOnGroupDelete.transfer ? '' : 'd-none'}`}
- value={transferToUserGroup != null ? getIdForRef(transferToUserGroup.item) : ''}
- onChange={handleGroupChange}
- >
- <option value="" disabled>{defaultOptionText}</option>
- {options}
- </select>
- );
- }, [deleteUserGroup, userGroups, t, actionName, transferToUserGroup, handleGroupChange]);
- const validateForm = useCallback(() => {
- let isValid = true;
- if (actionName === null) {
- isValid = false;
- }
- else if (actionName === PageActionOnGroupDelete.transfer) {
- isValid = transferToUserGroup != null;
- }
- return isValid;
- }, [actionName, transferToUserGroup]);
- return (
- <Modal className="modal-md" isOpen={props.isShow} toggle={toggleHandler}>
- <ModalHeader tag="h4" toggle={toggleHandler}>
- <span className="material-symbols-outlined">delete_forever</span> {t('admin:user_group_management.delete_modal.header')}
- </ModalHeader>
- <ModalBody>
- <div>
- <span className="fw-bold">{t('admin:user_group_management.group_name')}</span> : "{props?.deleteUserGroup?.name || ''}"
- </div>
- <div className="text-danger mt-3">
- {t('admin:user_group_management.delete_modal.desc')}
- </div>
- </ModalBody>
- <ModalFooter>
- <form className="d-flex justify-content-between w-100" onSubmit={handleSubmit}>
- <div className="d-flex mb-0 me-3">
- {renderPageActionSelector()}
- {renderGroupSelector()}
- </div>
- <button type="submit" value="" className="btn btn-sm btn-danger text-nowrap" disabled={!validateForm()}>
- <span className="material-symbols-outlined">delete_forever</span> {t('Delete')}
- </button>
- </form>
- {actionName === PageActionOnGroupDelete.publicize && (
- <div className="form-text text-muted">
- <small>{t('admin:user_group_management.delete_modal.option_explanation')}</small>
- </div>
- )}
- </ModalFooter>
- </Modal>
- );
- };
|