diff --git a/app/components/datasources/DataConnections.js b/app/components/datasources/DataConnections.js
index 709ef5f43c..d47ac28a1e 100644
--- a/app/components/datasources/DataConnections.js
+++ b/app/components/datasources/DataConnections.js
@@ -306,15 +306,13 @@ export const getConnectStateUI = (patient, isLoggedInUser, providerName) => {
}
};
-export const getDataConnectionProps = (patient, isLoggedInUser, selectedClinicId, setActiveHandler) => reduce(availableProviders, (result, providerName) => {
- result[providerName] = {};
-
- let connectState;
-
+export const resolveConnectState = (patient, providerName, isLoggedInUser = false) => {
const dataSource = getCurrentDataSourceForProvider(patient, providerName);
const connectStateUI = getConnectStateUI(patient, isLoggedInUser, providerName);
const inviteExpired = dataSource?.expirationTime < moment.utc().toISOString();
+ let connectState;
+
if (dataSource?.state) {
connectState = includes(keys(connectStateUI), dataSource.state)
? dataSource.state
@@ -331,6 +329,15 @@ export const getDataConnectionProps = (patient, isLoggedInUser, selectedClinicId
connectState = 'noPendingConnections';
}
+ return connectState;
+};
+
+export const getDataConnectionProps = (patient, isLoggedInUser, selectedClinicId, setActiveHandler) => reduce(availableProviders, (result, providerName) => {
+ result[providerName] = {};
+
+ const connectStateUI = getConnectStateUI(patient, isLoggedInUser, providerName);
+ const connectState = resolveConnectState(patient, providerName, isLoggedInUser);
+
const { color, icon, message, text, handler } = connectStateUI[connectState];
const {
diff --git a/app/pages/clinicworkspace/TideDashboardV2/DataIssues/Cells.js b/app/pages/clinicworkspace/TideDashboardV2/DataIssues/Cells.js
new file mode 100644
index 0000000000..1c7877dad4
--- /dev/null
+++ b/app/pages/clinicworkspace/TideDashboardV2/DataIssues/Cells.js
@@ -0,0 +1,141 @@
+import React, { useMemo } from 'react';
+import { useSelector } from 'react-redux';
+import { useTranslation } from 'react-i18next';
+import moment from 'moment-timezone';
+import { Box, Text } from 'theme-ui';
+import { resolveConnectState } from '../../../../components/datasources/DataConnections';
+import includes from 'lodash/includes';
+
+import Pill from '../../../../components/elements/Pill';
+import HoverButton from '../../../../components/elements/HoverButton';
+import PopoverMenu from '../../../../components/elements/PopoverMenu';
+import { colors, fontWeights } from '../../../../themes/baseTheme';
+import ErrorRoundedIcon from '@material-ui/icons/ErrorRounded';
+import EditIcon from '@material-ui/icons/EditRounded';
+import DataInIcon from '../../../../core/icons/DataInIcon.svg';
+
+export const DexcomConnectionStatusCell = ({ patient, onOpenDataConnectionsModal }) => {
+ const { t } = useTranslation();
+
+ const dexcomConnectStateUI = useMemo(() => ({
+ noPendingConnections: { colorPalette: 'neutral', icon: null, text: t('No Pending Connections') },
+ inviteJustSent: { colorPalette: 'info', icon: null, text: t('Invite Sent') },
+ pending: { colorPalette: 'info', icon: null, text: t('Invite Sent') },
+ pendingReconnect: { colorPalette: 'info', icon: null, text: t('Invite Sent') },
+ pendingExpired: { colorPalette: 'warning', icon: ErrorRoundedIcon, text: t('Invite Expired') },
+ connected: { colorPalette: 'info', icon: null, text: t('Connected') },
+ disconnected: { colorPalette: 'warning', icon: ErrorRoundedIcon, text: t('Patient Disconnected') },
+ error: { colorPalette: 'warning', icon: ErrorRoundedIcon, text: t('Error Connecting') },
+ unknown: { colorPalette: 'warning', icon: ErrorRoundedIcon, text: t('Unknown Status') },
+ }), [t]);
+
+ const dexcomConnectState = resolveConnectState(patient, 'dexcom');
+
+ if (!dexcomConnectState) return null;
+
+ const showViewButton = includes([
+ 'disconnected',
+ 'error',
+ 'noPendingConnections',
+ 'pendingExpired',
+ 'unknown',
+ ], dexcomConnectState);
+
+ const handleOpenDataConnectionsModal = () => onOpenDataConnectionsModal(patient.id);
+
+ const StatusBadge = () => (
+
+ );
+
+ if (!showViewButton) return ;
+
+ return (
+
+
+
+
+
+ );
+};
+
+export const DaysSinceLastDataCell = ({ patient }) => {
+ const timePrefs = useSelector(state => state.blip.timePrefs);
+
+ const daysSinceLastData = useMemo(() => {
+ if (!patient?.lastData) return null;
+
+ const timezone = timePrefs?.timezoneName || new Intl.DateTimeFormat().resolvedOptions().timeZone;
+ const startOfLastDataDay = moment.utc(patient.lastData).tz(timezone).startOf('day');
+ const startOfCurrentDay = moment.utc().tz(timezone).startOf('day');
+
+ return startOfCurrentDay.diff(startOfLastDataDay, 'days');
+ }, [patient?.lastData, timePrefs?.timezoneName]);
+
+ return (
+ {daysSinceLastData ?? '-'}
+ );
+};
+
+export const MoreMenuCell = ({ patient, onOpenEditPatientDialog, onOpenDataConnectionsModal }) => {
+ const { t } = useTranslation();
+
+ return (
+