From bbea2e8ae171ad559b864890782b4269145deace Mon Sep 17 00:00:00 2001 From: Cesar Ferreyra-Mansilla Date: Thu, 12 Dec 2024 13:32:21 -0500 Subject: [PATCH] feat: feedback link (#148) --- src/App.tsx | 438 +++++++++--------------- src/{ => css}/App.css | 628 +++++++++++++++++++---------------- src/css/NavigationBar.css | 220 ++++++++++++ src/icon.ts | 20 ++ src/ui/ExportDropdown.tsx | 6 +- src/ui/NavigationBar.tsx | 224 +++++++++++++ src/ui/NavigationButtons.tsx | 16 +- 7 files changed, 965 insertions(+), 587 deletions(-) rename src/{ => css}/App.css (71%) create mode 100644 src/css/NavigationBar.css create mode 100644 src/ui/NavigationBar.tsx diff --git a/src/App.tsx b/src/App.tsx index da2256be..033403a5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,8 @@ import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 're import { GoslingComponent, GoslingRef, embed } from 'gosling.js'; import { debounce, sample } from 'lodash'; import type { RouteComponentProps } from 'react-router-dom'; +import * as bootstrap from 'bootstrap/dist/js/bootstrap.bundle.min'; + import generateSpec from './main-spec'; import ErrorBoundary from './error'; import _allDrivers from './data/driver.json'; @@ -10,7 +12,6 @@ import samples, { SampleType } from './data/samples'; import getOneOfSmallMultiplesSpec from './small-multiples-spec'; import { CHROMOSOMES, THEME, WHOLE_CHROMOSOME_STR } from './constants'; import { ICONS } from './icon'; -import './App.css'; import { INTERNAL_SAVED_THUMBNAILS } from './data/external-thumbnails'; import { isChrome } from './utils'; import THUMBNAIL_PLACEHOLDER from './script/img/placeholder.png'; @@ -26,11 +27,11 @@ import { ExportDropdown } from './ui/ExportDropdown'; import { GenomeViewModal } from './ui/GenomeViewModal'; import { VariantViewModal } from './ui/VariantViewModal'; import { NavigationButtons } from './ui/NavigationButtons'; +import { Track, getTrackDocData } from './ui/getTrackDocData.js'; +import { NavigationBar } from './ui/NavigationBar'; import 'bootstrap/dist/css/bootstrap.min.css'; -import * as bootstrap from 'bootstrap/dist/js/bootstrap.bundle.min'; - -import { Track, getTrackDocData } from './ui/getTrackDocData.js'; +import './css/App.css'; const db = new Database(); const log = new BrowserDatabase(); @@ -43,6 +44,8 @@ const INIT_VIS_PANEL_WIDTH = window.innerWidth; const ZOOM_PADDING = 200; const ZOOM_DURATION = 500; +const FEEDBACK_EMAIL_ADDRESS = 'dominik_glodzik@hms.harvard.edu'; + const allDrivers = [ ...(_allDrivers as any), ..._customDrivers.map(d => { @@ -583,7 +586,7 @@ function App(props: RouteComponentProps) { return ( @@ -619,7 +622,7 @@ function App(props: RouteComponentProps) { })} ); - }, [demo, visPanelWidth, selectedSvId]); + }, [demo, visPanelWidth, selectedSvId, showSamples]); useLayoutEffect(() => { if (!gosRef.current) return; @@ -757,231 +760,103 @@ function App(props: RouteComponentProps) { }} > {!isMinimalMode && ( - - )} - {!isMinimalMode && ( - { - setShowSamples(true); - }} - > - Menu - - + )} -
- {!isMinimalMode && ( - <> - - CHROMOSCOPE - - { - setShowAbout(true); - }} - > - - - - About - - {' | '} - {/* {demo.cancer.charAt(0).toUpperCase() + demo.cancer.slice(1) + ' • ' + demo.id} */} - {demo.cancer.charAt(0).toUpperCase() + demo.cancer.slice(1)} - {demo.id} - - )} - {!isMinimalMode && ( - <> - gosRef.current?.api.exportPng()}> - - Export Image - {ICONS.PNG.path.map(p => ( - - ))} - - - { - const a = document.createElement('a'); - a.setAttribute( - 'href', - `data:text/plain;charset=utf-8,${encodeURIComponent( - getHtmlTemplate(currentSpec.current) - )}` - ); - a.download = 'visualization.html'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - }} - style={{ marginLeft: 40 }} - > - - Export HTML - {ICONS.HTML.path.map(p => ( - - ))} - - - { - const a = document.createElement('a'); - a.setAttribute( - 'href', - `data:text/plain;charset=utf-8,${encodeURIComponent(currentSpec.current)}` - ); - a.download = 'visualization.json'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - }} - style={{ marginLeft: 70 }} - > - - Export Gosling Spec (JSON) - {ICONS.JSON.path.map(p => ( - - ))} - - - { - const { xDomain } = gosRef.current.hgApi.api.getLocation(`${demo.id}-mid-ideogram`); - if (xDomain) { - // urlParams.set('demoIndex', demoIndex.current + ''); - // urlParams.set('domain', xDomain.join('-')); - let newUrl = window.location.origin + window.location.pathname + '?'; - newUrl += `demoIndex=${demoIndex.current}`; - newUrl += `&domain=${xDomain.join('-')}`; - if (externalDemoUrl.current) { - newUrl += `&external=${externalDemoUrl.current}`; - } else if (externalUrl) { - newUrl += `&external=${externalUrl}`; - } - navigator.clipboard - .writeText(newUrl) - .then(() => - alert( - 'The URL of the current session has been copied to your clipboard.' - ) - ); - } - }} - style={{ marginLeft: 100 }} - > - - Export Link - - - - - - )} - {!isChrome() ? ( - - ⚠️ Chromoscope is optimized for Google Chrome - - ) : null} - {!isMinimalMode && ( - <> - - - GitHub - - - GitHub - - - - - - Documentation - - - )} -
{!isMinimalMode && (
-
{ - if (e.target === e.currentTarget) setShowSamples(false); - }} - > - { - setShowSamples(false); +
+
{ + if (e.target === e.currentTarget) setShowSamples(false); }} > - Close - - - +
+ + + GitHub + + + GitHub + + - + - About + Docs - {' | '} Samples - setFilterSampleBy(e.target.value)} - hidden - /> -
- - - GitHub - - - GitHub - - - + + + Mail + + + Feedback + +
+ + {generateThumbnails + ? 'Stop Generating Thumbnails' + : 'Generate Missing Thumbnails'} + +
@@ -1097,7 +945,6 @@ function App(props: RouteComponentProps) { }} > {goslingComponent} - {trackTooltips} {jumpButtonInfo ? (
-
- +
@@ -1216,7 +1077,7 @@ function App(props: RouteComponentProps) { > { const trackId = `${demo.id}-mid-ideogram`; @@ -1338,7 +1199,7 @@ function App(props: RouteComponentProps) { // !! This should be identical to how the height of circos determined. // top: `${Math.min(visPanelWidth, 600)}px` }} - tabIndex={3} + tabIndex={showSamples ? -1 : 0} className="zoom-out-button control" onClick={e => { const trackId = `${demo.id}-mid-ideogram`; @@ -1363,7 +1224,7 @@ function App(props: RouteComponentProps) { // !! This should be identical to how the height of circos determined. // top: `${Math.min(visPanelWidth, 600)}px` }} - tabIndex={3} + tabIndex={showSamples ? -1 : 0} className="zoom-left-button control" onClick={e => { const trackId = `${demo.id}-mid-ideogram`; @@ -1387,7 +1248,7 @@ function App(props: RouteComponentProps) { // !! This should be identical to how the height of circos determined. // top: `${Math.min(visPanelWidth, 600)}px` }} - tabIndex={3} + tabIndex={showSamples ? -1 : 0} className="zoom-right-button control" onClick={e => { const trackId = `${demo.id}-mid-ideogram`; @@ -1408,6 +1269,7 @@ function App(props: RouteComponentProps) {
+ {trackTooltips} {!isMinimalMode && ( @@ -1577,7 +1439,7 @@ function App(props: RouteComponentProps) { )} +
+ + CHROMOSCOPE + + { + setShowAbout(true); + }} + > + + + + About + + {' | '} + {/* {demo.cancer.charAt(0).toUpperCase() + demo.cancer.slice(1) + ' • ' + demo.id} */} + {demo.cancer.charAt(0).toUpperCase() + demo.cancer.slice(1)} + {demo.id} + + + +
+ {!isChrome() ? ( + + ⚠️ Chromoscope is optimized for Google Chrome + + ) : null} + +
+ + + GitHub + + + GitHub + + + + + + Docs + +
+ + + Mail + + + Feedback + +
+
+ + ); +}; diff --git a/src/ui/NavigationButtons.tsx b/src/ui/NavigationButtons.tsx index a69a5b0d..487330c8 100644 --- a/src/ui/NavigationButtons.tsx +++ b/src/ui/NavigationButtons.tsx @@ -1,13 +1,19 @@ import React from 'react'; import { ICONS } from '../icon'; -export const NavigationButtons = () => { +type NavigationButtonsProps = { + showSamples: boolean; + isMinimalMode: boolean; +} + +export const NavigationButtons = ({ showSamples, isMinimalMode } : NavigationButtonsProps) => { + return (