diff --git a/package.json b/package.json index ec517f209e86044b198fa6461b13dd67236dff28..056038aaf6d4d517368d4e86db97e7ec0cda8ff5 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "luxon": "^1.21.3", "moment": "^2.24.0", "moment-timezone": "^0.5.27", - "node-sass": "^4.13.0", + "node-sass": "^4.14.0", "object-hash": "^2.0.3", "react": "16.12.0", "react-dom": "16.12.0", diff --git a/src/components/CommonKit/Modal/Modal.tsx b/src/components/CommonKit/Modal/Modal.tsx index 2b184f6e2a86dfd0f1e2858b428337852f54c1dc..88e366ea0611331b159fd7784403f33120cb539b 100644 --- a/src/components/CommonKit/Modal/Modal.tsx +++ b/src/components/CommonKit/Modal/Modal.tsx @@ -1,10 +1,10 @@ import React, { useEffect, ReactNode } from 'react' -import { createPortal } from 'react-dom' import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' import CloseIcon from 'assets/icons/ico/close.svg' import './Modal.scss' interface ModalProps { border?: boolean + hideClosure?: boolean handleCloseClick: () => void children: ReactNode yellowBorder?: boolean @@ -12,11 +12,13 @@ interface ModalProps { const Modal: React.FC<ModalProps> = ({ border, + hideClosure, handleCloseClick, children, yellowBorder, }: ModalProps) => { const yellow = yellowBorder ? 'yellow-border' : '' + const displayCloseButton = hideClosure ? false : true const disableBackgroundScroll = (disable: boolean) => { const backgroundDesktop = document.querySelector( @@ -43,6 +45,9 @@ const Modal: React.FC<ModalProps> = ({ useEffect(() => { disableBackgroundScroll(true) + return () => { + disableBackgroundScroll(false) + } }, []) return ( @@ -50,11 +55,13 @@ const Modal: React.FC<ModalProps> = ({ <div className={`modal-box ${border ? 'modal-box-bordered' : ''} ${yellow}`} > - <StyledIconButton - className="modal-close-button" - icon={CloseIcon} - onClick={closeClick} - /> + {displayCloseButton && ( + <StyledIconButton + className="modal-close-button" + icon={CloseIcon} + onClick={closeClick} + /> + )} <div className="modal-content">{children}</div> </div> </div> diff --git a/src/components/Connection/ConnectionFormLogin.tsx b/src/components/Connection/ConnectionFormLogin.tsx index da91882794f17f374ebe3ac5592ab5725275239c..407d75969f18a43022cd41c509ea95c595e91aac 100644 --- a/src/components/Connection/ConnectionFormLogin.tsx +++ b/src/components/Connection/ConnectionFormLogin.tsx @@ -90,7 +90,6 @@ const ConnectionFormLogin: React.FC<ConnectionFormLoginProps> = ({ ...fluidStatus.connection, account: _account, trigger: _trigger, - shouldLaunchKonnector: true, } setLoading(false) dispatch(updatedFluidConnection(fluidStatus.fluidType, updatedConnection)) diff --git a/src/components/Connection/ConnectionLaunch.tsx b/src/components/Connection/ConnectionLaunch.tsx deleted file mode 100644 index 9a10f65397e6eb712c69afdb820f7b4701370433..0000000000000000000000000000000000000000 --- a/src/components/Connection/ConnectionLaunch.tsx +++ /dev/null @@ -1,131 +0,0 @@ -// FIX Component not used, to keep ?? -import React, { useEffect, useState } from 'react' -import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { useClient } from 'cozy-client' - -import { Konnector, Trigger } from 'models' -import { isKonnectorRunning } from 'cozy-harvest-lib/dist/helpers/triggers' -import ConnectionFlow, { - ERROR_EVENT, - LOGIN_SUCCESS_EVENT, - SUCCESS_EVENT, -} from 'cozy-harvest-lib/dist/models/ConnectionFlow' - -import Lottie from 'react-lottie' -import * as loadingData from 'assets/anims/bounceloading.json' -import StyledButton from 'components/CommonKit/Button/StyledButton' -import Modal from 'components/CommonKit/Modal/Modal' -import StyledIcon from 'components/CommonKit/Icon/StyledIcon' -import errorIcon from 'assets/icons/visu/data-nok.svg' -import successIcon from 'assets/icons/visu/data-ok.svg' -import './connectionLaunch.scss' - -const loadingOptions = { - loop: true, - autoplay: true, - animationData: loadingData, - rendererSettings: { - preserveAspectRatio: 'xMidYMid slice', - }, -} - -interface ConnectionLaunchProps { - trigger: Trigger - konnector: Konnector - type: string - handleConnectionLaunch: Function -} - -const ConnectionLaunch: React.FC<ConnectionLaunchProps> = ({ - trigger, - konnector, - type, - handleConnectionLaunch, -}: ConnectionLaunchProps) => { - const { t } = useI18n() - const client = useClient() - const [state, setState] = useState<string | null>(null) - const [openModal, setOpenModal] = useState(false) - const callbackResponse = (_state: string) => { - setState(_state) - } - - const handleCloseClick = () => { - handleConnectionLaunch() - setOpenModal(false) - } - - useEffect(() => { - let subscribed = true - async function getData() { - if (subscribed && !isKonnectorRunning(trigger)) { - const connectionFlow = new ConnectionFlow(client, trigger, konnector) - await connectionFlow.launch() - connectionFlow.jobWatcher.on(ERROR_EVENT, () => { - callbackResponse(ERROR_EVENT) - }) - connectionFlow.jobWatcher.on(LOGIN_SUCCESS_EVENT, () => { - callbackResponse(LOGIN_SUCCESS_EVENT) - }) - connectionFlow.jobWatcher.on(SUCCESS_EVENT, () => { - callbackResponse(SUCCESS_EVENT) - }) - setOpenModal(true) - } - } - getData() - return () => { - subscribed = false - } - }, [client, konnector, trigger]) - - return openModal ? ( - <Modal handleCloseClick={handleCloseClick} border={false}> - <div className="klaunch-content"> - {!state ? ( - <> - <Lottie options={loadingOptions} height={50} width={50} speed={2} /> - <div className="klaunch-content-text klaunch-content-text-center text-16-normal"> - <div className="kc-wait">{t('KONNECTORCONFIG.PLZ_WAIT')}</div> - </div> - <div className="klaunch-content-text text-16-normal"> - <div>{t('KONNECTORCONFIG.LOADING_DATA')}</div> - </div> - </> - ) : ( - <> - <div className="klaunch-info"> - {state === ERROR_EVENT ? ( - <div className="konnector-config"> - <StyledIcon icon={errorIcon} size={48} /> - <div className="kce-picto-txt text-20-bold"> - {t('KONNECTORCONFIG.ERROR_TXT')} - </div> - <div>{t('KONNECTORCONFIG.ERROR_DATA_' + type)}</div> - <div>{t('KONNECTORCONFIG.ERROR_DATA_2')}</div> - </div> - ) : ( - <div className="konnector-config"> - <StyledIcon icon={successIcon} size={48} /> - <div className="kcs-picto-txt text-20-bold"> - {t('KONNECTORCONFIG.SUCCESS_TXT')} - </div> - {t('KONNECTORCONFIG.SUCCESS_DATA_' + type)} - </div> - )} - <StyledButton - type="button" - color="primary" - onClick={handleCloseClick} - > - <div>{t('KONNECTORCONFIG.OK')}</div> - </StyledButton> - </div> - </> - )} - </div> - </Modal> - ) : null -} - -export default ConnectionLaunch diff --git a/src/components/Connection/ConnectionResult.tsx b/src/components/Connection/ConnectionResult.tsx index f685517b6e2c2b907a7d7306b81359636ce9020c..5a74be53615d8150080f3d0b8028bc575eadf592 100644 --- a/src/components/Connection/ConnectionResult.tsx +++ b/src/components/Connection/ConnectionResult.tsx @@ -42,6 +42,7 @@ const ConnectionResult: React.FC<ConnectionResultProps> = ({ const updatedConnection: FluidConnection = { ...fluidStatus.connection, shouldLaunchKonnector: true, + isUpdating: true, } dispatch(updatedFluidConnection(fluidStatus.fluidType, updatedConnection)) setUpdating(false) diff --git a/src/components/Connection/connectionLaunch.scss b/src/components/Connection/connectionLaunch.scss deleted file mode 100644 index 52183f931c5e590549fc02c895121e26608f736e..0000000000000000000000000000000000000000 --- a/src/components/Connection/connectionLaunch.scss +++ /dev/null @@ -1,40 +0,0 @@ -@import 'src/styles/base/color'; -@import 'src/styles/base/breakpoint'; - -// KonnectorLoading -.klaunch-content { - margin: 0.5rem 1.5rem; - @media #{$large-phone} { - margin: 0.5rem 0; - } - .klaunch-content-text { - color: $grey-bright; - margin: 1rem; - text-align: center; - .kc-wait { - color: $soft-grey; - margin-bottom: 2rem; - } - } - .klaunch-content-text-center { - text-align: center; - } - .klaunch-info { - margin: 1.5rem; - .konnector-config { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - .kce-picto-txt { - color: $red-primary; - margin: 1.25rem; - } - .kcs-picto-txt { - color: $multi-color; - margin: 1.25rem; - } - } - } -} diff --git a/src/components/Exploration/ExplorationView.tsx b/src/components/Exploration/ExplorationView.tsx index 80be928f8e49be36a3818f6cd8b8a5ff83a48044..855950da01c28bb702994958f6e571e45298802e 100644 --- a/src/components/Exploration/ExplorationView.tsx +++ b/src/components/Exploration/ExplorationView.tsx @@ -4,21 +4,17 @@ import { AppStore } from 'store' import CozyBar from 'components/Header/CozyBar' import Content from 'components/Content/Content' import Header from 'components/Header/Header' -import { UserChallengeState } from 'enum/userChallenge.enum' - -import { UserChallenge } from 'models' - -import { useHistory } from 'react-router-dom' import { UserExplorationState } from 'enum/userExploration.enum' -import ExplorationError from './ExplorationError' +import { UserChallenge } from 'models' import ExplorationOngoing from './ExplorationOngoing' +import ExplorationError from './ExplorationError' const ExplorationView: React.FC = () => { const [headerHeight, setHeaderHeight] = useState<number>(0) const { currentChallenge } = useSelector( (state: AppStore) => state.ecolyo.challenge ) - const history = useHistory() + const defineHeaderHeight = useCallback((height: number) => { setHeaderHeight(height) }, []) @@ -27,6 +23,8 @@ const ExplorationView: React.FC = () => { switch (challenge.exploration.state) { case UserExplorationState.ONGOING: return <ExplorationOngoing userChallenge={challenge} /> + case UserExplorationState.DONE: + return 'ExplorationFinished' default: return <ExplorationError /> } @@ -34,21 +32,17 @@ const ExplorationView: React.FC = () => { return ( <> - <CozyBar titleKey={'COMMON.APP_DUEL_TITLE'} displayBackArrow={true} /> + <CozyBar + titleKey={'COMMON.APP_EXPLORATION_TITLE'} + displayBackArrow={true} + /> <Header setHeaderHeight={defineHeaderHeight} - desktopTitleKey={'COMMON.APP_DUEL_TITLE'} + desktopTitleKey={'COMMON.APP_EXPLORATION_TITLE'} displayBackArrow={true} ></Header> <Content height={headerHeight}> - <div> - {currentChallenge && - currentChallenge.state === UserChallengeState.DUEL ? ( - renderExploration(currentChallenge) - ) : ( - <ExplorationError /> - )} - </div> + {currentChallenge && renderExploration(currentChallenge)} </Content> </> ) diff --git a/src/components/Konnector/KonnectorModal.tsx b/src/components/Konnector/KonnectorModal.tsx index 2484c0ae6a3bd12fda1c1c0db34cb42db9b4ff30..baa211ba39b2259e2d41bd8367b4156caf2aa14e 100644 --- a/src/components/Konnector/KonnectorModal.tsx +++ b/src/components/Konnector/KonnectorModal.tsx @@ -24,12 +24,14 @@ const loadingOptions = { } interface KonnectorModalProps { + isUpdating: boolean state: string | null fluidType: FluidType handleCloseClick: Function } const KonnectorModal: React.FC<KonnectorModalProps> = ({ + isUpdating, state, fluidType, handleCloseClick, @@ -37,7 +39,11 @@ const KonnectorModal: React.FC<KonnectorModalProps> = ({ const { t } = useI18n() const fluidName: string = FluidType[fluidType] return ( - <Modal handleCloseClick={() => handleCloseClick()} border={false}> + <Modal + hideClosure={true} + handleCloseClick={() => handleCloseClick()} + border={false} + > <div className="kmodal-content"> {!state ? ( <> @@ -46,7 +52,11 @@ const KonnectorModal: React.FC<KonnectorModalProps> = ({ <div className="kc-wait">{t('KONNECTORCONFIG.PLZ_WAIT')}</div> </div> <div className="kmodal-content-text text-16-normal"> - <div>{t('KONNECTORCONFIG.LOADING_DATA')}</div> + <div> + {t( + `KONNECTORCONFIG.LOADING_DATA${isUpdating ? '_UPDATE' : ''}` + )} + </div> </div> </> ) : ( @@ -58,7 +68,13 @@ const KonnectorModal: React.FC<KonnectorModalProps> = ({ <div className="kce-picto-txt text-20-bold"> {t('KONNECTORCONFIG.ERROR_TXT')} </div> - <div>{t('KONNECTORCONFIG.ERROR_DATA_' + fluidName)}</div> + <div> + {t( + `KONNECTORCONFIG.ERROR_DATA_${ + isUpdating ? 'UPDATE_' : '' + }${fluidName}` + )} + </div> <div>{t('KONNECTORCONFIG.ERROR_DATA_2')}</div> </div> ) : ( @@ -67,7 +83,11 @@ const KonnectorModal: React.FC<KonnectorModalProps> = ({ <div className="kcs-picto-txt text-20-bold"> {t('KONNECTORCONFIG.SUCCESS_TXT')} </div> - {t('KONNECTORCONFIG.SUCCESS_DATA_' + fluidName)} + {t( + `KONNECTORCONFIG.SUCCESS_DATA_${ + isUpdating ? 'UPDATE_' : '' + }${fluidName}` + )} </div> )} <StyledButton diff --git a/src/components/Konnector/KonnectorViewerCard.tsx b/src/components/Konnector/KonnectorViewerCard.tsx index 968232987f7ed5d98c98fc5187804971b2668489..2a58a9636c742cb89172bc7c547905b488ea7680 100644 --- a/src/components/Konnector/KonnectorViewerCard.tsx +++ b/src/components/Konnector/KonnectorViewerCard.tsx @@ -43,7 +43,6 @@ import KonnectorModal from 'components/Konnector/KonnectorModal' import { isKonnectorRunning } from 'cozy-harvest-lib/dist/helpers/triggers' import ConnectionFlow, { ERROR_EVENT, - LOGIN_SUCCESS_EVENT, SUCCESS_EVENT, } from 'cozy-harvest-lib/dist/models/ConnectionFlow' @@ -68,7 +67,11 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ const [active, setActive] = useState<boolean>(false) const [openModal, setOpenModal] = useState(false) + const [isUpdating, setIsUpdating] = useState(false) const [konnectorState, setKonnectorState] = useState<string | null>(null) + const [updatedFluidStatus, setUpdatedFluidStatus] = useState<FluidStatus[]>( + [] + ) const { currentChallenge } = useSelector( (state: AppStore) => state.ecolyo.challenge ) @@ -90,20 +93,22 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ const updateProfileHaveSeenOldFluidModal = useCallback(async () => { const profileService = new ProfileService(client) - await profileService - .updateProfile({ haveSeenOldFluidModal: false }) - .then((updatedProfile: Profile | null) => { - if (updatedProfile) { - dispatch(updateProfile(updatedProfile)) - } - }) + const updatedProfile: Profile | null = await profileService.updateProfile({ + haveSeenOldFluidModal: false, + }) + if (updatedProfile) { + dispatch(updateProfile(updatedProfile)) + } }, [client, dispatch]) - const updateGlobalState = useCallback(async () => { + const updateGlobalFluidStatus = useCallback(async (): Promise< + FluidStatus[] + > => { const fluidService = new FluidService(client) - const updatedFluidStatus = await fluidService.getFluidStatus() - dispatch(setFluidStatus(updatedFluidStatus)) - }, [client, dispatch]) + const _updatedFluidStatus = await fluidService.getFluidStatus() + setUpdatedFluidStatus(_updatedFluidStatus) + return _updatedFluidStatus + }, [client]) const refreshChallengeState = useCallback(async () => { if ( @@ -130,18 +135,25 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ const handleConnectionEnd = useCallback(async () => { setActive(false) setOpenModal(false) - await updateGlobalState() - }, [updateGlobalState]) + setKonnectorState(null) + if (updatedFluidStatus.length > 0) { + dispatch(setFluidStatus(updatedFluidStatus)) + } + }, [dispatch, updatedFluidStatus]) const handleAccountDeletion = useCallback(async () => { await updateProfileHaveSeenOldFluidModal() await refreshChallengeState() - await updateGlobalState() + const _updatedFluidStatus = await updateGlobalFluidStatus() + if (_updatedFluidStatus.length > 0) { + dispatch(setFluidStatus(_updatedFluidStatus)) + } setActive(false) }, [ updateProfileHaveSeenOldFluidModal, - updateGlobalState, + updateGlobalFluidStatus, refreshChallengeState, + dispatch, ]) const getConnectionCard = useCallback(() => { @@ -168,6 +180,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ dispatch(updatedFluidConnection(fluidStatus.fluidType, updatedConnection)) await updateProfileHaveSeenOldFluidModal() await refreshChallengeState() + await updateGlobalFluidStatus() setKonnectorState(_state) }, [ @@ -176,6 +189,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ fluidStatus.fluidType, updateProfileHaveSeenOldFluidModal, refreshChallengeState, + updateGlobalFluidStatus, ] ) @@ -191,13 +205,15 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ connectionFlow.jobWatcher.on(ERROR_EVENT, () => { callbackResponse(ERROR_EVENT) }) - connectionFlow.jobWatcher.on(LOGIN_SUCCESS_EVENT, () => { - callbackResponse(LOGIN_SUCCESS_EVENT) - }) + // When LOGIN SUCESS EVENT is triggered, the status retrieve from the trigger is still running + // connectionFlow.jobWatcher.on(LOGIN_SUCCESS_EVENT, () => { + // callbackResponse(LOGIN_SUCCESS_EVENT) + // }) connectionFlow.jobWatcher.on(SUCCESS_EVENT, () => { callbackResponse(SUCCESS_EVENT) }) if (subscribed) { + if (fluidStatus.connection.isUpdating) setIsUpdating(true) setOpenModal(true) } } @@ -211,6 +227,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ konnector, trigger, fluidStatus.connection.shouldLaunchKonnector, + fluidStatus.connection.isUpdating, callbackResponse, ]) @@ -273,6 +290,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ </div> {openModal && ( <KonnectorModal + isUpdating={isUpdating} state={konnectorState} fluidType={fluidStatus.fluidType} handleCloseClick={handleConnectionEnd} diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index 650bc2ff317b89a59ba5a9b0f2286b4e214561f0..e650aa2dc1abbe60b1e2d1af0d50626b7c20a201 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -1,82 +1,84 @@ -import React, { Suspense, lazy } from 'react' -import { Route, Switch, Redirect } from 'react-router-dom' -import { FluidType } from 'enum/fluid.enum' -import ChallengeView from 'components/Challenge/ChallengeView' -import DuelView from 'components/Duel/DuelView' -import QuizView from 'components/Quiz/QuizView' - -const HomeView = lazy(() => import('components/Home/HomeView')) -const SingleFluidView = lazy(() => - import('components/SingleFluid/SingleFluidView') -) - -const EcogestureView = lazy(() => - import('components/Ecogesture/EcogestureView') -) -const OptionsView = lazy(() => import('components/Options/OptionsView')) -const FAQView = lazy(() => import('components/FAQ/FAQView')) -const LegalNoticeView = lazy(() => - import('components/LegalNotice/LegalNoticeView') -) -const ReportView = lazy(() => import('components/Report/ReportView')) - -const Routes = () => { - return ( - <Suspense fallback={<div></div>}> - <Switch> - <Route - path="/consumption" - render={({ match: { url } }) => ( - <> - <Route - path={`${url}/electricité`} - component={() => ( - <SingleFluidView fluidTypes={[FluidType.ELECTRICITY]} /> - )} - /> - <Route - path={`${url}/eau`} - component={() => ( - <SingleFluidView fluidTypes={[FluidType.WATER]} /> - )} - /> - <Route - path={`${url}/gaz`} - component={() => ( - <SingleFluidView fluidTypes={[FluidType.GAS]} /> - )} - /> - <Route path={`${url}/`} component={HomeView} exact /> - </> - )} - /> - <Route - path="/challenges" - render={({ match: { url } }) => ( - <> - <Route path={`${url}/duel`} component={DuelView} /> - <Route path={`${url}/quiz`} component={QuizView} /> - <Route path={`${url}/`} component={ChallengeView} exact /> - </> - )} - /> - <Route path="/ecogestures" component={EcogestureView} /> - <Route - path="/options" - render={({ match: { url } }) => ( - <> - <Route path={`${url}/FAQ`} component={FAQView} /> - <Route path={`${url}/legalnotice`} component={LegalNoticeView} /> - <Route path={`${url}/`} component={OptionsView} exact /> - </> - )} - /> - <Route path="/report" component={ReportView} /> - <Redirect from="/" to="/consumption" /> - <Redirect from="*" to="/consumption" /> - </Switch> - </Suspense> - ) -} - -export default Routes +import React, { Suspense, lazy } from 'react' +import { Route, Switch, Redirect } from 'react-router-dom' +import { FluidType } from 'enum/fluid.enum' +import ChallengeView from 'components/Challenge/ChallengeView' +import DuelView from 'components/Duel/DuelView' +import QuizView from 'components/Quiz/QuizView' +import ExplorationView from 'components/Exploration/ExplorationView' + +const HomeView = lazy(() => import('components/Home/HomeView')) +const SingleFluidView = lazy(() => + import('components/SingleFluid/SingleFluidView') +) + +const EcogestureView = lazy(() => + import('components/Ecogesture/EcogestureView') +) +const OptionsView = lazy(() => import('components/Options/OptionsView')) +const FAQView = lazy(() => import('components/FAQ/FAQView')) +const LegalNoticeView = lazy(() => + import('components/LegalNotice/LegalNoticeView') +) +const ReportView = lazy(() => import('components/Report/ReportView')) + +const Routes = () => { + return ( + <Suspense fallback={<div></div>}> + <Switch> + <Route + path="/consumption" + render={({ match: { url } }) => ( + <> + <Route + path={`${url}/electricité`} + component={() => ( + <SingleFluidView fluidTypes={[FluidType.ELECTRICITY]} /> + )} + /> + <Route + path={`${url}/eau`} + component={() => ( + <SingleFluidView fluidTypes={[FluidType.WATER]} /> + )} + /> + <Route + path={`${url}/gaz`} + component={() => ( + <SingleFluidView fluidTypes={[FluidType.GAS]} /> + )} + /> + <Route path={`${url}/`} component={HomeView} exact /> + </> + )} + /> + <Route + path="/challenges" + render={({ match: { url } }) => ( + <> + <Route path={`${url}/duel`} component={DuelView} /> + <Route path={`${url}/quiz`} component={QuizView} /> + <Route path={`${url}/exploration`} component={ExplorationView} /> + <Route path={`${url}/`} component={ChallengeView} exact /> + </> + )} + /> + <Route path="/ecogestures" component={EcogestureView} /> + <Route + path="/options" + render={({ match: { url } }) => ( + <> + <Route path={`${url}/FAQ`} component={FAQView} /> + <Route path={`${url}/legalnotice`} component={LegalNoticeView} /> + <Route path={`${url}/`} component={OptionsView} exact /> + </> + )} + /> + <Route path="/report" component={ReportView} /> + <Redirect from="/" to="/consumption" /> + <Redirect from="*" to="/consumption" /> + </Switch> + </Suspense> + ) +} + +export default Routes diff --git a/src/db/challengeEntity.json b/src/db/challengeEntity.json index c0c31df946c1b37f8faeef04ac7aec0545e787ad..f812b7316b8e27bebdeb1e95b459ba0ef2677b14 100644 --- a/src/db/challengeEntity.json +++ b/src/db/challengeEntity.json @@ -10,6 +10,12 @@ }, "duel": { "data": { "_id": "DUEL001", "_type": "com.grandlyon.ecolyo.duel" } + }, + "exploration": { + "data": { + "_id": "EXPLORATION001", + "_type": "com.grandlyon.ecolyo.exploration" + } } } }, @@ -24,6 +30,12 @@ }, "duel": { "data": { "_id": "DUEL002", "_type": "com.grandlyon.ecolyo.duel" } + }, + "exploration": { + "data": { + "_id": "EXPLORATION002", + "_type": "com.grandlyon.ecolyo.exploration" + } } } }, @@ -38,6 +50,12 @@ }, "duel": { "data": { "_id": "DUEL003", "_type": "com.grandlyon.ecolyo.duel" } + }, + "exploration": { + "data": { + "_id": "EXPLORATION003", + "_type": "com.grandlyon.ecolyo.exploration" + } } } } diff --git a/src/enum/userChallenge.enum.ts b/src/enum/userChallenge.enum.ts index b9d8796da67dc554a5f6540a3a842f4db687e017..128c5a980f80e1a7e70da31c90e623b5ffd4587a 100644 --- a/src/enum/userChallenge.enum.ts +++ b/src/enum/userChallenge.enum.ts @@ -11,7 +11,9 @@ export enum UserChallengeUpdateFlag { QUIZ_DONE = 22, QUIZ_RESET = 23, QUIZ_UPDATE = 24, - EXPLORATION = 30, + EXPLORATION_START = 30, + EXPLORATION_UPDATE = 31, + EXPLORATION_DONE = 32, } export enum UserChallengeState { diff --git a/src/locales/fr.json b/src/locales/fr.json index 2c442e8fbbb05ac131c9dd32e6f355501d335a14..b5b7163111293335f233b8dead825a6b249f0cf5 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -22,6 +22,7 @@ "APP_TITLE": "Ecolyo", "APP_CHALLENGE_TITLE": "Défi", "APP_QUIZ_TITLE": "Quiz", + "APP_EXPLORATION_TITLE": "Exploration", "APP_DUEL_TITLE": "Duel final", "APP_ECO_GESTURE_TITLE": "Ecogestes", "APP_OPTIONS_TITLE": "Options", @@ -148,6 +149,7 @@ "BTN_UPDATE": "Mettre à jour", "BTN_DELETE": "Supprimer", "LOADING_DATA": "Vos premières données seront disponibles dans quelques minutes et les prochaines données seront chargées automatiquement.", + "LOADING_DATA_UPDATE": "Vos données mises à jour seront disponibles dans quelques minutes.", "PLZ_WAIT": "Veuillez patienter", "NOT_INSTALLED": "Le connecteur n'est pas installé. Veuillez l'installer en cliquant sur le bouton ci-dessous.", "ERROR_NO_LOGIN_PASSWORD": "Identifiant et mot de passe requis", @@ -157,10 +159,16 @@ "SUCCESS_DATA_ELECTRICITY": "Vos données de consommation d'électricité sont maintenant connectées à Ecolyo.", "SUCCESS_DATA_WATER": "Vos données de consommation d'eau sont maintenant connectées à Ecolyo.", "SUCCESS_DATA_GAS": "Vos données de consommation de gaz sont maintenant connectées à Ecolyo.", + "SUCCESS_DATA_UPDATE_ELECTRICITY": "Vos données de consommation d'électricité sont maintenant à jour dans Ecolyo.", + "SUCCESS_DATA_UPDATE_WATER": "Vos données de consommation d'eau sont maintenant à jour dans Ecolyo.", + "SUCCESS_DATA_UPDATE_GAS": "Vos données de consommation de gaz sont maintenant à jour dans Ecolyo.", "ERROR_TXT": "Aïe !", "ERROR_DATA_ELECTRICITY": "Un problème a empêché vos données de consommation d'électricité de se connecter à Ecolyo.", - "ERROR_DATA_WATER": "Un problème a empêché vos données de consommation d'eau se connecter à Ecolyo.", + "ERROR_DATA_WATER": "Un problème a empêché vos données de consommation d'eau de se connecter à Ecolyo.", "ERROR_DATA_GAS": "Un problème a empêché vos données de consommation de gaz de se connecter à Ecolyo.", + "ERROR_DATA_UPDATE_ELECTRICITY": "Un problème a empêché vos données de consommation d'électricité de se mettre à jour dans Ecolyo.", + "ERROR_DATA_UPDATE_WATER": "Un problème a empêché vos données de consommation d'eau de se mettre à jour dans Ecolyo.", + "ERROR_DATA_UPDATE_GAS": "Un problème a empêché vos données de consommation de gaz de se mettre à jour dans Ecolyo.", "ERROR_DATA_2": "Merci de réessayer plus tard.", "ERROR_UPDATE": "Un problème est survenu lors du rappatriement de vos données.", "ERROR_UPDATE_OAUTH": "Le service demande d'autoriser à nouveau votre accès. Merci de supprimer puis reconnecter votre compte. Aucune donnée ne sera perdue.", diff --git a/src/models/fluid.model.ts b/src/models/fluid.model.ts index 2e92b74e8cbf1f872652f5e92e1c60ad0eea940f..00077fcd16dd5a3131070c7a1895836d93f0a92c 100644 --- a/src/models/fluid.model.ts +++ b/src/models/fluid.model.ts @@ -5,6 +5,7 @@ import { TriggerState } from './trigger.model' export interface FluidConnection { shouldLaunchKonnector: boolean + isUpdating: boolean konnector: Konnector | null account: Account | null trigger: Trigger | null diff --git a/src/services/challenge.service.spec.ts b/src/services/challenge.service.spec.ts index ad46483029d17834ef2c96be2311d3dc9e1da9e1..0ee62ce33d0fecc5517aad8cbd6f742016e3603b 100644 --- a/src/services/challenge.service.spec.ts +++ b/src/services/challenge.service.spec.ts @@ -1,5 +1,11 @@ import { QueryResult } from 'cozy-client' -import { DuelEntity, ChallengeEntity, UserChallenge, QuizEntity } from 'models' +import { + DuelEntity, + ChallengeEntity, + UserChallenge, + QuizEntity, + ExplorationEntity, +} from 'models' import { UserChallengeState, UserChallengeSuccess, @@ -24,6 +30,10 @@ import { DateTime, Duration } from 'luxon' import { graphData } from '../../test/__mocks__/datachartData.mock' import { UserDuelState } from 'enum/userDuel.enum' import { quizEntity, userQuiz } from '../../test/__mocks__/quizData.mock' +import { + explorationEntity, + UserExplorationUnlocked, +} from '../../test/__mocks__/explorationData.mock' const mockGetGraphData = jest.fn() jest.mock('./consumption.service', () => { @@ -56,7 +66,7 @@ describe('Challenge service', () => { describe('parseChallengeEntityToUserChallenge method', () => { it('should return a user challenge', () => { - const expectedResult = { + const expectedResult: UserChallenge = { id: challengeEntityData.id, title: challengeEntityData.title, description: challengeEntityData.description, @@ -72,42 +82,54 @@ describe('Challenge service', () => { startDate: null, endingDate: null, quiz: userQuiz, + exploration: UserExplorationUnlocked, } const result = challengeService.parseChallengeEntityToUserChallenge( challengeEntityData, duelData, - userQuiz + userQuiz, + UserExplorationUnlocked ) expect(result).toEqual(expectedResult) }) }) describe('buildUserChallengeList method', () => { + const mockQueryResult: QueryResult<ChallengeEntity[], DuelEntity[]> = { + data: allChallengeEntityData, + included: [duelEntity], + bookmark: '', + next: false, + skip: 0, + } + const mockQueryResultQuiz: QueryResult<ChallengeEntity[], QuizEntity[]> = { + data: allChallengeEntityData, + included: [quizEntity], + bookmark: '', + next: false, + skip: 0, + } + const mockQueryResultExploration: QueryResult< + ChallengeEntity[], + ExplorationEntity[] + > = { + data: allChallengeEntityData, + included: [explorationEntity], + bookmark: '', + next: false, + skip: 0, + } + const mockQueryResultUser: QueryResult<UserChallenge[]> = { + data: userChallengeData, + bookmark: '', + next: false, + skip: 0, + } it('should return all user challenge', async () => { - const mockQueryResult: QueryResult<ChallengeEntity[], DuelEntity[]> = { - data: allChallengeEntityData, - included: [duelEntity], - bookmark: '', - next: false, - skip: 0, - } mockClient.query.mockResolvedValueOnce(mockQueryResult) - const mockQueryResult2: QueryResult<ChallengeEntity[], QuizEntity[]> = { - data: allChallengeEntityData, - included: [quizEntity], - bookmark: '', - next: false, - skip: 0, - } - mockClient.query.mockResolvedValueOnce(mockQueryResult2) - const mockQueryResultUser: QueryResult<UserChallenge[]> = { - data: userChallengeData, - bookmark: '', - next: false, - skip: 0, - } + mockClient.query.mockResolvedValueOnce(mockQueryResultQuiz) + mockClient.query.mockResolvedValueOnce(mockQueryResultExploration) mockClient.query.mockResolvedValueOnce(mockQueryResultUser) - const result = await challengeService.buildUserChallengeList() expect(result).toEqual(userChallengeData) }) @@ -120,49 +142,23 @@ describe('Challenge service', () => { skip: 0, } mockClient.query.mockResolvedValueOnce(mockQueryResult) - const mockQueryResult2: QueryResult<ChallengeEntity[], QuizEntity[]> = { - data: allChallengeEntityData, - included: [quizEntity], - bookmark: '', - next: false, - skip: 0, - } - mockClient.query.mockResolvedValueOnce(mockQueryResult2) - const mockQueryResultUser: QueryResult<UserChallenge[]> = { - data: userChallengeData, - bookmark: '', - next: false, - skip: 0, - } + mockClient.query.mockResolvedValueOnce(mockQueryResultQuiz) + mockClient.query.mockResolvedValueOnce(mockQueryResultExploration) mockClient.query.mockResolvedValueOnce(mockQueryResultUser) const result = await challengeService.buildUserChallengeList() expect(result).toEqual(userChallengeData) }) it('should create all user challenge', async () => { - const mockQueryResult: QueryResult<ChallengeEntity[], DuelEntity[]> = { - data: allChallengeEntityData, - included: [duelEntity], - bookmark: '', - next: false, - skip: 0, - } - mockClient.query.mockResolvedValueOnce(mockQueryResult) - const mockQueryResult2: QueryResult<ChallengeEntity[], QuizEntity[]> = { - data: allChallengeEntityData, - included: [quizEntity], - bookmark: '', - next: false, - skip: 0, - } - mockClient.query.mockResolvedValueOnce(mockQueryResult2) - - const mockQueryResultUser: QueryResult<UserChallenge[]> = { + const mockQueryResultUserEmpty: QueryResult<UserChallenge[]> = { data: [], bookmark: '', next: false, skip: 0, } - mockClient.query.mockResolvedValueOnce(mockQueryResultUser) + mockClient.query.mockResolvedValueOnce(mockQueryResult) + mockClient.query.mockResolvedValueOnce(mockQueryResultQuiz) + mockClient.query.mockResolvedValueOnce(mockQueryResultExploration) + mockClient.query.mockResolvedValueOnce(mockQueryResultUserEmpty) const result = await challengeService.buildUserChallengeList() expect(result).toEqual(userChallengeDefault) }) diff --git a/src/services/challenge.service.ts b/src/services/challenge.service.ts index 603551b7bbad32c1bcb4c068361220df0097aa50..bd7ad98391f3c0bec5b1b044ffb7aec56dbb834a 100644 --- a/src/services/challenge.service.ts +++ b/src/services/challenge.service.ts @@ -13,6 +13,8 @@ import { Relation, TimePeriod, UserQuiz, + UserExploration, + ExplorationEntity, } from 'models' import { UserChallengeState, @@ -27,6 +29,7 @@ import QuizService from 'services/quiz.service' import ConsumptionDataManager from 'services/consumption.service' import { getRelationship } from 'utils/utils' import { getLagDays } from 'utils/date' +import ExplorationService from './exploration.service' export default class ChallengeService { private readonly _client: Client @@ -97,7 +100,8 @@ export default class ChallengeService { public parseChallengeEntityToUserChallenge( challenge: ChallengeEntity, duel: UserDuel, - quiz: UserQuiz + quiz: UserQuiz, + exploration: UserExploration ): UserChallenge { const userChallenge: UserChallenge = { id: challenge.id, @@ -115,6 +119,7 @@ export default class ChallengeService { startDate: null, endingDate: null, quiz: quiz, + exploration: exploration, } return userChallenge } @@ -130,12 +135,21 @@ export default class ChallengeService { const querySeasonEntityIncludeQuiz: QueryDefinition = Q( CHALLENGE_DOCTYPE ).include(['quiz']) + const querySeasonEntityIncludeExploration: QueryDefinition = Q( + CHALLENGE_DOCTYPE + ).include(['exploration']) const { data: challengeEntityList, included: duelEntities, }: QueryResult<ChallengeEntity[], DuelEntity[]> = await this._client.query( queryChallengeEntity ) + const { + included: explorationEntities, + }: QueryResult< + ChallengeEntity[], + ExplorationEntity[] + > = await this._client.query(querySeasonEntityIncludeExploration) const { included: quizEntities, }: QueryResult<ChallengeEntity[], QuizEntity[]> = await this._client.query( @@ -144,11 +158,16 @@ export default class ChallengeService { const userChallengeList: UserChallenge[] = await this.getAllUserChallengeEntities() const duelService = new DuelService(this._client) const quizService = new QuizService(this._client) + const explorationService = new ExplorationService(this._client) let buildList: UserChallenge[] = [] if (challengeEntityList.length > 0 && userChallengeList.length === 0) { challengeEntityList.forEach(async challenge => { const duelEntityRelation: Relation = getRelationship(challenge, 'duel') const quizEntityRelation: Relation = getRelationship(challenge, 'quiz') + const explorationEntityRelation: Relation = getRelationship( + challenge, + 'exploration' + ) const duel: UserDuel = duelService.getDuelfromDuelEntities( duelEntities || [], duelEntityRelation._id @@ -157,10 +176,15 @@ export default class ChallengeService { quizEntities || [], quizEntityRelation._id ) + const exploration: UserExploration = explorationService.getUserExplorationfromExplorationEntities( + explorationEntities || [], + explorationEntityRelation._id + ) const userChallenge = this.parseChallengeEntityToUserChallenge( challenge, duel, - quiz + quiz, + exploration ) buildList.push(userChallenge) @@ -184,6 +208,10 @@ export default class ChallengeService { challenge, 'quiz' ) + const explorationEntityRelation: Relation = getRelationship( + challenge, + 'exploration' + ) const duel: UserDuel = duelService.getDuelfromDuelEntities( duelEntities || [], duelEntityRelation._id @@ -192,8 +220,18 @@ export default class ChallengeService { quizEntities || [], quizEntityRelation._id ) + const exploration: UserExploration = explorationService.getUserExplorationfromExplorationEntities( + explorationEntities || [], + explorationEntityRelation._id + ) + buildList.push( - this.parseChallengeEntityToUserChallenge(challenge, duel, quiz) + this.parseChallengeEntityToUserChallenge( + challenge, + duel, + quiz, + exploration + ) ) } }) @@ -299,8 +337,10 @@ export default class ChallengeService { let updatedUserChallenge: UserChallenge let updatedDuel = userChallenge.duel let updatedQuiz = userChallenge.quiz + let updatedExploration = userChallenge.exploration const duelService = new DuelService(this._client) const quizService = new QuizService(this._client) + const explorationService = new ExplorationService(this._client) switch (flag) { case UserChallengeUpdateFlag.CHALLENGE: case UserChallengeUpdateFlag.DUEL_CONSUMPTION: @@ -392,6 +432,33 @@ export default class ChallengeService { quiz: updatedQuiz, } break + case UserChallengeUpdateFlag.EXPLORATION_START: + updatedExploration = await explorationService.startUserExploration( + userChallenge.exploration + ) + updatedUserChallenge = { + ...userChallenge, + exploration: updatedExploration, + } + break + case UserChallengeUpdateFlag.EXPLORATION_UPDATE: + updatedExploration = await explorationService.updateUserExploration( + userChallenge.exploration + ) + updatedUserChallenge = { + ...userChallenge, + exploration: updatedExploration, + } + break + case UserChallengeUpdateFlag.EXPLORATION_DONE: + updatedExploration = await explorationService.endUserExploration( + userChallenge.exploration + ) + updatedUserChallenge = { + ...userChallenge, + exploration: updatedExploration, + } + break default: updatedUserChallenge = userChallenge break diff --git a/src/services/fluid.service.spec.ts b/src/services/fluid.service.spec.ts index 383d94131a5606cf657251c7a43eaf1fe0b803ad..d1c2e0d5f1d8385730d0b2f6e7f191c32bae5e9e 100644 --- a/src/services/fluid.service.spec.ts +++ b/src/services/fluid.service.spec.ts @@ -74,6 +74,7 @@ describe('FLuid service', () => { trigger: triggersData[0], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Enedis', oauth: true, @@ -92,6 +93,7 @@ describe('FLuid service', () => { trigger: triggersData[1], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Eau du Grand Lyon', oauth: false, @@ -110,6 +112,7 @@ describe('FLuid service', () => { trigger: triggersData[2], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'GRDF', oauth: true, @@ -154,6 +157,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Enedis', oauth: true, @@ -172,6 +176,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Eau du Grand Lyon', oauth: false, @@ -190,6 +195,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'GRDF', oauth: true, @@ -234,6 +240,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Enedis', oauth: true, @@ -252,6 +259,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Eau du Grand Lyon', oauth: false, @@ -270,6 +278,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'GRDF', oauth: true, @@ -314,6 +323,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Enedis', oauth: true, @@ -332,6 +342,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Eau du Grand Lyon', oauth: false, @@ -350,6 +361,7 @@ describe('FLuid service', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'GRDF', oauth: true, @@ -394,6 +406,7 @@ describe('FLuid service', () => { trigger: triggersData[0], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Enedis', oauth: true, @@ -412,6 +425,7 @@ describe('FLuid service', () => { trigger: triggersData[1], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Eau du Grand Lyon', oauth: false, @@ -430,6 +444,7 @@ describe('FLuid service', () => { trigger: triggersData[2], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'GRDF', oauth: true, diff --git a/src/services/fluid.service.ts b/src/services/fluid.service.ts index 213933ea022afc845b0cd365ed2c375a85bede7b..0bc8b102ab76ab1f9ff4a7a4703bf8d39894ca5a 100644 --- a/src/services/fluid.service.ts +++ b/src/services/fluid.service.ts @@ -111,6 +111,7 @@ export default class FluidService { lastDataDate: lastDataDates[FluidType.ELECTRICITY], connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: elecKonnector, account: elecAccount, trigger: elecTrigger, @@ -124,6 +125,7 @@ export default class FluidService { lastDataDate: lastDataDates[FluidType.WATER], connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: waterKonnector, account: waterAccount, trigger: waterTrigger, @@ -137,6 +139,7 @@ export default class FluidService { lastDataDate: lastDataDates[FluidType.GAS], connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: gasKonnector, account: gasAccount, trigger: gasTrigger, diff --git a/src/store/global/global.reducer.spec.ts b/src/store/global/global.reducer.spec.ts index 79458f9bbb03ec55e941dc00fca3f7daf993e461..65b26f575582444a73e4d1489bee072852316ff8 100644 --- a/src/store/global/global.reducer.spec.ts +++ b/src/store/global/global.reducer.spec.ts @@ -26,6 +26,7 @@ const mockFluidStatus: FluidStatus[] = [ lastDataDate: null, connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: null, account: null, trigger: null, @@ -44,6 +45,7 @@ const mockFluidStatus: FluidStatus[] = [ lastDataDate: null, connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: null, account: null, trigger: null, @@ -62,6 +64,7 @@ const mockFluidStatus: FluidStatus[] = [ lastDataDate: null, connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: null, account: null, trigger: null, @@ -157,6 +160,7 @@ describe('global reducer', () => { trigger: triggersData[0], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Enedis', oauth: true, @@ -175,6 +179,7 @@ describe('global reducer', () => { trigger: triggersData[1], triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'Eau du Grand Lyon', oauth: false, @@ -193,6 +198,7 @@ describe('global reducer', () => { trigger: null, triggerState: null, shouldLaunchKonnector: false, + isUpdating: false, konnectorConfig: { name: 'GRDF', oauth: true, diff --git a/src/store/global/global.reducer.ts b/src/store/global/global.reducer.ts index ac5ced386155bea25b132d829f017f39d677eedb..ccfe689ebcdb59764570deb4cd3fb57e87d0c791 100644 --- a/src/store/global/global.reducer.ts +++ b/src/store/global/global.reducer.ts @@ -22,6 +22,7 @@ const initialState: GlobalState = { lastDataDate: null, connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: null, account: null, trigger: null, @@ -40,6 +41,7 @@ const initialState: GlobalState = { lastDataDate: null, connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: null, account: null, trigger: null, @@ -58,6 +60,7 @@ const initialState: GlobalState = { lastDataDate: null, connection: { shouldLaunchKonnector: false, + isUpdating: false, konnector: null, account: null, trigger: null, diff --git a/test/__mocks__/challengeEntity.mock.ts b/test/__mocks__/challengeEntity.mock.ts index 906f55e089666353ac0e99e50fb150c02c471a06..aa1176b9e8bd54b93d72cb0be4effdb8592de7ba 100644 --- a/test/__mocks__/challengeEntity.mock.ts +++ b/test/__mocks__/challengeEntity.mock.ts @@ -1,5 +1,6 @@ import { ChallengeEntity } from 'models' import { duelEntity } from './duelData.mock' +import { explorationEntity } from './explorationData.mock' import { quizEntity } from './quizData.mock' export const challengeEntityData: ChallengeEntity = { @@ -9,6 +10,7 @@ export const challengeEntityData: ChallengeEntity = { target: 15, duel: duelEntity, quiz: quizEntity, + exploration: explorationEntity, } export const allChallengeEntityData: ChallengeEntity[] = [ @@ -19,6 +21,7 @@ export const allChallengeEntityData: ChallengeEntity[] = [ target: 15, duel: duelEntity, quiz: quizEntity, + exploration: explorationEntity, }, { id: 'CHALLENGE0002', @@ -27,6 +30,7 @@ export const allChallengeEntityData: ChallengeEntity[] = [ target: 15, duel: duelEntity, quiz: quizEntity, + exploration: explorationEntity, }, { id: 'CHALLENGE0003', @@ -35,6 +39,7 @@ export const allChallengeEntityData: ChallengeEntity[] = [ target: 15, duel: duelEntity, quiz: quizEntity, + exploration: explorationEntity, }, { id: 'CHALLENGE0004', @@ -43,6 +48,7 @@ export const allChallengeEntityData: ChallengeEntity[] = [ target: 15, duel: duelEntity, quiz: quizEntity, + exploration: explorationEntity, }, { id: 'CHALLENGE0005', @@ -51,5 +57,6 @@ export const allChallengeEntityData: ChallengeEntity[] = [ target: 15, duel: duelEntity, quiz: quizEntity, + exploration: explorationEntity, }, ] diff --git a/test/__mocks__/explorationData.mock.ts b/test/__mocks__/explorationData.mock.ts index a1a0460db959d1ec61b636b2f1cca81841edbbc8..d88c7520262f0ea098feb99dc615811fe2c76cb2 100644 --- a/test/__mocks__/explorationData.mock.ts +++ b/test/__mocks__/explorationData.mock.ts @@ -16,6 +16,18 @@ export const explorationEntity: ExplorationEntity = { fluid_condition: [], priority_by_condition: 1, } +export const explorationDefault: UserExploration = { + id: '', + state: UserExplorationState.UNLOCKED, + description: '', + target: 0, + type: UserExplorationType.DECLARATIVE, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + progress: 0, +} export const allExplorationEntities: ExplorationEntity[] = [ { diff --git a/test/__mocks__/userChallengeData.mock.ts b/test/__mocks__/userChallengeData.mock.ts index cdda7c79b8a5bca0f10f92fe311461a3ee7d774e..ec80a41b8901031bcae7a776ec157dcaa47b5149 100644 --- a/test/__mocks__/userChallengeData.mock.ts +++ b/test/__mocks__/userChallengeData.mock.ts @@ -4,7 +4,10 @@ import { } from 'enum/userChallenge.enum' import { UserChallenge } from 'models' import { duelData, duelDefault } from './duelData.mock' -import { UserExplorationUnlocked } from './explorationData.mock' +import { + explorationDefault, + UserExplorationUnlocked, +} from './explorationData.mock' import { quizDefault, userQuiz } from './quizData.mock' export const userChallengeData: UserChallenge[] = [ @@ -117,7 +120,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, - exploration: UserExplorationUnlocked, + exploration: explorationDefault, }, { id: 'CHALLENGE0002', @@ -135,7 +138,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, - exploration: UserExplorationUnlocked, + exploration: explorationDefault, }, { id: 'CHALLENGE0003', @@ -153,7 +156,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, - exploration: UserExplorationUnlocked, + exploration: explorationDefault, }, { id: 'CHALLENGE0004', @@ -171,7 +174,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, - exploration: UserExplorationUnlocked, + exploration: explorationDefault, }, { id: 'CHALLENGE0005', @@ -189,6 +192,6 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, - exploration: UserExplorationUnlocked, + exploration: explorationDefault, }, ] diff --git a/yarn.lock b/yarn.lock index bea3fa171a6ff22a0fe737ceda994d4dd7cad4c6..675c4cd667d5f5210c753f74b4d9fea658d0fe12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9998,9 +9998,10 @@ node-releases@^1.1.46, node-releases@^1.1.58: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.59.tgz#4d648330641cec704bff10f8e4fe28e453ab8e8e" integrity sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw== -node-sass@^4.13.0: - version "4.13.1" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.1.tgz#9db5689696bb2eec2c32b98bfea4c7a2e992d0a3" +node-sass@^4.14.0: + version "4.14.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5" + integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -10016,7 +10017,7 @@ node-sass@^4.13.0: node-gyp "^3.8.0" npmlog "^4.0.0" request "^2.88.0" - sass-graph "^2.2.4" + sass-graph "2.2.5" stdout-stream "^1.4.0" "true-case-path" "^1.0.2" @@ -12545,14 +12546,15 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sass-graph@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" +sass-graph@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8" + integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== dependencies: glob "^7.0.0" lodash "^4.0.0" scss-tokenizer "^0.2.3" - yargs "^7.0.0" + yargs "^13.3.2" sass-loader@^8.0.0: version "8.0.2" @@ -13229,7 +13231,7 @@ string-length@^2.0.0: astral-regex "^1.0.0" strip-ansi "^4.0.0" -string-width@^1.0.1, string-width@^1.0.2: +string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= @@ -14593,10 +14595,6 @@ when@~3.6.x: resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -14818,12 +14816,6 @@ yargs-parser@^2.4.0: camelcase "^3.0.0" lodash.assign "^4.0.6" -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - dependencies: - camelcase "^3.0.0" - yargs-parser@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" @@ -14922,7 +14914,7 @@ yargs@^11.0.0: y18n "^3.2.1" yargs-parser "^9.0.2" -yargs@^13.3.0: +yargs@^13.3.0, yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== @@ -14955,24 +14947,6 @@ yargs@^15.0.0: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" - zxcvbn@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30"