@apollo-annotation/jbrowse-plugin-apollo 0.3.8 → 0.3.10

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 (54) hide show
  1. package/dist/index.esm.js +10914 -10799
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +10979 -10865
  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 +8799 -11326
  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 +7 -7
  12. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -1
  13. package/src/ApolloInternetAccount/model.ts +87 -65
  14. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +4 -4
  15. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +9 -7
  16. package/src/BackendDrivers/CollaborationServerDriver.ts +60 -23
  17. package/src/BackendDrivers/DesktopFileDriver.ts +2 -2
  18. package/src/ChangeManager.ts +22 -5
  19. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -4
  20. package/src/FeatureDetailsWidget/NumberTextField.tsx +5 -2
  21. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +68 -212
  22. package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +92 -0
  23. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -102
  24. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +33 -232
  25. package/src/LinearApolloDisplay/glyphs/util.ts +36 -0
  26. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +174 -0
  27. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +200 -0
  28. package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +62 -386
  29. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +6 -0
  30. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +122 -70
  31. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +33 -2
  32. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +101 -3
  33. package/src/components/AddAssembly.tsx +34 -38
  34. package/src/components/AddFeature.tsx +21 -18
  35. package/src/components/AddRefSeqAliases.tsx +56 -42
  36. package/src/components/CopyFeature.tsx +1 -1
  37. package/src/components/CreateApolloAnnotation.tsx +22 -10
  38. package/src/components/DeleteAssembly.tsx +2 -9
  39. package/src/components/DownloadGFF3.tsx +2 -2
  40. package/src/components/ImportFeatures.tsx +1 -1
  41. package/src/components/ManageChecks.tsx +2 -9
  42. package/src/components/ManageUsers.tsx +23 -22
  43. package/src/components/OntologyTermAutocomplete.tsx +3 -10
  44. package/src/components/OntologyTermMultiSelect.tsx +2 -2
  45. package/src/components/ViewChangeLog.tsx +25 -50
  46. package/src/components/ViewCheckResults.tsx +1 -7
  47. package/src/config.ts +3 -3
  48. package/src/index.ts +17 -16
  49. package/src/makeDisplayComponent.tsx +9 -13
  50. package/src/session/ClientDataStore.ts +33 -15
  51. package/src/session/session.ts +23 -27
  52. package/src/util/displayUtils.ts +28 -0
  53. package/src/util/glyphUtils.ts +196 -1
  54. package/src/util/loadAssemblyIntoClient.ts +3 -2
@@ -2,16 +2,194 @@ import {
2
2
  type AnnotationFeature,
3
3
  type TranscriptPartCoding,
4
4
  } from '@apollo-annotation/mst'
5
+ import { type BaseDisplayModel } from '@jbrowse/core/pluggableElementTypes'
5
6
  import { type MenuItem } from '@jbrowse/core/ui'
6
- import { type AbstractSessionModel } from '@jbrowse/core/util'
7
+ import {
8
+ type AbstractSessionModel,
9
+ getContainingView,
10
+ isSessionModelWithWidgets,
11
+ } from '@jbrowse/core/util'
7
12
  import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
13
+ import SkipNextRoundedIcon from '@mui/icons-material/SkipNextRounded'
14
+ import SkipPreviousRoundedIcon from '@mui/icons-material/SkipPreviousRounded'
8
15
 
9
16
  import { type LinearApolloDisplayMouseEvents } from '../LinearApolloDisplay/stateModel/mouseEvents'
10
17
  import { type LinearApolloSixFrameDisplayMouseEvents } from '../LinearApolloSixFrameDisplay/stateModel/mouseEvents'
11
18
  import { AddChildFeature, CopyFeature, DeleteFeature } from '../components'
19
+ import { type ApolloSessionModel } from '../session'
20
+
21
+ import { type MousePositionWithFeature } from '.'
12
22
 
13
23
  type NavLocation = Parameters<LinearGenomeViewModel['navTo']>[0]
14
24
 
