diff --git a/src/components/App/Page.js b/src/components/App/Page.js index 4ec00fd4b6..8a28a5bc25 100644 --- a/src/components/App/Page.js +++ b/src/components/App/Page.js @@ -1,3 +1,5 @@ +// @flow + // Copyright (c) 2017 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -18,27 +20,54 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import PropTypes from 'prop-types'; -import React from 'react'; +import * as React from 'react'; import Helmet from 'react-helmet'; +import { connect } from 'react-redux'; +import type { Location } from 'react-router-dom'; import TopNav from './TopNav'; +import { trackPageView } from '../../utils/metrics'; import './Page.css'; -export default function JaegerUIPage(props) { - const { children } = props; - return ( -
- - -
- {children} -
-
- ); +type PageProps = { + location: Location, + children: React.Node, +}; + +class Page extends React.Component { + props: PageProps; + + componentDidMount() { + const { pathname, search } = this.props.location; + trackPageView(pathname, search); + } + + componentWillReceiveProps(nextProps: PageProps) { + const { pathname, search } = this.props.location; + const { pathname: nextPathname, search: nextSearch } = nextProps.location; + if (pathname !== nextPathname || search !== nextSearch) { + trackPageView(nextPathname, nextSearch); + } + } + + render() { + const { children } = this.props; + return ( +
+ + +
+ {children} +
+
+ ); + } } -JaegerUIPage.propTypes = { - children: PropTypes.node, -}; +function mapStateToProps(state, ownProps) { + const { location } = state.routing; + return { ...ownProps, location }; +} + +export default connect(mapStateToProps)(Page); diff --git a/src/components/App/index.js b/src/components/App/index.js index 7a2ff2e59a..3e27b5d5fb 100644 --- a/src/components/App/index.js +++ b/src/components/App/index.js @@ -29,7 +29,6 @@ import 'semantic-ui-css/semantic.min.css'; import Page from './Page'; import NotFound from './NotFound'; -import trackedComponentEnahncer from './tracked-component-enhancer'; import { ConnectedDependencyGraphPage } from '../DependencyGraph'; import { ConnectedSearchTracePage } from '../SearchTracePage'; import { ConnectedTracePage } from '../TracePage'; @@ -41,10 +40,6 @@ import './App.css'; const defaultHistory = createHistory(); -const TrackedSearchPage = trackedComponentEnahncer(ConnectedSearchTracePage); -const TrackedTracePage = trackedComponentEnahncer(ConnectedTracePage); -const TrackedDependencyPage = trackedComponentEnahncer(ConnectedDependencyGraphPage); - export default class JaegerUIApp extends Component { static get propTypes() { return { @@ -73,9 +68,9 @@ export default class JaegerUIApp extends Component { - - - + + + diff --git a/src/components/App/tracked-component-enhancer.js b/src/components/App/tracked-component-enhancer.js deleted file mode 100644 index a94fb6eb74..0000000000 --- a/src/components/App/tracked-component-enhancer.js +++ /dev/null @@ -1,60 +0,0 @@ -// @flow - -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import * as React from 'react'; -import type { Location } from 'react-router-dom'; - -import { trackPageView } from '../../utils/metrics'; - -type TrackedComponentProps = { - location: Location, -}; - -/** - * Wrap `Component` to add tracking based on changes in - * `props.location.pathname` and `props.location.search`. If either change, a - * page-view is tracked. - */ -export default function trackedComponentEnhancer(Component: any) { - class TrackedComponent extends React.Component { - props: TrackedComponentProps; - - componentDidMount() { - const { pathname, search } = this.props.location; - trackPageView(pathname, search); - } - - componentWillReceiveProps(nextProps: TrackedComponentProps) { - const { pathname, search } = this.props.location; - const { pathname: nextPathname, search: nextSearch } = nextProps.location; - if (pathname !== nextPathname || search !== nextSearch) { - trackPageView(nextPathname, nextSearch); - } - } - - render() { - return ; - } - } - - return TrackedComponent; -}