@apollo-annotation/jbrowse-plugin-apollo 0.1.20 → 0.2.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.
Files changed (61) hide show
  1. package/dist/index.esm.js +552 -642
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +560 -650
  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 +11294 -1232
  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 -5
  12. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +4 -2
  13. package/src/ApolloInternetAccount/configSchema.ts +1 -1
  14. package/src/ApolloInternetAccount/model.ts +5 -10
  15. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +1 -1
  16. package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +4 -5
  17. package/src/BackendDrivers/DesktopFileDriver.ts +3 -2
  18. package/src/FeatureDetailsWidget/Attributes.tsx +1 -6
  19. package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -0
  20. package/src/FeatureDetailsWidget/StringTextField.tsx +1 -0
  21. package/src/FeatureDetailsWidget/TranscriptBasic.tsx +131 -382
  22. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +209 -284
  23. package/src/FeatureDetailsWidget/model.ts +4 -4
  24. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +1 -4
  25. package/src/LinearApolloDisplay/configSchema.ts +5 -14
  26. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +25 -3
  27. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +95 -32
  28. package/src/LinearApolloDisplay/index.ts +1 -1
  29. package/src/LinearApolloDisplay/stateModel/base.ts +104 -17
  30. package/src/LinearApolloDisplay/stateModel/index.ts +1 -1
  31. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +1 -1
  32. package/src/LinearApolloDisplay/stateModel/rendering.ts +1 -1
  33. package/src/OntologyManager/OntologyStore/fulltext.ts +5 -2
  34. package/src/OntologyManager/OntologyStore/index.ts +25 -22
  35. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +8 -3
  36. package/src/OntologyManager/index.ts +31 -8
  37. package/src/SixFrameFeatureDisplay/stateModel.ts +1 -1
  38. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +1 -0
  39. package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
  40. package/src/TabularEditor/model.ts +1 -1
  41. package/src/components/AddChildFeature.tsx +1 -0
  42. package/src/components/AddFeature.tsx +1 -1
  43. package/src/components/AddRefSeqAliases.tsx +1 -0
  44. package/src/components/CopyFeature.tsx +1 -0
  45. package/src/components/DeleteAssembly.tsx +1 -0
  46. package/src/components/DeleteFeature.tsx +1 -0
  47. package/src/components/LogOut.tsx +2 -1
  48. package/src/components/ManageChecks.tsx +1 -1
  49. package/src/components/ManageUsers.tsx +2 -1
  50. package/src/components/OntologyTermAutocomplete.tsx +7 -9
  51. package/src/components/OntologyTermMultiSelect.tsx +2 -1
  52. package/src/components/OpenLocalFile.tsx +3 -1
  53. package/src/components/ViewChangeLog.tsx +1 -0
  54. package/src/components/ViewCheckResults.tsx +1 -0
  55. package/src/config.ts +5 -0
  56. package/src/extensions/annotationFromPileup.ts +1 -1
  57. package/src/index.ts +2 -2
  58. package/src/makeDisplayComponent.tsx +77 -32
  59. package/src/session/ClientDataStore.ts +1 -1
  60. package/src/session/session.ts +2 -1
  61. package/src/LinearApolloDisplay/stateModel/trackHeightMixin.ts +0 -43
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
1
2
  /* eslint-disable @typescript-eslint/no-misused-promises */
2
3
  import { AnnotationFeature } from '@apollo-annotation/mst'
