diff --git a/web/src/context/MetricData/BusterMetricDataProvider.tsx b/web/src/context/MetricData/BusterMetricDataProvider.tsx index 7671bfa72..d86f8f247 100644 --- a/web/src/context/MetricData/BusterMetricDataProvider.tsx +++ b/web/src/context/MetricData/BusterMetricDataProvider.tsx @@ -1,4 +1,4 @@ -import React, { PropsWithChildren, useCallback, useState } from 'react'; +import React, { PropsWithChildren, useCallback, useRef, useState, useTransition } from 'react'; import { createContext, ContextSelector, @@ -9,27 +9,23 @@ import { useBusterWebSocket } from '../BusterWebSocket'; import type { BusterMetricData } from '../Metrics'; import { MetricEvent_fetchingData } from '@/api/buster_socket/metrics/eventsInterfaces'; import { MOCK_DATA } from './MOCK_DATA'; - -const DEFAULT_MESSAGE_DATA: BusterMetricData = { - fetched: false, - fetching: false, - fetchedAt: 0, - data_metadata: null, - code: null, - error: null -}; +import { DEFAULT_MESSAGE_DATA } from './config'; const useMetricData = () => { const busterSocket = useBusterWebSocket(); + const [isPending, startTransition] = useTransition(); - const [metricData, setMetricData] = useState>({}); + const metricDataRef = useRef>({}); const _setMetricData = useMemoizedFn( (metricId: string, newMetricData: Partial) => { - setMetricData((prev) => ({ - ...prev, - [metricId]: { ...prev[metricId], ...newMetricData } - })); + metricDataRef.current = { + ...metricDataRef.current, + [metricId]: { ...metricDataRef.current[metricId], ...newMetricData } + }; + startTransition(() => { + //trigger re-render + }); } ); @@ -90,6 +86,7 @@ const useMetricData = () => { const fetchDataByMetricId = useMemoizedFn(async ({ metricId }: { metricId: string }) => { const selectedMetricData = getMetricData(metricId); + if (selectedMetricData?.fetching || selectedMetricData?.fetched) { return; } @@ -121,17 +118,17 @@ const useMetricData = () => { const getMetricData = useCallback( (metricId: string | undefined) => { - if (metricId && metricData[metricId]) { - return metricData[metricId]; + if (metricId && metricDataRef.current[metricId]) { + return metricDataRef.current[metricId]; } return DEFAULT_MESSAGE_DATA; }, - [metricData] + [isPending] ); const getAllMetricDataMemoized = useMemoizedFn( (metricId: string): BusterMetricData | undefined => { - return metricData[metricId]; + return metricDataRef.current[metricId]; } ); @@ -143,7 +140,7 @@ const useMetricData = () => { }); return { - metricData, + metricData: metricDataRef.current, onSetMetricDataCode, onSetMetricData, fetchDataByMetricId, diff --git a/web/src/context/MetricData/config.ts b/web/src/context/MetricData/config.ts new file mode 100644 index 000000000..2ec910c80 --- /dev/null +++ b/web/src/context/MetricData/config.ts @@ -0,0 +1,10 @@ +import type { BusterMetricData } from '../Metrics'; + +export const DEFAULT_MESSAGE_DATA: BusterMetricData = { + fetched: false, + fetching: false, + fetchedAt: 0, + data_metadata: null, + code: null, + error: null +}; diff --git a/web/src/context/Metrics/BusterMetricsProvider.tsx b/web/src/context/Metrics/BusterMetricsProvider.tsx index af4ef5d00..2a84f4aae 100644 --- a/web/src/context/Metrics/BusterMetricsProvider.tsx +++ b/web/src/context/Metrics/BusterMetricsProvider.tsx @@ -292,6 +292,21 @@ export const useBusterMetrics = () => { onUpdateMetric(upgradedMetric); }); + const _setLoadingMetric = useMemoizedFn((metricId: string) => { + const metrics = metricsRef.current || {}; + metrics[metricId] = resolveEmptyMetric( + { + ...metrics[metricId], + fetching: true + }, + metricId + ); + + setMetrics(metrics); + + return metrics[metricId]; + }); + const bulkUpdateMetrics = useMemoizedFn((newMetrics: Record) => { metricsRef.current = { ...metricsRef.current, @@ -307,7 +322,6 @@ export const useBusterMetrics = () => { ...currentMetric, ...newMetricPartial }; - setMetrics({ [metricId]: newMetric }); @@ -359,8 +373,7 @@ export const useBusterMetrics = () => { ...currentMetric.chart_config, ...chartConfig }; - - return onUpdateMetric({ + onUpdateMetric({ id: metricId, chart_config: newChartConfig }); @@ -495,10 +508,12 @@ export const useBusterMetrics = () => { const { password } = getAssetPassword(metricId); const foundMetric: undefined | IBusterMetric = metricsRef.current[metricId]; - if (foundMetric && (foundMetric.fetching || foundMetric.fetched)) { + if (foundMetric && (foundMetric?.fetching || foundMetric?.fetched)) { return foundMetric; } + _setLoadingMetric(metricId); + //TODO: remove this setTimeout(() => { _onGetMetricState({ diff --git a/web/src/context/Metrics/MOCK_METRIC.ts b/web/src/context/Metrics/MOCK_METRIC.ts index a407a1b89..fb15029f3 100644 --- a/web/src/context/Metrics/MOCK_METRIC.ts +++ b/web/src/context/Metrics/MOCK_METRIC.ts @@ -16,7 +16,14 @@ const MOCK_CHART_CONFIG: IBusterMetricChartConfig = { x: ['date'], y: ['sales'], category: [] - // category: ['product'] + }, + pieChartAxis: { + x: ['product'], + y: ['sales'] + }, + scatterAxis: { + x: ['date'], + y: ['sales'] } }; diff --git a/web/src/context/Metrics/helpers/metricHelpers.ts b/web/src/context/Metrics/helpers/metricHelpers.ts index 0b1873709..f3aeeaa7d 100644 --- a/web/src/context/Metrics/helpers/metricHelpers.ts +++ b/web/src/context/Metrics/helpers/metricHelpers.ts @@ -37,7 +37,7 @@ export const resolveEmptyMetric = ( metricId: string ): IBusterMetric => { if (!metric || !metric?.id) { - return { ...defaultIBusterMetric, id: metricId }; + return { ...defaultIBusterMetric, ...metric, id: metricId }; } return metric; };