Skip to content

Commit

Permalink
Refactor Filter slice
Browse files Browse the repository at this point in the history
  • Loading branch information
louptheron committed Oct 7, 2024
1 parent 257f7e8 commit f816297
Show file tree
Hide file tree
Showing 46 changed files with 451 additions and 480 deletions.
3 changes: 3 additions & 0 deletions frontend/src/domain/entities/vessel/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,13 @@ export type TrackTypeRecordItem = {

export type VesselEnhancedLastPositionWebGLObject = {
coordinates: number[]
course: number
filterPreview: number // 0 is False, 1 is True - for WebGL
hasBeaconMalfunction: boolean
isAtPort: boolean
isFiltered: number // 0 is False, 1 is True - for WebGL
lastPositionSentAt: number
speed: number
vesselFeatureId: VesselFeatureId
vesselProperties: Vessel.VesselEnhancedObject
}
Expand Down
6 changes: 0 additions & 6 deletions frontend/src/domain/shared_slices/Global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ export const globalSlice = createSlice({
window.localStorage.setItem(lastSearchedVesselsLocalStorageKey, JSON.stringify(state.lastSearchedVessels))
},

closeVesselListModal(state) {
state.vesselListModalIsOpen = false
},

contractRightMenu(state) {
state.rightMenuIsOpen = false
},
Expand Down Expand Up @@ -178,10 +174,8 @@ export const globalSliceReducer = globalSlice.reducer

export const {
addSearchedVessel,
closeVesselListModal,
contractRightMenu,
expandRightMenu,
openVesselListModal,
removeError,
resetIsUpdatingVessels,
setBlockVesselsUpdate,
Expand Down
15 changes: 0 additions & 15 deletions frontend/src/domain/use_cases/vessel/addVesselListFilterZone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,3 @@ export const addVesselListFilterZone = (interactionType: InteractionType) => dis
})
)
}

export const closeDrawLayerModal = dispatch => {
dispatch(
setDisplayedComponents({
isDrawLayerModalDisplayed: false,
isInterestPointMapButtonDisplayed: true,
isMeasurementMapButtonDisplayed: true,
isVesselFiltersMapButtonDisplayed: true,
isVesselLabelsMapButtonDisplayed: true,
isVesselListDisplayed: true,
isVesselSearchDisplayed: true,
isVesselVisibilityMapButtonDisplayed: true
})
)
}
5 changes: 2 additions & 3 deletions frontend/src/domain/use_cases/vessel/showVessel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getVesselFromAPI } from '@api/vessel'
import { logbookActions } from '@features/Logbook/slice'
import { loadingVessel, resetLoadingVessel, setSelectedVessel, vesselsAdapter } from '@features/Vessel/slice'
import { loadingVessel, resetLoadingVessel, setSelectedVessel, vesselSelectors } from '@features/Vessel/slice'
import { DisplayedErrorKey } from '@libs/DisplayedError/constants'
import { captureMessage } from '@sentry/react'

