diff --git a/frontend/src/api/APIWorker.tsx b/frontend/src/api/APIWorker.tsx index 682792f5c1..79ae4281a2 100644 --- a/frontend/src/api/APIWorker.tsx +++ b/frontend/src/api/APIWorker.tsx @@ -29,10 +29,14 @@ export const THIRTY_SECONDS = 30 * 1000 export function APIWorker() { const dispatch = useMainAppDispatch() const isSuperUser = useIsSuperUser() - const { selectedVesselIdentity, vesselSidebarTab } = useMainAppSelector(state => state.vessel) + const selectedVesselIdentity = useMainAppSelector(state => state.vessel.selectedVesselIdentity) + const vesselSidebarTab = useMainAppSelector(state => state.vessel.vesselSidebarTab) const sideWindow = useMainAppSelector(state => state.sideWindow) - const { openedBeaconMalfunctionInKanban, vesselBeaconMalfunctionsResumeAndHistory } = useMainAppSelector( - state => state.beaconMalfunction + const openedBeaconMalfunctionInKanban = useMainAppSelector( + state => state.beaconMalfunction.openedBeaconMalfunctionInKanban + ) + const vesselBeaconMalfunctionsResumeAndHistory = useMainAppSelector( + state => state.beaconMalfunction.vesselBeaconMalfunctionsResumeAndHistory ) const sideWindowInterval = useRef() diff --git a/frontend/src/constants/constants.js b/frontend/src/constants/constants.js index 636e8901b4..6bfdf77dd9 100644 --- a/frontend/src/constants/constants.js +++ b/frontend/src/constants/constants.js @@ -1,20 +1,31 @@ export const COLORS = { - white: '#FFFFFF', - gainsboro: '#E5E5EB', - lightGray: '#CCCFD6', + // TODO Remove this color. + blue: '#0A18DF', + charcoal: '#3B4559', - slateGray: '#707785', + cultured: '#F7F7FA', - mediumSeaGreen: '#29b361', + + gainsboro: '#E5E5EB', + gunMetal: '#282F3E', + + lightGray: '#CCCFD6', + maximumRed: '#E1000F', - // TODO Remove this color. - blue: '#0A18DF', + + mediumSeaGreen: '#29b361', + + opal: '#a5bcc0', + + white: '#FFFFFF', + + powderBlue: '#9ED7D9', + + slateGray: '#707785', // TODO Remove this color (it's used as hex and not constant). titleBottomBorder: '#E0E0E0', - powderBlue: '#9ED7D9', - wheat: '#edd6a4', - opal: '#a5bcc0' + wheat: '#edd6a4' } export const HIT_PIXEL_TO_TOLERANCE = 10 diff --git a/frontend/src/domain/entities/estimatedPosition.js b/frontend/src/domain/entities/estimatedPosition.js index 1f203403ca..47d49fb879 100644 --- a/frontend/src/domain/entities/estimatedPosition.js +++ b/frontend/src/domain/entities/estimatedPosition.js @@ -1,12 +1,13 @@ -import { transform } from 'ol/proj' -import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from './map/constants' import Feature from 'ol/Feature' -import { LayerProperties } from './layers/constants' import LineString from 'ol/geom/LineString' import Point from 'ol/geom/Point' +import { transform } from 'ol/proj' + +import { LayerProperties } from './layers/constants' +import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from './map/constants' +import { Vessel } from './vessel/vessel' import { COLORS } from '../../constants/constants' import { theme } from '../../ui/theme' -import { Vessel } from './vessel/vessel' class EstimatedPosition { static colorProperty = 'color' @@ -25,25 +26,26 @@ class EstimatedPosition { * }} options * @returns [lineFeature, circleFeature] - array containing 2 features: one for the line, one for the point symbolising the last position */ - static getFeatures (vessel, options) { - const { - longitude, - latitude, - estimatedCurrentLongitude, - estimatedCurrentLatitude, - dateTime - } = vessel.vesselProperties + static getFeatures(vessel, options) { + const { dateTime, estimatedCurrentLatitude, estimatedCurrentLongitude, latitude, longitude } = + vessel.vesselProperties - if (!longitude || !latitude || !estimatedCurrentLongitude || !estimatedCurrentLatitude) return null + if (!longitude || !latitude || !estimatedCurrentLongitude || !estimatedCurrentLatitude) { + return null + } const currentCoordinates = transform([longitude, latitude], WSG84_PROJECTION, OPENLAYERS_PROJECTION) - const estimatedCoordinates = transform([estimatedCurrentLongitude, estimatedCurrentLatitude], WSG84_PROJECTION, OPENLAYERS_PROJECTION) + const estimatedCoordinates = transform( + [estimatedCurrentLongitude, estimatedCurrentLatitude], + WSG84_PROJECTION, + OPENLAYERS_PROJECTION + ) const vesselCompositeIdentifier = vessel.vesselFeatureId.replace(`${LayerProperties.VESSELS_POINTS.code}:`, '') const estimatedPositionObject = { + dateTime, latitude: estimatedCurrentLatitude, - longitude: estimatedCurrentLongitude, - dateTime: dateTime + longitude: estimatedCurrentLongitude } const features = [] @@ -60,20 +62,20 @@ class EstimatedPosition { const opacity = Vessel.getVesselOpacity(dateTime, options.vesselIsHidden, options.vesselIsOpacityReduced) const lineFeature = new Feature({ - geometry: new LineString([currentCoordinates, estimatedCoordinates]), color: lineColor, - opacity, - isHidden: options.hideNonSelectedVessels + geometry: new LineString([currentCoordinates, estimatedCoordinates]), + isHidden: options.hideNonSelectedVessels, + opacity }) lineFeature.estimatedPosition = estimatedPositionObject lineFeature.setId(`${LayerProperties.VESSEL_ESTIMATED_POSITION.code}:${vesselCompositeIdentifier}`) const circleFeature = new Feature({ + color: vesselColor, geometry: new Point(estimatedCoordinates), isCircle: true, - color: vesselColor, - opacity, - isHidden: options.hideNonSelectedVessels + isHidden: options.hideNonSelectedVessels, + opacity }) circleFeature.estimatedPosition = estimatedPositionObject circleFeature.setId(`${LayerProperties.VESSEL_ESTIMATED_POSITION.code}:circle:${vesselCompositeIdentifier}`) @@ -84,6 +86,4 @@ class EstimatedPosition { } } -export { - EstimatedPosition -} +export { EstimatedPosition } diff --git a/frontend/src/domain/entities/global.js b/frontend/src/domain/entities/global.js index b3455b6a7b..3b873e4240 100644 --- a/frontend/src/domain/entities/global.js +++ b/frontend/src/domain/entities/global.js @@ -1,5 +1,5 @@ export const LeftBoxOpened = { - REGULATIONS: 'REGULATIONS', FAVORITE_VESSELS: 'FAVORITE_VESSELS', - MISSIONS: 'MISSIONS' + MISSIONS: 'MISSIONS', + REGULATIONS: 'REGULATIONS' } diff --git a/frontend/src/domain/entities/interestPointLine.js b/frontend/src/domain/entities/interestPointLine.js index 9c045c1575..aa6374fa32 100644 --- a/frontend/src/domain/entities/interestPointLine.js +++ b/frontend/src/domain/entities/interestPointLine.js @@ -10,7 +10,7 @@ export class InterestPointLine { * @param {string[]} toCoordinates - The [longitude, latitude] of the overlay position * @param {string} featureId - The feature identifier */ - static getFeature (fromCoordinates, toCoordinates, featureId) { + static getFeature(fromCoordinates, toCoordinates, featureId) { const interestPointLineFeature = new Feature({ geometry: new LineString([fromCoordinates, toCoordinates]) }) @@ -20,7 +20,7 @@ export class InterestPointLine { return interestPointLineFeature } - static getFeatureId (uuid) { + static getFeatureId(uuid) { return `${uuid}:line` } } diff --git a/frontend/src/domain/entities/interestPoints.js b/frontend/src/domain/entities/interestPoints.js index 07408b59ba..ee83aa7237 100644 --- a/frontend/src/domain/entities/interestPoints.js +++ b/frontend/src/domain/entities/interestPoints.js @@ -1,27 +1,25 @@ export const interestPointType = { CONTROL_ENTITY: 'CONTROL_ENTITY', - FISHING_VESSEL: 'FISHING_VESSEL', FISHING_GEAR: 'FISHING_GEAR', + FISHING_VESSEL: 'FISHING_VESSEL', OTHER: 'OTHER' } export const INTEREST_POINT_STYLE = 150 -export function coordinatesOrTypeAreModified (drawingFeatureToUpdate, interestPointBeingDrawed) { +export function coordinatesOrTypeAreModified(drawingFeatureToUpdate, interestPointBeingDrawed) { return ( !isNaN(drawingFeatureToUpdate.getGeometry().getCoordinates()[0]) && !isNaN(drawingFeatureToUpdate.getGeometry().getCoordinates()[1]) && !isNaN(interestPointBeingDrawed.coordinates[0]) && - !isNaN(interestPointBeingDrawed.coordinates[1]) - ) && - ( - drawingFeatureToUpdate.getGeometry().getCoordinates()[0] !== interestPointBeingDrawed.coordinates[0] || + !isNaN(interestPointBeingDrawed.coordinates[1]) && + (drawingFeatureToUpdate.getGeometry().getCoordinates()[0] !== interestPointBeingDrawed.coordinates[0] || drawingFeatureToUpdate.getGeometry().getCoordinates()[1] !== interestPointBeingDrawed.coordinates[1] || - drawingFeatureToUpdate.getProperties().type !== interestPointBeingDrawed.type - ) + drawingFeatureToUpdate.getProperties().type !== interestPointBeingDrawed.type) + ) } -export function coordinatesAreModified (feature, previousFeature) { +export function coordinatesAreModified(feature, previousFeature) { return ( feature && previousFeature && @@ -30,10 +28,8 @@ export function coordinatesAreModified (feature, previousFeature) { !isNaN(feature.coordinates[0]) && !isNaN(feature.coordinates[1]) && !isNaN(previousFeature.coordinates[0]) && - !isNaN(previousFeature.coordinates[1]) - ) && - ( - feature.coordinates[0] !== previousFeature.coordinates[0] || - feature.coordinates[1] !== previousFeature.coordinates[1] + !isNaN(previousFeature.coordinates[1]) && + (feature.coordinates[0] !== previousFeature.coordinates[0] || + feature.coordinates[1] !== previousFeature.coordinates[1]) ) } diff --git a/frontend/src/domain/entities/mission/hooks/useGetFilteredMissionsQuery.ts b/frontend/src/domain/entities/mission/hooks/useGetFilteredMissionsQuery.ts index bd1c5750ca..dc7cbfc33f 100644 --- a/frontend/src/domain/entities/mission/hooks/useGetFilteredMissionsQuery.ts +++ b/frontend/src/domain/entities/mission/hooks/useGetFilteredMissionsQuery.ts @@ -19,7 +19,8 @@ export const useGetFilteredMissionsQuery = (): { missions: MissionWithActions[] missionsSeaFrontFiltered: MissionWithActions[] } => { - const { listFilterValues, listSeaFront } = useMainAppSelector(state => state.mission) + const listFilterValues = useMainAppSelector(state => state.mission.listFilterValues) + const listSeaFront = useMainAppSelector(state => state.mission.listSeaFront) const filteredSeaFronts = useMemo(() => SEA_FRONT_GROUP_SEA_FRONTS[listSeaFront], [listSeaFront]) diff --git a/frontend/src/domain/use_cases/beaconMalfunction/getAllBeaconMalfunctions.js b/frontend/src/domain/use_cases/beaconMalfunction/getAllBeaconMalfunctions.js index 14d5c20130..fa5786319d 100644 --- a/frontend/src/domain/use_cases/beaconMalfunction/getAllBeaconMalfunctions.js +++ b/frontend/src/domain/use_cases/beaconMalfunction/getAllBeaconMalfunctions.js @@ -1,14 +1,16 @@ -import { setError } from '../../shared_slices/Global' -import { setBeaconMalfunctions } from '../../shared_slices/BeaconMalfunction' import { getAllBeaconMalfunctionsFromAPI } from '../../../api/beaconMalfunction' +import { setBeaconMalfunctions } from '../../shared_slices/BeaconMalfunction' +import { setError } from '../../shared_slices/Global' const getAllBeaconMalfunctions = () => dispatch => { - getAllBeaconMalfunctionsFromAPI().then(beaconMalfunctions => { - dispatch(setBeaconMalfunctions(beaconMalfunctions)) - }).catch(error => { - console.error(error) - dispatch(setError(error)) - }) + getAllBeaconMalfunctionsFromAPI() + .then(beaconMalfunctions => { + dispatch(setBeaconMalfunctions(beaconMalfunctions)) + }) + .catch(error => { + console.error(error) + dispatch(setError(error)) + }) } export default getAllBeaconMalfunctions diff --git a/frontend/src/domain/use_cases/beaconMalfunction/openBeaconMalfunction.js b/frontend/src/domain/use_cases/beaconMalfunction/openBeaconMalfunction.js index 68ab986bd9..67ceee6c4a 100644 --- a/frontend/src/domain/use_cases/beaconMalfunction/openBeaconMalfunction.js +++ b/frontend/src/domain/use_cases/beaconMalfunction/openBeaconMalfunction.js @@ -1,6 +1,6 @@ -import { setError } from '../../shared_slices/Global' -import { setOpenedBeaconMalfunction } from '../../shared_slices/BeaconMalfunction' import { getBeaconMalfunctionFromAPI } from '../../../api/beaconMalfunction' +import { setOpenedBeaconMalfunction } from '../../shared_slices/BeaconMalfunction' +import { setError } from '../../shared_slices/Global' /** * Open a single beacon malfunction @@ -10,24 +10,32 @@ import { getBeaconMalfunctionFromAPI } from '../../../api/beaconMalfunction' */ const openBeaconMalfunction = (beaconMalfunction, isFromUserAction) => (dispatch, getState) => { const previousBeaconMalfunction = getState().beaconMalfunction.openedBeaconMalfunction - dispatch(setOpenedBeaconMalfunction({ - beaconMalfunction: beaconMalfunction, - showTab: isFromUserAction - })) - - getBeaconMalfunctionFromAPI(beaconMalfunction.beaconMalfunction?.id).then(beaconMalfunctionWithDetails => { - dispatch(setOpenedBeaconMalfunction({ - beaconMalfunction: beaconMalfunctionWithDetails, - showTab: isFromUserAction - })) - }).catch(error => { - console.error(error) - dispatch(setError(error)) - dispatch(setOpenedBeaconMalfunction({ - beaconMalfunction: previousBeaconMalfunction, + dispatch( + setOpenedBeaconMalfunction({ + beaconMalfunction, showTab: isFromUserAction - })) - }) + }) + ) + + getBeaconMalfunctionFromAPI(beaconMalfunction.beaconMalfunction?.id) + .then(beaconMalfunctionWithDetails => { + dispatch( + setOpenedBeaconMalfunction({ + beaconMalfunction: beaconMalfunctionWithDetails, + showTab: isFromUserAction + }) + ) + }) + .catch(error => { + console.error(error) + dispatch(setError(error)) + dispatch( + setOpenedBeaconMalfunction({ + beaconMalfunction: previousBeaconMalfunction, + showTab: isFromUserAction + }) + ) + }) } export default openBeaconMalfunction diff --git a/frontend/src/domain/use_cases/beaconMalfunction/saveBeaconMalfunctionCommentFromKanban.js b/frontend/src/domain/use_cases/beaconMalfunction/saveBeaconMalfunctionCommentFromKanban.js index 9638fb8163..4c1197d4da 100644 --- a/frontend/src/domain/use_cases/beaconMalfunction/saveBeaconMalfunctionCommentFromKanban.js +++ b/frontend/src/domain/use_cases/beaconMalfunction/saveBeaconMalfunctionCommentFromKanban.js @@ -1,10 +1,10 @@ -import { setError } from '../../shared_slices/Global' +import { saveBeaconMalfunctionCommentFromAPI } from '../../../api/beaconMalfunction' import { setOpenedBeaconMalfunction, setOpenedBeaconMalfunctionsInKanban, updateVesselBeaconMalfunctionsResumeAndHistory } from '../../shared_slices/BeaconMalfunction' -import { saveBeaconMalfunctionCommentFromAPI } from '../../../api/beaconMalfunction' +import { setError } from '../../shared_slices/Global' /** * Save a new comment to a beacon malfunction @@ -13,35 +13,40 @@ import { saveBeaconMalfunctionCommentFromAPI } from '../../../api/beaconMalfunct * @param {string} comment */ const saveBeaconMalfunctionCommentFromKanban = (beaconMalfunctionId, comment) => (dispatch, getState) => { - const userType = getState().global.userType + const { userType } = getState().global const newCommentInput = { comment, userType } - const beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction = getState().beaconMalfunction - .vesselBeaconMalfunctionsResumeAndHistory?.current?.beaconMalfunction?.id === beaconMalfunctionId - const beaconMalfunctionToUpdateIsOpened = getState().beaconMalfunction - .openedBeaconMalfunction?.beaconMalfunction?.id === beaconMalfunctionId - const beaconMalfunctionToUpdateIsOpenedInKanban = getState().beaconMalfunction - .openedBeaconMalfunctionInKanban?.beaconMalfunction?.id === beaconMalfunctionId + const beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction = + getState().beaconMalfunction.vesselBeaconMalfunctionsResumeAndHistory?.current?.beaconMalfunction?.id === + beaconMalfunctionId + const beaconMalfunctionToUpdateIsOpened = + getState().beaconMalfunction.openedBeaconMalfunction?.beaconMalfunction?.id === beaconMalfunctionId + const beaconMalfunctionToUpdateIsOpenedInKanban = + getState().beaconMalfunction.openedBeaconMalfunctionInKanban?.beaconMalfunction?.id === beaconMalfunctionId - return saveBeaconMalfunctionCommentFromAPI(beaconMalfunctionId, newCommentInput).then(beaconMalfunctionWithDetails => { - if (beaconMalfunctionToUpdateIsOpened) { - dispatch(setOpenedBeaconMalfunction({ - beaconMalfunction: beaconMalfunctionWithDetails, - showTab: false - })) - } - if (beaconMalfunctionToUpdateIsOpenedInKanban) { - dispatch(setOpenedBeaconMalfunctionsInKanban(beaconMalfunctionWithDetails)) - } - if (beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction) { - dispatch(updateVesselBeaconMalfunctionsResumeAndHistory(beaconMalfunctionWithDetails)) - } - }).catch(error => { - console.error(error) - dispatch(setError(error)) - }) + return saveBeaconMalfunctionCommentFromAPI(beaconMalfunctionId, newCommentInput) + .then(beaconMalfunctionWithDetails => { + if (beaconMalfunctionToUpdateIsOpened) { + dispatch( + setOpenedBeaconMalfunction({ + beaconMalfunction: beaconMalfunctionWithDetails, + showTab: false + }) + ) + } + if (beaconMalfunctionToUpdateIsOpenedInKanban) { + dispatch(setOpenedBeaconMalfunctionsInKanban(beaconMalfunctionWithDetails)) + } + if (beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction) { + dispatch(updateVesselBeaconMalfunctionsResumeAndHistory(beaconMalfunctionWithDetails)) + } + }) + .catch(error => { + console.error(error) + dispatch(setError(error)) + }) } export default saveBeaconMalfunctionCommentFromKanban diff --git a/frontend/src/domain/use_cases/beaconMalfunction/updateBeaconMalfunctionFromKanban.js b/frontend/src/domain/use_cases/beaconMalfunction/updateBeaconMalfunctionFromKanban.js index ae6cf67893..09b31deb8a 100644 --- a/frontend/src/domain/use_cases/beaconMalfunction/updateBeaconMalfunctionFromKanban.js +++ b/frontend/src/domain/use_cases/beaconMalfunction/updateBeaconMalfunctionFromKanban.js @@ -1,10 +1,12 @@ -import { setError } from '../../shared_slices/Global' +import { updateBeaconMalfunctionFromAPI } from '../../../api/beaconMalfunction' import { setBeaconMalfunctions, updateLocalBeaconMalfunction, - setOpenedBeaconMalfunctionsInKanban, setOpenedBeaconMalfunction, updateVesselBeaconMalfunctionsResumeAndHistory + setOpenedBeaconMalfunctionsInKanban, + setOpenedBeaconMalfunction, + updateVesselBeaconMalfunctionsResumeAndHistory } from '../../shared_slices/BeaconMalfunction' -import { updateBeaconMalfunctionFromAPI } from '../../../api/beaconMalfunction' +import { setError } from '../../shared_slices/Global' /** * Update a beacon malfunction @@ -15,30 +17,34 @@ import { updateBeaconMalfunctionFromAPI } from '../../../api/beaconMalfunction' const updateBeaconMalfunctionFromKanban = (id, nextBeaconMalfunction, updatedFields) => (dispatch, getState) => { const previousBeaconMalfunctions = getState().beaconMalfunction.beaconMalfunctions dispatch(updateLocalBeaconMalfunction(nextBeaconMalfunction)) - const beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction = getState().beaconMalfunction - .vesselBeaconMalfunctionsResumeAndHistory?.current?.beaconMalfunction?.id === id - const beaconMalfunctionToUpdateIsOpened = getState().beaconMalfunction - .openedBeaconMalfunction?.beaconMalfunction?.id === id - const beaconMalfunctionToUpdateIsOpenedInKanban = getState().beaconMalfunction - .openedBeaconMalfunctionInKanban?.beaconMalfunction?.id === id + const beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction = + getState().beaconMalfunction.vesselBeaconMalfunctionsResumeAndHistory?.current?.beaconMalfunction?.id === id + const beaconMalfunctionToUpdateIsOpened = + getState().beaconMalfunction.openedBeaconMalfunction?.beaconMalfunction?.id === id + const beaconMalfunctionToUpdateIsOpenedInKanban = + getState().beaconMalfunction.openedBeaconMalfunctionInKanban?.beaconMalfunction?.id === id - return updateBeaconMalfunctionFromAPI(id, updatedFields).then(updatedBeaconMalfunctionWithDetails => { - if (beaconMalfunctionToUpdateIsOpened) { - dispatch(setOpenedBeaconMalfunction({ - beaconMalfunction: updatedBeaconMalfunctionWithDetails, - showTab: false - })) - } - if (beaconMalfunctionToUpdateIsOpenedInKanban) { - dispatch(setOpenedBeaconMalfunctionsInKanban(updatedBeaconMalfunctionWithDetails)) - } - if (beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction) { - dispatch(updateVesselBeaconMalfunctionsResumeAndHistory(updatedBeaconMalfunctionWithDetails)) - } - }).catch(error => { - dispatch(setError(error)) - dispatch(setBeaconMalfunctions(previousBeaconMalfunctions)) - }) + return updateBeaconMalfunctionFromAPI(id, updatedFields) + .then(updatedBeaconMalfunctionWithDetails => { + if (beaconMalfunctionToUpdateIsOpened) { + dispatch( + setOpenedBeaconMalfunction({ + beaconMalfunction: updatedBeaconMalfunctionWithDetails, + showTab: false + }) + ) + } + if (beaconMalfunctionToUpdateIsOpenedInKanban) { + dispatch(setOpenedBeaconMalfunctionsInKanban(updatedBeaconMalfunctionWithDetails)) + } + if (beaconMalfunctionToUpdateIsOpenedAsCurrentVesselMalfunction) { + dispatch(updateVesselBeaconMalfunctionsResumeAndHistory(updatedBeaconMalfunctionWithDetails)) + } + }) + .catch(error => { + dispatch(setError(error)) + dispatch(setBeaconMalfunctions(previousBeaconMalfunctions)) + }) } export default updateBeaconMalfunctionFromKanban diff --git a/frontend/src/domain/use_cases/faoAreas/getFAOAreas.js b/frontend/src/domain/use_cases/faoAreas/getFAOAreas.js index a4a87083e5..a92a454210 100644 --- a/frontend/src/domain/use_cases/faoAreas/getFAOAreas.js +++ b/frontend/src/domain/use_cases/faoAreas/getFAOAreas.js @@ -1,10 +1,9 @@ -import { setError } from '../../shared_slices/Global' import { getFAOAreasFromAPI } from '../../../api/faoAreas' +import { setError } from '../../shared_slices/Global' -const getFAOAreas = () => dispatch => { - return getFAOAreasFromAPI().catch(error => { +const getFAOAreas = () => dispatch => + getFAOAreasFromAPI().catch(error => { dispatch(setError(error)) }) -} export default getFAOAreas diff --git a/frontend/src/domain/use_cases/gearCode/getAllGearCodes.js b/frontend/src/domain/use_cases/gearCode/getAllGearCodes.js index 83eeede023..0ef08800c2 100644 --- a/frontend/src/domain/use_cases/gearCode/getAllGearCodes.js +++ b/frontend/src/domain/use_cases/gearCode/getAllGearCodes.js @@ -1,11 +1,12 @@ -import { setCategoriesToGears, setGears, setGroupsToCategories, setGearsByCode } from '../../shared_slices/Gear' -import { setIsReadyToShowRegulatoryZones } from '../../../features/Regulation/slice' -import { setError } from '../../shared_slices/Global' import { batch } from 'react-redux' + import { getAllGearsFromAPI } from '../../../api/gearCode' +import { setIsReadyToShowRegulatoryZones } from '../../../features/Regulation/slice' import { REGULATED_GEARS_KEYS } from '../../entities/backoffice' +import { setCategoriesToGears, setGears, setGroupsToCategories, setGearsByCode } from '../../shared_slices/Gear' +import { setError } from '../../shared_slices/Global' -/*** +/** * * Get gear group name, see SQL init of table fishing_gear_groups: * * INSERT INTO public.fishing_gear_groups VALUES @@ -17,9 +18,12 @@ import { REGULATED_GEARS_KEYS } from '../../entities/backoffice' */ const getGroupName = groupId => { switch (groupId) { - case 1: return REGULATED_GEARS_KEYS.ALL_TOWED_GEARS - case 2: return REGULATED_GEARS_KEYS.ALL_PASSIVE_GEARS - default: return null + case 1: + return REGULATED_GEARS_KEYS.ALL_TOWED_GEARS + case 2: + return REGULATED_GEARS_KEYS.ALL_PASSIVE_GEARS + default: + return null } } @@ -28,53 +32,53 @@ const getAllGearCodes = () => (dispatch, getState) => { return } - getAllGearsFromAPI().then(gears => { - /** @type {Map} */ - const categoriesToGears = {} - /** @type {Map} */ - const groupToCategories = {} - /** @type {Map} */ - const gearsByCode = {} + getAllGearsFromAPI() + .then(gears => { + /** @type {Map} */ + const categoriesToGears = {} + /** @type {Map} */ + const groupToCategories = {} + /** @type {Map} */ + const gearsByCode = {} - gears.forEach(gear => { - const { - code, - category, - groupId - } = gear - gearsByCode[code] = gear + gears.forEach(gear => { + const { category, code, groupId } = gear + gearsByCode[code] = gear - if (!Object.keys(categoriesToGears).includes(category)) { - categoriesToGears[category] = [gear] - } else { - categoriesToGears[category].push(gear) - } + if (!Object.keys(categoriesToGears).includes(category)) { + categoriesToGears[category] = [gear] + } else { + categoriesToGears[category].push(gear) + } - const groupName = getGroupName(groupId) - if (!Object.keys(groupToCategories).includes(groupName)) { - groupToCategories[groupName] = [category] - } else { - if (!groupToCategories[groupName].includes(category)) { + const groupName = getGroupName(groupId) + if (!Object.keys(groupToCategories).includes(groupName)) { + groupToCategories[groupName] = [category] + } else if (!groupToCategories[groupName].includes(category)) { groupToCategories[groupName].push(category) } - } - }) - batch(() => { - dispatch(setGears(gears.sort((a, b) => { - if (a.code && b.code) { - return a.code.localeCompare(b.code) - } + }) + batch(() => { + dispatch( + setGears( + gears.sort((a, b) => { + if (a.code && b.code) { + return a.code.localeCompare(b.code) + } - return null - }))) - dispatch(setIsReadyToShowRegulatoryZones()) - dispatch(setCategoriesToGears(categoriesToGears)) - dispatch(setGroupsToCategories(groupToCategories)) - dispatch(setGearsByCode(gearsByCode)) + return null + }) + ) + ) + dispatch(setIsReadyToShowRegulatoryZones()) + dispatch(setCategoriesToGears(categoriesToGears)) + dispatch(setGroupsToCategories(groupToCategories)) + dispatch(setGearsByCode(gearsByCode)) + }) + }) + .catch(error => { + dispatch(setError(error)) }) - }).catch(error => { - dispatch(setError(error)) - }) } export default getAllGearCodes diff --git a/frontend/src/domain/use_cases/interestPoint/saveInterestPointFeature.js b/frontend/src/domain/use_cases/interestPoint/saveInterestPointFeature.js index 5b21bbc2dc..9137515a60 100644 --- a/frontend/src/domain/use_cases/interestPoint/saveInterestPointFeature.js +++ b/frontend/src/domain/use_cases/interestPoint/saveInterestPointFeature.js @@ -1,13 +1,12 @@ +import Feature from 'ol/Feature' import GeoJSON from 'ol/format/GeoJSON' +import Point from 'ol/geom/Point' + import { OPENLAYERS_PROJECTION } from '../../entities/map/constants' import { updateInterestPointKeyBeingDrawed } from '../../shared_slices/InterestPoint' -import Feature from 'ol/Feature' -import Point from 'ol/geom/Point' const saveInterestPointFeature = feature => (dispatch, getState) => { - const { - interestPointBeingDrawed - } = getState().interestPoint + const { interestPointBeingDrawed } = getState().interestPoint if (interestPointBeingDrawed?.feature) { return @@ -26,15 +25,18 @@ const saveInterestPointFeature = feature => (dispatch, getState) => { const geoJSONFeature = getGeoJSONFromFeature(feature) - dispatch(updateInterestPointKeyBeingDrawed({ - key: 'feature', - value: geoJSONFeature - })) + dispatch( + updateInterestPointKeyBeingDrawed({ + key: 'feature', + value: geoJSONFeature + }) + ) } } -function getGeoJSONFromFeature (feature) { +function getGeoJSONFromFeature(feature) { const parser = new GeoJSON() + return parser.writeFeatureObject(feature, { featureProjection: OPENLAYERS_PROJECTION }) } diff --git a/frontend/src/domain/use_cases/measurement/saveMeasurement.js b/frontend/src/domain/use_cases/measurement/saveMeasurement.js index daa8474d5b..5165d34798 100644 --- a/frontend/src/domain/use_cases/measurement/saveMeasurement.js +++ b/frontend/src/domain/use_cases/measurement/saveMeasurement.js @@ -1,10 +1,11 @@ import GeoJSON from 'ol/format/GeoJSON' -import { OPENLAYERS_PROJECTION } from '../../entities/map/constants' import Circle from 'ol/geom/Circle' import { fromCircle } from 'ol/geom/Polygon' -import { addMeasurementDrawed, resetCircleMeasurementInDrawing } from '../../shared_slices/Measurement' import { batch } from 'react-redux' + +import { OPENLAYERS_PROJECTION } from '../../entities/map/constants' import { setMapToolOpened } from '../../shared_slices/Global' +import { addMeasurementDrawed, resetCircleMeasurementInDrawing } from '../../shared_slices/Measurement' const saveMeasurement = (feature, measurement) => dispatch => { feature.setId(feature.ol_uid) @@ -17,18 +18,21 @@ const saveMeasurement = (feature, measurement) => dispatch => { const tooltipCoordinates = feature.getGeometry().getLastCoordinate() batch(() => { - dispatch(addMeasurementDrawed({ - feature: geoJSONFeature, - measurement: measurement, - coordinates: tooltipCoordinates - })) + dispatch( + addMeasurementDrawed({ + coordinates: tooltipCoordinates, + feature: geoJSONFeature, + measurement + }) + ) dispatch(resetCircleMeasurementInDrawing()) dispatch(setMapToolOpened(undefined)) }) } -function getGeoJSONFromFeature (feature) { +function getGeoJSONFromFeature(feature) { const parser = new GeoJSON() + return parser.writeFeatureObject(feature, { featureProjection: OPENLAYERS_PROJECTION }) } diff --git a/frontend/src/domain/use_cases/species/getAllSpecies.js b/frontend/src/domain/use_cases/species/getAllSpecies.js index 09186b2567..bbffaaa89e 100644 --- a/frontend/src/domain/use_cases/species/getAllSpecies.js +++ b/frontend/src/domain/use_cases/species/getAllSpecies.js @@ -1,33 +1,38 @@ +import { getAllSpeciesFromAPI } from '../../../api/species' import { setError } from '../../shared_slices/Global' import { setSpeciesAndSpeciesGroups } from '../../shared_slices/Species' -import { getAllSpeciesFromAPI } from '../../../api/species' const getAllSpecies = () => async (dispatch, getState) => { if (getState().species.speciesByCode?.length || getState().species.speciesGroups?.length) { return } - return getAllSpeciesFromAPI().then(speciesAndSpeciesGroups => { - const { - /** @type {Species[]} **/ - species, - /** @type {SpeciesGroup[]} **/ - groups - } = speciesAndSpeciesGroups + return getAllSpeciesFromAPI() + .then(speciesAndSpeciesGroups => { + const { + /** @type {Species[]} * */ + groups, + /** @type {SpeciesGroup[]} * */ + species + } = speciesAndSpeciesGroups + + const speciesByCode = species.reduce((map, _species) => { + map[_species.code] = _species - const speciesByCode = species.reduce((map, _species) => { - map[_species.code] = _species - return map - }, {}) + return map + }, {}) - return dispatch(setSpeciesAndSpeciesGroups({ - species, - speciesByCode, - groups - })) - }).catch(error => { - dispatch(setError(error)) - }) + return dispatch( + setSpeciesAndSpeciesGroups({ + groups, + species, + speciesByCode + }) + ) + }) + .catch(error => { + dispatch(setError(error)) + }) } export default getAllSpecies diff --git a/frontend/src/domain/use_cases/species/getUniqueSpeciesAndDistricts.js b/frontend/src/domain/use_cases/species/getUniqueSpeciesAndDistricts.js index 69d1d6c591..3309c0fe72 100644 --- a/frontend/src/domain/use_cases/species/getUniqueSpeciesAndDistricts.js +++ b/frontend/src/domain/use_cases/species/getUniqueSpeciesAndDistricts.js @@ -2,6 +2,7 @@ import { MonitorFishWorker } from '../../../workers/MonitorFishWorker' const getUniqueSpeciesAndDistricts = vessels => async () => { const monitorFishWorker = await new MonitorFishWorker() + return monitorFishWorker.getUniqueSpeciesAndDistricts(vessels) } diff --git a/frontend/src/domain/use_cases/vessel/navigateToFishingActivity.js b/frontend/src/domain/use_cases/vessel/navigateToFishingActivity.js index b3c99abd84..163af5ef75 100644 --- a/frontend/src/domain/use_cases/vessel/navigateToFishingActivity.js +++ b/frontend/src/domain/use_cases/vessel/navigateToFishingActivity.js @@ -1,20 +1,17 @@ -import { FishingActivitiesTab, VesselSidebarTab } from '../../entities/vessel/vessel' import { logbookActions } from '../../../features/Logbook/slice' +import { FishingActivitiesTab, VesselSidebarTab } from '../../entities/vessel/vessel' import { showVesselSidebarTab } from '../../shared_slices/Vessel' const navigateToFishingActivity = id => (dispatch, getState) => { - const { - vesselSidebarTab - } = getState().vessel + const { vesselSidebarTab } = getState().vessel - const { - fishingActivitiesTab - } = getState().fishingActivities + const { fishingActivitiesTab } = getState().fishingActivities if (vesselSidebarTab === VesselSidebarTab.VOYAGES && fishingActivitiesTab === FishingActivitiesTab.MESSAGES) { const element = document.getElementById(id) if (element) { scrollTo(element) + return } } @@ -35,7 +32,7 @@ const navigateToFishingActivity = id => (dispatch, getState) => { }, 100) } -function scrollTo (element) { +function scrollTo(element) { element.scrollIntoView() } diff --git a/frontend/src/domain/use_cases/vessel/showVesselFromBeaconMalfunctionsKanban.js b/frontend/src/domain/use_cases/vessel/showVesselFromBeaconMalfunctionsKanban.js index ea11d4dd57..082d3daf5c 100644 --- a/frontend/src/domain/use_cases/vessel/showVesselFromBeaconMalfunctionsKanban.js +++ b/frontend/src/domain/use_cases/vessel/showVesselFromBeaconMalfunctionsKanban.js @@ -1,8 +1,8 @@ -import { setSelectedVesselCustomTrackRequest, showVesselSidebarTab } from '../../shared_slices/Vessel' import { showVessel } from './showVessel' -import { VesselSidebarTab } from '../../entities/vessel/vessel' import { END_OF_MALFUNCTION_REASON_RECORD } from '../../entities/beaconMalfunction/constants' +import { VesselSidebarTab } from '../../entities/vessel/vessel' import { VesselTrackDepth } from '../../entities/vesselTrackDepth' +import { setSelectedVesselCustomTrackRequest, showVesselSidebarTab } from '../../shared_slices/Vessel' /** * Show the selected vessel on map. @@ -31,10 +31,10 @@ export const showVesselFromBeaconMalfunctionsKanban = (beaconMalfunction, openVM } } -function getDatesAroundMalfunctionDateTime (beaconMalfunction) { +function getDatesAroundMalfunctionDateTime(beaconMalfunction) { const afterDateTime = new Date(beaconMalfunction.malfunctionStartDateTime) const twentyFiveHours = 25 - afterDateTime.setTime(afterDateTime.getTime() - (twentyFiveHours * 60 * 60 * 1000)) + afterDateTime.setTime(afterDateTime.getTime() - twentyFiveHours * 60 * 60 * 1000) afterDateTime.setMilliseconds(0) const beforeDateTime = new Date(beaconMalfunction.malfunctionStartDateTime) diff --git a/frontend/src/domain/use_cases/vessel/updateVesselTracks.js b/frontend/src/domain/use_cases/vessel/updateVesselTracks.js index d044fd8ba6..a41412d983 100644 --- a/frontend/src/domain/use_cases/vessel/updateVesselTracks.js +++ b/frontend/src/domain/use_cases/vessel/updateVesselTracks.js @@ -1,18 +1,16 @@ -import { showVesselTrack } from './showVesselTrack' import { showVessel } from './showVessel' +import { showVesselTrack } from './showVesselTrack' export const updateVesselTracks = () => (dispatch, getState) => { - const { - selectedVesselIdentity, - vesselsTracksShowed - } = getState().vessel + const { selectedVesselIdentity, vesselsTracksShowed } = getState().vessel if (selectedVesselIdentity) { dispatch(showVessel(selectedVesselIdentity, false, false)) } - Object.keys(vesselsTracksShowed) - .forEach(vesselIdentity => updateVesselTracksWithDefaultTrackDepth(dispatch)(vesselsTracksShowed[vesselIdentity])) + Object.keys(vesselsTracksShowed).forEach(vesselIdentity => + updateVesselTracksWithDefaultTrackDepth(dispatch)(vesselsTracksShowed[vesselIdentity]) + ) } const updateVesselTracksWithDefaultTrackDepth = dispatch => vesselTrack => { @@ -20,8 +18,5 @@ const updateVesselTracksWithDefaultTrackDepth = dispatch => vesselTrack => { return } - dispatch(showVesselTrack( - vesselTrack.vesselIdentity, - false, - null)) + dispatch(showVesselTrack(vesselTrack.vesselIdentity, false, null)) } diff --git a/frontend/src/errors/NoControlsFoundError.js b/frontend/src/errors/NoControlsFoundError.js index 16464b204c..d7a16828c2 100644 --- a/frontend/src/errors/NoControlsFoundError.js +++ b/frontend/src/errors/NoControlsFoundError.js @@ -5,7 +5,7 @@ export default class NoControlsFoundError extends Error { type = ErrorType.INFO_AND_HIDDEN showEmptyComponentFields = true - constructor (message = '') { + constructor(message = '') { super(message) if (Error.captureStackTrace) { diff --git a/frontend/src/errors/NoDEPFoundError.js b/frontend/src/errors/NoDEPFoundError.js index bf1e7930b7..308b90e1ea 100644 --- a/frontend/src/errors/NoDEPFoundError.js +++ b/frontend/src/errors/NoDEPFoundError.js @@ -5,7 +5,7 @@ export default class NoDEPFoundError extends Error { type = ErrorType.INFO showEmptyComponentFields = true - constructor (message = '') { + constructor(message = '') { super(message) if (Error.captureStackTrace) { diff --git a/frontend/src/errors/NoLogbookMessagesFoundError.js b/frontend/src/errors/NoLogbookMessagesFoundError.js index e2c15165fe..e7bc1897a6 100644 --- a/frontend/src/errors/NoLogbookMessagesFoundError.js +++ b/frontend/src/errors/NoLogbookMessagesFoundError.js @@ -5,7 +5,7 @@ export default class NoLogbookMessagesFoundError extends Error { type = ErrorType.INFO_AND_HIDDEN showEmptyComponentFields = true - constructor (message = '') { + constructor(message = '') { super(message) if (Error.captureStackTrace) { diff --git a/frontend/src/errors/NoPositionsFoundError.js b/frontend/src/errors/NoPositionsFoundError.js index eee74cd836..59a7176afc 100644 --- a/frontend/src/errors/NoPositionsFoundError.js +++ b/frontend/src/errors/NoPositionsFoundError.js @@ -5,7 +5,7 @@ export default class NoPositionsFoundError extends Error { type = ErrorType.INFO showEmptyComponentFields = true - constructor (message = '') { + constructor(message = '') { super(message) if (Error.captureStackTrace) { diff --git a/frontend/src/errors/NoVesselsInFilterError.js b/frontend/src/errors/NoVesselsInFilterError.js index 5851f2a357..ba1c3ed029 100644 --- a/frontend/src/errors/NoVesselsInFilterError.js +++ b/frontend/src/errors/NoVesselsInFilterError.js @@ -5,7 +5,7 @@ export default class NoVesselsInFilterError extends Error { type = ErrorType.INFO showEmptyComponentFields = true - constructor (message = '') { + constructor(message = '') { super(message) if (Error.captureStackTrace) { diff --git a/frontend/src/features/AdministrativeZone/useCases/getAdministrativeZoneGeometry.js b/frontend/src/features/AdministrativeZone/useCases/getAdministrativeZoneGeometry.js index 03c7153404..0cddd4e254 100644 --- a/frontend/src/features/AdministrativeZone/useCases/getAdministrativeZoneGeometry.js +++ b/frontend/src/features/AdministrativeZone/useCases/getAdministrativeZoneGeometry.js @@ -1,6 +1,6 @@ -import { addZoneSelected } from '../../VesselList/slice' -import layer from '../../../domain/shared_slices/Layer' import { getAdministrativeZoneFromAPI } from '../../../api/geoserver' +import layer from '../../../domain/shared_slices/Layer' +import { addZoneSelected } from '../../VesselList/slice' const getAdministrativeZoneGeometry = (administrativeZoneCode, subZoneCode, zoneName, namespace) => (dispatch, getState) => { @@ -33,9 +33,9 @@ const getAdministrativeZoneGeometry = function dispatchZoneSelected(feature) { dispatch( addZoneSelected({ - name: zoneName, code: subZoneCode || administrativeZoneCode, - feature: feature + feature, + name: zoneName }) ) } diff --git a/frontend/src/features/AdministrativeZone/useCases/getZonesAndSubZonesPromises.js b/frontend/src/features/AdministrativeZone/useCases/getZonesAndSubZonesPromises.js index b89dd170af..94df1e0f1c 100644 --- a/frontend/src/features/AdministrativeZone/useCases/getZonesAndSubZonesPromises.js +++ b/frontend/src/features/AdministrativeZone/useCases/getZonesAndSubZonesPromises.js @@ -1,28 +1,32 @@ -import { LayerProperties, LayerType } from '../../../domain/entities/layers/constants' import { getAdministrativeSubZonesFromAPI } from '../../../api/geoserver' +import { LayerProperties, LayerType } from '../../../domain/entities/layers/constants' -export const getZonesAndSubZonesPromises = () => (dispatch, getState) => { - return Object.keys(LayerProperties) +export const getZonesAndSubZonesPromises = () => (dispatch, getState) => + Object.keys(LayerProperties) .map(layer => LayerProperties[layer]) .filter(layer => layer.type === LayerType.ADMINISTRATIVE) .filter(layer => layer.isIntersectable) .map(zone => { if (zone.hasSearchableZones) { - return getAdministrativeSubZonesFromAPI(zone.code, getState().global.isBackoffice).then(subZonesFeatures => { - return subZonesFeatures.features.map(subZone => { - return { + return getAdministrativeSubZonesFromAPI(zone.code, getState().global.isBackoffice) + .then(subZonesFeatures => + subZonesFeatures.features.map(subZone => ({ + code: subZone.id, group: zone.name, groupCode: zone.code, - label: subZone.properties[zone.zoneNamePropertyKey] ? subZone.properties[zone.zoneNamePropertyKey].toString() : 'Aucun nom', - name: subZone.properties[zone.zoneNamePropertyKey] ? subZone.properties[zone.zoneNamePropertyKey] : 'Aucun nom', - code: subZone.id, - value: subZone.id, - isSubZone: true - } + isSubZone: true, + label: subZone.properties[zone.zoneNamePropertyKey] + ? subZone.properties[zone.zoneNamePropertyKey].toString() + : 'Aucun nom', + name: subZone.properties[zone.zoneNamePropertyKey] + ? subZone.properties[zone.zoneNamePropertyKey] + : 'Aucun nom', + value: subZone.id + })) + ) + .catch(error => { + console.warn(error) }) - }).catch(error => { - console.warn(error) - }) } const nextZone = { ...zone } @@ -33,4 +37,3 @@ export const getZonesAndSubZonesPromises = () => (dispatch, getState) => { return nextZone }) -} diff --git a/frontend/src/features/Backoffice/index.tsx b/frontend/src/features/Backoffice/index.tsx index a7a324ff52..63c0147b11 100644 --- a/frontend/src/features/Backoffice/index.tsx +++ b/frontend/src/features/Backoffice/index.tsx @@ -34,12 +34,13 @@ export function Backoffice() { setMapMovingAndZoomEvent({ dummyUpdate: true }) } - const { layersTopicsByRegTerritory, regulatoryZoneMetadataPanelIsOpen } = useMainAppSelector( - state => state.regulatory + const layersTopicsByRegTerritory = useMainAppSelector(state => state.regulatory.layersTopicsByRegTerritory) + const regulatoryZoneMetadataPanelIsOpen = useMainAppSelector( + state => state.regulatory.regulatoryZoneMetadataPanelIsOpen ) // TODO Scritly type this once the store is perfectly typed. - const { regulationSaved } = useMainAppSelector(state => (state as any).regulation) + const regulationSaved = useMainAppSelector(state => (state as any).regulation.regulationSaved) const initBackoffice = useCallback(() => { batch(async () => { diff --git a/frontend/src/features/Healthcheck/components/HealthcheckHeadband.tsx b/frontend/src/features/Healthcheck/components/HealthcheckHeadband.tsx index 2f815690a5..b52ee4676e 100644 --- a/frontend/src/features/Healthcheck/components/HealthcheckHeadband.tsx +++ b/frontend/src/features/Healthcheck/components/HealthcheckHeadband.tsx @@ -13,7 +13,8 @@ import { getHealthcheckWarnings } from '../utils' export function HealthcheckHeadband() { const dispatch = useMainAppDispatch() - const { healthcheckTextWarning, previewFilteredVesselsMode } = useMainAppSelector(state => state.global) + const healthcheckTextWarning = useMainAppSelector(state => state.global.healthcheckTextWarning) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) const isOnline = useIsOnline() const { data: healthcheck, diff --git a/frontend/src/features/LayersSidebar/components/index.tsx b/frontend/src/features/LayersSidebar/components/index.tsx index a1b74dad62..6175b9eca9 100644 --- a/frontend/src/features/LayersSidebar/components/index.tsx +++ b/frontend/src/features/LayersSidebar/components/index.tsx @@ -20,10 +20,12 @@ import { closeRegulatoryZoneMetadata } from '../../Regulation/useCases/closeRegu export function LayersSidebar() { const dispatch = useMainAppDispatch() - const { regulatoryZoneMetadataPanelIsOpen } = useMainAppSelector(state => state.regulatory) - const { healthcheckTextWarning, leftBoxOpened, previewFilteredVesselsMode } = useMainAppSelector( - state => state.global + const regulatoryZoneMetadataPanelIsOpen = useMainAppSelector( + state => state.regulatory.regulatoryZoneMetadataPanelIsOpen ) + const healthcheckTextWarning = useMainAppSelector(state => state.global.healthcheckTextWarning) + const leftBoxOpened = useMainAppSelector(state => state.global.leftBoxOpened) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) const [numberOfRegulatoryLayersSaved, setNumberOfRegulatoryLayersSaved] = useState(0) diff --git a/frontend/src/features/LayersSidebar/useCases/zoomInLayer.js b/frontend/src/features/LayersSidebar/useCases/zoomInLayer.js index ca4e1d8525..300785e533 100644 --- a/frontend/src/features/LayersSidebar/useCases/zoomInLayer.js +++ b/frontend/src/features/LayersSidebar/useCases/zoomInLayer.js @@ -1,6 +1,7 @@ -import { animateToRegulatoryLayer } from '../../../domain/shared_slices/Map' -import { LayerProperties } from '../../../domain/entities/layers/constants' import { getCenter } from 'ol/extent' + +import { LayerProperties } from '../../../domain/entities/layers/constants' +import { animateToRegulatoryLayer } from '../../../domain/shared_slices/Map' import { isNumeric } from '../../../utils/isNumeric' /** @@ -12,25 +13,29 @@ import { isNumeric } from '../../../utils/isNumeric' * * @returns {any} */ -const zoomInLayer = ({ topicAndZone, feature }) => (dispatch, getState) => { - if (topicAndZone) { - const name = `${LayerProperties.REGULATORY.code}:${topicAndZone.topic}:${topicAndZone.zone}` - const layerToZoomIn = getState().layer.layersToFeatures.find(layer => layer.name === name) - if (layerToZoomIn) { - dispatchAnimateToRegulatoryLayer(layerToZoomIn.center, dispatch, name) +const zoomInLayer = + ({ feature, topicAndZone }) => + (dispatch, getState) => { + if (topicAndZone) { + const name = `${LayerProperties.REGULATORY.code}:${topicAndZone.topic}:${topicAndZone.zone}` + const layerToZoomIn = getState().layer.layersToFeatures.find(layer => layer.name === name) + if (layerToZoomIn) { + dispatchAnimateToRegulatoryLayer(layerToZoomIn.center, dispatch, name) + } + } else if (feature) { + const center = getCenter(feature.getGeometry().getExtent()) + dispatchAnimateToRegulatoryLayer(center, dispatch, LayerProperties.REGULATORY_PREVIEW) } - } else if (feature) { - const center = getCenter(feature.getGeometry().getExtent()) - dispatchAnimateToRegulatoryLayer(center, dispatch, LayerProperties.REGULATORY_PREVIEW) } -} const dispatchAnimateToRegulatoryLayer = (center, dispatch, name) => { if (center?.length && isNumeric(center[0]) && isNumeric(center[1])) { - dispatch(animateToRegulatoryLayer({ - name: name, - center: center - })) + dispatch( + animateToRegulatoryLayer({ + center, + name + }) + ) } } diff --git a/frontend/src/features/Logbook/components/VesselLogbook/FishingActivitiesSummary.tsx b/frontend/src/features/Logbook/components/VesselLogbook/FishingActivitiesSummary.tsx index f4e8d7f3b4..da91c4141c 100644 --- a/frontend/src/features/Logbook/components/VesselLogbook/FishingActivitiesSummary.tsx +++ b/frontend/src/features/Logbook/components/VesselLogbook/FishingActivitiesSummary.tsx @@ -36,10 +36,11 @@ type FishingActivitiesSummaryProps = { } export function FishingActivitiesSummary({ navigation, showLogbookMessages }: FishingActivitiesSummaryProps) { const dispatch = useMainAppDispatch() - const { selectedVessel } = useMainAppSelector(state => state.vessel) - const { fishingActivities, isFirstVoyage, isLastVoyage, tripNumber } = useMainAppSelector( - state => state.fishingActivities - ) + const selectedVessel = useMainAppSelector(state => state.vessel.selectedVessel) + const fishingActivities = useMainAppSelector(state => state.fishingActivities.fishingActivities) + const isFirstVoyage = useMainAppSelector(state => state.fishingActivities.isFirstVoyage) + const isLastVoyage = useMainAppSelector(state => state.fishingActivities.isLastVoyage) + const tripNumber = useMainAppSelector(state => state.fishingActivities.tripNumber) const fleetSegments = useMainAppSelector(state => state.fleetSegment.fleetSegments) const { data: lastLogbookTrips } = useGetLastLogbookTripsQuery(selectedVessel?.internalReferenceNumber || skipToken) diff --git a/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/LogbookMessage.tsx b/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/LogbookMessage.tsx index 2897b24b86..63ee6edf42 100644 --- a/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/LogbookMessage.tsx +++ b/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/LogbookMessage.tsx @@ -33,7 +33,7 @@ type LogbookMessageComponentType = { } export function LogbookMessage({ isFirst, message }: LogbookMessageComponentType) { const dispatch = useMainAppDispatch() - const { fishingActivitiesShowedOnMap } = useMainAppSelector(state => state.fishingActivities) + const fishingActivitiesShowedOnMap = useMainAppSelector(state => state.fishingActivities.fishingActivitiesShowedOnMap) const logbookHeaderTitle = useMemo(() => { switch (message.messageType) { diff --git a/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/index.tsx b/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/index.tsx index 517b132316..48412609d3 100644 --- a/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/index.tsx +++ b/frontend/src/features/Logbook/components/VesselLogbook/LogbookMessages/index.tsx @@ -79,9 +79,10 @@ type LogbookMessagesProps = { showFishingActivitiesSummary: () => void } export function LogbookMessages({ messageTypeFilter, navigation, showFishingActivitiesSummary }: LogbookMessagesProps) { - const { fishingActivities, isFirstVoyage, isLastVoyage, tripNumber } = useMainAppSelector( - state => state.fishingActivities - ) + const fishingActivities = useMainAppSelector(state => state.fishingActivities.fishingActivities) + const isFirstVoyage = useMainAppSelector(state => state.fishingActivities.isFirstVoyage) + const isLastVoyage = useMainAppSelector(state => state.fishingActivities.isLastVoyage) + const tripNumber = useMainAppSelector(state => state.fishingActivities.tripNumber) /** @type {LogbookMessage[]} logbookMessages */ const [logbookMessages, setLogbookMessages] = useState([]) diff --git a/frontend/src/features/MainWindow.tsx b/frontend/src/features/MainWindow.tsx index bfad78e012..7fcdf63392 100644 --- a/frontend/src/features/MainWindow.tsx +++ b/frontend/src/features/MainWindow.tsx @@ -23,13 +23,15 @@ import { SideWindowStatus } from '../domain/entities/sideWindow/constants' import { useMainAppSelector } from '../hooks/useMainAppSelector' export function MainWindow() { - const { - isControlUnitDialogDisplayed, - isControlUnitListDialogDisplayed, - isDrawLayerModalDisplayed, - isVesselListDisplayed, - isVesselSearchDisplayed - } = useMainAppSelector(state => state.displayedComponent) + const isControlUnitDialogDisplayed = useMainAppSelector( + state => state.displayedComponent.isControlUnitDialogDisplayed + ) + const isControlUnitListDialogDisplayed = useMainAppSelector( + state => state.displayedComponent.isControlUnitListDialogDisplayed + ) + const isDrawLayerModalDisplayed = useMainAppSelector(state => state.displayedComponent.isDrawLayerModalDisplayed) + const isVesselListDisplayed = useMainAppSelector(state => state.displayedComponent.isVesselListDisplayed) + const isVesselSearchDisplayed = useMainAppSelector(state => state.displayedComponent.isVesselSearchDisplayed) const isVesselSidebarOpen = useMainAppSelector(state => state.vessel.vesselSidebarIsOpen) const isDraftDirty = useMainAppSelector(state => state.mission.isDraftDirty) const status = useMainAppSelector(state => state.sideWindow.status) diff --git a/frontend/src/features/MapButtons/AlertsMapButton.tsx b/frontend/src/features/MapButtons/AlertsMapButton.tsx index 7fbf358bc2..47886b60a2 100644 --- a/frontend/src/features/MapButtons/AlertsMapButton.tsx +++ b/frontend/src/features/MapButtons/AlertsMapButton.tsx @@ -11,7 +11,7 @@ import AlertsSVG from '../icons/Icone_alertes.svg?react' export function AlertsMapButton() { const dispatch = useMainAppDispatch() - const { previewFilteredVesselsMode } = useMainAppSelector(state => state.global) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) const sideWindow = useMainAppSelector(state => state.sideWindow) const isActive = diff --git a/frontend/src/features/MapButtons/BeaconMalfunctionsMapButton.tsx b/frontend/src/features/MapButtons/BeaconMalfunctionsMapButton.tsx index e497dd102d..d6b4bdb9eb 100644 --- a/frontend/src/features/MapButtons/BeaconMalfunctionsMapButton.tsx +++ b/frontend/src/features/MapButtons/BeaconMalfunctionsMapButton.tsx @@ -11,7 +11,7 @@ import BeaconMalfunctionsSVG from '../icons/Icone_VMS.svg?react' export function BeaconMalfunctionsMapButton() { const dispatch = useMainAppDispatch() - const { previewFilteredVesselsMode } = useMainAppSelector(state => state.global) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) const sideWindow = useMainAppSelector(state => state.sideWindow) const isActive = diff --git a/frontend/src/features/MapButtons/InterestPoints/EditInterestPoint.tsx b/frontend/src/features/MapButtons/InterestPoints/EditInterestPoint.tsx index 0459788883..d136055507 100644 --- a/frontend/src/features/MapButtons/InterestPoints/EditInterestPoint.tsx +++ b/frontend/src/features/MapButtons/InterestPoints/EditInterestPoint.tsx @@ -28,7 +28,8 @@ type EditInterestPointProps = { export function EditInterestPoint({ close, isOpen }: EditInterestPointProps) { const dispatch = useMainAppDispatch() - const { interestPointBeingDrawed, isEditing } = useMainAppSelector(state => state.interestPoint) + const interestPointBeingDrawed = useMainAppSelector(state => state.interestPoint.interestPointBeingDrawed) + const isEditing = useMainAppSelector(state => state.interestPoint.isEditing) /** Coordinates formatted in DD [latitude, longitude] */ const coordinates: number[] = useMemo(() => { diff --git a/frontend/src/features/MapButtons/Measurements/index.tsx b/frontend/src/features/MapButtons/Measurements/index.tsx index 488f188532..aa34997d42 100644 --- a/frontend/src/features/MapButtons/Measurements/index.tsx +++ b/frontend/src/features/MapButtons/Measurements/index.tsx @@ -18,7 +18,8 @@ import { MapToolButton } from '../shared/MapToolButton' export function MeasurementMapButton() { const dispatch = useMainAppDispatch() const measurementTypeToAdd = useMainAppSelector(state => state.measurement.measurementTypeToAdd) - const { mapToolOpened, rightMenuIsOpen } = useMainAppSelector(state => state.global) + const mapToolOpened = useMainAppSelector(state => state.global.mapToolOpened) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) const isRightMenuShrinked = !rightMenuIsOpen const isOpen = useMemo(() => mapToolOpened === MapToolType.MEASUREMENT_MENU, [mapToolOpened]) diff --git a/frontend/src/features/MapButtons/Missions/index.tsx b/frontend/src/features/MapButtons/Missions/index.tsx index 720aace4cb..993201ab5e 100644 --- a/frontend/src/features/MapButtons/Missions/index.tsx +++ b/frontend/src/features/MapButtons/Missions/index.tsx @@ -17,8 +17,8 @@ import { MapToolButton } from '../shared/MapToolButton' export function MissionsMenu() { const dispatch = useMainAppDispatch() const sideWindow = useMainAppSelector(state => state.sideWindow) - const { leftBoxOpened } = useMainAppSelector(state => state.global) - const { isMissionsLayerDisplayed } = useMainAppSelector(state => state.displayedComponent) + const leftBoxOpened = useMainAppSelector(state => state.global.leftBoxOpened) + const isMissionsLayerDisplayed = useMainAppSelector(state => state.displayedComponent.isMissionsLayerDisplayed) const isActive = sideWindow.status !== SideWindowStatus.CLOSED && sideWindow.selectedPath.menu === SideWindowMenuKey.MISSION_LIST diff --git a/frontend/src/features/MapButtons/VesselVisibility/EditVesselVisibility.tsx b/frontend/src/features/MapButtons/VesselVisibility/EditVesselVisibility.tsx index 217ed254e9..7dde26bcab 100644 --- a/frontend/src/features/MapButtons/VesselVisibility/EditVesselVisibility.tsx +++ b/frontend/src/features/MapButtons/VesselVisibility/EditVesselVisibility.tsx @@ -22,11 +22,11 @@ import { MapToolBox } from '../shared/MapToolBox' export function EditVesselVisibility() { const dispatch = useMainAppDispatch() - const { hideNonSelectedVessels } = useMainAppSelector(state => state.vessel) - const { mapToolOpened } = useMainAppSelector(state => state.global) - const { hideVesselsAtPort, showingVesselsEstimatedPositions, vesselsLastPositionVisibility } = useMainAppSelector( - state => state.map - ) + const hideNonSelectedVessels = useMainAppSelector(state => state.vessel.hideNonSelectedVessels) + const mapToolOpened = useMainAppSelector(state => state.global.mapToolOpened) + const hideVesselsAtPort = useMainAppSelector(state => state.map.hideVesselsAtPort) + const showingVesselsEstimatedPositions = useMainAppSelector(state => state.map.showingVesselsEstimatedPositions) + const vesselsLastPositionVisibility = useMainAppSelector(state => state.map.vesselsLastPositionVisibility) const isOpen = useMemo(() => mapToolOpened === MapToolType.VESSEL_VISIBILITY, [mapToolOpened]) diff --git a/frontend/src/features/MapButtons/index.tsx b/frontend/src/features/MapButtons/index.tsx index 3526f35de1..3be8af0723 100644 --- a/frontend/src/features/MapButtons/index.tsx +++ b/frontend/src/features/MapButtons/index.tsx @@ -13,16 +13,28 @@ import { ControlUnitListDialogButton } from '../ControlUnit/components/ControlUn export function MapButtons() { const isSuperUser = useIsSuperUser() - const { - isAlertsMapButtonDisplayed, - isBeaconMalfunctionsMapButtonDisplayed, - isFavoriteVesselsMapButtonDisplayed, - isInterestPointMapButtonDisplayed, - isMeasurementMapButtonDisplayed, - isVesselFiltersMapButtonDisplayed, - isVesselLabelsMapButtonDisplayed, - isVesselVisibilityMapButtonDisplayed - } = useMainAppSelector(state => state.displayedComponent) + const isAlertsMapButtonDisplayed = useMainAppSelector(state => state.displayedComponent.isAlertsMapButtonDisplayed) + const isBeaconMalfunctionsMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isBeaconMalfunctionsMapButtonDisplayed + ) + const isFavoriteVesselsMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isFavoriteVesselsMapButtonDisplayed + ) + const isInterestPointMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isInterestPointMapButtonDisplayed + ) + const isMeasurementMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isMeasurementMapButtonDisplayed + ) + const isVesselFiltersMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isVesselFiltersMapButtonDisplayed + ) + const isVesselLabelsMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isVesselLabelsMapButtonDisplayed + ) + const isVesselVisibilityMapButtonDisplayed = useMainAppSelector( + state => state.displayedComponent.isVesselVisibilityMapButtonDisplayed + ) return ( <> diff --git a/frontend/src/features/MapButtons/shared/MapToolButton.tsx b/frontend/src/features/MapButtons/shared/MapToolButton.tsx index a76cafe640..5ee9cb1b36 100644 --- a/frontend/src/features/MapButtons/shared/MapToolButton.tsx +++ b/frontend/src/features/MapButtons/shared/MapToolButton.tsx @@ -11,7 +11,8 @@ type MapToolButtonProps = { isLeftButton?: boolean } & HTMLProps export function MapToolButton({ children, isActive, isLeftButton = false, ...props }: MapToolButtonProps) { - const { previewFilteredVesselsMode, rightMenuIsOpen } = useMainAppSelector(state => state.global) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) const isRightMenuShrinked = !rightMenuIsOpen && !isLeftButton return ( diff --git a/frontend/src/features/Regulation/components/RegulationSearch/index.tsx b/frontend/src/features/Regulation/components/RegulationSearch/index.tsx index 8de9e338a4..920c278fce 100644 --- a/frontend/src/features/Regulation/components/RegulationSearch/index.tsx +++ b/frontend/src/features/Regulation/components/RegulationSearch/index.tsx @@ -30,10 +30,11 @@ export function RegulationSearch({ }: RegulatoryLayerSearchProps) { const dispatch = useMainAppDispatch() const { setLayersSideBarOpenedLayerType } = layer[namespace].actions - const { layersSidebarOpenedLayerType } = useMainAppSelector(state => state.layer) - const { regulatoryLayersSearchResult, regulatoryZonesChecked } = useMainAppSelector( - state => state.regulatoryLayerSearch + const layersSidebarOpenedLayerType = useMainAppSelector(state => state.layer.layersSidebarOpenedLayerType) + const regulatoryLayersSearchResult = useMainAppSelector( + state => state.regulatoryLayerSearch.regulatoryLayersSearchResult ) + const regulatoryZonesChecked = useMainAppSelector(state => state.regulatoryLayerSearch.regulatoryZonesChecked) const escape = useEscapeFromKeyboard() const wrapperRef = useRef(null) diff --git a/frontend/src/features/Regulation/useCases/getAllRegulatoryLayers.js b/frontend/src/features/Regulation/useCases/getAllRegulatoryLayers.js index 2411d5387b..d2a0a677ff 100644 --- a/frontend/src/features/Regulation/useCases/getAllRegulatoryLayers.js +++ b/frontend/src/features/Regulation/useCases/getAllRegulatoryLayers.js @@ -1,14 +1,15 @@ import { batch } from 'react-redux' + +import { getAllRegulatoryLayersFromAPI } from '../../../api/geoserver' import { setError } from '../../../domain/shared_slices/Global' +import layer from '../../../domain/shared_slices/Layer' +import { MonitorFishWorker } from '../../../workers/MonitorFishWorker' import { setLayersTopicsByRegTerritory, setRegulatoryLayerLawTypes, setRegulatoryZones, setSelectedRegulatoryZone } from '../slice' -import layer from '../../../domain/shared_slices/Layer' -import { getAllRegulatoryLayersFromAPI } from '../../../api/geoserver' -import { MonitorFishWorker } from '../../../workers/MonitorFishWorker' const getAllRegulatoryLayers = () => async (dispatch, getState) => { const monitorFishWorker = await new MonitorFishWorker() @@ -24,15 +25,14 @@ const getAllRegulatoryLayers = () => async (dispatch, getState) => { return monitorFishWorker.convertGeoJSONFeaturesToStructuredRegulatoryObject(features, speciesByCode) }) .then(response => { - const { - layersWithoutGeometry, - layersTopicsByRegulatoryTerritory - } = response + const { layersTopicsByRegulatoryTerritory, layersWithoutGeometry } = response batch(() => { dispatch(setLayersTopicsByRegTerritory(layersTopicsByRegulatoryTerritory)) dispatch(setRegulatoryLayerLawTypes(layersTopicsByRegulatoryTerritory)) dispatch(setSelectedRegulatoryZone(layersWithoutGeometry)) - dispatch(setShowedLayersWithLocalStorageValues({ regulatoryZones: layersWithoutGeometry, namespace: 'homepage' })) + dispatch( + setShowedLayersWithLocalStorageValues({ namespace: 'homepage', regulatoryZones: layersWithoutGeometry }) + ) }) }) .catch(error => { diff --git a/frontend/src/features/Regulation/useCases/getAllRegulatoryLayersByRegTerritory.js b/frontend/src/features/Regulation/useCases/getAllRegulatoryLayersByRegTerritory.js index c76c4a7860..b7ede97631 100644 --- a/frontend/src/features/Regulation/useCases/getAllRegulatoryLayersByRegTerritory.js +++ b/frontend/src/features/Regulation/useCases/getAllRegulatoryLayersByRegTerritory.js @@ -1,24 +1,18 @@ import { batch } from 'react-redux' -import { setError } from '../../../domain/shared_slices/Global' -import { - setLayersTopicsByRegTerritory, - setRegulatoryLayerLawTypes -} from '../slice' + import { getAllRegulatoryLayersFromAPI } from '../../../api/geoserver' +import { setError } from '../../../domain/shared_slices/Global' import { MonitorFishWorker } from '../../../workers/MonitorFishWorker' +import { setLayersTopicsByRegTerritory, setRegulatoryLayerLawTypes } from '../slice' const getAllRegulatoryLayersByRegTerritory = () => async (dispatch, getState) => { const monitorFishWorker = await new MonitorFishWorker() const { speciesByCode } = getState().species return getAllRegulatoryLayersFromAPI(getState().global.isBackoffice) - .then(features => { - return monitorFishWorker.convertGeoJSONFeaturesToStructuredRegulatoryObject(features, speciesByCode) - }) + .then(features => monitorFishWorker.convertGeoJSONFeaturesToStructuredRegulatoryObject(features, speciesByCode)) .then(response => { - const { - layersTopicsByRegulatoryTerritory - } = response + const { layersTopicsByRegulatoryTerritory } = response batch(() => { dispatch(setLayersTopicsByRegTerritory(layersTopicsByRegulatoryTerritory)) diff --git a/frontend/src/features/Regulation/useCases/getGeometryWithoutRegulationReference.js b/frontend/src/features/Regulation/useCases/getGeometryWithoutRegulationReference.js index 93521b1b3f..64c1f2a9a1 100644 --- a/frontend/src/features/Regulation/useCases/getGeometryWithoutRegulationReference.js +++ b/frontend/src/features/Regulation/useCases/getGeometryWithoutRegulationReference.js @@ -1,14 +1,13 @@ -import { setError } from '../../../domain/shared_slices/Global' import { getAllGeometryWithoutProperty } from '../../../api/geoserver' +import { setError } from '../../../domain/shared_slices/Global' import { MonitorFishWorker } from '../../../workers/MonitorFishWorker' const getGeometryWithoutRegulationReference = () => async (dispatch, getState) => { const monitorFishWorker = await new MonitorFishWorker() return getAllGeometryWithoutProperty(getState().global.isBackoffice) - .then(features => { - return monitorFishWorker.getIdToGeometryObject(features) - }).catch(error => { + .then(features => monitorFishWorker.getIdToGeometryObject(features)) + .catch(error => { dispatch(setError(error)) }) } diff --git a/frontend/src/features/Regulation/useCases/resetRegulation.js b/frontend/src/features/Regulation/useCases/resetRegulation.js index f820a342ef..2912225cb4 100644 --- a/frontend/src/features/Regulation/useCases/resetRegulation.js +++ b/frontend/src/features/Regulation/useCases/resetRegulation.js @@ -1,12 +1,9 @@ import Feature from 'ol/Feature' -import { - REGULATION_ACTION_TYPE, - getRegulatoryFeatureId, - emptyRegulatoryFeatureObject -} from '../utils' + import updateRegulation from './updateRegulation' +import { REGULATION_ACTION_TYPE, getRegulatoryFeatureId, emptyRegulatoryFeatureObject } from '../utils' -const resetRegulation = (id, nextId) => (dispatch) => { +const resetRegulation = (id, nextId) => dispatch => { emptyRegulatoryFeatureObject.next_id = nextId const emptyFeature = new Feature(emptyRegulatoryFeatureObject) emptyFeature.setId(getRegulatoryFeatureId(id)) diff --git a/frontend/src/features/Regulation/useCases/showRegulationToEdit.js b/frontend/src/features/Regulation/useCases/showRegulationToEdit.js index 0d5c60ceb9..6c47a3f177 100644 --- a/frontend/src/features/Regulation/useCases/showRegulationToEdit.js +++ b/frontend/src/features/Regulation/useCases/showRegulationToEdit.js @@ -1,9 +1,9 @@ -import { mapToRegulatoryZone, DEFAULT_REGULATORY_TEXT } from '../utils' -import { setError } from '../../../domain/shared_slices/Global' -import { setProcessingRegulation, setSelectedRegulatoryZoneId, setStatus } from '../../Backoffice/slice' -import { LayerProperties } from '../../../domain/entities/layers/constants' import { getRegulatoryZoneFromAPI, REGULATORY_ZONE_METADATA_ERROR_MESSAGE } from '../../../api/geoserver' +import { LayerProperties } from '../../../domain/entities/layers/constants' +import { setError } from '../../../domain/shared_slices/Global' import { STATUS } from '../../Backoffice/constants' +import { setProcessingRegulation, setSelectedRegulatoryZoneId, setStatus } from '../../Backoffice/slice' +import { mapToRegulatoryZone, DEFAULT_REGULATORY_TEXT } from '../utils' const showRegulationToEdit = regulatoryZone => async (dispatch, getState) => { const { speciesByCode } = getState().species @@ -14,32 +14,32 @@ const showRegulationToEdit = regulatoryZone => async (dispatch, getState) => { const regulatoryZoneMetadata = mapToRegulatoryZone(feature, speciesByCode) const { + fishingPeriod, + gearRegulation, + geometry, + id, lawType, - topic, - zone, + otherInfo, region, regulatoryReferences, - id, - fishingPeriod, speciesRegulation, - gearRegulation, - geometry, - otherInfo + topic, + zone } = regulatoryZoneMetadata dispatch( setProcessingRegulation({ + fishingPeriod, + gearRegulation, + geometry, + id, lawType, - topic, - zone, + otherInfo, region: region ? region.split(', ') : [], - id, regulatoryReferences: regulatoryReferences?.length > 0 ? regulatoryReferences : [DEFAULT_REGULATORY_TEXT], - fishingPeriod, speciesRegulation, - gearRegulation, - geometry, - otherInfo + topic, + zone }) ) dispatch(setSelectedRegulatoryZoneId(id)) diff --git a/frontend/src/features/Regulation/useCases/showRegulatoryZone.js b/frontend/src/features/Regulation/useCases/showRegulatoryZone.js index 5f580fc95e..151034faac 100644 --- a/frontend/src/features/Regulation/useCases/showRegulatoryZone.js +++ b/frontend/src/features/Regulation/useCases/showRegulatoryZone.js @@ -1,16 +1,16 @@ -import { batch } from 'react-redux' import { getArea, getCenter } from 'ol/extent' import GeoJSON from 'ol/format/GeoJSON' import VectorImageLayer from 'ol/layer/VectorImage' import { all } from 'ol/loadingstrategy' import VectorSource from 'ol/source/Vector' +import { batch } from 'react-redux' import simplify from 'simplify-geojson' +import { getRegulatoryZoneFromAPI } from '../../../api/geoserver' import { LayerProperties } from '../../../domain/entities/layers/constants' -import { animateToRegulatoryLayer } from '../../../domain/shared_slices/Map' -import layer from '../../../domain/shared_slices/Layer' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from '../../../domain/entities/map/constants' -import { getRegulatoryZoneFromAPI } from '../../../api/geoserver' +import layer from '../../../domain/shared_slices/Layer' +import { animateToRegulatoryLayer } from '../../../domain/shared_slices/Map' import { isNumeric } from '../../../utils/isNumeric' import { getRegulatoryLayerStyle } from '../layers/styles/regulatoryLayer.style' @@ -18,12 +18,10 @@ const IRRETRIEVABLE_FEATURES_EVENT = 'IRRETRIEVABLE_FEATURES' let currentNamespace = 'homepage' -const setIrretrievableFeaturesEvent = error => { - return { - type: IRRETRIEVABLE_FEATURES_EVENT, - error: error - } -} +const setIrretrievableFeaturesEvent = error => ({ + error, + type: IRRETRIEVABLE_FEATURES_EVENT +}) /** * Show a Regulatory zone @@ -31,12 +29,11 @@ const setIrretrievableFeaturesEvent = error => { */ const showRegulatoryZone = zoneToShow => dispatch => { currentNamespace = zoneToShow.namespace - const { - addShowedLayer - } = layer[currentNamespace].actions + const { addShowedLayer } = layer[currentNamespace].actions if (!zoneToShow.zone) { console.error('No regulatory layer to show.') + return } dispatch(addShowedLayer(zoneToShow)) @@ -47,8 +44,8 @@ export const getVectorOLLayer = (dispatch, getState) => nextVisibleLayer => { const source = getRegulatoryVectorSource(dispatch, getState)(nextVisibleLayer) const _layer = new VectorImageLayer({ - source, className: 'regulatory', + source, style: feature => [getRegulatoryLayerStyle(feature, nextVisibleLayer)] }) _layer.name = name @@ -59,10 +56,7 @@ export const getVectorOLLayer = (dispatch, getState) => nextVisibleLayer => { const getRegulatoryVectorSource = (dispatch, getState) => regulatoryZoneProperties => { const zoneName = `${LayerProperties.REGULATORY.code}:${regulatoryZoneProperties.topic}:${regulatoryZoneProperties.zone}` - const { - setLastShowedFeatures, - pushLayerToFeatures - } = layer[currentNamespace].actions + const { pushLayerToFeatures, setLastShowedFeatures } = layer[currentNamespace].actions const vectorSource = new VectorSource({ format: new GeoJSON({ @@ -70,11 +64,16 @@ const getRegulatoryVectorSource = (dispatch, getState) => regulatoryZoneProperti featureProjection: OPENLAYERS_PROJECTION }), loader: extent => { - getRegulatoryZoneFromAPI(LayerProperties.REGULATORY.code, regulatoryZoneProperties, getState().global.isBackoffice) + getRegulatoryZoneFromAPI( + LayerProperties.REGULATORY.code, + regulatoryZoneProperties, + getState().global.isBackoffice + ) .then(regulatoryZone => { if (!regulatoryZone.geometry) { vectorSource.dispatchEvent(setIrretrievableFeaturesEvent(new Error('Aucune géometrie dans la zone'))) vectorSource.removeLoadedExtent(extent) + return } @@ -85,26 +84,32 @@ const getRegulatoryVectorSource = (dispatch, getState) => regulatoryZoneProperti console.error(e) } - const feature = getState().regulatory.simplifiedGeometries ? simplifiedRegulatoryZone || regulatoryZone : regulatoryZone + const feature = getState().regulatory.simplifiedGeometries + ? simplifiedRegulatoryZone || regulatoryZone + : regulatoryZone vectorSource.addFeatures(vectorSource.getFormat().readFeatures(feature)) const center = getCenter(vectorSource.getExtent()) const centerHasValidCoordinates = center?.length && isNumeric(center[0]) && isNumeric(center[1]) batch(() => { - dispatch(pushLayerToFeatures({ - name: zoneName, - area: getArea(vectorSource.getExtent()), - simplifiedFeatures: simplifiedRegulatoryZone, - features: regulatoryZone, - center: center - })) + dispatch( + pushLayerToFeatures({ + area: getArea(vectorSource.getExtent()), + center, + features: regulatoryZone, + name: zoneName, + simplifiedFeatures: simplifiedRegulatoryZone + }) + ) dispatch(setLastShowedFeatures(vectorSource.getFeatures())) if (centerHasValidCoordinates) { - dispatch(animateToRegulatoryLayer({ - name: zoneName, - center: center - })) + dispatch( + animateToRegulatoryLayer({ + center, + name: zoneName + }) + ) } }) }) diff --git a/frontend/src/features/Regulation/useCases/updateRegulation.js b/frontend/src/features/Regulation/useCases/updateRegulation.js index 81c66fd303..e6012e8f35 100644 --- a/frontend/src/features/Regulation/useCases/updateRegulation.js +++ b/frontend/src/features/Regulation/useCases/updateRegulation.js @@ -1,10 +1,10 @@ -import { setProcessingRegulationSaved, setProcessingRegulationDeleted } from '../../Backoffice/slice' +import { sendRegulationTransaction } from '../../../api/geoserver' import { setError } from '../../../domain/shared_slices/Global' +import { setProcessingRegulationSaved, setProcessingRegulationDeleted } from '../../Backoffice/slice' import { REGULATION_ACTION_TYPE } from '../utils' -import { sendRegulationTransaction } from '../../../api/geoserver' -const updateRegulation = (feature, type) => dispatch => { - return sendRegulationTransaction(feature, type) +const updateRegulation = (feature, type) => dispatch => + sendRegulationTransaction(feature, type) .then(_ => { if (type === REGULATION_ACTION_TYPE.DELETE) { dispatch(setProcessingRegulationDeleted(true)) @@ -16,6 +16,5 @@ const updateRegulation = (feature, type) => dispatch => { console.error(e.error) dispatch(setError(e)) }) -} export default updateRegulation diff --git a/frontend/src/features/Regulation/useCases/updateTopicForAllZones.js b/frontend/src/features/Regulation/useCases/updateTopicForAllZones.js index cb8a45cc27..9f68a703fd 100644 --- a/frontend/src/features/Regulation/useCases/updateTopicForAllZones.js +++ b/frontend/src/features/Regulation/useCases/updateTopicForAllZones.js @@ -1,16 +1,19 @@ -import { setError } from '../../../domain/shared_slices/Global' -import { getRegulatoryFeatureId, mapToRegulatoryFeatureObject, REGULATION_ACTION_TYPE } from '../utils' import { Feature } from 'ol' -import { setLayersTopicsByRegTerritory, setRegulatoryLayerLawTypes } from '../slice' import { sendRegulationTransaction } from '../../../api/geoserver' +import { setError } from '../../../domain/shared_slices/Global' +import { setLayersTopicsByRegTerritory, setRegulatoryLayerLawTypes } from '../slice' +import { getRegulatoryFeatureId, mapToRegulatoryFeatureObject, REGULATION_ACTION_TYPE } from '../utils' const UPDATE_TOPIC_NAME_ERROR = 'Une erreur est survenue lors la mise à jour de la thématique' const updateTopicForAllZones = (territory, lawType, oldLayerName, newLayerName) => (dispatch, getState) => { const { layersTopicsByRegTerritory } = getState().regulatory - if (!layersTopicsByRegTerritory || !layersTopicsByRegTerritory[territory] || - !layersTopicsByRegTerritory[territory][lawType]) { + if ( + !layersTopicsByRegTerritory || + !layersTopicsByRegTerritory[territory] || + !layersTopicsByRegTerritory[territory][lawType] + ) { console.error(`${UPDATE_TOPIC_NAME_ERROR} One value is undefined: layersTopicsByRegTerritory is ${layersTopicsByRegTerritory} @@ -23,7 +26,7 @@ const updateTopicForAllZones = (territory, lawType, oldLayerName, newLayerName) if (layersTopicsByRegTerritory[territory][lawType][oldLayerName]) { const zoneListToUpdate = layersTopicsByRegTerritory[territory][lawType][oldLayerName] - const promiseList = zoneListToUpdate.map((zone) => { + const promiseList = zoneListToUpdate.map(zone => { const feature = buildZoneFeature(zone, newLayerName) return new Promise((resolve, reject) => { @@ -35,7 +38,13 @@ const updateTopicForAllZones = (territory, lawType, oldLayerName, newLayerName) return Promise.all(promiseList) .then(_ => { - const newLayersTopicsByRegTerritory = mutateLayersTopicsWithNewTopic(layersTopicsByRegTerritory, territory, lawType, newLayerName, oldLayerName) + const newLayersTopicsByRegTerritory = mutateLayersTopicsWithNewTopic( + layersTopicsByRegTerritory, + territory, + lawType, + newLayerName, + oldLayerName + ) dispatch(setLayersTopicsByRegTerritory(newLayersTopicsByRegTerritory)) dispatch(setRegulatoryLayerLawTypes(newLayersTopicsByRegTerritory)) }) @@ -46,17 +55,18 @@ const updateTopicForAllZones = (territory, lawType, oldLayerName, newLayerName) } } -function buildZoneFeature (zone, newLayerName) { +function buildZoneFeature(zone, newLayerName) { const featureObject = mapToRegulatoryFeatureObject({ ...zone, topic: newLayerName }) const feature = new Feature(featureObject) feature.setId(getRegulatoryFeatureId(zone.id)) + return feature } -function mutateLayersTopicsWithNewTopic (layersTopicsByRegTerritory, territory, lawType, newTopic, oldTopic) { +function mutateLayersTopicsWithNewTopic(layersTopicsByRegTerritory, territory, lawType, newTopic, oldTopic) { const newTerritoryObject = { ...layersTopicsByRegTerritory[territory] } const newLawTypeObject = { ...newTerritoryObject[lawType] } newLawTypeObject[newTopic] = [...newLawTypeObject[oldTopic]] diff --git a/frontend/src/features/Reporting/components/VesselReportings/Current/CreateOrEditReporting.tsx b/frontend/src/features/Reporting/components/VesselReportings/Current/CreateOrEditReporting.tsx index dd2687133c..132947c1b6 100644 --- a/frontend/src/features/Reporting/components/VesselReportings/Current/CreateOrEditReporting.tsx +++ b/frontend/src/features/Reporting/components/VesselReportings/Current/CreateOrEditReporting.tsx @@ -13,7 +13,7 @@ import { setEditedReporting } from '../../../slice' export function CreateOrEditReporting() { const dispatch = useMainAppDispatch() - const { selectedVesselIdentity } = useMainAppSelector(state => state.vessel) + const selectedVesselIdentity = useMainAppSelector(state => state.vessel.selectedVesselIdentity) const editedReporting = useMainAppSelector(state => state.reporting.editedReporting) const [newReportingFormIsOpen, setNewReportingFormIsOpen] = useState(false) const previousSelectedVesselIdentity = usePrevious(selectedVesselIdentity) diff --git a/frontend/src/features/Reporting/components/VesselReportings/Current/index.tsx b/frontend/src/features/Reporting/components/VesselReportings/Current/index.tsx index 4bd840342b..8f1736005c 100644 --- a/frontend/src/features/Reporting/components/VesselReportings/Current/index.tsx +++ b/frontend/src/features/Reporting/components/VesselReportings/Current/index.tsx @@ -16,7 +16,10 @@ import type { Reporting } from '../../../../../domain/types/reporting' export function Current() { const dispatch = useMainAppDispatch() - const { currentAndArchivedReportingsOfSelectedVessel, editedReporting } = useMainAppSelector(state => state.reporting) + const currentAndArchivedReportingsOfSelectedVessel = useMainAppSelector( + state => state.reporting.currentAndArchivedReportingsOfSelectedVessel + ) + const editedReporting = useMainAppSelector(state => state.reporting.editedReporting) const [deletionModalIsOpenForId, setDeletionModalIsOpenForId] = useState(undefined) const getAlertsDesc = useCallback( diff --git a/frontend/src/features/Reporting/components/VesselReportings/index.tsx b/frontend/src/features/Reporting/components/VesselReportings/index.tsx index 134d127379..1b300d497a 100644 --- a/frontend/src/features/Reporting/components/VesselReportings/index.tsx +++ b/frontend/src/features/Reporting/components/VesselReportings/index.tsx @@ -20,9 +20,10 @@ export function VesselReportings() { const dispatch = useMainAppDispatch() const selectedVesselIdentity = useMainAppSelector(state => state.vessel.selectedVesselIdentity) - const { currentAndArchivedReportingsOfSelectedVessel, isLoadingReporting } = useMainAppSelector( - state => state.reporting + const currentAndArchivedReportingsOfSelectedVessel = useMainAppSelector( + state => state.reporting.currentAndArchivedReportingsOfSelectedVessel ) + const isLoadingReporting = useMainAppSelector(state => state.reporting.isLoadingReporting) const [reportingTab, setReportingTab] = useState(ReportingTab.CURRENT_REPORTING) const previousSelectedVesselIdentity = usePrevious(selectedVesselIdentity) diff --git a/frontend/src/features/Reporting/useCases/archiveReporting.js b/frontend/src/features/Reporting/useCases/archiveReporting.js index 7506342e9a..dd7a20273a 100644 --- a/frontend/src/features/Reporting/useCases/archiveReporting.js +++ b/frontend/src/features/Reporting/useCases/archiveReporting.js @@ -1,50 +1,57 @@ -import { removeError, setError } from '../../../domain/shared_slices/Global' import { batch } from 'react-redux' -import { - removeReportingsIdsFromCurrentReportings, - setCurrentAndArchivedReportingsOfSelectedVessel -} from '../slice' + import { archiveReportingFromAPI } from '../../../api/reporting' import { Vessel } from '../../../domain/entities/vessel/vessel' +import { removeError, setError } from '../../../domain/shared_slices/Global' import { removeVesselReporting } from '../../../domain/shared_slices/Vessel' +import { removeReportingsIdsFromCurrentReportings, setCurrentAndArchivedReportingsOfSelectedVessel } from '../slice' const archiveReporting = id => (dispatch, getState) => { - const { - selectedVesselIdentity - } = getState().vessel - const { - currentAndArchivedReportingsOfSelectedVessel - } = getState().reporting + const { selectedVesselIdentity } = getState().vessel + const { currentAndArchivedReportingsOfSelectedVessel } = getState().reporting const archivedReporting = currentAndArchivedReportingsOfSelectedVessel.current.find(reporting => reporting.id === id) - const nextCurrentAndArchivedReporting = moveReportingOfSelectedVesselToArchived(currentAndArchivedReportingsOfSelectedVessel, archivedReporting) - dispatch(setCurrentAndArchivedReportingsOfSelectedVessel({ - currentAndArchivedReportingsOfSelectedVessel: nextCurrentAndArchivedReporting, - vesselIdentity: selectedVesselIdentity - })) + const nextCurrentAndArchivedReporting = moveReportingOfSelectedVesselToArchived( + currentAndArchivedReportingsOfSelectedVessel, + archivedReporting + ) + dispatch( + setCurrentAndArchivedReportingsOfSelectedVessel({ + currentAndArchivedReportingsOfSelectedVessel: nextCurrentAndArchivedReporting, + vesselIdentity: selectedVesselIdentity + }) + ) - archiveReportingFromAPI(id).then(() => { - dispatch(removeReportingsIdsFromCurrentReportings([id])) - dispatch(removeVesselReporting({ - vesselFeatureId: Vessel.getVesselFeatureId(selectedVesselIdentity), - reportingType: archivedReporting?.type - })) - dispatch(removeError()) - }).catch(error => { - console.error(error) - batch(() => { - dispatch(setCurrentAndArchivedReportingsOfSelectedVessel({ - currentAndArchivedReportingsOfSelectedVessel: currentAndArchivedReportingsOfSelectedVessel, - vesselIdentity: selectedVesselIdentity - })) - dispatch(setError(error)) + archiveReportingFromAPI(id) + .then(() => { + dispatch(removeReportingsIdsFromCurrentReportings([id])) + dispatch( + removeVesselReporting({ + reportingType: archivedReporting?.type, + vesselFeatureId: Vessel.getVesselFeatureId(selectedVesselIdentity) + }) + ) + dispatch(removeError()) + }) + .catch(error => { + console.error(error) + batch(() => { + dispatch( + setCurrentAndArchivedReportingsOfSelectedVessel({ + currentAndArchivedReportingsOfSelectedVessel, + vesselIdentity: selectedVesselIdentity + }) + ) + dispatch(setError(error)) + }) }) - }) } -function moveReportingOfSelectedVesselToArchived (currentAndArchivedReportingsOfSelectedVessel, archivedReporting) { +function moveReportingOfSelectedVesselToArchived(currentAndArchivedReportingsOfSelectedVessel, archivedReporting) { const nextCurrentAndArchivedReporting = { ...currentAndArchivedReportingsOfSelectedVessel } - nextCurrentAndArchivedReporting.current = nextCurrentAndArchivedReporting.current.filter(reporting => reporting.id !== archivedReporting.id) + nextCurrentAndArchivedReporting.current = nextCurrentAndArchivedReporting.current.filter( + reporting => reporting.id !== archivedReporting.id + ) nextCurrentAndArchivedReporting.archived = nextCurrentAndArchivedReporting.archived.concat(archivedReporting) return nextCurrentAndArchivedReporting diff --git a/frontend/src/features/Reporting/useCases/archiveReportings.js b/frontend/src/features/Reporting/useCases/archiveReportings.js index 1728b5d9fa..8ce2507578 100644 --- a/frontend/src/features/Reporting/useCases/archiveReportings.js +++ b/frontend/src/features/Reporting/useCases/archiveReportings.js @@ -1,74 +1,86 @@ -import { removeError, setError } from '../../../domain/shared_slices/Global' -import { - removeReportingsIdsFromCurrentReportings, - setCurrentAndArchivedReportingsOfSelectedVessel -} from '../slice' import { archiveReportingsFromAPI } from '../../../api/reporting' import { Vessel } from '../../../domain/entities/vessel/vessel' +import { removeError, setError } from '../../../domain/shared_slices/Global' import { removeVesselReportings } from '../../../domain/shared_slices/Vessel' +import { removeReportingsIdsFromCurrentReportings, setCurrentAndArchivedReportingsOfSelectedVessel } from '../slice' /** * Archive multiple reportings * @param {number[]} ids - The ids of reporting to archive */ const archiveReportings = ids => async (dispatch, getState) => { - const { - selectedVesselIdentity - } = getState().vessel - const { - currentAndArchivedReportingsOfSelectedVessel, - currentReportings, - vesselIdentity - } = getState().reporting + const { selectedVesselIdentity } = getState().vessel + const { currentAndArchivedReportingsOfSelectedVessel, currentReportings, vesselIdentity } = getState().reporting const archivedReportings = getArchivedReportingsFromIds(ids, currentReportings) - return archiveReportingsFromAPI(ids).then(() => { - dispatch(removeReportingsIdsFromCurrentReportings(ids)) - dispatch(removeVesselReportings(archivedReportings)) - if (vesselIdentity && currentAndArchivedReportingsOfSelectedVessel.current?.length) { - const archivedReportingsOfSelectedVessel = getArchivedReportingsOfSelectedVesselFromIds(ids, currentAndArchivedReportingsOfSelectedVessel) + return archiveReportingsFromAPI(ids) + .then(() => { + dispatch(removeReportingsIdsFromCurrentReportings(ids)) + dispatch(removeVesselReportings(archivedReportings)) + if (vesselIdentity && currentAndArchivedReportingsOfSelectedVessel.current?.length) { + const archivedReportingsOfSelectedVessel = getArchivedReportingsOfSelectedVesselFromIds( + ids, + currentAndArchivedReportingsOfSelectedVessel + ) - const nextCurrentAndArchivedReporting = getUpdatedCurrentAndArchivedReportingOfSelectedVessel(currentAndArchivedReportingsOfSelectedVessel, archivedReportingsOfSelectedVessel) - dispatch(setCurrentAndArchivedReportingsOfSelectedVessel({ - currentAndArchivedReportingsOfSelectedVessel: nextCurrentAndArchivedReporting, - vesselIdentity: selectedVesselIdentity - })) - } - dispatch(removeError()) - }).catch(error => { - console.error(error) - dispatch(setError(error)) - }) + const nextCurrentAndArchivedReporting = getUpdatedCurrentAndArchivedReportingOfSelectedVessel( + currentAndArchivedReportingsOfSelectedVessel, + archivedReportingsOfSelectedVessel + ) + dispatch( + setCurrentAndArchivedReportingsOfSelectedVessel({ + currentAndArchivedReportingsOfSelectedVessel: nextCurrentAndArchivedReporting, + vesselIdentity: selectedVesselIdentity + }) + ) + } + dispatch(removeError()) + }) + .catch(error => { + console.error(error) + dispatch(setError(error)) + }) } -function getArchivedReportingsFromIds (ids, currentReportings) { - return ids.map(id => { - const reporting = currentReportings.find(reporting => reporting.id === id) - if (!reporting) { - return null - } +function getArchivedReportingsFromIds(ids, currentReportings) { + return ids + .map(id => { + const reporting = currentReportings.find(reporting => reporting.id === id) + if (!reporting) { + return null + } - return { - id: reporting.id, - type: reporting.type, - vesselFeatureId: Vessel.getVesselFeatureId(reporting), - } - }).filter(reporting => reporting) + return { + id: reporting.id, + type: reporting.type, + vesselFeatureId: Vessel.getVesselFeatureId(reporting) + } + }) + .filter(reporting => reporting) } -function getArchivedReportingsOfSelectedVesselFromIds (ids, currentAndArchivedReportingsOfSelectedVessel) { - return ids.map(id => { - const reportingToArchive = currentAndArchivedReportingsOfSelectedVessel.current.find(reporting => reporting.id === id) - if (reportingToArchive) { - return reportingToArchive - } - }).filter(reporting => reporting) +function getArchivedReportingsOfSelectedVesselFromIds(ids, currentAndArchivedReportingsOfSelectedVessel) { + return ids + .map(id => { + const reportingToArchive = currentAndArchivedReportingsOfSelectedVessel.current.find( + reporting => reporting.id === id + ) + if (reportingToArchive) { + return reportingToArchive + } + }) + .filter(reporting => reporting) } -function getUpdatedCurrentAndArchivedReportingOfSelectedVessel (currentAndArchivedReportingsOfSelectedVessel, archivedReportings) { +function getUpdatedCurrentAndArchivedReportingOfSelectedVessel( + currentAndArchivedReportingsOfSelectedVessel, + archivedReportings +) { const nextCurrentAndArchivedReporting = { ...currentAndArchivedReportingsOfSelectedVessel } archivedReportings.forEach(reportingToArchive => { - nextCurrentAndArchivedReporting.current = nextCurrentAndArchivedReporting.current.filter(reporting => reporting.id !== reportingToArchive.id) + nextCurrentAndArchivedReporting.current = nextCurrentAndArchivedReporting.current.filter( + reporting => reporting.id !== reportingToArchive.id + ) nextCurrentAndArchivedReporting.archived = nextCurrentAndArchivedReporting.archived.concat(reportingToArchive) }) diff --git a/frontend/src/features/Reporting/useCases/deleteReportings.js b/frontend/src/features/Reporting/useCases/deleteReportings.js index 58e8da611d..2da3d06453 100644 --- a/frontend/src/features/Reporting/useCases/deleteReportings.js +++ b/frontend/src/features/Reporting/useCases/deleteReportings.js @@ -1,74 +1,86 @@ -import { removeError, setError } from '../../../domain/shared_slices/Global' -import { - removeReportingsIdsFromCurrentReportings, - setCurrentAndArchivedReportingsOfSelectedVessel -} from '../slice' import { deleteReportingsFromAPI } from '../../../api/reporting' import { Vessel } from '../../../domain/entities/vessel/vessel' +import { removeError, setError } from '../../../domain/shared_slices/Global' import { removeVesselReportings } from '../../../domain/shared_slices/Vessel' +import { removeReportingsIdsFromCurrentReportings, setCurrentAndArchivedReportingsOfSelectedVessel } from '../slice' /** * Delete multiple reportings * @param {number[]} ids - The ids of reporting to delete */ const deleteReportings = ids => async (dispatch, getState) => { - const { - selectedVesselIdentity - } = getState().vessel - const { - currentAndArchivedReportingsOfSelectedVessel, - currentReportings, - vesselIdentity - } = getState().reporting + const { selectedVesselIdentity } = getState().vessel + const { currentAndArchivedReportingsOfSelectedVessel, currentReportings, vesselIdentity } = getState().reporting const deletedReportings = getDeletedReportingsFromIds(ids, currentReportings) - return deleteReportingsFromAPI(ids).then(() => { - dispatch(removeReportingsIdsFromCurrentReportings(ids)) - dispatch(removeVesselReportings(deletedReportings)) - if (vesselIdentity && currentAndArchivedReportingsOfSelectedVessel.current?.length) { - const deletedReportingsOfSelectedVessel = getDeletedReportingOfSelectedVesselFromIds(ids, currentAndArchivedReportingsOfSelectedVessel) + return deleteReportingsFromAPI(ids) + .then(() => { + dispatch(removeReportingsIdsFromCurrentReportings(ids)) + dispatch(removeVesselReportings(deletedReportings)) + if (vesselIdentity && currentAndArchivedReportingsOfSelectedVessel.current?.length) { + const deletedReportingsOfSelectedVessel = getDeletedReportingOfSelectedVesselFromIds( + ids, + currentAndArchivedReportingsOfSelectedVessel + ) - const nextCurrentAndArchivedReporting = getUpdatedCurrentAndArchivedReportingOfSelectedVessel(currentAndArchivedReportingsOfSelectedVessel, deletedReportingsOfSelectedVessel) - dispatch(setCurrentAndArchivedReportingsOfSelectedVessel({ - currentAndArchivedReportingsOfSelectedVessel: nextCurrentAndArchivedReporting, - vesselIdentity: selectedVesselIdentity - })) - } - dispatch(removeError()) - }).catch(error => { - console.error(error) - dispatch(setError(error)) - }) + const nextCurrentAndArchivedReporting = getUpdatedCurrentAndArchivedReportingOfSelectedVessel( + currentAndArchivedReportingsOfSelectedVessel, + deletedReportingsOfSelectedVessel + ) + dispatch( + setCurrentAndArchivedReportingsOfSelectedVessel({ + currentAndArchivedReportingsOfSelectedVessel: nextCurrentAndArchivedReporting, + vesselIdentity: selectedVesselIdentity + }) + ) + } + dispatch(removeError()) + }) + .catch(error => { + console.error(error) + dispatch(setError(error)) + }) } -function getDeletedReportingsFromIds (ids, currentReportings) { - return ids.map(id => { - const reporting = currentReportings.find(reporting => reporting.id === id) - if (!reporting) { - return null - } +function getDeletedReportingsFromIds(ids, currentReportings) { + return ids + .map(id => { + const reporting = currentReportings.find(reporting => reporting.id === id) + if (!reporting) { + return null + } - return { - id: reporting.id, - type: reporting.type, - vesselFeatureId: Vessel.getVesselFeatureId(reporting), - } - }).filter(reporting => reporting) + return { + id: reporting.id, + type: reporting.type, + vesselFeatureId: Vessel.getVesselFeatureId(reporting) + } + }) + .filter(reporting => reporting) } -function getDeletedReportingOfSelectedVesselFromIds (ids, currentAndArchivedReportingsOfSelectedVessel) { - return ids.map(id => { - const reportingToArchive = currentAndArchivedReportingsOfSelectedVessel.current.find(reporting => reporting.id === id) - if (reportingToArchive) { - return reportingToArchive - } - }).filter(reporting => reporting) +function getDeletedReportingOfSelectedVesselFromIds(ids, currentAndArchivedReportingsOfSelectedVessel) { + return ids + .map(id => { + const reportingToArchive = currentAndArchivedReportingsOfSelectedVessel.current.find( + reporting => reporting.id === id + ) + if (reportingToArchive) { + return reportingToArchive + } + }) + .filter(reporting => reporting) } -function getUpdatedCurrentAndArchivedReportingOfSelectedVessel (currentAndArchivedReportingsOfSelectedVessel, deletedReportings) { +function getUpdatedCurrentAndArchivedReportingOfSelectedVessel( + currentAndArchivedReportingsOfSelectedVessel, + deletedReportings +) { const nextCurrentAndArchivedReporting = { ...currentAndArchivedReportingsOfSelectedVessel } deletedReportings.forEach(reportingToArchive => { - nextCurrentAndArchivedReporting.current = nextCurrentAndArchivedReporting.current.filter(reporting => reporting.id !== reportingToArchive.id) + nextCurrentAndArchivedReporting.current = nextCurrentAndArchivedReporting.current.filter( + reporting => reporting.id !== reportingToArchive.id + ) }) return nextCurrentAndArchivedReporting diff --git a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/EditReporting.tsx b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/EditReporting.tsx index 84bd3bc476..291b2192cd 100644 --- a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/EditReporting.tsx +++ b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/EditReporting.tsx @@ -16,7 +16,7 @@ import type { CSSProperties } from 'react' export function EditReporting() { const dispatch = useMainAppDispatch() const baseUrl = window.location.origin - const { editedReportingInSideWindow } = useMainAppSelector(state => state.reporting) + const editedReportingInSideWindow = useMainAppSelector(state => state.reporting.editedReportingInSideWindow) const editReportingWrapperStyle: CSSProperties = useMemo( () => ({ diff --git a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertRow.tsx b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertRow.tsx index 1e2a10bd8b..696decad07 100644 --- a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertRow.tsx +++ b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertRow.tsx @@ -38,7 +38,8 @@ export function PendingAlertRow({ }: PendingAlertRowProps) { const dispatch = useMainAppDispatch() const ref = useRef() as MutableRefObject - const { focusedPendingAlertId, silencedAlertsQueue } = useMainAppSelector(state => state.alert) + const focusedPendingAlertId = useMainAppSelector(state => state.alert.focusedPendingAlertId) + const silencedAlertsQueue = useMainAppSelector(state => state.alert.silencedAlertsQueue) const baseUrl = window.location.origin const silencedAlertsQueueMatch = useMemo( diff --git a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertsList.tsx b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertsList.tsx index 56307b2f54..7cdbf25e82 100644 --- a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertsList.tsx +++ b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/PendingAlertsList.tsx @@ -30,7 +30,8 @@ export type PendingAlertsListProps = { */ export function PendingAlertsList({ baseRef, numberOfSilencedAlerts, selectedSeaFrontGroup }: PendingAlertsListProps) { const dispatch = useMainAppDispatch() - const { focusedPendingAlertId, pendingAlerts } = useMainAppSelector(state => state.alert) + const focusedPendingAlertId = useMainAppSelector(state => state.alert.focusedPendingAlertId) + const pendingAlerts = useMainAppSelector(state => state.alert.pendingAlerts) const baseUrl = window.location.origin const [sortColumn] = useState('creationDate') const [sortType] = useState(SortType.DESC) diff --git a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/index.tsx b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/index.tsx index aea86dfd38..398f3bb53b 100644 --- a/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/index.tsx +++ b/frontend/src/features/SideWindow/Alert/AlertListAndReportingList/index.tsx @@ -27,7 +27,9 @@ export function AlertListAndReportingList({ setSelectedTab }: AlertsAndReportingsProps) { const dispatch = useMainAppDispatch() - const { focusedPendingAlertId, pendingAlerts, silencedAlerts } = useMainAppSelector(state => state.alert) + const focusedPendingAlertId = useMainAppSelector(state => state.alert.focusedPendingAlertId) + const pendingAlerts = useMainAppSelector(state => state.alert.pendingAlerts) + const silencedAlerts = useMainAppSelector(state => state.alert.silencedAlerts) const filteredSilencedAlerts = useMemo( () => diff --git a/frontend/src/features/SideWindow/Alert/SilencedAlerts/index.tsx b/frontend/src/features/SideWindow/Alert/SilencedAlerts/index.tsx index 8cb15d4262..7b003a0c4a 100644 --- a/frontend/src/features/SideWindow/Alert/SilencedAlerts/index.tsx +++ b/frontend/src/features/SideWindow/Alert/SilencedAlerts/index.tsx @@ -22,7 +22,8 @@ import type { SilencedAlertData } from '../../../../domain/entities/alerts/types export function SilencedAlerts() { const dispatch = useMainAppDispatch() - const { focusedPendingAlertId, silencedAlerts } = useMainAppSelector(state => state.alert) + const focusedPendingAlertId = useMainAppSelector(state => state.alert.focusedPendingAlertId) + const silencedAlerts = useMainAppSelector(state => state.alert.silencedAlerts) const baseUrl = window.location.origin const [sortColumn] = useState('silencedBeforeDate') const [sortType] = useState(SortType.ASC) diff --git a/frontend/src/features/SideWindow/Alert/index.tsx b/frontend/src/features/SideWindow/Alert/index.tsx index c5d17c1ae7..56c1768567 100644 --- a/frontend/src/features/SideWindow/Alert/index.tsx +++ b/frontend/src/features/SideWindow/Alert/index.tsx @@ -19,7 +19,7 @@ type AlertProps = { export function Alert({ baseRef }: AlertProps) { const dispatch = useMainAppDispatch() const { pendingAlerts, subMenu } = useMainAppSelector(state => state.alert) - const { currentReportings } = useMainAppSelector(state => state.reporting) + const currentReportings = useMainAppSelector(state => state.reporting.currentReportings) const [selectedTab, setSelectedTab] = useState(AlertAndReportingTab.ALERT) const handleSubMenuChange = useCallback( diff --git a/frontend/src/features/SideWindow/BeaconMalfunctionBoard/BeaconMalfunctionDetailsFollowUp.tsx b/frontend/src/features/SideWindow/BeaconMalfunctionBoard/BeaconMalfunctionDetailsFollowUp.tsx index 640d4ef47c..001687e8e2 100644 --- a/frontend/src/features/SideWindow/BeaconMalfunctionBoard/BeaconMalfunctionDetailsFollowUp.tsx +++ b/frontend/src/features/SideWindow/BeaconMalfunctionBoard/BeaconMalfunctionDetailsFollowUp.tsx @@ -26,7 +26,7 @@ import type { CSSProperties } from 'react' export function BeaconMalfunctionDetailsFollowUp({ beaconMalfunctionWithDetails, firstStatus, smallSize }) { const { actions, beaconMalfunction, comments, notifications } = beaconMalfunctionWithDetails const dispatch = useMainAppDispatch() - const { userType } = useMainAppSelector(state => state.global) + const userType = useMainAppSelector(state => state.global.userType) const firstVesselStatus = VESSEL_STATUS.find(status => status.value === firstStatus) as BeaconMalfunctionStatusValue const [today, setToday] = useState('') const [yesterday, setYesterday] = useState('') diff --git a/frontend/src/features/SideWindow/BeaconMalfunctionBoard/StageColumn.tsx b/frontend/src/features/SideWindow/BeaconMalfunctionBoard/StageColumn.tsx index 87fe54de96..a476b910c7 100644 --- a/frontend/src/features/SideWindow/BeaconMalfunctionBoard/StageColumn.tsx +++ b/frontend/src/features/SideWindow/BeaconMalfunctionBoard/StageColumn.tsx @@ -30,7 +30,9 @@ export function StageColumn({ updateVesselStatus }: StageColumnType) { const verticalScrollRef = useRef(null) as MutableRefObject - const { openedBeaconMalfunctionInKanban } = useMainAppSelector(state => state.beaconMalfunction) + const openedBeaconMalfunctionInKanban = useMainAppSelector( + state => state.beaconMalfunction.openedBeaconMalfunctionInKanban + ) return ( diff --git a/frontend/src/features/SideWindow/MissionList/FilterBar.tsx b/frontend/src/features/SideWindow/MissionList/FilterBar.tsx index a744ab82e1..c7e69482e2 100644 --- a/frontend/src/features/SideWindow/MissionList/FilterBar.tsx +++ b/frontend/src/features/SideWindow/MissionList/FilterBar.tsx @@ -36,7 +36,7 @@ export type FilterBarProps = { export function FilterBar({ onQueryChange, searchQuery }: FilterBarProps) { const { newWindowContainerRef } = useNewWindow() - const { listFilterValues } = useMainAppSelector(store => store.mission) + const listFilterValues = useMainAppSelector(store => store.mission.listFilterValues) const [isCustomDateRangeOpen, setIsCustomDateRangeOpen] = useState(false) diff --git a/frontend/src/features/SideWindow/index.tsx b/frontend/src/features/SideWindow/index.tsx index cc5c42da50..e13dfe607f 100644 --- a/frontend/src/features/SideWindow/index.tsx +++ b/frontend/src/features/SideWindow/index.tsx @@ -38,9 +38,11 @@ export function SideWindow({ isFromURL }: SideWindowProps) { // eslint-disable-next-line no-null/no-null const wrapperRef = useRef(null) - const { openedBeaconMalfunctionInKanban } = useMainAppSelector(state => state.beaconMalfunction) - const { editedReportingInSideWindow } = useMainAppSelector(state => state.reporting) - const { selectedPath } = useMainAppSelector(state => state.sideWindow) + const openedBeaconMalfunctionInKanban = useMainAppSelector( + state => state.beaconMalfunction.openedBeaconMalfunctionInKanban + ) + const editedReportingInSideWindow = useMainAppSelector(state => state.reporting.editedReportingInSideWindow) + const selectedPath = useMainAppSelector(state => state.sideWindow.selectedPath) const dispatch = useMainAppDispatch() const [isFirstRender, setIsFirstRender] = useState(true) diff --git a/frontend/src/features/Vessel/components/VesselLoader.tsx b/frontend/src/features/Vessel/components/VesselLoader.tsx index 5bd7f1b672..6d303e2cf9 100644 --- a/frontend/src/features/Vessel/components/VesselLoader.tsx +++ b/frontend/src/features/Vessel/components/VesselLoader.tsx @@ -19,8 +19,9 @@ export function VesselLoader() { const isInLightMode = useIsInLightMode() const dispatch = useMainAppDispatch() - const { blockVesselsUpdate } = useMainAppSelector(state => state.global) - const { loadingPositions, vesselSidebarIsOpen } = useMainAppSelector(state => state.vessel) + const blockVesselsUpdate = useMainAppSelector(state => state.global.blockVesselsUpdate) + const loadingPositions = useMainAppSelector(state => state.vessel.loadingPositions) + const vesselSidebarIsOpen = useMainAppSelector(state => state.vessel.vesselSidebarIsOpen) const { data: vessels, diff --git a/frontend/src/features/VesselList/index.tsx b/frontend/src/features/VesselList/index.tsx index ab6be0e3f7..611727543f 100644 --- a/frontend/src/features/VesselList/index.tsx +++ b/frontend/src/features/VesselList/index.tsx @@ -64,7 +64,7 @@ type ZoneGroupAndChildren = { export function VesselList({ namespace }) { const dispatch = useMainAppDispatch() const { previewFilteredVesselsMode, rightMenuIsOpen } = useMainAppSelector(state => state.global) - const { isVesselListModalDisplayed } = useMainAppSelector(state => state.displayedComponent) + const isVesselListModalDisplayed = useMainAppSelector(state => state.displayedComponent.isVesselListModalDisplayed) const { drawedGeometry } = useListenForDrawedGeometry(InteractionListener.VESSELS_LIST) const { uniqueVesselsDistricts: districts, diff --git a/frontend/src/features/VesselSearch/VesselSearchResult.tsx b/frontend/src/features/VesselSearch/VesselSearchResult.tsx index 973f4194ef..21c2fbdbb7 100644 --- a/frontend/src/features/VesselSearch/VesselSearchResult.tsx +++ b/frontend/src/features/VesselSearch/VesselSearchResult.tsx @@ -7,7 +7,7 @@ import { getVesselCompositeIdentifier } from '../../domain/entities/vessel/vesse import { useMainAppSelector } from '../../hooks/useMainAppSelector' export function VesselSearchResult({ foundVessels, searchQuery, selectVessel, showLastSearchedVessels }) { - const { lastSearchedVessels } = useMainAppSelector(state => state.global) + const lastSearchedVessels = useMainAppSelector(state => state.global.lastSearchedVessels) const baseUrl = useMemo(() => window.location.origin, []) return ( diff --git a/frontend/src/features/VesselSearch/index.tsx b/frontend/src/features/VesselSearch/index.tsx index 575d3901f2..a67f17527c 100644 --- a/frontend/src/features/VesselSearch/index.tsx +++ b/frontend/src/features/VesselSearch/index.tsx @@ -55,7 +55,8 @@ export function VesselSearch({ const dispatch = useMainAppDispatch() const baseUrl = useMemo(() => window.location.origin, []) - const { selectedVesselIdentity, vessels } = useMainAppSelector(state => state.vessel) + const selectedVesselIdentity = useMainAppSelector(state => state.vessel.selectedVesselIdentity) + const vessels = useMainAppSelector(state => state.vessel.vessels) const escapeFromKeyboard = useEscapeFromKeyboard() const clickedOutsideComponent = useClickOutsideWhenOpenedWithinRef(wrapperRef, isExtended, baseRef) diff --git a/frontend/src/features/VesselSidebar/Body.tsx b/frontend/src/features/VesselSidebar/Body.tsx index 3e48c81c58..e34e32c47f 100644 --- a/frontend/src/features/VesselSidebar/Body.tsx +++ b/frontend/src/features/VesselSidebar/Body.tsx @@ -18,9 +18,10 @@ import { VesselReportings } from '../Reporting/components/VesselReportings' export function Body() { const isSuperUser = useIsSuperUser() const dispatch = useMainAppDispatch() - const { healthcheckTextWarning } = useMainAppSelector(state => state.global) + const healthcheckTextWarning = useMainAppSelector(state => state.global.healthcheckTextWarning) const vesselSidebarError = useMainAppSelector(state => state.displayedError.vesselSidebarError) - const { selectedVessel, vesselSidebarTab } = useMainAppSelector(state => state.vessel) + const selectedVessel = useMainAppSelector(state => state.vessel.selectedVessel) + const vesselSidebarTab = useMainAppSelector(state => state.vessel.vesselSidebarTab) if (vesselSidebarError) { return ( diff --git a/frontend/src/features/VesselSidebar/Controls/index.tsx b/frontend/src/features/VesselSidebar/Controls/index.tsx index 18f5afbc20..a6cde1fb0e 100644 --- a/frontend/src/features/VesselSidebar/Controls/index.tsx +++ b/frontend/src/features/VesselSidebar/Controls/index.tsx @@ -14,7 +14,7 @@ import { useMainAppSelector } from '../../../hooks/useMainAppSelector' export function Controls() { const dispatch = useMainAppDispatch() - const { selectedVessel } = useMainAppSelector(state => state.vessel) + const selectedVessel = useMainAppSelector(state => state.vessel.selectedVessel) const { controlsFromDate, currentControlSummary, loadingControls, nextControlSummary } = useMainAppSelector( state => state.controls diff --git a/frontend/src/features/VesselSidebar/Summary/index.tsx b/frontend/src/features/VesselSidebar/Summary/index.tsx index 58b608dad2..8462a91704 100644 --- a/frontend/src/features/VesselSidebar/Summary/index.tsx +++ b/frontend/src/features/VesselSidebar/Summary/index.tsx @@ -19,7 +19,7 @@ timeago.register('fr', timeagoFrenchLocale) export function VesselSummary() { const dispatch = useMainAppDispatch() - const { coordinatesFormat } = useMainAppSelector(state => state.map) + const coordinatesFormat = useMainAppSelector(state => state.map.coordinatesFormat) const { loadingVessel, selectedVessel, selectedVesselIdentity, selectedVesselPositions } = useMainAppSelector( state => state.vessel ) diff --git a/frontend/src/features/VesselSidebar/Tabs.tsx b/frontend/src/features/VesselSidebar/Tabs.tsx index 0b4746ebcc..c82e4d9473 100644 --- a/frontend/src/features/VesselSidebar/Tabs.tsx +++ b/frontend/src/features/VesselSidebar/Tabs.tsx @@ -20,7 +20,8 @@ import SummarySVG from '../icons/Picto_resume.svg?react' export function Tabs() { const dispatch = useMainAppDispatch() const isSuperUser = useIsSuperUser() - const { selectedVessel, vesselSidebarTab } = useMainAppSelector(state => state.vessel) + const selectedVessel = useMainAppSelector(state => state.vessel.selectedVessel) + const vesselSidebarTab = useMainAppSelector(state => state.vessel.vesselSidebarTab) useEffect(() => { if (!isSuperUser && forbiddenVesselSidebarPaths.includes(vesselSidebarTab)) { diff --git a/frontend/src/features/VesselSidebar/VesselSidebarHeader/index.tsx b/frontend/src/features/VesselSidebar/VesselSidebarHeader/index.tsx index aedd188195..964e1b4a1c 100644 --- a/frontend/src/features/VesselSidebar/VesselSidebarHeader/index.tsx +++ b/frontend/src/features/VesselSidebar/VesselSidebarHeader/index.tsx @@ -22,7 +22,8 @@ export function VesselSidebarHeader() { state => state.vessel ) - const { previewFilteredVesselsMode, rightMenuIsOpen } = useMainAppSelector(state => state.global) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) const isVesselNameShown = !isFocusedOnVesselSearch && selectedVesselIdentity const isRightMenuShrinked = vesselSidebarIsOpen && !rightMenuIsOpen diff --git a/frontend/src/features/VesselSidebar/actions/animate_to_track/index.tsx b/frontend/src/features/VesselSidebar/actions/animate_to_track/index.tsx index 763f9389d7..f6e65fee36 100644 --- a/frontend/src/features/VesselSidebar/actions/animate_to_track/index.tsx +++ b/frontend/src/features/VesselSidebar/actions/animate_to_track/index.tsx @@ -7,8 +7,8 @@ import ShowTrackSVG from '../../../icons/Bouton_afficher_toute_la_piste.svg?reac import { VesselSidebarActionButton } from '../VesselSidebarActionButton' export function AnimateToTrack({ isSidebarOpen }) { - const { rightMenuIsOpen } = useMainAppSelector(state => state.global) - const { selectedVesselPositions } = useMainAppSelector(state => state.vessel) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) + const selectedVesselPositions = useMainAppSelector(state => state.vessel.selectedVesselPositions) const dispatch = useMainAppDispatch() return ( diff --git a/frontend/src/features/VesselSidebar/actions/hide_non_selected_vessels/index.tsx b/frontend/src/features/VesselSidebar/actions/hide_non_selected_vessels/index.tsx index 3752166900..3497614d5f 100644 --- a/frontend/src/features/VesselSidebar/actions/hide_non_selected_vessels/index.tsx +++ b/frontend/src/features/VesselSidebar/actions/hide_non_selected_vessels/index.tsx @@ -10,8 +10,9 @@ import { VesselSidebarActionButton } from '../VesselSidebarActionButton' export function HideNonSelectedVessels({ isSidebarOpen }) { const dispatch = useMainAppDispatch() - const { rightMenuIsOpen } = useMainAppSelector(state => state.global) - const { hideNonSelectedVessels, selectedVesselPositions } = useMainAppSelector(state => state.vessel) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) + const hideNonSelectedVessels = useMainAppSelector(state => state.vessel.hideNonSelectedVessels) + const selectedVesselPositions = useMainAppSelector(state => state.vessel.selectedVesselPositions) return ( state.global) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) const { selectedVesselIdentity, selectedVesselPositions } = useMainAppSelector(state => state.vessel) const { areFishingActivitiesShowedOnMap, fishingActivities, fishingActivitiesShowedOnMap } = useMainAppSelector( state => state.fishingActivities diff --git a/frontend/src/features/VesselSidebar/beacon_malfunctions/details/BeaconMalfunctionDetails.tsx b/frontend/src/features/VesselSidebar/beacon_malfunctions/details/BeaconMalfunctionDetails.tsx index 3c53580f49..13b73900d1 100644 --- a/frontend/src/features/VesselSidebar/beacon_malfunctions/details/BeaconMalfunctionDetails.tsx +++ b/frontend/src/features/VesselSidebar/beacon_malfunctions/details/BeaconMalfunctionDetails.tsx @@ -16,7 +16,7 @@ type BeaconMalfunctionDetailsProps = { isCurrentBeaconMalfunctionDetails: boolean } export function BeaconMalfunctionDetails({ isCurrentBeaconMalfunctionDetails }: BeaconMalfunctionDetailsProps) { - const { openedBeaconMalfunction } = useMainAppSelector(state => state.beaconMalfunction) + const openedBeaconMalfunction = useMainAppSelector(state => state.beaconMalfunction.openedBeaconMalfunction) const dispatch = useMainAppDispatch() const navigateToResume = () => dispatch(setBeaconMalfunctionsTab(BeaconMalfunctionsTab.RESUME)) diff --git a/frontend/src/features/VesselSidebar/index.tsx b/frontend/src/features/VesselSidebar/index.tsx index f1aa7ea74d..550a0dc25d 100644 --- a/frontend/src/features/VesselSidebar/index.tsx +++ b/frontend/src/features/VesselSidebar/index.tsx @@ -11,7 +11,7 @@ import { useMainAppSelector } from '../../hooks/useMainAppSelector' import { MapComponent } from '../commonStyles/MapComponent' export function VesselSidebar() { - const { rightMenuIsOpen } = useMainAppSelector(state => state.global) + const rightMenuIsOpen = useMainAppSelector(state => state.global.rightMenuIsOpen) const isFocusedOnVesselSearch = useMainAppSelector(state => state.vessel.isFocusedOnVesselSearch) const [isFirstLoad, setIsFirstLoad] = useState(false) diff --git a/frontend/src/features/VesselSidebar/risk_factor/details/ProbabilityRiskFactorDetails.tsx b/frontend/src/features/VesselSidebar/risk_factor/details/ProbabilityRiskFactorDetails.tsx index db8b6b361f..d83b9d2726 100644 --- a/frontend/src/features/VesselSidebar/risk_factor/details/ProbabilityRiskFactorDetails.tsx +++ b/frontend/src/features/VesselSidebar/risk_factor/details/ProbabilityRiskFactorDetails.tsx @@ -5,7 +5,7 @@ import { useMainAppSelector } from '../../../../hooks/useMainAppSelector' import { InfractionsSummary } from '../../Controls/InfractionsSummary' export function ProbabilityRiskFactorDetails({ isOpen }) { - const { selectedVessel } = useMainAppSelector(state => state.vessel) + const selectedVessel = useMainAppSelector(state => state.vessel.selectedVessel) const currentYear = new Date().getUTCFullYear() if (!selectedVessel) { diff --git a/frontend/src/features/commonStyles/MapButton.tsx b/frontend/src/features/commonStyles/MapButton.tsx index 20e29d3f0c..5c97265b29 100644 --- a/frontend/src/features/commonStyles/MapButton.tsx +++ b/frontend/src/features/commonStyles/MapButton.tsx @@ -9,7 +9,7 @@ type MapButtonType = { isHidden?: boolean | undefined } & HTMLProps export function MapButton({ children, isHidden, ...props }: MapButtonType) { - const { healthcheckTextWarning } = useMainAppSelector(state => state.global) + const healthcheckTextWarning = useMainAppSelector(state => state.global.healthcheckTextWarning) return ( /** diff --git a/frontend/src/features/commonStyles/MapComponent.tsx b/frontend/src/features/commonStyles/MapComponent.tsx index 38f7579f20..97fab34272 100644 --- a/frontend/src/features/commonStyles/MapComponent.tsx +++ b/frontend/src/features/commonStyles/MapComponent.tsx @@ -10,7 +10,7 @@ type MapComponentStyleType = { isHidden?: boolean | undefined } export function MapComponent({ children, className, isHidden, ...props }: MapComponentStyleType) { - const { healthcheckTextWarning } = useMainAppSelector(state => state.global) + const healthcheckTextWarning = useMainAppSelector(state => state.global.healthcheckTextWarning) return ( state.displayedComponent) + const isMissionsLayerDisplayed = useMainAppSelector(state => state.displayedComponent.isMissionsLayerDisplayed) const [featuresAndLabels, setFeaturesAndLabels] = useState< { color: string diff --git a/frontend/src/features/map/layers/Vessel/VesselsLabelsLayer.tsx b/frontend/src/features/map/layers/Vessel/VesselsLabelsLayer.tsx index 65efaca4da..b0eb79628a 100644 --- a/frontend/src/features/map/layers/Vessel/VesselsLabelsLayer.tsx +++ b/frontend/src/features/map/layers/Vessel/VesselsLabelsLayer.tsx @@ -31,21 +31,21 @@ export function VesselsLabelsLayer({ mapMovingAndZoomEvent }) { const isSuperUser = useIsSuperUser() - const { hideNonSelectedVessels, selectedVessel, vessels, vesselsTracksShowed } = useMainAppSelector( - state => state.vessel - ) - const { areVesselsDisplayed } = useMainAppSelector(state => state.displayedComponent) - const { previewFilteredVesselsMode } = useMainAppSelector(state => state.global) - - const { - hideVesselsAtPort, - riskFactorShowedOnMap, - vesselLabel, - vesselLabelsShowedOnMap, - vesselsLastPositionVisibility - } = useMainAppSelector(state => state.map) - - const { filters, nonFilteredVesselsAreHidden } = useMainAppSelector(state => state.filter) + const hideNonSelectedVessels = useMainAppSelector(state => state.vessel.hideNonSelectedVessels) + const selectedVessel = useMainAppSelector(state => state.vessel.selectedVessel) + const vessels = useMainAppSelector(state => state.vessel.vessels) + const vesselsTracksShowed = useMainAppSelector(state => state.vessel.vesselsTracksShowed) + const areVesselsDisplayed = useMainAppSelector(state => state.displayedComponent.areVesselsDisplayed) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) + + const hideVesselsAtPort = useMainAppSelector(state => state.map.hideVesselsAtPort) + const riskFactorShowedOnMap = useMainAppSelector(state => state.map.riskFactorShowedOnMap) + const vesselLabel = useMainAppSelector(state => state.map.vesselLabel) + const vesselLabelsShowedOnMap = useMainAppSelector(state => state.map.vesselLabelsShowedOnMap) + const vesselsLastPositionVisibility = useMainAppSelector(state => state.map.vesselsLastPositionVisibility) + + const filters = useMainAppSelector(state => state.filter.filters) + const nonFilteredVesselsAreHidden = useMainAppSelector(state => state.filter.nonFilteredVesselsAreHidden) const [featuresAndLabels, setFeaturesAndLabels] = useState< { diff --git a/frontend/src/features/map/layers/Vessel/VesselsLayer/index.tsx b/frontend/src/features/map/layers/Vessel/VesselsLayer/index.tsx index 26bb03def6..9efcad3cf1 100644 --- a/frontend/src/features/map/layers/Vessel/VesselsLayer/index.tsx +++ b/frontend/src/features/map/layers/Vessel/VesselsLayer/index.tsx @@ -20,13 +20,16 @@ import type { WebGLPointsLayerWithName } from '../../../../../domain/types/layer function UnmemoizedVesselsLayer() { const dispatch = useMainAppDispatch() - const { areVesselsDisplayed } = useMainAppSelector(state => state.displayedComponent) + const areVesselsDisplayed = useMainAppSelector(state => state.displayedComponent.areVesselsDisplayed) - const { hideNonSelectedVessels, vessels } = useMainAppSelector(state => state.vessel) + const hideNonSelectedVessels = useMainAppSelector(state => state.vessel.hideNonSelectedVessels) + const vessels = useMainAppSelector(state => state.vessel.vessels) - const { hideVesselsAtPort, selectedBaseLayer, vesselsLastPositionVisibility } = useMainAppSelector(state => state.map) + const hideVesselsAtPort = useMainAppSelector(state => state.map.hideVesselsAtPort) + const selectedBaseLayer = useMainAppSelector(state => state.map.selectedBaseLayer) + const vesselsLastPositionVisibility = useMainAppSelector(state => state.map.vesselsLastPositionVisibility) - const { previewFilteredVesselsMode } = useMainAppSelector(state => state.global) + const previewFilteredVesselsMode = useMainAppSelector(state => state.global.previewFilteredVesselsMode) const { filterColor, filters, nonFilteredVesselsAreHidden, showedFilter } = useMainAppSelector(state => { const nextShowedFilter = state.filter?.filters?.find(filter => filter.showed) diff --git a/frontend/src/features/map/layers/Vessel/VesselsTracksLayer.tsx b/frontend/src/features/map/layers/Vessel/VesselsTracksLayer.tsx index 70ff602b1a..eb57babfd8 100644 --- a/frontend/src/features/map/layers/Vessel/VesselsTracksLayer.tsx +++ b/frontend/src/features/map/layers/Vessel/VesselsTracksLayer.tsx @@ -37,10 +37,9 @@ function VesselsTracksLayer() { const dispatch = useMainAppDispatch() const { highlightedVesselTrackPosition, selectedVessel, selectedVesselPositions, vesselsTracksShowed } = useMainAppSelector(state => state.vessel) - const { fishingActivitiesShowedOnMap, redrawFishingActivitiesOnMap } = useMainAppSelector( - state => state.fishingActivities - ) - const { doNotAnimate } = useMainAppSelector(state => state.map) + const fishingActivitiesShowedOnMap = useMainAppSelector(state => state.fishingActivities.fishingActivitiesShowedOnMap) + const redrawFishingActivitiesOnMap = useMainAppSelector(state => state.fishingActivities.redrawFishingActivitiesOnMap) + const doNotAnimate = useMainAppSelector(state => state.map.doNotAnimate) const previousHighlightedVesselTrackPosition = usePrevious(highlightedVesselTrackPosition) const previousFishingActivitiesShowedOnMap: FishingActivityShowedOnMap[] | undefined = diff --git a/frontend/src/features/map/overlays/VesselCardOverlay/VesselCard.tsx b/frontend/src/features/map/overlays/VesselCardOverlay/VesselCard.tsx index 3e2c622013..6d0a5281c3 100644 --- a/frontend/src/features/map/overlays/VesselCardOverlay/VesselCard.tsx +++ b/frontend/src/features/map/overlays/VesselCardOverlay/VesselCard.tsx @@ -20,7 +20,7 @@ timeago.register('fr', timeagoFrenchLocale) export function VesselCard({ feature, numberOfWarnings, overlayPosition }) { const isSuperUser = useIsSuperUser() - const { coordinatesFormat } = useMainAppSelector(state => state.map) + const coordinatesFormat = useMainAppSelector(state => state.map.coordinatesFormat) const { vesselProperties } = feature const featureCoordinates = feature.getGeometry().getCoordinates() diff --git a/frontend/src/utils.js b/frontend/src/utils.js index 4ea11f66c1..c9f5699474 100644 --- a/frontend/src/utils.js +++ b/frontend/src/utils.js @@ -1,7 +1,7 @@ import { createSlice } from '@reduxjs/toolkit' -import VectorSource from 'ol/source/Vector' import GeoJSON from 'ol/format/GeoJSON' import { all } from 'ol/loadingstrategy' +import VectorSource from 'ol/source/Vector' import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from './domain/entities/map/constants' @@ -11,22 +11,17 @@ import { OPENLAYERS_PROJECTION, WSG84_PROJECTION } from './domain/entities/map/c * @param {number[]} defaultColor * @returns */ -export const customHexToRGB = (hexColor) => { +export const customHexToRGB = hexColor => { if (!hexColor || !(typeof hexColor === 'string')) { return [0, 0, 0] } const aRgbHex = hexColor.substring(1).match(/.{1,2}/g) - const aRgb = [ - parseInt(aRgbHex[0], 16), - parseInt(aRgbHex[1], 16), - parseInt(aRgbHex[2], 16) - ] + const aRgb = [parseInt(aRgbHex[0], 16), parseInt(aRgbHex[1], 16), parseInt(aRgbHex[2], 16)] + return aRgb } -export const booleanToInt = (boolean) => { - return boolean ? 1 : 0 -} +export const booleanToInt = boolean => (boolean ? 1 : 0) export const calculatePointsDistance = (coord1, coord2) => { const dx = coord1[0] - coord2[0] const dy = coord1[1] - coord2[1] @@ -42,19 +37,22 @@ export const calculateSplitPointCoordinates = (startNode, nextNode, distanceBetw return [x, y] } -function getMonth (date) { +function getMonth(date) { const month = date.getUTCMonth() + 1 - return month < 10 ? '0' + month : '' + month + + return month < 10 ? `0${month}` : `${month}` } -function getDay (date) { +function getDay(date) { const day = date.getUTCDate() - return day < 10 ? '0' + day : '' + day + + return day < 10 ? `0${day}` : `${day}` } export const getDate = dateString => { if (dateString) { const date = new Date(dateString) + return `${getDay(date)}/${getMonth(date)}/${date.getUTCFullYear()}` } @@ -66,16 +64,16 @@ export const getTime = (dateString, withoutSeconds) => { const timeOptions = withoutSeconds ? { hour: '2-digit', + hourCycle: 'h24', minute: '2-digit', - timeZone: 'UTC', - hourCycle: 'h24' + timeZone: 'UTC' } : { hour: '2-digit', + hourCycle: 'h24', minute: '2-digit', second: '2-digit', - timeZone: 'UTC', - hourCycle: 'h24' + timeZone: 'UTC' } let time = date.toLocaleTimeString([], timeOptions) @@ -100,7 +98,7 @@ export const getDateTime = (dateString, withoutSeconds) => { * @param {Number} nofMonths no of months to get date before * @returns {Date} date before nofMonths months */ -export function getDateMonthsBefore (date, nofMonths) { +export function getDateMonthsBefore(date, nofMonths) { const thisMonth = date.getMonth() // set the month index of the date by subtracting nofMonths from the current month index date.setMonth(thisMonth - nofMonths) @@ -110,9 +108,9 @@ export function getDateMonthsBefore (date, nofMonths) { // if the result of subtraction is negative and add 6 to the index and check if JS has auto advanced the date, // then set the date again to last day of previous month // Else check if the result of subtraction is non negative, subtract nofMonths to the index and check the same. - if ((thisMonth - nofMonths < 0) && (date.getMonth() !== (thisMonth + nofMonths))) { + if (thisMonth - nofMonths < 0 && date.getMonth() !== thisMonth + nofMonths) { date.setDate(0) - } else if ((thisMonth - nofMonths >= 0) && (date.getMonth() !== thisMonth - nofMonths)) { + } else if (thisMonth - nofMonths >= 0 && date.getMonth() !== thisMonth - nofMonths) { date.setDate(0) } @@ -130,9 +128,8 @@ export const getTextWidth = text => { export const getLocalStorageState = (defaultValue, key) => { const stickyValue = window.localStorage.getItem(key) - return stickyValue !== null - ? JSON.parse(stickyValue) - : defaultValue + + return stickyValue !== null ? JSON.parse(stickyValue) : defaultValue } const SECONDS = 60 @@ -151,8 +148,7 @@ export const timeagoFrenchLocale = function (number, index, totalSec) { if (index === 6 || index === 7) { // Calculate seconds since midnight for right now const now = new Date() - const secondsSinceMidnight = - now.getSeconds() + (now.getMinutes() * SECONDS) + (now.getHours() * MINUTES * SECONDS) + const secondsSinceMidnight = now.getSeconds() + now.getMinutes() * SECONDS + now.getHours() * MINUTES * SECONDS // Subtract seconds since midnight from totalSec, divide by seconds in a day, round down // Result is off-by-one number of days since datetime (unless time was at midnight) @@ -162,6 +158,7 @@ export const timeagoFrenchLocale = function (number, index, totalSec) { const remainder = (totalSec - secondsSinceMidnight) % SECONDS_IN_DAY const days = remainder >= 1 ? daysFloored + 1 : daysFloored const noun = days === 1 ? 'jour' : 'jours' + return [`il y a ${days} ${noun}`, `${days} ${noun}`] } @@ -170,9 +167,7 @@ export const timeagoFrenchLocale = function (number, index, totalSec) { if (index === 8) { const days = Math.round(totalSec / SECONDS / MINUTES / HOURS) if (days > 8) { - return days === 13 - ? ['il y a 2 semaines', '2 semaines'] - : ['il y a %s jours', '%s jours'] + return days === 13 ? ['il y a 2 semaines', '2 semaines'] : ['il y a %s jours', '%s jours'] } } @@ -181,13 +176,13 @@ export const timeagoFrenchLocale = function (number, index, totalSec) { const days = Math.round(totalSec / SECONDS / MINUTES / HOURS) if (days <= 62) { return [`il y a ${days} jours`, `${days} jours`] - } else { - return ['il y a %s mois', '%s mois'] } + + return ['il y a %s mois', '%s mois'] } return [ - ['à l\'instant', 'un instant'], + ["à l'instant", 'un instant'], ['il y a %s secondes', '%s secondes'], ['il y a 1 minute', '1 minute'], ['il y a %s minutes', '%s minutes'], @@ -206,18 +201,18 @@ export const timeagoFrenchLocale = function (number, index, totalSec) { const accentsMap = { a: 'á|à|ã|â|À|Á|Ã|Â', + c: 'ç|Ç', e: 'é|è|ê|É|È|Ê', i: 'í|ì|î|Í|Ì|Î', + n: 'ñ|Ñ', o: 'ó|ò|ô|õ|Ó|Ò|Ô|Õ', - u: 'ú|ù|û|ü|Ú|Ù|Û|Ü', - c: 'ç|Ç', - n: 'ñ|Ñ' + u: 'ú|ù|û|ü|Ú|Ù|Û|Ü' } -export const removeAccents = text => Object.keys(accentsMap) - .reduce((acc, cur) => acc.toString().replace(new RegExp(accentsMap[cur], 'g'), cur), text) +export const removeAccents = text => + Object.keys(accentsMap).reduce((acc, cur) => acc.toString().replace(new RegExp(accentsMap[cur], 'g'), cur), text) -export function getTextForSearch (text) { +export function getTextForSearch(text) { if (!text) { return '' } @@ -231,18 +226,19 @@ export function getTextForSearch (text) { .replace(/["]/g, '') } -export function getNauticalMilesFromMeters (length) { +export function getNauticalMilesFromMeters(length) { return Math.round((length / 1000) * 100 * 0.539957) / 100 } -export function createGenericSlice (initialState, reducers, topic) { - const initialStateCopy = Object.assign({}, initialState) - const reducersCopy = Object.assign({}, reducers) +export function createGenericSlice(initialState, reducers, topic) { + const initialStateCopy = { ...initialState } + const reducersCopy = { ...reducers } const sliceObject = { - name: topic, initialState: initialStateCopy, + name: topic, reducers: reducersCopy } + return createSlice(sliceObject) } @@ -256,12 +252,10 @@ export function createGenericSlice (initialState, reducers, topic) { /** * @param {string} element * @return {SelectPickerObject} */ -const item = (e) => { - return { - label: e, - value: e - } -} +const item = e => ({ + label: e, + value: e +}) /** * @function convert a list of elements to a list of object : @@ -272,16 +266,18 @@ const item = (e) => { */ export const formatDataForSelectPicker = (list, groupName) => { if (list?.length > 0) { - const array = [...list] - .map(e => { - const i = item(e) - if (groupName) { - i.group = groupName - } - return i - }) + const array = [...list].map(e => { + const i = item(e) + if (groupName) { + i.group = groupName + } + + return i + }) + return array } + return [] } @@ -315,11 +311,13 @@ export const getExtentFromGeoJSON = features => { * @param {Object} objectTwo - Second object * @return {Object} The merged object */ -export function mergeObjects (objectOne, objectTwo) { +export function mergeObjects(objectOne, objectTwo) { const mergedObject = {} for (const key of Object.keys(objectOne)) { - if (!mergedObject[key]) mergedObject[key] = [] + if (!mergedObject[key]) { + mergedObject[key] = [] + } for (const innerKey of objectOne[key]) { mergedObject[key].push(innerKey) @@ -327,7 +325,9 @@ export function mergeObjects (objectOne, objectTwo) { } for (const key of Object.keys(objectTwo)) { - if (!mergedObject[key]) mergedObject[key] = [] + if (!mergedObject[key]) { + mergedObject[key] = [] + } for (const innerKey of objectTwo[key]) { mergedObject[key].push(innerKey) diff --git a/frontend/src/workers/MonitorFishWebWorker.js b/frontend/src/workers/MonitorFishWebWorker.js index 9ee42c2b00..84f37d4f81 100644 --- a/frontend/src/workers/MonitorFishWebWorker.js +++ b/frontend/src/workers/MonitorFishWebWorker.js @@ -1,4 +1,6 @@ import * as Comlink from 'comlink' + +import { VesselLocation, vesselSize } from '../domain/entities/vessel/vessel' import { FRANCE, getRegulatoryLawTypesFromZones, @@ -6,32 +8,25 @@ import { mapToRegulatoryZone } from '../features/Regulation/utils' import { getDateMonthsBefore } from '../utils' -import { VesselLocation, vesselSize } from '../domain/entities/vessel/vessel' class MonitorFishWebWorker { getStructuredRegulationLawTypes = regulatoryZones => getRegulatoryLawTypesFromZones(regulatoryZones) #getLayerTopicList = (features, speciesByCode) => { - const featuresWithoutGeometry = features.features.map(feature => { - return mapToRegulatoryZone(feature, speciesByCode) - }) + const featuresWithoutGeometry = features.features.map(feature => mapToRegulatoryZone(feature, speciesByCode)) const uniqueFeaturesWithoutGeometry = featuresWithoutGeometry.reduce((acc, current) => { - const found = acc.find(item => - item.topic === current.topic && - item.zone === current.zone) + const found = acc.find(item => item.topic === current.topic && item.zone === current.zone) if (!found) { return acc.concat([current]) - } else { - return acc } + + return acc }, []) const uniqueFeaturesWithoutGeometryByTopics = uniqueFeaturesWithoutGeometry .map(layer => layer.topic) - .map(topic => { - return uniqueFeaturesWithoutGeometry.filter(layer => layer.topic === topic) - }) + .map(topic => uniqueFeaturesWithoutGeometry.filter(layer => layer.topic === topic)) return { featuresWithoutGeometry, @@ -42,15 +37,14 @@ class MonitorFishWebWorker { mapGeoserverToRegulatoryZones = (geoJSON, speciesByCode) => geoJSON.features.map(feature => mapToRegulatoryZone(feature, speciesByCode)) - #getGeometryIdFromFeatureId = feature => { - return feature.properties?.id || feature.id.split('.')[1] - } + #getGeometryIdFromFeatureId = feature => feature.properties?.id || feature.id.split('.')[1] - getIdToGeometryObject (features) { + getIdToGeometryObject(features) { const geometryListAsObject = {} features.features.forEach(feature => { geometryListAsObject[this.#getGeometryIdFromFeatureId(feature)] = feature.geometry }) + return geometryListAsObject } @@ -107,18 +101,15 @@ class MonitorFishWebWorker { * } * } */ - convertGeoJSONFeaturesToStructuredRegulatoryObject (features, speciesByCode) { + convertGeoJSONFeaturesToStructuredRegulatoryObject(features, speciesByCode) { const regulatoryTopicList = new Set() - const { - featuresWithoutGeometry, - uniqueFeaturesWithoutGeometryByTopics: layerTopicArray - } = this.#getLayerTopicList(features, speciesByCode) + const { featuresWithoutGeometry, uniqueFeaturesWithoutGeometryByTopics: layerTopicArray } = this.#getLayerTopicList( + features, + speciesByCode + ) const layersTopicsByRegulatoryTerritory = layerTopicArray.reduce((accumulatedObject, zone) => { - const { - lawType, - topic - } = zone[0] + const { lawType, topic } = zone[0] if (topic && lawType) { regulatoryTopicList.add(topic) @@ -132,11 +123,12 @@ class MonitorFishWebWorker { } let orderZoneList = zone if (zone.length > 1) { - orderZoneList = zone.sort((a, b) => a.zone > b.zone ? 1 : a.zone === b.zone ? 0 : -1) + orderZoneList = zone.sort((a, b) => (a.zone > b.zone ? 1 : a.zone === b.zone ? 0 : -1)) } accumulatedObject[regulatoryTerritory][lawType][topic] = orderZoneList } } + return accumulatedObject }, {}) @@ -156,7 +148,7 @@ class MonitorFishWebWorker { } } - getUniqueSpeciesAndDistricts (vessels) { + getUniqueSpeciesAndDistricts(vessels) { const species = vessels .map(vessel => vessel.speciesOnboard) .flat() @@ -170,40 +162,40 @@ class MonitorFishWebWorker { .filter(_species => _species) const districts = vessels - .map(vessel => { - return { - district: vessel.district, - districtCode: vessel.districtCode - } - }) + .map(vessel => ({ + district: vessel.district, + districtCode: vessel.districtCode + })) .reduce((acc, district) => { const found = acc.find(item => item.district === district.district) if (!found) { return acc.concat([district]) - } else { - return acc } + + return acc }, []) - return { species, districts } + return { districts, species } } - getFilteredVessels (vessels, filters) { + getFilteredVessels(vessels, filters) { const { countriesFiltered, - lastPositionTimeAgoFilter, + districtsFiltered, fleetSegmentsFiltered, gearsFiltered, - districtsFiltered, - speciesFiltered, - vesselsSizeValuesChecked, lastControlMonthsAgo, - vesselsLocationFilter + lastPositionTimeAgoFilter, + speciesFiltered, + vesselsLocationFilter, + vesselsSizeValuesChecked } = filters if (countriesFiltered?.length) { - vessels = vessels.filter(vessel => countriesFiltered.some(country => vessel.vesselProperties?.flagState === country)) + vessels = vessels.filter(vessel => + countriesFiltered.some(country => vessel.vesselProperties?.flagState === country) + ) } if (lastPositionTimeAgoFilter) { @@ -233,36 +225,30 @@ class MonitorFishWebWorker { if (fleetSegmentsFiltered?.length) { vessels = vessels.filter(vessel => - fleetSegmentsFiltered.some(fleetSegment => { - return vessel.vesselProperties?.fleetSegmentsArray.includes(fleetSegment) - })) + fleetSegmentsFiltered.some(fleetSegment => vessel.vesselProperties?.fleetSegmentsArray.includes(fleetSegment)) + ) } if (gearsFiltered?.length) { - vessels = vessels.filter(vessel => - gearsFiltered.some(gear => { - return vessel.vesselProperties?.gearsArray.includes(gear) - })) + vessels = vessels.filter(vessel => gearsFiltered.some(gear => vessel.vesselProperties?.gearsArray.includes(gear))) } if (speciesFiltered?.length) { vessels = vessels.filter(vessel => - speciesFiltered.some(species => { - return vessel.vesselProperties?.speciesArray.includes(species) - })) + speciesFiltered.some(species => vessel.vesselProperties?.speciesArray.includes(species)) + ) } if (districtsFiltered?.length) { vessels = vessels.filter(vessel => - districtsFiltered.some(district => { - return vessel.vesselProperties?.district === district - })) + districtsFiltered.some(district => vessel.vesselProperties?.district === district) + ) } if (vesselsSizeValuesChecked?.length) { - vessels = vessels.filter(vessel => { - return this.evaluateVesselsSize(vesselsSizeValuesChecked, vessel.vesselProperties?.length) - }) + vessels = vessels.filter(vessel => + this.evaluateVesselsSize(vesselsSizeValuesChecked, vessel.vesselProperties?.length) + ) } if (vesselsLocationFilter?.length === 1) { @@ -278,23 +264,29 @@ class MonitorFishWebWorker { return vessels } - evaluateVesselsSize (vesselsSizeValuesChecked, length) { + evaluateVesselsSize(vesselsSizeValuesChecked, length) { if (vesselsSizeValuesChecked.length === 3) { return true } - if (vesselsSizeValuesChecked.includes(vesselSize.BELOW_TEN_METERS.code) && - vesselsSizeValuesChecked.includes(vesselSize.ABOVE_TWELVE_METERS.code)) { + if ( + vesselsSizeValuesChecked.includes(vesselSize.BELOW_TEN_METERS.code) && + vesselsSizeValuesChecked.includes(vesselSize.ABOVE_TWELVE_METERS.code) + ) { return vesselSize.BELOW_TEN_METERS.evaluate(length) || vesselSize.ABOVE_TWELVE_METERS.evaluate(length) } - if (vesselsSizeValuesChecked.includes(vesselSize.BELOW_TEN_METERS.code) && - vesselsSizeValuesChecked.includes(vesselSize.BELOW_TWELVE_METERS.code)) { + if ( + vesselsSizeValuesChecked.includes(vesselSize.BELOW_TEN_METERS.code) && + vesselsSizeValuesChecked.includes(vesselSize.BELOW_TWELVE_METERS.code) + ) { return vesselSize.BELOW_TWELVE_METERS.evaluate(length) } - if (vesselsSizeValuesChecked.includes(vesselSize.BELOW_TWELVE_METERS.code) && - vesselsSizeValuesChecked.includes(vesselSize.ABOVE_TWELVE_METERS.code)) { + if ( + vesselsSizeValuesChecked.includes(vesselSize.BELOW_TWELVE_METERS.code) && + vesselsSizeValuesChecked.includes(vesselSize.ABOVE_TWELVE_METERS.code) + ) { return true } diff --git a/frontend/src/workers/MonitorFishWorker.js b/frontend/src/workers/MonitorFishWorker.js index d117867ef2..d9dd0bdfc4 100644 --- a/frontend/src/workers/MonitorFishWorker.js +++ b/frontend/src/workers/MonitorFishWorker.js @@ -1,4 +1,5 @@ import * as Comlink from 'comlink' + import Worker from './MonitorFishWebWorker?worker' const worker = new Worker()