From da3b8b70c4c6de8621e4e64986728708b219ddae Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Fri, 3 Nov 2023 09:16:07 +0000 Subject: [PATCH] Update date range playhead behavior Playheads now only show up when there are features for analysis. --- .../components/timeline/timeline-controls.tsx | 59 +++++++++---------- .../components/timeline/timeline-head.tsx | 4 +- .../components/timeline/timeline.tsx | 35 +++++++++++ 3 files changed, 65 insertions(+), 33 deletions(-) diff --git a/app/scripts/components/exploration/components/timeline/timeline-controls.tsx b/app/scripts/components/exploration/components/timeline/timeline-controls.tsx index 0af9b24e1..f9a478df5 100644 --- a/app/scripts/components/exploration/components/timeline/timeline-controls.tsx +++ b/app/scripts/components/exploration/components/timeline/timeline-controls.tsx @@ -30,7 +30,6 @@ import { selectedDateAtom, selectedIntervalAtom } from '$components/exploration/atoms/atoms'; -import { emptyDateRange } from '$components/exploration/constants'; const TimelineControlsSelf = styled.div` width: 100%; @@ -149,36 +148,34 @@ export function TimelineControls(props: TimelineControlsProps) { )} - { - setSelectedInterval({ - start: d.start!, - end: d.end! - }); - }} - isClearable={false} - isRange - alignment='right' - renderTriggerElement={(props) => ( - - L - - {selectedInterval - ? format(selectedInterval.start, 'MMM do, yyyy') - : 'Date'} - - R - - {selectedInterval - ? format(selectedInterval.end, 'MMM do, yyyy') - : 'Date'} - - - - )} - /> + {selectedInterval && ( + { + setSelectedInterval({ + start: d.start!, + end: d.end! + }); + }} + isClearable={false} + isRange + alignment='right' + renderTriggerElement={(props) => ( + + From + + {format(selectedInterval.start, 'MMM do, yyyy')} + + to + + {format(selectedInterval.end, 'MMM do, yyyy')} + + + + )} + /> + )} - {label ?? 'L'} + {label} ); @@ -164,7 +164,7 @@ export function TimelineHeadOut(props: TimelineHeadProps) { dy='1em' textAnchor='end' > - {label ?? 'R'} + {label} ); diff --git a/app/scripts/components/exploration/components/timeline/timeline.tsx b/app/scripts/components/exploration/components/timeline/timeline.tsx index d1fbddfc0..95a63c3bd 100644 --- a/app/scripts/components/exploration/components/timeline/timeline.tsx +++ b/app/scripts/components/exploration/components/timeline/timeline.tsx @@ -54,6 +54,7 @@ import { import { useInteractionRectHover } from '$components/exploration/hooks/use-dataset-hover'; import { datasetLayers } from '$components/exploration/data-utils'; import { useAnalysisController } from '$components/exploration/hooks/use-analysis-data-request'; +import useAois from '$components/common/map/controls/hooks/use-aois'; const TimelineWrapper = styled.div` position: relative; @@ -166,6 +167,8 @@ export default function Timeline(props: TimelineProps) { const { setObsolete } = useAnalysisController(); + const { features } = useAois(); + useEffect(() => { // Set the analysis as obsolete when the selected interval changes. setObsolete(); @@ -362,6 +365,38 @@ export default function Timeline(props: TimelineProps) { selectedInterval ]); + // Set a date range selection when the user creates a new AOI. + const prevFeaturesCount = usePreviousValue(features.length); + useEffect(() => { + // If no feature change, no selected day, or no domain, skip. + if (prevFeaturesCount === features.length || !selectedDay || !dataDomain) + return; + + if (!features.length) { + // All features were removed. Reset the selected day/interval. + setSelectedInterval(null); + } + + if (prevFeaturesCount === 0 && features.length > 0) { + // We went from 0 features to some features. + const startDate = sub(selectedDay, { months: 2 }); + const endDate = add(selectedDay, { months: 2 }); + + // Set start and end days from the selected day, if able. + const [start, end] = dataDomain; + setSelectedInterval({ + start: isAfter(startDate, start) ? startDate : selectedDay, + end: isBefore(endDate, end) ? endDate : end + }); + } + }, [ + features.length, + prevFeaturesCount, + selectedDay, + dataDomain, + setSelectedInterval + ]); + const shouldRenderTimeline = xScaled && dataDomain; // Attach the needed event listeners to the interaction rectangle to capture