diff --git a/backend/src/main/resources/db/testdata/V666.5__insert_dummy_missions.sql b/backend/src/main/resources/db/testdata/V666.5__insert_dummy_missions.sql
index 7454cbcc4..f72fbdd19 100644
--- a/backend/src/main/resources/db/testdata/V666.5__insert_dummy_missions.sql
+++ b/backend/src/main/resources/db/testdata/V666.5__insert_dummy_missions.sql
@@ -101,7 +101,6 @@ VALUES
( 40, 10003),
( 41, 10002),
( 42, 10003),
- ( 43, 10018),
( 44, 10003),
( 45, 10014),
( 46, 10018),
@@ -118,7 +117,8 @@ VALUES
( 34, 10016, 'M. Capitaine Flame'),
( 34, 10017, 'Popeye 06789012345'),
( 47, 10002, 'A Team - Gimme your number'),
- ( 25, 10002, 'Full contact');
+ ( 25, 10002, 'Full contact'),
+ ( 43, 10018, 'Full contact');
INSERT INTO missions_control_resources
(mission_id, control_resource_id)
diff --git a/frontend/cypress/e2e/side_window/mission/close_mission_validation.spec.ts b/frontend/cypress/e2e/side_window/mission/close_mission_validation.spec.ts
index d11e40546..1727c7940 100644
--- a/frontend/cypress/e2e/side_window/mission/close_mission_validation.spec.ts
+++ b/frontend/cypress/e2e/side_window/mission/close_mission_validation.spec.ts
@@ -7,7 +7,7 @@ context('Mission', () => {
it('A new mission with control and surveillance can be closed with all required values', () => {
// Given
cy.get('*[data-cy="add-mission"]').click()
- cy.clickButton(' Enregistrer et clôturer')
+ cy.clickButton('Enregistrer et clôturer')
cy.wait(100)
cy.get('*[data-cy="mission-errors"]').should('exist')
@@ -24,6 +24,7 @@ context('Mission', () => {
cy.fill('Type de mission', ['Air'])
cy.get('*[data-cy="add-control-unit"]').click()
cy.get('.rs-picker-search-bar-input').type('Cross{enter}')
+ cy.fill("Contact de l'unité 1", 'contact').scrollIntoView()
cy.fill('Ouvert par', 'PCF').scrollIntoView()
cy.fill('Clôturé par', 'PCF').scrollIntoView()
@@ -32,7 +33,7 @@ context('Mission', () => {
// we add a control
cy.clickButton('Ajouter')
cy.clickButton('Ajouter des contrôles')
- cy.clickButton(' Enregistrer et clôturer')
+ cy.clickButton('Enregistrer et clôturer')
cy.wait(100)
cy.get('*[data-cy="mission-errors"]').should('exist')
@@ -80,6 +81,8 @@ context('Mission', () => {
// delete theme to test error
cy.fill('Thématique de surveillance', '')
+ cy.clickButton('Enregistrer et clôturer')
+ cy.wait(100)
cy.get('*[data-cy="mission-errors"]').should('exist')
cy.fill('Thématique de surveillance', 'Rejets illicites')
diff --git a/frontend/cypress/e2e/side_window/mission/create_mission.spec.ts b/frontend/cypress/e2e/side_window/mission/create_mission.spec.ts
index 4a9dde27c..4d3f7f3d4 100644
--- a/frontend/cypress/e2e/side_window/mission/create_mission.spec.ts
+++ b/frontend/cypress/e2e/side_window/mission/create_mission.spec.ts
@@ -7,7 +7,6 @@ context('Mission', () => {
it('A mission should be created', () => {
// Given
cy.intercept('GET', '/bff/v1/missions*').as('getMissions')
- cy.wait('@getMissions')
cy.wait(400)
cy.get('*[data-cy="Missions-numberOfDisplayedMissions"]').then($el => {
const numberOfMissions = parseInt($el.text(), 10)
@@ -44,7 +43,7 @@ context('Mission', () => {
cy.get('[name="openBy"]').scrollIntoView().type('PCF')
cy.intercept('PUT', '/bff/v1/missions').as('createMission')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@createMission').then(({ request, response }) => {
@@ -72,7 +71,6 @@ context('Mission', () => {
it('A mission should be deleted', () => {
// Given
cy.intercept('GET', '/bff/v1/missions*').as('getMissions')
- cy.wait('@getMissions')
cy.wait(400)
cy.get('*[data-cy="Missions-numberOfDisplayedMissions"]').then($el => {
const numberOfMissions = parseInt($el.text(), 10)
@@ -111,7 +109,7 @@ context('Mission', () => {
cy.get('*[data-cy="reopen-mission"]').click()
cy.get('*[data-cy="control-unit-contact"]').type('Contact 012345')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@updateMission').then(({ response }) => {
@@ -125,14 +123,15 @@ context('Mission', () => {
// Given
cy.wait(200)
cy.get('*[data-cy="edit-mission-43"]').click({ force: true })
- cy.intercept('PUT', `/bff/v1/missions/43`).as('updateMission')
+ cy.intercept('PUT', '/bff/v1/missions/43').as('updateMission')
+ cy.fill("Contact de l'unité 1", '')
+ cy.wait(300)
cy.clickButton('Enregistrer et clôturer')
-
// Then
cy.wait('@updateMission').then(({ request, response }) => {
expect(response && response.statusCode).equal(200)
- expect(request.body.controlUnits[0].contact).equal(null)
+ expect(request.body.controlUnits[0].contact).equal(undefined)
})
cy.get('*[data-cy="SideWindowHeader-title"]').contains('Missions et contrôles')
})
diff --git a/frontend/cypress/e2e/side_window/mission/mission_actions.spec.ts b/frontend/cypress/e2e/side_window/mission/mission_actions.spec.ts
index 247e7219d..82071478d 100644
--- a/frontend/cypress/e2e/side_window/mission/mission_actions.spec.ts
+++ b/frontend/cypress/e2e/side_window/mission/mission_actions.spec.ts
@@ -20,7 +20,7 @@ context('Mission actions', () => {
cy.get('*[data-cy="duplicate-infraction"]').eq(1).should('be.disabled')
cy.intercept('PUT', `/bff/v1/missions/34`).as('updateMission')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@updateMission').then(({ request, response }) => {
@@ -70,7 +70,7 @@ context('Mission actions', () => {
cy.get('*[data-cy="envaction-add-theme"]').should('not.exist')
cy.intercept('PUT', `/bff/v1/missions/34`).as('updateMission')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@updateMission').then(({ request, response }) => {
@@ -100,7 +100,7 @@ context('Mission actions', () => {
})
cy.intercept('PUT', `/bff/v1/missions/34`).as('updateMission')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@updateMission').then(({ request, response }) => {
@@ -138,7 +138,7 @@ context('Mission actions', () => {
cy.get('*[data-cy="envaction-protected-species-selector"]').should('have.length', 0)
cy.intercept('PUT', `/bff/v1/missions/34`).as('updateMission')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@updateMission').then(({ response }) => {
diff --git a/frontend/cypress/e2e/side_window/mission/mission_dates_validation.spec.ts b/frontend/cypress/e2e/side_window/mission/mission_dates_validation.spec.ts
index 9da3bb198..bcc18038a 100644
--- a/frontend/cypress/e2e/side_window/mission/mission_dates_validation.spec.ts
+++ b/frontend/cypress/e2e/side_window/mission/mission_dates_validation.spec.ts
@@ -223,7 +223,7 @@ context('Mission dates', () => {
cy.fill('Equipement de sécurité et respect des normes', false)
cy.intercept('PUT', `/bff/v1/missions/41`).as('updateMission')
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
// Then
cy.wait('@updateMission').then(({ request, response }) => {
@@ -249,6 +249,6 @@ context('Mission dates', () => {
cy.fill('Respect du code de la navigation sur le plan d’eau', true)
cy.fill('Gens de mer', true)
cy.fill('Equipement de sécurité et respect des normes', true)
- cy.get('form').submit()
+ cy.clickButton('Enregistrer et quitter')
})
})
diff --git a/frontend/src/features/map/tools/measurements/CustomCircleRange.tsx b/frontend/src/features/map/tools/measurements/CustomCircleRange.tsx
index 3467ab0ed..33bb6aa16 100644
--- a/frontend/src/features/map/tools/measurements/CustomCircleRange.tsx
+++ b/frontend/src/features/map/tools/measurements/CustomCircleRange.tsx
@@ -88,8 +88,12 @@ export function CustomCircleRange() {
)
const addCustomCircleRange = useCallback(
- (nextCoordinates, nextCircleRadius) => {
- dispatch(
+ async (nextCoordinates, nextCircleRadius) => {
+ if (!nextCoordinates?.length || !nextCircleRadius?.length) {
+ return
+ }
+
+ await dispatch(
setCircleMeasurementToAdd({
circleCoordinatesToAdd: nextCoordinates,
circleRadiusToAdd: nextCircleRadius
@@ -100,6 +104,7 @@ export function CustomCircleRange() {
const extent = transformExtent(boundingExtent([formattedCoordinates]), WSG84_PROJECTION, OPENLAYERS_PROJECTION)
dispatch(setFitToExtent(extent))
dispatch(setMeasurementTypeToAdd(undefined))
+ dispatch(resetCircleMeasurementInDrawing())
},
[dispatch]
)
@@ -131,6 +136,7 @@ export function CustomCircleRange() {
addCustomCircleRange(circleCoordinates, circleRadius)}
>
OK
diff --git a/frontend/src/features/missions/MissionForm/MissionForm.tsx b/frontend/src/features/missions/MissionForm/MissionForm.tsx
index 53b54653e..361a46edd 100644
--- a/frontend/src/features/missions/MissionForm/MissionForm.tsx
+++ b/frontend/src/features/missions/MissionForm/MissionForm.tsx
@@ -25,11 +25,10 @@ import { useAppSelector } from '../../../hooks/useAppSelector'
import { sideWindowActions } from '../../SideWindow/slice'
import { missionFactory } from '../Missions.helpers'
-export function MissionForm({ id, isAlreadyClosed, isNewMission, selectedMission, setShouldValidateOnChange }) {
+export function MissionForm({ id, isNewMission, selectedMission, setShouldValidateOnChange }) {
const dispatch = useAppDispatch()
const { sideWindow } = useAppSelector(state => state)
- const { dirty, handleSubmit, setFieldValue, setValues, validateForm, values } =
- useFormikContext>()
+ const { dirty, setFieldValue, setValues, validateForm, values } = useFormikContext>()
useSyncFormValuesWithRedux()
useUpdateSurveillance()
@@ -75,17 +74,12 @@ export function MissionForm({ id, isAlreadyClosed, isNewMission, selectedMission
dispatch(sideWindowActions.setCurrentPath(generatePath(sideWindowPaths.MISSIONS)))
}
- const submitMission = async () => {
+ const submitMission = () => {
setShouldValidateOnChange(false)
- // If the mission is not already closed (from the API), we want the `isClosed` field to be set to false.
- // if the user has already tried to close the mission and the `isClosed` field is set to true.
- if (!isAlreadyClosed) {
- await setFieldValue('isClosed', false)
- }
- validateForm().then(errors => {
+ validateForm({ ...values, isClosed: false }).then(errors => {
if (_.isEmpty(errors)) {
- handleSubmit()
+ dispatch(saveMission({ ...values, isClosed: true }))
return
}
@@ -93,27 +87,27 @@ export function MissionForm({ id, isAlreadyClosed, isNewMission, selectedMission
})
}
- const closeMission = async () => {
- await setFieldValue('isClosed', true)
- validateForm().then(errors => {
+ const closeMission = () => {
+ validateForm({ ...values, isClosed: true }).then(errors => {
if (_.isEmpty(errors)) {
- handleSubmit()
- } else {
- setShouldValidateOnChange(true)
+ dispatch(saveMission({ ...values, isClosed: true }))
+
+ return
}
+ setShouldValidateOnChange(true)
})
}
const reopenMission = () => {
validateForm({ ...values, isClosed: false }).then(errors => {
if (_.isEmpty(errors)) {
+ setFieldValue('isClosed', false)
if (dirty) {
return setIsReopenModalOpen(true)
}
return validateReopenMission()
}
- setFieldValue('isClosed', true)
return setShouldValidateOnChange(true)
})
diff --git a/frontend/src/features/missions/MissionForm/formikUseCases/updateActionThemes.ts b/frontend/src/features/missions/MissionForm/formikUseCases/updateActionThemes.ts
index 4dd6d0171..8e0da4a88 100644
--- a/frontend/src/features/missions/MissionForm/formikUseCases/updateActionThemes.ts
+++ b/frontend/src/features/missions/MissionForm/formikUseCases/updateActionThemes.ts
@@ -16,8 +16,11 @@ export const updateTheme =
export const updateSubThemes =
(setFieldValue: (field: string, value: any) => void) => (value: string, actionIndex: number, themeIndex: number) => {
const subThemesPath = `envActions[${actionIndex}].themes.${themeIndex}.subThemes`
-
+ const protectedSpeciesPath = `envActions[${actionIndex}].themes.${themeIndex}.protectedSpecies`
setFieldValue(subThemesPath, value)
+ if (!value || value?.length === 0) {
+ setFieldValue(protectedSpeciesPath, value)
+ }
}
export const updateProtectedSpecies =
(setFieldValue: (field: string, value: any) => void) => (value: string, actionIndex: number, themeIndex: number) => {
diff --git a/frontend/src/features/missions/MissionForm/index.tsx b/frontend/src/features/missions/MissionForm/index.tsx
index fb5824f4a..f177aa68a 100644
--- a/frontend/src/features/missions/MissionForm/index.tsx
+++ b/frontend/src/features/missions/MissionForm/index.tsx
@@ -1,13 +1,12 @@
import { skipToken } from '@reduxjs/toolkit/dist/query'
import { Formik } from 'formik'
+import { noop } from 'lodash'
import { useMemo, useState } from 'react'
import styled from 'styled-components'
import { MissionForm } from './MissionForm'
import { MissionSchema } from './Schemas'
import { useGetMissionQuery } from '../../../api/missionsAPI'
-import { saveMission } from '../../../domain/use_cases/missions/saveMission'
-import { useAppDispatch } from '../../../hooks/useAppDispatch'
import { useAppSelector } from '../../../hooks/useAppSelector'
import { FormikForm } from '../../../uiMonitor/CustomFormikFields/FormikForm'
import { getIdTyped } from '../../../utils/getIdTyped'
@@ -20,7 +19,6 @@ export function Mission() {
multiMissions: { selectedMissions },
sideWindow
} = useAppSelector(state => state)
- const dispatch = useAppDispatch()
const [shouldValidateOnChange, setShouldValidateOnChange] = useState(false)
const routeParams = getMissionPageRoute(sideWindow.currentPath)
@@ -44,10 +42,6 @@ export function Mission() {
return missionFactory(missionToEdit)
}, [idTyped, missionIsNewMission, missionToEdit])
- const handleSubmitForm = values => {
- dispatch(saveMission(values))
- }
-
if (isLoading) {
return Chargement en cours
}
@@ -58,7 +52,7 @@ export function Mission() {
key={idTyped}
enableReinitialize
initialValues={missionFormikValues}
- onSubmit={handleSubmitForm}
+ onSubmit={noop}
validateOnBlur={false}
validateOnChange={shouldValidateOnChange}
validateOnMount={false}
@@ -67,7 +61,6 @@ export function Mission() {
{
- const totalInfractions = infractions.length || 0
+ const totalInfractions = infractions?.length || 0
const ras = (actionNumberOfControls || 0) - totalInfractions
const infractionsWithReport =
infractions?.filter(inf => inf.infractionType === InfractionTypeEnum.WITH_REPORT)?.length || 0