@jbrowse/plugin-linear-genome-view 1.6.1 → 1.6.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "1.6.1",
3
+ "version": "1.6.5",
4
4
  "description": "JBrowse 2 linear genome view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -61,5 +61,5 @@
61
61
  "publishConfig": {
62
62
  "access": "public"
63
63
  },
64
- "gitHead": "d6ad1b8e7fbb00000f2ac87f463c82e9db12ea01"
64
+ "gitHead": "ab41f017840ffef09f5d60b008281cedaa5abe26"
65
65
  }
@@ -96,9 +96,7 @@ const Tooltip = observer(
96
96
  {...attributes.popper}
97
97
  >
98
98
  <TooltipContents
99
- ref={(elt: HTMLDivElement) =>
100
- setWidth(elt?.getBoundingClientRect().width || 0)
101
- }
99
+ ref={elt => setWidth(elt?.getBoundingClientRect().width || 0)}
102
100
  message={contents}
103
101
  />
104
102
  </div>
@@ -1,7 +1,7 @@
1
+ import React from 'react'
1
2
  import { makeStyles } from '@material-ui/core/styles'
2
3
  import { getContainingView } from '@jbrowse/core/util'
3
- import { observer, PropTypes } from 'mobx-react'
4
- import React from 'react'
4
+ import { observer } from 'mobx-react'
5
5
  import {
6
6
  ContentBlock,
7
7
  ElidedBlock,
@@ -14,6 +14,7 @@ import {
14
14
  ElidedBlock as ElidedBlockComponent,
15
15
  InterRegionPaddingBlock as InterRegionPaddingBlockComponent,
16
16
  } from './Block'
17
+ import { LinearGenomeViewModel } from '../../LinearGenomeView'
17
18
 
18
19
  const useStyles = makeStyles({
19
20
  linearBlocks: {
@@ -96,8 +97,7 @@ const RenderedBlocks = observer(
96
97
  function LinearBlocks({ model }: { model: BaseLinearDisplayModel }) {
97
98
  const classes = useStyles()
98
99
  const { blockDefinitions } = model
99
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
- const viewModel = getContainingView(model) as any
100
+ const viewModel = getContainingView(model) as LinearGenomeViewModel
101
101
  return (
102
102
  <div
103
103
  data-testid="Blockset"
@@ -111,9 +111,5 @@ function LinearBlocks({ model }: { model: BaseLinearDisplayModel }) {
111
111
  )
112
112
  }
113
113
 
114
- LinearBlocks.propTypes = {
115
- model: PropTypes.observableObject.isRequired,
116
- }
117
-
118
114
  export { RenderedBlocks, useStyles }
119
115
  export default observer(LinearBlocks)
@@ -387,7 +387,10 @@ export const BaseLinearDisplay = types
387
387
  self.setError()
388
388
  const aborter = new AbortController()
389
389
  const view = getContainingView(self) as LGV
390
- if (!view.initialized) {
390
+
391
+ // extra check for contentBlocks.length
392
+ // https://github.com/GMOD/jbrowse-components/issues/2694
393
+ if (!view.initialized || !view.staticBlocks.contentBlocks.length) {
391
394
  return
392
395
  }
393
396
 
@@ -411,7 +414,7 @@ export const BaseLinearDisplay = types
411
414
  afterAttach() {
412
415
  // this autorun performs stats estimation
413
416
  //
414
- // the chain of events calls estimateRegionStats against the data
417
+ // the chain of events calls estimateRegionsStats against the data
415
418
  // adapter which by default uses featureDensity, but can also respond
416
419
  // with a byte size estimate and fetch size limit (data adapter can
417
420
  // define what is too much data)
@@ -102,7 +102,10 @@ const TrackLabel = React.forwardRef(
102
102
  handleClose()
103
103
  }
104
104
 
105
- const items = track.trackMenuItems()
105
+ const items = [
106
+ ...session.getTrackActionMenuItems?.(trackConf),
107
+ ...track.trackMenuItems(),
108
+ ].sort((a, b) => (b.priority || 0) - (a.priority || 0))
106
109
 
107
110
  return (
108
111
  <>
@@ -148,10 +151,7 @@ const TrackLabel = React.forwardRef(
148
151
  onMenuItemClick={handleMenuItemClick}
149
152
  open={Boolean(anchorEl)}
150
153
  onClose={handleClose}
151
- menuItems={[
152
- ...session.getTrackActionMenuItems?.(trackConf),
153
- ...items,
154
- ].sort((a, b) => (b.priority || 0) - (a.priority || 0))}
154
+ menuItems={items}
155
155
  />
156
156
  </>
157
157
  )
@@ -505,10 +505,9 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
505
505
  <button
506
506
  aria-controls="simple-menu"
507
507
  aria-haspopup="true"
508
- class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary MuiIconButton-disabled MuiButtonBase-disabled"
508
+ class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
509
509
  data-testid="track_menu_icon"
510
- disabled=""
511
- tabindex="-1"
510
+ tabindex="0"
512
511
  type="button"
513
512
  >
514
513
  <span
@@ -525,6 +524,9 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
525
524
  />
526
525
  </svg>
527
526
  </span>
527
+ <span
528
+ class="MuiTouchRipple-root"
529
+ />
528
530
  </button>
529
531
  </div>
530
532
  <div
@@ -1397,10 +1399,9 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
1397
1399
  <button
1398
1400
  aria-controls="simple-menu"
1399
1401
  aria-haspopup="true"
1400
- class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary MuiIconButton-disabled MuiButtonBase-disabled"
1402
+ class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
1401
1403
  data-testid="track_menu_icon"
1402
- disabled=""
1403
- tabindex="-1"
1404
+ tabindex="0"
1404
1405
  type="button"
1405
1406
  >
1406
1407
  <span
@@ -1417,6 +1418,9 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
1417
1418
  />
1418
1419
  </svg>
1419
1420
  </span>
1421
+ <span
1422
+ class="MuiTouchRipple-root"
1423
+ />
1420
1424
  </button>
1421
1425
  </div>
1422
1426
  <div
@@ -1551,10 +1555,9 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
1551
1555
  <button
1552
1556
  aria-controls="simple-menu"
1553
1557
  aria-haspopup="true"
1554
- class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary MuiIconButton-disabled MuiButtonBase-disabled"
1558
+ class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
1555
1559
  data-testid="track_menu_icon"
1556
- disabled=""
1557
- tabindex="-1"
1560
+ tabindex="0"
1558
1561
  type="button"
1559
1562
  >
1560
1563
  <span
@@ -1571,6 +1574,9 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
1571
1574
  />
1572
1575
  </svg>
1573
1576
  </span>
1577
+ <span
1578
+ class="MuiTouchRipple-root"
1579
+ />
1574
1580
  </button>
1575
1581
  </div>
1576
1582
  <div
@@ -104,6 +104,12 @@ export const INTER_REGION_PADDING_WIDTH = 2
104
104
  export const WIDGET_HEIGHT = 32
105
105
  export const SPACING = 7
106
106
 
107
+ function localStorageGetItem(item: string) {
108
+ return typeof localStorage !== 'undefined'
109
+ ? localStorage.getItem(item)
110
+ : undefined
111
+ }
112
+
107
113
  export function stateModelFactory(pluginManager: PluginManager) {
108
114
  return types
109
115
  .compose(
@@ -128,15 +134,15 @@ export function stateModelFactory(pluginManager: PluginManager) {
128
134
  ),
129
135
  trackLabels: types.optional(
130
136
  types.string,
131
- () => localStorage.getItem('lgv-trackLabels') || 'overlapping',
137
+ () => localStorageGetItem('lgv-trackLabels') || 'overlapping',
132
138
  ),
133
139
  showCenterLine: types.optional(types.boolean, () => {
134
- const setting = localStorage.getItem('lgv-showCenterLine')
135
- return setting !== undefined ? !!setting : false
140
+ const setting = localStorageGetItem('lgv-showCenterLine')
141
+ return setting !== undefined && setting !== null ? !!+setting : false
136
142
  }),
137
143
  showCytobandsSetting: types.optional(types.boolean, () => {
138
- const setting = localStorage.getItem('lgv-showCytobands')
139
- return setting !== undefined ? !!setting : true
144
+ const setting = localStorageGetItem('lgv-showCytobands')
145
+ return setting !== undefined && setting !== null ? !!+setting : true
140
146
  }),
141
147
  }),
142
148
  )
@@ -1214,127 +1220,128 @@ export function stateModelFactory(pluginManager: PluginManager) {
1214
1220
  : 0
1215
1221
  },
1216
1222
  }))
1217
- .views(self => {
1218
- let currentlyCalculatedStaticBlocks: BlockSet | undefined
1219
- let stringifiedCurrentlyCalculatedStaticBlocks = ''
1220
- return {
1221
- menuItems(): MenuItem[] {
1222
- const { canShowCytobands, showCytobands } = self
1223
-
1224
- const menuItems: MenuItem[] = [
1225
- {
1226
- label: 'Return to import form',
1227
- onClick: () => {
1228
- getSession(self).queueDialog((doneCallback: Function) => [
1229
- ReturnToImportFormDlg,
1230
- { model: self, handleClose: doneCallback },
1231
- ])
1232
- },
1233
- icon: FolderOpenIcon,
1234
- },
1235
- {
1236
- label: 'Export SVG',
1237
- icon: PhotoCameraIcon,
1238
- onClick: () => {
1239
- getSession(self).queueDialog((doneCallback: Function) => [
1240
- ExportSvgDlg,
1241
- { model: self, handleClose: doneCallback },
1242
- ])
1243
- },
1244
- },
1245
- {
1246
- label: 'Open track selector',
1247
- onClick: self.activateTrackSelector,
1248
- icon: TrackSelectorIcon,
1249
- },
1250
- {
1251
- label: 'Horizontally flip',
1252
- icon: SyncAltIcon,
1253
- onClick: self.horizontallyFlip,
1254
- },
1255
- { type: 'divider' },
1256
- {
1257
- label: 'Show all regions in assembly',
1258
- icon: VisibilityIcon,
1259
- onClick: self.showAllRegionsInAssembly,
1260
- },
1261
- {
1262
- label: 'Show center line',
1263
- icon: VisibilityIcon,
1264
- type: 'checkbox',
1265
- checked: self.showCenterLine,
1266
- onClick: self.toggleCenterLine,
1267
- },
1268
- {
1269
- label: 'Show header',
1270
- icon: VisibilityIcon,
1271
- type: 'checkbox',
1272
- checked: !self.hideHeader,
1273
- onClick: self.toggleHeader,
1223
+ .views(self => ({
1224
+ menuItems(): MenuItem[] {
1225
+ const { canShowCytobands, showCytobands } = self
1226
+
1227
+ const menuItems: MenuItem[] = [
1228
+ {
1229
+ label: 'Return to import form',
1230
+ onClick: () => {
1231
+ getSession(self).queueDialog((doneCallback: Function) => [
1232
+ ReturnToImportFormDlg,
1233
+ { model: self, handleClose: doneCallback },
1234
+ ])
1274
1235
  },
1275
- {
1276
- label: 'Show header overview',
1277
- icon: VisibilityIcon,
1278
- type: 'checkbox',
1279
- checked: !self.hideHeaderOverview,
1280
- onClick: self.toggleHeaderOverview,
1281
- disabled: self.hideHeader,
1236
+ icon: FolderOpenIcon,
1237
+ },
1238
+ {
1239
+ label: 'Export SVG',
1240
+ icon: PhotoCameraIcon,
1241
+ onClick: () => {
1242
+ getSession(self).queueDialog((doneCallback: Function) => [
1243
+ ExportSvgDlg,
1244
+ { model: self, handleClose: doneCallback },
1245
+ ])
1282
1246
  },
1283
- {
1284
- label: 'Track labels',
1285
- icon: LabelIcon,
1286
- subMenu: [
1287
- {
1288
- label: 'Overlapping',
1289
- icon: VisibilityIcon,
1290
- type: 'radio',
1291
- checked: self.trackLabels === 'overlapping',
1292
- onClick: () => self.setTrackLabels('overlapping'),
1293
- },
1294
- {
1295
- label: 'Offset',
1296
- icon: VisibilityIcon,
1297
- type: 'radio',
1298
- checked: self.trackLabels === 'offset',
1299
- onClick: () => self.setTrackLabels('offset'),
1300
- },
1247
+ },
1248
+ {
1249
+ label: 'Open track selector',
1250
+ onClick: self.activateTrackSelector,
1251
+ icon: TrackSelectorIcon,
1252
+ },
1253
+ {
1254
+ label: 'Horizontally flip',
1255
+ icon: SyncAltIcon,
1256
+ onClick: self.horizontallyFlip,
1257
+ },
1258
+ { type: 'divider' },
1259
+ {
1260
+ label: 'Show all regions in assembly',
1261
+ icon: VisibilityIcon,
1262
+ onClick: self.showAllRegionsInAssembly,
1263
+ },
1264
+ {
1265
+ label: 'Show center line',
1266
+ icon: VisibilityIcon,
1267
+ type: 'checkbox',
1268
+ checked: self.showCenterLine,
1269
+ onClick: self.toggleCenterLine,
1270
+ },
1271
+ {
1272
+ label: 'Show header',
1273
+ icon: VisibilityIcon,
1274
+ type: 'checkbox',
1275
+ checked: !self.hideHeader,
1276
+ onClick: self.toggleHeader,
1277
+ },
1278
+ {
1279
+ label: 'Show header overview',
1280
+ icon: VisibilityIcon,
1281
+ type: 'checkbox',
1282
+ checked: !self.hideHeaderOverview,
1283
+ onClick: self.toggleHeaderOverview,
1284
+ disabled: self.hideHeader,
1285
+ },
1286
+ {
1287
+ label: 'Track labels',
1288
+ icon: LabelIcon,
1289
+ subMenu: [
1290
+ {
1291
+ label: 'Overlapping',
1292
+ icon: VisibilityIcon,
1293
+ type: 'radio',
1294
+ checked: self.trackLabels === 'overlapping',
1295
+ onClick: () => self.setTrackLabels('overlapping'),
1296
+ },
1297
+ {
1298
+ label: 'Offset',
1299
+ icon: VisibilityIcon,
1300
+ type: 'radio',
1301
+ checked: self.trackLabels === 'offset',
1302
+ onClick: () => self.setTrackLabels('offset'),
1303
+ },
1304
+ {
1305
+ label: 'Hidden',
1306
+ icon: VisibilityIcon,
1307
+ type: 'radio',
1308
+ checked: self.trackLabels === 'hidden',
1309
+ onClick: () => self.setTrackLabels('hidden'),
1310
+ },
1311
+ ],
1312
+ },
1313
+ ...(canShowCytobands
1314
+ ? [
1301
1315
  {
1302
- label: 'Hidden',
1303
- icon: VisibilityIcon,
1304
- type: 'radio',
1305
- checked: self.trackLabels === 'hidden',
1306
- onClick: () => self.setTrackLabels('hidden'),
1307
- },
1308
- ],
1309
- },
1310
- ...(canShowCytobands
1311
- ? [
1312
- {
1313
- label: showCytobands ? 'Hide ideogram' : 'Show ideograms',
1314
- onClick: () => {
1315
- self.setShowCytobands(!showCytobands)
1316
- },
1316
+ label: showCytobands ? 'Hide ideogram' : 'Show ideograms',
1317
+ onClick: () => {
1318
+ self.setShowCytobands(!showCytobands)
1317
1319
  },
1318
- ]
1319
- : []),
1320
- ]
1320
+ },
1321
+ ]
1322
+ : []),
1323
+ ]
1321
1324
 
1322
- // add track's view level menu options
1323
- for (const [key, value] of self.trackTypeActions.entries()) {
1324
- if (value.length) {
1325
- menuItems.push(
1326
- { type: 'divider' },
1327
- { type: 'subHeader', label: key },
1328
- )
1329
- value.forEach(action => {
1330
- menuItems.push(action)
1331
- })
1332
- }
1325
+ // add track's view level menu options
1326
+ for (const [key, value] of self.trackTypeActions.entries()) {
1327
+ if (value.length) {
1328
+ menuItems.push(
1329
+ { type: 'divider' },
1330
+ { type: 'subHeader', label: key },
1331
+ )
1332
+ value.forEach(action => {
1333
+ menuItems.push(action)
1334
+ })
1333
1335
  }
1336
+ }
1334
1337
 
1335
- return menuItems
1336
- },
1337
-
1338
+ return menuItems
1339
+ },
1340
+ }))
1341
+ .views(self => {
1342
+ let currentlyCalculatedStaticBlocks: BlockSet | undefined
1343
+ let stringifiedCurrentlyCalculatedStaticBlocks = ''
1344
+ return {
1338
1345
  get staticBlocks() {
1339
1346
  const ret = calculateStaticBlocks(self)
1340
1347
  const sret = JSON.stringify(ret)