1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-31 13:47:02 +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 { 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';
export type LabelsFilterProps = {
@ -23,6 +31,16 @@ export const LabelsFilter: FC<LabelsFilterProps> = ({
onChange(newLabels);
};
const handleAllToggle = (labelKey: string, checked: boolean) => {
const newLabels = { ...selectedLabels };
if (checked) {
newLabels[labelKey] = ['*'];
} else {
delete newLabels[labelKey];
}
onChange(newLabels);
};
const clearAllLabels = () => {
onChange({});
};
@ -45,42 +63,74 @@ export const LabelsFilter: FC<LabelsFilterProps> = ({
)}
</Box>
{Object.entries(availableLabels).map(([labelKey, values]) => (
<Autocomplete
key={labelKey}
multiple
options={values}
value={selectedLabels[labelKey] || []}
onChange={(_, newValues) =>
handleLabelChange(labelKey, newValues)
}
renderTags={(value, getTagProps) =>
value.map((option, index) => {
const { key, ...chipProps } = getTagProps({
index,
});
return (
<Chip
{...chipProps}
key={key}
label={option}
{Object.entries(availableLabels).map(([labelKey, values]) => {
const currentSelection = selectedLabels[labelKey] || [];
const isAllSelected = currentSelection.includes('*');
return (
<Box
key={labelKey}
sx={(theme) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(3),
})}
>
<Autocomplete
multiple
options={values}
value={isAllSelected ? [] : currentSelection}
onChange={(_, newValues) => {
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'
/>
);
})
}
renderInput={(params) => (
<TextField
{...params}
label={labelKey}
placeholder='Select values...'
variant='outlined'
size='small'
)}
sx={{ minWidth: 300, flexGrow: 1 }}
/>
)}
sx={{ minWidth: 300 }}
/>
))}
<FormControlLabel
control={
<Checkbox
checked={isAllSelected}
onChange={(e) =>
handleAllToggle(
labelKey,
e.target.checked,
)
}
/>
}
label='All'
/>
</Box>
);
})}
</Box>
);
};

View File

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