diff --git a/src/components/Ecogesture/EcogestureCard.tsx b/src/components/Ecogesture/EcogestureCard.tsx index 5e9311124a90512a769afd1cdf4dd0caf24326c9..da0e18a3e2c7f502e40e2c1895aa78c76210da04 100644 --- a/src/components/Ecogesture/EcogestureCard.tsx +++ b/src/components/Ecogesture/EcogestureCard.tsx @@ -11,10 +11,12 @@ import { Link } from '@material-ui/core/' interface EcogestureCardProps { ecogesture: Ecogesture + selectionCompleted: boolean } const EcogestureCard: React.FC<EcogestureCardProps> = ({ ecogesture, + selectionCompleted, }: EcogestureCardProps) => { const [ecogestureIcon, setEcogestureIcon] = useState<string>('') useEffect(() => { @@ -33,7 +35,10 @@ const EcogestureCard: React.FC<EcogestureCardProps> = ({ return ( <Link - to={`/ecogesture/${ecogesture.id}`} + to={{ + pathname: `/ecogesture/${ecogesture.id}`, + state: { selectionCompleted }, + }} component={RouterLink} className="ecogesture-list-item" > diff --git a/src/components/Ecogesture/EcogestureEmptyList.tsx b/src/components/Ecogesture/EcogestureEmptyList.tsx index d83cdec613cb77fdfb8df8a14d6fa632760a977a..234614fcb21c6bedfa61b9241554f158233548d1 100644 --- a/src/components/Ecogesture/EcogestureEmptyList.tsx +++ b/src/components/Ecogesture/EcogestureEmptyList.tsx @@ -12,11 +12,13 @@ interface EcogestureEmptyListProps { setTab: React.Dispatch<React.SetStateAction<number>> isObjective: boolean isSelectionDone: boolean + handleReinitClick: () => void } const EcogestureEmptyList: React.FC<EcogestureEmptyListProps> = ({ setTab, isObjective, isSelectionDone, + handleReinitClick, }: EcogestureEmptyListProps) => { const { t } = useI18n() const history = useHistory() @@ -57,6 +59,20 @@ const EcogestureEmptyList: React.FC<EcogestureEmptyListProps> = ({ > {t('ecogesture.emptyList.btn1')} </Button> + + {isSelectionDone && ( + <Button + aria-label={t('ecogesture.emptyList.reinit')} + onClick={handleReinitClick} + classes={{ + root: 'reinit-button btn-profile-next rounded', + label: 'text-16-bold', + }} + > + {t('ecogesture.reinit')} + </Button> + )} + {!isSelectionDone && ( <Button aria-label={t('ecogesture.emptyList.btn2')} diff --git a/src/components/Ecogesture/EcogestureList.tsx b/src/components/Ecogesture/EcogestureList.tsx index 029e36748d843c2b69784bb22bf0fb7a1ebe798a..cec76aff46bb1c3cc68e104b9d9ba5ebbf7d11b2 100644 --- a/src/components/Ecogesture/EcogestureList.tsx +++ b/src/components/Ecogesture/EcogestureList.tsx @@ -11,13 +11,15 @@ import EcogestureCard from 'components/Ecogesture/EcogestureCard' import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import Button from '@material-ui/core/Button' import './ecogestureList.scss' -import { Usage } from 'enum/ecogesture.enum' +import { EcogestureStatus, Usage } from 'enum/ecogesture.enum' interface EcogestureListProps { list: Ecogesture[] displaySelection: boolean selectionTotal: number selectionViewed: number + index: number + handleReinitClick: () => void } const EcogestureList: React.FC<EcogestureListProps> = ({ @@ -25,6 +27,8 @@ const EcogestureList: React.FC<EcogestureListProps> = ({ displaySelection, selectionTotal, selectionViewed, + index, + handleReinitClick, }: EcogestureListProps) => { const { t } = useI18n() const history = useHistory() @@ -50,7 +54,10 @@ const EcogestureList: React.FC<EcogestureListProps> = ({ .filter(ecogesture => Usage[ecogesture.usage] === activeFilter) .map((ecogesture, index) => ( <div key={index} className="ecogesture-list-item"> - <EcogestureCard ecogesture={ecogesture} /> + <EcogestureCard + ecogesture={ecogesture} + selectionCompleted={selectionViewed === selectionTotal} + /> </div> )) if (filtered.length > 0) { @@ -163,23 +170,30 @@ const EcogestureList: React.FC<EcogestureListProps> = ({ )} </div> <div className="ecogesture-content"> - {list.length > 0 && activeFilter === Usage[Usage.ALL] ? ( - list.map((ecogesture, index) => ( - <EcogestureCard ecogesture={ecogesture} key={index} /> - )) - ) : list.length > 0 && activeFilter !== Usage[Usage.ALL] ? ( - filterEcogesture(list) - ) : !displaySelection ? ( - <div className="ec-filter-error"> - <div className="text-20-normal"> - {t('ecogesture.no_ecogesture_filter.text1')} - </div> - <div className="text-16-italic"> - {t('ecogesture.no_ecogesture_filter.text2')} - </div> - </div> - ) : ( - '' + {list.length > 0 && activeFilter === Usage[Usage.ALL] + ? list.map((ecogesture, index) => ( + <EcogestureCard + ecogesture={ecogesture} + key={index} + selectionCompleted={selectionViewed === selectionTotal} + /> + )) + : list.length > 0 && activeFilter !== Usage[Usage.ALL] + ? filterEcogesture(list) + : !displaySelection && ( + <div className="ec-filter-error"> + <div className="text-20-normal"> + {t('ecogesture.no_ecogesture_filter.text1')} + </div> + <div className="text-16-italic"> + {t('ecogesture.no_ecogesture_filter.text2')} + </div> + </div> + )} + {!displaySelection && index !== EcogestureStatus.ALL && ( + <button className="reinit-button" onClick={handleReinitClick}> + <span>{t('ecogesture.reinit')}</span> + </button> )} </div> </div> diff --git a/src/components/Ecogesture/EcogestureReinitModal.spec.tsx b/src/components/Ecogesture/EcogestureReinitModal.spec.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2cc0a86e1516b66cb9ee543a30271f818bc2e7b9 --- /dev/null +++ b/src/components/Ecogesture/EcogestureReinitModal.spec.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import { mount } from 'enzyme' +import toJson from 'enzyme-to-json' +import configureStore from 'redux-mock-store' +import { globalStateData } from '../../../tests/__mocks__/globalStateData.mock' +import { challengeStateData } from '../../../tests/__mocks__/challengeStateData.mock' +import { Provider } from 'react-redux' +import EcogestureReinitModal from './EcogestureReinitModal' + +jest.mock('cozy-ui/transpiled/react/I18n', () => { + return { + useI18n: jest.fn(() => { + return { + t: (str: string) => str, + } + }), + } +}) +const mockImportIconbyId = jest.fn() +jest.mock('utils/utils', () => { + return { + importIconbyId: jest.fn(() => { + return mockImportIconbyId + }), + } +}) + +const mockStore = configureStore([]) + +describe('EcogestureReinitModal component', () => { + it('should be rendered correctly', async () => { + const store = mockStore({ + ecolyo: { + global: globalStateData, + challenge: challengeStateData, + }, + }) + + const wrapper = mount( + <Provider store={store}> + <EcogestureReinitModal + open={true} + handleCloseClick={jest.fn()} + handleLaunchReinit={jest.fn()} + /> + </Provider> + ) + expect(toJson(wrapper)).toMatchSnapshot() + }) +}) diff --git a/src/components/Ecogesture/EcogestureReinitModal.tsx b/src/components/Ecogesture/EcogestureReinitModal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cb6325857acdc3db7bfc7e071ff3c0f75f155939 --- /dev/null +++ b/src/components/Ecogesture/EcogestureReinitModal.tsx @@ -0,0 +1,90 @@ +import React from 'react' +import Dialog from '@material-ui/core/Dialog' +import { Button, IconButton } from '@material-ui/core' +import Icon from 'cozy-ui/transpiled/react/Icon' +import { useI18n } from 'cozy-ui/transpiled/react/I18n' +import CloseIcon from 'assets/icons/ico/close.svg' +import './ecogestureReinitModal.scss' +import warningIcon from 'assets/icons/ico/warn-orange.svg' +interface EcogestureReinitModalProps { + open: boolean + handleCloseClick: () => void + handleLaunchReinit: () => void +} +const EcogestureReinitModal: React.FC<EcogestureReinitModalProps> = ({ + open, + handleCloseClick, + handleLaunchReinit, +}: EcogestureReinitModalProps) => { + const { t } = useI18n() + return ( + <Dialog + open={open} + onClose={handleCloseClick} + aria-labelledby={'accessibility-title'} + classes={{ + root: 'modal-root', + paper: 'modal-paper', + }} + > + <div id={'accessibility-title'}> + {t('feedback.accessibility.window_title')} + </div> + <IconButton + aria-label={t('feedback.accessibility.button_close')} + className="modal-paper-close-button" + onClick={handleCloseClick} + > + <Icon icon={CloseIcon} size={16} /> + </IconButton> + <div className="eg-reinit-modal"> + <Icon icon={warningIcon} size={63} /> + <div className="title text-20-bold"> + {t('ecogesture.reinitModal.title_part1')} + <span className="warn-title"> + {t('ecogesture.reinitModal.title_part2')} + </span> + {t('ecogesture.reinitModal.title_part3')} + <span className="warn-title"> + {t('ecogesture.reinitModal.title_part4')} + </span> + {t('ecogesture.reinitModal.title_part5')} + <span className="warn-title"> + {t('ecogesture.reinitModal.title_part6')} + </span> + </div> + <div className="text-16-normal text"> + {t('ecogesture.reinitModal.text1')} + </div> + <div className="text-16-bold text"> + {t('ecogesture.reinitModal.text2')} + </div> + <div className="buttons-container"> + <Button + aria-label={t('ecogesture.reinitModal.btn1')} + onClick={handleCloseClick} + className="btn1" + classes={{ + root: 'btn-secondary-negative', + label: 'text-16-bold', + }} + > + {t('ecogesture.reinitModal.btn1')} + </Button> + <Button + aria-label={t('ecogesture.reinitModal.btn2')} + onClick={handleLaunchReinit} + classes={{ + root: 'btn-profile-next rounded', + label: 'text-16-bold', + }} + > + {t('ecogesture.reinitModal.btn2')} + </Button> + </div> + </div> + </Dialog> + ) +} + +export default EcogestureReinitModal diff --git a/src/components/Ecogesture/EcogestureView.tsx b/src/components/Ecogesture/EcogestureView.tsx index 3a4110cca29bb1bcf55966cfeb2968e9cf2150df..afd4096cc011e072107f3918ecff3dfc69cf08e2 100644 --- a/src/components/Ecogesture/EcogestureView.tsx +++ b/src/components/Ecogesture/EcogestureView.tsx @@ -18,6 +18,7 @@ import { FluidType } from 'enum/fluid.enum' import EcogestureEmptyList from './EcogestureEmptyList' import { EcogestureStatus } from 'enum/ecogesture.enum' import EcogestureInitModal from './EcogestureInitModal' +import EcogestureReinitModal from './EcogestureReinitModal' import { updateProfile } from 'store/profile/profile.actions' import { useHistory, useLocation } from 'react-router-dom' import { ProfileEcogesture } from 'models/profileEcogesture.model' @@ -79,6 +80,13 @@ const EcogestureView: React.FC = () => { const [openEcogestureInitModal, setOpenEcogestureInitModal] = useState< boolean >(!haveSeenEcogestureModal) + const [openEcogestureReinitModal, setOpenEcogestureReinitModal] = useState< + boolean + >(false) + + const handleReinitClick = useCallback(() => { + setOpenEcogestureReinitModal(true) + }, []) const handleLaunchForm = useCallback(async () => { dispatch(updateProfile({ haveSeenEcogestureModal: true })) @@ -91,6 +99,22 @@ const EcogestureView: React.FC = () => { setOpenEcogestureInitModal(false) }, [dispatch]) + const handleLaunchReinit = useCallback(async () => { + setOpenEcogestureReinitModal(false) + setIsLoaded(false) + const ecogestureService = new EcogestureService(client) + const reset = await ecogestureService.reinitAllEcogestures() + if (reset) { + setOpenEcogestureReinitModal(false) + setIsLoaded(true) + history.push('/ecogesture-form?modal=true') + } + }, [client, history]) + + const handleCloseEcogestureReinitModal = useCallback(() => { + setOpenEcogestureReinitModal(false) + }, []) + const handleChange = useCallback( (event: React.ChangeEvent<{}>, newValue: any) => { event.preventDefault() @@ -197,6 +221,7 @@ const EcogestureView: React.FC = () => { })} {...tabProps(EcogestureStatus.DOING)} ></Tab> + <Tab label={getLabel(EcogestureStatus.ALL)} className={classNames('single-tab', { @@ -215,6 +240,7 @@ const EcogestureView: React.FC = () => { setTab={setTabValue} isObjective={true} isSelectionDone={true} + handleReinitClick={handleReinitClick} /> ) : ( <EcogestureList @@ -222,6 +248,8 @@ const EcogestureView: React.FC = () => { displaySelection={totalAvailable !== totalViewed} selectionTotal={totalAvailable} selectionViewed={totalViewed} + index={EcogestureStatus.OBJECTIVE} + handleReinitClick={handleReinitClick} /> ) ) : ( @@ -229,6 +257,7 @@ const EcogestureView: React.FC = () => { setTab={setTabValue} isObjective={true} isSelectionDone={false} + handleReinitClick={handleReinitClick} /> )} </TabPanel> @@ -241,6 +270,7 @@ const EcogestureView: React.FC = () => { setTab={setTabValue} isObjective={false} isSelectionDone={true} + handleReinitClick={handleReinitClick} /> ) : ( <EcogestureList @@ -248,6 +278,8 @@ const EcogestureView: React.FC = () => { displaySelection={totalAvailable !== totalViewed} selectionTotal={totalAvailable} selectionViewed={totalViewed} + index={EcogestureStatus.DOING} + handleReinitClick={handleReinitClick} /> ) ) : ( @@ -255,9 +287,11 @@ const EcogestureView: React.FC = () => { setTab={setTabValue} isObjective={false} isSelectionDone={false} + handleReinitClick={handleReinitClick} /> )} </TabPanel> + <TabPanel value={tabValue} index={EcogestureStatus.ALL}> {allEcogestureList.length && ( <EcogestureList @@ -265,6 +299,8 @@ const EcogestureView: React.FC = () => { displaySelection={false} selectionTotal={totalAvailable} selectionViewed={totalViewed} + index={EcogestureStatus.ALL} + handleReinitClick={handleReinitClick} /> )} </TabPanel> @@ -278,6 +314,13 @@ const EcogestureView: React.FC = () => { handleLaunchForm={handleLaunchForm} /> )} + {openEcogestureReinitModal && ( + <EcogestureReinitModal + open={openEcogestureReinitModal} + handleCloseClick={handleCloseEcogestureReinitModal} + handleLaunchReinit={handleLaunchReinit} + /> + )} </> ) } diff --git a/src/components/Ecogesture/SingleEcogesture.spec.tsx b/src/components/Ecogesture/SingleEcogesture.spec.tsx index 8f45017fcaf5eb431b6a1d88e135d84c4bdc2df0..ae4e3360ee6982f4c34bbc59f26ad5c20eebfa3a 100644 --- a/src/components/Ecogesture/SingleEcogesture.spec.tsx +++ b/src/components/Ecogesture/SingleEcogesture.spec.tsx @@ -52,6 +52,12 @@ jest.mock('services/ecogesture.service', () => { const mockStore = configureStore([]) +jest.mock('react-router-dom', () => ({ + useLocation: jest.fn().mockReturnValue({ + state: { selectionCompleted: true }, + }), +})) + describe('SingleEcogesture component', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/components/Ecogesture/SingleEcogesture.tsx b/src/components/Ecogesture/SingleEcogesture.tsx index 96154c6c9c667603003ebb574e2bd079f663b76e..5694040186f35cc094a56adf5b7e7620272d51ed 100644 --- a/src/components/Ecogesture/SingleEcogesture.tsx +++ b/src/components/Ecogesture/SingleEcogesture.tsx @@ -24,6 +24,8 @@ import { useClient } from 'cozy-client' import ErrorPage from 'components/CommonKit/ErrorPage/ErrorPage' import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner' import { FluidType } from 'enum/fluid.enum' +import { useLocation } from 'react-router-dom' +import { Location } from 'history' interface SingleEcogestureProps { match: { params: { id: string } } @@ -34,6 +36,7 @@ const SingleEcogesture: React.FC<SingleEcogestureProps> = ({ }: SingleEcogestureProps) => { const { t } = useI18n() const client = useClient() + const location: Location<any> = useLocation<any>() const [ecogesture, setEcogesture] = useState<Ecogesture>() const [ecogestureIcon, setEcogestureIcon] = useState<string>('') const [isMoreDetail, setIsMoreDetail] = useState<boolean>(false) @@ -41,6 +44,7 @@ const SingleEcogesture: React.FC<SingleEcogestureProps> = ({ const [isObjective, setIsObjective] = useState<boolean>(false) const [isLoading, setIsLoading] = useState<boolean>(true) const ecogestureID: string = match.params.id + const selectionCompleted = location.state.selectionCompleted const ecogestureService = useMemo(() => new EcogestureService(client), [ client, @@ -132,6 +136,7 @@ const SingleEcogesture: React.FC<SingleEcogestureProps> = ({ </Content> ) } + return ecogesture ? ( <> <CozyBar @@ -182,41 +187,44 @@ const SingleEcogesture: React.FC<SingleEcogestureProps> = ({ : t('ecogesture_modal.show_more')} </div> </div> - <div className="buttons-selection"> - <IconButton - aria-label={t('ecogesture.objective')} - onClick={toggleObjective} - classes={{ - root: `btn-secondary-negative objective-btn ${isObjective && - 'active'}`, - label: 'text-15-normal', - }} - > - <Icon - className="status-icon" - icon={ - isObjective ? objectiveEnabledIcon : objectiveDisabledIcon - } - size={40} - /> - <span>{t('ecogesture.objective')}</span> - </IconButton> - <IconButton - aria-label={t('ecogesture.doing')} - onClick={toggleDoing} - classes={{ - root: `btn-secondary-negative doing-btn ${isDoing && 'active'}`, - label: 'text-15-normal', - }} - > - <Icon - className="status-icon" - icon={isDoing ? doingEnabledIcon : doingDisabledIcon} - size={40} - /> - <span>{t('ecogesture.doing')}</span> - </IconButton> - </div> + {selectionCompleted && ( + <div className="buttons-selection"> + <IconButton + aria-label={t('ecogesture.objective')} + onClick={toggleObjective} + classes={{ + root: `btn-secondary-negative objective-btn ${isObjective && + 'active'}`, + label: 'text-15-normal', + }} + > + <Icon + className="status-icon" + icon={ + isObjective ? objectiveEnabledIcon : objectiveDisabledIcon + } + size={40} + /> + <span>{t('ecogesture.objective')}</span> + </IconButton> + <IconButton + aria-label={t('ecogesture.doing')} + onClick={toggleDoing} + classes={{ + root: `btn-secondary-negative doing-btn ${isDoing && + 'active'}`, + label: 'text-15-normal', + }} + > + <Icon + className="status-icon" + icon={isDoing ? doingEnabledIcon : doingDisabledIcon} + size={40} + /> + <span>{t('ecogesture.doing')}</span> + </IconButton> + </div> + )} </div> </Content> </> diff --git a/src/components/Ecogesture/__snapshots__/EcogestureCard.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureCard.spec.tsx.snap index f919091582e7d742b443f548059551526e767bcb..5101707fde8e729be87ba46df5f4ed6d8eb7abf9 100644 --- a/src/components/Ecogesture/__snapshots__/EcogestureCard.spec.tsx.snap +++ b/src/components/Ecogesture/__snapshots__/EcogestureCard.spec.tsx.snap @@ -87,7 +87,14 @@ exports[`EcogestureCard component should be rendered correctly 1`] = ` "render": [Function], } } - to="/ecogesture/ECOGESTURE001" + to={ + Object { + "pathname": "/ecogesture/ECOGESTURE001", + "state": Object { + "selectionCompleted": undefined, + }, + } + } > <ForwardRef(Link) className="ecogesture-list-item" @@ -115,7 +122,14 @@ exports[`EcogestureCard component should be rendered correctly 1`] = ` "render": [Function], } } - to="/ecogesture/ECOGESTURE001" + to={ + Object { + "pathname": "/ecogesture/ECOGESTURE001", + "state": Object { + "selectionCompleted": undefined, + }, + } + } > <WithStyles(ForwardRef(Typography)) className="MuiLink-root MuiLink-underlineHover ecogesture-list-item" @@ -136,7 +150,14 @@ exports[`EcogestureCard component should be rendered correctly 1`] = ` } onBlur={[Function]} onFocus={[Function]} - to="/ecogesture/ECOGESTURE001" + to={ + Object { + "pathname": "/ecogesture/ECOGESTURE001", + "state": Object { + "selectionCompleted": undefined, + }, + } + } variant="inherit" > <ForwardRef(Typography) @@ -192,14 +213,28 @@ exports[`EcogestureCard component should be rendered correctly 1`] = ` } onBlur={[Function]} onFocus={[Function]} - to="/ecogesture/ECOGESTURE001" + to={ + Object { + "pathname": "/ecogesture/ECOGESTURE001", + "state": Object { + "selectionCompleted": undefined, + }, + } + } variant="inherit" > <Link className="MuiTypography-root MuiLink-root MuiLink-underlineHover ecogesture-list-item MuiTypography-colorPrimary" onBlur={[Function]} onFocus={[Function]} - to="/ecogesture/ECOGESTURE001" + to={ + Object { + "pathname": "/ecogesture/ECOGESTURE001", + "state": Object { + "selectionCompleted": undefined, + }, + } + } > <LinkAnchor className="MuiTypography-root MuiLink-root MuiLink-underlineHover ecogesture-list-item MuiTypography-colorPrimary" diff --git a/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap index 5ecf8327ab3872c13aa3cbb97aa041c35957cb8b..2b952c562e3f62fd514c329cf197985559249d2c 100644 --- a/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap +++ b/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap @@ -1871,6 +1871,7 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` } } key="0" + selectionCompleted={true} /> <mock-ecogesturecard ecogesture={ @@ -1908,6 +1909,7 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` } } key="1" + selectionCompleted={true} /> <mock-ecogesturecard ecogesture={ @@ -1948,7 +1950,15 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` } } key="2" + selectionCompleted={true} /> + <button + className="reinit-button" + > + <span> + ecogesture.reinit + </span> + </button> </div> </div> </EcogestureList> diff --git a/src/components/Ecogesture/__snapshots__/EcogestureReinitModal.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureReinitModal.spec.tsx.snap new file mode 100644 index 0000000000000000000000000000000000000000..49f0e57d37977177e6f46d84c0f160ae16bbab66 --- /dev/null +++ b/src/components/Ecogesture/__snapshots__/EcogestureReinitModal.spec.tsx.snap @@ -0,0 +1,1211 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EcogestureReinitModal component should be rendered correctly 1`] = ` +<Provider + store={ + Object { + "clearActions": [Function], + "dispatch": [Function], + "getActions": [Function], + "getState": [Function], + "replaceReducer": [Function], + "subscribe": [Function], + } + } +> + <EcogestureReinitModal + handleCloseClick={[MockFunction]} + handleLaunchReinit={[MockFunction]} + open={true} + > + <WithStyles(ForwardRef(Dialog)) + aria-labelledby="accessibility-title" + classes={ + Object { + "paper": "modal-paper", + "root": "modal-root", + } + } + onClose={[MockFunction]} + open={true} + > + <ForwardRef(Dialog) + aria-labelledby="accessibility-title" + classes={ + Object { + "container": "MuiDialog-container", + "paper": "MuiDialog-paper modal-paper", + "paperFullScreen": "MuiDialog-paperFullScreen", + "paperFullWidth": "MuiDialog-paperFullWidth", + "paperScrollBody": "MuiDialog-paperScrollBody", + "paperScrollPaper": "MuiDialog-paperScrollPaper", + "paperWidthFalse": "MuiDialog-paperWidthFalse", + "paperWidthLg": "MuiDialog-paperWidthLg", + "paperWidthMd": "MuiDialog-paperWidthMd", + "paperWidthSm": "MuiDialog-paperWidthSm", + "paperWidthXl": "MuiDialog-paperWidthXl", + "paperWidthXs": "MuiDialog-paperWidthXs", + "root": "MuiDialog-root modal-root", + "scrollBody": "MuiDialog-scrollBody", + "scrollPaper": "MuiDialog-scrollPaper", + } + } + onClose={[MockFunction]} + open={true} + > + <ForwardRef(Modal) + BackdropComponent={ + Object { + "$$typeof": Symbol(react.forward_ref), + "Naked": Object { + "$$typeof": Symbol(react.forward_ref), + "propTypes": Object { + "children": [Function], + "className": [Function], + "classes": [Function], + "invisible": [Function], + "open": [Function], + "transitionDuration": [Function], + }, + "render": [Function], + }, + "displayName": "WithStyles(ForwardRef(Backdrop))", + "options": Object { + "defaultTheme": Object { + "breakpoints": Object { + "between": [Function], + "down": [Function], + "keys": Array [ + "xs", + "sm", + "md", + "lg", + "xl", + ], + "only": [Function], + "up": [Function], + "values": Object { + "lg": 1280, + "md": 960, + "sm": 600, + "xl": 1920, + "xs": 0, + }, + "width": [Function], + }, + "direction": "ltr", + "mixins": Object { + "gutters": [Function], + "toolbar": Object { + "@media (min-width:0px) and (orientation: landscape)": Object { + "minHeight": 48, + }, + "@media (min-width:600px)": Object { + "minHeight": 64, + }, + "minHeight": 56, + }, + }, + "overrides": Object {}, + "palette": Object { + "action": Object { + "active": "rgba(0, 0, 0, 0.54)", + "disabled": "rgba(0, 0, 0, 0.26)", + "disabledBackground": "rgba(0, 0, 0, 0.12)", + "hover": "rgba(0, 0, 0, 0.08)", + "hoverOpacity": 0.08, + "selected": "rgba(0, 0, 0, 0.14)", + }, + "augmentColor": [Function], + "background": Object { + "default": "#fafafa", + "paper": "#fff", + }, + "common": Object { + "black": "#000", + "white": "#fff", + }, + "contrastThreshold": 3, + "divider": "rgba(0, 0, 0, 0.12)", + "error": Object { + "contrastText": "#fff", + "dark": "#d32f2f", + "light": "#e57373", + "main": "#f44336", + }, + "getContrastText": [Function], + "grey": Object { + "100": "#f5f5f5", + "200": "#eeeeee", + "300": "#e0e0e0", + "400": "#bdbdbd", + "50": "#fafafa", + "500": "#9e9e9e", + "600": "#757575", + "700": "#616161", + "800": "#424242", + "900": "#212121", + "A100": "#d5d5d5", + "A200": "#aaaaaa", + "A400": "#303030", + "A700": "#616161", + }, + "info": Object { + "contrastText": "#fff", + "dark": "#1976d2", + "light": "#64b5f6", + "main": "#2196f3", + }, + "primary": Object { + "contrastText": "#fff", + "dark": "#303f9f", + "light": "#7986cb", + "main": "#3f51b5", + }, + "secondary": Object { + "contrastText": "#fff", + "dark": "#c51162", + "light": "#ff4081", + "main": "#f50057", + }, + "success": Object { + "contrastText": "rgba(0, 0, 0, 0.87)", + "dark": "#388e3c", + "light": "#81c784", + "main": "#4caf50", + }, + "text": Object { + "disabled": "rgba(0, 0, 0, 0.38)", + "hint": "rgba(0, 0, 0, 0.38)", + "primary": "rgba(0, 0, 0, 0.87)", + "secondary": "rgba(0, 0, 0, 0.54)", + }, + "tonalOffset": 0.2, + "type": "light", + "warning": Object { + "contrastText": "rgba(0, 0, 0, 0.87)", + "dark": "#f57c00", + "light": "#ffb74d", + "main": "#ff9800", + }, + }, + "props": Object {}, + "shadows": Array [ + "none", + "0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)", + "0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)", + "0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)", + "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)", + "0px 3px 5px -1px rgba(0,0,0,0.2),0px 5px 8px 0px rgba(0,0,0,0.14),0px 1px 14px 0px rgba(0,0,0,0.12)", + "0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)", + "0px 4px 5px -2px rgba(0,0,0,0.2),0px 7px 10px 1px rgba(0,0,0,0.14),0px 2px 16px 1px rgba(0,0,0,0.12)", + "0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)", + "0px 5px 6px -3px rgba(0,0,0,0.2),0px 9px 12px 1px rgba(0,0,0,0.14),0px 3px 16px 2px rgba(0,0,0,0.12)", + "0px 6px 6px -3px rgba(0,0,0,0.2),0px 10px 14px 1px rgba(0,0,0,0.14),0px 4px 18px 3px rgba(0,0,0,0.12)", + "0px 6px 7px -4px rgba(0,0,0,0.2),0px 11px 15px 1px rgba(0,0,0,0.14),0px 4px 20px 3px rgba(0,0,0,0.12)", + "0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)", + "0px 7px 8px -4px rgba(0,0,0,0.2),0px 13px 19px 2px rgba(0,0,0,0.14),0px 5px 24px 4px rgba(0,0,0,0.12)", + "0px 7px 9px -4px rgba(0,0,0,0.2),0px 14px 21px 2px rgba(0,0,0,0.14),0px 5px 26px 4px rgba(0,0,0,0.12)", + "0px 8px 9px -5px rgba(0,0,0,0.2),0px 15px 22px 2px rgba(0,0,0,0.14),0px 6px 28px 5px rgba(0,0,0,0.12)", + "0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)", + "0px 8px 11px -5px rgba(0,0,0,0.2),0px 17px 26px 2px rgba(0,0,0,0.14),0px 6px 32px 5px rgba(0,0,0,0.12)", + "0px 9px 11px -5px rgba(0,0,0,0.2),0px 18px 28px 2px rgba(0,0,0,0.14),0px 7px 34px 6px rgba(0,0,0,0.12)", + "0px 9px 12px -6px rgba(0,0,0,0.2),0px 19px 29px 2px rgba(0,0,0,0.14),0px 7px 36px 6px rgba(0,0,0,0.12)", + "0px 10px 13px -6px rgba(0,0,0,0.2),0px 20px 31px 3px rgba(0,0,0,0.14),0px 8px 38px 7px rgba(0,0,0,0.12)", + "0px 10px 13px -6px rgba(0,0,0,0.2),0px 21px 33px 3px rgba(0,0,0,0.14),0px 8px 40px 7px rgba(0,0,0,0.12)", + "0px 10px 14px -6px rgba(0,0,0,0.2),0px 22px 35px 3px rgba(0,0,0,0.14),0px 8px 42px 7px rgba(0,0,0,0.12)", + "0px 11px 14px -7px rgba(0,0,0,0.2),0px 23px 36px 3px rgba(0,0,0,0.14),0px 9px 44px 8px rgba(0,0,0,0.12)", + "0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12)", + ], + "shape": Object { + "borderRadius": 4, + }, + "spacing": [Function], + "transitions": Object { + "create": [Function], + "duration": Object { + "complex": 375, + "enteringScreen": 225, + "leavingScreen": 195, + "short": 250, + "shorter": 200, + "shortest": 150, + "standard": 300, + }, + "easing": Object { + "easeIn": "cubic-bezier(0.4, 0, 1, 1)", + "easeInOut": "cubic-bezier(0.4, 0, 0.2, 1)", + "easeOut": "cubic-bezier(0.0, 0, 0.2, 1)", + "sharp": "cubic-bezier(0.4, 0, 0.6, 1)", + }, + "getAutoHeightDuration": [Function], + }, + "typography": Object { + "body1": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1rem", + "fontWeight": 400, + "letterSpacing": "0.00938em", + "lineHeight": 1.5, + }, + "body2": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.875rem", + "fontWeight": 400, + "letterSpacing": "0.01071em", + "lineHeight": 1.43, + }, + "button": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.875rem", + "fontWeight": 500, + "letterSpacing": "0.02857em", + "lineHeight": 1.75, + "textTransform": "uppercase", + }, + "caption": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.75rem", + "fontWeight": 400, + "letterSpacing": "0.03333em", + "lineHeight": 1.66, + }, + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": 14, + "fontWeightBold": 700, + "fontWeightLight": 300, + "fontWeightMedium": 500, + "fontWeightRegular": 400, + "h1": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "6rem", + "fontWeight": 300, + "letterSpacing": "-0.01562em", + "lineHeight": 1.167, + }, + "h2": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "3.75rem", + "fontWeight": 300, + "letterSpacing": "-0.00833em", + "lineHeight": 1.2, + }, + "h3": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "3rem", + "fontWeight": 400, + "letterSpacing": "0em", + "lineHeight": 1.167, + }, + "h4": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "2.125rem", + "fontWeight": 400, + "letterSpacing": "0.00735em", + "lineHeight": 1.235, + }, + "h5": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1.5rem", + "fontWeight": 400, + "letterSpacing": "0em", + "lineHeight": 1.334, + }, + "h6": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1.25rem", + "fontWeight": 500, + "letterSpacing": "0.0075em", + "lineHeight": 1.6, + }, + "htmlFontSize": 16, + "overline": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.75rem", + "fontWeight": 400, + "letterSpacing": "0.08333em", + "lineHeight": 2.66, + "textTransform": "uppercase", + }, + "pxToRem": [Function], + "round": [Function], + "subtitle1": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1rem", + "fontWeight": 400, + "letterSpacing": "0.00938em", + "lineHeight": 1.75, + }, + "subtitle2": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.875rem", + "fontWeight": 500, + "letterSpacing": "0.00714em", + "lineHeight": 1.57, + }, + }, + "zIndex": Object { + "appBar": 1100, + "drawer": 1200, + "mobileStepper": 1000, + "modal": 1300, + "snackbar": 1400, + "speedDial": 1050, + "tooltip": 1500, + }, + }, + "name": "MuiBackdrop", + }, + "propTypes": Object { + "classes": [Function], + "innerRef": [Function], + }, + "render": [Function], + "useStyles": [Function], + } + } + BackdropProps={ + Object { + "transitionDuration": Object { + "enter": 225, + "exit": 195, + }, + } + } + className="MuiDialog-root modal-root" + closeAfterTransition={true} + disableBackdropClick={false} + disableEscapeKeyDown={false} + onClose={[MockFunction]} + open={true} + > + <ForwardRef(Portal) + disablePortal={false} + > + <Portal + containerInfo={ + <body + style="padding-right: 0px; overflow: hidden;" + > + <div + class="MuiDialog-root modal-root" + role="presentation" + style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;" + > + <div + aria-hidden="true" + class="MuiBackdrop-root" + style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;" + /> + <div + data-test="sentinelStart" + tabindex="0" + /> + <div + class="MuiDialog-container MuiDialog-scrollPaper" + role="none presentation" + style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;" + tabindex="-1" + > + <div + aria-labelledby="accessibility-title" + class="MuiPaper-root MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm MuiPaper-elevation24 MuiPaper-rounded" + role="dialog" + > + <div + id="accessibility-title" + > + feedback.accessibility.window_title + </div> + <button + aria-label="feedback.accessibility.button_close" + class="MuiButtonBase-root MuiIconButton-root modal-paper-close-button" + tabindex="0" + type="button" + > + <span + class="MuiIconButton-label" + > + <svg + class="styles__icon___23x3R" + height="16" + width="16" + > + <use + xlink:href="#test-file-stub" + /> + </svg> + </span> + <span + class="MuiTouchRipple-root" + /> + </button> + <div + class="eg-reinit-modal" + > + <svg + class="styles__icon___23x3R" + height="63" + width="63" + > + <use + xlink:href="#test-file-stub" + /> + </svg> + <div + class="title text-20-bold" + > + ecogesture.reinitModal.title_part1 + <span + class="warn-title" + > + ecogesture.reinitModal.title_part2 + </span> + ecogesture.reinitModal.title_part3 + <span + class="warn-title" + > + ecogesture.reinitModal.title_part4 + </span> + ecogesture.reinitModal.title_part5 + <span + class="warn-title" + > + ecogesture.reinitModal.title_part6 + </span> + </div> + <div + class="text-16-normal text" + > + ecogesture.reinitModal.text1 + </div> + <div + class="text-16-bold text" + > + ecogesture.reinitModal.text2 + </div> + <div + class="buttons-container" + > + <button + aria-label="ecogesture.reinitModal.btn1" + class="MuiButtonBase-root MuiButton-root btn-secondary-negative MuiButton-text btn1" + tabindex="0" + type="button" + > + <span + class="MuiButton-label text-16-bold" + > + ecogesture.reinitModal.btn1 + </span> + <span + class="MuiTouchRipple-root" + /> + </button> + <button + aria-label="ecogesture.reinitModal.btn2" + class="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text" + tabindex="0" + type="button" + > + <span + class="MuiButton-label text-16-bold" + > + ecogesture.reinitModal.btn2 + </span> + <span + class="MuiTouchRipple-root" + /> + </button> + </div> + </div> + </div> + </div> + <div + data-test="sentinelEnd" + tabindex="0" + /> + </div> + </body> + } + > + <div + className="MuiDialog-root modal-root" + onKeyDown={[Function]} + role="presentation" + style={ + Object { + "bottom": 0, + "left": 0, + "position": "fixed", + "right": 0, + "top": 0, + "zIndex": 1300, + } + } + > + <WithStyles(ForwardRef(Backdrop)) + onClick={[Function]} + open={true} + transitionDuration={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <ForwardRef(Backdrop) + classes={ + Object { + "invisible": "MuiBackdrop-invisible", + "root": "MuiBackdrop-root", + } + } + onClick={[Function]} + open={true} + transitionDuration={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <ForwardRef(Fade) + in={true} + onClick={[Function]} + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <Transition + appear={true} + enter={true} + exit={true} + in={true} + mountOnEnter={false} + onClick={[Function]} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + unmountOnExit={false} + > + <div + aria-hidden={true} + className="MuiBackdrop-root" + onClick={[Function]} + style={ + Object { + "opacity": 1, + "visibility": undefined, + } + } + /> + </Transition> + </ForwardRef(Fade)> + </ForwardRef(Backdrop)> + </WithStyles(ForwardRef(Backdrop))> + <TrapFocus + disableAutoFocus={false} + disableEnforceFocus={false} + disableRestoreFocus={false} + getDoc={[Function]} + isEnabled={[Function]} + open={true} + > + <div + data-test="sentinelStart" + tabIndex={0} + /> + <ForwardRef(Fade) + appear={true} + in={true} + onEnter={[Function]} + onExited={[Function]} + role="none presentation" + tabIndex="-1" + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <Transition + appear={true} + enter={true} + exit={true} + in={true} + mountOnEnter={false} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + role="none presentation" + tabIndex="-1" + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + unmountOnExit={false} + > + <div + className="MuiDialog-container MuiDialog-scrollPaper" + onClick={[Function]} + onMouseDown={[Function]} + role="none presentation" + style={ + Object { + "opacity": 1, + "visibility": undefined, + } + } + tabIndex="-1" + > + <WithStyles(ForwardRef(Paper)) + aria-labelledby="accessibility-title" + className="MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm" + elevation={24} + role="dialog" + > + <ForwardRef(Paper) + aria-labelledby="accessibility-title" + className="MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm" + classes={ + Object { + "elevation0": "MuiPaper-elevation0", + "elevation1": "MuiPaper-elevation1", + "elevation10": "MuiPaper-elevation10", + "elevation11": "MuiPaper-elevation11", + "elevation12": "MuiPaper-elevation12", + "elevation13": "MuiPaper-elevation13", + "elevation14": "MuiPaper-elevation14", + "elevation15": "MuiPaper-elevation15", + "elevation16": "MuiPaper-elevation16", + "elevation17": "MuiPaper-elevation17", + "elevation18": "MuiPaper-elevation18", + "elevation19": "MuiPaper-elevation19", + "elevation2": "MuiPaper-elevation2", + "elevation20": "MuiPaper-elevation20", + "elevation21": "MuiPaper-elevation21", + "elevation22": "MuiPaper-elevation22", + "elevation23": "MuiPaper-elevation23", + "elevation24": "MuiPaper-elevation24", + "elevation3": "MuiPaper-elevation3", + "elevation4": "MuiPaper-elevation4", + "elevation5": "MuiPaper-elevation5", + "elevation6": "MuiPaper-elevation6", + "elevation7": "MuiPaper-elevation7", + "elevation8": "MuiPaper-elevation8", + "elevation9": "MuiPaper-elevation9", + "outlined": "MuiPaper-outlined", + "root": "MuiPaper-root", + "rounded": "MuiPaper-rounded", + } + } + elevation={24} + role="dialog" + > + <div + aria-labelledby="accessibility-title" + className="MuiPaper-root MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm MuiPaper-elevation24 MuiPaper-rounded" + role="dialog" + > + <div + id="accessibility-title" + > + feedback.accessibility.window_title + </div> + <WithStyles(ForwardRef(IconButton)) + aria-label="feedback.accessibility.button_close" + className="modal-paper-close-button" + onClick={[MockFunction]} + > + <ForwardRef(IconButton) + aria-label="feedback.accessibility.button_close" + className="modal-paper-close-button" + classes={ + Object { + "colorInherit": "MuiIconButton-colorInherit", + "colorPrimary": "MuiIconButton-colorPrimary", + "colorSecondary": "MuiIconButton-colorSecondary", + "disabled": "Mui-disabled", + "edgeEnd": "MuiIconButton-edgeEnd", + "edgeStart": "MuiIconButton-edgeStart", + "label": "MuiIconButton-label", + "root": "MuiIconButton-root", + "sizeSmall": "MuiIconButton-sizeSmall", + } + } + onClick={[MockFunction]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="feedback.accessibility.button_close" + centerRipple={true} + className="MuiIconButton-root modal-paper-close-button" + disabled={false} + focusRipple={true} + onClick={[MockFunction]} + > + <ForwardRef(ButtonBase) + aria-label="feedback.accessibility.button_close" + centerRipple={true} + className="MuiIconButton-root modal-paper-close-button" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + disabled={false} + focusRipple={true} + onClick={[MockFunction]} + > + <button + aria-label="feedback.accessibility.button_close" + className="MuiButtonBase-root MuiIconButton-root modal-paper-close-button" + disabled={false} + onBlur={[Function]} + onClick={[MockFunction]} + 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="MuiIconButton-label" + > + <Icon + icon="test-file-stub" + size={16} + spin={false} + > + <Component + className="styles__icon___23x3R" + height={16} + style={Object {}} + width={16} + > + <svg + className="styles__icon___23x3R" + height={16} + style={Object {}} + width={16} + > + <use + xlinkHref="#test-file-stub" + /> + </svg> + </Component> + </Icon> + </span> + <NoSsr> + <WithStyles(memo) + center={true} + > + <ForwardRef(TouchRipple) + center={true} + 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)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(IconButton)> + </WithStyles(ForwardRef(IconButton))> + <div + className="eg-reinit-modal" + > + <Icon + icon="test-file-stub" + size={63} + spin={false} + > + <Component + className="styles__icon___23x3R" + height={63} + style={Object {}} + width={63} + > + <svg + className="styles__icon___23x3R" + height={63} + style={Object {}} + width={63} + > + <use + xlinkHref="#test-file-stub" + /> + </svg> + </Component> + </Icon> + <div + className="title text-20-bold" + > + ecogesture.reinitModal.title_part1 + <span + className="warn-title" + > + ecogesture.reinitModal.title_part2 + </span> + ecogesture.reinitModal.title_part3 + <span + className="warn-title" + > + ecogesture.reinitModal.title_part4 + </span> + ecogesture.reinitModal.title_part5 + <span + className="warn-title" + > + ecogesture.reinitModal.title_part6 + </span> + </div> + <div + className="text-16-normal text" + > + ecogesture.reinitModal.text1 + </div> + <div + className="text-16-bold text" + > + ecogesture.reinitModal.text2 + </div> + <div + className="buttons-container" + > + <WithStyles(ForwardRef(Button)) + aria-label="ecogesture.reinitModal.btn1" + className="btn1" + classes={ + Object { + "label": "text-16-bold", + "root": "btn-secondary-negative", + } + } + onClick={[MockFunction]} + > + <ForwardRef(Button) + aria-label="ecogesture.reinitModal.btn1" + className="btn1" + 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-negative", + "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={[MockFunction]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="ecogesture.reinitModal.btn1" + className="MuiButton-root btn-secondary-negative MuiButton-text btn1" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[MockFunction]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="ecogesture.reinitModal.btn1" + className="MuiButton-root btn-secondary-negative MuiButton-text btn1" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[MockFunction]} + type="button" + > + <button + aria-label="ecogesture.reinitModal.btn1" + className="MuiButtonBase-root MuiButton-root btn-secondary-negative MuiButton-text btn1" + disabled={false} + onBlur={[Function]} + onClick={[MockFunction]} + 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" + > + ecogesture.reinitModal.btn1 + </span> + <NoSsr> + <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)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + <WithStyles(ForwardRef(Button)) + aria-label="ecogesture.reinitModal.btn2" + classes={ + Object { + "label": "text-16-bold", + "root": "btn-profile-next rounded", + } + } + onClick={[MockFunction]} + > + <ForwardRef(Button) + aria-label="ecogesture.reinitModal.btn2" + 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-profile-next rounded", + "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={[MockFunction]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="ecogesture.reinitModal.btn2" + className="MuiButton-root btn-profile-next rounded MuiButton-text" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[MockFunction]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="ecogesture.reinitModal.btn2" + className="MuiButton-root btn-profile-next rounded MuiButton-text" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[MockFunction]} + type="button" + > + <button + aria-label="ecogesture.reinitModal.btn2" + className="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text" + disabled={false} + onBlur={[Function]} + onClick={[MockFunction]} + 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" + > + ecogesture.reinitModal.btn2 + </span> + <NoSsr> + <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)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + </div> + </div> + </div> + </ForwardRef(Paper)> + </WithStyles(ForwardRef(Paper))> + </div> + </Transition> + </ForwardRef(Fade)> + <div + data-test="sentinelEnd" + tabIndex={0} + /> + </TrapFocus> + </div> + </Portal> + </ForwardRef(Portal)> + </ForwardRef(Modal)> + </ForwardRef(Dialog)> + </WithStyles(ForwardRef(Dialog))> + </EcogestureReinitModal> +</Provider> +`; diff --git a/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap index a438baf66a1755b3470bab2b62e3fb1b59f1502a..32c9365cd3446fe235df5db765ea157aaba4e915 100644 --- a/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap +++ b/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap @@ -565,6 +565,7 @@ exports[`EcogestureView component should be rendered correctly 1`] = ` role="tabpanel" > <EcogestureEmptyList + handleReinitClick={[Function]} isObjective={true} isSelectionDone={false} setTab={[Function]} @@ -904,6 +905,7 @@ exports[`EcogestureView component should be rendered correctly 1`] = ` role="tabpanel" > <EcogestureEmptyList + handleReinitClick={[Function]} isObjective={false} isSelectionDone={false} setTab={[Function]} @@ -1244,6 +1246,8 @@ exports[`EcogestureView component should be rendered correctly 1`] = ` > <mock-ecogesturelist displaySelection={false} + handleReinitClick={[Function]} + index={2} list={ Array [ Object { diff --git a/src/components/Ecogesture/ecogestureEmptyList.scss b/src/components/Ecogesture/ecogestureEmptyList.scss index 56ec9b82958fa9e5272625c59018612b5393ac4d..08a6ade8e032f81643da044b480f9e24a7b9eb96 100644 --- a/src/components/Ecogesture/ecogestureEmptyList.scss +++ b/src/components/Ecogesture/ecogestureEmptyList.scss @@ -25,5 +25,8 @@ margin-left: 1rem; } } + .reinit-button { + margin-left: 15px; + } } } diff --git a/src/components/Ecogesture/ecogestureList.scss b/src/components/Ecogesture/ecogestureList.scss index 07b207a0f9df5e8d05bf12e8f7f662c968718ec2..3be2e93b4dad901d3797f127bd67a66077e817ce 100644 --- a/src/components/Ecogesture/ecogestureList.scss +++ b/src/components/Ecogesture/ecogestureList.scss @@ -178,7 +178,7 @@ div.filter-menu { } } .filter-menu-list li { - color: white; + color: $white; text-transform: initial; font-family: $text-font; &.item-active { @@ -189,3 +189,17 @@ div.filter-menu { margin-left: auto; min-width: 0; } +.reinit-button { + background: transparent; + border: 1px solid $white-light; + border-radius: 2px; + margin: 20px 6px; + padding: 3px; + width: 100%; + cursor: pointer; + span { + color: $white; + display: inline-block; + max-width: 200px; + } +} diff --git a/src/components/Ecogesture/ecogestureReinitModal.scss b/src/components/Ecogesture/ecogestureReinitModal.scss new file mode 100644 index 0000000000000000000000000000000000000000..a73ec8a1c8f733a2f3253102806b6c692c012ab3 --- /dev/null +++ b/src/components/Ecogesture/ecogestureReinitModal.scss @@ -0,0 +1,28 @@ +@import '../../styles/base/color'; + +.eg-reinit-modal { + color: $grey-bright; + margin: 1rem 0; + text-align: center; + .title { + color: $white; + } + .warn-title { + color: $orange; + margin: 0 0.3rem; + } + .text { + margin: 1rem 0; + text-align: left; + } + .buttons-container { + display: flex; + button { + min-height: 45px; + cursor: pointer; + } + button.btn1 { + margin-right: 1rem; + } + } +} diff --git a/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx b/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx index b03d7b959c22cd28e74a599f9bde95b6dc2b29a9..536dcb3817aa92add426165d4cde497eb1c7d746 100644 --- a/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx +++ b/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx @@ -10,6 +10,7 @@ import { waitForComponentToPaint } from '../../../tests/__mocks__/testUtils' import EcogestureFormEquipment from './EcogestureFormEquipment' import { mockProfileEcogesture } from '../../../tests/__mocks__/profileEcogesture.mock' import { Button } from '@material-ui/core' +import { mockInitialEcolyoState } from '../../../tests/__mocks__/store' jest.mock('cozy-ui/transpiled/react/I18n', () => { return { @@ -22,6 +23,7 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => { }) const mockStore = configureStore([]) const mockSetPreviousStep = jest.fn() +const useSelectorSpy = jest.spyOn(reactRedux, 'useSelector') const mockHistoryPush = jest.fn() jest.mock('react-router-dom', () => ({ @@ -34,6 +36,10 @@ jest.mock('./EquipmentIcon', () => 'mock-equipment-icon') const mockUseDispatch = jest.spyOn(reactRedux, 'useDispatch') describe('EcogestureFormEquipment component', () => { + useSelectorSpy.mockReturnValue({ + ...mockInitialEcolyoState.profile, + }) + it('should be rendered correctly', async () => { const store = mockStore({ ecolyo: { @@ -46,6 +52,8 @@ describe('EcogestureFormEquipment component', () => { <EcogestureFormEquipment profileEcogesture={mockProfileEcogesture} setPreviousStep={mockSetPreviousStep} + setNextStep={jest.fn()} + step={0} /> </Provider> ) @@ -66,6 +74,8 @@ describe('EcogestureFormEquipment component', () => { <EcogestureFormEquipment profileEcogesture={mockProfileEcogesture} setPreviousStep={mockSetPreviousStep} + setNextStep={jest.fn()} + step={0} /> </Provider> ) @@ -89,6 +99,8 @@ describe('EcogestureFormEquipment component', () => { <EcogestureFormEquipment profileEcogesture={mockProfileEcogesture} setPreviousStep={mockSetPreviousStep} + setNextStep={jest.fn()} + step={0} /> </Provider> ) @@ -130,6 +142,8 @@ describe('EcogestureFormEquipment component', () => { <EcogestureFormEquipment profileEcogesture={mockProfileEcogesture} setPreviousStep={mockSetPreviousStep} + setNextStep={jest.fn()} + step={0} /> </Provider> ) diff --git a/src/components/EcogestureForm/EcogestureFormEquipment.tsx b/src/components/EcogestureForm/EcogestureFormEquipment.tsx index 3ea355582b3dacbaca1e3a91a4008a9ebfe97638..857f575a6383a374013fd4145c76611ee1317532 100644 --- a/src/components/EcogestureForm/EcogestureFormEquipment.tsx +++ b/src/components/EcogestureForm/EcogestureFormEquipment.tsx @@ -8,10 +8,11 @@ import { EquipmentType } from 'enum/ecogesture.enum' import EquipmentIcon from './EquipmentIcon' import './ecogestureFormEquipment.scss' import { newProfileEcogestureEntry } from 'store/profileEcogesture/profileEcogesture.actions' -import { useDispatch } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { updateProfile } from 'store/profile/profile.actions' import { useHistory } from 'react-router-dom' import { ProfileTypeStepForm } from 'enum/profileType.enum' +import { AppStore } from 'store' interface EcogestureFormEquipmentProps { profileEcogesture: ProfileEcogesture @@ -29,7 +30,12 @@ const EcogestureFormEquipment: React.FC<EcogestureFormEquipmentProps> = ({ const { t } = useI18n() const dispatch = useDispatch() const history = useHistory() - const [answer, setAnswer] = useState<string[]>([]) + const { isProfileEcogestureCompleted } = useSelector( + (state: AppStore) => state.ecolyo.profile + ) + const [answer, setAnswer] = useState<string[]>( + isProfileEcogestureCompleted ? profileEcogesture.equipments : [] + ) const handlePrevious = useCallback(() => { setPreviousStep(profileEcogesture) @@ -38,9 +44,13 @@ const EcogestureFormEquipment: React.FC<EcogestureFormEquipmentProps> = ({ const handleNext = useCallback(() => { profileEcogesture.equipments = answer as EquipmentType[] dispatch(newProfileEcogestureEntry(profileEcogesture)) - dispatch(updateProfile({ isProfileEcogestureCompleted: true })) // Check if gestureForm is used from Big profile or small profile - setNextStep ? setNextStep() : history.push('/ecogesture-selection') + if (setNextStep) { + setNextStep() + } else { + dispatch(updateProfile({ isProfileEcogestureCompleted: true })) + history.push('/ecogesture-selection') + } }, [profileEcogesture, setNextStep, answer, dispatch, history]) const isChecked = useCallback( diff --git a/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx b/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx index 790e0b4dbe99bd6bf5c6d7aa41d6d8ef96225bb1..7fa2f94474fc34ced9ad17b5605e9a120fe16f28 100644 --- a/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx +++ b/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx @@ -10,6 +10,8 @@ import { ProfileEcogestureAnswerChoices, } from 'models/profileEcogesture.model' import './ecogestureFormSingleChoice.scss' +import { useSelector } from 'react-redux' +import { AppStore } from 'store' interface EcogestureFormSingleChoiceProps { step: EcogestureStepForm viewedStep: EcogestureStepForm @@ -28,7 +30,12 @@ const EcogestureFormSingleChoice: React.FC<EcogestureFormSingleChoiceProps> = ({ setPrevioustStep, }: EcogestureFormSingleChoiceProps) => { const { t } = useI18n() - const [answer, setAnswer] = useState<ProfileEcogestureAnswerChoices>('') + const { isProfileEcogestureCompleted } = useSelector( + (state: AppStore) => state.ecolyo.profile + ) + const [answer, setAnswer] = useState<ProfileEcogestureAnswerChoices>( + isProfileEcogestureCompleted ? profileEcogesture[answerType.attribute] : '' + ) const handlePrevious = useCallback(() => { setPrevioustStep(profileEcogesture) diff --git a/src/components/EcogestureForm/EcogestureFormView.spec.tsx b/src/components/EcogestureForm/EcogestureFormView.spec.tsx index e3e0cbce3cc84773501f7aa58d87eb5de7631303..7dfa7f922b5d8feaaf630112efdb69031dce99f6 100644 --- a/src/components/EcogestureForm/EcogestureFormView.spec.tsx +++ b/src/components/EcogestureForm/EcogestureFormView.spec.tsx @@ -29,10 +29,6 @@ jest.mock( 'components/EcogestureForm/EcogestureLaunchFormModal', () => 'mock-ecogesturelaunchmodal' ) -jest.mock( - 'components/EcogestureForm/EcogestureFormEquipment', - () => 'mock-ecogestureformequipment' -) jest.mock('components/Content/Content', () => 'mock-content') jest.mock('react-router-dom', () => ({ @@ -68,7 +64,7 @@ describe('EcogestureFormView component', () => { await waitForComponentToPaint(wrapper) expect(wrapper.find('.ecogesture-form-single').exists()).toBeTruthy() }) - it('should render equipment step because profiletype is completed', async () => { + it('should render profiletype form step because profiletype is completed', async () => { const updatedProfile: Profile = { ...mockInitialEcolyoState.profile, isProfileTypeCompleted: true, @@ -80,12 +76,7 @@ describe('EcogestureFormView component', () => { </Provider> ) await waitForComponentToPaint(wrapper) - expect( - wrapper - .find('mock-ecogestureformequipment') - .first() - .exists() - ).toBeTruthy() + expect(wrapper.find('.profile-type-container').exists()).toBeTruthy() }) it('should go to next step', async () => { const wrapper = mount( diff --git a/src/components/EcogestureForm/EcogestureFormView.tsx b/src/components/EcogestureForm/EcogestureFormView.tsx index 54cdbd650e90e04294329ba50ec952255492f632..18812975d292be79358555e9dd838169b6e434ae 100644 --- a/src/components/EcogestureForm/EcogestureFormView.tsx +++ b/src/components/EcogestureForm/EcogestureFormView.tsx @@ -15,14 +15,16 @@ import { ProfileEcogesture, ProfileEcogestureAnswer, } from 'models/profileEcogesture.model' -import { Profile, ProfileType } from 'models' +import { Profile } from 'models' import ProfileEcogestureFormService from 'services/profileEcogestureForm.service' import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner' import { FluidType } from 'enum/fluid.enum' import './ecogestureFormView.scss' -import { useLocation } from 'react-router-dom' +import { useHistory, useLocation } from 'react-router-dom' +import ProfileTypeView from 'components/ProfileType/ProfileTypeView' const EcogestureFormView: React.FC = () => { + const history = useHistory() const [headerHeight, setHeaderHeight] = useState<number>(0) const defineHeaderHeight = (height: number) => { setHeaderHeight(height) @@ -33,9 +35,6 @@ const EcogestureFormView: React.FC = () => { const curProfileEcogesture: ProfileEcogesture = useSelector( (state: AppStore) => state.ecolyo.profileEcogesture ) - const profileType: ProfileType = useSelector( - (state: AppStore) => state.ecolyo.profileType - ) const shouldOpenModal = new URLSearchParams(useLocation().search).get('modal') const [step, setStep] = useState<EcogestureStepForm>( EcogestureStepForm.HEATING_TYPE @@ -64,12 +63,12 @@ const EcogestureFormView: React.FC = () => { setViewedStep(nextStep) } const _answerType: ProfileEcogestureAnswer = ProfileEcogestureFormService.getAnswerForStep( - isProfileTypeCompleted ? EcogestureStepForm.EQUIPMENTS : nextStep + nextStep ) setAnswerType(_answerType) setStep(nextStep) }, - [isProfileTypeCompleted, step, viewedStep] + [step, viewedStep] ) const setPreviousStep = useCallback( (_profileEcogesture: ProfileEcogesture) => { @@ -87,27 +86,12 @@ const EcogestureFormView: React.FC = () => { ) useEffect(() => { - let subscribed = true - if (isProfileTypeCompleted) { - if (subscribed) { - curProfileEcogesture.heating = profileType.heating - curProfileEcogesture.hotWater = profileType.hotWater - curProfileEcogesture.warmingFluid = profileType.warmingFluid - setStep(EcogestureStepForm.EQUIPMENTS) - } - } const _answerType: ProfileEcogestureAnswer = ProfileEcogestureFormService.getAnswerForStep( - isProfileTypeCompleted ? EcogestureStepForm.EQUIPMENTS : step + step ) setAnswerType(_answerType) - if (subscribed) { - setAnswerType(_answerType) - setIsLoading(false) - } - return () => { - subscribed = false - } - }, [step, curProfileEcogesture, isProfileTypeCompleted, profileType]) + setIsLoading(false) + }, [step]) if (isLoading) { return ( @@ -126,22 +110,30 @@ const EcogestureFormView: React.FC = () => { desktopTitleKey={'common.title_ecogestures'} ></Header> <Content height={headerHeight}> - {step === EcogestureStepForm.EQUIPMENTS && ( - <EcogestureFormEquipment - step={EcogestureStepForm.EQUIPMENTS} - profileEcogesture={profileEcogesture} - setPreviousStep={setPreviousStep} - /> - )} - {step !== EcogestureStepForm.EQUIPMENTS && ( - <EcogestureFormSingleChoice - step={step} - viewedStep={viewedStep} - profileEcogesture={profileEcogesture} - answerType={answerType} - setNextStep={setNextStep} - setPrevioustStep={setPreviousStep} + {isProfileTypeCompleted ? ( + <ProfileTypeView + handleEnd={() => history.push('/ecogesture-selection')} /> + ) : ( + <> + {step === EcogestureStepForm.EQUIPMENTS && ( + <EcogestureFormEquipment + step={EcogestureStepForm.EQUIPMENTS} + profileEcogesture={profileEcogesture} + setPreviousStep={setPreviousStep} + /> + )} + {step !== EcogestureStepForm.EQUIPMENTS && ( + <EcogestureFormSingleChoice + step={step} + viewedStep={viewedStep} + profileEcogesture={profileEcogesture} + answerType={answerType} + setNextStep={setNextStep} + setPrevioustStep={setPreviousStep} + /> + )} + </> )} </Content> <EcogestureLaunchFormModal diff --git a/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap index 454d1f0bd63bca2e8addbebbdd5f4611e787b105..8d8812b8b13da3ff901bfff8ed673c388ac52ad4 100644 --- a/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap +++ b/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap @@ -22,7 +22,9 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` "warmingFluid": 0, } } + setNextStep={[MockFunction]} setPreviousStep={[MockFunction]} + step={0} > <div className="ecogesture-profile-container" @@ -305,6 +307,7 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` handleNext={[Function]} handlePrevious={[Function]} isEcogesture={true} + step={0} > <div className="profile-navigation" @@ -318,7 +321,7 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` "root": "btn-profile-back", } } - disabled={false} + disabled={true} onClick={[Function]} > <ForwardRef(Button) @@ -357,14 +360,14 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` "textSizeSmall": "MuiButton-textSizeSmall", } } - disabled={false} + disabled={true} onClick={[Function]} > <WithStyles(ForwardRef(ButtonBase)) aria-label="profile_type.accessibility.button_previous" - className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled" component="button" - disabled={false} + disabled={true} focusRipple={true} focusVisibleClassName="Mui-focusVisible" onClick={[Function]} @@ -372,7 +375,7 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` > <ForwardRef(ButtonBase) aria-label="profile_type.accessibility.button_previous" - className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled" classes={ Object { "disabled": "Mui-disabled", @@ -381,7 +384,7 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` } } component="button" - disabled={false} + disabled={true} focusRipple={true} focusVisibleClassName="Mui-focusVisible" onClick={[Function]} @@ -389,8 +392,8 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` > <button aria-label="profile_type.accessibility.button_previous" - className="MuiButtonBase-root MuiButton-root btn-profile-back MuiButton-text profile-navigation-button" - disabled={false} + className="MuiButtonBase-root MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled Mui-disabled" + disabled={true} onBlur={[Function]} onClick={[Function]} onDragLeave={[Function]} @@ -403,7 +406,7 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` onTouchEnd={[Function]} onTouchMove={[Function]} onTouchStart={[Function]} - tabIndex={0} + tabIndex={-1} type="button" > <span @@ -411,36 +414,6 @@ exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` > < profile_type.form.button_previous </span> - <NoSsr> - <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)> - </NoSsr> </button> </ForwardRef(ButtonBase)> </WithStyles(ForwardRef(ButtonBase))> diff --git a/src/components/EcogestureSelection/EcogestureSelection.tsx b/src/components/EcogestureSelection/EcogestureSelection.tsx index 41e0db5e6610a7101a6e46bc17eb02f8426cf2c2..870a7719f2f41255ae25139eed4697dbca61b211 100644 --- a/src/components/EcogestureSelection/EcogestureSelection.tsx +++ b/src/components/EcogestureSelection/EcogestureSelection.tsx @@ -142,8 +142,7 @@ const EcogestureSelection: React.FC = () => { > <div className="eg-selection-header"> {indexEcogesture <= ecogestureList.length - 1 - ? `${totalViewed + indexEcogesture + 1}/${totalViewed + - ecogestureList.length}` + ? `${totalViewed + indexEcogesture + 1}/${totalAvailable}` : ''} </div> </Header> diff --git a/src/components/ProfileType/ProfileTypeFinished.tsx b/src/components/ProfileType/ProfileTypeFinished.tsx index c130bc8649637ddd0d2a11a0ee12eca8aafdd01f..714438c7fd798ead16b92fbcb12c4a4516e94e3d 100644 --- a/src/components/ProfileType/ProfileTypeFinished.tsx +++ b/src/components/ProfileType/ProfileTypeFinished.tsx @@ -68,6 +68,7 @@ const ProfileTypeFinished: React.FC<ProfileTypeFinishedProps> = ({ setIsSaved(true) dispatch( updateProfile({ + isProfileEcogestureCompleted: true, isProfileTypeCompleted: true, }) ) @@ -79,6 +80,7 @@ const ProfileTypeFinished: React.FC<ProfileTypeFinishedProps> = ({ setIsSaved(true) dispatch( updateProfile({ + isProfileEcogestureCompleted: true, isProfileTypeCompleted: true, }) ) diff --git a/src/components/ProfileType/ProfileTypeView.tsx b/src/components/ProfileType/ProfileTypeView.tsx index 83fa274cfee97f6fe1678bdce88652d3548e904f..40bfbdef84d4997c2daa6d9836fd305039685c3c 100644 --- a/src/components/ProfileType/ProfileTypeView.tsx +++ b/src/components/ProfileType/ProfileTypeView.tsx @@ -4,7 +4,7 @@ import CozyBar from 'components/Header/CozyBar' import Header from 'components/Header/Header' import Content from 'components/Content/Content' import ProfileTypeFormSingleChoice from 'components/ProfileType/ProfileTypeFormSingleChoice' -import ProfileTypeFormEnd from 'components/ProfileType/ProfileTypeFinished' +import ProfileTypeFinished from 'components/ProfileType/ProfileTypeFinished' import { ProfileType, ProfileTypeAnswer } from 'models/profileType.model' import { @@ -32,7 +32,13 @@ import ProfileTypeFormDateSelection from './ProfileTypeFormDateSelection' import EcogestureFormEquipment from 'components/EcogestureForm/EcogestureFormEquipment' import { ProfileEcogesture } from 'models/profileEcogesture.model' -const ProfileTypeView = () => { +interface ProfileTypeViewProps { + handleEnd: Function +} + +const ProfileTypeView: React.FC<ProfileTypeViewProps> = ({ + handleEnd, +}: ProfileTypeViewProps) => { const profile = useSelector((state: AppStore) => state.ecolyo.profile) const curProfileType = useSelector( (state: AppStore) => state.ecolyo.profileType @@ -64,7 +70,7 @@ const ProfileTypeView = () => { warmingFluid: WarmingType.ELECTRICITY, hotWaterFluid: FluidType.ELECTRICITY, cookingFluid: FluidType.ELECTRICITY, - equipments: '', + equipments: [], }) const [step, setStep] = useState<ProfileTypeStepForm>( ProfileTypeStepForm.HOUSING_TYPE @@ -88,6 +94,9 @@ const ProfileTypeView = () => { if (_profileType) { setProfileType(_profileType) profileTypeFormService = new ProfileTypeFormService(_profileType) + curProfileEcogesture.heating = _profileType.heating + curProfileEcogesture.hotWater = _profileType.hotWater + curProfileEcogesture.warmingFluid = _profileType.warmingFluid } else { // if equipments are updated, keep profileType as it is profileTypeFormService = new ProfileTypeFormService({ @@ -98,13 +107,23 @@ const ProfileTypeView = () => { step, !profile.isProfileTypeCompleted ) + if (nextStep === ProfileTypeStepForm.END && handleEnd) { + handleEnd() + } setIsLoading(true) if (nextStep > viewedStep) { setViewedStep(nextStep) } setStep(nextStep) }, - [profile.isProfileTypeCompleted, profileType, step, viewedStep] + [ + curProfileEcogesture, + handleEnd, + profile.isProfileTypeCompleted, + profileType, + step, + viewedStep, + ] ) const setPreviousStep = useCallback( @@ -219,7 +238,7 @@ const ProfileTypeView = () => { {isLoading ? null : step !== ProfileTypeStepForm.END ? ( selectForm() ) : ( - <ProfileTypeFormEnd profileType={profileType} /> + <ProfileTypeFinished profileType={profileType} /> )} </div> </Content> diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index 5267763350f7d8d119a7449b05a224c363b4c20d..2ef690160c189e3ebdb4e48c649719fa749dfd04 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -33,12 +33,8 @@ const ProfileTypeView = lazy(() => interface RouteProps { termsStatus: TermsStatus - isProfileEcogestureCompleted: boolean } -const Routes: React.FC<RouteProps> = ({ - termsStatus, - isProfileEcogestureCompleted, -}: RouteProps) => { +const Routes: React.FC<RouteProps> = ({ termsStatus }: RouteProps) => { return ( <Suspense fallback={<div></div>}> <Switch> @@ -68,9 +64,7 @@ const Routes: React.FC<RouteProps> = ({ <Route path={`/challenges/exploration`} component={ExplorationView} /> <Route path={`/challenges/action`} exact component={ActionView} /> <Route path={`/challenges/`} component={ChallengeView} exact /> - {!isProfileEcogestureCompleted && ( - <Route path="/ecogesture-form" component={EcogestureFormView} /> - )} + <Route path="/ecogesture-form" component={EcogestureFormView} /> <Route path="/ecogesture-selection" component={EcogestureSelection} /> <Route path="/ecogesture/:id/:tab" component={SingleEcogesture} /> <Route path="/ecogesture/:id" component={SingleEcogesture} /> diff --git a/src/locales/fr.json b/src/locales/fr.json index 1c098bfed3d6d8c2d2192e59733345d20d1fe6c6..beadc6d1271d583b241af1f5b7a438399aeb3118 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -406,6 +406,19 @@ "text3": "Afin de savoir quels écogestes correspondent à votre consommation, merci de répondre à quelques rapides questions.", "btn1": "Plus tard", "btn2": "C'est parti !" + }, + "reinit": "Réinitialiser ma sélection d'écogestes", + "reinitModal": { + "title_part1": "Cette action", + "title_part2": "supprimera tous les écogestes", + "title_part3": "sélectionnés dans", + "title_part4": "“Objectifsâ€", + "title_part5": "et", + "title_part6": "“Je fais déjà â€", + "text1": "Vous pourrez ensuite faire une nouvelle sélection d’écogestes adaptés à votre consommation.", + "text2": "Souhaitez-vous réinitialiser votre sélection d’écogestes ?", + "btn1": "Non", + "btn2": "Réinitialiser" } }, "ecogesture_modal": { diff --git a/src/models/profileType.model.ts b/src/models/profileType.model.ts index cd637842ec6237babcf1c77566188dc8ad5222aa..a4e6a7fdfacf1b6eda4524a434653242877771c3 100644 --- a/src/models/profileType.model.ts +++ b/src/models/profileType.model.ts @@ -12,6 +12,7 @@ import { } from 'enum/profileType.enum' import { FluidType } from 'enum/fluid.enum' import { DateTime } from 'luxon' +import { EquipmentType } from 'enum/ecogesture.enum' interface ProfileTypeIndexableTypes { [key: string]: @@ -25,6 +26,7 @@ interface ProfileTypeIndexableTypes { | HotWaterEquipment | FluidType | DateTime + | EquipmentType[] | number | string | string[] @@ -48,7 +50,7 @@ export interface ProfileType extends ProfileTypeIndexableTypes { hotWaterFluid: FluidType | null cookingFluid: FluidType updateDate: DateTime - equipments: string + equipments: EquipmentType[] } export interface MonthlyForecast { diff --git a/src/services/ecogesture.service.spec.ts b/src/services/ecogesture.service.spec.ts index 0b67426935ae2128ccab94f86e5d1dc2b4d35e26..12bfc03391b1477143d54cfad3f0d4d899c09db0 100644 --- a/src/services/ecogesture.service.spec.ts +++ b/src/services/ecogesture.service.spec.ts @@ -65,7 +65,7 @@ describe('Ecogesture service', () => { const result = await ecogestureService.deleteAllEcogestures() expect(result).toBe(true) }) - it('should return false when error happened on deletion', async () => { + it('should throw exception when error happened on deletion', async () => { const mockQueryResult: QueryResult<Ecogesture[]> = { data: ecogesturesData, bookmark: '', @@ -74,10 +74,50 @@ describe('Ecogesture service', () => { } mockClient.destroy.mockRejectedValue(new Error()) mockClient.query.mockResolvedValueOnce(mockQueryResult) - const result = await ecogestureService.deleteAllEcogestures() - expect(result).toBe(false) + await expect(ecogestureService.deleteAllEcogestures()).rejects.toThrow( + new Error() + ) }) }) + describe('reinitAllEcogestures', () => { + it('should return true when 3 ecogestures stored', async () => { + const mockQueryResult: QueryResult<Ecogesture[]> = { + data: ecogesturesData, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await ecogestureService.reinitAllEcogestures() + expect(mockClient.save).toBeCalledTimes(3) + expect(result).toBe(true) + }) + it('should return true when no ecogestures stored', async () => { + const mockQueryResult: QueryResult<Ecogesture[]> = { + data: [], + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await ecogestureService.reinitAllEcogestures() + expect(result).toBe(true) + }) + it('should throw exception when error happened on reinit', async () => { + const mockQueryResult: QueryResult<Ecogesture[]> = { + data: ecogesturesData, + bookmark: '', + next: false, + skip: 0, + } + mockClient.save.mockRejectedValue(new Error()) + mockClient.query.mockResolvedValueOnce(mockQueryResult) + await expect(ecogestureService.reinitAllEcogestures()).rejects.toThrow( + new Error() + ) + }) + }) + describe('filterByUsage', () => { it('should return ecogesture list including ECS ecogestures', async () => { const mockEcogestureList: Ecogesture[] = ecogesturesECSData diff --git a/src/services/ecogesture.service.ts b/src/services/ecogesture.service.ts index 409b2e566549bcf49844c2a8b1d362b00a3fd34b..0de5cd9e37f5087d3d6dca8b0a07924f02b551b7 100644 --- a/src/services/ecogesture.service.ts +++ b/src/services/ecogesture.service.ts @@ -63,12 +63,31 @@ export default class EcogestureService { public async deleteAllEcogestures(): Promise<boolean> { const ecogestures = await this.getAllEcogestures() try { - for (let index = 0; index < ecogestures.length; index++) { - await this._client.destroy(ecogestures[index]) + for (const ecogesture of ecogestures) { + await this._client.destroy(ecogesture) } return true } catch (error) { - return false + console.log('Error deleteAllEcogestures: ', error) + throw error + } + } + + public async reinitAllEcogestures(): Promise<boolean> { + const ecogestures = await this.getAllEcogestures() + try { + for (const ecogesture of ecogestures) { + await this.updateEcogesture({ + ...ecogesture, + objective: false, + doing: false, + viewedInSelection: false, + }) + } + return true + } catch (error) { + console.log('Error reinitAllEcogestures: ', error) + throw error } } diff --git a/src/services/profileEcogesture.service.spec.ts b/src/services/profileEcogesture.service.spec.ts index 1c516dfb9e48b8e0be508115b9db1c1a18ad707d..75329f55e2394f0fca8c21f22d26357ab2805e41 100644 --- a/src/services/profileEcogesture.service.spec.ts +++ b/src/services/profileEcogesture.service.spec.ts @@ -10,7 +10,7 @@ const profileEcogestureService = new ProfileEcogestureService(mockClient) describe('ProfileEcogesture service', () => { it('should get the Profile Ecogesture', async () => { const mockQueryResult: QueryResult<ProfileEcogesture> = { - data: mockProfileEcogestureUpdated, + data: [mockProfileEcogestureUpdated], bookmark: '', next: false, skip: 0, diff --git a/src/services/profileEcogesture.service.ts b/src/services/profileEcogesture.service.ts index 006809ad390dc64e0566382b4b25b9f75eb3de0c..6913923dbcbb8c2cc0bb3040508b8c5b868724e6 100644 --- a/src/services/profileEcogesture.service.ts +++ b/src/services/profileEcogesture.service.ts @@ -15,8 +15,8 @@ export default class ProfileEcogestureService { public async getProfileEcogesture(): Promise<ProfileEcogesture | null> { const query: QueryDefinition = Q(PROFILEECOGESTURE_DOCTYPE) const { - data: profileEcogesture, - }: QueryResult<ProfileEcogesture> = await this._client.query( + data: [profileEcogesture], + }: QueryResult<ProfileEcogesture[]> = await this._client.query( query.limitBy(1) ) if (profileEcogesture) return profileEcogesture diff --git a/src/styles/base/_color.scss b/src/styles/base/_color.scss index eb718058d534d4150daa2c8b9b1ad197b11c2ae8..8e6b7a884acf9aa1f24c963438205008fb903821 100644 --- a/src/styles/base/_color.scss +++ b/src/styles/base/_color.scss @@ -19,6 +19,9 @@ $gold-40: rgba(227, 184, 42, 0.4); $gold-light: #deaf0e; $gold-shadow: #e3b82a; +/** ORANGE **/ +$orange: #ec9d41; + /** BLUE **/ $blue: #58ffff; $blue-40: #58ffff40; diff --git a/tests/__mocks__/client.ts b/tests/__mocks__/client.ts index 184dcdec4987164480d516f0bbf225278e4ebb4b..3118714bde4d0e47cbbd4358e1feb0094b10d814 100644 --- a/tests/__mocks__/client.ts +++ b/tests/__mocks__/client.ts @@ -3,7 +3,9 @@ import { Client } from 'cozy-client' const mockClient = ({ query: jest.fn(), create: jest.fn(), - save: jest.fn(), + save: jest.fn().mockReturnValue({ + data: {}, + }), saveAll: jest.fn(), destroy: jest.fn(), collection: jest.fn().mockReturnValue({