import React, { FC, useState, useEffect, } from 'react'; import type { IUserGroupHasId, IUserGroupRelation, IUserHasId } from '@growi/core'; import dateFnsFormat from 'date-fns/format'; import { useTranslation } from 'next-i18next'; import Link from 'next/link'; type Props = { headerLabel?: string, userGroups: IUserGroupHasId[], userGroupRelations: IUserGroupRelation[], childUserGroups: IUserGroupHasId[], isAclEnabled: boolean, onEdit?: (userGroup: IUserGroupHasId) => void | Promise, onRemove?: (userGroup: IUserGroupHasId) => void | Promise, onDelete?: (userGroup: IUserGroupHasId) => void | Promise, }; /* * Utility */ const generateGroupIdToUsersMap = (userGroupRelations: IUserGroupRelation[]): Record[]> => { const userGroupMap = {}; userGroupRelations.forEach((relation) => { const group = relation.relatedGroup as string; // must be an id of related group const users: Partial[] = userGroupMap[group] || []; users.push(relation.relatedUser as IUserHasId); // register userGroupMap[group] = users; }); return userGroupMap; }; const generateGroupIdToChildGroupsMap = (childUserGroups: IUserGroupHasId[]): Record => { const map = {}; childUserGroups.forEach((group) => { const parentId = group.parent as string; // must be an id const groups: Partial[] = map[parentId] || []; groups.push(group); // register map[parentId] = groups; }); return map; }; export const UserGroupTable: FC = (props: Props) => { const { t } = useTranslation('admin'); /* * State */ const [groupIdToUsersMap, setGroupIdToUsersMap] = useState(generateGroupIdToUsersMap(props.userGroupRelations)); const [groupIdToChildGroupsMap, setGroupIdToChildGroupsMap] = useState(generateGroupIdToChildGroupsMap(props.childUserGroups)); /* * Function */ const findUserGroup = (e: React.ChangeEvent): IUserGroupHasId | undefined => { const groupId = e.target.getAttribute('data-user-group-id'); return props.userGroups.find((group) => { return group._id === groupId; }); }; const onClickEdit = async(e) => { if (props.onEdit == null) { return; } const userGroup = findUserGroup(e); if (userGroup == null) { return; } props.onEdit(userGroup); }; const onClickRemove = async(e) => { if (props.onRemove == null) { return; } const userGroup = findUserGroup(e); if (userGroup == null) { return; } try { await props.onRemove(userGroup); userGroup.parent = null; } catch { // } }; const onClickDelete = (e) => { // no preventDefault if (props.onDelete == null) { return; } const userGroup = findUserGroup(e); if (userGroup == null) { return; } props.onDelete(userGroup); }; /* * useEffect */ useEffect(() => { setGroupIdToUsersMap(generateGroupIdToUsersMap(props.userGroupRelations)); setGroupIdToChildGroupsMap(generateGroupIdToChildGroupsMap(props.childUserGroups)); }, [props.userGroupRelations, props.childUserGroups]); return (

{props.headerLabel}

{props.userGroups.map((group) => { const users = groupIdToUsersMap[group._id]; return ( {props.isAclEnabled ? ( ) : ( ) } {props.isAclEnabled ? ( ) : ( ) } ); })}
{t('Name')} {t('Description')} {t('User')} {t('user_group_management.child_user_group')} {t('Created')}
{group.name}{group.name}{group.description}
    {users != null && users.map((user) => { return
  • {user.username}
  • ; })}
    {groupIdToChildGroupsMap[group._id] != null && groupIdToChildGroupsMap[group._id].map((group) => { return (
  • {props.isAclEnabled ? ( {group.name} ) : (

    {group.name}

    ) }
  • ); })}
{dateFnsFormat(new Date(group.createdAt), 'yyyy-MM-dd')}
); };