@jbrowse/plugin-linear-genome-view 2.11.1 → 2.12.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 (53) hide show
  1. package/dist/BaseLinearDisplay/components/LinearBlocks.js +7 -7
  2. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +17 -1
  3. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +21 -0
  4. package/dist/BaseLinearDisplay/models/configSchema.d.ts +10 -0
  5. package/dist/BaseLinearDisplay/models/configSchema.js +15 -3
  6. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -0
  7. package/dist/LinearBareDisplay/configSchema.d.ts +5 -0
  8. package/dist/LinearBareDisplay/model.d.ts +17 -2
  9. package/dist/LinearBasicDisplay/components/AddFiltersDialog.d.ts +10 -0
  10. package/dist/LinearBasicDisplay/components/AddFiltersDialog.js +94 -0
  11. package/dist/LinearBasicDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -7
  12. package/dist/LinearBasicDisplay/configSchema.d.ts +5 -0
  13. package/dist/LinearBasicDisplay/model.d.ts +56 -21
  14. package/dist/LinearBasicDisplay/model.js +36 -5
  15. package/dist/LinearGenomeView/components/Gridlines.js +3 -4
  16. package/dist/LinearGenomeView/components/Highlight.js +20 -21
  17. package/dist/LinearGenomeView/components/OverviewScalebar.js +1 -2
  18. package/dist/LinearGenomeView/components/Scalebar.js +4 -5
  19. package/dist/LinearGenomeView/components/TrackLabel.js +4 -4
  20. package/dist/LinearGenomeView/components/TrackRenderingContainer.js +10 -5
  21. package/dist/LinearGenomeView/components/hooks.d.ts +2 -2
  22. package/dist/LinearGenomeView/components/hooks.js +8 -13
  23. package/dist/LinearGenomeView/model.d.ts +5 -22
  24. package/dist/LinearGenomeView/model.js +2 -2
  25. package/dist/index.d.ts +60 -129
  26. package/esm/BaseLinearDisplay/components/LinearBlocks.js +7 -7
  27. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +17 -1
  28. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +21 -0
  29. package/esm/BaseLinearDisplay/models/configSchema.d.ts +10 -0
  30. package/esm/BaseLinearDisplay/models/configSchema.js +15 -3
  31. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -0
  32. package/esm/LinearBareDisplay/configSchema.d.ts +5 -0
  33. package/esm/LinearBareDisplay/model.d.ts +17 -2
  34. package/esm/LinearBasicDisplay/components/AddFiltersDialog.d.ts +10 -0
  35. package/esm/LinearBasicDisplay/components/AddFiltersDialog.js +69 -0
  36. package/esm/LinearBasicDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -7
  37. package/esm/LinearBasicDisplay/configSchema.d.ts +5 -0
  38. package/esm/LinearBasicDisplay/model.d.ts +56 -21
  39. package/esm/LinearBasicDisplay/model.js +37 -6
  40. package/esm/LinearGenomeView/components/Gridlines.js +3 -4
  41. package/esm/LinearGenomeView/components/Highlight.js +20 -21
  42. package/esm/LinearGenomeView/components/OverviewScalebar.js +1 -2
  43. package/esm/LinearGenomeView/components/Scalebar.js +4 -5
  44. package/esm/LinearGenomeView/components/TrackLabel.js +4 -4
  45. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +10 -5
  46. package/esm/LinearGenomeView/components/hooks.d.ts +2 -2
  47. package/esm/LinearGenomeView/components/hooks.js +8 -10
  48. package/esm/LinearGenomeView/model.d.ts +5 -22
  49. package/esm/LinearGenomeView/model.js +3 -3
  50. package/esm/index.d.ts +60 -129
  51. package/package.json +2 -4
  52. /package/dist/LinearBasicDisplay/components/{SetMaxHeight.d.ts → SetMaxHeightDialog.d.ts} +0 -0
  53. /package/esm/LinearBasicDisplay/components/{SetMaxHeight.d.ts → SetMaxHeightDialog.d.ts} +0 -0
