Skip to content

Commit

Permalink
Merge pull request #897 from GlobalFishingWatch/vessel-history/perfor…
Browse files Browse the repository at this point in the history
…mance-improvements

Vessel history/performance improvements
  • Loading branch information
j8seangel authored Sep 8, 2021
2 parents 463b45b + 9bad2ee commit 9feea83
Show file tree
Hide file tree
Showing 14 changed files with 147 additions and 115 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-planes-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@globalfishingwatch/ui-components': minor
---

not mount every tab ui-component until used
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ exports[`<App /> renders home screen when not loading 1`] = `
class="input"
placeholder="Search vessels by name, MMSI, IMO"
role="search"
spellcheck="false"
type="search"
value=""
/>
Expand Down
14 changes: 6 additions & 8 deletions applications/vessel-history/src/features/map/Map.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ReactElement, useCallback, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useSelector } from 'react-redux'
import { InteractiveMap } from '@globalfishingwatch/react-map-gl'
import { useLayerComposer, useMapClick } from '@globalfishingwatch/react-hooks'
import { ExtendedStyleMeta } from '@globalfishingwatch/layer-composer'
Expand All @@ -20,7 +20,6 @@ import '@globalfishingwatch/mapbox-gl/dist/mapbox-gl.css'
const Map = (): ReactElement => {
const map = useMapInstance()
const mapRef = useRef<any>(null)
const dispatch = useDispatch()
const { selectVesselEventOnClick } = useMapEvents()
const { dispatchQueryParams } = useLocationConnect()
const { generatorsConfig, globalConfig, styleTransformations } = useGeneratorsConnect()
Expand All @@ -40,25 +39,24 @@ const Map = (): ReactElement => {
style?.metadata as ExtendedStyleMeta,
map
)

const url = useSelector(selectUrlViewport)

const onMapResize = useCallback(() => {
if (url && mapRef){
const {latitude, longitude} = url
if (url && mapRef) {
const { latitude, longitude } = url
if (mapRef.current?.getMap().getCenter().lat !== latitude) {
// avoid to center in every resize (if happen)
setMapCoordinates({
latitude,
longitude,
bearing: 0,
pitch: 0,
zoom: 8
zoom: 8,
})
}
}
},[setMapCoordinates, url]
)
}, [setMapCoordinates, url])

if (ENABLE_FLYTO) {
let flying = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Fragment, useCallback, useState } from 'react'
import { useSelector } from 'react-redux'
import cx from 'classnames'
import { useTranslation } from 'react-i18next'
import AutoSizer from 'react-virtualized-auto-sizer'
Expand All @@ -7,20 +8,22 @@ import Link from 'redux-first-router-link'
import { Button, Icon, IconButton, Modal, Spinner } from '@globalfishingwatch/ui-components'
import { useAppDispatch } from 'features/app/app.hooks'
import { SETTINGS } from 'routes/routes'
import { RenderedEvent } from 'features/vessels/activity/vessels-activity.selectors'
import { useActivityHighlightsConnect } from 'features/vessels/activity/vessel-highlight.hooks'
import {
RenderedEvent,
selectEventsLoading,
selectFilteredActivityHighlightEvents,
} from 'features/vessels/activity/vessels-activity.selectors'
import { selectAnyHighlightsSettingDefined } from 'features/vessels/activity/vessels-highlight.selectors'
import ActivityModalContent from './activity/ActivityModalContent'
import ActivityItem from './activity/ActivityItem'
import styles from './activity/Activity.module.css'

const Highlights: React.FC = (): React.ReactElement => {
const dispatch = useAppDispatch()
const { t } = useTranslation()
const {
highlightedEvents: events,
highlightsSettingDefined: anyHighlightsSettingDefined,
loading,
} = useActivityHighlightsConnect()
const anyHighlightsSettingDefined = useSelector(selectAnyHighlightsSettingDefined)
const events = useSelector(selectFilteredActivityHighlightEvents)
const loading = useSelector(selectEventsLoading)

const [isModalOpen, setIsOpen] = useState(false)
const [selectedEvent, setSelectedEvent] = useState<RenderedEvent>()
Expand All @@ -33,11 +36,9 @@ const Highlights: React.FC = (): React.ReactElement => {

return (
<div
className={cx(
styles.activityContainer,
styles.highlightsContainer,
!anyHighlightsSettingDefined || (events && events.length === 0) ? styles.noData : {}
)}
className={cx(styles.activityContainer, styles.highlightsContainer, {
[styles.noData]: anyHighlightsSettingDefined || (events && events.length === 0),
})}
>
<div className={styles.divider}></div>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { memoize } from 'lodash'
import { createSelector } from '@reduxjs/toolkit'
import { RootState } from 'store'
import { MarineRegionType, Region, RegionId, regionsEntityAdapter } from './regions.slice'
import { MarineRegionType, RegionId, regionsEntityAdapter } from './regions.slice'

const { selectById } = regionsEntityAdapter.getSelectors<RootState>((state) => state.regions)

const selectRegionsById = memoize((id: RegionId) =>
createSelector([(state: RootState) => state], (state) => {
const regionList = selectById(state, id)
const result = [...(regionList?.data ?? [])]
result.sort((a, b) => (a.label < b.label ? -1 : 1))
return result
return regionList?.data
})
)

Expand All @@ -21,19 +19,19 @@ export const selectRFMOs = selectRegionsById(MarineRegionType.rfmo)
export const selectRegionsStatus = (state: RootState) => state.regions.status

export const selectEezById = memoize((id: RegionId) =>
createSelector([selectEEZs], (eezs: Region[]) => {
if (!id) {
createSelector([selectEEZs], (eezs) => {
if (!id || !eezs) {
return null
}
return eezs.find(eez => eez.id.toString() === id.toString())
return eezs.find((eez) => eez.id.toString() === id.toString())
})
)

export const selectRfmoById = memoize((id: RegionId) =>
createSelector([selectRFMOs], (rfmos: Region[]) => {
if (!id) {
createSelector([selectRFMOs], (rfmos) => {
if (!id || !rfmos) {
return null
}
return rfmos.find(rfmo => rfmo.id.toString() === id.toString())
return rfmos.find((rfmo) => rfmo.id.toString() === id.toString())
})
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const initialState: RegionsState = {
...asyncInitialState,
}

const sortRegionAlphabetically = (a: Region, b: Region) => (a.label < b.label ? -1 : 1)

export const fetchRegionsThunk = createAsyncThunk(
'regions/fetch',
async (_, { rejectWithValue }) => {
Expand All @@ -60,9 +62,9 @@ export const fetchRegionsThunk = createAsyncThunk(
options
)
const result: Regions[] = [
{ id: MarineRegionType.eez, data: eezs },
{ id: MarineRegionType.mpa, data: mpas },
{ id: MarineRegionType.rfmo, data: rfmos },
{ id: MarineRegionType.eez, data: eezs.sort(sortRegionAlphabetically) },
{ id: MarineRegionType.mpa, data: mpas.sort(sortRegionAlphabetically) },
{ id: MarineRegionType.rfmo, data: rfmos.sort(sortRegionAlphabetically) },
]
return result
} catch (e: any) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const ActivityEvents: React.FC<SettingsProps> = (props): React.ReactElement => {
const { setSettingOptions, setSetting } = useSettingsConnect()

const { anyOption, EEZ_REGIONS, RFMOS_REGIONS, MPAS_REGIONS, getOptions } =
useSettingsRegionsConnect(section, settings)
useSettingsRegionsConnect(section)

const eez = useMemo(
() => getOptions(EEZ_REGIONS, 'eezs', settings.eezs),
Expand All @@ -43,7 +43,7 @@ const ActivityEvents: React.FC<SettingsProps> = (props): React.ReactElement => {
[RFMOS_REGIONS, settings.rfmos, getOptions]
)
const mpa = useMemo(
() => getOptions(MPAS_REGIONS.map(truncateLabels), 'mpas', settings.mpas),
() => getOptions(MPAS_REGIONS?.map(truncateLabels), 'mpas', settings.mpas),
[MPAS_REGIONS, settings.mpas, getOptions]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const PortVisits: React.FC<SettingsProps> = (props): React.ReactElement => {
const { settings, section } = props
const { t } = useTranslation()
const { setSetting } = useSettingsConnect()
const { COUNTRIES, getOptions } = useSettingsRegionsConnect('portVisits', settings)
const { COUNTRIES, getOptions } = useSettingsRegionsConnect('portVisits')

const flags = useMemo(
() =>
Expand Down
25 changes: 13 additions & 12 deletions applications/vessel-history/src/features/settings/settings.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,17 @@ export const useSettingsConnect = () => {
}
}

export const useSettingsRegionsConnect = (
section: SettingEventSectionName,
settings: SettingsEvents
) => {
const onlyUnique = (value: Region, index: number, self: Region[]) => {
return self.map((item) => item.id).indexOf(value.id) === index
}

export const useSettingsRegionsConnect = (section: SettingEventSectionName) => {
const { t } = useTranslation()
const { setSettingOptions } = useSettingsConnect()

const onlyUnique = useCallback((value: Region, index: number, self: Region[]) => {
return self.map((item) => item.id).indexOf(value.id) === index
}, [])

const EEZ_REGIONS: Region[] = useSelector(selectEEZs)
const RFMOS_REGIONS: Region[] = useSelector(selectRFMOs).filter(onlyUnique)
const MPAS_REGIONS: Region[] = useSelector(selectMPAs)
const EEZ_REGIONS = useSelector(selectEEZs)
const RFMOS_REGIONS = useSelector(selectRFMOs)?.filter(onlyUnique)
const MPAS_REGIONS = useSelector(selectMPAs)
const COUNTRIES: Region[] = flags

const anyOption: MultiSelectOption<string> = useMemo(
Expand Down Expand Up @@ -96,7 +93,11 @@ export const useSettingsRegionsConnect = (
)

const getOptions = useCallback(
(availableOptions: MultiSelectOption[], field: string, selected?: string | string[]) => {
(
availableOptions: MultiSelectOption[] | undefined = [],
field: string,
selected?: string | string[]
) => {
const allOptions = [anyOption, ...availableOptions]
const selectedOptions = allOptions.filter((option) => selected?.includes(option.id))
const options = [
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { ActivityEvent, Regions } from 'types/activity'
import { selectEEZs, selectRFMOs } from 'features/regions/regions.selectors'
import { getEEZName } from 'utils/region-name-transform'
import { Region } from 'features/regions/regions.slice'
import { selectSettings } from 'features/settings/settings.slice'
import { filterActivityHighlightEvents } from './vessels-highlight.worker'

export interface RenderedEvent extends ActivityEvent {
color: string
Expand All @@ -24,6 +26,23 @@ export interface RenderedEvent extends ActivityEvent {
duration: number
}

export const selectEventsResources = createSelector(
[selectActiveTrackDataviews, selectResources],
(trackDataviews, resources) => {
return trackDataviews.flatMap((dataview) => {
return resolveDataviewDatasetResources(dataview, DatasetTypes.Events).flatMap(
(eventResource) => {
return resources[eventResource.url] || []
}
)
})
}
)

export const selectEventsLoading = createSelector([selectEventsResources], (resources) =>
resources.map((resource) => resource?.status).includes(ResourceStatus.Loading)
)

export const selectEventsForTracks = createSelector(
[selectActiveTrackDataviews, selectResources],
(trackDataviews, resources) => {
Expand Down Expand Up @@ -72,7 +91,7 @@ export const selectEventsForTracks = createSelector(

export const selectEventsWithRenderingInfo = createSelector(
[selectEventsForTracks, selectEEZs, selectRFMOs],
(eventsForTrack, eezs, rfmos) => {
(eventsForTrack, eezs = [], rfmos = []) => {
const eventsWithRenderingInfo: RenderedEvent[][] = eventsForTrack.map(({ dataview, data }) => {
return (data || []).map((event: ActivityEvent, index) => {
// const vesselName = event.vessel.name || event.vessel.id
Expand Down Expand Up @@ -141,8 +160,8 @@ export const selectEventsWithRenderingInfo = createSelector(
: '',
duration.minutes && duration.minutes > 0
? t('event.minuteAbbreviated', '{{count}}m', {
count: Math.round(duration.minutes as number),
})
count: Math.round(duration.minutes as number),
})
: '',
].join(' ')

Expand All @@ -168,6 +187,12 @@ export const selectEventsWithRenderingInfo = createSelector(
return eventsWithRenderingInfo.flat()
}
)
export const selectFilteredActivityHighlightEvents = createSelector(
[selectEventsWithRenderingInfo, selectSettings],
(eventsWithRenderingInfo, settings) => {
return filterActivityHighlightEvents(eventsWithRenderingInfo, settings)
}
)

const getEventRegionDescription = (event: ActivityEvent, eezs: Region[], rfmos: Region[]) => {
const getRegionNamesByType = (regionType: string, values: string[]) => {
Expand Down
Loading

0 comments on commit 9feea83

Please sign in to comment.