Browser.tsx 4.84 KB
Newer Older
1
2
3
4
5
6
7
import React, {
  FunctionComponent,
  useCallback,
  useRef,
  useEffect
} from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
8
import { connect } from 'react-redux';
9

10
11
12
13
14
import BrowserBar from './browser-bar/BrowserBar';
import BrowserImage from './browser-image/BrowserImage';
import BrowserNavBar from './browser-nav/BrowserNavBar';
import TrackPanel from './track-panel/TrackPanel';
import Drawer from './drawer/Drawer';
15

16
import { RootState } from 'src/rootReducer';
17
18
19
20
21
22
import {
  BrowserOpenState,
  BrowserNavStates,
  ChrLocation
} from './browserState';
import {
23
  changeBrowserLocation,
24
  fetchObjectData,
25
26
27
  toggleDrawer,
  updateChrLocation,
  updateBrowserNavStates,
28
  updateBrowserActivated
29
} from './browserActions';
30
31
32
import {
  getBrowserOpenState,
  getDrawerOpened,
33
  getBrowserNavOpened,
34
  getChrLocation,
35
36
  getGenomeSelectorActive,
  getExampleObjects
37
} from './browserSelectors';
38

39
import styles from './Browser.scss';
40

41
import 'static/browser/browser.js';
42
import { getChrLocationFromStr, getChrLocationStr } from './browserHelper';
43

44
45
import { replace } from 'connected-react-router';

46
type StateProps = {
47
  browserNavOpened: boolean;
48
  browserOpenState: BrowserOpenState;
49
  chrLocation: ChrLocation;
50
  drawerOpened: boolean;
51
  exampleObjects: {};
52
  genomeSelectorActive: boolean;
53
54
55
};

type DispatchProps = {
56
57
58
59
  changeBrowserLocation: (
    chrLocation: ChrLocation,
    browserEl: HTMLDivElement
  ) => void;
60
  fetchObjectData: (objSymbol: string) => void;
61
  toggleDrawer: (drawerOpened: boolean) => void;
62
63
64
  updateBrowserActivated: (browserActivated: boolean) => void;
  updateBrowserNavStates: (browserNavStates: BrowserNavStates) => void;
  updateChrLocation: (chrLocation: ChrLocation) => void;
65
  replace: (path: string) => void;
66
};
67

68
69
type OwnProps = {};

70
type MatchParams = {
71
72
  location: string;
  objSymbol: string;
73
74
75
76
77
78
79
  species: string;
};

type BrowserProps = RouteComponentProps<MatchParams> &
  StateProps &
  DispatchProps &
  OwnProps;
80

81
82
83
export const Browser: FunctionComponent<BrowserProps> = (
  props: BrowserProps
) => {
84
85
  const browserRef: React.RefObject<HTMLDivElement> = useRef(null);

86
  const dispatchBrowserLocation = (chrLocation: ChrLocation) => {
87
    if (browserRef.current) {
88
      props.changeBrowserLocation(chrLocation, browserRef.current);
89
90
91
    }
  };

92
  useEffect(() => {
93
94
    const location = props.history.location.search;
    const { objSymbol } = props.match.params;
95
    const chrLocation = getChrLocationFromStr(location);
96

97
    dispatchBrowserLocation(chrLocation);
98
99
100
101
102
103
104
105
106
107

    let objectStableId = '';

    Object.values(props.exampleObjects).forEach((exampleObject: any) => {
      if (exampleObject.display_name === objSymbol) {
        objectStableId = exampleObject.stable_id;
      }
    });

    props.fetchObjectData(objectStableId);
108
  }, [props.match.params.objSymbol]);
109

110
  useEffect(() => {
111
    const { params } = props.match;
112
    const newChrLocationStr = getChrLocationStr(props.chrLocation);
113
114
115
    const newUrl = `/app/browser/${params.species}/${
      params.objSymbol
    }?region=${newChrLocationStr}`;
116

117
    props.replace(newUrl);
118
119
  }, [props.chrLocation]);

120
  const closeTrack = useCallback(() => {
121
    if (props.drawerOpened === false) {
122
123
124
      return;
    }

125
    props.toggleDrawer(false);
126
  }, [props.drawerOpened]);
127

128
129
  return (
    <section className={styles.browser}>
130
      <BrowserBar dispatchBrowserLocation={dispatchBrowserLocation} />
131
132
133
      {props.genomeSelectorActive ? (
        <div className={styles.browserOverlay} />
      ) : null}
134
135
136
137
138
139
140
      <div className={styles.browserInnerWrapper}>
        <div
          className={`${styles.browserImageWrapper} ${
            styles[props.browserOpenState]
          }`}
          onClick={closeTrack}
        >
141
142
143
          {props.browserNavOpened && !props.drawerOpened ? (
            <BrowserNavBar browserRef={browserRef} />
          ) : null}
144
145
146
147
148
149
150
          <BrowserImage
            browserRef={browserRef}
            browserNavOpened={props.browserNavOpened}
            updateBrowserActivated={props.updateBrowserActivated}
            updateBrowserNavStates={props.updateBrowserNavStates}
            updateChrLocation={props.updateChrLocation}
          />
151
        </div>
152
        <TrackPanel browserRef={browserRef} />
153
154
155
156
157
        {props.drawerOpened && <Drawer />}
      </div>
    </section>
  );
};
158

159
const mapStateToProps = (state: RootState): StateProps => ({
160
161
  browserNavOpened: getBrowserNavOpened(state),
  browserOpenState: getBrowserOpenState(state),
162
  chrLocation: getChrLocation(state),
163
  drawerOpened: getDrawerOpened(state),
164
  exampleObjects: getExampleObjects(state),
165
  genomeSelectorActive: getGenomeSelectorActive(state)
166
167
});

168
const mapDispatchToProps: DispatchProps = {
169
  changeBrowserLocation,
170
  fetchObjectData,
171
172
173
  toggleDrawer,
  updateBrowserActivated,
  updateBrowserNavStates,
174
175
  updateChrLocation,
  replace
176
177
};

178
179
180
181
182
183
export default withRouter(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(Browser)
);