@apollo-annotation/jbrowse-plugin-apollo 0.3.5 → 0.3.6

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.
Files changed (126) hide show
  1. package/dist/index.esm.js +5474 -4937
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +4609 -4089
  4. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
  5. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
  6. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
  7. package/dist/jbrowse-plugin-apollo.umd.development.js +3634 -3500
  8. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
  9. package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
  10. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
  11. package/package.json +4 -4
  12. package/src/ApolloInternetAccount/addMenuItems.ts +5 -2
  13. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
  14. package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
  15. package/src/ApolloInternetAccount/components/LoginIcons.tsx +1 -1
  16. package/src/ApolloInternetAccount/configSchema.ts +1 -1
  17. package/src/ApolloInternetAccount/model.ts +11 -10
  18. package/src/ApolloJobModel.ts +1 -1
  19. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +8 -6
  20. package/src/ApolloRefNameAliasAdapter/index.ts +2 -2
  21. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +4 -4
  22. package/src/ApolloSequenceAdapter/index.ts +1 -1
  23. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +8 -7
  24. package/src/ApolloTextSearchAdapter/index.ts +1 -1
  25. package/src/BackendDrivers/BackendDriver.ts +7 -7
  26. package/src/BackendDrivers/CollaborationServerDriver.ts +14 -10
  27. package/src/BackendDrivers/DesktopFileDriver.ts +11 -10
  28. package/src/BackendDrivers/InMemoryFileDriver.ts +10 -6
  29. package/src/ChangeManager.ts +5 -5
  30. package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +8 -7
  31. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +35 -14
  32. package/src/FeatureDetailsWidget/AttributeKey.tsx +50 -0
  33. package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +104 -0
  34. package/src/FeatureDetailsWidget/Attributes.tsx +210 -367
  35. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -5
  36. package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +104 -0
  37. package/src/FeatureDetailsWidget/DefaultAttributeViewer.tsx +22 -0
  38. package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +4 -4
  39. package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -1
  40. package/src/FeatureDetailsWidget/Sequence.tsx +2 -2
  41. package/src/FeatureDetailsWidget/StringTextField.tsx +1 -1
  42. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +3 -3
  43. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +21 -21
  44. package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +4 -4
  45. package/src/FeatureDetailsWidget/model.ts +8 -3
  46. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -6
  47. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +13 -14
  48. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +9 -9
  49. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +6 -5
  50. package/src/LinearApolloDisplay/glyphs/Glyph.ts +7 -7
  51. package/src/LinearApolloDisplay/stateModel/base.ts +52 -10
  52. package/src/LinearApolloDisplay/stateModel/index.ts +4 -3
  53. package/src/LinearApolloDisplay/stateModel/layouts.ts +8 -39
  54. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +13 -12
  55. package/src/LinearApolloDisplay/stateModel/rendering.ts +59 -31
  56. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +221 -0
  57. package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +40 -0
  58. package/src/LinearApolloSixFrameDisplay/components/index.ts +2 -0
  59. package/src/LinearApolloSixFrameDisplay/configSchema.ts +7 -0
  60. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +821 -0
  61. package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +63 -0
  62. package/src/LinearApolloSixFrameDisplay/glyphs/index.ts +1 -0
  63. package/src/LinearApolloSixFrameDisplay/index.ts +2 -0
  64. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +261 -0
  65. package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +27 -0
  66. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +236 -0
  67. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +349 -0
  68. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +199 -0
  69. package/src/LinearApolloSixFrameDisplay/types.ts +1 -0
  70. package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
  71. package/src/OntologyManager/OntologyStore/fulltext.ts +8 -3
  72. package/src/OntologyManager/OntologyStore/index.test.ts +3 -1
  73. package/src/OntologyManager/OntologyStore/index.ts +19 -14
  74. package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -5
  75. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +11 -5
  76. package/src/OntologyManager/index.ts +8 -6
  77. package/src/OntologyManager/util.ts +3 -2
  78. package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
  79. package/src/TabularEditor/HybridGrid/Feature.tsx +9 -7
  80. package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +1 -1
  81. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +3 -2
  82. package/src/TabularEditor/HybridGrid/ToolBar.tsx +1 -1
  83. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +6 -6
  84. package/src/TabularEditor/TabularEditorPane.tsx +1 -1
  85. package/src/TabularEditor/model.ts +2 -2
  86. package/src/TabularEditor/types.ts +5 -2
  87. package/src/components/AddAssembly.tsx +182 -179
  88. package/src/components/AddChildFeature.tsx +6 -5
  89. package/src/components/AddFeature.tsx +211 -38
  90. package/src/components/AddRefSeqAliases.tsx +14 -12
  91. package/src/components/CopyFeature.tsx +8 -7
  92. package/src/components/CreateApolloAnnotation.tsx +9 -8
  93. package/src/components/DeleteAssembly.tsx +9 -8
  94. package/src/components/DeleteFeature.tsx +5 -4
  95. package/src/components/Dialog.tsx +1 -1
  96. package/src/components/DownloadGFF3.tsx +11 -10
  97. package/src/components/FilterFeatures.tsx +6 -4
  98. package/src/components/ImportFeatures.tsx +7 -6
  99. package/src/components/LogOut.tsx +5 -4
  100. package/src/components/ManageChecks.tsx +9 -8
  101. package/src/components/ManageUsers.tsx +11 -10
  102. package/src/components/OntologyTermAutocomplete.tsx +5 -5
  103. package/src/components/OntologyTermMultiSelect.tsx +6 -6
  104. package/src/components/OpenLocalFile.tsx +4 -3
  105. package/src/components/ViewChangeLog.tsx +7 -6
  106. package/src/components/ViewCheckResults.tsx +8 -7
  107. package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -0
  108. package/src/extensions/annotationFromJBrowseFeature.ts +11 -10
  109. package/src/extensions/annotationFromPileup.ts +6 -6
  110. package/src/index.ts +33 -50
  111. package/src/makeDisplayComponent.tsx +90 -37
  112. package/src/session/ClientDataStore.ts +21 -17
  113. package/src/session/session.ts +20 -26
  114. package/src/types.ts +4 -4
  115. package/src/util/annotationFeatureUtils.ts +1 -1
  116. package/src/util/index.ts +3 -3
  117. package/src/util/loadAssemblyIntoClient.ts +10 -3
  118. package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +0 -13
  119. package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +0 -707
  120. package/src/ApolloSixFrameRenderer/configSchema.ts +0 -7
  121. package/src/ApolloSixFrameRenderer/index.ts +0 -3
  122. package/src/SixFrameFeatureDisplay/components/TrackLines.tsx +0 -19
  123. package/src/SixFrameFeatureDisplay/components/index.ts +0 -1
  124. package/src/SixFrameFeatureDisplay/configSchema.ts +0 -21
  125. package/src/SixFrameFeatureDisplay/index.ts +0 -2
  126. package/src/SixFrameFeatureDisplay/stateModel.ts +0 -443
