From c616a2a202df6d3afedc0bcdc98074db34a65f58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20PAILHAREY?= <rpailharey@grandlyon.com>
Date: Wed, 7 Dec 2022 14:54:10 +0000
Subject: [PATCH] feat: optional redirection after migration release notes

---
 src/components/Home/ConsumptionView.spec.tsx  | 23 ++++++++++++++++
 src/components/Home/ConsumptionView.tsx       | 19 +++++++++-----
 ...NotesModal.scss => ReleaseNotesModal.scss} |  0
 ...seNotesModal.tsx => ReleaseNotesModal.tsx} |  8 +++---
 src/components/Splash/SplashRoot.tsx          |  6 ++++-
 src/migrations/migration.data.ts              |  1 +
 src/migrations/migration.service.ts           |  4 +++
 src/migrations/migration.type.ts              |  1 +
 src/models/releaseNotes.model.ts              |  1 +
 src/store/global/global.actions.ts            |  7 ++---
 src/store/global/global.reducer.ts            | 26 +++++++++----------
 tests/__mocks__/store.ts                      |  5 +++-
 12 files changed, 73 insertions(+), 28 deletions(-)
 rename src/components/Home/{releaseNotesModal.scss => ReleaseNotesModal.scss} (100%)
 rename src/components/Home/{releaseNotesModal.tsx => ReleaseNotesModal.tsx} (98%)

diff --git a/src/components/Home/ConsumptionView.spec.tsx b/src/components/Home/ConsumptionView.spec.tsx
index 63e4c5b66..9aae9a960 100644
--- a/src/components/Home/ConsumptionView.spec.tsx
+++ b/src/components/Home/ConsumptionView.spec.tsx
@@ -51,6 +51,7 @@ jest.mock(
   () => 'mock-partnersissuemodal'
 )
 jest.mock('components/CustomPopup/CustomPopupModal', () => 'mock-custompopup')
+jest.mock('components/Home/ReleaseNotesModal', () => 'mock-releasenotes')
 
 const useSelectorSpy = jest.spyOn(reactRedux, 'useSelector')
 const useDispatchSpy = jest.spyOn(reactRedux, 'useDispatch')
@@ -252,4 +253,26 @@ describe('ConsumptionView component', () => {
     )
     expect(wrapper.find('mock-custompopup').exists()).toBeTruthy()
   })
+  it('should render releaseNotesModal if releaseNotes.show is true', async () => {
+    const updatedStatus: FluidStatus[] =
+      mockInitialEcolyoState.global.fluidStatus
+    updatedStatus[0] = mockExpiredElec
+    useSelectorSpy.mockReturnValue({
+      currentTimeStep: TimeStep.WEEK,
+      loading: true,
+      fluidStatus: updatedStatus,
+      releaseNotes: {
+        show: true,
+        notes: [{ description: 'description', title: 'title' }],
+      },
+    })
+    useDispatchSpy.mockReturnValue(jest.fn())
+    mockUpdateProfile.mockResolvedValue(mockTestProfile1)
+    const wrapper = mount(
+      <Provider store={store}>
+        <ConsumptionView fluidType={FluidType.ELECTRICITY} />
+      </Provider>
+    )
+    expect(wrapper.find('mock-releasenotes').exists()).toBeTruthy()
+  })
 })
diff --git a/src/components/Home/ConsumptionView.tsx b/src/components/Home/ConsumptionView.tsx
index 0ca0095e6..ae00f2458 100644
--- a/src/components/Home/ConsumptionView.tsx
+++ b/src/components/Home/ConsumptionView.tsx
@@ -20,6 +20,7 @@ import KonnectorViewerList from 'components/Konnector/KonnectorViewerList'
 import Loader from 'components/Loader/Loader'
 import PartnersIssueModal from 'components/PartnersIssue/PartnersIssueModal'
 import { useClient } from 'cozy-client'
