1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-04 13:48:56 +02:00

feat: add impact metrics wildcard label (#10373)

This commit is contained in:
Tymoteusz Czech 2025-07-21 10:50:14 +02:00 committed by GitHub
parent 253c2d71b3
commit c1df04548d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 85 additions and 34 deletions

View File

@ -1,5 +1,13 @@
import type { FC } from 'react'; import type { FC } from 'react';
import { Box, Autocomplete, TextField, Typography, Chip } from '@mui/material'; import {
Box,
Autocomplete,
TextField,
Typography,
Chip,
Checkbox,
FormControlLabel,
} from '@mui/material';
import type { ImpactMetricsLabels } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData'; import type { ImpactMetricsLabels } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
export type LabelsFilterProps = { export type LabelsFilterProps = {
@ -23,6 +31,16 @@ export const LabelsFilter: FC<LabelsFilterProps> = ({
onChange(newLabels); onChange(newLabels);
}; };
const handleAllToggle = (labelKey: string, checked: boolean) => {
const newLabels = { ...selectedLabels };
if (checked) {
newLabels[labelKey] = ['*'];
} else {
delete newLabels[labelKey];
}
onChange(newLabels);
};
const clearAllLabels = () => { const clearAllLabels = () => {
onChange({}); onChange({});
}; };
@ -45,42 +63,74 @@ export const LabelsFilter: FC<LabelsFilterProps> = ({
)} )}
</Box> </Box>
{Object.entries(availableLabels).map(([labelKey, values]) => ( {Object.entries(availableLabels).map(([labelKey, values]) => {
<Autocomplete const currentSelection = selectedLabels[labelKey] || [];
key={labelKey} const isAllSelected = currentSelection.includes('*');
multiple
options={values} return (
value={selectedLabels[labelKey] || []} <Box
onChange={(_, newValues) => key={labelKey}
handleLabelChange(labelKey, newValues) sx={(theme) => ({
} display: 'flex',
renderTags={(value, getTagProps) => alignItems: 'center',
value.map((option, index) => { gap: theme.spacing(3),
const { key, ...chipProps } = getTagProps({ })}
index, >
}); <Autocomplete
return ( multiple
<Chip options={values}
{...chipProps} value={isAllSelected ? [] : currentSelection}
key={key} onChange={(_, newValues) => {
label={option} handleLabelChange(labelKey, newValues);
}}
disabled={isAllSelected}
renderTags={(value, getTagProps) =>
value.map((option, index) => {
const { key, ...chipProps } = getTagProps({
index,
});
return (
<Chip
{...chipProps}
key={key}
label={option}
size='small'
/>
);
})
}
renderInput={(params) => (
<TextField
{...params}
label={labelKey}
placeholder={
isAllSelected
? 'All values selected'
: 'Select values…'
}
variant='outlined'
size='small' size='small'
/> />
); )}
}) sx={{ minWidth: 300, flexGrow: 1 }}
}
renderInput={(params) => (
<TextField
{...params}
label={labelKey}
placeholder='Select values...'
variant='outlined'
size='small'
/> />
)} <FormControlLabel
sx={{ minWidth: 300 }} control={
/> <Checkbox
))} checked={isAllSelected}
onChange={(e) =>
handleAllToggle(
labelKey,
e.target.checked,
)
}
/>
}
label='All'
/>
</Box>
);
})}
</Box> </Box>
); );
}; };

View File

@ -8,6 +8,7 @@ const getColorStartingIndex = (modulo: number, series?: string): number => {
return 0; return 0;
} }
// https://stackoverflow.com/a/7616484/1729641
let hash = 0; let hash = 0;
for (let i = 0; i < series.length; i++) { for (let i = 0; i < series.length; i++) {
const char = series.charCodeAt(i); const char = series.charCodeAt(i);