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

Target

Select target project
  • web-et-numerique/factory/llle_project/ecolyo
1 result
Show changes
Showing
with 276 additions and 222 deletions
......@@ -41,20 +41,17 @@
text-align: center;
color: white;
}
.description {
display: none;
margin: 1.5rem 0.5rem 0.5rem 0.5rem;
text-align: left;
}
.block {
display: block !important;
}
.toggle-text {
.showMore {
text-align: center;
text-decoration: underline;
margin-top: 1.5rem;
cursor: pointer;
}
.longDescription {
margin: 1em 0.5rem;
text-align: left;
}
}
.buttons-selection {
width: 100%;
......
......@@ -21,6 +21,21 @@ describe('EcogestureSelectionDetail component', () => {
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 () => {
const wrapper = mount(
<EcogestureSelectionDetail
......
import { Button } from '@material-ui/core'
import { Button, Collapse } from '@material-ui/core'
import doingIcon from 'assets/icons/ico/doing-enabled.svg'
import objectiveIcon from 'assets/icons/ico/objective-enabled.svg'
import skipIcon from 'assets/icons/ico/skip-enabled.svg'
......@@ -23,6 +23,7 @@ const EcogestureSelectionDetail = ({
}: EcogestureSelectionDetailProps) => {
const { t } = useI18n()
const [ecogestureIcon, setEcogestureIcon] = useState<string>('')
const [showDetails, setShowDetails] = useState(false)
useEffect(() => {
let subscribed = true
......@@ -33,6 +34,7 @@ const EcogestureSelectionDetail = ({
}
}
getIcon()
setShowDetails(false)
return () => {
subscribed = false
}
......@@ -41,9 +43,25 @@ const EcogestureSelectionDetail = ({
return (
<div className="eg-selection-detail-container">
<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 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 className="buttons">
<Button
......
......@@ -44,39 +44,43 @@ exports[`EcogestureSelectionDetail component should be rendered correctly 1`] =
<div
className="content"
>
<StyledIcon
className="icon"
icon="test-file-stub"
size={240}
<div
className="iconContainer"
>
<Icon
aria-hidden={true}
<StyledIcon
className="icon"
icon="test-file-stub"
size={240}
spin={false}
>
<Component
<Icon
aria-hidden={true}
className="icon styles__icon___23x3R"
height={240}
style={Object {}}
width={240}
className="icon"
icon="test-file-stub"
size={240}
spin={false}
>
<svg
<Component
aria-hidden={true}
className="icon styles__icon___23x3R"
height={240}
style={Object {}}
width={240}
>
<use
xlinkHref="#test-file-stub"
/>
</svg>
</Component>
</Icon>
</StyledIcon>
<svg
aria-hidden={true}
className="icon styles__icon___23x3R"
height={240}
style={Object {}}
width={240}
>
<use
xlinkHref="#test-file-stub"
/>
</svg>
</Component>
</Icon>
</StyledIcon>
</div>
<div
className="text-22 title"
>
......@@ -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.
</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
className="buttons"
......
......@@ -2,41 +2,42 @@
@import 'src/styles/base/breakpoint';
.eg-selection-detail-container {
min-height: inherit;
display: flex;
flex-direction: column;
text-align: center;
color: $grey-bright;
padding: 0 1.5rem;
flex: 1;
max-height: calc(100vh - 60px - 72px - 0px);
.content {
display: flex;
gap: 0.5rem;
flex-direction: column;
flex: 1;
justify-content: center;
justify-content: flex-start;
align-items: center;
overflow-y: auto;
.title {
color: $soft-grey;
font-weight: 700;
}
.icon {
@media #{$phone} {
width: 50%;
height: 50%;
}
@media #{$small-phone} {
width: 30%;
height: 30%;
}
.iconContainer {
height: 240px;
}
.showMore {
text-align: center;
text-decoration: underline;
margin-top: 1rem;
cursor: pointer;
}
.text {
min-height: 4.875rem;
display: flex;
align-items: center;
margin: 0 1rem;
.longDescription {
margin: 1rem 0.5rem;
text-align: left;
}
}
.buttons {
......
......@@ -143,7 +143,7 @@ const FluidChart = ({ fluidType, setActive }: FluidChartProps) => {
const LastDataValid = () => (
<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', {
date: currentFluidStatus?.lastDataDate?.toFormat('dd/MM/yy') || '-',
})}
......
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 StyledIcon from 'components/CommonKit/Icon/StyledIcon'
import Loader from 'components/Loader/Loader'
......@@ -431,9 +432,9 @@ const DisplayAlreadyUpdatedToday = ({
const DisplayManualUpdate = () => {
const { t } = useI18n()
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
icon={warningWhite}
icon={warningDark}
size={36}
className="warning-icon"
role="img"
......
......@@ -27,6 +27,26 @@
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 {
color: $grey-bright;
}
......@@ -42,7 +62,7 @@
gap: 1rem;
button.btn-secondary-positive {
span:first-child {
color: $red-primary !important;
color: $white !important;
}
}
}
......@@ -7,6 +7,7 @@ import {
import chevronDown from 'assets/icons/ico/chevron-down.svg'
import ErrorNotif from 'assets/icons/ico/notif_error.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 classNames from 'classnames'
import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
......@@ -221,11 +222,7 @@ const KonnectorViewerCard = ({
// RESTORE LAST KNOWN CREDENTIALS
if (lastEpglLogin) {
dispatch(
setLastEpglLogin({
lastEpglLogin: lastEpglLogin,
})
)
dispatch(setLastEpglLogin(lastEpglLogin))
}
} else {
if (isSuccess && currentFluidStatus.lastDataDate === null) {
......@@ -385,6 +382,48 @@ const KonnectorViewerCard = ({
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(() => {
return (
<div className="konnector-icon">
......@@ -392,33 +431,15 @@ const KonnectorViewerCard = ({
icon={currentFluidStatus.connection.account ? iconType : OfflinePicto}
size={49}
/>
{currentFluidStatus.maintenance ? (
<StyledIcon
icon={PartnersIssueNotif}
size={24}
className="konnector-state-picto"
/>
) : (
(currentFluidStatus.status === FluidState.ERROR ||
isOutdatedData ||
currentFluidStatus.status === FluidState.ERROR_LOGIN_FAILED) &&
currentFluidStatus.connection.account && (
<StyledIcon
icon={ErrorNotif}
size={24}
className="konnector-state-picto"
/>
)
{getIconForStatus(
currentFluidStatus.status,
currentFluidStatus.maintenance,
currentFluidStatus.connection,
isOutdatedData
)}
</div>
)
}, [
currentFluidStatus.connection.account,
currentFluidStatus.maintenance,
currentFluidStatus.status,
iconType,
isOutdatedData,
])
}, [currentFluidStatus, iconType, isOutdatedData])
const displayKonnectorHeader = useCallback(() => {
if (currentFluidStatus.maintenance) {
......
......@@ -40,6 +40,12 @@ const Navbar = () => {
},
[client]
)
/** Return class "is-active" if pathname includes matcher */
const isActive = (matcher: string) => {
return pathname.includes(matcher) ? 'is-active' : ''
}
return (
<aside className="o-sidebar">
<nav role="navigation" aria-label="navigation">
......@@ -51,9 +57,7 @@ const Navbar = () => {
<Link
component={NavLink}
to="/consumption"
className={`c-nav-link ${
pathname.includes('/consumption') ? 'is-active' : ''
}`}
className={`c-nav-link ${isActive('/consumption')}`}
>
<StyledIcon className="c-nav-icon off" icon={ConsoIconOff} />
<StyledIcon className="c-nav-icon on" icon={ConsoIconOn} />
......@@ -64,9 +68,7 @@ const Navbar = () => {
<Link
component={NavLink}
to="/challenges"
className={`c-nav-link ${
pathname.includes('/challenges') ? 'is-active' : ''
}`}
className={`c-nav-link ${isActive('/challenges')}`}
>
{(challengeExplorationNotification ||
challengeActionNotification ||
......@@ -83,9 +85,7 @@ const Navbar = () => {
<Link
component={NavLink}
to="/ecogestures"
className={`c-nav-link ${
pathname.includes('/ecogestures') ? 'is-active' : ''
}`}
className={`c-nav-link ${isActive('/ecogesture')}`}
>
<StyledIcon className="c-nav-icon off" icon={BulbIconOff} />
<StyledIcon className="c-nav-icon on" icon={BulbIconOn} />
......@@ -110,9 +110,7 @@ const Navbar = () => {
<Link
component={NavLink}
to="/options"
className={`c-nav-link ${
pathname.includes('/options') ? 'is-active' : ''
}`}
className={`c-nav-link ${isActive('/options')}`}
>
<StyledIcon className="c-nav-icon off" icon={ParameterIconOff} />
<StyledIcon className="c-nav-icon on" icon={ParameterIconOn} />
......
......@@ -484,8 +484,8 @@
"title_ecogesture": "Astuce",
"title_action": "Action",
"efficiency": "Efficacité",
"show_less": "Voir moins d’infos",
"show_more": "Voir plus d’infos",
"show_less": "Voir moins",
"show_more": "Voir plus",
"select_action": "Je choisis cette action",
"accessibility": {
"window_title_ecogesture": "Fenêtre astuce",
......
......@@ -7,19 +7,14 @@ const initialState: AnalysisState = {
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({
name: 'analysis',
initialState,
reducers: {
setPeriod: (state, action: SetPeriodAction) => {
setPeriod: (state, action: PayloadAction<'month' | 'year'>) => {
state.period = action.payload
},
setAnalysisMonth: (state, action: SetSelectedMonthAction) => {
setAnalysisMonth: (state, action: PayloadAction<DateTime>) => {
state.analysisMonth = action.payload
},
},
......
......@@ -8,25 +8,16 @@ const initialState: ChallengeState = {
currentDataload: [],
}
type SetUserChallengeList = PayloadAction<UserChallenge[]>
type UpdateUserChallengeList = PayloadAction<UserChallenge>
type UnlockNextUserChallenge = PayloadAction<UserChallenge>
type SetChallengeConsumption = PayloadAction<{
userChallenge: UserChallenge
currentDataload: Dataload[]
}>
export type ChallengeActionTypes =
| SetUserChallengeList
| UpdateUserChallengeList
| UnlockNextUserChallenge
| SetChallengeConsumption
export const challengeSlice = createSlice({
name: 'challenge',
initialState,
reducers: {
setUserChallengeList: (state, action: SetUserChallengeList) => {
setUserChallengeList: (state, action: PayloadAction<UserChallenge[]>) => {
const filteredCurrentChallenge = action.payload.filter(
challenge =>
challenge.state === UserChallengeState.ONGOING ||
......@@ -37,7 +28,7 @@ export const challengeSlice = createSlice({
state.userChallengeList = action.payload
state.currentChallenge = currentChallenge
},
updateUserChallengeList: (state, action: UpdateUserChallengeList) => {
updateUserChallengeList: (state, action: PayloadAction<UserChallenge>) => {
const id = action.payload.id
const currentChallenge =
action.payload.state === UserChallengeState.ONGOING ||
......@@ -51,7 +42,7 @@ export const challengeSlice = createSlice({
state.userChallengeList = updatedList
state.currentChallenge = currentChallenge || state.currentChallenge
},
unlockNextUserChallenge: (state, action: UnlockNextUserChallenge) => {
unlockNextUserChallenge: (state, action: PayloadAction<UserChallenge>) => {
const id = action.payload.id
const updatedList = [...state.userChallengeList]
const findIndex = updatedList.findIndex(challenge => challenge.id === id)
......
......@@ -3,25 +3,6 @@ import { TimeStep } from 'enums'
import { DateTime } from 'luxon'
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 = {
selectedDate: DateTime.local().endOf('minute').setZone('utc', {
keepLocalTime: true,
......@@ -39,31 +20,31 @@ export const chartSlice = createSlice({
name: 'chart',
initialState,
reducers: {
setCurrentDataChart: (state, action: SetCurrentDataChart) => {
setCurrentDataChart: (state, action: PayloadAction<Datachart>) => {
state.currentDatachart = action.payload
},
setCurrentDataChartIndex: (state, action: SetCurrentDataChartIndex) => {
setCurrentDataChartIndex: (state, action: PayloadAction<number>) => {
state.currentDatachartIndex = action.payload
},
setCurrentIndex: (state, action: SetCurrentIndex) => {
setCurrentIndex: (state, action: PayloadAction<number>) => {
state.currentIndex = action.payload
},
setCurrentTimeStep: (state, action: SetCurrentTimeStep) => {
setCurrentTimeStep: (state, action: PayloadAction<TimeStep>) => {
state.currentTimeStep = action.payload
if (state.currentTimeStep === TimeStep.YEAR) {
state.showCompare = false
}
},
setLoading: (state, action: SetLoading) => {
setLoading: (state, action: PayloadAction<boolean>) => {
state.loading = action.payload
},
setSelectedDate: (state, action: SetSelectedDate) => {
setSelectedDate: (state, action: PayloadAction<DateTime>) => {
state.selectedDate = action.payload
},
setShowCompare: (state, action: SetShowCompare) => {
setShowCompare: (state, action: PayloadAction<boolean>) => {
state.showCompare = action.payload
},
setShowOfflineData: (state, action: SetShowOfflineData) => {
setShowOfflineData: (state, action: PayloadAction<boolean>) => {
state.showOfflineData = action.payload
},
},
......
......@@ -301,13 +301,11 @@ describe('globalSlice', () => {
it('should handle setLastEpglLogin', () => {
const state = globalSlice.reducer(
mockGlobalState,
setLastEpglLogin({
lastEpglLogin: 'username',
})
setLastEpglLogin('1234567')
)
expect(state).toEqual({
...mockGlobalState,
lastEpglLogin: 'username',
lastEpglLogin: '1234567',
})
})
......
/* eslint-disable camelcase */
import { PayloadAction, createSlice } from '@reduxjs/toolkit'
import { FluidSlugType, FluidState, FluidType, ScreenType, Usage } from 'enums'
import {
......@@ -121,45 +122,15 @@ const initialState: GlobalState = {
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<{
fluidType: FluidType
fluidConnection: FluidConnection
}>
type SetLastEpglLogin = PayloadAction<{
lastEpglLogin: string
}>
type UpdateTermValidation = PayloadAction<TermsStatus>
type ShowReleaseNote = PayloadAction<{
show: boolean
notes: Notes[]
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 fluidTypes: FluidType[] = []
......@@ -182,45 +153,45 @@ export const globalSlice = createSlice({
name: 'global',
initialState,
reducers: {
changeScreenType: (state, action: ChangeScreenType) => {
changeScreenType: (state, action: PayloadAction<ScreenType>) => {
state.screenType = action.payload
},
toggleChallengeExplorationNotification: (
state,
action: ToggleChallengeExplorationNotification
action: PayloadAction<boolean>
) => {
state.challengeExplorationNotification = action.payload
},
toggleChallengeActionNotification: (
state,
action: ToggleChallengeActionNotification
action: PayloadAction<boolean>
) => {
state.challengeActionNotification = action.payload
},
toggleChallengeDuelNotification: (
state,
action: ToggleChallengeDuelNotification
action: PayloadAction<boolean>
) => {
state.challengeDuelNotification = action.payload
},
toggleAnalysisNotification: (state, action: ToggleAnalysisNotification) => {
toggleAnalysisNotification: (state, action: PayloadAction<boolean>) => {
state.analysisNotification = action.payload
},
setFluidStatus: (state, action: SetFluidStatus) => {
setFluidStatus: (state, action: PayloadAction<FluidStatus[]>) => {
state.fluidStatus = action.payload
state.fluidTypes = getFluidTypesFromStatus(action.payload)
},
updateTermsStatus: (state, action: UpdateTermValidation) => {
updateTermsStatus: (state, action: PayloadAction<TermsStatus>) => {
state.termsStatus = action.payload
},
showReleaseNotes: (state, action: ShowReleaseNote) => {
state.releaseNotes = action.payload
},
setPartnersInfo: (state, action: SetPartnersInfo) => {
setPartnersInfo: (state, action: PayloadAction<PartnersInfo>) => {
state.partnersInfo = action.payload
},
setShouldRefreshConsent: (state, action: SetShouldRefreshConsent) => {
setShouldRefreshConsent: (state, action: PayloadAction<boolean>) => {
state.shouldRefreshConsent = action.payload
},
updateFluidConnection: (
......@@ -229,16 +200,13 @@ export const globalSlice = createSlice({
) => {
state.fluidStatus[fluidType].connection = fluidConnection
},
setLastEpglLogin: (
state,
{ payload: { lastEpglLogin } }: SetLastEpglLogin
) => {
state.lastEpglLogin = lastEpglLogin
setLastEpglLogin: (state, action: PayloadAction<string>) => {
state.lastEpglLogin = action.payload
},
updateSgeStore: (state, action: SetSgeConnect) => {
updateSgeStore: (state, action: PayloadAction<SgeStore>) => {
state.sgeConnect = action.payload
},
updateEcogestureFilter: (state, action: UpdateEcogestureFilter) => {
updateEcogestureFilter: (state, action: PayloadAction<Usage>) => {
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 { ThunkDispatch } from 'redux-thunk'
import { AppActionsTypes, AppStore } from './store'
import { AppDispatch, AppState } from './store'
// Typed hooks
// https://redux.js.org/tutorials/typescript-quick-start#define-typed-hooks
/** Combine classic actions and thunk actions */
type TypedDispatch = ThunkDispatch<
AppStore,
{ client: Client },
AppActionsTypes
>
export const useAppDispatch = () => useDispatch<TypedDispatch>()
// TODO maybe use AppEcolyoStore
export const useAppSelector: TypedUseSelectorHook<AppStore> = useSelector
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector
......@@ -17,34 +17,26 @@ const initialState: ModalState = {
},
}
type OpenFeedbackModalAction = PayloadAction<boolean>
type OpenConnectionModalAction = PayloadAction<boolean>
type OpenPartnersModalAction = PayloadAction<{
egl: boolean
enedis: boolean
grdf: boolean
}>
type SetCustomPopup = PayloadAction<CustomPopup>
export type ModalActionTypes =
| OpenFeedbackModalAction
| OpenPartnersModalAction
| SetCustomPopup
export const modalSlice = createSlice({
name: 'modal',
initialState,
reducers: {
openFeedbackModal: (state, action: OpenFeedbackModalAction) => {
openFeedbackModal: (state, action: PayloadAction<boolean>) => {
state.isFeedbacksOpen = action.payload
},
openPartnersModal: (state, action: OpenPartnersModalAction) => {
state.partnersIssueModal = action.payload
},
openConnectionModal: (state, action: OpenConnectionModalAction) => {
openConnectionModal: (state, action: PayloadAction<boolean>) => {
state.isConnectionModalOpen = action.payload
},
setCustomPopup: (state, action: SetCustomPopup) => {
setCustomPopup: (state, action: PayloadAction<CustomPopup>) => {
state.customPopupModal = action.payload
},
},
......
......@@ -3,7 +3,7 @@ import { Client } from 'cozy-client'
import { DateTime } from 'luxon'
import { Profile } from 'models'
import ProfileService from 'services/profile.service'
import { AppDispatch, AppStore } from 'store/store'
import { AppDispatch, AppState } from 'store/store'
const initialState: Profile = {
id: '',
......@@ -67,7 +67,7 @@ export const profileSlice = createSlice({
export const updateProfile = createAsyncThunk<
Profile | void,
Partial<Profile>,
{ dispatch: AppDispatch; state: AppStore; extra: { client: Client } }
{ dispatch: AppDispatch; state: AppState; extra: { client: Client } }
>('profile/updateProfile', async (profileUpdates, thunkAPI) => {
const client = thunkAPI.extra.client
const profileService = new ProfileService(client)
......
......@@ -3,7 +3,7 @@ import { Client } from 'cozy-client'
import { PROFILEECOGESTURE_DOCTYPE } from 'doctypes'
import { IndividualOrCollective, WarmingType } from 'enums'
import { ProfileEcogesture } from 'models'
import { AppDispatch, AppStore } from 'store/store'
import { AppDispatch, AppState } from 'store/store'
const initialState: ProfileEcogesture = {
heating: IndividualOrCollective.INDIVIDUAL,
......@@ -12,15 +12,11 @@ const initialState: ProfileEcogesture = {
equipments: [],
}
type UpdateProfileEcogesture = PayloadAction<ProfileEcogesture>
export type ProfileEcogestureActionTypes = UpdateProfileEcogesture
export const profileEcogestureSlice = createSlice({
name: 'profileEcogesture',
initialState,
reducers: {
setProfileEcogesture: (state, action: UpdateProfileEcogesture) => {
setProfileEcogesture: (state, action: PayloadAction<ProfileEcogesture>) => {
Object.assign(state, action.payload)
},
},
......@@ -40,7 +36,7 @@ export const { setProfileEcogesture } = profileEcogestureSlice.actions
export const newProfileEcogestureEntry = createAsyncThunk<
ProfileEcogesture | void,
Partial<ProfileEcogesture>,
{ dispatch: AppDispatch; state: AppStore; extra: { client: Client } }
{ dispatch: AppDispatch; state: AppState; extra: { client: Client } }
>('profileEcogesture/newProfileEcogesture', async (updates, thunkAPI) => {
const client = thunkAPI.extra.client
const { data: newProfileEcogesture } = await client.create(
......