import React , { useState , useEffect } from 'react' ; import { EuiBadge , EuiBasicTableColumn , EuiInMemoryTable , EuiTextColor } from '@elastic/eui' ; import type { EuiSearchBarOnChangeArgs } from '@elastic/eui' ; import { ASRoleMapping } from '../../app_search/types' ; import { SingleUserRoleMapping } from '../../shared/types' ; import { WSRoleMapping } from '../../workplace_search/types' ; import { INVITATION_PENDING_LABEL , DEACTIVATED_LABEL , ALL_LABEL , FILTER_USERS_LABEL , NO_USERS_LABEL , ROLE_LABEL , USERNAME_LABEL , EMAIL_LABEL , GROUPS_LABEL , ENGINES_LABEL , } from './constants' ; import { UsersAndRolesRowActions } from './' ; interface AccessItem { name : string ; } interface SharedUser extends SingleUserRoleMapping < ASRoleMapping | WSRoleMapping > { accessItems : AccessItem [ ] ; username : string ; email : string | null ; roleType : string ; id : string ; enabled : boolean ; } interface SharedRoleMapping extends ASRoleMapping , WSRoleMapping { accessItems : AccessItem [ ] ; } interface Props { accessItemKey : 'groups' | 'engines' ; singleUserRoleMappings : Array < SingleUserRoleMapping < ASRoleMapping | WSRoleMapping > > ; initializeSingleUserRoleMapping ( roleMappingId ) : void ; handleDeleteMapping ( roleMappingId ) : void ; } const noItemsPlaceholder = < EuiTextColor color = "subdued" > & mdash ; < /EuiTextColor>; const invitationBadge = < EuiBadge color = "hollow" > { INVITATION_PENDING_LABEL } < /EuiBadge>; const deactivatedBadge = < EuiBadge color = "hollow" > { DEACTIVATED_LABEL } < /EuiBadge>; type Users = Array < Omit < SharedUser , 'elasticsearchUser | roleMapping' > > ; export const UsersTable = ( { accessItemKey , singleUserRoleMappings , initializeSingleUserRoleMapping , handleDeleteMapping , } ) => { const users = ( singleUserRoleMappings as SharedUser [ ] ) . map ( ( user ) => ( { username : user . elasticsearchUser . username , email : user . elasticsearchUser . email , enabled : user . elasticsearchUser . enabled , roleType : user . roleMapping . roleType , id : user . roleMapping . id , accessItems : ( user . roleMapping as SharedRoleMapping ) [ accessItemKey ] , invitation : user . invitation , } ) ) as unknown as Users ; const [ items , setItems ] = useState ( [ ] as Users ) ; useEffect ( ( ) => { setItems ( users ) ; } , [ singleUserRoleMappings ] ) ; const columns = [ { field : 'username' , name : USERNAME_LABEL , render : ( _ , { username , invitation , enabled } ) => ( < div data - test - subj = "UsernameCell" > { username } { ! invitation && ! enabled && deactivatedBadge } < /div>), } , { field : 'email' , name : EMAIL_LABEL , render : ( _ , { email , invitation } ) => { if ( ! email ) return noItemsPlaceholder ; return ( < div data - test - subj = "EmailDisplayValue" > { email } { invitation && invitationBadge } < /div>); } , } , { field : 'roleType' , name : ROLE_LABEL , render : ( _ , user ) => user . roleType , } , { field : 'accessItems' , name : accessItemKey === 'groups' ? GROUPS_LABEL : ENGINES_LABEL , render : ( _ , { accessItems } ) => { const numItems = accessItems . length ; if ( numItems === 0 ) return < span data - test - subj = "AllItems" > { ALL_LABEL } < /span>; const additionalItems = numItems > 2 ? ` + ${ numItems - 2 }` : '' ; const names = accessItems . map ( ( item ) => item . name ) ; return ( < span data - test - subj = "AccessItems" > { names . slice ( 0 , 2 ) . join ( ', ' ) + additionalItems } < /span>); } , } , { field : 'id' , name : '' , align : 'right' , render : ( _ , { id , username } ) => ( < UsersAndRolesRowActions username = { username } onManageClick = { ( ) => initializeSingleUserRoleMapping ( id ) } onDeleteClick = { ( ) => handleDeleteMapping ( id ) } />), } , ] ; const pagination = { hidePerPageOptions : true , pageSize : 10 , } ; const onQueryChange = ( { queryText } ) => { const filteredItems = users . filter ( ( user ) => { const normalizedTableItemString = JSON . stringify ( user ) . toLowerCase ( ) ; const normalizedQuery = queryText . toLowerCase ( ) ; return normalizedTableItemString . indexOf ( normalizedQuery ) !== - 1 ; } ) ; setItems ( filteredItems ) ; } ; const search = { onChange : onQueryChange , box : { incremental : true , fullWidth : false , placeholder : FILTER_USERS_LABEL , 'data-test-subj' : 'UsersTableSearchInput' , } , } ; return ( < EuiInMemoryTable data - test - subj = "UsersTable" columns = { columns } items = { items } search = { search } pagination = { pagination } message = { NO_USERS_LABEL } / > ) ; } ;