diff --git a/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelFilterItem/LabelFilterItem.tsx b/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelFilterItem/LabelFilterItem.tsx index 9c1bed136f..d33362c55e 100644 --- a/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelFilterItem/LabelFilterItem.tsx +++ b/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelFilterItem/LabelFilterItem.tsx @@ -1,13 +1,19 @@ import { + Alert, Autocomplete, - Box, Checkbox, Chip, FormControlLabel, + styled, TextField, + Typography, } from '@mui/material'; import type { FC } from 'react'; +const StyledSelectAllLabel = styled('span')(({ theme }) => ({ + fontSize: theme.fontSizes.smallBody, +})); + type LabelFilterItemProps = { labelKey: string; options: string[]; @@ -25,6 +31,7 @@ export const LabelFilterItem: FC = ({ const isAllSelected = value.includes('*'); const autocompleteId = `autocomplete-${labelKey}`; const selectAllId = `select-all-${labelKey}`; + const isTruncated = options.length >= 1_000; return ( <> @@ -46,16 +53,7 @@ export const LabelFilterItem: FC = ({ }} /> } - label={ - ({ - fontSize: theme.fontSizes.smallBody, - })} - > - Select all - - } + label={Select all} /> = ({ onChange(newValues); }} disabled={isAllSelected} - renderTags={(value, getTagProps) => - value.map((option, index) => { - const { key, ...chipProps } = getTagProps({ - index, - }); - return ( - - ); - }) - } + renderTags={(value, getTagProps) => { + const overflowCount = 5; + const displayedValues = value.slice(-overflowCount); + const remainingCount = value.length - overflowCount; + + return ( + <> + {displayedValues.map((option, index) => { + const { key, ...chipProps } = getTagProps({ + index, + }); + return ( + + ); + })} + {remainingCount > 0 ? ( + + {' '} + (+{remainingCount}) + + ) : null} + + ); + }} renderInput={(params) => ( - + <> + + {isTruncated && ( + ({ + padding: theme.spacing(1, 2), + marginTop: theme.spacing(1), + })} + > + Maximum of 1000 values loaded due to + performance. + + )} + )} /> diff --git a/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelsFilter.tsx b/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelsFilter.tsx index 7c69ee985a..12b3a9b926 100644 --- a/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelsFilter.tsx +++ b/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelsFilter.tsx @@ -72,30 +72,32 @@ export const LabelsFilter: FC = ({ flexGrow: 1, }} > - {Object.entries(availableLabels).map(([labelKey, values]) => { - const currentSelection = selectedLabels[labelKey] || []; + {Object.entries(availableLabels) + .sort() + .map(([labelKey, values]) => { + const currentSelection = selectedLabels[labelKey] || []; - return ( - - - handleLabelChange(labelKey, newValues) - } - handleAllToggle={handleAllToggle} - /> - - ); - })} + return ( + + + handleLabelChange(labelKey, newValues) + } + handleAllToggle={handleAllToggle} + /> + + ); + })} ); diff --git a/frontend/src/component/impact-metrics/ImpactMetricsChart.tsx b/frontend/src/component/impact-metrics/ImpactMetricsChart.tsx index ca19837ac0..56b0613db5 100644 --- a/frontend/src/component/impact-metrics/ImpactMetricsChart.tsx +++ b/frontend/src/component/impact-metrics/ImpactMetricsChart.tsx @@ -202,6 +202,19 @@ export const ImpactMetricsChart: FC = ({ ) : null} + {isPreview && debug?.isTruncated ? ( + ({ + padding: theme.spacing(0, 2), + })} + > + + Showing only {timeSeriesData.length} series due to + performance. Please change filters for more accurate + results. + + + ) : null} ); }; diff --git a/frontend/src/hooks/api/getters/useImpactMetricsData/useImpactMetricsData.ts b/frontend/src/hooks/api/getters/useImpactMetricsData/useImpactMetricsData.ts index fae49fa1b8..4863d82069 100644 --- a/frontend/src/hooks/api/getters/useImpactMetricsData/useImpactMetricsData.ts +++ b/frontend/src/hooks/api/getters/useImpactMetricsData/useImpactMetricsData.ts @@ -10,6 +10,7 @@ export type ImpactMetricsSeries = { data: TimeSeriesData; }; +// TODO(impactMetrics): use OpenAPI types export type ImpactMetricsResponse = { start?: string; end?: string; @@ -18,6 +19,7 @@ export type ImpactMetricsResponse = { labels?: ImpactMetricsLabels; debug?: { query?: string; + isTruncated?: string; }; };