@apollo-annotation/jbrowse-plugin-apollo 0.3.6 → 0.3.8
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 +4603 -2045
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +4611 -2039
- 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 +9387 -4016
- 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 +15 -15
- package/src/ApolloInternetAccount/model.ts +48 -13
- package/src/BackendDrivers/CollaborationServerDriver.ts +23 -2
- package/src/ChangeManager.ts +42 -18
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +64 -5
- package/src/FeatureDetailsWidget/Attributes.tsx +8 -3
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +70 -81
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +946 -190
- package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +4 -0
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +61 -73
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +55 -211
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +562 -108
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +78 -14
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +15 -9
- package/src/LinearApolloDisplay/stateModel/base.ts +63 -43
- package/src/LinearApolloDisplay/stateModel/layouts.ts +3 -2
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +79 -292
- package/src/LinearApolloDisplay/stateModel/rendering.ts +45 -344
- package/src/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.tsx +87 -0
- package/src/LinearApolloReferenceSequenceDisplay/components/index.ts +1 -0
- package/src/LinearApolloReferenceSequenceDisplay/configSchema.ts +7 -0
- package/src/LinearApolloReferenceSequenceDisplay/index.ts +3 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +227 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/index.ts +25 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +481 -0
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +102 -40
- package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +12 -20
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +382 -243
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +12 -8
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +83 -4
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +23 -11
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +118 -123
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +53 -63
- package/src/OntologyManager/index.ts +4 -1
- package/src/TabularEditor/HybridGrid/Feature.tsx +20 -14
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +7 -5
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +108 -16
- package/src/components/AddAssembly.tsx +1 -1
- package/src/components/AddAssemblyAliases.tsx +114 -0
- package/src/components/AddChildFeature.tsx +7 -7
- package/src/components/AddFeature.tsx +20 -15
- package/src/components/AddRefSeqAliases.tsx +9 -9
- package/src/components/CopyFeature.tsx +4 -4
- package/src/components/CreateApolloAnnotation.tsx +335 -151
- package/src/components/DeleteAssembly.tsx +1 -1
- package/src/components/DeleteFeature.tsx +358 -11
- package/src/components/DownloadGFF3.tsx +20 -1
- package/src/components/EditZoomThresholdDialog.tsx +69 -0
- package/src/components/FilterFeatures.tsx +7 -7
- package/src/components/FilterTranscripts.tsx +86 -0
- package/src/components/ImportFeatures.tsx +1 -1
- package/src/components/ManageChecks.tsx +1 -1
- package/src/components/MergeExons.tsx +193 -0
- package/src/components/MergeTranscripts.tsx +182 -0
- package/src/components/OntologyTermMultiSelect.tsx +11 -11
- package/src/components/OpenLocalFile.tsx +11 -7
- package/src/components/SplitExon.tsx +134 -0
- package/src/components/ViewCheckResults.tsx +1 -1
- package/src/components/index.ts +4 -0
- package/src/config.ts +11 -0
- package/src/extensions/annotationFromJBrowseFeature.ts +2 -0
- package/src/extensions/annotationFromPileup.ts +99 -89
- package/src/index.ts +42 -105
- package/src/makeDisplayComponent.tsx +0 -1
- package/src/menus/index.ts +1 -0
- package/src/{ApolloInternetAccount/addMenuItems.ts → menus/topLevelMenu.ts} +60 -33
- package/src/menus/topLevelMenuAdmin.ts +154 -0
- package/src/session/session.ts +163 -104
- package/src/util/annotationFeatureUtils.ts +59 -0
- package/src/util/copyToClipboard.ts +21 -0
- package/src/util/displayUtils.ts +149 -0
- package/src/util/glyphUtils.ts +201 -0
- package/src/util/index.ts +2 -0
- package/src/util/mouseEventsUtils.ts +145 -0
|
@@ -4,21 +4,30 @@
|
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
6
6
|
import { type AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
|
|
7
|
-
import { AddFeatureChange } from '@apollo-annotation/shared'
|
|
8
7
|
import { type Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
9
8
|
import { type DisplayType } from '@jbrowse/core/pluggableElementTypes'
|
|
10
9
|
import type PluggableElementBase from '@jbrowse/core/pluggableElementTypes/PluggableElementBase'
|
|
11
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type AbstractSessionModel,
|
|
12
|
+
getContainingView,
|
|
13
|
+
getSession,
|
|
14
|
+
} from '@jbrowse/core/util'
|
|
12
15
|
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
13
16
|
import AddIcon from '@mui/icons-material/Add'
|
|
14
17
|
import ObjectID from 'bson-objectid'
|
|
15
18
|
|
|
16
|
-
import {
|
|
19
|
+
import { CreateApolloAnnotation } from '../components/CreateApolloAnnotation'
|
|
17
20
|
|
|
18
|
-
function parseCigar(cigar: string): [string
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
function parseCigar(cigar: string): [string, number][] {
|
|
22
|
+
const regex = /(\d+)([MIDNSHPX=])/g
|
|
23
|
+
const result: [string, number][] = []
|
|
24
|
+
let match
|
|
25
|
+
|
|
26
|
+
while ((match = regex.exec(cigar)) !== null) {
|
|
27
|
+
result.push([match[2], Number.parseInt(match[1], 10)])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return result
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
@@ -62,55 +71,87 @@ export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
|
62
71
|
}
|
|
63
72
|
return refSeqId
|
|
64
73
|
},
|
|
65
|
-
|
|
74
|
+
getAnnotationFeature() {
|
|
66
75
|
const feature = self.contextMenuFeature
|
|
67
76
|
const assembly = self.getAssembly()
|
|
68
77
|
const refSeqId = self.getRefSeqId(assembly)
|
|
78
|
+
const start: number = feature.get('start')
|
|
79
|
+
const end: number = feature.get('end')
|
|
80
|
+
const strand = feature.get('strand')
|
|
81
|
+
const name = feature.get('name')
|
|
82
|
+
|
|
69
83
|
const cigarData: string = feature.get('CIGAR')
|
|
70
84
|
const ops = parseCigar(cigarData)
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
let openStart: number | undefined
|
|
85
|
+
let position = start
|
|
86
|
+
let currentExonStart: number | undefined
|
|
74
87
|
const exons: {
|
|
75
88
|
start: number
|
|
76
89
|
end: number
|
|
77
90
|
}[] = []
|
|
91
|
+
|
|
92
|
+
// Example: [[96,S], [4,M], [4216,N], [357,M], [1,I], [628,M], [94,S]]
|
|
93
|
+
// Results in 2 exons
|
|
94
|
+
// M, = and X are matches -> exon
|
|
95
|
+
// N is a gap in the reference sequence -> intron
|
|
96
|
+
// I, S, H and P -> not counted in reference position
|
|
78
97
|
for (const [op, len] of ops) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
switch (op) {
|
|
99
|
+
case 'M':
|
|
100
|
+
case '=':
|
|
101
|
+
case 'X': {
|
|
102
|
+
if (currentExonStart === undefined) {
|
|
103
|
+
currentExonStart = position
|
|
104
|
+
}
|
|
105
|
+
position += len
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
case 'N': {
|
|
110
|
+
if (currentExonStart !== undefined) {
|
|
111
|
+
exons.push({
|
|
112
|
+
start: currentExonStart,
|
|
113
|
+
end: position,
|
|
114
|
+
})
|
|
115
|
+
currentExonStart = undefined
|
|
116
|
+
}
|
|
117
|
+
position += len
|
|
118
|
+
break
|
|
119
|
+
}
|
|
120
|
+
case 'D': {
|
|
121
|
+
position += len
|
|
122
|
+
break
|
|
123
|
+
}
|
|
124
|
+
case 'I':
|
|
125
|
+
case 'S':
|
|
126
|
+
case 'H':
|
|
127
|
+
case 'P': {
|
|
128
|
+
// These operations do not affect the position in the reference sequence
|
|
129
|
+
break
|
|
130
|
+
}
|
|
131
|
+
default: {
|
|
132
|
+
throw new Error(`Unknown CIGAR operation: ${op}`)
|
|
85
133
|
}
|
|
86
|
-
} else if (op === 'N' && openStart !== undefined) {
|
|
87
|
-
// if it was open, then close and add the subfeature
|
|
88
|
-
exons.push({
|
|
89
|
-
start: openStart,
|
|
90
|
-
end: currOffset + openStart,
|
|
91
|
-
})
|
|
92
|
-
openStart = undefined
|
|
93
|
-
}
|
|
94
|
-
if (op !== 'I') {
|
|
95
|
-
// we ignore insertions when calculating potential exon length
|
|
96
|
-
currOffset += len
|
|
97
134
|
}
|
|
98
135
|
}
|
|
99
|
-
|
|
100
|
-
|
|
136
|
+
|
|
137
|
+
// If still in exon at end
|
|
138
|
+
if (currentExonStart !== undefined) {
|
|
101
139
|
exons.push({
|
|
102
|
-
start:
|
|
103
|
-
end:
|
|
140
|
+
start: currentExonStart,
|
|
141
|
+
end: position,
|
|
104
142
|
})
|
|
105
143
|
}
|
|
106
144
|
|
|
107
145
|
const newFeature: AnnotationFeatureSnapshot = {
|
|
108
146
|
_id: ObjectID().toHexString(),
|
|
109
147
|
refSeq: refSeqId,
|
|
110
|
-
min:
|
|
111
|
-
max:
|
|
148
|
+
min: start,
|
|
149
|
+
max: end,
|
|
112
150
|
type: 'mRNA',
|
|
113
|
-
strand
|
|
151
|
+
strand,
|
|
152
|
+
attributes: {
|
|
153
|
+
name: [name],
|
|
154
|
+
},
|
|
114
155
|
}
|
|
115
156
|
if (exons.length === 0) {
|
|
116
157
|
return newFeature
|
|
@@ -118,75 +159,28 @@ export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
|
118
159
|
|
|
119
160
|
const children: Record<string, AnnotationFeatureSnapshot> = {}
|
|
120
161
|
newFeature.children = children
|
|
121
|
-
const [firstExon] = exons
|
|
122
|
-
const cdsFeature: AnnotationFeatureSnapshot = {
|
|
123
|
-
_id: ObjectID().toHexString(),
|
|
124
|
-
refSeq: refSeqId,
|
|
125
|
-
min: firstExon.start,
|
|
126
|
-
max: firstExon.end,
|
|
127
|
-
type: 'CDS',
|
|
128
|
-
strand: feature.get('strand'),
|
|
129
|
-
}
|
|
130
|
-
newFeature.children[cdsFeature._id] = cdsFeature
|
|
131
|
-
if (exons.length === 1) {
|
|
132
|
-
const exon: AnnotationFeatureSnapshot = {
|
|
133
|
-
_id: ObjectID().toHexString(),
|
|
134
|
-
refSeq: refSeqId,
|
|
135
|
-
min: firstExon.start,
|
|
136
|
-
max: firstExon.end,
|
|
137
|
-
type: 'exon',
|
|
138
|
-
strand: feature.get('strand'),
|
|
139
|
-
}
|
|
140
|
-
newFeature.children[exon._id] = exon
|
|
141
|
-
return newFeature
|
|
142
|
-
}
|
|
143
162
|
|
|
144
|
-
const discontinuousLocations: {
|
|
145
|
-
start: number
|
|
146
|
-
end: number
|
|
147
|
-
phase: 0 | 1 | 2
|
|
148
|
-
}[] = []
|
|
149
|
-
let phase: 0 | 1 | 2 = 0
|
|
150
163
|
for (const exon of exons) {
|
|
151
|
-
cdsFeature.min = Math.min(cdsFeature.min, exon.start)
|
|
152
|
-
cdsFeature.max = Math.max(cdsFeature.max, exon.end)
|
|
153
|
-
const { end, start } = exon
|
|
154
|
-
discontinuousLocations.push({ start, end, phase })
|
|
155
|
-
const localPhase = (end - start) % 3
|
|
156
|
-
phase = ((phase + localPhase) % 3) as 0 | 1 | 2
|
|
157
164
|
const newExon: AnnotationFeatureSnapshot = {
|
|
158
165
|
_id: ObjectID().toHexString(),
|
|
159
166
|
refSeq: refSeqId,
|
|
160
|
-
min: start,
|
|
161
|
-
max: end,
|
|
167
|
+
min: exon.start,
|
|
168
|
+
max: exon.end,
|
|
162
169
|
type: 'exon',
|
|
163
|
-
strand
|
|
170
|
+
strand,
|
|
164
171
|
}
|
|
165
172
|
newFeature.children[newExon._id] = newExon
|
|
166
173
|
}
|
|
167
174
|
return newFeature
|
|
168
175
|
},
|
|
169
|
-
async onPileupFeatureContext() {
|
|
170
|
-
const newFeature = self.createFeature()
|
|
171
|
-
const assembly = self.getAssembly()
|
|
172
|
-
const assemblyId = assembly.name
|
|
173
|
-
const change = new AddFeatureChange({
|
|
174
|
-
changedIds: [newFeature._id],
|
|
175
|
-
typeName: 'AddFeatureChange',
|
|
176
|
-
assembly: assemblyId,
|
|
177
|
-
addedFeature: newFeature,
|
|
178
|
-
})
|
|
179
|
-
const session = getSession(self)
|
|
180
|
-
await (
|
|
181
|
-
session as unknown as ApolloSessionModel
|
|
182
|
-
).apolloDataStore.changeManager.submit(change)
|
|
183
|
-
session.notify('Annotation added successfully', 'success')
|
|
184
|
-
},
|
|
185
176
|
}))
|
|
186
177
|
.views((self) => {
|
|
187
178
|
const superContextMenuItems = self.contextMenuItems
|
|
188
179
|
return {
|
|
189
180
|
contextMenuItems() {
|
|
181
|
+
const session = getSession(self)
|
|
182
|
+
const assembly = self.getAssembly()
|
|
183
|
+
const region = self.getFirstRegion()
|
|
190
184
|
const feature = self.contextMenuFeature
|
|
191
185
|
if (!feature) {
|
|
192
186
|
return superContextMenuItems()
|
|
@@ -196,7 +190,23 @@ export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
|
196
190
|
{
|
|
197
191
|
label: 'Create Apollo annotation',
|
|
198
192
|
icon: AddIcon,
|
|
199
|
-
onClick:
|
|
193
|
+
onClick: () => {
|
|
194
|
+
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
195
|
+
(doneCallback) => [
|
|
196
|
+
CreateApolloAnnotation,
|
|
197
|
+
{
|
|
198
|
+
session,
|
|
199
|
+
handleClose: () => {
|
|
200
|
+
doneCallback()
|
|
201
|
+
},
|
|
202
|
+
annotationFeature: self.getAnnotationFeature(assembly),
|
|
203
|
+
assembly,
|
|
204
|
+
refSeqId: self.getRefSeqId(assembly),
|
|
205
|
+
region,
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
)
|
|
209
|
+
},
|
|
200
210
|
},
|
|
201
211
|
]
|
|
202
212
|
},
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
CDSCheck,
|
|
7
7
|
CoreValidation,
|
|
8
8
|
ParentChildValidation,
|
|
9
|
+
TranscriptCheck,
|
|
9
10
|
changes,
|
|
10
11
|
validationRegistry,
|
|
11
12
|
} from '@apollo-annotation/shared'
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
} from '@jbrowse/core/util'
|
|
31
32
|
import { type LinearGenomeViewStateModel } from '@jbrowse/plugin-linear-genome-view'
|
|
32
33
|
import AddIcon from '@mui/icons-material/Add'
|
|
34
|
+
import { alpha } from '@mui/material'
|
|
33
35
|
|
|
34
36
|
import { version } from '../package.json'
|
|
35
37
|
|
|
@@ -51,19 +53,16 @@ import {
|
|
|
51
53
|
configSchema as linearApolloDisplayConfigSchema,
|
|
52
54
|
stateModelFactory as LinearApolloDisplayStateModelFactory,
|
|
53
55
|
} from './LinearApolloDisplay'
|
|
56
|
+
import {
|
|
57
|
+
LinearApolloReferenceSequenceDisplay,
|
|
58
|
+
configSchema as linearApolloReferenceSequenceDisplayConfigSchema,
|
|
59
|
+
stateModelFactory as LinearApolloReferenceSequenceDisplayStateModelFactory,
|
|
60
|
+
} from './LinearApolloReferenceSequenceDisplay'
|
|
54
61
|
import {
|
|
55
62
|
configSchema as linearApolloSixFrameDisplayConfigSchema,
|
|
56
63
|
stateModelFactory as LinearApolloSixFrameDisplayStateModelFactory,
|
|
57
64
|
} from './LinearApolloSixFrameDisplay'
|
|
58
|
-
import {
|
|
59
|
-
AddFeature,
|
|
60
|
-
DownloadGFF3,
|
|
61
|
-
LogOut,
|
|
62
|
-
ManageChecks,
|
|
63
|
-
OpenLocalFile,
|
|
64
|
-
ViewChangeLog,
|
|
65
|
-
ViewCheckResults,
|
|
66
|
-
} from './components'
|
|
65
|
+
import { AddFeature } from './components'
|
|
67
66
|
import ApolloPluginConfigurationSchema from './config'
|
|
68
67
|
import {
|
|
69
68
|
annotationFromJBrowseFeature,
|
|
@@ -73,6 +72,7 @@ import {
|
|
|
73
72
|
LinearApolloDisplayComponent,
|
|
74
73
|
LinearApolloSixFrameDisplayComponent,
|
|
75
74
|
} from './makeDisplayComponent'
|
|
75
|
+
import { addTopLevelMenus } from './menus'
|
|
76
76
|
import { type ApolloSessionModel, extendSession } from './session'
|
|
77
77
|
|
|
78
78
|
interface RpcHandle {
|
|
@@ -106,6 +106,10 @@ for (const [changeName, change] of Object.entries(changes)) {
|
|
|
106
106
|
|
|
107
107
|
const cdsCheck = new CDSCheck()
|
|
108
108
|
checkRegistry.registerCheck(cdsCheck.name, cdsCheck)
|
|
109
|
+
|
|
110
|
+
const transcriptCheck = new TranscriptCheck()
|
|
111
|
+
checkRegistry.registerCheck(transcriptCheck.name, transcriptCheck)
|
|
112
|
+
|
|
109
113
|
validationRegistry.registerValidation(new CoreValidation())
|
|
110
114
|
validationRegistry.registerValidation(new ParentChildValidation())
|
|
111
115
|
|
|
@@ -201,6 +205,22 @@ export default class ApolloPlugin extends Plugin {
|
|
|
201
205
|
})
|
|
202
206
|
})
|
|
203
207
|
|
|
208
|
+
pluginManager.addDisplayType(() => {
|
|
209
|
+
const configSchema = linearApolloReferenceSequenceDisplayConfigSchema
|
|
210
|
+
return new DisplayType({
|
|
211
|
+
name: 'LinearApolloReferenceSequenceDisplay',
|
|
212
|
+
configSchema,
|
|
213
|
+
stateModel: LinearApolloReferenceSequenceDisplayStateModelFactory(
|
|
214
|
+
pluginManager,
|
|
215
|
+
configSchema,
|
|
216
|
+
),
|
|
217
|
+
displayName: 'Apollo reference sequence display',
|
|
218
|
+
trackType: 'ReferenceSequenceTrack',
|
|
219
|
+
viewType: 'LinearGenomeView',
|
|
220
|
+
ReactComponent: LinearApolloReferenceSequenceDisplay,
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
|
|
204
224
|
pluginManager.addToExtensionPoint(
|
|
205
225
|
'Core-extendSession',
|
|
206
226
|
// @ts-expect-error not sure how to deal with snapshot model types
|
|
@@ -357,103 +377,20 @@ export default class ApolloPlugin extends Plugin {
|
|
|
357
377
|
|
|
358
378
|
configure(pluginManager: PluginManager) {
|
|
359
379
|
if (isAbstractMenuManager(pluginManager.rootModel)) {
|
|
360
|
-
pluginManager.
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
],
|
|
373
|
-
)
|
|
374
|
-
},
|
|
375
|
-
})
|
|
376
|
-
pluginManager.rootModel.appendToMenu('Apollo', {
|
|
377
|
-
label: 'Manage Checks',
|
|
378
|
-
onClick: (session: ApolloSessionModel) => {
|
|
379
|
-
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
380
|
-
(doneCallback) => [
|
|
381
|
-
ManageChecks,
|
|
382
|
-
{
|
|
383
|
-
session,
|
|
384
|
-
handleClose: () => {
|
|
385
|
-
doneCallback()
|
|
386
|
-
},
|
|
387
|
-
},
|
|
388
|
-
],
|
|
389
|
-
)
|
|
390
|
-
},
|
|
391
|
-
})
|
|
392
|
-
pluginManager.rootModel.appendToMenu('Apollo', {
|
|
393
|
-
label: 'View Change Log',
|
|
394
|
-
onClick: (session: ApolloSessionModel) => {
|
|
395
|
-
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
396
|
-
(doneCallback) => [
|
|
397
|
-
ViewChangeLog,
|
|
398
|
-
{
|
|
399
|
-
session,
|
|
400
|
-
handleClose: () => {
|
|
401
|
-
doneCallback()
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
],
|
|
405
|
-
)
|
|
406
|
-
},
|
|
407
|
-
})
|
|
408
|
-
pluginManager.rootModel.appendToMenu('Apollo', {
|
|
409
|
-
label: 'Open local GFF3 file',
|
|
410
|
-
onClick: (session: ApolloSessionModel) => {
|
|
411
|
-
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
412
|
-
(doneCallback) => [
|
|
413
|
-
OpenLocalFile,
|
|
414
|
-
{
|
|
415
|
-
session,
|
|
416
|
-
handleClose: () => {
|
|
417
|
-
doneCallback()
|
|
418
|
-
},
|
|
419
|
-
inMemoryFileDriver: session.apolloDataStore.inMemoryFileDriver,
|
|
420
|
-
},
|
|
421
|
-
],
|
|
422
|
-
)
|
|
423
|
-
},
|
|
424
|
-
})
|
|
425
|
-
pluginManager.rootModel.appendToMenu('Apollo', {
|
|
426
|
-
label: 'View check results',
|
|
427
|
-
onClick: (session: ApolloSessionModel) => {
|
|
428
|
-
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
429
|
-
(doneCallback) => [
|
|
430
|
-
ViewCheckResults,
|
|
431
|
-
{
|
|
432
|
-
session,
|
|
433
|
-
handleClose: () => {
|
|
434
|
-
doneCallback()
|
|
435
|
-
},
|
|
436
|
-
},
|
|
437
|
-
],
|
|
438
|
-
)
|
|
439
|
-
},
|
|
440
|
-
})
|
|
441
|
-
pluginManager.rootModel.appendToMenu('Apollo', {
|
|
442
|
-
label: 'Log out',
|
|
443
|
-
onClick: (session: ApolloSessionModel) => {
|
|
444
|
-
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
445
|
-
(doneCallback) => [
|
|
446
|
-
LogOut,
|
|
447
|
-
{
|
|
448
|
-
session,
|
|
449
|
-
handleClose: () => {
|
|
450
|
-
doneCallback()
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
],
|
|
454
|
-
)
|
|
380
|
+
pluginManager.jexl.addFunction(
|
|
381
|
+
'colorFeature',
|
|
382
|
+
(featureType: 'pseudogenic_transcript' | 'nonCodingTranscript') => {
|
|
383
|
+
if (featureType === 'pseudogenic_transcript') {
|
|
384
|
+
return alpha('rgb(148, 203, 236)', 0.6)
|
|
385
|
+
}
|
|
386
|
+
if (featureType === 'nonCodingTranscript') {
|
|
387
|
+
return alpha('rgb(194, 106, 119)', 0.6)
|
|
388
|
+
}
|
|
389
|
+
throw new Error('Invalid type')
|
|
455
390
|
},
|
|
456
|
-
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
addTopLevelMenus(pluginManager.rootModel)
|
|
457
394
|
}
|
|
458
395
|
}
|
|
459
396
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { addTopLevelMenus } from './topLevelMenu'
|
|
@@ -2,112 +2,139 @@ import {
|
|
|
2
2
|
type AbstractMenuManager,
|
|
3
3
|
type AbstractSessionModel,
|
|
4
4
|
} from '@jbrowse/core/util'
|
|
5
|
+
import DownloadIcon from '@mui/icons-material/Download'
|
|
6
|
+
import FactCheckIcon from '@mui/icons-material/FactCheck'
|
|
7
|
+
import FileOpenIcon from '@mui/icons-material/FileOpen'
|
|
8
|
+
import LogoutIcon from '@mui/icons-material/Logout'
|
|
9
|
+
import RedoIcon from '@mui/icons-material/Redo'
|
|
10
|
+
import TrackChangesIcon from '@mui/icons-material/TrackChanges'
|
|
11
|
+
import UndoIcon from '@mui/icons-material/Undo'
|
|
5
12
|
|
|
6
13
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
DownloadGFF3,
|
|
15
|
+
LogOut,
|
|
16
|
+
OpenLocalFile,
|
|
17
|
+
ViewChangeLog,
|
|
18
|
+
ViewCheckResults,
|
|
12
19
|
} from '../components'
|
|
13
20
|
import { type ApolloSessionModel } from '../session'
|
|
14
21
|
|
|
15
|
-
export function
|
|
22
|
+
export function addTopLevelMenus(rootModel: AbstractMenuManager) {
|
|
23
|
+
rootModel.insertInMenu(
|
|
24
|
+
'Apollo',
|
|
25
|
+
{
|
|
26
|
+
label: 'Redo',
|
|
27
|
+
icon: RedoIcon,
|
|
28
|
+
onClick(session: ApolloSessionModel) {
|
|
29
|
+
const { apolloDataStore } = session
|
|
30
|
+
void apolloDataStore.changeManager.redoLastChange()
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
0,
|
|
34
|
+
)
|
|
35
|
+
rootModel.insertInMenu(
|
|
36
|
+
'Apollo',
|
|
37
|
+
{
|
|
38
|
+
label: 'Undo',
|
|
39
|
+
icon: UndoIcon,
|
|
40
|
+
onClick(session: ApolloSessionModel) {
|
|
41
|
+
const { apolloDataStore } = session
|
|
42
|
+
void apolloDataStore.changeManager.undoLastChange()
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
0,
|
|
46
|
+
)
|
|
47
|
+
|
|
16
48
|
rootModel.appendToMenu('Apollo', {
|
|
17
|
-
label: '
|
|
49
|
+
label: 'Download GFF3',
|
|
50
|
+
icon: DownloadIcon,
|
|
18
51
|
onClick: (session: ApolloSessionModel) => {
|
|
19
52
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
20
53
|
(doneCallback) => [
|
|
21
|
-
|
|
54
|
+
DownloadGFF3,
|
|
22
55
|
{
|
|
23
56
|
session,
|
|
24
57
|
handleClose: () => {
|
|
25
58
|
doneCallback()
|
|
26
59
|
},
|
|
27
|
-
changeManager: session.apolloDataStore.changeManager,
|
|
28
60
|
},
|
|
29
61
|
],
|
|
30
62
|
)
|
|
31
63
|
},
|
|
32
64
|
})
|
|
33
65
|
rootModel.appendToMenu('Apollo', {
|
|
34
|
-
label: '
|
|
66
|
+
label: 'View Change Log',
|
|
67
|
+
icon: TrackChangesIcon,
|
|
35
68
|
onClick: (session: ApolloSessionModel) => {
|
|
36
69
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
37
70
|
(doneCallback) => [
|
|
38
|
-
|
|
71
|
+
ViewChangeLog,
|
|
39
72
|
{
|
|
40
73
|
session,
|
|
41
74
|
handleClose: () => {
|
|
42
75
|
doneCallback()
|
|
43
76
|
},
|
|
44
|
-
changeManager: session.apolloDataStore.changeManager,
|
|
45
77
|
},
|
|
46
78
|
],
|
|
47
79
|
)
|
|
48
80
|
},
|
|
49
81
|
})
|
|
50
82
|
rootModel.appendToMenu('Apollo', {
|
|
51
|
-
label: '
|
|
83
|
+
label: 'Open local GFF3 file',
|
|
84
|
+
icon: FileOpenIcon,
|
|
52
85
|
onClick: (session: ApolloSessionModel) => {
|
|
53
86
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
54
87
|
(doneCallback) => [
|
|
55
|
-
|
|
88
|
+
OpenLocalFile,
|
|
56
89
|
{
|
|
57
90
|
session,
|
|
58
91
|
handleClose: () => {
|
|
59
92
|
doneCallback()
|
|
60
93
|
},
|
|
61
|
-
|
|
94
|
+
inMemoryFileDriver: session.apolloDataStore.inMemoryFileDriver,
|
|
62
95
|
},
|
|
63
96
|
],
|
|
64
97
|
)
|
|
65
98
|
},
|
|
66
99
|
})
|
|
67
100
|
rootModel.appendToMenu('Apollo', {
|
|
68
|
-
label: '
|
|
101
|
+
label: 'View check results',
|
|
102
|
+
icon: FactCheckIcon,
|
|
69
103
|
onClick: (session: ApolloSessionModel) => {
|
|
70
104
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
71
105
|
(doneCallback) => [
|
|
72
|
-
|
|
106
|
+
ViewCheckResults,
|
|
73
107
|
{
|
|
74
108
|
session,
|
|
75
109
|
handleClose: () => {
|
|
76
110
|
doneCallback()
|
|
77
111
|
},
|
|
78
|
-
changeManager: session.apolloDataStore.changeManager,
|
|
79
112
|
},
|
|
80
113
|
],
|
|
81
114
|
)
|
|
82
115
|
},
|
|
83
116
|
})
|
|
84
117
|
rootModel.appendToMenu('Apollo', {
|
|
85
|
-
label: '
|
|
118
|
+
label: 'Lock/Unlock session',
|
|
119
|
+
onClick: (session: ApolloSessionModel) => {
|
|
120
|
+
session.toggleLocked()
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
rootModel.appendToMenu('Apollo', {
|
|
124
|
+
label: 'Log out',
|
|
125
|
+
icon: LogoutIcon,
|
|
86
126
|
onClick: (session: ApolloSessionModel) => {
|
|
87
127
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
88
128
|
(doneCallback) => [
|
|
89
|
-
|
|
129
|
+
LogOut,
|
|
90
130
|
{
|
|
91
131
|
session,
|
|
92
132
|
handleClose: () => {
|
|
93
133
|
doneCallback()
|
|
94
134
|
},
|
|
95
|
-
changeManager: session.apolloDataStore.changeManager,
|
|
96
135
|
},
|
|
97
136
|
],
|
|
98
137
|
)
|
|
99
138
|
},
|
|
100
139
|
})
|
|
101
|
-
rootModel.appendToMenu('Apollo', {
|
|
102
|
-
label: 'Undo',
|
|
103
|
-
onClick: (session: ApolloSessionModel) => {
|
|
104
|
-
const { apolloDataStore } = session
|
|
105
|
-
const { notify } = session as unknown as AbstractSessionModel
|
|
106
|
-
if (apolloDataStore.changeManager.recentChanges.length > 0) {
|
|
107
|
-
void apolloDataStore.changeManager.revertLastChange()
|
|
108
|
-
} else {
|
|
109
|
-
notify('No changes to undo', 'info')
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
})
|
|
113
140
|
}
|