Skip to content

Commit

Permalink
Add "view in genome browser" button to variant zmenu (#1008)
Browse files Browse the repository at this point in the history
Also, moved the ZmenuAppLinks component out of the ZmenuContent component
for better flexibility/composability.
  • Loading branch information
azangru authored Jul 30, 2023
1 parent 6a6d0ee commit e535723
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 34 deletions.
11 changes: 8 additions & 3 deletions src/content/app/genome-browser/components/zmenu/Zmenu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,15 @@
color: $blue;
}

.zmenuAppLinks {
display: flex;
.zmenuLinksGrid {
display: grid;
grid-template-columns: auto [app-links] 1fr;
align-items: center;
justify-content: space-between;
}

.zmenuAppLinks {
grid-column: app-links;
justify-self: end;
}

.zmenuToggleFooter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ jest.mock('./ZmenuContent', () => () => (
jest.mock('./ZmenuInstantDownload', () => () => (
<div>ZmenuInstantDownload</div>
));
jest.mock('./zmenus/GeneAndOneTranscriptZmenu', () => () => (
<div data-test-id="gene-and-one-transcript-zmenu">
GeneAndOneTranscriptZmenu
</div>
));
jest.mock('./zmenus/VariantZmenu', () => () => <div>VariantZmenu</div>);
jest.mock('./zmenus/RegulationZmenu', () => () => <div>RegulationZmenu</div>);

const chrName = faker.lorem.word();
Expand Down Expand Up @@ -113,7 +119,7 @@ describe('<Zmenu />', () => {
describe('rendering', () => {
it('renders zmenu content', () => {
const { queryByTestId } = renderComponent();
expect(queryByTestId('zmenuContent')).toBeTruthy();
expect(queryByTestId('gene-and-one-transcript-zmenu')).toBeTruthy();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@
import React from 'react';

import * as urlFor from 'src/shared/helpers/urlHelper';
import { parseFocusIdFromUrl } from 'src/shared/helpers/focusObjectHelpers';

import useGenomeBrowserIds from 'src/content/app/genome-browser/hooks/useGenomeBrowserIds';
import useGenomeBrowser from '../../hooks/useGenomeBrowser';

import { ToggleButton as ToolboxToggleButton } from 'src/shared/components/toolbox';
import ViewInApp, {
LinksConfig
type LinksConfig
} from 'src/shared/components/view-in-app/ViewInApp';

import styles from './Zmenu.scss';
Expand All @@ -42,12 +40,6 @@ const ZmenuAppLinks = (props: Props) => {
const { changeFocusObject } = useGenomeBrowser();
const navigate = useNavigate();

const { type: featureType } = parseFocusIdFromUrl(featureId);

if (featureType !== 'gene') {
return null;
}

const onGenomeBrowserAppClick = () => {
if (!(focusObjectIdForUrl && focusObjectId)) {
return;
Expand Down Expand Up @@ -79,10 +71,6 @@ const ZmenuAppLinks = (props: Props) => {

return (
<div className={styles.zmenuAppLinks}>
<ToolboxToggleButton
className={styles.zmenuToggleFooter}
label="Download"
/>
<ViewInApp
theme="dark"
links={links}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import * as urlFor from 'src/shared/helpers/urlHelper';

import useGenomeBrowserIds from 'src/content/app/genome-browser/hooks/useGenomeBrowserIds';

import ZmenuAppLinks from './ZmenuAppLinks';

import {
ZmenuContentItem as ZmenuContentItemType,
Markup,
Expand Down Expand Up @@ -60,7 +58,6 @@ export const ZmenuContent = (props: ZmenuContentProps) => {
/>
</p>
))}
<ZmenuAppLinks featureId={featureId} destroyZmenu={props.destroyZmenu} />
</>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ import { useAppDispatch } from 'src/store';

import { changeHighlightedTrackId } from 'src/content/app/genome-browser/state/track-panel/trackPanelSlice';

import { ToolboxExpandableContent } from 'src/shared/components/toolbox';
import {
ToolboxExpandableContent,
ToggleButton as ToolboxToggleButton
} from 'src/shared/components/toolbox';
import ZmenuContent from '../ZmenuContent';
import ZmenuInstantDownload from '../ZmenuInstantDownload';
import ZmenuAppLinks from '../ZmenuAppLinks';

import type {
ZmenuContentTranscript,
Expand Down Expand Up @@ -73,11 +77,20 @@ const GeneAndOneTranscriptZmenu = (props: Props) => {
}, []);

const mainContent = (
<ZmenuContent
features={features}
featureId={featureId}
destroyZmenu={props.onDestroy}
/>
<>
<ZmenuContent
features={features}
featureId={featureId}
destroyZmenu={props.onDestroy}
/>
<div className={styles.zmenuLinksGrid}>
<ToolboxToggleButton
className={styles.zmenuToggleFooter}
label="Download"
/>
<ZmenuAppLinks featureId={featureId} destroyZmenu={props.onDestroy} />
</div>
</>
);

const footerContent = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,69 @@

import React from 'react';

import * as urlFor from 'src/shared/helpers/urlHelper';
import { buildFocusVariantId } from 'src/shared/helpers/focusObjectHelpers';
import { isEnvironment, Environment } from 'src/shared/helpers/environment';

import useGenomeBrowserIds from 'src/content/app/genome-browser/hooks/useGenomeBrowserIds';

import ZmenuContent from '../ZmenuContent';
import ViewInApp from 'src/shared/components/view-in-app/ViewInApp';

import type {
ZmenuPayload,
ZmenuContentVariantMetadata
} from 'src/content/app/genome-browser/services/genome-browser-service/types/zmenu';

import styles from '../Zmenu.scss';

type Props = {
payload: ZmenuPayload;
onDestroy: () => void;
};

const VariantZmenu = (props: Props) => {
const { content } = props.payload;
const { genomeIdForUrl } = useGenomeBrowserIds();

const variantMetadata = content[0]?.metadata as
| ZmenuContentVariantMetadata
| undefined;
const variantId = variantMetadata?.id ?? '';

if (!variantMetadata) {
// something has gone wrong
return null;
}

const variantId = buildFocusVariantId({
regionName: variantMetadata.region_name,
start: variantMetadata.start,
variantName: variantMetadata.id
});

const linkToVariantInGenomeBrowser = urlFor.browser({
genomeId: genomeIdForUrl,
focus: variantId
});

return (
<ZmenuContent
features={content}
featureId={`variant:${variantId}`}
destroyZmenu={props.onDestroy}
/>
<>
<ZmenuContent
features={content}
featureId={variantId}
destroyZmenu={props.onDestroy}
/>
{isEnvironment([Environment.DEVELOPMENT, Environment.INTERNAL]) && (
<div className={styles.zmenuLinksGrid}>
<ViewInApp
theme="dark"
links={{ genomeBrowser: { url: linkToVariantInGenomeBrowser } }}
onAnyAppClick={props.onDestroy}
className={styles.zmenuAppLinks}
/>
</div>
)}
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ export type ZmenuContentGeneMetadata = {
export type ZmenuContentVariantMetadata = {
alleles: string;
consequence: string;
id: string;
id: string; // just the rsID; will have to be combined with region name and start coordinate for full id
region_name: string; // needed to generate full variant id
start: number; // needed to generate full variant id
position: string; // formatted as "region:start-end". NOTE: start and end coordinates have commas in them
variety: string; // e.g. SNV, INS... Do we have a full list of such varieties?
type: ZmenuFeatureType.VARIANT;
Expand Down
3 changes: 2 additions & 1 deletion src/shared/components/view-in-app/ViewInApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export type ViewInAppProps = {
onAppClick?: AppClickHandlers;
onAnyAppClick?: (appName?: AppName) => void;
theme?: Theme;
className?: string;
};

export const ViewInApp = (props: ViewInAppProps) => {
Expand Down Expand Up @@ -107,7 +108,7 @@ export const ViewInApp = (props: ViewInAppProps) => {
}
};

const componentClasses = classNames(styles.viewInApp, {
const componentClasses = classNames(styles.viewInApp, props.className, {
[styles.viewInAppLight]: theme === 'light',
[styles.viewInAppDark]: theme === 'dark'
});
Expand Down
9 changes: 9 additions & 0 deletions src/shared/helpers/focusObjectHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,12 @@ export const parseFocusObjectIdFromUrl = (

export const getDisplayStableId = (focusObject: Partial<FocusGene>) =>
focusObject.versioned_stable_id || focusObject.stable_id || '';

export const buildFocusVariantId = (params: {
regionName: string;
start: number;
variantName: string;
}) => {
const { regionName, start, variantName } = params;
return `variant:${regionName}:${start}:${variantName}`;
};

0 comments on commit e535723

Please sign in to comment.