diff --git a/frontend/src/App.css b/frontend/src/App.css index 75c518f..7897306 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -30,6 +30,7 @@ html { color: rgba(12, 16, 64, 0.606); font-size: 16px; font-variant-caps: all-petite-caps; + margin-top: 16px; } .modeVariants { @@ -1101,6 +1102,10 @@ h5 { padding: 2px; } + .ReactModal__Overlay{ + z-index: 3; + } + .filters { padding: 4px; cursor: pointer; diff --git a/frontend/src/components/Analyses/AnalysesResults.js b/frontend/src/components/Analyses/AnalysesResults.js new file mode 100644 index 0000000..2445645 --- /dev/null +++ b/frontend/src/components/Analyses/AnalysesResults.js @@ -0,0 +1,477 @@ +import '../Individuals/Individuals.css' +import '../../App.css' +import TableResultsAnalyses from '../Results/AnalysesResults/TableResultsAnalyses' +import { useState, useEffect } from 'react' +import axios from 'axios' +import { AuthContext } from '../context/AuthContext' +import { useAuth } from 'oidc-react' +import configData from '../../config.json' +import { useContext } from 'react' + +function AnalysesResults (props) { + const [showLayout, setShowLayout] = useState(false) + + const [beaconsList, setBeaconsList] = useState([]) + + const [error, setError] = useState(false) + + const [numberResults, setNumberResults] = useState(0) + const [boolean, setBoolean] = useState(false) + const [results, setResults] = useState([]) + const [show1, setShow1] = useState(false) + const [show2, setShow2] = useState(false) + const [show3, setShow3] = useState(false) + + const [resultsPerDataset, setResultsDataset] = useState([]) + const [resultsNotPerDataset, setResultsNotPerDataset] = useState([]) + + const [timeOut, setTimeOut] = useState(false) + + const [logInRequired, setLoginRequired] = useState(false) + + const [messageLoginFullResp, setMessageLoginFullResp] = useState('') + + const [limit, setLimit] = useState(0) + const [skip, setSkip] = useState(0) + + const [skipTrigger, setSkipTrigger] = useState(0) + const [limitTrigger, setLimitTrigger] = useState(0) + + const [queryArray, setQueryArray] = useState([]) + const [arrayFilter, setArrayFilter] = useState([]) + + const { getStoredToken, authenticateUser } = useContext(AuthContext) + let queryStringTerm = '' + + let res = '' + + const auth = useAuth() + let isAuthenticated = auth.userData?.id_token ? true : false + + useEffect(() => { + const apiCall = async () => { + if (isAuthenticated === false) { + authenticateUser() + const token = getStoredToken() + + if (token !== 'undefined' && token !== null) { + isAuthenticated = true + } + } + + if (props.query !== null) { + if (props.query.includes(',')) { + queryStringTerm = props.query.split(',') + queryStringTerm.forEach((element, index) => { + element = element.trim() + if ( + element.includes('=') || + element.includes('>') || + element.includes('<') || + element.includes('!') || + element.includes('%') + ) { + if (element.includes('=')) { + queryArray[index] = element.split('=') + queryArray[index].push('=') + } else if (element.includes('>')) { + queryArray[index] = element.split('>') + queryArray[index].push('>') + } else if (element.includes('<')) { + queryArray[index] = element.split('<') + queryArray[index].push('<') + } else if (element.includes('!')) { + queryArray[index] = element.split('!') + queryArray[index].push('!') + } else { + queryArray[index] = element.split('%') + queryArray[index].push('%') + } + const alphaNumFilter = { + id: queryArray[index][0], + operator: queryArray[index][2], + value: queryArray[index][1] + } + arrayFilter.push(alphaNumFilter) + } else { + const filter2 = { + id: element, + includeDescendantTerms: props.descendantTerm + } + arrayFilter.push(filter2) + } + }) + } else { + if ( + props.query.includes('=') || + props.query.includes('>') || + props.query.includes('<') || + props.query.includes('!') || + props.query.includes('%') + ) { + if (props.query.includes('=')) { + queryArray[0] = props.query.split('=') + queryArray[0].push('=') + } else if (props.query.includes('>')) { + queryArray[0] = props.query.split('>') + queryArray[0].push('>') + } else if (props.query.includes('<')) { + queryArray[0] = props.query.split('<') + queryArray[0].push('<') + } else if (props.query.includes('!')) { + queryArray[0] = props.query.split('!') + queryArray[0].push('!') + } else { + queryArray[0] = props.query.split('%') + queryArray[0].push('%') + } + + const alphaNumFilter = { + id: queryArray[0][0], + operator: queryArray[0][2], + value: queryArray[0][1] + } + arrayFilter.push(alphaNumFilter) + } else { + const filter = { + id: props.query + } + arrayFilter.push(filter) + } + } + } + + try { + let res = await axios.get(configData.API_URL + '/info') + + res.data.responses.forEach(element => { + beaconsList.push(element) + }) + + beaconsList.reverse() + + if (props.query === null) { + // show all individuals + + var jsonData1 = { + meta: { + apiVersion: '2.0' + }, + query: { + filters: arrayFilter, + includeResultsetResponses: `${props.resultSets}`, + pagination: { + skip: 0, + limit: 0 + }, + testMode: false, + requestedGranularity: 'record' + } + } + jsonData1 = JSON.stringify(jsonData1) + + let token = null + if (auth.userData === null) { + token = getStoredToken() + } else { + token = auth.userData.access_token + } + + if (token === null) { + res = await axios.post( + configData.API_URL + '/analyses', + jsonData1 + ) + } else { + const headers = { Authorization: `Bearer ${token}` } + + res = await axios.post( + configData.API_URL + '/analyses', + jsonData1, + { headers: headers } + ) + } + setTimeOut(true) + + if ( + res.data.responseSummary.numTotalResults < 1 || + res.data.responseSummary.numTotalResults === undefined + ) { + setError('ERROR. Please check the query and retry') + setNumberResults(0) + setBoolean(false) + } else { + res.data.response.resultSets.forEach((element, index) => { + if (element.id && element.id !== '') { + if (resultsPerDataset.length > 0) { + console.log(resultsPerDataset) + resultsPerDataset.forEach(element2 => { + if (element2[0] === element.beaconId) { + element2[1].push(element.id) + element2[2].push(element.exists) + element2[3].push(element.resultsCount) + } else { + let arrayResultsPerDataset = [ + element.beaconId, + [element.id], + [element.exists], + [element.resultsCount] + ] + resultsPerDataset.push(arrayResultsPerDataset) + } + }) + } else { + let arrayResultsPerDataset = [ + element.beaconId, + [element.id], + [element.exists], + [element.resultsCount] + ] + resultsPerDataset.push(arrayResultsPerDataset) + } + } + + if (element.id === undefined || element.id === '') { + let arrayResultsNoDatasets = [element.beaconId] + resultsNotPerDataset.push(arrayResultsNoDatasets) + } + + if (res.data.response.resultSets[index].results) { + res.data.response.resultSets[index].results.forEach( + (element2, index2) => { + let arrayResult = [ + res.data.response.resultSets[index].beaconId, + res.data.response.resultSets[index].results[index2] + ] + results.push(arrayResult) + } + ) + } + }) + } + } else { + var jsonData2 = { + meta: { + apiVersion: '2.0' + }, + query: { + filters: arrayFilter, + includeResultsetResponses: `${props.resultSets}`, + pagination: { + skip: skip, + limit: limit + }, + testMode: false, + requestedGranularity: 'record' + } + } + jsonData2 = JSON.stringify(jsonData2) + let token = null + if (auth.userData === null) { + token = getStoredToken() + } else { + token = auth.userData.access_token + } + + if (token === null) { + console.log('Querying without token') + res = await axios.post( + configData.API_URL + '/analyses', + jsonData2 + ) + } else { + console.log('Querying WITH token') + const headers = { Authorization: `Bearer ${token}` } + + res = await axios.post( + configData.API_URL + '/analyses', + jsonData2, + { headers: headers } + ) + } + setTimeOut(true) + + if ( + res.data.responseSummary.numTotalResults < 1 || + res.data.responseSummary.numTotalResults === undefined + ) { + setError('ERROR. Please check the query and retry') + setNumberResults(0) + setBoolean(false) + } else { + res.data.response.resultSets.forEach((element, index) => { + console.log(res.data.response) + if (element.id && element.id !== '') { + console.log(resultsPerDataset) + if (resultsPerDataset.length > 0) { + resultsPerDataset.forEach(element2 => { + console.log(element2[0]) + console.log(element.beaconId) + if (element2[0] === element.beaconId) { + element2[1].push(element.id) + element2[2].push(element.exists) + element2[3].push(element.resultsCount) + } else { + console.log('hola') + + let arrayResultsPerDataset = [ + element.beaconId, + [element.id], + [element.exists], + [element.resultsCount] + ] + let found = false + + console.log(arrayResultsPerDataset) + resultsPerDataset.forEach(element => { + if (element[0] === arrayResultsPerDataset[0]) { + found = true + } + console.log(found) + }) + if (found === false) { + resultsPerDataset.push(arrayResultsPerDataset) + } + } + }) + } else { + let arrayResultsPerDataset = [ + element.beaconId, + [element.id], + [element.exists], + [element.resultsCount] + ] + console.log(arrayResultsPerDataset) + resultsPerDataset.push(arrayResultsPerDataset) + } + } + + if (element.id === undefined || element.id === '') { + let arrayResultsNoDatasets = [element.beaconId] + resultsNotPerDataset.push(arrayResultsNoDatasets) + } + + if (res.data.response.resultSets[index].results) { + res.data.response.resultSets[index].results.forEach( + (element2, index2) => { + let arrayResult = [ + res.data.response.resultSets[index].beaconId, + res.data.response.resultSets[index].results[index2] + ] + results.push(arrayResult) + } + ) + } + }) + } + } + } catch (error) { + setError('No results. Please check the query and the connection and retry') + setTimeOut(true) + console.log(error) + } + } + apiCall() + }, []) + + const handleTypeResults1 = () => { + setShow1(true) + setShow2(false) + setShow3(false) + } + + const handleTypeResults2 = () => { + setShow2(true) + setShow1(false) + setShow3(false) + } + + const handleTypeResults3 = () => { + setShow3(true) + setShow1(false) + setShow2(false) + } + const onSubmit = () => { + setSkipTrigger(skip) + setLimitTrigger(limit) + setTimeOut(false) + } + return ( +
+ {timeOut === false && ( +
+
+
+
+
+
+
+
+
+ )} + +
+
+ {' '} + {timeOut && error !== 'Connection error. Please retry' && ( +
+
+

Granularity:

+ + + +
+
+ )} + {timeOut && error === 'Connection error. Please retry' && ( +

  {error}

+ )} + {show3 && logInRequired === false && !error && ( +
+ +
+ )} + + {show3 && error &&

  {error}

} + {show2 && !error && ( +
+ +
+ )} + {show1 && !error && ( +
+ +
+ )} + {show2 && error &&

  {error}

} + {show1 && error &&

  {error}

} +
+
+
+ ) +} + +export default AnalysesResults diff --git a/frontend/src/components/Biosamples/BiosamplesResults.js b/frontend/src/components/Biosamples/BiosamplesResults.js index c9272ea..3ca7df6 100644 --- a/frontend/src/components/Biosamples/BiosamplesResults.js +++ b/frontend/src/components/Biosamples/BiosamplesResults.js @@ -8,7 +8,6 @@ import { useAuth } from 'oidc-react' import configData from '../../config.json' import { useContext } from 'react' - function BiosamplesResults (props) { const [showLayout, setShowLayout] = useState(false) @@ -29,7 +28,7 @@ function BiosamplesResults (props) { const [timeOut, setTimeOut] = useState(false) const [logInRequired, setLoginRequired] = useState(false) - + const [messageLoginFullResp, setMessageLoginFullResp] = useState('') const [limit, setLimit] = useState(0) @@ -203,7 +202,6 @@ function BiosamplesResults (props) { setBoolean(false) } else { res.data.response.resultSets.forEach((element, index) => { - if (element.id && element.id !== '') { if (resultsPerDataset.length > 0) { console.log(resultsPerDataset) @@ -213,7 +211,6 @@ function BiosamplesResults (props) { element2[2].push(element.exists) element2[3].push(element.resultsCount) } else { - let arrayResultsPerDataset = [ element.beaconId, [element.id], @@ -447,7 +444,7 @@ function BiosamplesResults (props) { )} {show3 && logInRequired === true &&

{messageLoginFullResp}

} {show3 && error &&

  {error}

} - {show2 && ( + {show2 && !error && (
)} - {show1 && ( + {show1 && !error && (
)} + {show2 && error &&

  {error}

} + {show1 && error &&

  {error}

} ) } -export default BiosamplesResults \ No newline at end of file +export default BiosamplesResults diff --git a/frontend/src/components/Cohorts/Cohorts.css b/frontend/src/components/Cohorts/Cohorts.css index 75fde08..6199fdf 100644 --- a/frontend/src/components/Cohorts/Cohorts.css +++ b/frontend/src/components/Cohorts/Cohorts.css @@ -107,107 +107,6 @@ align-items: center; } -.tab-content { - display: none; -} - -.tab:target .tab-content, -.tab:last-of-type .tab-content { - display: block; -} - -.tab:target ~ .tab:last-of-type .tab-content { - display: none; -} - -.tabs * { - box-sizing: border-box; -} - -.tab-container { - position: relative; - padding-top: var(--tabs-height); /* en esta zona colocaremos las pestañas */ - margin-left: 40px; - margin-right: 40px; - margin-top: 0px; -} -#tab1 > a { - --tabs-position: 0; -} -#tab2 > a { - --tabs-position: 1; -} -#tab3 > a { - --tabs-position: 2; -} -#tab4 > a { - --tabs-position: 3; -} -#tab5 > a { - --tabs-position: 4; -} -#tab6 > a { - --tabs-position: 5; -} -#tab7 > a { - --tabs-position: 6; -} -#tab8 > a { - --tabs-position: 7; -} -#tab9 > a { - --tabs-position: 8; -} -.tab > a { - text-align: center; - position: absolute; - width: calc(var(--tabs-width)); - height: calc(var(--tabs-height) + var(--tabs-border-size)); - top: 0; - left: calc( - var(--tabs-width) * var(--tabs-position) - ); /* posición de cada pestaña */ -} -:root { - --tabs-border-color: #abcdef; - --tabs-border-size: 3px; - --tabs-text-color: white; - --tabs-dark-color: #2768aa; - --tabs-lite-color: #adafc2; - --tabs-width: 150px; - --tabs-height: 60px; - font-size: 14px; - margin: 10px; -} -.tabs { - width: 100vw; - color: var(--tabs-text-color); -} -.tab-content { - background-color: var(--tabs-lite-color); - padding: 20px; - border: var(--tabs-border-size) solid var(--tabs-border-color); - border-radius: 0 0 10px 10px; - position: relative; - z-index: 100; -} -.tab > a { - background-color: var(--tabs-dark-color); - padding: 10px; - border: var(--tabs-border-size) solid var(--tabs-border-color); - border-radius: 10px 10px 0 0; - border-bottom: 0; -} -.tab:target > a, -.tab:last-of-type > a { - background-color: var(--tabs-lite-color); - z-index: 200; -} -.tab:target ~ .tab:last-of-type > a { - background-color: var(--tabs-dark-color); - z-index: 0; -} - h2, p { margin: 0; diff --git a/frontend/src/components/Cohorts/Cohorts.js b/frontend/src/components/Cohorts/Cohorts.js index 8f27fbc..785bfb9 100644 --- a/frontend/src/components/Cohorts/Cohorts.js +++ b/frontend/src/components/Cohorts/Cohorts.js @@ -5,6 +5,7 @@ import { useState, useEffect } from 'react' import Layout from '../Layout/Layout' import { NavLink, useNavigate } from 'react-router-dom' import configData from '../../config.json' +import CohortsModule from './CohortsModule' function Cohorts (props) { const API_ENDPOINT = configData.API_URL + '/cohorts' @@ -58,8 +59,11 @@ function Cohorts (props) { const [trigger, setTrigger] = useState(false) + const [trigger2, setTrigger2] = useState(false) const [noCollectionEvents, setNoCollectionEvents] = useState(false) + const [alreadySelectedCohort, setAlreadySelectedCohort] = useState(true) + //const handleSelectedFilter = e => { //setSelectedFilter(e.target.value) //} @@ -69,29 +73,33 @@ function Cohorts (props) { } useEffect(() => { - const fetchDataCohorts = async () => { - try { - let res = await axios.get(configData.API_URL + '/cohorts') - console.log(res) - res.data.response.collections.forEach(element => { - let obj = { - value: element.id, - label: element.id - } - optionsCohorts.push(obj) - arrayCohorts.push(element) - const timer = setTimeout(() => { - setTriggerLayout(true) - }, 2000) - return () => clearTimeout(timer) - }) - } catch (error) { - setTimeOut(true) - console.log(error) - setError('Unexpected error. Please retry') + if (!props.newSearch) { + const fetchDataCohorts = async () => { + try { + let res = await axios.get(configData.API_URL + '/cohorts') + console.log(res) + res.data.response.collections.forEach(element => { + let obj = { + value: element.id, + label: element.id + } + optionsCohorts.push(obj) + arrayCohorts.push(element) + const timer = setTimeout(() => { + setTriggerLayout(true) + }, 2000) + return () => clearTimeout(timer) + }) + } catch (error) { + setTimeOut(true) + console.log(error) + setError('Unexpected error. Please retry') + } } + fetchDataCohorts().catch(console.error) + } else { + setTimeOut(true) } - fetchDataCohorts().catch(console.error) }, []) useEffect(() => { @@ -528,7 +536,7 @@ function Cohorts (props) { if (selectedCohorts) { apiCall() } - }, [showGraphs, trigger]) + }, [showGraphs, trigger, trigger2]) return (
@@ -566,8 +574,132 @@ function Cohorts (props) { {error !== '' && {error}} - {trigger && !noCollectionEvents && ( + {trigger && trigger2 && !noCollectionEvents && showGraphs && ( + <> + + {nameCohort !== '' &&

{nameCohort}

} + {showGraphs === true && ( +
+
+
+
+
+ {/*
+ + + + + + +
*/} + + {/* {showEthFiltered && ( +
+
+
+ )} + {showEthFiltered2 && ( +
+
+
+ )} */} +
+
+
+
+ {/*
+ + + + + +
+ + {showDisFiltered && ( +
+
+
+ )} + {showDisFiltered2 && ( +
+
+
+ )} */} +
+
+
+ )} + + )} + {trigger && !trigger2 && !noCollectionEvents && showGraphs && ( <> + {nameCohort !== '' &&

{nameCohort}

} {showGraphs === true && (
@@ -669,8 +801,8 @@ function Cohorts (props) { )} - {trigger && noCollectionEvents && ( - NO GRAPHICS AVAILABLE FOR THE SELECTED COHORTS + {trigger && noCollectionEvents && showGraphs && ( + NO GRAPHICS AVAILABLE FOR THE SELECTED COHORT )} {showGraphs === true && dataAvailable === false && timeOut === true && (
diff --git a/frontend/src/components/Cohorts/CohortsModule.js b/frontend/src/components/Cohorts/CohortsModule.js index 2dbe074..46fe51d 100644 --- a/frontend/src/components/Cohorts/CohortsModule.js +++ b/frontend/src/components/Cohorts/CohortsModule.js @@ -3,24 +3,33 @@ import './Cohorts.css' import React, { useState, useEffect } from 'react' import Select from 'react-select' import makeAnimated from 'react-select/animated' +import Cohorts from './Cohorts' function CohortsModule (props) { const [results, setResults] = useState(null) const animatedComponents = makeAnimated() const [selected, setSelected] = useState(null) + + const [trigger, setTrigger] = useState(false) + const [newSearch, setNewSearch] = useState(true) + const onSubmitCohorts = () => { setResults('Cohorts') - props.setShowGraphs(true) } const handleChangeCohorts = selectedOption => { console.log(selectedOption) setSelected(selectedOption) - props.setSelectedCohorts(selectedOption) } + const handleSearchAgain = () => { + setTrigger(true) + props.setResponse('') + props.setTrigger2(!props.trigger2) + } + return (