Browser.tsx 6.56 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

17
import React, { useEffect } from 'react';
18
import { ApolloProvider } from '@apollo/client';
19
import { connect } from 'react-redux';
20
import { Link } from 'react-router-dom';
Andrey Azov's avatar
Andrey Azov committed
21

22 23
import useBrowserRouting from './hooks/useBrowserRouting';

24
import { client } from 'src/gql-client';
25 26 27
import analyticsTracking from 'src/services/analytics-service';
import * as urlFor from 'src/shared/helpers/urlHelper';
import { BreakpointWidth } from 'src/global/globalConfig';
28

29 30 31 32 33
import {
  parseEnsObjectId,
  buildFocusIdForUrl
} from 'src/shared/state/ens-object/ensObjectHelpers';

34 35 36
import { toggleTrackPanel } from 'src/content/app/browser/track-panel/trackPanelActions';
import { toggleDrawer } from './drawer/drawerActions';

37
import {
38
  getBrowserNavOpenState,
39
  getChrLocation,
40 41 42
  getBrowserActivated,
  getBrowserActiveGenomeId,
  getBrowserQueryParams,
Andrey Azov's avatar
Andrey Azov committed
43
  getBrowserActiveEnsObjectId,
44
  getBrowserActiveEnsObjectIds
45
} from './browserSelectors';
46

Imran Salam's avatar
Imran Salam committed
47 48
import { getIsTrackPanelOpened } from './track-panel/trackPanelSelectors';
import { getIsDrawerOpened } from './drawer/drawerSelectors';
49
import { getExampleEnsObjects } from 'src/shared/state/ens-object/ensObjectSelectors';
50
import { getBreakpointWidth } from 'src/global/globalSelectors';
51

52 53 54 55 56 57 58 59 60
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 TrackPanelBar from './track-panel/track-panel-bar/TrackPanelBar';
import TrackPanelTabs from './track-panel/track-panel-tabs/TrackPanelTabs';
import BrowserAppBar from './browser-app-bar/BrowserAppBar';
import Drawer from './drawer/Drawer';
import { StandardAppLayout } from 'src/shared/components/layout';
61
import BrowserInterstitial from './interstitial/BrowserInterstitial';
62

63
import { RootState } from 'src/store';
64
import { ChrLocation } from './browserState';
65
import { EnsObject } from 'src/shared/state/ens-object/ensObjectTypes';
66

67 68
import styles from './Browser.scss';

69
export type BrowserProps = {
Andrey Azov's avatar
Andrey Azov committed
70 71
  activeGenomeId: string | null;
  activeEnsObjectId: string | null;
72
  browserActivated: boolean;
73
  browserNavOpenState: boolean;
74
  browserQueryParams: { [key: string]: string };
Andrey Azov's avatar
Andrey Azov committed
75
  chrLocation: ChrLocation | null;
Imran Salam's avatar
Imran Salam committed
76 77
  isDrawerOpened: boolean;
  isTrackPanelOpened: boolean;
Andrey Azov's avatar
Andrey Azov committed
78
  exampleEnsObjects: EnsObject[];
79 80
  viewportWidth: BreakpointWidth;
  toggleTrackPanel: (isOpen: boolean) => void;
Imran Salam's avatar
Imran Salam committed
81
  toggleDrawer: (isDrawerOpened: boolean) => void;
82
};
83

