@jbrowse/plugin-linear-genome-view 2.8.0 → 2.9.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 (31) hide show
  1. package/dist/BasicTrack/configSchema.d.ts +5 -0
  2. package/dist/FeatureTrack/configSchema.d.ts +5 -0
  3. package/dist/LaunchLinearGenomeView/index.js +16 -14
  4. package/dist/LinearGenomeView/components/CenterLine.js +1 -1
  5. package/dist/LinearGenomeView/components/ImportForm.js +26 -74
  6. package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +12 -0
  7. package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +29 -0
  8. package/dist/LinearGenomeView/components/OverviewScalebar.js +1 -1
  9. package/dist/LinearGenomeView/components/SearchBox.js +19 -56
  10. package/dist/LinearGenomeView/model.d.ts +12 -1
  11. package/dist/LinearGenomeView/model.js +16 -0
  12. package/dist/index.d.ts +702 -6
  13. package/dist/index.js +2 -2
  14. package/dist/searchUtils.d.ts +26 -0
  15. package/dist/searchUtils.js +90 -0
  16. package/esm/BasicTrack/configSchema.d.ts +5 -0
  17. package/esm/FeatureTrack/configSchema.d.ts +5 -0
  18. package/esm/LaunchLinearGenomeView/index.js +16 -14
  19. package/esm/LinearGenomeView/components/CenterLine.js +1 -1
  20. package/esm/LinearGenomeView/components/ImportForm.js +26 -74
  21. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +12 -0
  22. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +24 -0
  23. package/esm/LinearGenomeView/components/OverviewScalebar.js +1 -1
  24. package/esm/LinearGenomeView/components/SearchBox.js +20 -57
  25. package/esm/LinearGenomeView/model.d.ts +12 -1
  26. package/esm/LinearGenomeView/model.js +16 -0
  27. package/esm/index.d.ts +702 -6
  28. package/esm/index.js +2 -2
  29. package/esm/searchUtils.d.ts +26 -0
  30. package/esm/searchUtils.js +79 -0
  31. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -29,6 +29,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.linearBasicDisplayModelFactory = exports.linearBasicDisplayConfigSchemaFactory = exports.SVGRuler = exports.totalHeight = exports.SVGTracks = exports.renderToSvg = exports.SearchBox = exports.RefNameAutocomplete = exports.TooLargeMessage = exports.FeatureDensityMixin = exports.TrackHeightMixin = exports.BaseLinearDisplayComponent = exports.BlockMsg = exports.BaseLinearDisplay = exports.baseLinearDisplayConfigSchema = exports.linearBareDisplayConfigSchemaFactory = void 0;
30
30
  const Plugin_1 = __importDefault(require("@jbrowse/core/Plugin"));
31
31
  const util_1 = require("@jbrowse/core/util");
32
+ const configuration_1 = require("@jbrowse/core/configuration");
33
+ const mobx_state_tree_1 = require("mobx-state-tree");
32
34
  // icons
33
35
  const LineStyle_1 = __importDefault(require("@mui/icons-material/LineStyle"));
34
36
  // locals
@@ -39,8 +41,6 @@ const LinearBasicDisplay_1 = __importDefault(require("./LinearBasicDisplay"));
39
41
  const FeatureTrack_1 = __importDefault(require("./FeatureTrack"));
40
42
  const BasicTrack_1 = __importDefault(require("./BasicTrack"));
41
43
  const LaunchLinearGenomeView_1 = __importDefault(require("./LaunchLinearGenomeView"));
