Plugins: Adds back getMappedValue to @grafana/data (#34746)

* Plugins: Adds back getMappedValue to @grafana/data

* Chore: fixes doc errors

* Tests: fixes snapshot

* Tests: dummy change to restart Drone

* Tests: tries to fix snapshot
This commit is contained in:
Hugo Häggmark 2021-05-27 09:29:22 +02:00 committed by GitHub
parent 49126bebaa
commit 3a68409e5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 225 additions and 3120 deletions

View File

@ -1,4 +1,5 @@
import * as arrayUtils from './arrayUtils';
export * from './Registry';
export * from './datasource';
export * from './deprecationWarning';
@ -21,3 +22,12 @@ export { DocsId } from './docs';
export { makeClassES5Compatible } from './makeClassES5Compatible';
export { anyToNumber } from './anyToNumber';
export { withLoadingIndicator, WithLoadingIndicatorOptions } from './withLoadingIndicator';
export {
getMappedValue,
convertOldAngularValueMappings,
LegacyValueMapping,
LegacyValueMap,
LegacyRangeMap,
LegacyBaseMap,
LegacyMappingType,
} from './valueMappings';

View File

@ -1,4 +1,5 @@
import { ValueMapping, MappingType, ValueMappingResult, SpecialValueMatch } from '../types';
import { MappingType, SpecialValueMatch, ThresholdsConfig, ValueMap, ValueMapping, ValueMappingResult } from '../types';
import { getActiveThreshold } from '../field';
export function getValueMappingResult(valueMappings: ValueMapping[], value: any): ValueMappingResult | null {
for (const vm of valueMappings) {
@ -86,3 +87,205 @@ export function getValueMappingResult(valueMappings: ValueMapping[], value: any)
export function isNumeric(num: any) {
return (typeof num === 'number' || (typeof num === 'string' && num.trim() !== '')) && !isNaN(num as number);
}
/**
* @deprecated use MappingType instead
* @internal
*/
export enum LegacyMappingType {
ValueToText = 1,
RangeToText = 2,
}
/**
* @deprecated use MappingType instead
* @internal
*/
export interface LegacyBaseMap {
id: number; // this could/should just be the array index
text: string; // the final display value
type: LegacyMappingType;
}
/**
* @deprecated use ValueMapping instead
* @internal
*/
export type LegacyValueMapping = LegacyValueMap | LegacyRangeMap;
/**
* @deprecated use ValueMap instead
* @internal
*/
export interface LegacyValueMap extends LegacyBaseMap {
value: string;
}
/**
* @deprecated use RangeMap instead
* @internal
*/
export interface LegacyRangeMap extends LegacyBaseMap {
from: string;
to: string;
}
/**
* @deprecated use getValueMappingResult instead
* @internal
*/
export function getMappedValue(valueMappings: LegacyValueMapping[], value: any): LegacyValueMapping {
const emptyResult = { type: LegacyMappingType.ValueToText, value: '', text: '', from: '', to: '', id: 0 };
if (!valueMappings?.length) {
return emptyResult;
}
const upgraded: ValueMapping[] = [];
for (const vm of valueMappings) {
if (isValueMapping(vm)) {
upgraded.push(vm);
continue;
}
upgraded.push(upgradeOldAngularValueMapping(vm));
}
if (!upgraded?.length) {
return emptyResult;
}
const result = getValueMappingResult(upgraded, value);
if (!result) {
return emptyResult;
}
return {
type: LegacyMappingType.ValueToText,
value: result.text,
text: result.text ?? '',
from: '',
to: '',
id: result.index ?? 0,
};
}
/**
* @alpha
* Converts the old Angular value mappings to new react style
*/
export function convertOldAngularValueMappings(panel: any): ValueMapping[] {
const mappings: ValueMapping[] = [];
// Guess the right type based on options
let mappingType = panel.mappingType;
if (!panel.mappingType) {
if (panel.valueMaps && panel.valueMaps.length) {
mappingType = 1;
} else if (panel.rangeMaps && panel.rangeMaps.length) {
mappingType = 2;
}
}
if (mappingType === 1) {
for (let i = 0; i < panel.valueMaps.length; i++) {
const map = panel.valueMaps[i];
mappings.push(
upgradeOldAngularValueMapping(
{
...map,
id: i, // used for order
type: MappingType.ValueToText,
},
panel.fieldConfig?.defaults?.thresholds
)
);
}
} else if (mappingType === 2) {
for (let i = 0; i < panel.rangeMaps.length; i++) {
const map = panel.rangeMaps[i];
mappings.push(
upgradeOldAngularValueMapping(
{
...map,
id: i, // used for order
type: MappingType.RangeToText,
},
panel.fieldConfig?.defaults?.thresholds
)
);
}
}
return mappings;
}
function upgradeOldAngularValueMapping(old: any, thresholds?: ThresholdsConfig): ValueMapping {
const valueMaps: ValueMap = { type: MappingType.ValueToText, options: {} };
const newMappings: ValueMapping[] = [];
// Use the color we would have picked from thesholds
let color: string | undefined = undefined;
const numeric = parseFloat(old.text);
if (thresholds && !isNaN(numeric)) {
const level = getActiveThreshold(numeric, thresholds.steps);
if (level && level.color) {
color = level.color;
}
}
switch (old.type) {
case LegacyMappingType.ValueToText:
case MappingType.ValueToText:
if (old.value != null) {
if (old.value === 'null') {
newMappings.push({
type: MappingType.SpecialValue,
options: {
match: SpecialValueMatch.Null,
result: { text: old.text, color },
},
});
} else {
valueMaps.options[String(old.value)] = {
text: old.text,
color,
};
}
}
break;
case LegacyMappingType.RangeToText:
case MappingType.RangeToText:
if (old.from === 'null' || old.to === 'null') {
newMappings.push({
type: MappingType.SpecialValue,
options: {
match: SpecialValueMatch.Null,
result: { text: old.text, color },
},
});
} else {
newMappings.push({
type: MappingType.RangeToText,
options: {
from: +old.from,
to: +old.to,
result: { text: old.text, color },
},
});
}
break;
}
if (Object.keys(valueMaps.options).length > 0) {
newMappings.unshift(valueMaps);
}
return newMappings[0];
}
function isValueMapping(map: any): map is ValueMapping {
if (!map) {
return false;
}
return map.hasOwnProperty('options') && typeof map.options === 'object';
}

View File

@ -1,20 +1,20 @@
import { cloneDeep, isNumber, omit } from 'lodash';
import {
fieldReducers,
Threshold,
sortThresholds,
convertOldAngularValueMappings,
FieldColorModeId,
FieldConfig,
ReducerID,
ValueMapping,
MappingType,
VizOrientation,
fieldReducers,
PanelModel,
ReduceDataOptions,
ThresholdsMode,
ReducerID,
sortThresholds,
Threshold,
ThresholdsConfig,
ThresholdsMode,
validateFieldConfig,
FieldColorModeId,
ValueMapping,
VizOrientation,
} from '@grafana/data';
import { OptionsWithTextFormatting } from '../../options';
@ -325,41 +325,9 @@ export function migrateOldThresholds(thresholds?: any[]): Threshold[] | undefine
}
/**
* @deprecated use convertOldAngularValueMappings instead
* Convert the angular single stat mapping to new react style
*/
export function convertOldAngularValueMapping(panel: any): ValueMapping[] {
const mappings: ValueMapping[] = [];
// Guess the right type based on options
let mappingType = panel.mappingType;
if (!panel.mappingType) {
if (panel.valueMaps && panel.valueMaps.length) {
mappingType = 1;
} else if (panel.rangeMaps && panel.rangeMaps.length) {
mappingType = 2;
}
}
// check value to text mappings if its enabled
if (mappingType === 1) {
for (let i = 0; i < panel.valueMaps.length; i++) {
const map = panel.valueMaps[i];
mappings.push({
...map,
id: i, // used for order
type: MappingType.ValueToText,
});
}
} else if (mappingType === 2) {
for (let i = 0; i < panel.rangeMaps.length; i++) {
const map = panel.rangeMaps[i];
mappings.push({
...map,
id: i, // used for order
type: MappingType.RangeToText,
});
}
}
return mappings;
return convertOldAngularValueMappings(panel);
}

View File

@ -256,7 +256,6 @@ describe('Wrapper', () => {
it('changes the document title of the explore page', async () => {
setup({ datasources: [] });
await waitFor(() => expect(document.querySelector('head')).toMatchSnapshot());
await waitFor(() => expect(document.title).toEqual('Explore - Grafana'));
});
});

File diff suppressed because it is too large Load Diff