@@ -1,22 +1,23 @@
1
- import { AnnotationFeature } from '@apollo-annotation/mst'
1
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
2
2
  import {
3
3
  LocationEndChange,
4
4
  LocationStartChange,
5
5
  } from '@apollo-annotation/shared'
6
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
7
- import PluginManager from '@jbrowse/core/PluginManager'
8
- import { MenuItem } from '@jbrowse/core/ui'
9
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
10
- import { Theme } from '@mui/material'
6
+ import type PluginManager from '@jbrowse/core/PluginManager'
7
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
8
+ import { type MenuItem } from '@jbrowse/core/ui'
9
+ import { type Frame, getFrame } from '@jbrowse/core/util'
10
+ import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
11
+ import { type Theme } from '@mui/material'
11
12
  import { autorun } from 'mobx'
12
- import { Instance, addDisposer } from 'mobx-state-tree'
13
- import type { CSSProperties } from 'react'
13
+ import { type Instance, addDisposer } from 'mobx-state-tree'
14
+ import { type CSSProperties } from 'react'
15
+
16
+ import { type Coord } from '../components'
17
+ import { type Glyph } from '../glyphs/Glyph'
18
+ import { type CanvasMouseEvent } from '../types'
14
19
 
15
- import { Coord } from '../components'
16
- import { Glyph } from '../glyphs/Glyph'
17
- import { CanvasMouseEvent } from '../types'
18
20
  import { renderingModelFactory } from './rendering'