42
- const configuration_1 = require("@jbrowse/core/configuration");
43
- const mobx_state_tree_1 = require("mobx-state-tree");
44
44
  class LinearGenomeViewPlugin extends Plugin_1.default {
45
45
  constructor() {
46
46
  super(...arguments);
@@ -0,0 +1,26 @@
1
+ import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
2
+ import { Assembly } from '@jbrowse/core/assemblyManager/assembly';
3
+ import { SearchType } from '@jbrowse/core/data_adapters/BaseAdapter';
4
+ import { SearchScope } from '@jbrowse/core/TextSearch/TextSearchManager';
5
+ import { TextSearchManager } from '@jbrowse/core/util';
6
+ import { LinearGenomeViewModel } from './LinearGenomeView';
7
+ export declare function navToOption({ option, model, assemblyName, }: {
8
+ model: LinearGenomeViewModel;
9
+ option: BaseResult;
10
+ assemblyName: string;
11
+ }): Promise<void>;
12
+ export declare function handleSelectedRegion({ input, model, assembly, }: {
13
+ input: string;
14
+ model: LinearGenomeViewModel;
15
+ assembly: Assembly;
16
+ }): Promise<void>;
17
+ export declare function checkRef(str: string, allRefs: string[]): boolean;
18
+ export declare function fetchResults({ queryString, searchType, searchScope, rankSearchResults, textSearchManager, assembly, }: {
19
+ queryString: string;
20
+ searchScope: SearchScope;
21
+ rankSearchResults: (results: BaseResult[]) => BaseResult[];
22
+ searchType?: SearchType;
23
+ textSearchManager?: TextSearchManager;
24
+ assembly?: Assembly;
25
+ }): Promise<BaseResult[]>;
26
+ export declare function splitLast(str: string, split: string): [string, string];
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.splitLast = exports.fetchResults = exports.checkRef = exports.handleSelectedRegion = exports.navToOption = void 0;
7
+ const util_1 = require("@jbrowse/core/util");
8
+ const BaseResults_1 = __importDefault(require("@jbrowse/core/TextSearch/BaseResults"));
9
+ const util_2 = require("@jbrowse/core/util");
10
+ async function navToOption({ option, model, assemblyName, }) {
11
+ const location = option.getLocation();
12
+ const trackId = option.getTrackId();
13
+ if (location) {
14
+ await model.navToLocString(location, assemblyName);
15
+ if (trackId) {
16
+ model.showTrack(trackId);
17
+ }
18
+ }
19
+ }
20
+ exports.navToOption = navToOption;
21
+ // gets a string as input, or use stored option results from previous query,
22
+ // then re-query and
23
+ // 1) if it has multiple results: pop a dialog
24
+ // 2) if it's a single result navigate to it
25
+ // 3) else assume it's a locstring and navigate to it
26
+ async function handleSelectedRegion({ input, model, assembly, }) {
27
+ const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
28
+ const assemblyName = assembly.name;
29
+ if (input.split(' ').every(entry => checkRef(entry, allRefs))) {
30
+ await model.navToLocString(input, assembly.name);
31
+ }
32
+ else {
33
+ const searchScope = model.searchScope(assemblyName);
34
+ const { textSearchManager } = (0, util_1.getSession)(model);
35
+ const results = await fetchResults({
36
+ queryString: input,
37
+ searchType: 'exact',
38
+ searchScope,
39
+ rankSearchResults: model.rankSearchResults,
40
+ textSearchManager,
41
+ assembly,
42
+ });
43
+ if (results.length > 1) {
44
+ model.setSearchResults(results, input.toLowerCase(), assemblyName);
45
+ }
46
+ else if (results.length === 1) {
47
+ await navToOption({
48
+ option: results[0],
49
+ model,
50
+ assemblyName,
51
+ });
52
+ }
53
+ else {
54
+ await model.navToLocString(input, assemblyName);
55
+ }
56
+ }
57
+ }
58
+ exports.handleSelectedRegion = handleSelectedRegion;
59
+ function checkRef(str, allRefs) {
60
+ const [ref, rest] = splitLast(str, ':');
61
+ return (allRefs.includes(str) ||
62
+ (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10))));
63
+ }
64
+ exports.checkRef = checkRef;
65
+ async function fetchResults({ queryString, searchType, searchScope, rankSearchResults, textSearchManager, assembly, }) {
66
+ var _a;
67
+ if (!textSearchManager) {
68
+ console.warn('No text search manager');
69
+ }
70
+ const textSearchResults = await (textSearchManager === null || textSearchManager === void 0 ? void 0 : textSearchManager.search({
71
+ queryString,
72
+ searchType,
73
+ }, searchScope, rankSearchResults));
74
+ const refNameResults = (_a = assembly === null || assembly === void 0 ? void 0 : assembly.allRefNames) === null || _a === void 0 ? void 0 : _a.filter(ref => ref.toLowerCase().startsWith(queryString.toLowerCase())).slice(0, 10).map(r => new BaseResults_1.default({ label: r }));
75
+ return (0, util_2.dedupe)([...(refNameResults || []), ...(textSearchResults || [])], elt => elt.getId());
76
+ }
77
+ exports.fetchResults = fetchResults;
78
+ // splits on the last instance of a character
79
+ function splitLast(str, split) {
80
+ const lastIndex = str.lastIndexOf(split);
81
+ if (lastIndex === -1) {
82
+ return [str, ''];
83
+ }
84
+ else {
85
+ const before = str.slice(0, lastIndex);
86
+ const after = str.slice(lastIndex + 1);
87
+ return [before, after];
88
+ }
89
+ }
90
+ exports.splitLast = splitLast;
@@ -58,6 +58,11 @@ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/c
58
58
  defaultValue: number;
