@apollo-annotation/jbrowse-plugin-apollo 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +3189 -3575
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +3185 -3570
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +14884 -15905
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/package.json +33 -33
- package/src/ApolloInternetAccount/addMenuItems.ts +18 -0
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
- package/src/ApolloInternetAccount/configSchema.ts +5 -2
- package/src/ApolloInternetAccount/model.ts +14 -5
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +94 -0
- package/src/ApolloRefNameAliasAdapter/configSchema.ts +12 -0
- package/src/ApolloRefNameAliasAdapter/index.ts +21 -0
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +1 -0
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +10 -10
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +35 -32
- package/src/BackendDrivers/BackendDriver.ts +8 -0
- package/src/BackendDrivers/CollaborationServerDriver.ts +49 -1
- package/src/BackendDrivers/DesktopFileDriver.ts +14 -1
- package/src/BackendDrivers/InMemoryFileDriver.ts +17 -1
- package/src/ChangeManager.ts +1 -1
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +5 -25
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +82 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +11 -3
- package/src/FeatureDetailsWidget/BasicInformation.tsx +38 -30
- package/src/FeatureDetailsWidget/Sequence.tsx +7 -7
- package/src/FeatureDetailsWidget/TranscriptBasic.tsx +446 -0
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +365 -0
- package/src/FeatureDetailsWidget/index.ts +2 -0
- package/src/FeatureDetailsWidget/model.ts +77 -9
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +0 -2
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +453 -380
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +520 -0
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +138 -134
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +38 -370
- package/src/LinearApolloDisplay/glyphs/index.ts +1 -2
- package/src/LinearApolloDisplay/stateModel/base.ts +3 -6
- package/src/LinearApolloDisplay/stateModel/getGlyph.ts +30 -30
- package/src/LinearApolloDisplay/stateModel/index.ts +5 -1
- package/src/LinearApolloDisplay/stateModel/layouts.ts +32 -24
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +206 -217
- package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -67
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -1
- package/src/OntologyManager/OntologyStore/index.ts +2 -1
- package/src/OntologyManager/index.ts +6 -2
- package/src/OntologyManager/util.ts +2 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +15 -10
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +21 -46
- package/src/TabularEditor/HybridGrid/Feature.tsx +31 -82
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +3 -2
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -3
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +46 -5
- package/src/TabularEditor/model.ts +5 -3
- package/src/components/AddAssembly.tsx +15 -9
- package/src/components/AddChildFeature.tsx +7 -73
- package/src/components/AddFeature.tsx +2 -57
- package/src/components/AddRefSeqAliases.tsx +285 -0
- package/src/components/CopyFeature.tsx +16 -33
- package/src/components/DeleteFeature.tsx +4 -6
- package/src/components/ImportFeatures.tsx +6 -3
- package/src/components/LogOut.tsx +105 -0
- package/src/components/ManageChecks.tsx +1 -0
- package/src/components/ManageUsers.tsx +21 -1
- package/src/components/ModifyFeatureAttribute.tsx +2 -2
- package/src/components/OntologyTermAutocomplete.tsx +0 -2
- package/src/components/OntologyTermMultiSelect.tsx +1 -0
- package/src/components/OpenLocalFile.tsx +6 -5
- package/src/components/ViewChangeLog.tsx +1 -0
- package/src/components/ViewCheckResults.tsx +1 -0
- package/src/components/index.ts +4 -0
- package/src/extensions/annotationFromPileup.ts +10 -16
- package/src/index.ts +57 -3
- package/src/session/ClientDataStore.ts +49 -46
- package/src/session/session.ts +186 -114
- package/src/util/loadAssemblyIntoClient.ts +4 -210
- package/src/FeatureDetailsWidget/RelatedFeature.tsx +0 -97
- package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +0 -1204
- package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +0 -716
- package/src/LinearApolloDisplay/stateModel/glyphs.ts +0 -47
|
@@ -10,29 +10,6 @@ import { ApolloSessionModel } from '../../session'
|
|
|
10
10
|
import { getGlyph } from './getGlyph'
|
|
11
11
|
import { layoutsModelFactory } from './layouts'
|
|
12
12
|
|
|
13
|
-
export type Frame = 1 | 2 | 3 | -1 | -2 | -3
|
|
14
|
-
|
|
15
|
-
export function getFrame(
|
|
16
|
-
start: number,
|
|
17
|
-
end: number,
|
|
18
|
-
strand: 1 | -1,
|
|
19
|
-
phase: 0 | 1 | 2,
|
|
20
|
-
): Frame {
|
|
21
|
-
return strand === 1
|
|
22
|
-
? ((((start + phase) % 3) + 1) as 1 | 2 | 3)
|
|
23
|
-
: ((-1 * ((end - phase) % 3) - 1) as -1 | -2 | -3)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const frameColors: [
|
|
27
|
-
null,
|
|
28
|
-
string,
|
|
29
|
-
string,
|
|
30
|
-
string,
|
|
31
|
-
string,
|
|
32
|
-
string,
|
|
33
|
-
string,
|
|
34
|
-
] = [null, '#FF8080', '#80FF80', '#8080FF', '#8080FF', '#80FF80', '#FF8080']
|
|
35
|
-
|
|
36
13
|
export function renderingModelIntermediateFactory(
|
|
37
14
|
pluginManager: PluginManager,
|
|
38
15
|
configSchema: AnyConfigurationSchemaType,
|
|
@@ -169,17 +146,13 @@ function colorCode(letter: string, theme?: Theme) {
|
|
|
169
146
|
)
|
|
170
147
|
}
|
|
171
148
|
|
|
172
|
-
function codonColorCode(letter: string
|
|
173
|
-
const colorMap: Record<string, string> = {
|
|
149
|
+
function codonColorCode(letter: string) {
|
|
150
|
+
const colorMap: Record<string, string | undefined> = {
|
|
174
151
|
M: '#33ee33',
|
|
175
152
|
'*': '#f44336',
|
|
176
153
|
}
|
|
177
154
|
|
|
178
|
-
|
|
179
|
-
return colorMap[letter.toUpperCase()]
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return bpPerPx <= 0.1 ? rowColorCode : 'lightgray'
|
|
155
|
+
return colorMap[letter.toUpperCase()]
|
|
183
156
|
}
|
|
184
157
|
|
|
185
158
|
function reverseCodonSeq(seq: string): string {
|
|
@@ -214,7 +187,6 @@ function drawTranslation(
|
|
|
214
187
|
seq: string,
|
|
215
188
|
i: number,
|
|
216
189
|
reverse: boolean,
|
|
217
|
-
rowColorCode: string,
|
|
218
190
|
) {
|
|
219
191
|
let codonSeq: string = seq.slice(i, i + 3).toUpperCase()
|
|
220
192
|
if (reverse) {
|
|
@@ -225,11 +197,13 @@ function drawTranslation(
|
|
|
225
197
|
if (!codonLetter) {
|
|
226
198
|
return
|
|
227
199
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
200
|
+
const fillColor = codonColorCode(codonLetter)
|
|
201
|
+
if (fillColor) {
|
|
202
|
+
seqTrackctx.fillStyle = fillColor
|
|
203
|
+
seqTrackctx.fillRect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
|
|
204
|
+
}
|
|
232
205
|
if (bpPerPx <= 0.1) {
|
|
206
|
+
seqTrackctx.rect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
|
|
233
207
|
seqTrackctx.stroke()
|
|
234
208
|
drawLetter(seqTrackctx, trnslStartPx, trnslWidthPx, codonLetter, trnslY)
|
|
235
209
|
}
|
|
@@ -267,6 +241,24 @@ export function sequenceRenderingModelFactory(
|
|
|
267
241
|
self.lgv.dynamicBlocks.totalWidthPx,
|
|
268
242
|
self.lgv.bpPerPx <= 1 ? 125 : 95,
|
|
269
243
|
)
|
|
244
|
+
const frames =
|
|
245
|
+
self.lgv.bpPerPx <= 1
|
|
246
|
+
? [3, 2, 1, 0, 0, -1, -2, -3]
|
|
247
|
+
: [3, 2, 1, -1, -2, -3]
|
|
248
|
+
let height = 0
|
|
249
|
+
for (const frame of frames) {
|
|
250
|
+
const frameColor = self.theme?.palette.framesCDS.at(frame)?.main
|
|
251
|
+
if (frameColor) {
|
|
252
|
+
seqTrackctx.fillStyle = frameColor
|
|
253
|
+
seqTrackctx.fillRect(
|
|
254
|
+
0,
|
|
255
|
+
height,
|
|
256
|
+
self.lgv.dynamicBlocks.totalWidthPx,
|
|
257
|
+
self.sequenceRowHeight,
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
height += self.sequenceRowHeight
|
|
261
|
+
}
|
|
270
262
|
|
|
271
263
|
for (const [idx, region] of self.regions.entries()) {
|
|
272
264
|
const driver = (
|
|
@@ -289,13 +281,12 @@ export function sequenceRenderingModelFactory(
|
|
|
289
281
|
regionNumber: idx,
|
|
290
282
|
})?.offsetPx ?? 0) - self.lgv.offsetPx
|
|
291
283
|
const trnslWidthPx = 3 / self.lgv.bpPerPx
|
|
292
|
-
const trnslStartPx = self.displayedRegions[idx].reversed
|
|
284
|
+
const trnslStartPx = self.lgv.displayedRegions[idx].reversed
|
|
293
285
|
? trnslXOffset - trnslWidthPx
|
|
294
286
|
: trnslXOffset
|
|
295
287
|
|
|
296
288
|
// Draw translation forward
|
|
297
289
|
for (let j = 2; j >= 0; j--) {
|
|
298
|
-
const color = frameColors.at(j + 1) ?? '#ffffff'
|
|
299
290
|
if ((region.start + i) % 3 === j) {
|
|
300
291
|
drawTranslation(
|
|
301
292
|
seqTrackctx,
|
|
@@ -307,7 +298,6 @@ export function sequenceRenderingModelFactory(
|
|
|
307
298
|
seq,
|
|
308
299
|
i,
|
|
309
300
|
false,
|
|
310
|
-
color,
|
|
311
301
|
)
|
|
312
302
|
}
|
|
313
303
|
}
|
|
@@ -320,7 +310,7 @@ export function sequenceRenderingModelFactory(
|
|
|
320
310
|
regionNumber: idx,
|
|
321
311
|
})?.offsetPx ?? 0) - self.lgv.offsetPx
|
|
322
312
|
const widthPx = 1 / self.lgv.bpPerPx
|
|
323
|
-
const startPx = self.displayedRegions[idx].reversed
|
|
313
|
+
const startPx = self.lgv.displayedRegions[idx].reversed
|
|
324
314
|
? xOffset - widthPx
|
|
325
315
|
: xOffset
|
|
326
316
|
|
|
@@ -370,7 +360,6 @@ export function sequenceRenderingModelFactory(
|
|
|
370
360
|
|
|
371
361
|
// Draw translation reverse
|
|
372
362
|
for (let k = 0; k <= 2; k++) {
|
|
373
|
-
const color = frameColors.at(-(k + 1)) ?? '#ffffff'
|
|
374
363
|
const rowOffset = self.lgv.bpPerPx <= 1 ? 5 : 3
|
|
375
364
|
if ((region.start + i) % 3 === k) {
|
|
376
365
|
drawTranslation(
|
|
@@ -383,7 +372,6 @@ export function sequenceRenderingModelFactory(
|
|
|
383
372
|
seq,
|
|
384
373
|
i,
|
|
385
374
|
true,
|
|
386
|
-
color,
|
|
387
375
|
)
|
|
388
376
|
}
|
|
389
377
|
}
|
|
@@ -412,21 +400,19 @@ export function renderingModelFactory(
|
|
|
412
400
|
self,
|
|
413
401
|
autorun(
|
|
414
402
|
() => {
|
|
415
|
-
|
|
403
|
+
const { canvas, featureLayouts, featuresHeight, lgv } = self
|
|
404
|
+
if (!lgv.initialized || self.regionCannotBeRendered()) {
|
|
416
405
|
return
|
|
417
406
|
}
|
|
418
|
-
const
|
|
407
|
+
const { displayedRegions, dynamicBlocks } = lgv
|
|
408
|
+
|
|
409
|
+
const ctx = canvas?.getContext('2d')
|
|
419
410
|
if (!ctx) {
|
|
420
411
|
return
|
|
421
412
|
}
|
|
422
|
-
ctx.clearRect(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
self.lgv.dynamicBlocks.totalWidthPx,
|
|
426
|
-
self.featuresHeight,
|
|
427
|
-
)
|
|
428
|
-
for (const [idx, featureLayout] of self.featureLayouts.entries()) {
|
|
429
|
-
const displayedRegion = self.displayedRegions[idx]
|
|
413
|
+
ctx.clearRect(0, 0, dynamicBlocks.totalWidthPx, featuresHeight)
|
|
414
|
+
for (const [idx, featureLayout] of featureLayouts.entries()) {
|
|
415
|
+
const displayedRegion = displayedRegions[idx]
|
|
430
416
|
for (const [row, featureLayoutRow] of featureLayout.entries()) {
|
|
431
417
|
for (const [featureRow, feature] of featureLayoutRow) {
|
|
432
418
|
if (featureRow > 0) {
|
|
@@ -442,20 +428,7 @@ export function renderingModelFactory(
|
|
|
442
428
|
) {
|
|
443
429
|
continue
|
|
444
430
|
}
|
|
445
|
-
|
|
446
|
-
(self.lgv.bpToPx({
|
|
447
|
-
refName: displayedRegion.refName,
|
|
448
|
-
coord: feature.min,
|
|
449
|
-
regionNumber: idx,
|
|
450
|
-
})?.offsetPx ?? 0) - self.lgv.offsetPx
|
|
451
|
-
getGlyph(feature, self.lgv.bpPerPx).draw(
|
|
452
|
-
self,
|
|
453
|
-
ctx,
|
|
454
|
-
feature,
|
|
455
|
-
x,
|
|
456
|
-
row,
|
|
457
|
-
displayedRegion.reversed,
|
|
458
|
-
)
|
|
431
|
+
getGlyph(feature).draw(ctx, feature, row, self, idx)
|
|
459
432
|
}
|
|
460
433
|
}
|
|
461
434
|
}
|
|
@@ -470,5 +443,8 @@ export function renderingModelFactory(
|
|
|
470
443
|
export type LinearApolloDisplayRenderingModel = ReturnType<
|
|
471
444
|
typeof renderingModelIntermediateFactory
|
|
472
445
|
>
|
|
473
|
-
|
|
474
|
-
|
|
446
|
+
// eslint disable because of
|
|
447
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
448
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
449
|
+
export interface LinearApolloDisplayRendering
|
|
450
|
+
extends Instance<LinearApolloDisplayRenderingModel> {}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
|
-
/* eslint-disable import/no-named-as-default-member */
|
|
3
3
|
// jsonpath triggers this rule for some reason. import { query } from 'jsonpath' does not work
|
|
4
4
|
|
|
5
5
|
import { checkAbortSignal } from '@jbrowse/core/util'
|
|
@@ -155,8 +155,12 @@ export const OntologyRecordConfiguration = ConfigurationSchema(
|
|
|
155
155
|
},
|
|
156
156
|
)
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
// eslint disables because of
|
|
159
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
161
|
+
export interface OntologyManager extends Instance<typeof OntologyManagerType> {}
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
163
|
+
export interface OntologyRecord extends Instance<typeof OntologyRecordType> {}
|
|
160
164
|
|
|
161
165
|
export type OntologyTerm = OntologyDBNode
|
|
162
166
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
2
2
|
|
|
3
3
|
import OntologyStore from './OntologyStore'
|
|
4
4
|
import { isOntologyClass } from '.'
|
|
5
5
|
|
|
6
6
|
export async function fetchValidDescendantTerms(
|
|
7
|
-
parentFeature:
|
|
7
|
+
parentFeature: AnnotationFeature | undefined,
|
|
8
8
|
ontologyStore: OntologyStore,
|
|
9
9
|
_signal: AbortSignal,
|
|
10
10
|
) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
4
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4
5
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
5
6
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
6
7
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
7
|
-
import {
|
|
8
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
8
9
|
import { ConfigurationReference } from '@jbrowse/core/configuration'
|
|
9
10
|
import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
|
|
10
11
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
@@ -48,7 +49,7 @@ export function stateModelFactory(
|
|
|
48
49
|
showIntronLines: true,
|
|
49
50
|
})
|
|
50
51
|
.volatile(() => ({
|
|
51
|
-
apolloFeatureUnderMouse: undefined as
|
|
52
|
+
apolloFeatureUnderMouse: undefined as AnnotationFeature | undefined,
|
|
52
53
|
apolloRowUnderMouse: undefined as number | undefined,
|
|
53
54
|
}))
|
|
54
55
|
.views((self) => {
|
|
@@ -169,7 +170,7 @@ export function stateModelFactory(
|
|
|
169
170
|
get features() {
|
|
170
171
|
const { regions } = self
|
|
171
172
|
const session = getSession(self) as ApolloSession
|
|
172
|
-
const features = new Map<string, Map<string,
|
|
173
|
+
const features = new Map<string, Map<string, AnnotationFeature>>()
|
|
173
174
|
for (const region of regions) {
|
|
174
175
|
const assembly = session.apolloDataStore.assemblies.get(
|
|
175
176
|
region.assemblyName,
|
|
@@ -177,7 +178,7 @@ export function stateModelFactory(
|
|
|
177
178
|
const ref = assembly?.getByRefName(region.refName)
|
|
178
179
|
let filteredRef = features.get(region.refName)
|
|
179
180
|
if (!filteredRef) {
|
|
180
|
-
filteredRef = new Map<string,
|
|
181
|
+
filteredRef = new Map<string, AnnotationFeature>()
|
|
181
182
|
features.set(region.refName, filteredRef)
|
|
182
183
|
}
|
|
183
184
|
for (const [featureId, feature] of ref?.features.entries() ??
|
|
@@ -204,7 +205,7 @@ export function stateModelFactory(
|
|
|
204
205
|
if (featureLocation.min < min) {
|
|
205
206
|
;({ min } = featureLocation)
|
|
206
207
|
}
|
|
207
|
-
if (featureLocation.
|
|
208
|
+
if (featureLocation.max > max) {
|
|
208
209
|
;({ max } = featureLocation)
|
|
209
210
|
}
|
|
210
211
|
}
|
|
@@ -269,7 +270,7 @@ export function stateModelFactory(
|
|
|
269
270
|
return codonLayout
|
|
270
271
|
},
|
|
271
272
|
get featureLayout() {
|
|
272
|
-
const featureLayout = new Map<number, [string,
|
|
273
|
+
const featureLayout = new Map<number, [string, AnnotationFeature][]>()
|
|
273
274
|
for (const [refSeq, featuresForRefSeq] of this.features || []) {
|
|
274
275
|
if (!featuresForRefSeq) {
|
|
275
276
|
continue
|
|
@@ -342,7 +343,7 @@ export function stateModelFactory(
|
|
|
342
343
|
}
|
|
343
344
|
return assembly.name
|
|
344
345
|
},
|
|
345
|
-
get selectedFeature():
|
|
346
|
+
get selectedFeature(): AnnotationFeature | undefined {
|
|
346
347
|
const session = getSession(self) as ApolloSession
|
|
347
348
|
return session.apolloSelectedFeature
|
|
348
349
|
},
|
|
@@ -352,11 +353,11 @@ export function stateModelFactory(
|
|
|
352
353
|
},
|
|
353
354
|
}))
|
|
354
355
|
.actions((self) => ({
|
|
355
|
-
setSelectedFeature(feature?:
|
|
356
|
+
setSelectedFeature(feature?: AnnotationFeature) {
|
|
356
357
|
const session = getSession(self) as ApolloSession
|
|
357
358
|
session.apolloSetSelectedFeature(feature)
|
|
358
359
|
},
|
|
359
|
-
setApolloFeatureUnderMouse(feature?:
|
|
360
|
+
setApolloFeatureUnderMouse(feature?: AnnotationFeature) {
|
|
360
361
|
self.apolloFeatureUnderMouse = feature
|
|
361
362
|
},
|
|
362
363
|
setApolloRowUnderMouse(row?: number) {
|
|
@@ -422,4 +423,8 @@ export function stateModelFactory(
|
|
|
422
423
|
export type SixFrameFeatureDisplayStateModel = ReturnType<
|
|
423
424
|
typeof stateModelFactory
|
|
424
425
|
>
|
|
425
|
-
|
|
426
|
+
// eslint disable because of
|
|
427
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
428
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
429
|
+
export interface SixFrameFeatureDisplay
|
|
430
|
+
extends Instance<SixFrameFeatureDisplayStateModel> {}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AnnotationFeature } from '@apollo-annotation/mst'
|
|
2
2
|
import {
|
|
3
|
-
DiscontinuousLocationEndChange,
|
|
4
|
-
DiscontinuousLocationStartChange,
|
|
5
3
|
LocationEndChange,
|
|
6
4
|
LocationStartChange,
|
|
7
5
|
TypeChange,
|
|
@@ -11,7 +9,7 @@ import type { ChangeManager } from '../../ChangeManager'
|
|
|
11
9
|
|
|
12
10
|
export function handleFeatureTypeChange(
|
|
13
11
|
changeManager: ChangeManager,
|
|
14
|
-
feature:
|
|
12
|
+
feature: AnnotationFeature,
|
|
15
13
|
oldType: string,
|
|
16
14
|
newType: string,
|
|
17
15
|
) {
|
|
@@ -29,60 +27,37 @@ export function handleFeatureTypeChange(
|
|
|
29
27
|
|
|
30
28
|
export function handleFeatureStartChange(
|
|
31
29
|
changeManager: ChangeManager,
|
|
32
|
-
feature:
|
|
30
|
+
feature: AnnotationFeature,
|
|
33
31
|
oldStart: number,
|
|
34
32
|
newStart: number,
|
|
35
|
-
index?: number,
|
|
36
33
|
) {
|
|
37
34
|
const featureId = feature._id
|
|
38
|
-
const change =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
})
|
|
48
|
-
: new DiscontinuousLocationStartChange({
|
|
49
|
-
typeName: 'DiscontinuousLocationStartChange',
|
|
50
|
-
changedIds: [featureId],
|
|
51
|
-
featureId,
|
|
52
|
-
oldStart,
|
|
53
|
-
newStart,
|
|
54
|
-
assembly: feature.assemblyId,
|
|
55
|
-
index,
|
|
56
|
-
})
|
|
35
|
+
const change = new LocationStartChange({
|
|
36
|
+
typeName: 'LocationStartChange',
|
|
37
|
+
changedIds: [featureId],
|
|
38
|
+
featureId,
|
|
39
|
+
oldStart,
|
|
40
|
+
newStart,
|
|
41
|
+
assembly: feature.assemblyId,
|
|
42
|
+
})
|
|
43
|
+
|
|
57
44
|
return changeManager.submit(change)
|
|
58
45
|
}
|
|
59
46
|
|
|
60
47
|
export function handleFeatureEndChange(
|
|
61
48
|
changeManager: ChangeManager,
|
|
62
|
-
feature:
|
|
49
|
+
feature: AnnotationFeature,
|
|
63
50
|
oldEnd: number,
|
|
64
51
|
newEnd: number,
|
|
65
|
-
index?: number,
|
|
66
52
|
) {
|
|
67
53
|
const featureId = feature._id
|
|
68
|
-
const change =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
assembly: feature.assemblyId,
|
|
77
|
-
})
|
|
78
|
-
: new DiscontinuousLocationEndChange({
|
|
79
|
-
typeName: 'DiscontinuousLocationEndChange',
|
|
80
|
-
changedIds: [featureId],
|
|
81
|
-
featureId,
|
|
82
|
-
oldEnd,
|
|
83
|
-
newEnd,
|
|
84
|
-
assembly: feature.assemblyId,
|
|
85
|
-
index,
|
|
86
|
-
})
|
|
54
|
+
const change = new LocationEndChange({
|
|
55
|
+
typeName: 'LocationEndChange',
|
|
56
|
+
changedIds: [featureId],
|
|
57
|
+
featureId,
|
|
58
|
+
oldEnd,
|
|
59
|
+
newEnd,
|
|
60
|
+
assembly: feature.assemblyId,
|
|
61
|
+
})
|
|
87
62
|
return changeManager.submit(change)
|
|
88
63
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
|
|
2
|
+
/* eslint-disable unicorn/no-nested-ternary */
|
|
1
3
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5
|
-
import { AnnotationFeatureI } from '@apollo-annotation/mst'
|
|
4
|
+
|
|
5
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
6
6
|
import { AbstractSessionModel } from '@jbrowse/core/util'
|
|
7
7
|
import { observer } from 'mobx-react'
|
|
8
8
|
import React from 'react'
|
|
@@ -21,6 +21,7 @@ import { FeatureAttributes } from './FeatureAttributes'
|
|
|
21
21
|
import { featureContextMenuItems } from './featureContextMenuItems'
|
|
22
22
|
import type { ContextMenuState } from './HybridGrid'
|
|
23
23
|
import { NumberCell } from './NumberCell'
|
|
24
|
+
import { getGlyph } from '../../LinearApolloDisplay/stateModel/getGlyph'
|
|
24
25
|
|
|
25
26
|
const useStyles = makeStyles()((theme) => ({
|
|
26
27
|
typeContent: {
|
|
@@ -59,7 +60,7 @@ const useStyles = makeStyles()((theme) => ({
|
|
|
59
60
|
|
|
60
61
|
function makeContextMenuItems(
|
|
61
62
|
display: DisplayStateModel,
|
|
62
|
-
feature:
|
|
63
|
+
feature: AnnotationFeature,
|
|
63
64
|
) {
|
|
64
65
|
const {
|
|
65
66
|
changeManager,
|
|
@@ -80,7 +81,7 @@ function makeContextMenuItems(
|
|
|
80
81
|
)
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
function getTopLevelFeature(feature:
|
|
84
|
+
function getTopLevelFeature(feature: AnnotationFeature): AnnotationFeature {
|
|
84
85
|
let cur = feature
|
|
85
86
|
while (cur.parent) {
|
|
86
87
|
cur = cur.parent
|
|
@@ -98,7 +99,7 @@ export const Feature = observer(function Feature({
|
|
|
98
99
|
setContextMenu,
|
|
99
100
|
}: {
|
|
100
101
|
model: DisplayStateModel
|
|
101
|
-
feature:
|
|
102
|
+
feature: AnnotationFeature
|
|
102
103
|
depth: number
|
|
103
104
|
isHovered: boolean
|
|
104
105
|
isSelected: boolean
|
|
@@ -114,16 +115,7 @@ export const Feature = observer(function Feature({
|
|
|
114
115
|
tabularEditor: tabularEditorState,
|
|
115
116
|
} = displayState
|
|
116
117
|
const { featureCollapsed, filterText } = tabularEditorState
|
|
117
|
-
const {
|
|
118
|
-
_id,
|
|
119
|
-
children,
|
|
120
|
-
discontinuousLocations,
|
|
121
|
-
end,
|
|
122
|
-
phase,
|
|
123
|
-
start,
|
|
124
|
-
strand,
|
|
125
|
-
type,
|
|
126
|
-
} = feature
|
|
118
|
+
const { _id, children, max, min, strand, type } = feature
|
|
127
119
|
const expanded = !featureCollapsed.get(_id)
|
|
128
120
|
const toggleExpanded = (e: React.MouseEvent) => {
|
|
129
121
|
e.stopPropagation()
|
|
@@ -142,6 +134,7 @@ export const Feature = observer(function Feature({
|
|
|
142
134
|
displayState.setApolloHover({
|
|
143
135
|
feature,
|
|
144
136
|
topLevelFeature: getTopLevelFeature(feature),
|
|
137
|
+
glyph: getGlyph(getTopLevelFeature(feature)),
|
|
145
138
|
})
|
|
146
139
|
}}
|
|
147
140
|
className={
|
|
@@ -222,72 +215,29 @@ export const Feature = observer(function Feature({
|
|
|
222
215
|
</div>
|
|
223
216
|
</td>
|
|
224
217
|
<td>
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
newStart - 1,
|
|
238
|
-
index,
|
|
239
|
-
)
|
|
240
|
-
}
|
|
241
|
-
/>
|
|
242
|
-
))}
|
|
243
|
-
</div>
|
|
244
|
-
) : (
|
|
245
|
-
<NumberCell
|
|
246
|
-
initialValue={start + 1}
|
|
247
|
-
notifyError={notifyError}
|
|
248
|
-
onChangeCommitted={(newStart) =>
|
|
249
|
-
handleFeatureStartChange(
|
|
250
|
-
changeManager,
|
|
251
|
-
feature,
|
|
252
|
-
start,
|
|
253
|
-
newStart - 1,
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
/>
|
|
257
|
-
)}
|
|
218
|
+
<NumberCell
|
|
219
|
+
initialValue={min + 1}
|
|
220
|
+
notifyError={notifyError}
|
|
221
|
+
onChangeCommitted={(newStart) =>
|
|
222
|
+
handleFeatureStartChange(
|
|
223
|
+
changeManager,
|
|
224
|
+
feature,
|
|
225
|
+
min,
|
|
226
|
+
newStart - 1,
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
/>
|
|
258
230
|
</td>
|
|
259
231
|
<td>
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
onChangeCommitted={(newEnd) =>
|
|
268
|
-
handleFeatureEndChange(
|
|
269
|
-
changeManager,
|
|
270
|
-
feature,
|
|
271
|
-
discontinuousLocations[index].end,
|
|
272
|
-
newEnd,
|
|
273
|
-
index,
|
|
274
|
-
)
|
|
275
|
-
}
|
|
276
|
-
/>
|
|
277
|
-
))}
|
|
278
|
-
</div>
|
|
279
|
-
) : (
|
|
280
|
-
<NumberCell
|
|
281
|
-
initialValue={end}
|
|
282
|
-
notifyError={notifyError}
|
|
283
|
-
onChangeCommitted={(newEnd) =>
|
|
284
|
-
handleFeatureEndChange(changeManager, feature, end, newEnd)
|
|
285
|
-
}
|
|
286
|
-
/>
|
|
287
|
-
)}
|
|
232
|
+
<NumberCell
|
|
233
|
+
initialValue={max}
|
|
234
|
+
notifyError={notifyError}
|
|
235
|
+
onChangeCommitted={(newEnd) =>
|
|
236
|
+
handleFeatureEndChange(changeManager, feature, max, newEnd)
|
|
237
|
+
}
|
|
238
|
+
/>
|
|
288
239
|
</td>
|
|
289
240
|
<td>{strand === 1 ? '+' : strand === -1 ? '-' : undefined}</td>
|
|
290
|
-
<td>{phase}</td>
|
|
291
241
|
<td>
|
|
292
242
|
<FeatureAttributes filterText={filterText} feature={feature} />
|
|
293
243
|
</td>
|
|
@@ -304,8 +254,7 @@ export const Feature = observer(function Feature({
|
|
|
304
254
|
return text.includes(filterText)
|
|
305
255
|
})
|
|
306
256
|
.map(([featureId, childFeature]) => {
|
|
307
|
-
const childHovered =
|
|
308
|
-
apolloHover?.feature?._id === childFeature._id
|
|
257
|
+
const childHovered = apolloHover?.feature._id === childFeature._id
|
|
309
258
|
const childSelected = selectedFeature?._id === childFeature._id
|
|
310
259
|
return (
|
|
311
260
|
<Feature
|
|
@@ -325,7 +274,7 @@ export const Feature = observer(function Feature({
|
|
|
325
274
|
)
|
|
326
275
|
})
|
|
327
276
|
async function fetchValidTypeTerms(
|
|
328
|
-
feature:
|
|
277
|
+
feature: AnnotationFeature,
|
|
329
278
|
ontologyStore: OntologyStore,
|
|
330
279
|
_signal: AbortSignal,
|
|
331
280
|
) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
|
2
|
-
import {
|
|
2
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
3
3
|
import { observer } from 'mobx-react'
|
|
4
4
|
import { getSnapshot } from 'mobx-state-tree'
|
|
5
5
|
import React from 'react'
|
|
@@ -10,7 +10,7 @@ export const FeatureAttributes = observer(function FeatureAttributes({
|
|
|
10
10
|
feature,
|
|
11
11
|
filterText,
|
|
12
12
|
}: {
|
|
13
|
-
feature:
|
|
13
|
+
feature: AnnotationFeature
|
|
14
14
|
filterText: string
|
|
15
15
|
}) {
|
|
16
16
|
const attrString = [...feature.attributes.entries()]
|
|
@@ -25,6 +25,7 @@ export const FeatureAttributes = observer(function FeatureAttributes({
|
|
|
25
25
|
}
|
|
26
26
|
return [key, getSnapshot(value)]
|
|
27
27
|
})
|
|
28
|
+
.filter(([key]) => key) // Leave empty keys off
|
|
28
29
|
.map(
|
|
29
30
|
([key, values]) =>
|
|
30
31
|
`${key}=${Array.isArray(values) ? values.join(', ') : values}`,
|
|
@@ -76,7 +76,6 @@ const HybridGrid = observer(function HybridGrid({
|
|
|
76
76
|
<th>Start</th>
|
|
77
77
|
<th>End</th>
|
|
78
78
|
<th>Strand</th>
|
|
79
|
-
<th>Phase</th>
|
|
80
79
|
<th>Attributes</th>
|
|
81
80
|
</tr>
|
|
82
81
|
</thead>
|
|
@@ -92,11 +91,11 @@ const HybridGrid = observer(function HybridGrid({
|
|
|
92
91
|
return text.includes(filterText)
|
|
93
92
|
})
|
|
94
93
|
.sort((a, b) => {
|
|
95
|
-
return a[1].
|
|
94
|
+
return a[1].min - b[1].min
|
|
96
95
|
})
|
|
97
96
|
.map(([featureId, feature]) => {
|
|
98
97
|
const isSelected = selectedFeature?._id === featureId
|
|
99
|
-
const isHovered = apolloHover?.feature
|
|
98
|
+
const isHovered = apolloHover?.feature._id === featureId
|
|
100
99
|
return (
|
|
101
100
|
<Feature
|
|
102
101
|
key={featureId}
|