@apollo-annotation/jbrowse-plugin-apollo 0.3.5 → 0.3.7

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 (136) hide show
  1. package/dist/index.esm.js +6964 -4598
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +6610 -4261
  4. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
  5. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
  6. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
  7. package/dist/jbrowse-plugin-apollo.umd.development.js +11563 -7493
  8. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
  9. package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
  10. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
  11. package/package.json +4 -4
  12. package/src/ApolloInternetAccount/addMenuItems.ts +23 -2
  13. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
  14. package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
  15. package/src/ApolloInternetAccount/components/LoginIcons.tsx +1 -1
  16. package/src/ApolloInternetAccount/configSchema.ts +1 -1
  17. package/src/ApolloInternetAccount/model.ts +11 -10
  18. package/src/ApolloJobModel.ts +1 -1
  19. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +8 -6
  20. package/src/ApolloRefNameAliasAdapter/index.ts +2 -2
  21. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +4 -4
  22. package/src/ApolloSequenceAdapter/index.ts +1 -1
  23. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +8 -7
  24. package/src/ApolloTextSearchAdapter/index.ts +1 -1
  25. package/src/BackendDrivers/BackendDriver.ts +7 -7
  26. package/src/BackendDrivers/CollaborationServerDriver.ts +14 -10
  27. package/src/BackendDrivers/DesktopFileDriver.ts +11 -10
  28. package/src/BackendDrivers/InMemoryFileDriver.ts +10 -6
  29. package/src/ChangeManager.ts +15 -11
  30. package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +8 -7
  31. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +35 -14
  32. package/src/FeatureDetailsWidget/AttributeKey.tsx +50 -0
  33. package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +104 -0
  34. package/src/FeatureDetailsWidget/Attributes.tsx +215 -367
  35. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -5
  36. package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +104 -0
  37. package/src/FeatureDetailsWidget/DefaultAttributeViewer.tsx +22 -0
  38. package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +4 -4
  39. package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -1
  40. package/src/FeatureDetailsWidget/Sequence.tsx +2 -2
  41. package/src/FeatureDetailsWidget/StringTextField.tsx +1 -1
  42. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +15 -23
  43. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +950 -196
  44. package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +8 -4
  45. package/src/FeatureDetailsWidget/model.ts +8 -3
  46. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +7 -7
  47. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +59 -72
  48. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +253 -60
  49. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +52 -6
  50. package/src/LinearApolloDisplay/glyphs/Glyph.ts +16 -8
  51. package/src/LinearApolloDisplay/stateModel/base.ts +81 -10
  52. package/src/LinearApolloDisplay/stateModel/index.ts +4 -3
  53. package/src/LinearApolloDisplay/stateModel/layouts.ts +8 -39
  54. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +63 -46
  55. package/src/LinearApolloDisplay/stateModel/rendering.ts +60 -31
  56. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +226 -0
  57. package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +32 -0
  58. package/src/LinearApolloSixFrameDisplay/components/index.ts +2 -0
  59. package/src/LinearApolloSixFrameDisplay/configSchema.ts +7 -0
  60. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +940 -0
  61. package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +63 -0
  62. package/src/LinearApolloSixFrameDisplay/glyphs/index.ts +1 -0
  63. package/src/LinearApolloSixFrameDisplay/index.ts +2 -0
  64. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +302 -0
  65. package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +27 -0
  66. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +252 -0
  67. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +368 -0
  68. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +201 -0
  69. package/src/LinearApolloSixFrameDisplay/types.ts +1 -0
  70. package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
  71. package/src/OntologyManager/OntologyStore/fulltext.ts +8 -3
  72. package/src/OntologyManager/OntologyStore/index.test.ts +3 -1
  73. package/src/OntologyManager/OntologyStore/index.ts +19 -14
  74. package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -5
  75. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +11 -5
  76. package/src/OntologyManager/index.ts +12 -7
  77. package/src/OntologyManager/util.ts +3 -2
  78. package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
  79. package/src/TabularEditor/HybridGrid/Feature.tsx +13 -7
  80. package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +1 -1
  81. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +3 -2
  82. package/src/TabularEditor/HybridGrid/ToolBar.tsx +1 -1
  83. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +114 -22
  84. package/src/TabularEditor/TabularEditorPane.tsx +1 -1
  85. package/src/TabularEditor/model.ts +2 -2
  86. package/src/TabularEditor/types.ts +5 -2
  87. package/src/components/AddAssembly.tsx +182 -179
  88. package/src/components/AddAssemblyAliases.tsx +114 -0
  89. package/src/components/AddChildFeature.tsx +8 -10
  90. package/src/components/AddFeature.tsx +216 -44
  91. package/src/components/AddRefSeqAliases.tsx +14 -12
  92. package/src/components/CopyFeature.tsx +10 -11
  93. package/src/components/CreateApolloAnnotation.tsx +342 -158
  94. package/src/components/DeleteAssembly.tsx +9 -8
  95. package/src/components/DeleteFeature.tsx +362 -14
  96. package/src/components/Dialog.tsx +1 -1
  97. package/src/components/DownloadGFF3.tsx +31 -11
  98. package/src/components/FilterFeatures.tsx +6 -4
  99. package/src/components/FilterTranscripts.tsx +86 -0
  100. package/src/components/ImportFeatures.tsx +7 -6
  101. package/src/components/LogOut.tsx +5 -4
  102. package/src/components/ManageChecks.tsx +9 -8
  103. package/src/components/ManageUsers.tsx +11 -10
  104. package/src/components/MergeExons.tsx +193 -0
  105. package/src/components/MergeTranscripts.tsx +185 -0
  106. package/src/components/OntologyTermAutocomplete.tsx +5 -5
  107. package/src/components/OntologyTermMultiSelect.tsx +6 -6
  108. package/src/components/OpenLocalFile.tsx +4 -3
  109. package/src/components/SplitExon.tsx +134 -0
  110. package/src/components/ViewChangeLog.tsx +7 -6
  111. package/src/components/ViewCheckResults.tsx +8 -7
  112. package/src/components/index.ts +3 -0
  113. package/src/config.ts +5 -0
  114. package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -0
  115. package/src/extensions/annotationFromJBrowseFeature.ts +13 -10
  116. package/src/extensions/annotationFromPileup.ts +104 -94
  117. package/src/index.ts +33 -50
  118. package/src/makeDisplayComponent.tsx +90 -37
  119. package/src/session/ClientDataStore.ts +21 -17
  120. package/src/session/session.ts +46 -39
  121. package/src/types.ts +4 -4
  122. package/src/util/annotationFeatureUtils.ts +66 -1
  123. package/src/util/copyToClipboard.ts +21 -0
  124. package/src/util/glyphUtils.ts +49 -0
  125. package/src/util/index.ts +5 -3
  126. package/src/util/loadAssemblyIntoClient.ts +10 -3
  127. package/src/util/mouseEventsUtils.ts +113 -0
  128. package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +0 -13
  129. package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +0 -707
  130. package/src/ApolloSixFrameRenderer/configSchema.ts +0 -7
  131. package/src/ApolloSixFrameRenderer/index.ts +0 -3
  132. package/src/SixFrameFeatureDisplay/components/TrackLines.tsx +0 -19
  133. package/src/SixFrameFeatureDisplay/components/index.ts +0 -1
  134. package/src/SixFrameFeatureDisplay/configSchema.ts +0 -21
  135. package/src/SixFrameFeatureDisplay/index.ts +0 -2
  136. package/src/SixFrameFeatureDisplay/stateModel.ts +0 -443
