Skip to content

Commit

Permalink
fix(pam): uncouple timeline and action
Browse files Browse the repository at this point in the history
 - Create a specific pam timeline hook to return only timeline needs
 - refactor pam components to use the new hook
  • Loading branch information
xtiannyeto committed Jan 10, 2025
1 parent e483020 commit b812177
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ interface MissionActionItemPamProps {

const MissionActionItemPam: FC<MissionActionItemPamProps> = ({ action, missionId, isMissionFinished }) => {
const { handleExecuteOnDelay } = useDelay()
const { component } = usePamActionRegistry(action.actionType)
const debounceTime = useStore(store, state => state.delayQuery.debounceTime)
const { actionComponent } = usePamActionRegistry(action.actionType)

const mutation = useUpdateMissionActionMutation(missionId, action?.id)

Expand All @@ -29,7 +29,7 @@ const MissionActionItemPam: FC<MissionActionItemPamProps> = ({ action, missionId

return (
<div style={{ width: '100%' }}>
{actionComponent && createElement(actionComponent, { action, onChange, isMissionFinished })}
{component && createElement(component, { action, onChange, isMissionFinished })}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { FC } from 'react'
import useGetActionQuery from '../../../common/services/use-mission-action'
import { MissionAction } from '../../../common/types/mission-action'
import MissionActionWrapper from '../../../mission-action/components/layout/mission-action-wrapper'
import MissionActionItemPam from './mission-action-item-pam'

interface MissionActionProps {
actionId?: string
missionId: number
isLoading?: boolean
error?: Error | null
action?: MissionAction
}

const MissionActionPamBody: FC<MissionActionProps> = ({ missionId, actionId }) => {
const query = useGetActionQuery(missionId, actionId)
const MissionActionPamBody: FC<MissionActionProps> = ({ missionId, error, action, isLoading }) => {
return (
<MissionActionWrapper
action={query.data}
action={action}
isError={error}
missionId={missionId}
isError={query.error}
isLoading={query.isLoading}
isLoading={isLoading}
item={MissionActionItemPam}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ const MissionActionPam: FC<MissionActionProps> = ({ missionId, actionId, status
<MissionActionPamHeader missionId={Number(missionId)} action={query.data} missionStatus={status} />
)
}
sectionBody={<MissionActionPamBody missionId={Number(missionId)} actionId={actionId} />}
sectionBody={
<MissionActionPamBody
action={query.data}
error={query.error}
isLoading={query.isLoading}
missionId={Number(missionId)}
/>
}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { FC } from 'react'
import { ModuleType } from '../../../common/types/module-type'
import { useNavigate } from 'react-router-dom'
import MissionTimelineHeaderWrapper from '../../../mission-timeline/components/layout/mission-timeline-Header-wrapper'
import { usePamTimelineRegistry } from '../../hooks/use-pam-timeline-registry'

interface MissionTimelineHeaderPamProps {
missionId: number
}

const MissionTimelineHeaderPam: FC<MissionTimelineHeaderPamProps> = ({ missionId }) => {
return <MissionTimelineHeaderWrapper missionId={missionId} moduleType={ModuleType.PAM} />
const navigate = useNavigate()
const { timelineDropdownItems } = usePamTimelineRegistry()
const handleOnSubmit = (id?: string) => navigate(`/v2/pam/missions/${missionId}/${id}`)

return (
<MissionTimelineHeaderWrapper
missionId={missionId}
onSubmit={handleOnSubmit}
dropdownItems={timelineDropdownItems}
/>
)
}

export default MissionTimelineHeaderPam
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { createElement, FC, useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { ModuleType } from '../../../common/types/module-type'
import MissionTimelineItemWrapper from '../../../mission-timeline/components/layout/mission-timeline-item-wrapper'
import { useTimeline } from '../../../mission-timeline/hooks/use-timeline'
import { MissionTimelineAction } from '../../../mission-timeline/types/mission-timeline-output'
import { usePamActionRegistry } from '../../hooks/use-pam-action-registry'
import { usePamTimelineRegistry } from '../../hooks/use-pam-timeline-registry'

interface MissionTimelineItemPamProps {
missionId?: number
Expand All @@ -13,21 +14,28 @@ interface MissionTimelineItemPamProps {

const MissionTimelineItemPam: FC<MissionTimelineItemPamProps> = ({ action, prevAction, missionId }) => {
const { actionId } = useParams()
const { isIncomplete } = useTimeline()
const { getTimeline } = usePamTimelineRegistry()
const [isSelected, setIsSelected] = useState<boolean>(false)
const { style, icon, title, timeline, hasStatusTag, isIncomplete } = usePamActionRegistry(action.type)

useEffect(() => {
setIsSelected(action.id === actionId)
}, [action, actionId])
return (
<MissionTimelineItemWrapper
style={style}
action={action}
missionId={missionId}
isSelected={isSelected}
moduleType={ModuleType.PAM}
card={createElement(timeline.component, { icon, title, action, prevAction, isSelected })}
isIncomplete={isIncomplete(action)}
style={getTimeline(action.type).style}
card={createElement(getTimeline(action.type).component, {
icon: getTimeline(action.type).icon,
title: getTimeline(action.type).title,
action,
prevAction,
isSelected
})}
/>
)
}
Expand Down
21 changes: 6 additions & 15 deletions frontend/src/v2/features/pam/hooks/use-pam-action-registry.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
import { ActionTypeEnum } from '@common/types/env-mission-types'
import { ActionRegistryHook, ActionRegistryItem, useActionRegistry } from '../../common/hooks/use-action-registry'
import { ActionType } from '../../common/types/action-type'
import MissionActionItemStatus from '../../mission-action/components/elements/mission-action-item-status'
import MissionTimelineItemStatusCard from '../../mission-timeline/components/elements/mission-timeline-item-status-card'

type PamActionRegistry = {
[key in ActionTypeEnum]?: ActionRegistryItem
[key in ActionType]?: ActionRegistryItem
}

const PAM_ACTION_REGISTRY: PamActionRegistry = {
[ActionTypeEnum.STATUS]: {
hasStatusTag: true,
style: {
minHeight: 0
},
[ActionType.STATUS]: {
title: 'Statut du navire',
timeline: {
noPadding: true,
dropdownText: 'Ajouter des contrôles',
component: MissionTimelineItemStatusCard
},
actionComponent: MissionActionItemStatus
component: MissionActionItemStatus
}
}

type PamActionRegistryHook = {} & PamActionRegistry & ActionRegistryHook

export function usePamActionRegistry(actionType: ActionTypeEnum): PamActionRegistryHook {
export function usePamActionRegistry(actionType: ActionType): PamActionRegistryHook {
const common = useActionRegistry(actionType)
const pam = PAM_ACTION_REGISTRY[actionType]
return { ...pam, ...common }
Expand Down
148 changes: 148 additions & 0 deletions frontend/src/v2/features/pam/hooks/use-pam-timeline-registry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { Icon, THEME } from '@mtes-mct/monitor-ui'
import { ActionGroupType, ActionType } from '../../common/types/action-type'
import MissionTimelineItemControlCard from '../../mission-timeline/components/elements/mission-timeline-item-control-card'
import MissionTimelineItemGenericCard from '../../mission-timeline/components/elements/mission-timeline-item-generic-card'
import MissionTimelineItemRescueCard from '../../mission-timeline/components/elements/mission-timeline-item-rescue-card'
import MissionTimelineItemStatusCard from '../../mission-timeline/components/elements/mission-timeline-item-status-card'
import MissionTimelineItemSurveillanceCard from '../../mission-timeline/components/elements/mission-timeline-item-surveillance-card'
import { Timeline, TimelineDropdownItem, TimelineRegistry } from '../../mission-timeline/hooks/use-timeline'

const TIME_LINE_DROPDOWN_PAM_ITEMS: TimelineDropdownItem[] = [
{ type: ActionType.CONTROL, icon: Icon.ControlUnit, dropdownText: 'Ajouter des contrôles' },
{ type: ActionType.NOTE, icon: Icon.Note, dropdownText: 'Ajouter une note libre' },
{ type: ActionType.RESCUE, icon: Icon.Rescue, dropdownText: 'Ajouter une assistance / sauvetage' },
{
icon: Icon.More,
type: ActionGroupType.OTHER_GROUP,
dropdownText: 'Ajouter une autre activité de mission',
subItems: [
{ type: ActionType.NAUTICAL_EVENT, dropdownText: 'Sécu de manifestation nautique' },
{ type: ActionType.BAAEM_PERMANENCE, dropdownText: 'Permanence BAAEM' },
{ type: ActionType.VIGIMER, dropdownText: 'Permanence Vigimer' },
{ type: ActionType.ANTI_POLLUTION, dropdownText: 'Opération de lutte anti-pollution' },
{ type: ActionType.ILLEGAL_IMMIGRATION, dropdownText: `Lutte contre l'immigration illégale` },
{ type: ActionType.PUBLIC_ORDER, dropdownText: `Maintien de l'ordre public` },
{ type: ActionType.REPRESENTATION, dropdownText: 'Représentation' }
]
}
]

const TIMELINE_PAM_REGISTRY: TimelineRegistry = {
[ActionType.STATUS]: {
noPadding: true,
style: { minHeight: 0 },
title: 'Statut du navire',
component: MissionTimelineItemStatusCard
},
[ActionType.CONTROL]: {
style: { backgroundColor: THEME.color.white, borderColor: THEME.color.lightGray },
title: 'Contrôles',
icon: Icon.ControlUnit,
component: MissionTimelineItemControlCard
},
[ActionType.SURVEILLANCE]: {
style: { backgroundColor: '#e5e5eb', borderColor: THEME.color.lightGray },
icon: Icon.Observation,
title: 'Surveillance Environnement',
component: MissionTimelineItemSurveillanceCard
},
[ActionType.NOTE]: {
style: { backgroundColor: THEME.color.blueYonder25, borderColor: THEME.color.lightGray },
title: 'Note libre',
icon: Icon.Note,
component: MissionTimelineItemGenericCard
},
[ActionType.VIGIMER]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: 'Permanence Vigimer',
component: MissionTimelineItemGenericCard
},
[ActionType.NAUTICAL_EVENT]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: 'Manifestation nautique',
component: MissionTimelineItemGenericCard
},
[ActionType.RESCUE]: {
style: {
backgroundColor: THEME.color.goldenPoppy25,
borderColor: THEME.color.blueYonder25
},
title: 'Assistance et sauvetage',
icon: Icon.Rescue,
component: MissionTimelineItemRescueCard
},
[ActionType.REPRESENTATION]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: 'Représentation',
component: MissionTimelineItemGenericCard
},
[ActionType.PUBLIC_ORDER]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: `Maintien de l'ordre public`,
component: MissionTimelineItemGenericCard
},
[ActionType.ANTI_POLLUTION]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: 'Opération de lutte anti-pollution',
component: MissionTimelineItemGenericCard
},
[ActionType.BAAEM_PERMANENCE]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: 'Permanence BAAEM',
component: MissionTimelineItemGenericCard
},
[ActionType.ILLEGAL_IMMIGRATION]: {
style: {
backgroundColor: THEME.color.blueGray25,
borderColor: THEME.color.lightGray
},
icon: Icon.More,
title: `Lutte contre l'immigration illégale`,
component: MissionTimelineItemGenericCard
},
[ActionType.OTHER]: {
style: {},
icon: Icon.More,
component: MissionTimelineItemGenericCard
},
[ActionType.CONTACT]: {
style: { backgroundColor: THEME.color.blueYonder25, borderColor: THEME.color.lightGray },
icon: Icon.Observation,
title: 'Contact',
component: MissionTimelineItemGenericCard
}
}

interface PamTimelineRegistrHook {
timelineDropdownItems: TimelineDropdownItem[]
getTimeline: (actionType: ActionType) => Timeline
}

export function usePamTimelineRegistry(): PamTimelineRegistrHook {
const getTimeline = (actionType: ActionType) => TIMELINE_PAM_REGISTRY[actionType] ?? ({} as Timeline)
return { timelineDropdownItems: TIME_LINE_DROPDOWN_PAM_ITEMS, getTimeline }
}

0 comments on commit b812177

Please sign in to comment.