From 7b8ff051713a6ff6f260b231d7aceb64e6d9b9dd Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Thu, 25 May 2023 14:21:14 +0000 Subject: [PATCH] feat(conso): display data from offline konnector --- src/components/Connection/Connection.tsx | 2 +- .../Connection/EPGLConnect/EpglBill.tsx | 27 +++- .../Connection/EPGLConnect/EpglInit.tsx | 20 +-- .../Connection/GRDFConnect/GrdfBill.tsx | 27 +++- .../Connection/GRDFConnect/GrdfForm.tsx | 14 +- .../Connection/GRDFConnect/GrdfInit.tsx | 23 ++-- .../Connection/SGEConnect/SgeInit.tsx | 12 ++ .../__snapshots__/SgeInit.spec.tsx.snap | 126 ++++++++++++++++++ .../__snapshots__/Connection.spec.tsx.snap | 126 ++++++++++++++++++ src/components/Connection/connection.scss | 31 ++--- .../DataloadConsumptionVisualizer.tsx | 1 - .../InfoDataConsumptionVisualizer.spec.tsx | 8 +- .../InfoDataConsumptionVisualizer.tsx | 2 +- .../infoDataConsumptionVisualizer.scss | 2 - src/components/FluidChart/FluidChart.tsx | 62 ++++++++- src/components/FluidChart/fluidChart.scss | 16 +++ src/components/Home/ConsumptionView.spec.tsx | 5 + src/components/Home/ConsumptionView.tsx | 31 +++-- src/locales/fr.json | 7 +- src/models/chart.model.ts | 1 + src/models/modal.model.ts | 1 + src/store/chart/chart.slice.spec.ts | 90 +++++++++++++ src/store/chart/chart.slice.ts | 7 + src/store/modal/modal.slice.spec.ts | 23 +++- src/store/modal/modal.slice.ts | 8 +- src/styles/components/_buttons.scss | 3 + src/utils/utils.spec.ts | 20 ++- src/utils/utils.ts | 13 ++ tests/__mocks__/store.ts | 2 + 29 files changed, 611 insertions(+), 99 deletions(-) diff --git a/src/components/Connection/Connection.tsx b/src/components/Connection/Connection.tsx index 184c15867..a6913571d 100644 --- a/src/components/Connection/Connection.tsx +++ b/src/components/Connection/Connection.tsx @@ -4,10 +4,10 @@ import React, { Dispatch, useCallback } from 'react' import { useDispatch } from 'react-redux' import { AppActionsTypes } from 'store' import { updatedFluidConnection } from 'store/global/global.actions' -import './connection.scss' import EpglInit from './EPGLConnect/EpglInit' import GrdfInit from './GRDFConnect/GrdfInit' import SgeInit from './SGEConnect/SgeInit' +import './connection.scss' interface ConnectionProps { fluidStatus: FluidStatus } diff --git a/src/components/Connection/EPGLConnect/EpglBill.tsx b/src/components/Connection/EPGLConnect/EpglBill.tsx index 7662a9112..ae01998eb 100644 --- a/src/components/Connection/EPGLConnect/EpglBill.tsx +++ b/src/components/Connection/EPGLConnect/EpglBill.tsx @@ -2,16 +2,18 @@ import Button from '@material-ui/core/Button' import WaterBillIcon from 'assets/icons/visu/onboarding/water_bill.svg' import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import React from 'react' +import { FluidStatus } from 'models' +import React, { Dispatch } from 'react' +import { useDispatch } from 'react-redux' +import { AppActionsTypes } from 'store' +import { setShowOfflineData } from 'store/chart/chart.slice' +import { openConnectionModal } from 'store/modal/modal.slice' import { decoreText } from 'utils/decoreText' import '../connection.scss' -interface EpglBillProps { - togglePartnerConnectionModal: () => void -} - -const EpglBill = ({ togglePartnerConnectionModal }: EpglBillProps) => { +const EpglBill = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { const { t } = useI18n() + const dispatch = useDispatch<Dispatch<AppActionsTypes>>() return ( <div className="connection-form"> @@ -27,7 +29,7 @@ const EpglBill = ({ togglePartnerConnectionModal }: EpglBillProps) => { <div className="connection-form-button"> <Button aria-label={t('auth.eglgrandlyon.accessibility.connect')} - onClick={togglePartnerConnectionModal} + onClick={() => dispatch(openConnectionModal(true))} classes={{ root: 'btn-highlight', label: 'text-16-bold', @@ -35,6 +37,17 @@ const EpglBill = ({ togglePartnerConnectionModal }: EpglBillProps) => { > {t('auth.eglgrandlyon.connect')} </Button> + {fluidStatus.firstDataDate && ( + <Button + classes={{ + root: 'btn-secondary', + label: 'text-16-bold', + }} + onClick={() => dispatch(setShowOfflineData(true))} + > + {t('auth.button_showOfflineData')} + </Button> + )} </div> </div> ) diff --git a/src/components/Connection/EPGLConnect/EpglInit.tsx b/src/components/Connection/EPGLConnect/EpglInit.tsx index 393d1a07b..fff3a0881 100644 --- a/src/components/Connection/EPGLConnect/EpglInit.tsx +++ b/src/components/Connection/EPGLConnect/EpglInit.tsx @@ -1,6 +1,9 @@ import EpglConnectModal from 'components/Connection/PartnerConnectModal/EpglConnectModal' import { FluidStatus } from 'models' -import React, { useCallback, useState } from 'react' +import React, { Dispatch, useCallback, useState } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { AppActionsTypes, AppStore } from 'store' +import { openConnectionModal } from 'store/modal/modal.slice' import '../connection.scss' import EpglBill from './EpglBill' import EpglForm from './EpglForm' @@ -10,16 +13,15 @@ interface EpglInitProps { } const EpglInit: React.FC<EpglInitProps> = ({ fluidStatus }: EpglInitProps) => { + const dispatch = useDispatch<Dispatch<AppActionsTypes>>() + const { + modal: { isConnectionModalOpen }, + } = useSelector((state: AppStore) => state.ecolyo) const siteLink: string = fluidStatus.connection.konnectorConfig.siteLink - const [openModal, setOpenModal] = useState(false) const [showForm, setShowForm] = useState(false) const [hasCreatedAccount, setHasCreatedAccount] = useState(false) - const toggleModal = useCallback(() => { - setOpenModal(prev => !prev) - }, []) - const goToPartnerSite = useCallback(() => { window.open(siteLink, '_blank') }, [siteLink]) @@ -27,7 +29,7 @@ const EpglInit: React.FC<EpglInitProps> = ({ fluidStatus }: EpglInitProps) => { return ( <> {!showForm ? ( - <EpglBill togglePartnerConnectionModal={toggleModal} /> + <EpglBill fluidStatus={fluidStatus} /> ) : ( <EpglForm fluidStatus={fluidStatus} @@ -35,8 +37,8 @@ const EpglInit: React.FC<EpglInitProps> = ({ fluidStatus }: EpglInitProps) => { /> )} <EpglConnectModal - open={openModal} - handleCloseClick={toggleModal} + open={isConnectionModalOpen} + handleCloseClick={() => dispatch(openConnectionModal(false))} setShowForm={setShowForm} goToPartnerSite={goToPartnerSite} setHasCreatedAccount={setHasCreatedAccount} diff --git a/src/components/Connection/GRDFConnect/GrdfBill.tsx b/src/components/Connection/GRDFConnect/GrdfBill.tsx index 2a7e17bb2..ad07fb26e 100644 --- a/src/components/Connection/GRDFConnect/GrdfBill.tsx +++ b/src/components/Connection/GRDFConnect/GrdfBill.tsx @@ -2,16 +2,18 @@ import Button from '@material-ui/core/Button' import GasBillIcon from 'assets/icons/visu/onboarding/gas_bill.svg' import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import React from 'react' +import { FluidStatus } from 'models' +import React, { Dispatch } from 'react' +import { useDispatch } from 'react-redux' +import { AppActionsTypes } from 'store' +import { setShowOfflineData } from 'store/chart/chart.slice' +import { openConnectionModal } from 'store/modal/modal.slice' import { decoreText } from 'utils/decoreText' import '../connection.scss' -interface GrdfBillProps { - togglePartnerConnectionModal: () => void -} - -const GrdfBill = ({ togglePartnerConnectionModal }: GrdfBillProps) => { +const GrdfBill = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { const { t } = useI18n() + const dispatch = useDispatch<Dispatch<AppActionsTypes>>() return ( <div className="connection-form"> @@ -26,7 +28,7 @@ const GrdfBill = ({ togglePartnerConnectionModal }: GrdfBillProps) => { <div className="connection-form-button"> <Button aria-label={t('auth.grdfgrandlyon.accessibility.connect')} - onClick={togglePartnerConnectionModal} + onClick={() => dispatch(openConnectionModal(true))} classes={{ root: 'btn-highlight', label: 'text-16-bold', @@ -34,6 +36,17 @@ const GrdfBill = ({ togglePartnerConnectionModal }: GrdfBillProps) => { > {t('auth.grdfgrandlyon.connect')} </Button> + {fluidStatus.firstDataDate && ( + <Button + classes={{ + root: 'btn-secondary', + label: 'text-16-bold', + }} + onClick={() => dispatch(setShowOfflineData(true))} + > + {t('auth.button_showOfflineData')} + </Button> + )} </div> </div> ) diff --git a/src/components/Connection/GRDFConnect/GrdfForm.tsx b/src/components/Connection/GRDFConnect/GrdfForm.tsx index 891e9cb64..b2f699e71 100644 --- a/src/components/Connection/GRDFConnect/GrdfForm.tsx +++ b/src/components/Connection/GRDFConnect/GrdfForm.tsx @@ -2,15 +2,15 @@ import Button from '@material-ui/core/Button' import iconGrdfLogo from 'assets/icons/visu/grdf-logo.svg' import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import React from 'react' +import React, { Dispatch } from 'react' +import { useDispatch } from 'react-redux' +import { AppActionsTypes } from 'store' +import { openConnectionModal } from 'store/modal/modal.slice' import '../connection.scss' -interface GrdfFormProps { - togglePartnerConnectionModal: () => void -} - -const GrdfForm = ({ togglePartnerConnectionModal }: GrdfFormProps) => { +const GrdfForm = () => { const { t } = useI18n() + const dispatch = useDispatch<Dispatch<AppActionsTypes>>() return ( <div className="connection-form"> @@ -24,7 +24,7 @@ const GrdfForm = ({ togglePartnerConnectionModal }: GrdfFormProps) => { <div className="connection-form-connect-button grdf"> <Button aria-label={t('auth.accessibility.button_connect')} - onClick={togglePartnerConnectionModal} + onClick={() => dispatch(openConnectionModal(true))} classes={{ root: 'btn-highlight', label: 'text-18-bold', diff --git a/src/components/Connection/GRDFConnect/GrdfInit.tsx b/src/components/Connection/GRDFConnect/GrdfInit.tsx index 4200ad870..27df3d8ff 100644 --- a/src/components/Connection/GRDFConnect/GrdfInit.tsx +++ b/src/components/Connection/GRDFConnect/GrdfInit.tsx @@ -3,12 +3,13 @@ import { useClient } from 'cozy-client' import { UsageEventType } from 'enum/usageEvent.enum' import { FluidConnection, FluidStatus, Konnector, Trigger } from 'models' import React, { Dispatch, useCallback, useState } from 'react' -import { useDispatch } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import AccountService from 'services/account.service' import TriggerService from 'services/triggers.service' import UsageEventService from 'services/usageEvent.service' -import { AppActionsTypes } from 'store' +import { AppActionsTypes, AppStore } from 'store' import { updatedFluidConnection } from 'store/global/global.actions' +import { openConnectionModal } from 'store/modal/modal.slice' import '../connection.scss' import GrdfBill from './GrdfBill' import GrdfForm from './GrdfForm' @@ -24,8 +25,10 @@ const GrdfInit: React.FC<GrdfInitProps> = ({ }: GrdfInitProps) => { const client = useClient() const dispatch = useDispatch<Dispatch<AppActionsTypes>>() + const { + modal: { isConnectionModalOpen }, + } = useSelector((state: AppStore) => state.ecolyo) - const [openModal, setOpenModal] = useState(false) const [showForm, setShowForm] = useState(false) const konnectorSlug: string = fluidStatus.connection.konnectorConfig.slug @@ -80,27 +83,19 @@ const GrdfInit: React.FC<GrdfInitProps> = ({ ] ) - const toggleModal = useCallback(() => { - setOpenModal((prev: boolean) => !prev) - }, []) - const goToPartnerSite = useCallback(() => { window.open(siteLink, '_blank') }, [siteLink]) return ( <> - {!showForm ? ( - <GrdfBill togglePartnerConnectionModal={toggleModal} /> - ) : ( - <GrdfForm togglePartnerConnectionModal={toggleModal} /> - )} + {!showForm ? <GrdfBill fluidStatus={fluidStatus} /> : <GrdfForm />} <GrdfConnectModal - open={openModal} + open={isConnectionModalOpen} showForm={showForm} konnector={konnector} fluidStatus={fluidStatus} - handleCloseClick={toggleModal} + handleCloseClick={() => dispatch(openConnectionModal(false))} setShowForm={setShowForm} goToPartnerSite={goToPartnerSite} handleSuccess={handleSuccess} diff --git a/src/components/Connection/SGEConnect/SgeInit.tsx b/src/components/Connection/SGEConnect/SgeInit.tsx index c882678e4..72dfc6f37 100644 --- a/src/components/Connection/SGEConnect/SgeInit.tsx +++ b/src/components/Connection/SGEConnect/SgeInit.tsx @@ -8,6 +8,7 @@ import React, { Dispatch, useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useNavigate } from 'react-router-dom' import { AppActionsTypes, AppStore } from 'store' +import { setShowOfflineData } from 'store/chart/chart.slice' import { setShouldRefreshConsent, updateSgeStore, @@ -67,6 +68,17 @@ const SgeInit: React.FC<SgeInitProps> = ({ fluidStatus }: SgeInitProps) => { > {t(`auth.${konnectorSlug}.connect`)} </Button> + {fluidStatus.firstDataDate && ( + <Button + classes={{ + root: 'btn-secondary', + label: 'text-16-bold', + }} + onClick={() => dispatch(setShowOfflineData(true))} + > + {t('auth.button_showOfflineData')} + </Button> + )} </div> </div> ) diff --git a/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap b/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap index 9664ddc16..83745b2d9 100644 --- a/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap +++ b/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap @@ -217,6 +217,132 @@ exports[`SgeInit component should be rendered correctly 1`] = ` </WithStyles(ForwardRef(ButtonBase))> </ForwardRef(Button)> </WithStyles(ForwardRef(Button))> + <WithStyles(ForwardRef(Button)) + classes={ + Object { + "label": "text-16-bold", + "root": "btn-secondary", + } + } + onClick={[Function]} + > + <ForwardRef(Button) + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-bold", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-secondary", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + className="MuiButton-root btn-secondary MuiButton-text" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + className="MuiButton-root btn-secondary MuiButton-text" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + className="MuiButtonBase-root MuiButton-root btn-secondary MuiButton-text" + disabled={false} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={0} + type="button" + > + <span + className="MuiButton-label text-16-bold" + > + auth.button_showOfflineData + </span> + <WithStyles(memo) + center={false} + > + <ForwardRef(TouchRipple) + center={false} + classes={ + Object { + "child": "MuiTouchRipple-child", + "childLeaving": "MuiTouchRipple-childLeaving", + "childPulsate": "MuiTouchRipple-childPulsate", + "ripple": "MuiTouchRipple-ripple", + "ripplePulsate": "MuiTouchRipple-ripplePulsate", + "rippleVisible": "MuiTouchRipple-rippleVisible", + "root": "MuiTouchRipple-root", + } + } + > + <span + className="MuiTouchRipple-root" + > + <TransitionGroup + childFactory={[Function]} + component={null} + exit={true} + /> + </span> + </ForwardRef(TouchRipple)> + </WithStyles(memo)> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> </div> </div> </SgeInit> diff --git a/src/components/Connection/__snapshots__/Connection.spec.tsx.snap b/src/components/Connection/__snapshots__/Connection.spec.tsx.snap index 3996b0f97..731f690ea 100644 --- a/src/components/Connection/__snapshots__/Connection.spec.tsx.snap +++ b/src/components/Connection/__snapshots__/Connection.spec.tsx.snap @@ -268,6 +268,132 @@ exports[`Connection component test should call EpglInit 1`] = ` </WithStyles(ForwardRef(ButtonBase))> </ForwardRef(Button)> </WithStyles(ForwardRef(Button))> + <WithStyles(ForwardRef(Button)) + classes={ + Object { + "label": "text-16-bold", + "root": "btn-secondary", + } + } + onClick={[Function]} + > + <ForwardRef(Button) + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-bold", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-secondary", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + className="MuiButton-root btn-secondary MuiButton-text" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + className="MuiButton-root btn-secondary MuiButton-text" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + className="MuiButtonBase-root MuiButton-root btn-secondary MuiButton-text" + disabled={false} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={0} + type="button" + > + <span + className="MuiButton-label text-16-bold" + > + auth.button_showOfflineData + </span> + <WithStyles(memo) + center={false} + > + <ForwardRef(TouchRipple) + center={false} + classes={ + Object { + "child": "MuiTouchRipple-child", + "childLeaving": "MuiTouchRipple-childLeaving", + "childPulsate": "MuiTouchRipple-childPulsate", + "ripple": "MuiTouchRipple-ripple", + "ripplePulsate": "MuiTouchRipple-ripplePulsate", + "rippleVisible": "MuiTouchRipple-rippleVisible", + "root": "MuiTouchRipple-root", + } + } + > + <span + className="MuiTouchRipple-root" + > + <TransitionGroup + childFactory={[Function]} + component={null} + exit={true} + /> + </span> + </ForwardRef(TouchRipple)> + </WithStyles(memo)> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> </div> </div> </SgeInit> diff --git a/src/components/Connection/connection.scss b/src/components/Connection/connection.scss index c12e34bfa..7593f4689 100644 --- a/src/components/Connection/connection.scss +++ b/src/components/Connection/connection.scss @@ -43,38 +43,23 @@ } .connection-form-button { - margin: 0 0.5rem; - button.btn-highlight { - padding: 0.5rem; - margin-top: 0.5rem; - margin-bottom: 0rem; - height: 2.5rem; - max-width: 22.5rem; - } - button.btn-secondary-negative { - padding: 0.5rem; - margin-top: 0.5rem; - margin-bottom: 1.5rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + button { height: 2.5rem; max-width: 22.5rem; + margin: 0; } } .connection-form-connect-button { margin: 0 0.5rem; - button.btn-highlight { + button { padding: 0.5rem; - margin-top: 0.5rem; - margin-bottom: 1rem; height: 5rem; - max-width: 22.5rem; - } - button.btn-secondary-negative { - padding: 0.5rem; - margin-top: 1rem; - margin-bottom: 2.5rem; - height: 5rem; - max-width: 22.5rem; } + &.grdf { margin-top: 2rem; } diff --git a/src/components/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx b/src/components/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx index 5a09cecc9..85ed7d955 100644 --- a/src/components/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx +++ b/src/components/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx @@ -19,7 +19,6 @@ const DataloadConsumptionVisualizer = ({ fluidType, dataload, compareDataload, - setActive, }: DataloadConsumptionVisualizerProps) => { const { loading, showCompare } = useSelector( diff --git a/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.spec.tsx b/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.spec.tsx index b56ed2c52..37aa7ad42 100644 --- a/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.spec.tsx +++ b/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.spec.tsx @@ -48,7 +48,7 @@ describe('InfoDataConsumptionVisualizer component', () => { expect(toJson(wrapper)).toMatchSnapshot() }) - describe('should render correctly consumption_visualizer.last_valid_data', () => { + describe('should render correctly consumption_visualizer.last_available_data', () => { it('case state MISSING', () => { const _mockdataLoad = { ...mockDataload, state: DataloadState.MISSING } const wrapper = mount( @@ -61,7 +61,7 @@ describe('InfoDataConsumptionVisualizer component', () => { </Provider> ) expect(wrapper.find('span').text()).toBe( - 'consumption_visualizer.last_valid_data : 01/10/20' + 'consumption_visualizer.last_available_data : 01/10/20' ) }) it('case state UPCOMING', () => { @@ -76,7 +76,7 @@ describe('InfoDataConsumptionVisualizer component', () => { </Provider> ) expect(wrapper.find('span').text()).toBe( - 'consumption_visualizer.last_valid_data : 01/10/20' + 'consumption_visualizer.last_available_data : 01/10/20' ) }) it('case state COMING', () => { @@ -94,7 +94,7 @@ describe('InfoDataConsumptionVisualizer component', () => { </Provider> ) expect(wrapper.find('span').text()).toBe( - 'consumption_visualizer.last_valid_data : 01/10/20' + 'consumption_visualizer.last_available_data : 01/10/20' ) }) it('case state AGGREGATED_HOLE_OR_MISSING', () => { diff --git a/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.tsx b/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.tsx index 758a187ff..4ac3bd966 100644 --- a/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.tsx +++ b/src/components/ConsumptionVisualizer/InfoDataConsumptionVisualizer.tsx @@ -62,7 +62,7 @@ const InfoDataConsumptionVisualizer = ({ <span className={`text-16-normal underlined-error`}> {(fluidType === FluidType.MULTIFLUID ? `${t('consumption_visualizer.last_valid_data_multi')}` - : `${t('consumption_visualizer.last_valid_data')}`) + + : `${t('consumption_visualizer.last_available_data')}`) + ` : ${lastDataDate ? lastDataDate.toFormat("dd'/'MM'/'yy") : '-'}`} </span> </div> diff --git a/src/components/ConsumptionVisualizer/infoDataConsumptionVisualizer.scss b/src/components/ConsumptionVisualizer/infoDataConsumptionVisualizer.scss index 057fd50f6..72cf43928 100644 --- a/src/components/ConsumptionVisualizer/infoDataConsumptionVisualizer.scss +++ b/src/components/ConsumptionVisualizer/infoDataConsumptionVisualizer.scss @@ -3,8 +3,6 @@ .error-line { color: $grey-bright; cursor: pointer; - display: flex; - align-items: center; } .underlined-error { text-align: center; diff --git a/src/components/FluidChart/FluidChart.tsx b/src/components/FluidChart/FluidChart.tsx index d79f5fb14..07e141014 100644 --- a/src/components/FluidChart/FluidChart.tsx +++ b/src/components/FluidChart/FluidChart.tsx @@ -1,3 +1,4 @@ +import { Button } from '@material-ui/core' import LegendComparisonIcon from 'assets/icons/ico/legendComparison.svg' import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import StyledSwitch from 'components/CommonKit/Switch/StyledSwitch' @@ -12,10 +13,19 @@ import { UsageEventType } from 'enum/usageEvent.enum' import { UserExplorationID } from 'enum/userExploration.enum' import React, { Dispatch, useCallback, useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { useNavigate } from 'react-router-dom' import ConsumptionService from 'services/consumption.service' +import DateChartService from 'services/dateChart.service' import UsageEventService from 'services/usageEvent.service' import { AppActionsTypes, AppStore } from 'store' -import { setShowCompare } from 'store/chart/chart.slice' +import { + setCurrentIndex, + setSelectedDate, + setShowCompare, + setShowOfflineData, +} from 'store/chart/chart.slice' +import { openConnectionModal } from 'store/modal/modal.slice' +import { getKonnectorSlug, isKonnectorActive } from 'utils/utils' import FluidChartSwipe from './FluidChartSwipe' import './fluidChart.scss' @@ -35,7 +45,10 @@ const FluidChart: React.FC<FluidChartProps> = ({ global: { fluidStatus }, } = useSelector((state: AppStore) => state.ecolyo) const dispatch = useDispatch<Dispatch<AppActionsTypes>>() + const navigate = useNavigate() + const currentFluidStatus = fluidStatus[fluidType] + const isFluidConnected = isKonnectorActive(fluidStatus, fluidType) const [, setValidExploration] = useExploration() // TODO use chart.loading ? const [isLoaded, setIsLoaded] = useState<boolean>(false) @@ -115,10 +128,57 @@ const FluidChart: React.FC<FluidChartProps> = ({ [lowercaseFluidType, lowercaseTimeStep, t] ) + // TODO if we keep this, use the same existing function + const moveToDate = () => { + if (currentFluidStatus?.lastDataDate) { + const dateChartService = new DateChartService() + const updatedIndex = dateChartService.defineDateIndex( + currentTimeStep, + currentFluidStatus.lastDataDate + ) + dispatch(setSelectedDate(currentFluidStatus.lastDataDate)) + dispatch(setCurrentIndex(updatedIndex)) + } + } + + const toggleModalConnection = () => { + switch (fluidType) { + case FluidType.ELECTRICITY: + navigate('/sge-connect') + break + case FluidType.GAS: + case FluidType.WATER: + dispatch(setShowOfflineData(false)) + dispatch(openConnectionModal(true)) + break + } + } + + const LastDataValid = () => ( + <div className="lastValidData"> + <span className={`text-16-normal date`} onClick={moveToDate}> + {t('consumption_visualizer.last_valid_data')} + {' : '} + {currentFluidStatus?.lastDataDate?.toFormat('dd/MM/yy') || '-'} + </span> + <p>{t('auth.warningOfflineData')}</p> + <Button + classes={{ + root: 'btn-secondary-negative', + label: 'text-16-bold', + }} + onClick={toggleModalConnection} + > + {t(`auth.${getKonnectorSlug(fluidType)}.connect`)} + </Button> + </div> + ) + return ( <> {isLoaded && ( <div className="fluidchart-root"> + {!isFluidConnected && <LastDataValid />} {currentTimeStep === TimeStep.HALF_AN_HOUR && !containsHalfHourData ? ( <HalfHourNoData /> diff --git a/src/components/FluidChart/fluidChart.scss b/src/components/FluidChart/fluidChart.scss index 6f5a4fcaf..ddd1e84f1 100644 --- a/src/components/FluidChart/fluidChart.scss +++ b/src/components/FluidChart/fluidChart.scss @@ -69,3 +69,19 @@ align-items: center; } } + +.lastValidData { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + span.date { + color: $grey-bright; + cursor: pointer; + text-decoration: underline; + } +} + +button { + max-width: 22.5rem; +} diff --git a/src/components/Home/ConsumptionView.spec.tsx b/src/components/Home/ConsumptionView.spec.tsx index 3d8d1dc09..704192b3e 100644 --- a/src/components/Home/ConsumptionView.spec.tsx +++ b/src/components/Home/ConsumptionView.spec.tsx @@ -88,6 +88,7 @@ describe('ConsumptionView component', () => { chart: { currentTimeStep: TimeStep.WEEK, loading: true, + showOfflineData: true, }, global: { fluidStatus: mockFluidStatus, @@ -116,6 +117,7 @@ describe('ConsumptionView component', () => { chart: { currentTimeStep: TimeStep.WEEK, loading: true, + showOfflineData: true, }, global: { fluidStatus: mockFluidStatus, @@ -160,6 +162,7 @@ describe('ConsumptionView component', () => { chart: { currentTimeStep: TimeStep.WEEK, loading: true, + showOfflineData: true, }, global: { fluidStatus: [], @@ -184,6 +187,7 @@ describe('ConsumptionView component', () => { chart: { currentTimeStep: TimeStep.WEEK, loading: true, + showOfflineData: true, }, global: { fluidStatus: updatedStatus, @@ -208,6 +212,7 @@ describe('ConsumptionView component', () => { chart: { currentTimeStep: TimeStep.WEEK, loading: true, + showOfflineData: true, }, global: { fluidStatus: updatedStatus, diff --git a/src/components/Home/ConsumptionView.tsx b/src/components/Home/ConsumptionView.tsx index 778eb6384..ab268ed1c 100644 --- a/src/components/Home/ConsumptionView.tsx +++ b/src/components/Home/ConsumptionView.tsx @@ -20,7 +20,7 @@ import { useDispatch, useSelector } from 'react-redux' import { useNavigate } from 'react-router-dom' import ProfileService from 'services/profile.service' import { AppActionsTypes, AppStore } from 'store' -import { setCurrentTimeStep, setLoading } from 'store/chart/chart.slice' +import { setCurrentTimeStep, setShowOfflineData } from 'store/chart/chart.slice' import { setCustomPopup, showReleaseNotes } from 'store/global/global.actions' import { openPartnersModal } from 'store/modal/modal.slice' import { @@ -40,14 +40,13 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ const navigate = useNavigate() const client = useClient() const dispatch = useDispatch<Dispatch<AppActionsTypes>>() - const isMulti = fluidType !== FluidType.MULTIFLUID + const isMulti = fluidType === FluidType.MULTIFLUID const { - chart: { currentTimeStep, loading }, + chart: { currentTimeStep, loading, showOfflineData }, global: { fluidStatus, releaseNotes, customPopupModal }, modal: { partnersIssueModal }, } = useSelector((state: AppStore) => state.ecolyo) - const [isFluidKonnected, setIsFluidKonnected] = useState<boolean>(false) const [openReleaseNoteModal, setOpenReleaseNoteModal] = useState<boolean>( releaseNotes.show ) @@ -137,19 +136,24 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ } } + /** Handle time change */ useEffect(() => { - setIsFluidKonnected(isKonnectorActive(fluidStatus, fluidType)) if ( fluidType !== FluidType.ELECTRICITY && currentTimeStep == TimeStep.HALF_AN_HOUR ) { dispatch(setCurrentTimeStep(TimeStep.WEEK)) } - }, [dispatch, fluidType, currentTimeStep, fluidStatus]) + }, [dispatch, fluidType, currentTimeStep]) + /** + * If fluid is not connected, display Connect components + * If fluid is connected, dispatch FluidChart + */ useEffect(() => { - dispatch(setLoading(true)) - }, [dispatch]) + const isFluidConnected = isKonnectorActive(fluidStatus, fluidType) + dispatch(setShowOfflineData(isFluidConnected)) + }, [dispatch, fluidStatus, fluidType]) useEffect(() => { let subscribed = true @@ -186,7 +190,7 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ handleCloseClick={handleCloseReleaseNoteModal} /> )} - {isFluidKonnected ? ( + {showOfflineData && ( <> {loading && ( <div className={'consumptionview-loading'} aria-busy="true"> @@ -205,7 +209,7 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ /> <ConsumptionDetails fluidType={fluidType} /> </div> - {isMulti && ( + {!isMulti && ( <div className="konnector-section"> <KonnectorViewerCard fluidStatus={fluidStatus[fluidType]} @@ -219,9 +223,12 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ </div> )} </> - ) : ( + )} + {!showOfflineData && ( <div className="konnector-section"> {isMulti ? ( + <KonnectorViewerList /> + ) : ( <KonnectorViewerCard fluidStatus={fluidStatus[fluidType]} fluidType={fluidType} @@ -230,8 +237,6 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ setActive={setActive} active={active} /> - ) : ( - <KonnectorViewerList /> )} </div> )} diff --git a/src/locales/fr.json b/src/locales/fr.json index f56626de4..da2a1f8ef 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -257,7 +257,9 @@ "button_connect": "Se connecter", "button_create_account": "Se créer un compte", "button_has_account": "J'ai déjà un compte", - "button_validate": "J'ai compris" + "button_validate": "J'ai compris", + "button_showOfflineData": "Voir mes anciennes données", + "warningOfflineData": "Attention, vous visualisez d’anciennes données. Pour actualiser vos données, connectez votre compteur" }, "challenge": { "card": { @@ -334,7 +336,8 @@ "no_data": "Pas de données", "why_no_data": "Pourquoi n'ai-je pas de données\u00a0?", "last_data": "Dernières données", - "last_valid_data": "Dernières données disponibles", + "last_valid_data": "Dernières données valides", + "last_available_data": "Dernières données disponibles", "last_valid_data_multi": "Dernières données complètes", "data_to_come": "à venir", "aie": "Aïe !", diff --git a/src/models/chart.model.ts b/src/models/chart.model.ts index 89ff47a09..787ad6861 100644 --- a/src/models/chart.model.ts +++ b/src/models/chart.model.ts @@ -10,4 +10,5 @@ export interface ChartState { loading: boolean selectedDate: DateTime showCompare: boolean + showOfflineData: boolean } diff --git a/src/models/modal.model.ts b/src/models/modal.model.ts index d98440cc5..94560f57f 100644 --- a/src/models/modal.model.ts +++ b/src/models/modal.model.ts @@ -1,4 +1,5 @@ export interface ModalState { + isConnectionModalOpen: boolean isFeedbacksOpen: boolean partnersIssueModal: { enedis: boolean diff --git a/src/store/chart/chart.slice.spec.ts b/src/store/chart/chart.slice.spec.ts index 3ba132b8f..717c26db4 100644 --- a/src/store/chart/chart.slice.spec.ts +++ b/src/store/chart/chart.slice.spec.ts @@ -126,3 +126,93 @@ describe('chart reducer', () => { }) }) }) + +describe('chart reducer', () => { + it('should return the initial state', () => { + const initialState = chartSlice.reducer(undefined, { type: undefined }) + expect(initialState).toEqual(mockInitialChartState) + }) + + it('should return same state if no action', () => { + const state = chartSlice.reducer(mockInitialChartState, { type: undefined }) + expect(state).toEqual(mockInitialChartState) + }) + + describe('setSelectedDate', () => { + it('should handle SET_SELECTED_DATE with payload', () => { + const mockDate = DateTime.fromISO('2021-01-01T00:00:00.000Z', { + zone: 'utc', + }) + const state = chartSlice.reducer( + mockInitialChartState, + setSelectedDate(mockDate) + ) + expect(state).toEqual({ + ...mockInitialChartState, + selectedDate: mockDate, + }) + }) + }) + + describe('setCurrentTimeStep', () => { + it('should handle SET_CURRENT_TIMESTEP with payload', () => { + const state = chartSlice.reducer( + mockInitialChartState, + setCurrentTimeStep(TimeStep.MONTH) + ) + expect(state).toEqual({ + ...mockInitialChartState, + currentTimeStep: TimeStep.MONTH, + }) + }) + }) + + describe('setCurrentIndex', () => { + it('should handle SET_CURRENT_INDEX with payload', () => { + const state = chartSlice.reducer( + mockInitialChartState, + setCurrentIndex(1) + ) + expect(state).toEqual({ + ...mockInitialChartState, + currentIndex: 1, + }) + }) + }) + + describe('setCurrentDataChart', () => { + it('should handle SET_CURRENT_DATACHART with payload', () => { + const state = chartSlice.reducer( + mockInitialChartState, + setCurrentDataChart(graphData) + ) + expect(state).toEqual({ + ...mockInitialChartState, + currentDatachart: graphData, + }) + }) + }) + + describe('setCurrentDataChartIndex', () => { + it('should handle SET_CURRENT_DATACHART_INDEX with payload', () => { + const state = chartSlice.reducer( + mockInitialChartState, + setCurrentDataChartIndex(1) + ) + expect(state).toEqual({ + ...mockInitialChartState, + currentDatachartIndex: 1, + }) + }) + }) + + describe('setLoading', () => { + it('should handle SET_LOADING with payload', () => { + const state = chartSlice.reducer(mockInitialChartState, setLoading(false)) + expect(state).toEqual({ + ...mockInitialChartState, + loading: false, + }) + }) + }) +}) diff --git a/src/store/chart/chart.slice.ts b/src/store/chart/chart.slice.ts index 9ebb8a25b..d724d93d0 100644 --- a/src/store/chart/chart.slice.ts +++ b/src/store/chart/chart.slice.ts @@ -10,6 +10,7 @@ type SetCurrentTimeStep = PayloadAction<TimeStep> type SetLoading = PayloadAction<boolean> type SetSelectedDate = PayloadAction<DateTime> type SetShowCompare = PayloadAction<boolean> +type SetShowOfflineData = PayloadAction<boolean> export type ChartActionTypes = | SetCurrentDataChart @@ -19,6 +20,7 @@ export type ChartActionTypes = | SetLoading | SetSelectedDate | SetShowCompare + | SetShowOfflineData const initialState: ChartState = { selectedDate: DateTime.local().endOf('minute').setZone('utc', { @@ -30,6 +32,7 @@ const initialState: ChartState = { currentDatachartIndex: 0, loading: true, showCompare: false, + showOfflineData: false, } export const chartSlice = createSlice({ @@ -60,6 +63,9 @@ export const chartSlice = createSlice({ setShowCompare: (state, action: SetShowCompare) => { state.showCompare = action.payload }, + setShowOfflineData: (state, action: SetShowOfflineData) => { + state.showOfflineData = action.payload + }, }, }) @@ -71,4 +77,5 @@ export const { setLoading, setSelectedDate, setShowCompare, + setShowOfflineData, } = chartSlice.actions diff --git a/src/store/modal/modal.slice.spec.ts b/src/store/modal/modal.slice.spec.ts index 28de84b03..86d390709 100644 --- a/src/store/modal/modal.slice.spec.ts +++ b/src/store/modal/modal.slice.spec.ts @@ -1,6 +1,11 @@ import { ModalState } from 'models' import { mockInitialModalState } from '../../../tests/__mocks__/store' -import { modalSlice, openFeedbackModal, openPartnersModal } from './modal.slice' +import { + modalSlice, + openConnectionModal, + openFeedbackModal, + openPartnersModal, +} from './modal.slice' describe('modal reducer', () => { it('should return the initial state', () => { @@ -9,7 +14,7 @@ describe('modal reducer', () => { }) describe('Feedback Modal', () => { - it('should handle UPDATE_FEEDBACK_MODAL with payload', () => { + it('should handle openFeedbackModal with payload', () => { const state = modalSlice.reducer( mockInitialModalState, openFeedbackModal(true) @@ -41,7 +46,7 @@ describe('modal reducer', () => { } expect(state).toEqual(expectedResult) }) - it('should handle OPEN_PARTNERS_MODAL to set all partners to true', () => { + it('should handle openPartnersModal to set all partners to true', () => { const state = modalSlice.reducer( mockInitialModalState, openPartnersModal({ egl: true, enedis: true, grdf: true }) @@ -54,7 +59,7 @@ describe('modal reducer', () => { } expect(state).toEqual(expectedResult) }) - it('should handle OPEN_PARTNERS_MODAL to set some partners to false', () => { + it('should handle openPartnersModal to set some partners to false', () => { const state = modalSlice.reducer( { ...mockInitialModalState, @@ -74,5 +79,15 @@ describe('modal reducer', () => { } expect(state).toEqual(expectedResult) }) + it('should handle openConnectionModal', () => { + const state = modalSlice.reducer( + mockInitialModalState, + openConnectionModal(true) + ) + expect(state).toEqual({ + ...mockInitialModalState, + isConnectionModalOpen: true, + }) + }) }) }) diff --git a/src/store/modal/modal.slice.ts b/src/store/modal/modal.slice.ts index 96eb360cb..e530d3fa4 100644 --- a/src/store/modal/modal.slice.ts +++ b/src/store/modal/modal.slice.ts @@ -2,6 +2,7 @@ import { PayloadAction, createSlice } from '@reduxjs/toolkit' import { ModalState } from 'models' const initialState: ModalState = { + isConnectionModalOpen: false, isFeedbacksOpen: false, partnersIssueModal: { enedis: false, @@ -11,6 +12,7 @@ const initialState: ModalState = { } type OpenFeedbackModalAction = PayloadAction<boolean> +type OpenConnectionModalAction = PayloadAction<boolean> type OpenPartnersModalAction = PayloadAction<{ egl: boolean enedis: boolean @@ -29,7 +31,11 @@ export const modalSlice = createSlice({ openPartnersModal: (state, action: OpenPartnersModalAction) => { state.partnersIssueModal = action.payload }, + openConnectionModal: (state, action: OpenConnectionModalAction) => { + state.isConnectionModalOpen = action.payload + }, }, }) -export const { openFeedbackModal, openPartnersModal } = modalSlice.actions +export const { openFeedbackModal, openPartnersModal, openConnectionModal } = + modalSlice.actions diff --git a/src/styles/components/_buttons.scss b/src/styles/components/_buttons.scss index 2ee92640a..8735392e4 100644 --- a/src/styles/components/_buttons.scss +++ b/src/styles/components/_buttons.scss @@ -33,6 +33,9 @@ button { } } } + &.btn-secondary { + @include button(transparent, $gold-euro, 1px solid $grey-dark); + } &.btn-secondary-positive { @include button( transparent, diff --git a/src/utils/utils.spec.ts b/src/utils/utils.spec.ts index ade89ea08..218e783cd 100644 --- a/src/utils/utils.spec.ts +++ b/src/utils/utils.spec.ts @@ -1,16 +1,18 @@ import { Season } from 'enum/ecogesture.enum' import { FluidType } from 'enum/fluid.enum' +import { FluidSlugType } from 'enum/fluidSlug.enum' import { DateTime } from 'luxon' import { formatNumberValues, getChallengeTitleWithLineReturn, getFluidType, + getKonnectorSlug, getSeason, } from './utils' -describe('utilis utilis test', () => { +describe('utils test', () => { describe('getFluidType test', () => { - it('should the electrity fluid type', () => { + it('should the electricity fluid type', () => { const result = getFluidType('eLectRicity') expect(result).toBe(FluidType.ELECTRICITY) }) @@ -25,6 +27,20 @@ describe('utilis utilis test', () => { expect(result).toBe(FluidType.GAS) }) }) + describe('getKonnectorSlug', () => { + it('should return correct slug for elec', () => { + const slug = getKonnectorSlug(FluidType.ELECTRICITY) + expect(slug).toBe(FluidSlugType.ELECTRICITY) + }) + it('should return correct slug for water', () => { + const slug = getKonnectorSlug(FluidType.WATER) + expect(slug).toBe(FluidSlugType.WATER) + }) + it('should return correct slug for gas', () => { + const slug = getKonnectorSlug(FluidType.GAS) + expect(slug).toBe(FluidSlugType.GAS) + }) + }) describe('formatNumberValues test', () => { it('should return --,-- if there is not value', () => { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 773eb7d0a..e24d187a2 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,4 +1,5 @@ import { Season } from 'enum/ecogesture.enum' +import { FluidSlugType } from 'enum/fluidSlug.enum' import get from 'lodash/get' import { DateTime, Interval } from 'luxon' import { FluidStatus, GetRelationshipsReturn, Relation } from 'models' @@ -18,6 +19,18 @@ export function getFluidType(type: string) { return FluidType.ELECTRICITY } } +export function getKonnectorSlug(fluidType: FluidType) { + switch (fluidType) { + case FluidType.ELECTRICITY: + return FluidSlugType.ELECTRICITY + case FluidType.WATER: + return FluidSlugType.WATER + case FluidType.GAS: + return FluidSlugType.GAS + default: + throw new Error('unknown fluidtype') + } +} export function getKonnectorUpdateError(type: string) { switch (type.toUpperCase()) { case 'USER_ACTION_NEEDED.OAUTH_OUTDATED': diff --git a/tests/__mocks__/store.ts b/tests/__mocks__/store.ts index 4185f3f78..73304af29 100644 --- a/tests/__mocks__/store.ts +++ b/tests/__mocks__/store.ts @@ -279,9 +279,11 @@ export const mockInitialChartState: ChartState = { currentDatachartIndex: 0, loading: true, showCompare: false, + showOfflineData: false, } export const mockInitialModalState: ModalState = { + isConnectionModalOpen: false, isFeedbacksOpen: false, partnersIssueModal: { enedis: false, -- GitLab