diff --git a/package-lock.json b/package-lock.json index 441d637ee..fac506d18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4507,9 +4507,9 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" }, "cytoscape": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.3.3.tgz", - "integrity": "sha512-6O+/o4Pb8hSqPLzpDveIRO63EjLLm4Y/PgOyGe/CqBDS4ptfwhheIo/+YG9K+K3DgbdP0RgUQii/dYY9vwKQew==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.10.0.tgz", + "integrity": "sha512-lWOnG4HJQD0cy+tCiBmbV/QRknInuZ8HvjcUifQZ7E4LWmKMvl6d5eP0LaaRLfBJAplXWcJfwc17ZJ/nwPeaYg==", "requires": { "heap": "^0.2.6", "lodash.debounce": "^4.0.8" @@ -4523,6 +4523,11 @@ "webcola": "^3.3.6" } }, + "cytoscape-context-menus": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/cytoscape-context-menus/-/cytoscape-context-menus-3.0.6.tgz", + "integrity": "sha512-eRsAIg/HYOZOUfTvBK4L0t9ikdRuQULoB8ilB8AZ9D7zGfRjQip/quDH/H20n3IFMe6pb9XYAwVMHWZtlMjR1w==" + }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -4538,18 +4543,18 @@ "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==" }, "d3-drag": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz", - "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.4.tgz", + "integrity": "sha512-ICPurDETFAelF1CTHdIyiUM4PsyZLaM+7oIBhmyP+cuVjze5vDZ8V//LdOFjg0jGnFIZD/Sfmk0r95PSiu78rw==", "requires": { "d3-dispatch": "1", "d3-selection": "1" } }, "d3-path": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", - "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.8.tgz", + "integrity": "sha512-J6EfUNwcMQ+aM5YPOB8ZbgAZu6wc82f/0WFxrxwV6Ll8wBwLaHLKCqQ5Imub02JriCVVdPjgI+6P3a4EWJCxAg==" }, "d3-selection": { "version": "1.4.0", @@ -4605,10 +4610,9 @@ } }, "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.1.tgz", + "integrity": "sha512-C14oTzTZy8DH1Eq8N78owrCWvf3+cnJw88BTK/N3DYWVxDJuJzPaNdplzYxDYuuXXGvqBcO4Vy5SOrwAooXSWw==" }, "date-now": { "version": "0.1.4", @@ -24095,6 +24099,11 @@ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, "js-cookie": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.0.tgz", @@ -24978,6 +24987,14 @@ "cli-cursor": "^2.1.0", "date-fns": "^1.27.2", "figures": "^2.0.0" + }, + "dependencies": { + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + } } }, "load-json-file": { @@ -26160,6 +26177,17 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" }, + "notistack": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-0.8.9.tgz", + "integrity": "sha512-nRHQVWUfgHnvnKrjRbRX9f+YAnbyh96yRyO5bEP/FCLVLuTZcJOwUr0GZ7Xr/8wK3+hXa9JYpXUkUhSxj1K8NQ==", + "requires": { + "classnames": "^2.2.6", + "hoist-non-react-statics": "^3.3.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.6" + } + }, "now-and-later": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", @@ -26614,6 +26642,11 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" }, + "papaparse": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.0.2.tgz", + "integrity": "sha512-FoaaFfNlCztJ7c+XD1Fgb0zIJ530HwSr6FBfM1mcMzLtIWoTxE5paBNJWiCWFjDrTzGiEG/uIUfqVzgKxqd+Sw==" + }, "parallel-transform": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", diff --git a/package.json b/package.json index 073c3aad5..911058625 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,22 @@ "@material-ui/styles": "^4.0.2", "aws-amplify": "^1.1.28", "clsx": "^1.0.4", - "cytoscape": "^3.3.3", + "color": "^3.1.2", + "cytoscape": "^3.10.0", "cytoscape-cola": "^2.3.0", + "cytoscape-context-menus": "^3.0.6", + "date-fns": "^2.0.1", "google-protobuf": "^3.8.0", "history": "^4.9.0", "html2canvas": "^1.0.0-alpha.12", + "jquery": "^3.4.1", "lodash": "latest", "material-design-icons": "^3.0.1", "material-ui": "^1.0.0-beta.47", "material-ui-flat-pagination": "^3.2.0", "material-ui-rating": "^3.1.1", + "notistack": "^0.8.9", + "papaparse": "^5.0.2", "react": "^16.8.6", "react-dom": "^16.8.6", "react-dropzone": "^8.0.4", @@ -35,7 +41,8 @@ "redux": "^4.0.1", "redux-thunk": "^2.3.0", "snet-sdk-web": "^1.0.0-beta.6", - "utf8": "^3.0.0" + "utf8": "^3.0.0", + "validate.js": "^0.13.1" }, "scripts": { "start": "react-scripts start", diff --git a/src/assets/images/ThirdPartyServices/snet/text_generation/BarackObama.jpg b/src/assets/images/ThirdPartyServices/snet/text_generation/BarackObama.jpg new file mode 100644 index 000000000..546c2cc3e Binary files /dev/null and b/src/assets/images/ThirdPartyServices/snet/text_generation/BarackObama.jpg differ diff --git a/src/assets/images/ThirdPartyServices/snet/text_generation/BarackObama_avatar.jpg b/src/assets/images/ThirdPartyServices/snet/text_generation/BarackObama_avatar.jpg new file mode 100644 index 000000000..d3e5529dc Binary files /dev/null and b/src/assets/images/ThirdPartyServices/snet/text_generation/BarackObama_avatar.jpg differ diff --git a/src/assets/thirdPartyServices/index.js b/src/assets/thirdPartyServices/index.js index 29c355655..9b23645c2 100644 --- a/src/assets/thirdPartyServices/index.js +++ b/src/assets/thirdPartyServices/index.js @@ -45,7 +45,6 @@ const SiggraphColorization = lazy(() => import("./snet/siggraph_colorization")); const TextGeneration = lazy(() => import("./snet/text_generation")); const PneumoniaDiagnosis = lazy(() => import("./snet/pneumonia_diagnosis")); - const AlertBox = lazy(() => import("../../components/common/AlertBox")); class ThirdPartyCustomUIComponents { @@ -122,5 +121,4 @@ addSnetCustomUI("siggraph-colorization", SiggraphColorization); addSnetCustomUI("text-generation", TextGeneration); addSnetCustomUI("pneumonia-diagnosis", PneumoniaDiagnosis); - export default thirdPartyCustomUIComponents; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationResultDownload.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationResultDownload.js deleted file mode 100644 index 2a66942a1..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationResultDownload.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; -import logo from "./mozi_globe.png"; -import { Grid, Button, Typography } from "@material-ui/core"; -import { ArrowDownward } from "@material-ui/icons"; - -export default class AnnotationResultDownload extends React.Component { - render() { - return ( - - - - MOZI globe logo - - Annotaion result ready! - - - The result was too large for visualization. Please click the button below to download the annotation - result file. - - - - - - - ); - } -} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationResultVisualizer.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationResultVisualizer.js deleted file mode 100644 index b2831fdbf..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationResultVisualizer.js +++ /dev/null @@ -1,330 +0,0 @@ -import React from "react"; -import * as cytoscape from "cytoscape"; -import { CYTOSCAPE_COLA_CONFIG, CYTOSCAPE_STYLE } from "./visualizer.config"; -import * as cola from "cytoscape-cola"; -import { - Grid, - FormControlLabel, - Checkbox, - IconButton, - Tooltip, - ExpansionPanel, - ExpansionPanelSummary, - ExpansionPanelDetails, - FormGroup, -} from "@material-ui/core"; -import { - Shuffle, - PhotoCameraOutlined, - FileCopyOutlined, - HelpOutline, - Share, - ExpandMore, - ChangeHistory, -} from "@material-ui/icons"; - -const AnnotationColorsLight = ["#c2ddf0", "#d2cfe2", "#e6e2cb", "#E0D0E3", "#C1CEE8", "#C8DECC"]; -const AnnotationColorsDark = ["#70b1dc", "#776fa9", "#b6a863", "#a06fa9", "#587bc1", "#70a97a"]; - -export default class AnnotationResultVisualizer extends React.Component { - constructor(props) { - super(props); - this.state = { - selectedNode: { node: null, position: null }, - history: [], - }; - this.cy_wrapper = React.createRef(); - cytoscape.use(cola); - } - - randomLayout() { - this.layout = this.cy.layout(CYTOSCAPE_COLA_CONFIG); - this.layout.run(); - } - - breadthFirstLayout() { - if (this.layout) this.layout.stop(); - this.layout = this.cy.layout({ name: "breadthfirst" }); - this.layout.run(); - } - - takeScreenshot() { - const image = this.cy.jpg(); - const link = document.createElement("a"); - link.setAttribute("href", image); - link.setAttribute("download", "mozi-graph.jpg"); - link.click(); - } - - componentDidMount() { - this.cy = cytoscape({ - container: this.cy_wrapper.current, - hideEdgesOnViewport: true, - }); - this.cy.add(this.props.graph.nodes.filter(n => n.data.group === "main" && n.data.id)); - this.toggleAnnotationVisibility(this.props.annotations[0], true); - this.cy.style(CYTOSCAPE_STYLE.concat(this.assignColorToAnnotations())); - this.registerEventListeners(); - this.randomLayout(); - } - - componentDidUpdate(prevProps) { - if (prevProps.sliderWidth != this.props.sliderWidth) { - this.randomLayout(); - } - } - - registerEventListeners() { - this.cy.nodes().on("mouseover", event => { - this.setState({ - selectedNode: { - node: event.target.data(), - position: event.renderedPosition, - }, - }); - }); - this.cy.nodes().on("select", event => { - this.focusOnNode(event.target.data().id); - }); - this.cy.nodes().on("mouseout", event => { - this.setState({ selectedNode: { node: null, position: null } }); - }); - this.cy.nodes().on("unselect", event => { - this.removeFocus(); - }); - } - - removeFocus() { - this.cy.batch(() => { - this.cy.elements().style({ opacity: 1 }); - }); - } - - assignColorToAnnotations() { - return this.props.annotations.reduce((acc, ann, i, arr) => { - acc.push({ - selector: 'edge[group="' + ann + '"]', - style: { - "line-color": AnnotationColorsLight[i], - "text-outline-color": AnnotationColorsLight[i], - "target-arrow-color": AnnotationColorsDark[i], - }, - }); - acc.push({ - selector: 'node[group="' + ann + '"]', - style: { - "background-color": AnnotationColorsDark[i], - color: "#fff", - "text-outline-width": 2, - "text-outline-color": AnnotationColorsDark[i], - }, - }); - return acc; - }, []); - } - - focusOnNode(id) { - const hood = this.cy.getElementById(id).closedNeighborhood(); - this.cy.fit(hood); - this.cy.batch(() => { - this.cy - .elements() - .difference(hood) - .style({ opacity: 0.1 }); - }); - } - - downloadGraphJSON() { - const json = `data:text/json;charset=utf-8, ${encodeURIComponent(JSON.stringify(this.props.graph))}`; - const link = document.createElement("a"); - link.setAttribute("href", json); - link.setAttribute("download", "annotation-graph.json"); - link.click(); - } - - toggleAnnotationVisibility(annotation, show) { - show - ? this.cy.batch(() => { - this.cy.add(this.props.graph.nodes.filter(e => e.data.group === annotation && e.data.id)); - this.cy.add( - this.props.graph.edges.filter(e => e.data.group === annotation && e.data.source && e.data.target) - ); - }) - : this.cy.remove(`[group='${annotation}']`); - this.randomLayout(); - this.registerEventListeners(); - } - - annotationPercentage(annotation) { - return ( - (100 * this.props.graph.edges.filter(e => e.data.group === annotation).length) / this.props.graph.edges.length - ); - } - - formatDescription(description) { - if (description.indexOf("https://") > -1 || description.indexOf("http://") > -1) { - return ( - - Learn more - - ); - } - return description; - } - - render() { - console.log("width", this.props.sliderWidth); - - return ( -
- - -
- - this.randomLayout()}> - - - - - this.breadthFirstLayout()}> - - - - - this.takeScreenshot()}> - - - - - - this.props.downloadSchemeFile()}> - - - - - this.downloadGraphJSON()}> - - - - -

Use the checkboxes to the right to filter the graph by annotations.

-

Click on a gene node to see annotations connected to it.

-

Click on an annotation to see which genes it annotates.