3
4
  import { DeleteFeatureChange } from '@apollo-annotation/shared'
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
1
2
  import {
2
3
  Button,
3
4
  DialogActions,
@@ -49,7 +50,7 @@ export function LogOut({ handleClose, session }: DeleteAssemblyProps) {
49
50
  event.preventDefault()
50
51
  setErrorMessage('')
51
52
  selectedInternetAccount.removeToken()
52
- window.location.reload()
53
+ globalThis.location.reload()
53
54
  }
54
55
 
55
56
  return (
@@ -182,7 +182,7 @@ export function ManageChecks({ handleClose, session }: ManageChecksProps) {
182
182
  }
183
183
  } else {
184
184
  const index = checks.indexOf(_id, 0)
185
- if (index > -1) {
185
+ if (index !== -1) {
186
186
  checks.splice(index, 1)
187
187
  }
188
188
  setSelectedChecks(checks)
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
1
2
  /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
2
3
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
3
4
  /* eslint-disable @typescript-eslint/no-misused-promises */
@@ -154,7 +155,7 @@ export function ManageUsers({
154
155
  key={`delete-${params.id}`}
155
156
  icon={<DeleteIcon />}
156
157
  onClick={async () => {
157
- if (window.confirm('Delete this user?')) {
158
+ if (globalThis.confirm('Delete this user?')) {
158
159
  await deleteUser(params.id)
159
160
  }
160
161
  }}
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4
- import { AbstractSessionModel, isAbortException } from '@jbrowse/core/util'
2
+
3
+ import { AbstractSessionModel } from '@jbrowse/core/util'
4
+ import { isAbortException } from '@jbrowse/core/util/aborting'
5
5
  import {
6
6
  Autocomplete,
7
7
  AutocompleteRenderInputParams,
@@ -76,7 +76,6 @@ export function OntologyTermAutocomplete({
76
76
  // effect for clearing choices when not open
77
77
  useEffect(() => {
78
78
  if (!open) {
79
- // eslint-disable-next-line unicorn/no-useless-undefined
80
79
  setTermChoices(undefined)
81
80
  }
82
81
  }, [open])
@@ -93,7 +92,7 @@ export function OntologyTermAutocomplete({
93
92
  setCurrentOntologyTerm(term)
94
93
  }
95
94
  },
96
- (error) => {
95
+ (error: unknown) => {
97
96
  if (!signal.aborted && !isAbortException(error)) {
98
97
  setCurrentOntologyTermInvalid(String(error))
99
98
  }
@@ -116,10 +115,10 @@ export function OntologyTermAutocomplete({
116
115
  setTermChoices(soTerms)
117
116
  }
118
117
  },
119
- (error) => {
118
+ (error: unknown) => {
120
119
  if (!signal.aborted && !isAbortException(error)) {
121
120
  ;(session as unknown as AbstractSessionModel).notify(
122
- error.message,
121
+ error instanceof Error ? error.message : String(error),
123
122
  'error',
124
123
  )
125
124
  }
@@ -145,7 +144,6 @@ export function OntologyTermAutocomplete({
145
144
  return
146
145
  }
147
146
  if (typeof newValue === 'string') {
148
- // eslint-disable-next-line unicorn/no-useless-undefined
149
147
  setCurrentOntologyTerm(undefined)
150
148
  onChange(valueString, newValue)
151
149
  } else if (newValue.lbl !== valueString) {
@@ -212,7 +210,7 @@ async function getCurrentTerm(
212
210
  currentTermLabel,
213
211
  { includeSubclasses: false },
214
212
  )
215
- const term = terms.find(filterTerms ?? (() => true))
213
+ const term = terms.find((term) => (filterTerms ?? (() => true))(term))
216
214
  if (!term) {
217
215
  throw new Error(`not a valid ${ontologyStore.ontologyName} term`)
218
216
  }
@@ -1,6 +1,7 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
1
2
  /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
2
3
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
3
- import { isAbortException } from '@jbrowse/core/util'
4
+ import { isAbortException } from '@jbrowse/core/util/aborting'
4
5
  import {
5
6
  Autocomplete,
6
7
  AutocompleteRenderGetTagProps,
@@ -1,3 +1,5 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
2
+ /* eslint-disable @typescript-eslint/unbound-method */
1
3
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
4
  /* eslint-disable @typescript-eslint/no-misused-promises */
3
5
  import { AbstractSessionModel, isElectron } from '@jbrowse/core/util'
@@ -35,7 +37,7 @@ export function OpenLocalFile({ handleClose, session }: OpenLocalFileProps) {
35
37
  const { apolloDataStore } = session
36
38
  const { addAssembly, addSessionAssembly, assemblyManager, notify } =
37
39
  session as unknown as AbstractSessionModel & {
38
- // eslint-disable-next-line @typescript-eslint/ban-types
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
39
41
  addSessionAssembly: Function
40
42
  }
41
43
 
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
1
2
  /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
2
3
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
3
4
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
1
2
  /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
2
3
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
4
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
package/src/config.ts CHANGED
@@ -5,6 +5,11 @@ import { OntologyRecordConfiguration } from './OntologyManager'
5
5
 
6
6
  const ApolloPluginConfigurationSchema = ConfigurationSchema('ApolloPlugin', {
7
7
  ontologies: types.array(OntologyRecordConfiguration),
8
+ featureTypeOntologyName: {
9
+ description: 'Name of the feature type ontology',
10
+ type: 'string',
11
+ defaultValue: 'Sequence Ontology',
12
+ },
8
13
  })
9
14
 
10
15
  export default ApolloPluginConfigurationSchema
@@ -17,7 +17,7 @@ import { ApolloSessionModel } from '../session'
17
17
 
18
18
  function parseCigar(cigar: string): [string | undefined, number][] {
19
19
  return (cigar.toUpperCase().match(/\d+\D/g) ?? []).map((op) => {
20
- return [(op.match(/\D/) ?? [])[0], Number.parseInt(op, 10)]
20
+ return [(/\D/.exec(op) ?? [])[0], Number.parseInt(op, 10)]
21
21
  })
22
22
  }
23
23
 
package/src/index.ts CHANGED
@@ -64,7 +64,7 @@ import {
64
64
  } from './FeatureDetailsWidget'
65
65
  import {
66
66
  stateModelFactory as LinearApolloDisplayStateModelFactory,
67
- configSchemaFactory as linearApolloDisplayConfigSchemaFactory,
67
+ configSchema as linearApolloDisplayConfigSchema,
68
68
  } from './LinearApolloDisplay'
69
69
  import {
70
70
  DisplayComponent,
@@ -174,7 +174,7 @@ export default class ApolloPlugin extends Plugin {
174
174
  })
175
175
 
176
176
  pluginManager.addDisplayType(() => {
177
- const configSchema = linearApolloDisplayConfigSchemaFactory(pluginManager)
177
+ const configSchema = linearApolloDisplayConfigSchema
178
178
  return new DisplayType({
179
179
  name: 'LinearApolloDisplay',
180
180
  configSchema,
@@ -3,7 +3,7 @@ import PluginManager from '@jbrowse/core/PluginManager'
3
3
  import type LinearGenomeViewPlugin from '@jbrowse/plugin-linear-genome-view'
4
4
  import ExpandLessIcon from '@mui/icons-material/ExpandLess'
5
5
  import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
6
- import { Typography, alpha } from '@mui/material'
6
+ import { Alert, Typography, alpha } from '@mui/material'
7
7
  import { observer } from 'mobx-react'
8
8
  import React, { useCallback, useEffect, useRef } from 'react'
9
9
  import { makeStyles } from 'tss-react/mui'
@@ -14,6 +14,9 @@ import { TrackLines } from './SixFrameFeatureDisplay/components'
14
14
  import { SixFrameFeatureDisplay } from './SixFrameFeatureDisplay/stateModel'
15
15
  import { TabularEditorPane } from './TabularEditor'
16
16
 
17
+ import { getSession } from '@jbrowse/core/util'
18
+ import { ApolloSessionModel } from './session'
19
+
17
20
  const accordionControlHeight = 12
18
21
 
19
22
  const useStyles = makeStyles()((theme) => ({
@@ -52,6 +55,11 @@ const useStyles = makeStyles()((theme) => ({
52
55
  // position: 'relative',
53
56
  userSelect: 'none',
54
57
  },
58
+ alertContainer: {
59
+ display: 'flex',
60
+ alignItems: 'center',
61
+ justifyContent: 'center',
62
+ },
55
63
  }))
56
64
 
57
65
  function scrollSelectedFeatureIntoView(
@@ -87,9 +95,9 @@ const ResizeHandle = ({
87
95
  (event: MouseEvent) => {
88
96
  event.stopPropagation()
89
97
  event.preventDefault()
90
- window.removeEventListener('mousemove', mouseMove)
91
- window.removeEventListener('mouseup', cancelDrag)
92
- window.removeEventListener('mouseleave', cancelDrag)
98
+ globalThis.removeEventListener('mousemove', mouseMove)
99
+ globalThis.removeEventListener('mouseup', cancelDrag)
100
+ globalThis.removeEventListener('mouseleave', cancelDrag)
93
101
  },
94
102
  [mouseMove],
95
103
  )
@@ -99,9 +107,9 @@ const ResizeHandle = ({
99
107
  <div
100
108
  onMouseDown={(event: React.MouseEvent) => {
101
109
  event.stopPropagation()
102
- window.addEventListener('mousemove', mouseMove)
103
- window.addEventListener('mouseup', cancelDrag)
104
- window.addEventListener('mouseleave', cancelDrag)
110
+ globalThis.addEventListener('mousemove', mouseMove)
111
+ globalThis.addEventListener('mouseup', cancelDrag)
112
+ globalThis.addEventListener('mouseleave', cancelDrag)
105
113
  }}
106
114
  onClick={(e) => {
107
115
  e.stopPropagation()
@@ -155,51 +163,88 @@ export const DisplayComponent = observer(function DisplayComponent({
155
163
  }: {
156
164
  model: LinearApolloDisplayI
157
165
  }) {
166
+ const session = getSession(model) as unknown as ApolloSessionModel
167
+ const { ontologyManager } = session.apolloDataStore
168
+ const { featureTypeOntology } = ontologyManager
169
+ const ontologyStore = featureTypeOntology?.dataStore
170
+
158
171
  const { classes } = useStyles()
159
172
 
160
173
  const {
174
+ detailsHeight,
175
+ graphical,
161
176
  height: overallHeight,
162
177
  isShown,
163
178
  selectedFeature,
179
+ table,
164
180
  tabularEditor,
165
181
  toggleShown,
166
182
  } = model
167
- const detailsHeight = tabularEditor.isShown ? model.detailsHeight : 0
168
- const featureAreaHeight = isShown
169
- ? overallHeight - detailsHeight - accordionControlHeight * 2
170
- : 0
171
-
172
- const onDetailsResize = (delta: number) => {
173
- model.setDetailsHeight(model.detailsHeight - delta)
174
- }
175
183
 
176
184
  const canvasScrollContainerRef = useRef<HTMLDivElement>(null)
177
185
  useEffect(() => {
178
186
  scrollSelectedFeatureIntoView(model, canvasScrollContainerRef)
179
187
  }, [model, selectedFeature])
180
- return (
181
- <div className={classes.details} style={{ height: overallHeight }}>
182
- <AccordionControl
183
- open={isShown}
184
- title="Graphical"
185
- onClick={toggleShown}
186
- />
188
+
189
+ const onDetailsResize = (delta: number) => {
190
+ model.setDetailsHeight(detailsHeight - delta)
191
+ }
192
+
193
+ if (!ontologyStore) {
194
+ return (
195
+ <div className={classes.alertContainer}>
196
+ <Alert severity="error">Could not load feature type ontology.</Alert>
197
+ </div>
198
+ )
199
+ }
200
+
201
+ if (graphical && table) {
202
+ const tabularHeight = tabularEditor.isShown ? detailsHeight : 0
203
+ const featureAreaHeight = isShown
204
+ ? overallHeight - detailsHeight - accordionControlHeight * 2
205
+ : 0
206
+ return (
207
+ <div style={{ height: overallHeight }}>
208
+ <AccordionControl
209
+ open={isShown}
210
+ title="Graphical"
211
+ onClick={toggleShown}
212
+ />
213
+ <div
214
+ className={classes.shading}
215
+ ref={canvasScrollContainerRef}
216
+ style={{ height: featureAreaHeight }}
217
+ >
218
+ <LinearApolloDisplay model={model} {...other} />
219
+ </div>
220
+ <AccordionControl
221
+ title="Table"
222
+ open={tabularEditor.isShown}
223
+ onClick={tabularEditor.togglePane}
224
+ onResize={onDetailsResize}
225
+ />
226
+ <div className={classes.details} style={{ height: tabularHeight }}>
227
+ <TabularEditorPane model={model} />
228
+ </div>
229
+ </div>
230
+ )
231
+ }
232
+
233
+ if (graphical) {
234
+ return (
187
235
  <div
188
236
  className={classes.shading}
189
237
  ref={canvasScrollContainerRef}
190
- style={{ height: featureAreaHeight }}
238
+ style={{ height: overallHeight }}
191
239
  >
192
240
  <LinearApolloDisplay model={model} {...other} />
193
241
  </div>
194
- <AccordionControl
195
- title="Table"
196
- open={tabularEditor.isShown}
197
- onClick={tabularEditor.togglePane}
198
- onResize={onDetailsResize}
199
- />
200
- <div style={{ height: detailsHeight }}>
201
- <TabularEditorPane model={model} />
202
- </div>
242
+ )
243
+ }
244
+
245
+ return (
246
+ <div className={classes.details} style={{ height: overallHeight }}>
247
+ <TabularEditorPane model={model} />
203
248
  </div>
204
249
  )
205
250
  })
@@ -51,6 +51,7 @@ export function clientDataStoreFactory(
51
51
  typeName: types.optional(types.literal('Client'), 'Client'),
52
52
  assemblies: types.map(ApolloAssembly),
53
53
  checkResults: types.map(CheckResult),
54
+ ontologyManager: types.optional(OntologyManagerType, {}),
54
55
  })
55
56
  .views((self) => ({
56
57
  get internetAccounts() {
@@ -136,7 +137,6 @@ export function clientDataStoreFactory(
136
137
  desktopFileDriver: isElectron
137
138
  ? new DesktopFileDriver(self as unknown as ClientDataStoreType)
138
139
  : undefined,
139
- ontologyManager: OntologyManagerType.create(),
140
140
  }))
141
141
  .actions((self) => ({
142
142
  afterCreate() {
@@ -419,6 +419,7 @@ export function extendSession(
419
419
  ([, assembly]) => assembly.backendDriverType === 'InMemoryFileDriver',
420
420
  ),
421
421
  )
422
+ // @ts-expect-error ontologyManager isn't actually required
422
423
  snap.apolloDataStore = {
423
424
  typeName: 'Client',
424
425
  assemblies,
@@ -433,5 +434,5 @@ export type ApolloSessionStateModel = ReturnType<typeof extendSession>
433
434
  // @ts-expect-error Snapshots seem to mess up types here
434
435
  // eslint disable because of
435
436
  // https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
436
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
437
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
437
438
  export interface ApolloSessionModel extends Instance<ApolloSessionStateModel> {}
@@ -1,43 +0,0 @@
1
- // TODO: get this added to LGV runtime exports so we don't have to duplicate it
2
- import { getConf } from '@jbrowse/core/configuration'
3
- import { types } from 'mobx-state-tree'
4
-
5
- const minDisplayHeight = 20
6
-
7
- /**
8
- * #stateModel TrackHeightMixin
9
- * #category display
10
- */
11
- export const TrackHeightMixin = types
12
- .model({
13
- heightPreConfig: types.maybe(
14
- types.refinement(
15
- 'displayHeight',
16
- types.number,
17
- (n) => n >= minDisplayHeight,
18
- ),
19
- ),
20
- })
21
- .volatile(() => ({
22
- scrollTop: 0,
23
- }))
24
- .views((self) => ({
25
- get height() {
26
- // @ts-expect-error getConf needs self.configuration
27
- return self.heightPreConfig ?? (getConf(self, 'height') as number)
28
- },
29
- }))
30
- .actions((self) => ({
31
- setScrollTop(scrollTop: number) {
32
- self.scrollTop = scrollTop
33
- },
34
- setHeight(displayHeight: number) {
35
- self.heightPreConfig = Math.max(displayHeight, minDisplayHeight)
36
- return self.height
37
- },
38
- resizeHeight(distance: number) {
39
- const oldHeight = self.height
40
- const newHeight = this.setHeight(self.height + distance)
41
- return newHeight - oldHeight
42
- },
43
- }))