+import { useHistory } from 'react-router-dom'
 import ProfileService from 'services/profile.service'
 import { setCurrentTimeStep, setLoading } from 'store/chart/chart.actions'
 import {
@@ -32,13 +33,14 @@ import {
   getTodayDate,
   isKonnectorActive,
 } from 'utils/utils'
-import ReleaseNotesModal from './releaseNotesModal'
+import ReleaseNotesModal from './ReleaseNotesModal'
 interface ConsumptionViewProps {
   fluidType: FluidType
 }
 const ConsumptionView: React.FC<ConsumptionViewProps> = ({
   fluidType,
 }: ConsumptionViewProps) => {
+  const history = useHistory()
   const client = useClient()
   const dispatch = useDispatch()
   const isMulti = fluidType !== FluidType.MULTIFLUID
@@ -80,10 +82,15 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({
     setHeaderHeight(height)
   }, [])
 
-  const toggleReleaseNoteModal = useCallback(() => {
-    setOpenReleaseNoteModal(prev => !prev)
-    dispatch(showReleaseNotes(false, releaseNotes.notes))
-  }, [dispatch, releaseNotes.notes])
+  const handleCloseReleaseNoteModal = useCallback(() => {
+    setOpenReleaseNoteModal(false)
+    dispatch(
+      showReleaseNotes(false, releaseNotes.notes, releaseNotes.redirectLink)
+    )
+    if (releaseNotes.redirectLink) {
+      history.push(releaseNotes.redirectLink)
+    }
+  }, [dispatch, history, releaseNotes.notes, releaseNotes.redirectLink])
 
   const handleCloseModal = useCallback(async () => {
     const profileService = new ProfileService(client)
@@ -153,7 +160,7 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({
         {openReleaseNoteModal && (
           <ReleaseNotesModal
             open={openReleaseNoteModal}
-            handleCloseClick={toggleReleaseNoteModal}
+            handleCloseClick={handleCloseReleaseNoteModal}
           ></ReleaseNotesModal>
         )}
         {isFluidKonnected ? (
diff --git a/src/components/Home/releaseNotesModal.scss b/src/components/Home/ReleaseNotesModal.scss
similarity index 100%
rename from src/components/Home/releaseNotesModal.scss
rename to src/components/Home/ReleaseNotesModal.scss
diff --git a/src/components/Home/releaseNotesModal.tsx b/src/components/Home/ReleaseNotesModal.tsx
similarity index 98%
rename from src/components/Home/releaseNotesModal.tsx
rename to src/components/Home/ReleaseNotesModal.tsx
index dfd8fe168..507f38650 100644
--- a/src/components/Home/releaseNotesModal.tsx
+++ b/src/components/Home/ReleaseNotesModal.tsx
@@ -1,11 +1,11 @@
-import React from 'react'
-import { useI18n } from 'cozy-ui/transpiled/react/I18n'
 import Button from '@material-ui/core/Button'
-import './releaseNotesModal.scss'
 import Dialog from '@material-ui/core/Dialog'
-import { AppStore } from 'store'
+import { useI18n } from 'cozy-ui/transpiled/react/I18n'
+import React from 'react'
 import { useSelector } from 'react-redux'
+import { AppStore } from 'store'
 import { decoreText } from 'utils/decoreText'
+import './ReleaseNotesModal.scss'
 
 interface ReleaseNotesModalProps {
   open: boolean
diff --git a/src/components/Splash/SplashRoot.tsx b/src/components/Splash/SplashRoot.tsx
index 8d0cf4a26..46fbf3390 100644
--- a/src/components/Splash/SplashRoot.tsx
+++ b/src/components/Splash/SplashRoot.tsx
@@ -123,7 +123,11 @@ const SplashRoot = ({ fadeTimer = 1000, children }: SplashRootProps) => {
 
         // Init last release notes when they exist
         dispatch(
-          showReleaseNotes(migrationsResult.show, migrationsResult.notes)
+          showReleaseNotes(
+            migrationsResult.show,
+            migrationsResult.notes,
+            migrationsResult.redirectLink
+          )
         )
 
         //init Terms
diff --git a/src/migrations/migration.data.ts b/src/migrations/migration.data.ts
index ae4bcb41f..62fa67e93 100644
--- a/src/migrations/migration.data.ts
+++ b/src/migrations/migration.data.ts
@@ -542,6 +542,7 @@ export const migrations: Migration[] = [
       description:
         "Pour continuer à accéder à vos données d'électricité, merci de vous reconnecter via ce nouveau parcours. Aucune donnée ne sera perdue, et vos données seront à nouveau mises à jour quotidiennement. <p>Pourquoi ce changement ?</p> Pour faciliter l'accès aux données de consommation au plus grand nombre. Plus besoin de se créer un compte Enedis, l'accès aux données en est facilité. N'hésitez pas à en parler autour de vous ! :)",
     },
+    redirectLink: '/consumption/electricity',
     docTypes: '',
     run: async (): Promise<any> => {},
     isEmpty: true,
diff --git a/src/migrations/migration.service.ts b/src/migrations/migration.service.ts
index 32a7ca9ae..2e151a871 100644
--- a/src/migrations/migration.service.ts
+++ b/src/migrations/migration.service.ts
@@ -48,6 +48,7 @@ export class MigrationService {
           description: '',
         },
       ],
+      redirectLink: '',
     }
     const currentVersion = await this.currentSchemaVersion(this._client)
     const targetVersion = migrations[migrations.length - 1].targetSchemaVersion
@@ -86,6 +87,9 @@ export class MigrationService {
         ) {
           releaseNotes.notes.push(migration.releaseNotes)
           releaseStatus = true
+          if (migration.redirectLink) {
+            releaseNotes.redirectLink = migration.redirectLink
+          }
         }
       }
       releaseNotes.show = releaseStatus
diff --git a/src/migrations/migration.type.ts b/src/migrations/migration.type.ts
index b65e8c2d6..1ee3c9776 100644
--- a/src/migrations/migration.type.ts
+++ b/src/migrations/migration.type.ts
@@ -26,6 +26,7 @@ export type Migration = {
   targetSchemaVersion: SchemaVersion
   description: string
   releaseNotes: Notes | null
+  redirectLink?: string
   docTypes: string
   isCreate?: boolean
   isDeprecated?: boolean
diff --git a/src/models/releaseNotes.model.ts b/src/models/releaseNotes.model.ts
index 79c8688a9..a1253d369 100644
--- a/src/models/releaseNotes.model.ts
+++ b/src/models/releaseNotes.model.ts
@@ -1,6 +1,7 @@
 export interface ReleaseNotes {
   show: boolean
   notes: Notes[]
+  redirectLink?: string
 }
 
 export interface Notes {
diff --git a/src/store/global/global.actions.ts b/src/store/global/global.actions.ts
index 4e78d9a10..49af36746 100644
--- a/src/store/global/global.actions.ts
+++ b/src/store/global/global.actions.ts
@@ -63,7 +63,7 @@ interface UpdateTermValidation {
 
 interface ShowReleaseNotes {
   type: typeof SHOW_RELEASE_NOTES
-  payload?: { show: boolean; notes: Notes[] }
+  payload?: { show: boolean; notes: Notes[]; redirectLink?: string }
 }
 
 interface SetPartnersIssue {
@@ -109,11 +109,12 @@ export function changeScreenType(screenType: ScreenType): GlobalActionTypes {
 
 export function showReleaseNotes(
   show: boolean,
-  notes: Notes[]
+  notes: Notes[],
+  redirectLink?: string
 ): GlobalActionTypes {
   return {
     type: SHOW_RELEASE_NOTES,
-    payload: { show, notes },
+    payload: { show, notes, redirectLink },
   }
 }
 
diff --git a/src/store/global/global.reducer.ts b/src/store/global/global.reducer.ts
index 561a14768..855bf9ac1 100644
--- a/src/store/global/global.reducer.ts
+++ b/src/store/global/global.reducer.ts
@@ -1,24 +1,24 @@
+import { FluidState, FluidType } from 'enum/fluid.enum'
+import { FluidSlugType } from 'enum/fluidSlug.enum'
+import { ScreenType } from 'enum/screen.enum'
+import { FluidStatus, GlobalState } from 'models'
 import { Reducer } from 'redux'
 import {
   CHANGE_SCREEN_TYPE,
-  TOGGLE_CHALLENGE_EXPLORATION_NOTIFICATION,
-  TOGGLE_CHALLENGE_ACTION_NOTIFICATION,
-  TOGGLE_CHALLENGE_DUEL_NOTIFICATION,
-  TOGGLE_ANALYSIS_NOTIFICATION,
-  SET_FLUID_STATUS,
-  UPDATE_FLUID_CONNECTION,
   GlobalActionTypes,
-  UPDATE_TERMS_VALIDATION,
-  SHOW_RELEASE_NOTES,
+  SET_CUSTOM_POPUP,
+  SET_FLUID_STATUS,
   SET_PARTNERS_ISSUE,
   SET_SHOULD_REFRESH_CONSENT,
+  SHOW_RELEASE_NOTES,
+  TOGGLE_ANALYSIS_NOTIFICATION,
+  TOGGLE_CHALLENGE_ACTION_NOTIFICATION,
+  TOGGLE_CHALLENGE_DUEL_NOTIFICATION,
+  TOGGLE_CHALLENGE_EXPLORATION_NOTIFICATION,
+  UPDATE_FLUID_CONNECTION,
   UPDATE_SGE_CONNECT,
-  SET_CUSTOM_POPUP,
+  UPDATE_TERMS_VALIDATION,
 } from 'store/global/global.actions'
-import { FluidStatus, GlobalState } from 'models'
-import { ScreenType } from 'enum/screen.enum'
-import { FluidState, FluidType } from 'enum/fluid.enum'
-import { FluidSlugType } from 'enum/fluidSlug.enum'
 
 const initialState: GlobalState = {
   screenType: ScreenType.MOBILE,
diff --git a/tests/__mocks__/store.ts b/tests/__mocks__/store.ts
index 509c4242e..f6b9cea2d 100644
--- a/tests/__mocks__/store.ts
+++ b/tests/__mocks__/store.ts
@@ -45,7 +45,10 @@ export const mockInitialGlobalState: GlobalState = {
     description: '',
   },
   openPartnersIssueModal: false,
-  releaseNotes: { show: false, notes: [{ description: '', title: '' }] },
+  releaseNotes: {
+    show: false,
+    notes: [{ description: '', title: '' }],
+  },
   fluidStatus: [
     {
       fluidType: FluidType.ELECTRICITY,
-- 
GitLab