Wrapper.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import React, { PureComponent } from 'react';
  2. import { connect, ConnectedProps } from 'react-redux';
  3. import { locationService } from '@grafana/runtime';
  4. import { ErrorBoundaryAlert } from '@grafana/ui';
  5. import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
  6. import { StoreState } from 'app/types';
  7. import { ExploreId, ExploreQueryParams } from 'app/types/explore';
  8. import { Branding } from '../../core/components/Branding/Branding';
  9. import { getNavModel } from '../../core/selectors/navModel';
  10. import { ExploreActions } from './ExploreActions';
  11. import { ExplorePaneContainer } from './ExplorePaneContainer';
  12. import { lastSavedUrl, resetExploreAction, richHistoryUpdatedAction } from './state/main';
  13. interface RouteProps extends GrafanaRouteComponentProps<{}, ExploreQueryParams> {}
  14. interface OwnProps {}
  15. const mapStateToProps = (state: StoreState) => {
  16. return {
  17. navModel: getNavModel(state.navIndex, 'explore'),
  18. exploreState: state.explore,
  19. };
  20. };
  21. const mapDispatchToProps = {
  22. resetExploreAction,
  23. richHistoryUpdatedAction,
  24. };
  25. const connector = connect(mapStateToProps, mapDispatchToProps);
  26. type Props = OwnProps & RouteProps & ConnectedProps<typeof connector>;
  27. class WrapperUnconnected extends PureComponent<Props> {
  28. componentWillUnmount() {
  29. this.props.resetExploreAction({});
  30. }
  31. componentDidMount() {
  32. lastSavedUrl.left = undefined;
  33. lastSavedUrl.right = undefined;
  34. // timeSrv (which is used internally) on init reads `from` and `to` param from the URL and updates itself
  35. // using those value regardless of what is passed to the init method.
  36. // The updated value is then used by Explore to get the range for each pane.
  37. // This means that if `from` and `to` parameters are present in the URL,
  38. // it would be impossible to change the time range in Explore.
  39. // We are only doing this on mount for 2 reasons:
  40. // 1: Doing it on update means we'll enter a render loop.
  41. // 2: when parsing time in Explore (before feeding it to timeSrv) we make sure `from` is before `to` inside
  42. // each pane state in order to not trigger un URL update from timeSrv.
  43. const searchParams = locationService.getSearchObject();
  44. if (searchParams.from || searchParams.to) {
  45. locationService.partial({ from: undefined, to: undefined }, true);
  46. }
  47. }
  48. componentDidUpdate(prevProps: Props) {
  49. const { left, right } = this.props.queryParams;
  50. const hasSplit = Boolean(left) && Boolean(right);
  51. const datasourceTitle = hasSplit
  52. ? `${this.props.exploreState.left.datasourceInstance?.name} | ${this.props.exploreState.right?.datasourceInstance?.name}`
  53. : `${this.props.exploreState.left.datasourceInstance?.name}`;
  54. const documentTitle = `${this.props.navModel.main.text} - ${datasourceTitle} - ${Branding.AppTitle}`;
  55. document.title = documentTitle;
  56. }
  57. render() {
  58. const { left, right } = this.props.queryParams;
  59. const hasSplit = Boolean(left) && Boolean(right);
  60. return (
  61. <div className="page-scrollbar-wrapper">
  62. <ExploreActions exploreIdLeft={ExploreId.left} exploreIdRight={ExploreId.right} />
  63. <div className="explore-wrapper">
  64. <ErrorBoundaryAlert style="page">
  65. <ExplorePaneContainer split={hasSplit} exploreId={ExploreId.left} urlQuery={left} />
  66. </ErrorBoundaryAlert>
  67. {hasSplit && (
  68. <ErrorBoundaryAlert style="page">
  69. <ExplorePaneContainer split={hasSplit} exploreId={ExploreId.right} urlQuery={right} />
  70. </ErrorBoundaryAlert>
  71. )}
  72. </div>
  73. </div>
  74. );
  75. }
  76. }
  77. const Wrapper = connector(WrapperUnconnected);
  78. export default Wrapper;