import { i18n } from '@kbn/i18n' ; import { isEmpty , last } from 'lodash' ; import React , { Fragment } from 'react' ; import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe' ; import { EmptyMessage } from '../../shared/empty_message' ; import { LibraryStacktrace } from './library_stacktrace' ; import { Stackframe as StackframeComponent } from './Stackframe' ; interface Props { stackframes ? : Stackframe [ ] ; codeLanguage ? : string ; } export function Stacktrace ( { stackframes = [ ] , codeLanguage } ) { if ( isEmpty ( stackframes ) ) { return ( < EmptyMessage heading = { i18n . translate ( 'xpack.apm.stacktraceTab.noStacktraceAvailableLabel' , { defaultMessage : 'No stack trace available.' , } ) } hideSubheading / > ) ; } const groups = getGroupedStackframes ( stackframes ) ; return ( < Fragment > { groups . map ( ( group , i ) => { if ( group . isLibraryFrame && groups . length > 1 ) { return ( < Fragment key = { i } > < LibraryStacktrace id = { i . toString ( ) } stackframes = { group . stackframes } codeLanguage = { codeLanguage } / > < /Fragment>); } return group . stackframes . map ( ( stackframe , idx ) => ( < Fragment key = { `${ i }-${ idx }` } > < StackframeComponent codeLanguage = { codeLanguage } id = { `${ i }-${ idx }` } initialIsOpen = { i === 0 && groups . length > 1 } stackframe = { stackframe } / > < /Fragment>)); } ) } < /Fragment>); } interface StackframesGroup { isLibraryFrame : boolean ; excludeFromGrouping : boolean ; stackframes : Stackframe [ ] ; } export function getGroupedStackframes ( stackframes ) { return stackframes . reduce ( ( acc , stackframe ) => { const prevGroup = last ( acc ) ; const shouldAppend = prevGroup && prevGroup . isLibraryFrame === stackframe . library_frame && ! prevGroup . excludeFromGrouping && ! stackframe . exclude_from_grouping ; if ( prevGroup && shouldAppend ) { prevGroup . stackframes . push ( stackframe ) ; return acc ; } acc . push ( { isLibraryFrame : Boolean ( stackframe . library_frame ) , excludeFromGrouping : Boolean ( stackframe . exclude_from_grouping ) , stackframes : [ stackframe ] , } ) ; return acc ; } , [ ] as StackframesGroup [ ] ) ; }