import { i18n } from '@kbn/i18n' ; import { EuiBasicTable , EuiBasicTableColumn } from '@elastic/eui' ; import { orderBy } from 'lodash' ; import React , { ReactNode , useCallback , useMemo } from 'react' ; import { useHistory } from 'react-router-dom' ; import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params' ; import { fromQuery , toQuery } from '../links/url_helpers' ; export interface ITableColumn < T > { name : ReactNode ; actions ? : Array < Record < string , unknown > > ; field ? : string ; dataType ? : string ; align ? : string ; width ? : string ; sortable ? : boolean ; truncateText ? : boolean ; render ? : ( value : any , item : T ) => unknown ; } interface Props < T > { items : T [ ] ; columns : Array < ITableColumn < T > > ; initialPageIndex ? : number ; initialPageSize ? : number ; initialSortField ? : ITableColumn < T > [ 'field' ] ; initialSortDirection ? : 'asc' | 'desc' ; hidePerPageOptions ? : boolean ; noItemsMessage ? : React . ReactNode ; sortItems ? : boolean ; sortFn ? : ( items : T [ ] , sortField : string , sortDirection : 'asc' | 'desc' ) => T [ ] ; pagination ? : boolean ; isLoading ? : boolean ; error ? : boolean ; tableLayout ? : 'auto' | 'fixed' ; } function defaultSortFn < T extends any > ( items , sortField , sortDirection ) { return orderBy ( items , sortField , sortDirection ) ; } function UnoptimizedManagedTable < T > ( props ) { const history = useHistory ( ) ; const { items , columns , initialPageIndex = 0 , initialPageSize = 10 , initialSortField = props . columns [ 0 ] ?. field || '' , initialSortDirection = 'asc' , hidePerPageOptions = true , noItemsMessage , sortItems = true , sortFn = defaultSortFn , pagination = true , isLoading = false , error = false , tableLayout , } = props ; const { urlParams : { page = initialPageIndex , pageSize = initialPageSize , sortField = initialSortField , sortDirection = initialSortDirection , } , } = useLegacyUrlParams ( ) ; const renderedItems = useMemo ( ( ) => { const sortedItems = sortItems ? sortFn ( items , sortField , sortDirection as 'asc' | 'desc' ) : items ; return sortedItems . slice ( page * pageSize , ( page + 1 ) * pageSize ) ; } , [ page , pageSize , sortField , sortDirection , items , sortItems , sortFn ] ) ; const sort = useMemo ( ( ) => { return { sort : { field : sortField as keyof T , direction : sortDirection as 'asc' | 'desc' , } , } ; } , [ sortField , sortDirection ] ) ; const onTableChange = useCallback ( ( options ) => { history . push ( { ... history . location , search : fromQuery ( { ... toQuery ( history . location . search ) , page : options . page . index , pageSize : options . page . size , sortField : options . sort ?. field , sortDirection : options . sort ?. direction , } ) , } ) ; } , [ history ] ) ; const paginationProps = useMemo ( ( ) => { if ( ! pagination ) { return ; } return { hidePerPageOptions , totalItemCount : items . length , pageIndex : page , pageSize , } ; } , [ hidePerPageOptions , items , page , pageSize , pagination ] ) ; const showNoItemsMessage = useMemo ( ( ) => { return isLoading ? i18n . translate ( 'xpack.apm.managedTable.loadingDescription' , { defaultMessage : 'Loading…' , } ) : noItemsMessage ; } , [ isLoading , noItemsMessage ] ) ; return ( < EuiBasicTable loading = { isLoading } tableLayout = { tableLayout } error = { error ? i18n . translate ( 'xpack.apm.managedTable.errorMessage' , { defaultMessage : 'Failed to fetch' , } ) : '' } noItemsMessage = { showNoItemsMessage } items = { renderedItems } columns = { columns as unknown as Array < EuiBasicTableColumn < T >> } sorting = { sort } onChange = { onTableChange } { ... ( paginationProps ? { pagination : paginationProps } : { } ) } />); } const ManagedTable = React . memo ( UnoptimizedManagedTable ) as typeof UnoptimizedManagedTable ; export { ManagedTable , UnoptimizedManagedTable } ;