@@ -77,7 +77,9 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
77
77
  };
78
78
  fetchSizeLimit: {
79
79
  type: string;
80
- defaultValue: number;
80
+ defaultValue: number; /**
81
+ * #method
82
+ */
81
83
  description: string;
82
84
  };
83
85
  height: {
@@ -91,6 +93,11 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
91
93
  defaultValue: string;
92
94
  contextVariable: string[];
93
95
  };
96
+ jexlFilters: {
97
+ type: string;
98
+ description: string;
99
+ defaultValue: never[];
100
+ };
94
101
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
95
102
  } & {
96
103
  /**
@@ -215,6 +222,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
215
222
  addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
216
223
  deleteBlock(key: string): void;
217
224
  selectFeature(feature: import("@jbrowse/core/util").Feature): void;
225
+ navToFeature(feature: import("@jbrowse/core/util").Feature): void;
218
226
  clearFeatureSelection(): void;
219
227
  setFeatureIdUnderMouse(feature?: string | undefined): void;
220
228
  setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature | undefined): void;
@@ -309,7 +317,9 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
309
317
  };
310
318
  fetchSizeLimit: {
311
319
  type: string;
312
- defaultValue: number;
320
+ defaultValue: number; /**
321
+ * #method
322
+ */
313
323
  description: string;
314
324
  };
315
325
  height: {
@@ -323,6 +333,11 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
323
333
  defaultValue: string;
324
334
  contextVariable: string[];
325
335
  };
336
+ jexlFilters: {
337
+ type: string;
338
+ description: string;
339
+ defaultValue: never[];
340
+ };
326
341
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
327
342
  }>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
328
343
  type: string;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ declare const AddFiltersDialog: ({ model, handleClose, }: {
3
+ model: {
4
+ jexlFilters?: string[];
5
+ activeFilters: string[];
6
+ setJexlFilters: (arg?: string[]) => void;
7
+ };
8
+ handleClose: () => void;
9
+ }) => React.JSX.Element;
10
+ export default AddFiltersDialog;
@@ -0,0 +1,69 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Dialog } from '@jbrowse/core/ui';
4
+ import { Button, DialogActions, DialogContent, TextField } from '@mui/material';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ import { stringToJexlExpression } from '@jbrowse/core/util/jexlStrings';
7
+ const useStyles = makeStyles()({
8
+ dialogContent: {
9
+ width: '80em',
10
+ },
11
+ textAreaFont: {
12
+ fontFamily: 'Courier New',
13
+ },
14
+ error: {
15
+ color: 'red',
16
+ fontSize: '0.8em',
17
+ },
18
+ });
19
+ function checkJexl(code) {
20
+ stringToJexlExpression(code);
21
+ }
22
+ const AddFiltersDialog = observer(function ({ model, handleClose, }) {
23
+ const { classes } = useStyles();
24
+ const { activeFilters } = model;
25
+ const [data, setData] = useState(activeFilters.join('\n'));
26
+ const [error, setError] = useState();
27
+ useEffect(() => {
28
+ try {
29
+ data
30
+ .split('\n')
31
+ .map(line => line.trim())
32
+ .filter(line => !!line)
33
+ .map(line => checkJexl(line.trim()));
34
+ setError(undefined);
35
+ }
36
+ catch (e) {
37
+ console.error(e);
38
+ setError(e);
39
+ }
40
+ }, [data]);
41
+ return (React.createElement(Dialog, { maxWidth: "xl", open: true, onClose: handleClose, title: "Add track filters" },
42
+ React.createElement(DialogContent, null,
43
+ React.createElement("div", null,
44
+ "Add filters, in jexl format, one per line, starting with the string jexl:. Examples:",
45
+ ' ',
46
+ React.createElement("ul", null,
47
+ React.createElement("li", null,
48
+ React.createElement("code", null, "jexl:get(feature,'name')=='BRCA1'"),
49
+ " - show only feature where the name attribute is BRCA1"),
50
+ React.createElement("li", null,
51
+ React.createElement("code", null, "jexl:get(feature,'type')=='gene'"),
52
+ " - show only gene type features in a GFF that has many other feature types"),
53
+ React.createElement("li", null,
54
+ React.createElement("code", null, "jexl:get(feature,'score') > 400"),
55
+ " - show only features that have a score greater than 400"))),
56
+ error ? React.createElement("p", { className: classes.error }, `${error}`) : null,
57
+ React.createElement(TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => setData(event.target.value), InputProps: {
58
+ classes: {
59
+ input: classes.textAreaFont,
60
+ },
61
+ } })),
62
+ React.createElement(DialogActions, null,
63
+ React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, disabled: !!error, onClick: () => {
64
+ model.setJexlFilters(data.split('\n'));
65
+ handleClose();
66
+ } }, "Submit"),
67
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"))));
68
+ });
69
+ export default AddFiltersDialog;
@@ -15,12 +15,12 @@ const SetMaxHeightDialog = observer(function ({ model, handleClose, }) {
15
15
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Set max height" },
16
16
  React.createElement(DialogContent, { className: classes.root },
17
17
  React.createElement(Typography, null, "Set max height for the track. For example, you can increase this if the layout says \"Max height reached\""),
18
- React.createElement(TextField, { value: max, onChange: event => setMax(event.target.value), placeholder: "Enter max score" }),
19
- React.createElement(DialogActions, null,
20
- React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
21
- model.setMaxHeight(max !== '' && !Number.isNaN(+max) ? +max : undefined);
22
- handleClose();
23
- } }, "Submit"),
24
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
18
+ React.createElement(TextField, { value: max, onChange: event => setMax(event.target.value), placeholder: "Enter max score" })),
19
+ React.createElement(DialogActions, null,
20
+ React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
21
+ model.setMaxHeight(max !== '' && !Number.isNaN(+max) ? +max : undefined);
22
+ handleClose();
23
+ } }, "Submit"),
24
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"))));
25
25
  });
