Skip to content

Commit

Permalink
Refactor listeners, simplify, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
insmac committed Dec 6, 2024
1 parent ac11a54 commit c6d0e22
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 97 deletions.
2 changes: 2 additions & 0 deletions packages/web-console/src/modules/EventBus/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
117 changes: 94 additions & 23 deletions packages/web-console/src/scenes/Editor/Metrics/index.tsx
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -87,14 +95,21 @@ const formatRefreshRateLabel = (

export const Metrics = () => {
const { activeBuffer, updateBuffer, buffers } = useEditor()

const [metricDuration, setMetricDuration] = useState<MetricDuration>(
MetricDuration.ONE_HOUR,
)
const [refreshRate, setRefreshRate] = useState<RefreshRate>(RefreshRate.AUTO)
const [refreshRate, setRefreshRate] = useState<RefreshRate>()
const [dialogOpen, setDialogOpen] = useState(false)
const [metrics, setMetrics] = useState<Metric[]>([])
const telemetryConfig = useSelector(selectors.telemetry.getConfig)
const [lastRefresh, setLastRefresh] = useState<number | undefined>()
const [lastRefresh, setLastRefresh] = useState<number>(new Date().getTime())

const tabInFocusRef = React.useRef<boolean>(true)
const refreshRateRef = React.useRef<RefreshRate>()
const intervalRef = React.useRef<NodeJS.Timeout>()

const { autoRefreshTables } = useLocalStorage()

const buffer = buffers.find((b) => b.id === activeBuffer?.id)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 (
<Root>
Expand Down Expand Up @@ -227,27 +285,41 @@ export const Metrics = () => {
tooltip="Refresh all widgets"
placement="bottom"
/>
<Select
name="refresh_rate"
value={refreshRate}
options={Object.values(RefreshRate).map((rate) => ({
label: formatRefreshRateLabel(rate, metricDuration),
value: rate,
}))}
onChange={(e) => setRefreshRate(e.target.value as RefreshRate)}
<IconWithTooltip
icon={
<Select
name="refresh_rate"
value={refreshRate}
options={Object.values(RefreshRate).map((rate) => ({
label: formatRefreshRateLabel(rate, metricDuration),
value: rate,
}))}
onChange={(e) =>
setRefreshRate(e.target.value as RefreshRate)
}
/>
}
tooltip="Widget refresh rate"
placement="bottom"
/>
</Box>
<Select
name="duration"
value={metricDuration}
options={Object.values(MetricDuration).map((duration) => ({
label: formatDurationLabel(duration),
value: duration,
}))}
onChange={(e) =>
setMetricDuration(e.target.value as MetricDuration)
<IconWithTooltip
icon={
<Select
name="duration"
value={metricDuration}
options={Object.values(MetricDuration).map((duration) => ({
label: formatDurationLabel(duration),
value: duration,
}))}
onChange={(e) =>
setMetricDuration(e.target.value as MetricDuration)
}
prefixIcon={<Time size="18px" />}
/>
}
prefixIcon={<Time size="18px" />}
tooltip="Time duration"
placement="bottom"
/>
</Box>
</Toolbar>
Expand All @@ -274,7 +346,6 @@ export const Metrics = () => {
key={index}
metric={metric}
metricDuration={metricDuration}
refreshRate={refreshRate}
onRemove={handleRemoveMetric}
onTableChange={handleTableChange}
onColorChange={handleColorChange}
Expand Down
77 changes: 4 additions & 73 deletions packages/web-console/src/scenes/Editor/Metrics/metric.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import React, {
useEffect,
useState,
useContext,
useCallback,
useRef,
} from "react"
import React, { useEffect, useState, useContext } from "react"
import { Metric as MetricItem } from "../../../store/buffers"
import {
durationInMinutes,
MetricDuration,
MetricType,
LastNotNull,
ResultType,
RefreshRate,
refreshRates,
autoRefreshRates,
} from "./utils"
import { widgets } from "./widgets"
import { QuestContext } from "../../../providers"
Expand All @@ -26,7 +17,6 @@ import { Box, Button, ForwardRef, Popover } from "@questdb/react-components"
import { Error, Palette, Trash } from "@styled-icons/boxicons-regular"
import { useSelector } from "react-redux"
import { selectors } from "../../../store"
import { useLocalStorage } from "../../../providers/LocalStorageProvider"
import { TableSelector } from "./table-selector"
import { IconWithTooltip } from "../../../components/IconWithTooltip"
import { ColorPalette } from "./color-palette"
Expand All @@ -48,7 +38,6 @@ const ActionButton = styled(Button)`
export const Metric = ({
metric,
metricDuration,
refreshRate,
onRemove,
onTableChange,
onColorChange,
Expand All @@ -57,7 +46,6 @@ export const Metric = ({
}: {
metric: MetricItem
metricDuration: MetricDuration
refreshRate: RefreshRate
onRemove: (metric: MetricItem) => void
onTableChange: (metric: MetricItem, tableId: number) => void
onColorChange: (metric: MetricItem, color: string) => void
Expand All @@ -69,16 +57,9 @@ export const Metric = ({
const [data, setData] = useState<uPlot.AlignedData>()
const [lastNotNull, setLastNotNull] = useState<number>()
const [colorPickerOpen, setColorPickerOpen] = useState(false)
const metricDurationRef = useRef(metricDuration)

const tables = useSelector(selectors.query.getTables)

const intervalRef = React.useRef<NodeJS.Timeout>()
const focusListenerRef = React.useRef(false)
const refreshRateRef = useRef<RefreshRate>(refreshRate)

const { autoRefreshTables } = useLocalStorage()

const widgetConfig = widgets[metric.metricType]

const minuteDurations: [MetricDuration, number][] = Object.entries(
Expand All @@ -95,7 +76,7 @@ export const Metric = ({
quest.query<ResultType[MetricType]>(
widgetConfig.getQuery({
tableId: metric.tableId,
metricDuration: metricDurationRef.current,
metricDuration: metricDuration,
}),
),
quest.query<LastNotNull>(
Expand Down Expand Up @@ -134,61 +115,11 @@ export const Metric = ({
}
}

const setupListeners = () => {
if (autoRefreshTables) {
if (refreshRate === RefreshRate.OFF) {
clearInterval(intervalRef.current)
} else {
intervalRef.current = setInterval(
() => fetchMetric(),
refreshRate === RefreshRate.AUTO
? refreshRates[autoRefreshRates[metricDuration]]
: refreshRates[refreshRate],
)
}
window.addEventListener("focus", focusListener)
focusListenerRef.current = true
} else {
clearInterval(intervalRef.current)
window.removeEventListener("focus", focusListener)
focusListenerRef.current = false
}
}

useEffect(() => {
metricDurationRef.current = metricDuration
refreshRateRef.current = refreshRate

if (metric.tableId) {
fetchMetric()
setupListeners()
}

return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current)
}
if (focusListenerRef.current) {
window.removeEventListener("focus", focusListener)
focusListenerRef.current = false
}
}
}, [autoRefreshTables, metricDuration, metric.tableId, refreshRate])

const focusListener = useCallback(() => {
if (
focusListenerRef.current &&
refreshRateRef.current !== RefreshRate.OFF
) {
fetchMetric()
}
}, [metric.tableId, refreshRateRef.current])

useEffect(() => {
if (lastRefresh) {
if (lastRefresh || metric.tableId) {
fetchMetric()
}
}, [lastRefresh])
}, [lastRefresh, metric.tableId])

if (!data && !loading && metric.tableId)
return (
Expand Down
23 changes: 22 additions & 1 deletion packages/web-console/src/scenes/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
******************************************************************************/

import React from "react"
import React, { useCallback, useEffect } from "react"
import styled from "styled-components"
import Footer from "../Footer"
import Console from "../Console"
Expand All @@ -40,6 +40,9 @@ import { ImageZoom } from "../News/image-zoom"

import "allotment/dist/style.css"

import { eventBus } from "../../modules/EventBus"
import { EventType } from "../../modules/EventBus/types"

const Page = styled.div`
display: flex;
width: 100%;
Expand Down Expand Up @@ -77,6 +80,24 @@ const Drawer = styled.div`
const Layout = () => {
const activeSidebar = useSelector(selectors.console.getActiveSidebar)

const focusListener = useCallback(() => {
eventBus.publish(EventType.TAB_FOCUS)
}, [])

const blurListener = useCallback(() => {
eventBus.publish(EventType.TAB_BLUR)
}, [])

useEffect(() => {
window.addEventListener("focus", focusListener)
window.addEventListener("blur", blurListener)

return () => {
window.removeEventListener("focus", focusListener)
window.removeEventListener("blur", blurListener)
}
}, [])

return (
<EditorProvider>
<TopBar />
Expand Down

0 comments on commit c6d0e22

Please sign in to comment.