mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: aggregation mode selection (#10367)
This commit is contained in:
		
							parent
							
								
									2d96becb28
								
							
						
					
					
						commit
						89f5f79836
					
				@ -120,7 +120,7 @@ export const ChartConfigModal: FC<ChartConfigModalProps> = ({
 | 
				
			|||||||
                            selectedRange={formData.selectedRange}
 | 
					                            selectedRange={formData.selectedRange}
 | 
				
			||||||
                            selectedLabels={formData.selectedLabels}
 | 
					                            selectedLabels={formData.selectedLabels}
 | 
				
			||||||
                            beginAtZero={formData.beginAtZero}
 | 
					                            beginAtZero={formData.beginAtZero}
 | 
				
			||||||
                            showRate={formData.showRate}
 | 
					                            aggregationMode={formData.aggregationMode}
 | 
				
			||||||
                        />
 | 
					                        />
 | 
				
			||||||
                    </StyledPreviewPanel>
 | 
					                    </StyledPreviewPanel>
 | 
				
			||||||
                </Box>
 | 
					                </Box>
 | 
				
			||||||
 | 
				
			|||||||
@ -21,8 +21,14 @@ const getConfigDescription = (config: DisplayChartConfig): string => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    parts.push(`last ${config.selectedRange}`);
 | 
					    parts.push(`last ${config.selectedRange}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.showRate) {
 | 
					    if (config.aggregationMode === 'rps') {
 | 
				
			||||||
        parts.push('rate per second');
 | 
					        parts.push('rate per second');
 | 
				
			||||||
 | 
					    } else if (config.aggregationMode === 'count') {
 | 
				
			||||||
 | 
					        parts.push('count');
 | 
				
			||||||
 | 
					    } else if (config.aggregationMode === 'avg') {
 | 
				
			||||||
 | 
					        parts.push('average');
 | 
				
			||||||
 | 
					    } else if (config.aggregationMode === 'sum') {
 | 
				
			||||||
 | 
					        parts.push('sum');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const labelCount = Object.keys(config.selectedLabels).length;
 | 
					    const labelCount = Object.keys(config.selectedLabels).length;
 | 
				
			||||||
@ -127,7 +133,7 @@ export const ChartItem: FC<ChartItemProps> = ({ config, onEdit, onDelete }) => (
 | 
				
			|||||||
                    selectedRange={config.selectedRange}
 | 
					                    selectedRange={config.selectedRange}
 | 
				
			||||||
                    selectedLabels={config.selectedLabels}
 | 
					                    selectedLabels={config.selectedLabels}
 | 
				
			||||||
                    beginAtZero={config.beginAtZero}
 | 
					                    beginAtZero={config.beginAtZero}
 | 
				
			||||||
                    showRate={config.showRate}
 | 
					                    aggregationMode={config.aggregationMode}
 | 
				
			||||||
                    aspectRatio={1.5}
 | 
					                    aspectRatio={1.5}
 | 
				
			||||||
                    overrideOptions={{ maintainAspectRatio: false }}
 | 
					                    overrideOptions={{ maintainAspectRatio: false }}
 | 
				
			||||||
                    emptyDataDescription='Send impact metrics using Unleash SDK for this series to view the chart.'
 | 
					                    emptyDataDescription='Send impact metrics using Unleash SDK for this series to view the chart.'
 | 
				
			||||||
 | 
				
			|||||||
@ -10,13 +10,14 @@ import { usePlaceholderData } from '../insights/hooks/usePlaceholderData.js';
 | 
				
			|||||||
import { getDisplayFormat, getTimeUnit, formatLargeNumbers } from './utils.ts';
 | 
					import { getDisplayFormat, getTimeUnit, formatLargeNumbers } from './utils.ts';
 | 
				
			||||||
import { fromUnixTime } from 'date-fns';
 | 
					import { fromUnixTime } from 'date-fns';
 | 
				
			||||||
import { useChartData } from './hooks/useChartData.ts';
 | 
					import { useChartData } from './hooks/useChartData.ts';
 | 
				
			||||||
 | 
					import type { AggregationMode } from './types.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ImpactMetricsChartProps = {
 | 
					type ImpactMetricsChartProps = {
 | 
				
			||||||
    selectedSeries: string;
 | 
					    selectedSeries: string;
 | 
				
			||||||
    selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
					    selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
				
			||||||
    selectedLabels: Record<string, string[]>;
 | 
					    selectedLabels: Record<string, string[]>;
 | 
				
			||||||
    beginAtZero: boolean;
 | 
					    beginAtZero: boolean;
 | 
				
			||||||
    showRate?: boolean;
 | 
					    aggregationMode?: AggregationMode;
 | 
				
			||||||
    aspectRatio?: number;
 | 
					    aspectRatio?: number;
 | 
				
			||||||
    overrideOptions?: Record<string, unknown>;
 | 
					    overrideOptions?: Record<string, unknown>;
 | 
				
			||||||
    errorTitle?: string;
 | 
					    errorTitle?: string;
 | 
				
			||||||
@ -30,7 +31,7 @@ export const ImpactMetricsChart: FC<ImpactMetricsChartProps> = ({
 | 
				
			|||||||
    selectedRange,
 | 
					    selectedRange,
 | 
				
			||||||
    selectedLabels,
 | 
					    selectedLabels,
 | 
				
			||||||
    beginAtZero,
 | 
					    beginAtZero,
 | 
				
			||||||
    showRate,
 | 
					    aggregationMode,
 | 
				
			||||||
    aspectRatio,
 | 
					    aspectRatio,
 | 
				
			||||||
    overrideOptions = {},
 | 
					    overrideOptions = {},
 | 
				
			||||||
    errorTitle = 'Failed to load impact metrics.',
 | 
					    errorTitle = 'Failed to load impact metrics.',
 | 
				
			||||||
@ -47,7 +48,7 @@ export const ImpactMetricsChart: FC<ImpactMetricsChartProps> = ({
 | 
				
			|||||||
            ? {
 | 
					            ? {
 | 
				
			||||||
                  series: selectedSeries,
 | 
					                  series: selectedSeries,
 | 
				
			||||||
                  range: selectedRange,
 | 
					                  range: selectedRange,
 | 
				
			||||||
                  showRate,
 | 
					                  aggregationMode,
 | 
				
			||||||
                  labels:
 | 
					                  labels:
 | 
				
			||||||
                      Object.keys(selectedLabels).length > 0
 | 
					                      Object.keys(selectedLabels).length > 0
 | 
				
			||||||
                          ? selectedLabels
 | 
					                          ? selectedLabels
 | 
				
			||||||
@ -121,14 +122,17 @@ export const ImpactMetricsChart: FC<ImpactMetricsChartProps> = ({
 | 
				
			|||||||
                  y: {
 | 
					                  y: {
 | 
				
			||||||
                      beginAtZero,
 | 
					                      beginAtZero,
 | 
				
			||||||
                      title: {
 | 
					                      title: {
 | 
				
			||||||
                          display: !!showRate,
 | 
					                          display: aggregationMode === 'rps',
 | 
				
			||||||
                          text: showRate ? 'Rate per second' : '',
 | 
					                          text:
 | 
				
			||||||
 | 
					                              aggregationMode === 'rps'
 | 
				
			||||||
 | 
					                                  ? 'Rate per second'
 | 
				
			||||||
 | 
					                                  : '',
 | 
				
			||||||
                      },
 | 
					                      },
 | 
				
			||||||
                      ticks: {
 | 
					                      ticks: {
 | 
				
			||||||
                          precision: 0,
 | 
					                          precision: 0,
 | 
				
			||||||
                          callback: (value: unknown): string | number =>
 | 
					                          callback: (value: unknown): string | number =>
 | 
				
			||||||
                              typeof value === 'number'
 | 
					                              typeof value === 'number'
 | 
				
			||||||
                                  ? `${formatLargeNumbers(value)}${showRate ? '/s' : ''}`
 | 
					                                  ? `${formatLargeNumbers(value)}${aggregationMode === 'rps' ? '/s' : ''}`
 | 
				
			||||||
                                  : (value as number),
 | 
					                                  : (value as number),
 | 
				
			||||||
                      },
 | 
					                      },
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
 | 
				
			|||||||
@ -2,13 +2,14 @@ import type { FC } from 'react';
 | 
				
			|||||||
import { Typography } from '@mui/material';
 | 
					import { Typography } from '@mui/material';
 | 
				
			||||||
import { StyledChartContainer } from 'component/insights/InsightsCharts.styles';
 | 
					import { StyledChartContainer } from 'component/insights/InsightsCharts.styles';
 | 
				
			||||||
import { ImpactMetricsChart } from './ImpactMetricsChart.tsx';
 | 
					import { ImpactMetricsChart } from './ImpactMetricsChart.tsx';
 | 
				
			||||||
 | 
					import type { AggregationMode } from './types.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ImpactMetricsChartPreviewProps = {
 | 
					type ImpactMetricsChartPreviewProps = {
 | 
				
			||||||
    selectedSeries: string;
 | 
					    selectedSeries: string;
 | 
				
			||||||
    selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
					    selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
				
			||||||
    selectedLabels: Record<string, string[]>;
 | 
					    selectedLabels: Record<string, string[]>;
 | 
				
			||||||
    beginAtZero: boolean;
 | 
					    beginAtZero: boolean;
 | 
				
			||||||
    showRate?: boolean;
 | 
					    aggregationMode?: AggregationMode;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ImpactMetricsChartPreview: FC<ImpactMetricsChartPreviewProps> = ({
 | 
					export const ImpactMetricsChartPreview: FC<ImpactMetricsChartPreviewProps> = ({
 | 
				
			||||||
@ -16,7 +17,7 @@ export const ImpactMetricsChartPreview: FC<ImpactMetricsChartPreviewProps> = ({
 | 
				
			|||||||
    selectedRange,
 | 
					    selectedRange,
 | 
				
			||||||
    selectedLabels,
 | 
					    selectedLabels,
 | 
				
			||||||
    beginAtZero,
 | 
					    beginAtZero,
 | 
				
			||||||
    showRate,
 | 
					    aggregationMode,
 | 
				
			||||||
}) => (
 | 
					}) => (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
        <Typography variant='h6' color='text.secondary'>
 | 
					        <Typography variant='h6' color='text.secondary'>
 | 
				
			||||||
@ -35,7 +36,7 @@ export const ImpactMetricsChartPreview: FC<ImpactMetricsChartPreviewProps> = ({
 | 
				
			|||||||
                selectedRange={selectedRange}
 | 
					                selectedRange={selectedRange}
 | 
				
			||||||
                selectedLabels={selectedLabels}
 | 
					                selectedLabels={selectedLabels}
 | 
				
			||||||
                beginAtZero={beginAtZero}
 | 
					                beginAtZero={beginAtZero}
 | 
				
			||||||
                showRate={showRate}
 | 
					                aggregationMode={aggregationMode}
 | 
				
			||||||
                isPreview
 | 
					                isPreview
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
        </StyledChartContainer>
 | 
					        </StyledChartContainer>
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,9 @@ import type { ImpactMetricsLabels } from 'hooks/api/getters/useImpactMetricsData
 | 
				
			|||||||
import { SeriesSelector } from './components/SeriesSelector.tsx';
 | 
					import { SeriesSelector } from './components/SeriesSelector.tsx';
 | 
				
			||||||
import { RangeSelector } from './components/RangeSelector.tsx';
 | 
					import { RangeSelector } from './components/RangeSelector.tsx';
 | 
				
			||||||
import { LabelsFilter } from './components/LabelsFilter.tsx';
 | 
					import { LabelsFilter } from './components/LabelsFilter.tsx';
 | 
				
			||||||
 | 
					import { ModeSelector } from './components/ModeSelector.tsx';
 | 
				
			||||||
import type { ChartFormState } from '../hooks/useChartFormState.ts';
 | 
					import type { ChartFormState } from '../hooks/useChartFormState.ts';
 | 
				
			||||||
 | 
					import { getMetricType } from '../utils.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ImpactMetricsControlsProps = {
 | 
					export type ImpactMetricsControlsProps = {
 | 
				
			||||||
    formData: ChartFormState['formData'];
 | 
					    formData: ChartFormState['formData'];
 | 
				
			||||||
@ -15,7 +17,7 @@ export type ImpactMetricsControlsProps = {
 | 
				
			|||||||
        | 'setSelectedRange'
 | 
					        | 'setSelectedRange'
 | 
				
			||||||
        | 'setBeginAtZero'
 | 
					        | 'setBeginAtZero'
 | 
				
			||||||
        | 'setSelectedLabels'
 | 
					        | 'setSelectedLabels'
 | 
				
			||||||
        | 'setShowRate'
 | 
					        | 'setAggregationMode'
 | 
				
			||||||
    >;
 | 
					    >;
 | 
				
			||||||
    metricSeries: (ImpactMetricsSeries & { name: string })[];
 | 
					    metricSeries: (ImpactMetricsSeries & { name: string })[];
 | 
				
			||||||
    loading?: boolean;
 | 
					    loading?: boolean;
 | 
				
			||||||
@ -68,17 +70,11 @@ export const ImpactMetricsControls: FC<ImpactMetricsControlsProps> = ({
 | 
				
			|||||||
                label='Begin at zero'
 | 
					                label='Begin at zero'
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {formData.selectedSeries.startsWith('unleash_counter_') ? (
 | 
					            {formData.selectedSeries ? (
 | 
				
			||||||
                <FormControlLabel
 | 
					                <ModeSelector
 | 
				
			||||||
                    control={
 | 
					                    value={formData.aggregationMode}
 | 
				
			||||||
                        <Checkbox
 | 
					                    onChange={actions.setAggregationMode}
 | 
				
			||||||
                            checked={formData.showRate}
 | 
					                    seriesType={getMetricType(formData.selectedSeries)!}
 | 
				
			||||||
                            onChange={(e) =>
 | 
					 | 
				
			||||||
                                actions.setShowRate(e.target.checked)
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        />
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    label='Show rate per second'
 | 
					 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
            ) : null}
 | 
					            ) : null}
 | 
				
			||||||
        </Box>
 | 
					        </Box>
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					import type { FC } from 'react';
 | 
				
			||||||
 | 
					import { FormControl, InputLabel, Select, MenuItem } from '@mui/material';
 | 
				
			||||||
 | 
					import type { AggregationMode } from '../../types.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ModeSelectorProps = {
 | 
				
			||||||
 | 
					    value: AggregationMode;
 | 
				
			||||||
 | 
					    onChange: (mode: AggregationMode) => void;
 | 
				
			||||||
 | 
					    seriesType: 'counter' | 'gauge' | 'unknown';
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ModeSelector: FC<ModeSelectorProps> = ({
 | 
				
			||||||
 | 
					    value,
 | 
				
			||||||
 | 
					    onChange,
 | 
				
			||||||
 | 
					    seriesType,
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					    if (seriesType === 'unknown') return null;
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <FormControl
 | 
				
			||||||
 | 
					            variant='outlined'
 | 
				
			||||||
 | 
					            size='small'
 | 
				
			||||||
 | 
					            sx={{ minWidth: 200, mt: 1 }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <InputLabel id='mode-select-label'>Mode</InputLabel>
 | 
				
			||||||
 | 
					            <Select
 | 
				
			||||||
 | 
					                labelId='mode-select-label'
 | 
				
			||||||
 | 
					                value={value}
 | 
				
			||||||
 | 
					                onChange={(e) => onChange(e.target.value as AggregationMode)}
 | 
				
			||||||
 | 
					                label='Mode'
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                {seriesType === 'counter'
 | 
				
			||||||
 | 
					                    ? [
 | 
				
			||||||
 | 
					                          <MenuItem key='rps' value='rps'>
 | 
				
			||||||
 | 
					                              Rate per second
 | 
				
			||||||
 | 
					                          </MenuItem>,
 | 
				
			||||||
 | 
					                          <MenuItem key='count' value='count'>
 | 
				
			||||||
 | 
					                              Count
 | 
				
			||||||
 | 
					                          </MenuItem>,
 | 
				
			||||||
 | 
					                      ]
 | 
				
			||||||
 | 
					                    : [
 | 
				
			||||||
 | 
					                          <MenuItem key='avg' value='avg'>
 | 
				
			||||||
 | 
					                              Average
 | 
				
			||||||
 | 
					                          </MenuItem>,
 | 
				
			||||||
 | 
					                          <MenuItem key='sum' value='sum'>
 | 
				
			||||||
 | 
					                              Sum
 | 
				
			||||||
 | 
					                          </MenuItem>,
 | 
				
			||||||
 | 
					                      ]}
 | 
				
			||||||
 | 
					            </Select>
 | 
				
			||||||
 | 
					        </FormControl>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
import { useState, useEffect } from 'react';
 | 
					import { useState, useEffect } from 'react';
 | 
				
			||||||
import { useImpactMetricsData } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
 | 
					import { useImpactMetricsData } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
 | 
				
			||||||
import type { ChartConfig } from '../types.ts';
 | 
					import type { AggregationMode, ChartConfig } from '../types.ts';
 | 
				
			||||||
import type { ImpactMetricsLabels } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
 | 
					import type { ImpactMetricsLabels } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
 | 
				
			||||||
 | 
					import { getMetricType } from '../utils.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UseChartConfigParams = {
 | 
					type UseChartConfigParams = {
 | 
				
			||||||
    open: boolean;
 | 
					    open: boolean;
 | 
				
			||||||
@ -14,7 +15,7 @@ export type ChartFormState = {
 | 
				
			|||||||
        selectedSeries: string;
 | 
					        selectedSeries: string;
 | 
				
			||||||
        selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
					        selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
				
			||||||
        beginAtZero: boolean;
 | 
					        beginAtZero: boolean;
 | 
				
			||||||
        showRate: boolean;
 | 
					        aggregationMode: AggregationMode;
 | 
				
			||||||
        selectedLabels: Record<string, string[]>;
 | 
					        selectedLabels: Record<string, string[]>;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    actions: {
 | 
					    actions: {
 | 
				
			||||||
@ -22,7 +23,7 @@ export type ChartFormState = {
 | 
				
			|||||||
        setSelectedSeries: (series: string) => void;
 | 
					        setSelectedSeries: (series: string) => void;
 | 
				
			||||||
        setSelectedRange: (range: 'hour' | 'day' | 'week' | 'month') => void;
 | 
					        setSelectedRange: (range: 'hour' | 'day' | 'week' | 'month') => void;
 | 
				
			||||||
        setBeginAtZero: (beginAtZero: boolean) => void;
 | 
					        setBeginAtZero: (beginAtZero: boolean) => void;
 | 
				
			||||||
        setShowRate: (showRate: boolean) => void;
 | 
					        setAggregationMode: (mode: AggregationMode) => void;
 | 
				
			||||||
        setSelectedLabels: (labels: Record<string, string[]>) => void;
 | 
					        setSelectedLabels: (labels: Record<string, string[]>) => void;
 | 
				
			||||||
        handleSeriesChange: (series: string) => void;
 | 
					        handleSeriesChange: (series: string) => void;
 | 
				
			||||||
        getConfigToSave: () => Omit<ChartConfig, 'id'>;
 | 
					        getConfigToSave: () => Omit<ChartConfig, 'id'>;
 | 
				
			||||||
@ -48,7 +49,12 @@ export const useChartFormState = ({
 | 
				
			|||||||
    const [selectedLabels, setSelectedLabels] = useState<
 | 
					    const [selectedLabels, setSelectedLabels] = useState<
 | 
				
			||||||
        Record<string, string[]>
 | 
					        Record<string, string[]>
 | 
				
			||||||
    >(initialConfig?.selectedLabels || {});
 | 
					    >(initialConfig?.selectedLabels || {});
 | 
				
			||||||
    const [showRate, setShowRate] = useState(initialConfig?.showRate || false);
 | 
					    const [aggregationMode, setAggregationMode] = useState<AggregationMode>(
 | 
				
			||||||
 | 
					        (initialConfig?.aggregationMode || getMetricType(selectedSeries)) ===
 | 
				
			||||||
 | 
					            'counter'
 | 
				
			||||||
 | 
					            ? 'count'
 | 
				
			||||||
 | 
					            : 'avg',
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const {
 | 
					    const {
 | 
				
			||||||
        data: { labels: currentAvailableLabels },
 | 
					        data: { labels: currentAvailableLabels },
 | 
				
			||||||
@ -57,7 +63,7 @@ export const useChartFormState = ({
 | 
				
			|||||||
            ? {
 | 
					            ? {
 | 
				
			||||||
                  series: selectedSeries,
 | 
					                  series: selectedSeries,
 | 
				
			||||||
                  range: selectedRange,
 | 
					                  range: selectedRange,
 | 
				
			||||||
                  showRate,
 | 
					                  aggregationMode,
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            : undefined,
 | 
					            : undefined,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -69,20 +75,31 @@ export const useChartFormState = ({
 | 
				
			|||||||
            setSelectedRange(initialConfig.selectedRange);
 | 
					            setSelectedRange(initialConfig.selectedRange);
 | 
				
			||||||
            setBeginAtZero(initialConfig.beginAtZero);
 | 
					            setBeginAtZero(initialConfig.beginAtZero);
 | 
				
			||||||
            setSelectedLabels(initialConfig.selectedLabels);
 | 
					            setSelectedLabels(initialConfig.selectedLabels);
 | 
				
			||||||
            setShowRate(initialConfig.showRate || false);
 | 
					            setAggregationMode(
 | 
				
			||||||
 | 
					                initialConfig.aggregationMode ||
 | 
				
			||||||
 | 
					                    (getMetricType(initialConfig.selectedSeries) === 'counter'
 | 
				
			||||||
 | 
					                        ? 'count'
 | 
				
			||||||
 | 
					                        : 'avg'),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        } else if (open && !initialConfig) {
 | 
					        } else if (open && !initialConfig) {
 | 
				
			||||||
            setTitle('');
 | 
					            setTitle('');
 | 
				
			||||||
            setSelectedSeries('');
 | 
					            setSelectedSeries('');
 | 
				
			||||||
            setSelectedRange('day');
 | 
					            setSelectedRange('day');
 | 
				
			||||||
            setBeginAtZero(false);
 | 
					            setBeginAtZero(false);
 | 
				
			||||||
            setSelectedLabels({});
 | 
					            setSelectedLabels({});
 | 
				
			||||||
            setShowRate(false);
 | 
					            setAggregationMode('count');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }, [open, initialConfig]);
 | 
					    }, [open, initialConfig]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const handleSeriesChange = (series: string) => {
 | 
					    const handleSeriesChange = (series: string) => {
 | 
				
			||||||
        setSelectedSeries(series);
 | 
					        setSelectedSeries(series);
 | 
				
			||||||
        setSelectedLabels({});
 | 
					        setSelectedLabels({});
 | 
				
			||||||
 | 
					        const metric = getMetricType(series);
 | 
				
			||||||
 | 
					        if (metric === 'counter') {
 | 
				
			||||||
 | 
					            setAggregationMode('count');
 | 
				
			||||||
 | 
					        } else if (metric === 'gauge') {
 | 
				
			||||||
 | 
					            setAggregationMode('avg');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const getConfigToSave = (): Omit<ChartConfig, 'id'> => ({
 | 
					    const getConfigToSave = (): Omit<ChartConfig, 'id'> => ({
 | 
				
			||||||
@ -91,7 +108,7 @@ export const useChartFormState = ({
 | 
				
			|||||||
        selectedRange,
 | 
					        selectedRange,
 | 
				
			||||||
        beginAtZero,
 | 
					        beginAtZero,
 | 
				
			||||||
        selectedLabels,
 | 
					        selectedLabels,
 | 
				
			||||||
        showRate,
 | 
					        aggregationMode,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const isValid = selectedSeries.length > 0;
 | 
					    const isValid = selectedSeries.length > 0;
 | 
				
			||||||
@ -102,7 +119,7 @@ export const useChartFormState = ({
 | 
				
			|||||||
            selectedSeries,
 | 
					            selectedSeries,
 | 
				
			||||||
            selectedRange,
 | 
					            selectedRange,
 | 
				
			||||||
            beginAtZero,
 | 
					            beginAtZero,
 | 
				
			||||||
            showRate,
 | 
					            aggregationMode,
 | 
				
			||||||
            selectedLabels,
 | 
					            selectedLabels,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        actions: {
 | 
					        actions: {
 | 
				
			||||||
@ -110,7 +127,7 @@ export const useChartFormState = ({
 | 
				
			|||||||
            setSelectedSeries,
 | 
					            setSelectedSeries,
 | 
				
			||||||
            setSelectedRange,
 | 
					            setSelectedRange,
 | 
				
			||||||
            setBeginAtZero,
 | 
					            setBeginAtZero,
 | 
				
			||||||
            setShowRate,
 | 
					            setAggregationMode,
 | 
				
			||||||
            setSelectedLabels,
 | 
					            setSelectedLabels,
 | 
				
			||||||
            handleSeriesChange,
 | 
					            handleSeriesChange,
 | 
				
			||||||
            getConfigToSave,
 | 
					            getConfigToSave,
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,7 @@ const TestComponent: FC<{
 | 
				
			|||||||
                            selectedSeries: 'test-series',
 | 
					                            selectedSeries: 'test-series',
 | 
				
			||||||
                            selectedRange: 'day',
 | 
					                            selectedRange: 'day',
 | 
				
			||||||
                            beginAtZero: true,
 | 
					                            beginAtZero: true,
 | 
				
			||||||
                            showRate: false,
 | 
					                            aggregationMode: 'count',
 | 
				
			||||||
                            selectedLabels: {},
 | 
					                            selectedLabels: {},
 | 
				
			||||||
                            title: 'Test Chart',
 | 
					                            title: 'Test Chart',
 | 
				
			||||||
                        })
 | 
					                        })
 | 
				
			||||||
@ -79,7 +79,7 @@ const mockSettings: ImpactMetricsState = {
 | 
				
			|||||||
            selectedSeries: 'test-series',
 | 
					            selectedSeries: 'test-series',
 | 
				
			||||||
            selectedRange: 'day' as const,
 | 
					            selectedRange: 'day' as const,
 | 
				
			||||||
            beginAtZero: true,
 | 
					            beginAtZero: true,
 | 
				
			||||||
            showRate: false,
 | 
					            aggregationMode: 'count',
 | 
				
			||||||
            selectedLabels: {},
 | 
					            selectedLabels: {},
 | 
				
			||||||
            title: 'Test Chart',
 | 
					            title: 'Test Chart',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@ -182,7 +182,7 @@ describe('useImpactMetricsState', () => {
 | 
				
			|||||||
                        selectedSeries: 'test-series',
 | 
					                        selectedSeries: 'test-series',
 | 
				
			||||||
                        selectedRange: 'day',
 | 
					                        selectedRange: 'day',
 | 
				
			||||||
                        beginAtZero: true,
 | 
					                        beginAtZero: true,
 | 
				
			||||||
                        showRate: false,
 | 
					                        mode: 'count',
 | 
				
			||||||
                        selectedLabels: {},
 | 
					                        selectedLabels: {},
 | 
				
			||||||
                        title: 'Test Chart',
 | 
					                        title: 'Test Chart',
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
@ -215,7 +215,7 @@ describe('useImpactMetricsState', () => {
 | 
				
			|||||||
                        selectedSeries: 'test-series',
 | 
					                        selectedSeries: 'test-series',
 | 
				
			||||||
                        selectedRange: 'day',
 | 
					                        selectedRange: 'day',
 | 
				
			||||||
                        beginAtZero: true,
 | 
					                        beginAtZero: true,
 | 
				
			||||||
                        showRate: false,
 | 
					                        mode: 'count',
 | 
				
			||||||
                        selectedLabels: {},
 | 
					                        selectedLabels: {},
 | 
				
			||||||
                        title: 'Test Chart',
 | 
					                        title: 'Test Chart',
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
 | 
				
			|||||||
@ -3,11 +3,13 @@ export type ChartConfig = {
 | 
				
			|||||||
    selectedSeries: string; // e.g. unleash_counter_my_metric
 | 
					    selectedSeries: string; // e.g. unleash_counter_my_metric
 | 
				
			||||||
    selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
					    selectedRange: 'hour' | 'day' | 'week' | 'month';
 | 
				
			||||||
    beginAtZero: boolean;
 | 
					    beginAtZero: boolean;
 | 
				
			||||||
    showRate: boolean;
 | 
					    aggregationMode: AggregationMode;
 | 
				
			||||||
    selectedLabels: Record<string, string[]>;
 | 
					    selectedLabels: Record<string, string[]>;
 | 
				
			||||||
    title?: string;
 | 
					    title?: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type AggregationMode = 'rps' | 'count' | 'avg' | 'sum';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type DisplayChartConfig = ChartConfig & {
 | 
					export type DisplayChartConfig = ChartConfig & {
 | 
				
			||||||
    type: 'counter' | 'gauge';
 | 
					    type: 'counter' | 'gauge';
 | 
				
			||||||
    displayName: string; // e.g. my_metric with unleash_counter stripped
 | 
					    displayName: string; // e.g. my_metric with unleash_counter stripped
 | 
				
			||||||
 | 
				
			|||||||
@ -60,3 +60,9 @@ export const formatLargeNumbers = (value: number): string => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return value.toString();
 | 
					    return value.toString();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getMetricType = (seriesName: string) => {
 | 
				
			||||||
 | 
					    if (seriesName.startsWith('unleash_counter_')) return 'counter';
 | 
				
			||||||
 | 
					    if (seriesName.startsWith('unleash_gauge_')) return 'gauge';
 | 
				
			||||||
 | 
					    return 'unknown';
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ export type ImpactMetricsQuery = {
 | 
				
			|||||||
    series: string;
 | 
					    series: string;
 | 
				
			||||||
    range: 'hour' | 'day' | 'week' | 'month';
 | 
					    range: 'hour' | 'day' | 'week' | 'month';
 | 
				
			||||||
    labels?: Record<string, string[]>;
 | 
					    labels?: Record<string, string[]>;
 | 
				
			||||||
    showRate?: boolean;
 | 
					    aggregationMode?: 'rps' | 'count' | 'avg' | 'sum';
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const useImpactMetricsData = (query?: ImpactMetricsQuery) => {
 | 
					export const useImpactMetricsData = (query?: ImpactMetricsQuery) => {
 | 
				
			||||||
@ -38,8 +38,8 @@ export const useImpactMetricsData = (query?: ImpactMetricsQuery) => {
 | 
				
			|||||||
            range: query.range,
 | 
					            range: query.range,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (query.showRate !== undefined) {
 | 
					        if (query.aggregationMode !== undefined) {
 | 
				
			||||||
            params.append('showRate', query.showRate.toString());
 | 
					            params.append('aggregationMode', query.aggregationMode);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (query.labels && Object.keys(query.labels).length > 0) {
 | 
					        if (query.labels && Object.keys(query.labels).length > 0) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user