198c9b8daecc44fbda6a6494c566c723920f030a lrnassar Wed Mar 11 18:25:21 2026 -0700 Fixing a few hundred clear typos with the help of Claude. Some are less important in code comments, but majority of them are in user-facing places. I manually approved 60%+ of the changes and didn't see any that were an incorrect suggestion, at worst it was potentially uncessesary, like a code comment having cant instead of can't. No RM. diff --git src/hg/js/react/hgIntegrator/hgIntegrator.jsx src/hg/js/react/hgIntegrator/hgIntegrator.jsx index 35bd15cf800..bcf5140598c 100644 --- src/hg/js/react/hgIntegrator/hgIntegrator.jsx +++ src/hg/js/react/hgIntegrator/hgIntegrator.jsx @@ -1,735 +1,735 @@ /** @jsx React.DOM */ /* global ImmutableUpdate, PathUpdate, CheckboxLabel, CladeOrgDb, Icon, LabeledSelect */ /* global LoadingImage, Modal, PositionSearch, Section, SetClearButtons, Sortable, TextInput */ /* global UserRegions */ var pt = React.PropTypes; // AnnoGrator interface. var RegionSelect = React.createClass({ // Let the user choose between position/search term, whole genome, or user-defined regions. // Modules PositionSearch and UserRegions handle the details. 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) // update(path + 'hgi_range') called when user changes genome/position select // update(path + 'changeRegions') called when user clicks to change pasted/uploaded regions // update(path + 'clearRegions') called when user clicks to reset pasted/uploaded regions propTypes: { regionSelect: pt.object.isRequired, // expected to be Immutable { // disableGenome (bool): disable genome-wide query option // hgi_range: position | genome | userRegions // loading (bool): display spinner (e.g. while uploading file) // positionInfo: PositionSearch's expected Immutable state // userRegions: UserRegions' expected Immutable state // } db: pt.string // must be given if positionInfo includes geneSuggestTrack }, menuOptions: Immutable.fromJS([ { label: 'position or search term', value: 'position' }, { label: 'genome', value: 'genome'}, { label: 'defined regions', value: 'userRegions'} ]), menuOptionsNoGenome: Immutable.fromJS([ { label: 'position or search term', value: 'position' }, { label: 'genome', value: 'genome', disabled: true }, { label: 'defined regions', value: 'userRegions' } ]), changeRegions: function() { // user clicked to edit pasted/uploaded regions this.props.update(this.props.path.concat('changeRegions')); }, clearRegions: function() { // user clicked to reset pasted/uploaded regions this.props.update(this.props.path.concat('clearRegions')); }, render: function() { var props = this.props; var regionSelect = props.regionSelect; var userRegions = regionSelect.get('userRegions'); var selected = regionSelect.get('hgi_range'); var disableGenome = regionSelect.get('disableGenome'); var menuOptions = disableGenome ? this.menuOptionsNoGenome : this.menuOptions; var modeControls = null; if (selected === 'userRegions') { modeControls = [ {userRegions.get('summary')}, , ]; } else if (selected !== 'genome') { modeControls = ; } var spinner = null; if (regionSelect.get('loading')) { spinner = ; } return (
{spinner} {modeControls}
); } }); // RegionSelect var LabeledSelectRow = React.createClass({ // Build a row of LabeledSelect's from an Immutable.List of Immutable descriptor objects // like {label, valLabels, selected} (or null, in which case skip to the next descriptor). mixins: [PathUpdate, ImmutableUpdate], // update(path + ix) called when user changes the ixth menu propTypes: { descriptors: pt.object.isRequired, // Immutable.List[{ valLabels, selected }] }, makeMenuFromDescriptor: function(descriptor, ix) { // Make a LabeledSelect using fields of descriptor if (! descriptor || descriptor.get('hide')) { return null; } else { var key = 'lsrMenu' + ix; return ( ); } }, render: function() { var descriptors = this.props.descriptors; return (
{descriptors.map(this.makeMenuFromDescriptor).toJS()}
); } }); // LabeledSelectRow function makeSchemaLink(schemaUrl) { // Return a React component link to hgTables' schema page. if (schemaUrl) { return View table schema ; } else { return null; } } var AddDataSource = React.createClass({ // A section-lite with group/track/table (or someday group/composite/view/etc) selects // and a button to add the selected track/table mixins: [PathUpdate, ImmutableUpdate], // update(path + 'addDataSource') called when user clicks Add button // update(path + 'addDsMenuSelect' + ix) called when user changes the ixth menu // update(path + 'trackHubs') called when user clicks track hubs button // update(path + 'customTracks') called when user clicks custom tracks button propTypes: { addDsInfo: pt.object.isRequired // Immutable obj w/List of menu descriptors, // hgTables schema URL, & disabled flag }, onAdd: function() { // Send path + 'addDataSource' to app model this.props.update(this.props.path.concat('addDataSource')); }, onTrackHubs: function() { // Send path + 'trackHubs' to app model this.props.update(this.props.path.concat('trackHubs')); }, onCustomTracks: function() { // Send path + 'customTracks' to app model this.props.update(this.props.path.concat('customTracks')); }, render: function() { var path = this.props.path || []; var addDsInfo = this.props.addDsInfo; if (! (addDsInfo && addDsInfo.size)) { // Still waiting for data from server return ; } var schemaLink = makeSchemaLink(addDsInfo.get('schemaUrl')); return (
Add Data Source
{schemaLink}
get more data:
); } }); // AddDataSource var FieldSelect = React.createClass({ // Popup with checkboxes for selecting fields of some tables. mixins: [PathUpdate, ImmutableUpdate], // update(path + 'checked' + track + table + field, newValue): // called when user clicks a field's checkbox // update(path + 'setAll' + track + table, newValue): // called when user clicks 'Set all' or 'Clear all' // update(path + 'remove') called when user clicks X icon to hide this popup // update(path + 'selectRelated' + track, newValue) : user changed related table select // update(path + 'addRelated' + track) : user clicked button to add selected table propTypes: { // Optional: fieldSelect: pt.object, // renders popup if truthy. // maps table to list of fields + checked state. }, onAddRelated: function(track) { // The user clicked the button for adding a related table for track. this.props.update(this.props.path.concat('addRelated', track)); }, onDone: function() { // Close the Modal when user clicks Done button. this.props.update(this.props.path.concat('remove')); }, renderTableInfo: function(track, table, tableInfo) { // Show table's label, set & clear buttons, and then a checkbox for each field, // labeled by field name. var update = this.props.update; var removePath = this.props.path.concat('removeRelated', track, table); var setClearPath = this.props.path.concat('setAll', track, table); var maybeRemoveIcon = (track !== table) ? : null; var fields = tableInfo.get('fields'); var bodyRows; if (! fields) { bodyRows = ; } else { bodyRows = fields.map(function(setting) { var field = setting.get('name'); var checked = setting.get('checked'); var desc = setting.get('desc'); var checkedPath = this.props.path.concat('checked', track, table, field); var tfPrefix = table + '.' + field + '.'; return ( {field} {desc} ); }, this).toArray(); } return [ {tableInfo.get('label')}
{maybeRemoveIcon} , bodyRows, ]; }, renderRelatedTables: function(track, relatedTables, disableAddButton) { // If a track has related tables, let the user choose one and click to add it. if (relatedTables) { var selected = relatedTables.get('selected'); var options = relatedTables.get('options'); var onAddRelated = _.bind(this.onAddRelated, this, track); return [ , , ]; } }, renderTrackSections: function() { // For each track, make a section with table name and field checkboxes for the track // table and any selected related tables, and (if appl.) a way to select related tables. var fieldSelect = this.props.fieldSelect; var i = 0; return fieldSelect.map(function(info, track) { // Make one track section var relatedTables = info.get('relatedAvailable'); var tableFields = info.get('tableFields'); var disableAddButton = info.get('disableAddButton'); var separator = null; if (i > 0) { separator = [ , ]; } i++; return [ separator, tableFields.map(function (tableInfo, table) { return this.renderTableInfo(track, table, tableInfo); }, this).toArray(), this.renderRelatedTables(track, relatedTables, disableAddButton) ]; }, this).toArray(); }, render: function() { if (this.props.fieldSelect) { if (this.props.fieldSelect.size > 0) { return (
{/* If tbody is omitted here, rows for newly selected tables are appended */} {/* after the tbody that Chrome automatically inserts, causing the new */} {/* tables to appear at the bottom of the table. */} {this.renderTrackSections()}
); } else { return ( ); } } else { return null; } } }); // FieldSelect var OutFileOptions = React.createClass({ // Show output file options, with button to choose fields. mixins: [PathUpdate, ImmutableUpdate], // update(path + 'doFile') called when user clicks file checkbox // update(path + 'fileName') called when user changes file name // update(path + 'doGzip') called when user clicks gzip checkbox // update(path + 'chooseFields') called when user clicks the select fields button // update(path + 'fieldSelect' + table + field + 'checked', newValue): // called when user clicks a field's checkbox // update(path + 'fieldSelect' + 'remove') // called when user clicks X icon to hide the fieldSelect popup // update(path + 'getOutput') called when user clicks the get output button propTypes: { // Optional: options: pt.object, // should be Immutable.Map {doFile, fileName, doGzip} fieldSelect: pt.object, // table/field info from server following click on // 'Choose fields' button showLoadingImage: pt.bool, // If true, show loading image disableGetOutput: pt.bool, // If true, disable Get output button disableGetOutputMessage: pt.node // If disableGetOutput, show this message }, getDefaultProps: function() { return { showLoadingImage: false }; }, onChooseFields: function() { // user click the "Choose fields..." button var path = this.props.path || []; this.props.update(path.concat('chooseFields')); }, onGetOutput: function() { // user click the "Get output" button var path = this.props.path || []; this.props.update(path.concat('getOutput')); }, render: function() { var doFile = this.props.options.get('doFile'); var fileName = this.props.options.get('fileName'); var doGzip = this.props.options.get('doGzip'); var path = this.props.path || []; var fileInputDisplay = doFile ? 'inline-block' : 'none'; if (this.props.disableGetOutput) { return this.props.disableGetOutputMessage; } return (
name:

); } }); // OutFileOptions var QueryBuilder = React.createClass({ // Interface for adding and configuring data sources and output options mixins: [PathUpdate, ImmutableUpdate], // update() calls: see OutFileOptions; also: // update(path + 'dataSources' + 'reorder'): user finished drag&drop of Sortable dataSource // update(path + 'dataSources' + i + 'remove'): remove the ith dataSource propTypes: { // Optional: dataSources: pt.object, // Data sources (tracks) outFileOptions: pt.object, // Output options addDsInfo: pt.object, // Options for adding a data source fieldSelect: pt.object, // If present, show 'Choose fields' modal showLoadingImage: pt.bool // If true, show loading image (for query execution) }, renderDataSource: function(dataSource, i) { // Render a single dataSource ({ trackPath, label, schemaUrl }). var dsKey = 'ds' + i; var path = this.props.path.concat('dataSources', i); var schemaLink = makeSchemaLink(dataSource.get('schemaUrl')); return (
{dataSource.get('label')} {schemaLink}
); }, renderDataSources: function(dataSources) { // Wrap Sortable around rendered dataSources if we have enough data. var reorderPath = this.props.path.concat('dataSources', 'reorder'); if (dataSources && dataSources.size) { return ( {dataSources.map(this.renderDataSource).toJS()} ); } else { return (
please add at least one data source
); } }, render: function() { var addDsInfo = this.props.addDsInfo; var dataSources = this.props.dataSources; var outputInfo = this.props.outFileOptions || Immutable.Map(); if (! (addDsInfo && dataSources)) { // Waiting for data from server return
; } else { var fieldSelect = this.props.fieldSelect; var disableGetOutput = (! (dataSources && dataSources.size)); var disableGetOutputMessage = At least one data source must be added. ; return (
{this.renderDataSources(dataSources)}
); } } }); // QueryBuilder var DbPosAndQueryBuilder = React.createClass({ // Container for selecting a species, configuring position/genome, and building a query. mixins: [PathUpdate, ImmutableUpdate], // update() calls: see CladeOrgDb, RegionSelect and QueryBuilder propTypes: { // Optional: cladeOrgDbInfo: pt.object, // See CladeOrgDb regionSelect: pt.object, // See RegionSelect dataSources: pt.object, // Data sources (tracks) outFileOptions: pt.object, // Output options addDsInfo: pt.object, // Options for adding a data source fieldSelect: pt.object, // If present, show 'Choose fields' modal showLoadingImage: pt.bool // If true, show loading image (for query execution) }, render: function() { var path = this.props.path; var cladeOrgDbInfo = this.props.cladeOrgDbInfo; if (! cladeOrgDbInfo) { // Waiting for initial data from server return
; } else { return (
); } } }); // dbPosAndQueryBuilder function helpSection() { return (

