react-msaview 9.0.0 → 9.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -10
- package/bundle/index.js +111 -115
- package/bundle/index.js.map +4 -4
- package/dist/blosum62.d.ts +3 -0
- package/dist/blosum62.js +43 -0
- package/dist/blosum62.js.map +1 -0
- package/dist/colorSchemes.js +2 -3
- package/dist/colorSchemes.js.map +1 -1
- package/dist/columnCounts.d.ts +0 -1
- package/dist/columnCounts.js +1 -1
- package/dist/columnCounts.js.map +1 -1
- package/dist/components/Loading.d.ts +3 -2
- package/dist/components/Loading.js +7 -7
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAView.d.ts +3 -2
- package/dist/components/MSAView.js +7 -4
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +1941 -4
- package/dist/components/MSAViewer.js +144 -201
- package/dist/components/MSAViewer.js.map +1 -1
- package/dist/components/MetadataTable.d.ts +4 -1
- package/dist/components/MetadataTable.js +55 -16
- package/dist/components/MetadataTable.js.map +1 -1
- package/dist/components/ResizeHandles.js +3 -2
- package/dist/components/ResizeHandles.js.map +1 -1
- package/dist/components/Track.js +8 -1
- package/dist/components/Track.js.map +1 -1
- package/dist/components/controls.d.ts +11 -0
- package/dist/components/controls.js +49 -0
- package/dist/components/controls.js.map +1 -0
- package/dist/components/dialogs/AnnotationFileDialog.js +12 -18
- package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js +5 -7
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.js +2 -2
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/{header/TreeSettingsMenu.d.ts → dialogs/GapThresholdDialog.d.ts} +3 -2
- package/dist/components/dialogs/GapThresholdDialog.js +15 -0
- package/dist/components/dialogs/GapThresholdDialog.js.map +1 -0
- package/dist/components/{header → dialogs}/GappynessSlider.d.ts +1 -1
- package/dist/components/{header → dialogs}/GappynessSlider.js +3 -10
- package/dist/components/dialogs/GappynessSlider.js.map +1 -0
- package/dist/components/{header → dialogs}/GoToBox.d.ts +4 -2
- package/dist/components/dialogs/GoToBox.js +48 -0
- package/dist/components/dialogs/GoToBox.js.map +1 -0
- package/dist/components/dialogs/GoToDialog.d.ts +6 -0
- package/dist/components/dialogs/GoToDialog.js +10 -0
- package/dist/components/dialogs/GoToDialog.js.map +1 -0
- package/dist/components/dialogs/HelpDialog.d.ts +6 -0
- package/dist/components/dialogs/HelpDialog.js +30 -0
- package/dist/components/dialogs/HelpDialog.js.map +1 -0
- package/dist/components/dialogs/MetadataDialog.js +11 -3
- package/dist/components/dialogs/MetadataDialog.js.map +1 -1
- package/dist/components/dialogs/goTo.d.ts +5 -0
- package/dist/components/{header → dialogs}/goTo.js +1 -1
- package/dist/components/dialogs/goTo.js.map +1 -0
- package/dist/components/dialogs/metadataLabels.d.ts +4 -0
- package/dist/components/dialogs/metadataLabels.js +52 -0
- package/dist/components/dialogs/metadataLabels.js.map +1 -0
- package/dist/components/dialogs/metadataRecord.d.ts +1 -0
- package/dist/components/dialogs/metadataRecord.js +38 -0
- package/dist/components/dialogs/metadataRecord.js.map +1 -0
- package/dist/components/header/Header.d.ts +6 -2
- package/dist/components/header/Header.js +30 -34
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HiddenColumnsChip.d.ts +6 -0
- package/dist/components/header/HiddenColumnsChip.js +15 -0
- package/dist/components/header/HiddenColumnsChip.js.map +1 -0
- package/dist/components/header/{FileMenu.d.ts → MenuBar.d.ts} +3 -3
- package/dist/components/header/MenuBar.js +33 -0
- package/dist/components/header/MenuBar.js.map +1 -0
- package/dist/components/header/ScrollZoomCheckbox.d.ts +7 -0
- package/dist/components/header/ScrollZoomCheckbox.js +19 -0
- package/dist/components/header/ScrollZoomCheckbox.js.map +1 -0
- package/dist/components/header/ZoomControls.js +12 -48
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/header/colorSchemeMenuItems.d.ts +4 -0
- package/dist/components/header/colorSchemeMenuItems.js +106 -0
- package/dist/components/header/colorSchemeMenuItems.js.map +1 -0
- package/dist/components/header/getAnnotationsMenu.d.ts +3 -30
- package/dist/components/header/getAnnotationsMenu.js +48 -54
- package/dist/components/header/getAnnotationsMenu.js.map +1 -1
- package/dist/components/header/menuBarItems.d.ts +11 -0
- package/dist/components/header/menuBarItems.js +277 -0
- package/dist/components/header/menuBarItems.js.map +1 -0
- package/dist/components/import/ImportForm.js +12 -6
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/data/seq2.d.ts +0 -1
- package/dist/components/import/data/seq2.js +0 -17
- package/dist/components/import/data/seq2.js.map +1 -1
- package/dist/components/minimap/Minimap.js +7 -3
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/minimap/MinimapSVG.js +2 -1
- package/dist/components/minimap/MinimapSVG.js.map +1 -1
- package/dist/components/minimap/minimapLayout.d.ts +12 -0
- package/dist/components/minimap/minimapLayout.js +20 -0
- package/dist/components/minimap/minimapLayout.js.map +1 -1
- package/dist/components/msa/MSACanvas.js +28 -10
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +17 -16
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/WheelZoomHint.d.ts +7 -0
- package/dist/components/msa/WheelZoomHint.js +38 -0
- package/dist/components/msa/WheelZoomHint.js.map +1 -0
- package/dist/components/msa/drawFeatureSpans.d.ts +50 -11
- package/dist/components/msa/drawFeatureSpans.js +99 -56
- package/dist/components/msa/drawFeatureSpans.js.map +1 -1
- package/dist/components/msa/msaKeys.js +3 -0
- package/dist/components/msa/msaKeys.js.map +1 -1
- package/dist/components/msa/msaRaster.d.ts +14 -2
- package/dist/components/msa/msaRaster.js +20 -10
- package/dist/components/msa/msaRaster.js.map +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +9 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +39 -8
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderHighlights.d.ts +2 -5
- package/dist/components/msa/renderHighlights.js +5 -6
- package/dist/components/msa/renderHighlights.js.map +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +6 -1
- package/dist/components/msa/renderMSABlock.js +44 -17
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +2 -1
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/msa/tileColor.js +7 -0
- package/dist/components/msa/tileColor.js.map +1 -1
- package/dist/components/renderCtx.d.ts +1 -1
- package/dist/components/rowpanels/RowPanelBlock.js +2 -2
- package/dist/components/rowpanels/RowPanelBlock.js.map +1 -1
- package/dist/components/rowpanels/renderFeaturePanel.d.ts +5 -1
- package/dist/components/rowpanels/renderFeaturePanel.js +12 -5
- package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -1
- package/dist/components/settings/MenuItemsForm.d.ts +10 -0
- package/dist/components/settings/MenuItemsForm.js +80 -0
- package/dist/components/settings/MenuItemsForm.js.map +1 -0
- package/dist/components/settings/SettingsPanel.d.ts +12 -0
- package/dist/components/settings/SettingsPanel.js +92 -0
- package/dist/components/settings/SettingsPanel.js.map +1 -0
- package/dist/components/{header/ZoomMenu.d.ts → settings/TrackList.d.ts} +2 -2
- package/dist/components/settings/TrackList.js +55 -0
- package/dist/components/settings/TrackList.js.map +1 -0
- package/dist/components/tracks/TrackBlocks.js +2 -2
- package/dist/components/tracks/TrackBlocks.js.map +1 -1
- package/dist/components/tracks/drawTracks.d.ts +1 -53
- package/dist/components/tracks/drawTracks.js +5 -5
- package/dist/components/tracks/drawTracks.js.map +1 -1
- package/dist/components/tree/CladeLabels.d.ts +1 -1
- package/dist/components/tree/CladeLabels.js +22 -34
- package/dist/components/tree/CladeLabels.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +2 -2
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeMenu.js +4 -6
- package/dist/components/tree/TreeMenu.js.map +1 -1
- package/dist/components/tree/TreeOverview.js +2 -2
- package/dist/components/tree/TreeOverview.js.map +1 -1
- package/dist/components/tree/cladeBrackets.d.ts +17 -10
- package/dist/components/tree/cladeBrackets.js +33 -3
- package/dist/components/tree/cladeBrackets.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.js +2 -8
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/components/tree/renderTreeOverview.js +4 -11
- package/dist/components/tree/renderTreeOverview.js.map +1 -1
- package/dist/constants.d.ts +4 -1
- package/dist/constants.js +7 -1
- package/dist/constants.js.map +1 -1
- package/dist/darkReader.d.ts +7 -0
- package/dist/darkReader.js +42 -0
- package/dist/darkReader.js.map +1 -0
- package/dist/element.js +25 -53
- package/dist/element.js.map +1 -1
- package/dist/exportLayout.d.ts +39 -0
- package/dist/exportLayout.js +78 -0
- package/dist/exportLayout.js.map +1 -0
- package/dist/featurePanels.d.ts +37 -0
- package/dist/featurePanels.js +187 -0
- package/dist/featurePanels.js.map +1 -0
- package/dist/filehandleLoader.d.ts +41 -0
- package/dist/filehandleLoader.js +99 -0
- package/dist/filehandleLoader.js.map +1 -0
- package/dist/headlessRenderEnv.d.ts +12 -39
- package/dist/headlessRenderEnv.js +18 -12
- package/dist/headlessRenderEnv.js.map +1 -1
- package/dist/hierarchy.d.ts +5 -8
- package/dist/hierarchy.js +5 -79
- package/dist/hierarchy.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/measureTextCanvas.d.ts +7 -0
- package/dist/measureTextCanvas.js +8 -6
- package/dist/measureTextCanvas.js.map +1 -1
- package/dist/model/treeModel.d.ts +6 -2
- package/dist/model/treeModel.js +8 -4
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +180 -76
- package/dist/model.js +358 -618
- package/dist/model.js.map +1 -1
- package/dist/neighborJoining.js +1 -40
- package/dist/neighborJoining.js.map +1 -1
- package/dist/renderToSvg.d.ts +2 -7
- package/dist/renderToSvg.js +33 -133
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rerootTree.d.ts +1 -0
- package/dist/rerootTree.js +7 -6
- package/dist/rerootTree.js.map +1 -1
- package/dist/schemeResidueColor.d.ts +12 -0
- package/dist/schemeResidueColor.js +33 -0
- package/dist/schemeResidueColor.js.map +1 -0
- package/dist/similarityColors.d.ts +11 -0
- package/dist/similarityColors.js +90 -0
- package/dist/similarityColors.js.map +1 -0
- package/dist/svgTestUtil.d.ts +74 -32
- package/dist/treeDisplay.d.ts +37 -0
- package/dist/treeDisplay.js +209 -0
- package/dist/treeDisplay.js.map +1 -0
- package/dist/types.d.ts +6 -3
- package/dist/useWheelScroll.d.ts +3 -1
- package/dist/useWheelScroll.js +36 -17
- package/dist/useWheelScroll.js.map +1 -1
- package/dist/util.d.ts +2 -0
- package/dist/util.js +2 -0
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/viewerSnapshot.d.ts +169 -0
- package/dist/viewerSnapshot.js +100 -0
- package/dist/viewerSnapshot.js.map +1 -0
- package/dist/wheelZoom.d.ts +8 -3
- package/dist/wheelZoom.js +44 -32
- package/dist/wheelZoom.js.map +1 -1
- package/dist/zoomSnapshot.d.ts +29 -0
- package/dist/zoomSnapshot.js +47 -0
- package/dist/zoomSnapshot.js.map +1 -0
- package/package.json +11 -11
- package/src/blosum62.ts +45 -0
- package/src/colorSchemes.ts +2 -4
- package/src/columnCounts.ts +1 -1
- package/src/components/Loading.tsx +25 -14
- package/src/components/MSAView.tsx +22 -5
- package/src/components/MSAViewer.tsx +275 -251
- package/src/components/MetadataTable.tsx +83 -26
- package/src/components/ResizeHandles.tsx +9 -2
- package/src/components/Track.tsx +15 -1
- package/src/components/controls.ts +62 -0
- package/src/components/dialogs/AnnotationFileDialog.tsx +16 -21
- package/src/components/dialogs/ExportSVGDialog.tsx +8 -19
- package/src/components/dialogs/FeatureDialog.tsx +2 -5
- package/src/components/dialogs/GapThresholdDialog.tsx +36 -0
- package/src/components/{header → dialogs}/GappynessSlider.tsx +3 -10
- package/src/components/{header → dialogs}/GoToBox.tsx +36 -10
- package/src/components/dialogs/GoToDialog.tsx +30 -0
- package/src/components/dialogs/HelpDialog.tsx +79 -0
- package/src/components/dialogs/MetadataDialog.tsx +32 -4
- package/src/components/{header → dialogs}/goTo.ts +1 -1
- package/src/components/dialogs/metadataLabels.ts +54 -0
- package/src/components/dialogs/metadataRecord.tsx +61 -0
- package/src/components/header/Header.tsx +75 -44
- package/src/components/header/HiddenColumnsChip.tsx +39 -0
- package/src/components/header/MenuBar.tsx +64 -0
- package/src/components/header/ScrollZoomCheckbox.tsx +46 -0
- package/src/components/header/ZoomControls.tsx +23 -74
- package/src/components/header/colorSchemeMenuItems.ts +121 -0
- package/src/components/header/getAnnotationsMenu.ts +52 -56
- package/src/components/header/menuBarItems.ts +357 -0
- package/src/components/import/ImportForm.tsx +19 -7
- package/src/components/import/data/seq2.ts +0 -18
- package/src/components/minimap/Minimap.tsx +11 -3
- package/src/components/minimap/MinimapSVG.tsx +17 -1
- package/src/components/minimap/minimapLayout.ts +27 -0
- package/src/components/msa/MSACanvas.tsx +24 -4
- package/src/components/msa/MSACanvasBlock.tsx +20 -17
- package/src/components/msa/MSAMouseoverCanvas.tsx +2 -2
- package/src/components/msa/WheelZoomHint.tsx +56 -0
- package/src/components/msa/drawFeatureSpans.ts +160 -79
- package/src/components/msa/msaKeys.ts +3 -0
- package/src/components/msa/msaRaster.ts +26 -10
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +62 -24
- package/src/components/msa/renderHighlights.ts +5 -6
- package/src/components/msa/renderMSABlock.ts +51 -15
- package/src/components/msa/renderMSAMouseover.ts +5 -1
- package/src/components/msa/tileColor.ts +7 -0
- package/src/components/renderCtx.ts +0 -1
- package/src/components/rowpanels/RowPanelBlock.tsx +2 -2
- package/src/components/rowpanels/renderFeaturePanel.ts +26 -7
- package/src/components/settings/MenuItemsForm.tsx +225 -0
- package/src/components/settings/SettingsPanel.tsx +156 -0
- package/src/components/settings/TrackList.tsx +119 -0
- package/src/components/tracks/TrackBlocks.tsx +2 -2
- package/src/components/tracks/drawTracks.ts +5 -5
- package/src/components/tree/CladeLabels.tsx +30 -54
- package/src/components/tree/TreeCanvasBlock.tsx +2 -2
- package/src/components/tree/TreeMenu.tsx +4 -6
- package/src/components/tree/TreeOverview.tsx +2 -2
- package/src/components/tree/cladeBrackets.ts +50 -3
- package/src/components/tree/renderTreeCanvas.ts +2 -13
- package/src/components/tree/renderTreeOverview.ts +7 -14
- package/src/constants.ts +9 -1
- package/src/darkReader.ts +57 -0
- package/src/element.ts +37 -64
- package/src/exportLayout.ts +134 -0
- package/src/featurePanels.ts +269 -0
- package/src/filehandleLoader.ts +136 -0
- package/src/headlessRenderEnv.ts +24 -11
- package/src/hierarchy.ts +5 -88
- package/src/index.ts +9 -5
- package/src/measureTextCanvas.ts +8 -6
- package/src/model/treeModel.ts +9 -3
- package/src/model.ts +452 -807
- package/src/neighborJoining.ts +1 -42
- package/src/renderToSvg.tsx +56 -207
- package/src/rerootTree.ts +7 -6
- package/src/schemeResidueColor.ts +37 -0
- package/src/similarityColors.ts +112 -0
- package/src/treeDisplay.ts +278 -0
- package/src/types.ts +6 -4
- package/src/useWheelScroll.ts +43 -22
- package/src/util.ts +3 -0
- package/src/version.ts +1 -1
- package/src/viewerSnapshot.ts +147 -0
- package/src/wheelZoom.ts +55 -33
- package/src/zoomSnapshot.ts +80 -0
- package/dist/components/header/ColorSchemeMenu.d.ts +0 -12
- package/dist/components/header/ColorSchemeMenu.js +0 -37
- package/dist/components/header/ColorSchemeMenu.js.map +0 -1
- package/dist/components/header/FileMenu.js +0 -66
- package/dist/components/header/FileMenu.js.map +0 -1
- package/dist/components/header/GappynessSlider.js.map +0 -1
- package/dist/components/header/GoToBox.js +0 -31
- package/dist/components/header/GoToBox.js.map +0 -1
- package/dist/components/header/MSASettingsMenu.d.ts +0 -6
- package/dist/components/header/MSASettingsMenu.js +0 -11
- package/dist/components/header/MSASettingsMenu.js.map +0 -1
- package/dist/components/header/ScrollZoomIcons.d.ts +0 -6
- package/dist/components/header/ScrollZoomIcons.js +0 -35
- package/dist/components/header/ScrollZoomIcons.js.map +0 -1
- package/dist/components/header/TreeSettingsMenu.js +0 -42
- package/dist/components/header/TreeSettingsMenu.js.map +0 -1
- package/dist/components/header/ZoomMenu.js +0 -37
- package/dist/components/header/ZoomMenu.js.map +0 -1
- package/dist/components/header/goTo.d.ts +0 -20
- package/dist/components/header/goTo.js.map +0 -1
- package/dist/components/header/settingsMenuItems.d.ts +0 -4
- package/dist/components/header/settingsMenuItems.js +0 -127
- package/dist/components/header/settingsMenuItems.js.map +0 -1
- package/src/components/header/ColorSchemeMenu.tsx +0 -56
- package/src/components/header/FileMenu.tsx +0 -81
- package/src/components/header/MSASettingsMenu.tsx +0 -26
- package/src/components/header/ScrollZoomIcons.tsx +0 -52
- package/src/components/header/TreeSettingsMenu.tsx +0 -60
- package/src/components/header/ZoomMenu.tsx +0 -48
- package/src/components/header/settingsMenuItems.ts +0 -157
|
@@ -1,21 +1,57 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
|
|
3
3
|
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
4
|
-
import { Table, TableBody, TableCell, TableRow } from '@mui/material'
|
|
5
4
|
|
|
6
|
-
const useStyles = makeStyles()({
|
|
5
|
+
const useStyles = makeStyles()(theme => ({
|
|
6
|
+
list: {
|
|
7
|
+
display: 'grid',
|
|
8
|
+
gridTemplateColumns: 'minmax(8em, max-content) minmax(0, 1fr)',
|
|
9
|
+
columnGap: theme.spacing(3),
|
|
10
|
+
margin: 0,
|
|
11
|
+
},
|
|
12
|
+
row: {
|
|
13
|
+
display: 'contents',
|
|
14
|
+
},
|
|
7
15
|
key: {
|
|
8
|
-
fontWeight:
|
|
9
|
-
|
|
16
|
+
fontWeight: 600,
|
|
17
|
+
padding: theme.spacing(0.75, 0),
|
|
18
|
+
borderTop: `1px solid ${theme.palette.divider}`,
|
|
19
|
+
},
|
|
20
|
+
code: {
|
|
21
|
+
marginLeft: theme.spacing(1),
|
|
22
|
+
fontWeight: 400,
|
|
23
|
+
fontSize: '0.75em',
|
|
24
|
+
fontFamily: 'monospace',
|
|
25
|
+
color: theme.palette.text.secondary,
|
|
10
26
|
},
|
|
11
27
|
value: {
|
|
28
|
+
margin: 0,
|
|
29
|
+
padding: theme.spacing(0.75, 0),
|
|
30
|
+
borderTop: `1px solid ${theme.palette.divider}`,
|
|
12
31
|
whiteSpace: 'pre-wrap',
|
|
13
|
-
|
|
32
|
+
overflowWrap: 'anywhere',
|
|
33
|
+
},
|
|
34
|
+
mono: {
|
|
35
|
+
fontFamily: 'monospace',
|
|
36
|
+
fontSize: '0.85em',
|
|
37
|
+
maxHeight: '8em',
|
|
38
|
+
overflow: 'auto',
|
|
14
39
|
},
|
|
15
|
-
|
|
40
|
+
nested: {
|
|
41
|
+
'& > dl': {
|
|
42
|
+
paddingLeft: theme.spacing(2),
|
|
43
|
+
borderLeft: `2px solid ${theme.palette.divider}`,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}))
|
|
16
47
|
|
|
17
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
18
|
-
return
|
|
48
|
+
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
49
|
+
return (
|
|
50
|
+
typeof value === 'object' &&
|
|
51
|
+
value !== null &&
|
|
52
|
+
!Array.isArray(value) &&
|
|
53
|
+
!React.isValidElement(value)
|
|
54
|
+
)
|
|
19
55
|
}
|
|
20
56
|
|
|
21
57
|
export function isEmpty(value: unknown) {
|
|
@@ -24,32 +60,53 @@ export function isEmpty(value: unknown) {
|
|
|
24
60
|
|
|
25
61
|
export default function MetadataTable({
|
|
26
62
|
record,
|
|
63
|
+
labels = {},
|
|
64
|
+
monospaceKeys,
|
|
27
65
|
}: {
|
|
28
66
|
record: Record<string, unknown>
|
|
67
|
+
labels?: Record<string, string>
|
|
68
|
+
monospaceKeys?: Set<string>
|
|
29
69
|
}) {
|
|
30
|
-
const { classes } = useStyles()
|
|
70
|
+
const { classes, cx } = useStyles()
|
|
31
71
|
return (
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{
|
|
43
|
-
<
|
|
72
|
+
<dl className={classes.list}>
|
|
73
|
+
{Object.entries(record)
|
|
74
|
+
.filter(([, value]) => value != null && !isEmpty(value))
|
|
75
|
+
.map(([key, value]) => {
|
|
76
|
+
const label = labels[key]
|
|
77
|
+
const nested = isRecord(value)
|
|
78
|
+
return (
|
|
79
|
+
<div key={key} className={classes.row}>
|
|
80
|
+
<dt className={classes.key}>
|
|
81
|
+
{label ?? key}
|
|
82
|
+
{label && label !== key ? (
|
|
83
|
+
<span className={classes.code}>{key}</span>
|
|
84
|
+
) : null}
|
|
85
|
+
</dt>
|
|
86
|
+
<dd
|
|
87
|
+
className={cx(
|
|
88
|
+
classes.value,
|
|
89
|
+
nested && classes.nested,
|
|
90
|
+
monospaceKeys?.has(key) && classes.mono,
|
|
91
|
+
)}
|
|
92
|
+
>
|
|
93
|
+
{nested ? (
|
|
94
|
+
<MetadataTable
|
|
95
|
+
record={value}
|
|
96
|
+
labels={labels}
|
|
97
|
+
monospaceKeys={monospaceKeys}
|
|
98
|
+
/>
|
|
44
99
|
) : Array.isArray(value) ? (
|
|
45
100
|
value.join('\n')
|
|
101
|
+
) : React.isValidElement(value) ? (
|
|
102
|
+
value
|
|
46
103
|
) : (
|
|
47
104
|
String(value)
|
|
48
105
|
)}
|
|
49
|
-
</
|
|
50
|
-
</
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
</
|
|
106
|
+
</dd>
|
|
107
|
+
</div>
|
|
108
|
+
)
|
|
109
|
+
})}
|
|
110
|
+
</dl>
|
|
54
111
|
)
|
|
55
112
|
}
|
|
@@ -7,6 +7,8 @@ import DragHandle from './DragHandle.tsx'
|
|
|
7
7
|
import type { MsaViewModel } from '../model.ts'
|
|
8
8
|
import type { BasicTrack } from '../types.ts'
|
|
9
9
|
|
|
10
|
+
const minViewHeight = 50
|
|
11
|
+
|
|
10
12
|
export const VerticalResizeHandle = observer(function ({
|
|
11
13
|
model,
|
|
12
14
|
}: {
|
|
@@ -14,7 +16,12 @@ export const VerticalResizeHandle = observer(function ({
|
|
|
14
16
|
}) {
|
|
15
17
|
const onDrag = useCallback(
|
|
16
18
|
(delta: number, startWidth: number) => {
|
|
17
|
-
model.setTreeAreaWidth(
|
|
19
|
+
model.setTreeAreaWidth(
|
|
20
|
+
Math.min(
|
|
21
|
+
Math.max(0, startWidth + delta),
|
|
22
|
+
model.width - model.resizeHandleWidth,
|
|
23
|
+
),
|
|
24
|
+
)
|
|
18
25
|
},
|
|
19
26
|
[model],
|
|
20
27
|
)
|
|
@@ -36,7 +43,7 @@ export const HorizontalResizeHandle = observer(function ({
|
|
|
36
43
|
}) {
|
|
37
44
|
const onDrag = useCallback(
|
|
38
45
|
(delta: number, startHeight: number) => {
|
|
39
|
-
model.setHeight(startHeight + delta)
|
|
46
|
+
model.setHeight(Math.max(minViewHeight, startHeight + delta))
|
|
40
47
|
},
|
|
41
48
|
[model],
|
|
42
49
|
)
|
package/src/components/Track.tsx
CHANGED
|
@@ -3,11 +3,13 @@ import React, { lazy, useCallback, useRef, useState } from 'react'
|
|
|
3
3
|
import BaseTooltip from '@jbrowse/core/ui/BaseTooltip'
|
|
4
4
|
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
5
5
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
|
|
6
|
+
import CloseIcon from '@mui/icons-material/Close'
|
|
6
7
|
import { IconButton, Menu, MenuItem } from '@mui/material'
|
|
7
8
|
import { observer } from 'mobx-react'
|
|
8
9
|
|
|
9
10
|
import { useWheelScroll } from '../useWheelScroll.ts'
|
|
10
11
|
import { onMsaKey } from './msa/msaKeys.ts'
|
|
12
|
+
import TrackBlocks from './tracks/TrackBlocks.tsx'
|
|
11
13
|
import TrackTooltipContent from './tracks/TrackTooltipContent.tsx'
|
|
12
14
|
import { useTrackHover } from './tracks/useTrackHover.ts'
|
|
13
15
|
|
|
@@ -50,6 +52,7 @@ const TrackLabel = observer(function TrackLabel({
|
|
|
50
52
|
} = track
|
|
51
53
|
const { classes } = useStyles()
|
|
52
54
|
const trackLabelHeight = Math.min(height, fontSize)
|
|
55
|
+
const closeSize = Math.min(height, Math.max(fontSize, 16))
|
|
53
56
|
|
|
54
57
|
return (
|
|
55
58
|
// a flex row, not inline text: zooming in grows fontSize against a tree
|
|
@@ -77,6 +80,17 @@ const TrackLabel = observer(function TrackLabel({
|
|
|
77
80
|
>
|
|
78
81
|
{drawLabels ? name : ''}
|
|
79
82
|
</span>
|
|
83
|
+
<IconButton
|
|
84
|
+
className={classes.button}
|
|
85
|
+
aria-label={`Hide ${name} track`}
|
|
86
|
+
title="Hide track"
|
|
87
|
+
style={{ width: closeSize, height: closeSize, flexShrink: 0 }}
|
|
88
|
+
onClick={() => {
|
|
89
|
+
model.toggleTrack(track.model.id)
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
<CloseIcon style={{ fontSize: closeSize * 0.8 }} />
|
|
93
|
+
</IconButton>
|
|
80
94
|
<IconButton
|
|
81
95
|
className={classes.button}
|
|
82
96
|
aria-label={`${name} track menu`}
|
|
@@ -184,7 +198,7 @@ const Track = observer(function ({
|
|
|
184
198
|
onMouseLeave()
|
|
185
199
|
}}
|
|
186
200
|
>
|
|
187
|
-
<
|
|
201
|
+
<TrackBlocks model={model} track={track} />
|
|
188
202
|
{anchor ? (
|
|
189
203
|
<BaseTooltip clientPoint={anchor.clientPoint}>
|
|
190
204
|
<TrackTooltipContent
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface Control {
|
|
2
|
+
label: string
|
|
3
|
+
action: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface KeyControl extends Control {
|
|
7
|
+
keys: string[]
|
|
8
|
+
shiftKey?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const arrows = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']
|
|
12
|
+
|
|
13
|
+
export const keyboardControls: KeyControl[] = [
|
|
14
|
+
{ label: 'Arrow keys', action: 'Scroll one cell', keys: arrows },
|
|
15
|
+
{
|
|
16
|
+
label: 'Shift + arrow keys',
|
|
17
|
+
action: 'Scroll one page',
|
|
18
|
+
keys: arrows,
|
|
19
|
+
shiftKey: true,
|
|
20
|
+
},
|
|
21
|
+
{ label: '+ and -', action: 'Zoom in and out', keys: ['+', '=', '-'] },
|
|
22
|
+
{ label: '0', action: 'Reset to the default cell size', keys: ['0'] },
|
|
23
|
+
{
|
|
24
|
+
label: 'Home and End',
|
|
25
|
+
action: 'Jump to the first and last column',
|
|
26
|
+
keys: ['Home', 'End'],
|
|
27
|
+
},
|
|
28
|
+
{ label: 'Escape', action: 'Clear the selection', keys: ['Escape'] },
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
const selectCells: Control = {
|
|
32
|
+
label: 'Shift + drag',
|
|
33
|
+
action: 'Select a block of cells',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const mouseControls: Control[] = [
|
|
37
|
+
{ label: 'Drag', action: 'Pan the alignment' },
|
|
38
|
+
{
|
|
39
|
+
label: 'Wheel',
|
|
40
|
+
action: 'Scroll, or zoom with Zoom on scroll checked',
|
|
41
|
+
},
|
|
42
|
+
{ label: 'Ctrl + wheel', action: 'Zoom at the cursor' },
|
|
43
|
+
selectCells,
|
|
44
|
+
{
|
|
45
|
+
label: 'Drag along a track',
|
|
46
|
+
action: 'Select a range of columns across every row',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
label: 'Click a tree node',
|
|
50
|
+
action: 'Collapse, rotate, reroot or show only that clade',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
label: 'Click the tree overview',
|
|
54
|
+
action: 'Show only the clade under the pointer',
|
|
55
|
+
},
|
|
56
|
+
{ label: 'Drag a divider', action: 'Resize the tree area or a track' },
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
export const alignmentAriaLabel = [
|
|
60
|
+
'Alignment',
|
|
61
|
+
...[...keyboardControls, selectCells].map(c => `${c.label}: ${c.action}`),
|
|
62
|
+
].join('. ')
|
|
@@ -7,31 +7,18 @@ import {
|
|
|
7
7
|
DialogContent,
|
|
8
8
|
FormControl,
|
|
9
9
|
FormControlLabel,
|
|
10
|
+
Link,
|
|
10
11
|
Radio,
|
|
11
12
|
RadioGroup,
|
|
12
13
|
TextField,
|
|
13
14
|
Typography,
|
|
14
15
|
} from '@mui/material'
|
|
15
16
|
import { observer } from 'mobx-react'
|
|
16
|
-
import {
|
|
17
|
-
annotationsToGFF,
|
|
18
|
-
interProScanResponseToAnnotations,
|
|
19
|
-
} from 'msa-parsers'
|
|
17
|
+
import { annotationTextToGFF } from 'msa-parsers'
|
|
20
18
|
|
|
21
19
|
import type { MsaViewModel } from '../../model.ts'
|
|
22
|
-
import type { InterProScanResponse } from 'msa-parsers'
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
// arrive as text and the model keeps GFF, so the JSON is converted on the way
|
|
26
|
-
// in rather than given a second path through the model
|
|
27
|
-
function toGFF(text: string) {
|
|
28
|
-
const trimmed = text.trimStart()
|
|
29
|
-
if (!trimmed.startsWith('{')) {
|
|
30
|
-
return text
|
|
31
|
-
}
|
|
32
|
-
const response: InterProScanResponse = JSON.parse(trimmed)
|
|
33
|
-
return annotationsToGFF(interProScanResponseToAnnotations(response))
|
|
34
|
-
}
|
|
21
|
+
const domainsTutorial = 'https://gmod.org/JBrowseMSA/tutorials/protein_family'
|
|
35
22
|
|
|
36
23
|
async function fetchText(url: string) {
|
|
37
24
|
const response = await fetch(url)
|
|
@@ -73,7 +60,14 @@ const AnnotationFileDialog = observer(function ({
|
|
|
73
60
|
{error ? <ErrorMessage error={error} /> : null}
|
|
74
61
|
<Typography>
|
|
75
62
|
Open a GFF3 file of annotations, such as the one `react-msaview-cli
|
|
76
|
-
interpro` writes, or the JSON an InterProScan run returns.
|
|
63
|
+
interpro` writes, or the JSON an InterProScan run returns.{' '}
|
|
64
|
+
<Link
|
|
65
|
+
href={domainsTutorial}
|
|
66
|
+
target="_blank"
|
|
67
|
+
rel="noopener noreferrer"
|
|
68
|
+
>
|
|
69
|
+
How to make one
|
|
70
|
+
</Link>
|
|
77
71
|
</Typography>
|
|
78
72
|
|
|
79
73
|
<div style={{ display: 'flex', margin: 30 }}>
|
|
@@ -137,11 +131,12 @@ const AnnotationFileDialog = observer(function ({
|
|
|
137
131
|
? file.text()
|
|
138
132
|
: fetchText(url))
|
|
139
133
|
// through the model's own GFF text, so the annotations travel
|
|
140
|
-
// in the snapshot and the shared URL like every other layer.
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
model.setGFF(
|
|
134
|
+
// in the snapshot and the shared URL like every other layer. A
|
|
135
|
+
// filehandle left set would make the snapshot drop that text
|
|
136
|
+
model.setGFFFilehandle(undefined)
|
|
137
|
+
model.setGFF(annotationTextToGFF(text))
|
|
144
138
|
model.setShowDomains(true)
|
|
139
|
+
model.setCellFill('domain')
|
|
145
140
|
handleClose()
|
|
146
141
|
} catch (e) {
|
|
147
142
|
console.error(e)
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from '@mui/material'
|
|
18
18
|
import { observer } from 'mobx-react'
|
|
19
19
|
|
|
20
|
+
import { exportPageSize, getLayout } from '../../exportLayout.ts'
|
|
20
21
|
import Checkbox2 from '../Checkbox2.tsx'
|
|
21
22
|
|
|
22
23
|
import type { MsaViewModel } from '../../model.ts'
|
|
@@ -46,24 +47,12 @@ const ExportSVGDialog = observer(function ({
|
|
|
46
47
|
const [error, setError] = useState<unknown>()
|
|
47
48
|
const [exporting, setExporting] = useState(false)
|
|
48
49
|
const theme = useTheme()
|
|
49
|
-
const {
|
|
50
|
-
totalWidth,
|
|
51
|
-
totalHeight,
|
|
52
|
-
effectiveTreeAreaWidth,
|
|
53
|
-
rowPanelsWidth,
|
|
54
|
-
turnedOnTracks,
|
|
55
|
-
totalTrackAreaHeight,
|
|
56
|
-
numColumns,
|
|
57
|
-
leaves,
|
|
58
|
-
showMsaLetters,
|
|
59
|
-
treeOverviewHeight,
|
|
60
|
-
} = model
|
|
50
|
+
const { turnedOnTracks, numColumns, leaves, showMsaLetters } = model
|
|
61
51
|
const hasTracks = turnedOnTracks.length > 0
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
treeOverviewHeight
|
|
52
|
+
const entire = exportPageSize(
|
|
53
|
+
model,
|
|
54
|
+
getLayout(model, { theme, exportType: 'entire', includeTracks }),
|
|
55
|
+
)
|
|
67
56
|
// the background is one raster image whatever its size, so what the figure
|
|
68
57
|
// actually costs is its residue letters: each is an svg element of its own.
|
|
69
58
|
// Past roughly this many the export runs to tens of seconds and can exhaust
|
|
@@ -126,8 +115,8 @@ const ExportSVGDialog = observer(function ({
|
|
|
126
115
|
</div>
|
|
127
116
|
{isLargeExport ? (
|
|
128
117
|
<Alert severity="warning" style={{ marginTop: 8 }}>
|
|
129
|
-
The entire MSA is {Math.round(
|
|
130
|
-
{Math.round(
|
|
118
|
+
The entire MSA is {Math.round(entire.width)}x
|
|
119
|
+
{Math.round(entire.height)} pixels and draws{' '}
|
|
131
120
|
{Math.round(glyphs / 1000)}k residue letters, each its own SVG
|
|
132
121
|
element. Export may be slow or fail — zooming out far enough to hide
|
|
133
122
|
the letters exports the same alignment as an image instead.
|
|
@@ -102,12 +102,9 @@ const FeatureTable = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
102
102
|
<TableRow key={accession}>
|
|
103
103
|
<TableCell padding="checkbox">
|
|
104
104
|
<Checkbox
|
|
105
|
-
checked={!model.
|
|
105
|
+
checked={!model.featureOff(accession)}
|
|
106
106
|
onChange={() => {
|
|
107
|
-
model.setFilter(
|
|
108
|
-
accession,
|
|
109
|
-
!!model.turnedOffFeatures.get(accession),
|
|
110
|
-
)
|
|
107
|
+
model.setFilter(accession, model.featureOff(accession))
|
|
111
108
|
}}
|
|
112
109
|
/>
|
|
113
110
|
</TableCell>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { Dialog } from '@jbrowse/core/ui'
|
|
4
|
+
import { Button, DialogActions, DialogContent, Typography } from '@mui/material'
|
|
5
|
+
import { observer } from 'mobx-react'
|
|
6
|
+
|
|
7
|
+
import GappynessSlider from './GappynessSlider.tsx'
|
|
8
|
+
|
|
9
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
10
|
+
|
|
11
|
+
const GapThresholdDialog = observer(function ({
|
|
12
|
+
model,
|
|
13
|
+
onClose,
|
|
14
|
+
}: {
|
|
15
|
+
model: MsaViewModel
|
|
16
|
+
onClose: () => void
|
|
17
|
+
}) {
|
|
18
|
+
return (
|
|
19
|
+
<Dialog open onClose={onClose} title="Hide gappy columns">
|
|
20
|
+
<DialogContent>
|
|
21
|
+
<Typography variant="body2" sx={{ mb: 2 }}>
|
|
22
|
+
The viewer hides each column where at least this share of the rows has
|
|
23
|
+
a gap.
|
|
24
|
+
</Typography>
|
|
25
|
+
<GappynessSlider model={model} />
|
|
26
|
+
</DialogContent>
|
|
27
|
+
<DialogActions>
|
|
28
|
+
<Button variant="contained" onClick={onClose}>
|
|
29
|
+
Close
|
|
30
|
+
</Button>
|
|
31
|
+
</DialogActions>
|
|
32
|
+
</Dialog>
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export default GapThresholdDialog
|
|
@@ -10,19 +10,15 @@ const GappynessSlider = observer(function GappynessSlider({
|
|
|
10
10
|
}: {
|
|
11
11
|
model: MsaViewModel
|
|
12
12
|
}) {
|
|
13
|
-
const { hideGaps, allowedGappyness } = model
|
|
14
13
|
const [dragValue, setDragValue] = useState<number>()
|
|
15
|
-
const value = dragValue ?? allowedGappyness
|
|
16
|
-
if (!hideGaps) {
|
|
17
|
-
return null
|
|
18
|
-
}
|
|
14
|
+
const value = dragValue ?? model.allowedGappyness
|
|
19
15
|
return (
|
|
20
16
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
21
17
|
{/* the threshold is inclusive: blanks are columns whose gap count is at
|
|
22
18
|
least ceil(allowedGappyness% of the rows), so at 100 it hides the
|
|
23
19
|
columns that are entirely gaps rather than nothing */}
|
|
24
20
|
<Typography style={{ whiteSpace: 'nowrap' }}>
|
|
25
|
-
|
|
21
|
+
≥{value}% gaps
|
|
26
22
|
</Typography>
|
|
27
23
|
<Slider
|
|
28
24
|
// In JBrowse other MUI Sliders share the page, so `.MuiSlider-thumb`
|
|
@@ -36,11 +32,8 @@ const GappynessSlider = observer(function GappynessSlider({
|
|
|
36
32
|
// The thumb follows local state while dragging and the model takes the
|
|
37
33
|
// value on release, since each write recomputes the gap columns over
|
|
38
34
|
// the whole alignment.
|
|
39
|
-
//
|
|
40
|
-
// The thumb centers on the track's ends, so the margin keeps its
|
|
41
|
-
// overhang off the label and the row search beside it.
|
|
42
35
|
data-testid="gappyness_slider"
|
|
43
|
-
style={{ width:
|
|
36
|
+
style={{ width: 200, marginInline: 10 }}
|
|
44
37
|
min={1}
|
|
45
38
|
max={100}
|
|
46
39
|
value={value}
|
|
@@ -26,14 +26,32 @@ export function labelledInput(params: AutocompleteRenderInputParams) {
|
|
|
26
26
|
: { inputProps: { ...inputProps, 'aria-label': label } }
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
// the menu that opens the dialog hands focus back to its button as it closes,
|
|
30
|
+
// after an autoFocus input would have taken it
|
|
31
|
+
function focusNextFrame(el: HTMLInputElement | null) {
|
|
32
|
+
if (el) {
|
|
33
|
+
requestAnimationFrame(() => {
|
|
34
|
+
el.focus()
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function canGoTo(model: MsaViewModel) {
|
|
40
|
+
return findableRowNames(model).length > 1 || model.numColumns > 0
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const GoToBox = observer(function ({
|
|
44
|
+
model,
|
|
45
|
+
onFound,
|
|
46
|
+
}: {
|
|
47
|
+
model: MsaViewModel
|
|
48
|
+
onFound?: () => void
|
|
49
|
+
}) {
|
|
30
50
|
const [missed, setMissed] = useState(false)
|
|
31
|
-
|
|
32
|
-
return names.length > 1 || model.numColumns > 0 ? (
|
|
51
|
+
return (
|
|
33
52
|
<Autocomplete
|
|
34
53
|
freeSolo
|
|
35
|
-
|
|
36
|
-
options={names}
|
|
54
|
+
options={findableRowNames(model)}
|
|
37
55
|
filterOptions={(options, { inputValue }) =>
|
|
38
56
|
rowNameSuggestions(options, inputValue)
|
|
39
57
|
}
|
|
@@ -44,21 +62,29 @@ const GoToBox = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
44
62
|
}}
|
|
45
63
|
onChange={(_, text) => {
|
|
46
64
|
if (text) {
|
|
47
|
-
|
|
65
|
+
const found = goTo(model, text)
|
|
66
|
+
setMissed(!found)
|
|
67
|
+
if (found) {
|
|
68
|
+
onFound?.()
|
|
69
|
+
}
|
|
48
70
|
}
|
|
49
71
|
}}
|
|
50
|
-
style={{ width: 180, margin: 'auto 8px' }}
|
|
51
72
|
renderInput={params => (
|
|
52
73
|
<TextField
|
|
53
74
|
{...params}
|
|
75
|
+
inputRef={focusNextFrame}
|
|
54
76
|
error={missed}
|
|
55
|
-
placeholder=
|
|
56
|
-
|
|
77
|
+
placeholder="Row name or column number"
|
|
78
|
+
helperText={
|
|
79
|
+
missed
|
|
80
|
+
? 'No row or column matches'
|
|
81
|
+
: 'Or name:N for residue N of that row'
|
|
82
|
+
}
|
|
57
83
|
{...labelledInput(params)}
|
|
58
84
|
/>
|
|
59
85
|
)}
|
|
60
86
|
/>
|
|
61
|
-
)
|
|
87
|
+
)
|
|
62
88
|
})
|
|
63
89
|
|
|
64
90
|
export default GoToBox
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { Dialog } from '@jbrowse/core/ui'
|
|
4
|
+
import { DialogContent } from '@mui/material'
|
|
5
|
+
|
|
6
|
+
import GoToBox from './GoToBox.tsx'
|
|
7
|
+
|
|
8
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
9
|
+
|
|
10
|
+
export default function GoToDialog({
|
|
11
|
+
model,
|
|
12
|
+
onClose,
|
|
13
|
+
}: {
|
|
14
|
+
model: MsaViewModel
|
|
15
|
+
onClose: () => void
|
|
16
|
+
}) {
|
|
17
|
+
return (
|
|
18
|
+
<Dialog
|
|
19
|
+
open
|
|
20
|
+
onClose={onClose}
|
|
21
|
+
title="Go to row or column"
|
|
22
|
+
maxWidth="xs"
|
|
23
|
+
fullWidth
|
|
24
|
+
>
|
|
25
|
+
<DialogContent>
|
|
26
|
+
<GoToBox model={model} onFound={onClose} />
|
|
27
|
+
</DialogContent>
|
|
28
|
+
</Dialog>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React, { lazy } from 'react'
|
|
2
|
+
|
|
3
|
+
import { Dialog } from '@jbrowse/core/ui'
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
DialogActions,
|
|
7
|
+
DialogContent,
|
|
8
|
+
Table,
|
|
9
|
+
TableBody,
|
|
10
|
+
TableCell,
|
|
11
|
+
TableRow,
|
|
12
|
+
Typography,
|
|
13
|
+
} from '@mui/material'
|
|
14
|
+
|
|
15
|
+
import { version } from '../../version.ts'
|
|
16
|
+
import { keyboardControls, mouseControls } from '../controls.ts'
|
|
17
|
+
|
|
18
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
19
|
+
import type { Control } from '../controls.ts'
|
|
20
|
+
|
|
21
|
+
const AboutDialog = lazy(() => import('./AboutDialog.tsx'))
|
|
22
|
+
|
|
23
|
+
function ControlTable({ title, rows }: { title: string; rows: Control[] }) {
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<Typography variant="subtitle2" sx={{ mt: 1 }}>
|
|
27
|
+
{title}
|
|
28
|
+
</Typography>
|
|
29
|
+
<Table size="small" aria-label={title}>
|
|
30
|
+
<TableBody>
|
|
31
|
+
{rows.map(({ label, action }) => (
|
|
32
|
+
<TableRow key={label}>
|
|
33
|
+
<TableCell sx={{ whiteSpace: 'nowrap', fontWeight: 500 }}>
|
|
34
|
+
{label}
|
|
35
|
+
</TableCell>
|
|
36
|
+
<TableCell>{action}</TableCell>
|
|
37
|
+
</TableRow>
|
|
38
|
+
))}
|
|
39
|
+
</TableBody>
|
|
40
|
+
</Table>
|
|
41
|
+
</>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default function HelpDialog({
|
|
46
|
+
model,
|
|
47
|
+
onClose,
|
|
48
|
+
}: {
|
|
49
|
+
model: MsaViewModel
|
|
50
|
+
onClose: () => void
|
|
51
|
+
}) {
|
|
52
|
+
return (
|
|
53
|
+
<Dialog open title="Mouse & keyboard" onClose={onClose}>
|
|
54
|
+
<DialogContent>
|
|
55
|
+
<ControlTable title="Mouse" rows={mouseControls} />
|
|
56
|
+
<ControlTable
|
|
57
|
+
title="Keyboard (click the alignment first)"
|
|
58
|
+
rows={keyboardControls}
|
|
59
|
+
/>
|
|
60
|
+
</DialogContent>
|
|
61
|
+
<DialogActions>
|
|
62
|
+
<Typography variant="caption" sx={{ mr: 'auto', pl: 1 }}>
|
|
63
|
+
MSAView {version}
|
|
64
|
+
</Typography>
|
|
65
|
+
<Button
|
|
66
|
+
onClick={() => {
|
|
67
|
+
model.queueDialog(done => [AboutDialog, { onClose: done }])
|
|
68
|
+
onClose()
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
About & credits
|
|
72
|
+
</Button>
|
|
73
|
+
<Button variant="contained" onClick={onClose}>
|
|
74
|
+
Close
|
|
75
|
+
</Button>
|
|
76
|
+
</DialogActions>
|
|
77
|
+
</Dialog>
|
|
78
|
+
)
|
|
79
|
+
}
|