@apollo-annotation/jbrowse-plugin-apollo 0.1.19 → 0.1.21

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/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@apollo-annotation/jbrowse-plugin-apollo",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Apollo plugin for JBrowse 2",
5
+ "keywords": [
6
+ "jbrowse",
7
+ "jbrowse2"
8
+ ],
5
9
  "repository": {
6
10
  "type": "git",
7
11
  "url": "https://github.com/GMOD/Apollo3.git",
8
12
  "directory": "packages/jbrowse-plugin-apollo"
9
13
  },
10
- "author": "JBrowse Team",
11
14
  "license": "Apache-2.0",
12
- "keywords": [
13
- "jbrowse",
14
- "jbrowse2"
15
- ],
15
+ "author": "JBrowse Team",
16
16
  "main": "dist/index.js",
17
17
  "module": "dist/index.esm.js",
18
18
  "typings": "dist/index.d.ts",
@@ -20,13 +20,6 @@
20
20
  "dist",
21
21
  "src"
22
22
  ],
23
- "config": {
24
- "jbrowse": {
25
- "plugin": {
26
- "name": "Apollo"
27
- }
28
- }
29
- },
30
23
  "scripts": {
31
24
  "setup": "rimraf .jbrowse && jbrowse create .jbrowse",
32
25
  "clean": "rimraf dist",
@@ -47,13 +40,17 @@
47
40
  "prepack": "yarn build",
48
41
  "postversion": "git push --follow-tags"
49
42
  },
50
- "jbrowse-plugin": {
51
- "name": "Apollo"
43
+ "config": {
44
+ "jbrowse": {
45
+ "plugin": {
46
+ "name": "Apollo"
47
+ }
48
+ }
52
49
  },
53
50
  "dependencies": {
54
- "@apollo-annotation/common": "^0.1.19",
55
- "@apollo-annotation/mst": "^0.1.19",
56
- "@apollo-annotation/shared": "^0.1.19",
51
+ "@apollo-annotation/common": "^0.1.21",
52
+ "@apollo-annotation/mst": "^0.1.21",
53
+ "@apollo-annotation/shared": "^0.1.21",
57
54
  "@emotion/react": "^11.10.6",
58
55
  "@emotion/styled": "^11.10.6",
59
56
  "@gmod/gff": "1.2.0",
@@ -74,18 +71,6 @@
74
71
  "socket.io-client": "^4.5.4",
75
72
  "tslib": "^2.3.1"
76
73
  },
77
- "peerDependencies": {
78
- "@jbrowse/core": "^2.13.1",
79
- "@mui/material": "^5.11.14",
80
- "mobx": "^6.6.1",
81
- "mobx-react": "^7.2.1",
82
- "mobx-state-tree": "^5.1.7",
83
- "prop-types": "^15.8.1",
84
- "react": "^18.2.0",
85
- "react-dom": "^18.2.0",
86
- "rxjs": "^7.4.0",
87
- "tss-react": "^4.6.1"
88
- },
89
74
  "devDependencies": {
90
75
  "@jbrowse/cli": "^2.6.2",
91
76
  "@jbrowse/core": "^2.13.1",
@@ -97,7 +82,7 @@
97
82
  "@types/file-saver": "^2",
98
83
  "@types/node": "^18.14.2",
99
84
  "@types/prop-types": "^15",
100
- "@types/react": "^17.0.34",
85
+ "@types/react": "^18.3.4",
101
86
  "@types/react-dom": "^18",
102
87
  "cypress": "12.17.3",
103
88
  "cypress-mongodb": "^6.2.0",
@@ -123,7 +108,22 @@
123
108
  "tss-react": "^4.6.1",
124
109
  "typescript": "^5.5.3"
125
110
  },
111
+ "peerDependencies": {
112
+ "@jbrowse/core": "^2.13.1",
113
+ "@mui/material": "^5.11.14",
114
+ "mobx": "^6.6.1",
115
+ "mobx-react": "^7.2.1",
116
+ "mobx-state-tree": "^5.1.7",
117
+ "prop-types": "^15.8.1",
118
+ "react": "^18.2.0",
119
+ "react-dom": "^18.2.0",
120
+ "rxjs": "^7.4.0",
121
+ "tss-react": "^4.6.1"
122
+ },
126
123
  "publishConfig": {
127
124
  "access": "public"
125
+ },
126
+ "jbrowse-plugin": {
127
+ "name": "Apollo"
128
128
  }
129
129
  }