Expand All @@ -23,8 +23,7 @@ export const showVessel =
try {
const { fishingActivities, map, vessel } = getState()
const { selectedVesselTrackRequest } = vessel
const vesselsSelector = vessel.vessels
const vessels = vesselsAdapter.getSelectors().selectAll(vesselsSelector)
const vessels = vesselSelectors.selectAll(getState())
const { defaultVesselTrackDepth } = map
const { areFishingActivitiesShowedOnMap } = fishingActivities
// TODO How to handle both the control unit dialog and the vessel sidebar ?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { COLORS } from '@constants/constants'
import { StyledModalHeader } from '@features/commonComponents/StyledModalHeader'
import { TextInput, Icon, Size } from '@mtes-mct/monitor-ui'
import { addFilter } from '@features/Filter/useCases/addFilter'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { Icon, Size, TextInput } from '@mtes-mct/monitor-ui'
import { useState } from 'react'
import { CirclePicker } from 'react-color'
import { Modal } from 'rsuite'
import styled from 'styled-components'
import { v4 as uuidv4 } from 'uuid'

import { TagList } from './TagList'
import { TagList } from './VesselFilters/TagList'

type SaveVesselFiltersModalProps = Readonly<{
addFilter: (filter: { color: string; filters: any; name: string; showed: boolean; uuid: string }) => void
closeAndResetVesselList: () => void
filters: any
isOpen: boolean
setIsOpen: (isOpen: boolean) => void
}>
export function SaveVesselFiltersModal({
addFilter,
closeAndResetVesselList,
filters,
isOpen,
setIsOpen
}: SaveVesselFiltersModalProps) {
const dispatch = useMainAppDispatch()
const [filterName, setFilterName] = useState<string | undefined>(undefined)
const [filterColor, setFilterColor] = useState('#2c6e49')

Expand All @@ -39,7 +40,7 @@ export function SaveVesselFiltersModal({
uuid: uuidv4()
}

addFilter(filter)
dispatch(addFilter(filter))

setIsOpen(false)
setFilterName('')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
import { COLORS } from '@constants/constants'
import { hideAllFilters } from '@features/Filter/useCases/hideAllFilters'
import { removeFilter } from '@features/Filter/useCases/removeFilter'
import { showFilter } from '@features/Filter/useCases/showFilter'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { useState } from 'react'
import styled from 'styled-components'

import { TagList } from './TagList'
import ChevronIconSVG from '../../../../icons/Chevron_simple_gris.svg?react'
import CloseIconSVG from '../../../../icons/Croix_grise.svg?react'
import FilterSVG from '../../../../icons/Icone_filtres_dark.svg?react'
import ShowIconSVG from '../../../../icons/oeil_affiche.svg?react'
import HideIconSVG from '../../../../icons/oeil_masque.svg?react'
import ChevronIconSVG from '../../../icons/Chevron_simple_gris.svg?react'
import CloseIconSVG from '../../../icons/Croix_grise.svg?react'
import FilterSVG from '../../../icons/Icone_filtres_dark.svg?react'
import ShowIconSVG from '../../../icons/oeil_affiche.svg?react'
import HideIconSVG from '../../../icons/oeil_masque.svg?react'

import type { VesselFilter } from 'domain/types/filter'
import type { VesselFilter } from '../../types'

type FilterProps = Readonly<{
filter: VesselFilter
hideFilters: () => void
index: number
isLastItem: boolean
removeFilter: (uuid: string) => void
removeTagFromFilter: (removeObject: {
type: string | undefined
uuid: string | undefined
value: number | string
}) => void
showFilter: (uuid: string) => void
}>
export function Filter({
filter,
hideFilters,
index,
isLastItem,
removeFilter,
removeTagFromFilter,
showFilter
}: FilterProps) {
export function Filter({ filter, index, isLastItem }: FilterProps) {
const dispatch = useMainAppDispatch()
const [isOpen, setIsOpen] = useState(false)

return (
Expand All @@ -44,14 +33,14 @@ export function Filter({
{filter.name ? filter.name.replace(/_/g, ' ') : `Filtre n°${index}`}
</Text>
{filter.showed ? (
<ShowIcon onClick={() => hideFilters()} title="Cacher le filtre" />
<ShowIcon onClick={() => dispatch(hideAllFilters())} title="Cacher le filtre" />
) : (
<HideIcon onClick={() => showFilter(filter.uuid)} title="Afficher le filtre" />
<HideIcon onClick={() => dispatch(showFilter(filter.uuid))} title="Afficher le filtre" />
)}
<CloseIcon onClick={() => removeFilter(filter.uuid)} title="Supprimer le filtre de ma sélection" />
<CloseIcon onClick={() => dispatch(removeFilter(filter.uuid))} title="Supprimer le filtre de ma sélection" />
</FilterItem>
<FilterTags $isLastItem={isLastItem} $isOpen={isOpen}>
<TagList filters={filter.filters} removeTagFromFilter={removeTagFromFilter} uuid={filter.uuid} />
<TagList filters={filter.filters} uuid={filter.uuid} />
</FilterTags>
</FilterWrapper>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { hideOrShowNonFilteredVessels } from '@features/Filter/useCases/hideOrShowNonFilteredVessels'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { useMainAppSelector } from '@hooks/useMainAppSelector'
import styled from 'styled-components'

import { setDisplayedComponents } from '../../../../../domain/shared_slices/DisplayedComponent'
import { MapPropertyTrigger } from '../../../../commonComponents/MapPropertyTrigger'
import HidingOtherVesselsSVG from '../../../../icons/Bouton_masquer_pistes_actif.svg?react'
import ShowingOtherVesselsSVG from '../../../../icons/Bouton_masquer_pistes_inactif.svg?react'
import { setDisplayedComponents } from '../../../../domain/shared_slices/DisplayedComponent'
import { MapPropertyTrigger } from '../../../commonComponents/MapPropertyTrigger'
import HidingOtherVesselsSVG from '../../../icons/Bouton_masquer_pistes_actif.svg?react'
import ShowingOtherVesselsSVG from '../../../icons/Bouton_masquer_pistes_inactif.svg?react'

type FilterParametersProps = Readonly<{
nonFilteredVesselsAreHidden: boolean
setNonFilteredVesselsAreHidden: (isChecked: boolean) => void
}>
export function FilterParameters({
nonFilteredVesselsAreHidden,
setNonFilteredVesselsAreHidden
}: FilterParametersProps) {
export function FilterParameters() {
const dispatch = useMainAppDispatch()
const nonFilteredVesselsAreHidden = useMainAppSelector(state => state.filter.nonFilteredVesselsAreHidden)

const handleCreateFilter = () => {
dispatch(
Expand All @@ -35,7 +31,7 @@ export function FilterParameters({
Icon={nonFilteredVesselsAreHidden ? ShowingOtherVesselsSVG : HidingOtherVesselsSVG}
inverse
text="les autres navires"
updateBooleanProperty={isChecked => setNonFilteredVesselsAreHidden(isChecked)}
updateBooleanProperty={isChecked => dispatch(hideOrShowNonFilteredVessels(isChecked))}
/>
</Wrapper>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import { removeTagFromFilter } from '@features/Filter/useCases/removeTagFromFilter'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { Icon, THEME } from '@mtes-mct/monitor-ui'
import styled from 'styled-components'

import type { FilterTag as FilterTagType } from '@features/Filter/types'

type FilterTagProps = Readonly<{
iconElement: JSX.Element | undefined
removeTagFromFilter:
| ((removeObject: { type: string | undefined; uuid: string | undefined; value: number | string }) => void)
| undefined
tag: FilterTagType
text: string
type: string | undefined
uuid: string | undefined
value: number | string
}>
export function FilterTag({ iconElement, removeTagFromFilter, text, type, uuid, value }: FilterTagProps) {
const callRemoveTagFromFilter = () => {
if (!removeTagFromFilter) {
return
}

const removeObject = { type, uuid, value }

removeTagFromFilter(removeObject)
}
export function FilterTag({ iconElement, tag, text, uuid }: FilterTagProps) {
const dispatch = useMainAppDispatch()

return (
<TagWrapper>
Expand All @@ -29,7 +21,7 @@ export function FilterTag({ iconElement, removeTagFromFilter, text, type, uuid,
<CloseIcon
color={THEME.color.gunMetal}
data-cy="vessel-filter-remove-tag"
onClick={callRemoveTagFromFilter}
onClick={() => dispatch(removeTagFromFilter({ ...tag, uuid }))}
size={10}
/>
</TagWrapper>
Expand Down
67 changes: 67 additions & 0 deletions frontend/src/features/Filter/components/VesselFilters/Filters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { COLORS } from '@constants/constants'
import { useMainAppSelector } from '@hooks/useMainAppSelector'
import { useMemo } from 'react'
import styled from 'styled-components'

import { Filter } from './Filter'
import { FilterParameters } from './FilterParameters'
import { MapBox } from '../../../../domain/entities/map/constants'
import { MapToolBox } from '../../../MainWindow/components/MapButtons/shared/MapToolBox'

export function Filters() {
const filters = useMainAppSelector(state => state.filter.filters)
const rightMapBoxOpened = useMainAppSelector(state => state.global.rightMapBoxOpened)

const isOpen = useMemo(() => rightMapBoxOpened === MapBox.FILTERS, [rightMapBoxOpened])

return (
<VesselFilterBox $isOpen={isOpen}>
<Header $isFirst>Mes filtres</Header>
{filters.length > 0 ? (
<FiltersSelectedList>
{filters.map((filter, index) => (
<Filter key={filter.uuid} filter={filter} index={index + 1} isLastItem={filters.length === index + 1} />
))}
</FiltersSelectedList>
) : (
<LastPositionInfo>Aucun filtre</LastPositionInfo>
)}
<FilterParameters />
</VesselFilterBox>
)
}

const FiltersSelectedList = styled.ul`
margin: 0;
background-color: ${COLORS.white};
border-radius: 0;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
padding: 0;
max-height: 550px;
overflow-x: hidden;
color: ${COLORS.gunMetal};
`

const LastPositionInfo = styled.div`
font-size: 13px;
margin: 15px;
color: ${COLORS.gunMetal};
`

const Header = styled.div<{
$isFirst: boolean
}>`
background: ${COLORS.charcoal};
color: ${COLORS.gainsboro};
padding: 9px 0 7px 15px;
font-size: 16px;
text-align: left;
border-top-left-radius: ${p => (p.$isFirst ? '2px' : '0')};
border-top-right-radius: ${p => (p.$isFirst ? '2px' : '0')};
`

const VesselFilterBox = styled(MapToolBox)`
width: 305px;
top: 124px;
`
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import styled from 'styled-components'

import FilterControlSVG from '../../../../icons/Label_controle.svg?react'
import FilterGearSVG from '../../../../icons/Label_engin_de_peche.svg?react'
import FilterSpeciesSVG from '../../../../icons/Label_poisson.svg?react'
import FilterDistrictSVG from '../../../../icons/Label_quartier.svg?react'
import FilterFleetSegmentSVG from '../../../../icons/Label_segment_de_flotte.svg?react'
import FilterLengthSVG from '../../../../icons/Label_taille_navire.svg?react'
import FilterZoneSVG from '../../../../icons/Label_zone.svg?react'
import FilterControlSVG from '../../../icons/Label_controle.svg?react'
import FilterGearSVG from '../../../icons/Label_engin_de_peche.svg?react'
import FilterSpeciesSVG from '../../../icons/Label_poisson.svg?react'
import FilterDistrictSVG from '../../../icons/Label_quartier.svg?react'
import FilterFleetSegmentSVG from '../../../icons/Label_segment_de_flotte.svg?react'
import FilterLengthSVG from '../../../icons/Label_taille_navire.svg?react'
import FilterZoneSVG from '../../../icons/Label_zone.svg?react'

const Zone = styled(FilterZoneSVG)`
height: 13px;
Expand Down
Loading

0 comments on commit f816297

Please sign in to comment.