@@ -30,7 +30,6 @@ import {
3030import type { BAITableProps , GraphQLFilter } from 'backend.ai-ui' ;
3131import { default as dayjs } from 'dayjs' ;
3232import * as _ from 'lodash-es' ;
33- import { CircleArrowDownIcon , CircleArrowUpIcon } from 'lucide-react' ;
3433import { parseAsJson , parseAsStringLiteral , useQueryStates } from 'nuqs' ;
3534import React , { useDeferredValue , useState , useTransition } from 'react' ;
3635import { useTranslation } from 'react-i18next' ;
@@ -52,12 +51,19 @@ type AutoScalingRuleNode = NonNullable<
5251 * - maxThreshold only → `[metric_name] < [maxThreshold]`
5352 * - minThreshold only → `[minThreshold] < [metric_name]`
5453 * - Both set → `[minThreshold] < [metric_name] < [maxThreshold]`
54+ *
55+ * For PROMETHEUS rules, the tag shows the preset name (from presetMap) instead of
56+ * the raw metricName, since users select a preset — not the metric directly.
5557 */
5658const renderCondition = (
5759 rule : AutoScalingRuleNode ,
5860 t : ( key : string ) => string ,
61+ presetMap ?: Map < string , string > ,
5962) => {
60- const metricName = rule . metricName ;
63+ const tagLabel =
64+ rule . metricSource === 'PROMETHEUS' && rule . prometheusQueryPresetId
65+ ? ( presetMap ?. get ( rule . prometheusQueryPresetId ) ?? rule . metricName )
66+ : rule . metricName ;
6167 const minThreshold = rule . minThreshold ;
6268 const maxThreshold = rule . maxThreshold ;
6369 const suffix = rule . metricSource === 'KERNEL' ? '%' : '' ;
@@ -68,7 +74,7 @@ const renderCondition = (
6874 { minThreshold }
6975 { suffix }
7076 < Tooltip title = { t ( 'autoScalingRule.MinThreshold' ) } > { '<' } </ Tooltip >
71- < Tag > { metricName } </ Tag >
77+ < Tag > { tagLabel } </ Tag >
7278 < Tooltip title = { t ( 'autoScalingRule.MaxThreshold' ) } > { '<' } </ Tooltip >
7379 { maxThreshold }
7480 { suffix }
@@ -79,7 +85,7 @@ const renderCondition = (
7985 if ( maxThreshold != null ) {
8086 return (
8187 < BAIFlex gap = { 'xs' } >
82- < Tag > { metricName } </ Tag >
88+ < Tag > { tagLabel } </ Tag >
8389 < Tooltip title = { t ( 'autoScalingRule.MaxThreshold' ) } > { '<' } </ Tooltip >
8490 { maxThreshold }
8591 { suffix }
@@ -93,7 +99,7 @@ const renderCondition = (
9399 { minThreshold }
94100 { suffix }
95101 < Tooltip title = { t ( 'autoScalingRule.MinThreshold' ) } > { '<' } </ Tooltip >
96- < Tag > { metricName } </ Tag >
102+ < Tag > { tagLabel } </ Tag >
97103 </ BAIFlex >
98104 ) ;
99105 }
@@ -195,7 +201,7 @@ const AutoScalingRuleListNodes: React.FC<AutoScalingRuleListNodesProps> = ({
195201 if ( ! row ) return '-' ;
196202 return (
197203 < BAINameActionCell
198- title = { renderCondition ( row , t ) }
204+ title = { renderCondition ( row , t , presetMap ) }
199205 showActions = "always"
200206 actions = { [
201207 {
@@ -218,22 +224,6 @@ const AutoScalingRuleListNodes: React.FC<AutoScalingRuleListNodesProps> = ({
218224 ) ;
219225 } ,
220226 } ,
221- {
222- key : 'prometheusPreset' ,
223- title : t ( 'autoScalingRule.PrometheusPreset' ) ,
224- render : ( _text , row ) => {
225- if (
226- row ?. metricSource !== 'PROMETHEUS' ||
227- ! row ?. prometheusQueryPresetId
228- ) {
229- return '-' ;
230- }
231- return (
232- presetMap . get ( row . prometheusQueryPresetId ) ||
233- row . prometheusQueryPresetId
234- ) ;
235- } ,
236- } ,
237227 {
238228 key : 'timeWindow' ,
239229 title : t ( 'autoScalingRule.TimeWindow' ) ,
@@ -248,40 +238,55 @@ const AutoScalingRuleListNodes: React.FC<AutoScalingRuleListNodesProps> = ({
248238 title : t ( 'autoScalingRule.StepSize' ) ,
249239 dataIndex : 'stepSize' ,
250240 render : ( _text , row ) => {
251- if ( row ?. stepSize ) {
252- return (
253- < BAIFlex gap = { 'xs' } >
254- < Typography . Text >
255- { row . stepSize > 0 ? (
256- < CircleArrowUpIcon />
257- ) : (
258- < CircleArrowDownIcon />
259- ) }
260- </ Typography . Text >
261- < Typography . Text > { Math . abs ( row . stepSize ) } </ Typography . Text >
262- </ BAIFlex >
263- ) ;
264- } else {
265- return '-' ;
266- }
241+ if ( ! row ?. stepSize ) return '-' ;
242+ const hasMin = row . minThreshold != null ;
243+ const hasMax = row . maxThreshold != null ;
244+ const sign = hasMin && hasMax ? '±' : hasMax ? '+' : '−' ;
245+ return (
246+ < BAIFlex gap = { 'xs' } >
247+ < Typography . Text > { sign } </ Typography . Text >
248+ < Typography . Text > { Math . abs ( row . stepSize ) } </ Typography . Text >
249+ </ BAIFlex >
250+ ) ;
267251 } ,
268252 } ,
269253 {
270254 key : 'minMaxReplicas' ,
271255 title : t ( 'autoScalingRule.MIN/MAXReplicas' ) ,
272- render : ( _text , row ) => (
273- < span >
274- { row ?. stepSize
275- ? row . stepSize > 0
276- ? t ( 'autoScalingRule.MaxReplicasValue' , {
277- value : row ?. maxReplicas ,
278- } )
279- : t ( 'autoScalingRule.MinReplicasValue' , {
280- value : row ?. minReplicas ,
281- } )
282- : '-' }
283- </ span >
284- ) ,
256+ render : ( _text , row ) => {
257+ if ( ! row ?. stepSize ) return '-' ;
258+ const hasMin = row . minThreshold != null ;
259+ const hasMax = row . maxThreshold != null ;
260+ if ( hasMin && hasMax ) {
261+ return (
262+ < span >
263+ { t ( 'autoScalingRule.MinReplicasValue' , {
264+ value : row ?. minReplicas ,
265+ } ) }
266+ { ' / ' }
267+ { t ( 'autoScalingRule.MaxReplicasValue' , {
268+ value : row ?. maxReplicas ,
269+ } ) }
270+ </ span >
271+ ) ;
272+ }
273+ if ( hasMax ) {
274+ return (
275+ < span >
276+ { t ( 'autoScalingRule.MaxReplicasValue' , {
277+ value : row ?. maxReplicas ,
278+ } ) }
279+ </ span >
280+ ) ;
281+ }
282+ return (
283+ < span >
284+ { t ( 'autoScalingRule.MinReplicasValue' , {
285+ value : row ?. minReplicas ,
286+ } ) }
287+ </ span >
288+ ) ;
289+ } ,
285290 } ,
286291 {
287292 key : 'createdAt' ,
0 commit comments