84
export const Browser = (props: BrowserProps) => {
85
  const { changeGenomeId } = useBrowserRouting();
Andrey Azov's avatar
Andrey Azov committed
86

87
  const { isDrawerOpened } = props;
88

89
  useEffect(() => {
90
    const { activeGenomeId } = props;
91 92 93
    if (!activeGenomeId) {
      return;
    }
94

95
    analyticsTracking.setSpeciesDimension(activeGenomeId);
Andrey Azov's avatar
Andrey Azov committed
96
  }, [props.activeGenomeId]);
97

98 99
  const onSidebarToggle = () => {
    props.toggleTrackPanel(!props.isTrackPanelOpened); // FIXME
100
  };
101

102 103
  const toggleDrawer = () => {
    props.toggleDrawer(!props.isDrawerOpened);
104 105
  };

106
  const shouldShowNavBar =
107
    props.browserActivated && props.browserNavOpenState && !isDrawerOpened;
108

109
  const mainContent = (
110
    <>
111 112 113 114 115 116
      {shouldShowNavBar && <BrowserNavBar />}
      <BrowserImage />
    </>
  );

  return (
117
    <ApolloProvider client={client}>
118
      <div className={styles.genomeBrowser}>
119
        <BrowserAppBar onSpeciesSelect={changeGenomeId} />
120
        {props.activeGenomeId && props.browserQueryParams.focus ? (
121 122 123 124 125 126 127 128 129 130 131 132 133 134
          <StandardAppLayout
            mainContent={mainContent}
            sidebarContent={<TrackPanel />}
            sidebarNavigation={<TrackPanelTabs />}
            sidebarToolstripContent={<TrackPanelBar />}
            onSidebarToggle={onSidebarToggle}
            topbarContent={<BrowserBar />}
            isSidebarOpen={props.isTrackPanelOpened}
            isDrawerOpen={props.isDrawerOpened}
            drawerContent={<Drawer />}
            onDrawerClose={toggleDrawer}
            viewportWidth={props.viewportWidth}
          />
        ) : (
135
          <BrowserInterstitial />
136 137 138
        )}
      </div>
    </ApolloProvider>
139
  );
Andrey Azov's avatar
Andrey Azov committed
140 141
};

142
export const ExampleObjectLinks = (props: BrowserProps) => {
Andrey Azov's avatar
Andrey Azov committed
143
  const { activeGenomeId } = props;
144

Andrey Azov's avatar
Andrey Azov committed
145 146 147
  if (!activeGenomeId) {
    return null;
  }
148

Andrey Azov's avatar
Andrey Azov committed
149
  const links = props.exampleEnsObjects.map((exampleObject: EnsObject) => {
150 151
    const parsedEnsObjectId = parseEnsObjectId(exampleObject.object_id);
    const focusId = buildFocusIdForUrl(parsedEnsObjectId);
Andrey Azov's avatar
Andrey Azov committed
152 153
    const path = urlFor.browser({
      genomeId: activeGenomeId,
154
      focus: focusId
Andrey Azov's avatar
Andrey Azov committed
155 156 157
    });

    return (
158
      <div key={exampleObject.object_id} className={styles.exampleLink}>
159 160 161
        <Link to={path} replace>
          Example {exampleObject.type}
        </Link>
Andrey Azov's avatar
Andrey Azov committed
162 163 164 165
      </div>
    );
  });

166 167
  return (
    <div>
168
      <div className={styles.exampleLinks__emptyTopbar} />
169 170 171
      <div className={styles.exampleLinks}>{links}</div>
    </div>
  );
172
};
173

Andrey Azov's avatar
Andrey Azov committed
174 175 176 177 178 179 180
const mapStateToProps = (state: RootState) => {
  const activeGenomeId = getBrowserActiveGenomeId(state);
  return {
    activeGenomeId,
    activeEnsObjectId: getBrowserActiveEnsObjectId(state),
    allActiveEnsObjectIds: getBrowserActiveEnsObjectIds(state),
    browserActivated: getBrowserActivated(state),
181
    browserNavOpenState: getBrowserNavOpenState(state),
Andrey Azov's avatar
Andrey Azov committed
182 183 184 185
    browserQueryParams: getBrowserQueryParams(state),
    chrLocation: getChrLocation(state),
    isDrawerOpened: getIsDrawerOpened(state),
    isTrackPanelOpened: getIsTrackPanelOpened(state),
186
    exampleEnsObjects: getExampleEnsObjects(state),
Andrey Azov's avatar
Andrey Azov committed
187 188 189
    viewportWidth: getBreakpointWidth(state)
  };
};
190

191
const mapDispatchToProps = {
192
  toggleDrawer,
193
  toggleTrackPanel
194 195
};

Andrey Azov's avatar
Andrey Azov committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
const ReduxConnectedBrowser = connect(
  mapStateToProps,
  mapDispatchToProps
)(Browser);

const WasmLoadingBrowserContainer = () => {
  useEffect(() => {
    /* eslint-disable */
    // @ts-ignore ensembl-genome-browser does not have typescript definitions
    import('ensembl-genome-browser');
    /* eslint-enable */
  });

  return <ReduxConnectedBrowser />;
};

212
export default WasmLoadingBrowserContainer;