From cc6416168b7fef20bc66ccfd121267ccdaac654e Mon Sep 17 00:00:00 2001 From: Colin Megill Date: Mon, 17 Aug 2020 16:36:12 -0400 Subject: [PATCH] mock reducer --- client/package-lock.json | 35 +++++- client/package.json | 1 + client/src/components/categorical/index.js | 15 ++- .../geneExpression/createGenesetDialogue.js | 117 ++++++++++++++++++ .../src/components/geneExpression/geneSet.js | 77 ++++++++---- client/src/components/geneExpression/index.js | 34 ++++- client/src/components/rightSidebar/index.js | 1 + client/src/reducers/genesets.js | 25 ++++ client/src/reducers/index.js | 2 + 9 files changed, 275 insertions(+), 32 deletions(-) create mode 100644 client/src/components/geneExpression/createGenesetDialogue.js create mode 100644 client/src/reducers/genesets.js diff --git a/client/package-lock.json b/client/package-lock.json index 9038fb82..2aa843aa 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -11858,7 +11858,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, "requires": { "loose-envify": "^1.0.0" } @@ -13797,6 +13796,11 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -13815,6 +13819,16 @@ "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", "dev": true }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, "lodash.kebabcase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", @@ -16413,6 +16427,15 @@ "scheduler": "^0.19.1" } }, + "react-easy-emoji": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-easy-emoji/-/react-easy-emoji-1.4.0.tgz", + "integrity": "sha512-TcufijpuWKgYgzbySEBukNef+y0HI/4PAJ4gc9vb1CF7Q4CcAS2ZV8VMZk0ObtKKwJJfVgAHVt86nXWOed8QXg==", + "requires": { + "lodash.assign": "^4.0.8", + "string-replace-to-array": "^1.0.1" + } + }, "react-fast-compare": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", @@ -18017,6 +18040,16 @@ "strip-ansi": "^6.0.0" } }, + "string-replace-to-array": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string-replace-to-array/-/string-replace-to-array-1.0.3.tgz", + "integrity": "sha1-yT66mZpe4k1zGuu69auja18Y978=", + "requires": { + "invariant": "^2.2.1", + "lodash.flatten": "^4.2.0", + "lodash.isstring": "^4.0.1" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", diff --git a/client/package.json b/client/package.json index b49053d0..9ab152e1 100644 --- a/client/package.json +++ b/client/package.json @@ -57,6 +57,7 @@ "react": "^16.13.1", "react-async": "^10.0.1", "react-dom": "^16.13.1", + "react-easy-emoji": "^1.4.0", "react-flip-toolkit": "^7.0.12", "react-helmet": "^5.2.1", "react-icons": "^3.10.0", diff --git a/client/src/components/categorical/index.js b/client/src/components/categorical/index.js index 0e48eba8..993fb4ee 100644 --- a/client/src/components/categorical/index.js +++ b/client/src/components/categorical/index.js @@ -2,6 +2,7 @@ import React from "react"; import { Button } from "@blueprintjs/core"; import { connect } from "react-redux"; +import emoji from "react-easy-emoji"; import * as globals from "../../globals"; import Category from "./category"; import { AnnotationsHelpers, ControlsHelpers } from "../../util/stateManager"; @@ -207,9 +208,19 @@ class Categories extends React.Component { ) : null} diff --git a/client/src/components/geneExpression/createGenesetDialogue.js b/client/src/components/geneExpression/createGenesetDialogue.js new file mode 100644 index 00000000..c7360a50 --- /dev/null +++ b/client/src/components/geneExpression/createGenesetDialogue.js @@ -0,0 +1,117 @@ +// import React from "react"; +// import { connect } from "react-redux"; +// import AnnoDialog from "../annoDialog"; +// // import LabelInput from "../labelInput"; +// // import { labelPrompt, isLabelErroneous } from "../labelUtil"; +// import actions from "../../actions"; + +// @connect((state) => ({ +// annotations: state.annotations, +// schema: state.annoMatrix?.schema, +// ontology: state.ontology, +// obsCrossfilter: state.obsCrossfilter, +// })) +// class CreateGenesetDialogue extends React.PureComponent { +// constructor(props) { +// super(props); +// this.state = { +// newLabelText: "", +// }; +// } + +// disableAddNewLabelMode = (e) => { +// const { dispatch } = this.props; +// this.setState({ +// newLabelText: "", +// }); +// dispatch({ +// type: "annotation: disable add new label mode", +// }); +// if (e) e.preventDefault(); +// }; + +// handleAddNewLabelToCategory = (e) => { +// const { dispatch, metadataField } = this.props; +// const { newLabelText } = this.state; + +// this.disableAddNewLabelMode(); +// dispatch( +// actions.annotationCreateLabelInCategory( +// metadataField, +// newLabelText, +// false +// ) +// ); +// e.preventDefault(); +// }; + +// addLabelAndAssignCells = (e) => { +// const { dispatch, metadataField } = this.props; +// const { newLabelText } = this.state; + +// this.disableAddNewLabelMode(); +// dispatch( +// actions.annotationCreateLabelInCategory(metadataField, newLabelText, true) +// ); +// e.preventDefault(); +// }; + +// labelNameError = (name) => { +// const { metadataField, ontology, schema } = this.props; +// return isLabelErroneous(name, metadataField, ontology, schema); +// }; + +// instruction = (label) => { +// return labelPrompt(this.labelNameError(label), "New, unique label", ":"); +// }; + +// handleChangeOrSelect = (label) => { +// this.setState({ newLabelText: label }); +// }; + +// render() { +// const { newLabelText } = this.state; +// const { metadataField, annotations, ontology, obsCrossfilter } = this.props; +// const ontologyEnabled = ontology?.enabled ?? false; + +// return ( +// <> +// +// } +// /> +// +// ); +// } +// } + +// export default CreateGenesetDialogue; diff --git a/client/src/components/geneExpression/geneSet.js b/client/src/components/geneExpression/geneSet.js index d49c45d0..c61f193c 100644 --- a/client/src/components/geneExpression/geneSet.js +++ b/client/src/components/geneExpression/geneSet.js @@ -4,34 +4,32 @@ import React from "react"; import _ from "lodash"; import { connect } from "react-redux"; -import HistogramBrush from "../brushableHistogram"; +import { Icon } from "@blueprintjs/core"; import * as globals from "../../globals"; import actions from "../../actions"; import Gene from "./gene"; -import { Button, ButtonGroup, Tooltip } from "@blueprintjs/core"; -import { - postUserErrorToast, - keepAroundErrorToast -} from "../framework/toasters"; import { memoize } from "../../util/dataframe/util"; +import Truncate from "../util/truncate"; -@connect(state => { +@connect((state) => { return { world: state.world, userDefinedGenes: state.controls.userDefinedGenes, - userDefinedGenesLoading: state.controls.userDefinedGenesLoading + userDefinedGenesLoading: state.controls.userDefinedGenesLoading, }; }) class GeneSet extends React.Component { + _memoGenesToUpper = memoize(this._genesToUpper, (arr) => arr); + constructor(props) { super(props); this.state = { isOpen: false, - haveFetched: false + haveFetched: false, }; } - _genesToUpper = listGenes => { + _genesToUpper = (listGenes) => { // Has to be a Map to preserve index const upperGenes = new Map(); for (let i = 0, { length } = listGenes; i < length; i += 1) { @@ -41,23 +39,19 @@ class GeneSet extends React.Component { return upperGenes; }; - _memoGenesToUpper = memoize(this._genesToUpper, arr => arr); - fetchGenes = () => { - const { world, dispatch, userDefinedGenes, setGenes } = this.props; + const { world, dispatch, setGenes } = this.props; const varIndexName = world.schema.annotations.var.index; - const { haveFetched } = this.state; const worldGenes = world.varAnnotations.col(varIndexName).asArray(); const upperGenes = this._genesToUpper(setGenes); - const upperUserDefinedGenes = this._genesToUpper(userDefinedGenes); const upperWorldGenes = this._memoGenesToUpper(worldGenes); dispatch({ type: "bulk user defined gene start" }); Promise.all( - [...upperGenes.keys()].map(upperGene => { + [...upperGenes.keys()].map((upperGene) => { /* Unlike bulk add... with gene sets this test needs to be within the set... */ // if (upperUserDefinedGenes.get(upperGene) !== undefined) { // return keepAroundErrorToast(`${upperGene} already exists`); @@ -87,25 +81,54 @@ class GeneSet extends React.Component { return undefined; }; + onGenesetMenuClick = () => { + const { isOpen, haveFetched } = this.state; + this.setState({ isOpen: !isOpen }); + if (!haveFetched) { + // this.fetchGenes(); TODO + } + }; + render() { const { setName, setGenes } = this.props; - const { haveFetched, isOpen } = this.state; + const { isOpen } = this.state; // console.log("geneSet setGenes variable: ", setGenes); return (
- + + + {setName} + + + + + {isOpen - ? _.map(setGenes, gene => { + ? _.map(setGenes, (gene) => { return ; }) : null} diff --git a/client/src/components/geneExpression/index.js b/client/src/components/geneExpression/index.js index 67b203ae..81beda76 100644 --- a/client/src/components/geneExpression/index.js +++ b/client/src/components/geneExpression/index.js @@ -3,10 +3,11 @@ import React from "react"; import _ from "lodash"; import { connect } from "react-redux"; +import emoji from "react-easy-emoji"; +import { Button } from "@blueprintjs/core"; import HistogramBrush from "../brushableHistogram"; import * as globals from "../../globals"; import GeneSet from "./geneSet"; -import AddGenes from "./addGenes"; import testGeneSets from "./test_data"; @@ -14,6 +15,7 @@ import testGeneSets from "./test_data"; return { userDefinedGenes: state.controls.userDefinedGenes, differential: state.differential, + genesets: state.genesets, }; }) class GeneExpression extends React.Component { @@ -29,8 +31,15 @@ class GeneExpression extends React.Component { return sets; }; + handleActivateCreateGenesetMode = () => { + const { dispatch } = this.props; + dispatch({ type: "geneset: activate add new geneset mode" }); + }; + render() { const { userDefinedGenes, differential } = this.props; + const geneSetsFeatureEnabledTODO = true; + console.log("genesets", this.props); return (
- + {geneSetsFeatureEnabledTODO ? ( +
+ +
+ ) : null} + {/* */} {userDefinedGenes.length > 0 ? _.map(userDefinedGenes, (geneName, index) => { return ( diff --git a/client/src/components/rightSidebar/index.js b/client/src/components/rightSidebar/index.js index 4e75ba05..dda4ea53 100644 --- a/client/src/components/rightSidebar/index.js +++ b/client/src/components/rightSidebar/index.js @@ -22,6 +22,7 @@ class RightSidebar extends React.Component { overflowY: "inherit", height: "inherit", width: "inherit", + padding: globals.leftSidebarSectionPadding, }} > diff --git a/client/src/reducers/genesets.js b/client/src/reducers/genesets.js new file mode 100644 index 00000000..b6812c2c --- /dev/null +++ b/client/src/reducers/genesets.js @@ -0,0 +1,25 @@ +/* +Reducers for geneset UI-state. +*/ +const GeneSets = ( + state = { + addGenesetModeActive: false, + isEditingGenesetName: false, + genesetAddingNewGenes: null, + }, + action +) => { + switch (action.type) { + case "geneset: activate add new geneset mode": { + return { + ...state, + addGenesetModeActive: true, + }; + } + + default: + return state; + } +}; + +export default GeneSets; diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js index 76d60f0c..9542f005 100644 --- a/client/src/reducers/index.js +++ b/client/src/reducers/index.js @@ -14,6 +14,7 @@ import differential from "./differential"; import layoutChoice from "./layoutChoice"; import controls from "./controls"; import annotations from "./annotations"; +import genesets from "./genesets"; import autosave from "./autosave"; import ontology from "./ontology"; import centroidLabels from "./centroidLabels"; @@ -30,6 +31,7 @@ const Reducer = undoable( ["obsCrossfilter", obsCrossfilter], ["ontology", ontology], ["annotations", annotations], + ["genesets", genesets], ["layoutChoice", layoutChoice], ["categoricalSelection", categoricalSelection], ["continuousSelection", continuousSelection],