From 2b2d22c36e10ad628a03ce99af8939effd568ff7 Mon Sep 17 00:00:00 2001 From: Ivan Gabriele Date: Fri, 16 Feb 2024 00:52:27 +0100 Subject: [PATCH] Merge MainApp feature slice into MissionForm component one --- .../domain/use_cases/map/clickOnMapFeature.ts | 6 +-- frontend/src/features/MainMap/slice.ts | 51 ------------------- .../Mission/components/MissionForm/slice.ts | 36 ++++++++++++- .../SelectedMissionActionsLayer/index.tsx | 2 +- .../layers/Mission/SelectedMissionLayer.tsx | 4 +- .../ControlOverlay/ControlDetails.tsx | 10 ++-- .../map/overlays/ControlOverlay/index.tsx | 2 +- .../MissionOverlay/MissionDetails.tsx | 8 +-- .../map/overlays/MissionOverlay/index.tsx | 2 +- .../overlays/SelectedControlOverlay/index.tsx | 2 +- .../overlays/SelectedMissionOverlay/index.tsx | 2 +- frontend/src/store/reducers.ts | 2 - 12 files changed, 54 insertions(+), 73 deletions(-) delete mode 100644 frontend/src/features/MainMap/slice.ts diff --git a/frontend/src/domain/use_cases/map/clickOnMapFeature.ts b/frontend/src/domain/use_cases/map/clickOnMapFeature.ts index 11c14bbb58..1c172903a3 100644 --- a/frontend/src/domain/use_cases/map/clickOnMapFeature.ts +++ b/frontend/src/domain/use_cases/map/clickOnMapFeature.ts @@ -1,6 +1,6 @@ import GeoJSON from 'ol/format/GeoJSON' -import { mainMapActions } from '../../../features/MainMap/slice' +import { missionFormActions } from '../../../features/Mission/components/MissionForm/slice' import { showRegulatoryZoneMetadata } from '../../../features/Regulation/useCases/showRegulatoryZoneMetadata' import { stationActions } from '../../../features/Station/slice' import { FeatureWithCodeAndEntityId } from '../../../libs/FeatureWithCodeAndEntityId' @@ -45,7 +45,7 @@ export const clickOnMapFeature = const featureGeoJSON = geoJSONParser.writeFeatureObject(mapClick.feature as Feature, { featureProjection: OPENLAYERS_PROJECTION }) - dispatch(mainMapActions.setSelectedMissionGeoJSON(featureGeoJSON)) + dispatch(missionFormActions.setSelectedMissionGeoJSON(featureGeoJSON)) return } @@ -57,7 +57,7 @@ export const clickOnMapFeature = const featureGeoJSON = geoJSONParser.writeFeatureObject(mapClick.feature as Feature, { featureProjection: OPENLAYERS_PROJECTION }) - dispatch(mainMapActions.setSelectedMissionActionGeoJSON(featureGeoJSON)) + dispatch(missionFormActions.setSelectedMissionActionGeoJSON(featureGeoJSON)) return } diff --git a/frontend/src/features/MainMap/slice.ts b/frontend/src/features/MainMap/slice.ts deleted file mode 100644 index ce05ef444f..0000000000 --- a/frontend/src/features/MainMap/slice.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit' - -import type { GeoJSON } from '../../domain/types/GeoJSON' -import type { PayloadAction } from '@reduxjs/toolkit' - -export interface MainMapState { - selectedMissionActionGeoJSON: GeoJSON.GeoJson | undefined - selectedMissionGeoJSON: GeoJSON.GeoJson | undefined -} -const INITIAL_STATE: MainMapState = { - selectedMissionActionGeoJSON: undefined, - selectedMissionGeoJSON: undefined -} - -const mainMapSlice = createSlice({ - initialState: INITIAL_STATE, - name: 'mission', - reducers: { - /** - * Set selected mission action GeoJSON - */ - setSelectedMissionActionGeoJSON(state, action: PayloadAction) { - state.selectedMissionActionGeoJSON = action.payload - }, - - /** - * Set selected mission GeoJSON - */ - setSelectedMissionGeoJSON(state, action: PayloadAction) { - state.selectedMissionGeoJSON = action.payload - }, - - /** - * Unset selected mission action GeoJSON - */ - unsetSelectedMissionActionGeoJSON(state) { - state.selectedMissionActionGeoJSON = undefined - }, - - /** - * Unset selected mission ID - */ - unsetSelectedMissionGeoJSON(state) { - state.selectedMissionGeoJSON = undefined - state.selectedMissionActionGeoJSON = undefined - } - } -}) - -export const mainMapActions = mainMapSlice.actions -export const mainMapReducer = mainMapSlice.reducer diff --git a/frontend/src/features/Mission/components/MissionForm/slice.ts b/frontend/src/features/Mission/components/MissionForm/slice.ts index 4e898d1881..d65b331c61 100644 --- a/frontend/src/features/Mission/components/MissionForm/slice.ts +++ b/frontend/src/features/Mission/components/MissionForm/slice.ts @@ -4,6 +4,7 @@ import { isEqual } from 'lodash/fp' import type { MissionMainFormValues } from './types' import type { MissionWithActionsDraft } from '../../types' import type { PayloadAction } from '@reduxjs/toolkit' +import type { GeoJSON } from 'domain/types/GeoJSON' export interface MissionFormState { // TODO For side window closure prevention and cross-form validation we don't need the entire forms values. @@ -20,6 +21,8 @@ export interface MissionFormState { isDraftDirty: boolean isListeningToEvents: boolean mustResetOtherControlsCheckboxes: boolean | undefined + selectedMissionActionGeoJSON: GeoJSON.GeoJson | undefined + selectedMissionGeoJSON: GeoJSON.GeoJson | undefined } const INITIAL_STATE: MissionFormState = { draft: undefined, @@ -27,7 +30,9 @@ const INITIAL_STATE: MissionFormState = { isClosing: false, isDraftDirty: false, isListeningToEvents: true, - mustResetOtherControlsCheckboxes: undefined + mustResetOtherControlsCheckboxes: undefined, + selectedMissionActionGeoJSON: undefined, + selectedMissionGeoJSON: undefined } const missionFormSlice = createSlice({ @@ -94,12 +99,41 @@ const missionFormSlice = createSlice({ state.isListeningToEvents = action.payload }, + /** + * Set selected mission action GeoJSON. + */ + setSelectedMissionActionGeoJSON(state, action: PayloadAction) { + state.selectedMissionActionGeoJSON = action.payload + }, + + /** + * Set selected mission GeoJSON. + */ + setSelectedMissionGeoJSON(state, action: PayloadAction) { + state.selectedMissionGeoJSON = action.payload + }, + /** * Unset geometry computed from controls to permit another modification of the mission's geometry * after adding another control to a mission. */ unsetGeometryComputedFromControls(state) { state.geometryComputedFromControls = undefined + }, + + /** + * Unset selected mission action GeoJSON. + */ + unsetSelectedMissionActionGeoJSON(state) { + state.selectedMissionActionGeoJSON = undefined + }, + + /** + * Unset selected mission ID. + */ + unsetSelectedMissionGeoJSON(state) { + state.selectedMissionGeoJSON = undefined + state.selectedMissionActionGeoJSON = undefined } } }) diff --git a/frontend/src/features/map/layers/Mission/SelectedMissionActionsLayer/index.tsx b/frontend/src/features/map/layers/Mission/SelectedMissionActionsLayer/index.tsx index d99244a47d..8bfebf4054 100644 --- a/frontend/src/features/map/layers/Mission/SelectedMissionActionsLayer/index.tsx +++ b/frontend/src/features/map/layers/Mission/SelectedMissionActionsLayer/index.tsx @@ -18,7 +18,7 @@ import type { MutableRefObject } from 'react' export function UnmemoizedSelectedMissionActionsLayer() { const { missions } = useGetFilteredMissionsQuery() - const selectedMissionGeoJSON = useMainAppSelector(store => store.mainMap.selectedMissionGeoJSON) + const selectedMissionGeoJSON = useMainAppSelector(store => store.missionForm.selectedMissionGeoJSON) const missionId = useMainAppSelector(store => store.sideWindow.selectedPath.id) const draft = useMainAppSelector(store => store.missionForm.draft) diff --git a/frontend/src/features/map/layers/Mission/SelectedMissionLayer.tsx b/frontend/src/features/map/layers/Mission/SelectedMissionLayer.tsx index c169551a39..09e56e5b37 100644 --- a/frontend/src/features/map/layers/Mission/SelectedMissionLayer.tsx +++ b/frontend/src/features/map/layers/Mission/SelectedMissionLayer.tsx @@ -17,7 +17,7 @@ import type { VectorLayerWithName } from '../../../../domain/types/layer' export function UnmemoizedSelectedMissionLayer() { const { missions } = useGetFilteredMissionsQuery() - const selectedMissionGeoJSON = useMainAppSelector(store => store.mainMap.selectedMissionGeoJSON) + const selectedMissionGeoJSON = useMainAppSelector(store => store.missionForm.selectedMissionGeoJSON) const missionId = useMainAppSelector(store => store.sideWindow.selectedPath.id) const draft = useMainAppSelector(store => store.missionForm.draft) @@ -97,7 +97,7 @@ export function UnmemoizedSelectedMissionLayer() { } // When creating a new mission, dummy NEW_MISSION_ID is used - const missionFeature = getMissionFeatureZone({ ...draft.mainFormValues, id: missionId || NEW_MISSION_ID }) + const missionFeature = getMissionFeatureZone({ ...draft.mainFormValues, id: missionId ?? NEW_MISSION_ID }) getVectorSource().addFeature(missionFeature) }, [getVectorSource, draft?.mainFormValues, missionId]) diff --git a/frontend/src/features/map/overlays/ControlOverlay/ControlDetails.tsx b/frontend/src/features/map/overlays/ControlOverlay/ControlDetails.tsx index ccb7669732..c0f6a6e7c0 100644 --- a/frontend/src/features/map/overlays/ControlOverlay/ControlDetails.tsx +++ b/frontend/src/features/map/overlays/ControlOverlay/ControlDetails.tsx @@ -7,17 +7,17 @@ import { margins } from './constants' import { useMainAppDispatch } from '../../../../hooks/useMainAppDispatch' import { pluralize } from '../../../../utils/pluralize' import { GreenCircle, RedCircle } from '../../../commonStyles/Circle.style' -import { mainMapActions } from '../../../MainMap/slice' +import { missionFormActions } from '../../../Mission/components/MissionForm/slice' import { Flag } from '../../../VesselList/tableCells' import { OverlayPosition } from '../Overlay' import type { Mission } from '../../../../domain/entities/mission/types' -type ControlDetailsProps = { +type ControlDetailsProps = Readonly<{ control: Mission.MissionActionFeatureProperties isSelected: boolean overlayPosition: OverlayPosition -} +}> export function ControlDetails({ control, isSelected, overlayPosition }: ControlDetailsProps) { const dispatch = useMainAppDispatch() @@ -67,12 +67,12 @@ export function ControlDetails({ control, isSelected, overlayPosition }: Control data-cy="mission-action-overlay-close" Icon={Icon.Close} iconSize={14} - onClick={() => dispatch(mainMapActions.unsetSelectedMissionActionGeoJSON())} + onClick={() => dispatch(missionFormActions.unsetSelectedMissionActionGeoJSON())} /> )} - ContrĂ´le du navire {control.vesselName || 'NOM INCONNU'} + ContrĂ´le du navire {control.vesselName ?? 'NOM INCONNU'} {control.flagState && ( <Flag rel="preload" diff --git a/frontend/src/features/map/overlays/ControlOverlay/index.tsx b/frontend/src/features/map/overlays/ControlOverlay/index.tsx index 130546a0c7..31cec4a57e 100644 --- a/frontend/src/features/map/overlays/ControlOverlay/index.tsx +++ b/frontend/src/features/map/overlays/ControlOverlay/index.tsx @@ -19,7 +19,7 @@ const overlayHeight = 130 const INITIAL_OFFSET_VALUE = [0, 0] export function ControlOverlay({ feature, isSelected = false }) { - const selectedMissionActionGeoJSON = useMainAppSelector(store => store.mainMap.selectedMissionActionGeoJSON) + const selectedMissionActionGeoJSON = useMainAppSelector(store => store.missionForm.selectedMissionActionGeoJSON) const currentOffsetRef = useRef(INITIAL_OFFSET_VALUE) const [controlProperties, setControlProperties] = useState<Mission.MissionActionFeatureProperties | undefined>( undefined diff --git a/frontend/src/features/map/overlays/MissionOverlay/MissionDetails.tsx b/frontend/src/features/map/overlays/MissionOverlay/MissionDetails.tsx index f8a309a065..5c7f45e743 100644 --- a/frontend/src/features/map/overlays/MissionOverlay/MissionDetails.tsx +++ b/frontend/src/features/map/overlays/MissionOverlay/MissionDetails.tsx @@ -8,17 +8,17 @@ import { getMissionSourceTagText } from '../../../../domain/entities/mission' import { Mission } from '../../../../domain/entities/mission/types' import { useMainAppDispatch } from '../../../../hooks/useMainAppDispatch' import { pluralize } from '../../../../utils/pluralize' -import { mainMapActions } from '../../../MainMap/slice' +import { missionFormActions } from '../../../Mission/components/MissionForm/slice' import { editMission } from '../../../Mission/useCases/editMission' import { OverlayPosition } from '../Overlay' import type { LegacyControlUnit } from '../../../../domain/types/legacyControlUnit' -type MissionDetailsProps = { +type MissionDetailsProps = Readonly<{ isSelected: boolean mission: Mission.MissionPointFeatureProperties overlayPosition: OverlayPosition -} +}> export function MissionDetails({ isSelected, mission, overlayPosition }: MissionDetailsProps) { const dispatch = useMainAppDispatch() @@ -35,7 +35,7 @@ export function MissionDetails({ isSelected, mission, overlayPosition }: Mission data-cy="mission-overlay-close" Icon={Icon.Close} iconSize={14} - onClick={() => dispatch(mainMapActions.unsetSelectedMissionGeoJSON())} + onClick={() => dispatch(missionFormActions.unsetSelectedMissionGeoJSON())} /> )} <ZoneText> diff --git a/frontend/src/features/map/overlays/MissionOverlay/index.tsx b/frontend/src/features/map/overlays/MissionOverlay/index.tsx index 753558aaad..bf2e4755e9 100644 --- a/frontend/src/features/map/overlays/MissionOverlay/index.tsx +++ b/frontend/src/features/map/overlays/MissionOverlay/index.tsx @@ -19,7 +19,7 @@ const overlayHeight = 200 const INITIAL_OFFSET_VALUE = [0, 0] export function MissionOverlay({ feature, isSelected = false }) { - const selectedMissionGeoJSON = useMainAppSelector(store => store.mainMap.selectedMissionGeoJSON) + const selectedMissionGeoJSON = useMainAppSelector(store => store.missionForm.selectedMissionGeoJSON) const currentOffsetRef = useRef(INITIAL_OFFSET_VALUE) const [missionProperties, setMissionProperties] = useState<Mission.MissionPointFeatureProperties | undefined>( undefined diff --git a/frontend/src/features/map/overlays/SelectedControlOverlay/index.tsx b/frontend/src/features/map/overlays/SelectedControlOverlay/index.tsx index 2738123bf0..5aab240c5e 100644 --- a/frontend/src/features/map/overlays/SelectedControlOverlay/index.tsx +++ b/frontend/src/features/map/overlays/SelectedControlOverlay/index.tsx @@ -6,7 +6,7 @@ import { useMainAppSelector } from '../../../../hooks/useMainAppSelector' import { ControlOverlay } from '../ControlOverlay' export function SelectedControlOverlay() { - const selectedControlGeoJSON = useMainAppSelector(store => store.mainMap.selectedMissionActionGeoJSON) + const selectedControlGeoJSON = useMainAppSelector(store => store.missionForm.selectedMissionActionGeoJSON) const selectedControl = useMemo(() => { if (!selectedControlGeoJSON) { return undefined diff --git a/frontend/src/features/map/overlays/SelectedMissionOverlay/index.tsx b/frontend/src/features/map/overlays/SelectedMissionOverlay/index.tsx index b305416dbb..331ec9ba78 100644 --- a/frontend/src/features/map/overlays/SelectedMissionOverlay/index.tsx +++ b/frontend/src/features/map/overlays/SelectedMissionOverlay/index.tsx @@ -6,7 +6,7 @@ import { useMainAppSelector } from '../../../../hooks/useMainAppSelector' import { MissionOverlay } from '../MissionOverlay' export function SelectedMissionOverlay() { - const selectedMissionGeoJSON = useMainAppSelector(store => store.mainMap.selectedMissionGeoJSON) + const selectedMissionGeoJSON = useMainAppSelector(store => store.missionForm.selectedMissionGeoJSON) const isMissionsLayerDisplayed = useMainAppSelector(store => store.displayedComponent.isMissionsLayerDisplayed) const selectedMission = useMemo(() => { diff --git a/frontend/src/store/reducers.ts b/frontend/src/store/reducers.ts index 054c07309a..55ecc8da12 100644 --- a/frontend/src/store/reducers.ts +++ b/frontend/src/store/reducers.ts @@ -25,7 +25,6 @@ import { controlUnitDialogReducer } from '../features/ControlUnit/components/Con import { controlUnitListDialogPersistedReducer } from '../features/ControlUnit/components/ControlUnitListDialog/slice' import { customZoneReducer, type CustomZoneState } from '../features/CustomZone/slice' import { logbookReducer } from '../features/Logbook/slice' -import { mainMapReducer } from '../features/MainMap/slice' import { missionFormReducer } from '../features/Mission/components/MissionForm/slice' import { missionListReducer, type MissionListState } from '../features/Mission/components/MissionList/slice' import { regulatoryLayerSearchReducer } from '../features/Regulation/components/RegulationSearch/slice' @@ -83,7 +82,6 @@ export const mainReducer = { infraction: infractionReducer, interestPoint: interestPointReducer, layer: layer.homepage.reducer, - mainMap: mainMapReducer, measurement: measurementReducer, missionForm: missionFormReducer, missionList: persistReducerTyped(