diff --git a/public/app/core/components/editors/registry.tsx b/public/app/core/components/editors/registry.tsx index 7573387f02f..d9e80595205 100644 --- a/public/app/core/components/editors/registry.tsx +++ b/public/app/core/components/editors/registry.tsx @@ -13,7 +13,7 @@ import { ValueMappingFieldConfigSettings, valueMappingsOverrideProcessor, } from '@grafana/data'; -import { ValueMappingsValueEditor } from 'app/features/dimensions/editors/ValueMappingsEditor/mappings'; +import { ValueMappingsEditor } from 'app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor'; import { ThresholdsValueEditor } from 'app/features/dimensions/editors/ThresholdsEditor/thresholds'; /** @@ -31,7 +31,7 @@ export const getAllOptionEditors = () => { id: 'mappings', name: 'Mappings', description: 'Allows defining value mappings', - editor: ValueMappingsValueEditor as any, + editor: ValueMappingsEditor as any, }; const thresholds: StandardEditorsRegistryItem = { diff --git a/public/app/features/dimensions/color.ts b/public/app/features/dimensions/color.ts index ebe82ef586e..d38a3fc34be 100644 --- a/public/app/features/dimensions/color.ts +++ b/public/app/features/dimensions/color.ts @@ -1,4 +1,4 @@ -import { DataFrame, Field, getFieldColorModeForField, getScaleCalculator, GrafanaTheme2 } from '@grafana/data'; +import { DataFrame, Field, getDisplayProcessor, getFieldColorModeForField, GrafanaTheme2 } from '@grafana/data'; import { ColorDimensionConfig, DimensionSupplier } from './types'; import { findField, getLastNotNullFieldValue } from './utils'; @@ -20,7 +20,7 @@ export function getColorDimensionForField( theme: GrafanaTheme2 ): DimensionSupplier { if (!field) { - const v = theme.visualization.getColorByName(config.fixed) ?? 'grey'; + const v = theme.visualization.getColorByName(config.fixed ?? 'grey'); return { isAssumed: Boolean(config.field?.length) || !config.fixed, fixed: v, @@ -28,23 +28,28 @@ export function getColorDimensionForField( get: (i) => v, }; } + + // Use the expensive color calculation by value const mode = getFieldColorModeForField(field); - if (!mode.isByValue) { - const fixed = mode.getCalculator(field, theme)(0, 0); + if (mode.isByValue || field.config.mappings?.length) { + const disp = getDisplayProcessor({ field, theme }); + const getColor = (value: any): string => { + return disp(value).color ?? '#ccc'; + }; + return { - fixed, - value: () => fixed, - get: (i) => fixed, field, + get: (index: number): string => getColor(field.values.get(index)), + value: () => getColor(getLastNotNullFieldValue(field)), }; } - const scale = getScaleCalculator(field, theme); + + // Typically series or fixed color (does not depend on value) + const fixed = mode.getCalculator(field, theme)(0, 0); return { - get: (i) => { - const val = field.values.get(i); - return scale(val).color; - }, + fixed, + value: () => fixed, + get: (i) => fixed, field, - value: () => scale(getLastNotNullFieldValue(field)).color, }; } diff --git a/public/app/features/dimensions/editors/ColorDimensionEditor.tsx b/public/app/features/dimensions/editors/ColorDimensionEditor.tsx index 699b9411aee..823fa1989c5 100644 --- a/public/app/features/dimensions/editors/ColorDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ColorDimensionEditor.tsx @@ -33,7 +33,7 @@ export const ColorDimensionEditor: FC )} {mode === ResourceDimensionMode.Mapping && ( diff --git a/public/app/features/dimensions/editors/ResourcePicker.tsx b/public/app/features/dimensions/editors/ResourcePicker.tsx index dd246ff3b0d..938792bc14d 100644 --- a/public/app/features/dimensions/editors/ResourcePicker.tsx +++ b/public/app/features/dimensions/editors/ResourcePicker.tsx @@ -1,34 +1,83 @@ import React, { createRef } from 'react'; import { css } from '@emotion/css'; -import { Button, InlineField, InlineFieldRow, Input, Popover, PopoverController, useStyles2 } from '@grafana/ui'; +import { + Button, + InlineField, + InlineFieldRow, + Input, + LinkButton, + Popover, + PopoverController, + useStyles2, + useTheme2, +} from '@grafana/ui'; import { GrafanaTheme2 } from '@grafana/data'; import SVG from 'react-inlinesvg'; -import { MediaType, ResourceFolderName } from '../types'; +import { MediaType, ResourceFolderName, ResourcePickerSize } from '../types'; import { closePopover } from '@grafana/ui/src/utils/closePopover'; import { ResourcePickerPopover } from './ResourcePickerPopover'; +import { getPublicOrAbsoluteUrl } from '../resource'; interface Props { + onChange: (value?: string) => void; + mediaType: MediaType; + folderName: ResourceFolderName; + size: ResourcePickerSize; + onClear?: (event: React.MouseEvent) => void; value?: string; //img/icons/unicons/0-plus.svg src?: string; name?: string; placeholder?: string; - onChange: (value?: string) => void; - onClear: (event: React.MouseEvent) => void; - mediaType: MediaType; - folderName: ResourceFolderName; + color?: string; } export const ResourcePicker = (props: Props) => { - const { value, src, name, placeholder, onChange, onClear, mediaType, folderName } = props; + const { value, src, name, placeholder, onChange, onClear, mediaType, folderName, size, color } = props; const styles = useStyles2(getStyles); + const theme = useTheme2(); const pickerTriggerRef = createRef(); const popoverElement = ( ); + let sanitizedSrc = src; + if (!sanitizedSrc && value) { + sanitizedSrc = getPublicOrAbsoluteUrl(value); + } + + const colorStyle = color && { + fill: theme.visualization.getColorByName(color), + }; + + const renderSmallResourcePicker = () => { + if (value && sanitizedSrc) { + return ; + } else { + return ( + + Set icon + + ); + } + }; + + const renderNormalResourcePicker = () => ( + + + } + suffix={