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 d33362c55e..491041bb31 100644 --- a/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelFilterItem/LabelFilterItem.tsx +++ b/frontend/src/component/impact-metrics/ChartConfigModal/LabelFilter/LabelFilterItem/LabelFilterItem.tsx @@ -3,17 +3,12 @@ import { Autocomplete, Checkbox, Chip, - FormControlLabel, - styled, TextField, Typography, } from '@mui/material'; +import { METRIC_LABELS_SELECT_ALL } from 'component/impact-metrics/hooks/useImpactMetricsState'; import type { FC } from 'react'; -const StyledSelectAllLabel = styled('span')(({ theme }) => ({ - fontSize: theme.fontSizes.smallBody, -})); - type LabelFilterItemProps = { labelKey: string; options: string[]; @@ -28,106 +23,111 @@ export const LabelFilterItem: FC = ({ value, onChange, }) => { - const isAllSelected = value.includes('*'); + const isAllSelected = value.includes(METRIC_LABELS_SELECT_ALL); const autocompleteId = `autocomplete-${labelKey}`; - const selectAllId = `select-all-${labelKey}`; const isTruncated = options.length >= 1_000; - return ( - <> - ({ - marginLeft: theme.spacing(0), - })} - control={ - - onChange(e.target.checked ? ['*'] : []) - } - inputProps={{ - 'aria-describedby': autocompleteId, - 'aria-label': `Select all ${labelKey} options`, - }} - /> - } - label={Select all} - /> - { - onChange(newValues); - }} - disabled={isAllSelected} - renderTags={(value, getTagProps) => { - const overflowCount = 5; - const displayedValues = value.slice(-overflowCount); - const remainingCount = value.length - overflowCount; + const optionsWithSelectAll = [METRIC_LABELS_SELECT_ALL, ...options]; - return ( - <> - {displayedValues.map((option, index) => { - const { key, ...chipProps } = getTagProps({ - index, - }); - return ( - - ); - })} - {remainingCount > 0 ? ( - - {' '} - (+{remainingCount}) - - ) : null} - - ); - }} - renderInput={(params) => ( + return ( + + option === METRIC_LABELS_SELECT_ALL ? '(Select all)' : option + } + onChange={(_, newValues, reason, details) => { + if (details?.option === METRIC_LABELS_SELECT_ALL) { + onChange(isAllSelected ? [] : [METRIC_LABELS_SELECT_ALL]); + return; + } + onChange( + newValues.filter((v) => v !== METRIC_LABELS_SELECT_ALL), + ); + }} + renderOption={(props, option, { selected }) => ( +
  • + + {option === METRIC_LABELS_SELECT_ALL ? ( + + Select all + + ) : ( + option + )} +
  • + )} + renderTags={(value, getTagProps) => { + const overflowCount = 5; + const displayedValues = value.slice(-overflowCount); + const remainingCount = value.length - overflowCount; + + return ( <> - - {isTruncated && ( - ({ - padding: theme.spacing(1, 2), - marginTop: theme.spacing(1), - })} + {displayedValues.map((option, index) => { + const { key, ...chipProps } = getTagProps({ + index, + }); + return ( + + ); + })} + {remainingCount > 0 ? ( + - Maximum of 1000 values loaded due to - performance. - - )} + {' '} + (+{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/hooks/useImpactMetricsState.ts b/frontend/src/component/impact-metrics/hooks/useImpactMetricsState.ts index b2e8caec52..55e427ea44 100644 --- a/frontend/src/component/impact-metrics/hooks/useImpactMetricsState.ts +++ b/frontend/src/component/impact-metrics/hooks/useImpactMetricsState.ts @@ -3,6 +3,12 @@ import { useImpactMetricsSettings } from 'hooks/api/getters/useImpactMetricsSett import { useImpactMetricsSettingsApi } from 'hooks/api/actions/useImpactMetricsSettingsApi/useImpactMetricsSettingsApi.js'; import type { ChartConfig, ImpactMetricsState, LayoutItem } from '../types.ts'; +/** + * "Select all" represents all current and future labels. + * Asterisk (*) is sent to the backend. This will create a different query then sending every current label. + */ +export const METRIC_LABELS_SELECT_ALL = '*'; + export const useImpactMetricsState = () => { const { settings,