Skip to content

Commit a777826

Browse files
committed
feat(FR-555): Improve the auto-scaling rule editor interface and list (#3202)
Resolves #3201 (FR-555) ### TL;DR > For test, please pull this lablup/backend.ai#3757 to your test server Redesigned the auto-scaling rule editor interface to improve usability and add separate controls for scale up/down operations. ### What changed? - Added distinct scale up/down options instead of combining them - Simplified metric selection with autocomplete and predefined options - Consolidated condition inputs (metric, comparator, threshold) into a single row - Removed redundant min/max replica fields based on scaling direction - Added tooltips and improved validation logic - Updated translations for all supported languages with new UI strings ### How to test? 1. Open the endpoint detail page 2. Click to add a new auto-scaling rule 3. Verify the new UI with separate scale up/down options 4. Test metric name autocomplete functionality 5. Confirm min/max replicas show correctly based on scale direction 6. Validate form submissions work for both scale up and down scenarios ### Why make this change? The previous interface combined scale up/down operations which made it confusing for users to configure rules correctly. This redesign separates the concerns and provides a more intuitive workflow while reducing potential configuration errors through better validation and clearer UI elements.
1 parent ed53e3c commit a777826

23 files changed

+421
-200
lines changed

react/src/components/AutoScalingRuleEditorModal.tsx

Lines changed: 226 additions & 137 deletions
Large diffs are not rendered by default.

react/src/pages/EndpointDetailPage.tsx

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ImageMetaIcon from '../components/ImageMetaIcon';
1212
import InferenceSessionErrorModal from '../components/InferenceSessionErrorModal';
1313
import ResourceNumber from '../components/ResourceNumber';
1414
import SessionDetailDrawer from '../components/SessionDetailDrawer';
15+
import UnmountModalAfterClose from '../components/UnmountModalAfterClose';
1516
import VFolderLazyView from '../components/VFolderLazyView';
1617
import { AutoScalingRuleEditorModalFragment$key } from '../components/__generated__/AutoScalingRuleEditorModalFragment.graphql';
1718
import { InferenceSessionErrorModalFragment$key } from '../components/__generated__/InferenceSessionErrorModalFragment.graphql';
@@ -63,7 +64,11 @@ import { DescriptionsItemType } from 'antd/es/descriptions';
6364
import graphql from 'babel-plugin-relay/macro';
6465
import { default as dayjs } from 'dayjs';
6566
import _ from 'lodash';
66-
import { BotMessageSquareIcon } from 'lucide-react';
67+
import {
68+
BotMessageSquareIcon,
69+
CircleArrowDownIcon,
70+
CircleArrowUpIcon,
71+
} from 'lucide-react';
6772
import React, { Suspense, useState, useTransition } from 'react';
6873
import { useTranslation } from 'react-i18next';
6974
import { useLazyLoadQuery, useMutation } from 'react-relay';
@@ -634,21 +639,33 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
634639
rowKey={'id'}
635640
columns={[
636641
{
637-
title: '#',
642+
title: t('autoScalingRule.ScalingType'),
638643
fixed: 'left',
639-
render: (id, record, index) => {
640-
++index;
641-
return index;
642-
},
644+
render: (text, row) =>
645+
(row?.step_size || 0) > 0 ? 'Up' : 'Down',
646+
},
647+
{
648+
title: t('autoScalingRule.MetricSource'),
649+
dataIndex: 'metric_source',
650+
// render: (text, row) => <Tag>{row?.metric_source}</Tag>,
643651
},
644652
{
645-
title: t('autoScalingRule.MetricName'),
653+
title: t('autoScalingRule.Condition'),
646654
dataIndex: 'metric_name',
647655
fixed: 'left',
648656
render: (text, row) => (
649-
<Typography.Text ellipsis copyable style={{ width: 150 }}>
650-
{row?.metric_name}
651-
</Typography.Text>
657+
<Flex gap={'xs'}>
658+
<Tag>{row?.metric_name}</Tag>
659+
{row?.comparator ? (
660+
<Tooltip title={row.comparator}>
661+
{/* @ts-ignore */}
662+
{COMPARATOR_LABELS[row.comparator]}
663+
</Tooltip>
664+
) : (
665+
'-'
666+
)}
667+
{row?.threshold}
668+
</Flex>
652669
),
653670
},
654671
{
@@ -769,32 +786,40 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
769786
</Flex>
770787
),
771788
},
772-
{
773-
title: t('autoScalingRule.MetricSource'),
774-
dataIndex: 'metric_source',
775-
render: (text, row) => <Tag>{row?.metric_source}</Tag>,
776-
},
777-
{
778-
title: t('autoScalingRule.Comparator'),
779-
dataIndex: 'comparator',
780-
render: (text, row) => (
781-
// @ts-ignore
782-
<Tooltip title={text}>{COMPARATOR_LABELS[text]}</Tooltip>
783-
),
784-
},
785-
{
786-
title: t('autoScalingRule.Threshold'),
787-
render: (text, row) => <span>{row?.threshold}</span>,
788-
},
789+
789790
{
790791
title: t('autoScalingRule.StepSize'),
791792
dataIndex: 'step_size',
793+
render: (text, row) => {
794+
if (row?.step_size) {
795+
return (
796+
<Flex gap={'xs'}>
797+
<Typography.Text>
798+
{row?.step_size > 0 ? (
799+
<CircleArrowUpIcon />
800+
) : (
801+
<CircleArrowDownIcon />
802+
)}
803+
</Typography.Text>
804+
<Typography.Text>
805+
{Math.abs(row?.step_size)}
806+
</Typography.Text>
807+
</Flex>
808+
);
809+
} else {
810+
return '-';
811+
}
812+
},
792813
},
793814
{
794815
title: t('autoScalingRule.MIN/MAXReplicas'),
795816
render: (text, row) => (
796817
<span>
797-
Min: {row?.min_replicas} / Max: {row?.max_replicas}
818+
{row?.step_size
819+
? row?.step_size > 0
820+
? `Max: ${row?.max_replicas}`
821+
: `Min: ${row?.min_replicas}`
822+
: '-'}
798823
</span>
799824
),
800825
},
@@ -1064,20 +1089,22 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
10641089
}}
10651090
/>
10661091
{isSupportAutoScalingRule && (
1067-
<AutoScalingRuleEditorModal
1068-
open={isOpenAutoScalingRuleModal}
1069-
endpoint_id={endpoint?.endpoint_id as string}
1070-
autoScalingRuleFrgmt={editingAutoScalingRule}
1071-
onRequestClose={(success) => {
1072-
setIsOpenAutoScalingRuleModal(!isOpenAutoScalingRuleModal);
1073-
setEditingAutoScalingRule(null);
1074-
if (success) {
1075-
startRefetchTransition(() => {
1076-
updateFetchKey();
1077-
});
1078-
}
1079-
}}
1080-
/>
1092+
<UnmountModalAfterClose>
1093+
<AutoScalingRuleEditorModal
1094+
open={isOpenAutoScalingRuleModal}
1095+
endpoint_id={endpoint?.endpoint_id as string}
1096+
autoScalingRuleFrgmt={editingAutoScalingRule}
1097+
onRequestClose={(success) => {
1098+
setIsOpenAutoScalingRuleModal(!isOpenAutoScalingRuleModal);
1099+
setEditingAutoScalingRule(null);
1100+
if (success) {
1101+
startRefetchTransition(() => {
1102+
updateFetchKey();
1103+
});
1104+
}
1105+
}}
1106+
/>
1107+
</UnmountModalAfterClose>
10811108
)}
10821109
<SessionDetailDrawer
10831110
open={!selectedSessionId}

