Wrapper.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, { PureComponent } from 'react';
  2. import { hot } from 'react-hot-loader';
  3. import { connect } from 'react-redux';
  4. import { updateLocation } from 'app/core/actions';
  5. import { StoreState } from 'app/types';
  6. import { ExploreUrlState } from 'app/types/explore';
  7. import Explore, { ExploreState } from './Explore';
  8. import { DEFAULT_RANGE } from './TimePicker';
  9. function parseUrlState(initial: string | undefined): ExploreUrlState {
  10. if (initial) {
  11. try {
  12. return JSON.parse(decodeURI(initial));
  13. } catch (e) {
  14. console.error(e);
  15. }
  16. }
  17. return { datasource: null, queries: [], range: DEFAULT_RANGE };
  18. }
  19. function serializeStateToUrlParam(state: ExploreState): string {
  20. const urlState: ExploreUrlState = {
  21. datasource: state.datasourceName,
  22. queries: state.queries.map(q => ({ query: q.query })),
  23. range: state.range,
  24. };
  25. return JSON.stringify(urlState);
  26. }
  27. interface WrapperProps {
  28. backendSrv?: any;
  29. datasourceSrv?: any;
  30. updateLocation: typeof updateLocation;
  31. urlStates: { [key: string]: string };
  32. }
  33. interface WrapperState {
  34. split: boolean;
  35. splitState: ExploreState;
  36. }
  37. const STATE_KEY_LEFT = 'state';
  38. const STATE_KEY_RIGHT = 'stateRight';
  39. export class Wrapper extends PureComponent<WrapperProps, WrapperState> {
  40. urlStates: { [key: string]: string };
  41. constructor(props: WrapperProps) {
  42. super(props);
  43. this.urlStates = props.urlStates;
  44. this.state = {
  45. split: Boolean(props.urlStates[STATE_KEY_RIGHT]),
  46. splitState: undefined,
  47. };
  48. }
  49. onChangeSplit = (split: boolean, splitState: ExploreState) => {
  50. this.setState({ split, splitState });
  51. };
  52. onSaveState = (key: string, state: ExploreState) => {
  53. const urlState = serializeStateToUrlParam(state);
  54. this.urlStates[key] = urlState;
  55. this.props.updateLocation({
  56. query: this.urlStates,
  57. });
  58. };
  59. render() {
  60. const { datasourceSrv } = this.props;
  61. // State overrides for props from first Explore
  62. const { split, splitState } = this.state;
  63. const urlStateLeft = parseUrlState(this.urlStates[STATE_KEY_LEFT]);
  64. const urlStateRight = parseUrlState(this.urlStates[STATE_KEY_RIGHT]);
  65. return (
  66. <div className="explore-wrapper">
  67. <Explore
  68. datasourceSrv={datasourceSrv}
  69. onChangeSplit={this.onChangeSplit}
  70. onSaveState={this.onSaveState}
  71. position="left"
  72. split={split}
  73. stateKey={STATE_KEY_LEFT}
  74. urlState={urlStateLeft}
  75. />
  76. {split && (
  77. <Explore
  78. datasourceSrv={datasourceSrv}
  79. onChangeSplit={this.onChangeSplit}
  80. onSaveState={this.onSaveState}
  81. position="right"
  82. split={split}
  83. splitState={splitState}
  84. stateKey={STATE_KEY_RIGHT}
  85. urlState={urlStateRight}
  86. />
  87. )}
  88. </div>
  89. );
  90. }
  91. }
  92. const mapStateToProps = (state: StoreState) => ({
  93. urlStates: state.location.query,
  94. });
  95. const mapDispatchToProps = {
  96. updateLocation,
  97. };
  98. export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(Wrapper));