@@ -31,7 +31,6 @@ import {
3131import type { BAITableProps , GraphQLFilter } from 'backend.ai-ui' ;
3232import { default as dayjs } from 'dayjs' ;
3333import * as _ from 'lodash-es' ;
34- import { CircleArrowDownIcon , CircleArrowUpIcon } from 'lucide-react' ;
3534import { parseAsJson , parseAsStringLiteral , useQueryStates } from 'nuqs' ;
3635import React , { useDeferredValue , useState , useTransition } from 'react' ;
3736import { useTranslation } from 'react-i18next' ;
@@ -48,12 +47,19 @@ type AutoScalingRuleNode = NonNullable<
4847 * - maxThreshold only → `[metric_name] < [maxThreshold]`
4948 * - minThreshold only → `[minThreshold] < [metric_name]`
5049 * - Both set → `[minThreshold] < [metric_name] < [maxThreshold]`
50+ *
51+ * For PROMETHEUS rules, the tag shows the preset name (from presetMap) instead of
52+ * the raw metricName, since users select a preset — not the metric directly.
5153 */
5254const renderCondition = (
5355 rule : AutoScalingRuleNode ,
5456 t : ( key : string ) => string ,
57+ presetMap ?: Map < string , string > ,
5558) => {
56- const metricName = rule . metricName ;
59+ const tagLabel =
60+ rule . metricSource === 'PROMETHEUS' && rule . prometheusQueryPresetId
61+ ? ( presetMap ?. get ( rule . prometheusQueryPresetId ) ?? rule . metricName )
62+ : rule . metricName ;
5763 const minThreshold = rule . minThreshold ;
5864 const maxThreshold = rule . maxThreshold ;
5965 const suffix = rule . metricSource === 'KERNEL' ? '%' : '' ;
@@ -64,7 +70,7 @@ const renderCondition = (
6470 { minThreshold }
6571 { suffix }
6672 < Tooltip title = { t ( 'autoScalingRule.MinThreshold' ) } > { '<' } </ Tooltip >
67- < Tag > { metricName } </ Tag >
73+ < Tag > { tagLabel } </ Tag >
6874 < Tooltip title = { t ( 'autoScalingRule.MaxThreshold' ) } > { '<' } </ Tooltip >
6975 { maxThreshold }
7076 { suffix }
@@ -75,7 +81,7 @@ const renderCondition = (
7581 if ( maxThreshold != null ) {
7682 return (
7783 < BAIFlex gap = { 'xs' } >
78- < Tag > { metricName } </ Tag >
84+ < Tag > { tagLabel } </ Tag >
7985 < Tooltip title = { t ( 'autoScalingRule.MaxThreshold' ) } > { '<' } </ Tooltip >
8086 { maxThreshold }
8187 { suffix }
@@ -89,7 +95,7 @@ const renderCondition = (
8995 { minThreshold }
9096 { suffix }
9197 < Tooltip title = { t ( 'autoScalingRule.MinThreshold' ) } > { '<' } </ Tooltip >
92- < Tag > { metricName } </ Tag >
98+ < Tag > { tagLabel } </ Tag >
9399 </ BAIFlex >
94100 ) ;
95101 }
@@ -191,7 +197,7 @@ const AutoScalingRuleListNodes: React.FC<AutoScalingRuleListNodesProps> = ({
191197 if ( ! row ) return '-' ;
192198 return (
193199 < BAINameActionCell
194- title = { renderCondition ( row , t ) }
200+ title = { renderCondition ( row , t , presetMap ) }
195201 showActions = "always"
196202 actions = { [
197203 {
@@ -214,22 +220,6 @@ const AutoScalingRuleListNodes: React.FC<AutoScalingRuleListNodesProps> = ({
214220 ) ;
215221 } ,
216222 } ,
217- {
218- key : 'prometheusPreset' ,
219- title : t ( 'autoScalingRule.PrometheusPreset' ) ,
220- render : ( _text , row ) => {
221- if (
222- row ?. metricSource !== 'PROMETHEUS' ||
223- ! row ?. prometheusQueryPresetId
224- ) {
225- return '-' ;
226- }
227- return (
228- presetMap . get ( row . prometheusQueryPresetId ) ||
229- row . prometheusQueryPresetId
230- ) ;
231- } ,
232- } ,
233223 {
234224 key : 'timeWindow' ,
235225 title : t ( 'autoScalingRule.TimeWindow' ) ,
@@ -244,40 +234,55 @@ const AutoScalingRuleListNodes: React.FC<AutoScalingRuleListNodesProps> = ({
244234 title : t ( 'autoScalingRule.StepSize' ) ,
245235 dataIndex : 'stepSize' ,
246236 render : ( _text , row ) => {
247- if ( row ?. stepSize ) {
248- return (
249- < BAIFlex gap = { 'xs' } >
250- < Typography . Text >
251- { row . stepSize > 0 ? (
252- < CircleArrowUpIcon />
253- ) : (
254- < CircleArrowDownIcon />
255- ) }
256- </ Typography . Text >
257- < Typography . Text > { Math . abs ( row . stepSize ) } </ Typography . Text >
258- </ BAIFlex >
259- ) ;
260- } else {
261- return '-' ;
262- }
237+ if ( ! row ?. stepSize ) return '-' ;
238+ const hasMin = row . minThreshold != null ;
239+ const hasMax = row . maxThreshold != null ;
240+ const sign = hasMin && hasMax ? '±' : hasMax ? '+' : '−' ;
241+ return (
242+ < BAIFlex gap = { 'xs' } >
243+ < Typography . Text > { sign } </ Typography . Text >
244+ < Typography . Text > { Math . abs ( row . stepSize ) } </ Typography . Text >
245+ </ BAIFlex >
246+ ) ;
263247 } ,
264248 } ,
265249 {
266250 key : 'minMaxReplicas' ,
267251 title : t ( 'autoScalingRule.MIN/MAXReplicas' ) ,
268- render : ( _text , row ) => (
269- < span >
270- { row ?. stepSize
271- ? row . stepSize > 0
272- ? t ( 'autoScalingRule.MaxReplicasValue' , {
273- value : row ?. maxReplicas ,
274- } )
275- : t ( 'autoScalingRule.MinReplicasValue' , {
276- value : row ?. minReplicas ,
277- } )
278- : '-' }
279- </ span >
280- ) ,
252+ render : ( _text , row ) => {
253+ if ( ! row ?. stepSize ) return '-' ;
254+ const hasMin = row . minThreshold != null ;
255+ const hasMax = row . maxThreshold != null ;
256+ if ( hasMin && hasMax ) {
257+ return (
258+ < span >
259+ { t ( 'autoScalingRule.MinReplicasValue' , {
260+ value : row ?. minReplicas ,
261+ } ) }
262+ { ' / ' }
263+ { t ( 'autoScalingRule.MaxReplicasValue' , {
264+ value : row ?. maxReplicas ,
265+ } ) }
266+ </ span >
267+ ) ;
268+ }
269+ if ( hasMax ) {
270+ return (
271+ < span >
272+ { t ( 'autoScalingRule.MaxReplicasValue' , {
273+ value : row ?. maxReplicas ,
274+ } ) }
275+ </ span >
276+ ) ;
277+ }
278+ return (
279+ < span >
280+ { t ( 'autoScalingRule.MinReplicasValue' , {
281+ value : row ?. minReplicas ,
282+ } ) }
283+ </ span >
284+ ) ;
285+ } ,
281286 } ,
282287 {
283288 key : 'createdAt' ,
0 commit comments