import type { FC, JSX } from 'react'; import React, { useState, useEffect } from 'react'; import type { IUserGroupHasId, IUserGroupRelation, IUserHasId } from '@growi/core'; import { format as dateFnsFormat } from 'date-fns/format'; import { useTranslation } from 'next-i18next'; import Link from 'next/link'; import type { IExternalUserGroupHasId } from '~/features/external-user-group/interfaces/external-user-group'; import styles from './UserGroupTable.module.scss'; const userGroupEditLinkStyle = styles['user-group-edit-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, isExternalGroup?: boolean }; /* * 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; }; type UserGroupEditLinkProps = { group:IUserGroupHasId, isExternalGroup:boolean, } const UserGroupEditLink = (props: UserGroupEditLinkProps): JSX.Element => { return ( group {props.group.name} edit ); }; export const UserGroupTable: FC = ({ headerLabel, userGroups, userGroupRelations, childUserGroups, isAclEnabled, onEdit, onRemove, onDelete, isExternalGroup = false, }: Props) => { const { t } = useTranslation('admin'); /* * State */ const [groupIdToUsersMap, setGroupIdToUsersMap] = useState(generateGroupIdToUsersMap(userGroupRelations)); const [groupIdToChildGroupsMap, setGroupIdToChildGroupsMap] = useState(generateGroupIdToChildGroupsMap(childUserGroups)); /* * Function */ const findUserGroup = (e: React.ChangeEvent): IUserGroupHasId | undefined => { const groupId = e.target.getAttribute('data-user-group-id'); return userGroups.find((group) => { return group._id === groupId; }); }; const onClickEdit = async(e) => { if (onEdit == null) { return; } const userGroup = findUserGroup(e); if (userGroup == null) { return; } onEdit(userGroup); }; const onClickRemove = async(e) => { if (onRemove == null) { return; } const userGroup = findUserGroup(e); if (userGroup == null) { return; } try { await onRemove(userGroup); userGroup.parent = null; } catch { // } }; const onClickDelete = (e) => { // no preventDefault if (onDelete == null) { return; } const userGroup = findUserGroup(e); if (userGroup == null) { return; } onDelete(userGroup); }; /* * useEffect */ useEffect(() => { setGroupIdToUsersMap(generateGroupIdToUsersMap(userGroupRelations)); setGroupIdToChildGroupsMap(generateGroupIdToChildGroupsMap(childUserGroups)); }, [userGroupRelations, childUserGroups]); return (

{headerLabel}

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

    {group.name}

    ) }
  • ); })}
{dateFnsFormat(new Date(group.createdAt), 'yyyy-MM-dd')}
{onRemove != null && ( )}
); };