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