@apollo-annotation/jbrowse-plugin-apollo 0.3.13 → 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
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
import { checkAbortSignal } from '@jbrowse/core/util/aborting'
|
|
6
6
|
import jsonpath from 'jsonpath'
|
|
7
7
|
|
|
8
|
-
import type { TextIndexFieldDefinition } from '..'
|
|
9
|
-
|
|
10
8
|
import { stopwords } from './fulltext-stopwords'
|
|
11
9
|
import type { OntologyDBNode } from './indexeddb-schema'
|
|
12
10
|
import { applyPrefixes } from './prefixes'
|
|
11
|
+
import type { TextIndexFieldDefinition } from './types'
|
|
13
12
|
|
|
14
13
|
// eslint-disable-next-line import/no-duplicates
|
|
15
14
|
import type OntologyStore from '.'
|
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
5
5
|
|
|
6
6
|
import { beforeAll, describe, expect, it, jest } from '@jest/globals'
|
|
7
7
|
|
|
8
|
-
import { type OntologyClass, isOntologyClass } from '
|
|
8
|
+
import { type OntologyClass, isOntologyClass } from './types'
|
|
9
9
|
|
|
10
10
|
import OntologyStore from '.'
|
|
11
11
|
|
|
@@ -40,7 +40,10 @@ jest.mock('jsonpath', () => {
|
|
|
40
40
|
let so: OntologyStore
|
|
41
41
|
|
|
42
42
|
beforeAll(async () => {
|
|
43
|
-
const localPath = path.resolve(
|
|
43
|
+
const localPath = path.resolve(
|
|
44
|
+
__dirname,
|
|
45
|
+
'../../../test_data/so-2024-11-18.json',
|
|
46
|
+
)
|
|
44
47
|
so = new OntologyStore(
|
|
45
48
|
'Sequence Ontology',
|
|
46
49
|
'automated testing',
|
|
@@ -15,14 +15,6 @@ import {
|
|
|
15
15
|
deleteDB,
|
|
16
16
|
} from 'idb/with-async-ittr'
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
type OntologyClass,
|
|
20
|
-
type OntologyProperty,
|
|
21
|
-
type OntologyTerm,
|
|
22
|
-
isOntologyClass,
|
|
23
|
-
isOntologyProperty,
|
|
24
|
-
} from '..'
|
|
25
|
-
|
|
26
18
|
import { textSearch } from './fulltext'
|
|
27
19
|
import {
|
|
28
20
|
type OntologyDB,
|
|
@@ -35,6 +27,13 @@ import {
|
|
|
35
27
|
loadOboGraphJson,
|
|
36
28
|
openDatabase,
|
|
37
29
|
} from './indexeddb-storage'
|
|
30
|
+
import {
|
|
31
|
+
type OntologyClass,
|
|
32
|
+
type OntologyProperty,
|
|
33
|
+
type OntologyTerm,
|
|
34
|
+
isOntologyClass,
|
|
35
|
+
isOntologyProperty,
|
|
36
|
+
} from './types'
|
|
38
37
|
|
|
39
38
|
export type SourceLocation = UriLocation | LocalPathLocation | BlobLocation
|
|
40
39
|
|
|
@@ -8,8 +8,6 @@ import {
|
|
|
8
8
|
openDB,
|
|
9
9
|
} from 'idb/with-async-ittr'
|
|
10
10
|
|
|
11
|
-
import { defaultTextIndexFields } from '..'
|
|
12
|
-
|
|
13
11
|
import { PREFIXED_ID_PATH, getWords } from './fulltext'
|
|
14
12
|
import {
|
|
15
13
|
type OntologyDB,
|
|
@@ -17,6 +15,7 @@ import {
|
|
|
17
15
|
isOntologyDBNode,
|
|
18
16
|
} from './indexeddb-schema'
|
|
19
17
|
import type { GraphDocument } from './obo-graph-json-schema'
|
|
18
|
+
import { defaultTextIndexFields } from './types'
|
|
20
19
|
|
|
21
20
|
import type OntologyStore from '.'
|
|
22
21
|
|
|
@@ -172,6 +171,7 @@ export async function loadOboGraphJson(this: OntologyStore, db: Database) {
|
|
|
172
171
|
const tx2 = db.transaction('meta', 'readwrite')
|
|
173
172
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
174
173
|
const { update, ...otherOptions } = this.options
|
|
174
|
+
await tx2.objectStore('meta').delete('meta')
|
|
175
175
|
await tx2.objectStore('meta').add(
|
|
176
176
|
{
|
|
177
177
|
ontologyRecord: {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OntologyDBNode } from './indexeddb-schema'
|
|
2
|
+
|
|
3
|
+
export type OntologyTerm = OntologyDBNode
|
|
4
|
+
|
|
5
|
+
export type OntologyClass = OntologyTerm & { type: 'CLASS' }
|
|
6
|
+
export function isOntologyClass(term: OntologyTerm): term is OntologyClass {
|
|
7
|
+
return term.type === 'CLASS'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type OntologyProperty = OntologyTerm & { type: 'PROPERTY' }
|
|
11
|
+
export function isOntologyProperty(
|
|
12
|
+
term: OntologyTerm,
|
|
13
|
+
): term is OntologyProperty {
|
|
14
|
+
return term.type === 'PROPERTY'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TextIndexFieldDefinition {
|
|
18
|
+
/** name to display in the UI for text taken from this field or fields */
|
|
19
|
+
displayName: string
|
|
20
|
+
/** JSONPath of the field(s) */
|
|
21
|
+
jsonPath: string
|
|
22
|
+
}
|
|
23
|
+
export const defaultTextIndexFields: TextIndexFieldDefinition[] = [
|
|
24
|
+
{ displayName: 'Label', jsonPath: '$.lbl' },
|
|
25
|
+
{ displayName: 'Synonym', jsonPath: '$.meta.synonyms[*].val' },
|
|
26
|
+
{ displayName: 'Definition', jsonPath: '$.meta.definition.val' },
|
|
27
|
+
]
|
|
@@ -23,8 +23,11 @@ import type ApolloPluginConfigurationSchema from '../config'
|
|
|
23
23
|
import type { ApolloRootModel } from '../types'
|
|
24
24
|
|
|
25
25
|
import OntologyStore, { type OntologyStoreOptions } from './OntologyStore'
|
|
26
|
-
import type { OntologyDBNode } from './OntologyStore/indexeddb-schema'
|
|
27
26
|
import { applyPrefixes, expandPrefixes } from './OntologyStore/prefixes'
|
|
27
|
+
import {
|
|
28
|
+
type OntologyTerm,
|
|
29
|
+
defaultTextIndexFields,
|
|
30
|
+
} from './OntologyStore/types'
|
|
28
31
|
|
|
29
32
|
export { isDeprecated } from './OntologyStore/indexeddb-schema'
|
|
30
33
|
|
|
@@ -200,17 +203,17 @@ export const OntologyManagerType = types
|
|
|
200
203
|
|
|
201
204
|
export default OntologyManagerType
|
|
202
205
|
|
|
203
|
-
export
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
export
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
export type {
|
|
207
|
+
OntologyClass,
|
|
208
|
+
OntologyProperty,
|
|
209
|
+
OntologyTerm,
|
|
210
|
+
TextIndexFieldDefinition,
|
|
211
|
+
} from './OntologyStore/types'
|
|
212
|
+
export {
|
|
213
|
+
defaultTextIndexFields,
|
|
214
|
+
isOntologyClass,
|
|
215
|
+
isOntologyProperty,
|
|
216
|
+
} from './OntologyStore/types'
|
|
214
217
|
|
|
215
218
|
export const OntologyRecordConfiguration = ConfigurationSchema(
|
|
216
219
|
'OntologyRecord',
|
|
@@ -248,17 +251,3 @@ export const OntologyRecordConfiguration = ConfigurationSchema(
|
|
|
248
251
|
export interface OntologyManager extends Instance<typeof OntologyManagerType> {}
|
|
249
252
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
250
253
|
export interface OntologyRecord extends Instance<typeof OntologyRecordType> {}
|
|
251
|
-
|
|
252
|
-
export type OntologyTerm = OntologyDBNode
|
|
253
|
-
|
|
254
|
-
export type OntologyClass = OntologyTerm & { type: 'CLASS' }
|
|
255
|
-
export function isOntologyClass(term: OntologyTerm): term is OntologyClass {
|
|
256
|
-
return term.type === 'CLASS'
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export type OntologyProperty = OntologyTerm & { type: 'PROPERTY' }
|
|
260
|
-
export function isOntologyProperty(
|
|
261
|
-
term: OntologyTerm,
|
|
262
|
-
): term is OntologyProperty {
|
|
263
|
-
return term.type === 'PROPERTY'
|
|
264
|
-
}
|
|
@@ -32,7 +32,6 @@ export function featureContextMenuItems(
|
|
|
32
32
|
) {
|
|
33
33
|
const internetAccount = getApolloInternetAccount(session)
|
|
34
34
|
const role = internetAccount ? internetAccount.role : 'admin'
|
|
35
|
-
const admin = role === 'admin'
|
|
36
35
|
const readOnly = !(role && ['admin', 'user'].includes(role))
|
|
37
36
|
const menuItems: MenuItem[] = []
|
|
38
37
|
if (feature) {
|
|
@@ -102,7 +101,7 @@ export function featureContextMenuItems(
|
|
|
102
101
|
},
|
|
103
102
|
{
|
|
104
103
|
label: 'Delete feature',
|
|
105
|
-
disabled:
|
|
104
|
+
disabled: readOnly,
|
|
106
105
|
onClick: () => {
|
|
107
106
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
108
107
|
(doneCallback) => [
|
|
@@ -124,7 +123,7 @@ export function featureContextMenuItems(
|
|
|
124
123
|
},
|
|
125
124
|
{
|
|
126
125
|
label: 'Merge transcripts',
|
|
127
|
-
disabled:
|
|
126
|
+
disabled: readOnly,
|
|
128
127
|
onClick: () => {
|
|
129
128
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
130
129
|
(doneCallback) => [
|
|
@@ -146,7 +145,7 @@ export function featureContextMenuItems(
|
|
|
146
145
|
},
|
|
147
146
|
{
|
|
148
147
|
label: 'Merge exons',
|
|
149
|
-
disabled:
|
|
148
|
+
disabled: readOnly,
|
|
150
149
|
onClick: () => {
|
|
151
150
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
152
151
|
(doneCallback) => [
|
|
@@ -168,7 +167,7 @@ export function featureContextMenuItems(
|
|
|
168
167
|
},
|
|
169
168
|
{
|
|
170
169
|
label: 'Split exon',
|
|
171
|
-
disabled:
|
|
170
|
+
disabled: readOnly,
|
|
172
171
|
onClick: () => {
|
|
173
172
|
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
174
173
|
(doneCallback) => [
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
AnnotationFeature,
|
|
5
|
+
AnnotationFeatureSnapshot,
|
|
6
|
+
} from '@apollo-annotation/mst'
|
|
4
7
|
import { AddFeatureChange } from '@apollo-annotation/shared'
|
|
5
8
|
import {
|
|
6
9
|
Button,
|
|
@@ -65,17 +68,21 @@ export function AddChildFeature({
|
|
|
65
68
|
event.preventDefault()
|
|
66
69
|
setErrorMessage('')
|
|
67
70
|
const _id = new ObjectID().toHexString()
|
|
71
|
+
const addedFeature: AnnotationFeatureSnapshot = {
|
|
72
|
+
_id,
|
|
73
|
+
refSeq: sourceFeature.refSeq,
|
|
74
|
+
min: Number(start) - 1,
|
|
75
|
+
max: Number(end),
|
|
76
|
+
type,
|
|
77
|
+
}
|
|
78
|
+
if (sourceFeature.strand) {
|
|
79
|
+
addedFeature.strand = sourceFeature.strand
|
|
80
|
+
}
|
|
68
81
|
const change = new AddFeatureChange({
|
|
69
82
|
changedIds: [sourceFeature._id],
|
|
70
83
|
typeName: 'AddFeatureChange',
|
|
71
84
|
assembly: sourceAssemblyId,
|
|
72
|
-
addedFeature
|
|
73
|
-
_id,
|
|
74
|
-
refSeq: sourceFeature.refSeq,
|
|
75
|
-
min: Number(start) - 1,
|
|
76
|
-
max: Number(end),
|
|
77
|
-
type,
|
|
78
|
-
},
|
|
85
|
+
addedFeature,
|
|
79
86
|
parentFeatureId: sourceFeature._id,
|
|
80
87
|
})
|
|
81
88
|
void changeManager.submit(change).then(() => {
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
|
+
|
|
3
|
+
import type { AnnotationFeature } from '@apollo-annotation/mst'
|
|
4
|
+
import { FeatureAttributeChange } from '@apollo-annotation/shared'
|
|
5
|
+
import { getSnapshot } from '@jbrowse/mobx-state-tree'
|
|
6
|
+
import {
|
|
7
|
+
Button,
|
|
8
|
+
DialogActions,
|
|
9
|
+
DialogContent,
|
|
10
|
+
DialogContentText,
|
|
11
|
+
} from '@mui/material'
|
|
12
|
+
import React, { useState } from 'react'
|
|
13
|
+
|
|
14
|
+
import type { ChangeManager } from '../ChangeManager'
|
|
15
|
+
import type { ApolloSessionModel } from '../session'
|
|
16
|
+
|
|
17
|
+
import { Dialog } from './Dialog'
|
|
18
|
+
|
|
19
|
+
const PRESET_COLORS = [
|
|
20
|
+
'#cc79a7',
|
|
21
|
+
'#d65e00',
|
|
22
|
+
'#e69f00',
|
|
23
|
+
'#f0e442',
|
|
24
|
+
'#56b3e9',
|
|
25
|
+
'#0072b2',
|
|
26
|
+
'#009e73',
|
|
27
|
+
] as const
|
|
28
|
+
|
|
29
|
+
interface ColorFeatureProps {
|
|
30
|
+
session: ApolloSessionModel
|
|
31
|
+
handleClose(): void
|
|
32
|
+
sourceFeature: AnnotationFeature
|
|
33
|
+
sourceAssemblyId: string
|
|
34
|
+
changeManager: ChangeManager
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ColorFeature({
|
|
38
|
+
changeManager,
|
|
39
|
+
handleClose,
|
|
40
|
+
sourceAssemblyId,
|
|
41
|
+
sourceFeature,
|
|
42
|
+
}: ColorFeatureProps) {
|
|
43
|
+
const existingColor = sourceFeature.attributes.get('apollo_color')?.[0]
|
|
44
|
+
const [color, setColor] = useState<string>(existingColor ?? PRESET_COLORS[0])
|
|
45
|
+
|
|
46
|
+
async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
|
|
47
|
+
event.preventDefault()
|
|
48
|
+
const currentColor = sourceFeature.attributes.get('apollo_color')?.[0]
|
|
49
|
+
if (currentColor === color) {
|
|
50
|
+
handleClose()
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
const oldAttributes = getSnapshot(sourceFeature.attributes)
|
|
54
|
+
const newAttributes = { ...oldAttributes, apollo_color: [color] }
|
|
55
|
+
const change = new FeatureAttributeChange({
|
|
56
|
+
changedIds: [sourceFeature._id],
|
|
57
|
+
typeName: 'FeatureAttributeChange',
|
|
58
|
+
assembly: sourceAssemblyId,
|
|
59
|
+
featureId: sourceFeature._id,
|
|
60
|
+
oldAttributes,
|
|
61
|
+
newAttributes,
|
|
62
|
+
})
|
|
63
|
+
await changeManager.submit(change)
|
|
64
|
+
handleClose()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function onRemove() {
|
|
68
|
+
const oldAttributes = getSnapshot(sourceFeature.attributes)
|
|
69
|
+
const { apollo_color: _removed, ...newAttributes } = oldAttributes
|
|
70
|
+
const change = new FeatureAttributeChange({
|
|
71
|
+
changedIds: [sourceFeature._id],
|
|
72
|
+
typeName: 'FeatureAttributeChange',
|
|
73
|
+
assembly: sourceAssemblyId,
|
|
74
|
+
featureId: sourceFeature._id,
|
|
75
|
+
oldAttributes,
|
|
76
|
+
newAttributes,
|
|
77
|
+
})
|
|
78
|
+
await changeManager.submit(change)
|
|
79
|
+
handleClose()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Dialog
|
|
84
|
+
open
|
|
85
|
+
title="Color feature"
|
|
86
|
+
handleClose={handleClose}
|
|
87
|
+
maxWidth={false}
|
|
88
|
+
data-testid="color-feature"
|
|
89
|
+
>
|
|
90
|
+
<form
|
|
91
|
+
onSubmit={(event) => {
|
|
92
|
+
void onSubmit(event)
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
<DialogContent style={{ display: 'flex', flexDirection: 'column' }}>
|
|
96
|
+
<DialogContentText>
|
|
97
|
+
Choose a color for this feature.
|
|
98
|
+
</DialogContentText>
|
|
99
|
+
<div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
|
|
100
|
+
{PRESET_COLORS.map((preset) => {
|
|
101
|
+
const selected = color.toLowerCase() === preset
|
|
102
|
+
return (
|
|
103
|
+
<button
|
|
104
|
+
key={preset}
|
|
105
|
+
type="button"
|
|
106
|
+
aria-label={preset}
|
|
107
|
+
aria-pressed={selected}
|
|
108
|
+
onClick={() => {
|
|
109
|
+
setColor(preset)
|
|
110
|
+
}}
|
|
111
|
+
style={{
|
|
112
|
+
width: 32,
|
|
113
|
+
height: 32,
|
|
114
|
+
padding: 0,
|
|
115
|
+
borderRadius: 4,
|
|
116
|
+
border: '1px solid rgba(0, 0, 0, 0.3)',
|
|
117
|
+
outline: selected ? '2px solid currentColor' : 'none',
|
|
118
|
+
outlineOffset: 2,
|
|
119
|
+
backgroundColor: preset,
|
|
120
|
+
cursor: 'pointer',
|
|
121
|
+
}}
|
|
122
|
+
/>
|
|
123
|
+
)
|
|
124
|
+
})}
|
|
125
|
+
</div>
|
|
126
|
+
<div
|
|
127
|
+
style={{
|
|
128
|
+
display: 'flex',
|
|
129
|
+
alignItems: 'center',
|
|
130
|
+
gap: 8,
|
|
131
|
+
marginTop: 16,
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
<label htmlFor="color-feature-custom">Custom:</label>
|
|
135
|
+
<input
|
|
136
|
+
id="color-feature-custom"
|
|
137
|
+
type="color"
|
|
138
|
+
value={color}
|
|
139
|
+
onChange={(event) => {
|
|
140
|
+
setColor(event.target.value)
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
</DialogContent>
|
|
145
|
+
<DialogActions>
|
|
146
|
+
<Button variant="contained" type="submit">
|
|
147
|
+
Submit
|
|
148
|
+
</Button>
|
|
149
|
+
<Button
|
|
150
|
+
variant="outlined"
|
|
151
|
+
color="error"
|
|
152
|
+
type="button"
|
|
153
|
+
disabled={existingColor === undefined}
|
|
154
|
+
onClick={() => {
|
|
155
|
+
void onRemove()
|
|
156
|
+
}}
|
|
157
|
+
>
|
|
158
|
+
Remove color
|
|
159
|
+
</Button>
|
|
160
|
+
<Button variant="outlined" type="button" onClick={handleClose}>
|
|
161
|
+
Cancel
|
|
162
|
+
</Button>
|
|
163
|
+
</DialogActions>
|
|
164
|
+
</form>
|
|
165
|
+
</Dialog>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
LocationStartChange,
|
|
10
10
|
} from '@apollo-annotation/shared'
|
|
11
11
|
import type { Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
12
|
+
import { readConfObject } from '@jbrowse/core/configuration'
|
|
12
13
|
import type { AbstractSessionModel } from '@jbrowse/core/util'
|
|
13
14
|
import { getSnapshot } from '@jbrowse/mobx-state-tree'
|
|
14
15
|
import {
|
|
@@ -30,6 +31,7 @@ import ObjectID from 'bson-objectid'
|
|
|
30
31
|
import React, { useEffect, useMemo, useState } from 'react'
|
|
31
32
|
|
|
32
33
|
import type { ApolloSessionModel } from '../session'
|
|
34
|
+
import { removeSkippedAttributes } from '../util'
|
|
33
35
|
|
|
34
36
|
import { Dialog } from './Dialog'
|
|
35
37
|
|
|
@@ -162,6 +164,11 @@ export function CreateApolloAnnotation({
|
|
|
162
164
|
region,
|
|
163
165
|
}: CreateApolloAnnotationProps) {
|
|
164
166
|
const apolloSessionModel = session as unknown as ApolloSessionModel
|
|
167
|
+
const configuredSkippedAttributes = readConfObject(
|
|
168
|
+
apolloSessionModel.getPluginConfiguration(),
|
|
169
|
+
'skippedAttributesOnCopy',
|
|
170
|
+
) as string[] | undefined
|
|
171
|
+
const skippedAttributesOnCopy = new Set(configuredSkippedAttributes ?? [])
|
|
165
172
|
const { featureTypeOntology } =
|
|
166
173
|
apolloSessionModel.apolloDataStore.ontologyManager
|
|
167
174
|
const childIds = useMemo(
|
|
@@ -340,23 +347,28 @@ export function CreateApolloAnnotation({
|
|
|
340
347
|
|
|
341
348
|
// Copies gene feature along with its selected children
|
|
342
349
|
const copyGeneFeature = async () => {
|
|
350
|
+
const copiedAnnotationFeature = {
|
|
351
|
+
...annotationFeature,
|
|
352
|
+
} as AnnotationFeatureSnapshot
|
|
353
|
+
removeSkippedAttributes(copiedAnnotationFeature, skippedAttributesOnCopy)
|
|
354
|
+
|
|
343
355
|
let change
|
|
344
356
|
if (
|
|
345
|
-
|
|
357
|
+
copiedAnnotationFeature.children &&
|
|
346
358
|
checkedChildrens.length !==
|
|
347
|
-
Object.values(
|
|
359
|
+
Object.values(copiedAnnotationFeature.children).length
|
|
348
360
|
) {
|
|
349
361
|
// IF SOME CHILDREN ARE CHECKED
|
|
350
362
|
const childrens: Record<string, AnnotationFeatureSnapshot> = {}
|
|
351
363
|
for (const childId of checkedChildrens) {
|
|
352
|
-
childrens[childId] =
|
|
364
|
+
childrens[childId] = copiedAnnotationFeature.children[childId]
|
|
353
365
|
}
|
|
354
366
|
change = new AddFeatureChange({
|
|
355
367
|
changedIds: [annotationFeature._id],
|
|
356
368
|
typeName: 'AddFeatureChange',
|
|
357
369
|
assembly: assembly.name,
|
|
358
370
|
addedFeature: {
|
|
359
|
-
...
|
|
371
|
+
...copiedAnnotationFeature,
|
|
360
372
|
children: childrens,
|
|
361
373
|
},
|
|
362
374
|
})
|
|
@@ -366,7 +378,7 @@ export function CreateApolloAnnotation({
|
|
|
366
378
|
changedIds: [annotationFeature._id],
|
|
367
379
|
typeName: 'AddFeatureChange',
|
|
368
380
|
assembly: assembly.name,
|
|
369
|
-
addedFeature:
|
|
381
|
+
addedFeature: copiedAnnotationFeature,
|
|
370
382
|
})
|
|
371
383
|
}
|
|
372
384
|
|
|
@@ -380,7 +392,10 @@ export function CreateApolloAnnotation({
|
|
|
380
392
|
return
|
|
381
393
|
}
|
|
382
394
|
for (const transcriptId of Object.keys(transcripts)) {
|
|
383
|
-
const transcript =
|
|
395
|
+
const transcript = {
|
|
396
|
+
...transcripts[transcriptId],
|
|
397
|
+
} as AnnotationFeatureSnapshot
|
|
398
|
+
removeSkippedAttributes(transcript, skippedAttributesOnCopy)
|
|
384
399
|
transcript.strand = selectedDestinationFeature.strand
|
|
385
400
|
|
|
386
401
|
// update strand of transcript children if they exist
|
|
@@ -405,9 +420,20 @@ export function CreateApolloAnnotation({
|
|
|
405
420
|
const createNewGeneFeatureWithTranscripts = async (
|
|
406
421
|
childrens: Record<string, AnnotationFeatureSnapshot>,
|
|
407
422
|
) => {
|
|
423
|
+
const copiedChildrens: Record<string, AnnotationFeatureSnapshot> = {}
|
|
424
|
+
for (const [childId, child] of Object.entries(childrens)) {
|
|
425
|
+
const copiedChild = { ...child } as AnnotationFeatureSnapshot
|
|
426
|
+
removeSkippedAttributes(copiedChild, skippedAttributesOnCopy)
|
|
427
|
+
copiedChildrens[childId] = copiedChild
|
|
428
|
+
}
|
|
429
|
+
|
|
408
430
|
const newGeneId = new ObjectID().toHexString()
|
|
409
|
-
const min = Math.min(
|
|
410
|
-
|
|
431
|
+
const min = Math.min(
|
|
432
|
+
...Object.values(copiedChildrens).map((child) => child.min),
|
|
433
|
+
)
|
|
434
|
+
const max = Math.max(
|
|
435
|
+
...Object.values(copiedChildrens).map((child) => child.max),
|
|
436
|
+
)
|
|
411
437
|
const change = new AddFeatureChange({
|
|
412
438
|
changedIds: [newGeneId],
|
|
413
439
|
typeName: 'AddFeatureChange',
|
|
@@ -419,7 +445,7 @@ export function CreateApolloAnnotation({
|
|
|
419
445
|
max,
|
|
420
446
|
strand: annotationFeature.strand,
|
|
421
447
|
type: 'gene',
|
|
422
|
-
children:
|
|
448
|
+
children: copiedChildrens,
|
|
423
449
|
attributes: {
|
|
424
450
|
name: [getGeneNameOrId(annotationFeature)],
|
|
425
451
|
gene_name: [getGeneNameOrId(annotationFeature)],
|