-
- } - > - - - - -
- - -
- - - - }> -
Annotations
-
- - - {this.props.annotations.map((a, i) => ( - - this.toggleAnnotationVisibility(a, e.target.checked)} - /> - } - label={a} - /> -
-
-
- - ))} - - - - - - {this.state.selectedNode.node && ( -
-

{`${this.state.selectedNode.node.name} ( ${this.state.selectedNode.node.id} )`}

-

{this.formatDescription(this.state.selectedNode.node.definition)}

-
- )} -
- ); - } -} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationSelection.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationSelection.js deleted file mode 100644 index 31f7a9c62..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/AnnotationSelection.js +++ /dev/null @@ -1,49 +0,0 @@ -import React from "react"; - -import { Checkbox, FormControlLabel, Grid, Typography } from "@material-ui/core"; - -const filterFormStyle = { - paddingLeft: "25px", - marginLeft: "5px", - borderLeft: "dashed 1px #ddd", -}; - -export default class AnnotationSelection extends React.Component { - isAnnotationSelected(annotation) { - return this.props.selectedAnnotations.some(sa => sa.name === annotation); - } - - render() { - return ( - - - Annotations: - - - - {this.props.availableAnnotations.map(a => ( - - this.props.handleAnnotationsChanged(e.target.checked, e.target.name)} - /> - } - label={a.name} - /> -
- {this.isAnnotationSelected(a.key) && ( -
- {a.fitlerForm(a.defaults, filter => this.props.handleFilterChanged(a.key, filter))} -
- )} -
- ))} -
-
-
- ); - } -} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/GOFilter.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/GOFilter.js deleted file mode 100644 index 0518fef73..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/GOFilter.js +++ /dev/null @@ -1,62 +0,0 @@ -import React from "react"; -import { TextField, Grid, Checkbox, FormControlLabel } from "@material-ui/core"; - -const namespaces = [ - { label: "Biological process", value: "biological_process" }, - { label: "Cellular component", value: "cellular_component" }, - { label: "Molecular function", value: "molecular_function" }, -]; - -export default class GOFilter extends React.Component { - constructor(props) { - super(props); - this.namespaces = this.props.defaults.namespace; - } - - render() { - return ( - -
- {namespaces.map(n => ( - { - if (e.target.checked) { - this.namespaces.push(e.target.name); - } else { - this.namespaces = this.namespaces.filter(n => n !== e.target.name); - } - this.props.handleFilterChanged({ - namespace: this.namespaces, - }); - }} - /> - } - label={n.label} - /> - ))} - - - - this.props.handleFilterChanged({ parents: n.target.value })} - /> - - - -
- ); - } -} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/GenePathwayFilter.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/GenePathwayFilter.js deleted file mode 100644 index daf9a7738..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/GenePathwayFilter.js +++ /dev/null @@ -1,74 +0,0 @@ -import React from "react"; -import { Grid, Checkbox, FormControlLabel, FormLabel, Switch } from "@material-ui/core"; - -const options = [{ label: "Reactome", value: "reactome" }]; - -export default class GenePathwayFilter extends React.Component { - constructor(props) { - super(props); - this.namespaces = this.props.defaults.namespace; - } - - render() { - return ( - -
- Select pathways - {options.map(n => ( - { - if (e.target.checked) { - this.namespaces.push(e.target.name); - } else { - this.namespaces = this.namespaces.filter(n => n !== e.target.name); - } - this.props.handleFilterChanged({ - namespace: this.namespaces, - }); - }} - /> - } - label={n.label} - /> - ))} - - - { - this.props.handleFilterChanged({ - include_small_molecule: e.target.checked, - }); - }} - /> - } - label="Small molecules" - /> - { - this.props.handleFilterChanged({ - include_prot: e.target.checked, - }); - }} - /> - } - label="Proteins" - /> - - - -
- ); - } -} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/GeneSelection.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/GeneSelection.js deleted file mode 100644 index dfba66c00..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/GeneSelection.js +++ /dev/null @@ -1,227 +0,0 @@ -import React from "react"; -import { - TextField, - Button, - FormControlLabel, - RadioGroup, - Radio, - Chip, - InputAdornment, - Grid, - Typography, -} from "@material-ui/core"; -import { CloudUpload, Check, Close, KeyboardReturn } from "@material-ui/icons"; -import Dropzone from "react-dropzone"; -import classNames from "classnames"; -import fileSize from "filesize"; - -const InputMethods = { - DIRECT_INPUT: "1", - FILE_UPLOAD: "2", -}; - -export default class GeneSelectionForm extends React.Component { - constructor(props) { - super(props); - this.state = { - inputMethod: InputMethods.DIRECT_INPUT, - currentGeneName: "", - validationErrors: { - gene: null, - }, - }; - this.uploaderAttributes = { - name: "geneList", - multiple: false, - beforeUpload: geneList => { - this.props.onGeneListUploaded(geneList); - return false; - }, - }; - this.handleGeneAdded = this.handleGeneAdded.bind(this); - } - - checkDuplicate(value, array) { - return array.includes(value) - ? { - error: true, - helperText: `"${value}" already exists.`, - } - : null; - } - - isValid() { - let validationErrors = Object.assign({}, this.state.validationErrors); - return Object.values(validationErrors).filter(v => v).length === 0; - } - - handleGeneAdded() { - if (this.state.currentGeneName && !this.state.validationErrors.gene) { - this.props.onGeneAdded(this.state.currentGeneName); - this.setState({ currentGeneName: "" }); - } - } - - render() { - const props = { - name: "geneList", - multiple: false, - onDrop: files => { - const file = files[0]; - this.props.onGeneListUploaded(file); - }, - }; - - return ( - - { - this.setState({ inputMethod: e.target.value }); - }} - style={{ display: "flex", flexDirection: "row" }} - value={this.state.inputMethod} - > - } label="Input directly" /> - } label="Import from file" /> - - {this.state.inputMethod === InputMethods.DIRECT_INPUT && ( - { - let validationErrors = Object.assign({}, this.state.validationErrors); - validationErrors.gene = this.checkDuplicate(e.target.value.trim(), this.props.genes); - this.setState({ - validationErrors: validationErrors, - currentGeneName: e.target.value, - }); - }} - onKeyDown={e => (e.key === "Enter" ? this.handleGeneAdded() : null)} - InputProps={{ - endAdornment: ( - this.handleGeneAdded()}> - - - ), - }} - /> - )} - - {this.state.inputMethod === InputMethods.FILE_UPLOAD && ( - - - {({ getRootProps, getInputProps, isDragActive }) => { - return ( -
- - {this.props.uploadedFile ? ( - - ) : ( - - )} - {isDragActive ? ( - - Drop file here... - - ) : ( - - Please make sure the file is a plain text file containing a gene name per line. - - )} -
- ); - }} -
- - {this.props.geneList && this.props.genes.length ? ( -
- - {this.props.geneList.name + " ( " + fileSize(this.props.geneList.size) + " )"} - -
- ) : null} -
- )} - -
- - Selected genes: - {this.props.genes.length ? ( - - ) : null} - - - - - {!this.props.genes.length ? ( -
- - The genes you input appear here. You may input gene names directly or import them from file. - -
- ) : null} - - {this.props.genes.length - ? this.props.genes.map(gene => ( - {gene}} - onDelete={() => this.props.onGeneRemoved(gene)} - color="primary" - key={gene} - /> - )) - : null} -
-
-
-
- ); - } -} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/annotation_pb.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/annotation_pb.js deleted file mode 100644 index 66757e516..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/annotation_pb.js +++ /dev/null @@ -1,971 +0,0 @@ -/** - * @fileoverview - * @enhanceable - * @public - */ -// GENERATED CODE -- DO NOT EDIT! -/*eslint-disable */ - -var jspb = require('google-protobuf'); -var goog = jspb; -var global = Function('return this')(); - -goog.exportSymbol('snet_gene_annotation_service.Annotation', null, global); -goog.exportSymbol('snet_gene_annotation_service.AnnotationRequest', null, global); -goog.exportSymbol('snet_gene_annotation_service.AnnotationResponse', null, global); -goog.exportSymbol('snet_gene_annotation_service.Filter', null, global); -goog.exportSymbol('snet_gene_annotation_service.Gene', null, global); - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -snet_gene_annotation_service.Filter = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, null, null); -}; -goog.inherits(snet_gene_annotation_service.Filter, jspb.Message); -if (goog.DEBUG && !COMPILED) { - snet_gene_annotation_service.Filter.displayName = 'snet_gene_annotation_service.Filter'; -} - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -snet_gene_annotation_service.Filter.prototype.toObject = function(opt_includeInstance) { - return snet_gene_annotation_service.Filter.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!snet_gene_annotation_service.Filter} msg The msg instance to transform. - * @return {!Object} - */ -snet_gene_annotation_service.Filter.toObject = function(includeInstance, msg) { - var f, obj = { - filter: msg.getFilter(), - value: msg.getValue() - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!snet_gene_annotation_service.Filter} - */ -snet_gene_annotation_service.Filter.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new snet_gene_annotation_service.Filter; - return snet_gene_annotation_service.Filter.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!snet_gene_annotation_service.Filter} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!snet_gene_annotation_service.Filter} - */ -snet_gene_annotation_service.Filter.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setFilter(value); - break; - case 2: - var value = /** @type {string} */ (reader.readString()); - msg.setValue(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!snet_gene_annotation_service.Filter} message - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.Filter.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -snet_gene_annotation_service.Filter.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.Filter.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getFilter(); - if (f.length > 0) { - writer.writeString( - 1, - f - ); - } - f = this.getValue(); - if (f.length > 0) { - writer.writeString( - 2, - f - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!snet_gene_annotation_service.Filter} The clone. - */ -snet_gene_annotation_service.Filter.prototype.cloneMessage = function() { - return /** @type {!snet_gene_annotation_service.Filter} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * optional string filter = 1; - * @return {string} - */ -snet_gene_annotation_service.Filter.prototype.getFilter = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, "")); -}; - - -/** @param {string} value */ -snet_gene_annotation_service.Filter.prototype.setFilter = function(value) { - jspb.Message.setField(this, 1, value); -}; - - -/** - * optional string value = 2; - * @return {string} - */ -snet_gene_annotation_service.Filter.prototype.getValue = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 2, "")); -}; - - -/** @param {string} value */ -snet_gene_annotation_service.Filter.prototype.setValue = function(value) { - jspb.Message.setField(this, 2, value); -}; - - - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -snet_gene_annotation_service.Annotation = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, snet_gene_annotation_service.Annotation.repeatedFields_, null); -}; -goog.inherits(snet_gene_annotation_service.Annotation, jspb.Message); -if (goog.DEBUG && !COMPILED) { - snet_gene_annotation_service.Annotation.displayName = 'snet_gene_annotation_service.Annotation'; -} -/** - * List of repeated fields within this message type. - * @private {!Array} - * @const - */ -snet_gene_annotation_service.Annotation.repeatedFields_ = [2]; - - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -snet_gene_annotation_service.Annotation.prototype.toObject = function(opt_includeInstance) { - return snet_gene_annotation_service.Annotation.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!snet_gene_annotation_service.Annotation} msg The msg instance to transform. - * @return {!Object} - */ -snet_gene_annotation_service.Annotation.toObject = function(includeInstance, msg) { - var f, obj = { - functionname: msg.getFunctionname(), - filtersList: jspb.Message.toObjectList(msg.getFiltersList(), - snet_gene_annotation_service.Filter.toObject, includeInstance) - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!snet_gene_annotation_service.Annotation} - */ -snet_gene_annotation_service.Annotation.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new snet_gene_annotation_service.Annotation; - return snet_gene_annotation_service.Annotation.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!snet_gene_annotation_service.Annotation} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!snet_gene_annotation_service.Annotation} - */ -snet_gene_annotation_service.Annotation.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setFunctionname(value); - break; - case 2: - var value = new snet_gene_annotation_service.Filter; - reader.readMessage(value,snet_gene_annotation_service.Filter.deserializeBinaryFromReader); - msg.getFiltersList().push(value); - msg.setFiltersList(msg.getFiltersList()); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!snet_gene_annotation_service.Annotation} message - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.Annotation.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -snet_gene_annotation_service.Annotation.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.Annotation.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getFunctionname(); - if (f.length > 0) { - writer.writeString( - 1, - f - ); - } - f = this.getFiltersList(); - if (f.length > 0) { - writer.writeRepeatedMessage( - 2, - f, - snet_gene_annotation_service.Filter.serializeBinaryToWriter - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!snet_gene_annotation_service.Annotation} The clone. - */ -snet_gene_annotation_service.Annotation.prototype.cloneMessage = function() { - return /** @type {!snet_gene_annotation_service.Annotation} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * optional string functionName = 1; - * @return {string} - */ -snet_gene_annotation_service.Annotation.prototype.getFunctionname = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, "")); -}; - - -/** @param {string} value */ -snet_gene_annotation_service.Annotation.prototype.setFunctionname = function(value) { - jspb.Message.setField(this, 1, value); -}; - - -/** - * repeated Filter filters = 2; - * If you change this array by adding, removing or replacing elements, or if you - * replace the array itself, then you must call the setter to update it. - * @return {!Array.} - */ -snet_gene_annotation_service.Annotation.prototype.getFiltersList = function() { - return /** @type{!Array.} */ ( - jspb.Message.getRepeatedWrapperField(this, snet_gene_annotation_service.Filter, 2)); -}; - - -/** @param {Array.} value */ -snet_gene_annotation_service.Annotation.prototype.setFiltersList = function(value) { - jspb.Message.setRepeatedWrapperField(this, 2, value); -}; - - -snet_gene_annotation_service.Annotation.prototype.clearFiltersList = function() { - this.setFiltersList([]); -}; - - - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -snet_gene_annotation_service.Gene = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, null, null); -}; -goog.inherits(snet_gene_annotation_service.Gene, jspb.Message); -if (goog.DEBUG && !COMPILED) { - snet_gene_annotation_service.Gene.displayName = 'snet_gene_annotation_service.Gene'; -} - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -snet_gene_annotation_service.Gene.prototype.toObject = function(opt_includeInstance) { - return snet_gene_annotation_service.Gene.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!snet_gene_annotation_service.Gene} msg The msg instance to transform. - * @return {!Object} - */ -snet_gene_annotation_service.Gene.toObject = function(includeInstance, msg) { - var f, obj = { - genename: msg.getGenename() - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!snet_gene_annotation_service.Gene} - */ -snet_gene_annotation_service.Gene.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new snet_gene_annotation_service.Gene; - return snet_gene_annotation_service.Gene.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!snet_gene_annotation_service.Gene} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!snet_gene_annotation_service.Gene} - */ -snet_gene_annotation_service.Gene.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setGenename(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!snet_gene_annotation_service.Gene} message - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.Gene.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -snet_gene_annotation_service.Gene.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.Gene.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getGenename(); - if (f.length > 0) { - writer.writeString( - 1, - f - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!snet_gene_annotation_service.Gene} The clone. - */ -snet_gene_annotation_service.Gene.prototype.cloneMessage = function() { - return /** @type {!snet_gene_annotation_service.Gene} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * optional string geneName = 1; - * @return {string} - */ -snet_gene_annotation_service.Gene.prototype.getGenename = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, "")); -}; - - -/** @param {string} value */ -snet_gene_annotation_service.Gene.prototype.setGenename = function(value) { - jspb.Message.setField(this, 1, value); -}; - - - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -snet_gene_annotation_service.AnnotationRequest = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, snet_gene_annotation_service.AnnotationRequest.repeatedFields_, null); -}; -goog.inherits(snet_gene_annotation_service.AnnotationRequest, jspb.Message); -if (goog.DEBUG && !COMPILED) { - snet_gene_annotation_service.AnnotationRequest.displayName = 'snet_gene_annotation_service.AnnotationRequest'; -} -/** - * List of repeated fields within this message type. - * @private {!Array} - * @const - */ -snet_gene_annotation_service.AnnotationRequest.repeatedFields_ = [1,2]; - - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -snet_gene_annotation_service.AnnotationRequest.prototype.toObject = function(opt_includeInstance) { - return snet_gene_annotation_service.AnnotationRequest.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!snet_gene_annotation_service.AnnotationRequest} msg The msg instance to transform. - * @return {!Object} - */ -snet_gene_annotation_service.AnnotationRequest.toObject = function(includeInstance, msg) { - var f, obj = { - annotationsList: jspb.Message.toObjectList(msg.getAnnotationsList(), - snet_gene_annotation_service.Annotation.toObject, includeInstance), - genesList: jspb.Message.toObjectList(msg.getGenesList(), - snet_gene_annotation_service.Gene.toObject, includeInstance) - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!snet_gene_annotation_service.AnnotationRequest} - */ -snet_gene_annotation_service.AnnotationRequest.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new snet_gene_annotation_service.AnnotationRequest; - return snet_gene_annotation_service.AnnotationRequest.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!snet_gene_annotation_service.AnnotationRequest} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!snet_gene_annotation_service.AnnotationRequest} - */ -snet_gene_annotation_service.AnnotationRequest.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = new snet_gene_annotation_service.Annotation; - reader.readMessage(value,snet_gene_annotation_service.Annotation.deserializeBinaryFromReader); - msg.getAnnotationsList().push(value); - msg.setAnnotationsList(msg.getAnnotationsList()); - break; - case 2: - var value = new snet_gene_annotation_service.Gene; - reader.readMessage(value,snet_gene_annotation_service.Gene.deserializeBinaryFromReader); - msg.getGenesList().push(value); - msg.setGenesList(msg.getGenesList()); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!snet_gene_annotation_service.AnnotationRequest} message - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.AnnotationRequest.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -snet_gene_annotation_service.AnnotationRequest.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.AnnotationRequest.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getAnnotationsList(); - if (f.length > 0) { - writer.writeRepeatedMessage( - 1, - f, - snet_gene_annotation_service.Annotation.serializeBinaryToWriter - ); - } - f = this.getGenesList(); - if (f.length > 0) { - writer.writeRepeatedMessage( - 2, - f, - snet_gene_annotation_service.Gene.serializeBinaryToWriter - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!snet_gene_annotation_service.AnnotationRequest} The clone. - */ -snet_gene_annotation_service.AnnotationRequest.prototype.cloneMessage = function() { - return /** @type {!snet_gene_annotation_service.AnnotationRequest} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * repeated Annotation annotations = 1; - * If you change this array by adding, removing or replacing elements, or if you - * replace the array itself, then you must call the setter to update it. - * @return {!Array.} - */ -snet_gene_annotation_service.AnnotationRequest.prototype.getAnnotationsList = function() { - return /** @type{!Array.} */ ( - jspb.Message.getRepeatedWrapperField(this, snet_gene_annotation_service.Annotation, 1)); -}; - - -/** @param {Array.} value */ -snet_gene_annotation_service.AnnotationRequest.prototype.setAnnotationsList = function(value) { - jspb.Message.setRepeatedWrapperField(this, 1, value); -}; - - -snet_gene_annotation_service.AnnotationRequest.prototype.clearAnnotationsList = function() { - this.setAnnotationsList([]); -}; - - -/** - * repeated Gene genes = 2; - * If you change this array by adding, removing or replacing elements, or if you - * replace the array itself, then you must call the setter to update it. - * @return {!Array.} - */ -snet_gene_annotation_service.AnnotationRequest.prototype.getGenesList = function() { - return /** @type{!Array.} */ ( - jspb.Message.getRepeatedWrapperField(this, snet_gene_annotation_service.Gene, 2)); -}; - - -/** @param {Array.} value */ -snet_gene_annotation_service.AnnotationRequest.prototype.setGenesList = function(value) { - jspb.Message.setRepeatedWrapperField(this, 2, value); -}; - - -snet_gene_annotation_service.AnnotationRequest.prototype.clearGenesList = function() { - this.setGenesList([]); -}; - - - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -snet_gene_annotation_service.AnnotationResponse = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, null, null); -}; -goog.inherits(snet_gene_annotation_service.AnnotationResponse, jspb.Message); -if (goog.DEBUG && !COMPILED) { - snet_gene_annotation_service.AnnotationResponse.displayName = 'snet_gene_annotation_service.AnnotationResponse'; -} - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -snet_gene_annotation_service.AnnotationResponse.prototype.toObject = function(opt_includeInstance) { - return snet_gene_annotation_service.AnnotationResponse.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!snet_gene_annotation_service.AnnotationResponse} msg The msg instance to transform. - * @return {!Object} - */ -snet_gene_annotation_service.AnnotationResponse.toObject = function(includeInstance, msg) { - var f, obj = { - graph: msg.getGraph(), - scm: msg.getScm() - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!snet_gene_annotation_service.AnnotationResponse} - */ -snet_gene_annotation_service.AnnotationResponse.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new snet_gene_annotation_service.AnnotationResponse; - return snet_gene_annotation_service.AnnotationResponse.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!snet_gene_annotation_service.AnnotationResponse} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!snet_gene_annotation_service.AnnotationResponse} - */ -snet_gene_annotation_service.AnnotationResponse.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setGraph(value); - break; - case 2: - var value = /** @type {string} */ (reader.readString()); - msg.setScm(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!snet_gene_annotation_service.AnnotationResponse} message - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.AnnotationResponse.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -snet_gene_annotation_service.AnnotationResponse.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -snet_gene_annotation_service.AnnotationResponse.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getGraph(); - if (f.length > 0) { - writer.writeString( - 1, - f - ); - } - f = this.getScm(); - if (f.length > 0) { - writer.writeString( - 2, - f - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!snet_gene_annotation_service.AnnotationResponse} The clone. - */ -snet_gene_annotation_service.AnnotationResponse.prototype.cloneMessage = function() { - return /** @type {!snet_gene_annotation_service.AnnotationResponse} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * optional string graph = 1; - * @return {string} - */ -snet_gene_annotation_service.AnnotationResponse.prototype.getGraph = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, "")); -}; - - -/** @param {string} value */ -snet_gene_annotation_service.AnnotationResponse.prototype.setGraph = function(value) { - jspb.Message.setField(this, 1, value); -}; - - -/** - * optional string scm = 2; - * @return {string} - */ -snet_gene_annotation_service.AnnotationResponse.prototype.getScm = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 2, "")); -}; - - -/** @param {string} value */ -snet_gene_annotation_service.AnnotationResponse.prototype.setScm = function(value) { - jspb.Message.setField(this, 2, value); -}; - - -goog.object.extend(exports, snet_gene_annotation_service); diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/add.svg b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/add.svg new file mode 100644 index 000000000..e12d152db --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/filter.svg b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/filter.svg new file mode 100644 index 000000000..1eed94715 --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/filter.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/mozi_globe.png b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/mozi_globe.png new file mode 100644 index 000000000..de3398242 Binary files /dev/null and b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/mozi_globe.png differ diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/remove.svg b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/remove.svg new file mode 100644 index 000000000..70f4ef654 --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/assets/remove.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/form/index.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/form/index.js new file mode 100644 index 000000000..da481c6e6 --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/form/index.js @@ -0,0 +1,411 @@ +import React, { useState } from "react"; +import { capitalizeFirstLetter } from "../service"; +import AppBar from "@material-ui/core/AppBar"; +import Tabs from "@material-ui/core/Tabs"; +import Tab from "@material-ui/core/Tab"; +import TextField from "@material-ui/core/TextField"; +import Chip from "@material-ui/core/Chip"; +import Button from "@material-ui/core/Button"; +import FormGroup from "@material-ui/core/FormGroup"; +import IconButton from "@material-ui/core/IconButton"; +import DeleteIcon from "@material-ui/icons/Delete"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Checkbox from "@material-ui/core/Checkbox"; +import Switch from "@material-ui/core/Switch"; +import Typography from "@material-ui/core/Typography"; +import CloudUpload from "@material-ui/icons/CloudUpload"; +import Check from "@material-ui/icons/Check"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import Dropzone from "react-dropzone"; +import { useSnackbar } from "notistack"; +import { Annotate } from "../proto/annotation_pb_service"; +import { AnnotationRequest, Annotation, Gene, Filter } from "../proto/annotation_pb"; +import "./style.css"; +const grpc = require("@improbable-eng/grpc-web").grpc; + +const GeneGoOptions = [ + { label: "Biological Process", value: "biological_process" }, + { label: "Cellular Component", value: "cellular_component" }, + { label: "Molecular Function", value: "molecular_function" }, +]; + +const Pathways = [{ label: "SMPDB", value: "smpdb" }, { label: "Reactome", value: "reactome" }]; + +const GeneInputMethods = { Manual: 0, Import: 1 }; + +const AnnotationForm = props => { + const { enqueueSnackbar } = useSnackbar(); + const geneInputRef = React.createRef(); + const [genes, setGenes] = useState([]); + const [currentGene, setCurrentGene] = useState(""); + const [annotations, setAnnotations] = useState([]); + const [parents, setParents] = useState(0); + const [pathways, setPathways] = useState(["reactome"]); + const [includeSmallMolecules, setIncludeSmallMolecules] = useState(false); + const [includeProtiens, setIncludeProtiens] = useState(true); + const [loading, setLoading] = useState(false); + const [GOSubgroups, setGOSubgroups] = useState(["biological_process", "cellular_component", "molecular_function"]); + const [geneInputMethod, setGeneInputMethod] = useState(GeneInputMethods.Manual); + + const addGene = e => { + const gene = e + .trim() + .toUpperCase() + .split(" ") + .filter(g => g); + gene.some(g => genes.includes(g)) + ? enqueueSnackbar("Gene already exists", { + variant: "warning", + anchorOrigin: { + vertical: "top", + horizontal: "center", + }, + }) + : setGenes([...genes, ...gene]); + setCurrentGene(""); + }; + + const toggleAnnotation = (annotation, e) => { + const updated = e.target.checked ? [...annotations, annotation] : annotations.filter(a => a !== annotation); + setAnnotations(updated); + }; + + const toggleGoSubgroup = (subgroup, e) => { + const updated = e.target.checked ? [...GOSubgroups, subgroup] : GOSubgroups.filter(s => s !== subgroup); + setGOSubgroups(updated); + }; + + const togglePathways = (subgroup, e) => { + const updated = e.target.checked ? [...pathways, subgroup] : pathways.filter(s => s !== subgroup); + setPathways(updated); + }; + + const handleFileUpload = file => { + const reader = new FileReader(); + reader.onload = () => { + setGenes(reader.result.split("\n")); + enqueueSnackbar("Genes imported!", { + variant: "success", + anchorOrigin: { + vertical: "top", + horizontal: "center", + }, + }); + }; + reader.readAsText(file); + }; + + const handleSubmit = () => { + setLoading(true); + const annotationRequest = new AnnotationRequest(); + annotationRequest.setGenesList( + genes.map(g => { + const gene = new Gene(); + gene.setGenename(g); + return gene; + }) + ); + // Namespace and number of parents + const namespace = new Filter(); + namespace.setFilter("namespace"); + namespace.setValue(GOSubgroups.join(" ")); + const nop = new Filter(); + nop.setFilter("parents"); + nop.setValue(parents); + annotationRequest.setAnnotationsList( + annotations.map(sa => { + const annotation = new Annotation(); + annotation.setFunctionname(sa); + if (sa === "gene-go-annotation") { + annotation.setFiltersList([namespace, nop]); + } else if (sa === "gene-pathway-annotation") { + const ps = new Filter(); + ps.setFilter("namespace"); + ps.setValue(pathways.join(" ")); + const ism = new Filter(); + ism.setFilter("include_small_molecule"); + ism.setValue(capitalizeFirstLetter(includeSmallMolecules.toString())); + const ip = new Filter(); + ip.setFilter("include_prot"); + ip.setValue(capitalizeFirstLetter(includeProtiens.toString())); + annotation.setFiltersList([ + ps, + ip, + ism, + ...(annotations.includes("gene-go-annotation") ? [namespace, nop] : []), + ]); + } else if (sa === "biogrid-interaction-annotation") { + const int = new Filter(); + int.setFilter("interaction"); + int.setValue(annotations.includes("gene-pathway-annotation") && includeProtiens ? "Proteins" : "Genes"); + annotation.setFiltersList([int, ...(annotations.includes("gene-go-annotation") ? [namespace, nop] : [])]); + } + return annotation; + }) + ); + + const requestProps = { + request: annotationRequest, + onEnd: ({ status, statusMessage, message: msg }) => { + setLoading(false); + if (status === grpc.Code.OK) { + props.onResponse(msg.array[0].substr(msg.array[0].indexOf("id=") + 3)); + } else { + if (statusMessage.includes("Gene Doesn't exist")) { + const invalidGenes = statusMessage + .split("`")[1] + .split(",") + .map(g => g.trim()) + .filter(g => g); + setGenes(genes.filter(g => !invalidGenes.includes(g))); + enqueueSnackbar("Gene not found!", { + variant: "warning", + anchorOrigin: { + vertical: "top", + horizontal: "center", + }, + }); + } else { + enqueueSnackbar( +
+ An error occurred + {statusMessage} +
, + { + variant: "error", + anchorOrigin: { + vertical: "top", + horizontal: "center", + }, + } + ); + } + } + }, + }; + + this.props.serviceClient.unary(Annotate.Annotate, requestProps); + }; + + return ( +
+ {/* Gene List */} + + Input Genes + + + { + setGeneInputMethod(value); + }} + variant="fullWidth" + > + + + + + {geneInputMethod === GeneInputMethods.Manual && ( + setCurrentGene(e.target.value)} + onKeyPress={e => { + if (e.key === "Enter") addGene(currentGene); + }} + /> + )} + {geneInputMethod === GeneInputMethods.Import && ( + { + const file = files[0]; + handleFileUpload(file); + }} + style={{ marginBottom: 15 }} + > + {({ getRootProps, getInputProps, isDragActive }) => { + return ( +
+ + + {isDragActive ? ( + + Drop file here... + + ) : ( + + Please make sure the file is a plain text file containing a gene name per line. + + )} +
+ ); + }} +
+ )} +
+ {genes.map(g => ( + setGenes(genes.filter(f => f !== g))} + /> + ))} + {genes.length > 1 && ( + + setGenes([])} /> + + )} +
+ {/* Annotations */} + + Annotations + +
    +
  • + + toggleAnnotation("gene-go-annotation", e)} />} + label="Gene-GO" + /> + + + {annotations.includes("gene-go-annotation") && ( +
    +
    + + {GeneGoOptions.map(o => ( + toggleGoSubgroup(o.value, e)} + /> + } + label={o.label} + /> + ))} + +
    +
    + setParents(e.target.value)} + type="number" + variant="outlined" + helperText={ + parents === "" || isNaN(parents) ? ( + + Number of parents needs to be a valid number + + ) : null + } + /> +
    +
    + )} +
  • +
  • + + toggleAnnotation("gene-pathway-annotation", e)} />} + label="Gene Pathway" + /> + + {annotations.includes("gene-pathway-annotation") && ( +
    +
    + {Pathways.map(p => ( + togglePathways(p.value, e)} + defaultChecked={pathways.includes(p.value)} + /> + } + label={p.label} + /> + ))} +
    +
    + + setIncludeSmallMolecules(e.target.checked)} + value="smallMolecules" + color="primary" + /> + } + label="Small molecules" + /> + +
    +
    + )} +
  • +
  • + + toggleAnnotation("biogrid-interaction-annotation", e)} /> + } + label="Biogrid Protien Interaction" + /> + +
  • +
