47ea57080b515e5dad5f658c58feb8944a7e7d61 chmalee Thu Jan 29 15:30:26 2026 -0800 Replace clade/assembly dropdowns with a search bar on most CGIs. Add a recents list to hgGateway and to the species bar and to the 'Genomes' dropdown menu. Track recently selected species in localStorage. Add toGenome and fromGenome arguemnts to hubApi/liftOver in order to find appropriate liftover assemblies, refs #36232 diff --git src/hg/js/react/lib/SpeciesSearch.jsx src/hg/js/react/lib/SpeciesSearch.jsx new file mode 100644 index 00000000000..73cef5c46d9 --- /dev/null +++ src/hg/js/react/lib/SpeciesSearch.jsx @@ -0,0 +1,71 @@ +/** @jsx React.DOM */ +/* global ImmutableUpdate, PathUpdate, Icon, Modal, TextInput */ +var pt = React.PropTypes; + +var SpeciesSearch = React.createClass({ + // Text input for position or search term, optionally with autocomplete if + // props includes geneSuggestTrack, and a PositionPopup (defined below) + // for multiple position/search matches. + + mixins: [PathUpdate, ImmutableUpdate], + // update(path + 'position', newValue) called when user changes position + // update(path + 'hidePosPopup') called when user clicks to hide popup + // update(path + 'positionMatch', matches): user clicks position link in popup + // (matches obj is from hgFind) + + propTypes: { // Immutable.Map { + // position: initial value of position input + // loading (bool): display spinner next to position input + // positionMatches (Immutable.Vector of Maps): multiple search results for popup + + // Optional + className: pt.string, // class(es) to pass to wrapper div + org: pt.string, // name of organism currently selected (ex. Human) + db: pt.string, // name of database currently selected (ex. hg38) + }, + + // No-op update function for TextInput - we don't want blur to trigger model updates, + // only the autocomplete selection should update the model via onSpeciesSelect + noOpUpdate: function() {}, + + onSpeciesSelect: function(selectEle, item) { + if (item.disabled || !item.genome) return; + selectEle.innerHTML = item.label; + this.props.update(this.props.path, item.genome); + }, + + onSearchError: function(jqXHR, textStatus, errorThrown, term) { + return [{label: 'No genomes found', value: '', genome: '', disabled: true}]; + }, + + componentDidMount: function() { + // If we have a geneSuggest track, set up autocomplete. + var inputNode, $input; + inputNode = this.refs.input.getDOMNode(); + var sel = document.getElementById("genomeLabel"); + var boundSel = this.onSpeciesSelect.bind(null, sel); + initSpeciesAutoCompleteDropdown(inputNode.id, boundSel, null, null, null, this.onSearchError); + }, + + render: function() { + return ( +
+ +
+ +
+ Current Genome: + {this.props.org + " (" + this.props.db + ")"} +
+
+
+ ); + } + +}); // SpeciesSearch + +// Without this, jshint complains that SpeciesSearch is not used. Module system would help. +SpeciesSearch = SpeciesSearch;