kibana/x-pack/plugins/apm/public/components/shared/Stacktrace/index.js
Søren Louv-Jansen ab47cae457
[APM] Distributed Tracing (#24062) (#24487)
* Adds traces overview with mock data (#22628)
* Updates service overview snapshots
* Adds tests for ManagedTable and ImpactBar
* Refactored transaction overview to use new managed table component
* Removed jsconfig file in apm
* [APM] Distributed tracing - Trace details (waterfall) (#22763)
* [APM] Add typescript to waterfall (#23635)
* [APM] Migrate get_trace and constants to Typescript (#23634)
* [APM] Add types for setup_request (#23762)
* [APM] Adds trace overview queries and some refactoring (#23605)
* ImpactBar component to align EuiProgress usage for impact bars
* Sharing some logic between transaction and trace queries
* Typescript support
* Quick fix ‘banana’
* [APM] Ensure backwards compatibility for v1 and v2 (#23636)
* Make interfaces versioned
* Rename eventType to docType
* Fixes trace links on traces overview (#24089)
* [APM] use react-redux-request (#24117)
* Updated yarn lockfile for new yarn version
* Updated dependency issues for react-router-dom types
* [APM] Display transaction info on span flyout (#24189)
* [APM] Display transaction info on span flyout
* Brings in real location and url param data for transaction flyout
* Converts flyout to TS
* Adds query param state for flyouts with ts support
* Updates styles and uses EuiTabs for transaction flyout
* [APM] Transaction flyout
* [APM] Minor docs cleanup (#24325)
* [APM] Minor docs cleanup
* [APM] Fix issues with v1 spans (#24332)
* [APM] Add agent marks (#24361)
* [APM] Typescript migration for the transaction endpoints (#24397)
* [APM] DT transaction sample header (#24294)

Transaction sample header completed
* Fixes link target for traces overview to include trans/trace ids as query params
* Converts Transaction index file to TS
* Adds trace link to sample section
* Refactors the trace link and applies it to two usages
* Implements transaction sample action context menu
* Calculates and implements duration percentage
* Re-typed how transaction groups work
* Fixes transaction flyout links and context menu
* Removes unnecessary ms multiplication
* Removes unused commented code
* Finalizes infra links
* Fixes some type shenanigans
2018-10-24 16:45:50 +02:00

131 lines
3.4 KiB
JavaScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { PureComponent } from 'react';
import styled from 'styled-components';
import { isEmpty, get } from 'lodash';
import CodePreview from '../../shared/CodePreview';
import { Ellipsis } from '../../shared/Icons';
import { units, px } from '../../../style/variables';
import EmptyMessage from '../../shared/EmptyMessage';
import { EuiLink, EuiTitle } from '@elastic/eui';
const LibraryFrameToggle = styled.div`
margin: 0 0 ${px(units.plus)} 0;
user-select: none;
`;
const LibraryFrames = styled.div``;
function getCollapsedLibraryFrames(stackframes) {
return stackframes.reduce((acc, stackframe) => {
if (!stackframe.libraryFrame) {
return [...acc, stackframe];
}
// current stackframe is library frame
const prevItem = acc[acc.length - 1];
if (!get(prevItem, 'libraryFrame')) {
return [...acc, { libraryFrame: true, stackframes: [stackframe] }];
}
return [
...acc.slice(0, -1),
{ ...prevItem, stackframes: [...prevItem.stackframes, stackframe] }
];
}, []);
}
class Stacktrace extends PureComponent {
state = {
libraryframes: {}
};
componentDidMount() {
if (!this.props.stackframes) {
// Don't do anything, if there are no stackframes
return false;
}
const hasAnyAppFrames = this.props.stackframes.some(
frame => !frame.libraryFrame
);
if (!hasAnyAppFrames) {
// If there are no app frames available, always show the only existing group
this.setState({ libraryframes: { 0: true } });
}
}
toggle = i =>
this.setState(({ libraryframes }) => {
return { libraryframes: { ...libraryframes, [i]: !libraryframes[i] } };
});
render() {
const { stackframes = [], codeLanguage } = this.props;
if (isEmpty(stackframes)) {
return <EmptyMessage heading="No stacktrace available." hideSubheading />;
}
return (
<div>
<EuiTitle size="xs">
<h3>Stack traces</h3>
</EuiTitle>
{getCollapsedLibraryFrames(stackframes).map((item, i) => {
if (!item.libraryFrame) {
return (
<CodePreview
key={i}
stackframe={item}
codeLanguage={codeLanguage}
/>
);
}
return (
<Libraryframes
key={i}
visible={this.state.libraryframes[i]}
stackframes={item.stackframes}
codeLanguage={codeLanguage}
onClick={() => this.toggle(i)}
/>
);
})}
</div>
);
}
}
function Libraryframes({ visible, stackframes, codeLanguage, onClick }) {
return (
<div>
<LibraryFrameToggle>
<EuiLink onClick={onClick}>
<Ellipsis horizontal={visible} style={{ marginRight: units.half }} />{' '}
{stackframes.length} library frames
</EuiLink>
</LibraryFrameToggle>
<LibraryFrames>
{visible &&
stackframes.map((stackframe, i) => (
<CodePreview
key={i}
stackframe={stackframe}
isLibraryFrame
codeLanguage={codeLanguage}
/>
))}
</LibraryFrames>
</div>
);
}
export default Stacktrace;