diff --git a/package-lock.json b/package-lock.json index b6d7c3ea..2f9eed3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "body-parser": "^1.20.0", "bootstrap": "^3.4.1", "core-js": "^3.6.5", + "csv-stringify": "^6.5.2", "d3": "^6.5.0", "d3-force": "^2.1.1", "dotenv": "^8.6.0", @@ -10326,6 +10327,12 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.11.tgz", "integrity": "sha512-l8YyEC9NBkSm783PFTvh0FmJy7s5pFKrDp49ZL7zBGX3fWkO+N4EEyan1qqp8cwPLDcD0OSdyY6hAMoxp34JFw==" }, + "node_modules/csv-stringify": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.5.2.tgz", + "integrity": "sha512-RFPahj0sXcmUyjrObAK+DOWtMvMIFV328n4qZJhgX3x2RqkQgOTU2mCUmiFR0CzM6AzChlRSUErjiJeEt8BaQA==", + "license": "MIT" + }, "node_modules/cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", diff --git a/package.json b/package.json index 2b9b395e..8988f48d 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "body-parser": "^1.20.0", "bootstrap": "^3.4.1", "core-js": "^3.6.5", + "csv-stringify": "^6.5.2", "d3": "^6.5.0", "d3-force": "^2.1.1", "dotenv": "^8.6.0", diff --git a/src/components/DownloadDialog.jsx b/src/components/DownloadDialog.jsx new file mode 100644 index 00000000..63df2733 --- /dev/null +++ b/src/components/DownloadDialog.jsx @@ -0,0 +1,95 @@ +import React from 'react'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormControl from '@material-ui/core/FormControl'; +import TextField from '@material-ui/core/TextField'; +import csv from 'csv-stringify'; + +const jsonToCsvString = (json) => new Promise((res, rej) => { + csv.stringify(json, (err, output) => { + if (err) rej(err); + else res(output); + }); +}); + +export default function DownloadDialog({ + open, setOpen, message, +}) { + const [type, setType] = React.useState('json'); + const [fileName, setFileName] = React.useState('ROBOKOP_message'); + + const handleClose = () => { + setOpen(false); + }; + + const handleClickDownload = async () => { + let blob; + if (type === 'json') { + blob = new Blob([JSON.stringify({ message }, null, 2)], { type: 'application/json' }); + } + if (type === 'csv') { + const subsetMessage = message.results.map((r) => [...Object.values(r.node_bindings).map((nb) => nb[0].id), r.score]); + const csvString = await jsonToCsvString(subsetMessage); + blob = new Blob([csvString], { type: 'text/csv' }); + } + + const a = document.createElement('a'); + a.download = `${fileName}.${type}`; + a.href = window.URL.createObjectURL(blob); + document.body.appendChild(a); + a.click(); + a.remove(); + + handleClose(); + }; + + return ( + + Download Answer + + { setFileName(e.target.value); }} + /> + + + { setType(e.target.value); }}> + } label="JSON" /> + } label="CSV" /> + + + + { + type === 'csv' && ( + + The CSV download contains a smaller subset of the answer information. To analyze the complete properties of the answer graphs, consider using JSON. + + ) + } + + + + + + + ); +} diff --git a/src/pages/answer/leftDrawer/LeftDrawer.jsx b/src/pages/answer/leftDrawer/LeftDrawer.jsx index e9ee883a..b2a73c4d 100644 --- a/src/pages/answer/leftDrawer/LeftDrawer.jsx +++ b/src/pages/answer/leftDrawer/LeftDrawer.jsx @@ -1,5 +1,4 @@ import React, { useState } from 'react'; -import { useRouteMatch } from 'react-router-dom'; import Drawer from '@material-ui/core/Drawer'; import Toolbar from '@material-ui/core/Toolbar'; import List from '@material-ui/core/List'; @@ -9,14 +8,11 @@ import ListItemText from '@material-ui/core/ListItemText'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; -import { useAuth0 } from '@auth0/auth0-react'; - -import CloudUploadIcon from '@material-ui/icons/CloudUpload'; import PublishIcon from '@material-ui/icons/Publish'; import GetAppIcon from '@material-ui/icons/GetApp'; -import HighlightOffIcon from '@material-ui/icons/HighlightOff'; import ConfirmDialog from '~/components/ConfirmDialog'; +import DownloadDialog from '~/components/DownloadDialog'; import './leftDrawer.css'; @@ -31,30 +27,15 @@ import './leftDrawer.css'; * @param {boolean} owned - does the user own this answer */ export default function LeftDrawer({ - onUpload, displayState, updateDisplayState, message, - saveAnswer, deleteAnswer, owned, + onUpload, displayState, updateDisplayState, message, deleteAnswer, }) { - const { isAuthenticated } = useAuth0(); - const urlHasAnswerId = useRouteMatch('/answer/:answer_id'); const [confirmOpen, setConfirmOpen] = useState(false); + const [downloadOpen, setDownloadOpen] = useState(false); function toggleDisplay(component, show) { updateDisplayState({ type: 'toggle', payload: { component, show } }); } - /** - * Download the current message - */ - async function download() { - const blob = new Blob([JSON.stringify({ message }, null, 2)], { type: 'application/json' }); - const a = document.createElement('a'); - a.download = 'ROBOKOP_message.json'; - a.href = window.URL.createObjectURL(blob); - document.body.appendChild(a); - a.click(); - a.remove(); - } - return ( { setDownloadOpen(true); }} > onUpload(e)} /> - - - - - - - - - setConfirmOpen(true)} - > - - - - - - - + ); } diff --git a/src/pages/explore/DrugDiseasePairs.jsx b/src/pages/explore/DrugDiseasePairs.jsx index 7d0f0211..06cc4dbb 100644 --- a/src/pages/explore/DrugDiseasePairs.jsx +++ b/src/pages/explore/DrugDiseasePairs.jsx @@ -38,12 +38,12 @@ export default function DrugDiseasePairs() { query_graph: { nodes: { n0: { - name: pair.disease.name, - ids: [pair.disease.id], + name: pair.disease_name, + ids: [pair.disease_id], }, n1: { - name: pair.drug.name, - ids: [pair.drug.id], + name: pair.drug_name, + ids: [pair.drug_id], }, }, edges: {