diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 1daea3648..1d20e637f 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -1,7 +1,8 @@ const path = require('path') module.exports = { - extends: '@ivangabriele/eslint-config-typescript-react', + extends: ['airbnb', 'airbnb/hooks', 'airbnb-typescript', 'prettier'], + plugins: ['prettier', 'sort-keys-fix', 'sort-destructure-keys', 'typescript-sort-keys'], parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 2022, @@ -12,56 +13,184 @@ module.exports = { browser: true }, rules: { - '@typescript/no-use-before-define': 'off', + curly: ['error', 'all'], + 'newline-before-return': 'error', + 'no-console': 'error', + + 'import/no-default-export': 'error', + 'import/order': [ + 'error', + { + alphabetize: { + caseInsensitive: true, + order: 'asc' + }, + groups: [['builtin', 'external', 'internal'], ['parent', 'index', 'sibling'], ['type'], ['object']], + 'newlines-between': 'always' + } + ], + 'import/prefer-default-export': 'off', + + 'prettier/prettier': 'error', + + 'react/jsx-pascal-case': [ + 'error', + { + ignore: ['LEGACY_*'] + } + ], + 'react/jsx-no-useless-fragment': 'off', + 'react/jsx-sort-props': 'error', + 'react/prop-types': 'off', + 'react/react-in-jsx-scope': 'off', + 'react/require-default-props': 'off', + + 'sort-destructure-keys/sort-destructure-keys': ['error', { caseSensitive: false }], + + 'sort-keys-fix/sort-keys-fix': ['error', 'asc', { caseSensitive: false, natural: false }], + + '@typescript-eslint/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }], + // We must add PascalCase in formats because ESLint trim the prefix before evaluating the case + // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/naming-convention.md#format-options + // > Note: As documented above, the prefix is trimmed before format is validated, + // > therefore PascalCase must be used to allow variables such as isEnabled using the prefix is. + '@typescript-eslint/naming-convention': [ + 'warn', + { + selector: 'function', + format: ['camelCase', 'PascalCase'] + }, + { + selector: 'typeLike', + format: ['PascalCase'] + }, + { + selector: 'accessor', + types: ['boolean'], + format: ['camelCase', 'PascalCase'] + }, + { + selector: 'classProperty', + types: ['boolean'], + format: ['camelCase', 'PascalCase'] + }, + { + selector: 'objectLiteralProperty', + types: ['boolean'], + format: ['camelCase', 'PascalCase'] + }, + { + selector: 'parameter', + types: ['boolean'], + format: ['camelCase', 'PascalCase'] + }, + { + selector: 'parameterProperty', + types: ['boolean'], + format: ['camelCase', 'PascalCase'] + }, + { + selector: 'variable', + types: ['boolean'], + format: ['camelCase', 'PascalCase', 'UPPER_CASE'] + } + ], + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + name: 'react-redux', + importNames: ['useSelector', 'useDispatch'], + message: 'Use typed hooks `useAppDispatch` and `useAppSelector` instead.' + } + ], '@typescript-eslint/no-use-before-define': 'off', - 'react/react-in-jsx-scope': 'off' + 'typescript-sort-keys/interface': 'error', + 'typescript-sort-keys/string-enum': 'error' }, overrides: [ + // Redux { - files: [ - 'src/domain/shared_slices/**/*.ts', - 'src/domain/shared_slices/**/*.js', - 'src/**/*.slice.ts', - 'src/**/*.slice.js', - 'src/**/slice.ts' - ], + files: ['src/domain/shared_slices/**/*.ts', 'src/**/slice.ts'], + rules: { + 'no-param-reassign': 'off' + } + }, + { + files: ['src/domain/types/*.ts', 'src/domain/**/types.ts', 'src/domain/shared_slices/**/*.ts', 'src/**/slice.ts'], + plugins: ['no-null'], rules: { 'no-param-reassign': 'off' } }, + + // UI { files: ['src/ui/**/*.tsx'], rules: { 'react/jsx-props-no-spreading': 'off' } }, + + // Jest + { + files: ['**/*.test.ts', '**/*.test.tsx'], + plugins: ['jest'], + env: { + jest: true + }, + rules: { + 'jest/no-disabled-tests': 'error', + 'jest/no-focused-tests': 'error', + 'jest/no-identical-title': 'error', + 'jest/prefer-to-have-length': 'error', + 'jest/valid-expect': 'error' + } + }, + + // Cypress { files: ['cypress/**/*.js', 'cypress/**/*.ts', 'cypress.config.ts'], - plugins: ['cypress', 'no-only-tests'], + plugins: ['cypress', 'mocha'], rules: { - 'cypress/no-assigning-return-values': 'error', - // TODO Hopefully we'll able to enforce that rule someday. - 'cypress/no-unnecessary-waiting': 'off', + // TODO Check why either Prettier or ESLint auto-formatting does that and why this rule is not enabled. + // 'max-len': ['warn', { code: 120 }], + + '@typescript-eslint/naming-convention': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + 'cypress/assertion-before-screenshot': 'error', + 'cypress/no-assigning-return-values': 'error', + 'cypress/no-async-tests': 'error', // TODO Hopefully we'll able to enforce that rule someday. 'cypress/no-force': 'off', - 'cypress/no-async-tests': 'error', 'cypress/no-pause': 'error', + // TODO Hopefully we'll able to enforce that rule someday. + 'cypress/no-unnecessary-waiting': 'off', 'import/no-default-export': 'off', 'import/no-extraneous-dependencies': 'off', - 'no-only-tests/no-only-tests': 'error' + + 'mocha/no-exclusive-tests': 'error', + 'mocha/no-skipped-tests': 'error' } }, - // Custom monitorenv rule + + // Configs & scripts { - files: ['**/*.stories.*'], - rules: { - 'import/no-anonymous-default-export': 'off', - 'import/no-default-export': 'off', - 'react/jsx-props-no-spreading': 'off', - 'no-console': 'off' + files: [ + '**/*.spec.js', + './*.cjs', + './*.js', + './config/**/*.js', + './scripts/**/*.js', + '**/*.spec.ts', + './config/**/*.ts', + './scripts/**/*.ts' + ], + env: { + browser: false, + node: true } } ] diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d8819dccc..4b1a18b4d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,8 +9,6 @@ "version": "0.1.0", "license": "AGPL-3.0", "dependencies": { - "@dnd-kit/core": "^4.0.3", - "@dnd-kit/modifiers": "^4.0.0", "@mtes-mct/monitor-ui": "10.1.1", "@reduxjs/toolkit": "1.9.5", "@rsuite/responsive-nav": "5.0.1", @@ -54,8 +52,6 @@ "yup": "^0.32.11" }, "devDependencies": { - "@ivangabriele/eslint-config-typescript-react": "4.2.0", - "@ivangabriele/prettier-config": "3.1.0", "@jest/globals": "29.7.0", "@storybook/addon-actions": "7.1.1", "@storybook/addon-essentials": "7.1.1", @@ -2371,50 +2367,6 @@ "node": ">=10.0.0" } }, - "node_modules/@dnd-kit/accessibility": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@dnd-kit/core": { - "version": "4.0.3", - "license": "MIT", - "dependencies": { - "@dnd-kit/accessibility": "^3.0.0", - "@dnd-kit/utilities": "^3.0.1", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@dnd-kit/modifiers": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "@dnd-kit/utilities": "^3.0.0", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "@dnd-kit/core": "^4.0.0" - } - }, - "node_modules/@dnd-kit/utilities": { - "version": "3.2.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.0", "license": "MIT", @@ -2713,39 +2665,6 @@ "node": ">=8" } }, - "node_modules/@ivangabriele/eslint-config-typescript-react": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@ivangabriele/prettier-config": "^3.0.2", - "@typescript-eslint/eslint-plugin": "^5.18.0", - "@typescript-eslint/parser": "^5.18.0", - "eslint": "^8.0.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.0.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-sort-destructure-keys": "^1.4.0", - "eslint-plugin-sort-keys-fix": "^1.1.2", - "eslint-plugin-typescript-sort-keys": "^2.1.0", - "prettier": "^2.5.1", - "typescript": "^4.4.4" - } - }, - "node_modules/@ivangabriele/prettier-config": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "prettier": "^2.0.0" - } - }, "node_modules/@jest/console": { "version": "27.5.1", "license": "MIT", diff --git a/frontend/package.json b/frontend/package.json index 6ade133eb..2d9d6af20 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,8 +31,6 @@ "test:unit:watch": "npm run test:unit -- --watch" }, "dependencies": { - "@dnd-kit/core": "^4.0.3", - "@dnd-kit/modifiers": "^4.0.0", "@mtes-mct/monitor-ui": "10.1.1", "@reduxjs/toolkit": "1.9.5", "@rsuite/responsive-nav": "5.0.1", @@ -76,8 +74,6 @@ "yup": "^0.32.11" }, "devDependencies": { - "@ivangabriele/eslint-config-typescript-react": "4.2.0", - "@ivangabriele/prettier-config": "3.1.0", "@jest/globals": "29.7.0", "@storybook/addon-actions": "7.1.1", "@storybook/addon-essentials": "7.1.1", diff --git a/frontend/src/api/APIWorker.js b/frontend/src/api/APIWorker.js index 346479f2a..51e60a844 100644 --- a/frontend/src/api/APIWorker.js +++ b/frontend/src/api/APIWorker.js @@ -1,13 +1,14 @@ import { useEffect } from 'react' -import { batch, useDispatch } from 'react-redux' +import { batch } from 'react-redux' import { loadRegulatoryData } from '../domain/use_cases/regulatory/loadRegulatoryData' +import { useAppDispatch } from '../hooks/useAppDispatch' export const FIVE_MINUTES = 5 * 60 * 1000 export const THIRTY_SECONDS = 30 * 1000 export function APIWorker() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() useEffect(() => { batch(() => { diff --git a/frontend/src/domain/shared_slices/index.ts b/frontend/src/domain/shared_slices/index.ts index d3d960fb1..11997d8f1 100644 --- a/frontend/src/domain/shared_slices/index.ts +++ b/frontend/src/domain/shared_slices/index.ts @@ -33,7 +33,7 @@ import { baseTablePersistedReducer } from '../../features/Base/components/BaseTa import { controlUnitDialogReducer } from '../../features/ControlUnit/components/ControlUnitDialog/slice' import { controlUnitListDialogPersistedReducer } from '../../features/ControlUnit/components/ControlUnitListDialog/slice' import { controlUnitTablePersistedReducer } from '../../features/ControlUnit/components/ControlUnitTable/slice' -import { layerSearchSliceReducer } from '../../features/layersSelector/search/LayerSearch.slice' +import { layerSearchSliceReducer } from '../../features/layersSelector/search/slice' import { mainWindowReducer } from '../../features/MainWindow/slice' import { sideWindowReducer } from '../../features/SideWindow/slice' diff --git a/frontend/src/features/LocateOnMap/index.tsx b/frontend/src/features/LocateOnMap/index.tsx index d371b1c4d..a0ebfab56 100644 --- a/frontend/src/features/LocateOnMap/index.tsx +++ b/frontend/src/features/LocateOnMap/index.tsx @@ -1,17 +1,17 @@ import { Accent, Icon, IconButton, Search, Size } from '@mtes-mct/monitor-ui' import { transformExtent } from 'ol/proj' import { useState } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { getPlaceCoordinates, useGooglePlacesAPI } from '../../api/googlePlacesAPI/googlePlacesAPI' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from '../../domain/entities/map/constants' import { ReportingContext, VisibilityState } from '../../domain/shared_slices/Global' import { setFitToExtent } from '../../domain/shared_slices/Map' +import { useAppDispatch } from '../../hooks/useAppDispatch' import { useAppSelector } from '../../hooks/useAppSelector' export function LocateOnMap() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { reportingFormVisibility } = useAppSelector(state => state.global) const [searchedLocation, setSearchedLocation] = useState('') const results = useGooglePlacesAPI(searchedLocation) diff --git a/frontend/src/features/Reportings/Filters/Map/index.tsx b/frontend/src/features/Reportings/Filters/Map/index.tsx index 0710c59c0..634a8721e 100644 --- a/frontend/src/features/Reportings/Filters/Map/index.tsx +++ b/frontend/src/features/Reportings/Filters/Map/index.tsx @@ -1,10 +1,10 @@ import { DateRangePicker, Checkbox, SingleTag, Accent } from '@mtes-mct/monitor-ui' import { forwardRef, useRef } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { ReportingSourceLabels } from '../../../../domain/entities/reporting' import { ReportingsFiltersEnum, reportingsFiltersActions } from '../../../../domain/shared_slices/ReportingsFilters' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { OptionValue, StyledCheckPicker, StyledSelect, StyledStatusFilter } from '../style' @@ -20,7 +20,7 @@ export function MapReportingsFiltersWithRef( }, ref ) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { periodFilter, sourceTypeFilter, diff --git a/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx b/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx index 11590f446..47d60d40c 100644 --- a/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx +++ b/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx @@ -1,13 +1,13 @@ import { Accent, SingleTag } from '@mtes-mct/monitor-ui' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { ReportingSourceLabels } from '../../../../domain/entities/reporting' import { ReportingsFiltersEnum, reportingsFiltersActions } from '../../../../domain/shared_slices/ReportingsFilters' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' export function FilterTags() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { seaFrontFilter, sourceFilter, sourceTypeFilter, subThemesFilter, themeFilter } = useAppSelector( state => state.reportingFilters ) diff --git a/frontend/src/features/Reportings/Filters/index.tsx b/frontend/src/features/Reportings/Filters/index.tsx index acf03442f..cc09aec62 100644 --- a/frontend/src/features/Reportings/Filters/index.tsx +++ b/frontend/src/features/Reportings/Filters/index.tsx @@ -1,7 +1,6 @@ import { customDayjs, type DateAsStringRange, getOptionsFromLabelledEnum } from '@mtes-mct/monitor-ui' import _, { reduce } from 'lodash' import { type MutableRefObject, useMemo, useRef, useState } from 'react' -import { useDispatch } from 'react-redux' import { MapReportingsFilters } from './Map' import { TableReportingsFilters } from './Table' @@ -17,6 +16,7 @@ import { } from '../../../domain/entities/reporting' import { seaFrontLabels } from '../../../domain/entities/seaFrontType' import { ReportingsFiltersEnum, reportingsFiltersActions } from '../../../domain/shared_slices/ReportingsFilters' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { getSubThemesAsListOptions } from '../../../utils/getSubThemesAsListOptions' import { getThemesAsListOptions } from '../../../utils/getThemesAsListOptions' @@ -26,7 +26,7 @@ export enum ReportingFilterContext { TABLE = 'TABLE' } export function ReportingsFilters({ context = ReportingFilterContext.TABLE }: { context?: string }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { periodFilter, sourceTypeFilter } = useAppSelector(state => state.reportingFilters) const wrapperRef = useRef() as MutableRefObject const [isCustomPeriodVisible, setIsCustomPeriodVisible] = useState(periodFilter === DateRangeEnum.CUSTOM) diff --git a/frontend/src/features/Reportings/ReportingForm/Form.tsx b/frontend/src/features/Reportings/ReportingForm/Form.tsx index 00aeea5ed..ec0845de0 100644 --- a/frontend/src/features/Reportings/ReportingForm/Form.tsx +++ b/frontend/src/features/Reportings/ReportingForm/Form.tsx @@ -1,7 +1,6 @@ import { Accent, FieldError, FormikTextarea, Icon, IconButton, getOptionsFromLabelledEnum } from '@mtes-mct/monitor-ui' import { useField, useFormikContext } from 'formik' import { useEffect, useState } from 'react' -import { useDispatch } from 'react-redux' import { Toggle } from 'rsuite' import { CancelEditDialog } from './FormComponents/Dialog/CancelEditDialog' @@ -23,6 +22,7 @@ import { reportingActions } from '../../../domain/shared_slices/reporting' import { closeReporting } from '../../../domain/use_cases/reporting/closeReporting' import { deleteReporting } from '../../../domain/use_cases/reporting/deleteReporting' import { reduceOrExpandReportingForm } from '../../../domain/use_cases/reporting/reduceOrExpandReportingForm' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { DeleteModal } from '../../commonComponents/Modals/Delete' import { useSyncFormValuesWithRedux } from '../hooks/useSyncFormValuesWithRedux' @@ -42,7 +42,7 @@ import { import { getReportingTitle } from '../utils' export function ReportingForm({ reducedReportingsOnContext, selectedReporting, setShouldValidateOnChange }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const reportingFormVisibility = useAppSelector(state => state.global.reportingFormVisibility) const isConfirmCancelDialogVisible = useAppSelector(state => state.reporting.isConfirmCancelDialogVisible) diff --git a/frontend/src/features/Reportings/ReportingForm/FormComponents/Footer.tsx b/frontend/src/features/Reportings/ReportingForm/FormComponents/Footer.tsx index a57d49a27..ed6af46bb 100644 --- a/frontend/src/features/Reportings/ReportingForm/FormComponents/Footer.tsx +++ b/frontend/src/features/Reportings/ReportingForm/FormComponents/Footer.tsx @@ -1,11 +1,11 @@ import { Accent, Icon, THEME, customDayjs, getLocalizedDayjs } from '@mtes-mct/monitor-ui' import { useFormikContext } from 'formik' import _ from 'lodash' -import { useDispatch } from 'react-redux' import { ReportingStatusEnum, type Reporting, getReportingStatus } from '../../../../domain/entities/reporting' import { ReportingContext } from '../../../../domain/shared_slices/Global' import { reopenReporting } from '../../../../domain/use_cases/reporting/reopenReporting' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { StyledButton, StyledSubmitButton, StyledDeleteButton, StyledFooter } from '../../style' import { isNewReporting } from '../../utils' @@ -16,7 +16,7 @@ export function Footer({ onCancel, onDelete, setMustIncreaseValidity, setShouldV const reportingContext = useAppSelector(state => activeReportingId ? state.reporting.reportings[activeReportingId]?.context : undefined ) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { handleSubmit, setFieldValue, validateForm, values } = useFormikContext() const reportingStatus = getReportingStatus(values) diff --git a/frontend/src/features/Reportings/ReportingForm/FormComponents/Position/index.tsx b/frontend/src/features/Reportings/ReportingForm/FormComponents/Position/index.tsx index dd1736e32..1045f4ef7 100644 --- a/frontend/src/features/Reportings/ReportingForm/FormComponents/Position/index.tsx +++ b/frontend/src/features/Reportings/ReportingForm/FormComponents/Position/index.tsx @@ -1,16 +1,16 @@ import { Accent, Button, Label, Icon, FieldError } from '@mtes-mct/monitor-ui' import { useField } from 'formik' import { useCallback } from 'react' -import { useDispatch } from 'react-redux' import { PointPicker } from './PointPicker' import { ZonePicker } from './ZonePicker' import { InteractionListener } from '../../../../../domain/entities/map/constants' import { drawPoint, drawPolygon } from '../../../../../domain/use_cases/draw/drawGeometry' +import { useAppDispatch } from '../../../../../hooks/useAppDispatch' import { StyledPositionContainer } from '../../../style' export function Position() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const [field, meta] = useField('geom') const { value } = field diff --git a/frontend/src/features/Reportings/ReportingForm/index.tsx b/frontend/src/features/Reportings/ReportingForm/index.tsx index 8963134f4..c1ef62f7d 100644 --- a/frontend/src/features/Reportings/ReportingForm/index.tsx +++ b/frontend/src/features/Reportings/ReportingForm/index.tsx @@ -1,7 +1,6 @@ import { skipToken } from '@reduxjs/toolkit/dist/query' import { Form, Formik } from 'formik' import { useMemo, useState } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { ReportingForm } from './Form' @@ -9,6 +8,7 @@ import { ReportingSchema } from './Schema' import { useGetReportingQuery } from '../../../api/reportingsAPI' import { ReportingContext, VisibilityState } from '../../../domain/shared_slices/Global' import { saveReporting } from '../../../domain/use_cases/reporting/saveReporting' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { SideWindowBackground, FormContainer } from '../style' import { getReportingInitialValues, isNewReporting } from '../utils' @@ -21,7 +21,7 @@ export function ReportingFormWithContext({ context, totalReportings }) { activeReportingId ? state.reporting.reportings[activeReportingId]?.context : undefined ) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const isReportingNew = useMemo(() => isNewReporting(activeReportingId), [activeReportingId]) diff --git a/frontend/src/features/Reportings/ReportingsButton/SearchReportings.tsx b/frontend/src/features/Reportings/ReportingsButton/SearchReportings.tsx index f064d3a5b..fd01d4530 100644 --- a/frontend/src/features/Reportings/ReportingsButton/SearchReportings.tsx +++ b/frontend/src/features/Reportings/ReportingsButton/SearchReportings.tsx @@ -1,17 +1,17 @@ import { Accent, Button, Icon, MapMenuDialog } from '@mtes-mct/monitor-ui' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { sideWindowPaths } from '../../../domain/entities/sideWindow' import { setDisplayedItems, ReportingContext } from '../../../domain/shared_slices/Global' import { saveMissionInLocalStore } from '../../../domain/use_cases/missions/saveMissionInLocalStore' import { addReporting } from '../../../domain/use_cases/reporting/addReporting' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { sideWindowActions } from '../../SideWindow/slice' import { ReportingFilterContext, ReportingsFilters } from '../Filters' export function SearchReportings() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { global: { displayReportingsLayer } } = useAppSelector(state => state) diff --git a/frontend/src/features/Reportings/ReportingsList/Cells/CellLocalizeReporting.tsx b/frontend/src/features/Reportings/ReportingsList/Cells/CellLocalizeReporting.tsx index 4ea010e14..1733a7fd6 100644 --- a/frontend/src/features/Reportings/ReportingsList/Cells/CellLocalizeReporting.tsx +++ b/frontend/src/features/Reportings/ReportingsList/Cells/CellLocalizeReporting.tsx @@ -1,13 +1,13 @@ import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui' import GeoJSON from 'ol/format/GeoJSON' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { OPENLAYERS_PROJECTION } from '../../../../domain/entities/map/constants' import { setFitToExtent } from '../../../../domain/shared_slices/Map' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' export function CellLocalizeReporting({ geom }: { geom: any }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() if (!geom) { return - diff --git a/frontend/src/features/Reportings/index.tsx b/frontend/src/features/Reportings/index.tsx index fb7c03fb7..e5be09032 100644 --- a/frontend/src/features/Reportings/index.tsx +++ b/frontend/src/features/Reportings/index.tsx @@ -1,7 +1,6 @@ import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui' import _ from 'lodash' import { useMemo } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { ReportingFormWithContext } from './ReportingForm' @@ -11,6 +10,7 @@ import { hideSideButtons, ReportingContext, VisibilityState } from '../../domain import { closeReporting } from '../../domain/use_cases/reporting/closeReporting' import { reduceOrExpandReportingForm } from '../../domain/use_cases/reporting/reduceOrExpandReportingForm' import { switchReporting } from '../../domain/use_cases/reporting/switchReporting' +import { useAppDispatch } from '../../hooks/useAppDispatch' import { useAppSelector } from '../../hooks/useAppSelector' export function Reportings({ context }: { context: ReportingContext }) { @@ -21,7 +21,7 @@ export function Reportings({ context }: { context: ReportingContext }) { activeReportingId ? state.reporting.reportings[activeReportingId]?.context : undefined ) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const reportingsTabs = useMemo( () => _.chain(Object.entries(reportings)) diff --git a/frontend/src/features/Semaphores/SearchSemaphoreButton/SearchSemaphores.tsx b/frontend/src/features/Semaphores/SearchSemaphoreButton/SearchSemaphores.tsx index ba968fe55..b2b277733 100644 --- a/frontend/src/features/Semaphores/SearchSemaphoreButton/SearchSemaphores.tsx +++ b/frontend/src/features/Semaphores/SearchSemaphoreButton/SearchSemaphores.tsx @@ -2,7 +2,6 @@ import { Accent, CustomSearch, Icon, Search } from '@mtes-mct/monitor-ui' import { reduce } from 'lodash' import { GeoJSON } from 'ol/format' import { useRef, useState } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { useGetSemaphoresQuery } from '../../../api/semaphoresAPI' @@ -10,13 +9,14 @@ import { OPENLAYERS_PROJECTION } from '../../../domain/entities/map/constants' import { setDisplayedItems } from '../../../domain/shared_slices/Global' import { setFitToExtent } from '../../../domain/shared_slices/Map' import { addSemaphore, setSelectedSemaphore } from '../../../domain/shared_slices/SemaphoresSlice' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { MenuWithCloseButton } from '../../commonStyles/map/MenuWithCloseButton' import type { Semaphore } from '../../../domain/entities/semaphore' export function SearchSemaphores() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { displaySemaphoresLayer } = useAppSelector(state => state.global) const { semaphoresResearchHistory } = useAppSelector(state => state.semaphoresSlice) diff --git a/frontend/src/features/SideWindow/index.tsx b/frontend/src/features/SideWindow/index.tsx index 1e1af20e6..83f3137e4 100644 --- a/frontend/src/features/SideWindow/index.tsx +++ b/frontend/src/features/SideWindow/index.tsx @@ -1,6 +1,5 @@ import { Icon, SideMenu, type NewWindowContextValue, NewWindowContext } from '@mtes-mct/monitor-ui' import { forwardRef, useEffect, useImperativeHandle, useMemo, useState, useRef } from 'react' -import { useDispatch } from 'react-redux' import { generatePath } from 'react-router' import { ToastContainer } from 'react-toastify' @@ -11,6 +10,7 @@ import { ErrorBoundary } from '../../components/ErrorBoundary' import { sideWindowPaths } from '../../domain/entities/sideWindow' import { ReportingContext } from '../../domain/shared_slices/Global' import { switchTab } from '../../domain/use_cases/missions/switchTab' +import { useAppDispatch } from '../../hooks/useAppDispatch' import { useAppSelector } from '../../hooks/useAppSelector' import { isMissionOrMissionsPage, isMissionPage, isReportingsPage } from '../../utils/routes' import { Mission } from '../missions/MissionForm' @@ -29,7 +29,7 @@ function SideWindowWithRef(_, ref: ForwardedRef) { const [isFirstRender, setIsFirstRender] = useState(true) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const isMissionButtonIsActive = useMemo(() => isMissionOrMissionsPage(currentPath), [currentPath]) const isReportingsButtonIsActive = useMemo(() => isReportingsPage(currentPath), [currentPath]) diff --git a/frontend/src/features/healthcheck/Healthcheck.js b/frontend/src/features/healthcheck/Healthcheck.js index 3739057ce..f5eabc94b 100644 --- a/frontend/src/features/healthcheck/Healthcheck.js +++ b/frontend/src/features/healthcheck/Healthcheck.js @@ -1,11 +1,11 @@ import React from 'react' -import { useSelector } from 'react-redux' import styled from 'styled-components' +import { useAppSelector } from '../../hooks/useAppSelector' import { ReactComponent as WarningSVG } from '../../uiMonitor/icons/Alert.svg' function Healthcheck() { - const { healthcheckTextWarning } = useSelector(state => state.global) + const { healthcheckTextWarning } = useAppSelector(state => state.global) return ( <> diff --git a/frontend/src/features/layersSelector/administrative/AdministrativeLayer.tsx b/frontend/src/features/layersSelector/administrative/AdministrativeLayer.tsx index d0d4e8a34..69b2dabbd 100644 --- a/frontend/src/features/layersSelector/administrative/AdministrativeLayer.tsx +++ b/frontend/src/features/layersSelector/administrative/AdministrativeLayer.tsx @@ -1,12 +1,12 @@ -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { hideAdministrativeLayer, showAdministrativeLayer } from '../../../domain/shared_slices/Administrative' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { ReactComponent as DisplaySVG } from '../../../uiMonitor/icons/Display.svg' export function AdministrativeLayer({ isGrouped, layer }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { showedAdministrativeLayerIds } = useAppSelector(state => state.administrative) const isLayerVisible = showedAdministrativeLayerIds.includes(layer.code as number) diff --git a/frontend/src/features/layersSelector/administrative/index.tsx b/frontend/src/features/layersSelector/administrative/index.tsx index 8b871ba6e..fb66eec13 100644 --- a/frontend/src/features/layersSelector/administrative/index.tsx +++ b/frontend/src/features/layersSelector/administrative/index.tsx @@ -1,15 +1,15 @@ -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { AdministrativeLayer } from './AdministrativeLayer' import { administrativeLayers } from '../../../domain/entities/administrativeLayers' import { toggleAdministrativeZones } from '../../../domain/shared_slices/LayerSidebar' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { ChevronIcon } from '../../commonStyles/icons/ChevronIcon.style' import { LayerSelectorMenu } from '../utils/LayerSelectorMenu.style' export function AdministrativeLayers() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { administrativeZonesIsOpen } = useAppSelector(state => state.layerSidebar) const onSectionTitleClicked = () => { diff --git a/frontend/src/features/layersSelector/amp/AMPLayerGroup.tsx b/frontend/src/features/layersSelector/amp/AMPLayerGroup.tsx index 4fb74f39e..be46672f4 100644 --- a/frontend/src/features/layersSelector/amp/AMPLayerGroup.tsx +++ b/frontend/src/features/layersSelector/amp/AMPLayerGroup.tsx @@ -1,14 +1,14 @@ import { Accent, Icon, IconButton, Size, Tag, THEME } from '@mtes-mct/monitor-ui' import _ from 'lodash' import { useState } from 'react' -import { useDispatch } from 'react-redux' import { AMPLayerZone } from './AMPLayerZone' import { hideAmpLayers, removeAmpZonesFromMyLayers, showAmpLayer } from '../../../domain/shared_slices/SelectedAmp' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { LayerSelector } from '../utils/LayerSelector.style' export function AMPLayerGroup({ groupName, layers, showedAmpLayerIds }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const groupLayerIds = layers.map(l => l.id) const [zonesAreOpen, setZonesAreOpen] = useState(false) diff --git a/frontend/src/features/layersSelector/amp/AMPLayerZone.tsx b/frontend/src/features/layersSelector/amp/AMPLayerZone.tsx index 490e0b7ea..2b044c26d 100644 --- a/frontend/src/features/layersSelector/amp/AMPLayerZone.tsx +++ b/frontend/src/features/layersSelector/amp/AMPLayerZone.tsx @@ -1,18 +1,18 @@ import { Accent, Icon, IconButton, Size } from '@mtes-mct/monitor-ui' import { transformExtent } from 'ol/proj' import Projection from 'ol/proj/Projection' -import { useDispatch } from 'react-redux' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from '../../../domain/entities/map/constants' import { setFitToExtent } from '../../../domain/shared_slices/Map' import { hideAmpLayer, removeAmpZonesFromMyLayers, showAmpLayer } from '../../../domain/shared_slices/SelectedAmp' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { AMPLayerLegend } from '../utils/LayerLegend.style' import { LayerSelector } from '../utils/LayerSelector.style' import type { AMP } from '../../../domain/entities/AMPs' export function AMPLayerZone({ amp, isDisplayed }: { amp: AMP; isDisplayed: boolean }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const handleRemoveZone = () => dispatch(removeAmpZonesFromMyLayers([amp.id])) const zoomToLayerExtent = () => { diff --git a/frontend/src/features/layersSelector/amp/index.tsx b/frontend/src/features/layersSelector/amp/index.tsx index 1e9b9b1a8..772812b0e 100644 --- a/frontend/src/features/layersSelector/amp/index.tsx +++ b/frontend/src/features/layersSelector/amp/index.tsx @@ -1,13 +1,12 @@ -import { useDispatch } from 'react-redux' - import { AMPLayersList } from './AMPLayersList' import { toggleMyAmps } from '../../../domain/shared_slices/LayerSidebar' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { ChevronIcon } from '../../commonStyles/icons/ChevronIcon.style' import { LayerSelectorMenu } from '../utils/LayerSelectorMenu.style' export function AmpLayers() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { selectedAmpLayerIds } = useAppSelector(state => state.selectedAmp) const { myAmpsIsOpen } = useAppSelector(state => state.layerSidebar) diff --git a/frontend/src/features/layersSelector/base/index.tsx b/frontend/src/features/layersSelector/base/index.tsx index 82f4e0f98..0bcb9f438 100644 --- a/frontend/src/features/layersSelector/base/index.tsx +++ b/frontend/src/features/layersSelector/base/index.tsx @@ -1,4 +1,3 @@ -import { useDispatch } from 'react-redux' import { RadioGroup } from 'rsuite' import styled from 'styled-components' @@ -6,6 +5,7 @@ import { BaseLayerItem } from './BaseLayerItem' import { BaseLayers } from '../../../domain/entities/layers/constants' import { toggleBaseLayer } from '../../../domain/shared_slices/LayerSidebar' import { selectBaseLayer } from '../../../domain/shared_slices/Map' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { ChevronIcon } from '../../commonStyles/icons/ChevronIcon.style' import { LayerSelectorMenu } from '../utils/LayerSelectorMenu.style' @@ -13,7 +13,7 @@ import { LayerSelectorMenu } from '../utils/LayerSelectorMenu.style' const baseLayersKeys = Object.keys(BaseLayers).filter(key => key !== BaseLayers.DARK.code) export function BaseLayerList() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { baselayerIsOpen } = useAppSelector(state => state.layerSidebar) const { selectedBaseLayer } = useAppSelector(state => state.map) const onSectionTitleClicked = () => { diff --git a/frontend/src/features/layersSelector/index.tsx b/frontend/src/features/layersSelector/index.tsx index a2d0df770..b4f319492 100644 --- a/frontend/src/features/layersSelector/index.tsx +++ b/frontend/src/features/layersSelector/index.tsx @@ -1,6 +1,5 @@ import { IconButton, Accent, Size, Icon, THEME } from '@mtes-mct/monitor-ui' import { FulfillingBouncingCircleSpinner } from 'react-epic-spinners' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { AdministrativeLayers } from './administrative' @@ -12,6 +11,7 @@ import { LayerSearch } from './search' import { useGetAMPsQuery } from '../../api/ampsAPI' import { setDisplayedItems } from '../../domain/shared_slices/Global' import { closeRegulatoryZoneMetadata } from '../../domain/use_cases/regulatory/closeRegulatoryZoneMetadata' +import { useAppDispatch } from '../../hooks/useAppDispatch' import { useAppSelector } from '../../hooks/useAppSelector' export function LayersSidebar() { @@ -20,7 +20,7 @@ export function LayersSidebar() { const { regulatoryLayers } = useAppSelector(state => state.regulatory) const amps = useGetAMPsQuery() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const toggleLayerSidebar = () => { if (isLayersSidebarVisible) { diff --git a/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerGroup.tsx b/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerGroup.tsx index 47cb7cd61..78c4fbae9 100644 --- a/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerGroup.tsx +++ b/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerGroup.tsx @@ -1,7 +1,6 @@ import { Tag, IconButton, Accent, Icon, Size, THEME } from '@mtes-mct/monitor-ui' import _ from 'lodash' import { useState } from 'react' -import { useDispatch } from 'react-redux' import { RegulatoryLayerZone } from './RegulatoryLayerZone' import { @@ -9,11 +8,12 @@ import { removeRegulatoryZonesFromMyLayers, showRegulatoryLayer } from '../../../../domain/shared_slices/Regulatory' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { LayerSelector } from '../../utils/LayerSelector.style' export function RegulatoryLayerGroup({ groupName, layers }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { showedRegulatoryLayerIds } = useAppSelector(state => state.regulatory) const { regulatoryMetadataLayerId } = useAppSelector(state => state.regulatoryMetadata) const groupLayerIds = layers.map(l => l.id) diff --git a/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerZone.tsx b/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerZone.tsx index 27e46dbf2..f739bc600 100644 --- a/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerZone.tsx +++ b/frontend/src/features/layersSelector/regulatory/menu/RegulatoryLayerZone.tsx @@ -1,7 +1,6 @@ import { IconButton, Accent, Size, Icon, THEME } from '@mtes-mct/monitor-ui' import { transformExtent } from 'ol/proj' import Projection from 'ol/proj/Projection' -import { useDispatch } from 'react-redux' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from '../../../../domain/entities/map/constants' import { setFitToExtent } from '../../../../domain/shared_slices/Map' @@ -12,12 +11,13 @@ import { } from '../../../../domain/shared_slices/Regulatory' import { closeRegulatoryZoneMetadata } from '../../../../domain/use_cases/regulatory/closeRegulatoryZoneMetadata' import { showRegulatoryZoneMetadata } from '../../../../domain/use_cases/regulatory/showRegulatoryZoneMetadata' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { RegulatoryLayerLegend } from '../../utils/LayerLegend.style' import { LayerSelector } from '../../utils/LayerSelector.style' export function RegulatoryLayerZone({ regulatoryZone }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { showedRegulatoryLayerIds } = useAppSelector(state => state.regulatory) const { regulatoryMetadataLayerId, regulatoryMetadataPanelIsOpen } = useAppSelector(state => state.regulatoryMetadata) const regulatoryZoneIsShowed = showedRegulatoryLayerIds.includes(regulatoryZone.id) diff --git a/frontend/src/features/layersSelector/regulatory/menu/index.tsx b/frontend/src/features/layersSelector/regulatory/menu/index.tsx index 70c45740a..7e9573317 100644 --- a/frontend/src/features/layersSelector/regulatory/menu/index.tsx +++ b/frontend/src/features/layersSelector/regulatory/menu/index.tsx @@ -1,13 +1,12 @@ -import { useDispatch } from 'react-redux' - import { RegulatoryLayersList } from './RegulatoryLayersList' import { toggleMyRegulatoryZones } from '../../../../domain/shared_slices/LayerSidebar' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { ChevronIcon } from '../../../commonStyles/icons/ChevronIcon.style' import { LayerSelectorMenu } from '../../utils/LayerSelectorMenu.style' export function RegulatoryLayers() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { regulatoryLayers, selectedRegulatoryLayerIds } = useAppSelector(state => state.regulatory) const { myRegulatoryZonesIsOpen } = useAppSelector(state => state.layerSidebar) diff --git a/frontend/src/features/layersSelector/regulatory/metadata/index.tsx b/frontend/src/features/layersSelector/regulatory/metadata/index.tsx index c9bac3ffa..39593f9f8 100644 --- a/frontend/src/features/layersSelector/regulatory/metadata/index.tsx +++ b/frontend/src/features/layersSelector/regulatory/metadata/index.tsx @@ -1,7 +1,6 @@ import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui' import { useCallback } from 'react' import { FingerprintSpinner } from 'react-epic-spinners' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { Identification } from './Identification' @@ -9,6 +8,7 @@ import { MetadataRegulatoryReferences } from './MetadataRegulatoryReferences' import { useGetRegulatoryLayerQuery } from '../../../../api/regulatoryLayersAPI' import { getTitle } from '../../../../domain/entities/regulatory' import { closeRegulatoryZoneMetadata } from '../../../../domain/use_cases/regulatory/closeRegulatoryZoneMetadata' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { ReactComponent as AlertSVG } from '../../../../uiMonitor/icons/Attention_controles.svg' import { RegulatoryLayerLegend } from '../../utils/LayerLegend.style' @@ -16,7 +16,7 @@ import { RegulatoryLayerLegend } from '../../utils/LayerLegend.style' const FOUR_HOURS = 4 * 60 * 60 * 1000 export function RegulatoryLayerZoneMetadata() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { regulatoryMetadataLayerId, regulatoryMetadataPanelIsOpen } = useAppSelector(state => state.regulatoryMetadata) const { currentData } = useGetRegulatoryLayerQuery({ id: regulatoryMetadataLayerId }, { pollingInterval: FOUR_HOURS }) const regulatoryMetadata = currentData?.properties diff --git a/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/AMPLayer.tsx b/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/AMPLayer.tsx index 860b36c14..151324ae3 100644 --- a/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/AMPLayer.tsx +++ b/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/AMPLayer.tsx @@ -3,7 +3,6 @@ import { transformExtent } from 'ol/proj' import Projection from 'ol/proj/Projection' import { createRef, useEffect } from 'react' import Highlighter from 'react-highlight-words' -import { useDispatch } from 'react-redux' import { useGetAMPsQuery } from '../../../../../api/ampsAPI' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from '../../../../../domain/entities/map/constants' @@ -13,12 +12,13 @@ import { removeAmpZonesFromMyLayers, setSelectedAmpLayerId } from '../../../../../domain/shared_slices/SelectedAmp' +import { useAppDispatch } from '../../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../../hooks/useAppSelector' import { AMPLayerLegend } from '../../../utils/LayerLegend.style' import { LayerSelector } from '../../../utils/LayerSelector.style' export function AMPLayer({ layerId, searchedText }: { layerId: number; searchedText: string }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const ref = createRef() const { layer } = useGetAMPsQuery(undefined, { diff --git a/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/index.tsx b/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/index.tsx index 9acde4b13..70714342f 100644 --- a/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/index.tsx +++ b/frontend/src/features/layersSelector/search/ResultsList/AMPLayerGroup/index.tsx @@ -2,7 +2,6 @@ import { IconButton, Icon, Accent, Size, THEME } from '@mtes-mct/monitor-ui' import _ from 'lodash' import { useState } from 'react' import Highlighter from 'react-highlight-words' -import { useDispatch } from 'react-redux' import { AMPLayer } from './AMPLayer' import { @@ -10,6 +9,7 @@ import { removeAmpZonesFromMyLayers, setSelectedAmpLayerId } from '../../../../../domain/shared_slices/SelectedAmp' +import { useAppDispatch } from '../../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../../hooks/useAppSelector' import { LayerSelector } from '../../../utils/LayerSelector.style' @@ -26,7 +26,7 @@ export function AMPLayerGroup({ layerIds: number[] searchedText: string }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { selectedAmpLayerId, selectedAmpLayerIds } = useAppSelector(state => state.selectedAmp) const totalNumberOfZones = groups[groupName]?.length diff --git a/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/RegulatoryLayer.tsx b/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/RegulatoryLayer.tsx index 2a65c4bc8..67c0d3ba5 100644 --- a/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/RegulatoryLayer.tsx +++ b/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/RegulatoryLayer.tsx @@ -3,7 +3,6 @@ import { transformExtent } from 'ol/proj' import Projection from 'ol/proj/Projection' import { createRef, useEffect } from 'react' import Highlighter from 'react-highlight-words' -import { useDispatch } from 'react-redux' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from '../../../../../domain/entities/map/constants' import { setFitToExtent } from '../../../../../domain/shared_slices/Map' @@ -13,12 +12,13 @@ import { } from '../../../../../domain/shared_slices/Regulatory' import { closeRegulatoryZoneMetadata } from '../../../../../domain/use_cases/regulatory/closeRegulatoryZoneMetadata' import { showRegulatoryZoneMetadata } from '../../../../../domain/use_cases/regulatory/showRegulatoryZoneMetadata' +import { useAppDispatch } from '../../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../../hooks/useAppSelector' import { RegulatoryLayerLegend } from '../../../utils/LayerLegend.style' import { LayerSelector } from '../../../utils/LayerSelector.style' export function RegulatoryLayer({ layerId, searchedText }: { layerId: number; searchedText: string }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { regulatoryLayersById: { [layerId]: layer }, selectedRegulatoryLayerIds diff --git a/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/index.tsx b/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/index.tsx index 580900f16..5c6a432bf 100644 --- a/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/index.tsx +++ b/frontend/src/features/layersSelector/search/ResultsList/RegulatoryLayerGroup/index.tsx @@ -2,13 +2,13 @@ import { IconButton, Icon, Accent, Size, THEME } from '@mtes-mct/monitor-ui' import _ from 'lodash' import { useState } from 'react' import Highlighter from 'react-highlight-words' -import { useDispatch } from 'react-redux' import { RegulatoryLayer } from './RegulatoryLayer' import { addRegulatoryZonesToMyLayers, removeRegulatoryZonesFromMyLayers } from '../../../../../domain/shared_slices/Regulatory' +import { useAppDispatch } from '../../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../../hooks/useAppSelector' import { LayerSelector } from '../../../utils/LayerSelector.style' @@ -21,7 +21,7 @@ export function RegulatoryLayerGroup({ layerIds: number[] searchedText: string }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { selectedRegulatoryLayerIds } = useAppSelector(state => state.regulatory) const { regulatoryMetadataLayerId } = useAppSelector(state => state.regulatoryMetadata) diff --git a/frontend/src/features/layersSelector/search/ResultsList/index.tsx b/frontend/src/features/layersSelector/search/ResultsList/index.tsx index 436ec7052..2000c8c1d 100644 --- a/frontend/src/features/layersSelector/search/ResultsList/index.tsx +++ b/frontend/src/features/layersSelector/search/ResultsList/index.tsx @@ -12,7 +12,7 @@ import { setIsAmpSearchResultsVisible, setIsRegulatorySearchResultsExpanded, setIsRegulatorySearchResultsVisible -} from '../LayerSearch.slice' +} from '../slice' export function ResultList({ searchedText }) { const { diff --git a/frontend/src/features/layersSelector/search/index.tsx b/frontend/src/features/layersSelector/search/index.tsx index c82b37aba..6ba716369 100644 --- a/frontend/src/features/layersSelector/search/index.tsx +++ b/frontend/src/features/layersSelector/search/index.tsx @@ -2,20 +2,15 @@ import { Accent, Icon, IconButton, Button, Size } from '@mtes-mct/monitor-ui' import Fuse from 'fuse.js' import _ from 'lodash' import { useState, useEffect, useMemo, useRef } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { LayerFilters } from './LayerFilters' -import { - resetSearchExtent, - setAMPsSearchResult, - setRegulatoryLayersSearchResult, - setSearchExtent -} from './LayerSearch.slice' import { ResultList } from './ResultsList' import { SearchInput } from './SearchInput' +import { resetSearchExtent, setAMPsSearchResult, setRegulatoryLayersSearchResult, setSearchExtent } from './slice' import { useGetAMPsQuery } from '../../../api/ampsAPI' import { setFitToExtent } from '../../../domain/shared_slices/Map' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { getIntersectingLayerIds } from '../utils/getIntersectingLayerIds' @@ -23,7 +18,7 @@ import type { AMP } from '../../../domain/entities/AMPs' import type { RegulatoryLayerType } from '../../../types' export function LayerSearch({ isVisible }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { data: amps } = useGetAMPsQuery() const { regulatoryLayers } = useAppSelector(state => state.regulatory) const { ampsSearchResult, regulatoryLayersSearchResult } = useAppSelector(state => state.layerSearch) diff --git a/frontend/src/features/layersSelector/search/LayerSearch.slice.ts b/frontend/src/features/layersSelector/search/slice.ts similarity index 100% rename from frontend/src/features/layersSelector/search/LayerSearch.slice.ts rename to frontend/src/features/layersSelector/search/slice.ts diff --git a/frontend/src/features/map/ShowRegulatoryMetadata.ts b/frontend/src/features/map/ShowRegulatoryMetadata.ts index 84119b99c..7cb75330c 100644 --- a/frontend/src/features/map/ShowRegulatoryMetadata.ts +++ b/frontend/src/features/map/ShowRegulatoryMetadata.ts @@ -1,13 +1,13 @@ import { useEffect } from 'react' -import { useDispatch } from 'react-redux' import { Layers } from '../../domain/entities/layers/constants' import { showRegulatoryZoneMetadata } from '../../domain/use_cases/regulatory/showRegulatoryZoneMetadata' +import { useAppDispatch } from '../../hooks/useAppDispatch' import type { BaseMapChildrenProps } from './BaseMap' export function ShowRegulatoryMetadata({ mapClickEvent }: BaseMapChildrenProps) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() useEffect(() => { if (mapClickEvent?.feature) { diff --git a/frontend/src/features/map/layers/InterestPointLayer.tsx b/frontend/src/features/map/layers/InterestPointLayer.tsx index 043c22b1c..8d1f9649f 100644 --- a/frontend/src/features/map/layers/InterestPointLayer.tsx +++ b/frontend/src/features/map/layers/InterestPointLayer.tsx @@ -5,7 +5,6 @@ import VectorLayer from 'ol/layer/Vector' import VectorSource from 'ol/source/Vector' import { getLength } from 'ol/sphere' import React, { useCallback, useEffect, useRef, useState } from 'react' -import { useDispatch } from 'react-redux' import { v4 as uuidv4 } from 'uuid' import { getInterestPointStyle, POIStyle } from './styles/interestPoint.style' @@ -28,6 +27,7 @@ import { updateInterestPointKeyBeingDrawed } from '../../../domain/shared_slices/InterestPoint' import { saveInterestPointFeature } from '../../../domain/use_cases/interestPoint/saveInterestPointFeature' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { usePrevious } from '../../../hooks/usePrevious' import InterestPointOverlay from '../overlays/InterestPointOverlay' @@ -48,7 +48,7 @@ type InterestPoint = { uuid: string } export function InterestPointLayer({ map }: BaseMapChildrenProps) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { interestPointBeingDrawed, diff --git a/frontend/src/features/map/layers/MeasurementLayer.tsx b/frontend/src/features/map/layers/MeasurementLayer.tsx index f2eb7356b..7a6b43614 100644 --- a/frontend/src/features/map/layers/MeasurementLayer.tsx +++ b/frontend/src/features/map/layers/MeasurementLayer.tsx @@ -12,7 +12,6 @@ import { METERS_PER_UNIT } from 'ol/proj/Units' import VectorSource from 'ol/source/Vector' import { getLength } from 'ol/sphere' import { useCallback, useEffect, useRef } from 'react' -import { useDispatch } from 'react-redux' import { measurementStyle, measurementStyleWithCenter } from './styles/measurement.style' import { Layers } from '../../../domain/entities/layers/constants' @@ -23,6 +22,7 @@ import { setCircleMeasurementInDrawing } from '../../../domain/shared_slices/Measurement' import { saveMeasurement } from '../../../domain/use_cases/measurement/saveMeasurement' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { getNauticalMilesFromMeters } from '../../../utils/utils' import { MeasurementOverlay } from '../overlays/MeasurementOverlay' @@ -68,7 +68,7 @@ function getNauticalMilesRadiusOfCircularPolygon(polygon, distanceUnit) { } export function MeasurementLayer({ map }: BaseMapChildrenProps) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { distanceUnit } = useAppSelector(state => state.map) diff --git a/frontend/src/features/map/layers/Missions/index.tsx b/frontend/src/features/map/layers/Missions/index.tsx index f0a67eb2f..b47caedb1 100644 --- a/frontend/src/features/map/layers/Missions/index.tsx +++ b/frontend/src/features/map/layers/Missions/index.tsx @@ -1,12 +1,12 @@ import VectorLayer from 'ol/layer/Vector' import VectorSource from 'ol/source/Vector' import { useCallback, useEffect, useMemo, useRef } from 'react' -import { useDispatch } from 'react-redux' import { getMissionZoneFeature } from './missionGeometryHelpers' import { missionWithCentroidStyleFn } from './missions.style' import { Layers } from '../../../../domain/entities/layers/constants' import { selectMissionOnMap } from '../../../../domain/use_cases/missions/selectMissionOnMap' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { useGetFilteredMissionsQuery } from '../../../../hooks/useGetFilteredMissionsQuery' @@ -14,7 +14,7 @@ import type { BaseMapChildrenProps } from '../../BaseMap' import type { Geometry } from 'ol/geom' export function MissionsLayer({ map, mapClickEvent }: BaseMapChildrenProps) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { displayMissionsLayer } = useAppSelector(state => state.global) const { missions } = useGetFilteredMissionsQuery() const listener = useAppSelector(state => state.draw.listener) diff --git a/frontend/src/features/map/layers/Reportings/index.tsx b/frontend/src/features/map/layers/Reportings/index.tsx index 8ac4b93fc..b8144edd6 100644 --- a/frontend/src/features/map/layers/Reportings/index.tsx +++ b/frontend/src/features/map/layers/Reportings/index.tsx @@ -2,12 +2,12 @@ import { reduce } from 'lodash' import VectorLayer from 'ol/layer/Vector' import VectorSource from 'ol/source/Vector' import { useCallback, useEffect, useMemo, useRef } from 'react' -import { useDispatch } from 'react-redux' import { getReportingZoneFeature } from './reportingsGeometryHelpers' import { reportingPinStyleFn } from './style' import { Layers } from '../../../../domain/entities/layers/constants' import { reportingActions } from '../../../../domain/shared_slices/reporting' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { useGetFilteredReportingsQuery } from '../../../Reportings/hooks/useGetFilteredReportingsQuery' @@ -16,7 +16,7 @@ import type { Feature } from 'ol' import type { Geometry } from 'ol/geom' export function ReportingsLayer({ map, mapClickEvent }: BaseMapChildrenProps) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { displayReportingsLayer, overlayCoordinates } = useAppSelector(state => state.global) const activeReportingId = useAppSelector(state => state.reporting.activeReportingId) const listener = useAppSelector(state => state.draw.listener) diff --git a/frontend/src/features/map/layers/Semaphores/index.ts b/frontend/src/features/map/layers/Semaphores/index.ts index f1bf05ba5..dfc5fe80a 100644 --- a/frontend/src/features/map/layers/Semaphores/index.ts +++ b/frontend/src/features/map/layers/Semaphores/index.ts @@ -2,7 +2,6 @@ import { cloneDeep, reduce } from 'lodash' import VectorLayer from 'ol/layer/Vector' import VectorSource from 'ol/source/Vector' import { useCallback, useEffect, useMemo, useRef } from 'react' -import { useDispatch } from 'react-redux' import { semaphoresStyleFn } from './semaphores.style' import { getSemaphoreZoneFeature } from './semaphoresGeometryHelpers' @@ -11,6 +10,7 @@ import { useGetSemaphoresQuery } from '../../../../api/semaphoresAPI' import { Layers } from '../../../../domain/entities/layers/constants' import { setOverlayCoordinates } from '../../../../domain/shared_slices/Global' import { setSelectedSemaphore } from '../../../../domain/shared_slices/SemaphoresSlice' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import type { BaseMapChildrenProps } from '../../BaseMap' @@ -18,7 +18,7 @@ import type { Feature } from 'ol' import type { Geometry } from 'ol/geom' export function SemaphoresLayer({ map, mapClickEvent }: BaseMapChildrenProps) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { displaySemaphoresLayer } = useAppSelector(state => state.global) const { isSemaphoreHighlighted, selectedSemaphoreId } = useAppSelector(state => state.semaphoresSlice) const { overlayCoordinates } = useAppSelector(state => state.global) diff --git a/frontend/src/features/map/overlays/InterestPointOverlay.js b/frontend/src/features/map/overlays/InterestPointOverlay.js index 9c8fc7dff..d729169cf 100644 --- a/frontend/src/features/map/overlays/InterestPointOverlay.js +++ b/frontend/src/features/map/overlays/InterestPointOverlay.js @@ -2,10 +2,10 @@ import LineString from 'ol/geom/LineString' import Overlay from 'ol/Overlay' import { getLength } from 'ol/sphere' import React, { createRef, useCallback, useEffect, useRef, useState } from 'react' -import { useSelector } from 'react-redux' import styled from 'styled-components' import { OPENLAYERS_PROJECTION } from '../../../domain/entities/map/constants' +import { useAppSelector } from '../../../hooks/useAppSelector' import { useMoveOverlayWhenDragging } from '../../../hooks/useMoveOverlayWhenDragging' import { usePrevious } from '../../../hooks/usePrevious' import { ReactComponent as DeleteSVG } from '../../../uiMonitor/icons/Delete.svg' @@ -27,7 +27,7 @@ function InterestPointOverlay({ observations, uuid }) { - const { coordinatesFormat } = useSelector(state => state.map) + const { coordinatesFormat } = useAppSelector(state => state.map) const ref = createRef() const currentOffset = useRef(initialOffsetValue) @@ -79,13 +79,13 @@ function InterestPointOverlay({ useMoveOverlayWhenDragging(overlayRef.current, map, currentOffset, moveInterestPointWithThrottle, showed) const previousCoordinates = usePrevious(coordinates) - function coordinatesAreModified(coordinates, previousCoordinates) { + function coordinatesAreModified(nextCoordinates, previousCoordinates) { return ( - !isNaN(coordinates[0]) && - !isNaN(coordinates[1]) && + !isNaN(nextCoordinates[0]) && + !isNaN(nextCoordinates[1]) && !isNaN(previousCoordinates[0]) && !isNaN(previousCoordinates[1]) && - (coordinates[0] !== previousCoordinates[0] || coordinates[1] !== previousCoordinates[1]) + (nextCoordinates[0] !== previousCoordinates[0] || nextCoordinates[1] !== previousCoordinates[1]) ) } diff --git a/frontend/src/features/map/overlays/missions/MissionCard.tsx b/frontend/src/features/map/overlays/missions/MissionCard.tsx index 34597bd5e..930eef5d9 100644 --- a/frontend/src/features/map/overlays/missions/MissionCard.tsx +++ b/frontend/src/features/map/overlays/missions/MissionCard.tsx @@ -1,16 +1,16 @@ import { Accent, Button, Icon, IconButton, Size, customDayjs as dayjs, pluralize } from '@mtes-mct/monitor-ui' import { useCallback } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { editMissionInLocalStore } from '../../../../domain/use_cases/missions/editMissionInLocalStore' import { clearSelectedMissionOnMap } from '../../../../domain/use_cases/missions/selectMissionOnMap' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { MissionSourceTag } from '../../../../ui/MissionSourceTag' import { MissionStatusLabel } from '../../../../ui/MissionStatusLabel' import { missionTypesToString } from '../../../../utils/missionTypes' export function MissionCard({ feature, selected = false }: { feature: any; selected?: boolean }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { controlUnits, endDateTimeUtc, diff --git a/frontend/src/features/map/overlays/reportings/ReportingCard.tsx b/frontend/src/features/map/overlays/reportings/ReportingCard.tsx index e5b35e43e..5412525d0 100644 --- a/frontend/src/features/map/overlays/reportings/ReportingCard.tsx +++ b/frontend/src/features/map/overlays/reportings/ReportingCard.tsx @@ -10,13 +10,13 @@ import { getLocalizedDayjs } from '@mtes-mct/monitor-ui' import { useCallback, useEffect, useMemo, useRef } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { ReportingTypeEnum, getFormattedReportingId, ReportingTypeLabels } from '../../../../domain/entities/reporting' import { ReportingContext } from '../../../../domain/shared_slices/Global' import { reportingActions } from '../../../../domain/shared_slices/reporting' import { editReportingInLocalStore } from '../../../../domain/use_cases/reporting/editReportingInLocalStore' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' export function ReportingCard({ @@ -28,7 +28,7 @@ export function ReportingCard({ selected?: boolean updateMargins: (margin: number) => void }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { global: { displayReportingsLayer } } = useAppSelector(state => state) diff --git a/frontend/src/features/map/shared/RightMenuOnHoverArea.tsx b/frontend/src/features/map/shared/RightMenuOnHoverArea.tsx index 695afb4f4..21e484e6f 100644 --- a/frontend/src/features/map/shared/RightMenuOnHoverArea.tsx +++ b/frontend/src/features/map/shared/RightMenuOnHoverArea.tsx @@ -1,13 +1,13 @@ import { useEffect, useRef } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { setReportingFormVisibility, ReportingContext, VisibilityState } from '../../../domain/shared_slices/Global' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { useClickOutsideWhenOpened } from '../../../hooks/useClickOutsideWhenOpened' export function RightMenuOnHoverArea() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { reportingFormVisibility: { context, visibility } } = useAppSelector(state => state.global) diff --git a/frontend/src/features/missions/MissionForm/MissionForm.tsx b/frontend/src/features/missions/MissionForm/MissionForm.tsx index 19b3e550b..80bec4b2a 100644 --- a/frontend/src/features/missions/MissionForm/MissionForm.tsx +++ b/frontend/src/features/missions/MissionForm/MissionForm.tsx @@ -1,7 +1,6 @@ import { FieldArray, useFormikContext } from 'formik' import _ from 'lodash' import { useEffect, useState } from 'react' -import { useDispatch } from 'react-redux' import { generatePath } from 'react-router' import styled from 'styled-components' @@ -20,12 +19,13 @@ import { setToast } from '../../../domain/shared_slices/Global' import { multiMissionsActions } from '../../../domain/shared_slices/MultiMissions' import { deleteMissionAndGoToMissionsList } from '../../../domain/use_cases/missions/deleteMission' import { saveMission } from '../../../domain/use_cases/missions/saveMission' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { sideWindowActions } from '../../SideWindow/slice' import { missionFactory } from '../Missions.helpers' export function MissionForm({ id, isAlreadyClosed, isNewMission, selectedMission, setShouldValidateOnChange }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { sideWindow } = useAppSelector(state => state) const { dirty, handleSubmit, setFieldValue, setValues, validateForm, values } = useFormikContext>() diff --git a/frontend/src/features/missions/MissionForm/index.tsx b/frontend/src/features/missions/MissionForm/index.tsx index 0783a2b97..fb5824f4a 100644 --- a/frontend/src/features/missions/MissionForm/index.tsx +++ b/frontend/src/features/missions/MissionForm/index.tsx @@ -1,13 +1,13 @@ import { skipToken } from '@reduxjs/toolkit/dist/query' import { Formik } from 'formik' import { useMemo, useState } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { MissionForm } from './MissionForm' import { MissionSchema } from './Schemas' import { useGetMissionQuery } from '../../../api/missionsAPI' import { saveMission } from '../../../domain/use_cases/missions/saveMission' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { FormikForm } from '../../../uiMonitor/CustomFormikFields/FormikForm' import { getIdTyped } from '../../../utils/getIdTyped' @@ -20,7 +20,7 @@ export function Mission() { multiMissions: { selectedMissions }, sideWindow } = useAppSelector(state => state) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const [shouldValidateOnChange, setShouldValidateOnChange] = useState(false) const routeParams = getMissionPageRoute(sideWindow.currentPath) diff --git a/frontend/src/features/missions/MissionsButton/index.tsx b/frontend/src/features/missions/MissionsButton/index.tsx index 6854036ad..5cd1b021a 100644 --- a/frontend/src/features/missions/MissionsButton/index.tsx +++ b/frontend/src/features/missions/MissionsButton/index.tsx @@ -1,6 +1,5 @@ import { Accent, Button, Icon, Size } from '@mtes-mct/monitor-ui' import { useMemo } from 'react' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { sideWindowPaths } from '../../../domain/entities/sideWindow' @@ -8,13 +7,14 @@ import { setDisplayedItems, ReportingContext, VisibilityState } from '../../../d import { addMission } from '../../../domain/use_cases/missions/addMission' import { saveMissionInLocalStore } from '../../../domain/use_cases/missions/saveMissionInLocalStore' import { reduceReportingFormOnMap } from '../../../domain/use_cases/reporting/reduceReportingFormOnMap' +import { useAppDispatch } from '../../../hooks/useAppDispatch' import { useAppSelector } from '../../../hooks/useAppSelector' import { isMissionOrMissionsPage } from '../../../utils/routes' import { MenuWithCloseButton } from '../../commonStyles/map/MenuWithCloseButton' import { sideWindowActions, SideWindowStatus } from '../../SideWindow/slice' export function MissionsMenu() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { displayMissionsLayer, isSearchMissionsVisible, reportingFormVisibility } = useAppSelector( state => state.global ) diff --git a/frontend/src/features/missions/MissionsList/CellEditMission.tsx b/frontend/src/features/missions/MissionsList/CellEditMission.tsx index 905727b9d..1018001e1 100644 --- a/frontend/src/features/missions/MissionsList/CellEditMission.tsx +++ b/frontend/src/features/missions/MissionsList/CellEditMission.tsx @@ -1,10 +1,10 @@ import { Button, Icon, Size } from '@mtes-mct/monitor-ui' -import { useDispatch } from 'react-redux' import { editMissionInLocalStore } from '../../../domain/use_cases/missions/editMissionInLocalStore' +import { useAppDispatch } from '../../../hooks/useAppDispatch' export function CellEditMission({ id }: { id: number }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const setMission = () => dispatch(editMissionInLocalStore(id)) return ( diff --git a/frontend/src/features/missions/MissionsList/CellLocalizeMission.tsx b/frontend/src/features/missions/MissionsList/CellLocalizeMission.tsx index 335170daa..e5a5cb3e5 100644 --- a/frontend/src/features/missions/MissionsList/CellLocalizeMission.tsx +++ b/frontend/src/features/missions/MissionsList/CellLocalizeMission.tsx @@ -1,13 +1,13 @@ import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui' import GeoJSON from 'ol/format/GeoJSON' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { OPENLAYERS_PROJECTION } from '../../../domain/entities/map/constants' import { setFitToExtent } from '../../../domain/shared_slices/Map' +import { useAppDispatch } from '../../../hooks/useAppDispatch' export function CellLocalizeMission({ geom }: { geom: any }) { - const dispatch = useDispatch() + const dispatch = useAppDispatch() if (!geom) { return - diff --git a/frontend/src/features/missions/MissionsList/Filters/FilterTags.tsx b/frontend/src/features/missions/MissionsList/Filters/FilterTags.tsx index ca4019061..e08ca4d29 100644 --- a/frontend/src/features/missions/MissionsList/Filters/FilterTags.tsx +++ b/frontend/src/features/missions/MissionsList/Filters/FilterTags.tsx @@ -1,13 +1,13 @@ import { SingleTag } from '@mtes-mct/monitor-ui' -import { useDispatch } from 'react-redux' import styled from 'styled-components' import { missionStatusLabels, missionTypeEnum } from '../../../../domain/entities/missions' import { MissionFiltersEnum, updateFilters } from '../../../../domain/shared_slices/MissionFilters' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' export function FilterTags() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { selectedAdministrationNames, selectedControlUnitIds, diff --git a/frontend/src/features/missions/MissionsList/Filters/index.tsx b/frontend/src/features/missions/MissionsList/Filters/index.tsx index f4d5e6c6f..40240e4b8 100644 --- a/frontend/src/features/missions/MissionsList/Filters/index.tsx +++ b/frontend/src/features/missions/MissionsList/Filters/index.tsx @@ -7,7 +7,6 @@ import { getOptionsFromIdAndName } from '@mtes-mct/monitor-ui' import { type MutableRefObject, useMemo, useRef, useState } from 'react' -import { useDispatch } from 'react-redux' import { CheckPicker } from 'rsuite' import styled from 'styled-components' @@ -19,12 +18,13 @@ import { DateRangeEnum, dateRangeLabels } from '../../../../domain/entities/date import { missionSourceEnum, missionStatusLabels, missionTypeEnum } from '../../../../domain/entities/missions' import { seaFrontLabels } from '../../../../domain/entities/seaFrontType' import { MissionFiltersEnum, resetMissionFilters, updateFilters } from '../../../../domain/shared_slices/MissionFilters' +import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' import { ReactComponent as ReloadSVG } from '../../../../uiMonitor/icons/Reload.svg' import { getThemesAsListOptions } from '../../../../utils/getThemesAsListOptions' export function MissionsTableFilters() { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { newWindowContainerRef } = useNewWindow() const { hasFilters, diff --git a/frontend/src/hooks/useAppSelector.ts b/frontend/src/hooks/useAppSelector.ts index 2f06ae7b2..b727ae407 100644 --- a/frontend/src/hooks/useAppSelector.ts +++ b/frontend/src/hooks/useAppSelector.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-restricted-imports */ import { useSelector } from 'react-redux' import type { HomeRootState } from '../store'