From c6d0e225dc2b2a962f613f6a2db68d66f7baf37e Mon Sep 17 00:00:00 2001 From: Maciej Bodek Date: Fri, 6 Dec 2024 09:48:19 +0100 Subject: [PATCH] Refactor listeners, simplify, cleanup --- .../web-console/src/modules/EventBus/types.ts | 2 + .../src/scenes/Editor/Metrics/index.tsx | 117 ++++++++++++++---- .../src/scenes/Editor/Metrics/metric.tsx | 77 +----------- .../web-console/src/scenes/Layout/index.tsx | 23 +++- 4 files changed, 122 insertions(+), 97 deletions(-) diff --git a/packages/web-console/src/modules/EventBus/types.ts b/packages/web-console/src/modules/EventBus/types.ts index e9a013475..c05e7bd1a 100644 --- a/packages/web-console/src/modules/EventBus/types.ts +++ b/packages/web-console/src/modules/EventBus/types.ts @@ -17,4 +17,6 @@ export enum EventType { MSG_CONNECTION_UNAUTHORIZED = "query.connection.unauthorized", MSG_CONNECTION_FORBIDDEN = "query.connection.forbidden", REACT_READY = "react.ready", + TAB_FOCUS = "tab.focus", + TAB_BLUR = "tab.blur", } diff --git a/packages/web-console/src/scenes/Editor/Metrics/index.tsx b/packages/web-console/src/scenes/Editor/Metrics/index.tsx index 9b1721d30..dad4d8d4d 100644 --- a/packages/web-console/src/scenes/Editor/Metrics/index.tsx +++ b/packages/web-console/src/scenes/Editor/Metrics/index.tsx @@ -1,9 +1,14 @@ -import React, { useEffect, useState, useMemo } from "react" +import React, { useCallback, useEffect, useState } from "react" import styled from "styled-components" import { Box, Button, Select } from "@questdb/react-components" import { Text, Link } from "../../../components" import { useEditor } from "../../../providers" -import { MetricDuration, RefreshRate, autoRefreshRates } from "./utils" +import { + MetricDuration, + RefreshRate, + autoRefreshRates, + refreshRates, +} from "./utils" import { Time, Refresh } from "@styled-icons/boxicons-regular" import { AddMetricDialog } from "./add-metric-dialog" import type { Metric } from "../../../store/buffers" @@ -15,6 +20,9 @@ import merge from "lodash.merge" import { AddChart } from "@styled-icons/material" import { getLocalTimeZone } from "../../../utils/dateTime" import { IconWithTooltip } from "../../../components/IconWithTooltip" +import { useLocalStorage } from "../../../providers/LocalStorageProvider" +import { eventBus } from "../../../modules/EventBus" +import { EventType } from "../../../modules/EventBus/types" const Root = styled.div` display: flex; @@ -87,14 +95,21 @@ const formatRefreshRateLabel = ( export const Metrics = () => { const { activeBuffer, updateBuffer, buffers } = useEditor() + const [metricDuration, setMetricDuration] = useState( MetricDuration.ONE_HOUR, ) - const [refreshRate, setRefreshRate] = useState(RefreshRate.AUTO) + const [refreshRate, setRefreshRate] = useState() const [dialogOpen, setDialogOpen] = useState(false) const [metrics, setMetrics] = useState([]) const telemetryConfig = useSelector(selectors.telemetry.getConfig) - const [lastRefresh, setLastRefresh] = useState() + const [lastRefresh, setLastRefresh] = useState(new Date().getTime()) + + const tabInFocusRef = React.useRef(true) + const refreshRateRef = React.useRef() + const intervalRef = React.useRef() + + const { autoRefreshTables } = useLocalStorage() const buffer = buffers.find((b) => b.id === activeBuffer?.id) @@ -139,6 +154,29 @@ export const Metrics = () => { } } + const focusListener = useCallback(() => { + tabInFocusRef.current = true + if (refreshRateRef.current !== RefreshRate.OFF) { + setLastRefresh(new Date().getTime()) + } + }, [refreshRateRef.current]) + + const setupListeners = () => { + if (autoRefreshTables && refreshRate && refreshRate !== RefreshRate.OFF) { + intervalRef.current = setInterval( + () => { + if (!tabInFocusRef.current) return + setLastRefresh(new Date().getTime()) + }, + refreshRate === RefreshRate.AUTO + ? refreshRates[autoRefreshRates[metricDuration]] + : refreshRates[refreshRate], + ) + } else { + clearInterval(intervalRef.current) + } + } + useEffect(() => { if (buffer) { const metrics = buffer?.metricsViewState?.metrics @@ -169,9 +207,29 @@ export const Metrics = () => { }, }) updateBuffer(buffer.id, merged) + + setLastRefresh(new Date().getTime()) } }, [metricDuration, refreshRate]) + useEffect(() => { + if (refreshRate) { + refreshRateRef.current = refreshRate + setupListeners() + } + }, [refreshRate]) + + useEffect(() => { + eventBus.subscribe(EventType.TAB_FOCUS, focusListener) + eventBus.subscribe(EventType.TAB_BLUR, () => { + tabInFocusRef.current = false + }) + + return () => { + eventBus.unsubscribe(EventType.TAB_FOCUS, focusListener) + } + }, []) + if (telemetryConfig && !telemetryConfig.enabled) { return ( @@ -227,27 +285,41 @@ export const Metrics = () => { tooltip="Refresh all widgets" placement="bottom" /> - ({ - label: formatDurationLabel(duration), - value: duration, - }))} - onChange={(e) => - setMetricDuration(e.target.value as MetricDuration) + ({ + label: formatDurationLabel(duration), + value: duration, + }))} + onChange={(e) => + setMetricDuration(e.target.value as MetricDuration) + } + prefixIcon={