@@ -7,17 +7,22 @@ import {
77 AutoScalingRuleEditorModalFragment$data ,
88 AutoScalingRuleEditorModalFragment$key ,
99} from '../__generated__/AutoScalingRuleEditorModalFragment.graphql' ;
10+ import { AutoScalingRuleEditorModalPresetResultQuery } from '../__generated__/AutoScalingRuleEditorModalPresetResultQuery.graphql' ;
1011import { AutoScalingRuleEditorModalPresetsQuery } from '../__generated__/AutoScalingRuleEditorModalPresetsQuery.graphql' ;
1112import { AutoScalingRuleEditorModalUpdateMutation } from '../__generated__/AutoScalingRuleEditorModalUpdateMutation.graphql' ;
1213import { SIGNED_32BIT_MAX_INT } from '../helper/const-vars' ;
14+ import ErrorBoundaryWithNullFallback from './ErrorBoundaryWithNullFallback' ;
15+ import { ReloadOutlined } from '@ant-design/icons' ;
1316import {
1417 App ,
1518 AutoComplete ,
19+ Button ,
1620 Form ,
1721 FormInstance ,
1822 InputNumber ,
1923 Segmented ,
2024 Select ,
25+ Spin ,
2126 Typography ,
2227} from 'antd' ;
2328import {
@@ -71,6 +76,92 @@ const METRIC_NAMES_MAP: Partial<
7176 INFERENCE_FRAMEWORK : [ ] ,
7277} ;
7378
79+ /**
80+ * Inline preview component that fetches and displays the current Prometheus
81+ * metric value for a selected preset. Uses useLazyLoadQuery with fetchKey
82+ * to support manual refresh without useEffect + setState.
83+ */
84+ const PrometheusPresetPreview : React . FC < {
85+ presetGlobalId : string ;
86+ } > = ( { presetGlobalId } ) => {
87+ 'use memo' ;
88+ const { t } = useTranslation ( ) ;
89+ const [ fetchKey , setFetchKey ] = useState ( 0 ) ;
90+
91+ const presetRawId = toLocalId ( presetGlobalId ) ;
92+
93+ const data = useLazyLoadQuery < AutoScalingRuleEditorModalPresetResultQuery > (
94+ graphql `
95+ query AutoScalingRuleEditorModalPresetResultQuery(
96+ $id: ID!
97+ $options: ExecuteQueryDefinitionOptionsInput
98+ ) {
99+ prometheusQueryPresetResult(id: $id, options: $options) {
100+ status
101+ resultType
102+ result {
103+ metric {
104+ key
105+ value
106+ }
107+ values {
108+ timestamp
109+ value
110+ }
111+ }
112+ }
113+ }
114+ ` ,
115+ {
116+ id : presetRawId ,
117+ options : {
118+ filterLabels : [ ] ,
119+ groupLabels : [ ] ,
120+ } ,
121+ } ,
122+ { fetchPolicy : 'network-only' , fetchKey : `preview-${ fetchKey } ` } ,
123+ ) ;
124+
125+ const results = data . prometheusQueryPresetResult . result ;
126+
127+ let displayValue : string | null = null ;
128+ if ( results . length === 0 ) {
129+ displayValue = null ;
130+ } else if ( results . length === 1 ) {
131+ const values = results [ 0 ] . values ;
132+ displayValue = values . length > 0 ? values [ values . length - 1 ] . value : null ;
133+ } else {
134+ const firstValues = results [ 0 ] . values ;
135+ const latestValue =
136+ firstValues . length > 0 ? firstValues [ firstValues . length - 1 ] . value : null ;
137+ displayValue =
138+ latestValue != null
139+ ? t ( 'autoScalingRule.MultipleSeriesResult' , {
140+ count : results . length ,
141+ value : latestValue ,
142+ } )
143+ : null ;
144+ }
145+
146+ return (
147+ < span >
148+ < Typography . Text type = "secondary" style = { { marginRight : 4 } } >
149+ { t ( 'autoScalingRule.CurrentValue' ) } :{ ' ' }
150+ </ Typography . Text >
151+ < Typography . Text strong >
152+ { displayValue ?? t ( 'autoScalingRule.NoDataAvailable' ) }
153+ </ Typography . Text >
154+ < Button
155+ type = "link"
156+ size = "small"
157+ icon = { < ReloadOutlined /> }
158+ onClick = { ( ) => setFetchKey ( ( k ) => k + 1 ) }
159+ title = { t ( 'autoScalingRule.RefreshPreview' ) }
160+ />
161+ </ span >
162+ ) ;
163+ } ;
164+
74165/**
75166 * Determines initial condition mode and direction from existing rule data.
76167 */
@@ -512,7 +603,24 @@ const AutoScalingRuleEditorModal: React.FC<AutoScalingRuleEditorModalProps> = ({
512603 />
513604 </ Form . Item >
514605 { selectedPreset && (
515- < Form . Item label = { t ( 'autoScalingRule.QueryTemplate' ) } >
606+ < Form . Item
607+ label = { t ( 'autoScalingRule.QueryTemplate' ) }
608+ extra = {
609+ selectedPresetId ? (
610+ < ErrorBoundaryWithNullFallback >
611+ < React . Suspense
612+ fallback = {
613+ < Spin size = "small" style = { { marginRight : 8 } } />
614+ }
615+ >
616+ < PrometheusPresetPreview
617+ presetGlobalId = { selectedPresetId }
618+ />
619+ </ React . Suspense >
620+ </ ErrorBoundaryWithNullFallback >
621+ ) : undefined
622+ }
623+ >
516624 < Typography . Text
517625 code
518626 style = { {
0 commit comments