59
59
  description: string;
60
60
  };
61
+ maxDepth: {
62
+ type: string;
63
+ defaultValue: number;
64
+ description: string;
65
+ };
61
66
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
62
67
  formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
63
68
  config: {
@@ -58,6 +58,11 @@ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/c
58
58
  defaultValue: number;
59
59
  description: string;
60
60
  };
61
+ maxDepth: {
62
+ type: string;
63
+ defaultValue: number;
64
+ description: string;
65
+ };
61
66
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
62
67
  formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
63
68
  config: {
@@ -1,4 +1,5 @@
1
1
  import { when } from '@jbrowse/core/util';
2
+ import { handleSelectedRegion } from '..//searchUtils';
2
3
  export default (pluginManager) => {
3
4
  pluginManager.addToExtensionPoint('LaunchView-LinearGenomeView',
4
5
  // @ts-expect-error
@@ -14,21 +15,9 @@ export default (pluginManager) => {
14
15
  if (!asm) {
15
16
  throw new Error(`Assembly "${assembly}" not found when launching linear genome view`);
16
17
  }
17
- await view.navToLocString(loc, assembly);
18
+ await handleSelectedRegion({ input: loc, model: view, assembly: asm });
18
19
  const idsNotFound = [];
19
- tracks.forEach(track => {
20
- try {
21
- view.showTrack(track);
22
- }
23
- catch (e) {
24
- if (`${e}`.match('Could not resolve identifier')) {
25
- idsNotFound.push(track);
26
- }
27
- else {
28
- throw e;
29
- }
30
- }
31
- });
20
+ tracks.forEach(track => tryTrack(view, track, idsNotFound));
32
21
  if (idsNotFound.length) {
33
22
  throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
34
23
  }
@@ -39,3 +28,16 @@ export default (pluginManager) => {
39
28
  }
40
29
  });
41
30
  };
31
+ function tryTrack(model, trackId, idsNotFound) {
32
+ try {
33
+ model.showTrack(trackId);
34
+ }
35
+ catch (e) {
36
+ if (`${e}`.match('Could not resolve identifier')) {
37
+ idsNotFound.push(trackId);
38
+ }
39
+ else {
40
+ throw e;
41
+ }
42
+ }
43
+ }
@@ -5,7 +5,7 @@ const useStyles = makeStyles()(theme => ({
5
5
  centerLineContainer: {
6
6
  background: 'transparent',
7
7
  height: '100%',
8
- zIndex: 5,
8
+ zIndex: 5, // above the track but under menu
9
9
  position: 'absolute',
10
10
  border: `1px ${theme.palette.action.active} dashed`,
11
11
  borderTop: 'none',
@@ -6,9 +6,8 @@ import { Button, FormControl, Container, Grid, CircularProgress, } from '@mui/ma
6
6
  import { ErrorMessage, AssemblySelector } from '@jbrowse/core/ui';
7
7
  // icons
8
8
  import CloseIcon from '@mui/icons-material/Close';
9
- // locals
10
- import RefNameAutocomplete from './RefNameAutocomplete';
11
- import { fetchResults, splitLast } from './util';
9
+ import { handleSelectedRegion, navToOption } from '../../searchUtils';
10
+ import ImportFormRefNameAutocomplete from './ImportFormRefNameAutocomplete';
12
11
  const useStyles = makeStyles()(theme => ({
13
12
  importFormContainer: {
14
13
  padding: theme.spacing(2),
@@ -24,11 +23,10 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
24
23
  var _a;
25
24
  const { classes } = useStyles();
26
25
  const session = getSession(model);
27
- const { assemblyNames, assemblyManager, textSearchManager } = session;
28
- const { rankSearchResults, error } = model;
26
+ const { assemblyNames, assemblyManager } = session;
27
+ const { error } = model;
29
28
  const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0]);
30
29
  const [option, setOption] = useState();
31
- const searchScope = model.searchScope(selectedAsm);
32
30
  const assembly = assemblyManager.get(selectedAsm);
33
31
  const assemblyError = assemblyNames.length
34
32
  ? assembly === null || assembly === void 0 ? void 0 : assembly.error
@@ -46,74 +44,37 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
46
44
  useEffect(() => {
47
45
  setValue(r0);
48
46
  }, [r0, selectedAsm]);
49
- async function navToOption(option) {
50
- const location = option.getLocation();
51
- const trackId = option.getTrackId();
52
- if (location) {
53
- await model.navToLocString(location, selectedAsm);
54
- if (trackId) {
55
- model.showTrack(trackId);
56
- }
57
- }
58
- }
59
- // gets a string as input, or use stored option results from previous query,
60
- // then re-query and
61
- // 1) if it has multiple results: pop a dialog
62
- // 2) if it's a single result navigate to it
63
- // 3) else assume it's a locstring and navigate to it
64
- async function handleSelectedRegion(input) {
65
- var _a;
66
- try {
67
- if ((option === null || option === void 0 ? void 0 : option.getDisplayString()) === input && option.hasLocation()) {
68
- await navToOption(option);
69
- }
70
- else if ((_a = option === null || option === void 0 ? void 0 : option.results) === null || _a === void 0 ? void 0 : _a.length) {
71
- model.setSearchResults(option.results, option.getLabel(), selectedAsm);
72
- }
73
- else {
74
- const [ref, rest] = splitLast(input, ':');
75
- const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
76
- if (allRefs.includes(input) ||
77
- (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10)))) {
78
- await model.navToLocString(input, selectedAsm);
79
- }
80
- else {
81
- const results = await fetchResults({
82
- queryString: input,
83
- searchType: 'exact',
84
- searchScope,
85
- rankSearchResults,
86
- textSearchManager,
87
- assembly,
88
- });
89
- if (results.length > 1) {
90
- model.setSearchResults(results, input.toLowerCase(), selectedAsm);
91
- }
92
- else if (results.length === 1) {
93
- await navToOption(results[0]);
94
- }
95
- else {
96
- await model.navToLocString(input, selectedAsm);
97
- }
98
- }
99
- }
100
- }
101
- catch (e) {
102
- console.error(e);
103
- session.notify(`${e}`, 'warning');
104
- }
105
- }
106
47
  // implementation notes:
107
48
  // having this wrapped in a form allows intuitive use of enter key to submit
108
49
  return (React.createElement("div", { className: classes.container },
109
50
  displayError ? React.createElement(ErrorMessage, { error: displayError }) : null,
110
51
  React.createElement(Container, { className: classes.importFormContainer },
111
52
  React.createElement("form", { onSubmit: async (event) => {
53
+ var _a;
112
54
  event.preventDefault();
113
55
  model.setError(undefined);
114
56
  if (value) {
115
57
  // has it's own error handling
116
- await handleSelectedRegion(value);
58
+ try {
59
+ if ((option === null || option === void 0 ? void 0 : option.getDisplayString()) === value &&
60
+ option.hasLocation()) {
61
+ await navToOption({
62
+ option,
63
+ model,
64
+ assemblyName: selectedAsm,
65
+ });
66
+ }
67
+ else if ((_a = option === null || option === void 0 ? void 0 : option.results) === null || _a === void 0 ? void 0 : _a.length) {
68
+ model.setSearchResults(option.results, option.getLabel(), selectedAsm);
69
+ }
70
+ else if (assembly) {
71
+ await handleSelectedRegion({ input: value, assembly, model });
72
+ }
73
+ }
74
+ catch (e) {
75
+ console.error(e);
76
+ session.notify(`${e}`, 'warning');
77
+ }
117
78
  }
118
79
  } },
119
80
  React.createElement(Grid, { container: true, spacing: 1, justifyContent: "center", alignItems: "center" },
@@ -121,16 +82,7 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
121
82
  React.createElement(FormControl, null,
122
83
  React.createElement(AssemblySelector, { onChange: val => setSelectedAsm(val), localStorageKey: "lgv", session: session, selected: selectedAsm }))),
123
84
  React.createElement(Grid, { item: true }, selectedAsm ? (assemblyError ? (React.createElement(CloseIcon, { style: { color: 'red' } })) : assemblyLoaded ? (React.createElement(FormControl, null,
124
- React.createElement(RefNameAutocomplete, { fetchResults: queryString => fetchResults({
125
- queryString,
126
- assembly,
127
- textSearchManager,
128
- rankSearchResults,
129
- searchScope,
130
- }), model: model, assemblyName: selectedAsm, value: value, minWidth: 270, onChange: str => setValue(str), onSelect: val => setOption(val), TextFieldProps: {
131
- variant: 'outlined',
132
- helperText: 'Enter sequence name, feature name, or location',
133
- } }))) : (React.createElement(CircularProgress, { size: 20, disableShrink: true }))) : null),
85
+ React.createElement(ImportFormRefNameAutocomplete, { value: value, setValue: setValue, selectedAsm: selectedAsm, setOption: setOption, model: model }))) : (React.createElement(CircularProgress, { size: 20, disableShrink: true }))) : null),
134
86
  React.createElement(Grid, { item: true },
135
87
  React.createElement(FormControl, null,
136
88
  React.createElement(Button, { type: "submit", disabled: !value, className: classes.button, variant: "contained", color: "primary" }, "Open")),
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
3
+ import { LinearGenomeViewModel } from '..';
4
+ type LGV = LinearGenomeViewModel;
5
+ declare const ImportFormRefNameAutocomplete: ({ model, selectedAsm, value, setValue, setOption, }: {
6
+ value: string;
7
+ setValue: (arg: string) => void;
8
+ model: LGV;
9
+ selectedAsm: string;
10
+ setOption: (arg: BaseResult) => void;
11
+ }) => React.JSX.Element;
12
+ export default ImportFormRefNameAutocomplete;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { getSession } from '@jbrowse/core/util';
4
+ // locals
5
+ import RefNameAutocomplete from './RefNameAutocomplete';
6
+ import { fetchResults } from './util';
7
+ const ImportFormRefNameAutocomplete = observer(function ({ model, selectedAsm, value, setValue, setOption, }) {
8
+ const session = getSession(model);
9
+ const { assemblyManager, textSearchManager } = session;
10
+ const { rankSearchResults } = model;
11
+ const searchScope = model.searchScope(selectedAsm);
12
+ const assembly = assemblyManager.get(selectedAsm);
13
+ return (React.createElement(RefNameAutocomplete, { fetchResults: queryString => fetchResults({
14
+ queryString,
15
+ assembly,
16
+ textSearchManager,
17
+ rankSearchResults,
18
+ searchScope,
19
+ }), model: model, assemblyName: selectedAsm, value: value, minWidth: 270, onChange: str => setValue(str), onSelect: val => setOption(val), TextFieldProps: {
20
+ variant: 'outlined',
21
+ helperText: 'Enter sequence name, feature name, or location',
22
+ } }));
23
+ });
24
+ export default ImportFormRefNameAutocomplete;
@@ -195,7 +195,7 @@ const OverviewScalebar = observer(function ({ model, children, }) {
195
195
  overview.showAllRegions();
196
196
  return overview;
197
197
  }, [
198
- JSON.stringify(displayedRegions),
198
+ JSON.stringify(displayedRegions), // eslint-disable-line react-hooks/exhaustive-deps
199
199
  model.minimumBlockWidth,
200
200
  modWidth,
201
201
  displayedRegions,
@@ -5,18 +5,14 @@ import { makeStyles } from 'tss-react/mui';
5
5
  import { getSession } from '@jbrowse/core/util';
6
6
  // locals
7
7
  import RefNameAutocomplete from './RefNameAutocomplete';
8
- import { fetchResults, splitLast } from './util';
8
+ import { fetchResults } from './util';
9
9
  import { SPACING, WIDGET_HEIGHT } from '..';
10
+ import { handleSelectedRegion, navToOption } from '../../searchUtils';
10
11
  const useStyles = makeStyles()(() => ({
11
12
  headerRefName: {
12
13
  minWidth: 100,
13
14
  },
14
15
  }));
15
- function checkRef(str, allRefs) {
16
- const [ref, rest] = splitLast(str, ':');
17
- return (allRefs.includes(str) ||
18
- (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10))));
19
- }
20
16
  const SearchBox = observer(function ({ model, showHelp, }) {
21
17
  const { classes } = useStyles();
22
18
  const theme = useTheme();
@@ -26,61 +22,28 @@ const SearchBox = observer(function ({ model, showHelp, }) {
26
22
  const assemblyName = assemblyNames[0];
27
23
  const assembly = assemblyManager.get(assemblyName);
28
24
  const searchScope = model.searchScope(assemblyName);
29
- async function navToOption(option) {
30
- const location = option.getLocation();
31
- const trackId = option.getTrackId();
32
- if (location) {
33
- await model.navToLocString(location, assemblyName);
34
- if (trackId) {
35
- model.showTrack(trackId);
36
- }
37
- }
38
- }
39
- // gets a string as input, or use stored option results from previous query,
40
- // then re-query and
41
- // 1) if it has multiple results: pop a dialog
42
- // 2) if it's a single result navigate to it
43
- // 3) else assume it's a locstring and navigate to it
44
- async function handleSelectedRegion(option) {
45
- var _a;
46
- try {
47
- const input = option.getLabel();
48
- const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
49
- if (option.hasLocation()) {
50
- await navToOption(option);
51
- }
52
- else if ((_a = option.results) === null || _a === void 0 ? void 0 : _a.length) {
53
- model.setSearchResults(option.results, option.getLabel());
54
- }
55
- else if (input.split(' ').every(entry => checkRef(entry, allRefs))) {
56
- await model.navToLocString(input, assemblyName);
57
- }
58
- else {
59
- const results = await fetchResults({
60
- queryString: input,
61
- searchType: 'exact',
62
- searchScope,
63
- rankSearchResults,
64
- textSearchManager,
65
- assembly,
66
- });
67
- if (results.length > 1) {
68
- model.setSearchResults(results, input.toLowerCase());
25
+ return (React.createElement(RefNameAutocomplete, { showHelp: showHelp, onSelect: async (option) => {
26
+ var _a;
27
+ try {
28
+ if (option.hasLocation()) {
29
+ await navToOption({ option, model, assemblyName });
69
30
  }
70
- else if (results.length === 1) {
71
- await navToOption(results[0]);
31
+ else if ((_a = option.results) === null || _a === void 0 ? void 0 : _a.length) {
32
+ model.setSearchResults(option.results, option.getLabel());
72
33
  }
73
- else {
74
- await model.navToLocString(input, assemblyName);
34
+ else if (assembly) {
35
+ await handleSelectedRegion({
36
+ input: option.getLabel(),
37
+ assembly,
38
+ model,
39
+ });
75
40
  }
76
41
  }
77
- }
78
- catch (e) {
79
- console.error(e);
80
- session.notify(`${e}`, 'warning');
81
- }
82
- }
83
- return (React.createElement(RefNameAutocomplete, { showHelp: showHelp, onSelect: handleSelectedRegion, assemblyName: assemblyName, fetchResults: queryString => fetchResults({
42
+ catch (e) {
43
+ console.error(e);
44
+ getSession(model).notify(`${e}`, 'warning');
45
+ }
46
+ }, assemblyName: assemblyName, fetchResults: queryString => fetchResults({
84
47
  queryString,
85
48
  searchScope,
86
49
  rankSearchResults,
@@ -6,6 +6,7 @@ import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
6
6
  import { BlockSet, BaseBlock } from '@jbrowse/core/util/blockTypes';
7
7
  import { Instance } from 'mobx-state-tree';
8
8
  import PluginManager from '@jbrowse/core/PluginManager';
9
+ import { Assembly } from '@jbrowse/core/assemblyManager/assembly';
9
10
  export interface BpOffset {
10
11
  refName?: string;
11
12
  index: number;
@@ -292,7 +293,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
292
293
  /**
293
294
  * #action
294
295
  */
295
- toggleTrack(trackId: string): void;
296
+ toggleTrack(trackId: string): boolean;
296
297
  /**
297
298
  * #action
298
299
  */
@@ -463,6 +464,16 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
463
464
  * navigating to the locstring
464
465
  */
465
466
  navToLocString(input: string, optAssemblyName?: string): Promise<void>;
467
+ /**
468
+ * #action
469
+ * Performs a text index search, and navigates to it immediately if a
470
+ * single result is returned. Will pop up a search dialog if multiple
471
+ * results are returned
472
+ */
473
+ navToSearchString({ input, assembly, }: {
474
+ input: string;
475
+ assembly: Assembly;
476
+ }): Promise<void>;
466
477
  /**
467
478
  * #action
468
479
  * Similar to `navToLocString`, but accepts parsed location objects
@@ -24,6 +24,7 @@ import MenuOpenIcon from '@mui/icons-material/MenuOpen';
24
24
  import MiniControls from './components/MiniControls';
25
25
  import Header from './components/Header';
26
26
  import { generateLocations, parseLocStrings } from './util';
27
+ import { handleSelectedRegion } from '../searchUtils';
27
28
  // lazies
28
29
  const ReturnToImportFormDialog = lazy(() => import('@jbrowse/core/ui/ReturnToImportFormDialog'));
29
30
  const SequenceSearchDialog = lazy(() => import('./components/SequenceSearchDialog'));
@@ -595,7 +596,9 @@ export function stateModelFactory(pluginManager) {
595
596
  // if none had that configuration, turn one on
596
597
  if (!hiddenCount) {
597
598
  self.showTrack(trackId);
599
+ return true;
598
600
  }
601
+ return false;
599
602
  },
600
603
  /**
601
604
  * #action
@@ -1077,6 +1080,19 @@ export function stateModelFactory(pluginManager) {
1077
1080
  }
1078
1081
  return this.navToLocations(parseLocStrings(input, assemblyName, isValidRefName), assemblyName);
1079
1082
  },
1083
+ /**
1084
+ * #action
1085
+ * Performs a text index search, and navigates to it immediately if a
1086
+ * single result is returned. Will pop up a search dialog if multiple
1087
+ * results are returned
1088
+ */
1089
+ async navToSearchString({ input, assembly, }) {
1090
+ await handleSelectedRegion({
1091
+ input,
1092
+ assembly,
1093
+ model: self,
1094
+ });
1095
+ },
1080
1096
  /**
1081
1097
  * #action
1082
1098
  * Similar to `navToLocString`, but accepts parsed location objects