diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index c8ff0a1e..23fa6a53 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,7 +1,7 @@ name: Deploy Documentation on: push: - branches: ["main", "2.*"] + branches: ['main', '2.*'] paths: - website/** @@ -16,7 +16,7 @@ permissions: id-token: write concurrency: - group: "pages" + group: 'pages' cancel-in-progress: false jobs: diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..72c8d15c --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +yarn test && yarn lint-staged diff --git a/.prettierrc b/.prettierrc index e9c9f029..8296facc 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,11 +1,8 @@ { "semi": false, "singleQuote": true, - "trailingComma": "es5", - "printWidth": 80, - "tabWidth": 2, - "jsxSingleQuote": false, - "jsxBracketSameLine": false, - "arrowParens": "always", - "endOfLine": "lf" + "plugins": ["@trivago/prettier-plugin-sort-imports"], + "importOrder": ["^react$", "^@/(.*)$", "^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true } diff --git a/build/remote-env.cjs b/build/remote-env.cjs index cb7c8230..e9e0aff4 100644 --- a/build/remote-env.cjs +++ b/build/remote-env.cjs @@ -13,7 +13,7 @@ log.blue(`MFE manage env for remote (micro-frontend)`) const nameOfMfeEnv = 'swEnv.js' const entryScriptPath = path.resolve( - `${process.cwd()}/dist/assets/${process.argv[2]}` + `${process.cwd()}/dist/assets/${process.argv[2]}`, ) const swEnvScriptPath = path.resolve(`${process.cwd()}/dist/${nameOfMfeEnv}`) @@ -27,6 +27,6 @@ if (isSwEnvScriptExists && isEntryScriptExists) { log.green(`✓ Added env file inside ${entryScriptPath}`) } else { log.red( - `x Nothing to do. Are you using vite-envs and federation plugin in your configuration vite.config.ts ?` + `x Nothing to do. Are you using vite-envs and federation plugin in your configuration vite.config.ts ?`, ) } diff --git a/eslint.config.js b/eslint.config.js index fa3faf3a..3e55efcd 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,30 +1,45 @@ +import js from '@eslint/js' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' import globals from 'globals' -import pluginJs from '@eslint/js' import tseslint from 'typescript-eslint' -import pluginReact from 'eslint-plugin-react' -import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' -export default [ - { files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] }, - { languageOptions: { globals: globals.browser } }, - pluginJs.configs.recommended, - ...tseslint.configs.recommended, - pluginReact.configs.flat['jsx-runtime'], - eslintPluginPrettierRecommended, +export default tseslint.config( { - settings: { react: { version: '18.3' } }, - rules: { - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-empty-object-type': 'off', - }, + ignores: ['dist', 'src/vite-env.d.ts'], + }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['src/**/*.{ts,tsx}'], languageOptions: { + ecmaVersion: 2020, globals: { + ...globals.browser, + ...globals.worker, importScripts: 'readonly', workbox: 'readonly', }, + parserOptions: { + project: './tsconfig.json', + }, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + // see https://typescript-eslint.netlify.app/rules/no-unused-vars/ + '@typescript-eslint/no-unused-vars': [ + 'error', + { argsIgnorePattern: '^_' }, + ], + '@typescript-eslint/no-explicit-any': ['off'], + '@typescript-eslint/no-namespace': ['off'], + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], }, }, -] +) diff --git a/index.html b/index.html index 904abf66..261380a4 100644 --- a/index.html +++ b/index.html @@ -1,23 +1,23 @@ - + + + + + + + + + + - - - - - - - - - + Questionnaire enquêteur + - - Questionnaire enquêteur - - - -
- - - - \ No newline at end of file + +
+ + + diff --git a/package.json b/package.json index 8035dcab..ac47aeec 100644 --- a/package.json +++ b/package.json @@ -5,16 +5,18 @@ "type": "module", "scripts": { "dev": "vite --port 5001 --strictPort", - "test": "vitest", + "test": "vitest run", + "test:watch": "vitest", "test:coverage": "vitest --coverage", "build": "tsc && vite build", "postbuild": "node build/remote-env.cjs remoteEntry.js", "preview": "vite preview --port 5001 --strictPort", - "_format": "prettier 'src/**/*.{ts,tsx,js,jsx,json,md}'", + "_format": "prettier --ignore-unknown .", "format": "npm run _format -- --write", - "lint": "eslint src/", "format:check": "npm run _format -- --list-different", - "stop": "kill-port --port 5000,5001,5002" + "lint": "eslint ./src", + "stop": "kill-port --port 5000,5001,5002", + "prepare": "husky" }, "dependencies": { "@emotion/react": "^11.11.4", @@ -41,31 +43,40 @@ "zod": "^3.22.4" }, "devDependencies": { + "@eslint/js": "^9.16.0", "@originjs/vite-plugin-federation": "^1.2.3", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.1", - "@eslint/js": "^9.13.0", + "@trivago/prettier-plugin-sort-imports": "^5.2.0", "@types/node": "^20.16.10", "@types/react": "^18.3.10", "@types/react-dom": "^18.2.22", "@vitejs/plugin-react": "^4.3.2", "@vitest/coverage-v8": "^2.1.3", - "jsdom": "^25.0.1", - "eslint": "^9.13.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-react": "^7.37.2", + "eslint": "^9.16.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.16", "globals": "^15.11.0", + "husky": "^9.1.7", + "jsdom": "^25.0.1", "kill-port": "^2.0.1", + "lint-staged": "^15.2.11", "prettier": "^3.2.5", "ts-node": "^10.9.2", "typescript": "^5.6.2", - "typescript-eslint": "^8.11.0", + "typescript-eslint": "^8.18.0", "vite": "^5.4.8", "vite-envs": "^4.4.5", "vite-plugin-pwa": "^0.19.8", "vite-tsconfig-paths": "^4.3.2", "vitest": "^2.1.3" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "eslint --fix", + "prettier --write --list-different" + ], + "!(*.js|*.jsx|*.ts|*.tsx)": "prettier --write --ignore-unknown --list-different" } } diff --git a/src/bootstrap.tsx b/src/bootstrap.tsx index e0f95d68..9c4e36b7 100644 --- a/src/bootstrap.tsx +++ b/src/bootstrap.tsx @@ -1,9 +1,10 @@ import { createRoot } from 'react-dom/client' import { RouterProvider } from 'react-router-dom' -import { unsubscribeOldSW } from 'unsubscribe_old_sw' -import { CoreProvider } from 'createCore' -import { createRouter, type RoutingStrategy } from 'ui/routing/createRouter' -import { CenteredSpinner } from 'ui/components/CenteredSpinner' + +import { CoreProvider } from '@/createCore' +import { CenteredSpinner } from '@/ui/components/CenteredSpinner' +import { type RoutingStrategy, createRouter } from '@/ui/routing/createRouter' +import { unsubscribeOldSW } from '@/unsubscribe_old_sw' const mount = ({ mountPoint, @@ -24,7 +25,7 @@ const mount = ({ root.render( }> - + , ) return () => queueMicrotask(() => root.unmount()) diff --git a/src/core/adapters/datastore/default.ts b/src/core/adapters/datastore/default.ts index 10ebde7f..d8640a31 100644 --- a/src/core/adapters/datastore/default.ts +++ b/src/core/adapters/datastore/default.ts @@ -1,7 +1,8 @@ -import type { Paradata, SurveyUnit } from 'core/model' -import type { DataStore } from 'core/ports/DataStore' import Dexie, { type Table } from 'dexie' +import type { Paradata, SurveyUnit } from '@/core/model' +import type { DataStore } from '@/core/ports/DataStore' + type Tables = { surveyUnit: Table paradata: Table diff --git a/src/core/adapters/localSyncStorage/default.ts b/src/core/adapters/localSyncStorage/default.ts index 902d5b5b..5e6b7fe9 100644 --- a/src/core/adapters/localSyncStorage/default.ts +++ b/src/core/adapters/localSyncStorage/default.ts @@ -1,7 +1,8 @@ import type { LocalStorageObject, LocalSyncStorage, -} from 'core/ports/LocalSyncStorage' +} from '@/core/ports/LocalSyncStorage' + import { localStorageObjectSchema } from './parser/localSyncObjectSchema' export function createLocalSyncStorage(params: { diff --git a/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.test.ts b/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.test.ts index 791df49b..b18f48df 100644 --- a/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.test.ts +++ b/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'vitest' + import { localStorageObjectSchema } from './localSyncObjectSchema' describe('localStorageObjectSchema', () => { diff --git a/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.ts b/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.ts index 52ddbe5d..6df1a86a 100644 --- a/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.ts +++ b/src/core/adapters/localSyncStorage/parser/localSyncObjectSchema.ts @@ -1,7 +1,8 @@ -import type { LocalStorageObject } from 'core/ports/LocalSyncStorage' import { type Equals, assert } from 'tsafe' import { z } from 'zod' +import type { LocalStorageObject } from '@/core/ports/LocalSyncStorage' + export const localStorageObjectSchema = z.object({ error: z.boolean(), surveyUnitsSuccess: z.array(z.string()), diff --git a/src/core/adapters/oidc/default.ts b/src/core/adapters/oidc/default.ts index 1d67dba1..b302066e 100644 --- a/src/core/adapters/oidc/default.ts +++ b/src/core/adapters/oidc/default.ts @@ -1,5 +1,7 @@ -import type { Oidc } from 'core/ports/Oidc' import { createOidc as createOidcSpa } from 'oidc-spa' + +import type { Oidc } from '@/core/ports/Oidc' + import { getMockedOidc } from './mock' export function createOidc(params: { diff --git a/src/core/adapters/oidc/mock.ts b/src/core/adapters/oidc/mock.ts index 0dc13b3f..9c2f16e2 100644 --- a/src/core/adapters/oidc/mock.ts +++ b/src/core/adapters/oidc/mock.ts @@ -1,6 +1,7 @@ -import type { Oidc } from 'core/ports/Oidc' import { id } from 'tsafe/id' +import type { Oidc } from '@/core/ports/Oidc' + export function createOidc(params: { isUserLoggedIn: boolean }): () => Promise { diff --git a/src/core/adapters/queenApi/default.ts b/src/core/adapters/queenApi/default.ts index 6fcb2b37..64726bd1 100644 --- a/src/core/adapters/queenApi/default.ts +++ b/src/core/adapters/queenApi/default.ts @@ -1,4 +1,5 @@ import axios, { AxiosError } from 'axios' + import type { Campaign, IdAndQuestionnaireId, @@ -6,9 +7,10 @@ import type { Questionnaire, RequiredNomenclatures, SurveyUnit, -} from 'core/model' -import type { QueenApi } from 'core/ports/QueenApi' -import { handleAxiosError } from 'core/tools/axiosError' +} from '@/core/model' +import type { QueenApi } from '@/core/ports/QueenApi' +import { handleAxiosError } from '@/core/tools/axiosError' + import { campaignSchema, idAndQuestionnaireIdSchema, @@ -50,7 +52,7 @@ export function createApiClient(params: { return Promise.reject(error) } return Promise.reject(handleAxiosError(error)) - } + }, ) return { axiosInstance } })() @@ -65,14 +67,14 @@ export function createApiClient(params: { axiosInstance .get(`/api/survey-units/interviewer`) .then(({ data }) => - data.map((surveyUnit) => surveyUnitSchema.parse(surveyUnit)) + data.map((surveyUnit) => surveyUnitSchema.parse(surveyUnit)), ), getSurveyUnit: (idSurveyUnit) => axiosInstance .get>(`/api/survey-unit/${idSurveyUnit}`) .then(({ data }) => - surveyUnitSchema.parse({ id: idSurveyUnit, ...data }) + surveyUnitSchema.parse({ id: idSurveyUnit, ...data }), ), putSurveyUnit: (surveyUnit) => axiosInstance @@ -100,7 +102,7 @@ export function createApiClient(params: { getRequiredNomenclaturesByCampaign: (idNomenclature) => axiosInstance .get( - `/api/questionnaire/${idNomenclature}/required-nomenclatures` + `/api/questionnaire/${idNomenclature}/required-nomenclatures`, ) .then(({ data }) => requiredNomenclaturesSchema.parse(data)), diff --git a/src/core/adapters/queenApi/mock.ts b/src/core/adapters/queenApi/mock.ts index 5ef5a80b..bea24b3d 100644 --- a/src/core/adapters/queenApi/mock.ts +++ b/src/core/adapters/queenApi/mock.ts @@ -1,6 +1,7 @@ -import type { QueenApi } from 'core/ports/QueenApi' +import type { SurveyUnit } from '@/core/model' +import type { QueenApi } from '@/core/ports/QueenApi' + import { surveySample } from './mockData/surveySample' -import type { SurveyUnit } from 'core/model' export function createApiClient(): QueenApi { return { @@ -15,13 +16,13 @@ export function createApiClient(): QueenApi { Promise.resolve(createSUMocked({ idSu: idSurveyUnit })), putSurveyUnit: (surveyUnit) => Promise.resolve( - console.log('putSurveyUnit', `id: ${surveyUnit.id}`, surveyUnit) + console.log('putSurveyUnit', `id: ${surveyUnit.id}`, surveyUnit), ), putSurveyUnitsData: (surveyUnitsData) => Promise.resolve(console.table(surveyUnitsData)), postSurveyUnitInTemp: (surveyUnit) => Promise.resolve( - console.log('postSurveyUnitInTemp', `id: ${surveyUnit.id}`, surveyUnit) + console.log('postSurveyUnitInTemp', `id: ${surveyUnit.id}`, surveyUnit), ), getCampaigns: () => Promise.resolve([ diff --git a/src/core/adapters/queenApi/mockData/surveySample.ts b/src/core/adapters/queenApi/mockData/surveySample.ts index 3b8549fc..f7a3afee 100644 --- a/src/core/adapters/queenApi/mockData/surveySample.ts +++ b/src/core/adapters/queenApi/mockData/surveySample.ts @@ -1,4 +1,4 @@ -import type { Questionnaire } from 'core/model/Questionnaire' +import type { Questionnaire } from '@/core/model/Questionnaire' export const surveySample = { componentType: 'Questionnaire', diff --git a/src/core/adapters/queenApi/parserSchema/campaignSchema.test.ts b/src/core/adapters/queenApi/parserSchema/campaignSchema.test.ts index e65703fc..3e4673ea 100644 --- a/src/core/adapters/queenApi/parserSchema/campaignSchema.test.ts +++ b/src/core/adapters/queenApi/parserSchema/campaignSchema.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'vitest' + import { campaignSchema } from './campaignSchema' describe('campaignSchema', () => { diff --git a/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.test.ts b/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.test.ts index 8f51d170..ff04f635 100644 --- a/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.test.ts +++ b/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest' +import { describe, expect, it } from 'vitest' + import { nomenclatureSchema, requiredNomenclaturesSchema, diff --git a/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.ts b/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.ts index e81c603a..523df1e5 100644 --- a/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.ts +++ b/src/core/adapters/queenApi/parserSchema/nomenclatureSchema.ts @@ -6,7 +6,7 @@ export const nomenclatureSchema = z.array( id: z.string(), label: z.string(), }) - .catchall(z.string()) + .catchall(z.string()), ) export const requiredNomenclaturesSchema = z.string().array() diff --git a/src/core/adapters/queenApi/parserSchema/paradataSchema.test.ts b/src/core/adapters/queenApi/parserSchema/paradataSchema.test.ts index 7deb02d4..1be9c197 100644 --- a/src/core/adapters/queenApi/parserSchema/paradataSchema.test.ts +++ b/src/core/adapters/queenApi/parserSchema/paradataSchema.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'vitest' + import { paradataSchema } from './paradataSchema' describe('eventSchema', () => { @@ -31,7 +32,7 @@ describe('eventSchema', () => { expect(result.success).toBe(false) if (!result.success) { expect(result.error.issues[0].message).toContain( - "Invalid enum value. Expected 'click' | 'session-started' | 'orchestrator-create', received 'invalid-type'" + "Invalid enum value. Expected 'click' | 'session-started' | 'orchestrator-create', received 'invalid-type'", ) } }) @@ -46,7 +47,7 @@ describe('eventSchema', () => { expect(result.success).toBe(false) if (!result.success) { expect(result.error.issues[0].message).toContain( - 'Number must be greater than or equal to 0' + 'Number must be greater than or equal to 0', ) } }) diff --git a/src/core/adapters/queenApi/parserSchema/surveyUnitDataSchema.test.ts b/src/core/adapters/queenApi/parserSchema/surveyUnitDataSchema.test.ts index 1f3a30f8..8977319b 100644 --- a/src/core/adapters/queenApi/parserSchema/surveyUnitDataSchema.test.ts +++ b/src/core/adapters/queenApi/parserSchema/surveyUnitDataSchema.test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest' +import { describe, expect, it } from 'vitest' + import { surveyUnitDataSchema } from './surveyUnitDataSchema' describe('surveyUnitDataSchema', () => { diff --git a/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.test.ts b/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.test.ts index 56ef0b6f..a9945145 100644 --- a/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.test.ts +++ b/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'vitest' + import { idAndQuestionnaireIdSchema, surveyUnitSchema, diff --git a/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.ts b/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.ts index 1db45732..f406d72a 100644 --- a/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.ts +++ b/src/core/adapters/queenApi/parserSchema/surveyUnitSchema.ts @@ -1,6 +1,8 @@ import { z } from 'zod' + +import type { PageTag } from '@/core/model' + import { surveyUnitDataSchema } from './surveyUnitDataSchema' -import type { PageTag } from 'core/model' export const idAndQuestionnaireIdSchema = z.object({ id: z.string(), @@ -23,7 +25,7 @@ const stateDataSchema = z.object({ { message: 'currentPage must be in the format `${number}.${number}#${number}` or `${number}`', - } + }, ), }) @@ -35,7 +37,7 @@ export const surveyUnitSchema = z.object({ z.object({ name: z.string(), value: z.string(), - }) + }), ) .optional(), data: surveyUnitDataSchema, diff --git a/src/core/bootstrap.ts b/src/core/bootstrap.ts index 5e362caa..a951d6ee 100644 --- a/src/core/bootstrap.ts +++ b/src/core/bootstrap.ts @@ -1,9 +1,11 @@ -import { usecases } from './usecases' -import { createCore, type GenericCore } from 'redux-clean-architecture' -import type { Oidc } from 'core/ports/Oidc' -import type { DataStore } from 'core/ports/DataStore' -import type { QueenApi } from 'core/ports/QueenApi' +import { type GenericCore, createCore } from 'redux-clean-architecture' + +import type { DataStore } from '@/core/ports/DataStore' +import type { Oidc } from '@/core/ports/Oidc' +import type { QueenApi } from '@/core/ports/QueenApi' + import type { LocalSyncStorage } from './ports/LocalSyncStorage' +import { usecases } from './usecases' type ParamsOfBootstrapCore = { apiUrl: string @@ -30,16 +32,16 @@ export type Thunks = Core['types']['Thunks'] export type CreateEvt = Core['types']['CreateEvt'] export async function bootstrapCore( - params: ParamsOfBootstrapCore + params: ParamsOfBootstrapCore, ): Promise<{ core: Core }> { const { apiUrl, oidcParams } = params const getOidc = await (async () => { if (oidcParams === undefined || oidcParams.issuerUri === '') { - const { createOidc } = await import('core/adapters/oidc/mock') + const { createOidc } = await import('@/core/adapters/oidc/mock') return createOidc({ isUserLoggedIn: true }) } - const { createOidc } = await import('core/adapters/oidc/default') + const { createOidc } = await import('@/core/adapters/oidc/default') return createOidc({ issuerUri: oidcParams.issuerUri, @@ -50,11 +52,11 @@ export async function bootstrapCore( const queenApi = await (async () => { if (apiUrl === '') { // When no apiUrl is provided, we use the mock - const { createApiClient } = await import('core/adapters/queenApi/mock') + const { createApiClient } = await import('@/core/adapters/queenApi/mock') return createApiClient() } - const { createApiClient } = await import('core/adapters/queenApi/default') + const { createApiClient } = await import('@/core/adapters/queenApi/default') return createApiClient({ apiUrl, @@ -70,7 +72,9 @@ export async function bootstrapCore( })() const dataStore = await (async () => { - const { createDataStore } = await import('core/adapters/datastore/default') + const { createDataStore } = await import( + '@/core/adapters/datastore/default' + ) /** * TODO : replace schema (There are impact on legacy queens) schema: { @@ -91,7 +95,7 @@ export async function bootstrapCore( const localSyncStorage = await (async () => { const { createLocalSyncStorage } = await import( - 'core/adapters/localSyncStorage/default' + '@/core/adapters/localSyncStorage/default' ) return createLocalSyncStorage({ localStorageKey: 'QUEEN_SYNC_RESULT' }) diff --git a/src/core/index.ts b/src/core/index.ts index 3cfbbd7c..7c928689 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -3,7 +3,8 @@ NOTE: Only here do we export the API for a specific framework (here react). In the rest of the core directory everything is agnostic to React */ import { createReactApi } from 'redux-clean-architecture/react' -import { bootstrapCore } from 'core/bootstrap' + +import { bootstrapCore } from '@/core/bootstrap' export const { createCoreProvider, useCore, useCoreState } = createReactApi({ bootstrapCore, diff --git a/src/core/model/SurveyUnit.ts b/src/core/model/SurveyUnit.ts index 865c5d89..810c8cfa 100644 --- a/src/core/model/SurveyUnit.ts +++ b/src/core/model/SurveyUnit.ts @@ -8,12 +8,10 @@ export type SurveyUnit = { questionnaireId: string personalization?: { name: string; value: string }[] data: SurveyUnitData - comment?: {} | undefined - stateData?: - | { - state: QuestionnaireState - date: number - currentPage: PageTag - } - | undefined + comment?: { [key: string]: unknown } + stateData?: { + state: QuestionnaireState + date: number + currentPage: PageTag + } } diff --git a/src/core/model/SurveyUnitData.ts b/src/core/model/SurveyUnitData.ts index e439e434..8b33f813 100644 --- a/src/core/model/SurveyUnitData.ts +++ b/src/core/model/SurveyUnitData.ts @@ -1,6 +1,6 @@ -import type { LunaticData, LunaticCollectedValue } from '@inseefr/lunatic' -import { assert } from 'tsafe/assert' +import type { LunaticCollectedValue, LunaticData } from '@inseefr/lunatic' import type { Extends } from 'tsafe/Extends' +import { assert } from 'tsafe/assert' type VariableType = | string diff --git a/src/core/ports/DataStore.ts b/src/core/ports/DataStore.ts index 76abd94b..492c86aa 100644 --- a/src/core/ports/DataStore.ts +++ b/src/core/ports/DataStore.ts @@ -1,4 +1,4 @@ -import type { Paradata, SurveyUnit } from 'core/model' +import type { Paradata, SurveyUnit } from '@/core/model' export type DataStore = { updateSurveyUnit: (surveyUnit: SurveyUnit) => Promise diff --git a/src/core/ports/QueenApi.ts b/src/core/ports/QueenApi.ts index 23d13423..542d851a 100644 --- a/src/core/ports/QueenApi.ts +++ b/src/core/ports/QueenApi.ts @@ -6,11 +6,11 @@ import type { Questionnaire, RequiredNomenclatures, SurveyUnit, -} from 'core/model' +} from '@/core/model' export type QueenApi = { getSurveyUnitsIdsAndQuestionnaireIdsByCampaign: ( - idCampaign: string + idCampaign: string, ) => Promise /** * Endpoint in development @@ -28,13 +28,13 @@ export type QueenApi = { * /api/survey-units/data */ putSurveyUnitsData: ( - surveyUnitsData: Omit[] + surveyUnitsData: Omit[], ) => Promise postSurveyUnitInTemp: (surveyUnit: SurveyUnit) => Promise getCampaigns: () => Promise getQuestionnaire: (idQuestionnaire: string) => Promise getRequiredNomenclaturesByCampaign: ( - idCampaign: string + idCampaign: string, ) => Promise getNomenclature: (idNomenclature: string) => Promise postParadata: (paradata: Paradata) => Promise diff --git a/src/core/tools/SurveyModelBreaking.ts b/src/core/tools/SurveyModelBreaking.ts index 8b0ad155..dd3277a5 100644 --- a/src/core/tools/SurveyModelBreaking.ts +++ b/src/core/tools/SurveyModelBreaking.ts @@ -1,6 +1,6 @@ -import { LUNATIC_MODEL_VERSION_BREAKING } from 'core/constants' -import type { Questionnaire } from 'core/model' -import { getTranslation } from 'i18n' +import { LUNATIC_MODEL_VERSION_BREAKING } from '@/core/constants' +import type { Questionnaire } from '@/core/model' +import { getTranslation } from '@/i18n' const { t } = getTranslation('errorMessage') diff --git a/src/core/tools/axiosError.test.ts b/src/core/tools/axiosError.test.ts index e363b8a4..b576684c 100644 --- a/src/core/tools/axiosError.test.ts +++ b/src/core/tools/axiosError.test.ts @@ -1,8 +1,9 @@ -import { describe, it, expect, vi } from 'vitest' -import { handleAxiosError } from './axiosError' import { AxiosError } from 'axios' +import { describe, expect, it, vi } from 'vitest' + +import { handleAxiosError } from './axiosError' -vi.mock('i18n', () => ({ +vi.mock('@/i18n', () => ({ getTranslation: () => ({ t: (keyMessage: string) => keyMessage }), })) @@ -19,7 +20,7 @@ describe('handleAxiosError', () => { const result = handleAxiosError(error) expect(result.message).toBe( - "Une erreur s'est produite lors du traitement de la requête. Veuillez réessayer plus tard." + "Une erreur s'est produite lors du traitement de la requête. Veuillez réessayer plus tard.", ) }) diff --git a/src/core/tools/axiosError.ts b/src/core/tools/axiosError.ts index 2ff490e9..e28f6582 100644 --- a/src/core/tools/axiosError.ts +++ b/src/core/tools/axiosError.ts @@ -1,5 +1,6 @@ import { AxiosError } from 'axios' -import { getTranslation } from 'i18n' + +import { getTranslation } from '@/i18n' const { t } = getTranslation('errorMessage') diff --git a/src/core/tools/externalResources.test.ts b/src/core/tools/externalResources.test.ts index 86a26315..eaf38b20 100644 --- a/src/core/tools/externalResources.test.ts +++ b/src/core/tools/externalResources.test.ts @@ -1,4 +1,14 @@ -import { describe, it, expect, vi, beforeAll, beforeEach } from 'vitest' +import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' + +import { EXTERNAL_RESOURCES_URL } from '@/core/constants' +import type { + ExternalQuestionnaire, + ExternalQuestionnaires, + ExternalQuestionnairesFiltered, + ExternalQuestionnairesWrapper, + Manifest, +} from '@/core/model' + import { filterTransformedManifest, getExternalQuestionnaireFiltered, @@ -7,14 +17,6 @@ import { getTransformedManifest, } from './externalResources' import { fetchUrl } from './fetchUrl' -import type { - ExternalQuestionnaire, - ExternalQuestionnaires, - ExternalQuestionnairesFiltered, - ExternalQuestionnairesWrapper, - Manifest, -} from 'core/model' -import { EXTERNAL_RESOURCES_URL } from 'core/constants' vi.mock('./fetchUrl', () => { return { @@ -139,7 +141,7 @@ describe('filterTransformedManifest', () => { const result = await filterTransformedManifest( cacheName, - transformedManifest + transformedManifest, ) const expectedResult = [ @@ -164,7 +166,7 @@ describe('filterTransformedManifest', () => { const result = await filterTransformedManifest( cacheName, - transformedManifest + transformedManifest, ) expect(result).toEqual(transformedManifest) @@ -176,7 +178,7 @@ describe('filterTransformedManifest', () => { const result = await filterTransformedManifest( cacheName, - transformedManifest + transformedManifest, ) expect(result).toEqual([]) diff --git a/src/core/tools/externalResources.ts b/src/core/tools/externalResources.ts index 808b726a..5c4ee5d4 100644 --- a/src/core/tools/externalResources.ts +++ b/src/core/tools/externalResources.ts @@ -1,12 +1,13 @@ +import { EXTERNAL_RESOURCES_URL } from '@/core/constants' import type { ExternalQuestionnaire, ExternalQuestionnaires, ExternalQuestionnairesFiltered, ExternalQuestionnairesWrapper, Manifest, -} from 'core/model' +} from '@/core/model' + import { fetchUrl } from './fetchUrl' -import { EXTERNAL_RESOURCES_URL } from 'core/constants' const EXTERNAL_QUESTIONNAIRES_KEYWORD = 'gide' @@ -21,7 +22,7 @@ export async function getExternalQuestionnaires(): Promise { // get the manifest for a questionnaireId const manifest = await fetchUrl({ @@ -30,7 +31,7 @@ export async function getTransformedManifest( // Transform the manifest values into resource URLs, and get an array of these resource URLs const transformedManifest = Object.values(manifest).map( - (resourceUrl) => `${EXTERNAL_RESOURCES_URL}/${resourceUrl}` + (resourceUrl) => `${EXTERNAL_RESOURCES_URL}/${resourceUrl}`, ) return transformedManifest @@ -39,7 +40,7 @@ export async function getTransformedManifest( // Filter resources from manifest that are already cached, to avoid useless requests (overly large files). export async function filterTransformedManifest( cacheName: string, - transformedManifest: string[] + transformedManifest: string[], ): Promise { // Open the specified cache const cacheForManifest = await caches.open(cacheName) @@ -51,12 +52,12 @@ export async function filterTransformedManifest( // Get all urls from the cache const cachedUrls = (await cacheForManifest.keys()).map( - (request) => request.url + (request) => request.url, ) // filter the transformedManifest for keeping only files that are not cached yet const uncachedResources = transformedManifest.filter( - (resourceUrl) => !cachedUrls.includes(resourceUrl) + (resourceUrl) => !cachedUrls.includes(resourceUrl), ) return uncachedResources @@ -64,13 +65,13 @@ export async function filterTransformedManifest( // Cache every external resources (not already cached) for a particular questionnaire export async function getResourcesFromExternalQuestionnaire( - questionnaire: ExternalQuestionnaire + questionnaire: ExternalQuestionnaire, ): Promise { const transformedManifest = await getTransformedManifest(questionnaire.id) const filteredTransformedManifest = await filterTransformedManifest( questionnaire.cacheName, - transformedManifest + transformedManifest, ) const manifestCache = await caches.open(questionnaire.cacheName) @@ -80,13 +81,13 @@ export async function getResourcesFromExternalQuestionnaire( // Separate, from the list of external questionnaires, those that are needed and those that are not needed export function getExternalQuestionnaireFiltered( neededQuestionnaireIds: string[], - externalQuestionnaires: ExternalQuestionnaires + externalQuestionnaires: ExternalQuestionnaires, ): ExternalQuestionnairesFiltered { return externalQuestionnaires.reduce( (result, questionnaire) => { // Check if the current questionnaire's id matches any of the needed IDs const isNeeded = neededQuestionnaireIds.some((neededId) => - neededId.toLowerCase().includes(questionnaire.id.toLowerCase()) + neededId.toLowerCase().includes(questionnaire.id.toLowerCase()), ) // If the external questionnaire is needed @@ -105,16 +106,16 @@ export function getExternalQuestionnaireFiltered( { neededQuestionnaires: [], notNeededQuestionnaires: [], - } as ExternalQuestionnairesFiltered + } as ExternalQuestionnairesFiltered, ) } // Get the list of caches where cacheName includes externalQuestionnairesKeyword, and that are not in needed external questionnaires export async function getOldExternalCacheNames( - neededQuestionnaires: ExternalQuestionnaires + neededQuestionnaires: ExternalQuestionnaires, ): Promise { const neededCaches = neededQuestionnaires.map( - (questionnaire) => questionnaire.cacheName + (questionnaire) => questionnaire.cacheName, ) const oldExternalCacheNames = (await caches.keys()).filter( @@ -122,7 +123,7 @@ export async function getOldExternalCacheNames( cacheName .toLowerCase() .includes(EXTERNAL_QUESTIONNAIRES_KEYWORD.toLowerCase()) && - !neededCaches.includes(cacheName) + !neededCaches.includes(cacheName), ) return oldExternalCacheNames diff --git a/src/core/tools/fetchUrl.test.ts b/src/core/tools/fetchUrl.test.ts index cdfdafac..b0f46e4b 100644 --- a/src/core/tools/fetchUrl.test.ts +++ b/src/core/tools/fetchUrl.test.ts @@ -1,5 +1,6 @@ -import { vi, describe, beforeEach, it, expect } from 'vitest' import axios from 'axios' +import { beforeEach, describe, expect, it, vi } from 'vitest' + import { fetchUrl } from './fetchUrl' vi.mock('axios') diff --git a/src/core/tools/makeSearchParamsObjectSchema.test.ts b/src/core/tools/makeSearchParamsObjectSchema.test.ts index 932f6d8b..ab35a0c6 100644 --- a/src/core/tools/makeSearchParamsObjectSchema.test.ts +++ b/src/core/tools/makeSearchParamsObjectSchema.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from 'vitest' import { z } from 'zod' + import { makeSearchParamsObjSchema } from './makeSearchParamsObjectSchema' describe('makeSearchParamsObjSchema', () => { @@ -9,7 +10,7 @@ describe('makeSearchParamsObjSchema', () => { key1: z.string(), key2: z.number(), key3: z.boolean(), - }) + }), ) const searchParams = new URLSearchParams() @@ -32,7 +33,7 @@ describe('makeSearchParamsObjSchema', () => { z.object({ key1: z.string().array(), key2: z.string(), - }) + }), ) const searchParams = new URLSearchParams() @@ -54,7 +55,7 @@ describe('makeSearchParamsObjSchema', () => { z.object({ key1: z.string(), key2: z.number(), - }) + }), ) const searchParams = new URLSearchParams() @@ -72,7 +73,7 @@ describe('makeSearchParamsObjSchema', () => { z.object({ key1: z.string(), key2: z.number().optional(), - }) + }), ) const searchParams = new URLSearchParams() @@ -90,7 +91,7 @@ describe('makeSearchParamsObjSchema', () => { const schema = makeSearchParamsObjSchema( z.object({ key1: z.string().optional(), - }) + }), ) const searchParams = new URLSearchParams() diff --git a/src/core/tools/makeSearchParamsObjectSchema.ts b/src/core/tools/makeSearchParamsObjectSchema.ts index d37388f3..e4c80375 100644 --- a/src/core/tools/makeSearchParamsObjectSchema.ts +++ b/src/core/tools/makeSearchParamsObjectSchema.ts @@ -9,14 +9,14 @@ function safeParseJSON(string: string): any { } function searchParamsToValues( - searchParams: URLSearchParams + searchParams: URLSearchParams, ): Record { return Array.from(searchParams.keys()).reduce( (record, key) => { const values = searchParams.getAll(key).map(safeParseJSON) return { ...record, [key]: values.length > 1 ? values : values[0] } }, - {} as Record + {} as Record, ) } diff --git a/src/core/usecases/collectSurvey/eventSender.test.ts b/src/core/usecases/collectSurvey/eventSender.test.ts index 4e28fe5a..13ea2582 100644 --- a/src/core/usecases/collectSurvey/eventSender.test.ts +++ b/src/core/usecases/collectSurvey/eventSender.test.ts @@ -1,9 +1,11 @@ -import { vi, describe, beforeEach, it, expect } from 'vitest' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import type { EventQuestionnaireState } from '@/core/model/QuestionnaireState' + import { - sendQuestionnaireStateChangedEvent, sendCloseEvent, + sendQuestionnaireStateChangedEvent, } from './eventSender' -import type { EventQuestionnaireState } from 'core/model/QuestionnaireState' describe('Event Dispatchers', () => { beforeEach(() => { @@ -27,7 +29,7 @@ describe('Event Dispatchers', () => { surveyUnit: surveyUnitId, state: state, }, - }) + }), ) }) @@ -46,7 +48,7 @@ describe('Event Dispatchers', () => { command: 'CLOSE_QUEEN', surveyUnit: surveyUnitId, }, - }) + }), ) }) }) diff --git a/src/core/usecases/collectSurvey/eventSender.ts b/src/core/usecases/collectSurvey/eventSender.ts index f96e0788..a67fc020 100644 --- a/src/core/usecases/collectSurvey/eventSender.ts +++ b/src/core/usecases/collectSurvey/eventSender.ts @@ -1,4 +1,4 @@ -import type { EventQuestionnaireState } from 'core/model/QuestionnaireState' +import type { EventQuestionnaireState } from '@/core/model/QuestionnaireState' type UpdateSurveyUnitData = { type: string @@ -22,7 +22,7 @@ const sendEvent = (data: UpdateSurveyUnitData | CloseQueenData) => { export const sendQuestionnaireStateChangedEvent = ( surveyUnitId: string, - state: EventQuestionnaireState + state: EventQuestionnaireState, ) => { const data: UpdateSurveyUnitData = { type: eventType, diff --git a/src/core/usecases/collectSurvey/thunks.ts b/src/core/usecases/collectSurvey/thunks.ts index fdb8e613..54637b55 100644 --- a/src/core/usecases/collectSurvey/thunks.ts +++ b/src/core/usecases/collectSurvey/thunks.ts @@ -1,12 +1,13 @@ -import type { Thunks } from 'core/bootstrap' -import type { SurveyUnit } from 'core/model' -import type { QuestionnaireState } from 'core/model/QuestionnaireState' -import { isSurveyCompatibleWithQueen } from 'core/tools/SurveyModelBreaking' +import type { Thunks } from '@/core/bootstrap' +import type { SurveyUnit } from '@/core/model' +import type { QuestionnaireState } from '@/core/model/QuestionnaireState' +import { isSurveyCompatibleWithQueen } from '@/core/tools/SurveyModelBreaking' +import { getTranslation } from '@/i18n' + import { sendCloseEvent, sendQuestionnaireStateChangedEvent, } from './eventSender' -import { getTranslation } from 'i18n' const { t } = getTranslation('errorMessage') @@ -24,8 +25,8 @@ export const thunks = { if (!surveyUnit || !surveyUnit.questionnaireId) { return Promise.reject( new Error( - `Impossible de récupérer le questionnaire de l'unité d'enquête ${surveyUnitId}` - ) + `Impossible de récupérer le questionnaire de l'unité d'enquête ${surveyUnitId}`, + ), ) } return surveyUnit.questionnaireId @@ -64,7 +65,7 @@ export const thunks = { t('wrongQuestionnaire', { surveyUnitId, questionnaireId, - }) + }), ) } return surveyUnit diff --git a/src/core/usecases/index.ts b/src/core/usecases/index.ts index cf675726..eeb4a0b9 100644 --- a/src/core/usecases/index.ts +++ b/src/core/usecases/index.ts @@ -1,8 +1,9 @@ -import * as userAuthentication from './userAuthentication' -import * as synchronizeData from './synchronizeData' -import * as visualizeSurvey from './visualizeSurvey' import * as collectSurvey from './collectSurvey' import * as reviewSurvey from './reviewSurvey' +import * as synchronizeData from './synchronizeData' +import * as userAuthentication from './userAuthentication' +import * as visualizeSurvey from './visualizeSurvey' + export const usecases = { userAuthentication, synchronizeData, diff --git a/src/core/usecases/reviewSurvey/thunks.ts b/src/core/usecases/reviewSurvey/thunks.ts index 7c66c055..f1210bdb 100644 --- a/src/core/usecases/reviewSurvey/thunks.ts +++ b/src/core/usecases/reviewSurvey/thunks.ts @@ -1,6 +1,6 @@ -import type { Thunks } from 'core/bootstrap' -import { isSurveyCompatibleWithQueen } from 'core/tools/SurveyModelBreaking' -import { getTranslation } from 'i18n' +import type { Thunks } from '@/core/bootstrap' +import { isSurveyCompatibleWithQueen } from '@/core/tools/SurveyModelBreaking' +import { getTranslation } from '@/i18n' const { t } = getTranslation('errorMessage') @@ -34,7 +34,7 @@ export const thunks = { t('wrongQuestionnaire', { surveyUnitId, questionnaireId, - }) + }), ) } return surveyUnit diff --git a/src/core/usecases/synchronizeData/evt.ts b/src/core/usecases/synchronizeData/evt.ts index 94c670c0..f9ebac59 100644 --- a/src/core/usecases/synchronizeData/evt.ts +++ b/src/core/usecases/synchronizeData/evt.ts @@ -1,5 +1,7 @@ -import type { CreateEvt } from 'core/bootstrap' import { Evt } from 'evt' + +import type { CreateEvt } from '@/core/bootstrap' + import { name } from './state' export const createEvt = (({ evtAction }) => { @@ -18,7 +20,7 @@ export const createEvt = (({ evtAction }) => { evt.post({ action: 'redirect', }) - } + }, ) return evt diff --git a/src/core/usecases/synchronizeData/selectors.ts b/src/core/usecases/synchronizeData/selectors.ts index 81f22f55..9e5d04e0 100644 --- a/src/core/usecases/synchronizeData/selectors.ts +++ b/src/core/usecases/synchronizeData/selectors.ts @@ -1,8 +1,10 @@ -import type { State as RootState } from 'core/bootstrap' import { createSelector } from 'redux-clean-architecture' -import { name } from './state' import { assert } from 'tsafe/assert' +import type { State as RootState } from '@/core/bootstrap' + +import { name } from './state' + const state = (rootState: RootState) => rootState[name] const downloadingState = createSelector(state, (state) => { @@ -82,7 +84,7 @@ const main = createSelector( nomenclatureProgress, surveyProgress, externalResourcesProgress, - uploadProgress + uploadProgress, ) => { switch (state.stateDescription) { case 'not running': @@ -108,7 +110,7 @@ const main = createSelector( } } } - } + }, ) export const selectors = { diff --git a/src/core/usecases/synchronizeData/state.ts b/src/core/usecases/synchronizeData/state.ts index 1ec25885..9556dc6a 100644 --- a/src/core/usecases/synchronizeData/state.ts +++ b/src/core/usecases/synchronizeData/state.ts @@ -1,7 +1,8 @@ import { createUsecaseActions } from 'redux-clean-architecture' -import { id } from 'tsafe/id' import { assert } from 'tsafe/assert' -import { EXTERNAL_RESOURCES_URL } from 'core/constants' +import { id } from 'tsafe/id' + +import { EXTERNAL_RESOURCES_URL } from '@/core/constants' export type State = State.NotRunning | State.Running @@ -43,7 +44,7 @@ export const { reducer, actions } = createUsecaseActions({ initialState: id( id({ stateDescription: 'not running', - }) + }), ), reducers: { runningDownload: () => @@ -62,7 +63,7 @@ export const { reducer, actions } = createUsecaseActions({ // undefined : external synchro is not triggered so we don't want the progress bar totalExternalResources: EXTERNAL_RESOURCES_URL ? Infinity : undefined, externalResourcesCompleted: 0, - }) + }), ), runningUpload: () => id( @@ -71,11 +72,11 @@ export const { reducer, actions } = createUsecaseActions({ type: 'upload', total: Infinity, surveyUnitCompleted: 0, - }) + }), ), updateDownloadTotalSurveyUnit: ( state, - { payload }: { payload: { totalSurveyUnit: number } } + { payload }: { payload: { totalSurveyUnit: number } }, ) => { const { totalSurveyUnit } = payload assert(state.stateDescription === 'running' && state.type === 'download') @@ -96,7 +97,7 @@ export const { reducer, actions } = createUsecaseActions({ }, setDownloadTotalSurvey: ( state, - { payload }: { payload: { totalSurvey: number } } + { payload }: { payload: { totalSurvey: number } }, ) => { const { totalSurvey } = payload assert(state.stateDescription === 'running' && state.type === 'download') @@ -111,7 +112,7 @@ export const { reducer, actions } = createUsecaseActions({ }, setDownloadTotalNomenclature: ( state, - { payload }: { payload: { totalNomenclature: number } } + { payload }: { payload: { totalNomenclature: number } }, ) => { const { totalNomenclature } = payload assert(state.stateDescription === 'running' && state.type === 'download') @@ -126,7 +127,7 @@ export const { reducer, actions } = createUsecaseActions({ }, setDownloadTotalExternalResources: ( state, - { payload }: { payload: { totalExternalResources: number } } + { payload }: { payload: { totalExternalResources: number } }, ) => { const { totalExternalResources } = payload assert(state.stateDescription === 'running' && state.type === 'download') diff --git a/src/core/usecases/synchronizeData/thunks.ts b/src/core/usecases/synchronizeData/thunks.ts index dca9f8f8..337124f5 100644 --- a/src/core/usecases/synchronizeData/thunks.ts +++ b/src/core/usecases/synchronizeData/thunks.ts @@ -1,14 +1,16 @@ -import type { Thunks } from 'core/bootstrap' -import { actions, name } from './state' import { AxiosError } from 'axios' -import type { Questionnaire } from 'core/model' + +import type { Thunks } from '@/core/bootstrap' +import { EXTERNAL_RESOURCES_URL } from '@/core/constants' +import type { Questionnaire } from '@/core/model' import { getExternalQuestionnaireFiltered, getExternalQuestionnaires, getOldExternalCacheNames, getResourcesFromExternalQuestionnaire, -} from 'core/tools/externalResources' -import { EXTERNAL_RESOURCES_URL } from 'core/constants' +} from '@/core/tools/externalResources' + +import { actions, name } from './state' const EXTERNAL_RESOURCES_ROOT_CACHE_NAME = 'cache-root-external' @@ -42,14 +44,14 @@ export const thunks = { const questionnaireIds = [ ...new Set( campaigns.map(({ questionnaireIds }) => questionnaireIds).flat() ?? - [] + [], ), ] dispatch( actions.setDownloadTotalSurvey({ totalSurvey: questionnaireIds.length, - }) + }), ) /* @@ -71,15 +73,15 @@ export const thunks = { }) .catch(() => { console.error( - ` Questionnaire : An error occurred and we were unable to retrieve survey ${questionnaireId}` + ` Questionnaire : An error occurred and we were unable to retrieve survey ${questionnaireId}`, ) return { success: false as const, questionnaireId, questionnaire: undefined, } - }) - ) + }), + ), ) const { questionnaireIdInSuccess, questionnaires } = @@ -94,7 +96,7 @@ export const thunks = { { questionnaireIdInSuccess: [], questionnaires: [] } as { questionnaireIdInSuccess: string[] questionnaires: Questionnaire[] - } + }, ) /* @@ -109,7 +111,7 @@ export const thunks = { dispatch( actions.updateDownloadTotalSurveyUnit({ totalSurveyUnit: arrayOfIds.length, - }) + }), ) return Promise.all( arrayOfIds.map(({ id }) => @@ -118,7 +120,7 @@ export const thunks = { .then((surveyUnit) => { dataStore.updateSurveyUnit(surveyUnit) return questionnaireIdInSuccess.includes( - surveyUnit.questionnaireId + surveyUnit.questionnaireId, ) }) .then((isSurveyWellDownload) => { @@ -135,16 +137,16 @@ export const thunks = { ) { console.error( `An error occurred while fetching surveyUnit : ${id}, synchronization continue`, - error + error, ) return } throw error - }) - ) + }), + ), ) - }) - ) + }), + ), ) /* @@ -155,13 +157,13 @@ export const thunks = { questionnaires .map((q) => q?.suggesters) .flat() - .map((suggester) => suggester?.name) + .map((suggester) => suggester?.name), ) dispatch( actions.setDownloadTotalNomenclature({ totalNomenclature: suggestersNames.length, - }) + }), ) //We don't store the data, but instead, we simply initiate the request for the service worker to cache the response @@ -172,13 +174,13 @@ export const thunks = { .catch((error) => { console.error( `Nomenclature : An error occurred and we were unable to retrieve nomenclature ${nomenclatureId}`, - error + error, ) }) .finally(() => { dispatch(actions.downloadNomenclatureCompleted()) - }) - ) + }), + ), ) /* @@ -197,7 +199,7 @@ export const thunks = { ) { console.error( `An error occurred while fetching external questionnaires list`, - error + error, ) } throw error @@ -206,14 +208,14 @@ export const thunks = { const { neededQuestionnaires, notNeededQuestionnaires } = getExternalQuestionnaireFiltered( questionnaireIdInSuccess, - externalQuestionnaires + externalQuestionnaires, ) // set the total of needed external questionnaires for progress bar dispatch( actions.setDownloadTotalExternalResources({ totalExternalResources: neededQuestionnaires.length, - }) + }), ) // add in cache the missing external resources for needed questionnaires @@ -221,22 +223,22 @@ export const thunks = { neededQuestionnaires.map(async (questionnaire) => { await getResourcesFromExternalQuestionnaire(questionnaire) .then(() => - dispatch(actions.downloadExternalResourceCompleted()) + dispatch(actions.downloadExternalResourceCompleted()), ) .catch((error) => console.error( `An error occurred while fetching external resources of questionnaire ${questionnaire.id}`, - error - ) + error, + ), ) - }) + }), ) // delete the cache of every not needed external questionnaires const prDeleteExternalResources = Promise.all( notNeededQuestionnaires.map((questionnaire) => - caches.delete(questionnaire.cacheName) - ) + caches.delete(questionnaire.cacheName), + ), ) // delete the root-cache of external resources if no external questionnaire is needed @@ -250,7 +252,7 @@ export const thunks = { await getOldExternalCacheNames(neededQuestionnaires) const prDeleteOldExternalCaches = Promise.all( - oldExternalCacheNames.map((cacheName) => caches.delete(cacheName)) + oldExternalCacheNames.map((cacheName) => caches.delete(cacheName)), ) // We await untill the promises for external resources are finished @@ -269,7 +271,7 @@ export const thunks = { } catch (error) { console.error( 'An unknown error occurred while we were fetching data so we stop the synchronization.', - error + error, ) localSyncStorage.addError(true) dispatch(actions.downloadFailed()) @@ -317,13 +319,13 @@ export const thunks = { .postSurveyUnitInTemp(surveyUnit) .then(() => localSyncStorage.addIdToSurveyUnitsInTempZone( - surveyUnit.id - ) + surveyUnit.id, + ), ) .catch((postError: Error) => { console.error( 'Error: Unable to post surveyUnit in tempZone', - postError + postError, ) throw postError }) @@ -337,7 +339,7 @@ export const thunks = { .catch((error) => { console.error('Error: Unable to upload data', error) throw error - }) + }), ) await Promise.all(surveyUnitPromises) } diff --git a/src/core/usecases/userAuthentication.test.ts b/src/core/usecases/userAuthentication.test.ts index b5291cae..39d4617b 100644 --- a/src/core/usecases/userAuthentication.test.ts +++ b/src/core/usecases/userAuthentication.test.ts @@ -1,6 +1,7 @@ -import { describe, it, expect, vi } from 'vitest' -import { thunks } from './userAuthentication' import type { Oidc } from 'oidc-spa' +import { describe, expect, it, vi } from 'vitest' + +import { thunks } from './userAuthentication' describe('userAuthentication thunks', () => { describe('loginIfNotLoggedIn', () => { @@ -9,7 +10,7 @@ describe('userAuthentication thunks', () => { Promise.resolve({ isUserLoggedIn: true, login: vi.fn(), - } as unknown as Oidc) + } as unknown as Oidc), ) await thunks.loginIfNotLoggedIn()( @@ -17,12 +18,12 @@ describe('userAuthentication thunks', () => { null as any, { getOidc: mockGetOidc, - } as any + } as any, ) expect(mockGetOidc).toHaveBeenCalled() expect( - (await mockGetOidc.mock.results[0].value).login + (await mockGetOidc.mock.results[0].value).login, ).not.toHaveBeenCalled() }) @@ -33,7 +34,7 @@ describe('userAuthentication thunks', () => { Promise.resolve({ isUserLoggedIn: false, login: mockLogin, - } as unknown as Oidc) + } as unknown as Oidc), ) await thunks.loginIfNotLoggedIn()( @@ -41,7 +42,7 @@ describe('userAuthentication thunks', () => { null as any, { getOidc: mockGetOidc, - } as any + } as any, ) expect(mockGetOidc).toHaveBeenCalled() diff --git a/src/core/usecases/userAuthentication.ts b/src/core/usecases/userAuthentication.ts index 1e7e6cce..f62db7ae 100644 --- a/src/core/usecases/userAuthentication.ts +++ b/src/core/usecases/userAuthentication.ts @@ -1,4 +1,4 @@ -import type { Thunks } from 'core/bootstrap' +import type { Thunks } from '@/core/bootstrap' export const name = 'userAuthentication' diff --git a/src/core/usecases/visualizeSurvey/parser/searchParamsSchema.test.ts b/src/core/usecases/visualizeSurvey/parser/searchParamsSchema.test.ts index 02e9f411..64ecc92c 100644 --- a/src/core/usecases/visualizeSurvey/parser/searchParamsSchema.test.ts +++ b/src/core/usecases/visualizeSurvey/parser/searchParamsSchema.test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest' +import { describe, expect, it } from 'vitest' + import { searchParamsSchema } from './searchParamsSchema' describe('searchParamsSchema', () => { diff --git a/src/core/usecases/visualizeSurvey/thunks.ts b/src/core/usecases/visualizeSurvey/thunks.ts index a382bafc..779d493e 100644 --- a/src/core/usecases/visualizeSurvey/thunks.ts +++ b/src/core/usecases/visualizeSurvey/thunks.ts @@ -1,16 +1,18 @@ -import type { Thunks } from 'core/bootstrap' +import { AxiosError } from 'axios' + +import type { Thunks } from '@/core/bootstrap' import type { Nomenclature, Questionnaire, SurveyUnit, WrappedQuestionnaire, -} from 'core/model' +} from '@/core/model' +import { isSurveyCompatibleWithQueen } from '@/core/tools/SurveyModelBreaking' +import { fetchUrl } from '@/core/tools/fetchUrl' +import { makeSearchParamsObjSchema } from '@/core/tools/makeSearchParamsObjectSchema' +import { getTranslation } from '@/i18n' + import { searchParamsSchema } from './parser/searchParamsSchema' -import { makeSearchParamsObjSchema } from 'core/tools/makeSearchParamsObjectSchema' -import { fetchUrl } from 'core/tools/fetchUrl' -import { isSurveyCompatibleWithQueen } from 'core/tools/SurveyModelBreaking' -import { getTranslation } from 'i18n' -import { AxiosError } from 'axios' const { t } = getTranslation('errorMessage') @@ -19,80 +21,71 @@ export const name = 'visualizeSurvey' export const reducer = null export const thunks = { - loader: - (params: { requestUrl: string }) => - async (...args) => { - const { requestUrl } = params - const url = new URL(requestUrl) - const result = makeSearchParamsObjSchema(searchParamsSchema).safeParse( - url.searchParams - ) + loader: (params: { requestUrl: string }) => async () => { + const { requestUrl } = params + const url = new URL(requestUrl) + const result = makeSearchParamsObjSchema(searchParamsSchema).safeParse( + url.searchParams, + ) - if (!result.success) { - console.error(result.error) - return null - } + if (!result.success) { + console.error(result.error) + return null + } - const { - questionnaire, - data, - readonly = false, - nomenclature, - } = result.data + const { questionnaire, data, readonly = false, nomenclature } = result.data - if (!questionnaire) { - return null - } + if (!questionnaire) { + return null + } - // TEMP : for PE, we fetch source from Queen-api which provides wrapped object : {value: source} - // We must accept it and unwrap it - const fetchedSource = await fetchUrl< - Questionnaire | WrappedQuestionnaire - >({ - url: questionnaire, - }).catch((error) => { - if ( - error instanceof AxiosError && - error.response && - [400, 403, 404, 500].includes(error.response.status) - ) { - throw new Error(t('questionnaireNotFound', { questionnaireId: '' })) - } - throw error - }) - - const isWrappedQuestionnaire = ( - source: Questionnaire | WrappedQuestionnaire - ): source is WrappedQuestionnaire => { - return ( - typeof source === 'object' && - Object.keys(source).length === 1 && - 'value' in source - ) + // TEMP : for PE, we fetch source from Queen-api which provides wrapped object : {value: source} + // We must accept it and unwrap it + const fetchedSource = await fetchUrl({ + url: questionnaire, + }).catch((error) => { + if ( + error instanceof AxiosError && + error.response && + [400, 403, 404, 500].includes(error.response.status) + ) { + throw new Error(t('questionnaireNotFound', { questionnaireId: '' })) } + throw error + }) - const source = isWrappedQuestionnaire(fetchedSource) - ? fetchedSource.value - : fetchedSource + const isWrappedQuestionnaire = ( + source: Questionnaire | WrappedQuestionnaire, + ): source is WrappedQuestionnaire => { + return ( + typeof source === 'object' && + Object.keys(source).length === 1 && + 'value' in source + ) + } - const isQuestionnaireCompatible = isSurveyCompatibleWithQueen({ - questionnaire: source, - }) + const source = isWrappedQuestionnaire(fetchedSource) + ? fetchedSource.value + : fetchedSource - if (!isQuestionnaireCompatible) { - throw new Error(t('questionnaireNotCompatible')) - } + const isQuestionnaireCompatible = isSurveyCompatibleWithQueen({ + questionnaire: source, + }) + + if (!isQuestionnaireCompatible) { + throw new Error(t('questionnaireNotCompatible')) + } - const surveyUnit = data - ? await fetchUrl({ - url: data, - }) - : undefined + const surveyUnit = data + ? await fetchUrl({ + url: data, + }) + : undefined - const getReferentiel = nomenclature - ? (name: string) => fetchUrl({ url: nomenclature[name] }) - : undefined + const getReferentiel = nomenclature + ? (name: string) => fetchUrl({ url: nomenclature[name] }) + : undefined - return { source, surveyUnit, readonly, getReferentiel } - }, + return { source, surveyUnit, readonly, getReferentiel } + }, } satisfies Thunks diff --git a/src/createCore.tsx b/src/createCore.tsx index 8ae1c9fd..6eccc99b 100644 --- a/src/createCore.tsx +++ b/src/createCore.tsx @@ -1,4 +1,4 @@ -import { createCoreProvider } from 'core' +import { createCoreProvider } from '@/core' export const { CoreProvider, prCore } = createCoreProvider({ apiUrl: import.meta.env.VITE_QUEEN_API_URL, diff --git a/src/i18n/componentKeys.ts b/src/i18n/componentKeys.ts index bf7e757a..1de7dad3 100644 --- a/src/i18n/componentKeys.ts +++ b/src/i18n/componentKeys.ts @@ -1,4 +1,5 @@ import { declareComponentKeys } from 'i18nifty' + import type { EnvValuesMessage, ErrorMessage, diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts index 1576cebd..241abf69 100644 --- a/src/i18n/i18n.ts +++ b/src/i18n/i18n.ts @@ -1,5 +1,7 @@ import { createI18nApi, declareComponentKeys } from 'i18nifty' + import type { ComponentKey } from './types' + export { declareComponentKeys } const languages = ['fr', 'en'] as const @@ -24,5 +26,5 @@ export const { { en: () => import('./resources/en').then(({ translations }) => translations), fr: () => import('./resources/fr').then(({ translations }) => translations), - } + }, ) diff --git a/src/i18n/resources/en.ts b/src/i18n/resources/en.ts index 34b0e31f..6e87ea97 100644 --- a/src/i18n/resources/en.ts +++ b/src/i18n/resources/en.ts @@ -1,4 +1,5 @@ -import { LUNATIC_MODEL_VERSION_BREAKING } from 'core/constants' +import { LUNATIC_MODEL_VERSION_BREAKING } from '@/core/constants' + import type { Translations } from '../types' export const translations: Translations<'en'> = { diff --git a/src/i18n/resources/fr.ts b/src/i18n/resources/fr.ts index d95314dd..bdf5b582 100644 --- a/src/i18n/resources/fr.ts +++ b/src/i18n/resources/fr.ts @@ -1,4 +1,5 @@ -import { LUNATIC_MODEL_VERSION_BREAKING } from 'core/constants' +import { LUNATIC_MODEL_VERSION_BREAKING } from '@/core/constants' + import type { Translations } from '../types' export const translations: Translations<'fr'> = { diff --git a/src/i18n/types.ts b/src/i18n/types.ts index 17dc6fef..4d310ab5 100644 --- a/src/i18n/types.ts +++ b/src/i18n/types.ts @@ -1,4 +1,5 @@ import type { GenericTranslations } from 'i18nifty' + import type { envValuesMessage, errorMessage, @@ -7,7 +8,7 @@ import type { synchronizeMessage, visualizeMessage, } from './componentKeys' -import type { fallbackLanguage, Language } from './i18n' +import type { Language, fallbackLanguage } from './i18n' export type ErrorMessage = | 'error' diff --git a/src/queen-service-worker.js b/src/queen-service-worker.js index f43dea43..7b43ada3 100644 --- a/src/queen-service-worker.js +++ b/src/queen-service-worker.js @@ -3,7 +3,7 @@ */ importScripts( - 'https://storage.googleapis.com/workbox-cdn/releases/7.1.0/workbox-sw.js' + 'https://storage.googleapis.com/workbox-cdn/releases/7.1.0/workbox-sw.js', ) /** @@ -51,7 +51,7 @@ registerRoute( statuses: [0, 200], }), ], - }) + }), ) // used by synchro for getting questionnaires @@ -64,7 +64,7 @@ registerRoute( statuses: [0, 200], }), ], - }) + }), ) // used by synchro for getting nomenclatures @@ -77,14 +77,14 @@ registerRoute( statuses: [0, 200], }), ], - }) + }), ) const dramaPrecacheController = async () => { const cache = await caches.open(dramaQueenCacheName) const urlsToPrecache = self.__WB_MANIFEST.reduce( (_, { url }) => [..._, `${self._DRAMAQUEEN_URL}/${url}`], - [] + [], ) await cache.addAll(urlsToPrecache) } diff --git a/src/ui/components/ErrorComponent.tsx b/src/ui/components/ErrorComponent.tsx index 794c4724..cfb31b61 100644 --- a/src/ui/components/ErrorComponent.tsx +++ b/src/ui/components/ErrorComponent.tsx @@ -1,9 +1,9 @@ import Stack from '@mui/material/Stack' import Typography from '@mui/material/Typography' -import { useTranslation } from 'i18n' - import { tss } from 'tss-react/mui' +import { useTranslation } from '@/i18n' + export function ErrorComponent(props: { message: string }) { const { message } = props diff --git a/src/ui/components/Modal.tsx b/src/ui/components/Modal.tsx index b050a3ed..ef9395b1 100644 --- a/src/ui/components/Modal.tsx +++ b/src/ui/components/Modal.tsx @@ -1,12 +1,12 @@ +import CloseIcon from '@mui/icons-material/Close' +import Button from '@mui/material/Button' import Dialog from '@mui/material/Dialog' -import DialogTitle from '@mui/material/DialogTitle' +import DialogActions from '@mui/material/DialogActions' import DialogContent from '@mui/material/DialogContent' -import IconButton from '@mui/material/IconButton' import DialogContentText from '@mui/material/DialogContentText' -import DialogActions from '@mui/material/DialogActions' -import Button from '@mui/material/Button' +import DialogTitle from '@mui/material/DialogTitle' +import IconButton from '@mui/material/IconButton' import Stack from '@mui/material/Stack' -import CloseIcon from '@mui/icons-material/Close' import { tss } from 'tss-react/mui' type ModalProps = { diff --git a/src/ui/components/orchestrator/Breadcrumb/Breadcrumb.tsx b/src/ui/components/orchestrator/Breadcrumb/Breadcrumb.tsx index 7b1ad6d8..2aa83e06 100644 --- a/src/ui/components/orchestrator/Breadcrumb/Breadcrumb.tsx +++ b/src/ui/components/orchestrator/Breadcrumb/Breadcrumb.tsx @@ -1,8 +1,10 @@ -import Button from '@mui/material/Button' import Breadcrumbs from '@mui/material/Breadcrumbs' +import Button from '@mui/material/Button' import { tss } from 'tss-react/mui' + +import { useTranslation } from '@/i18n' + import type { GoToPage, OverviewItem } from '../lunaticType' -import { useTranslation } from 'i18n' type BreadCrumbProps = { sequence: OverviewItem | undefined @@ -26,7 +28,7 @@ export function BreadCrumb(props: BreadCrumbProps) {