From 9fef7a98aaed29335cff292dc8faa455771a81eb Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 15:29:07 -0700 Subject: [PATCH 01/28] WEB-4460 add cells for each value --- .../clinicworkspace/TideDashboardV2/Cells.js | 69 +++++++++++++++++++ .../TideDashboardV2/TideDashboardV2.js | 26 +++---- .../TideDashboardV2/getPeriod.js | 11 +++ 3 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 app/pages/clinicworkspace/TideDashboardV2/getPeriod.js diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 31f5478f4c..4eb681ce6f 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -1,6 +1,14 @@ import React from 'react'; +import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { Box, Text } from 'theme-ui'; +import { utils as vizUtils } from '@tidepool/viz'; +const { bankersRound } = vizUtils.stat; +import { MGDL_UNITS } from '../../../core/constants'; + +import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; +import DeltaBar from '../../../components/elements/DeltaBar'; +import utils from '../../../core/utils'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); @@ -14,6 +22,67 @@ export const PatientCell = ({ patient }) => { ; }; +export const NumericTemplateCell = ({ value, isPercent = false }) => { + if (!value) return ; + + return {value} {isPercent && '%'}; +}; + +export const AvgGlucoseCell = ({ patient, period, units }) => { + const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.averageGlucoseMmol; + const value = utils.formatDecimal(rawValue, 1); // TODO: Fix for units + + return ; +}; + +export const PercentTIRCell = ({ patient, period }) => { + const selectedClinicId = useSelector(state => state.blip.selectedClinicId); + const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); + const clinicBgUnits = clinic?.preferredBgUnits || MGDL_UNITS; + + // TODO: need to add showExtremeHigh + + return ; +}; + +export const GMICell = ({ patient, period }) => { + const value = patient?.summary?.cgmStats?.periods?.[period]?.glucoseManagementIndicator; + + return ; +}; + +export const CGMUseCell = ({ patient, period }) => { + const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeCGMUsePercent; + const value = utils.formatDecimal(rawValue * 100, 1); + + return ; +}; + +export const ChangeTIRCell = ({ patient, period }) => { + const timeInTargetPercentDelta = patient?.summary?.cgmStats?.periods?.[period]?.timeInTargetPercentDelta; + + if (!timeInTargetPercentDelta) return --; + + return ; +}; + export default { PatientCell, + NumericTemplateCell, + AvgGlucoseCell, + PercentTIRCell, + ChangeTIRCell, + GMICell, + CGMUseCell, }; diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index d247d9edd8..0b399d181d 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -13,13 +13,14 @@ import PaginationControls from '../components/PaginationControls'; import ActiveFilterCount from '../components/ActiveFilterCount'; import TagListCell from '../components/TagListCell'; -import { PatientCell } from './Cells'; +import { AvgGlucoseCell, CGMUseCell, ChangeTIRCell, GMICell, PatientCell, PercentTIRCell } from './Cells'; import { resetTideDashboardState, setOffset } from './tideDashboardSlice'; import { useGetTideDashboardPatientsQuery } from './tideDashboardApi'; import ResetFilters from '../components/ResetFilters'; import useActiveFiltersCount from './useActiveFiltersCount'; import { resetTideDashboardFilters } from './tideDashboardFiltersSlice'; import moment from 'moment'; +import getPeriod from './getPeriod'; import { utils as vizUtils } from '@tidepool/viz'; const { getLocalizedCeiling} = vizUtils.datetime; @@ -58,6 +59,8 @@ const TideDashboard = () => { const tableData = data?.data || []; + const period = getPeriod(lastData); + return ( <> @@ -79,17 +82,16 @@ const TideDashboard = () => { variant="condensed" label="tideDashboardPatientsTable" columns={[ - { title: t('Patient Details'), field: 'fullName', align: 'left', render: patient => }, - { title: t('Flag'), field: '', align: 'left' }, - { title: t('Avg Glucose'), field: '', align: 'left' }, - { title: t('% TIR'), field: '', align: 'left' }, - { title: t('% Time in Range'), field: '', align: 'left' }, - { title: t('% Change in TIR'), field: '', align: 'left' }, - { title: t('GMI'), field: '', align: 'left' }, - { title: t('CGM Use'), field: '', align: 'left' }, - { title: t('Tags'), field: 'tags', align: 'left', render: patient => }, - { title: t('Last Reviewed'), field: '', align: 'left' }, - { title: t(''), field: '', align: 'left' }, // More + { title: t('Patient Details'), field: 'fullName', align: 'center', render: patient => }, + { title: t('Flag'), field: '', align: 'center' }, + { title: t('Avg Glucose'), field: '', align: 'center', render: patient => }, + { title: t('Time in Range'), field: '', align: 'center', render: patient => }, + { title: t('% Change in TIR'), field: '', align: 'center', render: patient => }, + { title: t('GMI'), field: '', align: 'center', render: patient => }, + { title: t('CGM Use'), field: '', align: 'center', render: patient => }, + { title: t('Tags'), field: 'tags', align: 'center', render: patient => }, + { title: t('Last Reviewed'), field: '', align: 'center' }, + { title: t(''), field: '', align: 'center' }, // More ]} data={tableData} // sx={tableStyle} diff --git a/app/pages/clinicworkspace/TideDashboardV2/getPeriod.js b/app/pages/clinicworkspace/TideDashboardV2/getPeriod.js new file mode 100644 index 0000000000..15c0865a74 --- /dev/null +++ b/app/pages/clinicworkspace/TideDashboardV2/getPeriod.js @@ -0,0 +1,11 @@ +const getPeriod = (lastData) => { + switch(lastData) { + case 1: return '1d'; + case 7: return '7d'; + case 14: return '14d'; + case 30: return '30d'; + default: return ''; + } +}; + +export default getPeriod; From c236e78a3653628515ee7e9e51e2156e071d5a16 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 15:42:55 -0700 Subject: [PATCH 02/28] WEB-4460 use selector function for period --- .../clinicworkspace/TideDashboardV2/Cells.js | 18 ++++++++++++------ .../TideDashboardV2/TideDashboardV2.js | 13 +++++-------- .../TideDashboardV2/getPeriod.js | 11 ----------- .../tideDashboardFiltersSlice.js | 11 +++++++++++ 4 files changed, 28 insertions(+), 25 deletions(-) delete mode 100644 app/pages/clinicworkspace/TideDashboardV2/getPeriod.js diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 4eb681ce6f..2742b682e4 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -9,6 +9,7 @@ import { MGDL_UNITS } from '../../../core/constants'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; +import { selectPeriod } from './tideDashboardFiltersSlice'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); @@ -28,14 +29,16 @@ export const NumericTemplateCell = ({ value, isPercent = false }) => { return {value} {isPercent && '%'}; }; -export const AvgGlucoseCell = ({ patient, period, units }) => { +export const AvgGlucoseCell = ({ patient, units }) => { // TODO: Fix for units + const period = useSelector(state => selectPeriod(state)); const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.averageGlucoseMmol; - const value = utils.formatDecimal(rawValue, 1); // TODO: Fix for units + const value = utils.formatDecimal(rawValue, 1); return ; }; -export const PercentTIRCell = ({ patient, period }) => { +export const PercentTIRCell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); const selectedClinicId = useSelector(state => state.blip.selectedClinicId); const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); const clinicBgUnits = clinic?.preferredBgUnits || MGDL_UNITS; @@ -52,20 +55,23 @@ export const PercentTIRCell = ({ patient, period }) => { />; }; -export const GMICell = ({ patient, period }) => { +export const GMICell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); const value = patient?.summary?.cgmStats?.periods?.[period]?.glucoseManagementIndicator; return ; }; -export const CGMUseCell = ({ patient, period }) => { +export const CGMUseCell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeCGMUsePercent; const value = utils.formatDecimal(rawValue * 100, 1); return ; }; -export const ChangeTIRCell = ({ patient, period }) => { +export const ChangeTIRCell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); const timeInTargetPercentDelta = patient?.summary?.cgmStats?.periods?.[period]?.timeInTargetPercentDelta; if (!timeInTargetPercentDelta) return --; diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index 0b399d181d..e32ea3a6f9 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -20,7 +20,6 @@ import ResetFilters from '../components/ResetFilters'; import useActiveFiltersCount from './useActiveFiltersCount'; import { resetTideDashboardFilters } from './tideDashboardFiltersSlice'; import moment from 'moment'; -import getPeriod from './getPeriod'; import { utils as vizUtils } from '@tidepool/viz'; const { getLocalizedCeiling} = vizUtils.datetime; @@ -59,8 +58,6 @@ const TideDashboard = () => { const tableData = data?.data || []; - const period = getPeriod(lastData); - return ( <> @@ -84,11 +81,11 @@ const TideDashboard = () => { columns={[ { title: t('Patient Details'), field: 'fullName', align: 'center', render: patient => }, { title: t('Flag'), field: '', align: 'center' }, - { title: t('Avg Glucose'), field: '', align: 'center', render: patient => }, - { title: t('Time in Range'), field: '', align: 'center', render: patient => }, - { title: t('% Change in TIR'), field: '', align: 'center', render: patient => }, - { title: t('GMI'), field: '', align: 'center', render: patient => }, - { title: t('CGM Use'), field: '', align: 'center', render: patient => }, + { title: t('Avg Glucose'), field: '', align: 'center', render: patient => }, + { title: t('Time in Range'), field: '', align: 'center', render: patient => }, + { title: t('% Change in TIR'), field: '', align: 'center', render: patient => }, + { title: t('GMI'), field: '', align: 'center', render: patient => }, + { title: t('CGM Use'), field: '', align: 'center', render: patient => }, { title: t('Tags'), field: 'tags', align: 'center', render: patient => }, { title: t('Last Reviewed'), field: '', align: 'center' }, { title: t(''), field: '', align: 'center' }, // More diff --git a/app/pages/clinicworkspace/TideDashboardV2/getPeriod.js b/app/pages/clinicworkspace/TideDashboardV2/getPeriod.js deleted file mode 100644 index 15c0865a74..0000000000 --- a/app/pages/clinicworkspace/TideDashboardV2/getPeriod.js +++ /dev/null @@ -1,11 +0,0 @@ -const getPeriod = (lastData) => { - switch(lastData) { - case 1: return '1d'; - case 7: return '7d'; - case 14: return '14d'; - case 30: return '30d'; - default: return ''; - } -}; - -export default getPeriod; diff --git a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js index 5db47ac172..9d9dd8e7e4 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js +++ b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js @@ -21,3 +21,14 @@ const tideDashboardFiltersSlice = createSlice({ export const { setLastDataFilter, setPatientTagsFilter, resetTideDashboardFilters } = tideDashboardFiltersSlice.actions; export default tideDashboardFiltersSlice.reducer; + +export const selectPeriod = (state) => { + switch(state.blip.tideDashboardFilters?.lastData) { + case 1: return '1d'; + case 7: return '7d'; + case 14: return '14d'; + case 30: return '30d'; + case 90: return '90d'; + default: return null; + } +}; From 7c36c0527719613cc09f92d3f51580f8a0e44147 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 17:10:27 -0700 Subject: [PATCH 03/28] WEB-4460 abstract tableColumns to easier to maintain format --- .../clinicworkspace/TideDashboardV2/Cells.js | 31 +++- .../TideDashboardV2/TideDashboardV2.js | 33 ++-- .../TideDashboardV2/useTableColumns.js | 142 ++++++++++++++++++ 3 files changed, 183 insertions(+), 23 deletions(-) create mode 100644 app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 2742b682e4..bbbca9e4de 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -37,7 +37,7 @@ export const AvgGlucoseCell = ({ patient, units }) => { // TODO: Fix for units return ; }; -export const PercentTIRCell = ({ patient }) => { +export const TimeInRangePercentBarChartCell = ({ patient }) => { const period = useSelector(state => selectPeriod(state)); const selectedClinicId = useSelector(state => state.blip.selectedClinicId); const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); @@ -55,6 +55,30 @@ export const PercentTIRCell = ({ patient }) => { />; }; +export const TimeInTargetPercentCell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); + const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeInTargetPercent; + const value = utils.formatDecimal(rawValue * 100, 0); + + return ; +}; + +export const TimeInAnyLowPercentCell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); + const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeInAnyLowPercent; + const value = utils.formatDecimal(rawValue * 100, 0); + + return ; +}; + +export const TimeInVeryLowPercentCell = ({ patient }) => { + const period = useSelector(state => selectPeriod(state)); + const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeInVeryLowPercent; + const value = utils.formatDecimal(rawValue * 100, 0); + + return ; +}; + export const GMICell = ({ patient }) => { const period = useSelector(state => selectPeriod(state)); const value = patient?.summary?.cgmStats?.periods?.[period]?.glucoseManagementIndicator; @@ -65,7 +89,7 @@ export const GMICell = ({ patient }) => { export const CGMUseCell = ({ patient }) => { const period = useSelector(state => selectPeriod(state)); const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeCGMUsePercent; - const value = utils.formatDecimal(rawValue * 100, 1); + const value = utils.formatDecimal(rawValue * 100, 0); return ; }; @@ -87,7 +111,8 @@ export default { PatientCell, NumericTemplateCell, AvgGlucoseCell, - PercentTIRCell, + TimeInRangePercentBarChartCell, + TimeInVeryLowPercentCell, ChangeTIRCell, GMICell, CGMUseCell, diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index e32ea3a6f9..cb2525377b 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation, Trans } from 'react-i18next'; @@ -12,8 +12,6 @@ import FilterByDataRecency from './FilterByDataRecency'; import PaginationControls from '../components/PaginationControls'; import ActiveFilterCount from '../components/ActiveFilterCount'; -import TagListCell from '../components/TagListCell'; -import { AvgGlucoseCell, CGMUseCell, ChangeTIRCell, GMICell, PatientCell, PercentTIRCell } from './Cells'; import { resetTideDashboardState, setOffset } from './tideDashboardSlice'; import { useGetTideDashboardPatientsQuery } from './tideDashboardApi'; import ResetFilters from '../components/ResetFilters'; @@ -22,6 +20,7 @@ import { resetTideDashboardFilters } from './tideDashboardFiltersSlice'; import moment from 'moment'; import { utils as vizUtils } from '@tidepool/viz'; +import useTableColumns from './useTableColumns'; const { getLocalizedCeiling} = vizUtils.datetime; const LIMIT = 12; @@ -36,17 +35,22 @@ const TideDashboard = () => { const { patientTags, lastData } = useSelector(state => state.blip.tideDashboardFilters); const timePrefs = useSelector((state) => state.blip.timePrefs); - // TODO: memoize so that new call isn't made every render due to changing timestamp - const lastDataTo = getLocalizedCeiling(new Date().toISOString(), timePrefs).toISOString(); - const lastDataFrom = moment(lastDataTo).subtract(lastData, 'days').toISOString(); + const tableColumns = useTableColumns(); + const activeFiltersCount = useActiveFiltersCount(); + + const lastDataTo = useMemo(() => { + return getLocalizedCeiling(new Date().toISOString(), timePrefs).toISOString(); + }, [timePrefs]); + + const lastDataFrom = useMemo(() => { + return moment(lastDataTo).subtract(lastData, 'days').toISOString(); + }, [lastDataTo, lastData]); const { data } = useGetTideDashboardPatientsQuery( { clinicId: selectedClinicId, offset, category, lastDataTo, lastDataFrom, tags: patientTags, limit: LIMIT }, { skip: !selectedClinicId } ); - const activeFiltersCount = useActiveFiltersCount(); - // reset state on dismount useEffect(() => { return () => dispatch(resetTideDashboardState()); @@ -78,18 +82,7 @@ const TideDashboard = () => { id="tideDashboardPatientsTable" variant="condensed" label="tideDashboardPatientsTable" - columns={[ - { title: t('Patient Details'), field: 'fullName', align: 'center', render: patient => }, - { title: t('Flag'), field: '', align: 'center' }, - { title: t('Avg Glucose'), field: '', align: 'center', render: patient => }, - { title: t('Time in Range'), field: '', align: 'center', render: patient => }, - { title: t('% Change in TIR'), field: '', align: 'center', render: patient => }, - { title: t('GMI'), field: '', align: 'center', render: patient => }, - { title: t('CGM Use'), field: '', align: 'center', render: patient => }, - { title: t('Tags'), field: 'tags', align: 'center', render: patient => }, - { title: t('Last Reviewed'), field: '', align: 'center' }, - { title: t(''), field: '', align: 'center' }, // More - ]} + columns={tableColumns} data={tableData} // sx={tableStyle} // onSort={handleSortChange} diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js new file mode 100644 index 0000000000..3c165dfbaf --- /dev/null +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -0,0 +1,142 @@ +import React, { useMemo } from 'react'; +import { useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; +import { CATEGORY } from './FilterByCategory'; + +import { + AvgGlucoseCell, + CGMUseCell, + ChangeTIRCell, + GMICell, + PatientCell, + TimeInRangePercentBarChartCell, + TimeInVeryLowPercentCell, + TimeInAnyLowPercentCell, + TimeInTargetPercentCell, +} from './Cells'; + +import TagListCell from '../components/TagListCell'; + +const getColumnTypes = (t) => ({ + patientDetails: { + title: t('Patient Details'), + field: 'fullName', + align: 'left', + render: patient => , + }, + flag: { + title: t('Flag'), + field: 'flag', + align: 'center', + }, + avgGlucose: { + title: t('Avg Glucose'), + field: 'avgGlucose', + align: 'center', + render: patient => , + }, + timeInRangeBarChart: { + title: t('Time in Range'), + field: 'timeInRangeBarChart', + align: 'center', + render: patient => , + }, + changeInTIR: { + title: t('% Change in TIR'), + field: 'changeInTIR', + align: 'center', + render: patient => , + }, + timeInVeryLow: { + title: t('% Time < 54'), + field: 'timeInVeryLow', + align: 'center', + render: patient => , + }, + timeInAnyLow: { + title: t('% Time < 70'), + field: 'timeInAnyLow', + align: 'center', + render: patient => , + }, + timeInTarget: { + title: t('% TIR 70-180'), + field: 'timeInTarget', + align: 'center', + render: patient => , + }, + gmi: { + title: t('GMI'), + field: 'gmi', + align: 'center', + render: patient => , + }, + cgmUse: { + title: t('CGM Use'), + field: 'cgmUse', + align: 'center', + render: patient => , + }, + tags: { + title: t('Tags'), + field: 'tags', + align: 'center', + render: patient => , + }, + lastReviewed: { + title: t('Last Reviewed'), + field: 'lastReviewed', + align: 'center', + }, + moreMenu: { + title: t(''), + field: 'moreMenu', + align: 'center', + }, // More +}); + +const useTableColumns = () => { + const { t } = useTranslation(); + const category = useSelector(state => state.blip.tideDashboard.category); + + const columns = useMemo(() => { + const columnTypes = getColumnTypes(t); + + switch(category) { + case CATEGORY.VERY_LOW: + return [ + columnTypes.patientDetails, + columnTypes.flag, + columnTypes.avgGlucose, + columnTypes.timeInVeryLow, + columnTypes.timeInAnyLow, + columnTypes.timeInTarget, + columnTypes.timeInRangeBarChart, + columnTypes.changeInTIR, + columnTypes.gmi, + columnTypes.tags, + columnTypes.lastReviewed, + columnTypes.moreMenu, + ]; + + case CATEGORY.DEFAULT: + default: + return [ + columnTypes.patientDetails, + columnTypes.flag, + columnTypes.avgGlucose, + columnTypes.timeInRangeBarChart, + columnTypes.changeInTIR, + columnTypes.gmi, + columnTypes.cgmUse, + columnTypes.tags, + columnTypes.lastReviewed, + columnTypes.moreMenu, + ]; + } + }, [category]); + + return columns; +}; + +export default useTableColumns; From 239c672945e1b15038b3e02fd797eb70d2e23558 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 17:28:04 -0700 Subject: [PATCH 04/28] WEB-4460 abstract column sets --- .../tideDashboardFiltersSlice.js | 1 + .../TideDashboardV2/useTableColumns.js | 83 ++++++++++++------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js index 9d9dd8e7e4..f99b4f8dc1 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js +++ b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js @@ -25,6 +25,7 @@ export default tideDashboardFiltersSlice.reducer; export const selectPeriod = (state) => { switch(state.blip.tideDashboardFilters?.lastData) { case 1: return '1d'; + case 2: return '2d'; case 7: return '7d'; case 14: return '14d'; case 30: return '30d'; diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index 3c165dfbaf..ba71da2aa6 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -102,37 +102,60 @@ const useTableColumns = () => { const columns = useMemo(() => { const columnTypes = getColumnTypes(t); - switch(category) { - case CATEGORY.VERY_LOW: - return [ - columnTypes.patientDetails, - columnTypes.flag, - columnTypes.avgGlucose, - columnTypes.timeInVeryLow, - columnTypes.timeInAnyLow, - columnTypes.timeInTarget, - columnTypes.timeInRangeBarChart, - columnTypes.changeInTIR, - columnTypes.gmi, - columnTypes.tags, - columnTypes.lastReviewed, - columnTypes.moreMenu, - ]; + const standardColumnSet = [ + columnTypes.patientDetails, + columnTypes.flag, + columnTypes.avgGlucose, + columnTypes.timeInTarget, + columnTypes.timeInRangeBarChart, + columnTypes.changeInTIR, + columnTypes.gmi, + columnTypes.cgmUse, + columnTypes.tags, + columnTypes.lastReviewed, + columnTypes.moreMenu, + ]; + + const lowColumnSet = [ + columnTypes.patientDetails, + columnTypes.flag, + columnTypes.avgGlucose, + columnTypes.timeInVeryLow, + columnTypes.timeInAnyLow, + columnTypes.timeInTarget, + columnTypes.timeInRangeBarChart, + columnTypes.changeInTIR, + columnTypes.gmi, + columnTypes.tags, + columnTypes.lastReviewed, + columnTypes.moreMenu, + ]; - case CATEGORY.DEFAULT: - default: - return [ - columnTypes.patientDetails, - columnTypes.flag, - columnTypes.avgGlucose, - columnTypes.timeInRangeBarChart, - columnTypes.changeInTIR, - columnTypes.gmi, - columnTypes.cgmUse, - columnTypes.tags, - columnTypes.lastReviewed, - columnTypes.moreMenu, - ]; + const highColumnSet = [ + columnTypes.patientDetails, + columnTypes.flag, + columnTypes.avgGlucose, + // columnTypes.timeInVeryLow, // TODO: Implement "high" columns + // columnTypes.timeInAnyLow, + columnTypes.timeInTarget, + columnTypes.timeInRangeBarChart, + columnTypes.changeInTIR, + columnTypes.gmi, + columnTypes.tags, + columnTypes.lastReviewed, + columnTypes.moreMenu, + ]; + + switch(category) { + case CATEGORY.DEFAULT: return standardColumnSet; + case CATEGORY.VERY_LOW: return lowColumnSet; + case CATEGORY.LOW: return lowColumnSet; + case CATEGORY.DROP_IN_TIR: return standardColumnSet; + case CATEGORY.HIGH: return highColumnSet; + case CATEGORY.VERY_HIGH: return highColumnSet; + case CATEGORY.LOW_CGM_WEAR: return standardColumnSet; + case CATEGORY.TARGET: return standardColumnSet; + default: return standardColumnSet; } }, [category]); From b0a7e8c5927de397daa4c2cc85fbf151fd730c74 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 17:43:54 -0700 Subject: [PATCH 05/28] WEB-4460 use correct summary period --- .../clinicworkspace/TideDashboardV2/Cells.js | 35 +++++++++---------- .../tideDashboardFiltersSlice.js | 12 ------- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index bbbca9e4de..8ad84b4145 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -9,7 +9,6 @@ import { MGDL_UNITS } from '../../../core/constants'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; -import { selectPeriod } from './tideDashboardFiltersSlice'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); @@ -30,15 +29,15 @@ export const NumericTemplateCell = ({ value, isPercent = false }) => { }; export const AvgGlucoseCell = ({ patient, units }) => { // TODO: Fix for units - const period = useSelector(state => selectPeriod(state)); - const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.averageGlucoseMmol; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.averageGlucoseMmol; const value = utils.formatDecimal(rawValue, 1); return ; }; export const TimeInRangePercentBarChartCell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const selectedClinicId = useSelector(state => state.blip.selectedClinicId); const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); const clinicBgUnits = clinic?.preferredBgUnits || MGDL_UNITS; @@ -47,56 +46,56 @@ export const TimeInRangePercentBarChartCell = ({ patient }) => { return ; }; export const TimeInTargetPercentCell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); - const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeInTargetPercent; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInTargetPercent; const value = utils.formatDecimal(rawValue * 100, 0); return ; }; export const TimeInAnyLowPercentCell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); - const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeInAnyLowPercent; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInAnyLowPercent; const value = utils.formatDecimal(rawValue * 100, 0); return ; }; export const TimeInVeryLowPercentCell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); - const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeInVeryLowPercent; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInVeryLowPercent; const value = utils.formatDecimal(rawValue * 100, 0); return ; }; export const GMICell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); - const value = patient?.summary?.cgmStats?.periods?.[period]?.glucoseManagementIndicator; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const value = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.glucoseManagementIndicator; return ; }; export const CGMUseCell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); - const rawValue = patient?.summary?.cgmStats?.periods?.[period]?.timeCGMUsePercent; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeCGMUsePercent; const value = utils.formatDecimal(rawValue * 100, 0); return ; }; export const ChangeTIRCell = ({ patient }) => { - const period = useSelector(state => selectPeriod(state)); - const timeInTargetPercentDelta = patient?.summary?.cgmStats?.periods?.[period]?.timeInTargetPercentDelta; + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const timeInTargetPercentDelta = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInTargetPercentDelta; if (!timeInTargetPercentDelta) return --; diff --git a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js index 137bcae5ed..2b36bb7969 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js +++ b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardFiltersSlice.js @@ -25,15 +25,3 @@ const tideDashboardFiltersSlice = createSlice({ export const { setLastDataFilter, setPatientTagsFilter, setSummaryPeriodFilter, resetTideDashboardFilters } = tideDashboardFiltersSlice.actions; export default tideDashboardFiltersSlice.reducer; - -export const selectPeriod = (state) => { - switch(state.blip.tideDashboardFilters?.lastData) { - case 1: return '1d'; - case 2: return '2d'; - case 7: return '7d'; - case 14: return '14d'; - case 30: return '30d'; - case 90: return '90d'; - default: return null; - } -}; From f27955dc7765b5087f274e7637d5afca9c092908 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 19:49:33 -0700 Subject: [PATCH 06/28] WEB-4460 use resolvedCategory to prevent visual glitch --- .../clinicworkspace/TideDashboardV2/TideDashboardV2.js | 9 ++++++--- .../clinicworkspace/TideDashboardV2/tideDashboardApi.js | 4 ++++ .../clinicworkspace/TideDashboardV2/useTableColumns.js | 4 +--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index 29cae04ac5..837ceebe19 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -36,9 +36,6 @@ const TideDashboard = () => { const { patientTags, lastData } = useSelector(state => state.blip.tideDashboardFilters); const timePrefs = useSelector((state) => state.blip.timePrefs); - const tableColumns = useTableColumns(); - const activeFiltersCount = useActiveFiltersCount(); - const lastDataTo = useMemo(() => { return getLocalizedCeiling(new Date().toISOString(), timePrefs).toISOString(); }, [timePrefs]); @@ -52,6 +49,12 @@ const TideDashboard = () => { { skip: !selectedClinicId } ); + // Sync category to data fetching resolution in order to prevent visual glitch + const resolvedCategory = data?.category || category; + + const tableColumns = useTableColumns(resolvedCategory); + const activeFiltersCount = useActiveFiltersCount(); + // reset state on dismount useEffect(() => { return () => dispatch(resetTideDashboardState()); diff --git a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js index 24241d1cb9..3b1d8b833e 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js +++ b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js @@ -39,6 +39,10 @@ const tideDashboardApi = RTKQueryApi.injectEndpoints({ params, }; }, + transformResponse: (response, _meta, arg) => ({ + ...response, + category: arg.category, + }), }), }), }); diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index ba71da2aa6..3ead203b0e 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -1,5 +1,4 @@ import React, { useMemo } from 'react'; -import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { CATEGORY } from './FilterByCategory'; @@ -95,9 +94,8 @@ const getColumnTypes = (t) => ({ }, // More }); -const useTableColumns = () => { +const useTableColumns = (category) => { const { t } = useTranslation(); - const category = useSelector(state => state.blip.tideDashboard.category); const columns = useMemo(() => { const columnTypes = getColumnTypes(t); From 12d95818bc9e08115eeca7241b423fe37e571be9 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 12 Mar 2026 19:52:33 -0700 Subject: [PATCH 07/28] WEB-4460 improve comment for visual glitch fix --- app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index 837ceebe19..b6f5ee1f25 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -49,7 +49,8 @@ const TideDashboard = () => { { skip: !selectedClinicId } ); - // Sync category to data fetching resolution in order to prevent visual glitch + // Sync category to data fetching resolution; prevents visual glitch due to + // category updating view before the API call resolves and updates it again const resolvedCategory = data?.category || category; const tableColumns = useTableColumns(resolvedCategory); From 3f6710adfa66356be43d2fb5114abfdaa395ef05 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Fri, 13 Mar 2026 10:05:11 -0700 Subject: [PATCH 08/28] WEB-4460 create high columns --- .../clinicworkspace/TideDashboardV2/Cells.js | 20 ++++++++++++-- .../TideDashboardV2/useTableColumns.js | 26 ++++++++++++++----- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 8ad84b4145..61690d2205 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -62,6 +62,14 @@ export const TimeInTargetPercentCell = ({ patient }) => { return ; }; +export const TimeInVeryLowPercentCell = ({ patient }) => { + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInVeryLowPercent; + const value = utils.formatDecimal(rawValue * 100, 0); + + return ; +}; + export const TimeInAnyLowPercentCell = ({ patient }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInAnyLowPercent; @@ -70,9 +78,17 @@ export const TimeInAnyLowPercentCell = ({ patient }) => { return ; }; -export const TimeInVeryLowPercentCell = ({ patient }) => { +export const TimeInVeryHighPercentCell = ({ patient }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); - const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInVeryLowPercent; + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInVeryHighPercent; + const value = utils.formatDecimal(rawValue * 100, 0); + + return ; +}; + +export const TimeInAnyHighPercentCell = ({ patient }) => { + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInAnyHighPercent; const value = utils.formatDecimal(rawValue * 100, 0); return ; diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index 3ead203b0e..69efc05e43 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -11,6 +11,8 @@ import { TimeInRangePercentBarChartCell, TimeInVeryLowPercentCell, TimeInAnyLowPercentCell, + TimeInVeryHighPercentCell, + TimeInAnyHighPercentCell, TimeInTargetPercentCell, } from './Cells'; @@ -47,17 +49,29 @@ const getColumnTypes = (t) => ({ render: patient => , }, timeInVeryLow: { - title: t('% Time < 54'), + title: t('% Time < 54'), // TODO: Fix to be variable based on unit field: 'timeInVeryLow', align: 'center', render: patient => , }, timeInAnyLow: { - title: t('% Time < 70'), + title: t('% Time < 70'), // TODO: Fix to be variable based on unit field: 'timeInAnyLow', align: 'center', render: patient => , }, + timeInVeryHigh: { + title: t('% Time > 180'), // TODO: Fix to be variable based on unit + field: 'timeInVeryHigh', + align: 'center', + render: patient => , + }, + timeInAnyHigh: { + title: t('% Time > 250'), // TODO: Fix to be variable based on unit + field: 'timeInAnyHigh', + align: 'center', + render: patient => , + }, timeInTarget: { title: t('% TIR 70-180'), field: 'timeInTarget', @@ -133,8 +147,8 @@ const useTableColumns = (category) => { columnTypes.patientDetails, columnTypes.flag, columnTypes.avgGlucose, - // columnTypes.timeInVeryLow, // TODO: Implement "high" columns - // columnTypes.timeInAnyLow, + columnTypes.timeInVeryHigh, + columnTypes.timeInAnyHigh, columnTypes.timeInTarget, columnTypes.timeInRangeBarChart, columnTypes.changeInTIR, @@ -147,9 +161,9 @@ const useTableColumns = (category) => { switch(category) { case CATEGORY.DEFAULT: return standardColumnSet; case CATEGORY.VERY_LOW: return lowColumnSet; - case CATEGORY.LOW: return lowColumnSet; + case CATEGORY.ANY_LOW: return lowColumnSet; case CATEGORY.DROP_IN_TIR: return standardColumnSet; - case CATEGORY.HIGH: return highColumnSet; + case CATEGORY.ANY_HIGH: return highColumnSet; case CATEGORY.VERY_HIGH: return highColumnSet; case CATEGORY.LOW_CGM_WEAR: return standardColumnSet; case CATEGORY.TARGET: return standardColumnSet; From 5e2d58009f70019871b730b29a15900c0bbf06dc Mon Sep 17 00:00:00 2001 From: henry-tp Date: Fri, 13 Mar 2026 10:26:50 -0700 Subject: [PATCH 09/28] WEB-4460 make column headers unit-specific --- .../TideDashboardV2/useTableColumns.js | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index 69efc05e43..37ac9cf77f 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -1,6 +1,11 @@ import React, { useMemo } from 'react'; +import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { CATEGORY } from './FilterByCategory'; +import { MGDL_UNITS } from '../../../core/constants'; +import mapValues from 'lodash/mapValues'; +import { utils as vizUtils } from '@tidepool/viz'; +const { DEFAULT_BG_BOUNDS } = vizUtils.constants; import { AvgGlucoseCell, @@ -18,7 +23,7 @@ import { import TagListCell from '../components/TagListCell'; -const getColumnTypes = (t) => ({ +const getColumnTypes = (t, thresholds) => ({ patientDetails: { title: t('Patient Details'), field: 'fullName', @@ -49,31 +54,31 @@ const getColumnTypes = (t) => ({ render: patient => , }, timeInVeryLow: { - title: t('% Time < 54'), // TODO: Fix to be variable based on unit + title: `${t('% Time')} < ${thresholds.veryLowThreshold}`, field: 'timeInVeryLow', align: 'center', render: patient => , }, timeInAnyLow: { - title: t('% Time < 70'), // TODO: Fix to be variable based on unit + title: `${t('% Time')} < ${thresholds.targetLowerBound}`, field: 'timeInAnyLow', align: 'center', render: patient => , }, timeInVeryHigh: { - title: t('% Time > 180'), // TODO: Fix to be variable based on unit + title: `${t('% Time')} > ${thresholds.veryHighThreshold}`, field: 'timeInVeryHigh', align: 'center', render: patient => , }, timeInAnyHigh: { - title: t('% Time > 250'), // TODO: Fix to be variable based on unit + title: `${t('% Time')} > ${thresholds.targetUpperBound}`, field: 'timeInAnyHigh', align: 'center', render: patient => , }, timeInTarget: { - title: t('% TIR 70-180'), + title: `${t('% TIR')} ${thresholds.targetLowerBound}-${thresholds.targetUpperBound}`, field: 'timeInTarget', align: 'center', render: patient => , @@ -108,11 +113,22 @@ const getColumnTypes = (t) => ({ }, // More }); +const getFormattedThresholds = (clinicBgUnits) => { + const thresholds = DEFAULT_BG_BOUNDS[clinicBgUnits]; + const precision = clinicBgUnits === MGDL_UNITS ? 0 : 1; + + return mapValues(thresholds, value => value.toFixed(precision)); +}; + const useTableColumns = (category) => { const { t } = useTranslation(); + const selectedClinicId = useSelector((state) => state.blip.selectedClinicId); + const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); + const clinicBgUnits = clinic?.preferredBgUnits || MGDL_UNITS; const columns = useMemo(() => { - const columnTypes = getColumnTypes(t); + const thresholds = getFormattedThresholds(clinicBgUnits); + const columnTypes = getColumnTypes(t, thresholds); const standardColumnSet = [ columnTypes.patientDetails, @@ -169,7 +185,7 @@ const useTableColumns = (category) => { case CATEGORY.TARGET: return standardColumnSet; default: return standardColumnSet; } - }, [category]); + }, [category, clinicBgUnits]); return columns; }; From 548afe3610bd7df3eeb64830f949274a9ea20367 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Mon, 16 Mar 2026 16:47:10 -0700 Subject: [PATCH 10/28] WEB-4460 add patient drawer --- .../PatientDrawer/CGMDeltaSummary/index.js | 2 +- .../PatientDrawer/CGMStatistics/index.js | 2 +- .../MenuBar/CGMClipboardButton.js | 4 +-- .../PatientDrawer/MenuBar/MenuBar.js | 12 ++++---- .../PatientDrawer/MenuBar/index.js | 0 .../PatientDrawer/Overview.js | 0 .../PatientDrawer/PatientDrawer.js | 8 +++--- .../PatientDrawer/StackedDaily.js | 8 +++--- .../PatientDrawer/getReportDaysText.js | 2 +- .../PatientDrawer/index.js | 0 .../useAgpCGM/buildGenerateAGPImages.js | 2 +- .../PatientDrawer/useAgpCGM/getOpts.js | 2 +- .../PatientDrawer/useAgpCGM/getQueries.js | 4 +-- .../PatientDrawer/useAgpCGM/index.js | 0 .../PatientDrawer/useAgpCGM/useAgpCGM.js | 6 ++-- .../clinicworkspace/TideDashboardV2/Cells.js | 12 ++++++-- .../PatientDrawerController.js | 28 +++++++++++++++++++ .../TideDashboardV2/TideDashboardV2.js | 5 +++- .../TideDashboardV2/tideDashboardSlice.js | 13 ++++++++- app/pages/dashboard/TideDashboard.js | 4 +-- 20 files changed, 82 insertions(+), 32 deletions(-) rename app/{pages/dashboard => components}/PatientDrawer/CGMDeltaSummary/index.js (99%) rename app/{pages/dashboard => components}/PatientDrawer/CGMStatistics/index.js (98%) rename app/{pages/dashboard => components}/PatientDrawer/MenuBar/CGMClipboardButton.js (94%) rename app/{pages/dashboard => components}/PatientDrawer/MenuBar/MenuBar.js (93%) rename app/{pages/dashboard => components}/PatientDrawer/MenuBar/index.js (100%) rename app/{pages/dashboard => components}/PatientDrawer/Overview.js (100%) rename app/{pages/dashboard => components}/PatientDrawer/PatientDrawer.js (95%) rename app/{pages/dashboard => components}/PatientDrawer/StackedDaily.js (97%) rename app/{pages/dashboard => components}/PatientDrawer/getReportDaysText.js (94%) rename app/{pages/dashboard => components}/PatientDrawer/index.js (100%) rename app/{pages/dashboard => components}/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js (97%) rename app/{pages/dashboard => components}/PatientDrawer/useAgpCGM/getOpts.js (98%) rename app/{pages/dashboard => components}/PatientDrawer/useAgpCGM/getQueries.js (95%) rename app/{pages/dashboard => components}/PatientDrawer/useAgpCGM/index.js (100%) rename app/{pages/dashboard => components}/PatientDrawer/useAgpCGM/useAgpCGM.js (95%) create mode 100644 app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js diff --git a/app/pages/dashboard/PatientDrawer/CGMDeltaSummary/index.js b/app/components/PatientDrawer/CGMDeltaSummary/index.js similarity index 99% rename from app/pages/dashboard/PatientDrawer/CGMDeltaSummary/index.js rename to app/components/PatientDrawer/CGMDeltaSummary/index.js index 238b1ec451..ed38fbb8e1 100644 --- a/app/pages/dashboard/PatientDrawer/CGMDeltaSummary/index.js +++ b/app/components/PatientDrawer/CGMDeltaSummary/index.js @@ -6,7 +6,7 @@ import { utils as vizUtils, colors as vizColors } from '@tidepool/viz'; import styled from '@emotion/styled'; const { bankersRound } = vizUtils.stat; const { getTimezoneFromTimePrefs } = vizUtils.datetime; -import { MS_IN_HOUR } from '../../../../core/constants'; +import { MS_IN_HOUR } from '../../../core/constants'; import getReportDaysText from '../getReportDaysText'; diff --git a/app/pages/dashboard/PatientDrawer/CGMStatistics/index.js b/app/components/PatientDrawer/CGMStatistics/index.js similarity index 98% rename from app/pages/dashboard/PatientDrawer/CGMStatistics/index.js rename to app/components/PatientDrawer/CGMStatistics/index.js index 5645dbab2b..45e9826a72 100644 --- a/app/pages/dashboard/PatientDrawer/CGMStatistics/index.js +++ b/app/components/PatientDrawer/CGMStatistics/index.js @@ -5,7 +5,7 @@ import { Flex, Box, Text } from 'theme-ui'; import { utils as vizUtils } from '@tidepool/viz'; const { formatDatum, bankersRound } = vizUtils.stat; const { getTimezoneFromTimePrefs } = vizUtils.datetime; -import { MGDL_UNITS } from '../../../../core/constants'; +import { MGDL_UNITS } from '../../../core/constants'; import getReportDaysText from '../getReportDaysText'; const TableRow = ({ label, sublabel, value, units, id }) => { diff --git a/app/pages/dashboard/PatientDrawer/MenuBar/CGMClipboardButton.js b/app/components/PatientDrawer/MenuBar/CGMClipboardButton.js similarity index 94% rename from app/pages/dashboard/PatientDrawer/MenuBar/CGMClipboardButton.js rename to app/components/PatientDrawer/MenuBar/CGMClipboardButton.js index bc17372335..6dd7cf9060 100644 --- a/app/pages/dashboard/PatientDrawer/MenuBar/CGMClipboardButton.js +++ b/app/components/PatientDrawer/MenuBar/CGMClipboardButton.js @@ -1,8 +1,8 @@ import React, { useEffect, useState, useMemo } from 'react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; -import Button from '../../../../components/elements/Button'; -import { MS_IN_HOUR } from '../../../../core/constants'; +import Button from '../../../components/elements/Button'; +import { MS_IN_HOUR } from '../../../core/constants'; import { Box, Flex } from 'theme-ui'; import { utils as vizUtils } from '@tidepool/viz'; const { agpCGMText } = vizUtils.text; diff --git a/app/pages/dashboard/PatientDrawer/MenuBar/MenuBar.js b/app/components/PatientDrawer/MenuBar/MenuBar.js similarity index 93% rename from app/pages/dashboard/PatientDrawer/MenuBar/MenuBar.js rename to app/components/PatientDrawer/MenuBar/MenuBar.js index 8cc65c6bf8..543f491e96 100644 --- a/app/pages/dashboard/PatientDrawer/MenuBar/MenuBar.js +++ b/app/components/PatientDrawer/MenuBar/MenuBar.js @@ -1,20 +1,20 @@ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; -import * as actions from '../../../../redux/actions'; +import * as actions from '../../../redux/actions'; import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { push } from 'connected-react-router'; import { Flex, Box, Text } from 'theme-ui'; import { colors as vizColors } from '@tidepool/viz'; -import Button from '../../../../components/elements/Button'; +import Button from '../../../components/elements/Button'; import moment from 'moment'; -import PatientLastReviewed from '../../../../components/clinic/PatientLastReviewed'; +import PatientLastReviewed from '../../../components/clinic/PatientLastReviewed'; import { useFlags } from 'launchdarkly-react-client-sdk'; import CGMClipboardButton from './CGMClipboardButton'; -import api from '../../../../core/api'; +import api from '../../../core/api'; import { map, keys } from 'lodash'; -import copyIcon from '../../../../core/icons/copyIcon.svg'; -import viewIcon from '../../../../core/icons/viewIcon.svg'; +import copyIcon from '../../../core/icons/copyIcon.svg'; +import viewIcon from '../../../core/icons/viewIcon.svg'; export const OVERVIEW_TAB_INDEX = 0; export const STACKED_DAILY_TAB_INDEX = 1; diff --git a/app/pages/dashboard/PatientDrawer/MenuBar/index.js b/app/components/PatientDrawer/MenuBar/index.js similarity index 100% rename from app/pages/dashboard/PatientDrawer/MenuBar/index.js rename to app/components/PatientDrawer/MenuBar/index.js diff --git a/app/pages/dashboard/PatientDrawer/Overview.js b/app/components/PatientDrawer/Overview.js similarity index 100% rename from app/pages/dashboard/PatientDrawer/Overview.js rename to app/components/PatientDrawer/Overview.js diff --git a/app/pages/dashboard/PatientDrawer/PatientDrawer.js b/app/components/PatientDrawer/PatientDrawer.js similarity index 95% rename from app/pages/dashboard/PatientDrawer/PatientDrawer.js rename to app/components/PatientDrawer/PatientDrawer.js index 92df8f3673..c8f72b1656 100644 --- a/app/pages/dashboard/PatientDrawer/PatientDrawer.js +++ b/app/components/PatientDrawer/PatientDrawer.js @@ -1,5 +1,5 @@ -import React from 'react'; -import Icon from '../../../components/elements/Icon'; +import React, { useState } from 'react'; +import Icon from '../../components/elements/Icon'; import { useLocation, useHistory } from 'react-router-dom'; import Drawer from '@material-ui/core/Drawer'; import styled from '@emotion/styled'; @@ -12,8 +12,8 @@ import Overview from './Overview'; import StackedDaily from './StackedDaily'; import MenuBar, { OVERVIEW_TAB_INDEX, STACKED_DAILY_TAB_INDEX } from './MenuBar'; import useAgpCGM from './useAgpCGM'; -import { shadows } from '../../../themes/baseTheme'; -import { useScrollToTop } from '../../../core/hooks'; +import { shadows } from '../../themes/baseTheme'; +import { useScrollToTop } from '../../core/hooks'; const StyledCloseButton = styled(Icon)` position: absolute; diff --git a/app/pages/dashboard/PatientDrawer/StackedDaily.js b/app/components/PatientDrawer/StackedDaily.js similarity index 97% rename from app/pages/dashboard/PatientDrawer/StackedDaily.js rename to app/components/PatientDrawer/StackedDaily.js index 246c50175c..d09fab05ea 100644 --- a/app/pages/dashboard/PatientDrawer/StackedDaily.js +++ b/app/components/PatientDrawer/StackedDaily.js @@ -15,13 +15,13 @@ const { getLocalizedCeiling } = vizUtils.datetime; import tidelineBlip from 'tideline/plugins/blip'; const chartDailyFactory = tidelineBlip.oneday; -import { MS_IN_DAY } from '../../../core/constants'; +import { MS_IN_DAY } from '../../core/constants'; import { NoPatientData } from './Overview'; import { STATUS } from './useAgpCGM'; -import { Body1, Body2 } from '../../../components/elements/FontStyles'; -import Button from '../../../components/elements/Button'; +import { Body1, Body2 } from '../../components/elements/FontStyles'; +import Button from '../../components/elements/Button'; import { STACKED_DAILY_TAB_INDEX } from './MenuBar'; -import BgLegend from '../../../components/chart/BgLegend'; +import BgLegend from '../../components/chart/BgLegend'; const CHART_HEIGHT = 200; diff --git a/app/pages/dashboard/PatientDrawer/getReportDaysText.js b/app/components/PatientDrawer/getReportDaysText.js similarity index 94% rename from app/pages/dashboard/PatientDrawer/getReportDaysText.js rename to app/components/PatientDrawer/getReportDaysText.js index 7e88335997..36f62dc66a 100644 --- a/app/pages/dashboard/PatientDrawer/getReportDaysText.js +++ b/app/components/PatientDrawer/getReportDaysText.js @@ -1,5 +1,5 @@ import moment from 'moment'; -import { MS_IN_MIN } from '../../../core/constants'; +import { MS_IN_MIN } from '../../core/constants'; import isNumber from 'lodash/isNumber'; import { utils as vizUtils } from '@tidepool/viz'; const { getOffset, formatDateRange } = vizUtils.datetime; diff --git a/app/pages/dashboard/PatientDrawer/index.js b/app/components/PatientDrawer/index.js similarity index 100% rename from app/pages/dashboard/PatientDrawer/index.js rename to app/components/PatientDrawer/index.js diff --git a/app/pages/dashboard/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js b/app/components/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js similarity index 97% rename from app/pages/dashboard/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js rename to app/components/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js index 9b89eb67a0..f7335ba5b7 100644 --- a/app/pages/dashboard/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js +++ b/app/components/PatientDrawer/useAgpCGM/buildGenerateAGPImages.js @@ -3,7 +3,7 @@ import _ from 'lodash'; import { utils as vizUtils } from '@tidepool/viz'; import Plotly from 'plotly.js-basic-dist-min'; -import * as actions from '../../../../redux/actions'; +import * as actions from '../../../redux/actions'; export const buildGenerateAGPImages = (dispatch) => { const props = { diff --git a/app/pages/dashboard/PatientDrawer/useAgpCGM/getOpts.js b/app/components/PatientDrawer/useAgpCGM/getOpts.js similarity index 98% rename from app/pages/dashboard/PatientDrawer/useAgpCGM/getOpts.js rename to app/components/PatientDrawer/useAgpCGM/getOpts.js index 4f017aec79..9907b7917e 100644 --- a/app/pages/dashboard/PatientDrawer/useAgpCGM/getOpts.js +++ b/app/components/PatientDrawer/useAgpCGM/getOpts.js @@ -2,7 +2,7 @@ import moment from 'moment-timezone'; import _ from 'lodash'; import get from 'lodash/get'; import { utils as vizUtils } from '@tidepool/viz'; -import utils from '../../../../core/utils'; +import utils from '../../../core/utils'; const getTimezoneFromTimePrefs = vizUtils.datetime.getTimezoneFromTimePrefs; diff --git a/app/pages/dashboard/PatientDrawer/useAgpCGM/getQueries.js b/app/components/PatientDrawer/useAgpCGM/getQueries.js similarity index 95% rename from app/pages/dashboard/PatientDrawer/useAgpCGM/getQueries.js rename to app/components/PatientDrawer/useAgpCGM/getQueries.js index 6d6750c203..1d1af429f0 100644 --- a/app/pages/dashboard/PatientDrawer/useAgpCGM/getQueries.js +++ b/app/components/PatientDrawer/useAgpCGM/getQueries.js @@ -2,8 +2,8 @@ import _ from 'lodash'; import { utils as vizUtils } from '@tidepool/viz'; const { commonStats } = vizUtils.stat; -import utils from '../../../../core/utils'; -import { DEFAULT_GLYCEMIC_RANGES } from '../../../../core/glycemicRangesUtils'; +import utils from '../../../core/utils'; +import { DEFAULT_GLYCEMIC_RANGES } from '../../../core/glycemicRangesUtils'; const getQueries = ( data, diff --git a/app/pages/dashboard/PatientDrawer/useAgpCGM/index.js b/app/components/PatientDrawer/useAgpCGM/index.js similarity index 100% rename from app/pages/dashboard/PatientDrawer/useAgpCGM/index.js rename to app/components/PatientDrawer/useAgpCGM/index.js diff --git a/app/pages/dashboard/PatientDrawer/useAgpCGM/useAgpCGM.js b/app/components/PatientDrawer/useAgpCGM/useAgpCGM.js similarity index 95% rename from app/pages/dashboard/PatientDrawer/useAgpCGM/useAgpCGM.js rename to app/components/PatientDrawer/useAgpCGM/useAgpCGM.js index fa8625a378..b33fb10aa2 100644 --- a/app/pages/dashboard/PatientDrawer/useAgpCGM/useAgpCGM.js +++ b/app/components/PatientDrawer/useAgpCGM/useAgpCGM.js @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import * as actions from '../../../../redux/actions'; +import * as actions from '../../../redux/actions'; import buildGenerateAGPImages from './buildGenerateAGPImages'; import moment from 'moment'; @@ -131,8 +131,8 @@ const useAgpCGM = ( return { status: lastCompletedStep, svgDataURLS: isCorrectPatientInState ? pdf.opts?.svgDataURLS : null, - agpCGM: isCorrectPatientInState ? cloneDeep(pdf.data?.agpCGM) : null, - offsetAgpCGM: isCorrectPatientInState ? cloneDeep(pdf.data?.offsetAgpCGM) : null, + agpCGM: isCorrectPatientInState ? pdf.data?.agpCGM : null, + offsetAgpCGM: isCorrectPatientInState ? pdf.data?.offsetAgpCGM : null, }; }; diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 61690d2205..9e9593c806 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -1,5 +1,5 @@ import React from 'react'; -import { useSelector } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { Box, Text } from 'theme-ui'; import { utils as vizUtils } from '@tidepool/viz'; @@ -9,13 +9,21 @@ import { MGDL_UNITS } from '../../../core/constants'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; +import { setPatientDrawerPatientId } from './tideDashboardSlice'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); + const dispatch = useDispatch(); const { fullName, birthDate, mrn } = patient || {}; - return + const handleClick = () => { + if (!patient.id) return; + + dispatch(setPatientDrawerPatientId(patient.id)); + }; + + return {fullName} {t('DOB:')} {birthDate} {mrn && , {t('MRN: {{mrn}}', { mrn: mrn })}} diff --git a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js new file mode 100644 index 0000000000..c7e6160968 --- /dev/null +++ b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import PatientDrawer from '../../../components/PatientDrawer/PatientDrawer'; +import { setPatientDrawerPatientId } from './tideDashboardSlice'; + +const trackMetric = () => {}; + +const PatientDrawerController = ({ api }) => { + const dispatch = useDispatch(); + const patientId = useSelector(state => state.blip.tideDashboard.patientDrawer.patientId); + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + + const handleClose = () => { + dispatch(setPatientDrawerPatientId(null)); + }; + + return ( + + ); +}; + +export default PatientDrawerController; diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index 44a833ea2a..7d3f0fb814 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -12,6 +12,7 @@ import FilterByDataRecency from './FilterByDataRecency'; import FilterBySummaryPeriod from './FilterBySummaryPeriod'; import PaginationControls from '../components/PaginationControls'; import ActiveFilterCount from '../components/ActiveFilterCount'; +import PatientDrawerController from './PatientDrawerController'; import { resetTideDashboardState, setOffset } from './tideDashboardSlice'; import { useGetTideDashboardPatientsQuery } from './tideDashboardApi'; @@ -26,7 +27,7 @@ const LIMIT = 12; const Divider = () => ; -const TideDashboard = () => { +const TideDashboard = ({ api }) => { const { t } = useTranslation(); const dispatch = useDispatch(); @@ -100,6 +101,8 @@ const TideDashboard = () => { onOffsetChange={handleChangeOffset} /> + + ); }; diff --git a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardSlice.js b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardSlice.js index d44e4d19bb..e9d5ef5850 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardSlice.js +++ b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardSlice.js @@ -5,6 +5,9 @@ import { CATEGORY } from './FilterByCategory'; const initialState = { category: CATEGORY.DEFAULT, offset: 0, + patientDrawer: { + patientId: null, + }, }; const tideDashboardSlice = createSlice({ @@ -17,9 +20,17 @@ const tideDashboardSlice = createSlice({ setOffset: (state, action) => { state.offset = action.payload; }, + setPatientDrawerPatientId: (state, action) => { + state.patientDrawer.patientId = action.payload; + }, resetTideDashboardState: () => initialState, }, }); -export const { setCategory, setOffset, resetTideDashboardState } = tideDashboardSlice.actions; +export const { + setCategory, + setOffset, + setPatientDrawerPatientId, + resetTideDashboardState, +} = tideDashboardSlice.actions; export default tideDashboardSlice.reducer; diff --git a/app/pages/dashboard/TideDashboard.js b/app/pages/dashboard/TideDashboard.js index 1daec2913b..dc4dd76d1f 100644 --- a/app/pages/dashboard/TideDashboard.js +++ b/app/pages/dashboard/TideDashboard.js @@ -58,7 +58,7 @@ import PopoverMenu from '../../components/elements/PopoverMenu'; import RadioGroup from '../../components/elements/RadioGroup'; import DeltaBar from '../../components/elements/DeltaBar'; import Pill from '../../components/elements/Pill'; -import PatientDrawer, { isValidAgpPeriod } from './PatientDrawer'; +import PatientDrawer, { isValidAgpPeriod } from '../../components/PatientDrawer'; import utils from '../../core/utils'; import { @@ -85,7 +85,7 @@ import DataInIcon from '../../core/icons/DataInIcon.svg'; import { colors, fontWeights, radii } from '../../themes/baseTheme'; import PatientLastReviewed from '../../components/clinic/PatientLastReviewed'; import { DEFAULT_GLYCEMIC_RANGES } from '../../core/glycemicRangesUtils'; -import { OVERVIEW_TAB_INDEX } from './PatientDrawer/MenuBar/MenuBar'; +import { OVERVIEW_TAB_INDEX } from '../../components/PatientDrawer/MenuBar/MenuBar'; const { Loader } = vizComponents; const { formatBgValue } = vizUtils.bg; From b399e42184d8aff96c9f68a2f55e930559c493a9 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Mon, 16 Mar 2026 17:05:46 -0700 Subject: [PATCH 11/28] WEB-4460 fix scroll issue --- app/components/PatientDrawer/PatientDrawer.js | 10 +++------- .../TideDashboardV2/PatientDrawerController.js | 5 +++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/components/PatientDrawer/PatientDrawer.js b/app/components/PatientDrawer/PatientDrawer.js index c8f72b1656..b85a406f01 100644 --- a/app/components/PatientDrawer/PatientDrawer.js +++ b/app/components/PatientDrawer/PatientDrawer.js @@ -6,14 +6,12 @@ import styled from '@emotion/styled'; import { makeStyles } from '@material-ui/core/styles'; import CloseRoundedIcon from '@material-ui/icons/CloseRounded'; import { Box } from 'theme-ui'; -import { useFlags } from 'launchdarkly-react-client-sdk'; import Overview from './Overview'; import StackedDaily from './StackedDaily'; import MenuBar, { OVERVIEW_TAB_INDEX, STACKED_DAILY_TAB_INDEX } from './MenuBar'; import useAgpCGM from './useAgpCGM'; import { shadows } from '../../themes/baseTheme'; -import { useScrollToTop } from '../../core/hooks'; const StyledCloseButton = styled(Icon)` position: absolute; @@ -64,7 +62,6 @@ const DrawerContent = ({ patientId, onClose, api, trackMetric, period }) => { const agpPeriodInDays = getAgpPeriodInDays(period); const agpCGMData = useAgpCGM(api, patientId, agpPeriodInDays); const contentRef = React.useRef(undefined); - useScrollToTop(contentRef?.current, [selectedTab]); function setDrawerTabParam(tabIndex) { const { search, pathname } = location; @@ -76,11 +73,12 @@ const DrawerContent = ({ patientId, onClose, api, trackMetric, period }) => { function handleSelectTab(tabIndex) { setSelectedTab(parseInt(tabIndex, 10)); setDrawerTabParam(tabIndex); + contentRef?.current?.scrollTo(0, 0); } const handleContentScroll = (e) => { setScrolledToTop((e.target.scrollTop || 0) <= 5); - } + }; return ( <> @@ -110,10 +108,8 @@ const DrawerContent = ({ patientId, onClose, api, trackMetric, period }) => { const PatientDrawer = ({ patientId, onClose, api, trackMetric, period }) => { const classes = useStyles(); - const { showTideDashboardPatientDrawer } = useFlags(); - const isOpen = !!patientId && isValidAgpPeriod(period); - if (!showTideDashboardPatientDrawer) return null; + const isOpen = !!patientId && isValidAgpPeriod(period); return ( {}; @@ -10,10 +11,14 @@ const PatientDrawerController = ({ api }) => { const patientId = useSelector(state => state.blip.tideDashboard.patientDrawer.patientId); const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const { showTideDashboardPatientDrawer } = useFlags(); + const handleClose = () => { dispatch(setPatientDrawerPatientId(null)); }; + if (!showTideDashboardPatientDrawer) return null; + return ( Date: Mon, 16 Mar 2026 17:22:03 -0700 Subject: [PATCH 12/28] WEB-4460 update drawer to use url params --- app/core/navutils.js | 4 ++-- .../clinicworkspace/TideDashboardV2/Cells.js | 13 ++++++++---- .../PatientDrawerController.js | 20 +++++++++++-------- .../TideDashboardV2/tideDashboardSlice.js | 7 ------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/app/core/navutils.js b/app/core/navutils.js index 375e32273e..55d3b92c77 100644 --- a/app/core/navutils.js +++ b/app/core/navutils.js @@ -44,11 +44,11 @@ export const getPatientListLink = (clinicFlowActive, selectedClinicId, query, pa const drawerTab = query?.drawerTab; if (dashboard && drawerTab !== undefined && patientId) { - return `/dashboard/${dashboard}?drawerPatientId=${patientId}&drawerTab=${drawerTab}`; + return `/clinic-workspace/tide-dashboard?drawerPatientId=${patientId}&drawerTab=${drawerTab}`; } if (dashboard) { - return `/dashboard/${dashboard}`; + return '/clinic-workspace/tide-dashboard'; } if (clinicFlowActive && selectedClinicId) { diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 9e9593c806..4ec2ac90e9 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -1,6 +1,7 @@ import React from 'react'; -import { useSelector, useDispatch } from 'react-redux'; +import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; +import { useLocation, useHistory } from 'react-router-dom'; import { Box, Text } from 'theme-ui'; import { utils as vizUtils } from '@tidepool/viz'; const { bankersRound } = vizUtils.stat; @@ -9,18 +10,22 @@ import { MGDL_UNITS } from '../../../core/constants'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; -import { setPatientDrawerPatientId } from './tideDashboardSlice'; +import { OVERVIEW_TAB_INDEX } from '../../../components/PatientDrawer/MenuBar/MenuBar'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); - const dispatch = useDispatch(); + const { search, pathname } = useLocation(); + const history = useHistory(); const { fullName, birthDate, mrn } = patient || {}; const handleClick = () => { if (!patient.id) return; - dispatch(setPatientDrawerPatientId(patient.id)); + const params = new URLSearchParams(search); + params.set('drawerPatientId', patient.id); + params.set('drawerTab', OVERVIEW_TAB_INDEX); + history.replace({ pathname, search: params.toString() }); }; return diff --git a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js index d63ac6aeb6..885fd415cd 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js +++ b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js @@ -1,20 +1,24 @@ -import React from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React, { useCallback } from 'react'; +import { useSelector } from 'react-redux'; +import { useLocation, useHistory } from 'react-router-dom'; import PatientDrawer from '../../../components/PatientDrawer/PatientDrawer'; -import { setPatientDrawerPatientId } from './tideDashboardSlice'; import { useFlags } from 'launchdarkly-react-client-sdk'; const trackMetric = () => {}; const PatientDrawerController = ({ api }) => { - const dispatch = useDispatch(); - const patientId = useSelector(state => state.blip.tideDashboard.patientDrawer.patientId); const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); - const { showTideDashboardPatientDrawer } = useFlags(); + const { search, pathname } = useLocation(); + const history = useHistory(); + + const drawerPatientId = new URLSearchParams(search)?.get('drawerPatientId') || null; const handleClose = () => { - dispatch(setPatientDrawerPatientId(null)); + const params = new URLSearchParams(search); + params.delete('drawerPatientId'); + params.delete('drawerTab'); + history.replace({ pathname, search: params.toString() }); }; if (!showTideDashboardPatientDrawer) return null; @@ -22,7 +26,7 @@ const PatientDrawerController = ({ api }) => { return ( { state.offset = action.payload; }, - setPatientDrawerPatientId: (state, action) => { - state.patientDrawer.patientId = action.payload; - }, resetTideDashboardState: () => initialState, }, }); @@ -30,7 +24,6 @@ const tideDashboardSlice = createSlice({ export const { setCategory, setOffset, - setPatientDrawerPatientId, resetTideDashboardState, } = tideDashboardSlice.actions; export default tideDashboardSlice.reducer; From e157429fc1f7d9ad1dd7ff3a270e5644449cf36e Mon Sep 17 00:00:00 2001 From: henry-tp Date: Mon, 16 Mar 2026 17:44:37 -0700 Subject: [PATCH 13/28] WEB-4460 add link when no patient drawer perms --- .../clinicworkspace/TideDashboardV2/Cells.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 4ec2ac90e9..c62115e560 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -1,31 +1,42 @@ import React from 'react'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { useLocation, useHistory } from 'react-router-dom'; import { Box, Text } from 'theme-ui'; import { utils as vizUtils } from '@tidepool/viz'; const { bankersRound } = vizUtils.stat; import { MGDL_UNITS } from '../../../core/constants'; +import { push } from 'connected-react-router'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; import { OVERVIEW_TAB_INDEX } from '../../../components/PatientDrawer/MenuBar/MenuBar'; +import { useFlags } from 'launchdarkly-react-client-sdk'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); const { search, pathname } = useLocation(); const history = useHistory(); + const dispatch = useDispatch(); + + const { showTideDashboardPatientDrawer } = useFlags(); const { fullName, birthDate, mrn } = patient || {}; const handleClick = () => { if (!patient.id) return; - const params = new URLSearchParams(search); - params.set('drawerPatientId', patient.id); - params.set('drawerTab', OVERVIEW_TAB_INDEX); - history.replace({ pathname, search: params.toString() }); + if (showTideDashboardPatientDrawer) { + const params = new URLSearchParams(search); + params.set('drawerPatientId', patient.id); + params.set('drawerTab', OVERVIEW_TAB_INDEX); + history.replace({ pathname, search: params.toString() }); + + return; + } + + dispatch(push(`/patients/${patient.id}/data?dashboard=tide`)); }; return From d0470f4bb671a6210e21941134b2dc78b51c8cd1 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 31 Mar 2026 12:58:25 -0700 Subject: [PATCH 14/28] WEB-4460 add flag cell --- .../clinicworkspace/TideDashboardV2/Cells.js | 86 ++++++++++++++++++- .../TideDashboardV2/useTableColumns.js | 2 + 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 61690d2205..e57a86de23 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -1,10 +1,11 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; -import { Box, Text } from 'theme-ui'; -import { utils as vizUtils } from '@tidepool/viz'; +import { Box, Flex, Text } from 'theme-ui'; +import { utils as vizUtils, colors as vizColors } from '@tidepool/viz'; const { bankersRound } = vizUtils.stat; import { MGDL_UNITS } from '../../../core/constants'; +import { colors } from '../../../themes/baseTheme'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; @@ -122,6 +123,86 @@ export const ChangeTIRCell = ({ patient }) => { />; }; +export const FlagCell = ({ patient }) => { + const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); + const period = patient?.summary?.cgmStats?.periods?.[summaryPeriod]; + + if (!period) return null; + + let value; + let rangeName; + let title; + + // TODO: Fix text to be bgUnit-sensitive + switch(true) { + case period.timeInVeryLowPercent > 0.01: + value = 'timeInVeryLowPercent'; + rangeName = 'veryLow'; + title = 'Very Low'; + break; + case period.timeInAnyLowPercent > 0.04: + value = 'timeInAnyLowPercent'; + rangeName = 'anyLow'; + title = 'Low'; + break; + case period.timeInVeryHighPercent > 0.05: + value = 'timeInVeryHighPercent'; + rangeName = 'veryHigh'; + title = 'Very High'; + break; + case period.timeInAnyHighPercent > 0.25: + value = 'timeInAnyHighPercent'; + rangeName = 'anyHigh'; + title = 'High'; + break; + case period.timeInTargetPercentDelta < -0.15: + value = 'timeInTargetPercentDelta'; + rangeName = 'anyLow'; + title = 'Large Drop in TIR'; + break; + case period.timeInTargetPercent < 0.70: + value = 'timeInTargetPercent'; + rangeName = 'anyLow'; + title = 'Low TIR'; + break; + case period.timeCGMUsePercent < 0.70: + value = 'timeCGMUsePercent'; + rangeName = 'anyLow'; + title = 'Low CGM Wear Time'; + break; + + // TODO: Need case for Meeting Targets + } + + if (!value) return null; + + return ( + + + + + + {title} + + + + ); +}; + export default { PatientCell, NumericTemplateCell, @@ -131,4 +212,5 @@ export default { ChangeTIRCell, GMICell, CGMUseCell, + FlagCell, }; diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index 37ac9cf77f..e094a83e2d 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -19,6 +19,7 @@ import { TimeInVeryHighPercentCell, TimeInAnyHighPercentCell, TimeInTargetPercentCell, + FlagCell, } from './Cells'; import TagListCell from '../components/TagListCell'; @@ -34,6 +35,7 @@ const getColumnTypes = (t, thresholds) => ({ title: t('Flag'), field: 'flag', align: 'center', + render: patient => , }, avgGlucose: { title: t('Avg Glucose'), From 2040be23a73c982443a5736c1e5ded894f33f43b Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 31 Mar 2026 14:00:01 -0700 Subject: [PATCH 15/28] WEB-4460 update flag cell to use category priority --- .../clinicworkspace/TideDashboardV2/Cells.js | 99 +++++++++---------- 1 file changed, 45 insertions(+), 54 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index e57a86de23..e6c6f4dd87 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -10,6 +10,7 @@ import { colors } from '../../../themes/baseTheme'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; +import { CATEGORY } from './FilterByCategory'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); @@ -124,60 +125,55 @@ export const ChangeTIRCell = ({ patient }) => { }; export const FlagCell = ({ patient }) => { + const { t } = useTranslation(); + const category = useSelector(state => state.blip.tideDashboard.category); const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const period = patient?.summary?.cgmStats?.periods?.[summaryPeriod]; + const { VERY_LOW, ANY_LOW, DROP_IN_TIR, ANY_HIGH, VERY_HIGH, LOW_CGM_WEAR, TARGET } = CATEGORY; + if (!period) return null; - let value; - let rangeName; - let title; - - // TODO: Fix text to be bgUnit-sensitive - switch(true) { - case period.timeInVeryLowPercent > 0.01: - value = 'timeInVeryLowPercent'; - rangeName = 'veryLow'; - title = 'Very Low'; - break; - case period.timeInAnyLowPercent > 0.04: - value = 'timeInAnyLowPercent'; - rangeName = 'anyLow'; - title = 'Low'; - break; - case period.timeInVeryHighPercent > 0.05: - value = 'timeInVeryHighPercent'; - rangeName = 'veryHigh'; - title = 'Very High'; - break; - case period.timeInAnyHighPercent > 0.25: - value = 'timeInAnyHighPercent'; - rangeName = 'anyHigh'; - title = 'High'; - break; - case period.timeInTargetPercentDelta < -0.15: - value = 'timeInTargetPercentDelta'; - rangeName = 'anyLow'; - title = 'Large Drop in TIR'; - break; - case period.timeInTargetPercent < 0.70: - value = 'timeInTargetPercent'; - rangeName = 'anyLow'; - title = 'Low TIR'; - break; - case period.timeCGMUsePercent < 0.70: - value = 'timeCGMUsePercent'; - rangeName = 'anyLow'; - title = 'Low CGM Wear Time'; - break; - - // TODO: Need case for Meeting Targets - } - - if (!value) return null; + const rangeName = (() => { + switch(true) { + // Current dashboard category takes priority + case category === VERY_LOW: return 'veryLow'; + case category === ANY_LOW: return 'anyLow'; + case category === VERY_HIGH: return 'veryHigh'; + case category === ANY_HIGH: return 'anyHigh'; + case category === DROP_IN_TIR: return 'dropInTIR'; + case category === VERY_LOW: return 'lowTIR'; + case category === LOW_CGM_WEAR: return 'lowSensorUsage'; + case category === TARGET: return 'meetingTargets'; + + // If no category, then read from summary + case period.timeInVeryLowPercent > 0.01: return 'veryLow'; + case period.timeInAnyLowPercent > 0.04: return 'anyLow'; + case period.timeInVeryHighPercent > 0.05: return 'veryHigh'; + case period.timeInAnyHighPercent > 0.25: return 'anyHigh'; + case period.timeInTargetPercentDelta < -0.15: return 'dropInTIR'; + case period.timeInTargetPercent < 0.70: return 'lowTIR'; + case period.timeCGMUsePercent < 0.70: return 'lowSensorUsage'; + + default: return null; + } + })(); + + if (!rangeName) return null; + + const flagLabels = { + veryLow: t('Very Low'), + anyLow: t('Low'), + veryHigh: t('Very High'), + anyHigh: t('High'), + dropInTIR: t('Large Drop in TIR'), + lowTIR: t('Low TIR'), + lowSensorUsage: t('Low CGM Wear Time'), + meetingTargets: t('Meeting Targets'), + }; return ( - + { alignItems: 'center', }}> - {title} + {flagLabels[rangeName] || ''} From 5bf9d476ca2a83cca92c2a8065bf6a979758101a Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 31 Mar 2026 14:17:20 -0700 Subject: [PATCH 16/28] WEB-4460 pass category through hook to remove jitter --- app/pages/clinicworkspace/TideDashboardV2/Cells.js | 3 +-- .../clinicworkspace/TideDashboardV2/useTableColumns.js | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index e6c6f4dd87..ffe1a1ff71 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -124,9 +124,8 @@ export const ChangeTIRCell = ({ patient }) => { />; }; -export const FlagCell = ({ patient }) => { +export const FlagCell = ({ patient, category = null, }) => { const { t } = useTranslation(); - const category = useSelector(state => state.blip.tideDashboard.category); const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const period = patient?.summary?.cgmStats?.periods?.[summaryPeriod]; diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index e094a83e2d..446f8f0a98 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -24,7 +24,7 @@ import { import TagListCell from '../components/TagListCell'; -const getColumnTypes = (t, thresholds) => ({ +const getColumnTypes = (t, category, thresholds) => ({ patientDetails: { title: t('Patient Details'), field: 'fullName', @@ -35,7 +35,7 @@ const getColumnTypes = (t, thresholds) => ({ title: t('Flag'), field: 'flag', align: 'center', - render: patient => , + render: patient => , }, avgGlucose: { title: t('Avg Glucose'), @@ -130,7 +130,7 @@ const useTableColumns = (category) => { const columns = useMemo(() => { const thresholds = getFormattedThresholds(clinicBgUnits); - const columnTypes = getColumnTypes(t, thresholds); + const columnTypes = getColumnTypes(t, category, thresholds); const standardColumnSet = [ columnTypes.patientDetails, From d0fb1803f25406a3b4db82a34ac9525a67bb1cf6 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 31 Mar 2026 15:08:49 -0700 Subject: [PATCH 17/28] WEb-4460 fix missing flag colors --- app/pages/clinicworkspace/TideDashboardV2/Cells.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index ffe1a1ff71..44c4176ee4 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -141,9 +141,8 @@ export const FlagCell = ({ patient, category = null, }) => { case category === VERY_HIGH: return 'veryHigh'; case category === ANY_HIGH: return 'anyHigh'; case category === DROP_IN_TIR: return 'dropInTIR'; - case category === VERY_LOW: return 'lowTIR'; case category === LOW_CGM_WEAR: return 'lowSensorUsage'; - case category === TARGET: return 'meetingTargets'; + case category === TARGET: return 'target'; // If no category, then read from summary case period.timeInVeryLowPercent > 0.01: return 'veryLow'; @@ -151,7 +150,6 @@ export const FlagCell = ({ patient, category = null, }) => { case period.timeInVeryHighPercent > 0.05: return 'veryHigh'; case period.timeInAnyHighPercent > 0.25: return 'anyHigh'; case period.timeInTargetPercentDelta < -0.15: return 'dropInTIR'; - case period.timeInTargetPercent < 0.70: return 'lowTIR'; case period.timeCGMUsePercent < 0.70: return 'lowSensorUsage'; default: return null; @@ -166,22 +164,23 @@ export const FlagCell = ({ patient, category = null, }) => { veryHigh: t('Very High'), anyHigh: t('High'), dropInTIR: t('Large Drop in TIR'), - lowTIR: t('Low TIR'), lowSensorUsage: t('Low CGM Wear Time'), - meetingTargets: t('Meeting Targets'), + target: t('Meeting Targets'), }; + const flagColor = colors.bg[rangeName] || vizColors.gold30; + return ( From f74906076aefb6be24c011be587ff22764d9a4c0 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 12 May 2026 11:51:17 -0700 Subject: [PATCH 18/28] WEB-4460 hide value it TimeInTargetPercent not shown --- app/pages/clinicworkspace/TideDashboardV2/Cells.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 44c4176ee4..ef0efe5c89 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -11,6 +11,7 @@ import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; import DeltaBar from '../../../components/elements/DeltaBar'; import utils from '../../../core/utils'; import { CATEGORY } from './FilterByCategory'; +import isUndefined from 'lodash/isUndefined'; export const PatientCell = ({ patient }) => { const { t } = useTranslation(); @@ -59,7 +60,9 @@ export const TimeInRangePercentBarChartCell = ({ patient }) => { export const TimeInTargetPercentCell = ({ patient }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInTargetPercent; - const value = utils.formatDecimal(rawValue * 100, 0); + let value = utils.formatDecimal(rawValue * 100, 0); + + if (isUndefined(rawValue)) value = ''; return ; }; From f16f767328ffb87401fc3ec0bd4ee0f8d274dd21 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Wed, 24 Jun 2026 14:46:12 -0700 Subject: [PATCH 19/28] WEB-4460 remove needed flag from PatientDrawer access --- .../clinicworkspace/TideDashboardV2/Cells.js | 21 ++++++------------- .../PatientDrawerController.js | 3 --- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 9a0ebe266f..89632269d3 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -2,13 +2,11 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { useLocation, useHistory } from 'react-router-dom'; -import { Box, Text } from 'theme-ui'; -import { utils as vizUtils } from '@tidepool/viz'; +import { Box, Flex, Text } from 'theme-ui'; +import { utils as vizUtils, colors as vizColors } from '@tidepool/viz'; const { bankersRound } = vizUtils.stat; import { MGDL_UNITS } from '../../../core/constants'; import { push } from 'connected-react-router'; -import { Box, Flex, Text } from 'theme-ui'; -import { utils as vizUtils, colors as vizColors } from '@tidepool/viz'; import { colors } from '../../../themes/baseTheme'; import BgSummaryCell from '../../../components/clinic/BgSummaryCell'; @@ -25,23 +23,16 @@ export const PatientCell = ({ patient }) => { const history = useHistory(); const dispatch = useDispatch(); - const { showTideDashboardPatientDrawer } = useFlags(); - const { fullName, birthDate, mrn } = patient || {}; const handleClick = () => { if (!patient.id) return; - if (showTideDashboardPatientDrawer) { - const params = new URLSearchParams(search); - params.set('drawerPatientId', patient.id); - params.set('drawerTab', OVERVIEW_TAB_INDEX); - history.replace({ pathname, search: params.toString() }); - - return; - } + const params = new URLSearchParams(search); + params.set('drawerPatientId', patient.id); + params.set('drawerTab', OVERVIEW_TAB_INDEX); - dispatch(push(`/patients/${patient.id}/data?dashboard=tide`)); + history.replace({ pathname, search: params.toString() }); }; return diff --git a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js index 885fd415cd..d6205e31a9 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js +++ b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js @@ -8,7 +8,6 @@ const trackMetric = () => {}; const PatientDrawerController = ({ api }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); - const { showTideDashboardPatientDrawer } = useFlags(); const { search, pathname } = useLocation(); const history = useHistory(); @@ -21,8 +20,6 @@ const PatientDrawerController = ({ api }) => { history.replace({ pathname, search: params.toString() }); }; - if (!showTideDashboardPatientDrawer) return null; - return ( Date: Mon, 29 Jun 2026 13:12:50 -0700 Subject: [PATCH 20/28] WEB-4460 remove category for cgm params --- app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js index 533c5203a0..374041b3cf 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js +++ b/app/pages/clinicworkspace/TideDashboardV2/tideDashboardApi.js @@ -20,7 +20,6 @@ export const buildGetTideDashboardPatientsParams = (offset, limit, category, las return { offset, limit, - category, 'cgm.lastDataTo': lastDataTo, 'cgm.lastDataFrom': lastDataFrom, tags: formattedTags, From c5262c9bb42a8102c9e99b1adcac2d6f483511ee Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 30 Jun 2026 14:50:18 -0700 Subject: [PATCH 21/28] WEB-4460 make cell changes for compact view --- .../clinicworkspace/TideDashboardV2/Cells.js | 52 ++++++++++++++----- .../TideDashboardV2/TideDashboardV2.js | 1 + .../TideDashboardV2/useTableColumns.js | 7 +-- .../clinicworkspace/components/TagListCell.js | 4 +- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index ef0efe5c89..875aad34af 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -1,6 +1,6 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { useTranslation } from 'react-i18next'; +import { useTranslation, withTranslation } from 'react-i18next'; import { Box, Flex, Text } from 'theme-ui'; import { utils as vizUtils, colors as vizColors } from '@tidepool/viz'; const { bankersRound } = vizUtils.stat; @@ -13,24 +13,33 @@ import utils from '../../../core/utils'; import { CATEGORY } from './FilterByCategory'; import isUndefined from 'lodash/isUndefined'; +export const COMPACT = '@container (max-width: 1200px)'; + export const PatientCell = ({ patient }) => { const { t } = useTranslation(); const { fullName, birthDate, mrn } = patient || {}; - return - {fullName} - {t('DOB:')} {birthDate} - {mrn && , {t('MRN: {{mrn}}', { mrn: mrn })}} + return + {fullName} + {t('DOB:')} {birthDate} + {mrn && {t('MRN: {{mrn}}', { mrn: mrn })}} ; }; export const NumericTemplateCell = ({ value, isPercent = false }) => { if (!value) return ; - return {value} {isPercent && '%'}; + return {value} {isPercent && '%'}; }; +export const AvgGlucoseHeader = withTranslation()(({ t }) => ( + <> + {t('Avg Glucose')} + {t('Avg Gluc.')} + +)); + export const AvgGlucoseCell = ({ patient, units }) => { // TODO: Fix for units const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const rawValue = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.averageGlucoseMmol; @@ -114,17 +123,34 @@ export const CGMUseCell = ({ patient }) => { return ; }; +export const ChangeTIRHeader = withTranslation()(({ t }) => ( + <> + {t('% Change in TIR')} + {t('% Δ TIR')} + +)); + export const ChangeTIRCell = ({ patient }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); const timeInTargetPercentDelta = patient?.summary?.cgmStats?.periods?.[summaryPeriod]?.timeInTargetPercentDelta; - if (!timeInTargetPercentDelta) return --; - - return ; + if (!timeInTargetPercentDelta) return -; + + const compactDisplayValue = utils.formatDecimal(timeInTargetPercentDelta * 100, 1); + + return <> + + + + + + + + ; }; export const FlagCell = ({ patient, category = null, }) => { diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index b7d8fc3680..391f280361 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -90,6 +90,7 @@ const TideDashboard = () => { columns={tableColumns} data={tableData} emptyContentNode={} + containerProps={{ sx: { containerType: 'inline-size' } }} // sx={tableStyle} // onSort={handleSortChange} // order={sort?.substring(0, 1) === '+' ? 'asc' : 'desc'} diff --git a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js index 446f8f0a98..ceaf67bb6e 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js +++ b/app/pages/clinicworkspace/TideDashboardV2/useTableColumns.js @@ -8,8 +8,10 @@ import { utils as vizUtils } from '@tidepool/viz'; const { DEFAULT_BG_BOUNDS } = vizUtils.constants; import { + AvgGlucoseHeader, AvgGlucoseCell, CGMUseCell, + ChangeTIRHeader, ChangeTIRCell, GMICell, PatientCell, @@ -41,6 +43,7 @@ const getColumnTypes = (t, category, thresholds) => ({ title: t('Avg Glucose'), field: 'avgGlucose', align: 'center', + titleComponent: () => , render: patient => , }, timeInRangeBarChart: { @@ -53,6 +56,7 @@ const getColumnTypes = (t, category, thresholds) => ({ title: t('% Change in TIR'), field: 'changeInTIR', align: 'center', + titleComponent: () => , render: patient => , }, timeInVeryLow: { @@ -136,7 +140,6 @@ const useTableColumns = (category) => { columnTypes.patientDetails, columnTypes.flag, columnTypes.avgGlucose, - columnTypes.timeInTarget, columnTypes.timeInRangeBarChart, columnTypes.changeInTIR, columnTypes.gmi, @@ -155,7 +158,6 @@ const useTableColumns = (category) => { columnTypes.timeInTarget, columnTypes.timeInRangeBarChart, columnTypes.changeInTIR, - columnTypes.gmi, columnTypes.tags, columnTypes.lastReviewed, columnTypes.moreMenu, @@ -170,7 +172,6 @@ const useTableColumns = (category) => { columnTypes.timeInTarget, columnTypes.timeInRangeBarChart, columnTypes.changeInTIR, - columnTypes.gmi, columnTypes.tags, columnTypes.lastReviewed, columnTypes.moreMenu, diff --git a/app/pages/clinicworkspace/components/TagListCell.js b/app/pages/clinicworkspace/components/TagListCell.js index 7f5a8fda77..38d2654858 100644 --- a/app/pages/clinicworkspace/components/TagListCell.js +++ b/app/pages/clinicworkspace/components/TagListCell.js @@ -2,6 +2,8 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { TagList } from '../../../components/elements/Tag'; +const MAX_TAGS = 2; + const TagListCell = ({ patient }) => { const selectedClinicId = useSelector(state => state.blip.selectedClinicId); const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); @@ -10,7 +12,7 @@ const TagListCell = ({ patient }) => { const tagIds = patient?.tags || []; const tags = tagIds.map(tag => patientTags.find(ptTag => ptTag.id === tag)); // TODO: index - return ; + return ; }; export default TagListCell; From 0c579b854ed2ec4eef4bc93daa5085195417af68 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 30 Jun 2026 15:31:25 -0700 Subject: [PATCH 22/28] WEB-4460 fix flag wrap --- app/pages/clinicworkspace/TideDashboardV2/Cells.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 875aad34af..6b356526f4 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -200,7 +200,7 @@ export const FlagCell = ({ patient, category = null, }) => { const flagColor = colors.bg[rangeName] || vizColors.gold30; return ( - + { mr={2} > - + {flagLabels[rangeName] || ''} From dbccfc11b751f64bb42c5bd10102cb3bcfb8b73d Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 11 Aug 2026 13:10:03 -0700 Subject: [PATCH 23/28] WEB-4460 fix flag definitions --- app/pages/clinicworkspace/TideDashboardV2/Cells.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index 88af337ca4..e4aa879b4c 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -191,12 +191,12 @@ export const FlagCell = ({ patient, category = null, }) => { case category === TARGET: return 'target'; // If no category, then read from summary - case period.timeInVeryLowPercent > 0.01: return 'veryLow'; - case period.timeInAnyLowPercent > 0.04: return 'anyLow'; - case period.timeInVeryHighPercent > 0.05: return 'veryHigh'; - case period.timeInAnyHighPercent > 0.25: return 'anyHigh'; - case period.timeInTargetPercentDelta < -0.15: return 'dropInTIR'; - case period.timeCGMUsePercent < 0.70: return 'lowSensorUsage'; + case period.timeInVeryLowPercent >= 0.005: return 'veryLow'; // >=1% + case period.timeInAnyLowPercent >= 0.035: return 'anyLow'; // >=4% + case period.timeInVeryHighPercent >= 0.045: return 'veryHigh'; // >=5% + case period.timeInAnyHighPercent >= 0.245: return 'anyHigh'; // >=25% + case period.timeInTargetPercentDelta <= -0.145: return 'dropInTIR'; // <=-15% + case period.timeCGMUsePercent < 0.695: return 'lowSensorUsage'; // <70% default: return null; } From e1393d94e7b2a599556b2640808c7f6159ef9316 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Tue, 11 Aug 2026 14:02:44 -0700 Subject: [PATCH 24/28] WEB-4460 fix flag ordering --- app/pages/clinicworkspace/TideDashboardV2/Cells.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/Cells.js index e4aa879b4c..e179f9e7a4 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/Cells.js +++ b/app/pages/clinicworkspace/TideDashboardV2/Cells.js @@ -193,9 +193,9 @@ export const FlagCell = ({ patient, category = null, }) => { // If no category, then read from summary case period.timeInVeryLowPercent >= 0.005: return 'veryLow'; // >=1% case period.timeInAnyLowPercent >= 0.035: return 'anyLow'; // >=4% - case period.timeInVeryHighPercent >= 0.045: return 'veryHigh'; // >=5% - case period.timeInAnyHighPercent >= 0.245: return 'anyHigh'; // >=25% case period.timeInTargetPercentDelta <= -0.145: return 'dropInTIR'; // <=-15% + case period.timeInAnyHighPercent >= 0.245: return 'anyHigh'; // >=25% + case period.timeInVeryHighPercent >= 0.045: return 'veryHigh'; // >=5% case period.timeCGMUsePercent < 0.695: return 'lowSensorUsage'; // <70% default: return null; From 4742fb93e41230787474f0225da9b8760e4ecc7d Mon Sep 17 00:00:00 2001 From: henry-tp Date: Wed, 12 Aug 2026 21:59:04 -0700 Subject: [PATCH 25/28] WEB-4460 fix rebase issues --- app/components/PatientDrawer/useAgpCGM/getOpts.js | 2 +- app/components/PatientDrawer/useAgpCGM/useAgpCGM.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/PatientDrawer/useAgpCGM/getOpts.js b/app/components/PatientDrawer/useAgpCGM/getOpts.js index 14bcf8e41e..d3597c9f2f 100644 --- a/app/components/PatientDrawer/useAgpCGM/getOpts.js +++ b/app/components/PatientDrawer/useAgpCGM/getOpts.js @@ -3,7 +3,7 @@ import _ from 'lodash'; import get from 'lodash/get'; import { utils as vizUtils } from '@tidepool/viz'; import utils from '../../../core/utils'; -import { getMostRecentDatumTimeByChartType } from '../../../../core/dataViewUtils'; +import { getMostRecentDatumTimeByChartType } from '../../../core/dataViewUtils'; const getTimezoneFromTimePrefs = vizUtils.datetime.getTimezoneFromTimePrefs; diff --git a/app/components/PatientDrawer/useAgpCGM/useAgpCGM.js b/app/components/PatientDrawer/useAgpCGM/useAgpCGM.js index 5bbc851795..920a57f85e 100644 --- a/app/components/PatientDrawer/useAgpCGM/useAgpCGM.js +++ b/app/components/PatientDrawer/useAgpCGM/useAgpCGM.js @@ -6,7 +6,7 @@ import moment from 'moment'; import getOpts from './getOpts'; import getQueries from './getQueries'; import { cloneDeep } from 'lodash'; -import { useGenerateAGPImages } from '../../../../core/agpUtils'; +import { useGenerateAGPImages } from '../../../core/agpUtils'; export const STATUS = { // States in order of happy path AGP generation sequence From beb266db172468900d2ec812f951ef0b76fcb159 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 13 Aug 2026 11:52:00 -0700 Subject: [PATCH 26/28] WEB-4460 use resolved category in TableCategoryHeader --- .../clinicworkspace/TideDashboardV2/TableCategoryHeader.js | 7 +++---- .../clinicworkspace/TideDashboardV2/TideDashboardV2.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/TableCategoryHeader.js b/app/pages/clinicworkspace/TideDashboardV2/TableCategoryHeader.js index 7d50d6fcb3..4844fb8dad 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TableCategoryHeader.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TableCategoryHeader.js @@ -13,9 +13,8 @@ const formatThreshold = (value, bgUnits) => bgUnits === MGDL_UNITS ? value : utils.formatDecimal(value, 1); -const useCategoryHeaderCopy = () => { +const useCategoryHeaderCopy = (category) => { const { t } = useTranslation(); - const category = useSelector(state => state.blip.tideDashboard.category); const selectedClinicId = useSelector(state => state.blip.selectedClinicId); const clinic = useSelector(state => state.blip.clinics?.[selectedClinicId]); const bgUnits = clinic?.preferredBgUnits || MGDL_UNITS; @@ -68,8 +67,8 @@ const useCategoryHeaderCopy = () => { } }; -const TableCategoryHeader = () => { - const { title, label } = useCategoryHeaderCopy(); +const TableCategoryHeader = ({ category }) => { + const { title, label } = useCategoryHeaderCopy(category); return diff --git a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js index 2c89360824..0e825ad223 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js +++ b/app/pages/clinicworkspace/TideDashboardV2/TideDashboardV2.js @@ -79,7 +79,7 @@ const TideDashboard = ({ api }) => { - + Date: Thu, 13 Aug 2026 12:23:10 -0700 Subject: [PATCH 27/28] WEB-4460 use global trackMetric fn --- .../TideDashboardV2/PatientDrawerController.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js index d6205e31a9..9bfd0f3372 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js +++ b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js @@ -1,10 +1,8 @@ -import React, { useCallback } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; import { useLocation, useHistory } from 'react-router-dom'; import PatientDrawer from '../../../components/PatientDrawer/PatientDrawer'; -import { useFlags } from 'launchdarkly-react-client-sdk'; - -const trackMetric = () => {}; +import { trackMetric } from '../../../core/metricUtils'; const PatientDrawerController = ({ api }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); From 9e179c9afeb7d4eed953e47ec9d34413f7c0b015 Mon Sep 17 00:00:00 2001 From: henry-tp Date: Thu, 13 Aug 2026 12:45:59 -0700 Subject: [PATCH 28/28] WEB-4460 remove unused trackMetric in patientdrawer --- app/components/PatientDrawer/MenuBar/MenuBar.js | 4 ++-- app/components/PatientDrawer/PatientDrawer.js | 10 +++++----- .../TideDashboardV2/PatientDrawerController.js | 2 -- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/components/PatientDrawer/MenuBar/MenuBar.js b/app/components/PatientDrawer/MenuBar/MenuBar.js index 543f491e96..724221191a 100644 --- a/app/components/PatientDrawer/MenuBar/MenuBar.js +++ b/app/components/PatientDrawer/MenuBar/MenuBar.js @@ -15,6 +15,7 @@ import api from '../../../core/api'; import { map, keys } from 'lodash'; import copyIcon from '../../../core/icons/copyIcon.svg'; import viewIcon from '../../../core/icons/viewIcon.svg'; +import { trackMetric } from '../../../core/metricUtils'; export const OVERVIEW_TAB_INDEX = 0; export const STACKED_DAILY_TAB_INDEX = 1; @@ -32,7 +33,7 @@ const tabs = { }, }; -const MenuBar = ({ patientId, onClose, onSelectTab, selectedTab, trackMetric }) => { +const MenuBar = ({ patientId, onClose, onSelectTab, selectedTab }) => { const dispatch = useDispatch(); const { t } = useTranslation(); const { showTideDashboardLastReviewed } = useFlags(); @@ -157,7 +158,6 @@ MenuBar.propTypes = { onClose: PropTypes.func.isRequired, onSelectTab: PropTypes.func.isRequired, selectedTab: PropTypes.number.isRequired, - trackMetric: PropTypes.func.isRequired, }; export default MenuBar; diff --git a/app/components/PatientDrawer/PatientDrawer.js b/app/components/PatientDrawer/PatientDrawer.js index b85a406f01..aa0f829b39 100644 --- a/app/components/PatientDrawer/PatientDrawer.js +++ b/app/components/PatientDrawer/PatientDrawer.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import Icon from '../../components/elements/Icon'; import { useLocation, useHistory } from 'react-router-dom'; import Drawer from '@material-ui/core/Drawer'; @@ -51,7 +51,7 @@ const getAgpPeriodInDays = (period) => { } }; -const DrawerContent = ({ patientId, onClose, api, trackMetric, period }) => { +const DrawerContent = ({ patientId, onClose, api, period }) => { // Only rendered when patient is selected and isOpen is true // this will also allow the hook to dismount and for the cleanup to be called const location = useLocation(); @@ -83,7 +83,7 @@ const DrawerContent = ({ patientId, onClose, api, trackMetric, period }) => { return ( <> - + @@ -106,7 +106,7 @@ const DrawerContent = ({ patientId, onClose, api, trackMetric, period }) => { ) } -const PatientDrawer = ({ patientId, onClose, api, trackMetric, period }) => { +const PatientDrawer = ({ patientId, onClose, api, period }) => { const classes = useStyles(); const isOpen = !!patientId && isValidAgpPeriod(period); @@ -129,7 +129,7 @@ const PatientDrawer = ({ patientId, onClose, api, trackMetric, period }) => { flexDirection: 'column', }} > - {isOpen && } + {isOpen && } ); diff --git a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js index 9bfd0f3372..aae581d4d5 100644 --- a/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js +++ b/app/pages/clinicworkspace/TideDashboardV2/PatientDrawerController.js @@ -2,7 +2,6 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { useLocation, useHistory } from 'react-router-dom'; import PatientDrawer from '../../../components/PatientDrawer/PatientDrawer'; -import { trackMetric } from '../../../core/metricUtils'; const PatientDrawerController = ({ api }) => { const summaryPeriod = useSelector(state => state.blip.tideDashboardFilters.summaryPeriod); @@ -23,7 +22,6 @@ const PatientDrawerController = ({ api }) => { api={api} patientId={drawerPatientId} onClose={handleClose} - trackMetric={trackMetric} period={summaryPeriod} /> );