Skip to content

Commit

Permalink
Merge pull request #378 from MTES-MCT/375-front-ajouter-une-infractio…
Browse files Browse the repository at this point in the history
…n-pour-cette-cible

375 -  front ajouter une infraction pour cette cible
  • Loading branch information
aleckvincent authored Oct 9, 2024
2 parents c48a9e4 + cca7e7e commit 3d3ec60
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 85 deletions.
2 changes: 1 addition & 1 deletion frontend/src/features/common/types/env-mission-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export enum ActionTargetTypeEnum {
export const actionTargetTypeLabels = {
COMPANY: {
code: 'COMPANY',
libelle: 'Société'
libelle: 'Personne morale'
},
INDIVIDUAL: {
code: 'INDIVIDUAL',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ const ActionControlEnv: React.FC<ActionControlPropsEnv> = ({ action }) => {
</Stack.Item>
<Stack.Item style={{ width: '100%' }}>
<EnvInfractionExistingTargets
actionTargetType={actionData?.actionTargetType}
infractionsByTarget={actionData?.infractions}
availableControlTypesForInfraction={actionData?.availableControlTypesForInfraction}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('EnvInfractionAddNewTarget', () => {
describe('testing rendering', () => {
it('should show the add button by default', async () => {
render(<EnvInfractionAddNewTarget {...props(undefined)} />)
expect(screen.getByText('Ajouter une nouvelle cible avec infraction')).toBeInTheDocument()
expect(screen.getByText('Ajouter une infraction')).toBeInTheDocument()
})
it('should show the form when clicking the button', async () => {
render(<EnvInfractionAddNewTarget {...props(undefined)} />)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const EnvInfractionAddNewTarget: React.FC<EnvInfractionNewTargetProps> = ({ avai
Icon={Icon.Plus}
role={'add-target'}
>
Ajouter une nouvelle cible avec infraction
Ajouter une infraction
</Button>
</Stack.Item>
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { render, screen, fireEvent } from '../../../../../../test-utils.tsx'
import { InfractionTypeEnum, VesselTypeEnum } from '../../../../../common/types/env-mission-types.ts'
import {
ActionTargetTypeEnum,
InfractionTypeEnum,
VesselTypeEnum
} from '../../../../../common/types/env-mission-types.ts'
import EnvInfractionExistingTargets from './env-infraction-existing-targets.tsx'
import { vi } from 'vitest'
import { Infraction, InfractionByTarget } from '../../../../../common/types/infraction-types.ts'
Expand Down Expand Up @@ -35,7 +39,8 @@ const infractionByTargetMock = (infractions: Infraction[], targetAddedByUnit: bo
})
const props = (infractionsByTarget?: InfractionByTarget[]) => ({
availableControlTypesForInfraction: [ControlType.ADMINISTRATIVE],
infractionsByTarget
infractionsByTarget,
actionTargetType: ActionTargetTypeEnum.VEHICLE
})

describe('EnvInfractionExistingTargets', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ import EnvInfractionTargetAddedByUnitForm from './env-infraction-target-added-by
import Text from '../../../../../common/components/ui/text.tsx'
import useDeleteInfraction from '../../../hooks/use-delete-infraction.tsx'
import useAddOrUpdateInfractionEnv from '../../../hooks/use-add-update-infraction-env.tsx'
import { ActionTargetTypeEnum } from '@common/types/env-mission-types.ts'

export interface EnvInfractionExistingTargetProps {
availableControlTypesForInfraction?: ControlType[]
infractionsByTarget?: InfractionByTarget[]
actionTargetType?: ActionTargetTypeEnum
}

const EnvInfractionExistingTargets: React.FC<EnvInfractionExistingTargetProps> = ({
availableControlTypesForInfraction,
infractionsByTarget
infractionsByTarget,
actionTargetType
}) => {
const { missionId, actionId } = useParams()

Expand Down Expand Up @@ -72,10 +75,7 @@ const EnvInfractionExistingTargets: React.FC<EnvInfractionExistingTargetProps> =
<div
key={infractionByTarget.vesselIdentifier}
style={{
width: '100%',
backgroundColor: THEME.color.white,
padding: '1rem',
marginBottom: '0.25rem'
width: '100%'
}}
>
{selectedVessel === infractionByTarget.vesselIdentifier ? (
Expand Down Expand Up @@ -119,6 +119,7 @@ const EnvInfractionExistingTargets: React.FC<EnvInfractionExistingTargetProps> =
</>
) : (
<EnvInfractionSummary
actionTargetType={actionTargetType}
infractionByTarget={infractionByTarget}
onAddInfractionForTarget={(infraction?: Partial<Infraction>) => {
setFormData(infraction as Infraction)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { render, screen, fireEvent } from '../../../../../../test-utils.tsx'
import EnvInfractionSummary from './env-infraction-summary.tsx'
import { ControlType } from '@common/types/control-types.ts'
import { InfractionTypeEnum, VesselTypeEnum } from '@common/types/env-mission-types.ts'
import { ActionTargetTypeEnum, InfractionTypeEnum, VesselTypeEnum } from '@common/types/env-mission-types.ts'
import { Infraction } from '@common/types/infraction-types.ts'
import { Icon } from '@mtes-mct/monitor-ui'

Check warning on line 6 in frontend/src/features/pam/mission/components/elements/infractions/env-infraction-summary.test.tsx

View workflow job for this annotation

GitHub Actions / build-and-test-frontend

'Icon' is defined but never used

const infractionMock = {
id: '123',
Expand All @@ -13,6 +14,15 @@ const infractionMock = {
target: undefined
}

const infractionControlTypeNullMockEnv = {

Check warning on line 17 in frontend/src/features/pam/mission/components/elements/infractions/env-infraction-summary.test.tsx

View workflow job for this annotation

GitHub Actions / build-and-test-frontend

'infractionControlTypeNullMockEnv' is assigned a value but never used
id: '123',
controlType: null,
infractionType: InfractionTypeEnum.WITHOUT_REPORT,
natinfs: ['123'],
observations: undefined,
target: undefined
}

const infractionMockEnv = {
id: '456',
controlType: null,
Expand All @@ -29,12 +39,30 @@ const infractionByTargetMock = (infractions: Infraction[]) => ({
targetAddedByUnit: false
})

const infractionByTargetCompanyMock = (infractions: Infraction[]) => ({
vesselIdentifier: null,
vesselType: null,
infractions,
controlTypesWithInfraction: [ControlType.ADMINISTRATIVE],
targetAddedByUnit: false
})

const props = infractionByTarget => ({
infractionByTarget,
onAddInfractionForTarget: vi.fn(),
onEditInfractionForTarget: vi.fn(),
onDeleteInfraction: vi.fn()
onDeleteInfraction: vi.fn(),
actionTargetType: ActionTargetTypeEnum.VEHICLE
})

const propsCompany = infractionByTarget => ({
infractionByTarget,
onAddInfractionForTarget: vi.fn(),
onEditInfractionForTarget: vi.fn(),
onDeleteInfraction: vi.fn(),
actionTargetType: ActionTargetTypeEnum.COMPANY
})

describe('EnvInfractionSummary', () => {
describe('testing rendering', () => {
test('renders the component', async () => {
Expand All @@ -51,11 +79,15 @@ describe('EnvInfractionSummary', () => {
expect(screen.queryByRole('edit-infraction')).toBeNull()
expect(screen.queryByRole('delete-infraction')).toBeNull()
})
test('should render the display button when controlType is null', async () => {
render(<EnvInfractionSummary {...props(infractionByTargetMock([infractionMockEnv]))} />)
expect(screen.queryByRole('display-infraction')).not.toBeNull()
})
})
describe('Nav infraction', () => {
test('should render the correct control title', async () => {
render(<EnvInfractionSummary {...props(infractionByTargetMock([infractionMock]))} />)
expect(screen.getByText('Contrôle administratif navire')).toBeInTheDocument()
expect(screen.getByTestId('env-infraction-control-title')).toHaveTextContent('Contrôle administratif navire')
})
test('should render the edit and delete buttons ', async () => {
render(<EnvInfractionSummary {...props(infractionByTargetMock([infractionMock]))} />)
Expand Down Expand Up @@ -92,4 +124,11 @@ describe('EnvInfractionSummary', () => {
expect(onDeleteInfraction).toHaveBeenCalled()
})
})

describe('rendering button "Ajouter une infraction pour cette cible"', () => {
test('should not render button "Ajouter une infraction pour cette cible" if action target type is not VEHICLE', async () => {
render(<EnvInfractionSummary {...propsCompany(infractionByTargetCompanyMock([infractionMock]))} />)
expect(screen.queryByText('infraction pour cette cible')).not.toBeInTheDocument()
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,83 @@ import { controlTitle, vesselTypeToHumanString } from '../../../utils/control-ut
import { Infraction, InfractionByTarget } from '@common/types/infraction-types.ts'
import InfractionTypeTag from '../../ui/infraction-type-tag.tsx'
import NatinfsTag from '../../ui/natinfs-tag.tsx'
import { ActionTargetTypeEnum } from '@common/types/env-mission-types.ts'

interface EnvInfractionSummaryProps {
infractionByTarget?: InfractionByTarget
onAddInfractionForTarget: (infraction?: Partial<Infraction>) => void
onEditInfractionForTarget: (infraction: Infraction) => void
onDeleteInfraction: (infractionId: string) => void
actionTargetType?: ActionTargetTypeEnum
}

const EnvInfractionSummary: React.FC<EnvInfractionSummaryProps> = ({
infractionByTarget,
onAddInfractionForTarget,
onEditInfractionForTarget,
onDeleteInfraction
onDeleteInfraction,
actionTargetType
}) => {
return (
<Stack direction="column" spacing={'0.5rem'} style={{ width: '100%' }}>
<Stack.Item style={{ width: '100%' }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={'0.5rem'}>
<Stack.Item>
<Text as="h3" weight="bold" color={THEME.color.gunMetal}>
{`${vesselTypeToHumanString(infractionByTarget?.vesselType)} - ${infractionByTarget?.vesselIdentifier}`}
</Text>
</Stack.Item>
<Stack.Item>
<Button
onClick={() =>
onAddInfractionForTarget({
target: infractionByTarget?.infractions?.find(infraction => !!infraction.target)?.target
})
}
accent={Accent.SECONDARY}
size={Size.NORMAL}
Icon={Icon.Plus}
role={'add-infraction'}
>
infraction pour cette cible
</Button>
</Stack.Item>
</Stack>
</Stack.Item>
{infractionByTarget?.infractions.map((infraction: Infraction) => (
<Stack.Item key={infraction.id} style={{ width: '100%' }}>
<Stack direction="row" spacing={'0.5rem'} justifyContent="space-between">
<Stack.Item key={infraction.id} style={{
width: '100%',
backgroundColor: THEME.color.white,
padding: '0.7rem',
marginBottom: '0.5rem'
}}>
<Stack direction="row" spacing={'0.5rem'} justifyContent="space-between" style={{marginBottom: '5px'}}>
<Stack.Item>
<Stack direction="row" spacing={'0.5rem'} wrap={true}>
<Stack.Item>
<Text as="h3" weight="bold" color={THEME.color.gunMetal}>
<Text as="h3" weight="bold" color={THEME.color.gunMetal} data-testid={'env-infraction-control-title'}>
{!infraction?.controlType
? 'Infraction contrôle de l’environnement'
: controlTitle(infraction.controlType)}
: `${infraction.target?.identityControlledPerson} | ${controlTitle(infraction.controlType)}`}
</Text>
</Stack.Item>
<Stack.Item>
<Stack direction="row" spacing={'0.5rem'}>
<Stack.Item>
<InfractionTypeTag type={infraction.infractionType} />
</Stack.Item>
<Stack.Item>
<NatinfsTag natinfs={infraction.natinfs} />
</Stack.Item>
</Stack>
</Stack.Item>
</Stack>
</Stack.Item>
{infraction.controlType !== null && (
<Stack.Item>
<Stack direction="row" alignItems="baseline" spacing={'0.5rem'}>
</Stack>

<Stack.Item style={{width: '100%'}}>
<Stack direction="row" alignItems="flex-end" spacing={'0.5rem'} justifyContent={'flex-end'} >
{actionTargetType === ActionTargetTypeEnum.VEHICLE && (
<Stack.Item>
<Button
onClick={() =>
onAddInfractionForTarget({
target: infractionByTarget?.infractions?.find(infraction => !!infraction.target)?.target
})
}
accent={Accent.SECONDARY}
size={Size.NORMAL}
Icon={Icon.Plus}
role={'add-infraction'}
>
infraction pour cette cible
</Button>
</Stack.Item>
)}
</Stack>
</Stack.Item>

<Stack.Item style={{width: '100%'}}>
<Stack direction="row" alignItems="baseline" spacing={'0.5rem'} justifyContent={'flex-start'}>
<Stack.Item >
<InfractionTypeTag type={infraction.infractionType} />
</Stack.Item>
<Stack.Item >
<NatinfsTag natinfs={infraction.natinfs} />
</Stack.Item>
</Stack>
</Stack.Item>

<Stack.Item>

{infraction.controlType ? (
<Stack direction="row" alignItems="baseline" spacing={'0.5rem'} justifyContent={'flex-end'}>
<Stack.Item>
<IconButton
Icon={Icon.EditUnbordered}
Expand All @@ -82,20 +92,36 @@ const EnvInfractionSummary: React.FC<EnvInfractionSummaryProps> = ({
onClick={() => onEditInfractionForTarget(infraction)}
/>
</Stack.Item>

<Stack.Item>
<IconButton
Icon={Icon.Delete}
accent={Accent.SECONDARY}
size={Size.NORMAL}
role="delete-infraction"
onClick={() => onDeleteInfraction(infraction.id)}
/>
</Stack.Item>
</Stack>
):
<Stack direction="row" alignItems="baseline" spacing={'0.5rem'} justifyContent={'flex-end'}>
<Stack.Item>
<IconButton
Icon={Icon.Delete}
Icon={Icon.Display}
accent={Accent.SECONDARY}
size={Size.NORMAL}
role="delete-infraction"
onClick={() => onDeleteInfraction(infraction.id)}
role="display-infraction"
onClick={() => onEditInfractionForTarget(infraction)}
/>
</Stack.Item>
</Stack>
</Stack.Item>
)}
</Stack>
}


</Stack.Item>

</Stack.Item>

))}
</Stack>
)
Expand Down
Loading

0 comments on commit 3d3ec60

Please sign in to comment.