+ setIncludeProtiens(e.target.checked)} + value="protiens" + color="primary" + /> + } + label="Include protiens" + /> +
+ +
+
+ ); +}; + +export default AnnotationForm; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/form/style.css b/src/assets/thirdPartyServices/snet/gene_annotation_service/form/style.css new file mode 100644 index 000000000..a9b901a51 --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/form/style.css @@ -0,0 +1,45 @@ +.MuiPaper-root.MuiPaper-elevation4.MuiAppBar-root.MuiAppBar-positionStatic.MuiAppBar-colorDefault { + box-shadow: none; +} + +.annotation-list { + list-style-type: none; + padding-left: 0; +} + +.gene-list { + margin: 15px 0 45px 0; +} + +.gene-list .ant-tag { + font-size: 1em; +} + +.annotation-parameters { + border-left: dashed 1px #aaa; + padding: 15px; + padding-left: 30px; +} + +.annotation-parameters .parameter { + display: block; + margin-bottom: 10px; +} + +.annotation-parameters .parameter .label { + display: inline; + margin-right: 10px; + color: rgba(0, 0, 0, 0.65); +} + +.actions { + margin-top: 45px; + width: 100%; + text-align: end; +} + +.form-wrapper .title { + display: block; + font-weight: bold; + margin-bottom: 10px; +} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/index.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/index.js index fd5096d9d..b1972cdc3 100644 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/index.js +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/index.js @@ -1,379 +1,18 @@ -import { MAXIMUM_GRAPH_SIZE } from "./visualizer.config"; -import React from "react"; -import GeneSelectionForm from "./GeneSelection"; -import AnnotationSelection from "./AnnotationSelection"; -import AnnotationResultVisualizer from "./AnnotationResultVisualizer"; -import AnnotationResultDownload from "./AnnotationResultDownload"; -import { Button, Grid } from "@material-ui/core"; -import { Check } from "@material-ui/icons"; -import GOFilter from "./GOFilter"; -import GenePathwayFilter from "./GenePathwayFilter"; -import { Snackbar, SnackbarContent, CircularProgress } from "@material-ui/core"; -import { withStyles } from "@material-ui/core/styles"; -import red from "@material-ui/core/colors/red"; +import React, { useState } from "react"; +import ReactDOM from "react-dom"; +import { SnackbarProvider } from "notistack"; +import AnnotationForm from "./form"; +import AnnotationResult from "./result"; +import "./style.css"; -import {Annotate} from "./annotation_pb_service" +const App = props => { + const [id, setId] = useState(undefined); -import {Filter, Annotation, Gene} from "./annotation_pb" - -const ErrorSnackbarContent = withStyles({ - root: { background: red[600] }, - message: { color: "#fff" }, -})(SnackbarContent); - -export const showNotification = ({ message, busy }, callBack) => { return ( - - {busy ? ( - - - {message} - - } - /> - ) : ( - {message}} /> - )} - +
+ {id ? : } +
); }; -const availableAnnotations = [ - { - key: "gene_go_annotation", - name: "Gene-GO", - defaults: { - namespace: ["biological_process", "cellular_component", "molecular_function"], - parents: 0, - }, - fitlerForm: (defaults, handleFilterChanged) => ( - - ), - }, - { - key: "gene_pathway_annotation", - name: "Gene pathway", - defaults: { - namespace: [], - include_prot: false, - include_small_molecule: true, - }, - fitlerForm: (defaults, handleFilterChanged) => ( - - ), - }, - { - key: "biogrid_interaction_annotation", - name: "Biogrid protein interaction", - fitlerForm: (defaults, handleFilterChanged) => null, - }, -]; - -export default class GeneAnnotationService extends React.Component { - constructor(props) { - super(props); - this.state = { - genes: [], - geneList: null, - selectedAnnotations: [], - notification: null, - methodName: "Annotate", - response: undefined, - }; - // bind functions - this.handleGeneAdded = this.handleGeneAdded.bind(this); - this.handleGeneRemoved = this.handleGeneRemoved.bind(this); - this.handleGeneListUploaded = this.handleGeneListUploaded.bind(this); - this.handleAllGenesRemoved = this.handleAllGenesRemoved.bind(this); - this.handleAnnotationsChanged = this.handleAnnotationsChanged.bind(this); - this.handleFilterChanged = this.handleFilterChanged.bind(this); - this.downloadSchemeFile = this.downloadSchemeFile.bind(this); - } - - componentDidUpdate(prevProps) { - if (prevProps.isComplete !== this.props.isComplete) { - this.setState({ notification: null }); - } - } - - parseResponse() { - const { response } = this.state; - if (typeof response !== "undefined") { - const r = { - graph: JSON.parse(response.graph), - schemeFile: response.scm, - }; - return r; - } - } - - handleGeneAdded(input) { - this.setState(state => { - let genes = state.genes.slice(0); - genes = [ - ...genes, - ...input - .trim() - .toUpperCase() - .split(" "), - ].filter((g, i, arr) => g && arr.indexOf(g) === i); - return { genes: genes }; - }); - } - - handleGeneRemoved(gene) { - this.setState(state => { - let genes = state.genes.slice(0); - return { genes: genes.filter(g => g !== gene) }; - }); - } - - handleGeneListUploaded(geneList) { - const fileReader = new FileReader(); - fileReader.readAsText(geneList); - fileReader.onload = () => { - const re = /^[a-z0-9\s]+$/i; - if (!re.test(fileReader.result)) { - this.setState({ - notification: { - message: "The selected file contains invalid characters.", - busy: false, - }, - }); - return; - } - const geneArray = fileReader.result.split("\n"); - const uniqueGeneArray = geneArray.reduce((accumulator, value) => { - if (value && accumulator.indexOf(value) === -1) accumulator.push(value); - return accumulator; - }, []); - this.setState({ geneList: geneList, genes: uniqueGeneArray }); - }; - } - - handleAllGenesRemoved() { - this.setState({ genes: [], geneList: null }); - } - - handleAnnotationsChanged(isSelected, annotation) { - this.setState(state => { - let selectedAnnotations = state.selectedAnnotations.slice(); - isSelected - ? selectedAnnotations.push({ - name: annotation, - filter: availableAnnotations.find(a => a.key === annotation).defaults, - }) - : (selectedAnnotations = selectedAnnotations.filter(a => a.name !== annotation)); - - return { selectedAnnotations: selectedAnnotations }; - }); - } - - handleFilterChanged(annotation, filter) { - this.setState(state => { - const selectedAnnotations = state.selectedAnnotations.map(sa => { - if (sa.name === annotation) { - sa.filter = Object.assign({}, sa.filter, filter); - } - return sa; - }); - return { selectedAnnotations: selectedAnnotations }; - }); - } - - isFormValid() { - let valid = true; - valid = valid && this.state.selectedAnnotations.length; - valid = valid && this.state.genes.length; - - // If Gene GO annotation is selected, namespace must be defined - const GO = this.state.selectedAnnotations.find(a => a.name === "gene_go_annotation"); - if (GO) valid = valid && GO.filter.namespace.length; - // If Gene Pathway annotation is selected, namespace must be defined - const Pathway = this.state.selectedAnnotations.find(a => a.name === "gene_pathway_annotation"); - if (Pathway) { - valid = valid && (Pathway.filter.namespace.includes("smpdb") || Pathway.filter.namespace.includes("reactome")); - } - return valid; - } - - downloadSchemeFile() { - const json = `data:application/txt, ${encodeURIComponent(this.parseResponse().schemeFile)}`; - const link = document.createElement("a"); - link.setAttribute("href", json); - link.setAttribute("download", "annotations-scheme.scm"); - link.click(); - } - - capitalizeFirstLetter(string) { - return string.charAt(0).toUpperCase() + string.slice(1); - } - - // TODO: Existsing code for the reference and need to modify once the Daemon is ready - /* - handleSubmit() { - const annotationResult = {}; - annotationResult.annotations = this.state.selectedAnnotations.map(sa => { - const annotation = {}; - annotation["functionName"] = sa.name; - annotation["filters"] = sa.filter - ? Object.keys(sa.filter).map(k => { - const filter = {}; - filter["filter"] = k; - filter["value"] = Array.isArray(sa.filter[k]) - ? sa.filter[k] - .reduce((acc, value) => { - return acc + " " + value; - }, "") - .trim() - : this.capitalizeFirstLetter(sa.filter[k].toString()); - return filter; - }) - : []; - return annotation; - }); - annotationResult.genes = this.state.genes.map(g => ({ geneName: g })); - this.props.callApiCallback("Annotate", "Annotate", annotationResult); - this.setState({ - notification: { message: "Fetching annotation results ...", busy: true }, - }); - } - */ - - // TODO: Need to update the code after validating with the Daemon Service - // Did an attempt to get the code for Proto TS based on the Proto Definition - handleSubmit() { - const {methodName} = this.state; - - const methodDescriptor = Annotate[methodName]; - const request = new methodDescriptor.requestType(); - - var annotations = this.state.selectedAnnotations.map(sa => { - - var annotation = new Annotation(); - - annotation.setFunctionname(sa.name) - - var filters = sa.filter - ? Object.keys(sa.filter).map(k => { - var filter = new Filter(); - filter.setFilter(k) - var val = Array.isArray(sa.filter[k]) - ? sa.filter[k] - .reduce((acc, value) => { - return acc + " " + value; - }, "") - .trim() - : this.capitalizeFirstLetter(sa.filter[k].toString()); - filter.setValue(val); - return filter; - }) - : []; - annotation.setFiltersList(filters); - return annotation; - }); - - var genes = this.state.genes.map(g => { - var gene = new Gene(); - gene.setGenename(g); - return gene; - }); - - request.setAnnotationsList(annotations); - request.setGenesList(genes); - - const props = { - request, - onEnd: ({message}) => { - this.setState({ - response: { status: "success", graph: message.getGraph(), scm: message.getScm() }, - }); - }, - }; - - this.props.serviceClient.unary(methodDescriptor, props); - - // this.setState({ - // notification: { message: "Fetching annotation results ...", busy: true }, - // }); -} - - - - - renderForm() { - return ( - - - - - - - - - - ); - } - - renderComplete() { - return ( - - {this.parseResponse().graph.nodes.length < MAXIMUM_GRAPH_SIZE ? ( - a.name)} - graph={this.parseResponse().graph} - downloadSchemeFile={this.downloadSchemeFile} - sliderWidth={this.props.sliderWidth} - /> - ) : ( - - )} - - ); - } - - render() { - return ( - - {this.state.notification && - showNotification(this.state.notification, () => { - this.setState({ notification: null }); - })} - {this.props.isComplete ? this.renderComplete() : this.renderForm()} - - ); - } -} +ReactDOM.render(, document.getElementById("app")); diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/mozi_globe.png b/src/assets/thirdPartyServices/snet/gene_annotation_service/mozi_globe.png deleted file mode 100644 index 2198c13a5..000000000 Binary files a/src/assets/thirdPartyServices/snet/gene_annotation_service/mozi_globe.png and /dev/null differ diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/proto/annotation_pb.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/proto/annotation_pb.js new file mode 100644 index 000000000..3a54cd7ec --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/proto/annotation_pb.js @@ -0,0 +1,844 @@ +/* eslint-disable */ +/** + * @fileoverview + * @enhanceable + * @public + */ +// GENERATED CODE -- DO NOT EDIT! + +var jspb = require("google-protobuf"); +var goog = jspb; +var global = Function("return this")(); + +goog.exportSymbol("proto.Annotation", null, global); +goog.exportSymbol("proto.AnnotationRequest", null, global); +goog.exportSymbol("proto.AnnotationResponse", null, global); +goog.exportSymbol("proto.Filter", null, global); +goog.exportSymbol("proto.Gene", null, global); + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.Filter = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.Filter, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.Filter.displayName = "proto.Filter"; +} + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ + proto.Filter.prototype.toObject = function(opt_includeInstance) { + return proto.Filter.toObject(opt_includeInstance, this); + }; + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.Filter} msg The msg instance to transform. + * @return {!Object} + */ + proto.Filter.toObject = function(includeInstance, msg) { + var f, + obj = { + filter: jspb.Message.getFieldWithDefault(msg, 1, ""), + value: jspb.Message.getFieldWithDefault(msg, 2, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.Filter} + */ +proto.Filter.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.Filter(); + return proto.Filter.deserializeBinaryFromReader(msg, reader); +}; + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.Filter} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.Filter} + */ +proto.Filter.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setFilter(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setValue(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.Filter.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.Filter.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.Filter} message + * @param {!jspb.BinaryWriter} writer + */ +proto.Filter.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getFilter(); + if (f.length > 0) { + writer.writeString(1, f); + } + f = message.getValue(); + if (f.length > 0) { + writer.writeString(2, f); + } +}; + +/** + * optional string filter = 1; + * @return {string} + */ +proto.Filter.prototype.getFilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + +/** @param {string} value */ +proto.Filter.prototype.setFilter = function(value) { + jspb.Message.setField(this, 1, value); +}; + +/** + * optional string value = 2; + * @return {string} + */ +proto.Filter.prototype.getValue = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + +/** @param {string} value */ +proto.Filter.prototype.setValue = function(value) { + jspb.Message.setField(this, 2, value); +}; + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.Annotation = function(opt_data) { + jspb.Message.initialize( + this, + opt_data, + 0, + -1, + proto.Annotation.repeatedFields_, + null + ); +}; +goog.inherits(proto.Annotation, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.Annotation.displayName = "proto.Annotation"; +} +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.Annotation.repeatedFields_ = [2]; + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ + proto.Annotation.prototype.toObject = function(opt_includeInstance) { + return proto.Annotation.toObject(opt_includeInstance, this); + }; + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.Annotation} msg The msg instance to transform. + * @return {!Object} + */ + proto.Annotation.toObject = function(includeInstance, msg) { + var f, + obj = { + functionname: jspb.Message.getFieldWithDefault(msg, 1, ""), + filtersList: jspb.Message.toObjectList( + msg.getFiltersList(), + proto.Filter.toObject, + includeInstance + ) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.Annotation} + */ +proto.Annotation.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.Annotation(); + return proto.Annotation.deserializeBinaryFromReader(msg, reader); +}; + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.Annotation} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.Annotation} + */ +proto.Annotation.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setFunctionname(value); + break; + case 2: + var value = new proto.Filter(); + reader.readMessage(value, proto.Filter.deserializeBinaryFromReader); + msg.addFilters(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.Annotation.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.Annotation.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.Annotation} message + * @param {!jspb.BinaryWriter} writer + */ +proto.Annotation.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getFunctionname(); + if (f.length > 0) { + writer.writeString(1, f); + } + f = message.getFiltersList(); + if (f.length > 0) { + writer.writeRepeatedMessage(2, f, proto.Filter.serializeBinaryToWriter); + } +}; + +/** + * optional string functionName = 1; + * @return {string} + */ +proto.Annotation.prototype.getFunctionname = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + +/** @param {string} value */ +proto.Annotation.prototype.setFunctionname = function(value) { + jspb.Message.setField(this, 1, value); +}; + +/** + * repeated Filter filters = 2; + * If you change this array by adding, removing or replacing elements, or if you + * replace the array itself, then you must call the setter to update it. + * @return {!Array.} + */ +proto.Annotation.prototype.getFiltersList = function() { + return /** @type{!Array.} */ (jspb.Message.getRepeatedWrapperField( + this, + proto.Filter, + 2 + )); +}; + +/** @param {!Array.} value */ +proto.Annotation.prototype.setFiltersList = function(value) { + jspb.Message.setRepeatedWrapperField(this, 2, value); +}; + +/** + * @param {!proto.Filter=} opt_value + * @param {number=} opt_index + * @return {!proto.Filter} + */ +proto.Annotation.prototype.addFilters = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField( + this, + 2, + opt_value, + proto.Filter, + opt_index + ); +}; + +proto.Annotation.prototype.clearFiltersList = function() { + this.setFiltersList([]); +}; + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.Gene = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.Gene, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.Gene.displayName = "proto.Gene"; +} + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ + proto.Gene.prototype.toObject = function(opt_includeInstance) { + return proto.Gene.toObject(opt_includeInstance, this); + }; + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.Gene} msg The msg instance to transform. + * @return {!Object} + */ + proto.Gene.toObject = function(includeInstance, msg) { + var f, + obj = { + genename: jspb.Message.getFieldWithDefault(msg, 1, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.Gene} + */ +proto.Gene.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.Gene(); + return proto.Gene.deserializeBinaryFromReader(msg, reader); +}; + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.Gene} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.Gene} + */ +proto.Gene.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setGenename(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.Gene.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.Gene.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.Gene} message + * @param {!jspb.BinaryWriter} writer + */ +proto.Gene.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getGenename(); + if (f.length > 0) { + writer.writeString(1, f); + } +}; + +/** + * optional string geneName = 1; + * @return {string} + */ +proto.Gene.prototype.getGenename = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + +/** @param {string} value */ +proto.Gene.prototype.setGenename = function(value) { + jspb.Message.setField(this, 1, value); +}; + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.AnnotationRequest = function(opt_data) { + jspb.Message.initialize( + this, + opt_data, + 0, + -1, + proto.AnnotationRequest.repeatedFields_, + null + ); +}; +goog.inherits(proto.AnnotationRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.AnnotationRequest.displayName = "proto.AnnotationRequest"; +} +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.AnnotationRequest.repeatedFields_ = [1, 2]; + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ + proto.AnnotationRequest.prototype.toObject = function(opt_includeInstance) { + return proto.AnnotationRequest.toObject(opt_includeInstance, this); + }; + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.AnnotationRequest} msg The msg instance to transform. + * @return {!Object} + */ + proto.AnnotationRequest.toObject = function(includeInstance, msg) { + var f, + obj = { + annotationsList: jspb.Message.toObjectList( + msg.getAnnotationsList(), + proto.Annotation.toObject, + includeInstance + ), + genesList: jspb.Message.toObjectList( + msg.getGenesList(), + proto.Gene.toObject, + includeInstance + ) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.AnnotationRequest} + */ +proto.AnnotationRequest.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.AnnotationRequest(); + return proto.AnnotationRequest.deserializeBinaryFromReader(msg, reader); +}; + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.AnnotationRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.AnnotationRequest} + */ +proto.AnnotationRequest.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new proto.Annotation(); + reader.readMessage(value, proto.Annotation.deserializeBinaryFromReader); + msg.addAnnotations(value); + break; + case 2: + var value = new proto.Gene(); + reader.readMessage(value, proto.Gene.deserializeBinaryFromReader); + msg.addGenes(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.AnnotationRequest.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.AnnotationRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.AnnotationRequest} message + * @param {!jspb.BinaryWriter} writer + */ +proto.AnnotationRequest.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getAnnotationsList(); + if (f.length > 0) { + writer.writeRepeatedMessage(1, f, proto.Annotation.serializeBinaryToWriter); + } + f = message.getGenesList(); + if (f.length > 0) { + writer.writeRepeatedMessage(2, f, proto.Gene.serializeBinaryToWriter); + } +}; + +/** + * repeated Annotation annotations = 1; + * If you change this array by adding, removing or replacing elements, or if you + * replace the array itself, then you must call the setter to update it. + * @return {!Array.} + */ +proto.AnnotationRequest.prototype.getAnnotationsList = function() { + return /** @type{!Array.} */ (jspb.Message.getRepeatedWrapperField( + this, + proto.Annotation, + 1 + )); +}; + +/** @param {!Array.} value */ +proto.AnnotationRequest.prototype.setAnnotationsList = function(value) { + jspb.Message.setRepeatedWrapperField(this, 1, value); +}; + +/** + * @param {!proto.Annotation=} opt_value + * @param {number=} opt_index + * @return {!proto.Annotation} + */ +proto.AnnotationRequest.prototype.addAnnotations = function( + opt_value, + opt_index +) { + return jspb.Message.addToRepeatedWrapperField( + this, + 1, + opt_value, + proto.Annotation, + opt_index + ); +}; + +proto.AnnotationRequest.prototype.clearAnnotationsList = function() { + this.setAnnotationsList([]); +}; + +/** + * repeated Gene genes = 2; + * If you change this array by adding, removing or replacing elements, or if you + * replace the array itself, then you must call the setter to update it. + * @return {!Array.} + */ +proto.AnnotationRequest.prototype.getGenesList = function() { + return /** @type{!Array.} */ (jspb.Message.getRepeatedWrapperField( + this, + proto.Gene, + 2 + )); +}; + +/** @param {!Array.} value */ +proto.AnnotationRequest.prototype.setGenesList = function(value) { + jspb.Message.setRepeatedWrapperField(this, 2, value); +}; + +/** + * @param {!proto.Gene=} opt_value + * @param {number=} opt_index + * @return {!proto.Gene} + */ +proto.AnnotationRequest.prototype.addGenes = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField( + this, + 2, + opt_value, + proto.Gene, + opt_index + ); +}; + +proto.AnnotationRequest.prototype.clearGenesList = function() { + this.setGenesList([]); +}; + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.AnnotationResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.AnnotationResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.AnnotationResponse.displayName = "proto.AnnotationResponse"; +} + +if (jspb.Message.GENERATE_TO_OBJECT) { + /** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ + proto.AnnotationResponse.prototype.toObject = function(opt_includeInstance) { + return proto.AnnotationResponse.toObject(opt_includeInstance, this); + }; + + /** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.AnnotationResponse} msg The msg instance to transform. + * @return {!Object} + */ + proto.AnnotationResponse.toObject = function(includeInstance, msg) { + var f, + obj = { + result: jspb.Message.getFieldWithDefault(msg, 1, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; + }; +} + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.AnnotationResponse} + */ +proto.AnnotationResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.AnnotationResponse(); + return proto.AnnotationResponse.deserializeBinaryFromReader(msg, reader); +}; + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.AnnotationResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.AnnotationResponse} + */ +proto.AnnotationResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setResult(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.AnnotationResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.AnnotationResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.AnnotationResponse} message + * @param {!jspb.BinaryWriter} writer + */ +proto.AnnotationResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getResult(); + if (f.length > 0) { + writer.writeString(1, f); + } +}; + +/** + * optional string result = 1; + * @return {string} + */ +proto.AnnotationResponse.prototype.getResult = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + +/** @param {string} value */ +proto.AnnotationResponse.prototype.setResult = function(value) { + jspb.Message.setField(this, 1, value); +}; + +goog.object.extend(exports, proto); \ No newline at end of file diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/annotation_pb_service.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/proto/annotation_pb_service.js similarity index 77% rename from src/assets/thirdPartyServices/snet/gene_annotation_service/annotation_pb_service.js rename to src/assets/thirdPartyServices/snet/gene_annotation_service/proto/annotation_pb_service.js index a4a117214..b861e80c0 100644 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/annotation_pb_service.js +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/proto/annotation_pb_service.js @@ -1,22 +1,22 @@ -// package: -// file: ProtoFiles/annotation.proto +// package: +// file: src/proto/annotation.proto -var ProtoFiles_annotation_pb = require("./annotation_pb"); +var src_proto_annotation_pb = require("./annotation_pb"); var grpc = require("@improbable-eng/grpc-web").grpc; -var Annotate = (function () { +var Annotate = (function() { function Annotate() {} Annotate.serviceName = "Annotate"; return Annotate; -}()); +})(); Annotate.Annotate = { methodName: "Annotate", service: Annotate, requestStream: false, responseStream: false, - requestType: ProtoFiles_annotation_pb.AnnotationRequest, - responseType: ProtoFiles_annotation_pb.AnnotationResponse + requestType: src_proto_annotation_pb.AnnotationRequest, + responseType: src_proto_annotation_pb.AnnotationResponse, }; exports.Annotate = Annotate; @@ -36,7 +36,7 @@ AnnotateClient.prototype.annotate = function annotate(requestMessage, metadata, metadata: metadata, transport: this.options.transport, debug: this.options.debug, - onEnd: function (response) { + onEnd: function(response) { if (callback) { if (response.status !== grpc.Code.OK) { var err = new Error(response.statusMessage); @@ -47,15 +47,14 @@ AnnotateClient.prototype.annotate = function annotate(requestMessage, metadata, callback(null, response.message); } } - } + }, }); return { - cancel: function () { + cancel: function() { callback = null; client.close(); - } + }, }; }; exports.AnnotateClient = AnnotateClient; - diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/result/index.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/result/index.js new file mode 100644 index 000000000..d4688298a --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/result/index.js @@ -0,0 +1,145 @@ +import React, { useState, useEffect, Fragment } from "react"; +import { parse, formatDistanceToNow } from "date-fns"; +import { RESULT_ADDR, downloadSchemeFile } from "../service"; +import TabbedTables from "../tables"; +import Visualizer from "../visualizer"; +import Button from "@material-ui/core/Button"; +import Typography from "@material-ui/core/Typography"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import CloudDownloadIcon from "@material-ui/icons/CloudDownloadOutlined"; +import TableChartOutlinedIcon from "@material-ui/icons/TableChartOutlined"; +import VisibilityIcon from "@material-ui/icons/VisibilityOutlined"; +import "./style.css"; + +export const AnnotationStatus = { + ACTIVE: 1, + COMPLETED: 2, + ERROR: -1, +}; + +const AnnotationResult = props => { + const [response, setResponse] = useState(undefined); + const [isTableShown, setTableShown] = useState(false); + const [isVisualizerShown, setVisualizerShown] = useState(false); + const [isFetchingResult, setFetchingResult] = useState(false); + const { ACTIVE, COMPLETED, ERROR } = AnnotationStatus; + const id = props.id; + + useEffect(() => { + setFetchingResult(true); + fetch(`${RESULT_ADDR}/status/${id}`) + .then(res => res.json()) + .then(res => { + if (res.status === 2) { + return fetch(`${RESULT_ADDR}/${id}`) + .then(res => res.json()) + .then(result => { + setFetchingResult(false); + setResponse(Object.assign({}, res, { result })); + }); + } + setFetchingResult(false); + setResponse({ + status: AnnotationStatus.ERROR, + statusMessage: res.response, + }); + }); + }, []); + + const fetchTableData = fileName => { + fetch(`${RESULT_ADDR}/csv_file/${id}/${fileName.substr(0, fileName.length - 4)}`).then(data => { + const res = Object.assign({}, response); + data + .clone() + .text() + .then(text => { + res.csv_files.find(f => f.fileName === fileName).data = text; + setResponse(res); + }); + }); + }; + + const renderActive = () => ( + + Processing annotation + The annotation task is still processing, refresh the page to check again. + + ); + + const renderError = () => ( + + {console.log(response)} + {response.statusMessage}. Try to + + + ); + + const renderComplete = () => { + const { nodes, edges } = response.result; + return ( + + + The result contains {nodes.length} entities and {edges.length} connections between them. + + + This page will expire in {formatDistanceToNow(parse(response.expire_time * 1000))}. + +
+ + + +
+ {/* + + */} + {/* Show the visualizer */} +
+ ); + }; + + return ( +
+ {/* Logo and title */} +
+ {response && response.status === COMPLETED && renderComplete()} + {response && response.status === ACTIVE && renderActive()} + {response && response.status === ERROR && renderError()} + {/* Show loader if there is a request being processed */} + {isFetchingResult && ( +
+ Fetching results ... +
+ )} +
+ {isVisualizerShown && ( + [...acc, ...n.data.group, n.data.subgroup], []) + .filter((a, i, self) => a && self.indexOf(a) === i)} + onClose={() => setVisualizerShown(false)} + /> + )} + {/* Show annotations tables */} + {isTableShown && ( + setTableShown(false)} + /> + )} +
+ ); +}; + +export default AnnotationResult; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/result/style.css b/src/assets/thirdPartyServices/snet/gene_annotation_service/result/style.css new file mode 100644 index 000000000..ea2ed303b --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/result/style.css @@ -0,0 +1,24 @@ +.ant-tree li .ant-tree-node-content-wrapper { + width: 100%; +} + +.spin-wrapper .ant-spin { + margin-right: 10px; +} + +.landing-page { + width: 100vw; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.search-input { + width: 300px; + text-align: center; +} + +.call-to-action { + margin-top: 45px; +} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/service.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/service.js new file mode 100644 index 000000000..88647adff --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/service.js @@ -0,0 +1,13 @@ +export const RESULT_ADDR = "https://annotation.mozi.ai/web"; + +export const downloadSchemeFile = id => { + window.open(`${RESULT_ADDR}/result_file/${id}`); +}; + +export const downloadCSVFile = (id, annotation) => { + window.open(`${RESULT_ADDR}/csv_file/${id}/${annotation.substr(0, annotation.length - 4)}`); +}; + +export const capitalizeFirstLetter = string => { + return string[0].toUpperCase() + string.slice(1); +}; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/style.css b/src/assets/thirdPartyServices/snet/gene_annotation_service/style.css new file mode 100644 index 000000000..e2f84e638 --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/style.css @@ -0,0 +1,3 @@ +.container { + padding: 15px; +} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/tables/index.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/tables/index.js new file mode 100644 index 000000000..04cb019ea --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/tables/index.js @@ -0,0 +1,361 @@ +import React, { useState, useEffect, Fragment } from "react"; +import Modal from "@material-ui/core/Modal"; +import AppBar from "@material-ui/core/AppBar"; +import Tabs from "@material-ui/core/Tabs"; +import Tab from "@material-ui/core/Tab"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import ExpansionPanel from "@material-ui/core/ExpansionPanel"; +import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; +import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; +import Typography from "@material-ui/core/Typography"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; +import Table from "@material-ui/core/Table"; +import TableBody from "@material-ui/core/TableBody"; +import TableCell from "@material-ui/core/TableCell"; +import TableHead from "@material-ui/core/TableHead"; +import TableRow from "@material-ui/core/TableRow"; +import Button from "@material-ui/core/Button"; +import CloudDownloadIcon from "@material-ui/icons/CloudDownloadOutlined"; +import { downloadCSVFile } from "../service"; +import * as papa from "papaparse"; +import "./style.css"; + +const parseTable = tableData => papa.parse(tableData); +const width = document.body.clientWidth || window.screen.width; + +const ResultTables = props => { + const [tab, setTab] = useState(0); + const { handleClose, tables, fetchTableData } = props; + + useEffect(() => { + fetchTableData(tables[tab].fileName); + }, []); + + useEffect(() => { + fetchTableData(tables[tab].fileName); + }, [tab]); + + const renderGeneGOTable = () => { + const data = tables.find(t => t.displayName === "GO").data; + const table = parseTable(data).data; + const genes = table[0].slice(1).filter((g, i) => table[0].indexOf(g) === i); + const tableData = table.slice(4); + return ( +
+ {genes.map((g, i) => ( + + } aria-controls="panel1a-content" id="panel1a-header"> + {g} + + +
+ {table[1][i * 6 + 1]} + + Learn more about {g} + + + + + No + GO molecular function + GO biological process + GO cellular component + + + ID + Name + ID + Name + ID + Name + + + + {tableData + .filter(row => { + const values = row.slice(i * 6 + 1, i * 6 + 7); + return values[0] || values[1] || values[2] || values[3] || values[4] || values[5]; + }) + .map((row, j) => { + const values = row.slice(i * 6 + 1, i * 6 + 7); + return ( + + {j + 1} + + + {values[1]} + + + {values[0]} + + {values[3]} + + {values[2]} + + + {values[5]} + + + {values[4]} + + ); + })} + +
+
+
+
+ ))} +
+ ); + }; + + const renderPathwayTable = () => { + const data = tables.find(t => t.displayName === "PATHWAY").data; + const table = parseTable(data).data; + const pathways = table[0].slice(1).filter((g, i) => table[0].indexOf(g) === i); + const tableData = table.slice(3); + return ( +
+ {pathways.map((p, i) => ( + + }> + {p} + + +
+ {table[1][i * 3 + 1]} + + Learn more about {p} + + + + + No + Gene + Protien + Small molecule + + + + {tableData + .filter(row => { + const values = row.slice(i * 3 + 1, i * 3 + 4); + return values[0] || values[1] || values[2]; + }) + .map((row, j) => { + const values = row.slice(i * 3 + 1, i * 3 + 4); + const protien = values[1] + .trim() + .split(" ") + .filter(s => s); + return ( + + {j + 1} + + + {values[0]}{" "} + + + + + {protien.length > 0 && ( + + + {protien[0]} + {" "} + + )} + {protien.length > 1 && ( + + {protien[1]}{" "} + + )} + + + + + + {values[2]} + + + + + ); + })} + +
+
+
+
+ ))} +
+ ); + }; + + const renderBiogridTable = () => { + const data = tables.find(t => t.displayName === "BIOGRID").data; + const table = parseTable(data).data; + const interactions = table[0].slice(1).filter((g, i) => table[0].indexOf(g) === i); + const tableData = table.slice(3); + return ( +
+ {interactions.map((b, i) => ( + + }> + {b} + + +
+ {table[1][i * 6 + 1]} + + Learn more about {b} + + + + + No + Location + Protiens + Interacting genes + Pubmed ID + + + + {tableData + .filter(row => { + const values = row.slice(i * 4 + 1, i * 4 + 5); + return values[0] || values[1] || values[2] || values[3]; + }) + .map((row, j) => { + const values = row.slice(i * 4 + 1, i * 4 + 5); + const protien = values[1] + .trim() + .split(" ") + .filter(s => s); + return ( + + {j + 1} + {values[0] || "-"} + + + {protien.length > 0 && ( + + + {console.log(values[1])} + {protien[0]} + {" "} + + )} + {protien.length > 1 && ( + + {protien[1]}{" "} + + )} + + + + + {values[2]}{" "} + + + + {values[3] + ? values[3] + .trim() + .split(",") + .map(t => + t.includes("http") ? ( + + + {t.slice(t.indexOf("=") + 1, t.length)} + {" "} + + ) : ( + t + ) + ) + : "-"} + + + ); + })} + +
+
+
+
+ ))} +
+ ); + }; + + return ( + +
+ + setTab(value)}> + {tables.map(t => ( + + ))} + +
+ +
+
+
+ {!tables[tab].data ? ( +
+ + Fetching table content ... + +
+ ) : null} + {tables[tab].data && tables[tab].displayName === "GO" && renderGeneGOTable()} + {tables[tab].data && tables[tab].displayName === "PATHWAY" && renderPathwayTable()} + {tables[tab].data && tables[tab].displayName === "BIOGRID" && renderBiogridTable()} +
+
+
+ ); +}; + +export default ResultTables; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/tables/style.css b/src/assets/thirdPartyServices/snet/gene_annotation_service/tables/style.css new file mode 100644 index 000000000..16d17799c --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/tables/style.css @@ -0,0 +1,33 @@ +.tables-modal .ant-modal-body { + padding: 10px 0 !important; +} + +.tables-modal .ant-collapse { + margin: 5px 10px; +} + +.table-tabs-wrapper { + padding: 0; + background-color: "#fff"; + position: relative; +} + +.tabbed-table-spinner-wrapper { + width: 100%; + text-align: center; + padding-top: 30; + padding-bottom: 30; +} + +.tabbed-table-spinner-wrapper .ant-spin { + margin-right: 10px; +} + +.table-definition-wrapper .title { + font-weight: bold; +} + +.ant-table-tbody > tr > td { + word-wrap: break-word; + word-break: break-all; +} diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer.config.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer.config.js deleted file mode 100644 index 43984b1c5..000000000 --- a/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer.config.js +++ /dev/null @@ -1,105 +0,0 @@ -export const MAXIMUM_GRAPH_SIZE = 1500; - -export const CYTOSCAPE_COLA_CONFIG = { - name: "cola", - animate: true, - maxSimulationTime: 3000, - ungrabifyWhileSimulating: true, - fit: true, - padding: 10, - randomize: true, - avoidOverlap: true, - handleDisconnected: true, - nodeSpacing: 20, - infinite: false, -}; - -export const CYTOSCAPE_STYLE = [ - // Node styles - { - selector: "node", - css: { - shape: "round-rectangle", - width: "mapData(id.length, 0, 20, 50, 300)", - height: "40", - content: "data(id)", - color: "#fff", - "text-wrap": "wrap", - "text-max-width": "350px", - "text-valign": "center", - "text-halign": "center", - "background-color": "#565656", - "text-outline-color": "#565656", - "text-outline-width": 1, - }, - }, - { - selector: 'node[group="biogrid_interaction_annotation"]', - css: { - shape: "ellipse", - width: 75, - height: 75, - }, - }, - { - selector: 'node[id^="Uni"]', - css: { - shape: "hexagon", - }, - }, - { - selector: 'node[id^="ChEBI"]', - css: { - shape: "diamond", - height: 75, - }, - }, - { - selector: "node:selected", - css: { - "border-width": 5, - "border-color": "#AAD8FF", - "border-opacity": 1, - }, - }, - { - selector: 'node[group="Gene"]', - style: { - shape: "ellipse", - content: "data(id)", - height: 75, - color: "#fff", - "text-outline-color": "#005bcd", - "background-color": "#005bcd", - }, - }, - { - selector: 'node[group="main"]', - style: { - shape: "ellipse", - content: "data(id)", - width: 75, - height: 75, - color: "#fff", - "background-color": "#005bcd", - "text-outline-color": "#005bcd", - }, - }, - // Edge styles - { - selector: "edge", - css: { - "curve-style": "haystack", - "line-color": "#ccc", - width: 4, - }, - }, - { - selector: "edge[group='gene_go_annotation']", - css: { - "curve-style": "straight", - "target-arrow-shape": "triangle", - "target-arrow-fill": "filled", - }, - }, -]; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer/index.js b/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer/index.js new file mode 100644 index 000000000..f06bb1b2c --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer/index.js @@ -0,0 +1,672 @@ +import React, { Fragment, useState, useEffect } from "react"; +import removeSvg from "../assets/remove.svg"; +import addSvg from "../assets/add.svg"; +import filterSvg from "../assets/filter.svg"; +import "cytoscape-context-menus/cytoscape-context-menus.css"; +import $ from "jquery"; +import IconButton from "@material-ui/core/IconButton"; +import Tooltip from "@material-ui/core/Tooltip"; +import SearchIcon from "@material-ui/icons/Search"; +import ClearIcon from "@material-ui/icons/Clear"; +import ShuffleIcon from "@material-ui/icons/Shuffle"; +import CategoryIcon from "@material-ui/icons/CategoryOutlined"; +import AdjustIcon from "@material-ui/icons/Adjust"; +import CameraAltIcon from "@material-ui/icons/CameraAltOutlined"; +import CloudDownloadIcon from "@material-ui/icons/CloudDownloadOutlined"; +import Paper from "@material-ui/core/Paper"; +import InputBase from "@material-ui/core/InputBase"; +import ExpansionPanel from "@material-ui/core/ExpansionPanel"; +import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; +import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; +import Typography from "@material-ui/core/Typography"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; +import Checkbox from "@material-ui/core/Checkbox"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import ArrowBackIcon from "@material-ui/icons/ArrowBack"; +import HelpIcon from "@material-ui/icons/HelpOutline"; +import { useSnackbar } from "notistack"; +import "./style.css"; + +const cytoscape = require("cytoscape"); +const cola = require("cytoscape-cola"); +const contextMenus = require("cytoscape-context-menus"); +const Color = require("color"); +contextMenus(cytoscape, $); + +const AnnotationGroups = [ + { + group: "gene-go-annotation", + subgroups: [ + { subgroup: "cellular_component", color: "#F57C00" }, + { subgroup: "molecular_function", color: "#F1C40F" }, + { subgroup: "biological_process", color: "#8BC34A" }, + ], + }, + { + group: "gene-pathway-annotation", + color: "#9B59B6", + subgroups: [{ subgroup: "Reactome" }], + }, + { + group: "biogrid-interaction-annotation", + color: "#3498DB", + subgroups: [], + }, +]; + +const CYTOSCAPE_COLA_CONFIG = { + name: "cola", + // fit: true, + animate: true, + padding: 10, + nodeSpacing: 10, + maxSimulationTime: 3000, + ungrabifyWhileSimulating: true, + randomize: true, + avoidOverlap: true, + handleDisconnected: true, + infinite: false, +}; + +const CYTOSCAPE_STYLE = [ + { + selector: "node", + css: { + content: "data(id)", + shape: "round-rectangle", + width: "mapData(id.length, 0, 20, 50, 300)", + height: 40, + color: "#fff", + "text-wrap": "wrap", + "text-max-width": "350px", + "text-valign": "center", + "text-halign": "center", + "background-color": "#565656", + "text-outline-color": "#565656", + "text-outline-width": 1, + }, + }, + { + selector: n => n.data().subgroup === "Genes", + style: { + shape: "ellipse", + height: 75, + width: 75, + }, + }, + { + selector: 'node[subgroup="Uniprot"]', + css: { shape: "hexagon" }, + }, + { + selector: 'node[subgroup="ChEBI"]', + css: { + shape: "diamond", + height: 75, + }, + }, + { + selector: "node:selected", + css: { + "border-width": 5, + "border-color": "#87bef5", + }, + }, + { + selector: "edge", + css: { + "curve-style": "straight", + "line-color": "#ccc", + width: 4, + }, + }, + { + selector: e => e.data().group.includes("gene-go-annotation"), + css: { + "target-arrow-shape": "triangle", + "target-arrow-fill": "filled", + }, + }, +]; + +const Visualizer = props => { + const { enqueueSnackbar } = useSnackbar(); + cytoscape.use(cola); + const cy_wrapper = React.createRef(); + const [cy, setCy] = useState(undefined); + const [layout, setLayout] = useState(undefined); + const [filteredElements, setFilteredElements] = useState(undefined); + const [contextMenu, setContextMenu] = useState(undefined); + const nodeTypes = props.graph.nodes + .map(n => n.data.subgroup) + .filter((s, i, arr) => { + return arr.indexOf(s) === i && ["Genes", "Uniprot", "ChEBI"].includes(s); + }); + + const [visibleNodeTypes, setVisibleNodeTypes] = useState(["Genes", "Uniprot", "ChEBI"]); + const [visibleAnnotations, setVisibleAnnotations] = useState(["main%"]); + const [selectedNode, setSelectedNode] = useState({ + node: null, + position: null, + }); + const [selectedEdge, setSelectedEdge] = useState({ + pubmed: null, + }); + const [searchToken, setSearchToken] = useState(undefined); + + useEffect(function() { + setCy( + cytoscape({ + container: cy_wrapper.current, + hideEdgesOnViewport: true, + wheelSensitivity: 0.3, + }) + ); + }, []); + + useEffect( + function() { + cy && toggleAnnotationVisibility(visibleAnnotations); + }, + [visibleAnnotations, visibleNodeTypes, cy] + ); + + useEffect( + function() { + if (!cy) return; + if (filteredElements) { + cy.batch(() => filteredElements.style({ opacity: 1 })); + cy.batch(() => + cy + .nodes() + .difference(filteredElements) + .style({ opacity: 0.1 }) + ); + cy.edges() + .difference(filteredElements) + .style({ opacity: 0 }); + contextMenu.showMenuItem("add"); + contextMenu.showMenuItem("remove"); + contextMenu.hideMenuItem("filter"); + } else { + cy.batch(() => cy.elements().style({ opacity: 1 })); + contextMenu.showMenuItem("filter"); + contextMenu.hideMenuItem("add"); + contextMenu.hideMenuItem("remove"); + } + }, + [filteredElements] + ); + + useEffect( + function() { + if (cy) { + cy.style([ + ...CYTOSCAPE_STYLE, + ...assignColorToAnnotations(), + { + selector: n => n.data().group.includes("main"), + style: { + "background-fill": "solid", + "background-color": "blue", + "text-outline-color": "blue", + }, + }, + ]); + var options = { + menuItems: [ + { + id: "filter", + content: "Filter", + selector: "node", + onClickFunction: e => { + addToFilter(e.target.data().id); + }, + hasTrailingDivider: true, + image: { src: filterSvg, width: 18, height: 18, x: 8, y: 8 }, + }, + { + id: "add", + content: "Add", + selector: "node", + image: { src: addSvg, width: 18, height: 18, x: 8, y: 8 }, + onClickFunction: e => addToFilter(e.target.data().id), + show: false, + }, + { + id: "remove", + content: "Remove", + selector: "node", + image: { src: removeSvg, width: 18, height: 18, x: 8, y: 8 }, + onClickFunction: e => removeFromFilter(e.target.data().id), + show: false, + }, + ], + menuItemClasses: ["context-menu-item"], + contextMenuClasses: ["context-menu"], + }; + setContextMenu(cy.contextMenus(options)); + } + }, + [cy] + ); + + useEffect( + function() { + if (layout) layout.run(); + }, + [layout] + ); + + const randomLayout = () => { + setLayout(cy.layout(CYTOSCAPE_COLA_CONFIG)); + }; + + const breadthFirstLayout = () => { + setLayout(cy.layout({ name: "breadthfirst" })); + }; + + const concentricLayout = () => { + setLayout( + cy.layout({ + name: "concentric", + concentric: node => node.degree(), + levelWidth: () => 3, + }) + ); + }; + + const takeScreenshot = () => { + const link = document.createElement("a"); + link.setAttribute("href", cy.jpg()); + link.setAttribute("download", "mozi-graph.jpg"); + document.body.appendChild(link); + link.click(); + link.remove(); + }; + + const registerEventListeners = () => { + cy.nodes() + .on("select", e => + setSelectedNode({ + node: e.target.data(), + position: e.target.renderedPosition(), + }) + ) + .on("unselect", e => setSelectedNode({ node: null })); + + cy.edges() + .on("select", e => { + let pubMedIds = e.target.data().pubmedId.split(","); + pubMedIds[0] !== "" + ? setSelectedEdge({ + pubmed: pubMedIds, + }) + : setSelectedEdge({ pubmed: null }); + }) + .on("unselect", e => setSelectedEdge({ pubmed: null, position: null })); + }; + + const clearFilter = () => { + setFilteredElements(undefined); + }; + + const removeFromFilter = id => { + const hood = cy.getElementById(id).union(cy.getElementById(id).connectedEdges()); + setFilteredElements(eles => eles.difference(hood)); + }; + + const addToFilter = id => { + const hood = cy.getElementById(id).closedNeighborhood(); + setFilteredElements(eles => (eles ? eles.union(hood) : hood)); + }; + + const downloadGraphJSON = () => { + let exportJson = { + data: { name: "Annotation Service Export" }, + elements: cy.json().elements, + }; + let json = JSON.stringify(exportJson); + const link = document.createElement("a"); + let file = new Blob([json], { type: "text/json" }); + link.href = URL.createObjectURL(file); + link.download = `annotation-graph.json`; + document.body.appendChild(link); + link.click(); + link.remove(); + }; + + const formatDescription = description => { + if (!description) return ""; + return description.includes("https://") || description.includes("http://") ? ( + + Learn more + + ) : ( + description + ); + }; + + const toggleAnnotationVisibility = visibleAnnotations => { + const { nodes, edges } = props.graph; + const visibleNodes = nodes.filter(n => { + const { group, subgroup } = n.data; + return ( + visibleAnnotations.some(a => { + const [g, sg] = a.split("%"); + return ( + group.includes(g) && + (["Genes", "Uniprot", "ChEBI"].includes(subgroup) + ? visibleNodeTypes.includes(subgroup) + : sg + ? sg === subgroup + : true) + ); + }) || group.includes("main") + ); + }); + const visibleEdges = edges.filter(e => { + const { source, target } = e.data; + return visibleNodes.some(n => n.data.id === source) && visibleNodes.some(n => n.data.id === target); + }); + cy.json({ elements: { nodes: visibleNodes } }); + cy.add(visibleEdges); + randomLayout(); + registerEventListeners(); + }; + + const getAnnotationPercentage = (group, subgroup) => { + const { nodes } = props.graph; + let filteredNodes = group ? nodes.filter(n => n.data.group.includes(group)) : nodes; + filteredNodes = subgroup ? filteredNodes.filter(n => n.data.subgroup === subgroup) : filteredNodes; + return (filteredNodes.length * 100) / nodes.length; + }; + + const assignColorToAnnotations = () => { + const styles = AnnotationGroups.reduce((acc, annotation) => { + const subGroupColors = annotation.subgroups.map(sg => { + return { + selector: n => n.data().group.includes(annotation.group) && n.data().subgroup === sg.subgroup, + style: { + "background-color": annotation.color || sg.color, + "text-outline-color": annotation.color || sg.color, + }, + }; + }); + return annotation.color + ? [ + ...acc, + { + selector: n => n.data().group.includes(annotation.group), + style: { + "background-color": annotation.color, + "text-outline-color": annotation.color, + "line-color": Color(annotation.color) + .lighten(0.6) + .hex(), + }, + }, + ...subGroupColors, + ] + : [...acc, ...subGroupColors]; + }, []); + + const multipleGroupsStyle = { + selector: n => n.data().group.length > 1, + style: { + "background-fill": "linear-gradient", + "background-gradient-direction": "to-bottom-right", + "text-outline-color": "#565656", + "background-gradient-stop-colors": n => + n.data().group.reduce((acc, group) => { + if (group === "main") return acc; + const color = AnnotationGroups.find(g => g.group === group).color || "#565656"; + return `${acc} ${color} ${color}`; + }, ""), + "background-gradient-stop-positions": n => { + const group = n.data().group.filter(g => g !== "main"); + const width = 100 / group.length; + let value = "0%"; + for (let i = 1; i < group.length; i++) { + value += ` ${width * i}% ${width * i}%`; + } + return value + " 100%"; + }, + }, + }; + + return [...styles, multipleGroupsStyle]; + }; + + const search = id => { + cy.batch(function() { + const selected = cy.nodes(`[id @= "${id}"]`); + if (selected.size()) { + selected.select(); + cy.zoom(2); + cy.center(selected); + } else { + enqueueSnackbar("No matching results.", { + variant: "warning", + anchorOrigin: { + vertical: "top", + horizontal: "center", + }, + }); + } + }); + }; + + const renderProgressBar = (percentage, color) => { + return ( +
+
+
+ ); + }; + + const renderDescriptionBox = (title, content) => { + return ( +
+

{title}

+

{content}

+
+ ); + }; + + const renderFilterControls = () => { + return ( +
+ + + + + +
+ ); + }; + + return ( + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Use the checkboxes to the right to filter the graph by annotations and node types.

+

Right click on a node to perform actions on it.

+

You may download the graph JSON and view it on Cytoscape desktop.

+

The search is case sensitive.

+
+ } + > + + + + +
+
+ + setSearchToken(e.target.value)} + onKeyPress={e => { + if (e.key === "Enter" && searchToken) search(searchToken); + }} + /> + { + if (searchToken) search(searchToken); + }} + > + + + + + + } id="genes"> + Genes + + + {nodeTypes.map(n => ( + { + return setVisibleNodeTypes(va => + e.target.checked ? (va.includes(n) ? va : [...va, n]) : va.filter(a => a !== n) + ); + }} + /> + } + label={n} + /> + ))} + + + + } id="annotations"> + Annotations + + +
+ {AnnotationGroups.filter(a => props.annotations.includes(a.group)).map((a, i) => { + return ( +
+ + + {a.group.includes("biogrid") && ( + { + const key = `${a.group}%`; + return setVisibleAnnotations(va => + e.target.checked ? (va.includes(key) ? va : [...va, key]) : va.filter(a => a !== key) + ); + }} + /> + )} + + {a.group} + + {renderProgressBar(getAnnotationPercentage(a.group), a.color || "#565656")} + + {a.subgroups + .filter(s => props.annotations.includes(s.subgroup)) + .map(s => ( + + { + const key = `${a.group}%${s.subgroup}`; + return setVisibleAnnotations(va => + e.target.checked + ? va.includes(key) + ? va + : [...va, key] + : va.filter(a => a !== key) + ); + }} + /> + } + label={ + + {s.subgroup} + {renderProgressBar(getAnnotationPercentage(a.group, s.subgroup), a.color || s.color)} + + } + /> + + ))} +
+ ); + })} +
+
+
+
+ {selectedNode.node && + renderDescriptionBox( + `${selectedNode.node.name} ( ${selectedNode.node.id.slice(selectedNode.node.id.indexOf(":") + 1)} )`, + formatDescription(selectedNode.node.definition) + )} + {selectedEdge.pubmed && + renderDescriptionBox( + "PubMed Id", + selectedEdge.pubmed.map((pubId, i) => ( +

+ {i + 1} -{" "} + + Learn more + +

+ )) + )} + {filteredElements && renderFilterControls()} +
+ ); +}; + +export default Visualizer; diff --git a/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer/style.css b/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer/style.css new file mode 100644 index 000000000..2cfd45ee5 --- /dev/null +++ b/src/assets/thirdPartyServices/snet/gene_annotation_service/visualizer/style.css @@ -0,0 +1,101 @@ +.context-menu { + border: none !important; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), + 0 1px 2px rgba(0, 0, 0, 0.24); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + -ms-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + -o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); +} + +.context-menu-item { + font-size: 1em !important; + padding: 7px 35px; + border: none !important; + min-width: 200px; +} + +.context-menu-item:hover { + background-color: #e8eaf6 !important; + color: #000 !important; +} + +.context-menu-item:first-child { + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.context-menu-item:last-child { + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + +.percentage-wrapper { + width: 100%; + height: 5px; + background-color: #eee; +} + +.percentage-bar { + height: 5px; + background-color: #000; +} + +.description-wrapper { + position: absolute; + bottom: 15px; + left: 15px; + width: 350px; + background-color: #c9e1f9; + border: solid 1px #87bef5; + padding: 5px; + border-radius: 3px; + max-height: 500px; + overflow-y: scroll; +} + +.annotation-toggle-wrapper { + position: absolute; + top: 15px; + right: 15px; + border-radius: 5px; + z-index: 2; + opacity: 0.9; + text-align: left; + width: 300px; +} + +.visualizer-wrapper { + width: 100vw; + height: 100vh; + position: absolute; + top: 0; + left: 0; + background-color: #fff; +} + +.visualizer-controls-wrapper { + position: absolute; + display: flex; + flex-direction: column; + border-radius: 5px; + top: 15px; + left: 15px; + opacity: 0.9; + z-index: 2; + background-color: #fff; +} + +.visualizer-controls-wrapper .ant-btn { + border: none; +} + +.inline-buttons button { + margin: 5px; +} + +.filter-controls { + position: absolute; + top: 15px; + left: 90px; +} diff --git a/src/assets/thirdPartyServices/snet/i3d_video_action_recognition/index.js b/src/assets/thirdPartyServices/snet/i3d_video_action_recognition/index.js index c2cf77e6b..4f765ce1a 100644 --- a/src/assets/thirdPartyServices/snet/i3d_video_action_recognition/index.js +++ b/src/assets/thirdPartyServices/snet/i3d_video_action_recognition/index.js @@ -160,7 +160,7 @@ export default class I3DActionRecognition extends React.Component {
Status: {status}
Top Predicted Actions: -
{value}
+
{value}
diff --git a/src/assets/thirdPartyServices/snet/text_generation/index.js b/src/assets/thirdPartyServices/snet/text_generation/index.js index e97996294..d3e4eb5ab 100644 --- a/src/assets/thirdPartyServices/snet/text_generation/index.js +++ b/src/assets/thirdPartyServices/snet/text_generation/index.js @@ -12,147 +12,93 @@ import InfoIcon from "@material-ui/icons/Info"; import Avatar from "@material-ui/core/Avatar"; import StyledButton from "../../../../components/common/StyledButton"; +import { GENGPT2 } from "./ntg_pb_service"; +import { useStyles } from "./styles"; +import AnchorLink from "../../../../components/common/AnchorLink"; -import BarackObama from "../../../images/ThirdPartyServices/snet/text_generation/BarackObama.jpg"; -import BarackObamaAvatar from "../../../images/ThirdPartyServices/snet/text_generation/BarackObama_avatar.jpg"; - -import BernieSanders from "../../../images/ThirdPartyServices/snet/text_generation/BernieSanders.jpg"; -import BernieSandersAvatar from "../../../images/ThirdPartyServices/snet/text_generation/BernieSanders_avatar.jpg"; - -import BethanyBrookshire from "../../../images/ThirdPartyServices/snet/text_generation/BethanyBrookshire.jpg"; -import BethanyBrookshireAvatar from "../../../images/ThirdPartyServices/snet/text_generation/BethanyBrookshire_avatar.jpg"; - -import BillGates from "../../../images/ThirdPartyServices/snet/text_generation/BillGates.jpg"; -import BillGatesAvatar from "../../../images/ThirdPartyServices/snet/text_generation/BillGates_avatar.jpg"; - -import BrianSwitek from "../../../images/ThirdPartyServices/snet/text_generation/BrianSwitek.jpg"; -import BrianSwitekAvatar from "../../../images/ThirdPartyServices/snet/text_generation/BrianSwitek_avatar.jpg"; - -import ConanOBrien from "../../../images/ThirdPartyServices/snet/text_generation/ConanOBrien.jpg"; -import ConanOBrienAvatar from "../../../images/ThirdPartyServices/snet/text_generation/ConanOBrien_avatar.jpg"; - -import DeborahBlum from "../../../images/ThirdPartyServices/snet/text_generation/DeborahBlum.jpg"; -import DeborahBlumAvatar from "../../../images/ThirdPartyServices/snet/text_generation/DeborahBlum_avatar.jpg"; - -import DeepakChopra from "../../../images/ThirdPartyServices/snet/text_generation/DeepakChopra.jpg"; -import DeepakChopraAvatar from "../../../images/ThirdPartyServices/snet/text_generation/DeepakChopra_avatar.jpg"; - -import DonaldTrump from "../../../images/ThirdPartyServices/snet/text_generation/DonaldTrump.jpg"; -import DonaldTrumpAvatar from "../../../images/ThirdPartyServices/snet/text_generation/DonaldTrump_avatar.jpg"; - -import DwayneJohnson from "../../../images/ThirdPartyServices/snet/text_generation/DwayneJohnson.jpg"; -import DwayneJohnsonAvatar from "../../../images/ThirdPartyServices/snet/text_generation/DwayneJohnson_avatar.jpg"; - -import EllenDeGeneres from "../../../images/ThirdPartyServices/snet/text_generation/EllenDeGeneres.jpg"; -import EllenDeGeneresAvatar from "../../../images/ThirdPartyServices/snet/text_generation/EllenDeGeneres_avatar.jpg"; - -import ElonMusk from "../../../images/ThirdPartyServices/snet/text_generation/ElonMusk.jpg"; -import ElonMuskAvatar from "../../../images/ThirdPartyServices/snet/text_generation/ElonMusk_avatar.jpg"; - -import EricWeinstein from "../../../images/ThirdPartyServices/snet/text_generation/EricWeinstein.png"; -import EricWeinsteinAvatar from "../../../images/ThirdPartyServices/snet/text_generation/EricWeinstein_avatar.png"; - -import god from "../../../images/ThirdPartyServices/snet/text_generation/god.jpg"; -import godAvatar from "../../../images/ThirdPartyServices/snet/text_generation/god_avatar.jpg"; - -import HillaryClinton from "../../../images/ThirdPartyServices/snet/text_generation/HillaryClinton.jpg"; -import HillaryClintonAvatar from "../../../images/ThirdPartyServices/snet/text_generation/HillaryClinton_avatar.jpg"; - -import JimmyFallon from "../../../images/ThirdPartyServices/snet/text_generation/JimmyFallon.jpg"; -import JimmyFallonAvatar from "../../../images/ThirdPartyServices/snet/text_generation/JimmyFallon_avatar.jpg"; - -import JoeBiden from "../../../images/ThirdPartyServices/snet/text_generation/JoeBiden.jpg"; -import JoeBidenAvatar from "../../../images/ThirdPartyServices/snet/text_generation/JoeBiden_avatar.jpg"; - -import JoeRogan from "../../../images/ThirdPartyServices/snet/text_generation/JoeRogan.png"; -import JoeRoganAvatar from "../../../images/ThirdPartyServices/snet/text_generation/JoeRogan_avatar.png"; - -import JordanPeterson from "../../../images/ThirdPartyServices/snet/text_generation/JordanPeterson.jpg"; -import JordanPetersonAvatar from "../../../images/ThirdPartyServices/snet/text_generation/JordanPeterson_avatar.jpg"; - -import JustinBieber from "../../../images/ThirdPartyServices/snet/text_generation/JustinBieber.jpg"; -import JustinBieberAvatar from "../../../images/ThirdPartyServices/snet/text_generation/JustinBieber_avatar.jpg"; - -import KatyPerry from "../../../images/ThirdPartyServices/snet/text_generation/KatyPerry.jpg"; -import KatyPerryAvatar from "../../../images/ThirdPartyServices/snet/text_generation/KatyPerry_avatar.jpg"; - -import KevinHart from "../../../images/ThirdPartyServices/snet/text_generation/KevinHart.jpg"; -import KevinHartAvatar from "../../../images/ThirdPartyServices/snet/text_generation/KevinHart_avatar.jpg"; - -import KimKardashian from "../../../images/ThirdPartyServices/snet/text_generation/KimKardashian.png"; -import KimKardashianAvatar from "../../../images/ThirdPartyServices/snet/text_generation/KimKardashian_avatar.png"; - -import LadyGaga from "../../../images/ThirdPartyServices/snet/text_generation/LadyGaga.jpg"; -import LadyGagaAvatar from "../../../images/ThirdPartyServices/snet/text_generation/LadyGaga_avatar.jpg"; - -import NeildeGrasseTyson from "../../../images/ThirdPartyServices/snet/text_generation/NeildeGrasseTyson.jpg"; -import NeildeGrasseTysonAvatar from "../../../images/ThirdPartyServices/snet/text_generation/NeildeGrasseTyson_avatar.jpg"; - -import PhilipPlait from "../../../images/ThirdPartyServices/snet/text_generation/PhilipPlait.jpg"; -import PhilipPlaitAvatar from "../../../images/ThirdPartyServices/snet/text_generation/PhilipPlait_avatar.jpg"; - -import RebeccaSkloot from "../../../images/ThirdPartyServices/snet/text_generation/RebeccaSkloot.jpg"; -import RebeccaSklootAvatar from "../../../images/ThirdPartyServices/snet/text_generation/RebeccaSkloot_avatar.jpg"; - -import RichardDawkins from "../../../images/ThirdPartyServices/snet/text_generation/RichardDawkins.jpg"; -import RichardDawkinsAvatar from "../../../images/ThirdPartyServices/snet/text_generation/RichardDawkins_avatar.jpg"; - -import RickyGervais from "../../../images/ThirdPartyServices/snet/text_generation/RickyGervais.jpg"; -import RickyGervaisAvatar from "../../../images/ThirdPartyServices/snet/text_generation/RickyGervais_avatar.jpg"; +const imgPath = (name, extension = "jpg") => { + const trimmedName = name.replace(/[\s\.\'']/g, ""); + return `${process.env.REACT_APP_SNET_CDN}/assets/images/ThirdPartyServices/snet/text_generation/${trimmedName}.${extension}`; +}; -import SamHarris from "../../../images/ThirdPartyServices/snet/text_generation/SamHarris.jpg"; -import SamHarrisAvatar from "../../../images/ThirdPartyServices/snet/text_generation/SamHarris_avatar.jpg"; +const avatarPath = (name, extension = "jpg") => { + const avatarName = name + "_avatar"; + return imgPath(avatarName, extension); +}; -import TerenceMcKenna from "../../../images/ThirdPartyServices/snet/text_generation/TerenceMcKenna.jpg"; -import TerenceMcKennaAvatar from "../../../images/ThirdPartyServices/snet/text_generation/TerenceMcKenna_avatar.jpg"; +const defaultImgPath = imgPath("DefaultImage", "png"); + +const runNamesWithoutMedia = [ + { key: "universal", value: "Universal Generator" }, + { key: "badastronomer", value: "Phil Plait" }, + { key: "barackobama", value: "Barack Obama" }, + { key: "beebrookshire", value: "Bethany Brookshire" }, + { key: "berniesanders", value: "Bernie Sanders" }, + { key: "billgates", value: "Bill Gates" }, + { key: "conanobrien", value: "Conan O'Brien" }, + { key: "deborahblum", value: "Deborah Blum" }, + { key: "deepakchopra", value: "Deepak Chopra" }, + { key: "elonmusk", value: "Elon Musk" }, + { + key: "ericrweinstein", + value: "Eric Weinstein", + image: imgPath("EricWeinstein", "png"), + avatar: avatarPath("EricWeinstein", "png"), + }, + { key: "hillaryclinton", value: "Hillary Clinton" }, + { key: "jimmyfallon", value: "Jimmy Fallon" }, + { key: "joebiden", value: "Joe Biden" }, + { + key: "joerogan", + value: "Joe Rogan", + image: imgPath("JoeRogan", "png"), + avatar: avatarPath("JoeRogan", "png"), + }, + { key: "jordanbpeterson", value: "Dr Jordan B Peterson" }, + { key: "justinbieber", value: "Justin Bieber" }, + { key: "katyperry", value: "Katy Perry" }, + { key: "kevinhart4real", value: "Kevin Hart" }, + { + key: "kimkardashian", + value: "Kim Kardashian West", + image: imgPath("Kim Kardashian West", "png"), + avatar: avatarPath("Kim Kardashian West", "png"), + }, + { key: "ladygaga", value: "Lady Gaga" }, + { key: "laelaps", value: "Brian Switek" }, + { key: "neiltyson", value: "Neil deGrasse Tyson" }, + { key: "trump", value: "Donald J. Trump" }, + { key: "rebeccaskloot", value: "Rebecca Skloot" }, + { key: "richarddawkins", value: "Richard Dawkins" }, + { key: "rickygervais", value: "Ricky Gervais" }, + { key: "samharrisorg", value: "Sam Harris" }, + { key: "terencemckenna_", value: "Terence McKenna" }, + { key: "theellenshow", value: "Ellen DeGeneres" }, + { key: "therock", value: "Dwayne Johnson" }, + { key: "thetweetofgod", value: "God" }, + { key: "ticbot", value: "TicBot" }, +]; -import { GENGPT2 } from "./ntg_pb_service"; -import { useStyles } from "./styles"; -import AnchorLink from "../../../../components/common/AnchorLink"; +const runNames = runNamesWithoutMedia.map(runName => { + const updatedRunName = { ...runName }; + if (!runName.image) { + updatedRunName.image = imgPath(runName.value); + } + if (!runName.avatar) { + updatedRunName.avatar = avatarPath(runName.value); + } + return updatedRunName; +}); const initialUserInput = { start_text: "", run_name: "trump", temperature: 0.8, - top_k: 20, + top_k: 0, length: 256, + selectedAvatar: avatarPath("DonaldJTrump"), }; -const runNames = [ - { key: "badastronomer", value: "Phil Plait", image: PhilipPlait, avatar: PhilipPlaitAvatar }, - { key: "barackobama", value: "Barack Obama", image: BarackObama, avatar: BarackObamaAvatar }, - { key: "beebrookshire", value: "Bethany Brookshire", image: BethanyBrookshire, avatar: BethanyBrookshireAvatar }, - { key: "berniesanders", value: "Bernie Sanders", image: BernieSanders, avatar: BernieSandersAvatar }, - { key: "billgates", value: "Bill Gates", image: BillGates, avatar: BillGatesAvatar }, - { key: "conanobrien", value: "Conan O'Brien", image: ConanOBrien, avatar: ConanOBrienAvatar }, - { key: "deborahblum", value: "Deborah Blum", image: DeborahBlum, image: DeborahBlumAvatar }, - { key: "deepakchopra", value: "Deepak Chopra", image: DeepakChopra, avatar: DeepakChopraAvatar }, - { key: "elonmusk", value: "Elon Musk", image: ElonMusk, avatar: ElonMuskAvatar }, - { key: "ericrweinstein", value: "Eric Weinstein", image: EricWeinstein, avatar: EricWeinsteinAvatar }, - { key: "hillaryclinton", value: "Hillary Clinton", image: HillaryClinton, avatar: HillaryClintonAvatar }, - { key: "jimmyfallon", value: "jimmyfallon", image: JimmyFallon, avatar: JimmyFallonAvatar }, - { key: "joebiden", value: "Joe Biden", image: JoeBiden, avatar: JoeBidenAvatar }, - { key: "joerogan", value: "Joe Rogan", image: JoeRogan, avatar: JoeRoganAvatar }, - { key: "jordanbpeterson", value: "Dr Jordan B Peterson", image: JordanPeterson, avatar: JordanPetersonAvatar }, - { key: "justinbieber", value: "Justin Bieber", image: JustinBieber, avatar: JustinBieberAvatar }, - { key: "katyperry", value: "Katy Perry", image: KatyPerry, avatar: KatyPerryAvatar }, - { key: "kevinhart4real", value: "Kevin Hart", image: KevinHart, avatar: KevinHartAvatar }, - { key: "kimkardashian", value: "Kim Kardashian West", image: KimKardashian, avatar: KimKardashianAvatar }, - { key: "ladygaga", value: "Lady Gaga", image: LadyGaga, avatar: LadyGagaAvatar }, - { key: "laelaps", value: "Brian Switek", image: BrianSwitek, avatar: BrianSwitekAvatar }, - { key: "neiltyson", value: "Neil deGrasse Tyson", image: NeildeGrasseTyson, avatar: NeildeGrasseTysonAvatar }, - { key: "trump", value: "Donald J. Trump", image: DonaldTrump, avatar: DonaldTrumpAvatar }, - { key: "rebeccaskloot", value: "Rebecca Skloot", image: RebeccaSkloot, avatar: RebeccaSklootAvatar }, - { key: "richarddawkins", value: "Richard Dawkins", image: RichardDawkins, avatar: RichardDawkinsAvatar }, - { key: "rickygervais", value: "Ricky Gervais", image: RickyGervais, avatar: RickyGervaisAvatar }, - { key: "samharrisorg", value: "Sam Harris", image: SamHarris, avatar: SamHarrisAvatar }, - { key: "terencemckenna_", value: "Terence McKenna", image: TerenceMcKenna, avatar: TerenceMcKennaAvatar }, - { key: "theellenshow", value: "Ellen DeGeneres", image: EllenDeGeneres, avatar: EllenDeGeneresAvatar }, - { key: "therock", value: "Dwayne Johnson", image: DwayneJohnson, avatar: DwayneJohnsonAvatar }, - { key: "thetweetofgod", value: "God", image: god, avatar: godAvatar }, - { key: "ticbot", value: "TicBot" }, -]; - class TextGenerationService extends React.Component { constructor(props) { super(props); @@ -183,9 +129,11 @@ class TextGenerationService extends React.Component { } handleFormUpdate(event) { - this.setState({ - [event.target.name]: event.target.value, - }); + const { name, value } = event.target; + this.setState({ [name]: value }); + if (name === "run_name") { + this.parseAvatarSrc(value); + } } onKeyPressvalidator(event) { @@ -211,7 +159,7 @@ class TextGenerationService extends React.Component { throw new Error(statusMessage); } const selectedRunName = runNames.find(el => el.key === this.state.run_name); - const image = selectedRunName && selectedRunName.image; + const image = (selectedRunName && selectedRunName.image) || defaultImgPath; this.setState({ ...initialUserInput, response: { status: "success", answer: message.getAnswer(), image, start_text }, @@ -222,20 +170,30 @@ class TextGenerationService extends React.Component { this.props.serviceClient.unary(methodDescriptor, props); } - parseAvatarSrc = () => { - const selectedRunName = runNames.find(el => el.key === this.state.run_name); - return selectedRunName && selectedRunName.avatar; + parseAvatarSrc = run_name => { + const selectedRunName = runNames.find(el => el.key === run_name); + const selectedAvatar = (selectedRunName && selectedRunName.avatar) || defaultImgPath; + this.setState({ selectedAvatar }); + }; + + handleAvatarLoadError = () => { + this.setState({ selectedAvatar: defaultImgPath }); + }; + + handleResponseImgError = () => { + this.setState(prevState => ({ response: { ...prevState.response, image: defaultImgPath } })); }; renderForm() { - const { run_name, start_text, length: maxResponseLength, top_k, temperature } = this.state; + const { run_name, start_text, length: maxResponseLength, top_k, temperature, selectedAvatar } = this.state; const { classes } = this.props; return (

- For this demo you will be asked to input a text content and the persona you would like the tweet to come from. + For this demo you will be asked to input a text content and the persona you would like the tweet to come + from.

Check out the @@ -273,7 +231,14 @@ class TextGenerationService extends React.Component { - + @@ -380,7 +345,7 @@ class TextGenerationService extends React.Component { - + diff --git a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/StyledCard/index.js b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/GridViewItem/index.js similarity index 84% rename from src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/StyledCard/index.js rename to src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/GridViewItem/index.js index d29ccc645..30f52cf27 100644 --- a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/StyledCard/index.js +++ b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/GridViewItem/index.js @@ -27,7 +27,7 @@ const StyledCard = props => { subheader: classes.cardSubheader, }} title={props.cardTitle} - subheader={

{props.cardSubheader}

} + subheader={props.cardSubheader} /> @@ -35,17 +35,12 @@ const StyledCard = props => { - - - {props.ratingGiven} {props.totalRating} - +
- + {props.cardDescription} diff --git a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/StyledCard/styles.js b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/GridViewItem/styles.js similarity index 59% rename from src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/StyledCard/styles.js rename to src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/GridViewItem/styles.js index ff4d21162..f88c09cea 100644 --- a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/StyledCard/styles.js +++ b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/GridViewItem/styles.js @@ -6,6 +6,8 @@ export const useStyles = makeStyles(theme => ({ padding: "13px 0", margin: "0 25px 25px 0", display: "inline-block", + fontFamily: theme.typography.primary.main, + fontSize: 18, "&:hover": { backgroundColor: theme.palette.text.offWhiteColor, "& h4": { color: theme.palette.text.primary }, @@ -13,30 +15,47 @@ export const useStyles = makeStyles(theme => ({ }, cardHeader: { padding: "0 18px", + alignItems: "flex-start", + "& .MuiCardHeader-avatar": { marginRight: 0 }, + "& .MuiCardHeader-content": { + textAlign: "left", + marginLeft: 10, + }, }, cardTitle: { - fontSize: 10, - color: theme.palette.text.lightShadedGray, - textTransform: "uppercase", - letterSpacing: 2, + fontFamily: theme.typography.primary.main, + fontSize: 18, + fontWeight: 600, + color: theme.palette.text.darkShadedGray, + letterSpacing: 0.23, }, cardSubheader: { - color: theme.palette.text.darkShadedGray, + margin: 0, + fontFamily: theme.typography.primary.main, + fontSize: 10, + color: theme.palette.text.lightShadedGray, fontWeight: 600, - fontSize: 18, - letterSpacing: 0.23, - lineHeight: "23px", - "& h4": { margin: "7px 0" }, + letterSpacing: 1.67, + lineHeight: "16px", + textTransform: "uppercase", }, CardMedia: { height: 175, - margin: "5px 0 13px", + margin: "12px 0 13px", + }, + fontSize: 18, + cardContent: { + padding: "0 13px", + fontFamily: theme.typography.primary.main, + fontSize: 18, + textAlign: "left", }, - cardContent: { padding: "0 13px" }, cardTypograpy: { color: theme.palette.text.mediumShadeGray, + fontFamily: theme.typography.primary.main, fontSize: 14, - lineHeight: "20px", + letterSpacing: 0.25, + lineHeight: "21px", }, cardActions: { padding: "16px 13px 0", diff --git a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/ServiceListItem/styles.js b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/ServiceListItem/styles.js index 5a37d87f8..9935d72e9 100644 --- a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/ServiceListItem/styles.js +++ b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/ServiceListItem/styles.js @@ -3,7 +3,7 @@ import { makeStyles } from "@material-ui/styles"; export const useStyles = makeStyles(theme => ({ cardItemsContainer: { flexWrap: "nowrap", - "@media(max-width: 480px)": { flexDirection: "column" }, + "@media(max-width: 768px)": { flexDirection: "column" }, }, card: { padding: 10, @@ -36,6 +36,7 @@ export const useStyles = makeStyles(theme => ({ letterSpacing: 1.25, }, "& .MuiCardHeader-avatar": { marginRight: 10 }, + "@media(max-width: 1279px)": { padding: "0 0 0 16px" }, }, cardTitle: { display: "inline-block", @@ -59,6 +60,7 @@ export const useStyles = makeStyles(theme => ({ cardContent: { padding: "0 10px", "&:last-of-type": { paddingBottom: 0 }, + "@media(max-width: 1279px)": { padding: "0 0 0 16px" }, }, cardTypograpy: { marginTop: 16, @@ -66,6 +68,8 @@ export const useStyles = makeStyles(theme => ({ fontFamily: theme.typography.primary.main, fontSize: 14, lineHeight: "20px", + textAlign: " left", + "@media(max-width: 1279px)": { marginTop: 5 }, }, showMore: { padding: 0, @@ -96,5 +100,12 @@ export const useStyles = makeStyles(theme => ({ position: "absolute", top: 10, right: 20, + "@media(max-width: 1279px)": { + padding: 0, + display: "flex", + justifyContent: "flex-end", + position: "static", + "& button": { padding: "5px 8px" }, + }, }, })); diff --git a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/index.js b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/index.js index 11d4d897f..0ea2c0167 100644 --- a/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/index.js +++ b/src/components/AiMarketplace/MainSection/ServiceCollection/CardGroup/index.js @@ -7,9 +7,11 @@ import ServiceListItem from "./ServiceListItem"; import CardImg from "../../../../../assets/images/SnetDefaultServiceImage.png"; import { useStyles } from "./styles"; import Routes from "../../../../../utility/constants/Routes"; +import GridViewItem from "./GridViewItem"; -const CardGroup = ({ cards, loading }) => { +const CardGroup = ({ data: cards, listView, loading }) => { const classes = useStyles(); + if (loading) { return (
@@ -20,7 +22,6 @@ const CardGroup = ({ cards, loading }) => {
); } - if (cards.length === 0) { return (
@@ -29,20 +30,41 @@ const CardGroup = ({ cards, loading }) => {
); } - + if (listView) { + return ( +
+ {cards.map(card => ( + + + + ))} +
+ ); + } return ( -
+
{cards.map(card => ( - ({ - cardCollection: { + lisViewCardCollection: { marginTop: 10, "@media(max-width: 1023px) and (min-width: 768px)": { textAlign: "center" }, + "& a": { + width: "100%", + textDecoration: "none ", + display: "inline-block", + verticalAlign: "top", + }, }, - routerLink: { - width: "100%", - textDecoration: "none ", - display: "inline-block", - verticalAlign: "top", - }, + circularProgressContainer: { paddingTop: 20, textAlign: "center", @@ -49,4 +50,22 @@ export const useStyles = makeStyles(theme => ({ lineHeight: "20px", }, }, + gridViewCardCollection: { + marginTop: 20, + display: "flex", + flexWrap: "wrap", + "& a": { + width: "100%", + textDecoration: "none ", + display: "inline-block", + verticalAlign: "top", + flex: 1, + "@media(max-width: 1024px)": { textAlign: "center" }, + "& > div": { + "@media(max-width: 768px)": { marginRight: 0 }, + }, + "@media(max-width: 768px)": { textAlign: "center" }, + }, + "@media(max-width: 768px)": { flexDirection: "column" }, + }, })); diff --git a/src/components/AiMarketplace/MainSection/ServiceCollection/StyledPagination/index.js b/src/components/AiMarketplace/MainSection/ServiceCollection/StyledPagination/index.js index 1600f2f9b..7fe48f064 100644 --- a/src/components/AiMarketplace/MainSection/ServiceCollection/StyledPagination/index.js +++ b/src/components/AiMarketplace/MainSection/ServiceCollection/StyledPagination/index.js @@ -34,7 +34,7 @@ const StyledPagination = ({ limit, offset, total_count, handleChange }) => { return ( - + { className={classes.styledPagination} /> - + Items per page