Skip to content

Commit

Permalink
add open observation on click
Browse files Browse the repository at this point in the history
  • Loading branch information
aleckvincent committed Nov 13, 2024
1 parent 1bbd0ba commit 20216ba
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { render, screen, fireEvent } from '../../../../../../test-utils.tsx'
import MissionListItem from '../mission-list-item.tsx'
import { ControlUnit } from '@mtes-mct/monitor-ui'
import ControlUnitResourceType = ControlUnit.ControlUnitResourceType
import { Mission } from '@common/types/mission-types.ts'
import MissionListing from '../mission-listing.tsx'

const mission1 = {
id: 1,
Expand Down Expand Up @@ -31,20 +33,27 @@ const queryAllMissionItemProps = () => ({
})

describe('MissionListItem component', () => {
const missions: Mission[] = [
{ id: 1, missionSource: 'source1', startDateTimeUtc: new Date().toISOString(), observationsByUnit: 'Observation 1' },
{ id: 2, missionSource: 'source2', startDateTimeUtc: new Date().toISOString(), observationsByUnit: 'Observation 2' },
];

const mockSetOpenIndex = vi.fn()

test('should render "N/A" if no ControlUnitResource provided', () => {
render(<MissionListItem mission={mission1} isUlam={true} />)
render(<MissionListItem mission={mission1} isUlam={true} index={0} openIndex={true} setOpenIndex={mockSetOpenIndex} />)
const noResource = screen.queryByText("N/A")
expect(noResource).toBeInTheDocument()
})

test('should render "Voiture" if ControlUnitResource contains CAR', () => {
render(<MissionListItem mission={mission2} isUlam={true} />)
render(<MissionListItem mission={mission2} isUlam={true} index={0} openIndex={true} setOpenIndex={mockSetOpenIndex} />)
const car = screen.queryByTestId("mission-list-item-control_unit_resources")
expect(car).toHaveTextContent('Voiture')
})

test('should render all properties for ulam', () => {
render(<MissionListItem isUlam={true} />)
render(<MissionListItem isUlam={true} index={0} openIndex={true} setOpenIndex={mockSetOpenIndex} />)
const {
missionIcon, missionNumber, openBy, openDate,
ressourcesUsed, crew, missionStatus, reportStatus
Expand All @@ -61,7 +70,7 @@ describe('MissionListItem component', () => {
})

test('should not render ulam props when isUlam set to false', () => {
render(<MissionListItem isUlam={false} />)
render(<MissionListItem isUlam={false} index={0} openIndex={true} setOpenIndex={mockSetOpenIndex} />)
const {
missionIcon, missionNumber, openBy, openDate,
ressourcesUsed, crew, missionStatus, reportStatus
Expand All @@ -78,27 +87,39 @@ describe('MissionListItem component', () => {
})

test('should render crew list with an ellipsis', () => {
render(<MissionListItem isUlam={true} mission={mission1}/> )
render(<MissionListItem isUlam={true} mission={mission1} index={0} openIndex={true} setOpenIndex={mockSetOpenIndex} /> )
const missionCrew = screen.queryByTestId("mission-list-item-crew__text")
expect(missionCrew).toHaveStyle('text-overflow: ellipsis')
expect(missionCrew).toHaveStyle(`overflow: hidden`)
expect(missionCrew).toHaveStyle(`white-space: nowrap`)
})

test('should displays details on mouse over and hides on mouse leave', () => {
render(<MissionListItem mission={mission1} isUlam={true} />);
it('should open an item on click and close others', () => {
render(<MissionListing missions={missions} isUlam={true} />);

const missionItems = screen.getAllByTestId('mission-list-item-with-hover');

const listItem = screen.getByTestId('mission-list-item-with-hover');
fireEvent.click(missionItems[0]);
expect(screen.getByText('Observation 1')).toBeVisible();

expect(screen.queryByTestId('mission-list-item-more')).toBeNull();
expect(screen.queryByText('Observation 2')).toBeNull();

fireEvent.mouseOver(listItem);
fireEvent.click(missionItems[1]);
expect(screen.getByText('Observation 2')).toBeVisible();
expect(screen.queryByText('Observation 1')).toBeNull();
});

it('should close the item when clicking outside', () => {
render(<MissionListing missions={missions} isUlam={true} />);

expect(screen.getByTestId('mission-list-item-more')).toBeInTheDocument();
const missionItems = screen.getAllByTestId('mission-list-item-with-hover');

fireEvent.mouseLeave(listItem);
fireEvent.click(missionItems[0]);
expect(screen.getByText('Observation 1')).toBeVisible();

expect(screen.queryByTestId('mission-list-item-more')).toBeNull();
fireEvent.mouseDown(document);
expect(screen.queryByText('Observation 1')).toBeNull();
});

})

Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ const MissionListHeader: React.FC<MissionListHeaderProps> = ({ isUlam}) => {

<FlexboxGrid align="middle" style={{ height: '100%', padding: '0.5rem 1rem' }}>
<FlexboxGrid.Item colspan={1} style={{ paddingTop: '8px' }}></FlexboxGrid.Item>
<FlexboxGrid.Item colspan={4} style={{ paddingTop: '8px' }}></FlexboxGrid.Item>
<FlexboxGrid.Item colspan={3} style={{ paddingTop: '8px' }}></FlexboxGrid.Item>
<FlexboxGrid.Item colspan={3}></FlexboxGrid.Item>
<FlexboxGrid.Item colspan={2}>
<p style={{ color: THEME.color.slateGray, fontSize: '12px' }}>Date d'ouverture</p>
</FlexboxGrid.Item>
{isUlam && (
<>
<FlexboxGrid.Item colspan={3}>
<FlexboxGrid.Item colspan={4}>
<p style={{ color: THEME.color.slateGray, fontSize: '12px' }}>Moyen(s) utilisé(s)</p>
</FlexboxGrid.Item>
<FlexboxGrid.Item colspan={3}>
<FlexboxGrid.Item colspan={4}>
<p style={{ color: THEME.color.slateGray, fontSize: '12px' }}>Agent(s)</p>
</FlexboxGrid.Item>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mission } from '@common/types/mission-types.ts';
import React, { useState } from 'react';
import React, { useEffect, useRef, useState } from 'react'
import { Icon, THEME } from '@mtes-mct/monitor-ui';
import { Divider, FlexboxGrid } from 'rsuite';
import { Link } from 'react-router-dom';
Expand All @@ -15,6 +15,9 @@ import { ULAM_V2_HOME_PATH } from '@router/router.tsx'
interface MissionListItemProps {
mission?: Mission;
isUlam: boolean;
index: number;
openIndex: number | null;
setOpenIndex: (index: number | null) => void;
}

const ListItemWithHover = styled.div`
Expand All @@ -36,17 +39,37 @@ const MissionCrewItem = styled.div`
padding-right: 8px;
`

const MissionListItem: React.FC<MissionListItemProps> = ({ mission, isUlam }) => {
const MissionListItem: React.FC<MissionListItemProps> = ({ mission, isUlam, index, openIndex, setOpenIndex }) => {
const controlUnitResourcesText = useControlUnitResourceLabel(mission?.controlUnits);
const missionName = formatDateForMissionName(mission?.startDateTimeUtc);
const missionDate = formatDateForFrenchHumans(mission?.startDateTimeUtc);
const missionCrew = useCrewForMissionList(mission?.crew);
const [displayDetails, setDisplayDetails] = useState<boolean>(false);

const listItemRef = useRef<HTMLDivElement>(null);
const isOpen = openIndex === index;

useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (listItemRef.current && !listItemRef.current.contains(event.target as Node)) {
setOpenIndex(null);
}
};

if (isOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}

return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOpen, setOpenIndex]);

return (
<ListItemWithHover
onMouseOver={() => setDisplayDetails(true)}
onMouseLeave={() => setDisplayDetails(false)}
ref={listItemRef}
onClick={() => setOpenIndex(isOpen ? null : index)}
data-testid="mission-list-item-with-hover"
>
<Link
Expand All @@ -60,7 +83,7 @@ const MissionListItem: React.FC<MissionListItemProps> = ({ mission, isUlam }) =>
<Icon.MissionAction size={28} color={THEME.color.charcoal} />
</FlexboxGrid.Item>

<FlexboxGrid.Item colspan={4} data-testid={'mission-list-item-mission_number'}>
<FlexboxGrid.Item colspan={3} data-testid={'mission-list-item-mission_number'}>
<p style={{ color: THEME.color.charcoal, fontSize: '16px', fontWeight: 'bold' }}>
Mission n°{missionName}
</p>
Expand All @@ -78,12 +101,12 @@ const MissionListItem: React.FC<MissionListItemProps> = ({ mission, isUlam }) =>

{isUlam && (
<>
<FlexboxGrid.Item colspan={3} data-testid={'mission-list-item-control_unit_resources'}>
<FlexboxGrid.Item colspan={4} data-testid={'mission-list-item-control_unit_resources'}>
<p style={{ color: THEME.color.charcoal, fontSize: '13px', fontWeight: 'bold' }}>
{controlUnitResourcesText}
</p>
</FlexboxGrid.Item>
<FlexboxGrid.Item colspan={3} data-testid={'mission-list-item-crew'}>
<FlexboxGrid.Item colspan={4} data-testid={'mission-list-item-crew'}>
<MissionCrewItem data-testid={'mission-list-item-crew__text'} title={missionCrew.text}>
{missionCrew.text}
</MissionCrewItem>
Expand Down Expand Up @@ -114,7 +137,7 @@ const MissionListItem: React.FC<MissionListItemProps> = ({ mission, isUlam }) =>
<Icon.Edit size={20} style={{ color: THEME.color.charcoal }} />
</FlexboxGrid.Item>

{(displayDetails && mission?.observationsByUnit) && (
{(isOpen && mission?.observationsByUnit) && (
<FlexboxGrid.Item colspan={24} data-testid={'mission-list-item-more'}>
<Divider style={{
backgroundColor: THEME.color.charcoal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC } from 'react'
import React, { FC, useState } from 'react'
import { Stack } from 'rsuite'
import MissionListItem from './mission-list-item.tsx'
import MissionListHeader from './mission-list-header.tsx'
Expand All @@ -11,14 +11,21 @@ interface MissionListingProps {


const MissionListing: FC<MissionListingProps> = ({missions, isUlam}) => {
const [openIndex, setOpenIndex] = useState<number | null>(null);
return (
<Stack direction="column" alignItems="flex-start" spacing="0.5rem" style={{ width: '100%' }}>
<Stack.Item style={{ width: '100%' }}>
<MissionListHeader isUlam={isUlam} />
</Stack.Item>
<Stack.Item style={{ width: '100%', height: '100%' }} >
{missions?.map((mission) => (
<MissionListItem isUlam={isUlam} mission={mission} />
{missions?.map((mission, index) => (
<MissionListItem
isUlam={isUlam}
mission={mission}
index={index}
openIndex={openIndex}
setOpenIndex={setOpenIndex}
/>
))
}
</Stack.Item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React, { JSX } from 'react'
import { Link, useNavigate } from 'react-router-dom'

Check warning on line 2 in frontend/src/v2/features/ulam/components/element/mission-list-ulam.tsx

View workflow job for this annotation

GitHub Actions / build-and-test-frontend

'Link' is defined but never used
import { Col, Container, FlexboxGrid, Loader, Stack } from 'rsuite'

Check warning on line 3 in frontend/src/v2/features/ulam/components/element/mission-list-ulam.tsx

View workflow job for this annotation

GitHub Actions / build-and-test-frontend

'Loader' is defined but never used

Check warning on line 3 in frontend/src/v2/features/ulam/components/element/mission-list-ulam.tsx

View workflow job for this annotation

GitHub Actions / build-and-test-frontend

'Stack' is defined but never used
import MissionListing from '../../../common/components/elements/mission-listing.tsx'
import MissionListDaterangeNavigator from '../../../common/components/elements/mission-list-daterange-navigator.tsx'
import { Icon } from '@mtes-mct/monitor-ui'
interface MissionListUlamProps {
dateRangeNavigator: JSX.Element,
Expand All @@ -16,7 +14,7 @@ const MissionListUlam: React.FC<MissionListUlamProps> = ({dateRangeNavigator, mi
justify="center"
style={{ padding: '4rem 2rem', display: 'flex', flex: 1 }}
>
<FlexboxGrid.Item as={Col} colspan={24} xxl={23}>
<FlexboxGrid.Item as={Col} colspan={24} xxl={20}>
<Container>
<h3 style={{marginBottom: '45px'}}><Icon.MissionAction size={26}/> Missions</h3>
<h4 style={{marginBottom: '25px'}}>Mes rapports de mission</h4>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'

const MissionListUlamTitle: React.FC = () => {
return <h4>Rapport Nav | Ulam 33</h4>
return <h4>Rapport Nav</h4>
}

export default MissionListUlamTitle

0 comments on commit 20216ba

Please sign in to comment.