@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.
- package/dist/index.esm.js +10914 -10799
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +10979 -10865
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +8799 -11326
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/package.json +7 -7
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -1
- package/src/ApolloInternetAccount/model.ts +87 -65
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +4 -4
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +9 -7
- package/src/BackendDrivers/CollaborationServerDriver.ts +60 -23
- package/src/BackendDrivers/DesktopFileDriver.ts +2 -2
- package/src/ChangeManager.ts +22 -5
- package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -4
- package/src/FeatureDetailsWidget/NumberTextField.tsx +5 -2
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +68 -212
- package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +92 -0
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -102
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +33 -232
- package/src/LinearApolloDisplay/glyphs/util.ts +36 -0
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +174 -0
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +200 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +62 -386
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +6 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +122 -70
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +33 -2
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +101 -3
- package/src/components/AddAssembly.tsx +34 -38
- package/src/components/AddFeature.tsx +21 -18
- package/src/components/AddRefSeqAliases.tsx +56 -42
- package/src/components/CopyFeature.tsx +1 -1
- package/src/components/CreateApolloAnnotation.tsx +22 -10
- package/src/components/DeleteAssembly.tsx +2 -9
- package/src/components/DownloadGFF3.tsx +2 -2
- package/src/components/ImportFeatures.tsx +1 -1
- package/src/components/ManageChecks.tsx +2 -9
- package/src/components/ManageUsers.tsx +23 -22
- package/src/components/OntologyTermAutocomplete.tsx +3 -10
- package/src/components/OntologyTermMultiSelect.tsx +2 -2
- package/src/components/ViewChangeLog.tsx +25 -50
- package/src/components/ViewCheckResults.tsx +1 -7
- package/src/config.ts +3 -3
- package/src/index.ts +17 -16
- package/src/makeDisplayComponent.tsx +9 -13
- package/src/session/ClientDataStore.ts +33 -15
- package/src/session/session.ts +23 -27
- package/src/util/displayUtils.ts +28 -0
- package/src/util/glyphUtils.ts +196 -1
- package/src/util/loadAssemblyIntoClient.ts +3 -2
package/src/util/glyphUtils.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
-
|
|
21
|
+
parseStringSync(gff3FileText, {
|
|
21
22
|
parseSequences: true,
|
|
22
23
|
parseComments: true,
|
|
23
24
|
parseDirectives: false,
|