resources/i18n/de.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Metrische Quelle",
17861786
"MIN/MAXReplicas": "Min / Max Replikas",
17871787
"LastTriggered": "Zuletzt ausgelöst",
1788-
"CreatedAt": "Zeit erstellt"
1788+
"CreatedAt": "Zeit erstellt",
1789+
"ConditionTooltip": "Sie können jede von der Laufzeitumgebung unterstützte Metrik frei eingeben.\nZum Beispiel: \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Typ",
1791+
"ScaleUp": "Hochskalieren",
1792+
"ScaleDown": "Verkleinern",
1793+
"Condition": "Zustand"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "Kernel ID",

resources/i18n/el.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Μετρική πηγή",
17861786
"MIN/MAXReplicas": "Min / Max Replicas",
17871787
"LastTriggered": "Τελευταία ενεργοποιημένη",
1788-
"CreatedAt": "Δημιουργήθηκε ώρα"
1788+
"CreatedAt": "Δημιουργήθηκε ώρα",
1789+
"ConditionTooltip": "Μπορείτε να εισαγάγετε ελεύθερα οποιαδήποτε μετρική που υποστηρίζεται από το περιβάλλον εκτέλεσης.\nΓια παράδειγμα: \"cuda_mem\", \"cuda_util\".",
1790+
"ScalingType": "Τύπος",
1791+
"ScaleUp": "Κλιμάκωση",
1792+
"ScaleDown": "Κλιμάκωση προς τα κάτω",
1793+
"Condition": "Κατάσταση"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "Αναγνωριστικό πυρήνα",

