updated metric data requests

This commit is contained in:
Nate Kelley 2025-03-10 13:58:50 -06:00
parent b3c4bad371
commit 613d4bcfe6
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
19 changed files with 84 additions and 99 deletions

29
web/package-lock.json generated
View File

@ -88,6 +88,7 @@
"@storybook/react": "^8.6.4",
"@storybook/test": "^8.6.4",
"@tailwindcss/postcss": "4.0.12",
"@testing-library/react": "^16.2.0",
"@types/canvas-confetti": "^1.9.0",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.16",
@ -6745,6 +6746,34 @@
"dev": true,
"license": "MIT"
},
"node_modules/@testing-library/react": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.2.0.tgz",
"integrity": "sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@testing-library/dom": "^10.0.0",
"@types/react": "^18.0.0 || ^19.0.0",
"@types/react-dom": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@testing-library/user-event": {
"version": "14.5.2",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",

View File

@ -96,6 +96,7 @@
"@storybook/react": "^8.6.4",
"@storybook/test": "^8.6.4",
"@tailwindcss/postcss": "4.0.12",
"@testing-library/react": "^16.2.0",
"@types/canvas-confetti": "^1.9.0",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.16",

View File

@ -2,8 +2,7 @@ import { DataMetadata, IDataResult } from './interfaces';
export type BusterMetricData = {
data: IDataResult | null;
dataFromRerun?: IDataResult;
dataFromRerun?: IDataResult; //this is actually only used in the UI. maybe move this to ?
data_metadata: DataMetadata;
code: string | null;
metricId: string;
};

View File

@ -1,7 +1,13 @@
import { useQuery } from '@tanstack/react-query';
import { QueryClient } from '@tanstack/react-query';
import { useMemoizedFn } from '@/hooks';
import { getMetric, getMetric_server, listMetrics, listMetrics_server } from './requests';
import {
getMetric,
getMetric_server,
getMetricData,
listMetrics,
listMetrics_server
} from './requests';
import type { GetMetricParams, ListMetricsParams } from './interfaces';
import { upgradeMetricToIMetric } from '@/lib/chat';
import { queryKeys } from '@/api/query_keys';
@ -61,3 +67,15 @@ export const prefetchGetMetricsList = async (
return queryClient;
};
export const useGetMetricData = (params: { id: string }) => {
const queryFn = useMemoizedFn(() => {
return getMetricData(params);
});
return useQuery({
...queryKeys.metricsGetData(params.id),
queryFn,
enabled: !!params.id
});
};

View File

