From cdd89d2945ffacb3eedd8dda33c25930359306c2 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Fri, 19 Nov 2021 01:19:21 -0500 Subject: [PATCH] Transformers: extract fields from JSON and text (alpha) (#41791) (#41936) Co-authored-by: Leon Sorokin (cherry picked from commit a6e60c62f458e7b5af3328c8863a5c29fe6d47d5) Co-authored-by: Ryan McKinley --- .../src/dataframe/processDataFrame.ts | 2 +- .../src/transformations/transformers/ids.ts | 1 + .../ExtractFieldsTransformerEditor.tsx | 94 +++++++++++++++++++ .../extractFields/extractFields.test.ts | 75 +++++++++++++++ .../extractFields/extractFields.ts | 92 ++++++++++++++++++ .../extractFields/fieldExtractor.test.ts | 53 +++++++++++ .../extractFields/fieldExtractors.ts | 70 ++++++++++++++ public/app/core/utils/standardTransformers.ts | 2 + 8 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 public/app/core/components/TransformersUI/extractFields/ExtractFieldsTransformerEditor.tsx create mode 100644 public/app/core/components/TransformersUI/extractFields/extractFields.test.ts create mode 100644 public/app/core/components/TransformersUI/extractFields/extractFields.ts create mode 100644 public/app/core/components/TransformersUI/extractFields/fieldExtractor.test.ts create mode 100644 public/app/core/components/TransformersUI/extractFields/fieldExtractors.ts diff --git a/packages/grafana-data/src/dataframe/processDataFrame.ts b/packages/grafana-data/src/dataframe/processDataFrame.ts index f0fee32b9fe..d1e10576b54 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.ts @@ -32,7 +32,7 @@ function convertTableToDataFrame(table: TableData): DataFrame { // TODO: should be Column but type does not exists there so not sure whats up here. const { text, type, ...disp } = c as any; return { - name: text, // rename 'text' to the 'name' field + name: text?.length ? text : c, // rename 'text' to the 'name' field config: (disp || {}) as FieldConfig, values: new ArrayVector(), type: type && Object.values(FieldType).includes(type as FieldType) ? (type as FieldType) : FieldType.other, diff --git a/packages/grafana-data/src/transformations/transformers/ids.ts b/packages/grafana-data/src/transformations/transformers/ids.ts index b2aafaa5cfe..6652199abb6 100644 --- a/packages/grafana-data/src/transformations/transformers/ids.ts +++ b/packages/grafana-data/src/transformations/transformers/ids.ts @@ -28,4 +28,5 @@ export enum DataTransformerID { prepareTimeSeries = 'prepareTimeSeries', convertFieldType = 'convertFieldType', fieldLookup = 'fieldLookup', + extractFields = 'extractFields', } diff --git a/public/app/core/components/TransformersUI/extractFields/ExtractFieldsTransformerEditor.tsx b/public/app/core/components/TransformersUI/extractFields/ExtractFieldsTransformerEditor.tsx new file mode 100644 index 00000000000..d7a868b7c2a --- /dev/null +++ b/public/app/core/components/TransformersUI/extractFields/ExtractFieldsTransformerEditor.tsx @@ -0,0 +1,94 @@ +import React from 'react'; +import { + DataTransformerID, + FieldNamePickerConfigSettings, + PluginState, + SelectableValue, + StandardEditorsRegistryItem, + TransformerRegistryItem, + TransformerUIProps, +} from '@grafana/data'; + +import { InlineField, InlineFieldRow, InlineSwitch, Select } from '@grafana/ui'; +import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker'; +import { ExtractFieldsOptions, extractFieldsTransformer } from './extractFields'; +import { FieldExtractorID, fieldExtractors } from './fieldExtractors'; + +const fieldNamePickerSettings: StandardEditorsRegistryItem = { + settings: { + width: 30, + placeholderText: 'Select field', + }, + name: '', + id: '', + editor: () => null, +}; + +export const extractFieldsTransformerEditor: React.FC> = ({ + input, + options, + onChange, +}) => { + const onPickSourceField = (source?: string) => { + onChange({ + ...options, + source, + }); + }; + + const onFormatChange = (format?: SelectableValue) => { + onChange({ + ...options, + format: format?.value, + }); + }; + + const onToggleReplace = () => { + onChange({ + ...options, + replace: !options.replace, + }); + }; + + const format = fieldExtractors.selectOptions(options.format ? [options.format] : undefined); + + return ( +
+ + + + + + + +