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 }; };