BrowserBar.tsx 6.78 KB
Newer Older
1
import React, { FunctionComponent, Fragment, useState, useEffect } from 'react';
2
import { connect } from 'react-redux';
Andrey Azov's avatar
Andrey Azov committed
3
import classNames from 'classnames';
4

Andrey Azov's avatar
Andrey Azov committed
5
import { browserInfoConfig, BrowserInfoItem } from '../browserConfig';
6
7
import { TrackType } from '../track-panel/trackPanelConfig';

8
import { toggleBrowserNav, toggleGenomeSelector } from '../browserActions';
9
import { ChrLocation } from '../browserState';
10
11
12
import {
  getBrowserNavOpened,
  getChrLocation,
13
  getBrowserActivated,
14
  getDefaultChrLocation,
15
16
17
18
19
  getGenomeSelectorActive
} from '../browserSelectors';
import { getDrawerOpened } from '../drawer/drawerSelectors';
import { getEnsObjectInfo } from 'src/ens-object/ensObjectSelectors';
import {
20
  getSelectedBrowserTab,
21
22
  getTrackPanelModalOpened,
  getTrackPanelOpened
23
24
25
} from '../track-panel/trackPanelSelectors';
import { selectBrowserTab } from '../track-panel/trackPanelActions';
import { toggleDrawer } from '../drawer/drawerActions';
Andrey Azov's avatar
Andrey Azov committed
26
import { RootState } from 'src/store';
27

Imran Salam's avatar
Imran Salam committed
28
import BrowserReset from '../browser-reset/BrowserReset';
29
import BrowserGenomeSelector from '../browser-genome-selector/BrowserGenomeSelector';
30
import BrowserTabs from '../browser-tabs/BrowserTabs';
31
32

import styles from './BrowserBar.scss';
33

34
type StateProps = {
35
  browserActivated: boolean;
36
  browserNavOpened: boolean;
37
  chrLocation: ChrLocation;
38
  defaultChrLocation: ChrLocation;
39
  drawerOpened: boolean;
40
  genomeSelectorActive: boolean;
41
  ensObjectInfo: any;
42
  selectedBrowserTab: TrackType;
43
  trackPanelModalOpened: boolean;
44
  trackPanelOpened: boolean;
45
46
47
};

type DispatchProps = {
48
  selectBrowserTab: (selectedBrowserTab: TrackType) => void;
49
  toggleBrowserNav: () => void;
50
  toggleDrawer: (drawerOpened: boolean) => void;
51
  toggleGenomeSelector: (genomeSelectorActive: boolean) => void;
52
53
};

Imran Salam's avatar
Imran Salam committed
54
type OwnProps = {
55
  dispatchBrowserLocation: (chrLocation: ChrLocation) => void;
Imran Salam's avatar
Imran Salam committed
56
};
57
58
59

type BrowserBarProps = StateProps & DispatchProps & OwnProps;

Andrey Azov's avatar
Andrey Azov committed
60
61
62
63
64
65
66
67
68
69
type BrowserInfoProps = {
  ensObjectInfo: any;
};

type BrowserNavigatorButtonProps = {
  toggleNavigator: () => void;
  navigator: BrowserInfoItem;
  icon: string; // TODO: use inline SVG
};

