Skip to content

Commit

Permalink
Add new completion and actions filters
Browse files Browse the repository at this point in the history
  • Loading branch information
louptheron committed Apr 8, 2024
1 parent a57150c commit aaa66e1
Show file tree
Hide file tree
Showing 37 changed files with 462 additions and 361 deletions.
5 changes: 5 additions & 0 deletions frontend/src/components/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from 'styled-components'

export const Bold = styled.span`
font-weight: 700;
`
31 changes: 0 additions & 31 deletions frontend/src/domain/entities/mission/utils.ts

This file was deleted.

6 changes: 3 additions & 3 deletions frontend/src/domain/entities/seaFront/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export type NoSeaFrontGroup = typeof NO_SEA_FRONT_GROUP

// TODO This should not be dedicated to Mission feature here.
export enum SeaFrontGroupLabel {
ALL = 'Toutes les missions',
ALL = 'TOUT',
MED = 'MED',
MEMN = 'MEMN',
NAMO = 'NAMO',
SA = 'SA',
OUTREMEROA = 'OUTRE-MER OA',
OUTREMEROI = 'OUTRE-MER OI'
OUTREMEROA = 'O-M OA',
OUTREMEROI = 'O-M OI'
}

export enum SeaFront {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Mission } from '@features/Mission/mission.types'
import { getMissionStatus } from '@features/Mission/utils'
import { expect } from '@jest/globals'
import { customDayjs } from '@mtes-mct/monitor-ui'

import { getMissionStatus } from '../utils'

