/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import { EuiIcon, EuiButtonEmpty, EuiFieldText, EuiPopover, EuiFlexGroup, EuiFieldNumber, EuiSelect, EuiButton, EuiFlexItem, EuiFormRow, } from '@elastic/eui'; import React, { useEffect, useState, useCallback, useMemo } from 'react'; interface RefreshIntervalProps { /** * When refresh value/unit/isPaused changed */ onRefreshChange?: (args: { value: number; isPaused: boolean }) => void; /** * When interval function is called */ onRefresh: () => void; /** * The minimum allowed interval value(in milliseconds) */ minInterval?: number; } const intervalUnitOptions = [ { text: 'seconds', value: 's' }, { text: 'minutes', value: 'm' }, { text: 'hours', value: 'h' }, ]; export const RefreshInterval = ({ onRefresh, onRefreshChange, minInterval = 10 * 1000, }: RefreshIntervalProps) => { // default interval 10s const [intervalValue, setIntervalValue] = useState(minInterval / 1000); const [intervalUnit, setIntervalUnit] = useState('s'); const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [isPaused, setIsPaused] = useState(true); const onIntervalValueChange = useCallback((e: React.ChangeEvent) => { setIntervalValue(Number(e.target.value)); }, []); const onUnitChange = useCallback((e: React.ChangeEvent) => { setIntervalUnit(e.target.value); }, []); const displayedIntervalValue = useMemo(() => { if (isPaused) { return 'Off'; } const unit = intervalUnitOptions.find((option) => option.value === intervalUnit); if (unit) { return `${intervalValue} ${unit.text}`; } }, [isPaused, intervalUnit, intervalValue]); const interval = useMemo(() => { switch (intervalUnit) { case 's': return intervalValue * 1000; case 'm': return intervalValue * 60 * 1000; case 'h': return intervalValue * 3600 * 1000; default: return null; } }, [intervalUnit, intervalValue]); const isInvalid = interval === null || interval < minInterval; useEffect(() => { if (isInvalid) { setIsPaused(true); } }, [isInvalid]); useEffect(() => { let intervalId: number | null = null; if (isPaused) { if (intervalId !== null) { window.clearInterval(intervalId); } } else { if (interval !== null) { intervalId = window.setInterval(() => { onRefresh(); }, interval); } } if (interval !== null && onRefreshChange) { onRefreshChange({ value: interval, isPaused }); } return () => { if (intervalId !== null) { window.clearInterval(intervalId); } }; }, [interval, isPaused, onRefresh, onRefreshChange]); const intervalButton = ( setIsPopoverOpen(!isPopoverOpen)} aria-label="set refresh interval" > ); let errors: string[] = []; if (isInvalid) { errors = ['Enter an auto-refresh rate greater than 10 seconds.']; } return ( setIsPopoverOpen(false)} > 0 ? '' : 'Enter an auto-refresh rate greater than 10 seconds.' } isInvalid={isInvalid} error={errors} > setIsPaused(!isPaused)} > {isPaused ? 'Start' : 'Stop'} } /> ); };