Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • web-et-numerique/factory/llle_project/ecolyo
1 result
Select Git revision
Show changes
Showing
with 276 additions and 222 deletions
...@@ -41,20 +41,17 @@ ...@@ -41,20 +41,17 @@
text-align: center; text-align: center;
color: white; color: white;
} }
.description {
display: none; .showMore {
margin: 1.5rem 0.5rem 0.5rem 0.5rem;
text-align: left;
}
.block {
display: block !important;
}
.toggle-text {
text-align: center; text-align: center;
text-decoration: underline; text-decoration: underline;
margin-top: 1.5rem; margin-top: 1.5rem;
cursor: pointer; cursor: pointer;
} }
.longDescription {
margin: 1em 0.5rem;
text-align: left;
}
} }
.buttons-selection { .buttons-selection {
width: 100%; width: 100%;
......
...@@ -21,6 +21,21 @@ describe('EcogestureSelectionDetail component', () => { ...@@ -21,6 +21,21 @@ describe('EcogestureSelectionDetail component', () => {
expect(toJson(wrapper)).toMatchSnapshot() expect(toJson(wrapper)).toMatchSnapshot()
}) })
it('should toggle more details', async () => {
const wrapper = mount(
<EcogestureSelectionDetail
ecogesture={mockedEcogesturesData[0]}
validate={mockValidate}
title={mockedEcogesturesData[0].shortName}
/>
)
await waitForComponentToPaint(wrapper)
wrapper.find('.showMore').first().simulate('click')
await waitForComponentToPaint(wrapper)
expect(wrapper.find('.showMore').text()).toBe('ecogesture_modal.show_less')
})
it('should call validate with objective to true', async () => { it('should call validate with objective to true', async () => {
const wrapper = mount( const wrapper = mount(
<EcogestureSelectionDetail <EcogestureSelectionDetail
......
import { Button } from '@material-ui/core' import { Button, Collapse } from '@material-ui/core'
import doingIcon from 'assets/icons/ico/doing-enabled.svg' import doingIcon from 'assets/icons/ico/doing-enabled.svg'
import objectiveIcon from 'assets/icons/ico/objective-enabled.svg' import objectiveIcon from 'assets/icons/ico/objective-enabled.svg'
import skipIcon from 'assets/icons/ico/skip-enabled.svg' import skipIcon from 'assets/icons/ico/skip-enabled.svg'
...@@ -23,6 +23,7 @@ const EcogestureSelectionDetail = ({ ...@@ -23,6 +23,7 @@ const EcogestureSelectionDetail = ({
}: EcogestureSelectionDetailProps) => { }: EcogestureSelectionDetailProps) => {
const { t } = useI18n() const { t } = useI18n()
const [ecogestureIcon, setEcogestureIcon] = useState<string>('') const [ecogestureIcon, setEcogestureIcon] = useState<string>('')
const [showDetails, setShowDetails] = useState(false)
useEffect(() => { useEffect(() => {
let subscribed = true let subscribed = true
...@@ -33,6 +34,7 @@ const EcogestureSelectionDetail = ({ ...@@ -33,6 +34,7 @@ const EcogestureSelectionDetail = ({
} }
} }
getIcon() getIcon()
setShowDetails(false)
return () => { return () => {
subscribed = false subscribed = false
} }
...@@ -41,9 +43,25 @@ const EcogestureSelectionDetail = ({ ...@@ -41,9 +43,25 @@ const EcogestureSelectionDetail = ({
return ( return (
<div className="eg-selection-detail-container"> <div className="eg-selection-detail-container">
<div className="content"> <div className="content">
<StyledIcon className="icon" icon={ecogestureIcon} size={240} /> <div className="iconContainer">
<StyledIcon className="icon" icon={ecogestureIcon} size={240} />
</div>
<div className="text-22 title">{title}</div> <div className="text-22 title">{title}</div>
<div className="text text-18-bold">{ecogesture.longName}</div> <div className="text text-18-bold">{ecogesture.longName}</div>
<div
className="showMore text-15-normal"
onClick={() => setShowDetails(prev => !prev)}
role="button"
>
{t(`ecogesture_modal.show_${showDetails ? 'less' : 'more'}`)}
</div>
<Collapse in={showDetails} exit={false}>
<div className="longDescription text-16-normal-150">
{ecogesture.longDescription}
</div>
</Collapse>
</div> </div>
<div className="buttons"> <div className="buttons">
<Button <Button
......
...@@ -44,39 +44,43 @@ exports[`EcogestureSelectionDetail component should be rendered correctly 1`] = ...@@ -44,39 +44,43 @@ exports[`EcogestureSelectionDetail component should be rendered correctly 1`] =
<div <div
className="content" className="content"
> >
<StyledIcon <div
className="icon" className="iconContainer"
icon="test-file-stub"
size={240}
> >
<Icon <StyledIcon
aria-hidden={true}
className="icon" className="icon"
icon="test-file-stub" icon="test-file-stub"
size={240} size={240}
spin={false}
> >
<Component <Icon
aria-hidden={true} aria-hidden={true}
className="icon styles__icon___23x3R" className="icon"
height={240} icon="test-file-stub"
style={Object {}} size={240}
width={240} spin={false}
> >
<svg <Component
aria-hidden={true} aria-hidden={true}
className="icon styles__icon___23x3R" className="icon styles__icon___23x3R"
height={240} height={240}
style={Object {}} style={Object {}}
width={240} width={240}
> >
<use <svg
xlinkHref="#test-file-stub" aria-hidden={true}
/> className="icon styles__icon___23x3R"
</svg> height={240}
</Component> style={Object {}}
</Icon> width={240}
</StyledIcon> >
<use
xlinkHref="#test-file-stub"
/>
</svg>
</Component>
</Icon>
</StyledIcon>
</div>
<div <div
className="text-22 title" className="text-22 title"
> >
...@@ -87,6 +91,71 @@ exports[`EcogestureSelectionDetail component should be rendered correctly 1`] = ...@@ -87,6 +91,71 @@ exports[`EcogestureSelectionDetail component should be rendered correctly 1`] =
> >
Je baisse le chauffage en mode hors gel lorsque je m'absente plus de 2 jours. Je baisse le chauffage en mode hors gel lorsque je m'absente plus de 2 jours.
</div> </div>
<div
className="showMore text-15-normal"
onClick={[Function]}
role="button"
>
ecogesture_modal.show_more
</div>
<WithStyles(ForwardRef(Collapse))
exit={false}
in={false}
>
<ForwardRef(Collapse)
classes={
Object {
"entered": "MuiCollapse-entered",
"hidden": "MuiCollapse-hidden",
"root": "MuiCollapse-root",
"wrapper": "MuiCollapse-wrapper",
"wrapperInner": "MuiCollapse-wrapperInner",
}
}
exit={false}
in={false}
>
<Transition
addEndListener={[Function]}
appear={false}
enter={true}
exit={false}
in={false}
mountOnEnter={false}
onEnter={[Function]}
onEntered={[Function]}
onEntering={[Function]}
onExit={[Function]}
onExited={[Function]}
onExiting={[Function]}
timeout={300}
unmountOnExit={false}
>
<div
className="MuiCollapse-root MuiCollapse-hidden"
style={
Object {
"minHeight": "0px",
}
}
>
<div
className="MuiCollapse-wrapper"
>
<div
className="MuiCollapse-wrapperInner"
>
<div
className="longDescription text-16-normal-150"
>
On se demande parfois si cela vaut le coup de "couper le chauffage" quand on s’absente… dès qu’il s’agit d’un week-end la réponse est « oui sûrement » ! Attention cependant au retour à ne pas faire de la surchauffe ! L’idéal est bien évidemment de régler sa programmation pour que le chauffage se relance quelques heures avant votre retour…
</div>
</div>
</div>
</div>
</Transition>
</ForwardRef(Collapse)>
</WithStyles(ForwardRef(Collapse))>
</div> </div>
<div <div
className="buttons" className="buttons"
......
...@@ -2,41 +2,42 @@ ...@@ -2,41 +2,42 @@
@import 'src/styles/base/breakpoint'; @import 'src/styles/base/breakpoint';
.eg-selection-detail-container { .eg-selection-detail-container {
min-height: inherit;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
text-align: center; text-align: center;
color: $grey-bright; color: $grey-bright;
padding: 0 1.5rem; padding: 0 1.5rem;
flex: 1;
max-height: calc(100vh - 60px - 72px - 0px);
.content { .content {
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
justify-content: center; justify-content: flex-start;
align-items: center; align-items: center;
overflow-y: auto;
.title { .title {
color: $soft-grey; color: $soft-grey;
font-weight: 700; font-weight: 700;
} }
.icon { .iconContainer {
@media #{$phone} { height: 240px;
width: 50%; }
height: 50%;
} .showMore {
@media #{$small-phone} { text-align: center;
width: 30%; text-decoration: underline;
height: 30%; margin-top: 1rem;
} cursor: pointer;
} }
.text { .longDescription {
min-height: 4.875rem; margin: 1rem 0.5rem;
display: flex; text-align: left;
align-items: center;
margin: 0 1rem;
} }
} }
.buttons { .buttons {
......
...@@ -143,7 +143,7 @@ const FluidChart = ({ fluidType, setActive }: FluidChartProps) => { ...@@ -143,7 +143,7 @@ const FluidChart = ({ fluidType, setActive }: FluidChartProps) => {
const LastDataValid = () => ( const LastDataValid = () => (
<div className="lastValidData"> <div className="lastValidData">
<span className={`text-16-normal date`} onClick={moveToDate}> <span className="text-16-bold date" onClick={moveToDate}>
{t('consumption_visualizer.last_valid_data', { {t('consumption_visualizer.last_valid_data', {
date: currentFluidStatus?.lastDataDate?.toFormat('dd/MM/yy') || '-', date: currentFluidStatus?.lastDataDate?.toFormat('dd/MM/yy') || '-',
})} })}
......
import Button from '@material-ui/core/Button' import Button from '@material-ui/core/Button'
import warningDark from 'assets/icons/ico/warning-dark.svg'
import warningWhite from 'assets/icons/ico/warning-white.svg' import warningWhite from 'assets/icons/ico/warning-white.svg'
import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
import Loader from 'components/Loader/Loader' import Loader from 'components/Loader/Loader'
...@@ -431,9 +432,9 @@ const DisplayAlreadyUpdatedToday = ({ ...@@ -431,9 +432,9 @@ const DisplayAlreadyUpdatedToday = ({
const DisplayManualUpdate = () => { const DisplayManualUpdate = () => {
const { t } = useI18n() const { t } = useI18n()
return ( return (
<div className="connection-caption-errored connection-update-errored warning-white text-16-normal"> <div className="connection-caption-warning connection-update-errored warning-white text-16-normal">
<StyledIcon <StyledIcon
icon={warningWhite} icon={warningDark}
size={36} size={36}
className="warning-icon" className="warning-icon"
role="img" role="img"
......
...@@ -27,6 +27,26 @@ ...@@ -27,6 +27,26 @@
margin-right: 1rem; margin-right: 1rem;
} }
} }
.connection-caption-warning {
background-color: $gold-shadow;
margin: 0 -2.5rem;
padding: 0.4rem 2.5rem;
display: flex;
align-items: center;
color: $dark-2;
@media #{$tablet} {
margin: 0 -1.2rem;
padding: 0.4rem 1.2rem;
}
.warning-icon {
min-width: 20px;
margin-right: 1rem;
}
.warning-white {
margin-right: 1rem;
}
}
.connection-caption { .connection-caption {
color: $grey-bright; color: $grey-bright;
} }
...@@ -42,7 +62,7 @@ ...@@ -42,7 +62,7 @@
gap: 1rem; gap: 1rem;
button.btn-secondary-positive { button.btn-secondary-positive {
span:first-child { span:first-child {
color: $red-primary !important; color: $white !important;
} }
} }
} }
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
import chevronDown from 'assets/icons/ico/chevron-down.svg' import chevronDown from 'assets/icons/ico/chevron-down.svg'
import ErrorNotif from 'assets/icons/ico/notif_error.svg' import ErrorNotif from 'assets/icons/ico/notif_error.svg'
import PartnersIssueNotif from 'assets/icons/ico/notif_maintenance.svg' import PartnersIssueNotif from 'assets/icons/ico/notif_maintenance.svg'
import WarningNotif from 'assets/icons/ico/notif_warning.svg'
import OfflinePicto from 'assets/icons/visu/offline-param.svg' import OfflinePicto from 'assets/icons/visu/offline-param.svg'
import classNames from 'classnames' import classNames from 'classnames'
import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
...@@ -221,11 +222,7 @@ const KonnectorViewerCard = ({ ...@@ -221,11 +222,7 @@ const KonnectorViewerCard = ({
// RESTORE LAST KNOWN CREDENTIALS // RESTORE LAST KNOWN CREDENTIALS
if (lastEpglLogin) { if (lastEpglLogin) {
dispatch( dispatch(setLastEpglLogin(lastEpglLogin))
setLastEpglLogin({
lastEpglLogin: lastEpglLogin,
})
)
} }
} else { } else {
if (isSuccess && currentFluidStatus.lastDataDate === null) { if (isSuccess && currentFluidStatus.lastDataDate === null) {
...@@ -385,6 +382,48 @@ const KonnectorViewerCard = ({ ...@@ -385,6 +382,48 @@ const KonnectorViewerCard = ({
updateGlobalFluidStatus, updateGlobalFluidStatus,
] ]
) )
const getIconForStatus = (
status: FluidState,
maintenance: boolean,
connection: FluidConnection,
outdatedData: number | null
) => {
if (maintenance) {
return (
<StyledIcon
icon={PartnersIssueNotif}
size={24}
className="konnector-state-picto"
/>
)
}
if (
(status === FluidState.ERROR ||
status === FluidState.ERROR_LOGIN_FAILED) &&
connection.account
) {
return (
<StyledIcon
icon={ErrorNotif}
size={24}
className="konnector-state-picto"
/>
)
}
if (outdatedData && outdatedData > 0) {
return (
<StyledIcon
icon={WarningNotif}
size={24}
className="konnector-state-picto"
/>
)
}
}
const displayKonnectorIcon = useCallback(() => { const displayKonnectorIcon = useCallback(() => {
return ( return (
<div className="konnector-icon"> <div className="konnector-icon">
...@@ -392,33 +431,15 @@ const KonnectorViewerCard = ({ ...@@ -392,33 +431,15 @@ const KonnectorViewerCard = ({
icon={currentFluidStatus.connection.account ? iconType : OfflinePicto} icon={currentFluidStatus.connection.account ? iconType : OfflinePicto}
size={49} size={49}
/> />
{currentFluidStatus.maintenance ? ( {getIconForStatus(
<StyledIcon currentFluidStatus.status,
icon={PartnersIssueNotif} currentFluidStatus.maintenance,
size={24} currentFluidStatus.connection,
className="konnector-state-picto" isOutdatedData
/>
) : (
(currentFluidStatus.status === FluidState.ERROR ||
isOutdatedData ||
currentFluidStatus.status === FluidState.ERROR_LOGIN_FAILED) &&
currentFluidStatus.connection.account && (
<StyledIcon
icon={ErrorNotif}
size={24}
className="konnector-state-picto"
/>
)
)} )}
</div> </div>
) )
}, [ }, [currentFluidStatus, iconType, isOutdatedData])
currentFluidStatus.connection.account,
currentFluidStatus.maintenance,
currentFluidStatus.status,
iconType,
isOutdatedData,
])
const displayKonnectorHeader = useCallback(() => { const displayKonnectorHeader = useCallback(() => {
if (currentFluidStatus.maintenance) { if (currentFluidStatus.maintenance) {
......
...@@ -40,6 +40,12 @@ const Navbar = () => { ...@@ -40,6 +40,12 @@ const Navbar = () => {
}, },
[client] [client]
) )
/** Return class "is-active" if pathname includes matcher */
const isActive = (matcher: string) => {
return pathname.includes(matcher) ? 'is-active' : ''
}
return ( return (
<aside className="o-sidebar"> <aside className="o-sidebar">
<nav role="navigation" aria-label="navigation"> <nav role="navigation" aria-label="navigation">
...@@ -51,9 +57,7 @@ const Navbar = () => { ...@@ -51,9 +57,7 @@ const Navbar = () => {
<Link <Link
component={NavLink} component={NavLink}
to="/consumption" to="/consumption"
className={`c-nav-link ${ className={`c-nav-link ${isActive('/consumption')}`}
pathname.includes('/consumption') ? 'is-active' : ''
}`}
> >
<StyledIcon className="c-nav-icon off" icon={ConsoIconOff} /> <StyledIcon className="c-nav-icon off" icon={ConsoIconOff} />
<StyledIcon className="c-nav-icon on" icon={ConsoIconOn} /> <StyledIcon className="c-nav-icon on" icon={ConsoIconOn} />
...@@ -64,9 +68,7 @@ const Navbar = () => { ...@@ -64,9 +68,7 @@ const Navbar = () => {
<Link <Link
component={NavLink} component={NavLink}
to="/challenges" to="/challenges"
className={`c-nav-link ${ className={`c-nav-link ${isActive('/challenges')}`}
pathname.includes('/challenges') ? 'is-active' : ''
}`}
> >
{(challengeExplorationNotification || {(challengeExplorationNotification ||
challengeActionNotification || challengeActionNotification ||
...@@ -83,9 +85,7 @@ const Navbar = () => { ...@@ -83,9 +85,7 @@ const Navbar = () => {
<Link <Link
component={NavLink} component={NavLink}
to="/ecogestures" to="/ecogestures"
className={`c-nav-link ${ className={`c-nav-link ${isActive('/ecogesture')}`}
pathname.includes('/ecogestures') ? 'is-active' : ''
}`}
> >
<StyledIcon className="c-nav-icon off" icon={BulbIconOff} /> <StyledIcon className="c-nav-icon off" icon={BulbIconOff} />
<StyledIcon className="c-nav-icon on" icon={BulbIconOn} /> <StyledIcon className="c-nav-icon on" icon={BulbIconOn} />
...@@ -110,9 +110,7 @@ const Navbar = () => { ...@@ -110,9 +110,7 @@ const Navbar = () => {
<Link <Link
component={NavLink} component={NavLink}
to="/options" to="/options"
className={`c-nav-link ${ className={`c-nav-link ${isActive('/options')}`}
pathname.includes('/options') ? 'is-active' : ''
}`}
> >
<StyledIcon className="c-nav-icon off" icon={ParameterIconOff} /> <StyledIcon className="c-nav-icon off" icon={ParameterIconOff} />
<StyledIcon className="c-nav-icon on" icon={ParameterIconOn} /> <StyledIcon className="c-nav-icon on" icon={ParameterIconOn} />
......
...@@ -484,8 +484,8 @@ ...@@ -484,8 +484,8 @@
"title_ecogesture": "Astuce", "title_ecogesture": "Astuce",
"title_action": "Action", "title_action": "Action",
"efficiency": "Efficacité", "efficiency": "Efficacité",
"show_less": "Voir moins d’infos", "show_less": "Voir moins",
"show_more": "Voir plus d’infos", "show_more": "Voir plus",
"select_action": "Je choisis cette action", "select_action": "Je choisis cette action",
"accessibility": { "accessibility": {
"window_title_ecogesture": "Fenêtre astuce", "window_title_ecogesture": "Fenêtre astuce",
......
...@@ -7,19 +7,14 @@ const initialState: AnalysisState = { ...@@ -7,19 +7,14 @@ const initialState: AnalysisState = {
analysisMonth: DateTime.local().minus({ months: 1 }).startOf('day'), analysisMonth: DateTime.local().minus({ months: 1 }).startOf('day'),
} }
type SetPeriodAction = PayloadAction<'month' | 'year'>
type SetSelectedMonthAction = PayloadAction<DateTime>
export type AnalysisActionTypes = SetPeriodAction | SetSelectedMonthAction
export const analysisSlice = createSlice({ export const analysisSlice = createSlice({
name: 'analysis', name: 'analysis',
initialState, initialState,
reducers: { reducers: {
setPeriod: (state, action: SetPeriodAction) => { setPeriod: (state, action: PayloadAction<'month' | 'year'>) => {
state.period = action.payload state.period = action.payload
}, },
setAnalysisMonth: (state, action: SetSelectedMonthAction) => { setAnalysisMonth: (state, action: PayloadAction<DateTime>) => {
state.analysisMonth = action.payload state.analysisMonth = action.payload
}, },
}, },
......
...@@ -8,25 +8,16 @@ const initialState: ChallengeState = { ...@@ -8,25 +8,16 @@ const initialState: ChallengeState = {
currentDataload: [], currentDataload: [],
} }
type SetUserChallengeList = PayloadAction<UserChallenge[]>
type UpdateUserChallengeList = PayloadAction<UserChallenge>
type UnlockNextUserChallenge = PayloadAction<UserChallenge>
type SetChallengeConsumption = PayloadAction<{ type SetChallengeConsumption = PayloadAction<{
userChallenge: UserChallenge userChallenge: UserChallenge
currentDataload: Dataload[] currentDataload: Dataload[]
}> }>
export type ChallengeActionTypes =
| SetUserChallengeList
| UpdateUserChallengeList
| UnlockNextUserChallenge
| SetChallengeConsumption
export const challengeSlice = createSlice({ export const challengeSlice = createSlice({
name: 'challenge', name: 'challenge',
initialState, initialState,
reducers: { reducers: {
setUserChallengeList: (state, action: SetUserChallengeList) => { setUserChallengeList: (state, action: PayloadAction<UserChallenge[]>) => {
const filteredCurrentChallenge = action.payload.filter( const filteredCurrentChallenge = action.payload.filter(
challenge => challenge =>
challenge.state === UserChallengeState.ONGOING || challenge.state === UserChallengeState.ONGOING ||
...@@ -37,7 +28,7 @@ export const challengeSlice = createSlice({ ...@@ -37,7 +28,7 @@ export const challengeSlice = createSlice({
state.userChallengeList = action.payload state.userChallengeList = action.payload
state.currentChallenge = currentChallenge state.currentChallenge = currentChallenge
}, },
updateUserChallengeList: (state, action: UpdateUserChallengeList) => { updateUserChallengeList: (state, action: PayloadAction<UserChallenge>) => {
const id = action.payload.id const id = action.payload.id
const currentChallenge = const currentChallenge =
action.payload.state === UserChallengeState.ONGOING || action.payload.state === UserChallengeState.ONGOING ||
...@@ -51,7 +42,7 @@ export const challengeSlice = createSlice({ ...@@ -51,7 +42,7 @@ export const challengeSlice = createSlice({
state.userChallengeList = updatedList state.userChallengeList = updatedList
state.currentChallenge = currentChallenge || state.currentChallenge state.currentChallenge = currentChallenge || state.currentChallenge
}, },
unlockNextUserChallenge: (state, action: UnlockNextUserChallenge) => { unlockNextUserChallenge: (state, action: PayloadAction<UserChallenge>) => {
const id = action.payload.id const id = action.payload.id
const updatedList = [...state.userChallengeList] const updatedList = [...state.userChallengeList]
const findIndex = updatedList.findIndex(challenge => challenge.id === id) const findIndex = updatedList.findIndex(challenge => challenge.id === id)
......
...@@ -3,25 +3,6 @@ import { TimeStep } from 'enums' ...@@ -3,25 +3,6 @@ import { TimeStep } from 'enums'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import { ChartState, Datachart } from 'models' import { ChartState, Datachart } from 'models'
type SetCurrentDataChart = PayloadAction<Datachart>
type SetCurrentDataChartIndex = PayloadAction<number>
type SetCurrentIndex = PayloadAction<number>
type SetCurrentTimeStep = PayloadAction<TimeStep>
type SetLoading = PayloadAction<boolean>
type SetSelectedDate = PayloadAction<DateTime>
type SetShowCompare = PayloadAction<boolean>
type SetShowOfflineData = PayloadAction<boolean>
export type ChartActionTypes =
| SetCurrentDataChart
| SetCurrentDataChartIndex
| SetCurrentIndex
| SetCurrentTimeStep
| SetLoading
| SetSelectedDate
| SetShowCompare
| SetShowOfflineData
const initialState: ChartState = { const initialState: ChartState = {
selectedDate: DateTime.local().endOf('minute').setZone('utc', { selectedDate: DateTime.local().endOf('minute').setZone('utc', {
keepLocalTime: true, keepLocalTime: true,
...@@ -39,31 +20,31 @@ export const chartSlice = createSlice({ ...@@ -39,31 +20,31 @@ export const chartSlice = createSlice({
name: 'chart', name: 'chart',
initialState, initialState,
reducers: { reducers: {
setCurrentDataChart: (state, action: SetCurrentDataChart) => { setCurrentDataChart: (state, action: PayloadAction<Datachart>) => {
state.currentDatachart = action.payload state.currentDatachart = action.payload
}, },
setCurrentDataChartIndex: (state, action: SetCurrentDataChartIndex) => { setCurrentDataChartIndex: (state, action: PayloadAction<number>) => {
state.currentDatachartIndex = action.payload state.currentDatachartIndex = action.payload
}, },
setCurrentIndex: (state, action: SetCurrentIndex) => { setCurrentIndex: (state, action: PayloadAction<number>) => {
state.currentIndex = action.payload state.currentIndex = action.payload
}, },
setCurrentTimeStep: (state, action: SetCurrentTimeStep) => { setCurrentTimeStep: (state, action: PayloadAction<TimeStep>) => {
state.currentTimeStep = action.payload state.currentTimeStep = action.payload
if (state.currentTimeStep === TimeStep.YEAR) { if (state.currentTimeStep === TimeStep.YEAR) {
state.showCompare = false state.showCompare = false
} }
}, },
setLoading: (state, action: SetLoading) => { setLoading: (state, action: PayloadAction<boolean>) => {
state.loading = action.payload state.loading = action.payload
}, },
setSelectedDate: (state, action: SetSelectedDate) => { setSelectedDate: (state, action: PayloadAction<DateTime>) => {
state.selectedDate = action.payload state.selectedDate = action.payload
}, },
setShowCompare: (state, action: SetShowCompare) => { setShowCompare: (state, action: PayloadAction<boolean>) => {
state.showCompare = action.payload state.showCompare = action.payload
}, },
setShowOfflineData: (state, action: SetShowOfflineData) => { setShowOfflineData: (state, action: PayloadAction<boolean>) => {
state.showOfflineData = action.payload state.showOfflineData = action.payload
}, },
}, },
......
...@@ -301,13 +301,11 @@ describe('globalSlice', () => { ...@@ -301,13 +301,11 @@ describe('globalSlice', () => {
it('should handle setLastEpglLogin', () => { it('should handle setLastEpglLogin', () => {
const state = globalSlice.reducer( const state = globalSlice.reducer(
mockGlobalState, mockGlobalState,
setLastEpglLogin({ setLastEpglLogin('1234567')
lastEpglLogin: 'username',
})
) )
expect(state).toEqual({ expect(state).toEqual({
...mockGlobalState, ...mockGlobalState,
lastEpglLogin: 'username', lastEpglLogin: '1234567',
}) })
}) })
......
/* eslint-disable camelcase */
import { PayloadAction, createSlice } from '@reduxjs/toolkit' import { PayloadAction, createSlice } from '@reduxjs/toolkit'
import { FluidSlugType, FluidState, FluidType, ScreenType, Usage } from 'enums' import { FluidSlugType, FluidState, FluidType, ScreenType, Usage } from 'enums'
import { import {
...@@ -121,45 +122,15 @@ const initialState: GlobalState = { ...@@ -121,45 +122,15 @@ const initialState: GlobalState = {
lastEpglLogin: '', lastEpglLogin: '',
} }
type ChangeScreenType = PayloadAction<ScreenType>
type SetPartnersInfo = PayloadAction<PartnersInfo>
type ToggleChallengeExplorationNotification = PayloadAction<boolean>
type ToggleChallengeActionNotification = PayloadAction<boolean>
type ToggleChallengeDuelNotification = PayloadAction<boolean>
type ToggleAnalysisNotification = PayloadAction<boolean>
type SetFluidStatus = PayloadAction<FluidStatus[]>
type UpdatedFluidConnection = PayloadAction<{ type UpdatedFluidConnection = PayloadAction<{
fluidType: FluidType fluidType: FluidType
fluidConnection: FluidConnection fluidConnection: FluidConnection
}> }>
type SetLastEpglLogin = PayloadAction<{
lastEpglLogin: string
}>
type UpdateTermValidation = PayloadAction<TermsStatus>
type ShowReleaseNote = PayloadAction<{ type ShowReleaseNote = PayloadAction<{
show: boolean show: boolean
notes: Notes[] notes: Notes[]
redirectLink?: string redirectLink?: string
}> }>
type SetShouldRefreshConsent = PayloadAction<boolean>
type SetSgeConnect = PayloadAction<SgeStore>
type UpdateEcogestureFilter = PayloadAction<Usage>
export type GlobalActionTypes =
| ChangeScreenType
| SetFluidStatus
| SetLastEpglLogin
| SetPartnersInfo
| SetSgeConnect
| SetShouldRefreshConsent
| ShowReleaseNote
| ToggleAnalysisNotification
| ToggleChallengeActionNotification
| ToggleChallengeDuelNotification
| ToggleChallengeExplorationNotification
| UpdatedFluidConnection
| UpdateEcogestureFilter
| UpdateTermValidation
const getFluidTypesFromStatus = (fluidStatus: FluidStatus[]): FluidType[] => { const getFluidTypesFromStatus = (fluidStatus: FluidStatus[]): FluidType[] => {
const fluidTypes: FluidType[] = [] const fluidTypes: FluidType[] = []
...@@ -182,45 +153,45 @@ export const globalSlice = createSlice({ ...@@ -182,45 +153,45 @@ export const globalSlice = createSlice({
name: 'global', name: 'global',
initialState, initialState,
reducers: { reducers: {
changeScreenType: (state, action: ChangeScreenType) => { changeScreenType: (state, action: PayloadAction<ScreenType>) => {
state.screenType = action.payload state.screenType = action.payload
}, },
toggleChallengeExplorationNotification: ( toggleChallengeExplorationNotification: (
state, state,
action: ToggleChallengeExplorationNotification action: PayloadAction<boolean>
) => { ) => {
state.challengeExplorationNotification = action.payload state.challengeExplorationNotification = action.payload
}, },
toggleChallengeActionNotification: ( toggleChallengeActionNotification: (
state, state,
action: ToggleChallengeActionNotification action: PayloadAction<boolean>
) => { ) => {
state.challengeActionNotification = action.payload state.challengeActionNotification = action.payload
}, },
toggleChallengeDuelNotification: ( toggleChallengeDuelNotification: (
state, state,
action: ToggleChallengeDuelNotification action: PayloadAction<boolean>
) => { ) => {
state.challengeDuelNotification = action.payload state.challengeDuelNotification = action.payload
}, },
toggleAnalysisNotification: (state, action: ToggleAnalysisNotification) => { toggleAnalysisNotification: (state, action: PayloadAction<boolean>) => {
state.analysisNotification = action.payload state.analysisNotification = action.payload
}, },
setFluidStatus: (state, action: SetFluidStatus) => { setFluidStatus: (state, action: PayloadAction<FluidStatus[]>) => {
state.fluidStatus = action.payload state.fluidStatus = action.payload
state.fluidTypes = getFluidTypesFromStatus(action.payload) state.fluidTypes = getFluidTypesFromStatus(action.payload)
}, },
updateTermsStatus: (state, action: UpdateTermValidation) => { updateTermsStatus: (state, action: PayloadAction<TermsStatus>) => {
state.termsStatus = action.payload state.termsStatus = action.payload
}, },
showReleaseNotes: (state, action: ShowReleaseNote) => { showReleaseNotes: (state, action: ShowReleaseNote) => {
state.releaseNotes = action.payload state.releaseNotes = action.payload
}, },
setPartnersInfo: (state, action: SetPartnersInfo) => { setPartnersInfo: (state, action: PayloadAction<PartnersInfo>) => {
state.partnersInfo = action.payload state.partnersInfo = action.payload
}, },
setShouldRefreshConsent: (state, action: SetShouldRefreshConsent) => { setShouldRefreshConsent: (state, action: PayloadAction<boolean>) => {
state.shouldRefreshConsent = action.payload state.shouldRefreshConsent = action.payload
}, },
updateFluidConnection: ( updateFluidConnection: (
...@@ -229,16 +200,13 @@ export const globalSlice = createSlice({ ...@@ -229,16 +200,13 @@ export const globalSlice = createSlice({
) => { ) => {
state.fluidStatus[fluidType].connection = fluidConnection state.fluidStatus[fluidType].connection = fluidConnection
}, },
setLastEpglLogin: ( setLastEpglLogin: (state, action: PayloadAction<string>) => {
state, state.lastEpglLogin = action.payload
{ payload: { lastEpglLogin } }: SetLastEpglLogin
) => {
state.lastEpglLogin = lastEpglLogin
}, },
updateSgeStore: (state, action: SetSgeConnect) => { updateSgeStore: (state, action: PayloadAction<SgeStore>) => {
state.sgeConnect = action.payload state.sgeConnect = action.payload
}, },
updateEcogestureFilter: (state, action: UpdateEcogestureFilter) => { updateEcogestureFilter: (state, action: PayloadAction<Usage>) => {
state.ecogestureFilter = action.payload state.ecogestureFilter = action.payload
}, },
}, },
......
import { Client } from 'cozy-client' // eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import { ThunkDispatch } from 'redux-thunk' import { AppDispatch, AppState } from './store'
import { AppActionsTypes, AppStore } from './store'
// Typed hooks // Typed hooks
// https://redux.js.org/tutorials/typescript-quick-start#define-typed-hooks // https://redux.js.org/tutorials/typescript-quick-start#define-typed-hooks
/** Combine classic actions and thunk actions */ export const useAppDispatch: () => AppDispatch = useDispatch
type TypedDispatch = ThunkDispatch< export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector
AppStore,
{ client: Client },
AppActionsTypes
>
export const useAppDispatch = () => useDispatch<TypedDispatch>()
// TODO maybe use AppEcolyoStore
export const useAppSelector: TypedUseSelectorHook<AppStore> = useSelector
...@@ -17,34 +17,26 @@ const initialState: ModalState = { ...@@ -17,34 +17,26 @@ const initialState: ModalState = {
}, },
} }
type OpenFeedbackModalAction = PayloadAction<boolean>
type OpenConnectionModalAction = PayloadAction<boolean>
type OpenPartnersModalAction = PayloadAction<{ type OpenPartnersModalAction = PayloadAction<{
egl: boolean egl: boolean
enedis: boolean enedis: boolean
grdf: boolean grdf: boolean
}> }>
type SetCustomPopup = PayloadAction<CustomPopup>
export type ModalActionTypes =
| OpenFeedbackModalAction
| OpenPartnersModalAction
| SetCustomPopup
export const modalSlice = createSlice({ export const modalSlice = createSlice({
name: 'modal', name: 'modal',
initialState, initialState,
reducers: { reducers: {
openFeedbackModal: (state, action: OpenFeedbackModalAction) => { openFeedbackModal: (state, action: PayloadAction<boolean>) => {
state.isFeedbacksOpen = action.payload state.isFeedbacksOpen = action.payload
}, },
openPartnersModal: (state, action: OpenPartnersModalAction) => { openPartnersModal: (state, action: OpenPartnersModalAction) => {
state.partnersIssueModal = action.payload state.partnersIssueModal = action.payload
}, },
openConnectionModal: (state, action: OpenConnectionModalAction) => { openConnectionModal: (state, action: PayloadAction<boolean>) => {
state.isConnectionModalOpen = action.payload state.isConnectionModalOpen = action.payload
}, },
setCustomPopup: (state, action: SetCustomPopup) => { setCustomPopup: (state, action: PayloadAction<CustomPopup>) => {
state.customPopupModal = action.payload state.customPopupModal = action.payload
}, },
}, },
......
...@@ -3,7 +3,7 @@ import { Client } from 'cozy-client' ...@@ -3,7 +3,7 @@ import { Client } from 'cozy-client'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import { Profile } from 'models' import { Profile } from 'models'
import ProfileService from 'services/profile.service' import ProfileService from 'services/profile.service'
import { AppDispatch, AppStore } from 'store/store' import { AppDispatch, AppState } from 'store/store'
const initialState: Profile = { const initialState: Profile = {
id: '', id: '',
...@@ -67,7 +67,7 @@ export const profileSlice = createSlice({ ...@@ -67,7 +67,7 @@ export const profileSlice = createSlice({
export const updateProfile = createAsyncThunk< export const updateProfile = createAsyncThunk<
Profile | void, Profile | void,
Partial<Profile>, Partial<Profile>,
{ dispatch: AppDispatch; state: AppStore; extra: { client: Client } } { dispatch: AppDispatch; state: AppState; extra: { client: Client } }
>('profile/updateProfile', async (profileUpdates, thunkAPI) => { >('profile/updateProfile', async (profileUpdates, thunkAPI) => {
const client = thunkAPI.extra.client const client = thunkAPI.extra.client
const profileService = new ProfileService(client) const profileService = new ProfileService(client)
......
...@@ -3,7 +3,7 @@ import { Client } from 'cozy-client' ...@@ -3,7 +3,7 @@ import { Client } from 'cozy-client'
import { PROFILEECOGESTURE_DOCTYPE } from 'doctypes' import { PROFILEECOGESTURE_DOCTYPE } from 'doctypes'
import { IndividualOrCollective, WarmingType } from 'enums' import { IndividualOrCollective, WarmingType } from 'enums'
import { ProfileEcogesture } from 'models' import { ProfileEcogesture } from 'models'
import { AppDispatch, AppStore } from 'store/store' import { AppDispatch, AppState } from 'store/store'
const initialState: ProfileEcogesture = { const initialState: ProfileEcogesture = {
heating: IndividualOrCollective.INDIVIDUAL, heating: IndividualOrCollective.INDIVIDUAL,
...@@ -12,15 +12,11 @@ const initialState: ProfileEcogesture = { ...@@ -12,15 +12,11 @@ const initialState: ProfileEcogesture = {
equipments: [], equipments: [],
} }
type UpdateProfileEcogesture = PayloadAction<ProfileEcogesture>
export type ProfileEcogestureActionTypes = UpdateProfileEcogesture
export const profileEcogestureSlice = createSlice({ export const profileEcogestureSlice = createSlice({
name: 'profileEcogesture', name: 'profileEcogesture',
initialState, initialState,
reducers: { reducers: {
setProfileEcogesture: (state, action: UpdateProfileEcogesture) => { setProfileEcogesture: (state, action: PayloadAction<ProfileEcogesture>) => {
Object.assign(state, action.payload) Object.assign(state, action.payload)
}, },
}, },
...@@ -40,7 +36,7 @@ export const { setProfileEcogesture } = profileEcogestureSlice.actions ...@@ -40,7 +36,7 @@ export const { setProfileEcogesture } = profileEcogestureSlice.actions
export const newProfileEcogestureEntry = createAsyncThunk< export const newProfileEcogestureEntry = createAsyncThunk<
ProfileEcogesture | void, ProfileEcogesture | void,
Partial<ProfileEcogesture>, Partial<ProfileEcogesture>,
{ dispatch: AppDispatch; state: AppStore; extra: { client: Client } } { dispatch: AppDispatch; state: AppState; extra: { client: Client } }
>('profileEcogesture/newProfileEcogesture', async (updates, thunkAPI) => { >('profileEcogesture/newProfileEcogesture', async (updates, thunkAPI) => {
const client = thunkAPI.extra.client const client = thunkAPI.extra.client
const { data: newProfileEcogesture } = await client.create( const { data: newProfileEcogesture } = await client.create(
......