diff --git a/drama-queen/src/core/adapters/localSyncStorage/default.ts b/drama-queen/src/core/adapters/localSyncStorage/default.ts index 690ee6b2..306e554c 100644 --- a/drama-queen/src/core/adapters/localSyncStorage/default.ts +++ b/drama-queen/src/core/adapters/localSyncStorage/default.ts @@ -4,8 +4,6 @@ import type { } from "core/ports/LocalSyncStorage"; import { localStorageObjectSchema } from "./parser/localSyncObjectSchema"; -//const LOCALSTORAGE_KEY = "QUEEN_SYNC_RESULT"; - export function createLocalSyncStorage(params: { localStorageKey: string; }): LocalSyncStorage { @@ -26,7 +24,7 @@ export function createLocalSyncStorage(params: { if (serializedData === null) { return null; } - return localStorageObjectSchema.parse(serializedData); + return localStorageObjectSchema.parse(JSON.parse(serializedData)); } catch (error) { console.error("Error retrieving data from localStorage:", error); return null; @@ -38,40 +36,41 @@ export function createLocalSyncStorage(params: { getObject: getDataFromLocalStorage, addIdToSurveyUnitsSuccess: (id) => { const existingData = getDataFromLocalStorage(); - - if (existingData) { - existingData.surveyUnitsSuccess.push(id); - saveDataToLocalStorage(existingData); + if (existingData === null) { + return saveDataToLocalStorage({ + error: false, + surveyUnitsInTempZone: [], + surveyUnitsSuccess: [id], + }); } - saveDataToLocalStorage({ - error: false, - surveyUnitsInTempZone: [], - surveyUnitsSuccess: [id], - }); + existingData.surveyUnitsSuccess.push(id); + saveDataToLocalStorage(existingData); }, addIdToSurveyUnitsInTempZone: (id) => { const existingData = getDataFromLocalStorage(); - if (existingData) { - existingData.surveyUnitsInTempZone.push(id); - saveDataToLocalStorage(existingData); + if (existingData === null) { + return saveDataToLocalStorage({ + error: false, + surveyUnitsInTempZone: [id], + surveyUnitsSuccess: [], + }); } - saveDataToLocalStorage({ - error: false, - surveyUnitsInTempZone: [id], - surveyUnitsSuccess: [], - }); + + existingData.surveyUnitsInTempZone.push(id); + saveDataToLocalStorage(existingData); }, addError: (error) => { const existingData = getDataFromLocalStorage(); - if (existingData) { - saveDataToLocalStorage({ ...existingData, error: error }); + + if (existingData === null) { + return saveDataToLocalStorage({ + error: error, + surveyUnitsInTempZone: [], + surveyUnitsSuccess: [], + }); } - saveDataToLocalStorage({ - error: error, - surveyUnitsInTempZone: [], - surveyUnitsSuccess: [], - }); + saveDataToLocalStorage({ ...existingData, error: error }); }, } satisfies LocalSyncStorage; } diff --git a/drama-queen/src/core/usecases/synchronizeData/thunks.ts b/drama-queen/src/core/usecases/synchronizeData/thunks.ts index 94d3cdab..d8823cd5 100644 --- a/drama-queen/src/core/usecases/synchronizeData/thunks.ts +++ b/drama-queen/src/core/usecases/synchronizeData/thunks.ts @@ -6,7 +6,8 @@ export const thunks = { download: () => async (...args) => { - const [dispatch, getState, { queenApi, dataStore }] = args; + const [dispatch, getState, { queenApi, dataStore, localSyncStorage }] = + args; { const state = getState()[name]; @@ -38,8 +39,6 @@ export const thunks = { * SurveyUnit */ - const surveyUnitSuccess: string[] = []; - const prSurveyUnit = campaignsIds.map((campaignId) => queenApi .getSurveyUnitsIdsAndQuestionnaireIdsByCampaign(campaignId) @@ -55,7 +54,7 @@ export const thunks = { .getSurveyUnit(id) .then((surveyUnit) => dataStore.updateSurveyUnit(surveyUnit)) .then(() => { - surveyUnitSuccess.push(id); + localSyncStorage.addIdToSurveyUnitsSuccess(id); dispatch(actions.downloadSurveyUnitCompleted()); }) ) @@ -65,7 +64,6 @@ export const thunks = { await Promise.all(prSurveyUnit); - //TODO -> Save surveyUnitSuccess /* * Survey */ @@ -79,7 +77,6 @@ export const thunks = { return questionnaire; }) .catch(() => { - //TODO Handle error console.error( ` Questionnaire : An error occurred and we were unable to retrieve survey ${questionnaireId}` ); @@ -111,7 +108,6 @@ export const thunks = { queenApi .getNomenclature(nomenclatureId) .catch(() => { - //TODO Handle Errors console.error( `Nomenclature : An error occurred and we were unable to retrieve nomenclature ${nomenclatureId}` ); @@ -125,7 +121,8 @@ export const thunks = { upload: () => async (...args) => { - const [dispatch, getState, { dataStore, queenApi }] = args; + const [dispatch, getState, { dataStore, queenApi, localSyncStorage }] = + args; { const state = getState()[name]; @@ -137,10 +134,16 @@ export const thunks = { dispatch(actions.runningUpload()); + // If localStorageData exists, we refresh it; otherwise, we initialize it. + localSyncStorage.saveObject({ + error: false, + surveyUnitsInTempZone: [], + surveyUnitsSuccess: [], + }); + try { const prSurveyUnits = dataStore.getAllSurveyUnits(); const surveyUnits = await prSurveyUnits; - const surveyUnitsInTemp: string[] = []; if (surveyUnits) { dispatch(actions.setUploadTotal({ total: surveyUnits.length ?? 0 })); @@ -155,31 +158,36 @@ export const thunks = { ) { return queenApi .postSurveyUnitInTemp(surveyUnit) - .then(() => surveyUnitsInTemp.push(surveyUnit.id)); - } else { - throw error; + .then(() => + localSyncStorage.addIdToSurveyUnitsInTempZone( + surveyUnit.id + ) + ) + .catch((postError: Error) => { + console.error( + "Error: Unable to post surveyUnit in tempZone", + postError + ); + throw postError; + }); } + throw error; }) - .then((result) => { - return dataStore.deleteSurveyUnit(surveyUnit.id); - }) + .then(() => dataStore.deleteSurveyUnit(surveyUnit.id)) .then(() => { dispatch(actions.uploadSurveyUnitCompleted()); }) .catch((error) => { - // TODO: Handle the error as needed -> Save LocalStorage - console.error(error); - dispatch(actions.uploadError()); + console.error("Error: Unable to upload data", error); + throw error; }) ); await Promise.all(surveyUnitPromises); } - dispatch(actions.uploadCompleted()); dispatch(thunks.download()); } catch (error) { - // TODO : Handle errors from prSurveyUnits - console.error(error); + localSyncStorage.addError(true); dispatch(actions.uploadError()); } }, diff --git a/drama-queen/src/hooks/useTranslate.ts b/drama-queen/src/hooks/useTranslate.ts index 0be68e14..1aa7063e 100644 --- a/drama-queen/src/hooks/useTranslate.ts +++ b/drama-queen/src/hooks/useTranslate.ts @@ -1,16 +1,17 @@ const texts = { - "sync": "Synchronisation en cours", + sync: "Synchronisation en cours", "sync.download": "Téléchargement des données...", "sync.download.surveyUnits": "Unités enquêtées", "sync.download.nomenclatures": "Nomenclatures", "sync.download.questionnaires": "Questionnaires", "sync.upload": "Envoi des données", + vizu: "Page de visualisation de questionnaire", } as const; const getTranslation = (s: keyof typeof texts) => texts[s] ?? s; export function useTranslate() { return { - __: getTranslation, + t: getTranslation, }; } diff --git a/drama-queen/src/ui/pages/queenMapping/SurveyUnitMapping.tsx b/drama-queen/src/ui/pages/queenMapping/SurveyUnitMapping.tsx index 8e72b7f9..a2a0eb38 100644 --- a/drama-queen/src/ui/pages/queenMapping/SurveyUnitMapping.tsx +++ b/drama-queen/src/ui/pages/queenMapping/SurveyUnitMapping.tsx @@ -1,6 +1,4 @@ -import { db } from 'core/indexedDb' -import { Navigate, useParams } from 'react-router-dom' -import { useLiveQuery } from "dexie-react-hooks"; +import { useParams } from 'react-router-dom' import { READ_ONLY } from "ui/constants"; type Params = { @@ -11,13 +9,6 @@ type Params = { export function SurveyUnitMapping() { const { readonly, id } = useParams(); - const surveyUnit = useLiveQuery( - () => db.surveyUnit.get({ id: id }), [id] - ) - - if (!surveyUnit) return
In Progress
- - - return
Survey Unit Mapping id : {id}, readonly : {JSON.stringify(surveyUnit)}
+ return
Survey Unit Mapping id : {id}
} diff --git a/drama-queen/src/ui/pages/queenMapping/VisualisationMapping.tsx b/drama-queen/src/ui/pages/queenMapping/VisualisationMapping.tsx index 82220472..fd7cd206 100644 --- a/drama-queen/src/ui/pages/queenMapping/VisualisationMapping.tsx +++ b/drama-queen/src/ui/pages/queenMapping/VisualisationMapping.tsx @@ -10,7 +10,6 @@ export function VisualisationMapping() { useEffect(() => { isQueenV2Survey(questionnaireUrl).then((r) => { - console.log("response", r); setIsQueenV2(r); setIsSurveyFetched(true); }).catch((e) => { diff --git a/drama-queen/src/ui/pages/synchronize-old/SynchronizePage.tsx b/drama-queen/src/ui/pages/synchronize-old/SynchronizePage.tsx deleted file mode 100644 index 808aac53..00000000 --- a/drama-queen/src/ui/pages/synchronize-old/SynchronizePage.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import LinearProgress from '@mui/material/LinearProgress'; -import Typography from '@mui/material/Typography'; -import Stack from '@mui/material/Stack'; -import { useTranslate } from "hooks/useTranslate"; -import preloader from 'ui/assets/preloader.svg'; -import { tss } from "tss-react/mui"; -import { Fragment, useEffect, useState } from "react"; -import { type PullData, usePullData } from 'hooks/usePullData'; -import { SyncError } from "hooks/queries/SyncError"; -import { storeSyncProgress } from "./storeSyncProgress"; -import { db } from 'core/indexedDb'; - -type SyncState = "Idle" | "Push" | "Pull" | "End"; - - -export const SynchronizePage = () => { - const { classes } = useStyles(); - const [state, setState] = useState("Pull") - - useEffect(() => { - storeSyncProgress() - }, []); - - const handlePullEnd = (data: PullData, errors: SyncError[]) => { - storeSyncProgress( - data, - errors - ) - db.surveyUnit.bulkAdd(data.surveyUnits); - setState("End") - } - - return - {state !== 'End' && } - {state === "Pull" && } - {state === "End" &&

Finished pulling data

} -
; -} - -const IndexProgress = () => { - return <>Index -} - -type DownloadProgressProps = { - onEnd: (data: PullData, errors: SyncError[]) => void -} - -const PullProgress = ({ onEnd }: DownloadProgressProps) => { - const { __ } = useTranslate(); - const { classes } = useStyles(); - const { progress, data, errors, status } = usePullData({ - onEnd: onEnd - }); - const progressBars = [{ - progress: progress.surveyUnits, - label: __('sync.surveyUnits') - }, - { - progress: progress.nomenclatures, - label: __('sync.nomenclatures') - }, - { - progress: progress.questionnaires, - label: __('sync.questionnaires') - }] - .filter(bar => bar.progress !== null) - - return <> - - {__('sync.progress')} - {__('sync.download')} - - - {progressBars.map(bar => - - - {bar.label} - - - )} - - -} - -const useStyles = tss - .create(() => ({ - lightText: { - opacity: .75, - }, - spinner: { - width: 200, - height: 200 - }, - progressBar: { - maxWidth: 700, - width: '80vw', - height: 10, - borderRadius: 10 - } - })); diff --git a/drama-queen/src/ui/pages/synchronize-old/index.ts b/drama-queen/src/ui/pages/synchronize-old/index.ts deleted file mode 100644 index 04ce3209..00000000 --- a/drama-queen/src/ui/pages/synchronize-old/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./SynchronizePage"; diff --git a/drama-queen/src/ui/pages/synchronize-old/storeSyncProgress.ts b/drama-queen/src/ui/pages/synchronize-old/storeSyncProgress.ts deleted file mode 100644 index 52237a56..00000000 --- a/drama-queen/src/ui/pages/synchronize-old/storeSyncProgress.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { SyncError } from "hooks/queries/SyncError"; -import { type PullData } from "hooks/usePullData"; - -const LOCALSTORAGE_KEY = "QUEEN_SYNC_RESULT"; - -type Store = - | { - error: boolean; - errors: string[]; - surveyUnitsSuccess: string[]; - surveyUnitsInTempZone: string[]; - } - | { error: "pending" }; - -/** - * Store progress in the localStorage so pearl can track the sync state - */ -export const storeSyncProgress = ( - data: PullData | null = null, - errors: SyncError[] = [] -) => { - if (data === null) { - window.localStorage.setItem( - LOCALSTORAGE_KEY, - JSON.stringify({ error: "pending" } satisfies Store) - ); - return; - } - window.localStorage.setItem( - LOCALSTORAGE_KEY, - JSON.stringify({ - error: false, - errors: errors.map((e) => e.title), - surveyUnitsSuccess: data.surveyUnits.map((s) => s.id), - surveyUnitsInTempZone: [], - } satisfies Store) - ); -}; diff --git a/drama-queen/src/ui/pages/synchronize/LoadingDisplay.tsx b/drama-queen/src/ui/pages/synchronize/LoadingDisplay.tsx index c391c1d0..21ca6731 100644 --- a/drama-queen/src/ui/pages/synchronize/LoadingDisplay.tsx +++ b/drama-queen/src/ui/pages/synchronize/LoadingDisplay.tsx @@ -16,12 +16,12 @@ type LoadingDisplayProps = { export function LoadingDisplay(props: LoadingDisplayProps) { const { syncStepTitle, progressBars } = props - const { __ } = useTranslate(); + const { t } = useTranslate(); const { classes } = useStyles(); return ( - {__('sync')} + {t('sync')} {syncStepTitle} @@ -29,8 +29,8 @@ export function LoadingDisplay(props: LoadingDisplayProps) { {bar.label !== undefined && - {bar.label}} + {bar.label}} diff --git a/drama-queen/src/ui/pages/synchronize/SynchronizeData.tsx b/drama-queen/src/ui/pages/synchronize/SynchronizeData.tsx index a42cd58a..12817ba6 100644 --- a/drama-queen/src/ui/pages/synchronize/SynchronizeData.tsx +++ b/drama-queen/src/ui/pages/synchronize/SynchronizeData.tsx @@ -5,7 +5,7 @@ import { useTranslate } from "hooks/useTranslate"; import { LoadingDisplay } from "./LoadingDisplay"; export function SynchronizeData() { - const { __ } = useTranslate(); + const { t } = useTranslate(); const { hideProgress, @@ -39,10 +39,6 @@ export function SynchronizeData() { [] ); - useEffect(() => { - console.log("surveyUnitProgress", surveyUnitProgress) - }, [surveyUnitProgress]); - if (hideProgress) { return null; } @@ -54,23 +50,23 @@ export function SynchronizeData() { progress: uploadProgress, label: undefined } - ]} syncStepTitle={__("sync.upload")} />} + ]} syncStepTitle={t("sync.upload")} />} {isDownloading && } ) } \ No newline at end of file diff --git a/drama-queen/src/ui/pages/visualize/Visualize.tsx b/drama-queen/src/ui/pages/visualize/Visualize.tsx new file mode 100644 index 00000000..47860597 --- /dev/null +++ b/drama-queen/src/ui/pages/visualize/Visualize.tsx @@ -0,0 +1,21 @@ +import { Container, Typography } from "@mui/material" +import { useTranslate } from "hooks/useTranslate" +import { tss } from "tss-react/mui"; +export function Visualize() { + const { t } = useTranslate() + const { classes } = useStyles() + return ( + + {t("vizu")} + + ) +} + + +const useStyles = tss.create( + () => ({ + title: { + textAlign: 'center', + } + }) +) \ No newline at end of file diff --git a/drama-queen/src/ui/queenApi.tsx b/drama-queen/src/ui/queenApi.tsx deleted file mode 100644 index 3c7204bd..00000000 --- a/drama-queen/src/ui/queenApi.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { ReactNode, createContext, useContext, useMemo, useRef } from "react"; -import { useGuaranteedMemo } from "hooks/tools/useGuaranteedMemo"; -import { QueenApi } from "core/ports/QueenApi"; - -const context = createContext(undefined); - -export function useQueenApi() { - const queenApi = useContext(context); - if (queenApi === undefined) throw new Error("This hook can not be used outside ApiProvider children") - return queenApi; -} - - -export function createQueenApiProvider( - params: { - apiUrl?: string; - } -) { - - const { apiUrl } = params; - - function QueenApiProvider(props: { - children: ReactNode; - }) { - const { children } = props; - - const apiClient = undefined; - - return {children}; - } - - return { QueenApiProvider }; - -} - diff --git a/drama-queen/src/ui/routing/routes.tsx b/drama-queen/src/ui/routing/routes.tsx index dde236be..fbff622a 100644 --- a/drama-queen/src/ui/routing/routes.tsx +++ b/drama-queen/src/ui/routing/routes.tsx @@ -2,10 +2,10 @@ import { DisplayEnvValues } from "ui/pages/env"; import { SurveyUnitMapping, VisualisationMapping } from "ui/pages/queenMapping"; import { READ_ONLY } from "ui/constants"; import type { RouteObject } from "react-router-dom"; -import { SynchronizePage as SynchronizeOld } from "ui/pages/synchronize-old/SynchronizePage"; import { SurveyMapping } from "ui/pages/queenMapping/SuryveyMapping"; import { RequiresAuthentication } from "ui/auth"; import { SynchronizeData } from "ui/pages/synchronize/SynchronizeData"; +import { Visualize } from "ui/pages/visualize/Visualize"; //ReadOnly path is a bad pattern must be change (affects pearl,moog,queen) export const routes: RouteObject[] = [ @@ -23,7 +23,7 @@ export const routes: RouteObject[] = [ }, { path: "/visualize/*", - element: + element: }, { path: "/synchronize",