Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist state data #55

Merged
merged 4 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .env.development
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
REACT_APP_STROMAE_BACK_OFFICE_API_BASE_URL=https://stromae-edt-kc.demo.insee.io/
REACT_APP_EDT_ORGANISATION_API_BASE_URL=https://edt-api-kc.demo.insee.io/
REACT_APP_STROMAE_BACK_OFFICE_API_BASE_URL=https://edt-stromae-v2-api.demo.insee.io/
REACT_APP_EDT_ORGANISATION_API_BASE_URL=https://edt-api.demo.insee.io/
REACT_APP_KEYCLOAK_AUTHORITY=https://auth.demo.insee.io/auth/realms/questionnaires-edt/
REACT_APP_KEYCLOAK_CLIENT_ID=client-edt
REACT_APP_KEYCLOAK_REDIRECT_URI=http://localhost:3000/
Expand All @@ -10,4 +10,4 @@ REACT_APP_CHROMIUM_PATH=node_modules/chromium/lib/chromium/chrome-win/chrome.exe
REACT_APP_NUM_ACTIVITY_SURVEYS=6
REACT_APP_NUM_WORKTIME_SURVEYS=3
REACT_APP_REVIEWER_ROLE=edt-reviewer
REACT_APP_SURVEYED_ROLE=repondant_coleman
REACT_APP_SURVEYED_ROLE=repondant_coleman
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"typescript": "^4.8.3"
},
"scripts": {
"start": "react-scripts start",
"start": "NODE_OPTIONS=--openssl-legacy-provider react-scripts start",
"build": "react-scripts --max_old_space_size=4096 build",
"build:staging": "env-cmd -f .env.staging react-scripts --max_old_space_size=4096 build",
"build:production": "env-cmd -f .env.production react-scripts --max_old_space_size=4096 build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ const onFinish = (
) => {
if (closed) {
const data = setValue(idSurvey, FieldNameEnum.ISCLOSED, true);
saveData(idSurvey, data ?? callbackHolder.getData(), false, true).then(() => {
saveData(idSurvey, { ...data, ...callbackHolder.getData() }, false, true).then(() => {
navigate(
getCurrentNavigatePath(
idSurvey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const ActivityDurationPage = () => {
}

if ((skip && isAfter) || !isAfter) {
saveDataLocally(idSurvey, callbackHolder.getData()).then(() => {
saveDataLocally(idSurvey, { ...context.data, ...callbackHolder.getData() }).then(() => {
navigate(
getLoopParameterizedNavigatePath(
idSurvey,
Expand Down
13 changes: 4 additions & 9 deletions src/pages/end-survey/EndSurvey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,12 @@ const EndSurveyPage = () => {
const handleError = () => {
setErrorSubmit(true);
};
if (!isDemoMode && navigator.onLine) {
if (isReviewer()) {
return remotePutSurveyDataReviewer(idSurvey, stateData, surveyData.data)
.then(navToHome)
.catch(handleError);
} else {
return remotePutSurveyData(idSurvey, surveyData).then(navToHome).catch(handleError);
}
} else {
if (isDemoMode) {
return saveDataAndInit(surveyData, true);
}
saveData(idSurvey, { ...surveyData.data, stateData: stateData }, false, true)
.then(navToHome)
.catch(handleError);
}, []);

const onPrevious = useCallback(() => {
Expand Down
48 changes: 16 additions & 32 deletions src/service/api-service/getRemoteData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { StateData, SurveyData, UserSurveys } from "interface/entity/Api";
import { LunaticData, ReferentielData, SourceData } from "interface/lunatic/Lunatic";
import { initStateData, initSurveyData } from "../survey-service";
import { getUserToken, isReviewer } from "../user-service";
import { AuthContextProps } from "oidc-react";
import { NomenclatureActivityOption } from "@inseefrlab/lunatic-edt";
import { ReferentielsEnum } from "enumerations/ReferentielsEnum";
import { revertTransformedArray } from "utils/utils";

Expand Down Expand Up @@ -35,14 +33,9 @@ export const getHeader = (origin?: string, userToken?: string) => {
};
};

const fetchRemoteReferentiel = (auth: AuthContextProps, idReferentiel: ReferentielsEnum) => {
return axios.get<NomenclatureActivityOption[]>(
stromaeBackOfficeApiBaseUrl + "api/nomenclature/" + idReferentiel,
getHeader(stromaeBackOfficeApiBaseUrl),
);
};

const fetchRemoteReferentiels = (setError: (error: ErrorCodeEnum) => void): Promise<ReferentielData> => {
export const fetchRemoteReferentiels = (
setError: (error: ErrorCodeEnum) => void,
): Promise<ReferentielData> => {
let refs: ReferentielData = {
[ReferentielsEnum.ACTIVITYNOMENCLATURE]: [],
[ReferentielsEnum.ACTIVITYAUTOCOMPLETE]: [],
Expand Down Expand Up @@ -86,7 +79,9 @@ const fetchRemoteReferentiels = (setError: (error: ErrorCodeEnum) => void): Prom
});
};

const fetchUserSurveysInfo = (setError: (error: ErrorCodeEnum) => void): Promise<UserSurveys[]> => {
export const fetchUserSurveysInfo = (
setError: (error: ErrorCodeEnum) => void,
): Promise<UserSurveys[]> => {
return new Promise(resolve => {
axios
.get(
Expand All @@ -107,7 +102,7 @@ const fetchUserSurveysInfo = (setError: (error: ErrorCodeEnum) => void): Promise
});
};

const fetchSurveysSourcesByIds = (
export const fetchSurveysSourcesByIds = (
sourcesIds: string[],
setError: (error: ErrorCodeEnum) => void,
): Promise<SourceData> => {
Expand Down Expand Up @@ -140,7 +135,9 @@ const fetchSurveysSourcesByIds = (
});
};

const fetchReviewerSurveysAssignments = (setError: (error: ErrorCodeEnum) => void): Promise<any> => {
export const fetchReviewerSurveysAssignments = (
setError: (error: ErrorCodeEnum) => void,
): Promise<any> => {
return new Promise(resolve => {
axios
.get(
Expand All @@ -160,7 +157,7 @@ const fetchReviewerSurveysAssignments = (setError: (error: ErrorCodeEnum) => voi
});
};

const remoteGetSurveyData = (
export const remoteGetSurveyData = (
idSurvey: string,
setError?: (error: ErrorCodeEnum) => void,
): Promise<SurveyData> => {
Expand Down Expand Up @@ -192,7 +189,7 @@ const remoteGetSurveyData = (
});
};

const remoteGetSurveyStateData = (
export const remoteGetSurveyStateData = (
idSurvey: string,
setError?: (error: ErrorCodeEnum) => void,
): Promise<StateData> => {
Expand All @@ -215,7 +212,7 @@ const remoteGetSurveyStateData = (
});
});
};
const remoteGetSurveyDataSurveyed = (
export const remoteGetSurveyDataSurveyed = (
idSurvey: string,
setError: (error: ErrorCodeEnum) => void,
): Promise<SurveyData> => {
Expand All @@ -232,7 +229,7 @@ const remoteGetSurveyDataSurveyed = (
});
};

const requestGetDataReviewer = (
export const requestGetDataReviewer = (
idSurvey: string,
setError: (error: ErrorCodeEnum) => void,
): Promise<LunaticData> => {
Expand Down Expand Up @@ -269,7 +266,7 @@ const requestGetDataReviewer = (
});
};

const requestGetSurveyDataReviewer = (
export const requestGetSurveyDataReviewer = (
idSurvey: string,
setError: (error: ErrorCodeEnum) => void,
): Promise<SurveyData> => {
Expand All @@ -286,7 +283,7 @@ const requestGetSurveyDataReviewer = (
});
};

const remoteGetSurveyDataReviewer = (
export const remoteGetSurveyDataReviewer = (
idSurvey: string,
setError: (error: ErrorCodeEnum) => void,
): Promise<SurveyData> => {
Expand All @@ -308,16 +305,3 @@ const remoteGetSurveyDataReviewer = (
return Promise.reject(err);
});
};

export {
fetchRemoteReferentiel,
fetchRemoteReferentiels,
fetchReviewerSurveysAssignments,
fetchSurveysSourcesByIds,
fetchUserSurveysInfo,
remoteGetSurveyData,
requestGetDataReviewer,
remoteGetSurveyStateData,
remoteGetSurveyDataReviewer,
remoteGetSurveyDataSurveyed,
};
22 changes: 6 additions & 16 deletions src/service/api-service/putRemoteData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import jwt, { JwtPayload } from "jwt-decode";
import { logout } from "service/auth-service";
import { transformCollectedArray } from "utils/utils";

const requestPutSurveyData = (
export const requestPutSurveyData = (
idSurvey: string,
data: SurveyData,
token?: string,
Expand Down Expand Up @@ -44,7 +44,7 @@ const requestPutSurveyData = (
});
};

const remotePutSurveyData = (idSurvey: string, data: SurveyData): Promise<SurveyData> => {
export const remotePutSurveyData = (idSurvey: string, data: SurveyData): Promise<SurveyData> => {
const now = new Date();
const tokenExpiresAt = jwt<JwtPayload>(getUserToken() ?? "").exp;
// * 1000 because tokenExpiresAt is in seconds and now.getTime() in milliseconds
Expand All @@ -64,7 +64,7 @@ const remotePutSurveyData = (idSurvey: string, data: SurveyData): Promise<Survey
}
};

const remotePutSurveyDataReviewer = (
export const remotePutSurveyDataReviewer = (
idSurvey: string,
stateData: StateData,
data: LunaticData,
Expand All @@ -88,7 +88,7 @@ const remotePutSurveyDataReviewer = (
}
};

const requestPutDataReviewer = (
export const requestPutDataReviewer = (
idSurvey: string,
data: LunaticData,
token?: string,
Expand All @@ -112,7 +112,7 @@ const requestPutDataReviewer = (
});
};

const requestPutStateReviewer = (
export const requestPutStateReviewer = (
idSurvey: string,
data: StateData,
token?: string,
Expand Down Expand Up @@ -140,7 +140,7 @@ const requestPutStateReviewer = (
});
};

const requestPutSurveyDataReviewer = (
export const requestPutSurveyDataReviewer = (
idSurvey: string,
data: LunaticData,
stateData: StateData,
Expand All @@ -155,13 +155,3 @@ const requestPutSurveyDataReviewer = (
return surveyData;
});
};

export {
remotePutSurveyData,
remotePutSurveyDataReviewer,
requestPutSurveyData,
requestPutDataReviewer,
requestPutStateReviewer,
requestPutSurveyDataReviewer,
transformCollectedArray,
};
56 changes: 33 additions & 23 deletions src/service/lunatic-database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ export interface LunaticDatabase {
clear(): Promise<void>;
}

class LunaticDatabaseImpl extends Dexie implements LunaticDatabase {
/**
* Database implementation that stores data in IndexedDB using Dexie
*/
class LunaticIndexedDB extends Dexie implements LunaticDatabase {
lunaticData!: Dexie.Table<LunaticData, string>;

public constructor() {
Expand All @@ -31,7 +34,10 @@ class LunaticDatabaseImpl extends Dexie implements LunaticDatabase {
}
}

class MemoryLunaticDatabaseImpl implements LunaticDatabase {
/**
* In-Memory database implementation, used as a fallback if Dexie fails to initialize
*/
class LunaticMemoryDB implements LunaticDatabase {
lunaticData = new Map<string, LunaticData>();

public save(id: string, data: LunaticData): Promise<string> {
Expand All @@ -49,35 +55,39 @@ class MemoryLunaticDatabaseImpl implements LunaticDatabase {
}
}

class PromiseProxyLunaticDatabaseImpl implements LunaticDatabase {
lunaticDatabasePromise = new Map<string, LunaticData>();
constructor(private promise: Promise<LunaticDatabase>) {}
/**
* Proxy the calls to the right database implementation according to browser support
*/
class BrowserDatabase implements LunaticDatabase {
private db: Promise<LunaticDatabase>;

constructor() {
this.db = new Promise(resolve => {
const database = new LunaticIndexedDB();
database
.get("")
.then(() => resolve(database))
.catch(e => {
console.warn(
"- Dexie will not work in this environment. We will use a memory database.",
);
console.debug(e);
resolve(new LunaticMemoryDB());
});
});
}

public save(id: string, data: LunaticData): Promise<string> {
return lunaticDatabasePromise.then(database => database.save(id, data));
return this.db.then(database => database.save(id, data));
}

public get(id: string): Promise<LunaticData | undefined> {
return lunaticDatabasePromise.then(database => database.get(id));
return this.db.then(database => database.get(id));
}

public clear(): Promise<void> {
return lunaticDatabasePromise.then(database => database.clear());
return this.db.then(database => database.clear());
}
}

// this is somewhat complexe as browser sometime cannot work with dexie in private mode
export const lunaticDatabasePromise = new Promise<LunaticDatabase>(resolve => {
// validate dexie is working on this computer
const database = new LunaticDatabaseImpl();
database
.get("")
.then(() => resolve(database))
.catch(e => {
console.warn("- Dexie will not work in this environment. We will use a memory database.");
console.debug(e);
resolve(new MemoryLunaticDatabaseImpl());
});
});

export const lunaticDatabase = new PromiseProxyLunaticDatabaseImpl(lunaticDatabasePromise);
export const lunaticDatabase = new BrowserDatabase();
Loading
Loading