/** * The page's first row (on the page, no block): the range as one menu between * ‹ › steppers, the days it covers in grey, then Refresh and the gear that * opens Settings. The range is remembered per browser; the stepped offset is * not. Every number always shows its change against the window before, except * Lifetime, which has none (D2: no Compare switch). */ import { useCallback, useState } from 'react'; import { __, sprintf } from '@wordpress/i18n'; import { useUi } from './ui-context'; import { refreshAll, storage } from './api'; import { shortDay, windowDays, windowFor, windowSpan } from './window'; const RANGES = () => [ { value: 'today', label: __( 'Today', 'saddle-analytics' ) }, { value: '7d', label: __( 'Last 7 days', 'saddle-analytics' ) }, { value: '30d', label: __( 'Last 30 days', 'saddle-analytics' ) }, { value: '90d', label: __( 'Last 90 days', 'saddle-analytics' ) }, { value: 'all', label: __( 'Lifetime', 'saddle-analytics' ) }, ]; /** Range and stepped offset, with the query params they make. */ export function useRange() { const [ range, setRange ] = useState( () => { const saved = storage.get( 'saddle-analytics-range', '30d' ); return RANGES().some( ( r ) => r.value === saved ) ? saved : '30d'; } ); const [ offset, setOffset ] = useState( 0 ); const pickRange = useCallback( ( value ) => { setRange( value ); // A window from the old range means nothing in the new one. setOffset( 0 ); storage.set( 'saddle-analytics-range', value ); }, [] ); return { range, offset, setOffset, pickRange, win: windowFor( range, offset ), canStep: null !== windowDays( range ), // Lifetime has no window before it. compare: 'all' !== range, }; } /** The grey text: "6 Sep to 5 Oct", "4 Oct", "Since 00:00 UTC", or nothing for Lifetime. */ function spanText( range, offset ) { const span = windowSpan( range, offset ); if ( ! span ) { return ''; } if ( 'today' === range && 0 === offset ) { return __( 'Since 00:00 UTC', 'saddle-analytics' ); } if ( span.from === span.to ) { return shortDay( span.from ); } /* translators: 1: first day of the window, 2: last day, such as "6 Sep to 5 Oct". */ return sprintf( __( '%1$s to %2$s', 'saddle-analytics' ), shortDay( span.from ), shortDay( span.to ) ); } export default function Toolbar( { r, onSettings } ) { const { Button, DropdownItem, DropdownMenu, IconButton, icons } = useUi(); const { Check, ChevronDown, ChevronLeft, ChevronRight, Refresh, Settings } = icons; const ranges = RANGES(); const current = ranges.find( ( x ) => x.value === r.range ) ?? ranges[ 2 ]; const span = spanText( r.range, r.offset ); return (
r.setOffset( ( o ) => o + 1 ) } > { current.label } } > { ranges.map( ( x ) => ( : } // Older Core ships a kit whose items fire onClick, newer ones // onSelect; picking a range twice is harmless. onSelect={ () => r.pickRange( x.value ) } onClick={ () => r.pickRange( x.value ) } > { x.label } ) ) } r.setOffset( ( o ) => Math.max( 0, o - 1 ) ) } >
{ span && { span } }
); }