26
26
  export default SetMaxHeightDialog;
@@ -30,5 +30,10 @@ declare function configSchemaFactory(pluginManager: PluginManager): import("@jbr
30
30
  defaultValue: string;
31
31
  contextVariable: string[];
32
32
  };
33
+ jexlFilters: {
34
+ type: string;
35
+ description: string;
36
+ defaultValue: never[];
37
+ };
33
38
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>;
34
39
  export default configSchemaFactory;
@@ -2,6 +2,7 @@
2
2
  import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
3
3
  import { MenuItem } from '@jbrowse/core/ui';
4
4
  import { Instance } from 'mobx-state-tree';
5
+ import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
5
6
  /**
6
7
  * #stateModel LinearBasicDisplay
7
8
  * #category display
@@ -50,11 +51,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
50
51
  model: {
51
52
  error?: unknown;
52
53
  reload: () => void;
53
- message: import("react").ReactNode;
54
- filled?: boolean | undefined;
55
- status?: string | undefined; /**
56
- * #getter
54
+ message: import("react").ReactNode; /**
55
+ * #property
57
56
  */
57
+ filled?: boolean | undefined;
58
+ status?: string | undefined;
58
59
  reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
59
60
  };
60
61
  }) => import("react").JSX.Element | undefined;
@@ -63,7 +64,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
63
64
  doReload(): void;
64
65
  afterAttach(): void;
65
66
  setStatus(message: string): void;
66
- setLoading(abortController: AbortController): void;
67
+ setLoading(abortController: AbortController): void; /**
68
+ * #getter
69
+ */
67
70
  setMessage(messageText: string): void;
