Skip to content

Commit

Permalink
Dataset visualization as prop to <DatasetSelect>
Browse files Browse the repository at this point in the history
This exposes the ability for pages (e.g. sars-cov-2, influenza)
to define which elements are rendered by <DatasetSelect>, and
inject custom elements.

For instance, the geographic map of SARS-CoV-2 datasets is now
handed to <DatasetSelect> as a prop for rendering.

This commit was based off an original design by eharkins

Co-authored-by: eharkins <eli.harkins@gmail.com>
  • Loading branch information
jameshadfield and eharkins committed Apr 10, 2021
1 parent d9a6ebf commit 20974e6
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
63 changes: 47 additions & 16 deletions static-site/src/components/Datasets/dataset-select.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import "react-select/dist/react-select.css";
import "react-virtualized-select/styles.css";
import { get, sortBy } from 'lodash';
import { DatasetFilteringSelection } from "./filter-selection";
import { FilterSelect } from "./filter-selection";
import { ListDatasets } from "./list-datasets";
import { FilterDisplay } from "./filter-display";
import { collectAvailableFilteringOptions, computeFilterValues } from "./filter-helpers";
Expand All @@ -17,6 +17,10 @@ import { collectAvailableFilteringOptions, computeFilterValues } from "./filter-
* @prop {string | undefined} intendedUri Intended URI. Browser address will be replaced with this.
* @prop {Array} datasets Available datasets. Array of Objects.
* @prop {boolean} noDates Note: will be replaced in a subsequent commit
* @prop {Array | undefined} interface What elements to render? Elements may be strings or functinos. Order is respected.
* Available strings: "FilterSelect" "FilterDisplay", "ListDatasets"
* Functions will be handed an object with key(s): `datasets` (which may be filtered), and should return a react component for rendering.
* Default: ["FilterSelect", "FilterDisplay", "ListDatasets"]
*
* @returns React Component
*
Expand Down Expand Up @@ -70,23 +74,49 @@ class DatasetSelect extends React.Component {
}

render() {
// options only need to be calculated a single time per render, and by adding a debounce
// to `loadFilterOptions` we don't slow things down by comparing queries to a large number of options
const childrenToRender = this.props.interface || ["FilterSelect", "FilterDisplay", "ListDatasets"];
const filteredDatasets = this.getFilteredDatasets();
return (
<>
<DatasetFilteringSelection
key={String(Object.keys(this.state.filters).length)}
datasets={this.props.datasets}
applyFilter={this.applyFilter}
/>
<FilterDisplay
filters={this.state.filters}
applyFilter={this.applyFilter}
/>
<ListDatasets
datasets={this.getFilteredDatasets()}
showDates={!this.props.noDates}
/>
{childrenToRender.map((Child) => {
switch (Child) {
case "FilterSelect":
return (
<FilterSelect
key={String(Object.keys(this.state.filters).length)}
datasets={this.props.datasets}
applyFilter={this.applyFilter}
/>
);
case "FilterDisplay":
return (
<FilterDisplay
key="FilterDisplay"
filters={this.state.filters}
applyFilter={this.applyFilter}
/>
);
case "ListDatasets":
return (
<ListDatasets
key="ListDatasets"
datasets={filteredDatasets}
showDates={!this.props.noDates}
/>
);
default:
if (typeof Child === "function") {
return (
<Child
key={Child.name}
datasets={filteredDatasets}
/>
);
}
console.error("Unknown interface element passed to DatasetSelect");
return null;
}
})}
</>
);
}
Expand All @@ -95,6 +125,7 @@ class DatasetSelect extends React.Component {
DatasetSelect.propTypes = {
urlDefinedFilterPath: PropTypes.string,
intendedUri: PropTypes.string,
interface: PropTypes.array,
noDates: PropTypes.bool,
datasets: PropTypes.array.isRequired
};
Expand Down
2 changes: 1 addition & 1 deletion static-site/src/components/Datasets/filter-selection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const StyledTooltip = styled(ReactTooltip)`
pointer-events: auto !important;
`;

export const DatasetFilteringSelection = ({datasets, applyFilter}) => {
export const FilterSelect = ({datasets, applyFilter}) => {

const options = collectAvailableFilteringOptions(datasets);

Expand Down
7 changes: 6 additions & 1 deletion static-site/src/pages/sars-cov-2-page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ class Index extends React.Component {
If you know of a dataset not listed here, please let us know!
Please note that inclusion on this list does not indicate an endorsement by the Nextstrain team.
</splashStyles.FocusParagraph>
<DatasetMap datasets={this.state.catalogueDatasets}/>
<div className="row">
<MediumSpacer />
<div className="col-md-1"/>
Expand All @@ -169,6 +168,12 @@ class Index extends React.Component {
<DatasetSelect
datasets={this.state.filterList}
noDates
interface={[
DatasetMap,
"FilterSelect",
"FilterDisplay",
"ListDatasets"
]}
urlDefinedFilterPath={this.props["*"]}
intendedUri={this.props.uri}
/>
Expand Down

0 comments on commit 20974e6

Please sign in to comment.