From cc000e19efc836fc190cfa18b36a165ff6ea8c46 Mon Sep 17 00:00:00 2001 From: frostyfan109 Date: Fri, 13 Sep 2024 17:57:55 -0400 Subject: [PATCH] tooltip updates, dynamically generate study source list --- .../search/concept-modal/concept-modal.js | 21 ++++++++---- src/components/search/context.js | 34 ++++++++++++++++++- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/components/search/concept-modal/concept-modal.js b/src/components/search/concept-modal/concept-modal.js index b8acfef3..2e116288 100644 --- a/src/components/search/concept-modal/concept-modal.js +++ b/src/components/search/concept-modal/concept-modal.js @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { Button, Menu, Modal, Result, Space, Spin, Typography, Tooltip, Divider, Popover } from 'antd' import CustomIcon, { InfoCircleOutlined as OverviewIcon, @@ -73,7 +73,7 @@ export const ConceptModalBody = ({ result }) => { const { analyticsEvents } = useAnalytics(); const { context } = useEnvironment(); const [currentTab, _setCurrentTab] = useState('overview') - const { query, setSelectedResult, fetchKnowledgeGraphs, fetchVariablesForConceptId, fetchCDEs } = useHelxSearch() + const { query, setSelectedResult, fetchKnowledgeGraphs, fetchVariablesForConceptId, fetchCDEs, studySources } = useHelxSearch() const [graphs, setGraphs] = useState([]) const [studies, setStudies] = useState([]) const [cdes, setCdes] = useState(null) @@ -115,8 +115,15 @@ export const ConceptModalBody = ({ result }) => { content: , tooltip:
The Studies tab displays studies referencing or researching the concept. - Studies are grouped into three categories: HEAL research programs, HEAL studies, - and non-HEAL studies. By default, all studies are shown, but categories can be filtered + Studies are grouped into { studySources.length } categories:  + { studySources.map((source, i) => ( + + { i === studySources.length - 1 ? "and " : ""} + { source } + { i !== studySources.length - 1 ? ", " : ". " } + + )) } + By default, all studies are shown, but categories can be filtered out by clicking on them. You can also click on studies to view which of their variables are related to the concept.
@@ -127,8 +134,10 @@ export const ConceptModalBody = ({ result }) => { content: , tooltip:
The CDEs tab displays{ context.brand === "heal" ? " HEAL-approved" : "" } common data elements (CDEs) - associated with the concept. {context.brand === "heal" ? - The + associated with the concept. A CDE is a standardized question used across studies and clinical + trials with a precisely defined set of permissible responses to ensure consistent data collection. + {context.brand === "heal" ? +  The HEAL CDE program provides further information. : null} diff --git a/src/components/search/context.js b/src/components/search/context.js index 7a37107f..e2d7f210 100644 --- a/src/components/search/context.js +++ b/src/components/search/context.js @@ -30,6 +30,8 @@ export const HelxSearch = ({ children }) => { const [error, setError] = useState({}) const [conceptPages, setConceptPages] = useState({}) const [conceptTypes, setConceptTypes] = useState({}) + // E.g. for HEAL, HEAL Studies, Non-HEAL studies, HEAL Research Programs + const [studySources, setStudySources] = useState([]) // const [concepts, setConcepts] = useState([]) const [totalConcepts, setTotalConcepts] = useState(0) const [currentPage, setCurrentPage] = useState(1) @@ -55,6 +57,7 @@ export const HelxSearch = ({ children }) => { /** Abort controllers */ const fetchConceptsController = useRef() const searchSelectedResultController = useRef() + const fetchStudySourcesController = useRef() // const selectedResultLoading = useMemo(() => selectedResult && selectedResult.loading === true, [selectedResult]) // const selectedResultFailed = useMemo(() => selectedResult && selectedResult.failed === true, [selectedResult]) @@ -219,6 +222,34 @@ export const HelxSearch = ({ children }) => { setVariableResults([]) }, [query]) + useEffect(() => { + const fetchStudySources = async () => { + fetchStudySourcesController.current?.abort() + fetchStudySourcesController.current = new AbortController() + + const response = await axios.get(`${helxSearchUrl}/agg_data_types`, undefined, { + signal: fetchStudySourcesController.current.signal + }) + if (response.status === 200 && response.data.status === 'success' && response.data.result) { + // We treat the CDE source as separate from the study sources, even though it is returned under + // `/agg_data_types` since CDE variables are classified under the `cde` data_type field + setStudySources( + response.data.result + .filter((source) => source !== "cde") + .sort((a, b) => a.localeCompare(b)) + ) + } else { + setStudySources([]) + } + } + + fetchStudySources() + + return () => { + fetchStudySourcesController.current?.abort() + } + }, [helxSearchUrl]) + useEffect(() => { setConceptPages({}) setCurrentPage(1) @@ -502,7 +533,8 @@ export const HelxSearch = ({ children }) => { conceptTypes, variableStudyResults, variableStudyResultCount, variableError, variableResults, isLoadingVariableResults, - totalVariableResults + totalVariableResults, + studySources }}> {children}