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

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 (56) hide show
  1. package/dist/index.esm.js +2679 -850
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +2676 -847
  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 +5194 -1258
  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 +18 -0
  13. package/src/ChangeManager.ts +10 -6
  14. package/src/FeatureDetailsWidget/Attributes.tsx +8 -3
  15. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +12 -20
  16. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +929 -175
  17. package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +4 -0
  18. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +1 -1
  19. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +48 -60
  20. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +244 -51
  21. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +46 -1
  22. package/src/LinearApolloDisplay/glyphs/Glyph.ts +9 -1
  23. package/src/LinearApolloDisplay/stateModel/base.ts +29 -0
  24. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +51 -35
  25. package/src/LinearApolloDisplay/stateModel/rendering.ts +2 -1
  26. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +7 -2
  27. package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +12 -20
  28. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +243 -124
  29. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +42 -1
  30. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +19 -3
  31. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +53 -34
  32. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +4 -2
  33. package/src/OntologyManager/index.ts +4 -1
  34. package/src/TabularEditor/HybridGrid/Feature.tsx +4 -0
  35. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +108 -16
  36. package/src/components/AddAssemblyAliases.tsx +114 -0
  37. package/src/components/AddChildFeature.tsx +3 -6
  38. package/src/components/AddFeature.tsx +14 -15
  39. package/src/components/CopyFeature.tsx +2 -4
  40. package/src/components/CreateApolloAnnotation.tsx +334 -151
  41. package/src/components/DeleteFeature.tsx +358 -11
  42. package/src/components/DownloadGFF3.tsx +20 -1
  43. package/src/components/FilterTranscripts.tsx +86 -0
  44. package/src/components/MergeExons.tsx +193 -0
  45. package/src/components/MergeTranscripts.tsx +185 -0
  46. package/src/components/SplitExon.tsx +134 -0
  47. package/src/components/index.ts +3 -0
  48. package/src/config.ts +5 -0
  49. package/src/extensions/annotationFromJBrowseFeature.ts +2 -0
  50. package/src/extensions/annotationFromPileup.ts +99 -89
  51. package/src/session/session.ts +26 -13
  52. package/src/util/annotationFeatureUtils.ts +65 -0
  53. package/src/util/copyToClipboard.ts +21 -0
  54. package/src/util/glyphUtils.ts +49 -0
  55. package/src/util/index.ts +2 -0
  56. package/src/util/mouseEventsUtils.ts +113 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollo-annotation/jbrowse-plugin-apollo",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Apollo plugin for JBrowse 2",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -48,9 +48,9 @@
48
48
  }
49
49
  },
50
50
  "dependencies": {
51
- "@apollo-annotation/common": "^0.3.6",
52
- "@apollo-annotation/mst": "^0.3.6",
53
- "@apollo-annotation/shared": "^0.3.6",
51
+ "@apollo-annotation/common": "^0.3.7",
52
+ "@apollo-annotation/mst": "^0.3.7",
53
+ "@apollo-annotation/shared": "^0.3.7",
54
54
  "@emotion/react": "^11.10.6",
55
55
  "@emotion/styled": "^11.10.6",
56
56
  "@gmod/gff": "1.2.0",
@@ -10,6 +10,7 @@ import {
10
10
  ImportFeatures,
11
11
  ManageUsers,
12
12
  } from '../components'
13
+ import { AddAssemblyAliases } from '../components/AddAssemblyAliases'
13
14
  import { type ApolloSessionModel } from '../session'
14
15
 
15
16
  export function addMenuItems(rootModel: AbstractMenuManager) {
@@ -81,6 +82,23 @@ export function addMenuItems(rootModel: AbstractMenuManager) {
81
82
  )
82
83
  },
83
84
  })