// TODO Test all mission statuses.
describe('domain/entities/mission/utils.getMissionStatus()', () => {
it('should return a first-letter-capitalized string', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getMissionCompletionFrontStatus } from '@features/Mission/components/MissionForm/utils'
import { MissionAction } from '@features/Mission/missionAction.types'
import { getMissionCompletionFrontStatus } from '@features/Mission/utils'
import { useMainAppSelector } from '@hooks/useMainAppSelector'

import FrontCompletionStatus = MissionAction.FrontCompletionStatus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { autoSaveMissionAction } from '@features/Mission/useCases/autoSaveMissio
import { deleteMission } from '@features/Mission/useCases/deleteMission'
import { deleteMissionAction } from '@features/Mission/useCases/deleteMissionAction'
import { saveMissionAndMissionActionsByDiff } from '@features/Mission/useCases/saveMissionAndMissionActionsByDiff'
import { getMissionStatus } from '@features/Mission/utils'
import { cleanMissionForm } from '@features/SideWindow/useCases/cleanMissionForm'
import { openSideWindowPath } from '@features/SideWindow/useCases/openSideWindowPath'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
Expand All @@ -26,7 +27,6 @@ import {
NotificationEvent
} from '@mtes-mct/monitor-ui'
import { assertNotNullish } from '@utils/assertNotNullish'
import { getMissionStatus } from 'domain/entities/mission/utils'
import { SideWindowMenuKey } from 'domain/entities/sideWindow/constants'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import styled from 'styled-components'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ExclamationPoint, Icon, Tag, THEME } from '@mtes-mct/monitor-ui'
import styled from 'styled-components'

import FrontCompletionStatus = MissionAction.FrontCompletionStatus
import FrontCompletionStatusLabel = MissionAction.FrontCompletionStatusLabel

type CompletionStatusTagProps = {
completion: FrontCompletionStatus
Expand All @@ -17,7 +18,7 @@ export function CompletionStatusTag({ completion }: CompletionStatusTagProps) {
Icon={Icon.Confirm}
iconColor={THEME.color.mediumSeaGreen}
>
Complétée
{FrontCompletionStatusLabel.COMPLETED}
</StyledTag>
)
case FrontCompletionStatus.UP_TO_DATE:
Expand All @@ -28,20 +29,22 @@ export function CompletionStatusTag({ completion }: CompletionStatusTagProps) {
Icon={Icon.Confirm}
iconColor={THEME.color.mediumSeaGreen}
>
À jour
{FrontCompletionStatusLabel.UP_TO_DATE}
</StyledTag>
)
case FrontCompletionStatus.TO_COMPLETE_MISSION_ENDED:
return (
<StyledTag backgroundColor={THEME.color.gainsboro} color={THEME.color.maximumRed}>
<ExclamationPoint backgroundColor={THEME.color.maximumRed} color={THEME.color.white} size={15} />À compléter
<ExclamationPoint backgroundColor={THEME.color.maximumRed} color={THEME.color.white} size={15} />
{FrontCompletionStatusLabel.TO_COMPLETE}
</StyledTag>
)

case FrontCompletionStatus.TO_COMPLETE:
return (
<StyledTag backgroundColor={THEME.color.gainsboro} color={THEME.color.charcoal}>
<ExclamationPoint backgroundColor={THEME.color.charcoal} color={THEME.color.white} size={15} />À compléter
<ExclamationPoint backgroundColor={THEME.color.charcoal} color={THEME.color.white} size={15} />
{FrontCompletionStatusLabel.TO_COMPLETE}
</StyledTag>
)
default:
Expand Down
54 changes: 0 additions & 54 deletions frontend/src/features/Mission/components/MissionForm/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { MainFormLiveSchema } from '@features/Mission/components/MissionForm/MainForm/schemas'
import { FormError, FormErrorCode } from '@libs/FormError'
import { validateRequiredFormValues } from '@utils/validateRequiredFormValues'
import { difference, omit } from 'lodash'

import { MISSION_ACTION_FORM_VALUES_SKELETON } from './constants'
import { getMissionStatus } from '../../../../domain/entities/mission/utils'
import { Mission } from '../../mission.types'
import { MissionAction } from '../../missionAction.types'

Expand All @@ -13,8 +11,6 @@ import type { Undefine } from '@mtes-mct/monitor-ui'
import type { LegacyControlUnit } from 'domain/types/legacyControlUnit'

import MissionActionType = MissionAction.MissionActionType
import CompletionStatus = MissionAction.CompletionStatus
import FrontCompletionStatus = MissionAction.FrontCompletionStatus

/**
*
Expand Down Expand Up @@ -164,53 +160,3 @@ export function getValidMissionDataControlUnit(

return validMissionDataControlUnit
}

export function getMissionCompletion(
mission: Partial<MissionMainFormValues> | Mission.Mission | undefined,
actionsCompletion: (CompletionStatus | undefined)[] | undefined
): CompletionStatus {
if (!mission || !actionsCompletion) {
return CompletionStatus.TO_COMPLETE
}

const hasAtLeastOnUncompletedAction = actionsCompletion.find(
completion => !completion || completion === CompletionStatus.TO_COMPLETE
)

if (hasAtLeastOnUncompletedAction || !MainFormLiveSchema.isValidSync(mission)) {
return CompletionStatus.TO_COMPLETE
}

return CompletionStatus.COMPLETED
}

export function getMissionCompletionFrontStatus(
mission: Partial<MissionMainFormValues> | Mission.Mission | undefined,
actionsCompletion: (CompletionStatus | undefined)[] | undefined
): FrontCompletionStatus {
const missionCompletion = getMissionCompletion(mission, actionsCompletion)

if (!mission) {
return FrontCompletionStatus.TO_COMPLETE
}

const missionStatus = getMissionStatus(mission)

if (missionStatus === Mission.MissionStatus.IN_PROGRESS && missionCompletion === CompletionStatus.COMPLETED) {
return FrontCompletionStatus.UP_TO_DATE
}

if (missionStatus === Mission.MissionStatus.IN_PROGRESS && missionCompletion === CompletionStatus.TO_COMPLETE) {
return FrontCompletionStatus.TO_COMPLETE
}

if (missionStatus === Mission.MissionStatus.DONE && missionCompletion === CompletionStatus.COMPLETED) {
return FrontCompletionStatus.COMPLETED
}

if (missionStatus === Mission.MissionStatus.DONE && missionCompletion === CompletionStatus.TO_COMPLETE) {
return FrontCompletionStatus.TO_COMPLETE_MISSION_ENDED
}

return FrontCompletionStatus.TO_COMPLETE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { MissionAction } from '@features/Mission/missionAction.types'
import { ExclamationPoint, Icon, THEME } from '@mtes-mct/monitor-ui'
import styled from 'styled-components'

import FrontCompletionStatus = MissionAction.FrontCompletionStatus
import FrontCompletionStatusLabel = MissionAction.FrontCompletionStatusLabel

export function CompletionStatusLabel({ completion = undefined }: { completion?: FrontCompletionStatus }) {
if (!completion) {
return <>-</>
}

switch (completion) {
case FrontCompletionStatus.COMPLETED:
return (
<CompletionStatusContainer>
<Icon.Confirm color={THEME.color.mediumSeaGreen} />
<Text $color={THEME.color.mediumSeaGreen}>{FrontCompletionStatusLabel.COMPLETED}</Text>
</CompletionStatusContainer>
)
case FrontCompletionStatus.UP_TO_DATE:
return (
<CompletionStatusContainer>
<Icon.Confirm color={THEME.color.mediumSeaGreen} />
<Text $color={THEME.color.mediumSeaGreen}>{FrontCompletionStatusLabel.UP_TO_DATE}</Text>
</CompletionStatusContainer>
)
case FrontCompletionStatus.TO_COMPLETE_MISSION_ENDED:
return (
<CompletionStatusContainer>
<ExclamationPoint backgroundColor={THEME.color.maximumRed} color={THEME.color.white} size={15} />
<Text $color={THEME.color.maximumRed}>{FrontCompletionStatusLabel.TO_COMPLETE}</Text>
</CompletionStatusContainer>
)

case FrontCompletionStatus.TO_COMPLETE:
return (
<CompletionStatusContainer>
<ExclamationPoint backgroundColor={THEME.color.charcoal} color={THEME.color.white} size={15} />
<Text $color={THEME.color.charcoal}>{FrontCompletionStatusLabel.TO_COMPLETE}</Text>
</CompletionStatusContainer>
)
default:
return null
}
}

const CompletionStatusContainer = styled.div`
display: inline-flex;
align-items: center;
gap: 4px;
`

const Text = styled.span<{ $color: string }>`
color: ${p => p.$color};
`
66 changes: 38 additions & 28 deletions frontend/src/features/Mission/components/MissionList/FilterBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { useGetLegacyControlUnitsQuery } from '@api/legacyControlUnit'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { useMainAppSelector } from '@hooks/useMainAppSelector'
import {
FormikCheckbox,
FormikCheckPicker,
FormikDateRangePicker,
FormikEffect,
FormikMultiSelect,
FormikSelect,
Icon,
Size,
Expand Down Expand Up @@ -116,24 +117,19 @@ export function FilterBar({ onQueryChange, searchQuery }: FilterBarProps) {
options={MISSION_FILTER_OPTIONS[MissionFilterType.DATE_RANGE]}
placeholder="Période"
/>
<FormikSelect
isLabelHidden
isTransparent
label="Origine"
name={MissionFilterType.SOURCE}
options={MISSION_FILTER_OPTIONS[MissionFilterType.SOURCE]}
placeholder="Origine"
/>
<FormikMultiSelect
<FormikCheckPicker
isLabelHidden
isTransparent
label="Statut"
name={MissionFilterType.STATUS}
options={MISSION_FILTER_OPTIONS[MissionFilterType.STATUS]}
placeholder="Statut"
renderValue={(_, items) => (items.length > 0 ? <OptionValue>Statut ({items.length}) </OptionValue> : <></>)}
label="Type de mission"
name={MissionFilterType.TYPE}
options={MISSION_FILTER_OPTIONS[MissionFilterType.TYPE]}
placeholder="Type de mission"
renderValue={(_, items) =>
items.length > 0 ? <OptionValue>Type de mission ({items.length}) </OptionValue> : <></>
}
style={tagPickerStyle}
/>
<FormikMultiSelect
<FormikCheckPicker
disabled={administrationsAsOptions.length === 0}
isLabelHidden
isTransparent
Expand All @@ -145,9 +141,9 @@ export function FilterBar({ onQueryChange, searchQuery }: FilterBarProps) {
items.length > 0 ? <OptionValue>Administration ({items.length}) </OptionValue> : <></>
}
searchable
style={{ minWidth: 200 }}
style={tagPickerStyle}
/>
<FormikMultiSelect
<FormikCheckPicker
key={unitMultiSelectKey}
disabled={activeAndFilteredUnitsAsOptions.length === 0}
isLabelHidden
Expand All @@ -158,27 +154,40 @@ export function FilterBar({ onQueryChange, searchQuery }: FilterBarProps) {
placeholder="Unité"
renderValue={(_, items) => (items.length > 0 ? <OptionValue>Unité ({items.length}) </OptionValue> : <></>)}
searchable
style={{ minWidth: 200 }}
style={tagPickerStyle}
/>
<FormikMultiSelect
<FormikCheckPicker
isLabelHidden
isTransparent
label="Type de mission"
name={MissionFilterType.TYPE}
options={MISSION_FILTER_OPTIONS[MissionFilterType.TYPE]}
placeholder="Type de mission"
label="Statut de mission"
name={MissionFilterType.STATUS}
options={MISSION_FILTER_OPTIONS[MissionFilterType.STATUS]}
placeholder="Statut de mission"
renderValue={(_, items) => (items.length > 0 ? <OptionValue>Statut ({items.length}) </OptionValue> : <></>)}
style={tagPickerStyle}
/>
<FormikCheckPicker
isLabelHidden
isTransparent
label="Etat des données"
name={MissionFilterType.COMPLETION_STATUS}
options={MISSION_FILTER_OPTIONS[MissionFilterType.COMPLETION_STATUS]}
placeholder="Etat des données"
renderValue={(_, items) =>
items.length > 0 ? <OptionValue>Type de mission ({items.length}) </OptionValue> : <></>
items.length > 0 ? <OptionValue>Etat des données ({items.length}) </OptionValue> : <></>
}
style={tagPickerStyle}
/>
<FormikCheckbox label="Missions avec actions CNSP" name={MissionFilterType.WITH_ACTIONS} />
</Row>

<FormikFilterTagBar
filterLabelEnums={MISSION_FILTER_LABEL_ENUMS}
ignoredFilterKeys={[
MissionFilterType.CUSTOM_DATE_RANGE,
MissionFilterType.DATE_RANGE,
MissionFilterType.SOURCE
MissionFilterType.SOURCE,
MissionFilterType.WITH_ACTIONS
]}
>
{isCustomDateRangeOpen && (
Expand All @@ -202,6 +211,7 @@ const Wrapper = styled.div`

const Row = styled.div`
display: flex;
align-items: center;
> div {
min-width: 200px;
Expand All @@ -223,11 +233,11 @@ const Row = styled.div`
}
`

const tagPickerStyle = { width: 184 }

export const OptionValue = styled.span`
display: flex;
overflow: hidden;
padding: 4px 0 0 8px;
pointer-events: none;
text-overflow: ellipsis;
white-space: nowrap;
`
Loading

0 comments on commit aaa66e1

Please sign in to comment.