@apollo-annotation/jbrowse-plugin-apollo 0.3.12 → 1.0.0
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/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts +1 -1
- package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts.map +1 -1
- package/dist/BackendDrivers/BackendDriver.d.ts +29 -4
- package/dist/BackendDrivers/BackendDriver.d.ts.map +1 -1
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts +3 -1
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts.map +1 -1
- package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts +22 -0
- package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts.map +1 -0
- package/dist/BackendDrivers/LocalDriver/db.d.ts +4 -0
- package/dist/BackendDrivers/LocalDriver/db.d.ts.map +1 -0
- package/dist/BackendDrivers/index.d.ts +1 -2
- package/dist/BackendDrivers/index.d.ts.map +1 -1
- package/dist/ChangeManager.d.ts +3 -3
- package/dist/ChangeManager.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts +0 -6
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/model.d.ts +0 -2
- package/dist/FeatureDetailsWidget/model.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/components/OverlayCanvas.d.ts +7 -0
- package/dist/LinearApolloDisplay/components/OverlayCanvas.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/components/Tooltip.d.ts +10 -0
- package/dist/LinearApolloDisplay/components/Tooltip.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts +0 -1
- package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/CDSGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/CDSGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts +26 -20
- package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/util.d.ts +13 -0
- package/dist/LinearApolloDisplay/glyphs/util.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/base.d.ts +17 -0
- package/dist/LinearApolloDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/index.d.ts +35 -17
- package/dist/LinearApolloDisplay/stateModel/index.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts +29 -7
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts +69 -23
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts +26 -9
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts +1 -1
- package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts +1 -1
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/index.d.ts +2 -2
- package/dist/OntologyManager/OntologyStore/index.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts +1 -1
- package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/types.d.ts +18 -0
- package/dist/OntologyManager/OntologyStore/types.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts.map +1 -1
- package/dist/components/AddChildFeature.d.ts.map +1 -1
- package/dist/components/ColorFeature.d.ts +13 -0
- package/dist/components/ColorFeature.d.ts.map +1 -0
- package/dist/components/CreateApolloAnnotation.d.ts.map +1 -1
- package/dist/components/DownloadGFF3.d.ts +4 -1
- package/dist/components/DownloadGFF3.d.ts.map +1 -1
- package/dist/components/DuplicateTranscript.d.ts.map +1 -1
- package/dist/components/ViewChangeLog.d.ts +2 -1
- package/dist/components/ViewChangeLog.d.ts.map +1 -1
- package/dist/components/ViewCheckResults.d.ts +2 -1
- package/dist/components/ViewCheckResults.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/extensions/annotationFromJBrowseFeature.d.ts.map +1 -1
- package/dist/extensions/annotationFromPileup.d.ts.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +6325 -5997
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +5869 -5541
- 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 +16782 -25897
- 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/dist/makeDisplayComponent.d.ts.map +1 -1
- package/dist/menus/Icons.d.ts +3 -0
- package/dist/menus/Icons.d.ts.map +1 -0
- package/dist/menus/topLevelMenu.d.ts.map +1 -1
- package/dist/session/changeHandlers.d.ts +9 -0
- package/dist/session/changeHandlers.d.ts.map +1 -0
- package/dist/util/annotationFeatureUtils.d.ts +2 -1
- package/dist/util/annotationFeatureUtils.d.ts.map +1 -1
- package/dist/util/glyphUtils.d.ts +3 -3
- package/dist/util/glyphUtils.d.ts.map +1 -1
- package/dist/util/index.d.ts +0 -1
- package/dist/util/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ApolloInternetAccount/model.ts +68 -4
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +6 -3
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +1 -1
- package/src/BackendDrivers/BackendDriver.ts +36 -3
- package/src/BackendDrivers/CollaborationServerDriver.ts +78 -23
- package/src/BackendDrivers/LocalDriver/LocalDriver.ts +367 -0
- package/src/BackendDrivers/LocalDriver/db.ts +37 -0
- package/src/BackendDrivers/index.ts +1 -2
- package/src/ChangeManager.ts +27 -25
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +1 -1
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +69 -53
- package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +1 -5
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +95 -115
- package/src/LinearApolloDisplay/components/OverlayCanvas.tsx +76 -0
- package/src/LinearApolloDisplay/components/Tooltip.tsx +42 -0
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +60 -302
- package/src/LinearApolloDisplay/glyphs/CDSGlyph.ts +145 -0
- package/src/LinearApolloDisplay/glyphs/ExonGlyph.ts +212 -0
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +65 -999
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +71 -181
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +42 -66
- package/src/LinearApolloDisplay/glyphs/TranscriptGlyph.ts +291 -0
- package/src/LinearApolloDisplay/glyphs/util.ts +87 -0
- package/src/LinearApolloDisplay/stateModel/base.ts +83 -0
- package/src/LinearApolloDisplay/stateModel/layouts.ts +198 -138
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +252 -158
- package/src/LinearApolloDisplay/stateModel/rendering.ts +103 -21
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +3 -3
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +20 -2
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +7 -2
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +8 -13
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +1 -1
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +4 -3
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +1 -1
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +2 -1
- package/src/OntologyManager/OntologyStore/__snapshots__/index.test.ts.snap +18262 -8519
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -2
- package/src/OntologyManager/OntologyStore/index.test.ts +5 -2
- package/src/OntologyManager/OntologyStore/index.ts +7 -8
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +2 -2
- package/src/OntologyManager/OntologyStore/types.ts +27 -0
- package/src/OntologyManager/index.ts +15 -26
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +4 -5
- package/src/components/AddChildFeature.tsx +15 -8
- package/src/components/ColorFeature.tsx +167 -0
- package/src/components/CreateApolloAnnotation.tsx +35 -9
- package/src/components/DownloadGFF3.tsx +92 -121
- package/src/components/DuplicateTranscript.tsx +10 -0
- package/src/components/ViewChangeLog.tsx +123 -83
- package/src/components/ViewCheckResults.tsx +15 -73
- package/src/components/index.ts +1 -1
- package/src/config.ts +37 -19
- package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -1
- package/src/extensions/annotationFromJBrowseFeature.ts +91 -63
- package/src/extensions/annotationFromPileup.ts +40 -40
- package/src/index.ts +45 -1
- package/src/makeDisplayComponent.tsx +10 -3
- package/src/menus/Icons.tsx +49 -0
- package/src/menus/topLevelMenu.ts +24 -96
- package/src/session/ClientDataStore.ts +16 -17
- package/src/session/changeHandlers.ts +261 -0
- package/src/session/session.ts +77 -46
- package/src/util/annotationFeatureUtils.ts +29 -1
- package/src/util/glyphUtils.ts +74 -31
- package/src/util/index.ts +0 -1
- package/dist/BackendDrivers/DesktopFileDriver.d.ts +0 -160
- package/dist/BackendDrivers/DesktopFileDriver.d.ts.map +0 -1
- package/dist/BackendDrivers/InMemoryFileDriver.d.ts +0 -162
- package/dist/BackendDrivers/InMemoryFileDriver.d.ts.map +0 -1
- package/dist/LinearApolloDisplay/glyphs/index.d.ts +0 -4
- package/dist/LinearApolloDisplay/glyphs/index.d.ts.map +0 -1
- package/dist/components/OpenLocalFile.d.ts +0 -15
- package/dist/components/OpenLocalFile.d.ts.map +0 -1
- package/dist/util/loadAssemblyIntoClient.d.ts +0 -5
- package/dist/util/loadAssemblyIntoClient.d.ts.map +0 -1
- package/src/BackendDrivers/DesktopFileDriver.ts +0 -184
- package/src/BackendDrivers/InMemoryFileDriver.ts +0 -107
- package/src/LinearApolloDisplay/glyphs/index.ts +0 -3
- package/src/components/OpenLocalFile.tsx +0 -189
- package/src/util/loadAssemblyIntoClient.ts +0 -94
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
5
3
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
6
|
-
import type { ApolloAssembly } from '@apollo-annotation/mst'
|
|
7
4
|
import { annotationFeatureToGFF3 } from '@apollo-annotation/shared'
|
|
8
|
-
import {
|
|
9
|
-
import type { Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
5
|
+
import { GFFFormattingTransformer } from '@gmod/gff'
|
|
10
6
|
import { getConf } from '@jbrowse/core/configuration'
|
|
11
|
-
import
|
|
7
|
+
import type { AbstractSessionModel } from '@jbrowse/core/util'
|
|
12
8
|
import {
|
|
13
9
|
Button,
|
|
14
10
|
Checkbox,
|
|
@@ -17,9 +13,8 @@ import {
|
|
|
17
13
|
DialogContentText,
|
|
18
14
|
FormControlLabel,
|
|
19
15
|
FormGroup,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
type SelectChangeEvent,
|
|
16
|
+
SvgIcon,
|
|
17
|
+
type SvgIconProps,
|
|
23
18
|
} from '@mui/material'
|
|
24
19
|
import { saveAs } from 'file-saver'
|
|
25
20
|
import React, { useState } from 'react'
|
|
@@ -27,8 +22,8 @@ import React, { useState } from 'react'
|
|
|
27
22
|
import type {
|
|
28
23
|
ApolloInternetAccount,
|
|
29
24
|
CollaborationServerDriver,
|
|
30
|
-
InMemoryFileDriver,
|
|
31
25
|
} from '../BackendDrivers'
|
|
26
|
+
import { openDb } from '../BackendDrivers/LocalDriver/db'
|
|
32
27
|
import type { ApolloSessionModel } from '../session'
|
|
33
28
|
import { createFetchErrorMessage } from '../util'
|
|
34
29
|
|
|
@@ -37,67 +32,65 @@ import { Dialog } from './Dialog'
|
|
|
37
32
|
interface DownloadGFF3Props {
|
|
38
33
|
session: ApolloSessionModel
|
|
39
34
|
handleClose(): void
|
|
35
|
+
assembly: string
|
|
40
36
|
}
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
// Icon source: https://pictogrammers.com/library/mdi/icon/export/
|
|
39
|
+
export function Export(props: SvgIconProps) {
|
|
40
|
+
return (
|
|
41
|
+
<SvgIcon viewBox="0 0 24 24" {...props}>
|
|
42
|
+
<path d="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
|
|
43
|
+
</SvgIcon>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function DownloadGFF3({
|
|
48
|
+
handleClose,
|
|
49
|
+
session,
|
|
50
|
+
assembly: assemblyName,
|
|
51
|
+
}: DownloadGFF3Props) {
|
|
43
52
|
const [includeFASTA, setincludeFASTA] = useState(false)
|
|
44
|
-
const [selectedAssembly, setSelectedAssembly] = useState<Assembly>()
|
|
45
53
|
const [errorMessage, setErrorMessage] = useState('')
|
|
46
54
|
|
|
47
|
-
const {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
internetAccountId?: string,
|
|
54
|
-
): ApolloInternetAccount
|
|
55
|
-
}
|
|
56
|
-
const assemblies = [
|
|
57
|
-
...collaborationServerDriver.getAssemblies(),
|
|
58
|
-
...inMemoryFileDriver.getAssemblies(),
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
function handleChangeAssembly(e: SelectChangeEvent) {
|
|
62
|
-
const newAssembly = assemblies.find((asm) => asm.name === e.target.value)
|
|
63
|
-
setSelectedAssembly(newAssembly)
|
|
55
|
+
const { getInternetAccount } = session.apolloDataStore as {
|
|
56
|
+
collaborationServerDriver: CollaborationServerDriver
|
|
57
|
+
getInternetAccount(
|
|
58
|
+
assemblyName?: string,
|
|
59
|
+
internetAccountId?: string,
|
|
60
|
+
): ApolloInternetAccount
|
|
64
61
|
}
|
|
65
62
|
|
|
63
|
+
const { assemblyManager } = session as unknown as AbstractSessionModel
|
|
64
|
+
const assembly = assemblyManager.get(assemblyName)
|
|
65
|
+
if (!assembly) {
|
|
66
|
+
setErrorMessage(`Assembly "${assemblyName}" not found`)
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const { internetAccountConfigId } = getConf(assembly, [
|
|
71
|
+
'sequence',
|
|
72
|
+
'metadata',
|
|
73
|
+
]) as { internetAccountConfigId?: string }
|
|
74
|
+
|
|
66
75
|
async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
|
|
67
76
|
event.preventDefault()
|
|
68
77
|
setErrorMessage('')
|
|
69
|
-
if (!selectedAssembly) {
|
|
70
|
-
setErrorMessage('Must select assembly to download')
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
]) as { internetAccountConfigId?: string }
|
|
78
|
-
if (internetAccountConfigId) {
|
|
79
|
-
await exportFromCollaborationServer(internetAccountConfigId)
|
|
80
|
-
} else {
|
|
81
|
-
exportFromMemory(session)
|
|
82
|
-
}
|
|
79
|
+
await (internetAccountConfigId
|
|
80
|
+
? exportFromCollaborationServer(internetAccountConfigId)
|
|
81
|
+
: downloadAssemblyGFF3(assemblyName))
|
|
83
82
|
handleClose()
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
async function exportFromCollaborationServer(
|
|
87
86
|
internetAccountConfigId: string,
|
|
88
87
|
) {
|
|
89
|
-
if (!selectedAssembly) {
|
|
90
|
-
setErrorMessage('Must select assembly to download')
|
|
91
|
-
return
|
|
92
|
-
}
|
|
93
88
|
const internetAccount = getInternetAccount(
|
|
94
|
-
|
|
89
|
+
assemblyName,
|
|
95
90
|
internetAccountConfigId,
|
|
96
91
|
)
|
|
97
92
|
const url = new URL('export/getID', internetAccount.baseURL)
|
|
98
|
-
const searchParams = new URLSearchParams({
|
|
99
|
-
assembly: selectedAssembly.name,
|
|
100
|
-
})
|
|
93
|
+
const searchParams = new URLSearchParams({ assembly: assemblyName })
|
|
101
94
|
url.search = searchParams.toString()
|
|
102
95
|
const uri = url.toString()
|
|
103
96
|
const apolloFetch = internetAccount.getFetcher({
|
|
@@ -127,83 +120,19 @@ export function DownloadGFF3({ handleClose, session }: DownloadGFF3Props) {
|
|
|
127
120
|
window.open(exportUri, '_blank')
|
|
128
121
|
}
|
|
129
122
|
|
|
130
|
-
function exportFromMemory(session: ApolloSessionModel) {
|
|
131
|
-
if (!selectedAssembly) {
|
|
132
|
-
setErrorMessage('Must select assembly to download')
|
|
133
|
-
return
|
|
134
|
-
}
|
|
135
|
-
const { assemblies } = session.apolloDataStore as {
|
|
136
|
-
assemblies: IMSTMap<typeof ApolloAssembly>
|
|
137
|
-
}
|
|
138
|
-
const assembly = assemblies.get(selectedAssembly.name)
|
|
139
|
-
const refSeqs = assembly?.refSeqs
|
|
140
|
-
if (!refSeqs) {
|
|
141
|
-
setErrorMessage(
|
|
142
|
-
`No refSeqs found for assembly "${selectedAssembly.name}"`,
|
|
143
|
-
)
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
const gff3Items: GFF3Item[] = [{ directive: 'gff-version', value: '3' }]
|
|
147
|
-
const sequenceFeatures = getConf(selectedAssembly, [
|
|
148
|
-
'sequence',
|
|
149
|
-
'adapter',
|
|
150
|
-
'features',
|
|
151
|
-
]) as { refName: string; start: number; end: number; seq: string }[]
|
|
152
|
-
for (const sequenceFeature of sequenceFeatures) {
|
|
153
|
-
const { end, refName, start } = sequenceFeature
|
|
154
|
-
gff3Items.push({
|
|
155
|
-
directive: 'sequence-region',
|
|
156
|
-
value: `${refName} ${start + 1} ${end}`,
|
|
157
|
-
})
|
|
158
|
-
}
|
|
159
|
-
for (const [, refSeq] of refSeqs) {
|
|
160
|
-
const { features } = refSeq
|
|
161
|
-
if (!features) {
|
|
162
|
-
continue
|
|
163
|
-
}
|
|
164
|
-
for (const [, feature] of features) {
|
|
165
|
-
gff3Items.push(annotationFeatureToGFF3(getSnapshot(feature)))
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
for (const sequenceFeature of sequenceFeatures) {
|
|
169
|
-
const { refName, seq } = sequenceFeature
|
|
170
|
-
gff3Items.push({ id: refName, description: '', sequence: seq })
|
|
171
|
-
}
|
|
172
|
-
const gff3 = formatSync(gff3Items)
|
|
173
|
-
const gff3Blob = new Blob([gff3], { type: 'text/plain;charset=utf-8' })
|
|
174
|
-
saveAs(
|
|
175
|
-
gff3Blob,
|
|
176
|
-
`${selectedAssembly.displayName ?? selectedAssembly.name}.gff3`,
|
|
177
|
-
)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
123
|
return (
|
|
181
124
|
<Dialog
|
|
182
125
|
open
|
|
183
|
-
title="Export
|
|
126
|
+
title="Export annotations"
|
|
184
127
|
handleClose={handleClose}
|
|
185
128
|
maxWidth={false}
|
|
186
129
|
data-testid="download-gff3"
|
|
187
130
|
>
|
|
188
131
|
<form onSubmit={onSubmit}>
|
|
189
132
|
<DialogContent style={{ display: 'flex', flexDirection: 'column' }}>
|
|
190
|
-
<DialogContentText>Select assembly</DialogContentText>
|
|
191
|
-
<Select
|
|
192
|
-
labelId="label"
|
|
193
|
-
value={selectedAssembly?.name ?? ''}
|
|
194
|
-
onChange={handleChangeAssembly}
|
|
195
|
-
disabled={assemblies.length === 0}
|
|
196
|
-
>
|
|
197
|
-
{assemblies.map((option) => (
|
|
198
|
-
<MenuItem key={option.name} value={option.name}>
|
|
199
|
-
{option.displayName ?? option.name}
|
|
200
|
-
</MenuItem>
|
|
201
|
-
))}
|
|
202
|
-
</Select>
|
|
203
133
|
<DialogContentText>
|
|
204
|
-
|
|
134
|
+
Exporting annotations for {assemblyName}
|
|
205
135
|
</DialogContentText>
|
|
206
|
-
|
|
207
136
|
<FormGroup>
|
|
208
137
|
<FormControlLabel
|
|
209
138
|
data-testid="include-fasta-checkbox"
|
|
@@ -213,6 +142,7 @@ export function DownloadGFF3({ handleClose, session }: DownloadGFF3Props) {
|
|
|
213
142
|
onChange={() => {
|
|
214
143
|
setincludeFASTA(!includeFASTA)
|
|
215
144
|
}}
|
|
145
|
+
disabled={!internetAccountConfigId}
|
|
216
146
|
/>
|
|
217
147
|
}
|
|
218
148
|
label="Include fasta sequence in GFF output"
|
|
@@ -220,11 +150,7 @@ export function DownloadGFF3({ handleClose, session }: DownloadGFF3Props) {
|
|
|
220
150
|
</FormGroup>
|
|
221
151
|
</DialogContent>
|
|
222
152
|
<DialogActions>
|
|
223
|
-
<Button
|
|
224
|
-
disabled={!selectedAssembly}
|
|
225
|
-
variant="contained"
|
|
226
|
-
type="submit"
|
|
227
|
-
>
|
|
153
|
+
<Button variant="contained" type="submit">
|
|
228
154
|
Download
|
|
229
155
|
</Button>
|
|
230
156
|
<Button variant="outlined" type="submit" onClick={handleClose}>
|
|
@@ -240,3 +166,48 @@ export function DownloadGFF3({ handleClose, session }: DownloadGFF3Props) {
|
|
|
240
166
|
</Dialog>
|
|
241
167
|
)
|
|
242
168
|
}
|
|
169
|
+
|
|
170
|
+
function getAssemblyGFF3Stream(assemblyName: string): ReadableStream<string> {
|
|
171
|
+
const featureStream = new ReadableStream({
|
|
172
|
+
async start(controller) {
|
|
173
|
+
for await (const feature of getFeaturesForAssembly(assemblyName)) {
|
|
174
|
+
const gff3Feature = annotationFeatureToGFF3(feature)
|
|
175
|
+
controller.enqueue(gff3Feature)
|
|
176
|
+
}
|
|
177
|
+
controller.close()
|
|
178
|
+
},
|
|
179
|
+
})
|
|
180
|
+
return featureStream.pipeThrough(
|
|
181
|
+
new TransformStream(new GFFFormattingTransformer()),
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function downloadAssemblyGFF3(assemblyName: string) {
|
|
186
|
+
const stream = getAssemblyGFF3Stream(assemblyName)
|
|
187
|
+
const fileName = `${assemblyName}.gff3`
|
|
188
|
+
try {
|
|
189
|
+
const handle = await (
|
|
190
|
+
globalThis as unknown as {
|
|
191
|
+
showSaveFilePicker: (opts: {
|
|
192
|
+
suggestedName: string
|
|
193
|
+
}) => Promise<FileSystemFileHandle>
|
|
194
|
+
}
|
|
195
|
+
).showSaveFilePicker({ suggestedName: fileName })
|
|
196
|
+
const writable = await handle.createWritable()
|
|
197
|
+
await stream.pipeTo(writable)
|
|
198
|
+
} catch {
|
|
199
|
+
const blob = await new Response(stream).blob()
|
|
200
|
+
saveAs(blob, fileName)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function* getFeaturesForAssembly(assemblyName: string) {
|
|
205
|
+
const db = await openDb(assemblyName, [])
|
|
206
|
+
for (const storeName of db.objectStoreNames) {
|
|
207
|
+
const tx = db.transaction(storeName)
|
|
208
|
+
for await (const cursor of tx.store.iterate()) {
|
|
209
|
+
yield cursor.value
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
db.close()
|
|
213
|
+
}
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
AnnotationFeatureSnapshot,
|
|
5
5
|
} from '@apollo-annotation/mst'
|
|
6
6
|
import { AddFeatureChange } from '@apollo-annotation/shared'
|
|
7
|
+
import { readConfObject } from '@jbrowse/core/configuration'
|
|
7
8
|
import type { AbstractSessionModel } from '@jbrowse/core/util/types'
|
|
8
9
|
import { getSnapshot } from '@jbrowse/mobx-state-tree'
|
|
9
10
|
import {
|
|
@@ -17,6 +18,7 @@ import React, { useState } from 'react'
|
|
|
17
18
|
|
|
18
19
|
import type { ChangeManager } from '../ChangeManager'
|
|
19
20
|
import type { ApolloSessionModel } from '../session'
|
|
21
|
+
import { removeSkippedAttributes } from '../util'
|
|
20
22
|
|
|
21
23
|
import { Dialog } from './Dialog'
|
|
22
24
|
|
|
@@ -71,6 +73,14 @@ export function DuplicateTranscript({
|
|
|
71
73
|
duplicateTranscript.children = newChildren
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
// skip attributes that are configured (SKIPPED_ATTRIBUTES_ON_COPY env var in backend)
|
|
77
|
+
const configuredSkippedAttributes = readConfObject(
|
|
78
|
+
session.getPluginConfiguration(),
|
|
79
|
+
'skippedAttributesOnCopy',
|
|
80
|
+
) as string[] | undefined
|
|
81
|
+
const skippedAttributesOnCopy = new Set(configuredSkippedAttributes ?? [])
|
|
82
|
+
removeSkippedAttributes(duplicateTranscript, skippedAttributesOnCopy)
|
|
83
|
+
|
|
74
84
|
const change = new AddFeatureChange({
|
|
75
85
|
parentFeatureId: parentGene._id,
|
|
76
86
|
changedIds: [parentGene._id],
|
|
@@ -1,44 +1,36 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
2
|
/* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
6
4
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
7
5
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
8
6
|
import { changeRegistry } from '@apollo-annotation/common'
|
|
7
|
+
import type { AbstractSessionModel } from '@jbrowse/core/util'
|
|
9
8
|
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
10
|
-
import { getRoot } from '@jbrowse/mobx-state-tree'
|
|
11
9
|
import {
|
|
12
10
|
Button,
|
|
13
11
|
DialogActions,
|
|
14
12
|
DialogContent,
|
|
15
13
|
DialogContentText,
|
|
16
|
-
MenuItem,
|
|
17
|
-
Select,
|
|
18
|
-
type SelectChangeEvent,
|
|
19
14
|
} from '@mui/material'
|
|
20
15
|
import {
|
|
21
16
|
DataGrid,
|
|
22
17
|
type GridColDef,
|
|
18
|
+
type GridFilterModel,
|
|
19
|
+
type GridPaginationModel,
|
|
23
20
|
type GridRowsProp,
|
|
24
|
-
|
|
21
|
+
type GridSortModel,
|
|
25
22
|
} from '@mui/x-data-grid'
|
|
26
23
|
import React, { useEffect, useState } from 'react'
|
|
27
24
|
|
|
28
|
-
import type {
|
|
29
|
-
import type {
|
|
30
|
-
ApolloInternetAccount,
|
|
31
|
-
CollaborationServerDriver,
|
|
32
|
-
} from '../BackendDrivers'
|
|
25
|
+
import type { GetChangesOpts } from '../BackendDrivers/BackendDriver'
|
|
33
26
|
import type { ApolloSessionModel } from '../session'
|
|
34
|
-
import type { ApolloRootModel } from '../types'
|
|
35
|
-
import { createFetchErrorMessage } from '../util'
|
|
36
27
|
|
|
37
28
|
import { Dialog } from './Dialog'
|
|
38
29
|
|
|
39
30
|
interface ViewChangeLogProps {
|
|
40
31
|
session: ApolloSessionModel
|
|
41
32
|
handleClose(): void
|
|
33
|
+
assembly: string
|
|
42
34
|
}
|
|
43
35
|
|
|
44
36
|
const useStyles = makeStyles()((theme) => ({
|
|
@@ -51,28 +43,67 @@ const useStyles = makeStyles()((theme) => ({
|
|
|
51
43
|
},
|
|
52
44
|
}))
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
function buildFiltersFromModel(
|
|
47
|
+
filterModel: GridFilterModel,
|
|
48
|
+
): GetChangesOpts['filters'] {
|
|
49
|
+
const filters: NonNullable<GetChangesOpts['filters']> = {}
|
|
50
|
+
for (const item of filterModel.items) {
|
|
51
|
+
if (item.value === undefined || item.value === '' || item.value === null) {
|
|
52
|
+
continue
|
|
53
|
+
}
|
|
54
|
+
switch (item.field) {
|
|
55
|
+
case 'user': {
|
|
56
|
+
filters.user = String(item.value)
|
|
57
|
+
break
|
|
58
|
+
}
|
|
59
|
+
case 'typeName': {
|
|
60
|
+
filters.typeName = String(item.value)
|
|
61
|
+
break
|
|
62
|
+
}
|
|
63
|
+
case 'createdAt': {
|
|
64
|
+
const date = new Date(
|
|
65
|
+
item.value as string | number | Date,
|
|
66
|
+
).toISOString()
|
|
67
|
+
if (item.operator === 'after' || item.operator === 'onOrAfter') {
|
|
68
|
+
filters.startTime = date
|
|
69
|
+
} else if (
|
|
70
|
+
item.operator === 'before' ||
|
|
71
|
+
item.operator === 'onOrBefore'
|
|
72
|
+
) {
|
|
73
|
+
filters.endTime = date
|
|
74
|
+
}
|
|
75
|
+
break
|
|
76
|
+
}
|
|
77
|
+
}
|
|
61
78
|
}
|
|
62
|
-
|
|
79
|
+
return filters
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function ViewChangeLog({
|
|
83
|
+
handleClose,
|
|
84
|
+
session,
|
|
85
|
+
assembly: assemblyId,
|
|
86
|
+
}: ViewChangeLogProps) {
|
|
63
87
|
const { classes } = useStyles()
|
|
64
88
|
const [errorMessage, setErrorMessage] = useState<string>()
|
|
65
89
|
const [displayGridData, setDisplayGridData] = useState<GridRowsProp[]>([])
|
|
90
|
+
const [rowCount, setRowCount] = useState(0)
|
|
91
|
+
const [loading, setLoading] = useState(false)
|
|
92
|
+
const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({
|
|
93
|
+
page: 0,
|
|
94
|
+
pageSize: 15,
|
|
95
|
+
})
|
|
96
|
+
const [sortModel, setSortModel] = useState<GridSortModel>([
|
|
97
|
+
{ field: 'sequence', sort: 'desc' },
|
|
98
|
+
])
|
|
99
|
+
const [filterModel, setFilterModel] = useState<GridFilterModel>({
|
|
100
|
+
items: [],
|
|
101
|
+
})
|
|
66
102
|
|
|
67
|
-
const {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
internetAccountId?: string,
|
|
72
|
-
): ApolloInternetAccount
|
|
73
|
-
}
|
|
74
|
-
const assemblies = collaborationServerDriver.getAssemblies()
|
|
75
|
-
const [selectedAssembly, setSelectedAssembly] = useState(assemblies.at(0))
|
|
103
|
+
const { apolloDataStore } = session
|
|
104
|
+
const { assemblyManager } = session as unknown as AbstractSessionModel
|
|
105
|
+
const assembly = assemblyManager.get(assemblyId)
|
|
106
|
+
const assemblyName = assembly?.displayName ?? assemblyId
|
|
76
107
|
|
|
77
108
|
const gridColumns: GridColDef[] = [
|
|
78
109
|
{ field: 'sequence' },
|
|
@@ -85,9 +116,11 @@ export function ViewChangeLog({ handleClose, session }: ViewChangeLogProps) {
|
|
|
85
116
|
valueOptions: [...changeRegistry.changes.keys()],
|
|
86
117
|
},
|
|
87
118
|
{
|
|
88
|
-
field: '
|
|
119
|
+
field: 'changeData',
|
|
89
120
|
headerName: 'Change JSON',
|
|
90
121
|
width: 600,
|
|
122
|
+
sortable: false,
|
|
123
|
+
filterable: false,
|
|
91
124
|
renderCell: ({ value }) => (
|
|
92
125
|
<textarea
|
|
93
126
|
className={classes.changeTextarea}
|
|
@@ -108,46 +141,53 @@ export function ViewChangeLog({ handleClose, session }: ViewChangeLogProps) {
|
|
|
108
141
|
|
|
109
142
|
useEffect(() => {
|
|
110
143
|
async function getGridData() {
|
|
111
|
-
|
|
144
|
+
const backendDriver = apolloDataStore.getBackendDriver(assemblyId)
|
|
145
|
+
if (!backendDriver) {
|
|
146
|
+
setErrorMessage(`No driver found for assembly "${assemblyId}"`)
|
|
112
147
|
return
|
|
113
148
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
149
|
+
setLoading(true)
|
|
150
|
+
const [sortEntry] = sortModel
|
|
151
|
+
const sortField = sortEntry?.field
|
|
152
|
+
const sortOrderValue = sortEntry?.sort
|
|
153
|
+
const sortOrder: 'asc' | 'desc' | undefined =
|
|
154
|
+
sortOrderValue === 'asc' || sortOrderValue === 'desc'
|
|
155
|
+
? sortOrderValue
|
|
156
|
+
: undefined
|
|
157
|
+
const { changes, totalCount } = await backendDriver.getChanges(
|
|
158
|
+
assemblyId,
|
|
159
|
+
{
|
|
160
|
+
page: paginationModel.page,
|
|
161
|
+
pageSize: paginationModel.pageSize,
|
|
162
|
+
sortField,
|
|
163
|
+
sortOrder,
|
|
164
|
+
filters: buildFiltersFromModel(filterModel),
|
|
165
|
+
},
|
|
166
|
+
)
|
|
167
|
+
const gridData = changes.map((change) => {
|
|
168
|
+
const {
|
|
169
|
+
sequence,
|
|
170
|
+
typeName,
|
|
171
|
+
changes: nestedChanges,
|
|
172
|
+
user,
|
|
173
|
+
createdAt,
|
|
174
|
+
...rest
|
|
175
|
+
} = change
|
|
176
|
+
const changeData = nestedChanges ?? { typeName, ...rest }
|
|
177
|
+
return { sequence, typeName, changeData, user, createdAt }
|
|
125
178
|
})
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
})
|
|
130
|
-
if (!response.ok) {
|
|
131
|
-
const newErrorMessage = await createFetchErrorMessage(
|
|
132
|
-
response,
|
|
133
|
-
'Error when retrieving changes',
|
|
134
|
-
)
|
|
135
|
-
setErrorMessage(newErrorMessage)
|
|
136
|
-
return
|
|
137
|
-
}
|
|
138
|
-
const data = await response.json()
|
|
139
|
-
setDisplayGridData(data)
|
|
140
|
-
}
|
|
179
|
+
// @ts-expect-error not sure how to type this
|
|
180
|
+
setDisplayGridData(gridData)
|
|
181
|
+
setRowCount(totalCount)
|
|
141
182
|
}
|
|
142
|
-
getGridData()
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
183
|
+
getGridData()
|
|
184
|
+
.catch((error) => {
|
|
185
|
+
setErrorMessage(String(error))
|
|
186
|
+
})
|
|
187
|
+
.finally(() => {
|
|
188
|
+
setLoading(false)
|
|
189
|
+
})
|
|
190
|
+
}, [apolloDataStore, assemblyId, paginationModel, sortModel, filterModel])
|
|
151
191
|
|
|
152
192
|
return (
|
|
153
193
|
<Dialog
|
|
@@ -157,27 +197,27 @@ export function ViewChangeLog({ handleClose, session }: ViewChangeLogProps) {
|
|
|
157
197
|
handleClose={handleClose}
|
|
158
198
|
data-testid="view-changelog"
|
|
159
199
|
>
|
|
160
|
-
<Select
|
|
161
|
-
style={{ width: 200, marginLeft: 40 }}
|
|
162
|
-
value={selectedAssembly?.name ?? ''}
|
|
163
|
-
onChange={handleChangeAssembly}
|
|
164
|
-
>
|
|
165
|
-
{assemblies.map((option) => (
|
|
166
|
-
<MenuItem key={option.name} value={option.name}>
|
|
167
|
-
{option.displayName || option.name}
|
|
168
|
-
</MenuItem>
|
|
169
|
-
))}
|
|
170
|
-
</Select>
|
|
171
|
-
|
|
172
200
|
<DialogContent>
|
|
201
|
+
<DialogContentText>Changes for {assemblyName}</DialogContentText>
|
|
173
202
|
<DataGrid
|
|
174
203
|
pagination
|
|
204
|
+
paginationMode="server"
|
|
205
|
+
sortingMode="server"
|
|
206
|
+
filterMode="server"
|
|
207
|
+
rowCount={rowCount}
|
|
208
|
+
paginationModel={paginationModel}
|
|
209
|
+
onPaginationModelChange={setPaginationModel}
|
|
210
|
+
sortModel={sortModel}
|
|
211
|
+
onSortModelChange={setSortModel}
|
|
212
|
+
filterModel={filterModel}
|
|
213
|
+
onFilterModelChange={setFilterModel}
|
|
214
|
+
loading={loading}
|
|
175
215
|
rows={displayGridData}
|
|
176
216
|
columns={gridColumns}
|
|
177
|
-
getRowId={(row) => row.
|
|
178
|
-
|
|
217
|
+
getRowId={(row) => row.sequence}
|
|
218
|
+
showToolbar
|
|
219
|
+
pageSizeOptions={[5, 15, 25, 50, 100]}
|
|
179
220
|
initialState={{
|
|
180
|
-
sorting: { sortModel: [{ field: 'sequence', sort: 'desc' }] },
|
|
181
221
|
columns: { columnVisibilityModel: { sequence: false } },
|
|
182
222
|
}}
|
|
183
223
|
/>
|