85
+ rootModel.appendToMenu('Apollo', {
86
+ label: 'Add Assembly aliases',
87
+ onClick: (session: ApolloSessionModel) => {
88
+ ;(session as unknown as AbstractSessionModel).queueDialog(
89
+ (doneCallback) => [
90
+ AddAssemblyAliases,
91
+ {
92
+ session,
93
+ handleClose: () => {
94
+ doneCallback()
95
+ },
96
+ changeManager: session.apolloDataStore.changeManager,
97
+ },
98
+ ],
99
+ )
100
+ },
101
+ })
84
102
  rootModel.appendToMenu('Apollo', {
85
103
  label: 'Manage Users',
86
104
  onClick: (session: ApolloSessionModel) => {
@@ -76,7 +76,10 @@ export class ChangeManager {
76
76
  jobsManager.abortJob(job.name, String(error))
77
77
  }
78
78
  console.error(error)
79
- session.notify(String(error), 'error')
79
+ session.notify(
80
+ `Error encountered in client: ${String(error)}. Data may be out of sync, please refresh the page`,
81
+ 'error',
82
+ )
80
83
  return
81
84
  }
82
85
 
@@ -123,10 +126,10 @@ export class ChangeManager {
123
126
  if (change.notification) {
124
127
  session.notify(change.notification, 'success')
125
128
  }
126
- }
127
- if (addToRecents) {
128
- // Push the change into array
129
- this.recentChanges.push(change)
129
+ if (addToRecents) {
130
+ // Push the change into array
131
+ this.recentChanges.push(change)
132
+ }
130
133
  }
131
134
 
132
135
  if (updateJobsManager) {
@@ -136,7 +139,8 @@ export class ChangeManager {
136
139
 
137
140
  async revert(change: Change, submitToBackend = true) {
138
141
  const inverseChange = change.getInverse()
139
- return this.submit(inverseChange, { submitToBackend, addToRecents: false })
142
+ const opts = { submitToBackend, addToRecents: false }
143
+ return this.submit(inverseChange, opts)
140
144
  }
141
145
 
142
146
  /**
@@ -105,13 +105,15 @@ export const Attributes = observer(function Attributes({
105
105
  typeName: 'FeatureAttributeChange',
106
106
  assembly,
107
107
  featureId: _id,
108
- attributes: remainingAttributes,
108
+ oldAttributes: attributesSerialized,
109
+ newAttributes: remainingAttributes,
109
110
  })
110
111
  void changeManager.submit(change)
111
112
  }
112
113
 
113
114
  function modifyFeatureAttribute(key: string, attribute: string[]) {
114
115
  const serializedAttributes = { ...getSnapshot(attributes) }
116
+ const oldAttributes = structuredClone(serializedAttributes)
115
117
  if (!(key in serializedAttributes)) {
116
118
  notify(`"${key}" not found in feature attributes`, 'error')
117
119
  return
@@ -127,13 +129,15 @@ export const Attributes = observer(function Attributes({
127
129
  typeName: 'FeatureAttributeChange',
128
130
  assembly,
129
131
  featureId: feature._id,
130
- attributes: serializedAttributes,
132
+ oldAttributes,
133
+ newAttributes: serializedAttributes,
131
134
  })
132
135
  void changeManager.submit(change)
133
136
  }
134
137
 
135
138
  function addFeatureAttribute(key: string, attribute: string[]) {
136
139
  const serializedAttributes = { ...getSnapshot(attributes) }
140
+ const oldAttributes = structuredClone(serializedAttributes)
137
141
  if (key in serializedAttributes) {
138
142
  notify(`Feature already has attribute "${key}"`, 'error')
139
143
  return
@@ -145,7 +149,8 @@ export const Attributes = observer(function Attributes({
145
149
  typeName: 'FeatureAttributeChange',
146
150
  assembly,
147
151
  featureId: feature._id,
148
- attributes: serializedAttributes,
152
+ oldAttributes,
153
+ newAttributes: serializedAttributes,
149
154
  })
150
155
  void changeManager.submit(change)
151
156
  }
@@ -13,6 +13,7 @@ import { observer } from 'mobx-react'
13
13
  import React, { useEffect, useRef, useState } from 'react'
14
14
 
15
15
  import { type ApolloSessionModel } from '../session'
16
+ import { copyToClipboard } from '../util/copyToClipboard'
16
17
 
17
18
  const SEQUENCE_WRAP_LENGTH = 60
18
19
 
@@ -112,13 +113,12 @@ function getSequenceSegments(
112
113
  const [firstLocation] = cdsLocations
113
114
  const locs: { min: number; max: number }[] = []
114
115
  for (const loc of firstLocation) {
115
- let sequence = getSequence(loc.min, loc.max)
116
- if (strand === -1) {
117
- sequence = revcom(sequence)
118
- }
119
- wholeSequence += sequence
116
+ wholeSequence += getSequence(loc.min, loc.max)
120
117
  locs.push({ min: loc.min, max: loc.max })
121
118
  }
119
+ if (strand === -1) {
120
+ wholeSequence = revcom(wholeSequence)
121
+ }
122
122
  const sequenceLines = splitStringIntoChunks(
123
123
  wholeSequence,
124
124
  SEQUENCE_WRAP_LENGTH,
@@ -131,13 +131,12 @@ function getSequenceSegments(
131
131
  const [firstLocation] = cdsLocations
132
132
  const locs: { min: number; max: number }[] = []
133
133
  for (const loc of firstLocation) {
134
- let sequence = getSequence(loc.min, loc.max)
135
- if (strand === -1) {
136
- sequence = revcom(sequence)
137
- }
138
- wholeSequence += sequence
134
+ wholeSequence += getSequence(loc.min, loc.max)
139
135
  locs.push({ min: loc.min, max: loc.max })
140
136
  }
137
+ if (strand === -1) {
138
+ wholeSequence = revcom(wholeSequence)
139
+ }
141
140
  let protein = ''
142
141
  for (let i = 0; i < wholeSequence.length; i += 3) {
143
142
  const codonSeq: string = wholeSequence.slice(i, i + 3).toUpperCase()
@@ -275,19 +274,12 @@ export const TranscriptSequence = observer(function TranscriptSequence({
275
274
  setLocationIntervals(locIntervals)
276
275
  }
277
276
 
278
- // Function to copy text to clipboard
279
- const copyToClipboard = () => {
277
+ const onCopyClick = () => {
280
278
  const seqDiv = seqRef.current
281
279
  if (!seqDiv) {
282
280
  return
283
281
  }
284
- const textBlob = new Blob([seqDiv.outerText], { type: 'text/plain' })
285
- const htmlBlob = new Blob([seqDiv.outerHTML], { type: 'text/html' })
286
- const clipboardItem = new ClipboardItem({
287
- [textBlob.type]: textBlob,
288
- [htmlBlob.type]: htmlBlob,
289
- })
290
- void navigator.clipboard.write([clipboardItem])
282
+ void copyToClipboard(seqDiv)
291
283
  }
292
284
 
293
285
  return (
@@ -306,7 +298,7 @@ export const TranscriptSequence = observer(function TranscriptSequence({
306
298
  </Select>
307
299
  <Button
308
300
  variant="contained"
309
- onClick={copyToClipboard}
301
+ onClick={onCopyClick}
310
302
  style={{ marginLeft: 10 }}
311
303
  size="medium"
312
304
  >