diff --git a/package.json b/package.json index 0c4b3f448..573267680 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pearl", - "version": "2.3.3", + "version": "2.4.0", "private": true, "dependencies": { "@emotion/react": "^11.11.1", @@ -12,8 +12,8 @@ "@mui/styles": "^5.15.10", "@mui/x-date-pickers": "^6.18.6", "date-fns": "^2.30.0", - "dexie": "^3.2.1", - "dexie-react-hooks": "^1.1.1", + "dexie": "^4.0.9", + "dexie-react-hooks": "^1.1.7", "keycloak-js": "^26.0.5", "postcss": "8.4.31", "react": "^18.2.0", diff --git a/src/types/pearl.d.ts b/src/types/pearl.d.ts deleted file mode 100644 index a083508aa..000000000 --- a/src/types/pearl.d.ts +++ /dev/null @@ -1,145 +0,0 @@ -export {}; - -declare global { - type SurveyUnitPhoneNumber = { - source: string; - favorite: boolean; - number: string; - }; - - type SurveyUnitPerson = { - id: number; - title: string; - firstName: string; - lastName: string; - email: string; - birthdate: number; - favoriteEmail: boolean; - privileged: boolean; - phoneNumbers: SurveyUnitPhoneNumber[]; - }; - - type SurveyUnitAddress = { - l1: string; - l2: string; - l3: string; - l4: string; - l5: string; - l6: string; - l7: string; - elevator: boolean; - building: string; - floor: string; - door: string; - staircase: string; - cityPriorityDistrict: boolean; - }; - - type SurveyUnitComment = { - type: string; - value: string; - }; - - type SurveyUnitState = { - id: number; - date: number; - type: string; - }; - - type SurveyUnitSampleIdentifiers = { - bs: number; - ec: string; - le: number; - noi: number; - numfa: number; - rges: number; - ssech: number; - nolog: number; - nole: number; - autre: string; - nograp: string; - }; - - type SurveyUnitIdentification = { - identification: unknown; - access: unknown; - situation: unknown; - category: unknown; - occupant: unknown; - }; - - type SurveyUnitContactAttempt = { - status: string; - date: number; - medium: string; - }; - - type SurveyUnitCommunicationRequest = { - emitter: 'INTERVIEWER' | 'TOOL'; - communicationTemplateId?: string; - reason?: string; - status: { date: number; status: string }[]; - }; - - type SurveyUnitNewCommunicationRequest = { - communicationTemplateId: string; - reason: string; - creationTimestamp: number; - }; - - type SurveyUnitCommunicationTemplate = { - medium: string; - reason: string; - type: string; - id: string; - }; - - type SurveyUnit = { - displayName: string; - id: string; - persons: SurveyUnitPerson[]; - address: SurveyUnitAddress; - priority: boolean; - move: boolean; - campaign: string; - comments: SurveyUnitComment[]; - sampleIdentifiers: SurveyUnitSampleIdentifiers; - states: SurveyUnitState[]; - contactAttempts: SurveyUnitContactAttempt[]; - contactOutcome?: { date: number; totalNumberOfContactAttempts: number; type: string }; - identification: SurveyUnitIdentification; - campaignLabel: string; - managementStartDate: number; - interviewerStartDate: number; - identificationPhaseStartDate: number; - collectionStartDate: number; - collectionEndDate: number; - endDate: number; - identificationConfiguration: string; - contactOutcomeConfiguration: string; - contactAttemptConfiguration: string; - useLetterCommunication: boolean; - communicationRequests: SurveyUnitCommunicationRequest[]; - communicationTemplates: SurveyUnitCommunicationTemplate[]; - }; - - type Notification = { - date: number; - type: string; - title: string; - messages: string[]; - state: 'warning' | 'success' | 'error'; - read: boolean; - detail: string; - id: number; - }; - - type SyncResult = { - state: string; - messages: string[]; - details: { - transmittedSurveyUnits: Record; - loadedSurveyUnits: Record; - }; - }; -} diff --git a/src/types/pearl.ts b/src/types/pearl.ts new file mode 100644 index 000000000..d77cee74c --- /dev/null +++ b/src/types/pearl.ts @@ -0,0 +1,141 @@ +type SurveyUnitPhoneNumber = { + source: string; + favorite: boolean; + number: string; +}; + +type SurveyUnitPerson = { + id: number; + title: string; + firstName: string; + lastName: string; + email: string; + birthdate: number; + favoriteEmail: boolean; + privileged: boolean; + phoneNumbers: SurveyUnitPhoneNumber[]; +}; + +type SurveyUnitAddress = { + l1: string; + l2: string; + l3: string; + l4: string; + l5: string; + l6: string; + l7: string; + elevator: boolean; + building: string; + floor: string; + door: string; + staircase: string; + cityPriorityDistrict: boolean; +}; + +type SurveyUnitComment = { + type: string; + value: string; +}; + +type SurveyUnitState = { + id: number; + date: number; + type: string; +}; + +type SurveyUnitSampleIdentifiers = { + bs: number; + ec: string; + le: number; + noi: number; + numfa: number; + rges: number; + ssech: number; + nolog: number; + nole: number; + autre: string; + nograp: string; +}; + +type SurveyUnitIdentification = { + identification: unknown; + access: unknown; + situation: unknown; + category: unknown; + occupant: unknown; +}; + +type SurveyUnitContactAttempt = { + status: string; + date: number; + medium: string; +}; + +type SurveyUnitCommunicationRequest = { + emitter: 'INTERVIEWER' | 'TOOL'; + communicationTemplateId?: string; + reason?: string; + status: { date: number; status: string }[]; +}; + +type SurveyUnitNewCommunicationRequest = { + communicationTemplateId: string; + reason: string; + creationTimestamp: number; +}; + +type SurveyUnitCommunicationTemplate = { + medium: string; + reason: string; + type: string; + id: string; +}; + +export type SurveyUnit = { + displayName: string; + id: string; + persons: SurveyUnitPerson[]; + address: SurveyUnitAddress; + priority: boolean; + move: boolean; + campaign: string; + comments: SurveyUnitComment[]; + sampleIdentifiers: SurveyUnitSampleIdentifiers; + states: SurveyUnitState[]; + contactAttempts: SurveyUnitContactAttempt[]; + contactOutcome?: { date: number; totalNumberOfContactAttempts: number; type: string }; + identification: SurveyUnitIdentification; + campaignLabel: string; + managementStartDate: number; + interviewerStartDate: number; + identificationPhaseStartDate: number; + collectionStartDate: number; + collectionEndDate: number; + endDate: number; + identificationConfiguration: string; + contactOutcomeConfiguration: string; + contactAttemptConfiguration: string; + useLetterCommunication: boolean; + communicationRequests: SurveyUnitCommunicationRequest[]; + communicationTemplates: SurveyUnitCommunicationTemplate[]; +}; + +export type Notification = { + date: number; + type: string; + title: string; + messages: string[]; + state: 'warning' | 'success' | 'error'; + read: boolean; + detail: string; + id: number; +}; + +export type SyncResult = { + state: string; + messages: string[]; + details: { + transmittedSurveyUnits: Record; + loadedSurveyUnits: Record; + }; +}; diff --git a/src/utils/indexeddb/idb-config.js b/src/utils/indexeddb/idb-config.ts similarity index 58% rename from src/utils/indexeddb/idb-config.js rename to src/utils/indexeddb/idb-config.ts index 13c3b1d5b..693ec1c82 100644 --- a/src/utils/indexeddb/idb-config.js +++ b/src/utils/indexeddb/idb-config.ts @@ -1,11 +1,23 @@ -import Dexie from 'dexie'; +import Dexie, { type EntityTable } from 'dexie'; import schema from './schema.json'; import schema2 from './schema-2.json'; import schema3 from './schema-3.json'; import schema4 from './schema-4.json'; import schema5 from './schema-5.json'; +import { User } from './model/user'; +import { SyncReport } from './model/syncReport'; +import { SurveyUnitMissing } from './model/surveyUnitMissing'; +import type { SurveyUnit, Notification } from '../../types/pearl'; -export const db = new Dexie('Pearl'); +export const db = new Dexie('Pearl') as Dexie & { + notification: EntityTable; + user: EntityTable; + syncReport: EntityTable; + surveyUnitMissing: EntityTable; + surveyUnit: EntityTable; +}; + +export type { User, SyncReport, Notification, SurveyUnitMissing, SurveyUnit }; db.version(1).stores(schema); // upgrade dataBase (please see https://dexie.org/docs/Tutorial/Design#database-versioning) diff --git a/src/utils/indexeddb/model/surveyUnitMissing.ts b/src/utils/indexeddb/model/surveyUnitMissing.ts new file mode 100644 index 000000000..ce400f1fc --- /dev/null +++ b/src/utils/indexeddb/model/surveyUnitMissing.ts @@ -0,0 +1,3 @@ +export type SurveyUnitMissing = { + id: string; +}; diff --git a/src/utils/indexeddb/model/syncReport.ts b/src/utils/indexeddb/model/syncReport.ts new file mode 100644 index 000000000..f6193045c --- /dev/null +++ b/src/utils/indexeddb/model/syncReport.ts @@ -0,0 +1,7 @@ +import { type SyncResult } from '../../../types/pearl'; + +export type SyncReport = { + id: string; + transmittedSurveyUnits: SyncResult['details']['transmittedSurveyUnits']; + loadedSurveyUnits: SyncResult['details']['loadedSurveyUnits']; +}; diff --git a/src/utils/indexeddb/model/user.ts b/src/utils/indexeddb/model/user.ts new file mode 100644 index 000000000..dbeb284b5 --- /dev/null +++ b/src/utils/indexeddb/model/user.ts @@ -0,0 +1,9 @@ +export type User = { + id: string; + civility: string; + email: string; + firstName: string; + lastName: string; + phoneNumber: string; + title: string; +}; diff --git a/src/utils/indexeddb/services/abstract-idb-service.js b/src/utils/indexeddb/services/abstract-idb-service.ts similarity index 59% rename from src/utils/indexeddb/services/abstract-idb-service.js rename to src/utils/indexeddb/services/abstract-idb-service.ts index ecfb17355..a0cc4ca25 100644 --- a/src/utils/indexeddb/services/abstract-idb-service.js +++ b/src/utils/indexeddb/services/abstract-idb-service.ts @@ -1,15 +1,20 @@ +import { type Table } from 'dexie'; import { db } from '../idb-config'; -export default class AbstractIdbService { - constructor(store) { - this.store = db[store]; +export type ID = string | number; + +export default class AbstractIdbService { + private store; + + constructor(store: keyof typeof db) { + this.store = db[store] as Table; } - get(id) { + get(id: ID) { return this.store.get({ id: Number(id) }); } - getById(id) { + getById(id: ID) { return this.store.get(id); } @@ -17,19 +22,19 @@ export default class AbstractIdbService { return this.store.toArray(); } - getAllSortedBy(indexedVariable) { + getAllSortedBy(indexedVariable: string | string[]) { return this.store.orderBy(indexedVariable).toArray(); } - insert(item) { + insert(item: T) { return this.store.add(item); } - update(item) { + update(item: T) { return this.store.put(item); } - delete(id) { + delete(id: ID) { return this.store.delete(id); } @@ -37,7 +42,7 @@ export default class AbstractIdbService { return this.store.clear(); } - async addOrUpdate(item) { + async addOrUpdate(item: T) { if (item.id) { if ((await this.store.get(item.id)) === undefined) { return this.insert(item); @@ -47,11 +52,11 @@ export default class AbstractIdbService { return 0; } - addAll(items) { + addAll(items: T[]) { return this.store.bulkPut(items); } - deleteByIds(ids) { + deleteByIds(ids: string[]) { return this.store.bulkDelete(ids); } } diff --git a/src/utils/indexeddb/services/notification-idb-service.js b/src/utils/indexeddb/services/notification-idb-service.ts similarity index 69% rename from src/utils/indexeddb/services/notification-idb-service.js rename to src/utils/indexeddb/services/notification-idb-service.ts index e70f20ce3..2598b25a3 100644 --- a/src/utils/indexeddb/services/notification-idb-service.js +++ b/src/utils/indexeddb/services/notification-idb-service.ts @@ -1,11 +1,12 @@ import AbstractIdbService from './abstract-idb-service'; +import { type Notification } from '../idb-config'; -class NotificationIdbService extends AbstractIdbService { +class NotificationIdbService extends AbstractIdbService { constructor() { super('notification'); } - async addOrUpdateNotif(item) { + async addOrUpdateNotif(item: Notification) { const { id } = item; /* prevent duplicated survey-unit */ if (id) { diff --git a/src/utils/indexeddb/services/surveyUnit-idb-service.js b/src/utils/indexeddb/services/surveyUnit-idb-service.ts similarity index 78% rename from src/utils/indexeddb/services/surveyUnit-idb-service.js rename to src/utils/indexeddb/services/surveyUnit-idb-service.ts index 5b578cd26..a668a6149 100644 --- a/src/utils/indexeddb/services/surveyUnit-idb-service.js +++ b/src/utils/indexeddb/services/surveyUnit-idb-service.ts @@ -1,16 +1,14 @@ import AbstractIdbService from './abstract-idb-service'; - -class SurveyUnitIdbService extends AbstractIdbService { +import { type SurveyUnit } from '../idb-config'; +class SurveyUnitIdbService extends AbstractIdbService { constructor() { super('surveyUnit'); } /** * Update or insert a surveyUnit if the ID is unknown - * @param {SurveyUnit} item - * @returns {Promise} */ - async addOrUpdateSU(item) { + async addOrUpdateSU(item: SurveyUnit) { const { id, ...other } = item; const surveyUnit = await this.getById(id); /* prevent duplicated survey-unit */ diff --git a/src/utils/indexeddb/services/surveyUnitMissing-idb-service.js b/src/utils/indexeddb/services/surveyUnitMissing-idb-service.ts similarity index 54% rename from src/utils/indexeddb/services/surveyUnitMissing-idb-service.js rename to src/utils/indexeddb/services/surveyUnitMissing-idb-service.ts index a2f20beaf..999b72c12 100644 --- a/src/utils/indexeddb/services/surveyUnitMissing-idb-service.js +++ b/src/utils/indexeddb/services/surveyUnitMissing-idb-service.ts @@ -1,6 +1,7 @@ +import { type SurveyUnitMissing } from '../idb-config'; import AbstractIdbService from './abstract-idb-service'; -class SurveyUnitMissingIdbService extends AbstractIdbService { +class SurveyUnitMissingIdbService extends AbstractIdbService { constructor() { super('surveyUnitMissing'); } diff --git a/src/utils/indexeddb/services/syncReport-idb-service.js b/src/utils/indexeddb/services/syncReport-idb-service.ts similarity index 67% rename from src/utils/indexeddb/services/syncReport-idb-service.js rename to src/utils/indexeddb/services/syncReport-idb-service.ts index d4edb049a..c53ee21a7 100644 --- a/src/utils/indexeddb/services/syncReport-idb-service.js +++ b/src/utils/indexeddb/services/syncReport-idb-service.ts @@ -1,11 +1,12 @@ import AbstractIdbService from './abstract-idb-service'; +import { type SyncReport } from '../idb-config'; -class SyncReportIdbService extends AbstractIdbService { +class SyncReportIdbService extends AbstractIdbService { constructor() { super('syncReport'); } - async addOrUpdateReport(item) { + async addOrUpdateReport(item: SyncReport) { const { id, ...other } = item; const report = await this.getById(id); if (report) { diff --git a/src/utils/indexeddb/services/user-idb-service.js b/src/utils/indexeddb/services/user-idb-service.ts similarity index 58% rename from src/utils/indexeddb/services/user-idb-service.js rename to src/utils/indexeddb/services/user-idb-service.ts index b63200ea5..15c39bc44 100644 --- a/src/utils/indexeddb/services/user-idb-service.js +++ b/src/utils/indexeddb/services/user-idb-service.ts @@ -1,6 +1,7 @@ import AbstractIdbService from './abstract-idb-service'; +import { type User } from '../idb-config'; -class UserIdbService extends AbstractIdbService { +class UserIdbService extends AbstractIdbService { constructor() { super('user'); } diff --git a/yarn.lock b/yarn.lock index e6dfd4c5e..1fb21bf8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2564,15 +2564,15 @@ dequal@^2.0.3: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -dexie-react-hooks@^1.1.1: +dexie-react-hooks@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/dexie-react-hooks/-/dexie-react-hooks-1.1.7.tgz#75bd92a609a7c3dc3643e2fd21e7db5df6df923b" integrity sha512-Lwv5W0Hk+uOW3kGnsU9GZoR1er1B7WQ5DSdonoNG+focTNeJbHW6vi6nBoX534VKI3/uwHebYzSw1fwY6a7mTw== -dexie@^3.2.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/dexie/-/dexie-3.2.4.tgz#b22a9729be1102acb2eee16102ea6e2bc76454cf" - integrity sha512-VKoTQRSv7+RnffpOJ3Dh6ozknBqzWw/F3iqMdsZg958R0AS8AnY9x9d1lbwENr0gzeGJHXKcGhAMRaqys6SxqA== +dexie@^4.0.9: + version "4.0.9" + resolved "https://registry.yarnpkg.com/dexie/-/dexie-4.0.9.tgz#8c4e827815a84ef4fdc6aa7923f89ea2cda87610" + integrity sha512-VQG1huEVSAdDZssb9Bb9mFy+d3jAE0PT4d1nIRYlT46ip1fzbs1tXi0SlUayRDgV3tTbJG8ZRqAo2um49gtynA== doctrine@^2.1.0: version "2.1.0"