diff --git a/.betterer.results b/.betterer.results index cb5461faa35..4f8d38ab988 100644 --- a/.betterer.results +++ b/.betterer.results @@ -2799,9 +2799,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "9"], [0, 0, 0, "Styles should be written using objects.", "10"] ], - "public/app/features/dashboard/components/TransformationsEditor/TransformationFilter.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], "public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] diff --git a/docs/sources/developers/kinds/core/dashboard/schema-reference.md b/docs/sources/developers/kinds/core/dashboard/schema-reference.md index e8fb56b1c18..60738bb0907 100644 --- a/docs/sources/developers/kinds/core/dashboard/schema-reference.md +++ b/docs/sources/developers/kinds/core/dashboard/schema-reference.md @@ -219,6 +219,7 @@ use the output of one transformation as the input to another transformation, etc | `options` | | **Yes** | | Options to be passed to the transformer
Valid options depend on the transformer id | | `disabled` | boolean | No | | Disabled transformations are skipped | | `filter` | [MatcherConfig](#matcherconfig) | No | | Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.
It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type. | +| `topic` | string | No | | Where to pull DataFrames from as input to transformation
Possible values are: `series`, `annotations`, `alertStates`. | ### MatcherConfig diff --git a/kinds/dashboard/dashboard_kind.cue b/kinds/dashboard/dashboard_kind.cue index 85e3a45040b..4a30d6866b8 100644 --- a/kinds/dashboard/dashboard_kind.cue +++ b/kinds/dashboard/dashboard_kind.cue @@ -438,6 +438,8 @@ lineage: schemas: [{ disabled?: bool // Optional frame matcher. When missing it will be applied to all results filter?: #MatcherConfig + // Where to pull DataFrames from as input to transformation + topic?: "series" | "annotations" | "alertStates" // replaced with common.DataTopic // Options to be passed to the transformer // Valid options depend on the transformer id options: _ diff --git a/packages/grafana-data/src/types/query.ts b/packages/grafana-data/src/types/query.ts index 30579b1e7dc..870a0b95094 100644 --- a/packages/grafana-data/src/types/query.ts +++ b/packages/grafana-data/src/types/query.ts @@ -1,4 +1,8 @@ -import { DataQuery as SchemaDataQuery, DataSourceRef as SchemaDataSourceRef } from '@grafana/schema'; +import { + DataQuery as SchemaDataQuery, + DataSourceRef as SchemaDataSourceRef, + DataTopic as SchemaDataTopic, +} from '@grafana/schema'; /** * @deprecated use the type from @grafana/schema @@ -13,12 +17,9 @@ export interface DataSourceRef extends SchemaDataSourceRef {} /** * Attached to query results (not persisted) * - * @public + * @deprecated use the type from @grafana/schema */ -export enum DataTopic { - Annotations = 'annotations', - AlertStates = 'alertStates', -} +export { SchemaDataTopic as DataTopic }; /** * Abstract representation of any label-based query diff --git a/packages/grafana-schema/src/common/common.gen.ts b/packages/grafana-schema/src/common/common.gen.ts index b05a4bdf359..79219a0d6ba 100644 --- a/packages/grafana-schema/src/common/common.gen.ts +++ b/packages/grafana-schema/src/common/common.gen.ts @@ -8,6 +8,16 @@ // Run 'make gen-cue' from repository root to regenerate. +/** + * A topic is attached to DataFrame metadata in query results. + * This specifies where the data should be used. + */ +export enum DataTopic { + AlertStates = 'alertStates', + Annotations = 'annotations', + Series = 'series', +} + /** * TODO docs */ diff --git a/packages/grafana-schema/src/common/data.cue b/packages/grafana-schema/src/common/data.cue new file mode 100644 index 00000000000..33cb5ab2f4e --- /dev/null +++ b/packages/grafana-schema/src/common/data.cue @@ -0,0 +1,5 @@ +package common + +// A topic is attached to DataFrame metadata in query results. +// This specifies where the data should be used. +DataTopic: "series" | "annotations" | "alertStates" @cuetsy(kind="enum",memberNames="Series|Annotations|AlertStates") \ No newline at end of file diff --git a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts index 8f4854b5bcb..44c982655e7 100644 --- a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts +++ b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts @@ -623,6 +623,10 @@ export interface DataTransformerConfig { * Valid options depend on the transformer id */ options: unknown; + /** + * Where to pull DataFrames from as input to transformation + */ + topic?: ('series' | 'annotations' | 'alertStates'); // replaced with common.DataTopic } /** diff --git a/packages/grafana-schema/src/veneer/dashboard.types.ts b/packages/grafana-schema/src/veneer/dashboard.types.ts index 5e1db960f4d..9976f4dec90 100644 --- a/packages/grafana-schema/src/veneer/dashboard.types.ts +++ b/packages/grafana-schema/src/veneer/dashboard.types.ts @@ -1,4 +1,4 @@ -import { DataSourceRef as CommonDataSourceRef, DataSourceRef } from '../common/common.gen'; +import { DataSourceRef as CommonDataSourceRef, DataSourceRef, DataTopic } from '../common/common.gen'; import * as raw from '../raw/dashboard/x/dashboard_types.gen'; import { DataQuery } from './common.types'; @@ -59,6 +59,7 @@ export interface MatcherConfig extends raw.MatcherConfig { export interface DataTransformerConfig extends raw.DataTransformerConfig { options: TOptions; + topic?: DataTopic; } export interface TimePickerConfig extends raw.TimePickerConfig {} diff --git a/pkg/kinds/dashboard/dashboard_spec_gen.go b/pkg/kinds/dashboard/dashboard_spec_gen.go index 08c57edfd93..498784a321b 100644 --- a/pkg/kinds/dashboard/dashboard_spec_gen.go +++ b/pkg/kinds/dashboard/dashboard_spec_gen.go @@ -26,6 +26,13 @@ const ( LinkTypeLink LinkType = "link" ) +// Defines values for DataTransformerConfigTopic. +const ( + DataTransformerConfigTopicAlertStates DataTransformerConfigTopic = "alertStates" + DataTransformerConfigTopicAnnotations DataTransformerConfigTopic = "annotations" + DataTransformerConfigTopicSeries DataTransformerConfigTopic = "series" +) + // Defines values for FieldColorModeId. const ( FieldColorModeIdContinuousBlPu FieldColorModeId = "continuous-BlPu" @@ -294,8 +301,14 @@ type DataTransformerConfig struct { // Options to be passed to the transformer // Valid options depend on the transformer id Options any `json:"options"` + + // Where to pull DataFrames from as input to transformation + Topic *DataTransformerConfigTopic `json:"topic,omitempty"` } +// Where to pull DataFrames from as input to transformation +type DataTransformerConfigTopic string + // DynamicConfigValue defines model for DynamicConfigValue. type DynamicConfigValue struct { Id string `json:"id"` diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationFilter.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationFilter.tsx index af96c50c98e..dce12d11781 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationFilter.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationFilter.tsx @@ -2,39 +2,69 @@ import { css } from '@emotion/css'; import React, { useMemo } from 'react'; import { - DataFrame, DataTransformerConfig, GrafanaTheme2, StandardEditorContext, StandardEditorsRegistryItem, } from '@grafana/data'; -import { Field, useStyles2 } from '@grafana/ui'; +import { DataTopic } from '@grafana/schema'; +import { Field, Select, useStyles2 } from '@grafana/ui'; import { FrameSelectionEditor } from 'app/plugins/panel/geomap/editor/FrameSelectionEditor'; +import { TransformationData } from './TransformationsEditor'; + interface TransformationFilterProps { index: number; config: DataTransformerConfig; - data: DataFrame[]; + data: TransformationData; onChange: (index: number, config: DataTransformerConfig) => void; } export const TransformationFilter = ({ index, data, config, onChange }: TransformationFilterProps) => { const styles = useStyles2(getStyles); - const context = useMemo(() => { - // eslint-disable-next-line - return { data } as StandardEditorContext; - }, [data]); + + const opts = useMemo(() => { + return { + // eslint-disable-next-line + context: { data: data.series } as StandardEditorContext, + showTopic: true || data.annotations?.length || config.topic?.length, + showFilter: config.topic !== DataTopic.Annotations, + source: [ + { value: DataTopic.Series, label: `Query results` }, + { value: DataTopic.Annotations, label: `Annotation data` }, + ], + }; + }, [data, config.topic]); return (
- onChange(index, { ...config, filter })} - /> + <> + {opts.showTopic && ( +