The Data Integrator finds items in different tracks that overlap by position, and unlike the Table Browser's intersection function, the Data Integrator can output all fields from all selected tracks. Up to 5 different tracks may be queried at a time.

This section contains a brief overview of Data Integrator controls. For more information on using the tools, see the Data Integrator User's Guide.

Select Genome Assembly and Region
The controls in this section are for selecting a genome assembly and region to search.

  • group: A species group: Mammal, Vertebrate, Insect etc.
  • genome: A single species such as Human or Mouse (not available for certain tracks with restrictions on data sharing).
  • assembly: A version of the reference genome assembly such as GRCh37/hg19.

Configure Data Sources
Currently selected data sources (tracks, custom tracks, hub tracks etc) are listed with icons for reordering the data sources. The first data source is special in that data from the remaining data sources appear only when they overlap with the first data source. Under "Add Data Source", several menus display available data sources:

  • track group: - A category of data track, for example "Genes and Gene Prediction" + A category of data track, for example "Genes and Gene Predictions" or "Regulation".
  • track: One or more data tables containing results of an experiment or a group of closely related experiments. Some tracks are not available when the region is set to genome due to the data provider's restrictions on sharing.
  • table: This appears only when the selected track has more than one data table.
These sections can be reordered by dragging on the section title or arrow icon on the left. To remove a section, click the icon to the right of the title. Click on the Add button to add a new data source.

Output Options

  • Send output to file: check this box to have output sent to a local file instead of to the web browser window.
    When this is checked, additional options appear:
    • name: the file name to which output will be saved
    • compress with gzip: check this box to have the output file compressed by gzip (.gz). This saves disk space and may reduce network transfer time.
  • Choose fields: click this button to pop up a dialog box with a checkbox for each field of each data source. If a checkbox is checked, that field will appear in the output. Some tracks also have related mysql tables that can be selected and added to output. However, some of those tables may be unavailable when region is set to genome due to the data provider's restrictions on sharing.

); } var AppComponent = React.createClass({ // AnnoGrator interface mixins: [ImmutableUpdate], getDefaultProps: function() { return { path: [] }; }, render: function() { var appState = this.props.appState; var appStateJS = appState.toJS(); console.log('top-level render:', appStateJS); var path = this.props.path; return (
Data Integrator
{helpSection()}
); } }); // Without this, jshint complains that AppComponent is not used. Module system would help. AppComponent = AppComponent;