25
+ export function selectFeatureAndOpenWidget(
26
+ stateModel:
27
+ | LinearApolloDisplayMouseEvents
28
+ | LinearApolloSixFrameDisplayMouseEvents,
29
+ feature: AnnotationFeature,
30
+ ) {
31
+ if (stateModel.apolloDragging) {
32
+ return
33
+ }
34
+ stateModel.setSelectedFeature(feature)
35
+ const { session } = stateModel
36
+ const { apolloDataStore } = session
37
+ const { featureTypeOntology } = apolloDataStore.ontologyManager
38
+ if (!featureTypeOntology) {
39
+ throw new Error('featureTypeOntology is undefined')
40
+ }
41
+
42
+ let containsCDSOrExon = false
43
+ for (const [, child] of feature.children ?? []) {
44
+ if (
45
+ featureTypeOntology.isTypeOf(child.type, 'CDS') ||
46
+ featureTypeOntology.isTypeOf(child.type, 'exon')
47
+ ) {
48
+ containsCDSOrExon = true
49
+ break
50
+ }
51
+ }
52
+ if (
53
+ (featureTypeOntology.isTypeOf(feature.type, 'transcript') ||
54
+ featureTypeOntology.isTypeOf(feature.type, 'pseudogenic_transcript')) &&
55
+ containsCDSOrExon
56
+ ) {
57
+ stateModel.showFeatureDetailsWidget(feature, [
58
+ 'ApolloTranscriptDetails',
59
+ 'apolloTranscriptDetails',
60
+ ])
61
+ } else {
62
+ stateModel.showFeatureDetailsWidget(feature)
63
+ }
64
+ }
65
+
66
+ export function isTranscriptFeature(
67
+ feature: AnnotationFeature,
68
+ session: ApolloSessionModel,
69
+ ): boolean {
70
+ const { featureTypeOntology } = session.apolloDataStore.ontologyManager
71
+ if (!featureTypeOntology) {
72
+ throw new Error('featureTypeOntology is undefined')
73
+ }
74
+ return (
75
+ featureTypeOntology.isTypeOf(feature.type, 'transcript') ||
76
+ featureTypeOntology.isTypeOf(feature.type, 'pseudogenic_transcript')
77
+ )
78
+ }
79
+
80
+ export function isExonFeature(
81
+ feature: AnnotationFeature,
82
+ session: ApolloSessionModel,
83
+ ): boolean {
84
+ const { featureTypeOntology } = session.apolloDataStore.ontologyManager
85
+ if (!featureTypeOntology) {
86
+ throw new Error('featureTypeOntology is undefined')
87
+ }
88
+ return featureTypeOntology.isTypeOf(feature.type, 'exon')
89
+ }
90
+
91
+ export function isCDSFeature(
92
+ feature: AnnotationFeature,
93
+ session: ApolloSessionModel,
94
+ ): boolean {
95
+ const { featureTypeOntology } = session.apolloDataStore.ontologyManager
96
+ if (!featureTypeOntology) {
97
+ throw new Error('featureTypeOntology is undefined')
98
+ }
99
+ return featureTypeOntology.isTypeOf(feature.type, 'CDS')
100
+ }
101
+
102
+ export interface AdjacentExons {
103
+ upstream: AnnotationFeature | undefined
104
+ downstream: AnnotationFeature | undefined
105
+ }
106
+
107
+ export function getAdjacentExons(
108
+ currentExon: AnnotationFeature,
109
+ display:
110
+ | LinearApolloDisplayMouseEvents
111
+ | LinearApolloSixFrameDisplayMouseEvents,
112
+ mousePosition: MousePositionWithFeature,
113
+ session: ApolloSessionModel,
114
+ ): AdjacentExons {
115
+ const lgv = getContainingView(
116
+ display as BaseDisplayModel,
117
+ ) as unknown as LinearGenomeViewModel
118
+
119
+ // Genomic coords of current view
120
+ const viewGenomicLeft = mousePosition.bp - lgv.bpPerPx * mousePosition.x
121
+ const viewGenomicRight = viewGenomicLeft + lgv.coarseTotalBp
122
+ if (!currentExon.parent) {
123
+ return { upstream: undefined, downstream: undefined }
124
+ }
125
+ const transcript = currentExon.parent
126
+ if (!transcript.children) {
127
+ throw new Error(`Error getting children of ${transcript._id}`)
128
+ }
129
+ const { featureTypeOntology } = session.apolloDataStore.ontologyManager
130
+ if (!featureTypeOntology) {
131
+ throw new Error('featureTypeOntology is undefined')
132
+ }
133
+
134
+ let exons = []
135
+ for (const [, child] of transcript.children) {
136
+ if (featureTypeOntology.isTypeOf(child.type, 'exon')) {
137
+ exons.push(child)
138
+ }
139
+ }
140
+ const adjacentExons: AdjacentExons = {
141
+ upstream: undefined,
142
+ downstream: undefined,
143
+ }
144
+ exons = exons.sort((a, b) => (a.min < b.min ? -1 : 1))
145
+ for (const exon of exons) {
146
+ if (exon.min > viewGenomicRight) {
147
+ adjacentExons.downstream = exon
148
+ break
149
+ }
150
+ }
151
+ exons = exons.sort((a, b) => (a.min > b.min ? -1 : 1))
152
+ for (const exon of exons) {
153
+ if (exon.max < viewGenomicLeft) {
154
+ adjacentExons.upstream = exon
155
+ break
156
+ }
157
+ }
158
+ if (transcript.strand === -1) {
159
+ const newUpstream = adjacentExons.downstream
160
+ adjacentExons.downstream = adjacentExons.upstream
161
+ adjacentExons.upstream = newUpstream
162
+ }
163
+ return adjacentExons
164
+ }
165
+
166
+ export function getStreamIcon(
167
+ strand: 1 | -1 | undefined,
168
+ isUpstream: boolean,
169
+ isFlipped: boolean | undefined,
170
+ ) {
171
+ // This is the icon you would use for strand=1, downstream, straight
172
+ // (non-flipped) view
173
+ let icon = SkipNextRoundedIcon
174
+
175
+ if (strand === -1) {
176
+ icon = SkipPreviousRoundedIcon
177
+ }
178
+ if (isUpstream) {
179
+ icon =
180
+ icon === SkipPreviousRoundedIcon
181
+ ? SkipNextRoundedIcon
182
+ : SkipPreviousRoundedIcon
183
+ }
184
+ if (isFlipped) {
185
+ icon =
186
+ icon === SkipPreviousRoundedIcon
187
+ ? SkipNextRoundedIcon
188
+ : SkipPreviousRoundedIcon
189
+ }
190
+ return icon
191
+ }
192
+
15
193
  export function getMinAndMaxPx(
16
194
  feature: AnnotationFeature | TranscriptPartCoding,
17
195
  refName: string,
@@ -186,6 +364,23 @@ export function getContextMenuItemsForFeature(
186
364
  },
187
365
  },
