diff --git a/client/src/components/framework/toasters.js b/client/src/components/framework/toasters.js index 3b0e67f4..46c9d4e8 100644 --- a/client/src/components/framework/toasters.js +++ b/client/src/components/framework/toasters.js @@ -13,6 +13,13 @@ A "user" error - eg, bad input export const postUserErrorToast = message => ErrorToastTopCenter.show({ message, intent: Intent.WARNING }); +/* +A toast the user must dismiss manually, because they need to act on its information, +ie., 8 bulk add genes out of 40 were bad. Manually see which ones and fix. +*/ +export const keepAroundErrorToast = message => + ErrorToastTopCenter.show({ message, timeout: 0, intent: Intent.WARNING }); + /* a hard network error */ diff --git a/client/src/components/geneExpression/index.js b/client/src/components/geneExpression/index.js index b17d5d51..8c1f53f7 100644 --- a/client/src/components/geneExpression/index.js +++ b/client/src/components/geneExpression/index.js @@ -6,12 +6,21 @@ import _ from "lodash"; import fuzzysort from "fuzzysort"; import { connect } from "react-redux"; -import { MenuItem, Button } from "@blueprintjs/core"; +import { + MenuItem, + Button, + FormGroup, + InputGroup, + ControlGroup +} from "@blueprintjs/core"; import { Suggest } from "@blueprintjs/select"; import HistogramBrush from "../brushableHistogram"; import * as globals from "../../globals"; import actions from "../../actions"; -import { postUserErrorToast } from "../framework/toasters"; +import { + postUserErrorToast, + keepAroundErrorToast +} from "../framework/toasters"; import ExpressionButtons from "./expressionButtons"; import finiteExtent from "../../util/finiteExtent"; @@ -67,6 +76,14 @@ const filterGenes = (query, genes) => { }; }) class GeneExpression extends React.Component { + constructor(props) { + super(props); + this.state = { + bulkAdd: "", + tab: "autosuggest" + }; + } + handleClick(g) { const { world, dispatch, userDefinedGenes } = this.props; const gene = g.target; @@ -87,6 +104,29 @@ class GeneExpression extends React.Component { } } + handleBulkAddClick() { + const { world, dispatch, userDefinedGenes } = this.props; + const { bulkAdd } = this.state; + + const genes = _.uniq(bulkAdd.split(", ").map(g => g.trim())); + + genes.forEach(gene => { + if (userDefinedGenes.indexOf(gene) !== -1) { + keepAroundErrorToast("That gene already exists"); + } else if (!_.find(world.varAnnotations, { name: gene })) { + keepAroundErrorToast(`${gene} doesn't appear to be a valid gene name.`); + } else { + dispatch(actions.requestUserDefinedGene(gene)); + dispatch({ + type: "user defined gene", + data: gene + }); + } + }); + + this.setState({ bulkAdd: "" }); + } + render() { const { world, @@ -95,6 +135,8 @@ class GeneExpression extends React.Component { differential } = this.props; + const { tab, bulkAdd } = this.state; + return (