diff --git a/frontend/.env b/frontend/.env index 82865a7c..c3825651 100644 --- a/frontend/.env +++ b/frontend/.env @@ -1,5 +1,5 @@ REACT_APP_CLIENT_ID='9db950db-31d8-4966-9f35-e8222d2fdcf6' -REACT_APP_CLIENT_SECRET='3fcedd8c-06cf-48a6-812e-d7c63154ec729c4f1734-4a67-4d17-a9a9-b3a7694f9063' +REACT_APP_CLIENT_SECRET='c1422e87-a545-4178-bcaa-5b7baf59f72b11d4dd3c-4d5e-4358-9aff-c654a7924335' REACT_APP_KEYCLOAK_CLIENT_SECRET='b26ca0f9-1137-4bee-b453-ee51eefbe7ba' REACT_APP_KEYCLOAK_CLIENT_ID='beacon' REACT_APP_KEYCLOAK_CLIENT_REALM='Beacon' \ No newline at end of file diff --git a/frontend/public/eraser.png b/frontend/public/eraser.png new file mode 100644 index 00000000..df2d564b Binary files /dev/null and b/frontend/public/eraser.png differ diff --git a/frontend/public/horizonEuropeLogo.png b/frontend/public/horizonEuropeLogo.png new file mode 100644 index 00000000..b55a8868 Binary files /dev/null and b/frontend/public/horizonEuropeLogo.png differ diff --git a/frontend/public/magnifier.png b/frontend/public/magnifier.png index 3e2f37bb..300fd945 100644 Binary files a/frontend/public/magnifier.png and b/frontend/public/magnifier.png differ diff --git a/frontend/src/App.css b/frontend/src/App.css index 4b01fe3e..749534a5 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -60,6 +60,13 @@ html { margin-top: 8px; } +.buttonsDiv { + height: 93px; + display: flex; + flex-direction: column; + justify-content: space-around; +} + .containerExtraSections2 { display: flex; flex-direction: column; @@ -84,10 +91,10 @@ html { } .version { - margin-right: 37px; + margin-right: 28px; margin-top: -18px; color: #3176b1 !important; - font-weight: 700 !important; + font-weight: 600 !important; } .logosVersionContainer { @@ -100,12 +107,42 @@ html { } .searchButton { - padding-right: 4px; - padding-left: 0px; cursor: pointer; margin-left: 12px; border: none; + border-radius: 100px; + background: #3176b1; + padding: 10px, 24px, 10px, 16px; + color: white; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-size: 14px; + display: flex; + font-weight: 500; + width: 99px; + height: 40px; + justify-content: space-evenly; + align-items: center; +} + +.clearButton { + cursor: pointer; + margin-left: 12px; + border: none; + border-radius: 100px; background: white; + padding: 10px, 24px, 10px, 16px; + color: #3176b1; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-size: 14px; + display: flex; + font-weight: 500; + width: 99px; + height: 40px; + justify-content: space-evenly; + align-items: center; + border: 1px solid #3176b1; } .scopeDiv { @@ -396,12 +433,12 @@ p a { } .searchIcon { - width: 31px; - margin-top: -1px; + width: 13px; + margin-right: -2px; } -.searchIcon:hover { - width: 33px; - margin-top: -3px; +.clearIcon { + width: 15px; + margin-right: -2px; } .forwardIcon { @@ -697,7 +734,8 @@ p a { .container2 { width: 100vw; display: flex; - margin-bottom: 40px; + margin-bottom: 18px; + margin-top: 10px; } .NavlinkVerifier { @@ -775,8 +813,8 @@ p a { transition: 0.2s ease-in-out; } -.eosc4cancer { - height: 86px; +.ega-logo { + height: 46px; margin-top: 30px; margin-bottom: 5px; margin-right: 35px; @@ -788,7 +826,7 @@ p a { .eosc4cancer, .by-covid-logo, -.eosc4cancer:hover { +.ega-logo:hover { -webkit-filter: grayscale(0%); filter: grayscale(0%); } @@ -839,15 +877,37 @@ p a { } .laCaixaLogo { - height: 33px; - margin-top: 42px; + height: 35px; + margin-top: 34px; margin-right: 30px; - -webkit-filter: grayscale(20%); - filter: grayscale(100%); - -webkit-transition: 0.2s ease-in-out; + filter: grayscale(40%); + transition: 0.2s ease-in-out; +} +.horizonEuropeLogo { + height: 30px; + margin-right: 10px; + filter: grayscale(40%); + transition: 0.2s ease-in-out; +} + +.elixirLogo { + margin-bottom: -13px; + height: 58px; + margin-right: 10px; + filter: grayscale(40%); transition: 0.2s ease-in-out; } +.elixirLogo:hover { + -webkit-filter: grayscale(0%); + filter: grayscale(0%); +} + +.horizonEuropeLogo:hover { + -webkit-filter: grayscale(0%); + filter: grayscale(0%); +} + .laCaixaLogo:hover { -webkit-filter: grayscale(0%); filter: grayscale(0%); @@ -1416,6 +1476,12 @@ h5 { text-underline-offset: 1px; } + .buttonsDiv { + display: flex; + flex-direction: column; + justify-content: space-around; + } + .crossQueriesTittle { margin-bottom: 12px; font-size: 12px; @@ -1471,7 +1537,7 @@ h5 { -webkit-transition: 0.2s ease-in-out; transition: 0.2s ease-in-out; } - .eosc4cancer { + .ega-logo { height: 36px; margin-top: 20px; margin-right: 30px; @@ -1512,8 +1578,8 @@ h5 { } .laCaixaLogo { - height: 31px; - margin-top: 31px; + height: 33px; + margin-top: 33px; margin-right: 30px; -webkit-filter: grayscale(100%); filter: grayscale(100%); @@ -1533,10 +1599,6 @@ h5 { box-shadow: rgb(234 221 221 / 16%) 0px 1px 4px; } - .container2 { - margin-bottom: 0px; - } - .exampleQuery { width: 100%; border: none; @@ -1692,28 +1754,6 @@ h5 { 'Helvetica Neue', sans-serif; text-transform: uppercase; } - .searchIcon { - width: 26px; - margin-top: -1px; - margin-left: -8px; - } - .searchIcon:hover { - width: 27px; - margin-top: -1px; - margin-left: -8px; - } - - .elixirLogo { - height: 70px; - margin-top: 18px; - margin-bottom: 37px; - margin-right: 21px; - } - - .searchButton { - height: 30px; - cursor: pointer; - } .examplesQueriesList { display: flex; @@ -1756,6 +1796,40 @@ h5 { text-underline-offset: 1px; } + .IdForm{ + font-size: 12px; + } + .selectedOperator { + background: white; + border: 1px solid rgb(143 147 196 / 61%); + /* border: 1px solid rgba(12, 16, 64, 0.606); */ + font-size: 12px; + border-radius: 4px; + width: 33px; + height: 27px; + /* margin-right: 20px; */ + box-shadow: 1px 2px 2px #cecece; + } + .ValueForm{ + font-size: 12px; + } + #operator { + display: flex; + flex-direction: column; + align-content: center; + justify-content: center; + align-items: center; + /* margin-top: -40px; */ + width: 46px; + } + + .buttonsDiv { + margin-top: 7px; + display: flex; + flex-direction: column; + justify-content: space-around; + height: 151px; + } .crossQueriesTittle { margin-bottom: 12px; font-size: 12px; @@ -1812,8 +1886,8 @@ h5 { transition: 0.2s ease-in-out; } - .eosc4cancer { - height: 68px; + .ega-logo { + height: 36px; margin-top: 20px; margin-right: 30px; -webkit-filter: grayscale(20%); @@ -1873,10 +1947,6 @@ h5 { box-shadow: rgb(234 221 221 / 16%) 0px 1px 4px; } - .container2 { - margin-bottom: 0px; - } - .exampleQuery { width: 100%; border: none; @@ -2049,28 +2119,6 @@ h5 { 'Helvetica Neue', sans-serif; text-transform: uppercase; } - .searchIcon { - width: 26px; - margin-top: -1px; - margin-left: -8px; - } - .searchIcon:hover { - width: 27px; - margin-top: -1px; - margin-left: -8px; - } - - .elixirLogo { - height: 70px; - margin-top: 18px; - margin-bottom: 37px; - margin-right: 21px; - } - - .searchButton { - height: 30px; - cursor: pointer; - } .examplesQueriesList { display: flex; diff --git a/frontend/src/components/Biosamples/BiosamplesResults.js b/frontend/src/components/Biosamples/BiosamplesResults.js index 5347cb6c..5ccbcd93 100644 --- a/frontend/src/components/Biosamples/BiosamplesResults.js +++ b/frontend/src/components/Biosamples/BiosamplesResults.js @@ -316,7 +316,10 @@ function BiosamplesResults (props) { queryArray[index].push('!') } else { queryArray[index] = term.split('%') - queryArray[index].push('%') + + queryArray[index][1] = '%' + queryArray[index][1] + '%' + + queryArray[index].push('=') } let alphanumericFilter = {} @@ -329,7 +332,7 @@ function BiosamplesResults (props) { if (queryArray[index][0].toLowerCase() === 'individual') { alphanumericFilter = { id: element.id, - scope: ['individual'] + scope: ['individuals'] } } else if ( queryArray[index][0].toLowerCase() === 'genomicvariation' @@ -465,7 +468,11 @@ function BiosamplesResults (props) { datasetList.push(res2.data.response.collections) } - if (updatedArrayFilterVar.length === 0) { + if (updatedArrayFilterVar.length === 0 && props.isNetwork === true) { + res.data.responses.forEach(element => { + beaconsList.push(element) + }) + } else if (updatedArrayFilterVar.length === 0 && props.isNetwork === false){ beaconsList.push(res.data.response) } @@ -473,7 +480,6 @@ function BiosamplesResults (props) { if (props.query === null || props.query === '') { // show all individuals - let jsonData1 = {} if (arrayRequestParameters.length > 0) { @@ -528,7 +534,9 @@ function BiosamplesResults (props) { configData.API_URL + '/biosamples', jsonData1 ) + } else { + const headers = { Authorization: `Bearer ${token}` } console.log('querying with token') res = await axios.post( @@ -719,6 +727,7 @@ function BiosamplesResults (props) { } setTriggerSubmit(true) } else { + let jsonData2 = {} variablePause = false @@ -856,14 +865,16 @@ function BiosamplesResults (props) { token = auth.userData.access_token } if (token === null) { + console.log('Querying without token') res = await axios.post( configData.API_URL + '/biosamples', jsonData2 ) + } else { console.log('Querying WITH token') - + const headers = { Authorization: `Bearer ${token}` } res = await axios.post( @@ -871,6 +882,7 @@ function BiosamplesResults (props) { jsonData2, { headers: headers } ) + } setTimeOut(true) diff --git a/frontend/src/components/CrossQueries/CrossQueries.css b/frontend/src/components/CrossQueries/CrossQueries.css index 38715402..0a14b776 100644 --- a/frontend/src/components/CrossQueries/CrossQueries.css +++ b/frontend/src/components/CrossQueries/CrossQueries.css @@ -135,18 +135,7 @@ h5:hover { margin-left: 10px; margin-right: 10px; } - .inputSearch { - width: 70vw; - height: -moz-fit-content; - height: fit-content; - padding: 10px; - font-size: 14 px; - border: 1px solid #3176b1; - text-overflow: clip; - max-width: 80vw; - font-size: 13px; - border-radius: 3px; - } + .crossQueriesForm { padding: 34px; display: flex; diff --git a/frontend/src/components/Dataset/BeaconInfo.css b/frontend/src/components/Dataset/BeaconInfo.css index ca9c8df4..784d8339 100644 --- a/frontend/src/components/Dataset/BeaconInfo.css +++ b/frontend/src/components/Dataset/BeaconInfo.css @@ -69,7 +69,6 @@ p a:hover { .tittle2 h1 { font-size: 14px; font-weight: normal; - margin: 14px; color: #5d5454; } @@ -97,7 +96,7 @@ p a:hover { margin-bottom: -3px; } .tittle { - width: 40vw; + width: 36vw; background: #c8d4e6; border-radius: 2px; /* height: 80px; */ @@ -120,7 +119,6 @@ p a:hover { flex-direction: row; justify-content: center; align-items: center; - margin-bottom: 7px; } .descriptionBeacon a { @@ -166,7 +164,7 @@ p a:hover { } .datasetCard { - width: 40vw; + width: 36.7vw; margin: 30px; /* border: 2px solid #3b9ad5; */ @@ -212,12 +210,23 @@ p a:hover { } .datasetCard p { - font-size: 12px; font-weight: normal; color: rgb(61 60 60); line-height: 20px; margin-top: -5px; + width: 35vw; + text-align: justify; + height: 92px; + overflow-y: scroll; + font-size: 13px; + -ms-overflow-style: none; /* for Internet Explorer, Edge */ + scrollbar-width: none; +} + +.datasetCard p::-webkit-scrollbar { + display: none; /* for Chrome, Safari, and Opera */ } + .datasetCardResults p { font-size: 12px; font-weight: normal; @@ -229,7 +238,6 @@ p a:hover { .tittle2 h1 { font-size: 14px; font-weight: normal; - margin: 14px; color: #5d5454; } @@ -269,13 +277,15 @@ p a:hover { margin-bottom: -3px; } .tittle { - width: 38vw; + width: 36vw; background: #c8d4e6; border-radius: 2px; - /* height: 80px; */ + height: fit-content; display: flex; padding: 2px; flex-direction: column; + align-items: center; + justify-content: center; } .tittleResults { @@ -290,6 +300,12 @@ p a:hover { flex-direction: column; align-items: center; overflow-y: scroll; + -ms-overflow-style: none; /* for Internet Explorer, Edge */ + scrollbar-width: none; +} + +.tittleResults::-webkit-scrollbar { + display: none; /* for Chrome, Safari, and Opera */ } .seeResultsContainer { @@ -321,6 +337,8 @@ p a:hover { color: rgba(12, 16, 64, 0.606); font-size: 12px; font-weight: 600; + margin-bottom: 8px; + margin-top: 2px; } .tittleResults h2 { @@ -346,6 +364,7 @@ p a:hover { background: #c8d4e6; flex-wrap: wrap; align-items: center; + margin-top: 8px; } .tittle4 { @@ -368,10 +387,23 @@ p a:hover { } h5 { - margin-top: 0px !important; margin-bottom: 0px !important; } +h5 { + color: rgb(209, 66, 66); + font-weight: bold; + width: -moz-fit-content; + width: fit-content; + /* width: 150%; */ + margin-top: 26px; + margin-left: 40vw; + display: flex; + /* align-items: center; */ + justify-content: center; + font-size: 14px; +} + .resultsRecord { display: flex; flex-direction: row; @@ -446,7 +478,7 @@ h5 { } .tittle { height: 82px; - width: 44vw; + width: 40vw; background: #c8d4e6; border-radius: 2px; /* height: 80px; */ @@ -493,7 +525,6 @@ h5 { .tittle2 h1 { font-size: 11px; font-weight: normal; - margin: 14px; color: #5d5454; } } @@ -540,14 +571,16 @@ h5 { margin-top: 2px; } .datasetCard p { - font-size: 11px; font-weight: normal; color: rgb(61 60 60); - line-height: 18px; + line-height: 20px; margin-top: -5px; - font-size: 11px !important; + width: 52vw; + text-align: justify; + height: 150px; + overflow-y: scroll; + font-size: 13px; } - .datasetCard { width: 58vw; margin: 30px; @@ -612,7 +645,6 @@ h5 { font-weight: bold; /* margin: 14px; */ color: #5d5454; - margin: 7px; } } diff --git a/frontend/src/components/Dataset/BeaconInfo.js b/frontend/src/components/Dataset/BeaconInfo.js index 603e8738..090221e4 100644 --- a/frontend/src/components/Dataset/BeaconInfo.js +++ b/frontend/src/components/Dataset/BeaconInfo.js @@ -147,118 +147,122 @@ function BeaconInfo (props) {
{resp.map(result => { return ( -
-
-
- {result.response.organization.logoUrl !== '' && - result.response.name !== 'NAGENpediatrics Beacon' && ( - {result.meta.beaconId} - )} - {result.response.name === 'NAGENpediatrics Beacon' && ( - {result.meta.beaconId} + {result.response && ( +
+
+
+ {result.response.organization.logoUrl !== '' && + result.response.name !== 'NAGENpediatrics Beacon' && ( + {result.meta.beaconId} + )} + {result.response.name === 'NAGENpediatrics Beacon' && ( + {result.meta.beaconId} + )} +

{result.response.name}

+
+

{result.response.organization.name}

+
+
+ {!result.response.description.includes('{result.response.description}

+ )} + {result.response.description.includes('
)} -

{result.response.name}

+
+ {result.meta.beaconId === + 'org.ega-archive.ga4gh-approval-beacon-test' && ( + + Beacon API + + )} + {result.meta.beaconId === 'es.elixir.bsc.beacon' && ( + + Beacon API + + )} + {result.meta.beaconId === 'org.progenetix' && ( + + Beacon API + + )} + {result.meta.beaconId !== 'es.elixir.bsc.beacon' && + result.meta.beaconId !== 'org.progenetix' && + result.meta.beaconId !== + 'org.ega-archive.ga4gh-approval-beacon-test' && ( + + Beacon API + + )} + {result.meta.beaconId === 'es.elixir.bsc.beacon' && ( + + Visit us + + )} + {result.meta.beaconId !== 'es.elixir.bsc.beacon' && ( + + Visit us + + )} + {result.meta.beaconId !== 'es.elixir.bsc.beacon' && ( + + Contact us + + )} + {result.meta.beaconId === 'es.elixir.bsc.beacon' && ( + + Contact us + + )} +
-

{result.response.organization.name}

-
-
- {!result.response.description.includes('{result.response.description}

- )} - {result.response.description.includes('
)} -
- {result.meta.beaconId === - 'org.ega-archive.ga4gh-approval-beacon-test' && ( - - Beacon API - - )} - {result.meta.beaconId === 'es.elixir.bsc.beacon' && ( - - Beacon API - - )} - {result.meta.beaconId === 'org.progenetix' && ( - - Beacon API - - )} - {result.meta.beaconId !== 'es.elixir.bsc.beacon' && - result.meta.beaconId !== 'org.progenetix' && - result.meta.beaconId !== - 'org.ega-archive.ga4gh-approval-beacon-test' && ( - - Beacon API - - )} - {result.meta.beaconId === 'es.elixir.bsc.beacon' && ( - - Visit us - - )} - {result.meta.beaconId !== 'es.elixir.bsc.beacon' && ( - - Visit us - - )} - {result.meta.beaconId !== 'es.elixir.bsc.beacon' && ( - - Contact us - - )} - {result.meta.beaconId === 'es.elixir.bsc.beacon' && ( - - Contact us - - )} -
-
+ ) })}
diff --git a/frontend/src/components/FilteringTerms/FilteringTerms.css b/frontend/src/components/FilteringTerms/FilteringTerms.css index cfd1d05e..186db15e 100644 --- a/frontend/src/components/FilteringTerms/FilteringTerms.css +++ b/frontend/src/components/FilteringTerms/FilteringTerms.css @@ -24,6 +24,40 @@ rgba(197, 150, 150, 0.13) 0px 0px 1px 1px; } +.buttonPaginationFilters { + border: 1px solid #a8a8cc; + border-radius: 4px; + padding: 6px; + margin-right: 17px; + width: 80px; +} + +.buttonPaginationFilters:hover { + background-color: rgb(231 244 255); +} + +.buttonPaginationFiltersNext:hover { + background-color: rgb(231 244 255); +} + +.buttonPaginationFiltersNext { + border: 1px solid #a8a8cc; + border-radius: 4px; + padding: 6px; + margin-left: 17px; + width: 80px; +} + +.pagination { + font-size: 14px; +} + +.pagination span { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; +} + .inputTerm { display: flex; align-items: center; @@ -68,15 +102,16 @@ tbody { height: fit-content; flex-direction: column; margin-left: 1vw; + align-items: center; + padding-bottom: 20px !important; } .tableWrapper { - height: 100vh; - width: 85vw; - overflow: scroll; display: flex; - justify-content: center; + flex-direction: column; + align-items: center; + padding-bottom: 58px; } .generalContainer { @@ -201,13 +236,17 @@ tbody { /* height: 100%; */ /* justify-content: center; */ overflow-x: scroll; - overflow-y: scroll; - margin-bottom: -23px; padding-left: 30px; padding-top: 10px; padding-bottom: 10px; font-size: 13px; + -ms-overflow-style: none; /* for Internet Explorer, Edge */ + scrollbar-width: none; +} + +.th4::-webkit-scrollbar { + display: none; /* for Chrome, Safari, and Opera */ } .th5 { @@ -309,9 +348,111 @@ tr { } .tableWrapper { height: 100vh; - width: 95vw; - overflow: scroll; + + display: flex; + justify-content: center; + } +} + +@media (max-width: 750px) { + tbody { + width: 96vw !important; + } + .thead1 { + position: sticky; + top: 0px; + z-index: 2; + width: 97%; + } + .searchTermInput { + margin: 5px; + width: 70%; + height: 28px; + /* margin-left: 34px; */ + border: 1px solid #3176b1; + border-radius: 2px; + box-shadow: rgba(216, 207, 207, 0.25) 0px 1px 1px, + rgba(197, 150, 150, 0.13) 0px 0px 1px 1px; + } + .tableWrapper { + height: 100vh; display: flex; justify-content: center; + width: 100vw; + margin-top: 127px; + } +} + +@media (max-width: 500px) { + .searchTermInput1, + .searchTermInput { + width: 80%; + height: 23px; + margin-left: 4px; + border: 1px solid #3176b1; + border-radius: 2px; + box-shadow: rgba(216, 207, 207, 0.25) 0px 1px 1px, + rgba(197, 150, 150, 0.13) 0px 0px 1px 1px; + font-size: 10px; + } + .tableWrapper { + height: 100vh; + display: flex; + justify-content: center; + width: 100vw; + margin-top: 138px; + } + + .th2 { + display: flex; + width: 73%; + /* height: 100%; */ + /* justify-content: center; */ + margin-top: 12px; + margin-bottom: 12px; + padding-left: 10px; + padding-left: 0px; + padding-top: 10px; + overflow-x: auto; + padding-bottom: 10px; + align-items: center; + font-size: 11px; + } + .th4 { + display: flex; + width: 104%; + /* height: 100%; */ + /* justify-content: center; */ + overflow-x: scroll; + margin-bottom: -23px; + padding-left: 30px; + padding-top: 10px; + padding-bottom: 10px; + font-size: 11px; + -ms-overflow-style: none; /* for Internet Explorer, Edge */ + scrollbar-width: none; + } + + input[type='checkbox']:before { + content: '✓'; + font-size: 15px; + color: transparent !important; + background: #ffffff; + display: block; + width: 8px; + height: 8px; + border: 1.8px solid #3176b1; + margin-right: 1px; + } + #table { + display: flex; + font-size: 15px; + width: 99%; + height: -moz-fit-content; + height: fit-content; + flex-direction: column; + margin-left: 1vw; + align-items: center; + padding-bottom: 20px !important; } } diff --git a/frontend/src/components/FilteringTerms/FilteringTerms.js b/frontend/src/components/FilteringTerms/FilteringTerms.js index 68a02810..5c3f5395 100644 --- a/frontend/src/components/FilteringTerms/FilteringTerms.js +++ b/frontend/src/components/FilteringTerms/FilteringTerms.js @@ -24,6 +24,23 @@ function FilteringTerms (props) { list: props.filteringTerms !== undefined ? props.filteringTerms : 'error' }) + const [currentPage, setCurrentPage] = useState(1) + const itemsPerPage = 10 // Adjust the number of items per page + const indexOfLastItem = currentPage * itemsPerPage + const indexOfFirstItem = indexOfLastItem - itemsPerPage + const currentItems = state.list.slice(indexOfFirstItem, indexOfLastItem) + + // Handle pagination controls + const handlePreviousPage = () => { + setCurrentPage(prevPage => Math.max(prevPage - 1, 1)) + } + + const handleNextPage = () => { + setCurrentPage(prevPage => prevPage + 1) + } + + const totalPages = Math.ceil(state.list.length / itemsPerPage) + const [trigger, setTrigger] = useState(false) const [hide, setHide] = useState(true) @@ -72,12 +89,12 @@ function FilteringTerms (props) { const [valueChosen, setValueChosen] = useState([]) - const handdleInclude = e => { + const handleInclude = e => { if (ID !== '' && valueFree !== '' && operator !== '') { - if (props.query !== null) { + if (props.query !== null && props.query !== '') { props.setQuery(props.query + ',' + `${ID}${operator}${valueFree}`) } - if (props.query === null) { + if (props.query === null || props.query === '') { props.setQuery(`${ID}${operator}${valueFree}`) } } @@ -100,17 +117,20 @@ function FilteringTerms (props) { state.list.forEach((element, index) => { if (element.scopes.length > 1) { - element.scopes.forEach(element2 => { - let arrayNew = {} - arrayNew = { ...element } - - arrayNew['scopes'] = [element2] - + element.scopes.forEach(scope => { + let arrayNew = { ...element } + arrayNew['scopes'] = [scope] state.list.push(arrayNew) }) + + // Mark the original element for deletion + element.toBeDeleted = true } }) + // Remove the original elements with multiple scopes + state.list = state.list.filter(element => !element.toBeDeleted) + setstate({ query: '', list: props.filteringTerms !== false ? state.list : 'error' @@ -324,61 +344,20 @@ function FilteringTerms (props) { removeTag={remove} /> - {!error && ( -
- - - - - - {hide === false && } - - - - - - - - - - - {hide === false && ( - +
+ {!error && ( +
+
termlabeltypescopes
-
- -
-
-
- -
-
+ + + + + {hide === false && } + + + + + - )} - { - + - } - - - {props.filteringTerms !== undefined && - state.list !== 'error' && - state.list.map((term, index) => { - return ( - <> - - {index % 2 === 0 && ( - - {term.type.toLowerCase() !== 'alphanumeric' && ( - - )} - {term.type.toLowerCase() === 'alphanumeric' && ( - - )} - {term.label !== '' ? ( - - ) : ( - - )} - - {hide === false && ( - - )} - - - - )} - {index % 2 == !0 && ( - - {term.type.toLowerCase() !== 'alphanumeric' && ( - + + + )} + { + + + + } + + + {props.filteringTerms !== undefined && + state.list !== 'error' && + currentItems.map((term, index) => { + return ( + <> + + {index % 2 === 0 && ( + + {term.type.toLowerCase() !== 'alphanumeric' && ( + + )} + {term.type.toLowerCase() === 'alphanumeric' && ( + + )} + {term.label !== '' ? ( + + ) : ( + + )} + + {hide === false && ( + + )} + + - )} - {term.type.toLowerCase() === 'alphanumeric' && ( - + )} + {index % 2 !== 0 && ( + + {term.type.toLowerCase() !== 'alphanumeric' && ( + + )} + {term.type.toLowerCase() === 'alphanumeric' && ( + + )} + {term.label !== '' ? ( + + ) : ( + + )} + + {hide === false && ( + + )} + + - )} - {term.label !== '' ? ( - - ) : ( - - )} - - {hide === false && ( - - )} + + )} - - - )} - - {index % 2 == !0 && - term.type.toLowerCase() === 'alphanumeric' && - valueChosen.includes(term.id) && ( - -
-
-
- - - - -
- + {index % 2 !== 0 && + term.type.toLowerCase() === 'alphanumeric' && + valueChosen.includes(term.id) && ( +
+
+
+
+ + + + +
+ +
+ + +
- - -
+
- - - - )} - {index % 2 === 0 && - term.type.toLowerCase() === 'alphanumeric' && - valueChosen.includes(term.id) && ( - -
-
-
- - - - -
- +
+ )} + {index % 2 === 0 && + term.type.toLowerCase() === 'alphanumeric' && + valueChosen.includes(term.id) && ( + +
+
+
+ + + + +
+ +
+ + +
- - -
+
- - - - )} - - - ) - })} -
termlabeltypescopes
-
+
-
+
- {' '} - - {term.id} - - {' '} - - {term.id} - {term.label}-{term.type} - {Array.isArray(term.scopes) && - term.scopes.map((term2, index) => { - return index < term.scopes.length - 1 - ? term2 + '' + ',' - : term2 + '' - })} -
- {' '} - - {term.id} + {hide === false && ( +
+
+ +
+
+
+ +
+
+ {' '} + + {term.id} + + {' '} + + {term.id} + {term.label}-{term.type} + {Array.isArray(term.scopes) && + term.scopes.map((term2, index) => { + return index < term.scopes.length - 1 + ? term2 + '' + ',' + : term2 + '' + })} - {' '} - - {term.id} +
+ {' '} + + {term.id} + + {' '} + + {term.id} + {term.label}-{term.type} + {Array.isArray(term.scopes) && + term.scopes.map((term2, index) => { + return index < term.scopes.length - 1 + ? term2 + '' + ',' + : term2 + '' + })} {term.label}-{term.type}
- {Array.isArray(term.scopes) && - term.scopes.map((term2, index) => { - return index < term.scopes.length - 1 - ? term2 + '' + ',' - : term2 + '' - })} -
-
- )} + + )} + + + ) + })} + + +
+ + + Page {currentPage} of {totalPages} + + +
+
+ )} + ) } diff --git a/frontend/src/components/GenomicVariations/VariantsResults.js b/frontend/src/components/GenomicVariations/VariantsResults.js index 2fadb262..f929091a 100644 --- a/frontend/src/components/GenomicVariations/VariantsResults.js +++ b/frontend/src/components/GenomicVariations/VariantsResults.js @@ -316,7 +316,10 @@ function VariantsResults (props) { queryArray[index].push('!') } else { queryArray[index] = term.split('%') - queryArray[index].push('%') + + queryArray[index][1] = '%' + queryArray[index][1] + '%' + + queryArray[index].push('=') } let alphanumericFilter = {} @@ -329,7 +332,7 @@ function VariantsResults (props) { if (queryArray[index][0].toLowerCase() === 'individual') { alphanumericFilter = { id: element.id, - scope: ['individual'] + scope: ['individuals'] } } else if ( queryArray[index][0].toLowerCase() === 'genomicvariation' @@ -465,7 +468,11 @@ function VariantsResults (props) { datasetList.push(res2.data.response.collections) } - if (updatedArrayFilterVar.length === 0) { + if (updatedArrayFilterVar.length === 0 && props.isNetwork === true) { + res.data.responses.forEach(element => { + beaconsList.push(element) + }) + } else if (updatedArrayFilterVar.length === 0 && props.isNetwork === false){ beaconsList.push(res.data.response) } @@ -473,7 +480,6 @@ function VariantsResults (props) { if (props.query === null || props.query === '') { // show all individuals - let jsonData1 = {} if (arrayRequestParameters.length > 0) { @@ -528,9 +534,11 @@ function VariantsResults (props) { configData.API_URL + '/g_variants', jsonData1 ) + } else { + const headers = { Authorization: `Bearer ${token}` } - console.log('querying with token') + res = await axios.post( configData.API_URL + '/g_variants', jsonData1, @@ -719,6 +727,7 @@ function VariantsResults (props) { } setTriggerSubmit(true) } else { + let jsonData2 = {} variablePause = false @@ -856,14 +865,15 @@ function VariantsResults (props) { token = auth.userData.access_token } if (token === null) { - console.log('Querying without token') + res = await axios.post( configData.API_URL + '/g_variants', jsonData2 ) + } else { console.log('Querying WITH token') - + const headers = { Authorization: `Bearer ${token}` } res = await axios.post( @@ -926,7 +936,6 @@ function VariantsResults (props) { if (element.id === undefined || element.id === '') { let arrayResultsNoDatasets = [element.beaconId] resultsNotPerDataset.push(arrayResultsNoDatasets) - console.log(arrayResultsNoDatasets) } if (res.data.response.resultSets[index].results) { diff --git a/frontend/src/components/Individuals/IndividualsResults.js b/frontend/src/components/Individuals/IndividualsResults.js index 6bba35b4..eb2aae15 100644 --- a/frontend/src/components/Individuals/IndividualsResults.js +++ b/frontend/src/components/Individuals/IndividualsResults.js @@ -80,10 +80,12 @@ function IndividualsResults (props) { const handleChangeScope = (event, idx) => { const value = event.target.value + setSelectedScopes(prevState => ({ ...prevState, [idx]: value })) + } const submitScopeChosen = () => { @@ -128,115 +130,6 @@ function IndividualsResults (props) { } var arrayRequestParameters = [] - // var requestParametersSequence = {} - - // var requestParametersRange = {} - - // var requestParametersGene = {} - - // if (props.seqModuleArray.length > 0) { - // props.seqModuleArray.forEach(element => { - // if (element.assemblyId !== '') { - // requestParametersSequence['assemblyId'] = element.assemblyId - // } - // if (element.referenceName !== '') { - // requestParametersSequence['referenceName'] = element.referenceName - // } - // if (element.start !== '') { - // requestParametersSequence['start'] = element.start - // } - // if (element.referenceBases !== '') { - // requestParametersSequence['referenceBases'] = element.referenceBases - // } - // if (element.alternateBases !== '') { - // requestParametersSequence['alternateBases'] = element.alternateBases - // } - // if (element.clinicalRelevance !== '') { - // requestParametersSequence['clinicalRelevance'] = - // element.clinicalRelevance - // } - - // arrayRequestParameters.push(requestParametersSequence) - // requestParametersSequence = {} - // }) - // } - - // if (props.rangeModuleArray.length > 0) { - // console.log(props.rangeModuleArray) - // props.rangeModuleArray.forEach(element => { - // if (element.assemblyId !== '') { - // requestParametersRange['assemblyId'] = element.assemblyId - // } - // if (element.referenceName !== '') { - // requestParametersRange['referenceName'] = element.referenceName - // } - // if (element.start !== '') { - // requestParametersRange['start'] = element.start - // } - // if (element.end !== '') { - // requestParametersRange['end'] = element.end - // } - // if (element.variantType !== '') { - // requestParametersRange['variantType'] = element.variantType - // } - // if (element.alternateBases !== '') { - // requestParametersRange['alternateBases'] = element.alternateBases - // } - - // if (element.referenceBases !== '') { - // requestParametersRange['referenceBases'] = element.referenceBases - // } - - // if (element.aminoacid !== '') { - // requestParametersRange['aminoacidChange'] = element.aminoacid - // } - // if (element.variantMinLength !== '') { - // requestParametersRange['variantMinLength'] = - // element.variantMinLength - // } - // if (element.variantMaxLength !== '') { - // requestParametersRange['variantMaxLength'] = - // element.variantMaxLength - // } - // if (element.clinicalRelevance !== '') { - // requestParametersSequence['clinicalRelevance'] = - // element.clinicalRelevance - // } - // arrayRequestParameters.push(requestParametersRange) - // requestParametersRange = {} - // }) - // } - - // if (props.geneModuleArray.length > 0) { - // props.geneModuleArray.forEach(element => { - // console.log(element) - // if (element.geneID !== '') { - // requestParametersGene['geneId'] = element.geneID - // } - // if (element.assemblyId !== '') { - // requestParametersGene['assemblyId'] = element.assemblyId - // } - // if (element.variantType !== '') { - // requestParametersGene['variantType'] = element.variantType - // } - // if (element.variantMinLength !== '') { - // requestParametersGene['variantMinLength'] = element.variantMinLength - // } - // if (element.variantMaxLength !== '') { - // requestParametersGene['variantMaxLength'] = element.variantMaxLength - // } - // if (element.aminoacid !== '') { - // requestParametersGene['aminoacidChange'] = element.aminoacid - // } - // if (element.clinicalRelevance !== '') { - // requestParametersSequence['clinicalRelevance'] = - // element.clinicalRelevance - // } - // arrayRequestParameters.push(requestParametersGene) - // requestParametersGene = {} - // }) - // } - var requestParameters = {} if (props.query !== null) { @@ -266,24 +159,41 @@ function IndividualsResults (props) { arrayRequestParameters.push(requestParameters) } } else if (props.query.includes(':') && props.query.includes('>')) { - let reqParameters = props.query.split(':') + // Split the query by '&' to separate different parts + let parts = props.query.split('&') - let position = [] - if (props.query.includes('-')) { - position = reqParameters[0].split('-') - } else { - position = reqParameters[0] - } + // Initialize an empty object for request parameters + let requestParameters = {} - let bases = reqParameters[2].split('>') + // Iterate over each part of the split query + parts.forEach(part => { + if (part.includes(':') && part.includes('>')) { + let reqParameters = part.split(':') + let position = [] - requestParameters['start'] = position[0] - if (position[1]) { - requestParameters['end'] = position[1] - } - requestParameters['variantType'] = reqParameters[1] - requestParameters['alternateBases'] = bases[1] - requestParameters['referenceBases'] = bases[0] + if (part.includes('-')) { + position = reqParameters[0].split('-') + } else { + position = [reqParameters[0]] + } + + let bases = reqParameters[2].split('>') + + requestParameters['start'] = position[0] + if (position[1]) { + requestParameters['end'] = position[1] + } + requestParameters['variantType'] = reqParameters[1] + requestParameters['alternateBases'] = bases[1] + requestParameters['referenceBases'] = bases[0] + } else if (part.includes(':')) { + // Split part by ':' to get key-value pairs for additional parameters + let additionalParam = part.split(':') + requestParameters[additionalParam[0]] = additionalParam[1] + } + }) + + // Add the processed requestParameters object to the array arrayRequestParameters.push(requestParameters) } else { queryStringTerm.push(props.query.trim()) @@ -316,12 +226,19 @@ function IndividualsResults (props) { queryArray[index].push('!') } else { queryArray[index] = term.split('%') - queryArray[index].push('%') + + queryArray[index][1] = '%' + queryArray[index][1] + '%' + + queryArray[index].push('=') } let alphanumericFilter = {} props.filteringTerms.forEach(element => { - if (element.label) { + if ( + element.label && + element.id !== 'NCIT:C46113' && + element.id !== 'NCIT:C46112' + ) { if ( queryArray[index][1].toLowerCase() === element.label.toLowerCase() @@ -358,6 +275,7 @@ function IndividualsResults (props) { scope: ['run'] } } else { + alphanumericFilter = { id: element.id, scope: element.scopes @@ -465,7 +383,14 @@ function IndividualsResults (props) { datasetList.push(res2.data.response.collections) } - if (updatedArrayFilterVar.length === 0) { + if (updatedArrayFilterVar.length === 0 && props.isNetwork === true) { + res.data.responses.forEach(element => { + beaconsList.push(element) + }) + } else if ( + updatedArrayFilterVar.length === 0 && + props.isNetwork === false + ) { beaconsList.push(res.data.response) } @@ -473,7 +398,6 @@ function IndividualsResults (props) { if (props.query === null || props.query === '') { // show all individuals - let jsonData1 = {} if (arrayRequestParameters.length > 0) { @@ -528,6 +452,7 @@ function IndividualsResults (props) { configData.API_URL + '/individuals', jsonData1 ) + } else { const headers = { Authorization: `Bearer ${token}` } console.log('querying with token') @@ -723,15 +648,17 @@ function IndividualsResults (props) { variablePause = false if (updatedArrayFilterVar.length > 0) { + updatedArrayFilterVar.forEach((element, index) => { if (Array.isArray(element.scope) && !selectedScopes[index]) { setPause(true) variablePause = true - let newOptionsScope = [...optionsScope] + let newOptionsScope = [] element.scope.forEach(elementScope => { newOptionsScope[index] = newOptionsScope[index] || [] + newOptionsScope[index].push(elementScope) }) @@ -740,7 +667,7 @@ function IndividualsResults (props) { let newOntologyMultipleScope = [...ontologyMultipleScope] props.filteringTerms.forEach(element2 => { if (element2.label && element2.id === element.id) { - newOntologyMultipleScope.push(element2.label) + newOntologyMultipleScope[index] = element2.label } }) setOntologyMultipleScope(newOntologyMultipleScope) @@ -756,6 +683,7 @@ function IndividualsResults (props) { } else { let newOptionsScope = [...optionsScope] arrayFilter.forEach((element, index) => { + if ( Array.isArray(element.scope) && element.scope.length > 1 && @@ -763,23 +691,26 @@ function IndividualsResults (props) { ) { setPause(true) variablePause = true - + element.scope.forEach(elementScope => { newOptionsScope[index] = newOptionsScope[index] || [] newOptionsScope[index].push(elementScope) }) setOptionsScope(newOptionsScope) - - let newOntologyMultipleScope = [...ontologyMultipleScope] + let newOntologyMultipleScope = [] + if (index !== 0) { + + newOntologyMultipleScope = [...ontologyMultipleScope] + } props.filteringTerms.forEach(element2 => { if (element2.label && element2.id === element.id) { newOntologyMultipleScope[index] = newOntologyMultipleScope[index] || [] - newOntologyMultipleScope[index].push(element2.label) + newOntologyMultipleScope[index] = element2.label } }) - + setOntologyMultipleScope(newOntologyMultipleScope) } else if ( Array.isArray(element.scope) && @@ -787,8 +718,10 @@ function IndividualsResults (props) { selectedScopes[index] ) { element.scope = selectedScopes[index] + } else { element.scope = element.scope[0] + } }) } @@ -856,11 +789,13 @@ function IndividualsResults (props) { token = auth.userData.access_token } if (token === null) { + console.log('Querying without token') res = await axios.post( configData.API_URL + '/individuals', jsonData2 ) + } else { console.log('Querying WITH token') @@ -871,6 +806,7 @@ function IndividualsResults (props) { jsonData2, { headers: headers } ) + } setTimeOut(true) @@ -1023,6 +959,7 @@ function IndividualsResults (props) { handleTypeResults3() } }, []) + return (
{timeOut === false && ( diff --git a/frontend/src/components/Layout/Layout.css b/frontend/src/components/Layout/Layout.css index ac832d3f..1d5a08fe 100644 --- a/frontend/src/components/Layout/Layout.css +++ b/frontend/src/components/Layout/Layout.css @@ -1,10 +1,9 @@ .containerSelection { display: flex; width: 100vw; - align-items: center; + /* align-items: center; */ justify-content: center; margin-bottom: 40px; - margin-top: -60px; } .buttonShowExamples { @@ -28,7 +27,8 @@ margin-bottom: 4px; /* display: flex; */ align-items: flex-start; - /* margin-left: 4px; */ + margin-left: 5px; + margin-right: 5px; display: flex; flex-direction: column; } @@ -42,6 +42,7 @@ /* margin-top: -53px; */ /* margin-bottom: 10px; */ margin-top: 24px; + align-items: center; } .buttonAllFilters:hover { @@ -61,7 +62,12 @@ .formInput { display: flex; - align-items: center; + align-items: flex-start; + margin-top: 0px; +} + +.layout-container { + width: 82vw; } .moduleAddedVariant h4 { @@ -77,8 +83,14 @@ width: 90%; } +.searchButton:hover { + background-color: #023452; +} +.clearButton:hover { + background-color: rgb(231 244 255); +} + p { - font-size: 15px !important; color: #2a6169; } @@ -101,6 +113,7 @@ p { display: flex; flex-direction: column; min-width: 112px; + position: relative; } .tabs { @@ -117,6 +130,8 @@ p { Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; color: #3176b1; font-weight: 600; + border-top-left-radius: 5px; + border-top-right-radius: 5px; } .tab.active { @@ -124,11 +139,16 @@ p { border-top: 1px solid #3176b1; border-left: 1px solid #3176b1; border-right: 1px solid #3176b1; + border-top-left-radius: 5px; + border-top-right-radius: 5px; } .tab-content { - padding: 10px; + padding: 3px; border: 1px solid #3176b1; + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; } .label-ontology-div label { @@ -136,19 +156,20 @@ p { } .inputSearch { width: 36vw; - height: -moz-fit-content; - height: fit-content; + resize: none; + padding-top: 6px; + height: 85px; padding-top: -10px; padding-left: 10px; font-size: 16px; - border-radius: 3px; + border-radius: 5px; border: 1px solid #3176b1; text-overflow: clip; - line-height: 3.1; max-width: 50vw; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + line-height: 1.4; } .filterTermsContainer { @@ -208,7 +229,6 @@ p { align-content: space-between; /* justify-content: space-around; */ align-items: flex-end; - margin-top: 30px; } .moduleAddedVariant2 h2 { @@ -298,8 +318,6 @@ ul div { margin-bottom: 4px; display: flex; align-items: flex-start; - margin-left: 4px; - margin-right: 4px; } .label-ontology-div2 input { @@ -311,6 +329,10 @@ ul div { border-radius: 4px; } +.label-ontology-div2 { + position: relative; +} + .subTitle { font-weight: 500; } @@ -330,8 +352,7 @@ label { sans-serif; } .divFilter { - margin-right: 10px; - margin-left: 10px; + margin-right: 20px; margin-bottom: 4px; width: -moz-fit-content; width: fit-content; @@ -339,11 +360,12 @@ label { } .resetButton { - background-color: rgb(249, 249, 249); - border: 1px solid rgb(169, 169, 216); + background-color: #ddf2f7; + border: 1.9px solid rgb(37 66 200); border-radius: 2px; - margin-bottom: 3px; cursor: pointer; + height: 28px; + margin-left: 5px; } .resetButton:hover { @@ -361,9 +383,6 @@ label { max-width: 181px; width: fit-content; } -.onHover { - display: none; -} h14 { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', @@ -373,25 +392,29 @@ h14 { color: #64646a; margin-left: 10px; margin-right: 10px; + margin-top: 4.2px; } -.label:hover + .onHover { - display: block; - color: #fff; +.onHover { + display: none; + position: absolute; /* Position it absolutely */ + top: 0px; /* Adjust as needed */ + left: 50px; /* Adjust as needed */ z-index: 4; + color: #fff; font-weight: 500; - margin-top: -20px; background: #6e9ef0; - padding-top: 4px; - padding-bottom: 4px; - padding-right: 4px; - padding-left: 4px; - display: flex; + padding: 4px; border-radius: 2px; font-size: 11.5px; align-content: center; justify-content: center; } + +/* Display the hover element when the label is hovered */ +.label:hover + .onHover { + display: flex; +} .deleteIcon ion-icon { color: black; margin-bottom: -11px; @@ -471,8 +494,8 @@ h14 { .formula { width: 20px; - margin-right: 12.5px; - margin-left: 7px; + margin-right: 8.5px; + margin-left: 6px; } .dictionary { @@ -568,27 +591,16 @@ h14 { /* margin-left: -10px; */ /* padding-top: 30px; */ /* padding-left: 26px; */ - } } @media (max-width: 1200px) { .inputSearch { width: 28vw; - height: fit-content; - padding: 10px; - font-size: 14 px; + border: 1px solid #3176b1; - border-radius: 3px; text-overflow: clip; max-width: 38vw; } - .containerSelection { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 40px; - margin-top: -60px; - } } @media (max-width: 900) { ul div { @@ -605,46 +617,70 @@ h14 { @media (max-width: 950px) { .inputSearch { width: 28vw; - height: fit-content; - padding: 10px; font-size: 14 px; border: 1px solid #3176b1; text-overflow: clip; max-width: 40vw; - border-radius: 3px; + height: 139px; + font-size: 14px; } - .containerSelection { + .selectModule1 { + font-size: 14px; + } + .selectModule2 { + font-size: 14px; + } + .buttonText { + display: none !important; + } + .searchButton { + cursor: pointer; + margin-left: 12px; + border: none; + border-radius: 100px; + background: #3176b1; + padding: 10px, 24px, 10px, 16px; + color: white; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', + sans-serif; + font-size: 14px; display: flex; + font-weight: 500; + width: 99px; + height: 40px; + width: 40px; + justify-content: space-evenly; align-items: center; - justify-content: center; - margin-bottom: 40px; - margin-top: -60px; - } - - .selectModule1 { - width: 150px !important; } -} -@media (max-width: 950px) { - .inputSearch { - width: 28vw; - height: fit-content; - padding: 10px; - font-size: 14 px; + .clearButton { + cursor: pointer; + margin-left: 12px; + border: none; + border-radius: 100px; + background: white; + padding: 10px, 24px, 10px, 16px; + color: #3176b1; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', + sans-serif; + font-size: 14px; + display: flex; + font-weight: 500; + width: 40px; + height: 40px; + justify-content: space-evenly; + align-items: center; border: 1px solid #3176b1; - text-overflow: clip; - max-width: 80vw; - border-radius: 3px; } .containerSelection { + flex-wrap: wrap; display: flex; - align-items: center; + width: 100vw; + /* align-items: center; */ justify-content: center; margin-bottom: 40px; - margin-top: 20px; - width: 100vw; - flex-wrap: wrap; } ul { @@ -683,7 +719,100 @@ h14 { } } +@media (max-width: 750px) { + .inputSearch { + width: 63vw; + + font-size: 13px; + border: 1px solid #3176b1; + text-overflow: clip; + max-width: 80vw; + margin-top: 10px; + margin-left: 26px; + } + .filterTermsContainer { + display: flex; + width: 84vw; + justify-content: space-evenly; + /* margin-bottom: 18px; */ + flex-wrap: wrap; + height: -moz-fit-content; + height: fit-content; + border: none; + /* margin-left: -10px; */ + padding-top: 30px; + padding-left: 0px; + /* border-radius: 8px; */ + } + .containerSelection { + margin-top: 12px; + } + ul { + padding-left: 0; + + display: flex; + list-style: none; + max-height: none; + + flex-direction: column; + + justify-content: center; + } +} + @media (max-width: 500px) { + .searchButton { + cursor: pointer; + margin-left: 12px; + border: none; + border-radius: 100px; + background: #3176b1; + padding: 10px, 24px, 10px, 16px; + color: white; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', + sans-serif; + font-size: 14px; + display: flex; + font-weight: 500; + width: 99px; + height: 36px; + width: 36px; + justify-content: space-evenly; + align-items: center; + } + .clearButton { + cursor: pointer; + margin-left: 12px; + border: none; + border-radius: 100px; + background: white; + padding: 10px, 24px, 10px, 16px; + color: #3176b1; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', + sans-serif; + font-size: 14px; + display: flex; + font-weight: 500; + width: 36px; + height: 36px; + justify-content: space-evenly; + align-items: center; + border: 1px solid #3176b1; + } + + .buttonAllFilters h4 { + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', + sans-serif; + font-size: 12px; + color: #3176b1; + margin-left: 3px; + margin-bottom: 0px; + margin-top: 0px; + font-weight: 600; + } ul { padding-left: 0; @@ -698,6 +827,9 @@ h14 { .scopeSelection h10 { font-size: 12px; } + .formInput { + margin-top: 12px; + } .scopeSelection { position: absolute; top: 286px; @@ -722,6 +854,20 @@ h14 { select { height: 21px; } + + .inputSearch { + margin-left: 0px; + } + + .resetButton { + background-color: #ddf2f7; + border: 1.9px solid rgb(37 66 200); + border-radius: 2px; + cursor: pointer; + height: 25px; + margin-left: 5px; + font-size: 12px; + } } @media (max-width: 300px) { diff --git a/frontend/src/components/Layout/Layout.js b/frontend/src/components/Layout/Layout.js index 0e0205ae..74801c77 100644 --- a/frontend/src/components/Layout/Layout.js +++ b/frontend/src/components/Layout/Layout.js @@ -2,7 +2,7 @@ import '../../App.css' import './Layout.css' import FilteringTerms from '../FilteringTerms/FilteringTerms' import filtersConfig from '../../config-examples-cancer.json' - +import filtersConfig2 from '../../config-examples-covid.json' import VariantsResults from '../GenomicVariations/VariantsResults' import BiosamplesResults from '../Biosamples/BiosamplesResults' @@ -30,7 +30,7 @@ function Layout (props) { const [query, setQuery] = useState('') const [queryAux, setQueryAux] = useState(null) const [filtersTab1, setFiltersTab1] = useState(filtersConfig.filters) - + const [filtersTab2, setFiltersTab2] = useState(filtersConfig2.filters) const [exampleQ, setExampleQ] = useState([]) const [isNetwork, setIsNetwork] = useState(false) @@ -139,11 +139,12 @@ function Layout (props) { const handleValueChanges = e => { setValueFree(e.target.value) } - const handdleInclude = e => { + const handleInclude = e => { if (ID !== '' && valueFree !== '' && operator !== '') { + if (query !== null && query !== '') { setQuery(query + ',' + `${ID}${operator}${valueFree}`) - } + } if (query === null || query == '') { setQuery(`${ID}${operator}${valueFree}`) } @@ -152,88 +153,111 @@ function Layout (props) { const handleOption = (e, array, optionIndex, tab) => { const updatedInputValues = - tab === 'tab1' ? { ...inputValuesTab1 } : { ...inputValuesTab2 } + tab === 'tab1' ? { ...inputValuesTab1 } : { ...inputValuesTab2 }; const updatedCheckedOptions = - tab === 'tab1' ? { ...checkedOptionsTab1 } : { ...checkedOptionsTab2 } - const filterIndex = e.target.getAttribute('data-filter-index') - const elementLabel = e.target.getAttribute('data-element-label') // Get the element label from the checkbox - const optionId = `option-${filterIndex}-${optionIndex}-${elementLabel}` // Construct the correct key - - updatedCheckedOptions[optionId] = e.target.checked // Update the checked state - + tab === 'tab1' ? { ...checkedOptionsTab1 } : { ...checkedOptionsTab2 }; + const filterIndex = e.target.getAttribute('data-filter-index'); + const elementLabel = e.target.getAttribute('data-element-label'); // Get the element label from the checkbox + const optionId = `option-${filterIndex}-${optionIndex}-${elementLabel}`; // Construct the correct key + + updatedCheckedOptions[optionId] = e.target.checked; // Update the checked state + if (tab === 'tab1') { - setCheckedOptionsTab1(updatedCheckedOptions) + setCheckedOptionsTab1(updatedCheckedOptions); } else { - setCheckedOptionsTab2(updatedCheckedOptions) + setCheckedOptionsTab2(updatedCheckedOptions); } - - let start, end, variantType, referenceBases, alternateBases - const title = [] - const value = [] - + + let start, end, variantType, referenceBases, alternateBases,assemblyId; + const title = []; + const value = []; + array.forEach(element => { - title.push(element.schemaField) + title.push(element.schemaField); const inputValue = updatedInputValues[ `${optionIndex}-${element.label}-${element.schemaField}` - ] - value.push(inputValue || element.value) - + ]; + value.push(inputValue || element.value); + switch (element.schemaField) { case 'start': - start = inputValue || element.value - break + start = inputValue || element.value; + break; case 'end': - end = inputValue || element.value - break + end = inputValue || element.value; + break; case 'variantType': - variantType = inputValue || element.value - break + variantType = inputValue || element.value; + break; case 'referenceBases': - referenceBases = inputValue || element.value - break + referenceBases = inputValue || element.value; + break; case 'alternateBases': - alternateBases = inputValue || element.value - break + alternateBases = inputValue || element.value; + break; + case 'assemblyId': + assemblyId = inputValue || element.value; default: - break + break; } - }) - - const specialQuery = - start && end && variantType && referenceBases && alternateBases - ? `${start}-${end}:${variantType}:${referenceBases}>${alternateBases}` - : null - + }); + +const specialQuery = + start && end && variantType && referenceBases && alternateBases + ? `${start}-${end}:${variantType}:${referenceBases}>${alternateBases}${assemblyId ? `&assemblyId:${assemblyId}` : ''}` + : null; + const arrayQuery = title .map((titleQuery, indexQuery) => titleQuery === 'geneId' || titleQuery === 'aminoacidChange' ? `${titleQuery}:${value[indexQuery]}` : `${titleQuery}=${value[indexQuery]}` ) - .join('&') - + .join('&'); + + const addQuery = specialQuery || arrayQuery; + if (e.target.checked) { setQuery(prevQuery => { - if (!prevQuery) return specialQuery || arrayQuery - return `${prevQuery},${specialQuery || arrayQuery}` - }) + if (!prevQuery) return addQuery; + return `${prevQuery},${addQuery}`; + }); } else { setQuery(prevQuery => { - const updatedQuery = prevQuery - .split(',') - .filter(item => item !== (specialQuery || arrayQuery)) - .join(',') - return updatedQuery || '' - }) + const updatedQueries = prevQuery.split(',').filter(query => { + if (specialQuery) { + // Remove only the exact specialQuery + return query !== specialQuery; + } else { + // Remove only the exact arrayQuery components + return !title.some((titleQuery, indexQuery) => { + const valueQuery = `${titleQuery}=${value[indexQuery]}`; + const colonQuery = `${titleQuery}:${value[indexQuery]}`; + const mixQuery = `${titleQuery}:${value[indexQuery]}&${titleQuery}:${value[indexQuery]}` + return query === valueQuery || query === colonQuery|| query === mixQuery + }); + } + }); + return updatedQueries.join(','); + }); + const queriesToRemove = title.map((titleQuery, indexQuery) => { + if (titleQuery === 'geneId' || titleQuery === 'aminoacidChange') { + return `${titleQuery}:${value[indexQuery]}`; + } else { + return `${titleQuery}=${value[indexQuery]}`; + } + }); + } - + if (tab === 'tab1') { - setInputValuesTab1(updatedInputValues) + setInputValuesTab1(updatedInputValues); } else { - setInputValuesTab2(updatedInputValues) + setInputValuesTab2(updatedInputValues); } - } + }; + const handleOptionAlphanum = (schemaField, value) => { setShowAlphanum(true) @@ -263,8 +287,7 @@ function Layout (props) { setQuery('') setShowAlphanum(false) // Clear the state for input values and checked options - setInputValuesTab1({}) - setInputValuesTab2({}) + setCheckedOptionsTab1({}) setCheckedOptionsTab2({}) @@ -428,8 +451,8 @@ function Layout (props) { } setInputValuesTab1(initializeInputValues(filtersTab1)) - - }, [filtersTab1]) + setInputValuesTab2(initializeInputValues(filtersTab2)) + }, [filtersTab1, filtersTab2]) return (
@@ -437,7 +460,7 @@ function Layout (props) {
-
-

v0.5.5

+

v0.5.6

@@ -489,20 +512,25 @@ function Layout (props) { value={query} onChange={e => search(e)} /> -
- +
+ + +
@@ -553,7 +581,7 @@ function Layout (props) { /> - @@ -566,8 +594,9 @@ function Layout (props) { className={`tab ${activeTab === 'tab1' ? 'active' : ''}`} onClick={() => setActiveTab('tab1')} > - QUERY EXAMPLES + CANCER +
{activeTab === 'tab1' && ( @@ -585,7 +614,21 @@ function Layout (props) { activeTab={activeTab} /> )} - + {activeTab === 'tab2' && ( + + handleOption(e, array, optionIndex, 'tab2') + } + handleOptionAlphanum={handleOptionAlphanum} + handleInputChange={(e, key) => + handleInputChange(e, key, 'tab2') + } + inputValues={inputValuesTab2} + checkedOptions={checkedOptionsTab2} + activeTab={activeTab} + /> + )}