Commit 3d6ecaff authored by Imran Salam's avatar Imran Salam
Browse files

make drawer state unique to species instance

parent 9c68f247
Pipeline #26311 passed with stage
in 1 minute and 53 seconds
......@@ -15,7 +15,7 @@ import TrackPanel from './track-panel/TrackPanel';
import AppBar from 'src/shared/app-bar/AppBar';
import { RootState } from 'src/store';
import { BrowserNavStates, ChrLocation } from './browserState';
import { ChrLocation } from './browserState';
import {
changeBrowserLocation,
setDataFromUrlAndSave,
......@@ -55,7 +55,7 @@ import styles from './Browser.scss';
import 'static/browser/browser.js';
type StateProps = {
activeGenomeId: string | null;
activeGenomeId: string;
activeEnsObjectId: string | null;
allActiveEnsObjectIds: { [genomeId: string]: string };
browserActivated: boolean;
......@@ -63,7 +63,7 @@ type StateProps = {
browserQueryParams: { [key: string]: string };
chrLocation: ChrLocation | null;
allChrLocations: { [genomeId: string]: ChrLocation };
drawerOpened: boolean;
drawerOpened: { [genomeId: string]: boolean };
genomeSelectorActive: boolean;
trackPanelOpened: boolean;
launchbarExpanded: boolean;
......@@ -79,7 +79,7 @@ type DispatchProps = {
) => void;
fetchGenomeData: (genomeId: string) => void;
replace: Replace;
toggleDrawer: (drawerOpened: boolean) => void;
toggleDrawer: (drawerOpened: { [genomeId: string]: boolean }) => void;
setDataFromUrlAndSave: (payload: ParsedUrlPayload) => void;
};
......@@ -102,6 +102,7 @@ export const Browser: FunctionComponent<BrowserProps> = (
TrackStates
>({});
const lastGenomeIdRef = useRef(props.activeGenomeId);
const drawerOpenedForGenome = props.drawerOpened[props.activeGenomeId];
const setDataFromUrl = () => {
const { genomeId = null } = props.match.params;
......@@ -253,10 +254,11 @@ export const Browser: FunctionComponent<BrowserProps> = (
}, [props.chrLocation]);
const closeTrack = () => {
if (props.drawerOpened === false) {
if (drawerOpenedForGenome === false) {
return;
}
props.toggleDrawer(false);
props.toggleDrawer({ [props.activeGenomeId]: false });
};
const [trackAnimation, setTrackAnimation] = useSpring(() => ({
......@@ -266,7 +268,7 @@ export const Browser: FunctionComponent<BrowserProps> = (
}));
const getBrowserWidth = (): string => {
if (props.drawerOpened) {
if (drawerOpenedForGenome === true) {
return 'calc(41px + 0vw)';
}
return props.trackPanelOpened
......@@ -278,7 +280,7 @@ export const Browser: FunctionComponent<BrowserProps> = (
setTrackAnimation({
width: getBrowserWidth()
});
}, [props.drawerOpened, props.trackPanelOpened]);
}, [drawerOpenedForGenome, props.trackPanelOpened]);
const getHeightClass = (launchbarExpanded: boolean): string => {
return launchbarExpanded ? styles.shorter : styles.taller;
......@@ -312,7 +314,7 @@ export const Browser: FunctionComponent<BrowserProps> = (
<animated.div style={trackAnimation}>
<div className={styles.browserImageWrapper} onClick={closeTrack}>
{props.browserNavOpened &&
!props.drawerOpened &&
!drawerOpenedForGenome &&
browserRef.current ? (
<BrowserNavBar browserElement={browserRef.current} />
) : null}
......
......@@ -34,12 +34,12 @@ import BrowserTabs from '../browser-tabs/BrowserTabs';
import styles from './BrowserBar.scss';
type StateProps = {
activeGenomeId: string | null;
activeGenomeId: string;
browserActivated: boolean;
browserNavOpened: boolean;
chrLocation: ChrLocation | null;
defaultChrLocation: ChrLocation | null;
drawerOpened: boolean;
drawerOpened: { [genomeId: string]: boolean };
genomeSelectorActive: boolean;
ensObject: EnsObject | null;
selectedBrowserTab: { [genomeId: string]: TrackType };
......@@ -50,7 +50,7 @@ type StateProps = {
type DispatchProps = {
selectBrowserTabAndSave: (selectedBrowserTab: TrackType) => void;
toggleBrowserNav: () => void;
toggleDrawer: (drawerOpened: boolean) => void;
toggleDrawer: (drawerOpened: { [genomeId: string]: boolean }) => void;
toggleGenomeSelector: (genomeSelectorActive: boolean) => void;
};
......@@ -73,6 +73,8 @@ type BrowserNavigatorButtonProps = {
export const BrowserBar: FunctionComponent<BrowserBarProps> = (
props: BrowserBarProps
) => {
const drawerOpenedForGenome = props.drawerOpened[props.activeGenomeId];
const shouldShowBrowserInfo = () => {
const { defaultChrLocation } = props;
const isLocationOfWholeChromosome = !defaultChrLocation;
......@@ -97,7 +99,7 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = (
}, [props.defaultChrLocation, props.genomeSelectorActive]);
const getBrowserNavIcon = () => {
if (props.drawerOpened) {
if (drawerOpenedForGenome === true) {
return navigator.icon.grey as string;
} else if (props.browserNavOpened) {
return navigator.icon.selected as string;
......@@ -107,7 +109,7 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = (
};
const toggleNavigator = () => {
if (props.drawerOpened) {
if (drawerOpenedForGenome === true) {
return;
}
......@@ -116,7 +118,7 @@ export const BrowserBar: FunctionComponent<BrowserBarProps> = (
const className = classNames(styles.browserInfo, {
[styles.browserInfoExpanded]: !props.trackPanelOpened,
[styles.browserInfoGreyed]: props.drawerOpened
[styles.browserInfoGreyed]: drawerOpenedForGenome
});
if (!(props.chrLocation && props.ensObject)) {
......
......@@ -15,11 +15,11 @@ import styles from './BrowserGenomeSelector.scss';
import { getChrLocationStr } from '../browserHelper';
type BrowserGenomeSelectorProps = {
activeGenomeId: string | null;
activeGenomeId: string;
browserActivated: boolean;
chrLocation: ChrLocation;
dispatchBrowserLocation: (genomeId: string, chrLocation: ChrLocation) => void;
drawerOpened: boolean;
drawerOpened: { [genomeId: string]: boolean };
genomeSelectorActive: boolean;
toggleGenomeSelector: (genomeSelectorActive: boolean) => void;
};
......@@ -27,7 +27,7 @@ type BrowserGenomeSelectorProps = {
const BrowserGenomeSelector: FunctionComponent<BrowserGenomeSelectorProps> = (
props: BrowserGenomeSelectorProps
) => {
const { activeGenomeId, chrLocation } = props;
const { activeGenomeId, chrLocation, drawerOpened } = props;
const chrLocationStr = getChrLocationStr(chrLocation);
const [chrLocationPlaceholder, setChrLocationPlaceholder] = useState('');
......@@ -36,6 +36,8 @@ const BrowserGenomeSelector: FunctionComponent<BrowserGenomeSelectorProps> = (
const [chrCode, chrStart, chrEnd] = chrLocation;
const displayChrRegion = !(chrStart === 0 && chrEnd === 0);
const drawerOpenedForGenome = drawerOpened[activeGenomeId];
useEffect(() => {
setChrLocationPlaceholder(chrLocationStr);
}, []);
......@@ -43,7 +45,7 @@ const BrowserGenomeSelector: FunctionComponent<BrowserGenomeSelectorProps> = (
const getGenomeSelectorClasses = () => {
let classNames = styles.browserGenomeSelector;
if (props.drawerOpened === true) {
if (drawerOpenedForGenome === true) {
classNames += ` ${styles.browserGenomeSelectorDisabled}`;
}
......@@ -51,7 +53,7 @@ const BrowserGenomeSelector: FunctionComponent<BrowserGenomeSelectorProps> = (
};
const activateForm = () => {
if (props.drawerOpened === true) {
if (drawerOpenedForGenome === true) {
return;
}
......
......@@ -16,8 +16,7 @@ import {
getTrackConfigLabel,
getBrowserCogTrackList,
getBrowserNavOpened,
getBrowserActivated,
getBrowserActiveGenomeId
getBrowserActivated
} from '../browserSelectors';
import {
activateBrowser,
......@@ -34,7 +33,6 @@ import { RootState } from 'src/store';
import { TrackStates } from '../track-panel/trackPanelConfig';
type StateProps = {
activeGenomeId: string | null;
browserCogTrackList: CogList;
browserNavOpened: boolean;
trackConfigNames: any;
......@@ -213,7 +211,6 @@ function getBrowserImageClasses(browserNavOpened: boolean): string {
}
const mapStateToProps = (state: RootState): StateProps => ({
activeGenomeId: getBrowserActiveGenomeId(state),
browserCogTrackList: getBrowserCogTrackList(state),
browserNavOpened: getBrowserNavOpened(state),
trackConfigLabel: getTrackConfigLabel(state),
......
......@@ -10,11 +10,11 @@ import styles from './BrowserReset.scss';
import { getChrLocationStr } from '../browserHelper';
type BrowserResetProps = {
activeGenomeId: string | null;
activeGenomeId: string;
chrLocation: ChrLocation | null;
defaultChrLocation: ChrLocation | null;
dispatchBrowserLocation: (genomeId: string, chrLocation: ChrLocation) => void;
drawerOpened: boolean;
drawerOpened: { [genomeId: string]: boolean };
};
export const BrowserReset: FunctionComponent<BrowserResetProps> = (
......@@ -27,6 +27,8 @@ export const BrowserReset: FunctionComponent<BrowserResetProps> = (
drawerOpened
} = props;
const drawerOpenedForGenome = drawerOpened[activeGenomeId];
const getResetIconStatus = (): ImageButtonStatus => {
if (!(activeGenomeId && chrLocation && defaultChrLocation)) {
return ImageButtonStatus.DISABLED;
......@@ -35,7 +37,10 @@ export const BrowserReset: FunctionComponent<BrowserResetProps> = (
const chrLocationStr = getChrLocationStr(chrLocation);
const defaultChrLocationStr = getChrLocationStr(defaultChrLocation);
if (chrLocationStr === defaultChrLocationStr || drawerOpened === true) {
if (
chrLocationStr === defaultChrLocationStr ||
drawerOpenedForGenome === true
) {
return ImageButtonStatus.DISABLED;
}
......@@ -43,7 +48,7 @@ export const BrowserReset: FunctionComponent<BrowserResetProps> = (
};
const resetBrowser = () => {
if (drawerOpened === true) {
if (drawerOpenedForGenome === true) {
return;
}
......
......@@ -7,7 +7,6 @@ import {
TrackToggleStates
} from './track-panel/trackPanelConfig';
import { ChrLocations } from './browserState';
import { ImageButtonStatus } from 'src/shared/image-button/ImageButton';
export enum StorageKeys {
ACTIVE_GENOME_ID = 'browser.activeGenomeId',
......
......@@ -7,24 +7,26 @@ import styles from './BrowserTabs.scss';
type BrowserTabsProps = {
activeGenomeId: string;
ensObject: EnsObject;
drawerOpened: boolean;
drawerOpened: { [genomeId: string]: boolean };
genomeSelectorActive: boolean;
selectBrowserTabAndSave: (selectedBrowserTab: TrackType) => void;
selectedBrowserTab: { [genomeId: string]: TrackType };
toggleDrawer: (drawerOpened: boolean) => void;
toggleDrawer: (drawerOpened: { [genomeId: string]: boolean }) => void;
trackPanelModalOpened: boolean;
};
const BrowserTabs: FunctionComponent<BrowserTabsProps> = (
props: BrowserTabsProps
) => {
const drawerOpenedForGenome = props.drawerOpened[props.activeGenomeId];
const handleTabClick = (value: TrackType) => {
if (props.genomeSelectorActive || !props.ensObject.genome_id) {
return;
}
if (props.drawerOpened) {
props.toggleDrawer(false);
if (drawerOpenedForGenome === true) {
props.toggleDrawer({ [props.activeGenomeId]: false });
}
props.selectBrowserTabAndSave(value);
......@@ -39,7 +41,7 @@ const BrowserTabs: FunctionComponent<BrowserTabsProps> = (
if (
props.ensObject.genome_id &&
selectedBrowserTab === trackType &&
drawerOpened === false &&
drawerOpened[activeGenomeId] === false &&
trackPanelModalOpened === false
) {
classNames += ` ${styles.browserTabActive} ${styles.browserTabArrow}`;
......
......@@ -35,7 +35,7 @@ export function browserInfo(
? BrowserOpenState.SEMI_EXPANDED
: BrowserOpenState.EXPANDED
};
case getType(drawerActions.toggleDrawer):
case getType(drawerActions.toggleDrawerForGenome):
return {
...state,
browserOpenState: action.payload
......
......@@ -15,7 +15,7 @@ export const getBrowserActivated = (state: RootState): boolean =>
export const getBrowserOpenState = (state: RootState): BrowserOpenState =>
state.browser.browserInfo.browserOpenState;
export const getBrowserActiveGenomeId = (state: RootState): string | null =>
export const getBrowserActiveGenomeId = (state: RootState): string =>
state.browser.browserEntity.activeGenomeId;
export const getBrowserActiveGenomeInfo = (state: RootState) => {
......
......@@ -42,7 +42,7 @@ export const defaultBrowserState: BrowserState = {
};
export type BrowserEntityState = Readonly<{
activeGenomeId: string | null;
activeGenomeId: string;
activeEnsObjectIds: { [genomeId: string]: string };
trackStates: TrackStates;
}>;
......
......@@ -4,7 +4,10 @@ import { connect } from 'react-redux';
import { RootState } from 'src/store';
import { toggleDrawer } from './drawerActions';
import { getDrawerView } from './drawerSelectors';
import { getBrowserActiveEnsObject } from '../browserSelectors';
import {
getBrowserActiveEnsObject,
getBrowserActiveGenomeId
} from '../browserSelectors';
import DrawerGene from './drawer-views/DrawerGene';
import DrawerTranscript from './drawer-views/DrawerTranscript';
......@@ -21,12 +24,13 @@ import SnpIndels from './drawer-views/SnpIndels';
import { EnsObject } from 'src/ens-object/ensObjectTypes';
type StateProps = {
drawerView: string;
activeGenomeId: string;
drawerView: { [genomeId: string]: string };
ensObject: EnsObject | null;
};
type DispatchProps = {
toggleDrawer: (drawerOpened?: boolean) => void;
toggleDrawer: (drawerOpened: boolean) => void;
};
type OwnProps = {};
......@@ -34,13 +38,14 @@ type OwnProps = {};
type DrawerProps = StateProps & DispatchProps & OwnProps;
const Drawer: FunctionComponent<DrawerProps> = (props: DrawerProps) => {
const { ensObject } = props;
const { ensObject, drawerView, activeGenomeId } = props;
if (!ensObject) {
return null;
}
const getDrawerViewComponent = () => {
switch (props.drawerView) {
switch (drawerView[activeGenomeId]) {
case 'gene-feat':
return <DrawerGene ensObject={ensObject} />;
case 'gene-feat-1':
......@@ -75,6 +80,7 @@ const Drawer: FunctionComponent<DrawerProps> = (props: DrawerProps) => {
};
const mapStateToProps = (state: RootState): StateProps => ({
activeGenomeId: getBrowserActiveGenomeId(state),
drawerView: getDrawerView(state),
ensObject: getBrowserActiveEnsObject(state)
});
......
import { createAction } from 'typesafe-actions';
import { getDrawerAnalyticsObject } from 'src/analyticsHelper';
import { ActionCreator, Action, Dispatch } from 'redux';
import { ThunkAction } from 'redux-thunk';
import { RootState } from 'src/store';
import { getBrowserActiveGenomeId } from '../browserSelectors';
export const changeDrawerView = createAction(
'drawer/change-drawer-view',
export const changeDrawerViewForGenome = createAction(
'drawer/update-drawer-view',
(resolve) => {
return (drawerView: string) =>
return (drawerView: { [genomeId: string]: string }) =>
resolve(drawerView, getDrawerAnalyticsObject('User Interaction'));
}
);
export const toggleDrawer = createAction('drawer/toggle-drawer', (resolve) => {
return (drawerOpened?: boolean) =>
resolve(drawerOpened, getDrawerAnalyticsObject('User Interaction'));
});
export const changeDrawerView: ActionCreator<
ThunkAction<void, any, null, Action<string>>
> = (drawerViewForGenome: string) => (
dispatch: Dispatch,
getState: () => RootState
) => {
const activeGenomeId = getBrowserActiveGenomeId(getState());
if (!activeGenomeId) {
return;
}
const drawerView = {
[activeGenomeId]: drawerViewForGenome
};
dispatch(changeDrawerViewForGenome(drawerView));
};
export const toggleDrawerForGenome = createAction(
'drawer/toggle-drawer',
(resolve) => {
return (drawerOpened: { [genomeId: string]: boolean }) =>
resolve(drawerOpened, getDrawerAnalyticsObject('User Interaction'));
}
);
export const toggleDrawer: ActionCreator<
ThunkAction<void, any, null, Action<boolean>>
> = (drawerOpened: boolean) => (
dispatch: Dispatch,
getState: () => RootState
) => {
const activeGenomeId = getBrowserActiveGenomeId(getState());
if (!activeGenomeId) {
return;
}
const drawerOpenedForGenome = {
[activeGenomeId]: drawerOpened
};
dispatch(toggleDrawerForGenome(drawerOpenedForGenome));
};
......@@ -8,16 +8,22 @@ export default function drawer(
action: ActionType<typeof drawerActions>
): DrawerState {
switch (action.type) {
case getType(drawerActions.changeDrawerView):
case getType(drawerActions.changeDrawerViewForGenome):
return {
...state,
drawerView: action.payload
drawerView: { ...state.drawerView, ...action.payload }
};
case getType(drawerActions.toggleDrawer):
case getType(drawerActions.toggleDrawerForGenome):
const genomeId = Object.keys(action.payload)[0];
let drawerOpenedValue = Object.values(action.payload)[0];
let drawerViewForGenome = drawerOpenedValue
? state.drawerView[genomeId]
: '';
return {
...state,
drawerOpened: action.payload,
drawerView: action.payload ? state.drawerView : ''
drawerOpened: { ...state.drawerOpened, ...action.payload },
drawerView: { ...state.drawerView, [genomeId]: drawerViewForGenome }
};
default:
return state;
......
import { RootState } from 'src/store';
export const getDrawerView = (state: RootState): string =>
state.drawer.drawerView;
export const getDrawerView = (state: RootState) => state.drawer.drawerView;
export const getDrawerOpened = (state: RootState): boolean =>
state.drawer.drawerOpened;
export const getDrawerOpened = (state: RootState) => state.drawer.drawerOpened;
export type DrawerState = Readonly<{
drawerOpened: boolean;
drawerView: string;
drawerOpened: { [genomeId: string]: boolean };
drawerView: { [genomeId: string]: string };
}>;
export const defaultDrawerState = {
drawerOpened: false,
drawerView: ''
drawerOpened: {},
drawerView: {}
};
......@@ -43,11 +43,11 @@ import { EnsObject } from 'src/ens-object/ensObjectTypes';
import styles from './TrackPanel.scss';
type StateProps = {
activeGenomeId: string | null;
activeGenomeId: string;
breakpointWidth: BreakpointWidth;
browserActivated: boolean;
drawerOpened: boolean;
drawerView: string;
drawerOpened: { [genomeId: string]: boolean };
drawerView: { [genomeId: string]: string };
ensObject: EnsObject | null;
launchbarExpanded: boolean;
selectedBrowserTab: { [genomeId: string]: TrackType };
......@@ -76,6 +76,9 @@ type TrackPanelProps = StateProps & DispatchProps & OwnProps;
const TrackPanel: FunctionComponent<TrackPanelProps> = (
props: TrackPanelProps
) => {
const drawerOpenedForGenome =
props.drawerOpened[props.activeGenomeId as string];
useEffect(() => {
if (props.breakpointWidth !== BreakpointWidth.LARGE) {
props.toggleTrackPanel(false);
......@@ -93,7 +96,7 @@ const TrackPanel: FunctionComponent<TrackPanelProps> = (
}));
const getBrowserWidth = (): string => {
if (props.drawerOpened) {
if (drawerOpenedForGenome === true) {
return 'calc(41px + 0vw)';
}
return props.trackPanelOpened
......@@ -105,13 +108,14 @@ const TrackPanel: FunctionComponent<TrackPanelProps> = (
setTrackAnimation({
left: getBrowserWidth()
});
}, [props.drawerOpened, props.trackPanelOpened]);
}, [drawerOpenedForGenome, props.trackPanelOpened]);
return props.activeGenomeId ? (
<animated.div style={trackAnimation}>
{props.browserActivated && props.ensObject ? (
<div className={styles.trackPanel}>
<TrackPanelBar
activeGenomeId={props.activeGenomeId}
closeTrackPanelModal={props.closeTrackPanelModal}
drawerOpened={props.drawerOpened}
launchbarExpanded={props.launchbarExpanded}
......@@ -144,7 +148,7 @@ const TrackPanel: FunctionComponent<TrackPanelProps> = (
trackPanelModalView={props.trackPanelModalView}
/>
) : null}
{props.drawerOpened && <Drawer />}
{drawerOpenedForGenome && <Drawer />}
</div>
) : null}
</animated.div>
......
......@@ -10,8 +10,9 @@ import chevronRightIcon from 'static/img/shared/chevron-right.svg';
import styles from './TrackPanelBar.scss';
type TrackPanelBarProps = {
activeGenomeId: string;
closeTrackPanelModal: () => void;
drawerOpened: boolean;