68
71
  setRendered(props: {
69
72
  reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
@@ -94,10 +97,17 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
94
97
  };
95
98
  mouseover: {
96
99
  type: string;
97
- description: string;
100
+ description: string; /**
101
+ * #property
102
+ */
98
103
  defaultValue: string;
99
104
  contextVariable: string[];
100
105
  };
106
+ jexlFilters: {
107
+ type: string;
108
+ description: string;
109
+ defaultValue: never[];
110
+ };
101
111
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
102
112
  } & {
103
113
  /**
@@ -124,6 +134,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
124
134
  * #property
125
135
  */
126
136
  configuration: AnyConfigurationSchemaType;
137
+ /**
138
+ * #property
139
+ */
140
+ jexlFilters: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>>;
127
141
  }, {
128
142
  rendererTypeName: string;
129
143
  error: unknown;
@@ -140,7 +154,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
140
154
  message: string | undefined;
141
155
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
142
156
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
143
- type: import("mobx-state-tree").ISimpleType<string>;
157
+ type: import("mobx-state-tree").ISimpleType<string>; /**
158
+ * #property
159
+ */
144
160
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
145
161
  }, {
146
162
  rendererTypeName: string;
@@ -166,11 +182,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
166
182
  }, {
167
183
  rendererTypeName: string;
168
184
  error: unknown;
169
- message: string | undefined; /**
170
- * #action
171
- */
185
+ message: string | undefined;
172
186
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
173
- }> | null;
187
+ }> | null; /**
188
+ * #getter
189
+ */
174
190
  readonly adapterConfig: any;
175
191
  readonly parentTrack: any;
176
192
  renderProps(): any;
@@ -208,13 +224,13 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
208
224
  setCurrStatsBpPerPx(n: number): void;
209
225
  setFeatureDensityStatsLimit(stats?: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined): void;
210
226
  getFeatureDensityStats(): Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats>;
211
- setFeatureDensityStatsP(arg: any): void; /**
212
- * #method
213
- */
227
+ setFeatureDensityStatsP(arg: any): void;
214
228
  setFeatureDensityStats(featureDensityStats?: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined): void;
215
229
  clearFeatureDensityStats(): void;
216
230
  } & {
217
- readonly regionTooLarge: boolean;
231
+ readonly regionTooLarge: boolean; /**
232
+ * #method
233
+ */
218
234
  readonly regionTooLargeReason: string;
219
235
  } & {
220
236
  regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
@@ -240,6 +256,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
240
256
  addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
241
257
  deleteBlock(key: string): void;
242
258
  selectFeature(feature: import("@jbrowse/core/util").Feature): void;
259
+ navToFeature(feature: import("@jbrowse/core/util").Feature): void;
243
260
  clearFeatureSelection(): void;
244
261
  setFeatureIdUnderMouse(feature?: string | undefined): void;
245
262
  setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature | undefined): void;
@@ -253,6 +270,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
253
270
  renderSvg(opts: import("../BaseLinearDisplay").ExportSvgDisplayOptions): Promise<import("react").JSX.Element>;
254
271
  afterAttach(): void;
255
272
  } & {
273
+ /**
274
+ * #getter
275
+ */
276
+ readonly activeFilters: any;
256
277
  /**
257
278
  * #getter
258
279
  */
@@ -283,6 +304,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
283
304
  setSubschema(slotName: string, data: unknown): any;
284
305
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
285
306
  } & {
307
+ /**
308
+ * #action
309
+ */
310
+ setJexlFilters(f?: string[]): void;
286
311
  /**
287
312
  * #action
288
313
  */
@@ -309,6 +334,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
309
334
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
310
335
  setSubschema(slotName: string, data: unknown): any;
311
336
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
337
+ filters: SerializableFilterChain;
312
338
  };
313
339
  /**
314
340
  * #method
@@ -355,11 +381,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
355
381
  model: {
356
382
  error?: unknown;
357
383
  reload: () => void;
358
- message: import("react").ReactNode;
359
- filled?: boolean | undefined;
360
- status?: string | undefined; /**
361
- * #getter
384
+ message: import("react").ReactNode; /**
385
+ * #property
362
386
  */