@ -1,7 +1,11 @@
import { mainApi } from '../instances';
import { serverFetch } from '@/api/createServerInstance';
import type { GetMetricParams, ListMetricsParams } from './interfaces';
import type { BusterMetric, BusterMetricListItem } from '@/api/asset_interfaces/metric';
import type {
BusterMetric,
BusterMetricData,
BusterMetricListItem
} from '@/api/asset_interfaces/metric';
export const getMetric = async ({ id, password }: GetMetricParams) => {
return mainApi
@ -24,3 +28,7 @@ export const listMetrics = async (params: ListMetricsParams) => {
export const listMetrics_server = async (params: ListMetricsParams) => {
return await serverFetch<BusterMetricListItem[]>('/metrics/list', { params });
};
export const getMetricData = async (params: { id: string }) => {
return mainApi.get<BusterMetricData>(`/metrics/data`, { params }).then((res) => res.data);
};

View File

@ -1,10 +0,0 @@
import type { BusterChartConfigProps, DataMetadata, IDataResult } from '../../asset_interfaces';
import type { EventBase } from '../base_interfaces';
export type MetricEvent_fetchingData = {
metric_id: string;
data: IDataResult;
data_metadata: DataMetadata;
chart_config: BusterChartConfigProps;
code: string | null;
} & EventBase;

View File

@ -5,7 +5,6 @@ import {
MetricSubscribeRequest,
MetricUpdateRequest,
MetricDeleteRequest,
MetricGetDataByMessageIdRequest,
MetricSearchRequest,
MetricDuplicateRequest
} from '@/api/request_interfaces/metrics';
@ -41,14 +40,6 @@ export type MetricUpdateMetric = BusterSocketRequestBase<'/metrics/update', Metr
*/
export type MetricDelete = BusterSocketRequestBase<'/metrics/delete', MetricDeleteRequest>;
/**
* Request payload for retrieving metric data by message ID
*/
export type MetricGetDataByMessageId = BusterSocketRequestBase<
'/metrics/data',
MetricGetDataByMessageIdRequest
>;
/**
* Request payload for searching metrics
*/
@ -69,5 +60,4 @@ export type MetricEmits =
| MetricUpdateMetric
| MetricSubscribeToMetric
| MetricDelete
| MetricGetDataByMessageId
| MetricSearch;

View File

@ -1,5 +1,4 @@
import { BusterMetric, BusterMetricListItem } from '@/api/asset_interfaces/metric';
import { MetricEvent_fetchingData } from './eventsInterfaces';
export enum MetricResponses {
'/metrics/list:getMetricList' = '/metrics/list:getMetricList',
@ -29,12 +28,6 @@ export type Metric_Unsubscribe = {
onError?: (d: unknown) => void;
};
export type MetricGet_fetchingData = {
route: '/metrics/get:fetchingData';
callback: (d: MetricEvent_fetchingData) => void;
onError?: (d: unknown) => void;
};
export type MetricList_updateMetricList = {
route: '/metrics/list:updateMetricList';
callback: (d: BusterMetricListItem[]) => void;
@ -61,5 +54,4 @@ export type MetricResponseTypes =
| MetricGet_updateMetricState
| MetricList_updateMetricList
| MetricDelete_deleteMetricState
| MetricUpdate_updateMetricState
| MetricGet_fetchingData;
| MetricUpdate_updateMetricState;

View File

@ -41,9 +41,16 @@ export const metricsGetDataByMessageId = (messageId: string) =>
staleTime: 60 * 60 * 1000 // 1 hour
});
export const metricsGetData = (id: string) =>
queryOptions<BusterMetricData>({
queryKey: ['metrics', 'data', id] as const,
staleTime: 3 * 60 * 60 * 1000 // 3 hours,
});
export const metricsQueryKeys = {
metricsGetMetric,
useMetricsGetMetric,
metricsGetList,
metricsGetDataByMessageId
metricsGetDataByMessageId,
metricsGetData
};

View File

@ -70,14 +70,6 @@ export type MetricDeleteRequest = {
ids: string[];
};
/**
* Request payload for retrieving metric data by message ID
*/
export type MetricGetDataByMessageIdRequest = {
/** Message ID to retrieve metric data for */
id: string;
};
/**
* Request payload for searching metrics
*/

View File

@ -1,4 +1,4 @@
import type { ColumnMetaData } from '@/api/asset_interfaces';
import type { ColumnMetaData } from '@/api/asset_interfaces/metric';
import type { BusterChartConfigProps } from './chartConfigProps';
export type BusterChartProps = {

View File

@ -12,11 +12,11 @@ export const AppCodeBlock: React.FC<{
wrapperClassName?: string;
children?: React.ReactNode;
style?: React.CSSProperties;
showCopyButton?: boolean;
title?: string;
buttons?: React.ReactNode;
}> = React.memo(({ title, buttons, ...props }) => {
showLoader?: boolean;
}> = React.memo(({ title, buttons, showLoader, ...props }) => {
const {
children,
className = '',

View File

@ -44,14 +44,7 @@ const MOCK_DATA: Required<BusterMetricData> = {
data: mockData(),
metricId: faker.string.uuid(),
data_metadata: dataMetadata,
dataFromRerun: null,
code: `SELECT
sales,
date,
product
FROM sales_data
WHERE date BETWEEN '2024-01-01' AND '2024-01-31'
ORDER BY date ASC`
dataFromRerun: null
};
export const createMockData = (metricId: string): Required<BusterMetricData> => {

View File

@ -1,6 +1,4 @@
import { queryKeys } from '@/api/query_keys';
import { useSocketQueryEmitAndOnce } from '@/api/buster_socket_query';
import type { BusterMetricData } from '@/api/asset_interfaces/metric';
import { useGetMetricData } from '@/api/buster_rest/metrics';
export const useMetricDataIndividual = ({ metricId }: { metricId: string }) => {
const {
@ -9,25 +7,7 @@ export const useMetricDataIndividual = ({ metricId }: { metricId: string }) => {
refetch: refetchMetricData,
dataUpdatedAt: metricDataUpdatedAt,
error: metricDataError
} = useSocketQueryEmitAndOnce({
emitEvent: {
route: '/metrics/data',
payload: { id: metricId }
},
responseEvent: '/metrics/get:fetchingData',
options: queryKeys.chatsMessagesFetchingData(metricId),
callback: (currentData, responseData) => {
const metricId = responseData.metric_id;
const newMetricData: BusterMetricData = {
...currentData,
metricId,
data: responseData.data ?? currentData?.data!,
data_metadata: responseData.data_metadata ?? currentData?.data_metadata!,
code: responseData.code
};
return newMetricData;
}
});
} = useGetMetricData({ id: metricId });
return {
metricData,

View File

@ -51,7 +51,6 @@ export const useSQLProvider = () => {
metricId,
data,
data_metadata,
code,
isDataFromRerun
}: {
metricId: string;
@ -66,8 +65,7 @@ export const useSQLProvider = () => {
queryClient.setQueryData(options.queryKey, {
...currentData!,
[setter]: data,
data_metadata,
code
data_metadata
});
};
@ -80,7 +78,7 @@ export const useSQLProvider = () => {
if (!originalConfigs.current[metricId]) {
originalConfigs.current[metricId] = {
chartConfig: metricMessage?.chart_config!,
code: currentMessageData?.code!,
code: metricMessage?.code!,
data: currentMessageData?.data!,
dataMetadata: currentMessageData?.data_metadata!
};

View File

@ -6,9 +6,9 @@ import { useFavoriteProvider } from './useFavoriteProvider';
import { useGetMyUserInfo } from '@/api/buster_rest/users';
import { useSupabaseContext } from '../Supabase';
import { createContext, useContextSelector } from 'use-context-selector';
import { checkIfUserIsAdmin } from './helpers';
import { useUserOrganization } from './useUserOrganization';
import { useInviteUser } from './useInviteUser';
import { checkIfUserIsAdmin } from '@/lib/user';
export const useUserConfigProvider = ({ userInfo }: { userInfo: BusterUserResponse | null }) => {
const isAnonymousUser = useSupabaseContext((state) => state.isAnonymousUser);

View File

@ -1,17 +0,0 @@
import { BusterOrganizationRole } from '@/api/asset_interfaces/organizations';
import { type BusterUserResponse } from '@/api/asset_interfaces/users';
export const checkIfUserIsAdmin = (userInfo?: BusterUserResponse | null): boolean => {
if (!userInfo) return false;
const userOrganization = userInfo?.organizations?.[0];
if (!userOrganization) return false;
const userRole = userOrganization.role;
return (
userRole === BusterOrganizationRole.DATA_ADMIN ||
userRole === BusterOrganizationRole.WORKSPACE_ADMIN
);
};

View File

@ -1,2 +1 @@
export * from './UserConfigProvider';
export * from './helpers';

View File

@ -24,5 +24,11 @@
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"exclude": [
"node_modules",
"**/*.stories.tsx",
"**/*.stories.ts",
"**/*.test.tsx",
"**/*.test.ts"
]
}