diff --git a/apps/fishing-map/features/app/selectors/app.timebar.selectors.ts b/apps/fishing-map/features/app/selectors/app.timebar.selectors.ts index 907f255c08..98ca7fbc64 100644 --- a/apps/fishing-map/features/app/selectors/app.timebar.selectors.ts +++ b/apps/fishing-map/features/app/selectors/app.timebar.selectors.ts @@ -40,6 +40,17 @@ export const selectTimebarSelectedEnvId = createSelector( } ) +const selectTimebarSelectedVGIdSelector = selectWorkspaceStateProperty('timebarSelectedVGId') +export const selectTimebarSelectedVGId = createSelector( + [selectTimebarSelectedVGIdSelector, selectTimebarVisualisation, selectEnvironmentalDataviews], + (timebarSelectedVGId, timebarVisualisation, envDataviews): string => { + if (timebarVisualisation === TimebarVisualisations.Environment) { + return timebarSelectedVGId || envDataviews[0]?.id + } + return timebarSelectedVGId + } +) + const selectTimebarGraphSelector = selectWorkspaceStateProperty('timebarGraph') export const selectTimebarGraph = createSelector( [selectTimebarGraphSelector, selectActiveVesselsDataviews], diff --git a/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts b/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts index e06adbb259..d4fbce7d50 100644 --- a/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts +++ b/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts @@ -29,7 +29,10 @@ import { } from 'routes/routes.selectors' import { getReportCategoryFromDataview } from 'features/area-report/reports.utils' import { selectViewOnlyVessel } from 'features/vessel/vessel.config.selectors' -import { selectTimebarSelectedEnvId } from 'features/app/selectors/app.timebar.selectors' +import { + selectTimebarSelectedEnvId, + selectTimebarSelectedVGId, +} from 'features/app/selectors/app.timebar.selectors' import { selectActiveVesselsDataviews, selectAllDataviewInstancesResolved, @@ -48,6 +51,7 @@ import { selectDetectionsDataviews, selectEnvironmentalDataviews, selectEventsDataviews, + selectVesselGroupDataviews, } from './dataviews.categories.selectors' const REPORT_ONLY_VISIBLE_LAYERS = [ @@ -217,6 +221,11 @@ export const selectActiveDetectionsDataviews = createSelector( (dataviews): UrlDataviewInstance[] => dataviews?.filter((d) => d.config?.visible) ) +export const selectActiveVesselGroupDataviews = createSelector( + [selectVesselGroupDataviews], + (dataviews): UrlDataviewInstance[] => dataviews?.filter((d) => d.config?.visible) +) + export const selectDetectionsMergedDataviewId = createSelector( [selectActiveDetectionsDataviews], (dataviews): string => { @@ -323,15 +332,32 @@ export const selectActiveActivityDataviewsByVisualisation = ( selectActiveReportActivityDataviews, selectActiveDetectionsDataviews, selectActiveHeatmapEnvironmentalDataviewsWithoutStatic, + selectActiveVesselGroupDataviews, selectTimebarSelectedEnvId, + selectTimebarSelectedVGId, ], - (activityDataviews, detectionsDataviews, environmentDataviews, timebarSelectedEnvId) => { + ( + activityDataviews, + detectionsDataviews, + environmentDataviews, + vesselGroupDataviews, + timebarSelectedEnvId, + timebarSelectedVGId + ) => { if (timebarVisualisation === TimebarVisualisations.HeatmapActivity) { return activityDataviews } if (timebarVisualisation === TimebarVisualisations.HeatmapDetections) { return detectionsDataviews } + if (timebarVisualisation === TimebarVisualisations.VesselGroup) { + const selectedVGDataview = + timebarSelectedVGId && vesselGroupDataviews.find((d) => d.id === timebarSelectedVGId) + + if (selectedVGDataview) { + return [selectedVGDataview] + } else if (vesselGroupDataviews[0]) return [vesselGroupDataviews[0]] + } const selectedEnvDataview = timebarSelectedEnvId && environmentDataviews.find((d) => d.id === timebarSelectedEnvId) diff --git a/apps/fishing-map/features/timebar/Timebar.tsx b/apps/fishing-map/features/timebar/Timebar.tsx index 2ec12dbd9a..2fede5689f 100644 --- a/apps/fishing-map/features/timebar/Timebar.tsx +++ b/apps/fishing-map/features/timebar/Timebar.tsx @@ -408,6 +408,7 @@ const TimebarWrapper = () => { {(timebarVisualisation === TimebarVisualisations.HeatmapActivity || timebarVisualisation === TimebarVisualisations.HeatmapDetections || + timebarVisualisation === TimebarVisualisations.VesselGroup || timebarVisualisation === TimebarVisualisations.Environment) && ( )} diff --git a/apps/fishing-map/features/timebar/TimebarSettings.tsx b/apps/fishing-map/features/timebar/TimebarSettings.tsx index 27617a31ad..5c32999fe3 100644 --- a/apps/fishing-map/features/timebar/TimebarSettings.tsx +++ b/apps/fishing-map/features/timebar/TimebarSettings.tsx @@ -12,6 +12,7 @@ import { selectActiveReportActivityDataviews, selectActiveDetectionsDataviews, selectActiveHeatmapEnvironmentalDataviewsWithoutStatic, + selectActiveVesselGroupDataviews, } from 'features/dataviews/selectors/dataviews.selectors' import { getEventLabel } from 'utils/analytics' import { ReactComponent as AreaIcon } from 'assets/icons/timebar-area.svg' @@ -25,10 +26,12 @@ import { selectActiveTrackDataviews, selectActiveVesselsDataviews, } from 'features/dataviews/selectors/dataviews.instances.selectors' +import { formatInfoField } from 'utils/info' import { useTimebarVisualisationConnect, useTimebarGraphConnect, useTimebarEnvironmentConnect, + useTimebarVesselGroupConnect, } from './timebar.hooks' import styles from './TimebarSettings.module.css' @@ -67,6 +70,7 @@ const TimebarSettings = ({ loading = false }: { loading: boolean }) => { selectActiveHeatmapEnvironmentalDataviewsWithoutStatic ) const activeTrackDataviews = useSelector(selectActiveTrackDataviews) + const activeVesselGroupDataviews = useSelector(selectActiveVesselGroupDataviews) const isStandaloneVesselLocation = useSelector(selectIsVesselLocation) const vesselIds = activeTrackDataviews.map((v) => v.id) const trackLayers = useGetDeckLayers(vesselIds) @@ -78,6 +82,7 @@ const TimebarSettings = ({ loading = false }: { loading: boolean }) => { const activeVesselsDataviews = useSelector(selectActiveVesselsDataviews) const { timebarVisualisation, dispatchTimebarVisualisation } = useTimebarVisualisationConnect() const { timebarSelectedEnvId, dispatchTimebarSelectedEnvId } = useTimebarEnvironmentConnect() + const { timebarSelectedVGId, dispatchTimebarSelectedVGId } = useTimebarVesselGroupConnect() const { timebarGraph, dispatchTimebarGraph } = useTimebarGraphConnect() const timebarGraphEnabled = activeVesselsDataviews && activeVesselsDataviews!?.length <= 2 @@ -102,6 +107,10 @@ const TimebarSettings = ({ loading = false }: { loading: boolean }) => { dispatchTimebarVisualisation(TimebarVisualisations.Environment) dispatchTimebarSelectedEnvId(environmentalDataviewId) } + const setVesselGroupActive = (vesselGroupDataviewId: string) => { + dispatchTimebarVisualisation(TimebarVisualisations.VesselGroup) + dispatchTimebarSelectedVGId(vesselGroupDataviewId) + } const setVesselActive = () => { dispatchTimebarVisualisation(TimebarVisualisations.Vessel) dispatchTimebarGraph(TimebarGraphs.None) @@ -174,6 +183,26 @@ const TimebarSettings = ({ loading = false }: { loading: boolean }) => { tooltip={detectionsTooltipLabel} onClick={setHeatmapDetectionsActive} /> + {activeVesselGroupDataviews.map((vgDataview) => { + return ( + + } + active={ + timebarVisualisation === TimebarVisualisations.VesselGroup && + timebarSelectedVGId === vgDataview.id + } + tooltip={activityTooltipLabel} + onClick={() => setVesselGroupActive(vgDataview.id)} + /> + ) + })} )} { return { timebarSelectedEnvId, dispatchTimebarSelectedEnvId } } +export const useTimebarVesselGroupConnect = () => { + const { dispatchQueryParams } = useLocationConnect() + const timebarSelectedVGId = useSelector(selectTimebarSelectedVGId) + + const dispatchTimebarSelectedVGId = useCallback( + (timebarSelectedVGId: string) => { + dispatchQueryParams({ timebarSelectedVGId }) + }, + [dispatchQueryParams] + ) + + return { timebarSelectedVGId, dispatchTimebarSelectedVGId } +} + export const useTimebarGraphConnect = () => { const timebarGraph = useSelector(selectTimebarGraph) const { dispatchQueryParams } = useLocationConnect() diff --git a/apps/fishing-map/features/timebar/timebar.selectors.ts b/apps/fishing-map/features/timebar/timebar.selectors.ts index e8b9cf75e1..97b13f9b08 100644 --- a/apps/fishing-map/features/timebar/timebar.selectors.ts +++ b/apps/fishing-map/features/timebar/timebar.selectors.ts @@ -5,6 +5,7 @@ import { TimebarVisualisations } from 'types' import { selectDataviewInstancesResolved } from 'features/dataviews/selectors/dataviews.instances.selectors' import { selectTimebarSelectedEnvId, + selectTimebarSelectedVGId, selectTimebarVisualisation, } from 'features/app/selectors/app.timebar.selectors' import { AVAILABLE_END, AVAILABLE_START } from 'data/config' @@ -14,6 +15,7 @@ import { selectActiveActivityDataviews, selectActiveDetectionsDataviews, selectActiveHeatmapEnvironmentalDataviewsWithoutStatic, + selectActiveVesselGroupDataviews, } from 'features/dataviews/selectors/dataviews.selectors' import { selectActivityVisualizationMode, @@ -54,8 +56,10 @@ export const selectTimebarSelectedDataviews = createSelector( [ selectTimebarVisualisation, selectTimebarSelectedEnvId, + selectTimebarSelectedVGId, selectActiveDetectionsDataviews, selectActiveActivityDataviews, + selectActiveVesselGroupDataviews, selectActiveHeatmapEnvironmentalDataviewsWithoutStatic, selectReportCategory, selectIsAnyReportLocation, @@ -63,8 +67,10 @@ export const selectTimebarSelectedDataviews = createSelector( ( timebarVisualisation, timebarSelectedEnvId, + timebarSelectedVGId, detectionsDataviews, activityDataviews, + vesselGroupDataviews, environmentalDataviews, reportCategory, isReportLocation @@ -73,6 +79,9 @@ export const selectTimebarSelectedDataviews = createSelector( if (timebarVisualisation === TimebarVisualisations.Environment) { return environmentalDataviews.filter((d) => d.id === timebarSelectedEnvId) } + if (timebarVisualisation === TimebarVisualisations.VesselGroup) { + return vesselGroupDataviews.filter((d) => d.id === timebarSelectedVGId) + } if (timebarVisualisation === TimebarVisualisations.HeatmapDetections) { return detectionsDataviews } diff --git a/apps/fishing-map/types/index.ts b/apps/fishing-map/types/index.ts index 01a7b177f9..3a365ecb25 100644 --- a/apps/fishing-map/types/index.ts +++ b/apps/fishing-map/types/index.ts @@ -56,6 +56,7 @@ export interface WorkspaceState extends BaseUrlWorkspace { sidebarOpen?: boolean timebarGraph?: TimebarGraphs timebarSelectedEnvId?: string + timebarSelectedVGId?: string timebarVisualisation?: TimebarVisualisations visibleEvents?: VisibleEvents } @@ -96,6 +97,7 @@ export enum TimebarVisualisations { HeatmapActivity = 'heatmap', HeatmapDetections = 'heatmapDetections', Vessel = 'vessel', + VesselGroup = 'vesselGroup', Environment = 'environment', }