Skip to content

Commit

Permalink
Merge pull request #476 from MTES-MCT/date-validation-v2
Browse files Browse the repository at this point in the history
feat: add simple date range validation on v2
  • Loading branch information
lwih authored Jan 21, 2025
2 parents 8074ab0 + 1c39218 commit 6ef6769
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class MissionActionRestController(
}

@PutMapping("{actionId}")
@Operation(summary = "Create a new mission action")
@Operation(summary = "Update an existing mission action")
fun updateAction(
@PathVariable(name = "actionId") actionId: String,
@RequestBody body: MissionAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import { MissionAction } from '../../../common/types/mission-action'
import MissionControlEnvForm from '../../../mission-control/components/elements/mission-control-env-form'
import MissionInfractionEnvList from '../../../mission-infraction/components/elements/mission-infraction-env-list-form'
import { useMissionActionEnvControl } from '../../hooks/use-mission-action-env-control'
import { ActionEnvControlInput } from '../../types/action-type'
import {ActionEnvControlInput} from '../../types/action-type'
import MissionActionEnvControlPlan from '../ui/mission-action-env-control-plan'
import MissionActionEnvControlSummary from '../ui/mission-action-env-control-summary'
import { MissionActionFormikCoordinateInputDMD } from '../ui/mission-action-formik-coordonate-input-dmd'
import { MissionActionFormikDateRangePicker } from '../ui/mission-action-formik-date-range-picker'
import {simpleDateRangeValidationSchema} from "../../validation-schema/date-validation.ts";

type MissionActionItemEnvControlProps = {
action: MissionAction
Expand All @@ -36,10 +37,13 @@ const MissionActionItemEnvControl: React.FC<MissionActionItemEnvControlProps> =
return (
<form style={{ width: '100%' }}>
{initValue && (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true}>
{({ values }) => (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true} validationSchema={simpleDateRangeValidationSchema}>
{({ values, errors, validateForm }) => (
<>
<FormikEffect onChange={nextValues => handleSubmit(nextValues as ActionEnvControlInput)} />
<FormikEffect onChange={async nextValues => {
await validateForm(values)
await handleSubmit(nextValues as ActionEnvControlInput, errors)
}} />
<Stack
direction="column"
spacing="2rem"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import FishControlOtherObservationsSection from '../../../mission-control/compon
import FishControlSeizureSection from '../../../mission-control/components/ui/mission-control-fish-seizure-section'
import FishControlSpeciesSection from '../../../mission-control/components/ui/mission-control-fish-species-section'
import { useMissionActionFishControl } from '../../hooks/use-mission-action-fish-control'
import { ActionFishControlInput } from '../../types/action-type'
import {ActionFishControlInput} from '../../types/action-type'
import { MissionActionFormikCoordinateInputDMD } from '../ui/mission-action-formik-coordonate-input-dmd'
import { MissionActionFormikDateRangePicker } from '../ui/mission-action-formik-date-range-picker'
import {simpleDateRangeValidationSchema} from "../../validation-schema/date-validation.ts";

const MissionActionItemFishControl: FC<{
action: MissionAction
Expand All @@ -27,10 +28,13 @@ const MissionActionItemFishControl: FC<{
return (
<div style={{ width: '100%' }}>
{initValue && (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true}>
{({ values }) => (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true} validationSchema={simpleDateRangeValidationSchema}>
{({ values, errors, validateForm }) => (
<>
<FormikEffect onChange={nextValues => handleSubmit(nextValues as ActionFishControlInput)} />
<FormikEffect onChange={async nextValues => {
await validateForm(values)
await handleSubmit(nextValues as ActionFishControlInput, errors)
}} />
<Stack
direction="column"
spacing="2rem"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import { FormikEffect, FormikTextarea } from '@mtes-mct/monitor-ui'
import { Formik } from 'formik'
import { Formik} from 'formik'
import { FC } from 'react'
import { Stack } from 'rsuite'
import { MissionAction } from '../../../common/types/mission-action'
import { useMissionActionGenericDateObservation } from '../../hooks/use-mission-action-generic-date-observation'
import { ActionGenericDateObservationInput } from '../../types/action-type'
import { MissionActionFormikDateRangePicker } from '../ui/mission-action-formik-date-range-picker'
import {simpleDateRangeValidationSchema} from "../../validation-schema/date-validation.ts";

const MissionActionItemGenericDateObservation: FC<{
action: MissionAction
onChange: (newAction: MissionAction, debounceTime?: number) => Promise<unknown>
}> = ({ action, onChange }) => {
const { initValue, handleSubmit } = useMissionActionGenericDateObservation(action, onChange)

return (
<form style={{ width: '100%' }}>
{initValue && (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true}>
<Formik //
initialValues={initValue}
onSubmit={handleSubmit}
validationSchema={simpleDateRangeValidationSchema}
validateOnChange={true}>
{({ values, errors, validateForm }) => (
<>
<FormikEffect onChange={nextValue => handleSubmit(nextValue as ActionGenericDateObservationInput)} />
<FormikEffect onChange={async (nextValue) => {
await validateForm(values)
await handleSubmit(nextValue as ActionGenericDateObservationInput, errors)
}} />
<Stack direction="column" spacing="2rem" alignItems="flex-start" style={{ width: '100%' }}>
<Stack.Item style={{ width: '100%' }}>
<Stack direction="row" spacing="0.5rem" style={{ width: '100%' }}>
<Stack.Item grow={1}>
<MissionActionFormikDateRangePicker name="dates" />
<MissionActionFormikDateRangePicker name="dates" isLight={true} errors={errors} />
</Stack.Item>
</Stack>
</Stack.Item>
Expand All @@ -31,6 +41,7 @@ const MissionActionItemGenericDateObservation: FC<{
</Stack.Item>
</Stack>
</>
)}
</Formik>
)}
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { MissionAction } from '../../../common/types/mission-action'
import MissionControlNavForm from '../../../mission-control/components/elements/mission-control-nav-form'
import MissionControlNavSummary from '../../../mission-control/components/ui/mission-control-nav-summary'
import { useMissionActionNavControl } from '../../hooks/use-mission-action-nav-control'
import { ActionNavControlInput } from '../../types/action-type'
import { ActionNavControlInput} from '../../types/action-type'
import { MissionActionFormikCoordinateInputDMD } from '../ui/mission-action-formik-coordonate-input-dmd'
import { MissionActionFormikDateRangePicker } from '../ui/mission-action-formik-date-range-picker'
import { MissionActionFormikTextInput } from '../ui/mission-action-formik-text-input'
Expand All @@ -30,9 +30,12 @@ const MissionActionItemNavControl: FC<{
validateOnChange={true}
validationSchema={validationSchema}
>
{({ values }) => (
{({ values, errors, validateForm }) => (
<>
<FormikEffect onChange={nextValues => handleSubmit(nextValues as ActionNavControlInput)} />
<FormikEffect onChange={async (nextValue) => {
await validateForm(values)
await handleSubmit(nextValue as ActionNavControlInput, errors)
}} />
<Stack
direction="column"
spacing="2rem"
Expand All @@ -47,7 +50,7 @@ const MissionActionItemNavControl: FC<{
<MissionControlNavSummary vesselType={values?.vesselType} controlMethod={values?.controlMethod} />
</Stack.Item>
<Stack.Item grow={1}>
<MissionActionFormikDateRangePicker name="dates" />
<MissionActionFormikDateRangePicker name="dates" isLight={true} errors={errors}/>
</Stack.Item>
<Stack.Item style={{ width: '100%' }}>
<MissionActionFormikCoordinateInputDMD name={'geoCoords'} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Divider, Stack } from 'rsuite'
import { MissionAction } from '../../../common/types/mission-action'
import { RescueType } from '../../../common/types/rescue-type'
import { useMissionActionRescue } from '../../hooks/use-mission-action-rescue'
import { ActionRescueInput } from '../../types/action-type'
import { ActionRescueInput} from '../../types/action-type'
import { MissionActionFormikCoordinateInputDMD } from '../ui/mission-action-formik-coordonate-input-dmd'
import { MissionActionFormikDateRangePicker } from '../ui/mission-action-formik-date-range-picker'
import { MissionActionFormikNumberInput } from '../ui/mission-action-formik-number-input'
Expand Down Expand Up @@ -47,13 +47,17 @@ const MissionActionItemRescue: FC<{
initialValues={initValue}
validationSchema={validationSchema}
>
{({ values, errors, validateForm }) => (
<>
<FormikEffect onChange={nextValues => handleSubmit(nextValues as ActionRescueInput)} />
<FormikEffect onChange={async (nextValue) => {
await validateForm(values)
await handleSubmit(nextValue as ActionRescueInput, errors)
}} />
<Stack direction="column" spacing="2rem" alignItems="flex-start" style={{ width: '100%' }}>
<Stack.Item style={{ width: '100%' }}>
<Stack direction="row" spacing="0.5rem" style={{ width: '100%' }}>
<Stack.Item grow={1}>
<MissionActionFormikDateRangePicker name="dates" />
<MissionActionFormikDateRangePicker name="dates" isLight={true} errors={errors}/>
</Stack.Item>
</Stack>
</Stack.Item>
Expand Down Expand Up @@ -178,6 +182,7 @@ const MissionActionItemRescue: FC<{
</Stack>
)}
</>
)}
</Formik>
)}
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { FC } from 'react'
import { Stack } from 'rsuite'
import { MissionAction } from '../../../common/types/mission-action'
import { useMissionActionSurveillance } from '../../hooks/use-mission-action-surveillance'
import { ActionSurveillanceInput } from '../../types/action-type'
import { ActionSurveillanceInput} from '../../types/action-type'
import MissionActionEnvControlPlan from '../ui/mission-action-env-control-plan'
import { MissionActionFormikDateRangePicker } from '../ui/mission-action-formik-date-range-picker'
import {simpleDateRangeValidationSchema} from "../../validation-schema/date-validation.ts";

const MissionActionItemSurveillance: FC<{
action: MissionAction
Expand All @@ -17,15 +18,18 @@ const MissionActionItemSurveillance: FC<{
return (
<form style={{ width: '100%' }}>
{initValue && (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true}>
{({ values }) => (
<Formik initialValues={initValue} onSubmit={handleSubmit} validateOnChange={true} validationSchema={simpleDateRangeValidationSchema}>
{({ values, errors, validateForm }) => (
<>
<FormikEffect onChange={nextValue => handleSubmit(nextValue as ActionSurveillanceInput)} />
<FormikEffect onChange={async (nextValue) => {
await validateForm(values)
await handleSubmit(nextValue as ActionSurveillanceInput, errors)
}} />
<Stack direction="column" spacing="2rem" alignItems="flex-start" style={{ width: '100%' }}>
<Stack.Item style={{ width: '100%' }}>
<Stack direction="row" spacing="0.5rem" style={{ width: '100%' }}>
<Stack.Item grow={1}>
<MissionActionFormikDateRangePicker name="dates" />
<MissionActionFormikDateRangePicker name="dates" isLight={true} errors={errors}/>
</Stack.Item>
</Stack>
</Stack.Item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,56 @@
import { FormikDateRangePicker, FormikDateRangePickerWithDateDateProps } from '@mtes-mct/monitor-ui'
import {
FormikDatePicker, FormikDatePickerWithDateDateProps,
Label, THEME,
} from '@mtes-mct/monitor-ui'
import styled from 'styled-components'
import {Stack} from "rsuite";
import Text from "@common/components/ui/text.tsx";

type MissionActionFormikDateRangePickerProps = Omit<FormikDatePickerWithDateDateProps, 'label'> & {
errors: any
}

export const MissionActionFormikDateRangePicker = styled(
(props: Omit<FormikDateRangePickerWithDateDateProps, 'label'>) => (
<FormikDateRangePicker
isLight={true}
withTime={true}
isCompact={true}
isRequired={true}
label="Date et heure de début et de fin"
{...props}
/>
(props: MissionActionFormikDateRangePickerProps) => (
<Stack direction={'column'} alignItems={'flex-start'}>
<Stack.Item>
<Label>Date et heure de début et de fin</Label>
</Stack.Item>
<Stack.Item>
<Stack direction={'row'} spacing={'0.5rem'}>
<Stack.Item>
<FormikDatePicker
{...props}
isErrorMessageHidden={true}
label={''}
name={'startDateTimeUtc'}
isRequired={true}
withTime={true}
isCompact={true}

/>
</Stack.Item>
<Stack.Item alignSelf={'center'}>
<Text as={'h4'}>au</Text>
</Stack.Item>
<Stack.Item>
<FormikDatePicker
{...props}
isErrorMessageHidden={true}
label={''}
name={'endDateTimeUtc'}
isRequired={true}
withTime={true}
isCompact={true}
/>
</Stack.Item>
</Stack>
</Stack.Item>
<Stack.Item style={{marginTop: '0.2rem'}}>
<Text as={'h3'} color={THEME.color.maximumRed}>
{props.errors?.endDateTimeUtc ?? props.errors?.startDateTimeUtc ?? ''}
</Text>
</Stack.Item>
</Stack>
)
)({})
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export function useMissionActionGenericDateObservation(
const fromFieldValueToInput = (data: MissionActionData): ActionGenericDateObservationInput => {
const endDate = preprocessDateForPicker(data.endDateTimeUtc)
const startDate = preprocessDateForPicker(data.startDateTimeUtc)
return { ...data, dates: [startDate, endDate] }
return { ...data, startDateTimeUtc: startDate.toISOString(), endDateTimeUtc: endDate.toISOString() }
}

const fromInputToFieldValue = (value: ActionGenericDateObservationInput): MissionActionData => {
const { dates, ...newData } = value
const endDateTimeUtc = postprocessDateFromPicker(dates[1])
const startDateTimeUtc = postprocessDateFromPicker(dates[0])
return { ...newData, startDateTimeUtc, endDateTimeUtc }
const { endDateTimeUtc, startDateTimeUtc, ...newData } = value
const processedEndDateTimeUtc = postprocessDateFromPicker(endDateTimeUtc)
const processedStartDateTimeUtc = postprocessDateFromPicker(startDateTimeUtc)
return { ...newData, startDateTimeUtc: processedStartDateTimeUtc, endDateTimeUtc: processedEndDateTimeUtc }
}

const { initValue, handleSubmit, isError } = useAbstractFormik<MissionActionData, ActionGenericDateObservationInput>(
Expand All @@ -32,6 +32,7 @@ export function useMissionActionGenericDateObservation(
)

const onSubmit = async (valueToSubmit?: MissionActionData) => {
debugger
if (!valueToSubmit) return
await onChange({ ...action, data: valueToSubmit })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useDate } from '../../common/hooks/use-date'
import { AbstractFormikSubFormHook } from '../../common/types/abstract-formik-hook'
import { MissionAction, MissionNavActionData } from '../../common/types/mission-action'
import { ActionNavControlInput } from '../types/action-type'
import {simpleDateRangeValidationSchema} from "../validation-schema/date-validation.ts";

export function useMissionActionNavControl(
action: MissionAction,
Expand Down Expand Up @@ -52,7 +53,7 @@ export function useMissionActionNavControl(
handleSubmit(value, errors, onSubmit)
}

const validationSchema = object().shape({
const validationSchema = simpleDateRangeValidationSchema.concat(object().shape({
isMissionFinished: boolean(),
vesselSize: mixed<VesselSizeEnum>()
.nullable()
Expand All @@ -71,7 +72,7 @@ export function useMissionActionNavControl(
is: true,
then: schema => schema.nonNullable().required()
})
})
}))

return {
isError,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AbstractFormikSubFormHook } from '../../common/types/abstract-formik-ho
import { MissionAction, MissionNavActionData } from '../../common/types/mission-action'
import { RescueType } from '../../common/types/rescue-type'
import { ActionRescueInput } from '../types/action-type'
import {simpleDateRangeValidationSchema} from "../validation-schema/date-validation.ts";

export function useMissionActionRescue(
action: MissionAction,
Expand Down Expand Up @@ -75,7 +76,7 @@ export function useMissionActionRescue(
handleSubmit(value, errors, onSubmit)
}

const validationSchema = object().shape({
const validationSchema = simpleDateRangeValidationSchema.concat( object().shape({
isMissionFinished: boolean(),
isPersonRescue: boolean(),
isMigrationRescue: boolean(),
Expand Down Expand Up @@ -109,7 +110,7 @@ export function useMissionActionRescue(
then: schema => schema.nonNullable().required(),
otherwise: schema => schema.nullable()
})
})
}))

return {
isError,
Expand Down
Loading

0 comments on commit 6ef6769

Please sign in to comment.