@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.
- package/dist/index.esm.js +6964 -4598
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +6610 -4261
- 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 +11563 -7493
- 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 +4 -4
- package/src/ApolloInternetAccount/addMenuItems.ts +23 -2
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
- package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
- package/src/ApolloInternetAccount/components/LoginIcons.tsx +1 -1
- package/src/ApolloInternetAccount/configSchema.ts +1 -1
- package/src/ApolloInternetAccount/model.ts +11 -10
- package/src/ApolloJobModel.ts +1 -1
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +8 -6
- package/src/ApolloRefNameAliasAdapter/index.ts +2 -2
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +4 -4
- package/src/ApolloSequenceAdapter/index.ts +1 -1
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +8 -7
- package/src/ApolloTextSearchAdapter/index.ts +1 -1
- package/src/BackendDrivers/BackendDriver.ts +7 -7
- package/src/BackendDrivers/CollaborationServerDriver.ts +14 -10
- package/src/BackendDrivers/DesktopFileDriver.ts +11 -10
- package/src/BackendDrivers/InMemoryFileDriver.ts +10 -6
- package/src/ChangeManager.ts +15 -11
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +8 -7
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +35 -14
- package/src/FeatureDetailsWidget/AttributeKey.tsx +50 -0
- package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +104 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +215 -367
- package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -5
- package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +104 -0
- package/src/FeatureDetailsWidget/DefaultAttributeViewer.tsx +22 -0
- package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +4 -4
- package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -1
- package/src/FeatureDetailsWidget/Sequence.tsx +2 -2
- package/src/FeatureDetailsWidget/StringTextField.tsx +1 -1
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +15 -23
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +950 -196
- package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +8 -4
- package/src/FeatureDetailsWidget/model.ts +8 -3
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +7 -7
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +59 -72
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +253 -60
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +52 -6
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +16 -8
- package/src/LinearApolloDisplay/stateModel/base.ts +81 -10
- package/src/LinearApolloDisplay/stateModel/index.ts +4 -3
- package/src/LinearApolloDisplay/stateModel/layouts.ts +8 -39
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +63 -46
- package/src/LinearApolloDisplay/stateModel/rendering.ts +60 -31
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +226 -0
- package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +32 -0
- package/src/LinearApolloSixFrameDisplay/components/index.ts +2 -0
- package/src/LinearApolloSixFrameDisplay/configSchema.ts +7 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +940 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +63 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/index.ts +1 -0
- package/src/LinearApolloSixFrameDisplay/index.ts +2 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +302 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +27 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +252 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +368 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +201 -0
- package/src/LinearApolloSixFrameDisplay/types.ts +1 -0
- package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
- package/src/OntologyManager/OntologyStore/fulltext.ts +8 -3
- package/src/OntologyManager/OntologyStore/index.test.ts +3 -1
- package/src/OntologyManager/OntologyStore/index.ts +19 -14
- package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -5
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +11 -5
- package/src/OntologyManager/index.ts +12 -7
- package/src/OntologyManager/util.ts +3 -2
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
- package/src/TabularEditor/HybridGrid/Feature.tsx +13 -7
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +1 -1
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +3 -2
- package/src/TabularEditor/HybridGrid/ToolBar.tsx +1 -1
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +114 -22
- package/src/TabularEditor/TabularEditorPane.tsx +1 -1
- package/src/TabularEditor/model.ts +2 -2
- package/src/TabularEditor/types.ts +5 -2
- package/src/components/AddAssembly.tsx +182 -179
- package/src/components/AddAssemblyAliases.tsx +114 -0
- package/src/components/AddChildFeature.tsx +8 -10
- package/src/components/AddFeature.tsx +216 -44
- package/src/components/AddRefSeqAliases.tsx +14 -12
- package/src/components/CopyFeature.tsx +10 -11
- package/src/components/CreateApolloAnnotation.tsx +342 -158
- package/src/components/DeleteAssembly.tsx +9 -8
- package/src/components/DeleteFeature.tsx +362 -14
- package/src/components/Dialog.tsx +1 -1
- package/src/components/DownloadGFF3.tsx +31 -11
- package/src/components/FilterFeatures.tsx +6 -4
- package/src/components/FilterTranscripts.tsx +86 -0
- package/src/components/ImportFeatures.tsx +7 -6
- package/src/components/LogOut.tsx +5 -4
- package/src/components/ManageChecks.tsx +9 -8
- package/src/components/ManageUsers.tsx +11 -10
- package/src/components/MergeExons.tsx +193 -0
- package/src/components/MergeTranscripts.tsx +185 -0
- package/src/components/OntologyTermAutocomplete.tsx +5 -5
- package/src/components/OntologyTermMultiSelect.tsx +6 -6
- package/src/components/OpenLocalFile.tsx +4 -3
- package/src/components/SplitExon.tsx +134 -0
- package/src/components/ViewChangeLog.tsx +7 -6
- package/src/components/ViewCheckResults.tsx +8 -7
- package/src/components/index.ts +3 -0
- package/src/config.ts +5 -0
- package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -0
- package/src/extensions/annotationFromJBrowseFeature.ts +13 -10
- package/src/extensions/annotationFromPileup.ts +104 -94
- package/src/index.ts +33 -50
- package/src/makeDisplayComponent.tsx +90 -37
- package/src/session/ClientDataStore.ts +21 -17
- package/src/session/session.ts +46 -39
- package/src/types.ts +4 -4
- package/src/util/annotationFeatureUtils.ts +66 -1
- package/src/util/copyToClipboard.ts +21 -0
- package/src/util/glyphUtils.ts +49 -0
- package/src/util/index.ts +5 -3
- package/src/util/loadAssemblyIntoClient.ts +10 -3
- package/src/util/mouseEventsUtils.ts +113 -0
- package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +0 -13
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +0 -707
- package/src/ApolloSixFrameRenderer/configSchema.ts +0 -7
- package/src/ApolloSixFrameRenderer/index.ts +0 -3
- package/src/SixFrameFeatureDisplay/components/TrackLines.tsx +0 -19
- package/src/SixFrameFeatureDisplay/components/index.ts +0 -1
- package/src/SixFrameFeatureDisplay/configSchema.ts +0 -21
- package/src/SixFrameFeatureDisplay/index.ts +0 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +0 -443
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
|
-
import
|
|
3
|
-
import type LinearGenomeViewPlugin from '@jbrowse/plugin-linear-genome-view'
|
|
2
|
+
import { getSession } from '@jbrowse/core/util'
|
|
4
3
|
import ExpandLessIcon from '@mui/icons-material/ExpandLess'
|
|
5
4
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
|
6
5
|
import { Alert, Typography, alpha } from '@mui/material'
|
|
@@ -9,13 +8,11 @@ import React, { useCallback, useEffect, useRef } from 'react'
|
|
|
9
8
|
import { makeStyles } from 'tss-react/mui'
|
|
10
9
|
|
|
11
10
|
import { LinearApolloDisplay } from './LinearApolloDisplay/components'
|
|
12
|
-
import { LinearApolloDisplay as LinearApolloDisplayI } from './LinearApolloDisplay/stateModel'
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
11
|
+
import { type LinearApolloDisplay as LinearApolloDisplayI } from './LinearApolloDisplay/stateModel'
|
|
12
|
+
import { LinearApolloSixFrameDisplay } from './LinearApolloSixFrameDisplay/components'
|
|
13
|
+
import { type LinearApolloSixFrameDisplay as LinearApolloSixFrameDisplayI } from './LinearApolloSixFrameDisplay/stateModel'
|
|
15
14
|
import { TabularEditorPane } from './TabularEditor'
|
|
16
|
-
|
|
17
|
-
import { getSession } from '@jbrowse/core/util'
|
|
18
|
-
import { ApolloSessionModel } from './session'
|
|
15
|
+
import { type ApolloSessionModel } from './session'
|
|
19
16
|
|
|
20
17
|
const accordionControlHeight = 12
|
|
21
18
|
|
|
@@ -63,7 +60,7 @@ const useStyles = makeStyles()((theme) => ({
|
|
|
63
60
|
}))
|
|
64
61
|
|
|
65
62
|
function scrollSelectedFeatureIntoView(
|
|
66
|
-
model: LinearApolloDisplayI,
|
|
63
|
+
model: LinearApolloDisplayI | LinearApolloSixFrameDisplayI,
|
|
67
64
|
scrollContainerRef: React.RefObject<HTMLDivElement>,
|
|
68
65
|
) {
|
|
69
66
|
const { apolloRowHeight, selectedFeature } = model
|
|
@@ -157,7 +154,7 @@ const AccordionControl = observer(function AccordionControl({
|
|
|
157
154
|
)
|
|
158
155
|
})
|
|
159
156
|
|
|
160
|
-
export const
|
|
157
|
+
export const LinearApolloDisplayComponent = observer(function DisplayComponent({
|
|
161
158
|
model,
|
|
162
159
|
...other
|
|
163
160
|
}: {
|
|
@@ -248,40 +245,96 @@ export const DisplayComponent = observer(function DisplayComponent({
|
|
|
248
245
|
)
|
|
249
246
|
})
|
|
250
247
|
|
|
251
|
-
export
|
|
252
|
-
|
|
253
|
-
| LinearGenomeViewPlugin
|
|
254
|
-
| undefined
|
|
255
|
-
if (!LGVPlugin) {
|
|
256
|
-
throw new Error('LinearGenomeView plugin not found')
|
|
257
|
-
}
|
|
258
|
-
const { BaseLinearDisplayComponent } = LGVPlugin.exports
|
|
259
|
-
function ApolloDisplayComponent({
|
|
248
|
+
export const LinearApolloSixFrameDisplayComponent = observer(
|
|
249
|
+
function DisplayComponent({
|
|
260
250
|
model,
|
|
261
251
|
...other
|
|
262
252
|
}: {
|
|
263
|
-
model:
|
|
253
|
+
model: LinearApolloSixFrameDisplayI
|
|
264
254
|
}) {
|
|
255
|
+
const session = getSession(model) as unknown as ApolloSessionModel
|
|
256
|
+
const { ontologyManager } = session.apolloDataStore
|
|
257
|
+
const { featureTypeOntology } = ontologyManager
|
|
258
|
+
const ontologyStore = featureTypeOntology?.dataStore
|
|
259
|
+
|
|
265
260
|
const { classes } = useStyles()
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
261
|
+
|
|
262
|
+
const {
|
|
263
|
+
detailsHeight,
|
|
264
|
+
graphical,
|
|
265
|
+
height: overallHeight,
|
|
266
|
+
isShown,
|
|
267
|
+
selectedFeature,
|
|
268
|
+
table,
|
|
269
|
+
tabularEditor,
|
|
270
|
+
toggleShown,
|
|
271
|
+
} = model
|
|
272
|
+
|
|
273
|
+
const canvasScrollContainerRef = useRef<HTMLDivElement>(null)
|
|
274
|
+
useEffect(() => {
|
|
275
|
+
scrollSelectedFeatureIntoView(model, canvasScrollContainerRef)
|
|
276
|
+
}, [model, selectedFeature])
|
|
277
|
+
|
|
278
|
+
const onDetailsResize = (delta: number) => {
|
|
279
|
+
model.setDetailsHeight(detailsHeight - delta)
|
|
270
280
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
<div className={classes.
|
|
275
|
-
<
|
|
281
|
+
|
|
282
|
+
if (!ontologyStore) {
|
|
283
|
+
return (
|
|
284
|
+
<div className={classes.alertContainer}>
|
|
285
|
+
<Alert severity="error">Could not load feature type ontology.</Alert>
|
|
286
|
+
</div>
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (graphical && table) {
|
|
291
|
+
const tabularHeight = tabularEditor.isShown ? detailsHeight : 0
|
|
292
|
+
const featureAreaHeight = isShown
|
|
293
|
+
? overallHeight - detailsHeight - accordionControlHeight * 2
|
|
294
|
+
: 0
|
|
295
|
+
return (
|
|
296
|
+
<div style={{ height: overallHeight }}>
|
|
297
|
+
<AccordionControl
|
|
298
|
+
open={isShown}
|
|
299
|
+
title="Graphical"
|
|
300
|
+
onClick={toggleShown}
|
|
301
|
+
/>
|
|
302
|
+
<div
|
|
303
|
+
className={classes.shading}
|
|
304
|
+
ref={canvasScrollContainerRef}
|
|
305
|
+
style={{ height: featureAreaHeight }}
|
|
306
|
+
>
|
|
307
|
+
<LinearApolloSixFrameDisplay model={model} {...other} />
|
|
308
|
+
</div>
|
|
309
|
+
<AccordionControl
|
|
310
|
+
title="Table"
|
|
311
|
+
open={tabularEditor.isShown}
|
|
312
|
+
onClick={tabularEditor.togglePane}
|
|
313
|
+
onResize={onDetailsResize}
|
|
314
|
+
/>
|
|
315
|
+
<div className={classes.details} style={{ height: tabularHeight }}>
|
|
316
|
+
<TabularEditorPane model={model} />
|
|
317
|
+
</div>
|
|
276
318
|
</div>
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (graphical) {
|
|
323
|
+
return (
|
|
324
|
+
<div
|
|
325
|
+
className={classes.shading}
|
|
326
|
+
ref={canvasScrollContainerRef}
|
|
327
|
+
style={{ height: overallHeight }}
|
|
328
|
+
>
|
|
329
|
+
<LinearApolloSixFrameDisplay model={model} {...other} />
|
|
282
330
|
</div>
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return (
|
|
335
|
+
<div className={classes.details} style={{ height: overallHeight }}>
|
|
336
|
+
<TabularEditorPane model={model} />
|
|
283
337
|
</div>
|
|
284
338
|
)
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
}
|
|
339
|
+
},
|
|
340
|
+
)
|
|
@@ -2,23 +2,27 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5
|
-
import { ClientDataStore as ClientDataStoreType } from '@apollo-annotation/common'
|
|
5
|
+
import { type ClientDataStore as ClientDataStoreType } from '@apollo-annotation/common'
|
|
6
6
|
import {
|
|
7
|
-
AnnotationFeatureModel,
|
|
8
|
-
AnnotationFeatureSnapshot,
|
|
7
|
+
type AnnotationFeatureModel,
|
|
8
|
+
type AnnotationFeatureSnapshot,
|
|
9
9
|
ApolloAssembly,
|
|
10
|
-
ApolloAssemblySnapshot,
|
|
10
|
+
type ApolloAssemblySnapshot,
|
|
11
11
|
ApolloRefSeq,
|
|
12
|
-
BackendDriverType,
|
|
12
|
+
type BackendDriverType,
|
|
13
13
|
CheckResult,
|
|
14
|
-
CheckResultSnapshot,
|
|
14
|
+
type CheckResultSnapshot,
|
|
15
15
|
} from '@apollo-annotation/mst'
|
|
16
16
|
import { getConf, readConfObject } from '@jbrowse/core/configuration'
|
|
17
|
-
import { ConfigurationModel } from '@jbrowse/core/configuration/types'
|
|
18
|
-
import { Region, getSession, isElectron } from '@jbrowse/core/util'
|
|
19
|
-
import { LocalPathLocation, UriLocation } from '@jbrowse/core/util/types/mst'
|
|
17
|
+
import { type ConfigurationModel } from '@jbrowse/core/configuration/types'
|
|
18
|
+
import { type Region, getSession, isElectron } from '@jbrowse/core/util'
|
|
20
19
|
import {
|
|
21
|
-
|
|
20
|
+
type LocalPathLocation,
|
|
21
|
+
type UriLocation,
|
|
22
|
+
} from '@jbrowse/core/util/types/mst'
|
|
23
|
+
import { autorun } from 'mobx'
|
|
24
|
+
import {
|
|
25
|
+
type Instance,
|
|
22
26
|
addDisposer,
|
|
23
27
|
flow,
|
|
24
28
|
getParentOfType,
|
|
@@ -28,21 +32,21 @@ import {
|
|
|
28
32
|
} from 'mobx-state-tree'
|
|
29
33
|
|
|
30
34
|
import {
|
|
31
|
-
ApolloInternetAccount,
|
|
35
|
+
type ApolloInternetAccount,
|
|
32
36
|
CollaborationServerDriver,
|
|
33
37
|
DesktopFileDriver,
|
|
34
38
|
InMemoryFileDriver,
|
|
35
39
|
} from '../BackendDrivers'
|
|
36
40
|
import { ChangeManager } from '../ChangeManager'
|
|
37
|
-
import ApolloPluginConfigurationSchema from '../config'
|
|
38
41
|
import {
|
|
39
42
|
OntologyManagerType,
|
|
40
|
-
OntologyRecordConfiguration,
|
|
41
|
-
TextIndexFieldDefinition,
|
|
43
|
+
type OntologyRecordConfiguration,
|
|
44
|
+
type TextIndexFieldDefinition,
|
|
42
45
|
} from '../OntologyManager'
|
|
43
|
-
import
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
+
import type ApolloPluginConfigurationSchema from '../config'
|
|
47
|
+
import { type ApolloRootModel } from '../types'
|
|
48
|
+
|
|
49
|
+
import { type ApolloSessionModel } from './session'
|
|
46
50
|
|
|
47
51
|
export function clientDataStoreFactory(
|
|
48
52
|
AnnotationFeatureExtended: typeof AnnotationFeatureModel,
|
package/src/session/session.ts
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
-
import { ClientDataStore as ClientDataStoreType } from '@apollo-annotation/common'
|
|
4
|
+
import { type ClientDataStore as ClientDataStoreType } from '@apollo-annotation/common'
|
|
5
5
|
import {
|
|
6
|
-
AnnotationFeature,
|
|
6
|
+
type AnnotationFeature,
|
|
7
7
|
AnnotationFeatureModel,
|
|
8
8
|
} from '@apollo-annotation/mst'
|
|
9
9
|
import {
|
|
10
|
-
filterJBrowseConfig,
|
|
11
10
|
ImportJBrowseConfigChange,
|
|
12
|
-
JBrowseConfig,
|
|
13
|
-
UserLocation,
|
|
11
|
+
type JBrowseConfig,
|
|
12
|
+
type UserLocation,
|
|
13
|
+
filterJBrowseConfig,
|
|
14
14
|
} from '@apollo-annotation/shared'
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
15
|
+
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
16
|
+
import { type AssemblyModel } from '@jbrowse/core/assemblyManager/assembly'
|
|
17
|
+
import { getConf, readConfObject } from '@jbrowse/core/configuration'
|
|
18
|
+
import { type BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes'
|
|
19
|
+
import {
|
|
20
|
+
type AbstractSessionModel,
|
|
21
|
+
type SessionWithAddTracks,
|
|
22
|
+
} from '@jbrowse/core/util'
|
|
23
|
+
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
20
24
|
import SaveIcon from '@mui/icons-material/Save'
|
|
21
25
|
import { autorun, observable } from 'mobx'
|
|
22
26
|
import {
|
|
23
|
-
Instance,
|
|
24
|
-
SnapshotOut,
|
|
27
|
+
type Instance,
|
|
28
|
+
type SnapshotOut,
|
|
25
29
|
applySnapshot,
|
|
26
30
|
flow,
|
|
27
31
|
getRoot,
|
|
@@ -29,13 +33,14 @@ import {
|
|
|
29
33
|
types,
|
|
30
34
|
} from 'mobx-state-tree'
|
|
31
35
|
|
|
32
|
-
import { ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
|
|
36
|
+
import { type ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
|
|
33
37
|
import { ApolloJobModel } from '../ApolloJobModel'
|
|
34
|
-
import { ChangeManager } from '../ChangeManager'
|
|
35
|
-
import
|
|
38
|
+
import { type ChangeManager } from '../ChangeManager'
|
|
39
|
+
import type ApolloPluginConfigurationSchema from '../config'
|
|
40
|
+
import { type ApolloRootModel } from '../types'
|
|
36
41
|
import { createFetchErrorMessage } from '../util'
|
|
42
|
+
|
|
37
43
|
import { clientDataStoreFactory } from './ClientDataStore'
|
|
38
|
-
import { AssemblyModel } from '@jbrowse/core/assemblyManager/assembly'
|
|
39
44
|
|
|
40
45
|
export interface ApolloSession extends AbstractSessionModel {
|
|
41
46
|
apolloDataStore: ClientDataStoreType & { changeManager: ChangeManager }
|
|
@@ -119,16 +124,6 @@ export function extendSession(
|
|
|
119
124
|
: {}),
|
|
120
125
|
},
|
|
121
126
|
},
|
|
122
|
-
displays: [
|
|
123
|
-
{
|
|
124
|
-
type: 'LinearApolloDisplay',
|
|
125
|
-
displayId: `${trackId}-LinearApolloDisplay`,
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
type: 'SixFrameFeatureDisplay',
|
|
129
|
-
displayId: `${trackId}-SixFrameFeatureDisplay`,
|
|
130
|
-
},
|
|
131
|
-
],
|
|
132
127
|
})
|
|
133
128
|
}
|
|
134
129
|
},
|
|
@@ -191,15 +186,6 @@ export function extendSession(
|
|
|
191
186
|
}))
|
|
192
187
|
.actions((self) => ({
|
|
193
188
|
afterCreate: flow(function* afterCreate() {
|
|
194
|
-
// When the initial config.json loads, it doesn't include the Apollo
|
|
195
|
-
// tracks, which would result in a potentially invalid session snapshot
|
|
196
|
-
// if any tracks are open. Here we copy the session snapshot, apply an
|
|
197
|
-
// empty session snapshot, and then restore the original session
|
|
198
|
-
// snapshot after the updated config.json loads.
|
|
199
|
-
const sessionSnapshot = getSnapshot(self)
|
|
200
|
-
const { id, name } = sessionSnapshot
|
|
201
|
-
applySnapshot(self, { name, id })
|
|
202
|
-
const { internetAccounts, jbrowse } = getRoot<ApolloRootModel>(self)
|
|
203
189
|
autorun(
|
|
204
190
|
() => {
|
|
205
191
|
// broadcastLocations() // **** This is not working and therefore we need to duplicate broadcastLocations() -method code here because autorun() does not observe changes otherwise
|
|
@@ -260,7 +246,29 @@ export function extendSession(
|
|
|
260
246
|
},
|
|
261
247
|
{ name: 'ApolloSession' },
|
|
262
248
|
)
|
|
263
|
-
//
|
|
249
|
+
// When the initial config.json loads, it doesn't include the Apollo
|
|
250
|
+
// tracks, which would result in a potentially invalid session snapshot
|
|
251
|
+
// if any tracks are open. Here we copy the session snapshot, apply an
|
|
252
|
+
// empty session snapshot, and then restore the original session
|
|
253
|
+
// snapshot after the updated config.json loads.
|
|
254
|
+
// @ts-expect-error type is missing on ApolloRootModel
|
|
255
|
+
const { internetAccounts, jbrowse, reloadPluginManagerCallback } =
|
|
256
|
+
getRoot<ApolloRootModel>(self)
|
|
257
|
+
const pluginConfiguration =
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
259
|
+
jbrowse.configuration.ApolloPlugin as Instance<
|
|
260
|
+
typeof ApolloPluginConfigurationSchema
|
|
261
|
+
>
|
|
262
|
+
const hasRole = readConfObject(
|
|
263
|
+
pluginConfiguration,
|
|
264
|
+
'hasRole',
|
|
265
|
+
) as boolean
|
|
266
|
+
if (hasRole) {
|
|
267
|
+
return
|
|
268
|
+
}
|
|
269
|
+
const sessionSnapshot = getSnapshot(self)
|
|
270
|
+
const { id, name } = sessionSnapshot
|
|
271
|
+
applySnapshot(self, { name, id })
|
|
264
272
|
|
|
265
273
|
// fetch and initialize assemblies for each of our Apollo internet accounts
|
|
266
274
|
for (const internetAccount of internetAccounts as ApolloInternetAccountModel[]) {
|
|
@@ -296,9 +304,8 @@ export function extendSession(
|
|
|
296
304
|
console.error(error)
|
|
297
305
|
continue
|
|
298
306
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
applySnapshot(self, sessionSnapshot)
|
|
307
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
308
|
+
reloadPluginManagerCallback(jbrowseConfig, sessionSnapshot)
|
|
302
309
|
}
|
|
303
310
|
}),
|
|
304
311
|
beforeDestroy() {
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseInternetAccountModel } from '@jbrowse/core/pluggableElementTypes'
|
|
2
|
-
import { AppRootModel } from '@jbrowse/core/util'
|
|
1
|
+
import { type BaseInternetAccountModel } from '@jbrowse/core/pluggableElementTypes'
|
|
2
|
+
import { type AppRootModel } from '@jbrowse/core/util'
|
|
3
3
|
|
|
4
|
-
import { ApolloInternetAccountModel } from './ApolloInternetAccount/model'
|
|
5
|
-
import { ApolloSessionModel } from './session'
|
|
4
|
+
import { type ApolloInternetAccountModel } from './ApolloInternetAccount/model'
|
|
5
|
+
import { type ApolloSessionModel } from './session'
|
|
6
6
|
|
|
7
7
|
export interface ApolloRootModel extends Omit<AppRootModel, 'session'> {
|
|
8
8
|
session: ApolloSessionModel
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
1
|
+
import { type AnnotationFeature } from '@apollo-annotation/mst'
|
|
2
|
+
|
|
3
|
+
import { type MousePosition } from '../LinearApolloDisplay/stateModel/mouseEvents'
|
|
2
4
|
|
|
3
5
|
export function getFeatureName(feature: AnnotationFeature) {
|
|
4
6
|
const { attributes } = feature
|
|
@@ -51,3 +53,66 @@ export function getStrand(strand: number | undefined) {
|
|
|
51
53
|
}
|
|
52
54
|
return ''
|
|
53
55
|
}
|
|
56
|
+
|
|
57
|
+
function getChildren(feature: AnnotationFeature): AnnotationFeature[] {
|
|
58
|
+
const children: AnnotationFeature[] = []
|
|
59
|
+
//
|
|
60
|
+
if (feature.children) {
|
|
61
|
+
for (const [, ff] of feature.children) {
|
|
62
|
+
children.push(ff)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return children
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getParents(feature: AnnotationFeature): AnnotationFeature[] {
|
|
69
|
+
const parents: AnnotationFeature[] = []
|
|
70
|
+
let { parent } = feature
|
|
71
|
+
while (parent) {
|
|
72
|
+
parents.push(parent)
|
|
73
|
+
;({ parent } = parent)
|
|
74
|
+
}
|
|
75
|
+
return parents
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function getFeaturesUnderClick(
|
|
79
|
+
mousePosition: MousePosition,
|
|
80
|
+
includeSiblings = false,
|
|
81
|
+
): AnnotationFeature[] {
|
|
82
|
+
const clickedFeatures: AnnotationFeature[] = []
|
|
83
|
+
if (!mousePosition.featureAndGlyphUnderMouse) {
|
|
84
|
+
return clickedFeatures
|
|
85
|
+
}
|
|
86
|
+
clickedFeatures.push(mousePosition.featureAndGlyphUnderMouse.feature)
|
|
87
|
+
for (const x of getParents(mousePosition.featureAndGlyphUnderMouse.feature)) {
|
|
88
|
+
clickedFeatures.push(x)
|
|
89
|
+
}
|
|
90
|
+
const { bp } = mousePosition
|
|
91
|
+
const children = getChildren(mousePosition.featureAndGlyphUnderMouse.feature)
|
|
92
|
+
for (const child of children) {
|
|
93
|
+
if (child.min < bp && child.max >= bp) {
|
|
94
|
+
clickedFeatures.push(child)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!includeSiblings) {
|
|
98
|
+
return clickedFeatures
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Also add siblings , i.e. features having the same parent as the clicked
|
|
102
|
+
// one and intersecting the click position
|
|
103
|
+
if (mousePosition.featureAndGlyphUnderMouse.feature.parent) {
|
|
104
|
+
const siblings =
|
|
105
|
+
mousePosition.featureAndGlyphUnderMouse.feature.parent.children
|
|
106
|
+
if (siblings) {
|
|
107
|
+
for (const [, sib] of siblings) {
|
|
108
|
+
if (sib._id == mousePosition.featureAndGlyphUnderMouse.feature._id) {
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
if (sib.min < bp && sib.max >= bp) {
|
|
112
|
+
clickedFeatures.push(sib)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return clickedFeatures
|
|
118
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export async function copyToClipboard(element: HTMLElement) {
|
|
2
|
+
if (isSecureContext) {
|
|
3
|
+
const textBlob = new Blob([element.outerText], { type: 'text/plain' })
|
|
4
|
+
const htmlBlob = new Blob([element.outerHTML], { type: 'text/html' })
|
|
5
|
+
const clipboardItem = new ClipboardItem({
|
|
6
|
+
[textBlob.type]: textBlob,
|
|
7
|
+
[htmlBlob.type]: htmlBlob,
|
|
8
|
+
})
|
|
9
|
+
return navigator.clipboard.write([clipboardItem])
|
|
10
|
+
}
|
|
11
|
+
const copyCallback = (event: ClipboardEvent) => {
|
|
12
|
+
event.clipboardData?.setData('text/plain', element.outerText)
|
|
13
|
+
event.clipboardData?.setData('text/html', element.outerHTML)
|
|
14
|
+
event.preventDefault()
|
|
15
|
+
}
|
|
16
|
+
document.addEventListener('copy', copyCallback)
|
|
17
|
+
// fall back to deprecated only in non-secure contexts
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
19
|
+
document.execCommand('copy')
|
|
20
|
+
document.removeEventListener('copy', copyCallback)
|
|
21
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AnnotationFeature,
|
|
3
|
+
type TranscriptPartCoding,
|
|
4
|
+
} from '@apollo-annotation/mst'
|
|
5
|
+
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
6
|
+
|
|
7
|
+
export function getMinAndMaxPx(
|
|
8
|
+
feature: AnnotationFeature | TranscriptPartCoding,
|
|
9
|
+
refName: string,
|
|
10
|
+
regionNumber: number,
|
|
11
|
+
lgv: LinearGenomeViewModel,
|
|
12
|
+
): [number, number] | undefined {
|
|
13
|
+
const minPxInfo = lgv.bpToPx({
|
|
14
|
+
refName,
|
|
15
|
+
coord: feature.min,
|
|
16
|
+
regionNumber,
|
|
17
|
+
})
|
|
18
|
+
const maxPxInfo = lgv.bpToPx({
|
|
19
|
+
refName,
|
|
20
|
+
coord: feature.max,
|
|
21
|
+
regionNumber,
|
|
22
|
+
})
|
|
23
|
+
if (minPxInfo === undefined || maxPxInfo === undefined) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
const { offsetPx } = lgv
|
|
27
|
+
const minPx = minPxInfo.offsetPx - offsetPx
|
|
28
|
+
const maxPx = maxPxInfo.offsetPx - offsetPx
|
|
29
|
+
return [minPx, maxPx]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getOverlappingEdge(
|
|
33
|
+
feature: AnnotationFeature,
|
|
34
|
+
x: number,
|
|
35
|
+
minMax: [number, number],
|
|
36
|
+
): { feature: AnnotationFeature; edge: 'min' | 'max' } | undefined {
|
|
37
|
+
const [minPx, maxPx] = minMax
|
|
38
|
+
// Feature is too small to tell if we're overlapping an edge
|
|
39
|
+
if (Math.abs(maxPx - minPx) < 8) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if (Math.abs(minPx - x) < 4) {
|
|
43
|
+
return { feature, edge: 'min' }
|
|
44
|
+
}
|
|
45
|
+
if (Math.abs(maxPx - x) < 4) {
|
|
46
|
+
return { feature, edge: 'max' }
|
|
47
|
+
}
|
|
48
|
+
return
|
|
49
|
+
}
|
package/src/util/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getParent } from 'mobx-state-tree'
|
|
2
2
|
|
|
3
|
-
import { ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
|
|
4
|
-
import { ApolloSessionModel } from '../session'
|
|
5
|
-
import { ApolloRootModel } from '../types'
|
|
3
|
+
import { type ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
|
|
4
|
+
import { type ApolloSessionModel } from '../session'
|
|
5
|
+
import { type ApolloRootModel } from '../types'
|
|
6
6
|
|
|
7
7
|
export async function createFetchErrorMessage(
|
|
8
8
|
response: Response,
|
|
@@ -30,3 +30,5 @@ export function getApolloInternetAccount(session: ApolloSessionModel) {
|
|
|
30
30
|
|
|
31
31
|
export * from './loadAssemblyIntoClient'
|
|
32
32
|
export * from './annotationFeatureUtils'
|
|
33
|
+
export * from './glyphUtils'
|
|
34
|
+
export * from './mouseEventsUtils'
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import { ClientDataStore, checkRegistry } from '@apollo-annotation/common'
|
|
2
|
-
import {
|
|
1
|
+
import { type ClientDataStore, checkRegistry } from '@apollo-annotation/common'
|
|
2
|
+
import {
|
|
3
|
+
type ApolloAssemblyI,
|
|
4
|
+
type CheckResultSnapshot,
|
|
5
|
+
} from '@apollo-annotation/mst'
|
|
3
6
|
import { gff3ToAnnotationFeature } from '@apollo-annotation/shared'
|
|
4
|
-
import gff, {
|
|
7
|
+
import gff, {
|
|
8
|
+
type GFF3Comment,
|
|
9
|
+
type GFF3Feature,
|
|
10
|
+
type GFF3Sequence,
|
|
11
|
+
} from '@gmod/gff'
|
|
5
12
|
import { getSnapshot } from 'mobx-state-tree'
|
|
6
13
|
|
|
7
14
|
export async function loadAssemblyIntoClient(
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { type AnnotationFeature } from '@apollo-annotation/mst'
|
|
2
|
+
|
|
3
|
+
type MinEdge = 'min'
|
|
4
|
+
type MaxEdge = 'max'
|
|
5
|
+
export type Edge = MinEdge | MaxEdge
|
|
6
|
+
|
|
7
|
+
interface LocationChange {
|
|
8
|
+
featureId: string
|
|
9
|
+
oldLocation: number
|
|
10
|
+
newLocation: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function expandFeatures(
|
|
14
|
+
feature: AnnotationFeature,
|
|
15
|
+
newLocation: number,
|
|
16
|
+
edge: Edge,
|
|
17
|
+
): LocationChange[] {
|
|
18
|
+
const featureId = feature._id
|
|
19
|
+
const oldLocation = feature[edge]
|
|
20
|
+
const changes: LocationChange[] = [{ featureId, oldLocation, newLocation }]
|
|
21
|
+
const { parent } = feature
|
|
22
|
+
if (
|
|
23
|
+
parent &&
|
|
24
|
+
((edge === 'min' && parent[edge] > newLocation) ||
|
|
25
|
+
(edge === 'max' && parent[edge] < newLocation))
|
|
26
|
+
) {
|
|
27
|
+
changes.push(...expandFeatures(parent, newLocation, edge))
|
|
28
|
+
}
|
|
29
|
+
return changes
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function shrinkFeatures(
|
|
33
|
+
feature: AnnotationFeature,
|
|
34
|
+
newLocation: number,
|
|
35
|
+
edge: Edge,
|
|
36
|
+
shrinkParent: boolean,
|
|
37
|
+
childIdToSkip?: string,
|
|
38
|
+
): LocationChange[] {
|
|
39
|
+
const featureId = feature._id
|
|
40
|
+
const oldLocation = feature[edge]
|
|
41
|
+
const changes: LocationChange[] = [{ featureId, oldLocation, newLocation }]
|
|
42
|
+
const { parent, children } = feature
|
|
43
|
+
if (children) {
|
|
44
|
+
for (const [, child] of children) {
|
|
45
|
+
if (child._id === childIdToSkip) {
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
if (
|
|
49
|
+
(edge === 'min' && child[edge] < newLocation) ||
|
|
50
|
+
(edge === 'max' && child[edge] > newLocation)
|
|
51
|
+
) {
|
|
52
|
+
changes.push(...shrinkFeatures(child, newLocation, edge, shrinkParent))
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (parent && shrinkParent) {
|
|
57
|
+
const siblings: AnnotationFeature[] = []
|
|
58
|
+
if (parent.children) {
|
|
59
|
+
for (const [, c] of parent.children) {
|
|
60
|
+
if (c._id === featureId) {
|
|
61
|
+
continue
|
|
62
|
+
}
|
|
63
|
+
siblings.push(c)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (siblings.length === 0) {
|
|
67
|
+
changes.push(
|
|
68
|
+
...shrinkFeatures(parent, newLocation, edge, shrinkParent, featureId),
|
|
69
|
+
)
|
|
70
|
+
} else {
|
|
71
|
+
const oldLocation = parent[edge]
|
|
72
|
+
const boundedLocation = Math[edge](
|
|
73
|
+
...siblings.map((s) => s[edge]),
|
|
74
|
+
newLocation,
|
|
75
|
+
)
|
|
76
|
+
if (boundedLocation !== oldLocation) {
|
|
77
|
+
changes.push(
|
|
78
|
+
...shrinkFeatures(
|
|
79
|
+
parent,
|
|
80
|
+
boundedLocation,
|
|
81
|
+
edge,
|
|
82
|
+
shrinkParent,
|
|
83
|
+
featureId,
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return changes
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function getPropagatedLocationChanges(
|
|
93
|
+
feature: AnnotationFeature,
|
|
94
|
+
newLocation: number,
|
|
95
|
+
edge: Edge,
|
|
96
|
+
shrinkParent = false,
|
|
97
|
+
): LocationChange[] {
|
|
98
|
+
const oldLocation = feature[edge]
|
|
99
|
+
if (newLocation === oldLocation) {
|
|
100
|
+
throw new Error(`New and existing locations are the same: "${newLocation}"`)
|
|
101
|
+
}
|
|
102
|
+
if (edge === 'min') {
|
|
103
|
+
if (newLocation > oldLocation) {
|
|
104
|
+
// shrinking feature, may need to shrink children and/or parents
|
|
105
|
+
return shrinkFeatures(feature, newLocation, edge, shrinkParent)
|
|
106
|
+
}
|
|
107
|
+
return expandFeatures(feature, newLocation, edge)
|
|
108
|
+
}
|
|
109
|
+
if (newLocation < oldLocation) {
|
|
110
|
+
return shrinkFeatures(feature, newLocation, edge, shrinkParent)
|
|
111
|
+
}
|
|
112
|
+
return expandFeatures(feature, newLocation, edge)
|
|
113
|
+
}
|