Imran Salam's avatar
Imran Salam committed
70
71
72
export const BrowserBar: FunctionComponent<BrowserBarProps> = (
  props: BrowserBarProps
) => {
Andrey Azov's avatar
Andrey Azov committed
73
  const shouldShowBrowserInfo = () => {
74
    const [, chrStart, chrEnd] = props.defaultChrLocation;
Andrey Azov's avatar
Andrey Azov committed
75
    const isLocationOfWholeChromosome = chrStart === 0 && chrEnd === 0;
76

Andrey Azov's avatar
Andrey Azov committed
77
    return !(props.genomeSelectorActive || isLocationOfWholeChromosome);
78
79
  };

80
  const { navigator } = browserInfoConfig;
Andrey Azov's avatar
Andrey Azov committed
81
82
83
  const [showBrowserInfo, toggleShowBrowserInfo] = useState(
    shouldShowBrowserInfo()
  );
84

Andrey Azov's avatar
Andrey Azov committed
85
86
87
88
  const setBrowserInfoVisibility = () => {
    const shouldToggleVisibility = showBrowserInfo !== shouldShowBrowserInfo();
    if (shouldToggleVisibility) {
      toggleShowBrowserInfo(!showBrowserInfo);
89
90
91
    }
  };

Andrey Azov's avatar
Andrey Azov committed
92
93
94
95
  useEffect(() => {
    setBrowserInfoVisibility();
  }, [props.defaultChrLocation, props.genomeSelectorActive]);

96
  const getBrowserNavIcon = () => {
97
    if (props.drawerOpened === true) {
Andrey Azov's avatar
Andrey Azov committed
98
      return navigator.icon.grey as string;
99
    } else if (props.browserNavOpened === true) {
Andrey Azov's avatar
Andrey Azov committed
100
      return navigator.icon.selected as string;
101
102
103
104
105
    } else {
      return navigator.icon.default;
    }
  };

106
107
108
109
110
111
112
113
  const toggleNavigator = () => {
    if (props.drawerOpened === true) {
      return;
    }

    props.toggleBrowserNav();
  };

Andrey Azov's avatar
Andrey Azov committed
114
115
116
117
118
  const className = classNames(styles.browserInfo, {
    [styles.browserInfoExpanded]: !props.trackPanelOpened,
    [styles.browserInfoGreyed]: props.drawerOpened
  });

Imran Salam's avatar
Imran Salam committed
119
120
  return (
    <div className={styles.browserBar}>
Andrey Azov's avatar
Andrey Azov committed
121
      <div className={className}>
Imran Salam's avatar
Imran Salam committed
122
        <dl className={styles.browserInfoLeft}>
123
          <BrowserReset
124
            dispatchBrowserLocation={props.dispatchBrowserLocation}
125
126
            chrLocation={props.chrLocation}
            defaultChrLocation={props.defaultChrLocation}
127
            drawerOpened={props.drawerOpened}
128
          />
Andrey Azov's avatar
Andrey Azov committed
129
130
131
          {showBrowserInfo && (
            <BrowserInfo ensObjectInfo={props.ensObjectInfo} />
          )}
Imran Salam's avatar
Imran Salam committed
132
133
        </dl>
        <dl className={styles.browserInfoRight}>
134
135
          <BrowserGenomeSelector
            browserActivated={props.browserActivated}
136
            dispatchBrowserLocation={props.dispatchBrowserLocation}
137
            chrLocation={props.chrLocation}
138
            drawerOpened={props.drawerOpened}
139
140
            genomeSelectorActive={props.genomeSelectorActive}
            toggleGenomeSelector={props.toggleGenomeSelector}
141
          />
Andrey Azov's avatar
Andrey Azov committed
142
143
144
145
146
147
          {!props.genomeSelectorActive && (
            <BrowserNavigatorButton
              navigator={navigator}
              toggleNavigator={toggleNavigator}
              icon={getBrowserNavIcon()}
            />
148
          )}
149
150
        </dl>
      </div>
Andrey Azov's avatar
Andrey Azov committed
151
      {props.trackPanelOpened && (
152
153
154
155
156
157
158
159
        <BrowserTabs
          drawerOpened={props.drawerOpened}
          genomeSelectorActive={props.genomeSelectorActive}
          selectBrowserTab={props.selectBrowserTab}
          selectedBrowserTab={props.selectedBrowserTab}
          toggleDrawer={props.toggleDrawer}
          trackPanelModalOpened={props.trackPanelModalOpened}
        />
Andrey Azov's avatar
Andrey Azov committed
160
      )}
Imran Salam's avatar
Imran Salam committed
161
162
163
    </div>
  );
};
164

Andrey Azov's avatar
Andrey Azov committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
export const BrowserInfo = ({ ensObjectInfo }: BrowserInfoProps) => (
  <Fragment>
    <dd className={styles.geneSymbol}>
      <label>Gene</label>
      <span className={styles.value}>{ensObjectInfo.obj_symbol}</span>
    </dd>
    <dd>
      <label>Stable ID</label>
      <span className={styles.value}>{ensObjectInfo.stable_id}</span>
    </dd>
    <dd className="show-for-large">
      <label>Spliced mRNA length</label>
      <span className={styles.value}>{ensObjectInfo.spliced_length}</span>
      <label>bp</label>
    </dd>
    <dd className={`show-for-large ${styles.nonLabelValue}`}>
      {ensObjectInfo.bio_type}
    </dd>
    <dd className={`show-for-large ${styles.nonLabelValue}`}>
      {ensObjectInfo.strand} strand
    </dd>
  </Fragment>
);

export const BrowserNavigatorButton = (props: BrowserNavigatorButtonProps) => (
  <dd className={styles.navigator}>
    <button title={props.navigator.description} onClick={props.toggleNavigator}>
      <img src={props.icon} alt={props.navigator.description} />
    </button>
  </dd>
);

197
const mapStateToProps = (state: RootState): StateProps => ({
198
  browserActivated: getBrowserActivated(state),
199
  browserNavOpened: getBrowserNavOpened(state),
200
  chrLocation: getChrLocation(state),
201
  defaultChrLocation: getDefaultChrLocation(state),
202
  drawerOpened: getDrawerOpened(state),
203
  ensObjectInfo: getEnsObjectInfo(state),
204
  genomeSelectorActive: getGenomeSelectorActive(state),
205
  selectedBrowserTab: getSelectedBrowserTab(state),
206
207
  trackPanelModalOpened: getTrackPanelModalOpened(state),
  trackPanelOpened: getTrackPanelOpened(state)
208
209
210
});

const mapDispatchToProps: DispatchProps = {
211
  selectBrowserTab,
212
  toggleBrowserNav,
213
  toggleDrawer,
214
  toggleGenomeSelector
215
216
217
218
219
220
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(BrowserBar);