@apollo-annotation/jbrowse-plugin-apollo 0.1.18 → 0.1.20
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 +3189 -3575
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +3185 -3570
- 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 +14884 -15905
- 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 +33 -33
- package/src/ApolloInternetAccount/addMenuItems.ts +18 -0
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
- package/src/ApolloInternetAccount/configSchema.ts +5 -2
- package/src/ApolloInternetAccount/model.ts +14 -5
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +94 -0
- package/src/ApolloRefNameAliasAdapter/configSchema.ts +12 -0
- package/src/ApolloRefNameAliasAdapter/index.ts +21 -0
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +1 -0
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +10 -10
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +35 -32
- package/src/BackendDrivers/BackendDriver.ts +8 -0
- package/src/BackendDrivers/CollaborationServerDriver.ts +49 -1
- package/src/BackendDrivers/DesktopFileDriver.ts +14 -1
- package/src/BackendDrivers/InMemoryFileDriver.ts +17 -1
- package/src/ChangeManager.ts +1 -1
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +5 -25
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +82 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +11 -3
- package/src/FeatureDetailsWidget/BasicInformation.tsx +38 -30
- package/src/FeatureDetailsWidget/Sequence.tsx +7 -7
- package/src/FeatureDetailsWidget/TranscriptBasic.tsx +446 -0
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +365 -0
- package/src/FeatureDetailsWidget/index.ts +2 -0
- package/src/FeatureDetailsWidget/model.ts +77 -9
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +0 -2
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +453 -380
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +520 -0
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +138 -134
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +38 -370
- package/src/LinearApolloDisplay/glyphs/index.ts +1 -2
- package/src/LinearApolloDisplay/stateModel/base.ts +3 -6
- package/src/LinearApolloDisplay/stateModel/getGlyph.ts +30 -30
- package/src/LinearApolloDisplay/stateModel/index.ts +5 -1
- package/src/LinearApolloDisplay/stateModel/layouts.ts +32 -24
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +206 -217
- package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -67
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -1
- package/src/OntologyManager/OntologyStore/index.ts +2 -1
- package/src/OntologyManager/index.ts +6 -2
- package/src/OntologyManager/util.ts +2 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +15 -10
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +21 -46
- package/src/TabularEditor/HybridGrid/Feature.tsx +31 -82
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +3 -2
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -3
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +46 -5
- package/src/TabularEditor/model.ts +5 -3
- package/src/components/AddAssembly.tsx +15 -9
- package/src/components/AddChildFeature.tsx +7 -73
- package/src/components/AddFeature.tsx +2 -57
- package/src/components/AddRefSeqAliases.tsx +285 -0
- package/src/components/CopyFeature.tsx +16 -33
- package/src/components/DeleteFeature.tsx +4 -6
- package/src/components/ImportFeatures.tsx +6 -3
- package/src/components/LogOut.tsx +105 -0
- package/src/components/ManageChecks.tsx +1 -0
- package/src/components/ManageUsers.tsx +21 -1
- package/src/components/ModifyFeatureAttribute.tsx +2 -2
- package/src/components/OntologyTermAutocomplete.tsx +0 -2
- package/src/components/OntologyTermMultiSelect.tsx +1 -0
- package/src/components/OpenLocalFile.tsx +6 -5
- package/src/components/ViewChangeLog.tsx +1 -0
- package/src/components/ViewCheckResults.tsx +1 -0
- package/src/components/index.ts +4 -0
- package/src/extensions/annotationFromPileup.ts +10 -16
- package/src/index.ts +57 -3
- package/src/session/ClientDataStore.ts +49 -46
- package/src/session/session.ts +186 -114
- package/src/util/loadAssemblyIntoClient.ts +4 -210
- package/src/FeatureDetailsWidget/RelatedFeature.tsx +0 -97
- package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +0 -1204
- package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +0 -716
- package/src/LinearApolloDisplay/stateModel/glyphs.ts +0 -47
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
3
4
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
+
AnnotationFeature,
|
|
6
7
|
AnnotationFeatureSnapshot,
|
|
7
8
|
} from '@apollo-annotation/mst'
|
|
8
9
|
import { AddFeatureChange } from '@apollo-annotation/shared'
|
|
@@ -30,7 +31,7 @@ import { Dialog } from './Dialog'
|
|
|
30
31
|
interface CopyFeatureProps {
|
|
31
32
|
session: ApolloSessionModel
|
|
32
33
|
handleClose(): void
|
|
33
|
-
sourceFeature:
|
|
34
|
+
sourceFeature: AnnotationFeature
|
|
34
35
|
sourceAssemblyId: string
|
|
35
36
|
changeManager: ChangeManager
|
|
36
37
|
}
|
|
@@ -88,7 +89,7 @@ export function CopyFeature({
|
|
|
88
89
|
>(assemblies.find((a) => a.name !== sourceAssemblyId)?.name)
|
|
89
90
|
const [refNames, setRefNames] = useState<Collection[]>([])
|
|
90
91
|
const [selectedRefSeqId, setSelectedRefSeqId] = useState('')
|
|
91
|
-
const [start, setStart] = useState(sourceFeature.
|
|
92
|
+
const [start, setStart] = useState(sourceFeature.min)
|
|
92
93
|
const [errorMessage, setErrorMessage] = useState('')
|
|
93
94
|
|
|
94
95
|
function handleChangeAssembly(e: SelectChangeEvent) {
|
|
@@ -173,22 +174,12 @@ export function CopyFeature({
|
|
|
173
174
|
delete attributeMap.Parent
|
|
174
175
|
}
|
|
175
176
|
|
|
176
|
-
// Update gffId value if it's ObjectId
|
|
177
|
-
if (
|
|
178
|
-
newFeatureLine.gffId &&
|
|
179
|
-
ObjectID.isValid(newFeatureLine.gffId.toString())
|
|
180
|
-
) {
|
|
181
|
-
newFeatureLine.gffId = newFeatureLine._id
|
|
182
|
-
}
|
|
183
177
|
newFeatureLine.refSeq = selectedRefSeqId
|
|
184
|
-
const locationMove = start - newFeatureLine.
|
|
185
|
-
newFeatureLine.
|
|
186
|
-
newFeatureLine.
|
|
187
|
-
// Updates children start
|
|
188
|
-
const updatedChildren =
|
|
189
|
-
newFeatureLine,
|
|
190
|
-
locationMove,
|
|
191
|
-
)
|
|
178
|
+
const locationMove = start - newFeatureLine.min
|
|
179
|
+
newFeatureLine.min = start
|
|
180
|
+
newFeatureLine.max = start + featureLength
|
|
181
|
+
// Updates children start and end values
|
|
182
|
+
const updatedChildren = updateRefSeqStartEnd(newFeatureLine, locationMove)
|
|
192
183
|
|
|
193
184
|
const change = new AddFeatureChange({
|
|
194
185
|
changedIds: [newFeatureLine._id],
|
|
@@ -197,18 +188,15 @@ export function CopyFeature({
|
|
|
197
188
|
addedFeature: {
|
|
198
189
|
_id: newFeatureLine._id,
|
|
199
190
|
refSeq: newFeatureLine.refSeq,
|
|
200
|
-
|
|
201
|
-
|
|
191
|
+
min: newFeatureLine.min,
|
|
192
|
+
max: newFeatureLine.max,
|
|
202
193
|
type: newFeatureLine.type,
|
|
203
194
|
children: updatedChildren.children as unknown as Record<
|
|
204
195
|
string,
|
|
205
196
|
AnnotationFeatureSnapshot
|
|
206
197
|
>,
|
|
207
198
|
attributes: attributeMap,
|
|
208
|
-
discontinuousLocations: newFeatureLine.discontinuousLocations,
|
|
209
199
|
strand: newFeatureLine.strand,
|
|
210
|
-
score: newFeatureLine.score,
|
|
211
|
-
phase: newFeatureLine.phase,
|
|
212
200
|
},
|
|
213
201
|
copyFeature: true,
|
|
214
202
|
allIds: featureIds,
|
|
@@ -221,27 +209,22 @@ export function CopyFeature({
|
|
|
221
209
|
}
|
|
222
210
|
|
|
223
211
|
/**
|
|
224
|
-
* Recursively loop children and update refSeq, start,
|
|
212
|
+
* Recursively loop children and update refSeq, start, and end values
|
|
225
213
|
* @param feature - parent feature
|
|
226
214
|
* @param locationMove - how much location has been moved from original
|
|
227
215
|
* @returns
|
|
228
216
|
*/
|
|
229
|
-
function
|
|
217
|
+
function updateRefSeqStartEnd(
|
|
230
218
|
feature: AnnotationFeatureSnapshot,
|
|
231
219
|
locationMove: number,
|
|
232
220
|
): AnnotationFeatureSnapshot {
|
|
233
221
|
const children: Record<string, AnnotationFeatureSnapshot> = {}
|
|
234
222
|
if (feature.children) {
|
|
235
223
|
for (const child of Object.values(feature.children)) {
|
|
236
|
-
const newChild =
|
|
237
|
-
// Update gffId value if it's ObjectId
|
|
238
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
239
|
-
if (ObjectID.isValid(newChild.gffId!.toString())) {
|
|
240
|
-
newChild.gffId = newChild._id
|
|
241
|
-
}
|
|
224
|
+
const newChild = updateRefSeqStartEnd(child, locationMove)
|
|
242
225
|
newChild.refSeq = selectedRefSeqId
|
|
243
|
-
newChild.
|
|
244
|
-
newChild.
|
|
226
|
+
newChild.min = newChild.min + locationMove
|
|
227
|
+
newChild.max = newChild.max + locationMove
|
|
245
228
|
children[newChild._id] = newChild
|
|
246
229
|
}
|
|
247
230
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
1
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
4
|
-
import {
|
|
2
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
5
3
|
import { DeleteFeatureChange } from '@apollo-annotation/shared'
|
|
6
4
|
import { AbstractSessionModel } from '@jbrowse/core/util'
|
|
7
5
|
import {
|
|
@@ -20,11 +18,11 @@ import { Dialog } from './Dialog'
|
|
|
20
18
|
interface DeleteFeatureProps {
|
|
21
19
|
session: ApolloSessionModel
|
|
22
20
|
handleClose(): void
|
|
23
|
-
sourceFeature:
|
|
21
|
+
sourceFeature: AnnotationFeature
|
|
24
22
|
sourceAssemblyId: string
|
|
25
23
|
changeManager: ChangeManager
|
|
26
|
-
selectedFeature?:
|
|
27
|
-
setSelectedFeature(feature?:
|
|
24
|
+
selectedFeature?: AnnotationFeature
|
|
25
|
+
setSelectedFeature(feature?: AnnotationFeature): void
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
export function DeleteFeature({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
|
|
1
2
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
4
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
@@ -158,14 +159,16 @@ export function ImportFeatures({
|
|
|
158
159
|
const { baseURL } = apolloInternetAccount
|
|
159
160
|
|
|
160
161
|
// First upload file
|
|
161
|
-
const url = new URL('files', baseURL)
|
|
162
|
+
const url = new URL('files', baseURL)
|
|
163
|
+
url.searchParams.set('type', 'text/x-gff3')
|
|
164
|
+
const uri = url.href
|
|
162
165
|
const formData = new FormData()
|
|
163
166
|
formData.append('file', file)
|
|
164
167
|
formData.append('fileName', file.name)
|
|
165
168
|
formData.append('type', 'text/x-gff3')
|
|
166
169
|
const apolloFetchFile = apolloInternetAccount.getFetcher({
|
|
167
170
|
locationType: 'UriLocation',
|
|
168
|
-
uri
|
|
171
|
+
uri,
|
|
169
172
|
})
|
|
170
173
|
|
|
171
174
|
handleClose()
|
|
@@ -187,7 +190,7 @@ export function ImportFeatures({
|
|
|
187
190
|
|
|
188
191
|
if (apolloFetchFile) {
|
|
189
192
|
const { signal } = controller
|
|
190
|
-
const response = await apolloFetchFile(
|
|
193
|
+
const response = await apolloFetchFile(uri, {
|
|
191
194
|
method: 'POST',
|
|
192
195
|
body: formData,
|
|
193
196
|
signal,
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
DialogActions,
|
|
4
|
+
DialogContent,
|
|
5
|
+
DialogContentText,
|
|
6
|
+
MenuItem,
|
|
7
|
+
Select,
|
|
8
|
+
SelectChangeEvent,
|
|
9
|
+
} from '@mui/material'
|
|
10
|
+
import { getRoot } from 'mobx-state-tree'
|
|
11
|
+
import React, { useState } from 'react'
|
|
12
|
+
|
|
13
|
+
import { ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
|
|
14
|
+
import { ApolloSessionModel } from '../session'
|
|
15
|
+
import { ApolloRootModel } from '../types'
|
|
16
|
+
import { Dialog } from './Dialog'
|
|
17
|
+
|
|
18
|
+
interface DeleteAssemblyProps {
|
|
19
|
+
session: ApolloSessionModel
|
|
20
|
+
handleClose(): void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function LogOut({ handleClose, session }: DeleteAssemblyProps) {
|
|
24
|
+
const { internetAccounts } = getRoot<ApolloRootModel>(session)
|
|
25
|
+
const [errorMessage, setErrorMessage] = useState('')
|
|
26
|
+
const apolloInternetAccounts = internetAccounts.filter(
|
|
27
|
+
(ia) => ia.type === 'ApolloInternetAccount',
|
|
28
|
+
) as ApolloInternetAccountModel[]
|
|
29
|
+
if (apolloInternetAccounts.length === 0) {
|
|
30
|
+
throw new Error('No Apollo internet account found')
|
|
31
|
+
}
|
|
32
|
+
const [selectedInternetAccount, setSelectedInternetAccount] = useState(
|
|
33
|
+
apolloInternetAccounts[0],
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
function handleChangeInternetAccount(e: SelectChangeEvent) {
|
|
37
|
+
const newlySelectedInternetAccount = apolloInternetAccounts.find(
|
|
38
|
+
(ia) => ia.internetAccountId === e.target.value,
|
|
39
|
+
)
|
|
40
|
+
if (!newlySelectedInternetAccount) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Could not find internetAccount with ID "${e.target.value}"`,
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
setSelectedInternetAccount(newlySelectedInternetAccount)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function onSubmit(event: React.FormEvent<HTMLFormElement>) {
|
|
49
|
+
event.preventDefault()
|
|
50
|
+
setErrorMessage('')
|
|
51
|
+
selectedInternetAccount.removeToken()
|
|
52
|
+
window.location.reload()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Dialog
|
|
57
|
+
open
|
|
58
|
+
title="Log out"
|
|
59
|
+
handleClose={handleClose}
|
|
60
|
+
maxWidth={false}
|
|
61
|
+
data-testid="log-out"
|
|
62
|
+
>
|
|
63
|
+
<form onSubmit={onSubmit}>
|
|
64
|
+
<DialogContent style={{ display: 'flex', flexDirection: 'column' }}>
|
|
65
|
+
{apolloInternetAccounts.length > 1 ? (
|
|
66
|
+
<>
|
|
67
|
+
<DialogContentText>Select account</DialogContentText>
|
|
68
|
+
<Select
|
|
69
|
+
value={selectedInternetAccount.internetAccountId}
|
|
70
|
+
onChange={handleChangeInternetAccount}
|
|
71
|
+
>
|
|
72
|
+
{internetAccounts.map((option) => (
|
|
73
|
+
<MenuItem key={option.id} value={option.internetAccountId}>
|
|
74
|
+
{option.name}
|
|
75
|
+
</MenuItem>
|
|
76
|
+
))}
|
|
77
|
+
</Select>
|
|
78
|
+
</>
|
|
79
|
+
) : null}
|
|
80
|
+
<DialogContentText>
|
|
81
|
+
Are you sure you want to log out?
|
|
82
|
+
</DialogContentText>
|
|
83
|
+
</DialogContent>
|
|
84
|
+
|
|
85
|
+
<DialogActions>
|
|
86
|
+
<Button
|
|
87
|
+
disabled={!selectedInternetAccount}
|
|
88
|
+
variant="contained"
|
|
89
|
+
type="submit"
|
|
90
|
+
>
|
|
91
|
+
Log Out
|
|
92
|
+
</Button>
|
|
93
|
+
<Button variant="outlined" type="submit" onClick={handleClose}>
|
|
94
|
+
Cancel
|
|
95
|
+
</Button>
|
|
96
|
+
</DialogActions>
|
|
97
|
+
</form>
|
|
98
|
+
{errorMessage ? (
|
|
99
|
+
<DialogContent>
|
|
100
|
+
<DialogContentText color="error">{errorMessage}</DialogContentText>
|
|
101
|
+
</DialogContent>
|
|
102
|
+
) : null}
|
|
103
|
+
</Dialog>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
3
4
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
@@ -123,7 +124,26 @@ export function ManageUsers({
|
|
|
123
124
|
headerName: 'Role',
|
|
124
125
|
width: 140,
|
|
125
126
|
type: 'singleSelect',
|
|
126
|
-
valueOptions: ['', '
|
|
127
|
+
valueOptions: ['readOnly', 'user', 'admin', 'none'],
|
|
128
|
+
getOptionLabel(value) {
|
|
129
|
+
switch (value) {
|
|
130
|
+
case 'readOnly': {
|
|
131
|
+
return 'Read-only'
|
|
132
|
+
}
|
|
133
|
+
case 'user': {
|
|
134
|
+
return 'User'
|
|
135
|
+
}
|
|
136
|
+
case 'admin': {
|
|
137
|
+
return 'Admin'
|
|
138
|
+
}
|
|
139
|
+
case 'none': {
|
|
140
|
+
return 'None'
|
|
141
|
+
}
|
|
142
|
+
default: {
|
|
143
|
+
return 'unknown'
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
127
147
|
editable: true,
|
|
128
148
|
},
|
|
129
149
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
4
|
-
import {
|
|
4
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
5
5
|
import { FeatureAttributeChange } from '@apollo-annotation/shared'
|
|
6
6
|
import { AbstractSessionModel } from '@jbrowse/core/util'
|
|
7
7
|
import DeleteIcon from '@mui/icons-material/Delete'
|
|
@@ -35,7 +35,7 @@ import { OntologyTermMultiSelect } from './OntologyTermMultiSelect'
|
|
|
35
35
|
interface ModifyFeatureAttributeProps {
|
|
36
36
|
session: ApolloSessionModel
|
|
37
37
|
handleClose(): void
|
|
38
|
-
sourceFeature:
|
|
38
|
+
sourceFeature: AnnotationFeature
|
|
39
39
|
sourceAssemblyId: string
|
|
40
40
|
changeManager: ChangeManager
|
|
41
41
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
1
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
4
3
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
@@ -10,7 +9,6 @@ import {
|
|
|
10
9
|
} from '@mui/material'
|
|
11
10
|
import React, { useCallback, useEffect, useState } from 'react'
|
|
12
11
|
|
|
13
|
-
import type { OntologyManager } from '../OntologyManager'
|
|
14
12
|
import { OntologyTerm, isDeprecated } from '../OntologyManager'
|
|
15
13
|
import OntologyStore from '../OntologyManager/OntologyStore'
|
|
16
14
|
import { ApolloSessionModel } from '../session'
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
1
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
2
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
4
3
|
import { AbstractSessionModel, isElectron } from '@jbrowse/core/util'
|
|
@@ -33,7 +32,7 @@ export interface RefSeqInterface {
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
export function OpenLocalFile({ handleClose, session }: OpenLocalFileProps) {
|
|
36
|
-
const {
|
|
35
|
+
const { apolloDataStore } = session
|
|
37
36
|
const { addAssembly, addSessionAssembly, assemblyManager, notify } =
|
|
38
37
|
session as unknown as AbstractSessionModel & {
|
|
39
38
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
@@ -79,8 +78,10 @@ export function OpenLocalFile({ handleClose, session }: OpenLocalFileProps) {
|
|
|
79
78
|
try {
|
|
80
79
|
await loadAssemblyIntoClient(assemblyId, fileData, apolloDataStore)
|
|
81
80
|
} catch (error) {
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
console.error(error)
|
|
82
|
+
notify(`Error loading GFF3 ${file.name}, ${String(error)}`, 'error')
|
|
83
|
+
handleClose()
|
|
84
|
+
return
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
const assemblyConfig = {
|
|
@@ -105,7 +106,7 @@ export function OpenLocalFile({ handleClose, session }: OpenLocalFileProps) {
|
|
|
105
106
|
const a = await assemblyManager.waitForAssembly(assemblyConfig.name)
|
|
106
107
|
if (a) {
|
|
107
108
|
// @ts-expect-error MST type coercion problem?
|
|
108
|
-
addApolloTrackConfig(a)
|
|
109
|
+
session.addApolloTrackConfig(a)
|
|
109
110
|
notify(`Loaded GFF3 ${file.name}`, 'success')
|
|
110
111
|
} else {
|
|
111
112
|
notify(`Error loading GFF3 ${file.name}`, 'error')
|
package/src/components/index.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
export * from './AddAssembly'
|
|
2
2
|
export * from './AddChildFeature'
|
|
3
|
+
export * from './AddFeature'
|
|
3
4
|
export * from './CopyFeature'
|
|
4
5
|
export * from './DeleteAssembly'
|
|
5
6
|
export * from './DeleteFeature'
|
|
6
7
|
export * from './DownloadGFF3'
|
|
7
8
|
export * from './ImportFeatures'
|
|
9
|
+
export * from './LogOut'
|
|
8
10
|
export * from './ManageChecks'
|
|
9
11
|
export * from './ManageUsers'
|
|
10
12
|
export * from './ModifyFeatureAttribute'
|
|
11
13
|
export * from './OpenLocalFile'
|
|
12
14
|
export * from './ViewChangeLog'
|
|
15
|
+
export * from './AddRefSeqAliases'
|
|
16
|
+
export * from './ViewCheckResults'
|
|
@@ -106,10 +106,9 @@ export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
|
106
106
|
|
|
107
107
|
const newFeature: AnnotationFeatureSnapshot = {
|
|
108
108
|
_id: ObjectID().toHexString(),
|
|
109
|
-
gffId: '',
|
|
110
109
|
refSeq: refSeqId,
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
min: feature.get('start'),
|
|
111
|
+
max: feature.get('end'),
|
|
113
112
|
type: 'mRNA',
|
|
114
113
|
strand: feature.get('strand'),
|
|
115
114
|
}
|
|
@@ -122,22 +121,19 @@ export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
|
122
121
|
const [firstExon] = exons
|
|
123
122
|
const cdsFeature: AnnotationFeatureSnapshot = {
|
|
124
123
|
_id: ObjectID().toHexString(),
|
|
125
|
-
gffId: '',
|
|
126
124
|
refSeq: refSeqId,
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
min: firstExon.start,
|
|
126
|
+
max: firstExon.end,
|
|
129
127
|
type: 'CDS',
|
|
130
128
|
strand: feature.get('strand'),
|
|
131
|
-
phase: 0,
|
|
132
129
|
}
|
|
133
130
|
newFeature.children[cdsFeature._id] = cdsFeature
|
|
134
131
|
if (exons.length === 1) {
|
|
135
132
|
const exon: AnnotationFeatureSnapshot = {
|
|
136
133
|
_id: ObjectID().toHexString(),
|
|
137
|
-
gffId: '',
|
|
138
134
|
refSeq: refSeqId,
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
min: firstExon.start,
|
|
136
|
+
max: firstExon.end,
|
|
141
137
|
type: 'exon',
|
|
142
138
|
strand: feature.get('strand'),
|
|
143
139
|
}
|
|
@@ -152,24 +148,22 @@ export function annotationFromPileup(pluggableElement: PluggableElementBase) {
|
|
|
152
148
|
}[] = []
|
|
153
149
|
let phase: 0 | 1 | 2 = 0
|
|
154
150
|
for (const exon of exons) {
|
|
155
|
-
cdsFeature.
|
|
156
|
-
cdsFeature.
|
|
151
|
+
cdsFeature.min = Math.min(cdsFeature.min, exon.start)
|
|
152
|
+
cdsFeature.max = Math.max(cdsFeature.max, exon.end)
|
|
157
153
|
const { end, start } = exon
|
|
158
154
|
discontinuousLocations.push({ start, end, phase })
|
|
159
155
|
const localPhase = (end - start) % 3
|
|
160
156
|
phase = ((phase + localPhase) % 3) as 0 | 1 | 2
|
|
161
157
|
const newExon: AnnotationFeatureSnapshot = {
|
|
162
158
|
_id: ObjectID().toHexString(),
|
|
163
|
-
gffId: '',
|
|
164
159
|
refSeq: refSeqId,
|
|
165
|
-
start,
|
|
166
|
-
end,
|
|
160
|
+
min: start,
|
|
161
|
+
max: end,
|
|
167
162
|
type: 'exon',
|
|
168
163
|
strand: feature.get('strand'),
|
|
169
164
|
}
|
|
170
165
|
newFeature.children[newExon._id] = newExon
|
|
171
166
|
}
|
|
172
|
-
cdsFeature.discontinuousLocations = discontinuousLocations
|
|
173
167
|
return newFeature
|
|
174
168
|
},
|
|
175
169
|
async onPileupFeatureContext() {
|
package/src/index.ts
CHANGED
|
@@ -46,18 +46,21 @@ import {
|
|
|
46
46
|
import { installApolloTextSearchAdapter } from './ApolloTextSearchAdapter'
|
|
47
47
|
import { BackendDriver } from './BackendDrivers'
|
|
48
48
|
import {
|
|
49
|
+
AddFeature,
|
|
49
50
|
DownloadGFF3,
|
|
51
|
+
LogOut,
|
|
50
52
|
ManageChecks,
|
|
51
53
|
OpenLocalFile,
|
|
52
54
|
ViewChangeLog,
|
|
55
|
+
ViewCheckResults,
|
|
53
56
|
} from './components'
|
|
54
|
-
import { AddFeature } from './components/AddFeature'
|
|
55
|
-
import { ViewCheckResults } from './components/ViewCheckResults'
|
|
56
57
|
import ApolloPluginConfigurationSchema from './config'
|
|
57
58
|
import { annotationFromPileup } from './extensions'
|
|
58
59
|
import {
|
|
59
60
|
ApolloFeatureDetailsWidget,
|
|
60
61
|
ApolloFeatureDetailsWidgetModel,
|
|
62
|
+
ApolloTranscriptDetailsModel,
|
|
63
|
+
ApolloTranscriptDetailsWidget,
|
|
61
64
|
} from './FeatureDetailsWidget'
|
|
62
65
|
import {
|
|
63
66
|
stateModelFactory as LinearApolloDisplayStateModelFactory,
|
|
@@ -72,6 +75,7 @@ import {
|
|
|
72
75
|
stateModelFactory as SixFrameFeatureDisplayStateModelFactory,
|
|
73
76
|
configSchemaFactory as sixFrameFeatureDisplayConfigSchemaFactory,
|
|
74
77
|
} from './SixFrameFeatureDisplay'
|
|
78
|
+
import { installApolloRefNameAliasAdapter } from './ApolloRefNameAliasAdapter'
|
|
75
79
|
|
|
76
80
|
interface RpcHandle {
|
|
77
81
|
on(event: string, listener: (event: MessageEvent) => void): this
|
|
@@ -114,6 +118,7 @@ export default class ApolloPlugin extends Plugin {
|
|
|
114
118
|
|
|
115
119
|
install(pluginManager: PluginManager) {
|
|
116
120
|
installApolloSequenceAdapter(pluginManager)
|
|
121
|
+
installApolloRefNameAliasAdapter(pluginManager)
|
|
117
122
|
installApolloTextSearchAdapter(pluginManager)
|
|
118
123
|
|
|
119
124
|
pluginManager.addWidgetType(() => {
|
|
@@ -127,7 +132,17 @@ export default class ApolloPlugin extends Plugin {
|
|
|
127
132
|
})
|
|
128
133
|
return widgetType
|
|
129
134
|
})
|
|
130
|
-
|
|
135
|
+
pluginManager.addWidgetType(() => {
|
|
136
|
+
const configSchema = ConfigurationSchema('ApolloTranscriptDetails', {})
|
|
137
|
+
const widgetType = new WidgetType({
|
|
138
|
+
name: 'ApolloTranscriptDetails',
|
|
139
|
+
heading: 'Apollo transcript details',
|
|
140
|
+
configSchema,
|
|
141
|
+
stateModel: ApolloTranscriptDetailsModel,
|
|
142
|
+
ReactComponent: ApolloTranscriptDetailsWidget,
|
|
143
|
+
})
|
|
144
|
+
return widgetType
|
|
145
|
+
})
|
|
131
146
|
pluginManager.addTrackType(() => {
|
|
132
147
|
const configSchema = ConfigurationSchema(
|
|
133
148
|
'ApolloTrack',
|
|
@@ -203,6 +218,7 @@ export default class ApolloPlugin extends Plugin {
|
|
|
203
218
|
|
|
204
219
|
pluginManager.addToExtensionPoint(
|
|
205
220
|
'Core-extendSession',
|
|
221
|
+
// @ts-expect-error not sure how to deal with snapshot model types
|
|
206
222
|
extendSession.bind(this, pluginManager),
|
|
207
223
|
)
|
|
208
224
|
|
|
@@ -317,6 +333,28 @@ export default class ApolloPlugin extends Plugin {
|
|
|
317
333
|
})
|
|
318
334
|
break
|
|
319
335
|
}
|
|
336
|
+
case 'getRefNameAliases': {
|
|
337
|
+
const { assembly } = event
|
|
338
|
+
const dataStore = (
|
|
339
|
+
pluginManager.rootModel?.session as
|
|
340
|
+
| ApolloSessionModel
|
|
341
|
+
| undefined
|
|
342
|
+
)?.apolloDataStore
|
|
343
|
+
if (!dataStore) {
|
|
344
|
+
break
|
|
345
|
+
}
|
|
346
|
+
const backendDriver = dataStore.getBackendDriver(
|
|
347
|
+
assembly,
|
|
348
|
+
) as BackendDriver
|
|
349
|
+
const refNameAliases =
|
|
350
|
+
await backendDriver.getRefNameAliases(assembly)
|
|
351
|
+
handle.workers[0].postMessage({
|
|
352
|
+
apollo,
|
|
353
|
+
messageId,
|
|
354
|
+
refNameAliases,
|
|
355
|
+
})
|
|
356
|
+
break
|
|
357
|
+
}
|
|
320
358
|
default: {
|
|
321
359
|
break
|
|
322
360
|
}
|
|
@@ -411,6 +449,22 @@ export default class ApolloPlugin extends Plugin {
|
|
|
411
449
|
)
|
|
412
450
|
},
|
|
413
451
|
})
|
|
452
|
+
pluginManager.rootModel.appendToMenu('Apollo', {
|
|
453
|
+
label: 'Log out',
|
|
454
|
+
onClick: (session: ApolloSessionModel) => {
|
|
455
|
+
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
456
|
+
(doneCallback) => [
|
|
457
|
+
LogOut,
|
|
458
|
+
{
|
|
459
|
+
session,
|
|
460
|
+
handleClose: () => {
|
|
461
|
+
doneCallback()
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
],
|
|
465
|
+
)
|
|
466
|
+
},
|
|
467
|
+
})
|
|
414
468
|
}
|
|
415
469
|
}
|
|
416
470
|
}
|