@jbrowse/plugin-linear-genome-view 2.4.1 → 2.5.0

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.
Files changed (201) hide show
  1. package/dist/BaseLinearDisplay/components/LinearBlocks.d.ts +1 -4
  2. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +8 -43
  3. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  4. package/dist/BaseLinearDisplay/components/TooLargeMessage.d.ts +3 -4
  5. package/dist/BaseLinearDisplay/components/TooLargeMessage.js +9 -9
  6. package/dist/BaseLinearDisplay/components/TooLargeMessage.js.map +1 -1
  7. package/dist/BaseLinearDisplay/components/Tooltip.d.ts +0 -1
  8. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +81 -35
  9. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +105 -143
  10. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  11. package/dist/BaseLinearDisplay/models/configSchema.d.ts +35 -1
  12. package/dist/BaseLinearDisplay/models/configSchema.js +9 -0
  13. package/dist/BaseLinearDisplay/models/configSchema.js.map +1 -1
  14. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +10 -6
  15. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  16. package/dist/BaseLinearDisplay/models/util.d.ts +8 -0
  17. package/dist/BaseLinearDisplay/models/util.js +33 -1
  18. package/dist/BaseLinearDisplay/models/util.js.map +1 -1
  19. package/dist/BasicTrack/configSchema.d.ts +73 -1
  20. package/dist/FeatureTrack/configSchema.d.ts +75 -1
  21. package/dist/LinearBareDisplay/configSchema.d.ts +28 -1
  22. package/dist/LinearBareDisplay/index.js +1 -0
  23. package/dist/LinearBareDisplay/index.js.map +1 -1
  24. package/dist/LinearBareDisplay/model.d.ts +66 -23
  25. package/dist/LinearBareDisplay/model.js +2 -2
  26. package/dist/LinearBareDisplay/model.js.map +1 -1
  27. package/dist/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -2
  28. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +2 -5
  29. package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  30. package/dist/LinearBasicDisplay/configSchema.d.ts +28 -1
  31. package/dist/LinearBasicDisplay/configSchema.js +0 -9
  32. package/dist/LinearBasicDisplay/configSchema.js.map +1 -1
  33. package/dist/LinearBasicDisplay/index.js +1 -1
  34. package/dist/LinearBasicDisplay/model.d.ts +76 -36
  35. package/dist/LinearBasicDisplay/model.js.map +1 -1
  36. package/dist/LinearGenomeView/components/CenterLine.d.ts +0 -1
  37. package/dist/LinearGenomeView/components/Cytobands.d.ts +22 -23
  38. package/dist/LinearGenomeView/components/ExportSvgDialog.d.ts +0 -1
  39. package/dist/LinearGenomeView/components/GetSequenceDialog.d.ts +0 -1
  40. package/dist/LinearGenomeView/components/GetSequenceDialog.js +14 -16
  41. package/dist/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
  42. package/dist/LinearGenomeView/components/Gridlines.d.ts +0 -1
  43. package/dist/LinearGenomeView/components/Header.d.ts +0 -1
  44. package/dist/LinearGenomeView/components/HelpDialog.d.ts +0 -1
  45. package/dist/LinearGenomeView/components/ImportForm.d.ts +0 -1
  46. package/dist/LinearGenomeView/components/ImportForm.js +4 -7
  47. package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
  48. package/dist/LinearGenomeView/components/LinearGenomeView.d.ts +0 -1
  49. package/dist/LinearGenomeView/components/LinearGenomeView.js +0 -4
  50. package/dist/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  51. package/dist/LinearGenomeView/components/MiniControls.d.ts +0 -1
  52. package/dist/LinearGenomeView/components/OverviewScalebar.js +2 -1
  53. package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
  54. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +53 -52
  55. package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  56. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +0 -1
  57. package/dist/LinearGenomeView/components/SearchBox.d.ts +0 -1
  58. package/dist/LinearGenomeView/components/SearchResultsDialog.d.ts +5 -3
  59. package/dist/LinearGenomeView/components/SearchResultsDialog.js +6 -82
  60. package/dist/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  61. package/dist/LinearGenomeView/components/SearchResultsTable.d.ts +8 -0
  62. package/dist/LinearGenomeView/components/SearchResultsTable.js +83 -0
  63. package/dist/LinearGenomeView/components/SearchResultsTable.js.map +1 -0
  64. package/dist/LinearGenomeView/components/SequenceSearchDialog.d.ts +0 -1
  65. package/dist/LinearGenomeView/components/TrackContainer.d.ts +0 -1
  66. package/dist/LinearGenomeView/components/TrackContainer.js +8 -2
  67. package/dist/LinearGenomeView/components/TrackContainer.js.map +1 -1
  68. package/dist/LinearGenomeView/components/TracksContainer.js +5 -7
  69. package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
  70. package/dist/LinearGenomeView/components/VerticalGuide.d.ts +0 -1
  71. package/dist/LinearGenomeView/components/ZoomControls.d.ts +0 -1
  72. package/dist/LinearGenomeView/components/util.js +1 -1
  73. package/dist/LinearGenomeView/components/util.js.map +1 -1
  74. package/dist/LinearGenomeView/model.d.ts +49 -36
  75. package/dist/LinearGenomeView/model.js +121 -198
  76. package/dist/LinearGenomeView/model.js.map +1 -1
  77. package/dist/LinearGenomeView/svgcomponents/SVGBackground.d.ts +0 -1
  78. package/dist/LinearGenomeView/svgcomponents/SVGHeader.d.ts +0 -1
  79. package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +0 -1
  80. package/dist/LinearGenomeView/svgcomponents/SVGRuler.d.ts +0 -1
  81. package/dist/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +0 -1
  82. package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +0 -1
  83. package/dist/LinearGenomeView/svgcomponents/SVGTracks.d.ts +0 -1
  84. package/dist/LinearGenomeView/util.d.ts +29 -0
  85. package/dist/LinearGenomeView/util.js +79 -1
  86. package/dist/LinearGenomeView/util.js.map +1 -1
  87. package/dist/index.d.ts +201 -106
  88. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +1 -4
  89. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +8 -20
  90. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  91. package/esm/BaseLinearDisplay/components/TooLargeMessage.d.ts +3 -4
  92. package/esm/BaseLinearDisplay/components/TooLargeMessage.js +9 -9
  93. package/esm/BaseLinearDisplay/components/TooLargeMessage.js.map +1 -1
  94. package/esm/BaseLinearDisplay/components/Tooltip.d.ts +0 -1
  95. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +81 -35
  96. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +105 -143
  97. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  98. package/esm/BaseLinearDisplay/models/configSchema.d.ts +35 -1
  99. package/esm/BaseLinearDisplay/models/configSchema.js +9 -0
  100. package/esm/BaseLinearDisplay/models/configSchema.js.map +1 -1
  101. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +10 -6
  102. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  103. package/esm/BaseLinearDisplay/models/util.d.ts +8 -0
  104. package/esm/BaseLinearDisplay/models/util.js +30 -0
  105. package/esm/BaseLinearDisplay/models/util.js.map +1 -1
  106. package/esm/BasicTrack/configSchema.d.ts +73 -1
  107. package/esm/FeatureTrack/configSchema.d.ts +75 -1
  108. package/esm/LinearBareDisplay/configSchema.d.ts +28 -1
  109. package/esm/LinearBareDisplay/index.js +1 -0
  110. package/esm/LinearBareDisplay/index.js.map +1 -1
  111. package/esm/LinearBareDisplay/model.d.ts +66 -23
  112. package/esm/LinearBareDisplay/model.js +1 -1
  113. package/esm/LinearBareDisplay/model.js.map +1 -1
  114. package/esm/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -2
  115. package/esm/LinearBasicDisplay/components/SetMaxHeight.js +2 -5
  116. package/esm/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  117. package/esm/LinearBasicDisplay/configSchema.d.ts +28 -1
  118. package/esm/LinearBasicDisplay/configSchema.js +0 -9
  119. package/esm/LinearBasicDisplay/configSchema.js.map +1 -1
  120. package/esm/LinearBasicDisplay/index.js +1 -1
  121. package/esm/LinearBasicDisplay/model.d.ts +76 -36
  122. package/esm/LinearBasicDisplay/model.js.map +1 -1
  123. package/esm/LinearGenomeView/components/CenterLine.d.ts +0 -1
  124. package/esm/LinearGenomeView/components/Cytobands.d.ts +22 -23
  125. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +0 -1
  126. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +0 -1
  127. package/esm/LinearGenomeView/components/GetSequenceDialog.js +15 -17
  128. package/esm/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
  129. package/esm/LinearGenomeView/components/Gridlines.d.ts +0 -1
  130. package/esm/LinearGenomeView/components/Header.d.ts +0 -1
  131. package/esm/LinearGenomeView/components/HelpDialog.d.ts +0 -1
  132. package/esm/LinearGenomeView/components/ImportForm.d.ts +0 -1
  133. package/esm/LinearGenomeView/components/ImportForm.js +5 -8
  134. package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
  135. package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +0 -1
  136. package/esm/LinearGenomeView/components/LinearGenomeView.js +0 -4
  137. package/esm/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  138. package/esm/LinearGenomeView/components/MiniControls.d.ts +0 -1
  139. package/esm/LinearGenomeView/components/OverviewScalebar.js +2 -1
  140. package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
  141. package/esm/LinearGenomeView/components/RefNameAutocomplete.js +53 -52
  142. package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  143. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +0 -1
  144. package/esm/LinearGenomeView/components/SearchBox.d.ts +0 -1
  145. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +5 -3
  146. package/esm/LinearGenomeView/components/SearchResultsDialog.js +7 -83
  147. package/esm/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  148. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +8 -0
  149. package/esm/LinearGenomeView/components/SearchResultsTable.js +77 -0
  150. package/esm/LinearGenomeView/components/SearchResultsTable.js.map +1 -0
  151. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +0 -1
  152. package/esm/LinearGenomeView/components/TrackContainer.d.ts +0 -1
  153. package/esm/LinearGenomeView/components/TrackContainer.js +8 -2
  154. package/esm/LinearGenomeView/components/TrackContainer.js.map +1 -1
  155. package/esm/LinearGenomeView/components/TracksContainer.js +5 -7
  156. package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
  157. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +0 -1
  158. package/esm/LinearGenomeView/components/ZoomControls.d.ts +0 -1
  159. package/esm/LinearGenomeView/components/util.js +1 -1
  160. package/esm/LinearGenomeView/components/util.js.map +1 -1
  161. package/esm/LinearGenomeView/model.d.ts +49 -36
  162. package/esm/LinearGenomeView/model.js +122 -199
  163. package/esm/LinearGenomeView/model.js.map +1 -1
  164. package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +0 -1
  165. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +0 -1
  166. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +0 -1
  167. package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +0 -1
  168. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +0 -1
  169. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +0 -1
  170. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +0 -1
  171. package/esm/LinearGenomeView/util.d.ts +29 -0
  172. package/esm/LinearGenomeView/util.js +76 -0
  173. package/esm/LinearGenomeView/util.js.map +1 -1
  174. package/esm/index.d.ts +201 -106
  175. package/package.json +3 -3
  176. package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +8 -28
  177. package/src/BaseLinearDisplay/components/TooLargeMessage.tsx +13 -11
  178. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +148 -197
  179. package/src/BaseLinearDisplay/models/configSchema.ts +10 -0
  180. package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +19 -13
  181. package/src/BaseLinearDisplay/models/util.ts +43 -0
  182. package/src/LinearBareDisplay/index.ts +1 -0
  183. package/src/LinearBareDisplay/model.ts +1 -1
  184. package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +3 -7
  185. package/src/LinearBasicDisplay/configSchema.ts +0 -10
  186. package/src/LinearBasicDisplay/index.ts +1 -1
  187. package/src/LinearBasicDisplay/model.ts +1 -1
  188. package/src/LinearGenomeView/components/GetSequenceDialog.tsx +15 -25
  189. package/src/LinearGenomeView/components/ImportForm.tsx +4 -14
  190. package/src/LinearGenomeView/components/LinearGenomeView.tsx +0 -14
  191. package/src/LinearGenomeView/components/OverviewScalebar.tsx +2 -1
  192. package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +122 -82
  193. package/src/LinearGenomeView/components/SearchResultsDialog.tsx +17 -112
  194. package/src/LinearGenomeView/components/SearchResultsTable.tsx +121 -0
  195. package/src/LinearGenomeView/components/TrackContainer.tsx +12 -3
  196. package/src/LinearGenomeView/components/TracksContainer.tsx +9 -6
  197. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +11 -11
  198. package/src/LinearGenomeView/components/util.ts +2 -1
  199. package/src/LinearGenomeView/index.test.ts +10 -12
  200. package/src/LinearGenomeView/model.ts +163 -236
  201. package/src/LinearGenomeView/util.ts +98 -0
