diff --git a/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx b/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx
index 6206c9f15..b481d9684 100644
--- a/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx
+++ b/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx
@@ -67,7 +67,7 @@ const _DashboardMetricItem: React.FC<{
const cardClassNamesMemoized = useMemo(() => {
return {
body: `h-full w-full overflow-hidden ${isTable ? '!p-0' : '!px-2 !pt-2 !pb-0.5'} relative`,
- header: cx(`!p-0 !min-h-[52px]`, styles.cardTitle)
+ header: cx(`!p-0 !min-h-[52px] !mb-0`, styles.cardTitle)
};
}, [isTable]);
diff --git a/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx b/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx
index 5855f9ef8..74092bb8e 100644
--- a/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx
+++ b/web/src/app/app/_controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx
@@ -51,7 +51,7 @@ export const MetricTitle: React.FC<{
{`${title}`}
diff --git a/web/src/components/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx b/web/src/components/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx
index 7665e3da4..26050b6e7 100644
--- a/web/src/components/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx
+++ b/web/src/components/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx
@@ -31,6 +31,7 @@ export const BusterChartJSTooltip: React.FC<{
const isScatter = selectedChartType === ChartType.Scatter;
const isLine = selectedChartType === ChartType.Line;
const isBar = selectedChartType === ChartType.Bar;
+ const isPie = selectedChartType === ChartType.Pie;
const isComboChart = selectedChartType === ChartType.Combo;
const datasets = chart.data.datasets;
const dataPoints = dataPointsProp.filter((item) => !item.dataset.isTrendline);
@@ -38,7 +39,6 @@ export const BusterChartJSTooltip: React.FC<{
const title = useMemo(() => {
if (isScatter) return undefined;
- const isTimeAxis = chart.scales.x.type === 'time';
const dataIndex = dataPoints[0].dataIndex;
const value = chart.data.labels?.[dataIndex!];
if (typeof value === 'string') return String(value);
@@ -50,16 +50,8 @@ export const BusterChartJSTooltip: React.FC<{
const key = xAxisKeys.at(0)!;
const columnLabelFormat = columnLabelFormats[key!];
- // if (columnLabelFormat.dateFormat === 'auto') {
- // const parsedXValue = dataPoints[0]?.parsed?.x;
- // const assosciatedTick = chart.scales.x.ticks.find((tick) => tick.value === parsedXValue);
- // if (assosciatedTick) {
- // return assosciatedTick.label as string;
- // }
- // }
-
return formatLabel(value as number | Date, columnLabelFormat);
- }, [dataPoints, chart]);
+ }, [dataPoints, isPie, isScatter, chart]);
const tooltipItems: ITooltipItem[] = useMemo(() => {
if (isBar || isLine || isComboChart) {
diff --git a/web/src/components/charts/LoadingComponents/ChartLoadingComponents.tsx b/web/src/components/charts/LoadingComponents/ChartLoadingComponents.tsx
index ed91e5cb3..7c5de3ba4 100644
--- a/web/src/components/charts/LoadingComponents/ChartLoadingComponents.tsx
+++ b/web/src/components/charts/LoadingComponents/ChartLoadingComponents.tsx
@@ -1,6 +1,6 @@
'use client';
-import { Text } from '@/components/text';
+import { ShimmerText, Text } from '@/components/text';
import { busterChartsTwMerge } from '@/styles/busterChartsTwMerge';
import React from 'react';
@@ -8,17 +8,22 @@ export const PreparingYourRequestLoader: React.FC<{
className?: string;
text?: string;
error?: string | null;
-}> = ({ className = '', text = 'Processing your request...', error }) => {
+ useShimmer?: boolean;
+}> = ({ className = '', text = 'Processing your request...', error, useShimmer = true }) => {
return (
-
- {/* {!!error && } */}
- {error || text}
-
+ {error || useShimmer === false ? (
+
+ {/* {!!error && } */}
+ {error || text}
+
+ ) : (
+
+ )}
);
};
diff --git a/web/src/context/MetricData/BusterMetricDataProvider.tsx b/web/src/context/MetricData/BusterMetricDataProvider.tsx
index 126468c3b..0dcee635c 100644
--- a/web/src/context/MetricData/BusterMetricDataProvider.tsx
+++ b/web/src/context/MetricData/BusterMetricDataProvider.tsx
@@ -8,8 +8,8 @@ import { useMemoizedFn, useMount } from 'ahooks';
import { useBusterWebSocket } from '../BusterWebSocket';
import type { BusterMetricData } from '../Metrics';
import { MetricEvent_fetchingData } from '@/api/buster_socket/metrics/eventsInterfaces';
-import { MOCK_DATA } from './MOCK_DATA';
import { DEFAULT_MESSAGE_DATA } from './config';
+import { createMockData } from './MOCK_DATA';
const useMetricData = () => {
const busterSocket = useBusterWebSocket();
@@ -103,10 +103,7 @@ const useMetricData = () => {
setTimeout(() => {
//TODO: remove mock data
// _setMetricData(metricId, { ...MOCK_DATA, fetched: true });
- onSetDataForMetric({
- ...MOCK_DATA,
- metricId
- });
+ onSetDataForMetric(createMockData(metricId));
}, Math.random() * 5000);
return await busterSocket.emitAndOnce({
diff --git a/web/src/context/MetricData/MOCK_DATA.ts b/web/src/context/MetricData/MOCK_DATA.ts
index 56c477437..0346b830c 100644
--- a/web/src/context/MetricData/MOCK_DATA.ts
+++ b/web/src/context/MetricData/MOCK_DATA.ts
@@ -3,15 +3,13 @@ import type { BusterMetricData } from '../Metrics';
import { faker } from '@faker-js/faker';
const mockData = (): Record[] => {
- return Array.from({ length: faker.number.int({ min: 20, max: 150 }) }, (x, index) => ({
+ return Array.from({ length: faker.number.int({ min: 5, max: 150 }) }, (x, index) => ({
sales: index + 1,
date: faker.date.past({ years: index + 1 }).toISOString(),
product: faker.commerce.productName()
}));
};
-const data = mockData();
-
const dataMetadata: DataMetadata = {
column_count: 3,
column_metadata: [
@@ -40,15 +38,15 @@ const dataMetadata: DataMetadata = {
type: 'text'
}
],
- row_count: data.length
+ row_count: 1
};
-export const MOCK_DATA: Required = {
+const MOCK_DATA: Required = {
fetched: true,
fetching: false,
error: null,
fetchedAt: Date.now(),
- data: data,
+ data: mockData(),
metricId: faker.string.uuid(),
data_metadata: dataMetadata,
dataFromRerun: null,
@@ -62,9 +60,14 @@ ORDER BY date ASC`
};
export const createMockData = (metricId: string): Required => {
+ const data = mockData();
return {
...MOCK_DATA,
metricId,
- data: mockData()
+ data: data,
+ data_metadata: {
+ ...dataMetadata,
+ row_count: data.length
+ }
};
};
diff --git a/web/src/context/Metrics/MOCK_METRIC.ts b/web/src/context/Metrics/MOCK_METRIC.ts
index 2fbf7a58d..7e225a690 100644
--- a/web/src/context/Metrics/MOCK_METRIC.ts
+++ b/web/src/context/Metrics/MOCK_METRIC.ts
@@ -9,22 +9,38 @@ import { IBusterMetric } from './interfaces';
import { faker } from '@faker-js/faker';
import { ChartType } from '@/components/charts';
-const MOCK_CHART_CONFIG: IBusterMetricChartConfig = {
- ...DEFAULT_CHART_CONFIG,
- selectedChartType: ChartType.Bar,
- barAndLineAxis: {
- x: ['date'],
- y: ['sales'],
- category: []
- },
- pieChartAxis: {
- x: ['product'],
- y: ['sales']
- },
- scatterAxis: {
- x: ['date'],
- y: ['sales']
- }
+const createMockChartConfig = (): IBusterMetricChartConfig => {
+ const chartType = faker.helpers.arrayElement([
+ ChartType.Bar,
+ ChartType.Table,
+ ChartType.Line,
+ ChartType.Pie,
+ ChartType.Scatter,
+ ChartType.Metric
+ ]);
+
+ return {
+ ...DEFAULT_CHART_CONFIG,
+ selectedChartType: chartType,
+ barAndLineAxis: {
+ x: ['date'],
+ y: ['sales'],
+ category: []
+ },
+ pieChartAxis: {
+ x: ['product'],
+ y: ['sales']
+ },
+ scatterAxis: {
+ x: ['date'],
+ y: ['sales']
+ },
+ metricColumnId: 'sales',
+ metricHeader: {
+ columnId: 'sales',
+ useValue: false
+ }
+ };
};
const dataMetadata: DataMetadata = {
@@ -58,105 +74,100 @@ const dataMetadata: DataMetadata = {
row_count: 10
};
-export const MOCK_METRIC = (id = ''): IBusterMetric => ({
- id: id || '123',
- title: id + ' - ' + faker.lorem.words({ min: 2, max: 6 }),
- version_number: 1,
- file_name: `${faker.lorem.words({ min: 1, max: 3 })}.yml`,
- description: faker.commerce.productName(),
- data_source_id: '6840fa04-c0d7-4e0e-8d3d-ea9190d93874',
- time_frame: '1d',
- type: 'metric',
- chart_config: MOCK_CHART_CONFIG,
- fetched: true,
- fetching: false,
- fetchedAt: 0,
- dataset_id: '21c91803-c324-4341-98d1-960ef6a3e003',
- dataset_name: 'Mock Dataset',
- error: null,
- data_metadata: dataMetadata,
- status: VerificationStatus.notRequested,
- evaluation_score: 'Moderate',
- evaluation_summary: faker.lorem.sentence(33),
- file: `
-metric:
- name: sales_performance
- description: Monthly sales performance by product
- source: sales_database
- refresh_interval: daily
-
-dimensions:
- - name: date
- type: date
- format: YYYY-MM-DD
- - name: product
- type: string
- - name: region
- type: string
-
-measures:
- - name: sales_amount
- type: decimal
- aggregation: sum
- - name: units_sold
- type: integer
- aggregation: sum
-
-filters:
- - field: date
- operator: between
- value: [2024-01-01, 2024-12-31]
- - field: region
- operator: in
- value: [North, South, East, West]
-
-joins:
- - name: product_details
- type: left
- on: product_id
-
-sorting:
- - field: sales_amount
- direction: desc
-
-limit: 1000`,
- created_at: '',
- updated_at: '',
- sent_by_id: '',
- sent_by_name: '',
- sent_by_avatar_url: '',
- code: `WITH records AS (
- SELECT
- response_time_id,
- interaction_id,
- agent_id,
- customer_id,
- channel,
- date
- FROM demo.response_times
- ORDER BY date ASC
- LIMIT 100
-)
-SELECT * FROM records;`,
- feedback: null,
- draft_session_id: null,
- collections: [],
- dashboards: [],
- sharingKey: '',
- individual_permissions: [],
- team_permissions: [],
- organization_permissions: [],
- password_secret_id: '',
- public_expiry_date: '',
- public_enabled_by: '',
- publicly_accessible: false,
- public_password: '',
- permission: ShareRole.OWNER
-});
-
export const createMockMetric = (id: string): IBusterMetric => {
return {
- ...MOCK_METRIC(id),
+ title: id + ' - ' + faker.lorem.words({ min: 2, max: 6 }),
+ version_number: 1,
+ file_name: `${faker.lorem.words({ min: 1, max: 3 })}.yml`,
+ description: faker.commerce.productName(),
+ data_source_id: '6840fa04-c0d7-4e0e-8d3d-ea9190d93874',
+ time_frame: '1d',
+ type: 'metric',
+ chart_config: createMockChartConfig(),
+ fetched: true,
+ fetching: false,
+ fetchedAt: 0,
+ dataset_id: '21c91803-c324-4341-98d1-960ef6a3e003',
+ dataset_name: 'Mock Dataset',
+ error: null,
+ data_metadata: dataMetadata,
+ status: VerificationStatus.notRequested,
+ evaluation_score: 'Moderate',
+ evaluation_summary: faker.lorem.sentence(33),
+ file: `
+ metric:
+ name: sales_performance
+ description: Monthly sales performance by product
+ source: sales_database
+ refresh_interval: daily
+
+ dimensions:
+ - name: date
+ type: date
+ format: YYYY-MM-DD
+ - name: product
+ type: string
+ - name: region
+ type: string
+
+ measures:
+ - name: sales_amount
+ type: decimal
+ aggregation: sum
+ - name: units_sold
+ type: integer
+ aggregation: sum
+
+ filters:
+ - field: date
+ operator: between
+ value: [2024-01-01, 2024-12-31]
+ - field: region
+ operator: in
+ value: [North, South, East, West]
+
+ joins:
+ - name: product_details
+ type: left
+ on: product_id
+
+ sorting:
+ - field: sales_amount
+ direction: desc
+
+ limit: 1000`,
+ created_at: '',
+ updated_at: '',
+ sent_by_id: '',
+ sent_by_name: '',
+ sent_by_avatar_url: '',
+ code: `WITH records AS (
+ SELECT
+ response_time_id,
+ interaction_id,
+ agent_id,
+ customer_id,
+ channel,
+ date
+ FROM demo.response_times
+ ORDER BY date ASC
+ LIMIT 100
+ )
+ SELECT * FROM records;`,
+ feedback: null,
+ draft_session_id: null,
+ collections: [],
+ dashboards: [],
+ sharingKey: '',
+ individual_permissions: [],
+ team_permissions: [],
+ organization_permissions: [],
+ password_secret_id: '',
+ public_expiry_date: '',
+ public_enabled_by: '',
+ publicly_accessible: false,
+ public_password: '',
+ permission: ShareRole.OWNER,
id
};
};