diff --git a/src/components/Connection/Connection.spec.tsx b/src/components/Connection/Connection.spec.tsx index c5915516acfff3f7dca52840d7c9e2c01f5e1604..ba59c476150e5239a40ca42fe343f9305220116f 100644 --- a/src/components/Connection/Connection.spec.tsx +++ b/src/components/Connection/Connection.spec.tsx @@ -1,9 +1,9 @@ import Connection from 'components/Connection/Connection' +import { FluidType } from 'enums' import { mount } from 'enzyme' import toJson from 'enzyme-to-json' import React from 'react' import { Provider } from 'react-redux' -import { fluidStatusConnectedData } from 'tests/__mocks__/fluidStatusData.mock' import { createMockEcolyoStore } from 'tests/__mocks__/store' jest.mock('components/Connection/EPGLConnect/EpglInit', () => 'mock-EpglInit') @@ -15,7 +15,7 @@ describe('Connection component test', () => { it('should call GrdfInit', () => { const wrapper = mount( <Provider store={store}> - <Connection fluidStatus={fluidStatusConnectedData[2]} /> + <Connection fluidType={FluidType.GAS} /> </Provider> ) expect(toJson(wrapper)).toMatchSnapshot() @@ -24,7 +24,7 @@ describe('Connection component test', () => { it('should call EpglInit', () => { const wrapper = mount( <Provider store={store}> - <Connection fluidStatus={fluidStatusConnectedData[0]} /> + <Connection fluidType={FluidType.WATER} /> </Provider> ) expect(toJson(wrapper)).toMatchSnapshot() diff --git a/src/components/Connection/Connection.tsx b/src/components/Connection/Connection.tsx index 7097c8f0c0e87d9293ae722306622060d84098e7..04513039f6f7c9d959eefa6649142fb884619e5b 100644 --- a/src/components/Connection/Connection.tsx +++ b/src/components/Connection/Connection.tsx @@ -1,39 +1,35 @@ import { FluidType } from 'enums' -import { FluidConnection, FluidStatus } from 'models' +import { FluidConnection } from 'models' import React, { useCallback } from 'react' import { updateFluidConnection } from 'store/global/global.slice' -import { useAppDispatch } from 'store/hooks' +import { useAppDispatch, useAppSelector } from 'store/hooks' import EpglInit from './EPGLConnect/EpglInit' import GrdfInit from './GRDFConnect/GrdfInit' import SgeInit from './SGEConnect/SgeInit' import './connection.scss' -const Connection = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { +const Connection = ({ fluidType }: { fluidType: FluidType }) => { + const { fluidStatus } = useAppSelector(state => state.ecolyo.global) + const currentFluidStatus = fluidStatus[fluidType] const dispatch = useAppDispatch() const handleSuccess = useCallback(async () => { const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, shouldLaunchKonnector: true, } dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: fluidType, fluidConnection: updatedConnection, }) ) - }, [dispatch, fluidStatus.fluidType, fluidStatus.connection]) + }, [dispatch, fluidType, currentFluidStatus.connection]) return ( <div className="konnector-form"> - {fluidStatus.fluidType === FluidType.ELECTRICITY && ( - <SgeInit fluidStatus={fluidStatus} /> - )} - {fluidStatus.fluidType === FluidType.WATER && ( - <EpglInit fluidStatus={fluidStatus} /> - )} - {fluidStatus.fluidType === FluidType.GAS && ( - <GrdfInit fluidStatus={fluidStatus} onSuccess={handleSuccess} /> - )} + {fluidType === FluidType.ELECTRICITY && <SgeInit />} + {fluidType === FluidType.WATER && <EpglInit />} + {fluidType === FluidType.GAS && <GrdfInit onSuccess={handleSuccess} />} </div> ) } diff --git a/src/components/Connection/EPGLConnect/EpglBill.tsx b/src/components/Connection/EPGLConnect/EpglBill.tsx index 23f5c6177fb56a46dc0958b5dd8d4c694eccfd6d..649848d8fa79bf9374a3f1d95c5357745e4d4a7a 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 { FluidStatus } from 'models' +import { FluidType } from 'enums' import React from 'react' import { setShowOfflineData } from 'store/chart/chart.slice' -import { useAppDispatch } from 'store/hooks' +import { useAppDispatch, useAppSelector } from 'store/hooks' import { openConnectionModal } from 'store/modal/modal.slice' import '../connection.scss' -const EpglBill = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { +const EpglBill = () => { const { t } = useI18n() const dispatch = useAppDispatch() + const { fluidStatus } = useAppSelector(state => state.ecolyo.global) + const currentFluidStatus = fluidStatus[FluidType.WATER] return ( <div className="connection-form"> @@ -36,7 +38,7 @@ const EpglBill = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { > {t('auth.eglgrandlyon.connect')} </Button> - {fluidStatus.firstDataDate && ( + {currentFluidStatus.firstDataDate && ( <Button classes={{ root: 'btn-secondary', diff --git a/src/components/Connection/EPGLConnect/EpglForm.tsx b/src/components/Connection/EPGLConnect/EpglForm.tsx index 3ff6e8792bf7e2df7c55cf8b14d89dab42056070..7626152639d743c4bfd23c1ba892c365bedd1387 100644 --- a/src/components/Connection/EPGLConnect/EpglForm.tsx +++ b/src/components/Connection/EPGLConnect/EpglForm.tsx @@ -1,15 +1,9 @@ import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { FluidStatus } from 'models' import React from 'react' import '../connection.scss' import FormLogin from './FormLogin/FormLogin' -interface EpglFormProps { - fluidStatus: FluidStatus - hasCreatedAccount: boolean -} - -const EpglForm = ({ fluidStatus, hasCreatedAccount }: EpglFormProps) => { +const EpglForm = ({ hasCreatedAccount }: { hasCreatedAccount: boolean }) => { const { t } = useI18n() return ( @@ -22,7 +16,7 @@ const EpglForm = ({ fluidStatus, hasCreatedAccount }: EpglFormProps) => { <div className="connection-form-subtitle text-18-bold"> {t('auth.eglgrandlyon.with_account.subtitle1')} </div> - <FormLogin fluidStatus={fluidStatus} /> + <FormLogin /> </div> ) } diff --git a/src/components/Connection/EPGLConnect/EpglInit.tsx b/src/components/Connection/EPGLConnect/EpglInit.tsx index 23a1057a3130c3f67238ca017090c8d812096f96..d79dd4a9d07517da49bed11e57cc3d59342c7bf5 100644 --- a/src/components/Connection/EPGLConnect/EpglInit.tsx +++ b/src/components/Connection/EPGLConnect/EpglInit.tsx @@ -1,5 +1,5 @@ import EpglConnectModal from 'components/Connection/PartnerConnectModal/EpglConnectModal' -import { FluidStatus } from 'models' +import { FluidType } from 'enums' import React, { useCallback, useState } from 'react' import { useAppDispatch, useAppSelector } from 'store/hooks' import { openConnectionModal } from 'store/modal/modal.slice' @@ -7,10 +7,15 @@ import '../connection.scss' import EpglBill from './EpglBill' import EpglForm from './EpglForm' -const EpglInit = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { +const EpglInit = () => { const dispatch = useAppDispatch() - const { isConnectionModalOpen } = useAppSelector(state => state.ecolyo.modal) - const siteLink: string = fluidStatus.connection.konnectorConfig.siteLink + const { + modal: { isConnectionModalOpen }, + global: { fluidStatus }, + } = useAppSelector(state => state.ecolyo) + const currentFluidStatus = fluidStatus[FluidType.WATER] + const siteLink: string = + currentFluidStatus.connection.konnectorConfig.siteLink const [showForm, setShowForm] = useState(false) const [hasCreatedAccount, setHasCreatedAccount] = useState(false) @@ -22,12 +27,9 @@ const EpglInit = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { return ( <> {!showForm ? ( - <EpglBill fluidStatus={fluidStatus} /> + <EpglBill /> ) : ( - <EpglForm - fluidStatus={fluidStatus} - hasCreatedAccount={hasCreatedAccount} - /> + <EpglForm hasCreatedAccount={hasCreatedAccount} /> )} <EpglConnectModal open={isConnectionModalOpen} diff --git a/src/components/Connection/EPGLConnect/FormLogin/FormLogin.tsx b/src/components/Connection/EPGLConnect/FormLogin/FormLogin.tsx index 054e74e51c9c8c2c1ece0c1b96056e5e12b7c46f..118d594a9c37eade4fa537cfa2976342d3755106 100644 --- a/src/components/Connection/EPGLConnect/FormLogin/FormLogin.tsx +++ b/src/components/Connection/EPGLConnect/FormLogin/FormLogin.tsx @@ -6,18 +6,22 @@ import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' import useKonnectorAuth from 'components/Hooks/useKonnectorAuth' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import { FluidType } from 'enums' -import { Account, AccountAuthData, FluidStatus } from 'models' +import { Account, AccountAuthData } from 'models' import React, { useEffect, useState } from 'react' +import { useAppSelector } from 'store/hooks' import { getPartnerPicto } from 'utils/picto' import './formLogin.scss' -const FormLogin = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { +const FormLogin = () => { const { t } = useI18n() - const konnectorSlug: string = fluidStatus.connection.konnectorConfig.slug - const lastKnownCredentials: string | undefined = - fluidStatus.connection.konnectorConfig.lastKnownCredentials - const fluidName: string = FluidType[fluidStatus.fluidType] - const account: Account | null = fluidStatus.connection.account + const { fluidStatus, lastEpglLogin } = useAppSelector( + state => state.ecolyo.global + ) + const currentFluidStatus = fluidStatus[FluidType.WATER] + const konnectorSlug: string = + currentFluidStatus.connection.konnectorConfig.slug + const fluidName: string = FluidType[currentFluidStatus.fluidType] + const account: Account | null = currentFluidStatus.connection.account const [login, setLogin] = useState<string>('') const [password, setPassword] = useState<string>('') @@ -26,7 +30,7 @@ const FormLogin = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { const icon = getPartnerPicto(konnectorSlug) const [connect, update, connectError] = useKonnectorAuth( - fluidStatus, + currentFluidStatus.fluidType, login, password ) @@ -87,11 +91,11 @@ const FormLogin = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { if (authData.login) { setLogin(authData.login) } - } else if (lastKnownCredentials) { - setLogin(lastKnownCredentials) + } else if (lastEpglLogin) { + setLogin(lastEpglLogin) setError(t('konnector_form.error_login_failed')) } - }, [account, lastKnownCredentials, t]) + }, [account, lastEpglLogin, t]) return ( <form diff --git a/src/components/Connection/GRDFConnect/GrdfBill.tsx b/src/components/Connection/GRDFConnect/GrdfBill.tsx index 40c1dd0af27e666c1df30ff3bcdbf99a6e14051b..bd4a97115f34f03b240b41242b9bbc6d9f6aa8f9 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 { FluidStatus } from 'models' +import { FluidType } from 'enums' import React from 'react' import { setShowOfflineData } from 'store/chart/chart.slice' -import { useAppDispatch } from 'store/hooks' +import { useAppDispatch, useAppSelector } from 'store/hooks' import { openConnectionModal } from 'store/modal/modal.slice' import '../connection.scss' -const GrdfBill = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { +const GrdfBill = () => { const { t } = useI18n() const dispatch = useAppDispatch() + const { fluidStatus } = useAppSelector(state => state.ecolyo.global) + const currentFluidStatus = fluidStatus[FluidType.GAS] return ( <div className="connection-form"> @@ -35,7 +37,7 @@ const GrdfBill = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { > {t('auth.grdfgrandlyon.connect')} </Button> - {fluidStatus.firstDataDate && ( + {currentFluidStatus.firstDataDate && ( <Button classes={{ root: 'btn-secondary', diff --git a/src/components/Connection/GRDFConnect/GrdfInit.tsx b/src/components/Connection/GRDFConnect/GrdfInit.tsx index f6ff3a663c8fd633f3042ca76c6b092dcf393c97..8761ee395e1bac7ac8fbcc9a15b075cb798a7731 100644 --- a/src/components/Connection/GRDFConnect/GrdfInit.tsx +++ b/src/components/Connection/GRDFConnect/GrdfInit.tsx @@ -1,7 +1,7 @@ import GrdfConnectModal from 'components/Connection/PartnerConnectModal/GrdfConnectModal' import { useClient } from 'cozy-client' -import { UsageEventType } from 'enums' -import { FluidConnection, FluidStatus, Konnector, Trigger } from 'models' +import { FluidType, UsageEventType } from 'enums' +import { FluidConnection, Konnector, Trigger } from 'models' import React, { useCallback, useState } from 'react' import AccountService from 'services/account.service' import TriggerService from 'services/triggers.service' @@ -13,21 +13,22 @@ import '../connection.scss' import GrdfBill from './GrdfBill' import GrdfForm from './GrdfForm' -interface GrdfInitProps { - fluidStatus: FluidStatus - onSuccess: () => Promise<void> -} - -const GrdfInit = ({ fluidStatus, onSuccess }: GrdfInitProps) => { +const GrdfInit = ({ onSuccess }: { onSuccess: () => Promise<void> }) => { const client = useClient() const dispatch = useAppDispatch() - const { isConnectionModalOpen } = useAppSelector(state => state.ecolyo.modal) + const { + modal: { isConnectionModalOpen }, + global: { fluidStatus }, + } = useAppSelector(state => state.ecolyo) const [showForm, setShowForm] = useState(false) - const konnectorSlug: string = fluidStatus.connection.konnectorConfig.slug - const siteLink: string = fluidStatus.connection.konnectorConfig.siteLink - const konnector: Konnector | null = fluidStatus.connection.konnector + const currentFluidStatus = fluidStatus[FluidType.GAS] + const konnectorSlug: string = + currentFluidStatus.connection.konnectorConfig.slug + const siteLink: string = + currentFluidStatus.connection.konnectorConfig.siteLink + const konnector: Konnector | null = currentFluidStatus.connection.konnector const handleSuccess = useCallback( async (accountId: string) => { @@ -36,13 +37,13 @@ const GrdfInit = ({ fluidStatus, onSuccess }: GrdfInitProps) => { const account = await accountService.getAccount(accountId) if (!account) { const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, account: null, trigger: null, } dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: currentFluidStatus.fluidType, fluidConnection: updatedConnection, }) ) @@ -58,13 +59,13 @@ const GrdfInit = ({ fluidStatus, onSuccess }: GrdfInitProps) => { konnector ) const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, account: account, trigger: trigger, } dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: currentFluidStatus.fluidType, fluidConnection: updatedConnection, }) ) @@ -76,8 +77,8 @@ const GrdfInit = ({ fluidStatus, onSuccess }: GrdfInitProps) => { client, konnector, dispatch, - fluidStatus.fluidType, - fluidStatus.connection, + currentFluidStatus.fluidType, + currentFluidStatus.connection, onSuccess, konnectorSlug, ] @@ -89,12 +90,10 @@ const GrdfInit = ({ fluidStatus, onSuccess }: GrdfInitProps) => { return ( <> - {!showForm ? <GrdfBill fluidStatus={fluidStatus} /> : <GrdfForm />} + {!showForm ? <GrdfBill /> : <GrdfForm />} <GrdfConnectModal open={isConnectionModalOpen} showForm={showForm} - konnector={konnector} - fluidStatus={fluidStatus} handleCloseClick={() => dispatch(openConnectionModal(false))} setShowForm={setShowForm} goToPartnerSite={goToPartnerSite} diff --git a/src/components/Connection/PartnerConnectModal/EpglConnectModal.tsx b/src/components/Connection/PartnerConnectModal/EpglConnectModal.tsx index e465daa66604048383e891b4ace5189aeed7cd46..f32093cd6c8e96f72beb6a0a660eb86546f343dd 100644 --- a/src/components/Connection/PartnerConnectModal/EpglConnectModal.tsx +++ b/src/components/Connection/PartnerConnectModal/EpglConnectModal.tsx @@ -4,9 +4,9 @@ import { useI18n } from 'cozy-ui/transpiled/react/I18n' import Icon from 'cozy-ui/transpiled/react/Icon' import React, { useEffect, useState } from 'react' import './PartnerConnectModal.scss' +import { StepContent } from './StepContent.interface' import EpglCreateAccount from './Steps/EpglCreateAccount' import EpglDoYouHaveAccount from './Steps/EpglDoYouHaveAccount' -import { StepContent } from './stepContent.interface' enum StepEnum { DoYouHaveAccount, diff --git a/src/components/Connection/PartnerConnectModal/GrdfConnectModal.tsx b/src/components/Connection/PartnerConnectModal/GrdfConnectModal.tsx index 4521904582745b56b22f34d8a648c89fe87260c8..20d12143ecc8e46692e03c81caf9f32a4c0fd192 100644 --- a/src/components/Connection/PartnerConnectModal/GrdfConnectModal.tsx +++ b/src/components/Connection/PartnerConnectModal/GrdfConnectModal.tsx @@ -3,13 +3,12 @@ import CloseIcon from 'assets/icons/ico/close.svg' import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import GrdfFormOAuth from 'components/Connection/PartnerConnectModal/Steps/GrdfFormOAuth' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { FluidStatus, Konnector } from 'models' import React, { useEffect, useState } from 'react' import './PartnerConnectModal.scss' +import { StepContent } from './StepContent.interface' import GrdfCreateAccount from './Steps/GrdfCreateAccount' import GrdfDoYouHaveAccount from './Steps/GrdfDoYouHaveAccount' import GrdfGiveConsent from './Steps/GrdfGiveConsent' -import { StepContent } from './stepContent.interface' enum StepEnum { DoYouHaveAccount, @@ -20,8 +19,6 @@ enum StepEnum { interface GrdfConnectModalProps { open: boolean showForm: boolean - konnector: Konnector | null - fluidStatus: FluidStatus handleCloseClick: () => void setShowForm: (value: boolean) => void goToPartnerSite: () => void @@ -31,8 +28,6 @@ interface GrdfConnectModalProps { const GrdfConnectModal = ({ open, showForm, - konnector, - fluidStatus, handleCloseClick, setShowForm, goToPartnerSite, @@ -40,6 +35,7 @@ const GrdfConnectModal = ({ }: GrdfConnectModalProps) => { const { t } = useI18n() const [currentStep, setCurrentStep] = useState(StepEnum.DoYouHaveAccount) + useEffect(() => { if (open) { showForm @@ -121,13 +117,7 @@ const GrdfConnectModal = ({ {`< ${t('auth.button_previous')}`} </Button> ), - rightButton: ( - <GrdfFormOAuth - konnector={konnector} - onSuccess={handleSuccess} - fluidStatus={fluidStatus} - /> - ), + rightButton: <GrdfFormOAuth onSuccess={handleSuccess} />, }, } diff --git a/src/components/Connection/PartnerConnectModal/Steps/GrdfFormOAuth.tsx b/src/components/Connection/PartnerConnectModal/Steps/GrdfFormOAuth.tsx index 7b962fd1c06dc68dea4741add9e1cb3dc1a2578b..287f55d0d558879517fbc87f6f9a2b3612936975 100644 --- a/src/components/Connection/PartnerConnectModal/Steps/GrdfFormOAuth.tsx +++ b/src/components/Connection/PartnerConnectModal/Steps/GrdfFormOAuth.tsx @@ -2,30 +2,28 @@ import Button from '@material-ui/core/Button' import { useClient } from 'cozy-client' import { OAuthWindow } from 'cozy-harvest-lib/dist/components/OAuthWindow' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { UsageEventType } from 'enums' -import { FluidStatus, Konnector } from 'models' +import { FluidType, UsageEventType } from 'enums' +import { Konnector } from 'models' import React, { useCallback, useEffect, useState } from 'react' import UsageEventService from 'services/usageEvent.service' import { setShouldRefreshConsent } from 'store/global/global.slice' import { useAppDispatch, useAppSelector } from 'store/hooks' -interface GrdfFormOAuthProps { - konnector: Konnector | null - onSuccess: (accountId: string) => Promise<void> - fluidStatus: FluidStatus -} - const GrdfFormOAuth = ({ - konnector, onSuccess, - fluidStatus, -}: GrdfFormOAuthProps) => { +}: { + onSuccess: (accountId: string) => Promise<void> +}) => { const IDLE = 'idle' const WAITING = 'waiting' const { t } = useI18n() const client = useClient() - const { shouldRefreshConsent } = useAppSelector(state => state.ecolyo.global) + const { shouldRefreshConsent, fluidStatus } = useAppSelector( + state => state.ecolyo.global + ) + const currentFluidStatus = fluidStatus[FluidType.GAS] + const konnector: Konnector | null = currentFluidStatus.connection.konnector const dispatch = useAppDispatch() const [status, setStatus] = useState<string>(IDLE) const endOAuth = useCallback(() => { @@ -36,7 +34,7 @@ const GrdfFormOAuth = ({ const startOAuth = useCallback(async () => { // If first connexion, send the usage event - if (konnector?.slug && fluidStatus.lastDataDate === null) { + if (konnector?.slug && currentFluidStatus.lastDataDate === null) { await UsageEventService.addEvent(client, { type: UsageEventType.KONNECTOR_ATTEMPT_EVENT, target: konnector.slug, @@ -44,7 +42,7 @@ const GrdfFormOAuth = ({ }) } setStatus(WAITING) - }, [client, fluidStatus.lastDataDate, konnector]) + }, [client, currentFluidStatus.lastDataDate, konnector]) const handleAccountId = useCallback( (accountId: string) => { diff --git a/src/components/Connection/SGEConnect/SgeInit.spec.tsx b/src/components/Connection/SGEConnect/SgeInit.spec.tsx index 840893b54596f048dfc9fd03f6720d0d824e3783..cd01cfb542a872b7cc810cc3e3db94545f6b4fad 100644 --- a/src/components/Connection/SGEConnect/SgeInit.spec.tsx +++ b/src/components/Connection/SGEConnect/SgeInit.spec.tsx @@ -3,10 +3,7 @@ import { mount } from 'enzyme' import toJson from 'enzyme-to-json' import React from 'react' import { Provider } from 'react-redux' -import { - fluidStatusData, - SgeStatusWithAccount, -} from 'tests/__mocks__/fluidStatusData.mock' +import { SgeStatusWithAccount } from 'tests/__mocks__/fluidStatusData.mock' import { createMockEcolyoStore, mockGlobalState } from 'tests/__mocks__/store' import { waitForComponentToPaint } from 'tests/__mocks__/testUtils' import SgeInit from './SgeInit' @@ -29,7 +26,7 @@ describe('SgeInit component', () => { it('should be rendered correctly', () => { const wrapper = mount( <Provider store={store}> - <SgeInit fluidStatus={fluidStatusData[0]} /> + <SgeInit /> </Provider> ) expect(toJson(wrapper)).toMatchSnapshot() @@ -37,7 +34,7 @@ describe('SgeInit component', () => { it('should go to sge connect steps', () => { const wrapper = mount( <Provider store={store}> - <SgeInit fluidStatus={fluidStatusData[0]} /> + <SgeInit /> </Provider> ) wrapper.find(Button).first().simulate('click') @@ -46,6 +43,7 @@ describe('SgeInit component', () => { it('should launch account and trigger creation process', async () => { const store = createMockEcolyoStore({ global: { + ...mockGlobalState, sgeConnect: { ...mockGlobalState.sgeConnect, shouldLaunchAccount: true, @@ -55,7 +53,7 @@ describe('SgeInit component', () => { const wrapper = mount( <Provider store={store}> - <SgeInit fluidStatus={fluidStatusData[0]} /> + <SgeInit /> </Provider> ) await waitForComponentToPaint(wrapper) @@ -64,6 +62,8 @@ describe('SgeInit component', () => { it('should launch existing account update process', async () => { const store = createMockEcolyoStore({ global: { + ...mockGlobalState, + fluidStatus: [SgeStatusWithAccount], sgeConnect: { ...mockGlobalState.sgeConnect, shouldLaunchAccount: true, @@ -72,7 +72,7 @@ describe('SgeInit component', () => { }) const wrapper = mount( <Provider store={store}> - <SgeInit fluidStatus={SgeStatusWithAccount} /> + <SgeInit /> </Provider> ) await waitForComponentToPaint(wrapper) diff --git a/src/components/Connection/SGEConnect/SgeInit.tsx b/src/components/Connection/SGEConnect/SgeInit.tsx index 57b6bf02f7fccf597bac917ece67475c6d676841..c36fecbf61a44c02b469b72473c5870a1ca12600 100644 --- a/src/components/Connection/SGEConnect/SgeInit.tsx +++ b/src/components/Connection/SGEConnect/SgeInit.tsx @@ -3,7 +3,8 @@ import ElectricityBillIcon from 'assets/icons/visu/onboarding/electricity_bill.s import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import useKonnectorAuth from 'components/Hooks/useKonnectorAuth' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { Account, FluidStatus } from 'models' +import { FluidType } from 'enums' +import { Account } from 'models' import React, { useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { setShowOfflineData } from 'store/chart/chart.slice' @@ -13,14 +14,17 @@ import { } from 'store/global/global.slice' import { useAppDispatch, useAppSelector } from 'store/hooks' -const SgeInit = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { +const SgeInit = () => { const { t } = useI18n() const navigate = useNavigate() - const konnectorSlug: string = fluidStatus.connection.konnectorConfig.slug - const account: Account | null = fluidStatus.connection.account + const { fluidStatus } = useAppSelector(state => state.ecolyo.global) + const currentFluidStatus = fluidStatus[FluidType.ELECTRICITY] + const konnectorSlug: string = + currentFluidStatus.connection.konnectorConfig.slug + const account: Account | null = currentFluidStatus.connection.account const { sgeConnect } = useAppSelector(state => state.ecolyo.global) const dispatch = useAppDispatch() - const [connect, update] = useKonnectorAuth(fluidStatus) + const [connect, update] = useKonnectorAuth(currentFluidStatus.fluidType) useEffect(() => { async function launchConnect() { @@ -61,7 +65,7 @@ const SgeInit = ({ fluidStatus }: { fluidStatus: FluidStatus }) => { > {t(`auth.${konnectorSlug}.connect`)} </Button> - {fluidStatus.firstDataDate && ( + {currentFluidStatus.firstDataDate && ( <Button classes={{ root: 'btn-secondary', diff --git a/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap b/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap index 1f9dee3a2b4609e028abfe60780d5583f9a32169..d59746e33a69f42117eff9e6430a81fa8788b571 100644 --- a/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap +++ b/src/components/Connection/SGEConnect/__snapshots__/SgeInit.spec.tsx.snap @@ -13,32 +13,7 @@ exports[`SgeInit component should be rendered correctly 1`] = ` } } > - <SgeInit - fluidStatus={ - Object { - "connection": Object { - "account": null, - "isUpdating": false, - "konnector": null, - "konnectorConfig": Object { - "activation": "", - "name": "", - "oauth": false, - "siteLink": "", - "slug": "enedissgegrandlyon", - }, - "shouldLaunchKonnector": false, - "trigger": null, - "triggerState": null, - }, - "firstDataDate": "2019-09-01T00:00:00.000Z", - "fluidType": 0, - "lastDataDate": "2020-09-01T00:00:00.000Z", - "maintenance": false, - "status": 0, - } - } - > + <SgeInit> <div className="connection-form" > @@ -220,132 +195,6 @@ 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 3579c54ab88ad34d8f1db15334f65455e1c9f4da..231973b119e83bc5c5972c545c7242f1beec4092 100644 --- a/src/components/Connection/__snapshots__/Connection.spec.tsx.snap +++ b/src/components/Connection/__snapshots__/Connection.spec.tsx.snap @@ -14,392 +14,12 @@ exports[`Connection component test should call EpglInit 1`] = ` } > <Connection - fluidStatus={ - Object { - "connection": Object { - "account": Object { - "_id": "test", - "account_type": "test", - "auth": Object { - "address": "address", - "city": "Lyon", - "firstname": "Jane", - "lastname": "Doe", - "pointId": "testid", - "postalCode": "69200", - }, - }, - "isUpdating": false, - "konnector": null, - "konnectorConfig": Object { - "activation": "", - "name": "", - "oauth": false, - "siteLink": "", - "slug": "enedissgegrandlyon", - }, - "shouldLaunchKonnector": false, - "trigger": null, - "triggerState": null, - }, - "firstDataDate": "2019-09-01T00:00:00.000Z", - "fluidType": 0, - "lastDataDate": "2020-09-01T00:00:00.000Z", - "maintenance": false, - "status": 200, - } - } + fluidType={1} > <div className="konnector-form" > - <SgeInit - fluidStatus={ - Object { - "connection": Object { - "account": Object { - "_id": "test", - "account_type": "test", - "auth": Object { - "address": "address", - "city": "Lyon", - "firstname": "Jane", - "lastname": "Doe", - "pointId": "testid", - "postalCode": "69200", - }, - }, - "isUpdating": false, - "konnector": null, - "konnectorConfig": Object { - "activation": "", - "name": "", - "oauth": false, - "siteLink": "", - "slug": "enedissgegrandlyon", - }, - "shouldLaunchKonnector": false, - "trigger": null, - "triggerState": null, - }, - "firstDataDate": "2019-09-01T00:00:00.000Z", - "fluidType": 0, - "lastDataDate": "2020-09-01T00:00:00.000Z", - "maintenance": false, - "status": 200, - } - } - > - <div - className="connection-form" - > - <p - className="connection-form-title enedissgegrandlyon text-20-bold" - > - auth.enedissgegrandlyon.title - </p> - <StyledIcon - icon="test-file-stub" - size={180} - > - <Icon - aria-hidden={true} - icon="test-file-stub" - size={180} - spin={false} - > - <Component - aria-hidden={true} - className="styles__icon___23x3R" - height={180} - style={Object {}} - width={180} - > - <svg - aria-hidden={true} - className="styles__icon___23x3R" - height={180} - style={Object {}} - width={180} - > - <use - xlinkHref="#test-file-stub" - /> - </svg> - </Component> - </Icon> - </StyledIcon> - <p - className="connection-form-subtitle enedissgegrandlyon text-16-regular" - dangerouslySetInnerHTML={ - Object { - "__html": "auth.enedissgegrandlyon.bill", - } - } - /> - <div - className="connection-form-button" - > - <WithStyles(ForwardRef(Button)) - aria-label="auth.enedissgegrandlyon.accessibility.connect" - classes={ - Object { - "label": "text-16-bold", - "root": "btn-highlight", - } - } - onClick={[Function]} - > - <ForwardRef(Button) - aria-label="auth.enedissgegrandlyon.accessibility.connect" - 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-highlight", - "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)) - aria-label="auth.enedissgegrandlyon.accessibility.connect" - className="MuiButton-root btn-highlight MuiButton-text" - component="button" - disabled={false} - focusRipple={true} - focusVisibleClassName="Mui-focusVisible" - onClick={[Function]} - type="button" - > - <ForwardRef(ButtonBase) - aria-label="auth.enedissgegrandlyon.accessibility.connect" - className="MuiButton-root btn-highlight 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 - aria-label="auth.enedissgegrandlyon.accessibility.connect" - className="MuiButtonBase-root MuiButton-root btn-highlight 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.enedissgegrandlyon.connect - </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))> - <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> + <mock-EpglInit /> </div> </Connection> </Provider> @@ -419,59 +39,12 @@ exports[`Connection component test should call GrdfInit 1`] = ` } > <Connection - fluidStatus={ - Object { - "connection": Object { - "account": null, - "isUpdating": false, - "konnector": null, - "konnectorConfig": Object { - "activation": "", - "name": "", - "oauth": true, - "siteLink": "", - "slug": "grdfgrandlyon", - }, - "shouldLaunchKonnector": false, - "trigger": null, - "triggerState": null, - }, - "firstDataDate": "2019-09-01T00:00:00.000Z", - "fluidType": 2, - "lastDataDate": "2020-09-01T00:00:00.000Z", - "maintenance": false, - "status": 200, - } - } + fluidType={2} > <div className="konnector-form" > <mock-GrdfInit - fluidStatus={ - Object { - "connection": Object { - "account": null, - "isUpdating": false, - "konnector": null, - "konnectorConfig": Object { - "activation": "", - "name": "", - "oauth": true, - "siteLink": "", - "slug": "grdfgrandlyon", - }, - "shouldLaunchKonnector": false, - "trigger": null, - "triggerState": null, - }, - "firstDataDate": "2019-09-01T00:00:00.000Z", - "fluidType": 2, - "lastDataDate": "2020-09-01T00:00:00.000Z", - "maintenance": false, - "status": 200, - } - } onSuccess={[Function]} /> </div> diff --git a/src/components/Consumption/ConsumptionView.tsx b/src/components/Consumption/ConsumptionView.tsx index a8814841b243bf68e64750d6e93248e144fba0fc..a706350e5e1c67c4c19fb3b835fe8c79f8c11f63 100644 --- a/src/components/Consumption/ConsumptionView.tsx +++ b/src/components/Consumption/ConsumptionView.tsx @@ -262,9 +262,7 @@ const ConsumptionView = ({ fluidType }: { fluidType: FluidType }) => { {!isMulti && ( <div className="konnector-section"> <KonnectorViewerCard - fluidStatus={fluidStatus[fluidType]} fluidType={fluidType} - isParam={true} isDisconnected={false} showOfflineData={true} setActive={setActive} @@ -281,9 +279,7 @@ const ConsumptionView = ({ fluidType }: { fluidType: FluidType }) => { <KonnectorViewerList /> ) : ( <KonnectorViewerCard - fluidStatus={fluidStatus[fluidType]} fluidType={fluidType} - isParam={false} isDisconnected={true} showOfflineData={false} setActive={setActive} @@ -300,7 +296,7 @@ const ConsumptionView = ({ fluidType }: { fluidType: FluidType }) => { .map(issuedFluid => ( <PartnerIssueModal key={issuedFluid.fluidType} - issuedFluid={issuedFluid} + issuedFluid={issuedFluid.fluidType} open={partnersIssueModal[getPartnerKey(issuedFluid.fluidType)]} handleCloseClick={handleClosePartnerIssueModal} /> diff --git a/src/components/Hooks/useKonnectorAuth.tsx b/src/components/Hooks/useKonnectorAuth.tsx index 6f9bb70340706467392eb050078f7af4f9ae4f8f..e0f926074670f37703cfdb1c5d86a012115e7809 100644 --- a/src/components/Hooks/useKonnectorAuth.tsx +++ b/src/components/Hooks/useKonnectorAuth.tsx @@ -1,15 +1,14 @@ import * as Sentry from '@sentry/react' import { useClient } from 'cozy-client' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { FluidSlugType, UsageEventType } from 'enums' +import { FluidSlugType, FluidType, UsageEventType } from 'enums' import { AccountAuthData, AccountSgeData, FluidConnection, - FluidStatus, UsageEvent, } from 'models' -import { useCallback, useState } from 'react' +import { useState } from 'react' import AccountService from 'services/account.service' import ConnectionService from 'services/connection.service' import UsageEventService from 'services/usageEvent.service' @@ -19,31 +18,21 @@ import { useAppDispatch, useAppSelector } from 'store/hooks' import logApp from 'utils/logger' const useKonnectorAuth = ( - fluidStatus: FluidStatus, + fluidType: FluidType, login?: string, password?: string ): [() => Promise<null | undefined>, () => Promise<void>, string] => { const client = useClient() const { t } = useI18n() const dispatch = useAppDispatch() + const { sgeConnect, fluidStatus } = useAppSelector( + state => state.ecolyo.global + ) + const currentFluidStatus = fluidStatus[fluidType] const konnectorSlug: FluidSlugType = - fluidStatus.connection.konnectorConfig.slug - const { sgeConnect } = useAppSelector(state => state.ecolyo.global) + currentFluidStatus.connection.konnectorConfig.slug const [connectError, setError] = useState<string>('') - const onSuccess = useCallback(async () => { - const updatedConnection: FluidConnection = { - ...fluidStatus.connection, - shouldLaunchKonnector: true, - } - dispatch( - updateFluidConnection({ - fluidType: fluidStatus.fluidType, - fluidConnection: updatedConnection, - }) - ) - }, [dispatch, fluidStatus.fluidType, fluidStatus.connection]) - const sendUsageEventError = async (slug: string): Promise<UsageEvent> => { return UsageEventService.addEvent(client, { type: UsageEventType.KONNECTOR_CONNECT_EVENT, @@ -78,18 +67,18 @@ const useKonnectorAuth = ( return null } const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, account: _account, trigger: _trigger, + shouldLaunchKonnector: true, } setLoading(false) dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: currentFluidStatus.fluidType, fluidConnection: updatedConnection, }) ) - onSuccess() } catch (error) { setLoading(false) sendUsageEventError(konnectorSlug) @@ -99,8 +88,8 @@ const useKonnectorAuth = ( } const update = async () => { - if (fluidStatus.connection.account) { - const _account = fluidStatus.connection.account + if (currentFluidStatus.connection.account) { + const _account = currentFluidStatus.connection.account let auth: AccountAuthData | AccountSgeData if (konnectorSlug === FluidSlugType.WATER) { auth = { @@ -121,16 +110,16 @@ const useKonnectorAuth = ( const accountService = new AccountService(client) const updatedAccount = await accountService.updateAccount(_account) const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, account: updatedAccount, + shouldLaunchKonnector: true, } dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: currentFluidStatus.fluidType, fluidConnection: updatedConnection, }) ) - onSuccess() } } return [connect, update, connectError] diff --git a/src/components/Konnector/ConnectionResult/ConnectionResult.tsx b/src/components/Konnector/ConnectionResult/ConnectionResult.tsx index 617d68831428482e6e3ae4c4db9370903650d9e6..efac612a459c617f4fd9364505fda6081b1ade6f 100644 --- a/src/components/Konnector/ConnectionResult/ConnectionResult.tsx +++ b/src/components/Konnector/ConnectionResult/ConnectionResult.tsx @@ -22,26 +22,26 @@ import { updateFluidConnection, updateSgeStore, } from 'store/global/global.slice' -import { useAppDispatch } from 'store/hooks' +import { useAppDispatch, useAppSelector } from 'store/hooks' import { getKonnectorUpdateError } from 'utils/utils' import DeleteGRDFAccountModal from '../../Connection/GRDFDeleteAccountModal/DeleteGRDFAccountModal' import './connectionResult.scss' interface ConnectionResultProps { - fluidStatus: FluidStatus handleAccountDeletion: () => Promise<void> fluidType: FluidType } const ConnectionResult = ({ - fluidStatus, handleAccountDeletion, fluidType, }: ConnectionResultProps) => { const { t } = useI18n() const client = useClient() const dispatch = useAppDispatch() - const account: Account | null = fluidStatus.connection.account + const { fluidStatus } = useAppSelector(state => state.ecolyo.global) + const currentFluidStatus = fluidStatus[fluidType] + const account: Account | null = currentFluidStatus.connection.account const [deleting, setDeleting] = useState<boolean>(false) const [updating, setUpdating] = useState<boolean>(false) @@ -63,13 +63,13 @@ const ConnectionResult = ({ setLastExecutionDate('-') setKonnectorError('') const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, shouldLaunchKonnector: true, isUpdating: true, } dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: currentFluidStatus.fluidType, fluidConnection: updatedConnection, }) ) @@ -100,8 +100,11 @@ const ConnectionResult = ({ const isOutdated = useCallback(() => { const dateChartService = new DateChartService() - return dateChartService.isDataOutdated(fluidStatus.lastDataDate, fluidType) - }, [fluidStatus, fluidType]) + return dateChartService.isDataOutdated( + currentFluidStatus.lastDataDate, + currentFluidStatus.fluidType + ) + }, [currentFluidStatus]) const hasUpdatedToday = useCallback(() => { const todayDate = DateTime.local() @@ -122,7 +125,7 @@ const ConnectionResult = ({ const handleRefreshConsent = useCallback( (fluidType: FluidType) => { if (fluidType == FluidType.ELECTRICITY) { - const accountData = fluidStatus.connection.account + const accountData = currentFluidStatus.connection.account ?.auth as AccountSgeData // store the previous account data since the onDelete will remove account from DB dispatch( @@ -144,31 +147,37 @@ const ConnectionResult = ({ deleteAccountsAndTriggers() } }, - [deleteAccountsAndTriggers, dispatch, fluidStatus.connection.account?.auth] + [ + deleteAccountsAndTriggers, + dispatch, + currentFluidStatus.connection.account?.auth, + ] ) useEffect(() => { - if (fluidStatus.connection.triggerState?.last_success) { + if (currentFluidStatus.connection.triggerState?.last_success) { const result = DateTime.fromISO( - fluidStatus.connection.triggerState.last_success + currentFluidStatus.connection.triggerState.last_success ) setLastExecutionDate(result) } else { setLastExecutionDate('-') } if ( - fluidStatus.connection.triggerState?.status === 'errored' && - fluidStatus.connection.triggerState?.last_error + currentFluidStatus.connection.triggerState?.status === 'errored' && + currentFluidStatus.connection.triggerState?.last_error ) { setStatus('errored') setKonnectorError( - getKonnectorUpdateError(fluidStatus.connection.triggerState.last_error) + getKonnectorUpdateError( + currentFluidStatus.connection.triggerState.last_error + ) ) } if (isOutdated()) { setOutDatedDataDays(isOutdated()) } - }, [fluidStatus.connection.triggerState, isOutdated]) + }, [currentFluidStatus.connection.triggerState, isOutdated]) const getFluidTypeTranslation = (fluidType: FluidType) => { switch (fluidType) { @@ -194,7 +203,7 @@ const ConnectionResult = ({ */ const getConnectionStatus = () => { // First check if there is partner error from backoffice - if (fluidStatus.maintenance) { + if (currentFluidStatus.maintenance) { return ( <div className="connection-caption text-16-normal"> <div className="text-16-normal"> @@ -220,7 +229,7 @@ const ConnectionResult = ({ if (outDatedDataDays) { return ( <DisplayDataOutdated - fluidStatus={fluidStatus} + fluidStatus={currentFluidStatus} fluidType={fluidType} lastExecutionDate={lastExecutionDate} hasUpdatedToday={hasUpdatedToday()} @@ -240,7 +249,9 @@ const ConnectionResult = ({ <div className="connection-update-result"> <div className={ - status === 'errored' && !hasUpdatedToday() && !fluidStatus.maintenance + status === 'errored' && + !hasUpdatedToday() && + !currentFluidStatus.maintenance ? 'connection-update-errored' : '' } diff --git a/src/components/Konnector/KonnectorViewerCard.tsx b/src/components/Konnector/KonnectorViewerCard.tsx index 19b1cb27e4f848b865bfc24d83be3246cfb195e6..a6fcdf8110da707b983bdf6fe424ecade380fcaf 100644 --- a/src/components/Konnector/KonnectorViewerCard.tsx +++ b/src/components/Konnector/KonnectorViewerCard.tsx @@ -56,18 +56,17 @@ import { setChallengeConsumption } from 'store/challenge/challenge.slice' import { setSelectedDate, setShowOfflineData } from 'store/chart/chart.slice' import { setFluidStatus, + setLastEpglLogin, toggleChallengeDuelNotification, updateFluidConnection, } from 'store/global/global.slice' import { useAppDispatch, useAppSelector } from 'store/hooks' import { openConnectionModal } from 'store/modal/modal.slice' -import { getAddPicto, getParamPicto } from 'utils/picto' +import { getParamPicto } from 'utils/picto' import { getKonnectorSlug } from 'utils/utils' import './konnectorViewerCard.scss' interface KonnectorViewerCardProps { - fluidStatus: FluidStatus - isParam: boolean isDisconnected: boolean showOfflineData: boolean active: boolean @@ -76,8 +75,6 @@ interface KonnectorViewerCardProps { } const KonnectorViewerCard = ({ - fluidStatus, - isParam, isDisconnected, showOfflineData, active, @@ -88,28 +85,23 @@ const KonnectorViewerCard = ({ const client = useClient() const dispatch = useAppDispatch() const navigate = useNavigate() - - const fluidSlug = fluidStatus.connection.konnectorConfig.slug - const fluidState = fluidStatus.status - const konnector: Konnector | null = fluidStatus.connection.konnector - const account: Account | null = fluidStatus.connection.account - const trigger: Trigger | null = fluidStatus.connection.trigger const { challenge: { currentChallenge }, - global: { fluidStatus: statusArray, shouldRefreshConsent, partnersInfo }, + global: { fluidStatus, shouldRefreshConsent, partnersInfo }, } = useAppSelector(state => state.ecolyo) + const currentFluidStatus = fluidStatus[fluidType] + const fluidSlug = currentFluidStatus.connection.konnectorConfig.slug + const fluidState = currentFluidStatus.status + const konnector: Konnector | null = currentFluidStatus.connection.konnector + const account: Account | null = currentFluidStatus.connection.account + const trigger: Trigger | null = currentFluidStatus.connection.trigger const [openModal, setOpenModal] = useState(false) const [isUpdating, setIsUpdating] = useState(false) - const [isLogging, setIsLogging] = useState( - fluidSlug !== FluidSlugType.GAS ? true : false - ) + const [isLogging, setIsLogging] = useState(fluidSlug !== FluidSlugType.GAS) const [konnectorErrorDescription, setKonnectorErrorDescription] = useState<KonnectorError | null>(null) const [konnectorState, setKonnectorState] = useState<string | null>(null) - const [updatedFluidStatus, setUpdatedFluidStatus] = useState<FluidStatus[]>( - [] - ) const [isOutdatedData, setIsOutdatedData] = useState<number | null>(null) const fluidService = useMemo(() => new FluidService(client), [client]) const partnersInfoService = useMemo( @@ -118,14 +110,11 @@ const KonnectorViewerCard = ({ ) const lastDataDate = - fluidType !== FluidType.MULTIFLUID && statusArray[fluidType].lastDataDate - ? statusArray[fluidType].lastDataDate!.toLocaleString() + fluidType + fluidType !== FluidType.MULTIFLUID && currentFluidStatus.lastDataDate + ? currentFluidStatus.lastDataDate.toLocaleString() + fluidType : fluidType - const iconType = getParamPicto(fluidStatus.fluidType) - const iconAddType = isParam - ? getParamPicto(fluidStatus.fluidType) - : getAddPicto(fluidStatus.fluidType) + const iconType = getParamPicto(currentFluidStatus.fluidType) const toggleAccordion = () => { setActive(prev => !prev) @@ -136,7 +125,6 @@ const KonnectorViewerCard = ({ > => { const _updatedFluidStatus: FluidStatus[] = await fluidService.getFluidStatus() - setUpdatedFluidStatus(_updatedFluidStatus) const refDate = DateTime.fromISO('0001-01-01') let _lastDataDate: DateTime | null = DateTime.fromISO('0001-01-01') for (const fluid of _updatedFluidStatus) { @@ -201,7 +189,8 @@ const KonnectorViewerCard = ({ konnectorErrorDescription === KonnectorError.LOGIN_FAILED || konnectorErrorDescription === KonnectorError.UNKNOWN_ERROR || konnectorErrorDescription === KonnectorError.CHALLENGE_ASKED || - konnectorErrorDescription === KonnectorError.CRITICAL + konnectorErrorDescription === KonnectorError.CRITICAL || + konnectorErrorDescription === KonnectorError.MISSING_SECRET // CASE FOR ENEDIS CODE INSEE ERROR const isEnedisCodeInseeError = @@ -210,39 +199,47 @@ const KonnectorViewerCard = ({ const shouldDeleteAccount = account && !isSuccess && - fluidStatus && - fluidStatus.connection.account && + currentFluidStatus && + currentFluidStatus.connection.account && (isGlobalLoginFailed || isEnedisCodeInseeError) if (shouldDeleteAccount) { - // KEEP CREDENTIALS FOR EGL + // KEEP LAST LOGIN FOR EPGL + let lastEpglLogin = '' if ( fluidSlug === FluidSlugType.WATER && - fluidStatus.connection.account?.auth + currentFluidStatus.connection.account?.auth ) { - const auth = fluidStatus.connection.account.auth as AccountAuthData - fluidStatus.connection.konnectorConfig.lastKnownCredentials = - auth.login + const auth = currentFluidStatus.connection.account + .auth as AccountAuthData + lastEpglLogin = auth.login } // DELETE ACCOUNT const accountService = new AccountService(client) await accountService.deleteAccount(account) await handleAccountDeletion() + + // RESTORE LAST KNOWN CREDENTIALS + if (lastEpglLogin) { + dispatch( + setLastEpglLogin({ + lastEpglLogin: lastEpglLogin, + }) + ) + } } else { - if (isSuccess && fluidStatus.lastDataDate === null) { + if (isSuccess && currentFluidStatus.lastDataDate === null) { // UPDATE THE DACC EVENT STATUS TO SUCCESS - await UsageEventService.udpateConnectionAttemptEvent( + await UsageEventService.updateConnectionAttemptEvent( client, fluidSlug ) } - if (updatedFluidStatus.length > 0) { - // const partnersInfo = await partnersInfoService.getPartnersInfo() - const updatedFluidStatus = await fluidService.getFluidStatus( - partnersInfo - ) - dispatch(setFluidStatus(updatedFluidStatus)) - } + // const partnersInfo = await partnersInfoService.getPartnersInfo() + const updatedFluidStatus = await fluidService.getFluidStatus( + partnersInfo + ) + dispatch(setFluidStatus(updatedFluidStatus)) } setActive(false) @@ -254,14 +251,13 @@ const KonnectorViewerCard = ({ [ account, konnectorErrorDescription, - fluidStatus, + currentFluidStatus, isUpdating, fluidType, setActive, fluidSlug, client, handleAccountDeletion, - updatedFluidStatus.length, fluidService, partnersInfo, dispatch, @@ -300,7 +296,7 @@ const KonnectorViewerCard = ({ [client] ) - const toggleModalConnection = () => { + const toggleModalConnection = useCallback(() => { switch (fluidType) { case FluidType.ELECTRICITY: navigate('/sge-connect') @@ -311,7 +307,7 @@ const KonnectorViewerCard = ({ dispatch(openConnectionModal(true)) break } - } + }, [dispatch, fluidType, navigate]) const getConnectionCard = useCallback(() => { if (showOfflineData && !account) { @@ -334,40 +330,43 @@ const KonnectorViewerCard = ({ else if ( (fluidState === FluidState.ERROR_LOGIN_FAILED && fluidType === FluidType.WATER) || - (account && fluidStatus.status !== FluidState.NOT_CONNECTED) + (account && currentFluidStatus.status !== FluidState.NOT_CONNECTED) ) { return ( <ConnectionResult - fluidStatus={fluidStatus} handleAccountDeletion={handleAccountDeletion} fluidType={fluidType} key={lastDataDate} /> ) } else { - return <Connection fluidStatus={fluidStatus} /> + return <Connection fluidType={currentFluidStatus.fluidType} /> } }, [ - fluidState, - isUpdating, account, - fluidStatus, + currentFluidStatus.fluidType, + currentFluidStatus.status, fluidSlug, - handleAccountDeletion, + fluidState, fluidType, + handleAccountDeletion, + isUpdating, lastDataDate, + showOfflineData, + t, + toggleModalConnection, ]) const callbackResponse = useCallback( async (_state: string) => { if (_state !== LOGIN_SUCCESS_EVENT) { const updatedConnection: FluidConnection = { - ...fluidStatus.connection, + ...currentFluidStatus.connection, shouldLaunchKonnector: false, } dispatch( updateFluidConnection({ - fluidType: fluidStatus.fluidType, + fluidType: currentFluidStatus.fluidType, fluidConnection: updatedConnection, }) ) @@ -380,8 +379,8 @@ const KonnectorViewerCard = ({ }, [ dispatch, - fluidStatus.connection, - fluidStatus.fluidType, + currentFluidStatus.connection, + currentFluidStatus.fluidType, refreshChallengeState, updateGlobalFluidStatus, ] @@ -390,20 +389,20 @@ const KonnectorViewerCard = ({ return ( <div className="konnector-icon"> <Icon - icon={fluidStatus.connection.account ? iconType : OfflinePicto} + icon={currentFluidStatus.connection.account ? iconType : OfflinePicto} size={49} /> - {fluidStatus.maintenance ? ( + {currentFluidStatus.maintenance ? ( <StyledIcon icon={PartnersIssueNotif} size={24} className="konnector-state-picto" /> ) : ( - (fluidStatus.status === FluidState.ERROR || + (currentFluidStatus.status === FluidState.ERROR || isOutdatedData || - fluidStatus.status === FluidState.ERROR_LOGIN_FAILED) && - fluidStatus.connection.account && ( + currentFluidStatus.status === FluidState.ERROR_LOGIN_FAILED) && + currentFluidStatus.connection.account && ( <StyledIcon icon={ErrorNotif} size={24} @@ -414,22 +413,21 @@ const KonnectorViewerCard = ({ </div> ) }, [ - fluidStatus.connection.account, - fluidStatus.maintenance, - fluidStatus.status, - iconAddType, + currentFluidStatus.connection.account, + currentFluidStatus.maintenance, + currentFluidStatus.status, iconType, isOutdatedData, ]) const displayKonnectorHeader = useCallback(() => { - if (fluidStatus.maintenance) { + if (currentFluidStatus.maintenance) { return ( <span className="text-16-bold"> {t(`konnector_options.partner_issue`)} </span> ) - } else if (isOutdatedData && fluidStatus.connection.account) { + } else if (isOutdatedData && currentFluidStatus.connection.account) { return ( <span className="text-16-bold outdated"> {t('konnector_options.outdated', { @@ -437,19 +435,19 @@ const KonnectorViewerCard = ({ })} </span> ) - } else if (fluidStatus.connection.account && !isOutdatedData) { - return t(`FLUID.${FluidType[fluidStatus.fluidType]}.LABEL`) + } else if (currentFluidStatus.connection.account && !isOutdatedData) { + return t(`FLUID.${FluidType[currentFluidStatus.fluidType]}.LABEL`) } else { return t( `konnector_options.label_offline_${FluidType[ - fluidStatus.fluidType + currentFluidStatus.fluidType ].toLowerCase()}` ) } }, [ - fluidStatus.connection.account, - fluidStatus.fluidType, - fluidStatus.maintenance, + currentFluidStatus.connection.account, + currentFluidStatus.fluidType, + currentFluidStatus.maintenance, isOutdatedData, t, ]) @@ -470,28 +468,45 @@ const KonnectorViewerCard = ({ let subscribed = true async function getData() { if ( - fluidStatus.connection.shouldLaunchKonnector && + currentFluidStatus.connection.shouldLaunchKonnector && !isKonnectorRunning(trigger) ) { if (subscribed) { - if (fluidStatus.connection.isUpdating) setIsUpdating(true) + if (currentFluidStatus.connection.isUpdating) setIsUpdating(true) setOpenModal(true) - fluidStatus.connection.shouldLaunchKonnector = false + const updatedConnection: FluidConnection = { + ...currentFluidStatus.connection, + shouldLaunchKonnector: false, + } + dispatch( + updateFluidConnection({ + fluidType: currentFluidStatus.fluidType, + fluidConnection: updatedConnection, + }) + ) } - const connectionFlow = new ConnectionFlow(client, trigger, konnector) await connectionFlow.launch() connectionFlow.jobWatcher.on(ERROR_EVENT, () => { - sendUsageEventError(fluidSlug, fluidStatus.lastDataDate === null) + sendUsageEventError( + fluidSlug, + currentFluidStatus.lastDataDate === null + ) setKonnectorErrorDescription(connectionFlow.jobWatcher.on()._error) callbackResponse(ERROR_EVENT) }) connectionFlow.jobWatcher.on(LOGIN_SUCCESS_EVENT, () => { setIsLogging(false) - sendUsageEventSuccess(fluidSlug, fluidStatus.lastDataDate === null) + sendUsageEventSuccess( + fluidSlug, + currentFluidStatus.lastDataDate === null + ) }) connectionFlow.jobWatcher.on(SUCCESS_EVENT, () => { - sendUsageEventSuccess(fluidSlug, fluidStatus.lastDataDate === null) + sendUsageEventSuccess( + fluidSlug, + currentFluidStatus.lastDataDate === null + ) callbackResponse(SUCCESS_EVENT) }) } @@ -499,27 +514,28 @@ const KonnectorViewerCard = ({ !shouldRefreshConsent && getData() const dateChartService = new DateChartService() setIsOutdatedData( - dateChartService.isDataOutdated(fluidStatus.lastDataDate, fluidType) + dateChartService.isDataOutdated( + currentFluidStatus.lastDataDate, + fluidType + ) ) return () => { subscribed = false } }, [ - client, - konnector, - trigger, - fluidStatus.connection, - fluidStatus.connection.shouldLaunchKonnector, - fluidStatus.connection.isUpdating, - fluidStatus.fluidType, callbackResponse, - setActive, - fluidStatus.lastDataDate, + client, + currentFluidStatus.connection, + currentFluidStatus.fluidType, + currentFluidStatus.lastDataDate, + dispatch, + fluidSlug, fluidType, + konnector, sendUsageEventError, - fluidSlug, sendUsageEventSuccess, shouldRefreshConsent, + trigger, ]) return ( @@ -530,9 +546,9 @@ const KonnectorViewerCard = ({ onChange={toggleAccordion} classes={{ root: `expansion-panel-root ${ - !fluidStatus.maintenance && - (fluidStatus.status === FluidState.ERROR || - fluidStatus.status === FluidState.ERROR_LOGIN_FAILED) + !currentFluidStatus.maintenance && + (currentFluidStatus.status === FluidState.ERROR || + currentFluidStatus.status === FluidState.ERROR_LOGIN_FAILED) ? 'red-border' : '' }`, @@ -541,7 +557,7 @@ const KonnectorViewerCard = ({ <AccordionSummary aria-label={t( `konnector_options.accessibility.button_toggle_detail_${FluidType[ - fluidStatus.fluidType + currentFluidStatus.fluidType ].toLowerCase()}` )} expandIcon={ @@ -555,9 +571,11 @@ const KonnectorViewerCard = ({ {displayKonnectorIcon()} <div className={classNames('text-16-bold konnector-title', { - [`${FluidType[fluidStatus.fluidType].toLowerCase()}-connected`]: - fluidStatus.status !== FluidState.NOT_CONNECTED && - !fluidStatus.maintenance, + [`${FluidType[ + currentFluidStatus.fluidType + ].toLowerCase()}-connected`]: + currentFluidStatus.status !== FluidState.NOT_CONNECTED && + !currentFluidStatus.maintenance, })} > {displayKonnectorHeader()} @@ -582,7 +600,7 @@ const KonnectorViewerCard = ({ isLogging={isLogging} state={konnectorState} error={konnectorErrorDescription} - fluidType={fluidStatus.fluidType} + fluidType={currentFluidStatus.fluidType} handleCloseClick={handleConnectionEnd} handleAccountDeletion={handleAccountDeletion} account={account} diff --git a/src/components/PartnerIssue/PartnerIssueModal.spec.tsx b/src/components/PartnerIssue/PartnerIssueModal.spec.tsx index 4aaf2652da6311e72375e239a01f4a283aa3156b..c3ac2e4d67277124e28e68950db4d32b468138bc 100644 --- a/src/components/PartnerIssue/PartnerIssueModal.spec.tsx +++ b/src/components/PartnerIssue/PartnerIssueModal.spec.tsx @@ -1,8 +1,8 @@ import { Button } from '@material-ui/core' +import { FluidType } from 'enums' import { mount } from 'enzyme' import toJson from 'enzyme-to-json' import React from 'react' -import { mockInitialEcolyoState } from 'tests/__mocks__/store' import PartnerIssueModal from './PartnerIssueModal' const mockHandleClose = jest.fn() @@ -12,7 +12,7 @@ describe('PartnerIssueModal component', () => { <PartnerIssueModal open={true} handleCloseClick={mockHandleClose} - issuedFluid={mockInitialEcolyoState.global.fluidStatus[0]} + issuedFluid={FluidType.ELECTRICITY} /> ) expect(toJson(wrapper)).toMatchSnapshot() @@ -22,7 +22,7 @@ describe('PartnerIssueModal component', () => { <PartnerIssueModal open={true} handleCloseClick={mockHandleClose} - issuedFluid={mockInitialEcolyoState.global.fluidStatus[0]} + issuedFluid={FluidType.ELECTRICITY} /> ) expect(wrapper.text().includes('error_connect_elec')).toBeTruthy() @@ -32,7 +32,7 @@ describe('PartnerIssueModal component', () => { <PartnerIssueModal open={true} handleCloseClick={mockHandleClose} - issuedFluid={mockInitialEcolyoState.global.fluidStatus[1]} + issuedFluid={FluidType.WATER} /> ) expect(wrapper.text().includes('error_connect_water')).toBeTruthy() @@ -42,7 +42,7 @@ describe('PartnerIssueModal component', () => { <PartnerIssueModal open={true} handleCloseClick={mockHandleClose} - issuedFluid={mockInitialEcolyoState.global.fluidStatus[0]} + issuedFluid={FluidType.ELECTRICITY} /> ) wrapper.find(Button).simulate('click') @@ -54,7 +54,7 @@ describe('PartnerIssueModal component', () => { <PartnerIssueModal open={false} handleCloseClick={mockHandleClose} - issuedFluid={mockInitialEcolyoState.global.fluidStatus[0]} + issuedFluid={FluidType.ELECTRICITY} /> ) expect(wrapper.find('div.partnerIssueModal').exists()).toBeFalsy() diff --git a/src/components/PartnerIssue/PartnerIssueModal.tsx b/src/components/PartnerIssue/PartnerIssueModal.tsx index 85c28abf05c12bdbf7f46f14300287f6db451ac8..2faa8e0f8a4e631451334f88269ccc3499178257 100644 --- a/src/components/PartnerIssue/PartnerIssueModal.tsx +++ b/src/components/PartnerIssue/PartnerIssueModal.tsx @@ -7,13 +7,12 @@ import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import Icon from 'cozy-ui/transpiled/react/Icon' import { FluidType } from 'enums' -import { FluidStatus } from 'models' import React from 'react' import './partnerIssueModal.scss' interface PartnerIssueModalProps { open: boolean - issuedFluid: FluidStatus + issuedFluid: FluidType handleCloseClick: (fluidType: FluidType) => void } @@ -25,7 +24,7 @@ const PartnerIssueModal = ({ const { t } = useI18n() const getFluidTypeLabel = () => { - switch (issuedFluid.fluidType) { + switch (issuedFluid) { case FluidType.ELECTRICITY: return 'elec' case FluidType.WATER: @@ -40,9 +39,7 @@ const PartnerIssueModal = ({ open={open} disableEscapeKeyDown onClose={(event, reason): void => { - event && - reason !== 'backdropClick' && - handleCloseClick(issuedFluid.fluidType) + event && reason !== 'backdropClick' && handleCloseClick(issuedFluid) }} aria-labelledby={'accessibility-title'} classes={{ @@ -57,7 +54,7 @@ const PartnerIssueModal = ({ <IconButton aria-label={t('feedback.accessibility.button_close')} className="modal-paper-close-button" - onClick={() => handleCloseClick(issuedFluid.fluidType)} + onClick={() => handleCloseClick(issuedFluid)} > <Icon icon={CloseIcon} size={16} /> </IconButton> @@ -82,7 +79,7 @@ const PartnerIssueModal = ({ }} /> <Button - onClick={() => handleCloseClick(issuedFluid.fluidType)} + onClick={() => handleCloseClick(issuedFluid)} classes={{ root: 'btn-highlight', label: 'text-16-bold', diff --git a/src/components/PartnerIssue/__snapshots__/PartnerIssueModal.spec.tsx.snap b/src/components/PartnerIssue/__snapshots__/PartnerIssueModal.spec.tsx.snap index ebba481d47d69a83785ed650c928e0d27426ef9e..afd0cdd3465ce6bc9272539e4f51558166690e5e 100644 --- a/src/components/PartnerIssue/__snapshots__/PartnerIssueModal.spec.tsx.snap +++ b/src/components/PartnerIssue/__snapshots__/PartnerIssueModal.spec.tsx.snap @@ -3,30 +3,7 @@ exports[`PartnerIssueModal component should render correctly 1`] = ` <PartnerIssueModal handleCloseClick={[MockFunction]} - issuedFluid={ - Object { - "connection": Object { - "account": null, - "isUpdating": false, - "konnector": null, - "konnectorConfig": Object { - "activation": "", - "name": "", - "oauth": false, - "siteLink": "", - "slug": "enedissgegrandlyon", - }, - "shouldLaunchKonnector": false, - "trigger": null, - "triggerState": null, - }, - "firstDataDate": null, - "fluidType": 0, - "lastDataDate": null, - "maintenance": false, - "status": 0, - } - } + issuedFluid={0} open={true} > <WithStyles(ForwardRef(Dialog)) diff --git a/src/enums/konnectorStatus.enum.ts b/src/enums/konnectorStatus.enum.ts index ae8cba6476c772d041e34febae807cee00ebfc02..4e8543316bd8de24d6cf05a1843e1e2a88371467 100644 --- a/src/enums/konnectorStatus.enum.ts +++ b/src/enums/konnectorStatus.enum.ts @@ -5,6 +5,7 @@ export enum KonnectorError { CHALLENGE_ASKED = 'CHALLENGE_ASKED', UNKNOWN_ERROR = 'UNKNOWN_ERROR', CRITICAL = 'exit status 1', + MISSING_SECRET = "Cannot read property 'secret' of null", } export enum KonnectorUpdate { diff --git a/src/models/config.model.ts b/src/models/config.model.ts index e81248d9ae8a3d52e938a8ce06277f214f9aadc3..66171535b8b17f68ef290c36022b065d7d4c39ca 100644 --- a/src/models/config.model.ts +++ b/src/models/config.model.ts @@ -5,7 +5,6 @@ export interface KonnectorConfig { oauth: boolean slug: FluidSlugType cron?: string - lastKnownCredentials?: string siteLink: string activation: string } diff --git a/src/models/global.model.ts b/src/models/global.model.ts index c9ca17dfda660933c7ebff88a14fbe4d6a513cc5..8885c78cd72d5debe8c04da2c799feef04e131c2 100644 --- a/src/models/global.model.ts +++ b/src/models/global.model.ts @@ -19,4 +19,5 @@ export interface GlobalState { sgeConnect: SgeStore partnersInfo: PartnersInfo ecogestureFilter: Usage + lastEpglLogin: string } diff --git a/src/services/usageEvent.service.spec.ts b/src/services/usageEvent.service.spec.ts index 3994abba1328121a249063816982b316aaf5d2d5..eed34dce581ff7903a847774abf0fcd424d2cd71 100644 --- a/src/services/usageEvent.service.spec.ts +++ b/src/services/usageEvent.service.spec.ts @@ -127,7 +127,7 @@ describe('UsageEvent service', () => { expect(result).toEqual(usageEventData) }) }) - describe('udpateConnectionAttemptEvent method', () => { + describe('updateConnectionAttemptEvent method', () => { it('should update the last attempt to true', async () => { const mockQueryResult: QueryResult<UsageEventEntity[]> = { data: [connectionAttemptEGLError], @@ -143,7 +143,7 @@ describe('UsageEvent service', () => { } mockClient.query.mockResolvedValueOnce(mockQueryResult) mockClient.save.mockResolvedValueOnce(mockQueryResult2) - const result = await UsageEventService.udpateConnectionAttemptEvent( + const result = await UsageEventService.updateConnectionAttemptEvent( mockClient, 'eglgrandlyon' ) @@ -157,7 +157,7 @@ describe('UsageEvent service', () => { skip: 0, } mockClient.query.mockResolvedValueOnce(mockQueryResult) - const result = await UsageEventService.udpateConnectionAttemptEvent( + const result = await UsageEventService.updateConnectionAttemptEvent( mockClient, 'eglgrandlyon' ) @@ -171,7 +171,7 @@ describe('UsageEvent service', () => { skip: 0, } mockClient.query.mockResolvedValueOnce(mockQueryResult) - const result = await UsageEventService.udpateConnectionAttemptEvent( + const result = await UsageEventService.updateConnectionAttemptEvent( mockClient, 'eglgrandlyon' ) diff --git a/src/services/usageEvent.service.ts b/src/services/usageEvent.service.ts index 32f5c96ca1910c493df6771bd5c8cdceb36e3f58..d974895456a14838be60268e59b425d8ac58aa5f 100644 --- a/src/services/usageEvent.service.ts +++ b/src/services/usageEvent.service.ts @@ -72,7 +72,7 @@ export default class UsageEventService { * @param {string} konnectorSlug * @returns */ - static async udpateConnectionAttemptEvent( + static async updateConnectionAttemptEvent( client: Client, konnectorSlug: string ): Promise<UsageEventEntity | undefined> { @@ -101,7 +101,7 @@ export default class UsageEventService { return savedEvent } } catch (error) { - const errorMessage = `UsageEvent service error on udpateConnectionAttemptEvent: ${JSON.stringify( + const errorMessage = `UsageEvent service error on updateConnectionAttemptEvent: ${JSON.stringify( error )}` logStack('error', errorMessage) diff --git a/src/store/global/global.slice.spec.ts b/src/store/global/global.slice.spec.ts index 43f74e7bfe0c34d3bb534b966d7d62bd49132d7e..da398b617868cc5bd172a0604105498a3be6eaee 100644 --- a/src/store/global/global.slice.spec.ts +++ b/src/store/global/global.slice.spec.ts @@ -11,6 +11,7 @@ import { changeScreenType, globalSlice, setFluidStatus, + setLastEpglLogin, setPartnersInfo, setShouldRefreshConsent, showReleaseNotes, @@ -297,6 +298,19 @@ describe('globalSlice', () => { }) }) + it('should handle setLastEpglLogin', () => { + const state = globalSlice.reducer( + mockGlobalState, + setLastEpglLogin({ + lastEpglLogin: 'username', + }) + ) + expect(state).toEqual({ + ...mockGlobalState, + lastEpglLogin: 'username', + }) + }) + it('should change the ecogestureFilter', () => { const state = globalSlice.reducer( mockGlobalState, diff --git a/src/store/global/global.slice.ts b/src/store/global/global.slice.ts index 65c387677ad65c806592af6a85480b848e82984a..4a9ed0a1609ec3e4bbce6a6999336fb3e0744225 100644 --- a/src/store/global/global.slice.ts +++ b/src/store/global/global.slice.ts @@ -118,6 +118,7 @@ const initialState: GlobalState = { shouldLaunchAccount: false, }, ecogestureFilter: Usage.ALL, + lastEpglLogin: '', } type ChangeScreenType = PayloadAction<ScreenType> @@ -131,6 +132,9 @@ type UpdatedFluidConnection = PayloadAction<{ fluidType: FluidType fluidConnection: FluidConnection }> +type SetLastEpglLogin = PayloadAction<{ + lastEpglLogin: string +}> type UpdateTermValidation = PayloadAction<TermsStatus> type ShowReleaseNote = PayloadAction<{ show: boolean @@ -144,6 +148,7 @@ type UpdateEcogestureFilter = PayloadAction<Usage> export type GlobalActionTypes = | ChangeScreenType | SetFluidStatus + | SetLastEpglLogin | SetPartnersInfo | SetSgeConnect | SetShouldRefreshConsent @@ -218,14 +223,17 @@ export const globalSlice = createSlice({ setShouldRefreshConsent: (state, action: SetShouldRefreshConsent) => { state.shouldRefreshConsent = action.payload }, - updateFluidConnection: (state, action: UpdatedFluidConnection) => { - const updatedFluidStatus = [...state.fluidStatus] - const fluidType: FluidType = action.payload.fluidType - const findIndex = state.fluidStatus.findIndex( - fluid => fluid.fluidType === fluidType - ) - updatedFluidStatus[findIndex].connection = action.payload.fluidConnection - state.fluidStatus = updatedFluidStatus + updateFluidConnection: ( + state, + { payload: { fluidType, fluidConnection } }: UpdatedFluidConnection + ) => { + state.fluidStatus[fluidType].connection = fluidConnection + }, + setLastEpglLogin: ( + state, + { payload: { lastEpglLogin } }: SetLastEpglLogin + ) => { + state.lastEpglLogin = lastEpglLogin }, updateSgeStore: (state, action: SetSgeConnect) => { state.sgeConnect = action.payload @@ -239,6 +247,7 @@ export const globalSlice = createSlice({ export const { changeScreenType, setFluidStatus, + setLastEpglLogin, setPartnersInfo, setShouldRefreshConsent, showReleaseNotes, diff --git a/tests/__mocks__/store/global.state.mock.ts b/tests/__mocks__/store/global.state.mock.ts index 373b81070b4c12ab3a3c22187a2634dcd457575e..ddc0d309f58fab3acdb351c8541b654f6df8e8a6 100644 --- a/tests/__mocks__/store/global.state.mock.ts +++ b/tests/__mocks__/store/global.state.mock.ts @@ -8,6 +8,7 @@ export const mockGlobalState: GlobalState = { challengeActionNotification: false, challengeDuelNotification: false, analysisNotification: false, + lastEpglLogin: '', termsStatus: { accepted: true, versionType: 'init',