Commit bcfd2588 authored by Imran Salam's avatar Imran Salam
Browse files

implement browser tabs and grey out browser navigator icon when drawer opened

parent ca1e18a1
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
@include flex; @include flex;
background: $ens-light-grey; background: $ens-light-grey;
box-shadow: 0 2px 3px $ens-grey; box-shadow: 0 2px 3px $ens-grey;
height: 32px;
padding: 7px 0 3px 0; padding: 7px 0 3px 0;
position: relative; position: relative;
z-index: 200; z-index: 200;
......
...@@ -2,11 +2,14 @@ import React, { FunctionComponent, Fragment } from 'react'; ...@@ -2,11 +2,14 @@ import React, { FunctionComponent, Fragment } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { browserInfoConfig } from '../browserConfig'; import { browserInfoConfig } from '../browserConfig';
import { TrackType } from '../track-panel/trackPanelConfig';
import { import {
toggleBrowserNav, toggleBrowserNav,
updateDefaultChrLocation, updateDefaultChrLocation,
updateChrLocation, updateChrLocation,
toggleGenomeSelector toggleGenomeSelector,
selectBrowserTab
} from '../browserActions'; } from '../browserActions';
import { ChrLocation } from '../browserState'; import { ChrLocation } from '../browserState';
import { import {
...@@ -15,7 +18,8 @@ import { ...@@ -15,7 +18,8 @@ import {
getBrowserActivated, getBrowserActivated,
getDefaultChrLocation, getDefaultChrLocation,
getGenomeSelectorActive, getGenomeSelectorActive,
getDrawerOpened getDrawerOpened,
getSelectedBrowserTab
} from '../browserSelectors'; } from '../browserSelectors';
import { RootState } from 'src/rootReducer'; import { RootState } from 'src/rootReducer';
...@@ -32,9 +36,11 @@ type StateProps = { ...@@ -32,9 +36,11 @@ type StateProps = {
defaultChrLocation: ChrLocation; defaultChrLocation: ChrLocation;
drawerOpened: boolean; drawerOpened: boolean;
genomeSelectorActive: boolean; genomeSelectorActive: boolean;
selectedBrowserTab: TrackType;
}; };
type DispatchProps = { type DispatchProps = {
selectBrowserTab: (selectedBrowserTab: TrackType) => void;
toggleBrowserNav: () => void; toggleBrowserNav: () => void;
toggleGenomeSelector: (genomeSelectorActive: boolean) => void; toggleGenomeSelector: (genomeSelectorActive: boolean) => void;
updateChrLocation: (chrLocation: ChrLocation) => void; updateChrLocation: (chrLocation: ChrLocation) => void;
...@@ -65,11 +71,21 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = ( ...@@ -65,11 +71,21 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = (
const getBrowserNavIcon = () => { const getBrowserNavIcon = () => {
if (props.browserNavOpened === true) { if (props.browserNavOpened === true) {
return navigator.icon.selected; return navigator.icon.selected;
} else if (props.drawerOpened === true) {
return navigator.icon.grey;
} else { } else {
return navigator.icon.default; return navigator.icon.default;
} }
}; };
const toggleNavigator = () => {
if (props.drawerOpened === true) {
return;
}
props.toggleBrowserNav();
};
return ( return (
<div className={styles.browserBar}> <div className={styles.browserBar}>
<div className={getBrowserInfoClasses()}> <div className={getBrowserInfoClasses()}>
...@@ -118,17 +134,19 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = ( ...@@ -118,17 +134,19 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = (
/> />
{props.genomeSelectorActive ? null : ( {props.genomeSelectorActive ? null : (
<dd className={styles.navigator}> <dd className={styles.navigator}>
<button <button title={navigator.description} onClick={toggleNavigator}>
title={navigator.description}
onClick={props.toggleBrowserNav}
>
<img src={getBrowserNavIcon()} alt={navigator.description} /> <img src={getBrowserNavIcon()} alt={navigator.description} />
</button> </button>
</dd> </dd>
)} )}
</dl> </dl>
</div> </div>
<BrowserTabs /> <BrowserTabs
drawerOpened={props.drawerOpened}
genomeSelectorActive={props.genomeSelectorActive}
selectBrowserTab={props.selectBrowserTab}
selectedBrowserTab={props.selectedBrowserTab}
/>
</div> </div>
); );
}; };
...@@ -139,10 +157,12 @@ const mapStateToProps = (state: RootState): StateProps => ({ ...@@ -139,10 +157,12 @@ const mapStateToProps = (state: RootState): StateProps => ({
chrLocation: getChrLocation(state), chrLocation: getChrLocation(state),
defaultChrLocation: getDefaultChrLocation(state), defaultChrLocation: getDefaultChrLocation(state),
drawerOpened: getDrawerOpened(state), drawerOpened: getDrawerOpened(state),
genomeSelectorActive: getGenomeSelectorActive(state) genomeSelectorActive: getGenomeSelectorActive(state),
selectedBrowserTab: getSelectedBrowserTab(state)
}); });
const mapDispatchToProps: DispatchProps = { const mapDispatchToProps: DispatchProps = {
selectBrowserTab,
toggleBrowserNav, toggleBrowserNav,
toggleGenomeSelector, toggleGenomeSelector,
updateChrLocation, updateChrLocation,
......
...@@ -10,11 +10,15 @@ ...@@ -10,11 +10,15 @@
} }
.browserTab { .browserTab {
color: $ens-blue; button {
color: $ens-blue;
}
} }
.browserTabActive { .browserTabActive {
color: inherit; button {
color: inherit;
}
} }
.browserTabArrow { .browserTabArrow {
...@@ -31,7 +35,7 @@ ...@@ -31,7 +35,7 @@
right: calc(60% - 6px); right: calc(60% - 6px);
transform-origin: 0 0; transform-origin: 0 0;
transform: rotate(-45deg); transform: rotate(-45deg);
top: 21px; top: 24px;
width: 0; width: 0;
} }
} }
import React, { FunctionComponent } from 'react'; import React, { FunctionComponent, useEffect, useState } from 'react';
import { TrackType } from '../track-panel/trackPanelConfig';
import styles from './BrowserTabs.scss'; import styles from './BrowserTabs.scss';
type BrowserTabsProps = {}; type BrowserTabsProps = {
drawerOpened: boolean;
genomeSelectorActive: boolean;
selectBrowserTab: (selectedBrowserTab: TrackType) => void;
selectedBrowserTab: TrackType;
};
type ClickHandlers = {
[key: string]: () => void;
};
const BrowserTabs: FunctionComponent<BrowserTabsProps> = ( const BrowserTabs: FunctionComponent<BrowserTabsProps> = (
props: BrowserTabsProps props: BrowserTabsProps
) => { ) => {
const initClickHandlers: ClickHandlers = {};
const [clickHandlers, setClickHandlers] = useState(initClickHandlers);
const getBrowserTabClasses = (trackType: TrackType) => {
let classNames = styles.browserTab;
if (props.selectedBrowserTab === trackType) {
classNames += ` ${styles.browserTabActive}`;
if (props.drawerOpened === false) {
classNames += ` ${styles.browserTabArrow}`;
}
}
return classNames;
};
useEffect(() => {
const callbacks: ClickHandlers = {};
Object.values(TrackType).forEach((value: TrackType) => {
callbacks[value] = () => {
if (props.genomeSelectorActive === true) {
return;
}
props.selectBrowserTab(value);
};
});
setClickHandlers(callbacks);
}, [props.genomeSelectorActive]);
return ( return (
<dl className={`${styles.browserTabs} show-for-large`}> <dl className={`${styles.browserTabs} show-for-large`}>
<dd> {Object.values(TrackType).map((value: TrackType) => (
<button className={styles.browserTabActive}>Genomic</button> <dd
</dd> className={getBrowserTabClasses(value)}
<dd> key={value}
<button>Variation</button> onClick={clickHandlers[value]}
</dd> >
<dd> <button>{value}</button>
<button>Expression</button> </dd>
</dd> ))}
</dl> </dl>
); );
}; };
......
import { createAction } from 'typesafe-actions'; import { createAction } from 'typesafe-actions';
import { BrowserNavStates, ChrLocation } from './browserState'; import { BrowserNavStates, ChrLocation } from './browserState';
import { TrackType } from './track-panel/trackPanelConfig';
export const updateBrowserActivated = createAction( export const updateBrowserActivated = createAction(
'browser/update-browser-activated', 'browser/update-browser-activated',
...@@ -68,3 +69,10 @@ export const toggleGenomeSelector = createAction( ...@@ -68,3 +69,10 @@ export const toggleGenomeSelector = createAction(
return (genomeSelectorActive: boolean) => resolve(genomeSelectorActive); return (genomeSelectorActive: boolean) => resolve(genomeSelectorActive);
} }
); );
export const selectBrowserTab = createAction(
'select-browser-tab',
(resolve) => {
return (selectedBrowserTab: TrackType) => resolve(selectedBrowserTab);
}
);
...@@ -3,6 +3,7 @@ import resetGreyIcon from 'static/img/browser/reset-grey.svg'; ...@@ -3,6 +3,7 @@ import resetGreyIcon from 'static/img/browser/reset-grey.svg';
import navigatorIcon from 'static/img/browser/navigator.svg'; import navigatorIcon from 'static/img/browser/navigator.svg';
import navigatorSelectedIcon from 'static/img/browser/navigator-selected.svg'; import navigatorSelectedIcon from 'static/img/browser/navigator-selected.svg';
import navigatorGreyIcon from 'static/img/browser/navigator-grey.svg';
import navigateUpIcon from 'static/img/browser/navigate-up.svg'; import navigateUpIcon from 'static/img/browser/navigate-up.svg';
import navigateUpOffIcon from 'static/img/browser/navigate-up-off.svg'; import navigateUpOffIcon from 'static/img/browser/navigate-up-off.svg';
...@@ -53,6 +54,7 @@ export const browserInfoConfig: BrowserInfoType = { ...@@ -53,6 +54,7 @@ export const browserInfoConfig: BrowserInfoType = {
description: 'toggle browser navigation', description: 'toggle browser navigation',
icon: { icon: {
default: navigatorIcon, default: navigatorIcon,
grey: navigatorGreyIcon,
selected: navigatorSelectedIcon selected: navigatorSelectedIcon
}, },
name: 'navigator' name: 'navigator'
......
...@@ -50,6 +50,8 @@ export default ( ...@@ -50,6 +50,8 @@ export default (
}; };
case getType(browser.toggleGenomeSelector): case getType(browser.toggleGenomeSelector):
return { ...state, genomeSelectorActive: action.payload }; return { ...state, genomeSelectorActive: action.payload };
case getType(browser.selectBrowserTab):
return { ...state, selectedBrowserTab: action.payload };
default: default:
return state; return state;
} }
......
...@@ -4,6 +4,7 @@ import { ...@@ -4,6 +4,7 @@ import {
BrowserNavStates, BrowserNavStates,
ChrLocation ChrLocation
} from './browserState'; } from './browserState';
import { TrackType } from './track-panel/trackPanelConfig';
export const getBrowserActivated = (state: RootState): boolean => export const getBrowserActivated = (state: RootState): boolean =>
state.browser.browserActivated; state.browser.browserActivated;
...@@ -40,3 +41,6 @@ export const getTrackPanelModalView = (state: RootState): string => ...@@ -40,3 +41,6 @@ export const getTrackPanelModalView = (state: RootState): string =>
export const getGenomeSelectorActive = (state: RootState): boolean => export const getGenomeSelectorActive = (state: RootState): boolean =>
state.browser.genomeSelectorActive; state.browser.genomeSelectorActive;
export const getSelectedBrowserTab = (state: RootState): TrackType =>
state.browser.selectedBrowserTab;
import { TrackType } from './track-panel/trackPanelConfig';
export enum BrowserOpenState { export enum BrowserOpenState {
EXPANDED = 'expanded', EXPANDED = 'expanded',
SEMI_EXPANDED = 'semiExpanded', SEMI_EXPANDED = 'semiExpanded',
...@@ -26,6 +28,7 @@ export type BrowserState = Readonly<{ ...@@ -26,6 +28,7 @@ export type BrowserState = Readonly<{
drawerOpened: boolean; drawerOpened: boolean;
drawerView: string; drawerView: string;
genomeSelectorActive: boolean; genomeSelectorActive: boolean;
selectedBrowserTab: TrackType;
trackPanelModalOpened: boolean; trackPanelModalOpened: boolean;
trackPanelModalView: string; trackPanelModalView: string;
trackPanelOpened: boolean; trackPanelOpened: boolean;
...@@ -41,6 +44,7 @@ export const defaultState: BrowserState = { ...@@ -41,6 +44,7 @@ export const defaultState: BrowserState = {
drawerOpened: false, drawerOpened: false,
drawerView: '', drawerView: '',
genomeSelectorActive: false, genomeSelectorActive: false,
selectedBrowserTab: TrackType.GENOMIC,
trackPanelModalOpened: false, trackPanelModalOpened: false,
trackPanelModalView: '', trackPanelModalView: '',
trackPanelOpened: true trackPanelOpened: true
......
...@@ -8,6 +8,7 @@ import { connect } from 'react-redux'; ...@@ -8,6 +8,7 @@ import { connect } from 'react-redux';
import TrackPanelBar from './track-panel-bar/TrackPanelBar'; import TrackPanelBar from './track-panel-bar/TrackPanelBar';
import TrackPanelList from './track-panel-list/TrackPanelList'; import TrackPanelList from './track-panel-list/TrackPanelList';
import TrackPanelModal from './track-panel-modal/TrackPanelModal';
import { RootState } from 'src/rootReducer'; import { RootState } from 'src/rootReducer';
...@@ -25,15 +26,16 @@ import { ...@@ -25,15 +26,16 @@ import {
getTrackPanelOpened, getTrackPanelOpened,
getBrowserActivated, getBrowserActivated,
getTrackPanelModalOpened, getTrackPanelModalOpened,
getTrackPanelModalView getTrackPanelModalView,
getSelectedBrowserTab
} from '../browserSelectors'; } from '../browserSelectors';
import { getLaunchbarExpanded } from 'src/header/headerSelectors'; import { getLaunchbarExpanded } from 'src/header/headerSelectors';
import { getBreakpointWidth } from 'src/globalSelectors'; import { getBreakpointWidth } from 'src/globalSelectors';
import { BreakpointWidth } from 'src/globalConfig'; import { BreakpointWidth } from 'src/globalConfig';
import { TrackType } from './trackPanelConfig';
import styles from './TrackPanel.scss'; import styles from './TrackPanel.scss';
import TrackPanelModal from './track-panel-modal/TrackPanelModal';
type StateProps = { type StateProps = {
browserActivated: boolean; browserActivated: boolean;
...@@ -41,6 +43,7 @@ type StateProps = { ...@@ -41,6 +43,7 @@ type StateProps = {
drawerView: string; drawerView: string;
breakpointWidth: BreakpointWidth; breakpointWidth: BreakpointWidth;
launchbarExpanded: boolean; launchbarExpanded: boolean;
selectedBrowserTab: TrackType;
trackPanelModalOpened: boolean; trackPanelModalOpened: boolean;
trackPanelModalView: string; trackPanelModalView: string;
trackPanelOpened: boolean; trackPanelOpened: boolean;
...@@ -91,6 +94,7 @@ const TrackPanel: FunctionComponent<TrackPanelProps> = ( ...@@ -91,6 +94,7 @@ const TrackPanel: FunctionComponent<TrackPanelProps> = (
browserRef={props.browserRef} browserRef={props.browserRef}
drawerView={props.drawerView} drawerView={props.drawerView}
launchbarExpanded={props.launchbarExpanded} launchbarExpanded={props.launchbarExpanded}
selectedBrowserTab={props.selectedBrowserTab}
toggleDrawer={props.toggleDrawer} toggleDrawer={props.toggleDrawer}
updateDrawerView={props.changeDrawerView} updateDrawerView={props.changeDrawerView}
/> />
...@@ -115,6 +119,7 @@ const mapStateToProps = (state: RootState): StateProps => ({ ...@@ -115,6 +119,7 @@ const mapStateToProps = (state: RootState): StateProps => ({
drawerOpened: getDrawerOpened(state), drawerOpened: getDrawerOpened(state),
drawerView: getDrawerView(state), drawerView: getDrawerView(state),
launchbarExpanded: getLaunchbarExpanded(state), launchbarExpanded: getLaunchbarExpanded(state),
selectedBrowserTab: getSelectedBrowserTab(state),
trackPanelModalOpened: getTrackPanelModalOpened(state), trackPanelModalOpened: getTrackPanelModalOpened(state),
trackPanelModalView: getTrackPanelModalView(state), trackPanelModalView: getTrackPanelModalView(state),
trackPanelOpened: getTrackPanelOpened(state) trackPanelOpened: getTrackPanelOpened(state)
......
import React, { FunctionComponent, RefObject, useCallback } from 'react'; import React, {
FunctionComponent,
RefObject,
useCallback,
useState,
useEffect
} from 'react';
import TrackPanelListItem from './TrackPanelListItem'; import TrackPanelListItem from './TrackPanelListItem';
import { import {
TrackPanelCategory, TrackPanelCategory,
TrackPanelItem, TrackPanelItem,
trackPanelConfig trackPanelConfig,
TrackType
} from '../trackPanelConfig'; } from '../trackPanelConfig';
import styles from './TrackPanelList.scss'; import styles from './TrackPanelList.scss';
...@@ -13,6 +20,7 @@ type TrackPanelListProps = { ...@@ -13,6 +20,7 @@ type TrackPanelListProps = {
browserRef: RefObject<HTMLDivElement>; browserRef: RefObject<HTMLDivElement>;
drawerView: string; drawerView: string;
launchbarExpanded: boolean; launchbarExpanded: boolean;
selectedBrowserTab: TrackType;
toggleDrawer: (drawerOpened: boolean) => void; toggleDrawer: (drawerOpened: boolean) => void;
updateDrawerView: (drawerView: string) => void; updateDrawerView: (drawerView: string) => void;
}; };
...@@ -20,6 +28,19 @@ type TrackPanelListProps = { ...@@ -20,6 +28,19 @@ type TrackPanelListProps = {
const TrackPanelList: FunctionComponent<TrackPanelListProps> = ( const TrackPanelList: FunctionComponent<TrackPanelListProps> = (
props: TrackPanelListProps props: TrackPanelListProps
) => { ) => {
const [trackCategories, setTrackCategories] = useState(
trackPanelConfig.categories
);
useEffect(() => {
setTrackCategories(
trackPanelConfig.categories.filter(
(category: TrackPanelCategory) =>
category.types.indexOf(props.selectedBrowserTab) > -1
)
);
}, [props.selectedBrowserTab]);
const changeDrawerView = useCallback( const changeDrawerView = useCallback(
(currentTrack: string) => { (currentTrack: string) => {
const { drawerView, toggleDrawer, updateDrawerView } = props; const { drawerView, toggleDrawer, updateDrawerView } = props;
...@@ -61,7 +82,7 @@ const TrackPanelList: FunctionComponent<TrackPanelListProps> = ( ...@@ -61,7 +82,7 @@ const TrackPanelList: FunctionComponent<TrackPanelListProps> = (
<section> <section>
<dl>{getTrackListItem(trackPanelConfig.main)}</dl> <dl>{getTrackListItem(trackPanelConfig.main)}</dl>
</section> </section>
{trackPanelConfig.categories.map((category: TrackPanelCategory) => ( {trackCategories.map((category: TrackPanelCategory) => (
<section key={category.name}> <section key={category.name}>
<h4>{category.name}</h4> <h4>{category.name}</h4>
<dl> <dl>
......
...@@ -21,9 +21,16 @@ export type TrackPanelItem = { ...@@ -21,9 +21,16 @@ export type TrackPanelItem = {
selectedInfo?: string; selectedInfo?: string;
}; };
export enum TrackType {
GENOMIC = 'Genomic',
VARIATION = 'Variation',
EXPRESSION = 'Expression'
}
export type TrackPanelCategory = { export type TrackPanelCategory = {
name: string; name: string;
trackList: TrackPanelItem[]; trackList: TrackPanelItem[];
types: TrackType[];
}; };