@@ -64,7 +64,6 @@ export const LinearApolloDisplay = observer(function LinearApolloDisplay(
64
64
  setSeqTrackCanvas,
65
65
  setSeqTrackOverlayCanvas,
66
66
  setTheme,
67
- tabularEditor,
68
67
  } = model
69
68
  const { classes } = useStyles()
70
69
  const lgv = getContainingView(model) as unknown as LinearGenomeViewModel
@@ -170,9 +169,6 @@ export const LinearApolloDisplay = observer(function LinearApolloDisplay(
170
169
  onMouseLeave={onMouseLeave}
171
170
  onMouseDown={onMouseDown}
172
171
  onMouseUp={onMouseUp}
173
- onClick={() => {
174
- tabularEditor.showPane()
175
- }}
176
172
  className={classes.canvas}
177
173
  style={{ cursor: cursor ?? 'default' }}
178
174
  data-testid="overlayCanvas"
@@ -1,16 +1,7 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration'
2
- import PluginManager from '@jbrowse/core/PluginManager'
3
- import type LinearGenomeViewPlugin from '@jbrowse/plugin-linear-genome-view'
4
2
 
5
- export function configSchemaFactory(pluginManager: PluginManager) {
6
- const LGVPlugin = pluginManager.getPlugin(
7
- 'LinearGenomeViewPlugin',
8
- ) as LinearGenomeViewPlugin
9
- const { baseLinearDisplayConfigSchema } = LGVPlugin.exports
10
-
11
- return ConfigurationSchema(
12
- 'LinearApolloDisplay',
13
- { height: { type: 'number', defaultValue: 500 } },
14
- { baseConfiguration: baseLinearDisplayConfigSchema, explicitlyTyped: true },
15
- )
16
- }
3
+ export const configSchema = ConfigurationSchema(
4
+ 'LinearApolloDisplay',
5
+ {},
6
+ { explicitIdentifier: 'displayId', explicitlyTyped: true },
7
+ )
@@ -1,2 +1,2 @@
1
- export { configSchemaFactory } from './configSchema'
1
+ export { configSchema } from './configSchema'
2
2
  export { stateModelFactory } from './stateModel'
@@ -22,29 +22,27 @@ import { addDisposer, getRoot, types } from 'mobx-state-tree'
22
22
  import { ApolloInternetAccountModel } from '../../ApolloInternetAccount/model'
23
23
  import { ApolloSessionModel } from '../../session'
24
24
  import { ApolloRootModel } from '../../types'
25
- import { TrackHeightMixin } from './trackHeightMixin'
25
+
26
+ const minDisplayHeight = 20
26
27
 
27
28
  export function baseModelFactory(
28
29
  _pluginManager: PluginManager,
29
30
  configSchema: AnyConfigurationSchemaType,
30
31
  ) {
31
- // TODO: Restore this when TRackHeightMixin is in LGV runtime exports
32
-
33
- // const LGVPlugin = pluginManager.getPlugin(
34
- // 'LinearGenomeViewPlugin',
35
- // ) as LinearGenomeViewPlugin
36
- // const { TrackHeightMixin } = LGVPlugin.exports
37
-
38
- return types
39
- .compose(BaseDisplay, TrackHeightMixin)
40
- .named('BaseLinearApolloDisplay')
32
+ return BaseDisplay.named('BaseLinearApolloDisplay')
41
33
  .props({
42
34
  type: types.literal('LinearApolloDisplay'),
43
35
  configuration: ConfigurationReference(configSchema),
36
+ graphical: true,
37
+ table: false,
38
+ heightPreConfig: types.maybe(
39
+ types.refinement(
40
+ 'displayHeight',
41
+ types.number,
42
+ (n) => n >= minDisplayHeight,
43
+ ),
44
+ ),
44
45
  })
45
- .volatile((self) => ({
46
- lgv: getContainingView(self) as unknown as LinearGenomeViewModel,
47
- }))
48
46
  .views((self) => {
49
47
  const { configuration, renderProps: superRenderProps } = self
50
48
  return {
@@ -57,6 +55,26 @@ export function baseModelFactory(
57
55
  },
58
56
  }
59
57
  })
58
+ .volatile(() => ({
59
+ scrollTop: 0,
60
+ }))
61
+ .views((self) => ({
62
+ get lgv() {
63
+ return getContainingView(self) as unknown as LinearGenomeViewModel
64
+ },
65
+ get height() {
66
+ if (self.heightPreConfig) {
67
+ return self.heightPreConfig
68
+ }
69
+ if (self.graphical && self.table) {
70
+ return 500
71
+ }
72
+ if (self.graphical) {
73
+ return 200
74
+ }
75
+ return 300
76
+ },
77
+ }))
60
78
  .views((self) => ({
61
79
  get rendererTypeName() {
62
80
  return self.configuration.renderer.type
@@ -119,6 +137,73 @@ export function baseModelFactory(
119
137
  .apolloSelectedFeature
120
138
  },
121
139
  }))
140
+ .actions((self) => ({
141
+ setScrollTop(scrollTop: number) {
142
+ self.scrollTop = scrollTop
143
+ },
144
+ setHeight(displayHeight: number) {
145
+ self.heightPreConfig = Math.max(displayHeight, minDisplayHeight)
146
+ return self.height
147
+ },
148
+ resizeHeight(distance: number) {
149
+ const oldHeight = self.height
150
+ const newHeight = this.setHeight(self.height + distance)
151
+ return newHeight - oldHeight
152
+ },
153
+ showGraphicalOnly() {
154
+ self.graphical = true
155
+ self.table = false
156
+ },
157
+ showTableOnly() {
158
+ self.graphical = false
159
+ self.table = true
160
+ },
161
+ showGraphicalAndTable() {
162
+ self.graphical = true
163
+ self.table = true
164
+ },
165
+ }))
166
+ .views((self) => {
167
+ const { trackMenuItems: superTrackMenuItems } = self
168
+ return {
169
+ trackMenuItems() {
170
+ const { graphical, table } = self
171
+ return [
172
+ ...superTrackMenuItems(),
173
+ {
174
+ type: 'subMenu',
175
+ label: 'Appearance',
176
+ subMenu: [
177
+ {
178
+ label: 'Show graphical display',
179
+ type: 'radio',
180
+ checked: graphical && !table,
181
+ onClick: () => {
182
+ self.showGraphicalOnly()
183
+ },
184
+ },
185
+ {
186
+ label: 'Show table display',
187
+ type: 'radio',
188
+ checked: table && !graphical,
189
+ onClick: () => {
190
+ self.showTableOnly()
191
+ },
192
+ },
193
+ {
194
+ label: 'Show both graphical and table display',
195
+ type: 'radio',
196
+ checked: table && graphical,
197
+ onClick: () => {
198
+ self.showGraphicalAndTable()
199
+ },
200
+ },
201
+ ],
202
+ },
203
+ ]
204
+ },
205
+ }
206
+ })
122
207
  .actions((self) => ({
123
208
  setSelectedFeature(feature?: AnnotationFeature) {
124
209
  ;(
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
- /* eslint-disable import/no-named-as-default-member */
4
3
  // jsonpath triggers this rule for some reason. import { query } from 'jsonpath' does not work
5
4
 
6
5
  import { checkAbortSignal } from '@jbrowse/core/util'
@@ -225,7 +225,7 @@ export function AddAssembly({
225
225
  const fileUploadChangeBase = {
226
226
  assembly: new ObjectID().toHexString(),
227
227
  assemblyName,
228
- fileId,
228
+ fileIds: { fa: fileId },
229
229
  }
230
230
  change =
231
231
  fileType === FileType.GFF3 && importFeatures
@@ -124,7 +124,26 @@ export function ManageUsers({
124
124
  headerName: 'Role',
125
125
  width: 140,
126
126
  type: 'singleSelect',
127
- valueOptions: ['', 'readOnly', 'user', 'admin'],
127
+ valueOptions: ['readOnly', 'user', 'admin', 'none'],
128
+ getOptionLabel(value) {
129
+ switch (value) {
130
+ case 'readOnly': {
131
+ return 'Read-only'
132
+ }
133
+ case 'user': {
134
+ return 'User'
135
+ }
136
+ case 'admin': {
137
+ return 'Admin'
138
+ }
139
+ case 'none': {
140
+ return 'None'
141
+ }
142
+ default: {
143
+ return 'unknown'
144
+ }
145
+ }
146
+ },
128
147
  editable: true,
129
148
  },
130
149
  {
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,
@@ -158,48 +158,72 @@ export const DisplayComponent = observer(function DisplayComponent({
158
158
  const { classes } = useStyles()
159
159
 
160
160
  const {
161
+ detailsHeight,
162
+ graphical,
161
163
  height: overallHeight,
162
164
  isShown,
163
165
  selectedFeature,
166
+ table,
164
167
  tabularEditor,
165
168
  toggleShown,
166
169
  } = 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
170
 
176
171
  const canvasScrollContainerRef = useRef<HTMLDivElement>(null)
177
172
  useEffect(() => {
178
173
  scrollSelectedFeatureIntoView(model, canvasScrollContainerRef)
179
174
  }, [model, selectedFeature])
180
- return (
181
- <div className={classes.details} style={{ height: overallHeight }}>
182
- <AccordionControl
183
- open={isShown}
184
- title="Graphical"
185
- onClick={toggleShown}
186
- />
175
+
176
+ const onDetailsResize = (delta: number) => {
177
+ model.setDetailsHeight(detailsHeight - delta)
178
+ }
179
+
180
+ if (graphical && table) {
181
+ const tabularHeight = tabularEditor.isShown ? detailsHeight : 0
182
+ const featureAreaHeight = isShown
183
+ ? overallHeight - detailsHeight - accordionControlHeight * 2
184
+ : 0
185
+ return (
186
+ <div style={{ height: overallHeight }}>
187
+ <AccordionControl
188
+ open={isShown}
189
+ title="Graphical"
190
+ onClick={toggleShown}
191
+ />
192
+ <div
193
+ className={classes.shading}
194
+ ref={canvasScrollContainerRef}
195
+ style={{ height: featureAreaHeight }}
196
+ >
197
+ <LinearApolloDisplay model={model} {...other} />
198
+ </div>
199
+ <AccordionControl
200
+ title="Table"
201
+ open={tabularEditor.isShown}
202
+ onClick={tabularEditor.togglePane}
203
+ onResize={onDetailsResize}
204
+ />
205
+ <div className={classes.details} style={{ height: tabularHeight }}>
206
+ <TabularEditorPane model={model} />
207
+ </div>
208
+ </div>
209
+ )
210
+ }
211
+
212
+ if (graphical) {
213
+ return (
187
214
  <div
188
215
  className={classes.shading}
189
216
  ref={canvasScrollContainerRef}
190
- style={{ height: featureAreaHeight }}
217
+ style={{ height: overallHeight }}
191
218
  >
192
219
  <LinearApolloDisplay model={model} {...other} />
193
220
  </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>
221
+ )
222
+ }
223
+
224
+ return (
225
+ <div className={classes.details} style={{ height: overallHeight }}>
226
+ <TabularEditorPane model={model} />
203
227
  </div>
204
228
  )
205
229
  })
@@ -323,7 +323,7 @@ export function extendSession(
323
323
  if (Object.keys(filteredConfig).length === 0) {
324
324
  filteredConfig = undefined
325
325
  }
326
- let trackConfigSnapshot = getSnapshot(conf) as {
326
+ const trackConfigSnapshot = getSnapshot(conf) as {
327
327
  trackId: string
328
328
  type: string
329
329
  }
@@ -331,7 +331,7 @@ export function extendSession(
331
331
  0,
332
332
  trackId.length - sessionTrackIdentifier.length,
333
333
  )
334
- trackConfigSnapshot = {
334
+ const newTrackConfigSnapshot = {
335
335
  ...trackConfigSnapshot,
336
336
  trackId: newTrackId,
337
337
  }
@@ -346,7 +346,7 @@ export function extendSession(
346
346
  ...filteredConfig,
347
347
  tracks: filteredConfig?.tracks && [
348
348
  ...filteredConfig.tracks,
349
- trackConfigSnapshot,
349
+ newTrackConfigSnapshot,
350
350
  ],
351
351
  },
352
352
  })
@@ -357,6 +357,10 @@ export function extendSession(
357
357
  const { notify } = self as unknown as AbstractSessionModel
358
358
  notify('Track added', 'success')
359
359
  }
360
+ // @ts-expect-error This method is missing in the JB types
361
+ self.deleteTrackConf(conf)
362
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
363
+ jbrowse.addTrackConf(newTrackConfigSnapshot)
360
364
  },
361
365
  icon: SaveIcon,
362
366
  },
@@ -396,6 +400,10 @@ export function extendSession(
396
400
  const { notify } = self as unknown as AbstractSessionModel
397
401
  notify('Track removed', 'success')
398
402
  }
403
+ // @ts-expect-error This method is missing in the JB types
404
+ self.deleteTrackConf(conf)
405
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
406
+ jbrowse.deleteTrackConf(conf)
399
407
  },
400
408
  icon: SaveIcon,
401
409
  },
@@ -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
- }))