+
{typeLabel}
- {type === 'query' && onToggleVisibility && (
+ {(type === 'query' || type === 'expression') && onToggleVisibility && (
)}
- {type === 'query' && onDuplicate && (
+ {(type === 'query' || type === 'expression') && onDuplicate && (
{
: `${theme.visualization.getColorByName('orange')}15`,
borderBottom: `1px solid ${theme.colors.border.weak}`,
}),
+ headerExpression: css({
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ padding: theme.spacing(1, 1.5),
+ background: theme.isDark
+ ? `${theme.visualization.getColorByName('purple')}20`
+ : `${theme.visualization.getColorByName('purple')}15`,
+ borderBottom: `1px solid ${theme.colors.border.weak}`,
+ }),
headerLeft: css({
display: 'flex',
alignItems: 'center',
diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryTransformList.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryTransformList.tsx
index 26ea518417b..7f7fc9500f2 100644
--- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryTransformList.tsx
+++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryTransformList.tsx
@@ -2,15 +2,16 @@ import { css } from '@emotion/css';
import { memo } from 'react';
import { DataTransformerConfig, GrafanaTheme2 } from '@grafana/data';
-import { Trans } from '@grafana/i18n';
import { SceneDataQuery } from '@grafana/scenes';
-import { Button, ScrollContainer, Stack, useStyles2 } from '@grafana/ui';
+import { ScrollContainer, useStyles2 } from '@grafana/ui';
+import { ExpressionQueryType } from 'app/features/expressions/types';
+import { AddDataItemMenu } from './AddDataItemMenu';
import { QueryTransformCard } from './QueryTransformCard';
export interface QueryTransformItem {
id: string;
- type: 'query' | 'transform';
+ type: 'query' | 'transform' | 'expression';
data: SceneDataQuery | DataTransformerConfig;
index: number;
}
@@ -21,9 +22,13 @@ interface QueryTransformListProps {
onSelect: (id: string) => void;
onAddQuery: () => void;
onAddTransform: () => void;
+ onAddExpression: (type: ExpressionQueryType) => void;
onDuplicateQuery?: (index: number) => void;
onRemoveQuery?: (index: number) => void;
onToggleQueryVisibility?: (index: number) => void;
+ onDuplicateExpression?: (index: number) => void;
+ onRemoveExpression?: (index: number) => void;
+ onToggleExpressionVisibility?: (index: number) => void;
onRemoveTransform?: (index: number) => void;
}
@@ -34,14 +39,19 @@ export const QueryTransformList = memo(
onSelect,
onAddQuery,
onAddTransform,
+ onAddExpression,
onDuplicateQuery,
onRemoveQuery,
onToggleQueryVisibility,
+ onDuplicateExpression,
+ onRemoveExpression,
+ onToggleExpressionVisibility,
onRemoveTransform,
}: QueryTransformListProps) => {
const styles = useStyles2(getStyles);
const queries = items.filter((item) => item.type === 'query');
+ const expressions = items.filter((item) => item.type === 'expression');
const transforms = items.filter((item) => item.type === 'transform');
return (
@@ -69,6 +79,26 @@ export const QueryTransformList = memo(
)}
+ {expressions.length > 0 && (
+
+ {expressions.map((item) => (
+ onSelect(item.id)}
+ onDuplicate={onDuplicateExpression ? () => onDuplicateExpression(item.index) : undefined}
+ onRemove={onRemoveExpression ? () => onRemoveExpression(item.index) : undefined}
+ onToggleVisibility={
+ onToggleExpressionVisibility ? () => onToggleExpressionVisibility(item.index) : undefined
+ }
+ />
+ ))}
+
+ )}
+
{transforms.length > 0 && (
{transforms.map((item) => (
@@ -89,14 +119,7 @@ export const QueryTransformList = memo(
-
-
-
-
+
);
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index 4c943e42886..227a7c04f5c 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -5798,6 +5798,18 @@
"label-use-static-key-dimensions": "Use static key dimensions",
"name-allow-custom-values": "Allow custom values"
},
+ "add-data-item-menu": {
+ "add-button": "Add",
+ "add-query": "Query",
+ "add-transformation": "Transformation",
+ "expression-classic": "Classic condition",
+ "expression-math": "Math",
+ "expression-reduce": "Reduce",
+ "expression-resample": "Resample",
+ "expression-sql": "SQL",
+ "expression-threshold": "Threshold",
+ "expressions-group": "Expression"
+ },
"add-to-dashboard": {
"message": {
"could-navigate-selected-dashboard-please-again": "Could not navigate to the selected dashboard. Please try again.",
@@ -5988,6 +6000,9 @@
"sql-name": "Transform with SQL",
"sql-transformation-description": "Manipulate your data using MySQL-like syntax"
},
+ "expression-detail-view": {
+ "loading": "Loading expression editor..."
+ },
"general-settings-edit-view": {
"editable_options": {
"label": {
@@ -6250,10 +6265,6 @@
"remove-transform": "Remove transformation",
"show-response": "Show response"
},
- "query-transform-list": {
- "add-query": "Add query",
- "add-transformation": "Add transformation"
- },
"query-variable-editor-form": {
"description-examples": "Named capture groups can be used to separate the display text and value (<1>see examples1> ).",
"description-optional": "Optional, if you want to extract part of a series name or metric node segment.",