diff --git a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTable.stories.jsx b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTable.stories.jsx index 49d043dc19..aef1dd23eb 100644 --- a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTable.stories.jsx +++ b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTable.stories.jsx @@ -3,6 +3,10 @@ import { QueryClient, QueryClientProvider } from 'react-query'; import { rest } from 'msw'; import AttritionTable from './AttritionTable'; import { SourceContextProvider } from '../../../Utils/Source'; +import { + generateEulerTestData, + generateHistogramTestData, +} from '../../../TestData/generateDiagramTestData'; import '../../../GWASApp.css'; export default { @@ -12,26 +16,6 @@ export default { const mockedQueryClient = new QueryClient(); -const generateHistogramTestData = () => { - const minNumberOfBars = 5; - const maxNumberOfBars = 15; - const minPersonCount = 100; - const maxPersonCount = 2000; - const binSizeOffSet = 10; - const numberOfBars = - Math.floor(Math.random() * maxNumberOfBars) + minNumberOfBars; - // Create an array of numberOfBars objects - const objectsArray = Array.from({ length: numberOfBars }, (v, i) => { - return { - start: i * binSizeOffSet, - end: start + binSizeOffSet, - personCount: Math.floor(Math.random() * (maxPersonCount - minPersonCount)) + - minPersonCount, - }; - }); - return objectsArray; -}; - const MockTemplate = () => { const [covariateArrSizeTable1, setCovariateArrSizeTable1] = useState(10); const [covariateArrSizeTable2, setCovariateArrSizeTable2] = useState(2); @@ -41,6 +25,8 @@ const MockTemplate = () => { }; const outcome = { variable_type: 'custom_dichotomous', + cohort_sizes: [10000, 20000], + cohort_names: ['name1', 'name2'], cohort_ids: [1, 2], provided_name: 'dichotomous test1', }; @@ -58,6 +44,8 @@ const MockTemplate = () => { (_, i) => ({ variable_type: 'custom_dichotomous', provided_name: 'providednamebyuser' + i, + cohort_sizes: [10000, 20000], + cohort_names: ['name1', 'name2'], cohort_ids: [i, i * i], }) ); @@ -179,6 +167,15 @@ MockedSuccess.parameters = { ); } ), + rest.post( + 'http://:cohortmiddlewarepath/cohort-middleware/cohort-stats/check-overlap/by-source-id/:sourceid/by-cohort-definition-ids/:cohortdefinitionA/:cohortdefinitionB', + (req, res, ctx) => { + const { cohortmiddlewarepath } = req.params; + const { cohortdefinitionA } = req.params; + const { cohortdefinitionB } = req.params; + return res(ctx.delay(1100), ctx.json(generateEulerTestData())); + } + ), ], }, }; diff --git a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.jsx b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.jsx index e103752ecc..2abe3c4543 100644 --- a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.jsx +++ b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.jsx @@ -36,7 +36,7 @@ const AttritionTableModal = ({ modalInfo, setModalInfo }) => { modalInfo.rowObject.variable_type === 'custom_dichotomous' && (
null} + useInlineErrorMessages selectedStudyPopulationCohort={modalInfo.selectedCohort} selectedCaseCohort={{ cohort_name: modalInfo?.rowObject?.cohort_names[0], diff --git a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.test.jsx b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.test.jsx index fa9fcaa49a..e0c1b7a41b 100644 --- a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.test.jsx +++ b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTable/AttritionTableModal/AttritionTableModal.test.jsx @@ -1,9 +1,9 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; +import { QueryClient, QueryClientProvider } from 'react-query'; import AttritionTableModal from './AttritionTableModal'; import { SourceContextProvider } from '../../../../Utils/Source'; -import { QueryClient, QueryClientProvider } from 'react-query'; import { fetchSimpleOverlapInfo, useSourceFetch, @@ -12,7 +12,7 @@ import { // Mock the PhenotypeHistogram component jest.mock( '../../../Diagrams/PhenotypeHistogram/PhenotypeHistogram', - () => () => null + () => () => null, ); jest.mock('../../../../Utils/cohortMiddlewareApi'); fetchSimpleOverlapInfo.mockResolvedValue({ @@ -49,7 +49,7 @@ describe('AttritionTableModal', () => { render(); expect(screen.getByText('Test Modal')).toBeInTheDocument(); expect( - screen.queryByTestId('phenotype-histogram-diagram') + screen.queryByTestId('phenotype-histogram-diagram'), ).toBeInTheDocument(); expect(screen.queryByTestId('euler-diagram')).not.toBeInTheDocument(); }); @@ -77,11 +77,11 @@ describe('AttritionTableModal', () => { - + , ); expect(screen.queryByTestId('euler-diagram')).toBeInTheDocument(); expect( - screen.queryByTestId('phenotype-histogram-diagram') + screen.queryByTestId('phenotype-histogram-diagram'), ).not.toBeInTheDocument(); }); @@ -96,7 +96,7 @@ describe('AttritionTableModal', () => { render(); expect(screen.getByText('Test Modal')).toBeInTheDocument(); expect( - screen.queryByTestId('phenotype-histogram-diagram') + screen.queryByTestId('phenotype-histogram-diagram'), ).not.toBeInTheDocument(); expect(screen.queryByTestId('euler-diagram')).not.toBeInTheDocument(); }); diff --git a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTableWrapper.stories.jsx b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTableWrapper.stories.jsx index 1007320e6a..e2bbe748f9 100644 --- a/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTableWrapper.stories.jsx +++ b/src/Analysis/GWASApp/Components/AttritionTableWrapper/AttritionTableWrapper.stories.jsx @@ -3,6 +3,10 @@ import { QueryClient, QueryClientProvider } from 'react-query'; import { rest } from 'msw'; import AttritionTableWrapper from './AttritionTableWrapper'; import { SourceContextProvider } from '../../Utils/Source'; +import { + generateEulerTestData, + generateHistogramTestData, +} from '../../TestData/generateDiagramTestData'; import '../../GWASApp.css'; let rowCount = 0; @@ -32,10 +36,14 @@ WithConceptOutcome.args = { { variable_type: 'custom_dichotomous', provided_name: 'providednamebyuser', + cohort_sizes: [9999912, 9999932], + cohort_names: ['name1', 'name2'], cohort_ids: [12, 32], }, { variable_type: 'custom_dichotomous', + cohort_sizes: [9999912, 9999932], + cohort_names: ['name1', 'name2'], cohort_ids: [1, 2], provided_name: 'dichotomous test1', }, @@ -106,6 +114,26 @@ WithConceptOutcome.parameters = { ); } ), + rest.post( + 'http://:cohortmiddlewarepath/cohort-middleware/histogram/by-source-id/:sourceid/by-cohort-definition-id/:cohortdefinitionId/by-histogram-concept-id/:conceptId', + (req, res, ctx) => { + return res( + ctx.delay(2000), + ctx.json({ + bins: generateHistogramTestData(), + }) + ); + } + ), + rest.post( + 'http://:cohortmiddlewarepath/cohort-middleware/cohort-stats/check-overlap/by-source-id/:sourceid/by-cohort-definition-ids/:cohortdefinitionA/:cohortdefinitionB', + (req, res, ctx) => { + const { cohortmiddlewarepath } = req.params; + const { cohortdefinitionA } = req.params; + const { cohortdefinitionB } = req.params; + return res(ctx.delay(1100), ctx.json(generateEulerTestData())); + } + ), ], }, }; @@ -115,6 +143,8 @@ WithDichotomousOutcome.args = { ...WithConceptOutcome.args, outcome: { variable_type: 'custom_dichotomous', + cohort_sizes: [9999912, 9999932], + cohort_names: ['name1', 'name2'], cohort_ids: [1, 2], provided_name: 'dichotomous test1', }, diff --git a/src/Analysis/GWASApp/Components/Covariates/CustomDichotomousCovariates.jsx b/src/Analysis/GWASApp/Components/Covariates/CustomDichotomousCovariates.jsx index 4b0df3b2b3..781678b587 100644 --- a/src/Analysis/GWASApp/Components/Covariates/CustomDichotomousCovariates.jsx +++ b/src/Analysis/GWASApp/Components/Covariates/CustomDichotomousCovariates.jsx @@ -23,11 +23,11 @@ const CustomDichotomousCovariates = ({ variable_type: 'custom_dichotomous', cohort_names: [ firstPopulation.cohort_name, - secondPopulation.cohort_name + secondPopulation.cohort_name, ], cohort_sizes: [ firstPopulation.size, - secondPopulation.size + secondPopulation.size, ], cohort_ids: [ firstPopulation.cohort_definition_id, diff --git a/src/Analysis/GWASApp/Components/Diagrams/CohortsOverlapDiagram/CohortsOverlapDiagram.jsx b/src/Analysis/GWASApp/Components/Diagrams/CohortsOverlapDiagram/CohortsOverlapDiagram.jsx index bdd237fe64..ee9d6b7625 100644 --- a/src/Analysis/GWASApp/Components/Diagrams/CohortsOverlapDiagram/CohortsOverlapDiagram.jsx +++ b/src/Analysis/GWASApp/Components/Diagrams/CohortsOverlapDiagram/CohortsOverlapDiagram.jsx @@ -22,14 +22,7 @@ const CohortsOverlapDiagram = ({ selectedCovariates, outcome, }) => { - const objects = [ - selectedStudyPopulationCohort, - selectedCaseCohort, - selectedControlCohort, - selectedCovariates, - outcome, - ]; - + const [inlineErrorMessage, setInlineErrorMessage] = useState(null); const { source } = useSourceContext(); const [showTextVersion, setShowTextVersion] = useState(false); const sourceId = source; // TODO - change name of source to sourceId for clarity @@ -149,15 +142,19 @@ const CohortsOverlapDiagram = ({ dataStudyPopulationAndCase.cohort_overlap.case_control_overlap === 0 || dataStudyPopulationAndControl.cohort_overlap.case_control_overlap === 0 ) { - dispatch({ - type: ACTIONS.ADD_MESSAGE, - payload: MESSAGES.OVERLAP_ERROR, - }); + setInlineErrorMessage(

❌ {MESSAGES.OVERLAP_ERROR.title}

); + dispatch && + dispatch({ + type: ACTIONS.ADD_MESSAGE, + payload: MESSAGES.OVERLAP_ERROR, + }); } else { - dispatch({ - type: ACTIONS.DELETE_MESSAGE, - payload: MESSAGES.OVERLAP_ERROR, - }); + setInlineErrorMessage(null); + dispatch && + dispatch({ + type: ACTIONS.DELETE_MESSAGE, + payload: MESSAGES.OVERLAP_ERROR, + }); } } }, [dataStudyPopulationAndCase, dataStudyPopulationAndControl]); @@ -203,6 +200,7 @@ const CohortsOverlapDiagram = ({ {!showTextVersion && ( + <>{inlineErrorMessage} { + const minNumberOfBars = 5; + const maxNumberOfBars = 15; + const minPersonCount = 100; + const maxPersonCount = 2000; + const binSizeOffSet = 10; + const numberOfBars = + Math.floor(Math.random() * maxNumberOfBars) + minNumberOfBars; + // Create an array of numberOfBars objects + const objectsArray = Array.from({ length: numberOfBars }, (v, i) => { + const start = i * binSizeOffSet; + return { + start: start, + end: start + binSizeOffSet, + personCount: + Math.floor(Math.random() * (maxPersonCount - minPersonCount)) + + minPersonCount, + }; + }); + return objectsArray; +}; + +export const generateEulerTestData = () => ({ + cohort_overlap: { + case_control_overlap: Math.floor(Math.random() * 5000), + }, // because of random here, we get some data that does not really make sense...SuccessCase2 tries to fix that for some of the relevant group overlaps... +});