19
- import { Frame, getFrame } from '@jbrowse/core/util'
20
21
 
21
22
  export interface FeatureAndGlyphUnderMouse {
22
23
  feature: AnnotationFeature
@@ -1,12 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
3
- import PluginManager from '@jbrowse/core/PluginManager'
2
+ import type PluginManager from '@jbrowse/core/PluginManager'
3
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
4
4
  import { defaultCodonTable, doesIntersect2, revcom } from '@jbrowse/core/util'
5
- import { Theme } from '@mui/material'
5
+ import { type Theme } from '@mui/material'
6
6
  import { autorun } from 'mobx'
7
- import { Instance, addDisposer } from 'mobx-state-tree'
7
+ import { type Instance, addDisposer } from 'mobx-state-tree'
8
+
9
+ import { type ApolloSessionModel } from '../../session'
8
10
 
9
- import { ApolloSessionModel } from '../../session'
10
11
  import { layoutsModelFactory } from './layouts'
11
12
 
12
13
  export function renderingModelIntermediateFactory(
@@ -145,10 +146,10 @@ function colorCode(letter: string, theme?: Theme) {
145
146
  )
146
147
  }
147
148
 
148
- function codonColorCode(letter: string) {
149
+ function codonColorCode(letter: string, highContrast?: boolean) {
149
150
  const colorMap: Record<string, string | undefined> = {
150
151
  M: '#33ee33',
151
- '*': '#f44336',
152
+ '*': highContrast ? '#000000' : '#f44336',
152
153
  }
153
154
 
154
155
  return colorMap[letter.toUpperCase()]
@@ -188,6 +189,9 @@ function drawTranslation(
188
189
  seq: string,
189
190
  i: number,
190
191
  reverse: boolean,
192
+ showStartCodons: boolean,
193
+ showStopCodons: boolean,
194
+ highContrast: boolean,
191
195
  ) {
192
196
  let codonSeq: string = seq.slice(i, i + 3).toUpperCase()
193
197
  if (reverse) {
@@ -198,8 +202,12 @@ function drawTranslation(
198
202
  if (!codonLetter) {
199
203
  return
200
204
  }
201
- const fillColor = codonColorCode(codonLetter)
202
- if (fillColor) {
205
+ const fillColor = codonColorCode(codonLetter, highContrast)
206
+ if (
207
+ fillColor &&
208
+ ((showStopCodons && codonLetter == '*') ||
209
+ (showStartCodons && codonLetter != '*'))
210
+ ) {
203
211
  seqTrackctx.fillStyle = fillColor
204
212
  seqTrackctx.fillRect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
205
213
  }
@@ -224,11 +232,13 @@ export function sequenceRenderingModelFactory(
224
232
  addDisposer(
225
233
  self,
226
234
  autorun(
227
- async () => {
235
+ () => {
236
+ const { theme } = self
228
237
  if (!self.lgv.initialized || self.regionCannotBeRendered()) {
229
238
  return
230
239
  }
231
- if (self.lgv.bpPerPx > 3) {
240
+ const trnslWidthPx = 3 / self.lgv.bpPerPx
241
+ if (trnslWidthPx < 1) {
232
242
  return
233
243
  }
234
244
  const seqTrackctx = self.seqTrackCanvas?.getContext('2d')
@@ -247,30 +257,43 @@ export function sequenceRenderingModelFactory(
247
257
  ? [3, 2, 1, 0, 0, -1, -2, -3]
248
258
  : [3, 2, 1, -1, -2, -3]
249
259
  let height = 0
250
- for (const frame of frames) {
251
- const frameColor = self.theme?.palette.framesCDS.at(frame)?.main
252
- if (frameColor) {
253
- seqTrackctx.fillStyle = frameColor
254
- seqTrackctx.fillRect(
255
- 0,
256
- height,
257
- self.lgv.dynamicBlocks.totalWidthPx,
258
- self.sequenceRowHeight,
259
- )
260
+ if (theme) {
261
+ for (const frame of frames) {
262
+ let frameColor = theme.palette.framesCDS.at(frame)?.main
263
+ if (frameColor) {
264
+ let offsetPx = 0
265
+ if (self.highContrast) {
266
+ frameColor = 'white'
267
+ offsetPx = 1
268
+ // eslint-disable-next-line prefer-destructuring
269
+ seqTrackctx.fillStyle = theme.palette.grey[200]
270
+ seqTrackctx.fillRect(
271
+ 0,
272
+ height,
273
+ self.lgv.dynamicBlocks.totalWidthPx,
274
+ self.sequenceRowHeight,
275
+ )
276
+ }
277
+ seqTrackctx.fillStyle = frameColor
278
+ seqTrackctx.fillRect(
279
+ 0 + offsetPx,
280
+ height + offsetPx,
281
+ self.lgv.dynamicBlocks.totalWidthPx - 2 * offsetPx,
282
+ self.sequenceRowHeight - 2 * offsetPx,
283
+ )
284
+ }
285
+ height += self.sequenceRowHeight
260
286
  }
261
- height += self.sequenceRowHeight
262
287
  }
263
288
 
264
289
  for (const [idx, region] of self.regions.entries()) {
265
- const driver = (
290
+ const { apolloDataStore } =
266
291
  self.session as unknown as ApolloSessionModel
267
- ).apolloDataStore.getBackendDriver(region.assemblyName)
268
-
269
- if (!driver) {
270
- throw new Error('Failed to get the backend driver')
271
- }
272
- const { seq } = await driver.getSequence(region)
273
-
292
+ const assembly = apolloDataStore.assemblies.get(
293
+ region.assemblyName,
294
+ )
295
+ const ref = assembly?.getByRefName(region.refName)
296
+ const seq = ref?.getSequence(region.start, region.end)
274
297
  if (!seq) {
275
298
  return
276
299
  }
@@ -283,7 +306,6 @@ export function sequenceRenderingModelFactory(
283
306
  coord: region.start + i,
284
307
  regionNumber: idx,
285
308
  })?.offsetPx ?? 0) - self.lgv.offsetPx
286
- const trnslWidthPx = 3 / self.lgv.bpPerPx
287
309
  const trnslStartPx = self.lgv.displayedRegions[idx].reversed
288
310
  ? trnslXOffset - trnslWidthPx
289
311
  : trnslXOffset
@@ -301,6 +323,9 @@ export function sequenceRenderingModelFactory(
301
323
  seq,
302
324
  i,
303
325
  false,
326
+ self.showStartCodons,
327
+ self.showStopCodons,
328
+ self.highContrast,
304
329
  )
305
330
  }
306
331
  }
@@ -375,6 +400,9 @@ export function sequenceRenderingModelFactory(
375
400
  seq,
376
401
  i,
377
402
  true,
403
+ self.showStartCodons,
404
+ self.showStopCodons,
405
+ self.highContrast,
378
406
  )
379
407
  }
380
408
  }
@@ -0,0 +1,221 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
2
+ /* eslint-disable @typescript-eslint/no-misused-promises */
3
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
4
+ import { Menu, type MenuItem } from '@jbrowse/core/ui'
5
+ import {
6
+ type AbstractSessionModel,
7
+ doesIntersect2,
8
+ getContainingView,
9
+ } from '@jbrowse/core/util'
10
+ import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
11
+ import ErrorIcon from '@mui/icons-material/Error'
12
+ import { Alert, Avatar, Tooltip, useTheme } from '@mui/material'
13
+ import { observer } from 'mobx-react'
14
+ import React, { useEffect, useState } from 'react'
15
+ import { makeStyles } from 'tss-react/mui'
16
+
17
+ import { type LinearApolloSixFrameDisplay as LinearApolloSixFrameDisplayI } from '../stateModel'
18
+
19
+ import { TrackLines } from './TrackLines'
20
+
21
+ interface LinearApolloSixFrameDisplayProps {
22
+ model: LinearApolloSixFrameDisplayI
23
+ }
24
+ export type Coord = [number, number]
25
+
26
+ const useStyles = makeStyles()((theme) => ({
27
+ canvasContainer: {
28
+ position: 'relative',
29
+ left: 0,
30
+ },
31
+ canvas: {
32
+ position: 'absolute',
33
+ left: 0,
34
+ },
35
+ ellipses: {
36
+ textOverflow: 'ellipsis',
37
+ overflow: 'hidden',
38
+ },
39
+ avatar: {
40
+ position: 'absolute',
41
+ color: theme.palette.warning.light,
42
+ backgroundColor: theme.palette.warning.contrastText,
43
+ },
44
+ }))
45
+
46
+ export const LinearApolloSixFrameDisplay = observer(
47
+ function LinearApolloSixFrameDisplay(
48
+ props: LinearApolloSixFrameDisplayProps,
49
+ ) {
50
+ const theme = useTheme()
51
+ const { model } = props
52
+ const {
53
+ apolloRowHeight,
54
+ contextMenuItems: getContextMenuItems,
55
+ cursor,
56
+ featuresHeight,
57
+ isShown,
58
+ onMouseDown,
59
+ onMouseLeave,
60
+ onMouseMove,
61
+ onMouseUp,
62
+ regionCannotBeRendered,
63
+ session,
64
+ setCanvas,
65
+ setCollaboratorCanvas,
66
+ setOverlayCanvas,
67
+ setTheme,
68
+ } = model
69
+ const { classes } = useStyles()
70
+ const lgv = getContainingView(model) as unknown as LinearGenomeViewModel
71
+
72
+ useEffect(() => {
73
+ setTheme(theme)
74
+ }, [theme, setTheme])
75
+ const [contextCoord, setContextCoord] = useState<Coord>()
76
+ const [contextMenuItems, setContextMenuItems] = useState<MenuItem[]>([])
77
+ const message = regionCannotBeRendered()
78
+ if (!isShown) {
79
+ return null
80
+ }
81
+ const { assemblyManager } = session as unknown as AbstractSessionModel
82
+ return (
83
+ <>
84
+ <div
85
+ className={classes.canvasContainer}
86
+ style={{
87
+ width: lgv.dynamicBlocks.totalWidthPx,
88
+ height: featuresHeight,
89
+ }}
90
+ onContextMenu={(event) => {
91
+ event.preventDefault()
92
+ if (contextMenuItems.length > 0) {
93
+ // There's already a context menu open, so close it
94
+ setContextMenuItems([])
95
+ } else {
96
+ const coord: [number, number] = [event.clientX, event.clientY]
97
+ setContextCoord(coord)
98
+ setContextMenuItems(getContextMenuItems(coord))
99
+ }
100
+ }}
101
+ >
102
+ {message ? (
103
+ <Alert severity="warning" classes={{ message: classes.ellipses }}>
104
+ <Tooltip title={message}>
105
+ <div>{message}</div>
106
+ </Tooltip>
107
+ </Alert>
108
+ ) : (
109
+ // Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
110
+ // https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
111
+ <>
112
+ <TrackLines model={model} strand={1} />
113
+ <TrackLines model={model} strand={-1} />
114
+ <canvas
115
+ ref={async (node: HTMLCanvasElement) => {
116
+ await Promise.resolve()
117
+ setCollaboratorCanvas(node)
118
+ }}
119
+ width={lgv.dynamicBlocks.totalWidthPx}
120
+ height={featuresHeight}
121
+ className={classes.canvas}
122
+ data-testid="collaboratorCanvas"
123
+ />
124
+ <canvas
125
+ ref={async (node: HTMLCanvasElement) => {
126
+ await Promise.resolve()
127
+ setCanvas(node)
128
+ }}
129
+ width={lgv.dynamicBlocks.totalWidthPx}
130
+ height={featuresHeight}
131
+ className={classes.canvas}
132
+ data-testid="canvas"
133
+ />
134
+ <canvas
135
+ ref={async (node: HTMLCanvasElement) => {
136
+ await Promise.resolve()
137
+ setOverlayCanvas(node)
138
+ }}
139
+ width={lgv.dynamicBlocks.totalWidthPx}
140
+ height={featuresHeight}
141
+ onMouseMove={onMouseMove}
142
+ onMouseLeave={onMouseLeave}
143
+ onMouseDown={onMouseDown}
144
+ onMouseUp={onMouseUp}
145
+ className={classes.canvas}
146
+ style={{ cursor: cursor ?? 'default' }}
147
+ data-testid="overlayCanvas"
148
+ />
149
+ {lgv.displayedRegions.flatMap((region, idx) => {
150
+ const assembly = assemblyManager.get(region.assemblyName)
151
+ return [...session.apolloDataStore.checkResults.values()]
152
+ .filter(
153
+ (checkResult) =>
154
+ assembly?.isValidRefName(checkResult.refSeq) &&
155
+ assembly.getCanonicalRefName(checkResult.refSeq) ===
156
+ region.refName &&
157
+ doesIntersect2(
158
+ region.start,
159
+ region.end,
160
+ checkResult.start,
161
+ checkResult.end,
162
+ ),
163
+ )
164
+ .map((checkResult) => {
165
+ const left =
166
+ (lgv.bpToPx({
167
+ refName: region.refName,
168
+ coord: checkResult.start,
169
+ regionNumber: idx,
170
+ })?.offsetPx ?? 0) - lgv.offsetPx
171
+ const [feature] = checkResult.ids
172
+ if (!feature || !feature.parent?.looksLikeGene) {
173
+ return null
174
+ }
175
+ const top = 0
176
+ const height = apolloRowHeight
177
+ return (
178
+ <Tooltip
179
+ key={checkResult._id}
180
+ title={checkResult.message}
181
+ >
182
+ <Avatar
183
+ className={classes.avatar}
184
+ style={{ top, left, height, width: height }}
185
+ >
186
+ <ErrorIcon />
187
+ </Avatar>
188
+ </Tooltip>
189
+ )
190
+ })
191
+ })}
192
+ <Menu
193
+ open={contextMenuItems.length > 0}
194
+ onMenuItemClick={(_, callback) => {
195
+ callback()
196
+ setContextMenuItems([])
197
+ }}
198
+ onClose={() => {
199
+ setContextMenuItems([])
200
+ }}
201
+ TransitionProps={{
202
+ onExit: () => {
203
+ setContextMenuItems([])
204
+ },
205
+ }}
206
+ anchorReference="anchorPosition"
207
+ anchorPosition={
208
+ contextCoord
209
+ ? { top: contextCoord[1], left: contextCoord[0] }
210
+ : undefined
211
+ }
212
+ style={{ zIndex: theme.zIndex.tooltip }}
213
+ menuItems={contextMenuItems}
214
+ />
215
+ </>
216
+ )}
217
+ </div>
218
+ </>
219
+ )
220
+ },
221
+ )
@@ -0,0 +1,40 @@
1
+ import { observer } from 'mobx-react'
2
+ import React from 'react'
3
+
4
+ import { type LinearApolloSixFrameDisplay } from '../stateModel'
5
+
6
+ export const TrackLines = observer(function TrackLines({
7
+ model,
8
+ strand,
9
+ }: {
10
+ model: LinearApolloSixFrameDisplay
11
+ strand: number
12
+ }) {
13
+ const { apolloRowHeight, highestRow, lastRowTooltipBufferHeight } = model
14
+ return strand == 1 ? (
15
+ <div
16
+ style={{
17
+ position: 'absolute',
18
+ left: 0,
19
+ top: (apolloRowHeight * (highestRow + 1)) / 2 - 2,
20
+ width: '100%',
21
+ }}
22
+ >
23
+ <hr style={{ margin: 0, top: 0, color: 'black' }} />
24
+ </div>
25
+ ) : (
26
+ <div
27
+ style={{
28
+ position: 'absolute',
29
+ left: 0,
30
+ bottom:
31
+ (apolloRowHeight * (highestRow + 1) + lastRowTooltipBufferHeight) /
32
+ 2 +
33
+ 3,
34
+ width: '100%',
35
+ }}
36
+ >
37
+ <hr style={{ margin: 0, top: 0, color: 'black' }} />
38
+ </div>
39
+ )
40
+ })
@@ -0,0 +1,2 @@
1
+ export * from './LinearApolloSixFrameDisplay'
2
+ export * from './TrackLines'
@@ -0,0 +1,7 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration'
2
+
3
+ export const configSchema = ConfigurationSchema(
4
+ 'LinearApolloSixFrameDisplay',
5
+ {},
6
+ { explicitIdentifier: 'displayId', explicitlyTyped: true },
7
+ )