resources/i18n/en.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,12 @@
17911791
"StepSize": "Step Size",
17921792
"MIN/MAXReplicas": "Min / MAX Replicas",
17931793
"LastTriggered": "Last Triggered",
1794-
"CreatedAt": "Created At"
1794+
"CreatedAt": "Created At",
1795+
"ScaleUp": "Scale Up",
1796+
"ScaleDown": "Scale Down",
1797+
"Condition": "Condition",
1798+
"ConditionTooltip": "You can freely input any metric supported by the runtime environment.\nFor example: \"cuda_mem\", \"cuda_util\"",
1799+
"ScalingType": "Type"
17951800
},
17961801
"kernel": {
17971802
"KernelId": "Kernel ID",

resources/i18n/es.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Fuente métrica",
17861786
"MIN/MAXReplicas": "Réplicas min / max",
17871787
"LastTriggered": "Última activación",
1788-
"CreatedAt": "Tiempo creado"
1788+
"CreatedAt": "Tiempo creado",
1789+
"ConditionTooltip": "Puede introducir libremente cualquier métrica admitida por el entorno de ejecución.\nPor ejemplo: \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Tipo",
1791+
"ScaleUp": "Ampliar",
1792+
"ScaleDown": "Reducción de escala",
1793+
"Condition": "Condición"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID de núcleo",

resources/i18n/fi.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1784,7 +1784,12 @@
17841784
"MetricSource": "Metrilähde",
17851785
"MIN/MAXReplicas": "Min / max -kopiot",
17861786
"LastTriggered": "Viimeksi laukaistu",
1787-
"CreatedAt": "Luotu aika"
1787+
"CreatedAt": "Luotu aika",
1788+
"ConditionTooltip": "Voit syöttää vapaasti minkä tahansa ajoympäristön tukeman mittarin.\nEsimerkiksi: \"cuda_mem\", \"cuda_util\".",
1789+
"ScalingType": "Tyyppi",
1790+
"ScaleUp": "Laajentaminen",
1791+
"ScaleDown": "Pienennä mittakaavaa",
1792+
"Condition": "Kunto"
17881793
},
17891794
"kernel": {
17901795
"KernelId": "Ytimen tunnus",

resources/i18n/fr.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Source métrique",
17861786
"MIN/MAXReplicas": "Répliques min / max",
17871787
"LastTriggered": "Dernière déclenché",
1788-
"CreatedAt": "Temps créé"
1788+
"CreatedAt": "Temps créé",
1789+
"ConditionTooltip": "Vous pouvez saisir librement n'importe quelle mesure prise en charge par l'environnement d'exécution.\nPar exemple : \"cuda_mem\", \"cuda_util\", etc : \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Type",
1791+
"ScaleUp": "Augmentation d'échelle",
1792+
"ScaleDown": "Réduction d'échelle",
1793+
"Condition": "Condition"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID du noyau",

resources/i18n/id.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Sumber metrik",
17861786
"MIN/MAXReplicas": "Replika min / maks",
17871787
"LastTriggered": "Terakhir dipicu",
1788-
"CreatedAt": "Waktu yang dibuat"
1788+
"CreatedAt": "Waktu yang dibuat",
1789+
"ConditionTooltip": "Anda dapat dengan bebas memasukkan metrik apa pun yang didukung oleh lingkungan runtime.\nSebagai contoh: \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Jenis",
1791+
"ScaleUp": "Meningkatkan Skala",
1792+
"ScaleDown": "Skala Turun",
1793+
"Condition": "Kondisi"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID kernel",

resources/i18n/it.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,12 @@
17831783
"MetricSource": "Fonte metrica",
17841784
"MIN/MAXReplicas": "Repliche min / max",
17851785
"LastTriggered": "Ultimo attivato",
1786-
"CreatedAt": "Tempo creato"
1786+
"CreatedAt": "Tempo creato",
1787+
"ConditionTooltip": "È possibile inserire liberamente qualsiasi metrica supportata dall'ambiente di runtime.\nAd esempio: \"cuda_mem\", \"cuda_util\".",
1788+
"ScalingType": "Tipo",
1789+
"ScaleUp": "Scalare",
1790+
"ScaleDown": "Riduzione della scala",
1791+
"Condition": "Condizione"
17871792
},
17881793
"kernel": {
17891794
"KernelId": "Kernel ID",

resources/i18n/ja.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "メトリックソース",
17861786
"MIN/MAXReplicas": "min / maxレプリカ",
17871787
"LastTriggered": "最後にトリガーされました",
1788-
"CreatedAt": "作成された時間"
1788+
"CreatedAt": "作成された時間",
1789+
"ConditionTooltip": "ランタイム環境でサポートされている任意の指標を自由に入力することができる。\nたとえば\"cuda_mem\"\"cuda_util\"",
1790+
"ScalingType": "タイプ",
1791+
"ScaleUp": "スケールアップ",
1792+
"ScaleDown": "スケールダウン",
1793+
"Condition": "コンディション"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "カーネルID",

resources/i18n/ko.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,12 @@
17891789
"MetricSource": "메트릭 소스",
17901790
"MIN/MAXReplicas": "최소 / 최대 복제본 수",
17911791
"LastTriggered": "최근 실행 시점",
1792-
"CreatedAt": "생성 시간"
1792+
"CreatedAt": "생성 시간",
1793+
"ScaleUp": "스케일 업",
1794+
"ScaleDown": "스케일 다운",
1795+
"Condition": "조건",
1796+
"ConditionTooltip": "실행 환경에서 지원하는 메트릭을 자유롭게 입력할 수 있습니다. 예) \"cuda_mem\", \"cuda_util\"",
1797+
"ScalingType": "타입"
17931798
},
17941799
"kernel": {
17951800
"KernelId": "커널 ID",

resources/i18n/mn.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1784,7 +1784,12 @@
17841784
"MetricSource": "Метрийн эх сургай",
17851785
"MIN/MAXReplicas": "Мин / Макс хуулбарууд",
17861786
"LastTriggered": "Хамгийн сүүлд өдөөсөн",
1787-
"CreatedAt": "Үед"
1787+
"CreatedAt": "Үед",
1788+
"ConditionTooltip": "Ажиллах цагийн орчинд ямар ч хэмжигдэхүүнийг чөлөөтэй оруулж болно.\n\nЖишээлбэл: \"Cuda_mem\", \"Cuda_util\"",
1789+
"ScalingType": "Маяг",
1790+
"ScaleUp": "Газар дамжуулах",
1791+
"ScaleDown": "Хэмжээ",
1792+
"Condition": "Болзол"
17881793
},
17891794
"kernel": {
17901795
"KernelId": "Kernel ID",

resources/i18n/ms.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Sumber metrik",
17861786
"MIN/MAXReplicas": "Replika min / max",
17871787
"LastTriggered": "Yang terakhir dicetuskan",
1788-
"CreatedAt": "Masa yang dicipta"
1788+
"CreatedAt": "Masa yang dicipta",
1789+
"ConditionTooltip": "Anda boleh memasukkan mana -mana metrik yang disokong oleh persekitaran runtime.\n\nContohnya: \"CUDA_MEM\", \"CUDA_UTIL\"",
1790+
"ScalingType": "Jenis",
1791+
"ScaleUp": "Skala",
1792+
"ScaleDown": "Skala ke bawah",
1793+
"Condition": "Keadaan"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID Kernel",

resources/i18n/pl.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Źródło metryczne",
17861786
"MIN/MAXReplicas": "Repliki min / max",
17871787
"LastTriggered": "Ostatni wyzwolenie",
1788-
"CreatedAt": "Utworzony czas"
1788+
"CreatedAt": "Utworzony czas",
1789+
"ConditionTooltip": "Możesz dowolnie wprowadzić dowolną metrykę obsługiwaną przez środowisko wykonawcze.\nNa przykład: \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Typ",
1791+
"ScaleUp": "Zwiększanie skali",
1792+
"ScaleDown": "Skalowanie w dół",
1793+
"Condition": "Stan"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID jądra",

resources/i18n/pt-BR.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Fonte métrica",
17861786
"MIN/MAXReplicas": "Min / Max Replicas",
17871787
"LastTriggered": "Último desencadeado",
1788-
"CreatedAt": "Tempo criado"
1788+
"CreatedAt": "Tempo criado",
1789+
"ConditionTooltip": "Pode introduzir livremente qualquer métrica suportada pelo ambiente de tempo de execução.\nPor exemplo: \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Tipo",
1791+
"ScaleUp": "Aumentar a escala",
1792+
"ScaleDown": "Reduzir a escala",
1793+
"Condition": "Estado"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID do kernel",

resources/i18n/pt.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Fonte métrica",
17861786
"MIN/MAXReplicas": "Min / Max Replicas",
17871787
"LastTriggered": "Último desencadeado",
1788-
"CreatedAt": "Tempo criado"
1788+
"CreatedAt": "Tempo criado",
1789+
"ConditionTooltip": "Pode introduzir livremente qualquer métrica suportada pelo ambiente de tempo de execução.\nPor exemplo: \"cuda_mem\", \"cuda_util\"",
1790+
"ScalingType": "Tipo",
1791+
"ScaleUp": "Aumentar a escala",
1792+
"ScaleDown": "Reduzir a escala",
1793+
"Condition": "Estado"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "ID do kernel",

resources/i18n/ru.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,12 @@
17851785
"MetricSource": "Метрический источник",
17861786
"MIN/MAXReplicas": "Мин / максимальные реплики",
17871787
"LastTriggered": "Последний вызван",
1788-
"CreatedAt": "Создано время"
1788+
"CreatedAt": "Создано время",
1789+
"ConditionTooltip": "Вы можете свободно ввести любую метрику, поддерживаемую средой выполнения.\nНапример: \"cuda_mem\", \"cuda_util\".",
1790+
"ScalingType": "Тип",
1791+
"ScaleUp": "Увеличение масштаба",
1792+
"ScaleDown": "Уменьшение масштаба",
1793+
"Condition": "Состояние"
17891794
},
17901795
"kernel": {
17911796
"KernelId": "Ядро идентификатор",

resources/i18n/th.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1766,7 +1766,12 @@
17661766
"MetricSource": "แหล่งวัด",
17671767
"MIN/MAXReplicas": "แบบจำลองขั้นต่ำ / สูงสุด",
17681768
"LastTriggered": "ทริกเกอร์ครั้งสุดท้าย",
1769-
"CreatedAt": "สร้างเวลา"
1769+
"CreatedAt": "สร้างเวลา",
1770+
"ConditionTooltip": "คุณสามารถป้อนตัวชี้วัดใด ๆ ที่รองรับโดยสภาพแวดล้อมรันไทม์ได้อย่างอิสระ\n\nตัวอย่างเช่น: \"cuda_mem\", \"cuda_util\"",
1771+
"ScalingType": "พิมพ์",
1772+
"ScaleUp": "ขยาย",
1773+
"ScaleDown": "ลดขนาดลง",
1774+
"Condition": "เงื่อนไข"
17701775
},
17711776
"kernel": {
17721777
"KernelId": "ID เคอร์เนล",

0 commit comments

Comments
 (0)