188
366
  )
367
+ if (isSessionModelWithWidgets(session)) {
368
+ menuItems.push({
369
+ label: 'Open feature details',
370
+ onClick: () => {
371
+ const apolloGeneWidget = session.addWidget(
372
+ 'ApolloFeatureDetailsWidget',
373
+ 'apolloFeatureDetailsWidget',
374
+ {
375
+ feature: sourceFeature,
376
+ assembly: currentAssemblyId,
377
+ refName: region.refName,
378
+ },
379
+ )
380
+ session.showWidget(apolloGeneWidget)
381
+ },
382
+ })
383
+ }
189
384
  return menuItems
190
385
  }
191
386
 
@@ -4,10 +4,11 @@ import {
4
4
  type CheckResultSnapshot,
5
5
  } from '@apollo-annotation/mst'
6
6
  import { gff3ToAnnotationFeature } from '@apollo-annotation/shared'
7
- import gff, {
7
+ import {
8
8
  type GFF3Comment,
9
9
  type GFF3Feature,
10
10
  type GFF3Sequence,
11
+ parseStringSync,
11
12
  } from '@gmod/gff'
12
13
  import { getSnapshot } from 'mobx-state-tree'
13
14
 
@@ -17,7 +18,7 @@ export async function loadAssemblyIntoClient(
17
18
  apolloDataStore: ClientDataStore,
18
19
  ) {
19
20
  const featuresAndSequences: (GFF3Feature | GFF3Sequence | GFF3Comment)[] =
20
- gff.parseStringSync(gff3FileText, {
21
+ parseStringSync(gff3FileText, {
21
22
  parseSequences: true,
22
23
  parseComments: true,
23
24
  parseDirectives: false,