387
+ filled?: boolean | undefined;
388
+ status?: string | undefined;
363
389
  reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
364
390
  };
365
391
  }) => import("react").JSX.Element | undefined;
@@ -368,7 +394,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
368
394
  doReload(): void;
369
395
  afterAttach(): void;
370
396
  setStatus(message: string): void;
371
- setLoading(abortController: AbortController): void;
397
+ setLoading(abortController: AbortController): void; /**
398
+ * #getter
399
+ */
372
400
  setMessage(messageText: string): void;
373
401
  setRendered(props: {
374
402
  reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
@@ -399,10 +427,17 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
399
427
  };
400
428
  mouseover: {
401
429
  type: string;
402
- description: string;
430
+ description: string; /**
431
+ * #property
432
+ */
403
433
  defaultValue: string;
404
434
  contextVariable: string[];
405
435
  };
436
+ jexlFilters: {
437
+ type: string;
438
+ description: string;
439
+ defaultValue: never[];
440
+ };
406
441
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
407
442
  }>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
408
443
  type: string;
@@ -1,12 +1,14 @@
1
1
  import { lazy } from 'react';
2
2
  import { getConf, ConfigurationReference, } from '@jbrowse/core/configuration';
3
3
  import { getSession } from '@jbrowse/core/util';
4
- import { types, getEnv } from 'mobx-state-tree';
4
+ import { types, getEnv, cast } from 'mobx-state-tree';
5
5
  // icons
6
6
  import VisibilityIcon from '@mui/icons-material/Visibility';
7
7
  // locals
8
8
  import { BaseLinearDisplay } from '../BaseLinearDisplay';
9
- const SetMaxHeightDialog = lazy(() => import('./components/SetMaxHeight'));
9
+ import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
10
+ const SetMaxHeightDialog = lazy(() => import('./components/SetMaxHeightDialog'));
11
+ const AddFiltersDialog = lazy(() => import('./components/AddFiltersDialog'));
10
12
  /**
11
13
  * #stateModel LinearBasicDisplay
12
14
  * #category display
@@ -43,8 +45,21 @@ function stateModelFactory(configSchema) {
43
45
  * #property
44
46
  */
45
47
  configuration: ConfigurationReference(configSchema),
48
+ /**
49
+ * #property
50
+ */
51
+ jexlFilters: types.maybe(types.array(types.string)),
46
52
  }))
47
53
  .views(self => ({
54
+ /**
55
+ * #getter
56
+ */
57
+ get activeFilters() {
58
+ var _a;
59
+ // config jexlFilters are deferred evaluated so they are prepended with
60
+ // jexl at runtime rather than being stored with jexl in the config
61
+ return ((_a = self.jexlFilters) !== null && _a !== void 0 ? _a : getConf(self, 'jexlFilters').map((r) => `jexl:${r}`));
62
+ },
48
63
  /**
49
64
  * #getter
50
65
  */
@@ -97,6 +112,12 @@ function stateModelFactory(configSchema) {
97
112
  },
98
113
  }))
