11import { css } from '@emotion/css' ;
22import { useCallback , useEffect , useRef } from 'react' ;
33
4- import { DataSourceApi , GrafanaTheme2 , QueryEditorProps } from '@grafana/data' ;
4+ import { DataSourceApi , FeatureState , GrafanaTheme2 , QueryEditorProps } from '@grafana/data' ;
55import { t , Trans } from '@grafana/i18n' ;
66import { reportInteraction } from '@grafana/runtime' ;
7- import { Button , IconButton , InlineField , PopoverContent , useStyles2 } from '@grafana/ui' ;
7+ import { Button , FeatureBadge , IconButton , InlineField , PopoverContent , useStyles2 } from '@grafana/ui' ;
88
99import { ClassicConditions } from './components/ClassicConditions' ;
1010import { ExpressionTypeDropdown } from './components/ExpressionTypeDropdown' ;
@@ -23,21 +23,33 @@ const labelWidth = 15;
2323type NonClassicExpressionType = Exclude < ExpressionQueryType , ExpressionQueryType . classic > ;
2424type ExpressionTypeConfigStorage = Partial < Record < NonClassicExpressionType , string > > ;
2525
26- // Help text for each expression type - can be expanded with more detailed content
27- const getExpressionHelpText = ( type : ExpressionQueryType ) : PopoverContent | string => {
26+ /**
27+ * Get the configuration for an expression type (helper text and feature state).
28+ * @param type - The expression type.
29+ * @returns The configuration for the expression type.
30+ */
31+ const getExpressionTypeConfig = (
32+ type : ExpressionQueryType
33+ ) : { helperText : PopoverContent ; featureState : FeatureState | undefined } => {
2834 const description = expressionTypes . find ( ( { value } ) => value === type ) ?. description ;
2935
3036 switch ( type ) {
3137 case ExpressionQueryType . sql :
32- return (
33- < Trans i18nKey = "expressions.expression-query-editor.helper-text-sql" >
34- Run MySQL-dialect SQL against the tables returned from your data sources. Data source queries (ie
35- "A", "B") are available as tables and referenced by query-name. Fields are available as
36- columns, as returned from the data source.
37- </ Trans >
38- ) ;
38+ return {
39+ helperText : (
40+ < Trans i18nKey = "expressions.expression-query-editor.helper-text-sql" >
41+ Run MySQL-dialect SQL against the tables returned from your data sources. Data source queries (ie
42+ "A", "B") are available as tables and referenced by query-name. Fields are available as
43+ columns, as returned from the data source.
44+ </ Trans >
45+ ) ,
46+ featureState : FeatureState . preview ,
47+ } ;
3948 default :
40- return description ?? '' ;
49+ return {
50+ helperText : description ?? '' ,
51+ featureState : undefined ,
52+ } ;
4153 }
4254} ;
4355
@@ -148,7 +160,7 @@ export function ExpressionQueryEditor(props: ExpressionQueryEditorProps) {
148160 }
149161 } ;
150162
151- const helperText = getExpressionHelpText ( query . type ) ;
163+ const { helperText, featureState } = getExpressionTypeConfig ( query . type ) ;
152164
153165 return (
154166 < div >
@@ -163,7 +175,10 @@ export function ExpressionQueryEditor(props: ExpressionQueryEditorProps) {
163175 </ Button >
164176 </ ExpressionTypeDropdown >
165177 </ InlineField >
166- { helperText && < IconButton className = { styles . infoIcon } name = "info-circle" tooltip = { helperText } /> }
178+ < div className = { styles . fieldContainer } >
179+ { featureState && < FeatureBadge featureState = { featureState } /> }
180+ { helperText && < IconButton name = "info-circle" tooltip = { helperText } /> }
181+ </ div >
167182 </ div >
168183 { renderExpressionType ( ) }
169184 </ div >
@@ -176,7 +191,10 @@ const getStyles = (theme: GrafanaTheme2) => ({
176191 alignItems : 'center' ,
177192 gap : theme . spacing ( 1 ) ,
178193 } ) ,
179- infoIcon : css ( {
194+ fieldContainer : css ( {
195+ display : 'flex' ,
196+ alignItems : 'center' ,
197+ gap : theme . spacing ( 1 ) ,
180198 marginBottom : theme . spacing ( 0.5 ) , // Align with the select field
181199 } ) ,
182200} ) ;
0 commit comments