metric results invalidate updates 🐈‍⬛

This commit is contained in:
Nate Kelley 2025-04-10 17:01:54 -06:00
parent 03cf81cbb0
commit aaf1a29b34
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
5 changed files with 44 additions and 20 deletions

View File

@ -48,8 +48,8 @@ export const EditorContent: React.FC<{
try { try {
const result = await runQuery(); const result = await runQuery();
if (result && result.length > 0) { if (result && result.length > 0) {
const headerHeight = 50; const headerHeight = 30;
const heightOfRow = 36; const heightOfRow = 28;
const heightOfDataContainer = headerHeight + heightOfRow * (result.length || 0); const heightOfDataContainer = headerHeight + heightOfRow * (result.length || 0);
const containerHeight = ref.current?.clientHeight || 0; const containerHeight = ref.current?.clientHeight || 0;
const maxHeight = Math.floor(containerHeight * 0.6); const maxHeight = Math.floor(containerHeight * 0.6);

View File

@ -7,7 +7,6 @@ import { useMemoizedFn } from '@/hooks';
import { Button } from '@/components/ui/buttons/Button'; import { Button } from '@/components/ui/buttons/Button';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import type { AppVerticalCodeSplitterProps } from './AppVerticalCodeSplitter'; import type { AppVerticalCodeSplitterProps } from './AppVerticalCodeSplitter';
import { cn } from '@/lib/classMerge';
import { ErrorClosableContainer } from '@/components/ui/error/ErrorClosableContainer'; import { ErrorClosableContainer } from '@/components/ui/error/ErrorClosableContainer';
import { FileCard } from '@/components/ui/card/FileCard'; import { FileCard } from '@/components/ui/card/FileCard';
@ -16,12 +15,13 @@ export const SQLContainer: React.FC<{
sql: string | undefined; sql: string | undefined;
setDatasetSQL: (sql: string) => void; setDatasetSQL: (sql: string) => void;
onRunQuery: () => Promise<void>; onRunQuery: () => Promise<void>;
onSaveSQL?: AppVerticalCodeSplitterProps['onSaveSQL']; onSaveSQL: AppVerticalCodeSplitterProps['onSaveSQL'];
disabledSave?: AppVerticalCodeSplitterProps['disabledSave']; disabledSave?: AppVerticalCodeSplitterProps['disabledSave'];
error?: string | null; error?: string | null;
}> = React.memo( }> = React.memo(
({ disabledSave, className = '', sql, setDatasetSQL, onRunQuery, onSaveSQL, error }) => { ({ disabledSave, className = '', sql, setDatasetSQL, onRunQuery, onSaveSQL, error }) => {
const [isRunning, setIsRunning] = useState(false); const [isRunning, setIsRunning] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const { openInfoMessage } = useBusterNotifications(); const { openInfoMessage } = useBusterNotifications();
const onCopySQL = useMemoizedFn(() => { const onCopySQL = useMemoizedFn(() => {
@ -35,6 +35,12 @@ export const SQLContainer: React.FC<{
setIsRunning(false); setIsRunning(false);
}); });
const onSaveSQLPreflight = useMemoizedFn(async () => {
setIsSaving(true);
await onSaveSQL?.();
setIsSaving(false);
});
const memoizedFooter = useMemo(() => { const memoizedFooter = useMemo(() => {
return ( return (
<> <>
@ -45,7 +51,8 @@ export const SQLContainer: React.FC<{
<Button <Button
disabled={disabledSave || !sql || isRunning} disabled={disabledSave || !sql || isRunning}
variant="black" variant="black"
onClick={onSaveSQL}> loading={isSaving}
onClick={onSaveSQLPreflight}>
Save Save
</Button> </Button>
)} )}

View File

@ -20,7 +20,7 @@ export const initializeColumnWidths = (
return initial; return initial;
}; };
const OFFSET = 20; const OFFSET = 40;
const getDefaultColumnWidth = ( const getDefaultColumnWidth = (
rows: Record<string, string | number | null | Date>[], rows: Record<string, string | number | null | Date>[],

View File

@ -59,12 +59,12 @@ export const MetricViewResults: React.FC<{ metricId: string }> = React.memo(({ m
if (res && res.data && res.data.length > 0) { if (res && res.data && res.data.length > 0) {
const data = res.data; const data = res.data;
const headerHeight = 50; const headerHeight = 28.1;
const heightOfRow = 36; const heightOfRow = 28.1;
const heightOfDataContainer = headerHeight + heightOfRow * (data.length || 0); const heightOfDataContainer = headerHeight + heightOfRow * (data.length || 0);
const containerHeight = containerRef.current?.clientHeight || 0; const containerHeight = containerRef.current?.clientHeight || 0;
const maxHeight = Math.floor(containerHeight * 0.6); const maxHeight = Math.floor(containerHeight * 0.6);
const finalHeight = Math.min(heightOfDataContainer, maxHeight); const finalHeight = Math.min(heightOfDataContainer, maxHeight) + 12;
appSplitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]); appSplitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]);
} }
} catch (error) { } catch (error) {

View File

@ -1,4 +1,8 @@
import type { BusterMetricData, IBusterMetricChartConfig } from '@/api/asset_interfaces/metric'; import type {
BusterMetricData,
IBusterMetricChartConfig,
IBusterMetricData
} from '@/api/asset_interfaces/metric';
import { RunSQLResponse } from '@/api/asset_interfaces/sql'; import { RunSQLResponse } from '@/api/asset_interfaces/sql';
import { queryKeys } from '@/api/query_keys'; import { queryKeys } from '@/api/query_keys';
import { useBusterNotifications } from '@/context/BusterNotifications'; import { useBusterNotifications } from '@/context/BusterNotifications';
@ -9,6 +13,8 @@ import { didColumnDataChange, simplifyChatConfigForSQLChange } from './helpers';
import { useRunSQL as useRunSQLQuery } from '@/api/buster_rest'; import { useRunSQL as useRunSQLQuery } from '@/api/buster_rest';
import { useUpdateMetric } from '@/api/buster_rest/metrics'; import { useUpdateMetric } from '@/api/buster_rest/metrics';
import { useGetMetricMemoized } from '@/context/Metrics'; import { useGetMetricMemoized } from '@/context/Metrics';
import { createDefaultChartConfig } from '@/lib/metrics/messageAutoChartHandler';
import { timeout } from '@/lib';
export const useMetricRunSQL = () => { export const useMetricRunSQL = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@ -35,7 +41,7 @@ export const useMetricRunSQL = () => {
const { openSuccessNotification } = useBusterNotifications(); const { openSuccessNotification } = useBusterNotifications();
const getDataByMetricIdMemoized = useMemoizedFn( const getDataByMetricIdMemoized = useMemoizedFn(
(metricId: string): BusterMetricData | undefined => { (metricId: string): IBusterMetricData | undefined => {
const options = queryKeys.metricsGetData(metricId); const options = queryKeys.metricsGetData(metricId);
return queryClient.getQueryData(options.queryKey); return queryClient.getQueryData(options.queryKey);
} }
@ -61,11 +67,14 @@ export const useMetricRunSQL = () => {
}) => { }) => {
const options = queryKeys.metricsGetData(metricId); const options = queryKeys.metricsGetData(metricId);
const currentData = getDataByMetricIdMemoized(metricId); const currentData = getDataByMetricIdMemoized(metricId);
if (!currentData) return;
const setter = isDataFromRerun ? 'dataFromRerun' : 'data'; const setter = isDataFromRerun ? 'dataFromRerun' : 'data';
queryClient.setQueryData(options.queryKey, { queryClient.setQueryData(options.queryKey, {
...currentData!, ...currentData,
[setter]: data, [setter]: data,
data_metadata data_metadata,
...(!isDataFromRerun && { dataFromRerun: undefined })
}); });
}; };
@ -88,7 +97,6 @@ export const useMetricRunSQL = () => {
const newColumnData = data_metadata?.column_metadata; const newColumnData = data_metadata?.column_metadata;
const didDataMetadataChange = didColumnDataChange(oldColumnData, newColumnData); const didDataMetadataChange = didColumnDataChange(oldColumnData, newColumnData);
const totallyDefaultChartConfig: IBusterMetricChartConfig = didDataMetadataChange const totallyDefaultChartConfig: IBusterMetricChartConfig = didDataMetadataChange
? simplifyChatConfigForSQLChange(metricMessage.chart_config, data_metadata) ? simplifyChatConfigForSQLChange(metricMessage.chart_config, data_metadata)
: metricMessage.chart_config; : metricMessage.chart_config;
@ -154,11 +162,10 @@ export const useMetricRunSQL = () => {
sql: string; sql: string;
dataSourceId?: string; dataSourceId?: string;
}) => { }) => {
const ogConfigs = originalConfigs.current;
const currentMetric = getMetricMemoized(metricId); const currentMetric = getMetricMemoized(metricId);
const dataSourceId = dataSourceIdProp || currentMetric?.data_source_id; const dataSourceId = dataSourceIdProp || currentMetric?.data_source_id;
if (!ogConfigs || ogConfigs.sql !== sql) { if (!originalConfigs.current || originalConfigs.current.sql !== sql) {
try { try {
await runSQL({ await runSQL({
metricId, metricId,
@ -169,21 +176,31 @@ export const useMetricRunSQL = () => {
throw error; throw error;
} }
} }
await timeout(50);
const currentChartConfig = getMetricMemoized(metricId)?.chart_config; //grab it like this because we need the reset based on stageMetric function
await saveMetric({ await saveMetric({
id: metricId, id: metricId,
sql sql,
chart_config: currentChartConfig //this is reset based on stageMetric function
}); });
await timeout(50);
if (originalConfigs.current) { const currentData = getDataByMetricIdMemoized(metricId);
if (currentData?.data_metadata && currentData?.dataFromRerun) {
onSetDataForMetric({ onSetDataForMetric({
metricId, metricId,
data: originalConfigs.current?.data!, data: currentData?.dataFromRerun,
data_metadata: originalConfigs.current?.dataMetadata!, data_metadata: currentData?.data_metadata,
isDataFromRerun: false isDataFromRerun: false
}); });
} }
await queryClient.invalidateQueries({
queryKey: queryKeys.metricsGetMetric(metricId).queryKey
});
setTimeout(() => { setTimeout(() => {
openSuccessNotification({ openSuccessNotification({
title: 'SQL Saved', title: 'SQL Saved',