99
114
  .actions(self => ({
115
+ /**
116
+ * #action
117
+ */
118
+ setJexlFilters(f) {
119
+ self.jexlFilters = cast(f);
120
+ },
100
121
  /**
101
122
  * #action
102
123
  */
@@ -129,12 +150,13 @@ function stateModelFactory(configSchema) {
129
150
  * #method
130
151
  */
131
152
  renderProps() {
132
- const config = self.rendererConfig;
133
153
  const superProps = superRenderProps();
134
- const superPropsOmit = superProps;
135
154
  return {
136
- ...superPropsOmit,
137
- config,
155
+ ...superProps,
156
+ config: self.rendererConfig,
157
+ filters: new SerializableFilterChain({
158
+ filters: self.activeFilters,
159
+ }),
138
160
  };
139
161
  },
140
162
  /**
@@ -179,6 +201,15 @@ function stateModelFactory(configSchema) {
179
201
  ]);
180
202
  },
181
203
  },
204
+ {
205
+ label: 'Edit filters',
206
+ onClick: () => {
207
+ getSession(self).queueDialog(handleClose => [
208
+ AddFiltersDialog,
209
+ { model: self, handleClose },
210
+ ]);
211
+ },
212
+ },
182
213
  ];
183
214
  },
184
215
  };
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import { ContentBlock, ElidedBlock, InterRegionPaddingBlock, } from '@jbrowse/core/util/blockTypes';
3
2
  import { makeStyles } from 'tss-react/mui';
4
3
  import { observer } from 'mobx-react';
5
4
  import { ContentBlock as ContentBlockComponent, ElidedBlock as ElidedBlockComponent, InterRegionPaddingBlock as InterRegionPaddingBlockComponent, } from '../../BaseLinearDisplay/components/Block';
@@ -45,13 +44,13 @@ const RenderedVerticalGuides = observer(({ model }) => {
45
44
  const { staticBlocks, bpPerPx } = model;
46
45
  return (React.createElement(React.Fragment, null, staticBlocks.map((block, index) => {
47
46
  const k = `${block.key}-${index}`;
48
- if (block instanceof ContentBlock) {
47
+ if (block.type === 'ContentBlock') {
49
48
  return React.createElement(RenderedBlockLines, { key: k, block: block, bpPerPx: bpPerPx });
50
49
  }
51
- else if (block instanceof ElidedBlock) {
50
+ else if (block.type === 'ElidedBlock') {
52
51
  return React.createElement(ElidedBlockComponent, { key: k, width: block.widthPx });
53
52
  }
54
- else if (block instanceof InterRegionPaddingBlock) {
53
+ else if (block.type === 'InterRegionPaddingBlock') {
55
54
  return (React.createElement(InterRegionPaddingBlockComponent, { key: k, width: block.widthPx, boundary: block.variant === 'boundary' }));
56
55
  }
57
56
  return null;
@@ -33,26 +33,6 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
33
33
  const dismissHighlight = () => {
34
34
  model.removeHighlight(highlight);
35
35
  };
36
- const menuItems = [
37
- {
38
- label: 'Dismiss highlight',
39
- icon: CloseIcon,
40
- onClick: () => dismissHighlight(),
41
- },
42
- {
43
- label: 'Bookmark highlighted region',
44
- icon: BookmarkIcon,
45
- onClick: () => {
46
- let bookmarkWidget = session.widgets.get('GridBookmark');
47
- if (!bookmarkWidget) {
48
- bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
49
- }
50
- // @ts-ignore
51
- bookmarkWidget.addBookmark(highlight);
52
- dismissHighlight();
53
- },
54
- },
55
- ];
56
36
  function handleClose() {
57
37
  setOpen(false);
58
38
  }
@@ -90,7 +70,26 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
90
70
  React.createElement(Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
91
71
  callback(session);
92
72
  handleClose();
93
- }, open: open, onClose: handleClose, menuItems: menuItems }))) : null;
73
+ }, open: open, onClose: handleClose, menuItems: [
74
+ {
75
+ label: 'Dismiss highlight',
76
+ icon: CloseIcon,
77
+ onClick: () => dismissHighlight(),
78
+ },
79
+ {
80
+ label: 'Bookmark highlighted region',
81
+ icon: BookmarkIcon,
82
+ onClick: () => {
83
+ let bookmarkWidget = session.widgets.get('GridBookmark');
84
+ if (!bookmarkWidget) {
85
+ bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
86
+ }
87
+ // @ts-ignore
88
+ bookmarkWidget.addBookmark(highlight);
89
+ dismissHighlight();
90
+ },
91
+ },
92
+ ] }))) : null;
94
93
  });
95
94
  const HighlightGroup = observer(function HighlightGroup({ model, }) {
96
95
  return model.highlight.map((highlight, idx) => (React.createElement(Highlight, { key: JSON.stringify(highlight) + '-' + idx, model: model, highlight: highlight })));
@@ -5,7 +5,6 @@ import { observer } from 'mobx-react';
5
5
  // core
6
6
  import Base1DView from '@jbrowse/core/util/Base1DViewModel';
7
7
  import { getEnv, getSession, getTickDisplayStr } from '@jbrowse/core/util';
8
- import { ContentBlock } from '@jbrowse/core/util/blockTypes';
9
8
  // locals
10
9
  import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT, } from '..';
11
10
  import { chooseGridPitch } from '../util';
@@ -148,7 +147,7 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
148
147
  borderColor: color,
149
148
  } }),
150
149
  overviewVisibleRegions.map((block, idx) => {
151
- return !(block instanceof ContentBlock) ? (React.createElement("div", { key: `${JSON.stringify(block)}-${idx}`, className: classes.scalebarContig, style: {
150
+ return !(block.type === 'ContentBlock') ? (React.createElement("div", { key: `${JSON.stringify(block)}-${idx}`, className: classes.scalebarContig, style: {
152
151
  width: block.widthPx,
153
152
  left: block.offsetPx,
154
153
  backgroundColor: '#999',
@@ -1,6 +1,5 @@
1
1
  import { Paper, Typography } from '@mui/material';
2
2
  import { makeStyles } from 'tss-react/mui';
3
- import { ContentBlock, ElidedBlock, InterRegionPaddingBlock, } from '@jbrowse/core/util/blockTypes';
4
3
  import { observer } from 'mobx-react';
5
4
  import React from 'react';
6
5
  import { ContentBlock as ContentBlockComponent, ElidedBlock as ElidedBlockComponent, InterRegionPaddingBlock as InterRegionPaddingBlockComponent, } from '../../BaseLinearDisplay/components/Block';
@@ -56,7 +55,7 @@ const RenderedRefNameLabels = observer(({ model }) => {
56
55
  }
57
56
  });
58
57
  return (React.createElement(React.Fragment, null, model.staticBlocks.map((block, index) => {
59
- return block instanceof ContentBlock &&
58
+ return block.type === 'ContentBlock' &&
60
59
  (block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (React.createElement(Typography, { key: `refLabel-${block.key}-${index}`, style: {
61
60
  left: index === lastLeftBlock
62
61
  ? Math.max(0, -model.offsetPx)
@@ -83,13 +82,13 @@ const RenderedScalebarLabels = observer(({ model }) => {
83
82
  return (React.createElement(React.Fragment, null, staticBlocks.map((block, idx) => {
84
83
  const { key, widthPx } = block;
85
84
  const k = `${key}-${idx}`;
86
- if (block instanceof ContentBlock) {
85
+ if (block.type === 'ContentBlock') {
87
86
  return React.createElement(RenderedBlockTicks, { key: k, block: block, bpPerPx: bpPerPx });
88
87
  }
89
- else if (block instanceof ElidedBlock) {
88
+ else if (block.type === 'ElidedBlock') {
90
89
  return React.createElement(ElidedBlockComponent, { key: k, width: widthPx });
91
90
  }
92
- else if (block instanceof InterRegionPaddingBlock) {
91
+ else if (block.type === 'InterRegionPaddingBlock') {
93
92
  return (React.createElement(InterRegionPaddingBlockComponent, { key: k, width: widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }));
94
93
  }
95
94
  return null;
@@ -25,10 +25,7 @@ const useStyles = makeStyles()(theme => ({
25
25
  },
26
26
  },
27
27
  trackName: {
28
- margin: '0 auto',
29
- width: '90%',
30
28
  fontSize: '0.8rem',
31
- pointerEvents: 'none',
32
29
  },
33
30
  iconButton: {
34
31
  padding: theme.spacing(1),
@@ -82,7 +79,10 @@ const TrackLabel = observer(React.forwardRef(function TrackLabel2({ track, class
82
79
  React.createElement(TrackLabelDragHandle, { track: track, trackId: trackId, view: view }),
83
80
  React.createElement(IconButton, { onClick: () => view.hideTrack(trackId), className: classes.iconButton, title: "close this track" },
84
81
  React.createElement(CloseIcon, { fontSize: "small" })),
85
- React.createElement(Typography, { variant: "body1", component: "span", className: classes.trackName },
82
+ React.createElement(Typography, { variant: "body1", component: "span", className: classes.trackName, onMouseDown: event => {
83
+ // avoid becoming a click-and-drag action on the lgv
84
+ event.stopPropagation();
85
+ } },
86
86
  React.createElement(SanitizedHTML, { html: [trackName, minimized ? '(minimized)' : '']
87
87
  .filter(f => !!f)
88
88
  .join(' ') })),
@@ -26,19 +26,24 @@ const TrackRenderingContainer = observer(function ({ model, track, onDragEnter,
26
26
  const { classes } = useStyles();
27
27
  const display = track.displays[0];
28
28
  const { height, RenderingComponent, DisplayBlurb } = display;
29
+ const { trackRefs, id, scaleFactor } = model;
29
30
  const trackId = getConf(track, 'trackId');
30
31
  const ref = useRef(null);
31
32
  const minimized = track.minimized;
32
33
  useEffect(() => {
33
34
  if (ref.current) {
34
- model.trackRefs[trackId] = ref.current;
35
+ trackRefs[trackId] = ref.current;
35
36
  }
36
37
  return () => {
37
- delete model.trackRefs[trackId];
38
+ delete trackRefs[trackId];
38
39
  };
39
- }, [model.trackRefs, trackId]);
40
- return (React.createElement("div", { className: classes.trackRenderingContainer, style: { height: minimized ? 20 : height }, onScroll: evt => display.setScrollTop(evt.currentTarget.scrollTop), onDragEnter: onDragEnter, "data-testid": `trackRenderingContainer-${model.id}-${trackId}` }, !minimized ? (React.createElement(React.Fragment, null,
41
- React.createElement("div", { ref: ref, className: classes.renderingComponentContainer, style: { transform: `scaleX(${model.scaleFactor})` } },
40
+ }, [trackRefs, trackId]);
41
+ return (React.createElement("div", { className: classes.trackRenderingContainer, style: {
42
+ height: minimized ? 20 : height,
43
+ }, onScroll: evt => display.setScrollTop(evt.currentTarget.scrollTop), onDragEnter: onDragEnter, "data-testid": `trackRenderingContainer-${id}-${trackId}` }, !minimized ? (React.createElement(React.Fragment, null,
44
+ React.createElement("div", { ref: ref, className: classes.renderingComponentContainer, style: {
45
+ transform: scaleFactor !== 1 ? `scaleX(${scaleFactor})` : undefined,
46
+ } },
42
47
  React.createElement(Suspense, { fallback: React.createElement(LoadingEllipses, null) },
43
48
  React.createElement(RenderingComponent, { model: display, onHorizontalScroll: model.horizontalScroll }))),
44
49
  DisplayBlurb ? (React.createElement("div", { style: {
@@ -42,7 +42,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement>, mod
42
42
  offset: number;
43
43
  start: number;
44
44
  end: number;
45
- reversed: boolean;
45
+ reversed?: boolean | undefined;
46
46
  };
47
47
  rightBpOffset: {
48
48
  coord: number;
@@ -53,7 +53,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement>, mod
53
53
  offset: number;
54
54
  start: number;
55
55
  end: number;
56
- reversed: boolean;
56
+ reversed?: boolean | undefined;
57
57
  };
58
58
  anchorPosition: AnchorPosition | undefined;
59
59
  numOfBpSelected: number;