diff --git a/client/src/components/geneExpression/index.js b/client/src/components/geneExpression/index.js index adcec5f9..92f97fee 100644 --- a/client/src/components/geneExpression/index.js +++ b/client/src/components/geneExpression/index.js @@ -1,31 +1,26 @@ /* rc slider https://www.npmjs.com/package/rc-slider */ import React from "react"; -import _ from "lodash"; import { connect } from "react-redux"; import { Button } from "@blueprintjs/core"; import GeneSet from "./geneSet"; -import testGeneSets from "./test_data"; import CreateGenesetDialogue from "./menus/createGenesetDialogue"; @connect((state) => { return { - userDefinedGenes: state.controls.userDefinedGenes, differential: state.differential, - genesets: state.genesets, + genesets: state.genesets.genesets, }; }) class GeneExpression extends React.Component { - renderTestGeneSets = () => { + renderGeneSets = () => { const sets = []; + const { genesets } = this.props; - _.forEach(testGeneSets, (setGenes, setName) => { - sets.push( - - ); - }); - + for (const [name, genes] of genesets) { + sets.push(); + } return sets; }; @@ -75,7 +70,7 @@ class GeneExpression extends React.Component {
{this.renderDiffexpGeneSets()}
-
{this.renderTestGeneSets()}
+
{this.renderGeneSets()}
); } diff --git a/client/src/components/geneExpression/menus/createGenesetDialogue.js b/client/src/components/geneExpression/menus/createGenesetDialogue.js index d4ed99f0..bba23b84 100644 --- a/client/src/components/geneExpression/menus/createGenesetDialogue.js +++ b/client/src/components/geneExpression/menus/createGenesetDialogue.js @@ -10,7 +10,7 @@ import LabelInput from "../../categorical/labelInput"; schema: state.annoMatrix?.schema, ontology: state.ontology, obsCrossfilter: state.obsCrossfilter, - genesets: state.genesets, + genesetsUI: state.genesetsUI, })) class CreateGenesetDialogue extends React.PureComponent { constructor(props) { @@ -60,12 +60,12 @@ class CreateGenesetDialogue extends React.PureComponent { render() { const { genesetName } = this.state; - const { metadataField, genesets } = this.props; + const { metadataField, genesetsUI } = this.props; return ( <> { switch (action.type) { - case "geneset: activate add new geneset mode": { - return { - ...state, - createGenesetModeActive: true, - }; - } - case "geneset: disable create geneset mode": { - return { - ...state, - createGenesetModeActive: false, - }; - } + /** + * { + * type: "geneset: create", + * name: string, // gene set name + * genes: Set || Array || undefined + * } + */ case "geneset: create": { + const { name, genes } = action; + const { genesets } = state; + if (genesets.has(name) !== undefined) + throw new Error("geneset: create -- name already defined."); + + const newGenesets = new Map(genesets); // clone + newGenesets.set(name, new Set(genes || [])); return { - ...state, - userCreatedGenesets: Object.assign( - {}, - { [action.genesetName]: {} }, - ...state.userCreatedGenesets - ), + genesets: newGenesets, }; } + + /** + * { + * type: "geneset: delete", + * name: string + * } + */ + case "geneset: delete": { + const { name } = action; + const { genesets } = state; + if (!genesets.has(name)) + throw new Error("geneset: delete -- name does not exist."); + + const newGenesets = new Map(genesets); // clone + newGenesets.delete(name); + return { + genesets: newGenesets, + }; + } + + /** + * { + * type: "geneset: add genes" + * name: string, // gene set name + * genes: Set || Array // genes to add + * } + */ + case "geneset: add genes": { + const { name, genes } = action; + const { genesets } = state; + if (!genesets.has(name)) + throw new Error("geneset: add genes -- name does not exist."); + + const newGenesets = new Map(genesets); // clone + const newGenes = new Set(genesets.get(name)); // clone + for (const gene of genes) { + newGenes.add(gene); + } + newGenesets.set(name, newGenes); + return { + genesets: newGenesets, + }; + } + + /** + * { + * type: "geneset: del genes" + * name: string, // gene set name + * genes: Set || Array // genes to delete + * } + */ + case "geneset: del genes": { + const { name, genes } = action; + const { genesets } = state; + if (!genesets.has(name)) + throw new Error("geneset: add genes -- name does not exist."); + + const newGenesets = new Map(genesets); // clone + const newGenes = new Set(genesets.get(name)); // clone + for (const gene of genes) { + newGenes.delete(gene); + } + newGenesets.set(name, newGenes); + return { + genesets: newGenesets, + }; + } + default: return state; } diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js index a16af6f4..a5a5a59d 100644 --- a/client/src/reducers/index.js +++ b/client/src/reducers/index.js @@ -4,7 +4,7 @@ import thunk from "redux-thunk"; import cascadeReducers from "./cascade"; import undoable from "./undoable"; import config from "./config"; -import userInfo from "./userinfo"; +import userInfo from "./userInfo"; import annoMatrix from "./annoMatrix"; import obsCrossfilter from "./obsCrossfilter"; import categoricalSelection from "./categoricalSelection"; @@ -16,6 +16,7 @@ import layoutChoice from "./layoutChoice"; import controls from "./controls"; import annotations from "./annotations"; import genesets from "./genesets"; +import genesetsUI from "./genesetsUI"; import autosave from "./autosave"; import ontology from "./ontology"; import centroidLabels from "./centroidLabels"; @@ -33,6 +34,7 @@ const Reducer = undoable( ["ontology", ontology], ["annotations", annotations], ["genesets", genesets], + ["genesetsUI", genesetsUI], ["layoutChoice", layoutChoice], ["categoricalSelection", categoricalSelection], ["continuousSelection", continuousSelection],