Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded components (SearchTraces and Tracepage ) #263

Merged
merged 2 commits into from
Nov 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/jaeger-ui/src/components/App/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import type { Location } from 'react-router-dom';
import { withRouter } from 'react-router-dom';

import { isEmbed } from '../../utils/embedded';
import TopNav from './TopNav';
import { trackPageView } from '../../utils/tracking';

Expand Down Expand Up @@ -56,10 +56,12 @@ export class PageImpl extends React.Component<Props> {
<div>
<Helmet title="Jaeger UI" />
<Layout>
<Header className="Page--topNav">
<TopNav />
</Header>
<Content className="Page--content">{this.props.children}</Content>
{!isEmbed(this.props.search) && (
<Header className="Page--topNav">
<TopNav />
</Header>
)}
<Content className={!isEmbed(this.props.search) && 'Page--content'}>{this.props.children}</Content>
</Layout>
</div>
);
Expand Down
19 changes: 19 additions & 0 deletions packages/jaeger-ui/src/components/App/Page.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,23 @@ describe('<Page>', () => {
wrapper.setProps(props);
expect(trackPageView.mock.calls).toEqual([[props.pathname, props.search]]);
});

describe('Page embedded', () => {
beforeEach(() => {
trackPageView.mockReset();
props = {
pathname: String(Math.random()),
search: 'embed=v0&hideGraph',
};
wrapper = mount(<Page {...props} />);
});

it('does not explode', () => {
expect(wrapper).toBeDefined();
});

it('does not render Header', () => {
expect(wrapper.find('Header').length).toBe(0);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Props = {
linkTo: string,
toggleComparison: string => void,
trace: Trace,
disableComparision: boolean,
};

const isErrorTag = ({ key, value }) => key === 'error' && (value === true || value === 'true');
Expand All @@ -44,7 +45,14 @@ export default class ResultItem extends React.PureComponent<Props> {
props: Props;

render() {
const { durationPercent, isInDiffCohort, linkTo, toggleComparison, trace } = this.props;
const {
disableComparision,
durationPercent,
isInDiffCohort,
linkTo,
toggleComparison,
trace,
} = this.props;
const { duration, services, startTime, spans, traceName, traceID } = trace;
const mDate = moment(startTime / 1000);
const timeStr = mDate.format('h:mm:ss a');
Expand All @@ -61,6 +69,7 @@ export default class ResultItem extends React.PureComponent<Props> {
toggleComparison={toggleComparison}
traceID={traceID}
traceName={traceName}
disableComparision={disableComparision}
/>
<Link to={linkTo}>
<Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Props = {
toggleComparison: (string, boolean) => void,
traceID: string,
traceName: string,
disableComparision?: boolean,
};

export default class ResultItemTitle extends React.PureComponent<Props> {
Expand Down Expand Up @@ -64,6 +65,7 @@ export default class ResultItemTitle extends React.PureComponent<Props> {
state,
traceID,
traceName,
disableComparision,
} = this.props;
let WrapperComponent = 'div';
const wrapperProps: { [string]: string } = { className: 'ResultItemTitle--item ub-flex-auto' };
Expand All @@ -74,12 +76,14 @@ export default class ResultItemTitle extends React.PureComponent<Props> {
const isErred = state === fetchedState.ERROR;
return (
<div className="ResultItemTitle">
<Checkbox
className="ResultItemTitle--item ub-flex-none"
checked={!isErred && isInDiffCohort}
disabled={isErred}
onChange={this.toggleComparison}
/>
{!disableComparision && (
<Checkbox
className="ResultItemTitle--item ub-flex-none"
checked={!isErred && isInDiffCohort}
disabled={isErred}
onChange={this.toggleComparison}
/>
)}
<WrapperComponent {...wrapperProps}>
<span className="ResultItemTitle--durationBar" style={{ width: `${durationPercent}%` }} />
{duration != null && <span className="ub-right ub-relative">{formatDuration(duration)}</span>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// limitations under the License.

import * as React from 'react';
import { Select } from 'antd';
import { Select, Button } from 'antd';
import { Field, reduxForm, formValueSelector } from 'redux-form';

import DiffSelection from './DiffSelection';
Expand All @@ -27,6 +27,7 @@ import * as orderBy from '../../../model/order-by';
import { getPercentageOfDuration } from '../../../utils/date';
import prefixUrl from '../../../utils/prefix-url';
import reduxFormFieldAdapter from '../../../utils/redux-form-field-adapter';
import { VERSION_API } from '../../../utils/embedded';

import type { FetchedTrace } from '../../../types';

Expand All @@ -37,7 +38,10 @@ type SearchResultsProps = {
cohortRemoveTrace: string => void,
diffCohort: FetchedTrace[],
goToTrace: string => void,
embed?: boolean,
hideGraph?: boolean,
loading: boolean,
getSearchURL: () => string,
maxTraceDuration: number,
skipMessage?: boolean,
traces: TraceSummary[],
Expand Down Expand Up @@ -85,8 +89,20 @@ export default class SearchResults extends React.PureComponent<SearchResultsProp
};

render() {
const { loading, diffCohort, skipMessage, traces } = this.props;
const diffSelection = <DiffSelection toggleComparison={this.toggleComparison} traces={diffCohort} />;
const {
loading,
diffCohort,
skipMessage,
traces,
goToTrace,
embed,
hideGraph,
getSearchURL,
maxTraceDuration,
} = this.props;
const diffSelection = !embed && (
<DiffSelection toggleComparison={this.toggleComparison} traces={diffCohort} />
);
if (loading) {
return (
<React.Fragment>
Expand All @@ -107,28 +123,41 @@ export default class SearchResults extends React.PureComponent<SearchResultsProp
</React.Fragment>
);
}
const { goToTrace, maxTraceDuration } = this.props;
const cohortIds = new Set(diffCohort.map(datum => datum.id));
return (
<div>
<div>
<div className="SearchResults--header">
<div className="ub-p3">
<ScatterPlot
data={traces.map(t => ({
x: t.startTime,
y: t.duration,
traceID: t.traceID,
size: t.spans.length,
name: t.traceName,
}))}
onValueClick={t => {
goToTrace(t.traceID);
}}
/>
</div>
{!hideGraph && (
<div className="ub-p3">
<ScatterPlot
data={traces.map(t => ({
x: t.startTime,
y: t.duration,
traceID: t.traceID,
size: t.spans.length,
name: t.traceName,
}))}
onValueClick={t => {
goToTrace(t.traceID);
}}
/>
</div>
)}
<div className="SearchResults--headerOverview">
<SelectSort />
{embed && (
<label className="ub-right">
<Button
className="ub-mr2 ub-items-center"
icon="export"
target="_blank"
aljesusg marked this conversation as resolved.
Show resolved Hide resolved
href={getSearchURL()}
>
View Results
</Button>
</label>
)}
<h2 className="ub-m0">
{traces.length} Trace{traces.length > 1 && 's'}
</h2>
Expand All @@ -143,9 +172,16 @@ export default class SearchResults extends React.PureComponent<SearchResultsProp
<ResultItem
durationPercent={getPercentageOfDuration(trace.duration, maxTraceDuration)}
isInDiffCohort={cohortIds.has(trace.traceID)}
linkTo={prefixUrl(`/trace/${trace.traceID}`)}
linkTo={prefixUrl(
embed
? `/trace/${trace.traceID}?embed=${VERSION_API}&fromSearch=${encodeURIComponent(
getSearchURL()
)}`
: `/trace/${trace.traceID}`
)}
toggleComparison={this.toggleComparison}
trace={trace}
disableComparision={embed}
/>
</li>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import SearchResults from './';
import * as markers from './index.markers';
import ResultItem from './ResultItem';
import ScatterPlot from './ScatterPlot';
import DiffSelection from './DiffSelection.js';
import LoadingIndicator from '../../common/LoadingIndicator';

describe('<SearchResults>', () => {
Expand Down Expand Up @@ -48,6 +49,16 @@ describe('<SearchResults>', () => {
expect(wrapper.find(LoadingIndicator).length).toBe(1);
});

it('hide scatter plot if queryparam hideGraph', () => {
wrapper.setProps({ hideGraph: true });
expect(wrapper.find(ScatterPlot).length).toBe(0);
});

it('hide DiffSelection if is an embedded component', () => {
wrapper.setProps({ embed: true, getSearchURL: () => 'SEARCH_URL' });
expect(wrapper.find(DiffSelection).length).toBe(0);
});

describe('search finished with results', () => {
it('shows a scatter plot', () => {
expect(wrapper.find(ScatterPlot).length).toBe(1);
Expand Down
54 changes: 38 additions & 16 deletions packages/jaeger-ui/src/components/SearchTracePage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { fetchedState } from '../../constants';
import { sortTraces } from '../../model/search';
import getLastXformCacher from '../../utils/get-last-xform-cacher';
import prefixUrl from '../../utils/prefix-url';
import { isEmbed } from '../../utils/embedded';

import './index.css';
import JaegerLogo from '../../img/jaeger-logo.svg';
Expand Down Expand Up @@ -60,7 +61,13 @@ export class SearchTracePageImpl extends Component {
}

goToTrace = traceID => {
this.props.history.push(prefixUrl(`/trace/${traceID}`));
const url = this.props.embed ? `/trace/${traceID}?embed` : `/trace/${traceID}`;
this.props.history.push(prefixUrl(url));
};

getSearchURL = () => {
const { embed: _, ...urlQuery } = this.props.query;
return `/search?${queryString.stringify(urlQuery)}`;
aljesusg marked this conversation as resolved.
Show resolved Hide resolved
};

render() {
Expand All @@ -75,20 +82,24 @@ export class SearchTracePageImpl extends Component {
maxTraceDuration,
services,
traceResults,
embed,
hideGraph,
} = this.props;
const hasTraceResults = traceResults && traceResults.length > 0;
const showErrors = errors && !loadingTraces;
const showLogo = isHomepage && !hasTraceResults && !loadingTraces && !errors;
return (
<div>
<Row>
<Col span={6} className="SearchTracePage--column">
<div className="SearchTracePage--find">
<h2>Find Traces</h2>
{!loadingServices && services ? <SearchForm services={services} /> : <LoadingIndicator />}
</div>
</Col>
<Col span={18} className="SearchTracePage--column">
{!embed && (
<Col span={6} className="SearchTracePage--column">
<div className="SearchTracePage--find">
<h2>Find Traces</h2>
{!loadingServices && services ? <SearchForm services={services} /> : <LoadingIndicator />}
</div>
</Col>
)}
<Col span={!embed ? 18 : 24} className="SearchTracePage--column">
{showErrors && (
<div className="js-test-error-message">
<h2>There was an error querying for traces:</h2>
Expand All @@ -104,17 +115,21 @@ export class SearchTracePageImpl extends Component {
cohortRemoveTrace={cohortRemoveTrace}
diffCohort={diffCohort}
skipMessage={isHomepage}
getSearchURL={this.getSearchURL}
traces={traceResults}
embed={embed}
hideGraph={hideGraph}
/>
)}
{showLogo && (
<img
className="SearchTracePage--logo js-test-logo"
alt="presentation"
src={JaegerLogo}
width="400"
/>
)}
{showLogo &&
!embed && (
<img
className="SearchTracePage--logo js-test-logo"
alt="presentation"
src={JaegerLogo}
width="400"
/>
)}
</Col>
</Row>
</div>
Expand All @@ -123,7 +138,10 @@ export class SearchTracePageImpl extends Component {
}

SearchTracePageImpl.propTypes = {
query: PropTypes.object,
isHomepage: PropTypes.bool,
embed: PropTypes.bool,
hideGraph: PropTypes.bool,
// eslint-disable-next-line react/forbid-prop-types
traceResults: PropTypes.array,
diffCohort: PropTypes.array,
Expand Down Expand Up @@ -196,6 +214,7 @@ const stateServicesXformer = getLastXformCacher(stateServices => {
// export to test
export function mapStateToProps(state) {
const query = queryString.parse(state.router.location.search);
const { hideGraph } = queryString.parse(state.router.location.search);
const isHomepage = !Object.keys(query).length;
const { traces, maxDuration, traceError, loadingTraces } = stateTraceXformer(state.trace);
const diffCohort = stateTraceDiffXformer(state.trace, state.traceDiff);
Expand All @@ -210,7 +229,10 @@ export function mapStateToProps(state) {
const sortBy = sortFormSelector(state, 'sortBy');
const traceResults = sortedTracesXformer(traces, sortBy);
return {
query,
diffCohort,
embed: isEmbed(state.router.location.search),
hideGraph: hideGraph !== undefined,
isHomepage,
loadingServices,
loadingTraces,
Expand Down
Loading