1import React, { FC, useCallback } from 'react'; 2import { GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; 3import { ColorDimensionConfig } from '../types'; 4import { Select, ColorPicker, useStyles2 } from '@grafana/ui'; 5import { 6 useFieldDisplayNames, 7 useSelectOptions, 8} from '../../../../../packages/grafana-ui/src/components/MatchersUI/utils'; 9import { css } from '@emotion/css'; 10 11const fixedColorOption: SelectableValue<string> = { 12 label: 'Fixed color', 13 value: '_____fixed_____', 14}; 15 16export const ColorDimensionEditor: FC<StandardEditorProps<ColorDimensionConfig, any, any>> = (props) => { 17 const { value, context, onChange } = props; 18 19 const defaultColor = 'dark-green'; 20 21 const styles = useStyles2(getStyles); 22 const fieldName = value?.field; 23 const isFixed = Boolean(!fieldName); 24 const names = useFieldDisplayNames(context.data); 25 const selectOptions = useSelectOptions(names, fieldName, fixedColorOption); 26 27 const onSelectChange = useCallback( 28 (selection: SelectableValue<string>) => { 29 const field = selection.value; 30 if (field && field !== fixedColorOption.value) { 31 onChange({ 32 ...value, 33 field, 34 }); 35 } else { 36 const fixed = value.fixed ?? defaultColor; 37 onChange({ 38 ...value, 39 field: undefined, 40 fixed, 41 }); 42 } 43 }, 44 [onChange, value] 45 ); 46 47 const onColorChange = useCallback( 48 (c: string) => { 49 onChange({ 50 field: undefined, 51 fixed: c ?? defaultColor, 52 }); 53 }, 54 [onChange] 55 ); 56 57 const selectedOption = isFixed ? fixedColorOption : selectOptions.find((v) => v.value === fieldName); 58 return ( 59 <> 60 <div className={styles.container}> 61 <Select 62 menuShouldPortal 63 value={selectedOption} 64 options={selectOptions} 65 onChange={onSelectChange} 66 noOptionsMessage="No fields found" 67 /> 68 {isFixed && ( 69 <div className={styles.picker}> 70 <ColorPicker color={value?.fixed ?? defaultColor} onChange={onColorChange} enableNamedColors={true} /> 71 </div> 72 )} 73 </div> 74 </> 75 ); 76}; 77 78const getStyles = (theme: GrafanaTheme2) => ({ 79 container: css` 80 display: flex; 81 flex-wrap: nowrap; 82 justify-content: flex-end; 83 align-items: center; 84 `, 85 picker: css` 86 padding-left: 8px; 87 `, 88}); 89