@@ -63,19 +63,25 @@ const blockState = types
63
63
  },
64
64
  afterAttach() {
65
65
  const display = getContainingDisplay(self)
66
- makeAbortableReaction(
67
- self as any,
68
- renderBlockData,
69
- renderBlockEffect, // reaction doesn't expect async here
70
- {
71
- name: `${display.id}/${assembleLocString(self.region)} rendering`,
72
- delay: display.renderDelay,
73
- fireImmediately: true,
74
- },
75
- this.setLoading,
76
- this.setRendered,
77
- this.setError,
78
- )
66
+ setTimeout(() => {
67
+ if (isAlive(self)) {
68
+ makeAbortableReaction(
69
+ self as any,
70
+ renderBlockData,
71
+ renderBlockEffect, // reaction doesn't expect async here
72
+ {
73
+ name: `${display.id}/${assembleLocString(
74
+ self.region,
75
+ )} rendering`,
76
+ delay: display.renderDelay,
77
+ fireImmediately: true,
78
+ },
79
+ this.setLoading,
80
+ this.setRendered,
81
+ this.setError,
82
+ )
83
+ }
84
+ }, display.renderDelay)
79
85
  },
80
86
  setStatus(message: string) {
81
87
  self.status = message
@@ -1,3 +1,10 @@
1
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration'
2
+ import { FeatureDensityStats } from '@jbrowse/core/data_adapters/BaseAdapter'
3
+ import { getContainingView, getSession } from '@jbrowse/core/util'
4
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks'
5
+ import { IAnyStateTreeNode, isAlive } from 'mobx-state-tree'
6
+ import { LinearGenomeViewModel } from '../../LinearGenomeView'
7
+
1
8
  export interface RenderProps {
2
9
  rendererType: any // eslint-disable-line @typescript-eslint/no-explicit-any
3
10
  renderArgs: { [key: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -22,3 +29,39 @@ export function getDisplayStr(totalBytes: number) {
22
29
  }
23
30
  return displayBp
24
31
  }
32
+
33
+ // stabilize clipid under test for snapshot
34
+ export function getId(id: string, index: number) {
35
+ const isJest = typeof jest === 'undefined'
36
+ return `clip-${isJest ? id : 'jest'}-${index}`
37
+ }
38
+
39
+ export async function getFeatureDensityStatsPre(
40
+ self: IAnyStateTreeNode & {
41
+ adapterConfig?: AnyConfigurationModel
42
+ setMessage: (arg: string) => void
43
+ },
44
+ ) {
45
+ const view = getContainingView(self) as LinearGenomeViewModel
46
+ const regions = view.staticBlocks.contentBlocks
47
+
48
+ const { rpcManager } = getSession(self)
49
+ const { adapterConfig } = self
50
+ if (!adapterConfig) {
51
+ // A track extending the base track might not have an adapter config
52
+ // e.g. Apollo tracks don't use adapters
53
+ return {}
54
+ }
55
+ const sessionId = getRpcSessionId(self)
56
+
57
+ return rpcManager.call(sessionId, 'CoreGetFeatureDensityStats', {
58
+ sessionId,
59
+ regions,
60
+ adapterConfig,
61
+ statusCallback: (message: string) => {
62
+ if (isAlive(self)) {
63
+ self.setMessage(message)
64
+ }
65
+ },
66
+ }) as Promise<FeatureDensityStats>
67
+ }
@@ -12,6 +12,7 @@ export default (pluginManager: PluginManager) => {
12
12
  return new DisplayType({
13
13
  name: 'LinearBareDisplay',
14
14
  configSchema,
15
+ displayName: 'Bare feature display',
15
16
  stateModel: stateModelFactory(configSchema),
16
17
  trackType: 'BasicTrack',
17
18
  viewType: 'LinearGenomeView',
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AnyConfigurationSchemaType,
3
3
  ConfigurationReference,
4
- } from '@jbrowse/core/configuration/configurationSchema'
4
+ } from '@jbrowse/core/configuration'
5
5
  import { getParentRenderProps } from '@jbrowse/core/util/tracks'
6
6
  import { types } from 'mobx-state-tree'
7
7
  import { BaseLinearDisplay } from '../BaseLinearDisplay'
@@ -10,15 +10,11 @@ import {
10
10
  } from '@mui/material'
11
11
  import { makeStyles } from 'tss-react/mui'
12
12
 
13
- const useStyles = makeStyles()(theme => ({
13
+ const useStyles = makeStyles()({
14
14
  root: {
15
15
  width: 500,
16
16
  },
17
-
18
- field: {
19
- margin: theme.spacing(2),
20
- },
21
- }))
17
+ })
22
18
 
23
19
  function SetMaxHeightDlg({
24
20
  model,
@@ -26,7 +22,7 @@ function SetMaxHeightDlg({
26
22
  }: {
27
23
  model: {
28
24
  maxHeight?: number
29
- setMaxHeight: Function
25
+ setMaxHeight: (arg?: number) => void
30
26
  }
31
27
  handleClose: () => void
32
28
  }) {
@@ -9,16 +9,6 @@ function configSchemaFactory(pluginManager: PluginManager) {
9
9
  return ConfigurationSchema(
10
10
  'LinearBasicDisplay',
11
11
  {
12
- /**
13
- * #slot
14
- */
15
- mouseover: {
16
- type: 'string',
17
- description: 'what to display in a given mouseover',
18
- defaultValue: `jexl:get(feature,'name')`,
19
-
20
- contextVariable: ['feature'],
21
- },
22
12
  /**
23
13
  * #slot
24
14
  */
@@ -11,7 +11,7 @@ export default (pluginManager: PluginManager) => {
11
11
  const config = configSchema(pluginManager)
12
12
  return new DisplayType({
13
13
  name: 'LinearBasicDisplay',
14
- displayName: 'Basic deature display',
14
+ displayName: 'Basic feature display',
15
15
  configSchema: config,
16
16
  stateModel: modelFactory(config),
17
17
  trackType: 'FeatureTrack',
@@ -137,7 +137,7 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
137
137
  /**
138
138
  * #action
139
139
  */
140
- setMaxHeight(val: number) {
140
+ setMaxHeight(val?: number) {
141
141
  self.trackMaxHeight = val
142
142
  },
143
143
  }))
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from 'react'
1
+ import React, { useEffect, useState } from 'react'
2
2
  import { makeStyles } from 'tss-react/mui'
3
3
  import {
4
4
  Button,
@@ -96,14 +96,6 @@ function SequenceDialog({
96
96
  const { leftOffset, rightOffset } = model
97
97
  const loading = Boolean(sequenceChunks === undefined)
98
98
 
99
- // avoid infinite looping of useEffect
100
- // random note: the current selected region can't be a computed because it
101
- // uses action on base1dview even though it's on the ephemeral base1dview
102
- const regionsSelected = useMemo(
103
- () => model.getSelectedRegions(leftOffset, rightOffset),
104
- [model, leftOffset, rightOffset],
105
- )
106
-
107
99
  useEffect(() => {
108
100
  let active = true
109
101
  const controller = new AbortController()
@@ -111,18 +103,17 @@ function SequenceDialog({
111
103
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
112
104
  ;(async () => {
113
105
  try {
114
- if (regionsSelected.length > 0) {
115
- const chunks = await fetchSequence(
116
- model,
117
- regionsSelected,
118
- controller.signal,
119
- )
120
- if (active) {
121
- setSequenceChunks(chunks)
122
- }
123
- } else {
106
+ // random note: the current selected region can't be a computed because
107
+ // it uses action on base1dview even though it's on the ephemeral
108
+ // base1dview
109
+ const selection = model.getSelectedRegions(leftOffset, rightOffset)
110
+ if (selection.length === 0) {
124
111
  throw new Error('Selected region is out of bounds')
125
112
  }
113
+ const chunks = await fetchSequence(model, selection, controller.signal)
114
+ if (active) {
115
+ setSequenceChunks(chunks)
116
+ }
126
117
  } catch (e) {
127
118
  console.error(e)
128
119
  if (active) {
@@ -135,7 +126,7 @@ function SequenceDialog({
135
126
  controller.abort()
136
127
  active = false
137
128
  }
138
- }, [model, session, regionsSelected])
129
+ }, [model, session, leftOffset, rightOffset])
139
130
 
140
131
  const sequence = sequenceChunks
141
132
  ? formatSeqFasta(
@@ -146,10 +137,10 @@ function SequenceDialog({
146
137
  const chunkRefName = chunk.get('refName')
147
138
  const chunkStart = chunk.get('start') + 1
148
139
  const chunkEnd = chunk.get('end')
149
- const chunkLocstring = `${chunkRefName}:${chunkStart}-${chunkEnd}`
140
+ const loc = `${chunkRefName}:${chunkStart}-${chunkEnd}`
150
141
  if (chunkSeq?.length !== chunkEnd - chunkStart + 1) {
151
142
  throw new Error(
152
- `${chunkLocstring} returned ${chunkSeq.length.toLocaleString()} bases, but should have returned ${(
143
+ `${loc} returned ${chunkSeq.length.toLocaleString()} bases, but should have returned ${(
153
144
  chunkEnd - chunkStart
154
145
  ).toLocaleString()}`,
155
146
  )
@@ -162,8 +153,7 @@ function SequenceDialog({
162
153
  chunkSeq = complement(chunkSeq)
163
154
  }
164
155
  return {
165
- header:
166
- chunkLocstring + (rev ? '-rev' : '') + (comp ? '-comp' : ''),
156
+ header: loc + (rev ? '-rev' : '') + (comp ? '-comp' : ''),
167
157
  seq: chunkSeq,
168
158
  }
169
159
  }),
@@ -178,7 +168,7 @@ function SequenceDialog({
178
168
  open
179
169
  onClose={() => {
180
170
  handleClose()
181
- model.setOffsets(undefined, undefined)
171
+ model.setOffsets()
182
172
  }}
183
173
  title="Reference sequence"
184
174
  >
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, lazy } from 'react'
1
+ import React, { useState, useEffect } from 'react'
2
2
  import { makeStyles } from 'tss-react/mui'
3
3
  import { observer } from 'mobx-react'
4
4
  import { getSession } from '@jbrowse/core/util'
@@ -20,9 +20,6 @@ import RefNameAutocomplete from './RefNameAutocomplete'
20
20
  import { fetchResults, splitLast } from './util'
21
21
  import { LinearGenomeViewModel } from '..'
22
22
 
23
- // lazies
24
- const SearchResultsDialog = lazy(() => import('./SearchResultsDialog'))
25
-
26
23
  const useStyles = makeStyles()(theme => ({
27
24
  importFormContainer: {
28
25
  padding: theme.spacing(2),
@@ -41,7 +38,7 @@ export default observer(function ({ model }: { model: LGV }) {
41
38
  const { classes } = useStyles()
42
39
  const session = getSession(model)
43
40
  const { assemblyNames, assemblyManager, textSearchManager } = session
44
- const { rankSearchResults, isSearchDialogDisplayed, error } = model
41
+ const { rankSearchResults, error } = model
45
42
  const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0])
46
43
  const [option, setOption] = useState<BaseResult>()
47
44
  const searchScope = model.searchScope(selectedAsm)
@@ -85,7 +82,7 @@ export default observer(function ({ model }: { model: LGV }) {
85
82
  if (option?.getDisplayString() === input && option.hasLocation()) {
86
83
  await navToOption(option)
87
84
  } else if (option?.results?.length) {
88
- model.setSearchResults(option.results, option.getLabel())
85
+ model.setSearchResults(option.results, option.getLabel(), selectedAsm)
89
86
  } else {
90
87
  const [ref, rest] = splitLast(input, ':')
91
88
  const allRefs = assembly?.allRefNamesWithLowerCase || []
@@ -105,7 +102,7 @@ export default observer(function ({ model }: { model: LGV }) {
105
102
  })
106
103
 
107
104
  if (results.length > 1) {
108
- model.setSearchResults(results, input.toLowerCase())
105
+ model.setSearchResults(results, input.toLowerCase(), selectedAsm)
109
106
  } else if (results.length === 1) {
110
107
  await navToOption(results[0])
111
108
  } else {
@@ -215,13 +212,6 @@ export default observer(function ({ model }: { model: LGV }) {
215
212
  </Grid>
216
213
  </form>
217
214
  </Container>
218
- {isSearchDialogDisplayed ? (
219
- <SearchResultsDialog
220
- model={model}
221
- optAssemblyName={selectedAsm}
222
- handleClose={() => model.setSearchResults(undefined, undefined)}
223
- />
224
- ) : null}
225
215
  </div>
226
216
  )
227
217
  })
@@ -10,8 +10,6 @@ import { LinearGenomeViewModel } from '..'
10
10
  import TrackContainer from './TrackContainer'
11
11
  import TracksContainer from './TracksContainer'
12
12
  import ImportForm from './ImportForm'
13
- import GetSequenceDialog from './GetSequenceDialog'
14
- import SearchResultsDialog from './SearchResultsDialog'
15
13
 
16
14
  type LGV = LinearGenomeViewModel
17
15
 
@@ -39,18 +37,6 @@ const LinearGenomeView = observer(({ model }: { model: LGV }) => {
39
37
 
40
38
  return (
41
39
  <div style={{ position: 'relative' }}>
42
- {model.seqDialogDisplayed ? (
43
- <GetSequenceDialog
44
- model={model}
45
- handleClose={() => model.setGetSequenceDialogOpen(false)}
46
- />
47
- ) : null}
48
- {model.isSearchDialogDisplayed ? (
49
- <SearchResultsDialog
50
- model={model}
51
- handleClose={() => model.setSearchResults(undefined, undefined)}
52
- />
53
- ) : null}
54
40
  <HeaderComponent model={model} />
55
41
  <MiniControlsComponent model={model} />
56
42
  <TracksContainer model={model}>
@@ -69,6 +69,7 @@ const useStyles = makeStyles()(theme => ({
69
69
  position: 'relative',
70
70
  },
71
71
  overviewSvg: {
72
+ pointerEvents: 'none',
72
73
  width: '100%',
73
74
  position: 'absolute',
74
75
  },
@@ -170,7 +171,7 @@ const OverviewBox = observer(function ({
170
171
  style={{
171
172
  left: block.offsetPx + 3,
172
173
  color: canDisplayCytobands
173
- ? theme.palette.primary.contrastText
174
+ ? theme.palette.text.primary
174
175
  : refNameColor,
175
176
  }}
176
177
  className={classes.scalebarRefName}
@@ -6,6 +6,7 @@ import BaseResult, {
6
6
  } from '@jbrowse/core/TextSearch/BaseResults'
7
7
  import {
8
8
  Autocomplete,
9
+ AutocompleteRenderInputParams,
9
10
  IconButton,
10
11
  InputAdornment,
11
12
  TextField,
@@ -30,13 +31,12 @@ export interface Option {
30
31
  function aggregateResults(results: BaseResult[]) {
31
32
  const m: { [key: string]: BaseResult[] } = {}
32
33
 
33
- for (let i = 0; i < results.length; i++) {
34
- const r = results[i]
35
- const d = r.getDisplayString()
36
- if (!m[d]) {
37
- m[d] = []
34
+ for (const result of results) {
35
+ const displayString = result.getDisplayString()
36
+ if (!m[displayString]) {
37
+ m[displayString] = []
38
38
  }
39
- m[d].push(r)
39
+ m[displayString].push(result)
40
40
  }
41
41
  return m
42
42
  }
@@ -63,13 +63,28 @@ function getDeduplicatedResult(results: BaseResult[]) {
63
63
  // because they do not have a matchedObject. the trix search results already
64
64
  // filter so don't need re-filtering
65
65
  function filterOptions(options: Option[], searchQuery: string) {
66
- return options.filter(option => {
67
- const { result } = option
68
- return (
66
+ return options.filter(
67
+ ({ result }) =>
69
68
  result.getLabel().toLowerCase().includes(searchQuery) ||
70
- result.matchedObject
71
- )
72
- })
69
+ result.matchedObject,
70
+ )
71
+ }
72
+
73
+ function getFiltered(opts: Option[], inputValue: string) {
74
+ const filtered = filterOptions(opts, inputValue.toLocaleLowerCase())
75
+ return [
76
+ ...filtered.slice(0, 100),
77
+ ...(filtered.length > 100
78
+ ? [
79
+ {
80
+ group: 'limitOption',
81
+ result: new BaseResult({
82
+ label: 'keep typing for more results',
83
+ }),
84
+ },
85
+ ]
86
+ : []),
87
+ ]
73
88
  }
74
89
 
75
90
  function RefNameAutocomplete({
@@ -101,7 +116,6 @@ function RefNameAutocomplete({
101
116
  const { assemblyManager } = session
102
117
  const [open, setOpen] = useState(false)
103
118
  const [loaded, setLoaded] = useState(true)
104
- const [isHelpDialogDisplayed, setHelpDialogDisplayed] = useState(false)
105
119
  const [currentSearch, setCurrentSearch] = useState('')
106
120
  const [inputValue, setInputValue] = useState('')
107
121
  const [searchOptions, setSearchOptions] = useState<Option[]>()
@@ -109,18 +123,17 @@ function RefNameAutocomplete({
109
123
  const assembly = assemblyName ? assemblyManager.get(assemblyName) : undefined
110
124
  const { coarseVisibleLocStrings, hasDisplayedRegions } = model
111
125
 
112
- // eslint-disable-next-line react-hooks/exhaustive-deps
113
- const regions = assembly?.regions || []
126
+ const regions = assembly?.regions
114
127
 
115
128
  const options = useMemo(
116
129
  () =>
117
- regions.map(option => ({
130
+ regions?.map(option => ({
118
131
  result: new RefSequenceResult({
119
132
  refName: option.refName,
120
133
  label: option.refName,
121
134
  matchedAttribute: 'refName',
122
135
  }),
123
- })),
136
+ })) || [],
124
137
  [regions],
125
138
  )
126
139
 
@@ -155,10 +168,12 @@ function RefNameAutocomplete({
155
168
 
156
169
  const inputBoxVal = coarseVisibleLocStrings || value || ''
157
170
 
158
- // heuristic, text width + icon width + 50 accommodates help icon and search
171
+ // heuristic, text width + 60 accommodates help icon and search
159
172
  // icon
160
- const w = measureText(inputBoxVal, 16) + 50
161
- const width = Math.min(Math.max(w, minWidth), maxWidth)
173
+ const width = Math.min(
174
+ Math.max(measureText(inputBoxVal, 14) + 100, minWidth),
175
+ maxWidth,
176
+ )
162
177
 
163
178
  // notes on implementation:
164
179
  // The selectOnFocus setting helps highlight the field when clicked
@@ -205,70 +220,77 @@ function RefNameAutocomplete({
205
220
  setInputValue(inputBoxVal)
206
221
  }}
207
222
  options={!searchOptions?.length ? options : searchOptions}
208
- getOptionDisabled={option => option?.group === 'limitOption'}
209
- filterOptions={(options, params) => {
210
- const filtered = filterOptions(
211
- options,
212
- params.inputValue.toLocaleLowerCase(),
213
- )
214
- return [
215
- ...filtered.slice(0, 100),
216
- ...(filtered.length > 100
217
- ? [
218
- {
219
- group: 'limitOption',
220
- result: new BaseResult({
221
- label: 'keep typing for more results',
222
- }),
223
- },
224
- ]
225
- : []),
226
- ]
227
- }}
228
- renderInput={params => {
229
- const { helperText, InputProps = {} } = TextFieldProps
230
- return (
231
- <TextField
232
- onBlur={() =>
233
- // this is used to restore a refName or the non-user-typed input
234
- // to the box on blurring
235
- setInputValue(inputBoxVal)
236
- }
237
- {...params}
238
- {...TextFieldProps}
239
- helperText={helperText}
240
- InputProps={{
241
- ...params.InputProps,
242
- ...InputProps,
243
-
244
- endAdornment: (
245
- <>
246
- <InputAdornment position="end" style={{ marginRight: 7 }}>
247
- <SearchIcon fontSize="small" />
248
- {showHelp ? (
249
- <IconButton
250
- onClick={() => setHelpDialogDisplayed(true)}
251
- size="small"
252
- >
253
- <HelpIcon fontSize="small" />
254
- </IconButton>
255
- ) : null}
256
- </InputAdornment>
257
- {params.InputProps.endAdornment}
258
- </>
259
- ),
260
- }}
261
- placeholder="Search for location"
262
- onChange={e => setCurrentSearch(e.target.value)}
263
- />
264
- )
265
- }}
266
- getOptionLabel={option =>
267
- (typeof option === 'string'
268
- ? option
269
- : option.result.getDisplayString()) || ''
223
+ getOptionDisabled={option => option.group === 'limitOption'}
224
+ filterOptions={(opts, { inputValue }) => getFiltered(opts, inputValue)}
225
+ renderInput={params => (
226
+ <AutocompleteTextField
227
+ showHelp={showHelp}
228
+ params={params}
229
+ inputBoxVal={inputBoxVal}
230
+ TextFieldProps={TextFieldProps}
231
+ setCurrentSearch={setCurrentSearch}
232
+ setInputValue={setInputValue}
233
+ />
234
+ )}
235
+ getOptionLabel={opt =>
236
+ typeof opt === 'string' ? opt : opt.result.getDisplayString()
270
237
  }
271
238
  />
239
+ </>
240
+ )
241
+ }
242
+
243
+ function AutocompleteTextField({
244
+ TextFieldProps,
245
+ inputBoxVal,
246
+ params,
247
+ showHelp,
248
+ setInputValue,
249
+ setCurrentSearch,
250
+ }: {
251
+ TextFieldProps: TFP
252
+ inputBoxVal: string
253
+ showHelp?: boolean
254
+ params: AutocompleteRenderInputParams
255
+ setInputValue: (arg: string) => void
256
+ setCurrentSearch: (arg: string) => void
257
+ }) {
258
+ const { helperText, InputProps = {} } = TextFieldProps
259
+ return (
260
+ <TextField
261
+ onBlur={() =>
262
+ // this is used to restore a refName or the non-user-typed input
263
+ // to the box on blurring
264
+ setInputValue(inputBoxVal)
265
+ }
266
+ {...params}
267
+ {...TextFieldProps}
268
+ size="small"
269
+ helperText={helperText}
270
+ InputProps={{
271
+ ...params.InputProps,
272
+ ...InputProps,
273
+
274
+ endAdornment: (
275
+ <EndAdornment
276
+ showHelp={showHelp}
277
+ endAdornment={params.InputProps.endAdornment}
278
+ />
279
+ ),
280
+ }}
281
+ placeholder="Search for location"
282
+ onChange={e => setCurrentSearch(e.target.value)}
283
+ />
284
+ )
285
+ }
286
+
287
+ function HelpAdornment() {
288
+ const [isHelpDialogDisplayed, setHelpDialogDisplayed] = useState(false)
289
+ return (
290
+ <>
291
+ <IconButton onClick={() => setHelpDialogDisplayed(true)} size="small">
292
+ <HelpIcon fontSize="small" />
293
+ </IconButton>
272
294
  {isHelpDialogDisplayed ? (
273
295
  <Suspense fallback={<div />}>
274
296
  <HelpDialog handleClose={() => setHelpDialogDisplayed(false)} />
@@ -278,4 +300,22 @@ function RefNameAutocomplete({
278
300
  )
279
301
  }
280
302
 
303
+ function EndAdornment({
304
+ showHelp,
305
+ endAdornment,
306
+ }: {
307
+ showHelp?: boolean
308
+ endAdornment: React.ReactNode
309
+ }) {
310
+ return (
311
+ <>
312
+ <InputAdornment position="end" style={{ marginRight: 7 }}>
313
+ <SearchIcon fontSize="small" />
314
+ {showHelp ? <HelpAdornment /> : null}
315
+ </InputAdornment>
316
+ {endAdornment}
317
+ </>
318
+ )
319
+ }
320
+
281
321
  export default observer(RefNameAutocomplete)