@@ -1,9 +1,16 @@
1
- import { AnnotationFeature } from '@apollo-annotation/mst'
1
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
2
+ import { type MenuItem } from '@jbrowse/core/ui'
2
3
 
3
- import { LinearApolloDisplay } from '../stateModel'
4
- import { boxGlyph, isSelectedFeature, drawBox } from './BoxGlyph'
5
- import { Glyph } from './Glyph'
6
- import { LinearApolloDisplayRendering } from '../stateModel/rendering'
4
+ import { getFeaturesUnderClick } from '../../util/annotationFeatureUtils'
5
+ import { type LinearApolloDisplay } from '../stateModel'
6
+ import {
7
+ type LinearApolloDisplayMouseEvents,
8
+ type MousePositionWithFeatureAndGlyph,
9
+ } from '../stateModel/mouseEvents'
10
+ import { type LinearApolloDisplayRendering } from '../stateModel/rendering'
11
+
12
+ import { boxGlyph, drawBox, isSelectedFeature } from './BoxGlyph'
13
+ import { type Glyph } from './Glyph'
7
14
 
8
15
  function featuresForRow(feature: AnnotationFeature): AnnotationFeature[][] {
9
16
  const features = [[feature]]
@@ -129,12 +136,50 @@ function getRowForFeature(
129
136
  return
130
137
  }
131
138
 
139
+ function getContextMenuItems(
140
+ display: LinearApolloDisplayMouseEvents,
141
+ mousePosition: MousePositionWithFeatureAndGlyph,
142
+ ): MenuItem[] {
143
+ const { apolloHover, session } = display
144
+ const menuItems: MenuItem[] = []
145
+ if (!apolloHover) {
146
+ return menuItems
147
+ }
148
+ const { feature: sourceFeature } = apolloHover
149
+ const { featureTypeOntology } = session.apolloDataStore.ontologyManager
150
+ if (!featureTypeOntology) {
151
+ throw new Error('featureTypeOntology is undefined')
152
+ }
153
+ const sourceFeatureMenuItems = boxGlyph.getContextMenuItems(
154
+ display,
155
+ mousePosition,
156
+ )
157
+ menuItems.push({
158
+ label: sourceFeature.type,
159
+ subMenu: sourceFeatureMenuItems,
160
+ })
161
+ for (const relative of getFeaturesUnderClick(mousePosition)) {
162
+ if (relative._id === sourceFeature._id) {
163
+ continue
164
+ }
165
+ const contextMenuItemsForFeature = boxGlyph.getContextMenuItemsForFeature(
166
+ display,
167
+ relative,
168
+ )
169
+ menuItems.push({
170
+ label: relative.type,
171
+ subMenu: contextMenuItemsForFeature,
172
+ })
173
+ }
174
+ return menuItems
175
+ }
176
+
132
177
  // False positive here, none of these functions use "this"
133
178
  /* eslint-disable @typescript-eslint/unbound-method */
134
179
  const {
135
180
  drawDragPreview,
136
181
  drawTooltip,
137
- getContextMenuItems,
182
+ getContextMenuItemsForFeature,
138
183
  onMouseDown,
139
184
  onMouseLeave,
140
185
  onMouseMove,
@@ -147,6 +192,7 @@ export const genericChildGlyph: Glyph = {
147
192
  drawDragPreview,
148
193
  drawHover,
149
194
  drawTooltip,
195
+ getContextMenuItemsForFeature,
150
196
  getContextMenuItems,
151
197
  getFeatureFromLayout,
152
198
  getRowCount,
@@ -1,13 +1,13 @@
1
- import { AnnotationFeature } from '@apollo-annotation/mst'
2
- import { MenuItem } from '@jbrowse/core/ui'
1
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
2
+ import { type MenuItem } from '@jbrowse/core/ui'
3
3
 
4
+ import { type OntologyRecord } from '../../OntologyManager'
4
5
  import {
5
- LinearApolloDisplayMouseEvents,
6
- MousePositionWithFeatureAndGlyph,
6
+ type LinearApolloDisplayMouseEvents,
7
+ type MousePositionWithFeatureAndGlyph,
7
8
  } from '../stateModel/mouseEvents'
8
- import { LinearApolloDisplayRendering } from '../stateModel/rendering'
9
- import { CanvasMouseEvent } from '../types'
10
- import { OntologyRecord } from '../../OntologyManager'
9
+ import { type LinearApolloDisplayRendering } from '../stateModel/rendering'
10
+ import { type CanvasMouseEvent } from '../types'
11
11
 
12
12
  export interface Glyph {
13
13
  /** @returns number of layout rows used by this glyph with this feature and zoom level */
@@ -76,5 +76,13 @@ export interface Glyph {
76
76
  context: CanvasRenderingContext2D,
77
77
  ): void
78
78
 
79
- getContextMenuItems(display: LinearApolloDisplayMouseEvents): MenuItem[]
79
+ getContextMenuItemsForFeature(
80
+ display: LinearApolloDisplayMouseEvents,
81
+ sourceFeature: AnnotationFeature,
82
+ ): MenuItem[]
83
+
84
+ getContextMenuItems(
85
+ display: LinearApolloDisplayMouseEvents,
86
+ currentMousePosition: MousePositionWithFeatureAndGlyph,
87
+ ): MenuItem[]
80
88
  }
@@ -3,26 +3,27 @@
3
3
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
4
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
5
5
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
6
- import { AnnotationFeature } from '@apollo-annotation/mst'
6
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
7
+ import type PluginManager from '@jbrowse/core/PluginManager'
7
8
  import { ConfigurationReference, getConf } from '@jbrowse/core/configuration'
8
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
9
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
9
10
  import { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'
10
- import PluginManager from '@jbrowse/core/PluginManager'
11
11
  import {
12
- AbstractSessionModel,
12
+ type AbstractSessionModel,
13
+ type SessionWithWidgets,
13
14
  getContainingView,
14
15
  getSession,
15
16
  } from '@jbrowse/core/util'
16
17
  import { getParentRenderProps } from '@jbrowse/core/util/tracks'
17
18
  // import type LinearGenomeViewPlugin from '@jbrowse/plugin-linear-genome-view'
18
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
19
+ import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
19
20
  import { autorun } from 'mobx'
20
- import { addDisposer, cast, getRoot, types, getSnapshot } from 'mobx-state-tree'
21
+ import { addDisposer, cast, getRoot, getSnapshot, types } from 'mobx-state-tree'
21
22
 
22
- import { ApolloInternetAccountModel } from '../../ApolloInternetAccount/model'
23
- import { ApolloSessionModel } from '../../session'
24
- import { ApolloRootModel } from '../../types'
23
+ import { type ApolloInternetAccountModel } from '../../ApolloInternetAccount/model'
25
24
  import { FilterFeatures } from '../../components/FilterFeatures'
25
+ import { type ApolloSessionModel } from '../../session'
26
+ import { type ApolloRootModel } from '../../types'
26
27
 
27
28
  const minDisplayHeight = 20
28
29
 
@@ -36,6 +37,9 @@ export function baseModelFactory(
36
37
  configuration: ConfigurationReference(configSchema),
37
38
  graphical: true,
38
39
  table: false,
40
+ showStartCodons: false,
41
+ showStopCodons: true,
42
+ highContrast: false,
39
43
  heightPreConfig: types.maybe(
40
44
  types.refinement(
41
45
  'displayHeight',
@@ -168,6 +172,15 @@ export function baseModelFactory(
168
172
  self.graphical = true
169
173
  self.table = true
170
174
  },
175
+ toggleShowStartCodons() {
176
+ self.showStartCodons = !self.showStartCodons
177
+ },
178
+ toggleShowStopCodons() {
179
+ self.showStopCodons = !self.showStopCodons
180
+ },
181
+ toggleHighContrast() {
182
+ self.highContrast = !self.highContrast
183
+ },
171
184
  updateFilteredFeatureTypes(types: string[]) {
172
185
  self.filteredFeatureTypes = cast(types)
173
186
  },
@@ -179,7 +192,13 @@ export function baseModelFactory(
179
192
  const { filteredFeatureTypes, trackMenuItems: superTrackMenuItems } = self
180
193
  return {
181
194
  trackMenuItems() {
182
- const { graphical, table } = self
195
+ const {
196
+ graphical,
197
+ table,
198
+ showStartCodons,
199
+ showStopCodons,
200
+ highContrast,
201
+ } = self
183
202
  return [
184
203
  ...superTrackMenuItems(),
185
204
  {
@@ -210,6 +229,30 @@ export function baseModelFactory(
210
229
  self.showGraphicalAndTable()
211
230
  },
212
231
  },
232
+ {
233
+ label: 'Show start codons',
234
+ type: 'checkbox',
235
+ checked: showStartCodons,
236
+ onClick: () => {
237
+ self.toggleShowStartCodons()
238
+ },
239
+ },
240
+ {
241
+ label: 'Show stop codons',
242
+ type: 'checkbox',
243
+ checked: showStopCodons,
244
+ onClick: () => {
245
+ self.toggleShowStopCodons()
246
+ },
247
+ },
248
+ {
249
+ label: 'Use high contrast colors',
250
+ type: 'checkbox',
251
+ checked: highContrast,
252
+ onClick: () => {
253
+ self.toggleHighContrast()
254
+ },
255
+ },
213
256
  ],
214
257
  },
215
258
  {
@@ -243,6 +286,34 @@ export function baseModelFactory(
243
286
  self.session as unknown as ApolloSessionModel
244
287
  ).apolloSetSelectedFeature(feature)
245
288
  },
289
+ showFeatureDetailsWidget(
290
+ feature: AnnotationFeature,
291
+ customWidgetNameAndId?: [string, string],
292
+ ) {
293
+ const [region] = self.regions
294
+ const { assemblyName, refName } = region
295
+ const assembly = self.getAssemblyId(assemblyName)
296
+ if (!assembly) {
297
+ return
298
+ }
299
+ const { session } = self
300
+ const { changeManager } = session.apolloDataStore
301
+ const [widgetName, widgetId] = customWidgetNameAndId ?? [
302
+ 'ApolloFeatureDetailsWidget',
303
+ 'apolloFeatureDetailsWidget',
304
+ ]
305
+ const apolloFeatureWidget = (
306
+ session as unknown as SessionWithWidgets
307
+ ).addWidget(widgetName, widgetId, {
308
+ feature,
309
+ assembly,
310
+ refName,
311
+ changeManager,
312
+ })
313
+ ;(session as unknown as SessionWithWidgets).showWidget(
314
+ apolloFeatureWidget,
315
+ )
316
+ },
246
317
  afterAttach() {
247
318
  addDisposer(
248
319
  self,
@@ -1,8 +1,9 @@
1
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
2
- import PluginManager from '@jbrowse/core/PluginManager'
3
- import { Instance, types } from 'mobx-state-tree'
1
+ import type PluginManager from '@jbrowse/core/PluginManager'
2
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
3
+ import { type Instance, types } from 'mobx-state-tree'
4
4
 
5
5
  import { TabularEditorStateModelType } from '../../TabularEditor'
6
+
6
7
  import { mouseEventsModelFactory } from './mouseEvents'
7
8
 
8
9
  export function stateModelFactory(
@@ -1,16 +1,17 @@
1
1
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
2
 
3
- import { AnnotationFeature } from '@apollo-annotation/mst'
4
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
5
- import PluginManager from '@jbrowse/core/PluginManager'
6
- import { AbstractSessionModel, doesIntersect2 } from '@jbrowse/core/util'
3
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
4
+ import type PluginManager from '@jbrowse/core/PluginManager'
5
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
6
+ import { type AbstractSessionModel, doesIntersect2 } from '@jbrowse/core/util'
7
7
  import { autorun, observable } from 'mobx'
8
8
  import { addDisposer, isAlive } from 'mobx-state-tree'
9
9
 
10
- import { ApolloSessionModel } from '../../session'
11
- import { baseModelFactory } from './base'
10
+ import { type ApolloSessionModel } from '../../session'
12
11
  import { boxGlyph, geneGlyph, genericChildGlyph } from '../glyphs'
13
12
 
13
+ import { baseModelFactory } from './base'
14
+
14
15
  function getRowsForFeature(
15
16
  startingRow: number,
16
17
  rowCount: number,
@@ -62,7 +63,7 @@ export function layoutsModelFactory(
62
63
  return self.seenFeatures.get(id)
63
64
  },
64
65
  getGlyph(feature: AnnotationFeature) {
65
- if (this.looksLikeGene(feature)) {
66
+ if (feature.looksLikeGene) {
66
67
  return geneGlyph
67
68
  }
68
69
  if (feature.children?.size) {
@@ -70,38 +71,6 @@ export function layoutsModelFactory(
70
71
  }
71
72
  return boxGlyph
72
73
  },
73
- looksLikeGene(feature: AnnotationFeature): boolean {
74
- const { featureTypeOntology } =
75
- self.session.apolloDataStore.ontologyManager
76
- if (!featureTypeOntology) {
77
- return false
78
- }
79
- const { children } = feature
80
- if (!children?.size) {
81
- return false
82
- }
83
- const isGene =
84
- featureTypeOntology.isTypeOf(feature.type, 'gene') ||
85
- featureTypeOntology.isTypeOf(feature.type, 'pseudogene')
86
- if (!isGene) {
87
- return false
88
- }
89
- for (const [, child] of children) {
90
- if (
91
- featureTypeOntology.isTypeOf(child.type, 'transcript') ||
92
- featureTypeOntology.isTypeOf(child.type, 'pseudogenic_transcript')
93
- ) {
94
- const { children: grandChildren } = child
95
- if (!grandChildren?.size) {
96
- return false
97
- }
98
- return [...grandChildren.values()].some((grandchild) =>
99
- featureTypeOntology.isTypeOf(grandchild.type, 'exon'),
100
- )
101
- }
102
- }
103
- return false
104
- },
105
74
  }))
106
75
  .actions((self) => ({
107
76
  addSeenFeature(feature: AnnotationFeature) {
@@ -1,22 +1,23 @@
1
- import { AnnotationFeature } from '@apollo-annotation/mst'
1
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
2
2
  import {
3
3
  LocationEndChange,
4
4
  LocationStartChange,
5
5
  } from '@apollo-annotation/shared'
6
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
7
- import PluginManager from '@jbrowse/core/PluginManager'
8
- import { MenuItem } from '@jbrowse/core/ui'
9
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
10
- import { Theme } from '@mui/material'
6
+ import type PluginManager from '@jbrowse/core/PluginManager'
7
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
8
+ import { type MenuItem } from '@jbrowse/core/ui'
9
+ import { type Frame, getFrame } from '@jbrowse/core/util'
10
+ import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
11
+ import { type Theme } from '@mui/material'
11
12
  import { autorun } from 'mobx'
12
- import { Instance, addDisposer } from 'mobx-state-tree'
13
- import type { CSSProperties } from 'react'
13
+ import { type Instance, addDisposer } from 'mobx-state-tree'
14
+ import { type CSSProperties } from 'react'
15
+
16
+ import { type Edge, getPropagatedLocationChanges } from '../../util'
17
+ import { type Glyph } from '../glyphs/Glyph'
18
+ import { type CanvasMouseEvent } from '../types'
14
19
 
15
- import { Coord } from '../components'
16
- import { Glyph } from '../glyphs/Glyph'
17
- import { CanvasMouseEvent } from '../types'
18
20
  import { renderingModelFactory } from './rendering'
19
- import { Frame, getFrame } from '@jbrowse/core/util'
20
21
 
21
22
  export interface FeatureAndGlyphUnderMouse {
22
23
  feature: AnnotationFeature
@@ -43,7 +44,7 @@ export function isMousePositionWithFeatureAndGlyph(
43
44
  }
44
45
 
45
46
  function getMousePosition(
46
- event: CanvasMouseEvent,
47
+ event: React.MouseEvent,
47
48
  lgv: LinearGenomeViewModel,
48
49
  ): MousePosition {
49
50
  const canvas = event.currentTarget
@@ -124,13 +125,14 @@ export function mouseEventsModelIntermediateFactory(
124
125
  start: MousePosition
125
126
  current: MousePosition
126
127
  feature: AnnotationFeature
127
- edge: 'min' | 'max'
128
+ edge: Edge
129
+ shrinkParent: boolean
128
130
  } | null,
129
131
  cursor: undefined as CSSProperties['cursor'] | undefined,
130
132
  apolloHover: undefined as FeatureAndGlyphUnderMouse | undefined,
131
133
  }))
132
134
  .views((self) => ({
133
- getMousePosition(event: CanvasMouseEvent): MousePosition {
135
+ getMousePosition(event: React.MouseEvent): MousePosition {
134
136
  const mousePosition = getMousePosition(event, self.lgv)
135
137
  const { bp, regionNumber, y } = mousePosition
136
138
  const row = Math.floor(y / self.apolloRowHeight)
@@ -195,6 +197,10 @@ export function mouseEventsModelIntermediateFactory(
195
197
  self.cursor = cursor
196
198
  }
197
199
  },
200
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
201
+ updateFilteredTranscripts(forms: string[]) {
202
+ return
203
+ },
198
204
  }))
199
205
  .actions(() => ({
200
206
  // onClick(event: CanvasMouseEvent) {
@@ -339,14 +345,18 @@ export function mouseEventsModelFactory(
339
345
  )
340
346
 
341
347
  return LinearApolloDisplayMouseEvents.views((self) => ({
342
- contextMenuItems(contextCoord?: Coord): MenuItem[] {
348
+ contextMenuItems(event: React.MouseEvent<HTMLDivElement>): MenuItem[] {
343
349
  const { apolloHover } = self
344
- if (!(apolloHover && contextCoord)) {
350
+ if (!apolloHover) {
345
351
  return []
346
352
  }
353
+ const mousePosition = self.getMousePosition(event)
347
354
  const { topLevelFeature } = apolloHover
348
355
  const glyph = self.getGlyph(topLevelFeature)
349
- return glyph.getContextMenuItems(self)
356
+ if (isMousePositionWithFeatureAndGlyph(mousePosition)) {
357
+ return glyph.getContextMenuItems(self, mousePosition)
358
+ }
359
+ return []
350
360
  },
351
361
  }))
352
362
  .actions((self) => ({
@@ -355,20 +365,23 @@ export function mouseEventsModelFactory(
355
365
  startDrag(
356
366
  mousePosition: MousePositionWithFeatureAndGlyph,
357
367
  feature: AnnotationFeature,
358
- edge: 'min' | 'max',
368
+ edge: Edge,
369
+ shrinkParent = false,
359
370
  ) {
360
371
  self.apolloDragging = {
361
372
  start: mousePosition,
362
373
  current: mousePosition,
363
374
  feature,
364
375
  edge,
376
+ shrinkParent,
365
377
  }
366
378
  },
367
379
  endDrag() {
368
380
  if (!self.apolloDragging) {
369
381
  throw new Error('endDrag() called with no current drag in progress')
370
382
  }
371
- const { current, edge, feature, start } = self.apolloDragging
383
+ const { current, edge, feature, start, shrinkParent } =
384
+ self.apolloDragging
372
385
  // don't do anything if it was only dragged a tiny bit
373
386
  if (Math.abs(current.x - start.x) <= 4) {
374
387
  self.setDragging()
@@ -378,33 +391,35 @@ export function mouseEventsModelFactory(
378
391
  const { displayedRegions } = self.lgv
379
392
  const region = displayedRegions[start.regionNumber]
380
393
  const assembly = self.getAssemblyId(region.assemblyName)
394
+ const changes = getPropagatedLocationChanges(
395
+ feature,
396
+ current.bp,
397
+ edge,
398
+ shrinkParent,
399
+ )
381
400
 
382
- let change: LocationEndChange | LocationStartChange
383
- if (edge === 'max') {
384
- const featureId = feature._id
385
- const oldEnd = feature.max
386
- const newEnd = current.bp
387
- change = new LocationEndChange({
388
- typeName: 'LocationEndChange',
389
- changedIds: [featureId],
390
- featureId,
391
- oldEnd,
392
- newEnd,
393
- assembly,
394
- })
395
- } else {
396
- const featureId = feature._id
397
- const oldStart = feature.min
398
- const newStart = current.bp
399
- change = new LocationStartChange({
400
- typeName: 'LocationStartChange',
401
- changedIds: [featureId],
402
- featureId,
403
- oldStart,
404
- newStart,
405
- assembly,
406
- })
407
- }
401
+ const change: LocationEndChange | LocationStartChange =
402
+ edge === 'max'
403
+ ? new LocationEndChange({
404
+ typeName: 'LocationEndChange',
405
+ changedIds: changes.map((c) => c.featureId),
406
+ changes: changes.map((c) => ({
407
+ featureId: c.featureId,
408
+ oldEnd: c.oldLocation,
409
+ newEnd: c.newLocation,
410
+ })),
411
+ assembly,
412
+ })
413
+ : new LocationStartChange({
414
+ typeName: 'LocationStartChange',
415
+ changedIds: changes.map((c) => c.featureId),
416
+ changes: changes.map((c) => ({
417
+ featureId: c.featureId,
418
+ oldStart: c.oldLocation,
419
+ newStart: c.newLocation,
420
+ })),
421
+ assembly,
422
+ })
408
423
  void self.changeManager.submit(change)
409
424
  self.setDragging()
410
425
  self.setCursor()
@@ -460,6 +475,8 @@ export function mouseEventsModelFactory(
460
475
  mousePosition,
461
476
  event,
462
477
  )
478
+ } else {
479
+ self.setSelectedFeature()
463
480
  }
464
481
 
465
482
  if (self.apolloDragging) {