go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/components/metrics_selector/metrics_selector.tsx (about) 1 // Copyright 2023 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { 16 Checkbox, 17 ListItemText, 18 MenuItem, 19 OutlinedInput, 20 Select, 21 SelectChangeEvent, 22 } from '@mui/material'; 23 24 import { ProjectMetric } from '@/proto/go.chromium.org/luci/analysis/proto/v1/metrics.pb'; 25 import { MetricId } from '@/types/metric_id'; 26 27 const MenuProps = { 28 PaperProps: { 29 style: { 30 maxHeight: 500, 31 width: 250, 32 }, 33 }, 34 }; 35 36 interface Props { 37 metrics: ProjectMetric[]; 38 selectedMetrics: MetricId[]; 39 handleSelectedMetricsChanged: (selectedMetricsIds: MetricId[]) => void; 40 labelId?: string; 41 } 42 43 const MetricsSelector = ({ 44 metrics, 45 selectedMetrics, 46 handleSelectedMetricsChanged, 47 labelId, 48 }: Props) => { 49 function selectionChanged(event: SelectChangeEvent<string[]>) { 50 const { 51 target: { value }, 52 } = event; 53 // On autofill we get a stringified value. 54 const selectedMetricsValue = typeof value === 'string' ? value.split(',') : value; 55 56 handleSelectedMetricsChanged(selectedMetricsValue); 57 } 58 59 function renderValue(selected: string[]) { 60 return metrics.filter((m) => selected.indexOf(m.metricId) >= 0) 61 .map((m) => m.humanReadableName).join(', '); 62 } 63 return ( 64 <Select 65 labelId={labelId} 66 multiple 67 value={selectedMetrics} 68 onChange={selectionChanged} 69 input={<OutlinedInput label="Metrics" />} 70 renderValue={renderValue} 71 MenuProps={MenuProps} 72 inputProps={{ 73 'data-testid': 'metrics-selector', 74 }} 75 > 76 {metrics.map((metric) => ( 77 <MenuItem key={metric.metricId} value={metric.metricId} sx={{ 78 whiteSpace: 'unset', 79 wordBreak: 'break-word', 80 }}> 81 <Checkbox checked={selectedMetrics.indexOf(metric.metricId) > -1} /> 82 <ListItemText primary={metric.humanReadableName} secondary={metric.description} /> 83 </MenuItem> 84 ))} 85 </Select> 86 ); 87 }; 88 89 export default MetricsSelector;