diff --git a/src/components/DetailsMetrics/DetailsMetrics.scss b/src/components/DetailsMetrics/DetailsMetrics.scss
index 8bf7e95a2a..a36bdcd10d 100644
--- a/src/components/DetailsMetrics/DetailsMetrics.scss
+++ b/src/components/DetailsMetrics/DetailsMetrics.scss
@@ -10,6 +10,7 @@ $stickyHeaderHeight: 55px;
z-index: 2;
display: flex;
justify-content: space-between;
+ background-color: colors.$white;
&__custom-filters {
display: flex;
diff --git a/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx b/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx
index 2ffa16ef07..15b39c1d91 100644
--- a/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx
+++ b/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx
@@ -44,6 +44,7 @@ import { getScssVariableValue } from 'igz-controls/utils/common.util'
import { isDetailsTabExists } from '../../../utils/link-helper.util'
import { isRowRendered, useVirtualization } from '../../../hooks/useVirtualization.hook'
import { setFilters } from '../../../reducers/filtersReducer'
+import { clearMetricsOptions } from '../../../reducers/detailsReducer'
import { useFiltersFromSearchParams } from '../../../hooks/useFiltersFromSearchParams.hook'
import { useInitialTableFetch } from '../../../hooks/useInitialTableFetch.hook'
import { useModelsPage } from '../ModelsPage.context'
@@ -191,6 +192,12 @@ const ModelEndpoints = () => {
}
}, [dispatch, params.projectName])
+ useEffect(()=> {
+ return () => {
+ dispatch(clearMetricsOptions())
+ }
+ }, [dispatch])
+
useEffect(() => {
if (params.name && modelEndpoints.length > 0) {
const searchItem = modelEndpoints.find(item => item.metadata?.uid === params.tag)
diff --git a/src/reducers/detailsReducer.js b/src/reducers/detailsReducer.js
index 8cb57b79ba..1770702edd 100644
--- a/src/reducers/detailsReducer.js
+++ b/src/reducers/detailsReducer.js
@@ -104,7 +104,7 @@ export const fetchModelEndpointMetrics = createAsyncThunk(
.then(({ data = [] }) => {
const metrics = generateMetricsItems(data, applicationName)
- return { endpointUid: uid, metrics }
+ return { endpointUid: uid, metrics, applicationName }
})
.catch(error => thunkAPI.rejectWithValue(error))
}
@@ -189,6 +189,14 @@ const detailsStoreSlice = createSlice({
decreaseDetailsLoadingCounter(state) {
state.loadingCounter = state.loadingCounter - 1
},
+ clearMetricsOptions(state) {
+ state.metricsOptions = {
+ all: [],
+ lastSelected: [],
+ preselected: [],
+ selectedByEndpoint: {}
+ }
+ }
},
extraReducers: builder => {
builder.addCase(fetchModelFeatureVector.pending, state => {
@@ -289,6 +297,7 @@ export const {
setSelectedMetricsOptions,
increaseDetailsLoadingCounter,
decreaseDetailsLoadingCounter,
+ clearMetricsOptions
} = detailsStoreSlice.actions
export default detailsStoreSlice.reducer
diff --git a/tests/mockServer/data/metrics.json b/tests/mockServer/data/metrics.json
index 6dc5f883fb..d10def30b8 100644
--- a/tests/mockServer/data/metrics.json
+++ b/tests/mockServer/data/metrics.json
@@ -12,23 +12,224 @@
"project": "default"
},
{
- "full_name": "default.histogram-data-drift-1.metric.tvdar_mean_1",
+ "full_name": "default.monitorAppV1.metric.tvdar_mean_1",
"type": "metric",
- "app": "histogram-data-drift-1",
+ "app": "monitorAppV1",
"name": "tvdar_mean_1",
"project": "default"
},
{
- "full_name": "default.histogram-data-drift-1.metric.tvdop_mean_1",
+ "full_name": "default.monitorAppV1.metric.tvdop_mean_1",
"type": "metric",
- "app": "histogram-data-drift-1",
+ "app": "monitorAppV1",
"name": "tvdop_mean_1",
"project": "default"
},
{
- "full_name": "default.histogram-data-drift-1.metric.tvds_mean_1",
+ "full_name": "default.monitorAppV1.metric.tvds_mean_1",
"type": "metric",
- "app": "histogram-data-drift-1",
+ "app": "monitorAppV1",
+ "name": "tvds_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.result.hellinger_mean_1",
+ "type": "result",
+ "app": "monitorAppV1",
+ "name": "hellinger_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.data_drift_test_1",
+ "type": "metric",
+ "app": "monitorAppV1",
+ "name": "data_drift_test_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.general_drift_1",
+ "type": "metric",
+ "app": "monitorAppV1",
+ "name": "general_drift_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.result.model_perf_1",
+ "type": "result",
+ "app": "monitorAppV1",
+ "name": "model_perf_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.kld_mean_1",
+ "type": "metric",
+ "app": "monitorAppV2",
+ "name": "kld_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.kld_mean_1",
+ "type": "metric",
+ "app": "monitorAppV2",
+ "name": "kld_mean_1",
+ "project": "default"
+ }
+ ],
+ "metricsValues": [
+ {
+ "full_name": "default.rujmfi.result.data_drift_test",
+ "type": "result",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.hskoyl.result.data_drift_test",
+ "type": "result",
+ "data": "true",
+ "values": [
+ 5
+ ]
+ },
+ {
+ "full_name": "default.mlrun-infra.metric.invocations-rate",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10, true
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvdar_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvdop_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvds_mean_1",
+ "type": "metric",
+ "data": false
+ },
+ {
+ "full_name": "default.monitorAppV1.result.hellinger_mean_1",
+ "type": "result",
+ "result_kind": 0,
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.data_drift_test_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.general_drift_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.result.model_perf_1",
+ "type": "result",
+ "result_kind": 1,
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.kld_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.kld_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ }
+ ]
+ },
+ {
+ "modelEndpointUID": "a7c95783e6a726a1a233e581ea898ba44fa7e342",
+ "project": "default",
+ "metricsOptions": [
+ {
+ "full_name": "default.mlrun-infra.metric.invocations-rate",
+ "type": "metric",
+ "app": "mlrun-infra",
+ "name": "invocations-rate",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvdar_mean_1",
+ "type": "metric",
+ "app": "monitorAppV1",
+ "name": "tvdar_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.tvdar_mean_1",
+ "type": "metric",
+ "app": "monitorAppV2",
+ "name": "tvdar_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV3.metric.tvdar_mean_1",
+ "type": "metric",
+ "app": "monitorAppV3",
+ "name": "tvdar_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvdop_mean_1",
+ "type": "metric",
+ "app": "monitorAppV1",
+ "name": "tvdop_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.tvdop_mean_1",
+ "type": "metric",
+ "app": "monitorAppV2",
+ "name": "tvdop_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvds_mean_1",
+ "type": "metric",
+ "app": "monitorAppV1",
+ "name": "tvds_mean_1",
+ "project": "default"
+ },
+ {
+ "full_name": "default.monitorAppV3.metric.tvds_mean_1",
+ "type": "metric",
+ "app": "monitorAppV3",
"name": "tvds_mean_1",
"project": "default"
},
@@ -101,7 +302,7 @@
]
},
{
- "full_name": "default.histogram-data-drift-1.metric.tvdar_mean_1",
+ "full_name": "default.monitorAppV1.metric.tvdar_mean_1",
"type": "metric",
"data": "true",
"values": [
@@ -109,7 +310,7 @@
]
},
{
- "full_name": "default.histogram-data-drift-1.metric.tvdop_mean_1",
+ "full_name": "default.monitorAppV2.metric.tvdar_mean_1",
"type": "metric",
"data": "true",
"values": [
@@ -117,7 +318,36 @@
]
},
{
- "full_name": "default.histogram-data-drift-1.metric.tvds_mean_1",
+ "full_name": "default.monitorAppV3.metric.tvdar_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV2.metric.tvdop_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvdop_mean_1",
+ "type": "metric",
+ "data": "true",
+ "values": [
+ 10
+ ]
+ },
+ {
+ "full_name": "default.monitorAppV1.metric.tvds_mean_1",
+ "type": "metric",
+ "data": false
+ },
+ {
+ "full_name": "default.monitorAppV3.metric.tvds_mean_1",
"type": "metric",
"data": false
},
diff --git a/tests/mockServer/data/modelEndpoints.json b/tests/mockServer/data/modelEndpoints.json
index 96ac7a9b0c..100968951d 100644
--- a/tests/mockServer/data/modelEndpoints.json
+++ b/tests/mockServer/data/modelEndpoints.json
@@ -262,6 +262,268 @@
"sampling_percentage": 20
}
},
+ {
+ "kind": "model-endpoint",
+ "metadata": {
+ "project": "default",
+ "labels": {
+ "my-key": "my-value",
+ "owner": "admin",
+ "v3io_user": "admin"
+ },
+ "endpoint_type": 3,
+ "name": "RandomForestClassifier2",
+ "created": "2024-11-03T09:18:59.079000",
+ "updated": "2024-11-03T09:40:58.317000",
+ "uid": "a7c95783e6a726a1a233e581ea898ba44fa7e342"
+ },
+ "spec": {
+ "function_name": "transaction-fraud",
+ "function_tag": "latest",
+ "function_uid": "unversioned-latest",
+ "function_uri": "default/aggregate@79fd83704a8514dc2415bded0e9d0ffd94262e92",
+ "model_name": "RandomForestClassifier",
+ "model_class": "ClassifierModel",
+ "model_uid": "898baa010eb35b914558182ad487bc582defde34",
+ "model_tag": null,
+ "model_uri": "store://models/default/model_default:latest",
+ "feature_names": [
+ "amount_max_2h",
+ "amount_sum_2h",
+ "amount_count_2h",
+ "amount_avg_2h",
+ "amount_max_12h",
+ "label"
+ ],
+ "label_names": ["label", "__index_level_0__"],
+ "children": null,
+ "children_uids": null,
+ "feature_stats": {
+ "amount_max_2h": {
+ "count": 7446,
+ "mean": 41.994970453935,
+ "std": 104.4010819361322,
+ "min": 0,
+ "max": 4759.79,
+ "hist": [
+ [7352, 57, 19, 6, 2, 2, 0, 1, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1],
+ [
+ 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916,
+ 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997,
+ 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79
+ ]
+ ]
+ },
+ "amount_sum_2h": {
+ "count": 7446,
+ "mean": 46.912805533172175,
+ "std": 107.48110128941029,
+ "min": -147.49,
+ "max": 4770.01,
+ "hist": [
+ [6920, 467, 32, 13, 2, 3, 1, 0, 4, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1],
+ [
+ -147.49, 98.38499999999999, 344.26, 590.135, 836.01, 1081.885, 1327.76, 1573.635,
+ 1819.51, 2065.385, 2311.26, 2557.135, 2803.01, 3048.885, 3294.76, 3540.635, 3786.51,
+ 4032.385, 4278.26, 4524.135, 4770.01
+ ]
+ ]
+ },
+ "amount_count_2h": {
+ "count": 7446,
+ "mean": 1.2539618587160892,
+ "std": 0.5436930806122989,
+ "min": -1,
+ "max": 6,
+ "hist": [
+ [6, 0, 0, 0, 0, 5860, 0, 0, 1306, 0, 0, 229, 0, 0, 42, 0, 0, 2, 0, 1],
+ [
+ -1, -0.65, -0.30000000000000004, 0.04999999999999982, 0.3999999999999999, 0.75,
+ 1.0999999999999996, 1.4499999999999997, 1.7999999999999998, 2.15, 2.5,
+ 2.8499999999999996, 3.1999999999999993, 3.55, 3.8999999999999995, 4.25, 4.6,
+ 4.949999999999999, 5.3, 5.6499999999999995, 6
+ ]
+ ]
+ },
+ "amount_avg_2h": {
+ "count": 7446,
+ "mean": 38.96664405945027,
+ "std": 140.24284088047725,
+ "min": -107.44000000000001,
+ "max": 6405.95,
+ "hist": [
+ [7366, 49, 19, 4, 0, 0, 3, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2],
+ [
+ -107.44000000000001, 218.22949999999997, 543.8989999999999, 869.5684999999999,
+ 1195.2379999999998, 1520.9074999999998, 1846.5769999999998, 2172.2464999999997,
+ 2497.9159999999997, 2823.5854999999997, 3149.2549999999997, 3474.9244999999996,
+ 3800.5939999999996, 4126.2635, 4451.933, 4777.6025, 5103.272, 5428.9415, 5754.611,
+ 6080.2805, 6405.95
+ ]
+ ]
+ },
+ "amount_max_12h": {
+ "count": 7446,
+ "mean": 53.890123556271824,
+ "std": 122.18467228149133,
+ "min": 0,
+ "max": 4759.79,
+ "hist": [
+ [7300, 92, 24, 13, 3, 4, 0, 2, 3, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1],
+ [
+ 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916,
+ 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997,
+ 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79
+ ]
+ ]
+ },
+ "label": {
+ "count": 7446,
+ "mean": 0.014907332796132152,
+ "std": 0.12119025003595912,
+ "min": 0,
+ "max": 1,
+ "hist": [
+ [7335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111],
+ [
+ 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004,
+ 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65,
+ 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1
+ ]
+ ]
+ }
+ },
+ "monitoring_feature_set_uri": "store://feature-sets/default/stocks:latest"
+ },
+ "status": {
+ "state": null,
+ "monitoring_mode": "enabled",
+ "current_stats": {
+ "amount_avg_2h": {
+ "count": 11,
+ "mean": 28.0887273020327,
+ "std": 11.304901433309531,
+ "min": 12.19,
+ "max": 38.615200064471935,
+ "hist": [
+ [1, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5],
+ [
+ 12.19, 13.511260003223596, 14.832520006447194, 16.15378000967079,
+ 17.475040012894386, 18.796300016117982, 20.117560019341582, 21.438820022565178,
+ 22.760080025788774, 24.08134002901237, 25.402600032235966, 26.723860035459566,
+ 28.04512003868316, 29.36638004190676, 30.687640045130358, 32.00890004835395,
+ 33.33016005157755, 34.65142005480114, 35.97268005802474, 37.29394006124834,
+ 38.615200064471935
+ ]
+ ]
+ },
+ "amount_count_2h": {
+ "count": 11,
+ "mean": 0.5454545454545454,
+ "std": 0.5222329678670935,
+ "min": 0,
+ "max": 1,
+ "hist": [
+ [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6],
+ [
+ 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004,
+ 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65,
+ 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1
+ ]
+ ]
+ },
+ "amount_max_12h": {
+ "count": 11,
+ "mean": 55.03636363636363,
+ "std": 57.971923596293976,
+ "min": 20.92,
+ "max": 224.11,
+ "hist": [
+ [3, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ [
+ 20.92, 31.079500000000003, 41.239000000000004, 51.3985, 61.558, 71.7175, 81.877,
+ 92.0365, 102.196, 112.35549999999999, 122.515, 132.6745, 142.834,
+ 152.99349999999998, 163.15300000000002, 173.3125, 183.47199999999998,
+ 193.63150000000002, 203.791, 213.95049999999998, 224.11
+ ]
+ ]
+ },
+ "amount_max_2h": {
+ "count": 11,
+ "mean": 29.96273243391514,
+ "std": 13.260285022445734,
+ "min": 12.19,
+ "max": 42.738011354613306,
+ "hist": [
+ [1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5],
+ [
+ 12.19, 13.717400567730666, 15.24480113546133, 16.772201703191996,
+ 18.299602270922662, 19.82700283865333, 21.354403406383994, 22.881803974114657,
+ 24.409204541845323, 25.93660510957599, 27.464005677306652, 28.991406245037318,
+ 30.518806812767984, 32.04620738049865, 33.573607948229316, 35.10100851595998,
+ 36.62840908369065, 38.155809651421315, 39.68321021915198, 41.21061078688264,
+ 42.738011354613306
+ ]
+ ]
+ },
+ "amount_sum_2h": {
+ "count": 11,
+ "mean": 10.536363636363637,
+ "std": 11.31334457419845,
+ "min": 0,
+ "max": 30.42,
+ "hist": [
+ [5, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1],
+ [
+ 0, 1.5210000000000001, 3.0420000000000003, 4.563000000000001, 6.0840000000000005,
+ 7.605, 9.126000000000001, 10.647, 12.168000000000001, 13.689000000000002, 15.21,
+ 16.731, 18.252000000000002, 19.773000000000003, 21.294, 22.815, 24.336000000000002,
+ 25.857000000000003, 27.378000000000004, 28.899, 30.42
+ ]
+ ]
+ }
+ },
+ "first_request": "2022-05-02 11:14:21.082236+00:00",
+ "last_request": "2022-05-19 09:43:49.502045+00:00",
+ "error_count": null,
+ "drift_status": "DRIFT_DETECTED",
+ "avg_latency": null,
+ "drift_measures": {
+ "amount_max_2h": {
+ "tvd": 0.9006299904768882,
+ "hellinger": 0.8026729143746129,
+ "kld": 8.03097275516625
+ },
+ "tvd_sum": 4.0574683173393895,
+ "tvd_mean": 0.8114936634678779,
+ "hellinger_sum": 3.7935228606235265,
+ "hellinger_mean": 0.7587045721247053,
+ "kld_sum": 40.22159405569385,
+ "kld_mean": 8.04431881113877,
+ "amount_count_2h": {
+ "tvd": 0.9990598979317755,
+ "hellinger": 0.9860541717475733,
+ "kld": 15.975132772583372
+ },
+ "amount_avg_2h": {
+ "tvd": 0.9019729934314947,
+ "hellinger": 0.8046642697553347,
+ "kld": 7.91538219147246
+ },
+ "amount_sum_2h": {
+ "tvd": 0.5447830439772423,
+ "hellinger": 0.5827239245591163,
+ "kld": 4.424521130663923
+ },
+ "amount_max_12h": {
+ "tvd": 0.7110223915219885,
+ "hellinger": 0.6174075801868897,
+ "kld": 3.8755852058078455
+ }
+ },
+ "sampling_percentage": 20
+ }
+ },
{
"kind": "model-endpoint",
"metadata": {
@@ -519,6 +781,264 @@
},
"sampling_percentage": null
}
+ },
+ {
+ "kind": "model-endpoint",
+ "metadata": {
+ "project": "default",
+ "labels": {},
+ "endpoint_type": 3,
+ "name": "GradientBoostingClassifier2",
+ "created": "2024-12-03T09:18:59.079000",
+ "updated": "2024-12-03T09:40:58.317000",
+ "uid": "d6df9915e64e9ba9441a82983c4yc7f874550b31"
+ },
+ "spec": {
+ "function_name": "transaction-fraud",
+ "function_tag": "latest",
+ "function_uid": "unversioned-latest",
+ "function_uri": "default/vizro@69200c7de5447f61f15bd28913714c5970b831eb",
+ "model_name": "GradientBoostingClassifier2",
+ "model_uid": "898baa010eb35b914558182ad487bc582defde34",
+ "model_tag": null,
+ "model_class": "ClassifierModel",
+ "model_uri": "store://models/default/train_model:latest",
+ "feature_names": [
+ "amount_max_2h",
+ "amount_sum_2h",
+ "amount_count_2h",
+ "amount_avg_2h",
+ "amount_max_12h",
+ "label"
+ ],
+ "label_names": ["label", "__index_level_0__"],
+ "children": null,
+ "children_uids": null,
+ "feature_stats": {
+ "amount_max_2h": {
+ "count": 7446,
+ "mean": 41.994970453935,
+ "std": 104.4010819361322,
+ "min": 0,
+ "max": 4759.79,
+ "hist": [
+ [7352, 57, 19, 6, 2, 2, 0, 1, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1],
+ [
+ 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916,
+ 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997,
+ 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79
+ ]
+ ]
+ },
+ "amount_sum_2h": {
+ "count": 7446,
+ "mean": 46.912805533172175,
+ "std": 107.48110128941029,
+ "min": -147.49,
+ "max": 4770.01,
+ "hist": [
+ [6920, 467, 32, 13, 2, 3, 1, 0, 4, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1],
+ [
+ -147.49, 98.38499999999999, 344.26, 590.135, 836.01, 1081.885, 1327.76, 1573.635,
+ 1819.51, 2065.385, 2311.26, 2557.135, 2803.01, 3048.885, 3294.76, 3540.635, 3786.51,
+ 4032.385, 4278.26, 4524.135, 4770.01
+ ]
+ ]
+ },
+ "amount_count_2h": {
+ "count": 7446,
+ "mean": 1.2539618587160892,
+ "std": 0.5436930806122989,
+ "min": -1,
+ "max": 6,
+ "hist": [
+ [6, 0, 0, 0, 0, 5860, 0, 0, 1306, 0, 0, 229, 0, 0, 42, 0, 0, 2, 0, 1],
+ [
+ -1, -0.65, -0.30000000000000004, 0.04999999999999982, 0.3999999999999999, 0.75,
+ 1.0999999999999996, 1.4499999999999997, 1.7999999999999998, 2.15, 2.5,
+ 2.8499999999999996, 3.1999999999999993, 3.55, 3.8999999999999995, 4.25, 4.6,
+ 4.949999999999999, 5.3, 5.6499999999999995, 6
+ ]
+ ]
+ },
+ "amount_avg_2h": {
+ "count": 7446,
+ "mean": 38.96664405945027,
+ "std": 140.24284088047725,
+ "min": -107.44000000000001,
+ "max": 6405.95,
+ "hist": [
+ [7366, 49, 19, 4, 0, 0, 3, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2],
+ [
+ -107.44000000000001, 218.22949999999997, 543.8989999999999, 869.5684999999999,
+ 1195.2379999999998, 1520.9074999999998, 1846.5769999999998, 2172.2464999999997,
+ 2497.9159999999997, 2823.5854999999997, 3149.2549999999997, 3474.9244999999996,
+ 3800.5939999999996, 4126.2635, 4451.933, 4777.6025, 5103.272, 5428.9415, 5754.611,
+ 6080.2805, 6405.95
+ ]
+ ]
+ },
+ "amount_max_12h": {
+ "count": 7446,
+ "mean": 53.890123556271824,
+ "std": 122.18467228149133,
+ "min": 0,
+ "max": 4759.79,
+ "hist": [
+ [7300, 92, 24, 13, 3, 4, 0, 2, 3, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1],
+ [
+ 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916,
+ 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997,
+ 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79
+ ]
+ ]
+ },
+ "label": {
+ "count": 7446,
+ "mean": 0.014907332796132152,
+ "std": 0.12119025003595912,
+ "min": 0,
+ "max": 1,
+ "hist": [
+ [7335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111],
+ [
+ 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004,
+ 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65,
+ 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1
+ ]
+ ]
+ }
+ },
+ "monitoring_feature_set_uri": "store://feature-sets/default/test-m2:latest"
+ },
+ "status": {
+ "state": null,
+ "monitoring_mode": "enabled",
+ "current_stats": {
+ "amount_avg_2h": {
+ "count": 11,
+ "mean": 28.0887273020327,
+ "std": 11.304901433309531,
+ "min": 12.19,
+ "max": 38.615200064471935,
+ "hist": [
+ [1, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5],
+ [
+ 12.19, 13.511260003223596, 14.832520006447194, 16.15378000967079,
+ 17.475040012894386, 18.796300016117982, 20.117560019341582, 21.438820022565178,
+ 22.760080025788774, 24.08134002901237, 25.402600032235966, 26.723860035459566,
+ 28.04512003868316, 29.36638004190676, 30.687640045130358, 32.00890004835395,
+ 33.33016005157755, 34.65142005480114, 35.97268005802474, 37.29394006124834,
+ 38.615200064471935
+ ]
+ ]
+ },
+ "amount_count_2h": {
+ "count": 11,
+ "mean": 0.5454545454545454,
+ "std": 0.5222329678670935,
+ "min": 0,
+ "max": 1,
+ "hist": [
+ [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6],
+ [
+ 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004,
+ 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65,
+ 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1
+ ]
+ ]
+ },
+ "amount_max_12h": {
+ "count": 11,
+ "mean": 55.03636363636363,
+ "std": 57.971923596293976,
+ "min": 20.92,
+ "max": 224.11,
+ "hist": [
+ [3, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ [
+ 20.92, 31.079500000000003, 41.239000000000004, 51.3985, 61.558, 71.7175, 81.877,
+ 92.0365, 102.196, 112.35549999999999, 122.515, 132.6745, 142.834,
+ 152.99349999999998, 163.15300000000002, 173.3125, 183.47199999999998,
+ 193.63150000000002, 203.791, 213.95049999999998, 224.11
+ ]
+ ]
+ },
+ "amount_max_2h": {
+ "count": 11,
+ "mean": 29.96273243391514,
+ "std": 13.260285022445734,
+ "min": 12.19,
+ "max": 42.738011354613306,
+ "hist": [
+ [1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5],
+ [
+ 12.19, 13.717400567730666, 15.24480113546133, 16.772201703191996,
+ 18.299602270922662, 19.82700283865333, 21.354403406383994, 22.881803974114657,
+ 24.409204541845323, 25.93660510957599, 27.464005677306652, 28.991406245037318,
+ 30.518806812767984, 32.04620738049865, 33.573607948229316, 35.10100851595998,
+ 36.62840908369065, 38.155809651421315, 39.68321021915198, 41.21061078688264,
+ 42.738011354613306
+ ]
+ ]
+ },
+ "amount_sum_2h": {
+ "count": 11,
+ "mean": 10.536363636363637,
+ "std": 11.31334457419845,
+ "min": 0,
+ "max": 30.42,
+ "hist": [
+ [5, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1],
+ [
+ 0, 1.5210000000000001, 3.0420000000000003, 4.563000000000001, 6.0840000000000005,
+ 7.605, 9.126000000000001, 10.647, 12.168000000000001, 13.689000000000002, 15.21,
+ 16.731, 18.252000000000002, 19.773000000000003, 21.294, 22.815, 24.336000000000002,
+ 25.857000000000003, 27.378000000000004, 28.899, 30.42
+ ]
+ ]
+ }
+ },
+ "first_request": "2022-05-02 11:14:21.082452+00:00",
+ "last_request": "2022-05-19 09:43:49.502382+00:00",
+ "error_count": null,
+ "avg_latency": null,
+ "drift_status": "DRIFT_DETECTED",
+ "drift_measures": {
+ "amount_max_2h": {
+ "tvd": 0.9006299904768882,
+ "hellinger": 0.8026729143746129,
+ "kld": 8.03097275516625
+ },
+ "tvd_sum": 4.0574683173393895,
+ "tvd_mean": 0.8114936634678779,
+ "hellinger_sum": 3.7935228606235265,
+ "hellinger_mean": 0.7587045721247053,
+ "kld_sum": 40.22159405569385,
+ "kld_mean": 8.04431881113877,
+ "amount_count_2h": {
+ "tvd": 0.9990598979317755,
+ "hellinger": 0.9860541717475733,
+ "kld": 15.975132772583372
+ },
+ "amount_avg_2h": {
+ "tvd": 0.9019729934314947,
+ "hellinger": 0.8046642697553347,
+ "kld": 7.91538219147246
+ },
+ "amount_sum_2h": {
+ "tvd": 0.5447830439772423,
+ "hellinger": 0.5827239245591163,
+ "kld": 4.424521130663923
+ },
+ "amount_max_12h": {
+ "tvd": 0.7110223915219885,
+ "hellinger": 0.6174075801868897,
+ "kld": 3.8755852058078455
+ }
+ },
+ "sampling_percentage": null
+ }
}
]
}
diff --git a/tests/mockServer/mock.js b/tests/mockServer/mock.js
index 86cc3b1957..26f4b6b567 100644
--- a/tests/mockServer/mock.js
+++ b/tests/mockServer/mock.js
@@ -865,7 +865,7 @@ function getMonitoringApplicationsSummary(req, res) {
function getMonitoringApplicationData(req, res) {
const monitoringApplication = (monitoringApplications[req.params['project']] || []).find(
application => {
- return application.name.toLowerCase() === req.params['func']
+ return application.name.toLowerCase() === req.params['func'].toLowerCase()
}
)
From bc75379291e8a68e452260862969a61912f71478 Mon Sep 17 00:00:00 2001
From: Taras-Hlukhovetskyi
<155433425+Taras-Hlukhovetskyi@users.noreply.github.com>
Date: Tue, 2 Sep 2025 17:05:04 +0300
Subject: [PATCH 134/228] Fix [Batch run] small issues in the Data inputs
"Path" field (#3413)
---
package.json | 2 +-
src/common/TargetPath/TargetPath.jsx | 15 +++++-
src/common/TargetPath/targetPath.util.js | 52 +++++++++++++++----
.../FormDataInputsRow/FormDataInputsRow.jsx | 2 +
4 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/package.json b/package.json
index e418388322..4152bb6720 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
"final-form-arrays": "^3.1.0",
"fs-extra": "^10.0.0",
"identity-obj-proxy": "^3.0.0",
- "iguazio.dashboard-react-controls": "3.1.8",
+ "iguazio.dashboard-react-controls": "3.1.9",
"is-wsl": "^1.1.0",
"js-base64": "^2.6.4",
"js-yaml": "^4.1.0",
diff --git a/src/common/TargetPath/TargetPath.jsx b/src/common/TargetPath/TargetPath.jsx
index 18c753d454..84971086c1 100644
--- a/src/common/TargetPath/TargetPath.jsx
+++ b/src/common/TargetPath/TargetPath.jsx
@@ -36,6 +36,7 @@ import {
handleStoreInputPathChange,
isPathInputInvalid,
pathPlaceholders,
+ prepareTargetPathInitialState,
targetPathInitialState
} from './targetPath.util'
import { MLRUN_STORAGE_INPUT_PATH_SCHEME } from '../../constants'
@@ -44,7 +45,9 @@ const TargetPath = ({
density = 'normal',
formState,
formStateFieldInfo,
+ formStateDataInputState = '',
hiddenSelectOptionsIds = [],
+ inputDefaultState = null,
inputDefaultValue = '',
label = '',
name,
@@ -54,7 +57,9 @@ const TargetPath = ({
selectPlaceholder = '',
setFieldState
}) => {
- const [dataInputState, setDataInputState] = useState(targetPathInitialState)
+ const [dataInputState, setDataInputState] = useState(
+ prepareTargetPathInitialState(inputDefaultState, inputDefaultValue, selectDefaultValue)
+ )
const dispatch = useDispatch()
const handleOnChange = (selectValue, inputValue) => {
@@ -215,9 +220,13 @@ const TargetPath = ({
if (value.length !== 0) {
formState.form.change(`${formStateFieldInfo}.value`, value.replace(/[^:/]*:[/]{2,3}/, ''))
formState.form.change(`${formStateFieldInfo}.pathType`, value.match(/^\w*:[/]{2,3}/)[0])
+
+ if (formStateDataInputState) {
+ formState.form.change(`${formStateDataInputState}`, dataInputState)
+ }
}
},
- [formState.form, formStateFieldInfo]
+ [dataInputState, formState.form, formStateDataInputState, formStateFieldInfo]
)
return (
@@ -270,7 +279,9 @@ TargetPath.propTypes = {
density: PropTypes.oneOf(['dense', 'normal', 'medium', 'chunky']),
formState: PropTypes.object.isRequired,
formStateFieldInfo: PropTypes.string.isRequired,
+ formStateDataInputState: PropTypes.string,
hiddenSelectOptionsIds: PropTypes.arrayOf(PropTypes.string),
+ inputDefaultState: PropTypes.object,
inputDefaultValue: PropTypes.string,
label: PropTypes.string,
name: PropTypes.string.isRequired,
diff --git a/src/common/TargetPath/targetPath.util.js b/src/common/TargetPath/targetPath.util.js
index 86ea3c0e86..7ef8437766 100644
--- a/src/common/TargetPath/targetPath.util.js
+++ b/src/common/TargetPath/targetPath.util.js
@@ -17,7 +17,7 @@ illegal under applicable law, and the grant of the foregoing license
under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/
-import { get, isNil, uniqBy } from 'lodash'
+import { debounce, get, isNil, uniqBy } from 'lodash'
import {
ARTIFACT_OTHER_TYPE,
@@ -39,6 +39,7 @@ import { fetchArtifact, fetchArtifacts } from '../../reducers/artifactsReducer'
import { fetchFeatureVector, fetchFeatureVectors } from '../../reducers/featureStoreReducer'
import { fetchProjectsNames } from '../../reducers/projectReducer'
import { isCommunityEdition } from '../../utils/helper'
+import { parseUri } from '../../utils/parseUri'
const targetPathRegex =
/^(store|v3io|s3|az|gs):(\/\/\/|\/\/)(?!.*:\/\/)([\w\-._~:?#[\]@!$&'()*+,;=]+)\/([\w\-._~:/?#[\]%@!$&'()*+,;=]+)$/i
@@ -332,7 +333,7 @@ export const generateArtifactsReferencesList = artifacts => {
return uniqBy(generatedArtifacts, 'id')
}
-export const getProjectsNames = (dispatch, setDataInputState, projectName) => {
+export const getProjectsNames = debounce((dispatch, setDataInputState, projectName) => {
dispatch(fetchProjectsNames())
.unwrap()
.then(result => {
@@ -342,9 +343,9 @@ export const getProjectsNames = (dispatch, setDataInputState, projectName) => {
}))
})
.catch(() => {})
-}
+}, 300)
-export const getArtifacts = (dispatch, project, storePathType, setDataInputState) => {
+export const getArtifacts = debounce((dispatch, project, storePathType, setDataInputState) => {
dispatch(
fetchArtifacts({
project,
@@ -373,9 +374,9 @@ export const getArtifacts = (dispatch, project, storePathType, setDataInputState
.catch(error => {
showErrorNotification(dispatch, error, '', 'Failed to fetch artifacts')
})
-}
+}, 300)
-export const getFeatureVectors = (dispatch, project, setDataInputState) => {
+export const getFeatureVectors = debounce((dispatch, project, setDataInputState) => {
dispatch(fetchFeatureVectors({ project, filters: {}, config: {} }))
.unwrap()
.then(featureVectors => {
@@ -393,9 +394,9 @@ export const getFeatureVectors = (dispatch, project, setDataInputState) => {
featureVectors: featureVectorsList
}))
})
-}
+}, 300)
-export const getArtifact = (dispatch, project, projectItem, setDataInputState) => {
+export const getArtifact = debounce((dispatch, project, projectItem, setDataInputState) => {
dispatch(fetchArtifact({ project, artifact: projectItem }))
.unwrap()
.then(artifacts => {
@@ -409,9 +410,9 @@ export const getArtifact = (dispatch, project, projectItem, setDataInputState) =
.catch(error => {
showErrorNotification(dispatch, error, '', 'Failed to fetch artifact data')
})
-}
+}, 300)
-export const getFeatureVector = (dispatch, project, projectItem, setDataInputState) => {
+export const getFeatureVector = debounce((dispatch, project, projectItem, setDataInputState) => {
dispatch(fetchFeatureVector({ project, featureVector: projectItem }))
.unwrap()
.then(featureVectors => {
@@ -436,4 +437,35 @@ export const getFeatureVector = (dispatch, project, projectItem, setDataInputSta
.catch(error => {
showErrorNotification(dispatch, error, '', 'Failed to fetch feature vector data')
})
+}, 300)
+
+export const prepareTargetPathInitialState = (
+ inputDefaultState,
+ inputDefaultValue = '',
+ selectDefaultValue = ''
+) => {
+ if (inputDefaultState) {
+ return inputDefaultState
+ }
+
+ if (inputDefaultValue && selectDefaultValue.startsWith('store')) {
+ const state = { ...targetPathInitialState }
+ const { key, project, kind } = parseUri(selectDefaultValue + inputDefaultValue)
+ const projectItemReference = inputDefaultValue.split(`${kind}/${project}/${key}`)?.[1] || ''
+ state.storePathType = kind
+ state.project = project
+ state.projectItem = key
+ state.inputProjectItemPathEntered = true
+ state.inputProjectPathEntered = true
+ state.inputStorePathTypeEntered = true
+
+ if (projectItemReference) {
+ state.projectItemReference = projectItemReference
+ state.inputProjectItemReferencePathEntered = true
+ }
+
+ return state
+ }
+
+ return targetPathInitialState
}
diff --git a/src/elements/FormDataInputsTable/FormDataInputsRow/FormDataInputsRow.jsx b/src/elements/FormDataInputsTable/FormDataInputsRow/FormDataInputsRow.jsx
index 9f154929eb..fc6dba1831 100644
--- a/src/elements/FormDataInputsTable/FormDataInputsRow/FormDataInputsRow.jsx
+++ b/src/elements/FormDataInputsTable/FormDataInputsRow/FormDataInputsRow.jsx
@@ -106,6 +106,7 @@ const FormDataInputsRow = ({
density="normal"
formState={formState}
formStateFieldInfo={`${rowPath}.data.fieldInfo`}
+ formStateDataInputState={`${rowPath}.data.dataInputState`}
hiddenSelectOptionsIds={
fieldData.data.name === MODEL_PATH_DATA_INPUT && fieldData.isPredefined
? [
@@ -120,6 +121,7 @@ const FormDataInputsRow = ({
: []
}
inputDefaultValue={editingItem.data.fieldInfo?.value}
+ inputDefaultState={editingItem.data.dataInputState}
name={`${rowPath}.data.path`}
params={params}
required
From 7e3dfc76e8e85ebf4bba3555fd7ebdeffcf2bda6 Mon Sep 17 00:00:00 2001
From: Andrew Mavdryk
Date: Tue, 2 Sep 2025 17:06:43 +0300
Subject: [PATCH 135/228] Fix [ESLint] Add `import/named` rule, fix eslint
warnings (#3414)
---
eslint.config.mjs | 5 ++++-
package.json | 1 +
src/common/MlChart/MlChart.jsx | 2 +-
.../RegisterArtifactModal/RegisterArtifactModal.jsx | 2 --
src/elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp.jsx | 5 +++--
src/elements/RegisterModelModal/RegisterModelModal.jsx | 2 --
6 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 5fbdd6a2a6..6ec622e15d 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -3,6 +3,7 @@ import globals from 'globals'
import js from '@eslint/js'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
+import eslintPluginImport from 'eslint-plugin-import'
export default [
{ ignores: ['dist'] },
@@ -21,7 +22,8 @@ export default [
},
plugins: {
react: react,
- 'react-hooks': reactHooks
+ 'react-hooks': reactHooks,
+ import: eslintPluginImport
},
settings: {
react: {
@@ -34,6 +36,7 @@ export default [
'react/react-in-jsx-scope': 'off',
'react/no-unescaped-entities': 'off',
'import/no-anonymous-default-export': 'off',
+ 'import/named': process.env.NODE_ENV === 'production' ? 2 : 1,
'no-unused-vars': process.env.NODE_ENV === 'production' ? 2 : 1,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 1,
'no-console': process.env.NODE_ENV === 'production' ? 2 : 1,
diff --git a/package.json b/package.json
index 4152bb6720..2379ee692f 100644
--- a/package.json
+++ b/package.json
@@ -113,6 +113,7 @@
"eslint": "^9.13.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-babel": "^5.3.1",
+ "eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.1.0",
diff --git a/src/common/MlChart/MlChart.jsx b/src/common/MlChart/MlChart.jsx
index 7300795a9c..58b45b6fb8 100644
--- a/src/common/MlChart/MlChart.jsx
+++ b/src/common/MlChart/MlChart.jsx
@@ -19,7 +19,7 @@ such restriction.
*/
import React, { useState, useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
-import { Chart } from 'chart.js/auto'
+import { Chart } from 'chart.js'
import classnames from 'classnames'
import { Loader } from 'igz-controls/components'
diff --git a/src/components/RegisterArtifactModal/RegisterArtifactModal.jsx b/src/components/RegisterArtifactModal/RegisterArtifactModal.jsx
index e25ca9aba3..da496174e5 100644
--- a/src/components/RegisterArtifactModal/RegisterArtifactModal.jsx
+++ b/src/components/RegisterArtifactModal/RegisterArtifactModal.jsx
@@ -41,8 +41,6 @@ import { convertChipsData } from '../../utils/convertChipsData'
import { createArtifactMessages } from '../../utils/createArtifact.util'
import { setFieldState, isSubmitDisabled } from 'igz-controls/utils/form.util'
import { setNotification } from 'igz-controls/reducers/notificationReducer'
-import { showErrorNotification } from 'igz-controls/utils/notification.util'
-import { openPopUp } from 'igz-controls/utils/common.util'
import { useModalBlockHistory } from '../../hooks/useModalBlockHistory.hook'
import { processActionAfterTagUniquesValidation } from '../../utils/artifacts.util'
diff --git a/src/elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp.jsx b/src/elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp.jsx
index 27fe954e32..4bbb0a7933 100644
--- a/src/elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp.jsx
+++ b/src/elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp.jsx
@@ -166,14 +166,15 @@ const ArtifactPopUp = ({ artifactData, isOpen, onResolve }) => {
onResolve()
})
}, [
- artifactData,
artifactContext,
dispatch,
onResolve,
+ artifactData.key,
artifactData.iteration,
artifactData.tree,
artifactData.uid,
- artifactData.tag
+ artifactData.tag,
+ artifactData.project
])
const actionsMenu = useMemo(
diff --git a/src/elements/RegisterModelModal/RegisterModelModal.jsx b/src/elements/RegisterModelModal/RegisterModelModal.jsx
index 917e35cb09..82ab960268 100644
--- a/src/elements/RegisterModelModal/RegisterModelModal.jsx
+++ b/src/elements/RegisterModelModal/RegisterModelModal.jsx
@@ -42,8 +42,6 @@ import { getChipOptions } from 'igz-controls/utils/chips.util'
import { getValidationRules } from 'igz-controls/utils/validation.util'
import { setFieldState, isSubmitDisabled } from 'igz-controls/utils/form.util'
import { setNotification } from 'igz-controls/reducers/notificationReducer'
-import { showErrorNotification } from 'igz-controls/utils/notification.util'
-import { openPopUp } from 'igz-controls/utils/common.util'
import { useModalBlockHistory } from '../../hooks/useModalBlockHistory.hook'
import { processActionAfterTagUniquesValidation } from '../../utils/artifacts.util'
From 95a4c26bcf2dab047f50c79a7a75210eec3c69ad Mon Sep 17 00:00:00 2001
From: Ilank <63646693+ilan7empest@users.noreply.github.com>
Date: Wed, 3 Sep 2025 19:02:11 +0800
Subject: [PATCH 136/228] Fix [Counters] UI crash - TypeError: Cannot read
properties of undefined (reading 'endpoint_alerts_count') (#3409)
---
src/components/ProjectsPage/projects.util.jsx | 47 +++++++++----------
src/elements/ProjectCard/projectCard.util.js | 4 +-
src/elements/ProjectJobs/projectJobs.utils.js | 10 ++--
.../AlertsCounters.jsx | 16 +++----
4 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/src/components/ProjectsPage/projects.util.jsx b/src/components/ProjectsPage/projects.util.jsx
index a25d7a4c24..939ce3fa1d 100644
--- a/src/components/ProjectsPage/projects.util.jsx
+++ b/src/components/ProjectsPage/projects.util.jsx
@@ -222,9 +222,8 @@ export const pollDeletingProjects = (terminatePollRef, deletingProjects, refresh
setNotification({
status: 200,
id: Math.random(),
- message: `Project "${
- deletingProjects?.[task.metadata.name]
- }" was deleted successfully`
+ message: `Project "${deletingProjects?.[task.metadata.name]
+ }" was deleted successfully`
})
)
} else {
@@ -260,9 +259,9 @@ export const generateAlerts = (data, dispatch) => {
data.forEach(project => {
const projectName = project.name
projectAlerts[projectName] =
- (project.endpoint_alerts_count || 0) +
- (project.job_alerts_count || 0) +
- (project.other_alerts_count || 0)
+ (project?.endpoint_alerts_count || 0) +
+ (project?.job_alerts_count || 0) +
+ (project?.other_alerts_count || 0)
})
dispatch(setProjectTotalAlerts(projectAlerts))
@@ -311,47 +310,47 @@ export const generateMonitoringCounters = (data, dispatch) => {
}
data.forEach(project => {
- monitoringCounters.jobs.completed += project.runs_completed_recent_count || 0
- monitoringCounters.jobs.failed += project.runs_failed_recent_count || 0
- monitoringCounters.jobs.running += project.runs_running_count || 0
+ monitoringCounters.jobs.completed += project?.runs_completed_recent_count || 0
+ monitoringCounters.jobs.failed += project?.runs_failed_recent_count || 0
+ monitoringCounters.jobs.running += project?.runs_running_count || 0
monitoringCounters.jobs.total =
monitoringCounters.jobs.completed +
monitoringCounters.jobs.failed +
monitoringCounters.jobs.running
- monitoringCounters.workflows.completed += project.pipelines_completed_recent_count || 0
- monitoringCounters.workflows.failed += project.pipelines_failed_recent_count || 0
- monitoringCounters.workflows.running += project.pipelines_running_count || 0
+ monitoringCounters.workflows.completed += project?.pipelines_completed_recent_count || 0
+ monitoringCounters.workflows.failed += project?.pipelines_failed_recent_count || 0
+ monitoringCounters.workflows.running += project?.pipelines_running_count || 0
monitoringCounters.workflows.total =
monitoringCounters.workflows.completed +
monitoringCounters.workflows.failed +
monitoringCounters.workflows.running
- monitoringCounters.scheduled.jobs += project.distinct_scheduled_jobs_pending_count || 0
+ monitoringCounters.scheduled.jobs += project?.distinct_scheduled_jobs_pending_count || 0
monitoringCounters.scheduled.workflows +=
- project.distinct_scheduled_pipelines_pending_count || 0
+ project?.distinct_scheduled_pipelines_pending_count || 0
monitoringCounters.scheduled.total =
monitoringCounters.scheduled.jobs + monitoringCounters.scheduled.workflows
- monitoringCounters.alerts.endpoint += project.endpoint_alerts_count || 0
- monitoringCounters.alerts.jobs += project.job_alerts_count || 0
- monitoringCounters.alerts.application += project.other_alerts_count || 0
+ monitoringCounters.alerts.endpoint += project?.endpoint_alerts_count || 0
+ monitoringCounters.alerts.jobs += project?.job_alerts_count || 0
+ monitoringCounters.alerts.application += project?.other_alerts_count || 0
monitoringCounters.alerts.total =
monitoringCounters.alerts.endpoint +
monitoringCounters.alerts.jobs +
monitoringCounters.alerts.application
- monitoringCounters.models.total += project.models_count || 0
+ monitoringCounters.models.total += project?.models_count || 0
- monitoringCounters.monitoring_app.running += project.running_model_monitoring_functions || 0
- monitoringCounters.monitoring_app.failed += project.failed_model_monitoring_functions || 0
+ monitoringCounters.monitoring_app.running += project?.running_model_monitoring_functions || 0
+ monitoringCounters.monitoring_app.failed += project?.failed_model_monitoring_functions || 0
monitoringCounters.monitoring_app.total =
monitoringCounters.monitoring_app.failed + monitoringCounters.monitoring_app.running
- monitoringCounters.artifacts.llm_prompts += project.llm_prompts_count || 0
- monitoringCounters.artifacts.datasets += project.datasets_count || 0
- monitoringCounters.artifacts.files += project.files_count || 0
- monitoringCounters.artifacts.documents += project.documents_count || 0
+ monitoringCounters.artifacts.llm_prompts += project?.llm_prompts_count || 0
+ monitoringCounters.artifacts.datasets += project?.datasets_count || 0
+ monitoringCounters.artifacts.files += project?.files_count || 0
+ monitoringCounters.artifacts.documents += project?.documents_count || 0
monitoringCounters.artifacts.total =
monitoringCounters.artifacts.llm_prompts +
monitoringCounters.artifacts.datasets +
diff --git a/src/elements/ProjectCard/projectCard.util.js b/src/elements/ProjectCard/projectCard.util.js
index 41dd4c2677..f23a61cce2 100644
--- a/src/elements/ProjectCard/projectCard.util.js
+++ b/src/elements/ProjectCard/projectCard.util.js
@@ -45,7 +45,7 @@ export const generateProjectStatistic = (
className:
!fetchProjectsSummaryFailure &&
!fetchNuclioFunctionsFailure &&
- projectSummary.runs_running_count + runningNuclioFunctions > 0
+ projectSummary?.runs_running_count + runningNuclioFunctions > 0
? 'running'
: 'default',
counterTooltip: 'ML jobs and Nuclio functions',
@@ -56,7 +56,7 @@ export const generateProjectStatistic = (
? 'N/A'
: isEmpty(projectSummary)
? '-'
- : projectSummary.runs_running_count + runningNuclioFunctions
+ : projectSummary?.runs_running_count + runningNuclioFunctions
},
failedJobs: {
className:
diff --git a/src/elements/ProjectJobs/projectJobs.utils.js b/src/elements/ProjectJobs/projectJobs.utils.js
index 69f8f1a7bc..40ab03691d 100644
--- a/src/elements/ProjectJobs/projectJobs.utils.js
+++ b/src/elements/ProjectJobs/projectJobs.utils.js
@@ -27,10 +27,10 @@ import { typesOfJob } from '../../utils/jobs.util'
export const getJobsStatistics = (projectCounter, projectName) => {
return {
running: {
- value: projectCounter.error ? 'N/A' : projectCounter.data.runs_running_count,
+ value: projectCounter.error ? 'N/A' : projectCounter?.data?.runs_running_count,
label: 'In Process',
className:
- projectCounter.error || projectCounter.data.runs_running_count === 0
+ projectCounter.error || projectCounter?.data?.runs_running_count === 0
? 'default'
: 'running',
status: 'running',
@@ -39,10 +39,10 @@ export const getJobsStatistics = (projectCounter, projectName) => {
loading: projectCounter.loading
},
failed: {
- value: projectCounter.error ? 'N/A' : projectCounter.data.runs_failed_recent_count,
+ value: projectCounter.error ? 'N/A' : projectCounter?.data?.runs_failed_recent_count,
label: 'Failed',
className:
- projectCounter.error || projectCounter.data.runs_failed_recent_count === 0
+ projectCounter.error || projectCounter?.data?.runs_failed_recent_count === 0
? 'running'
: 'failed',
status: 'failed',
@@ -51,7 +51,7 @@ export const getJobsStatistics = (projectCounter, projectName) => {
loading: projectCounter.loading
},
succeeded: {
- value: projectCounter.error ? 'N/A' : projectCounter.data.runs_completed_recent_count,
+ value: projectCounter.error ? 'N/A' : projectCounter?.data?.runs_completed_recent_count,
label: 'Succeeded',
status: 'succeeded',
className: 'running',
diff --git a/src/elements/ProjectsMonitoringCounters/AlertsCounters.jsx b/src/elements/ProjectsMonitoringCounters/AlertsCounters.jsx
index e7e2233c1d..11236643e8 100644
--- a/src/elements/ProjectsMonitoringCounters/AlertsCounters.jsx
+++ b/src/elements/ProjectsMonitoringCounters/AlertsCounters.jsx
@@ -60,9 +60,9 @@ const AlertsCounters = () => {
}
if (projectName !== '*') {
- const endpoint = projectStore.projectSummary.data.endpoint_alerts_count || 0
- const jobs = projectStore.projectSummary.data.job_alerts_count || 0
- const application = projectStore.projectSummary.data.other_alerts_count || 0
+ const endpoint = projectStore?.projectSummary?.data?.endpoint_alerts_count || 0
+ const jobs = projectStore?.projectSummary?.data?.job_alerts_count || 0
+ const application = projectStore?.projectSummary?.data?.other_alerts_count || 0
return {
projectName,
@@ -77,14 +77,14 @@ const AlertsCounters = () => {
return {
projectName,
- data: defaults({}, projectStore.jobsMonitoringData.alerts, defaultAlertData)
+ data: defaults({}, projectStore?.jobsMonitoringData?.alerts, defaultAlertData)
}
}, [
paramProjectName,
- projectStore.jobsMonitoringData.alerts,
- projectStore.projectSummary.data.endpoint_alerts_count,
- projectStore.projectSummary.data.job_alerts_count,
- projectStore.projectSummary.data.other_alerts_count
+ projectStore?.jobsMonitoringData?.alerts,
+ projectStore?.projectSummary?.data?.endpoint_alerts_count,
+ projectStore?.projectSummary?.data?.job_alerts_count,
+ projectStore?.projectSummary?.data?.other_alerts_count
])
const alertsStats = useMemo(
From 2e8f578a0fcc8766222a5dfa6f6dad651967366e Mon Sep 17 00:00:00 2001
From: adi-gini
Date: Wed, 3 Sep 2025 14:02:50 +0300
Subject: [PATCH 137/228] Fix [Projects Monitoring] Titles formatting and
filtering defaults (#3415)
---
src/utils/generateMonitoringData.js | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/utils/generateMonitoringData.js b/src/utils/generateMonitoringData.js
index 77e902f270..dd22d972d9 100644
--- a/src/utils/generateMonitoringData.js
+++ b/src/utils/generateMonitoringData.js
@@ -51,8 +51,7 @@ export const generateMonitoringStats = (data, navigate, tab, projectName) => {
const linkClassNameDetails = (projectName, noLine) =>
classNames(!noLine && 'stats__line', projectName && 'stats__link')
- const linkClassNameHeader = projectName =>
- classNames(projectName && 'stats__link')
+ const linkClassNameHeader = projectName => classNames(projectName && 'stats__link')
const navigateToTab = (projectName, tab) => {
projectName && navigate(`/projects/${projectName}/${tab}`)
@@ -224,7 +223,7 @@ export const generateMonitoringStats = (data, navigate, tab, projectName) => {
counter: data.running || 0,
className: classNames(projectName && 'stats__link'),
link: () => navigateToTab(projectName, MONITORING_APP_PAGE),
- statusClass: 'completed',
+ statusClass: 'running',
label: RUNNING,
popUpClassName: classNames({ 'card-popup_text_link': projectName })
},
From 5bbd347adf5bb5524d128aaa60b3f9f123378ee7 Mon Sep 17 00:00:00 2001
From: Andrew Mavdryk
Date: Wed, 3 Sep 2025 15:44:24 +0300
Subject: [PATCH 138/228] Fix [Model Endpoints] Page crash on `Features
analysis` and `Metrics` tabs (#3416)
---
src/common/MlChart/MlChart.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/common/MlChart/MlChart.jsx b/src/common/MlChart/MlChart.jsx
index 58b45b6fb8..ddae2ab2be 100644
--- a/src/common/MlChart/MlChart.jsx
+++ b/src/common/MlChart/MlChart.jsx
@@ -19,7 +19,7 @@ such restriction.
*/
import React, { useState, useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
-import { Chart } from 'chart.js'
+import Chart from 'chart.js/auto'
import classnames from 'classnames'
import { Loader } from 'igz-controls/components'
From e76d3c569acb4fa178772b1e296ecddb14726c6f Mon Sep 17 00:00:00 2001
From: Taras-Hlukhovetskyi
<155433425+Taras-Hlukhovetskyi@users.noreply.github.com>
Date: Thu, 4 Sep 2025 15:06:30 +0300
Subject: [PATCH 139/228] Fix [Artifacts] Clicking on the current artifacts
screen does not trigger a request (#3417)
---
src/App.jsx | 20 ++++++---
src/elements/NavbarLink/NavbarLink.jsx | 1 +
...apComponentForNavbarNavigationTracking.jsx | 41 +++++++++++++++++++
3 files changed, 56 insertions(+), 6 deletions(-)
create mode 100644 src/utils/wrapComponentForNavbarNavigationTracking.jsx
diff --git a/src/App.jsx b/src/App.jsx
index 25858deefa..84ead1754b 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -41,6 +41,7 @@ import localStorageService from './utils/localStorageService'
import { lazyRetry } from './lazyWithRetry'
import { useMode } from './hooks/mode.hook'
import { useNuclioMode } from './hooks/nuclioMode.hook'
+import wrapComponentForNavbarNavigationTracking from './utils/wrapComponentForNavbarNavigationTracking'
import {
ALERTS_PAGE_PATH,
@@ -148,6 +149,13 @@ const App = () => {
const isHeaderShown = localStorageService.getStorageValue('mlrunUi.headerHidden') !== 'true'
const mlAppContainerClasses = classNames('ml-app-container', isHeaderShown && 'has-header')
+ const FilesComponent = wrapComponentForNavbarNavigationTracking(Files)
+ const DatasetsComponent = wrapComponentForNavbarNavigationTracking(Datasets)
+ const DocumentsComponent = wrapComponentForNavbarNavigationTracking(Documents)
+ const LLMPromptsComponent = wrapComponentForNavbarNavigationTracking(LLMPrompts)
+ const FunctionsOldComponent = wrapComponentForNavbarNavigationTracking(FunctionsOld)
+ const FunctionsComponent = wrapComponentForNavbarNavigationTracking(Functions)
+
const router = createBrowserRouter(
createRoutesFromElements(
<>
@@ -255,7 +263,7 @@ const App = () => {
}
+ element={}
/>
))
@@ -265,7 +273,7 @@ const App = () => {
'projects/:projectName/functions/:funcName/:tag/:tab'
].map((path, index) => (
- } />
+ } />
))}
{[
@@ -275,7 +283,7 @@ const App = () => {
`projects/:projectName/datasets/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab`
].map((path, index) => (
- } />
+ } />
))}
{
`projects/:projectName/files/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab`
].map((path, index) => (
- } />
+ } />
))}
{[
@@ -366,7 +374,7 @@ const App = () => {
`projects/:projectName/documents/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab`
].map((path, index) => (
- } />
+ } />
))}
{[
@@ -376,7 +384,7 @@ const App = () => {
`projects/:projectName/llm-prompts/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab`
].map((path, index) => (
- } />
+ } />
))}
} />
diff --git a/src/elements/NavbarLink/NavbarLink.jsx b/src/elements/NavbarLink/NavbarLink.jsx
index 8a96a0b814..554a17d697 100644
--- a/src/elements/NavbarLink/NavbarLink.jsx
+++ b/src/elements/NavbarLink/NavbarLink.jsx
@@ -37,6 +37,7 @@ const NavbarLink = ({ externalLink = false, icon = {}, label = '', link = '', ..
{...props}
className="nav-link__button btn btn-secondary"
activeclassname="active"
+ state={{navbarNavigate: true}}
>
{icon}
{label}
diff --git a/src/utils/wrapComponentForNavbarNavigationTracking.jsx b/src/utils/wrapComponentForNavbarNavigationTracking.jsx
new file mode 100644
index 0000000000..26cd2e304f
--- /dev/null
+++ b/src/utils/wrapComponentForNavbarNavigationTracking.jsx
@@ -0,0 +1,41 @@
+/*
+Copyright 2019 Iguazio Systems Ltd.
+
+Licensed under the Apache License, Version 2.0 (the "License") with
+an addition restriction as set forth herein. You may not use this
+file except in compliance with the License. You may obtain a copy of
+the License at http://www.apache.org/licenses/LICENSE-2.0.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied. See the License for the specific language governing
+permissions and limitations under the License.
+
+In addition, you may not use the software for any purposes that are
+illegal under applicable law, and the grant of the foregoing license
+under the Apache 2.0 license is conditioned upon your compliance with
+such restriction.
+*/
+import { useMemo, useRef } from 'react'
+import { useLocation } from 'react-router-dom'
+
+const wrapComponentForNavbarNavigationTracking = WrappedComponent => {
+ const Wrap = props => {
+ const location = useLocation()
+ const savedKeyRef = useRef(0)
+ const key = useMemo(() => {
+ if (location.state?.navbarNavigate) {
+ return ++savedKeyRef.current
+ }
+
+ return savedKeyRef.current
+ }, [location.state?.navbarNavigate])
+
+ return
+ }
+
+ return Wrap
+}
+
+export default wrapComponentForNavbarNavigationTracking
\ No newline at end of file
From a9a2f048e7defde856d9594288caab79cac18847 Mon Sep 17 00:00:00 2001
From: Andrew Mavdryk
Date: Sat, 6 Sep 2025 05:04:42 +0300
Subject: [PATCH 140/228] Fix [Download] Issues with the download container
(#3418)
---
src/common/Download/DownloadContainer.jsx | 4 ++--
src/common/Download/downloadContainer.scss | 8 ++++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/common/Download/DownloadContainer.jsx b/src/common/Download/DownloadContainer.jsx
index 171db576a8..61cbb5594c 100644
--- a/src/common/Download/DownloadContainer.jsx
+++ b/src/common/Download/DownloadContainer.jsx
@@ -74,8 +74,8 @@ const DownloadContainer = () => {
- {downloadStore.downloadList.map((downloadItem, index) => {
- return
+ {downloadStore.downloadList.map((downloadItem) => {
+ return
})}
diff --git a/src/common/Download/downloadContainer.scss b/src/common/Download/downloadContainer.scss
index 365f2af2c9..6c4fbb1b2a 100644
--- a/src/common/Download/downloadContainer.scss
+++ b/src/common/Download/downloadContainer.scss
@@ -3,7 +3,7 @@
.download-container {
position: relative;
- z-index: 10;
+ z-index: 9;
align-self: flex-end;
opacity: 0;
width: 220px;
@@ -48,8 +48,12 @@
}
}
+ &__status {
+ margin-left: auto;
+ }
+
&__buttons {
- min-width: 20px;
+ min-width: 10px;
.round-icon-cp__circle {
width: 20px;
From 3f353ca37a38986e9402ba9a7bc692d262bc2080 Mon Sep 17 00:00:00 2001
From: illia-prokopchuk <78905712+illia-prokopchuk@users.noreply.github.com>
Date: Mon, 8 Sep 2025 15:33:33 +0300
Subject: [PATCH 141/228] Fix [Monitoring app] Wrong redirection to function
details from System functions section (#3420)
---
.../MonitoringApplications/monitoringApplications.util.js | 4 +++-
src/elements/ApplicationTableRow/ApplicationTableRow.jsx | 2 ++
src/elements/ApplicationTableRow/applicationTableRow.scss | 5 +++++
src/utils/createApplicationContent.jsx | 1 +
4 files changed, 11 insertions(+), 1 deletion(-)
create mode 100644 src/elements/ApplicationTableRow/applicationTableRow.scss
diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js b/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js
index 68c25e7756..298b7e6eba 100644
--- a/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js
+++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js
@@ -48,10 +48,12 @@ export const generateOperatingFunctionsTable = (functions, projectName) => {
]
const tableBody = functions.map(func => {
+ const nuclioFunctionName = `${projectName}-${func.name.toLowerCase()}`.slice(0, 63)
+
return {
name: {
value: capitalize(func.name),
- link: generateNuclioLink(`/projects/${projectName}/functions/${func.name}`),
+ href: generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`),
className: 'table-cell_big'
},
status: {
diff --git a/src/elements/ApplicationTableRow/ApplicationTableRow.jsx b/src/elements/ApplicationTableRow/ApplicationTableRow.jsx
index 717ad74d9a..e1c362032e 100644
--- a/src/elements/ApplicationTableRow/ApplicationTableRow.jsx
+++ b/src/elements/ApplicationTableRow/ApplicationTableRow.jsx
@@ -25,6 +25,8 @@ import { TableCell, ActionsMenu } from 'igz-controls/components'
import { ACTIONS_MENU } from 'igz-controls/types'
+import './applicationTableRow.scss'
+
const ApplicationTableRow = ({ actionsMenu, hideActionsMenu = false, rowItem }) => {
const rowClassNames = classnames('table-row', 'table-body-row', 'parent-row')
diff --git a/src/elements/ApplicationTableRow/applicationTableRow.scss b/src/elements/ApplicationTableRow/applicationTableRow.scss
new file mode 100644
index 0000000000..a453fe793f
--- /dev/null
+++ b/src/elements/ApplicationTableRow/applicationTableRow.scss
@@ -0,0 +1,5 @@
+ .table-body__cell {
+ a {
+ display: flex;
+ }
+ }
diff --git a/src/utils/createApplicationContent.jsx b/src/utils/createApplicationContent.jsx
index 26cfe6c7e6..402ee2584a 100644
--- a/src/utils/createApplicationContent.jsx
+++ b/src/utils/createApplicationContent.jsx
@@ -100,6 +100,7 @@ export const createApplicationContent = (application, projectName) => {
className: 'table-cell-2',
getLink: () =>
generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`),
+ linkIsExternal: true,
showStatus: true
}
]
From 7fd6264351d96a9eeb80d42ff4b458625d1dcab3 Mon Sep 17 00:00:00 2001
From: Ilank <63646693+ilan7empest@users.noreply.github.com>
Date: Mon, 8 Sep 2025 15:34:05 +0300
Subject: [PATCH 142/228] Fix [Counters] Add info icon to cross-project and
project-screen (#3419)
---
src/elements/PageHeader/pageHeader.scss | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/elements/PageHeader/pageHeader.scss b/src/elements/PageHeader/pageHeader.scss
index 9a44603745..c83d2604f1 100644
--- a/src/elements/PageHeader/pageHeader.scss
+++ b/src/elements/PageHeader/pageHeader.scss
@@ -26,11 +26,11 @@
.tooltip-wrapper {
display: flex;
align-items: center;
- margin-left: 10px;
+ margin-left: 5px;
svg {
- width: 20px;
- height: 20px;
+ width: 16px;
+ height: 16px;
path {
fill: variables.$secondaryTextColor;
From 59a3f66c15aaecaa69d33a605e18d636936e1880 Mon Sep 17 00:00:00 2001
From: illia-prokopchuk <78905712+illia-prokopchuk@users.noreply.github.com>
Date: Tue, 9 Sep 2025 09:40:42 +0300
Subject: [PATCH 143/228] Fix [Monitoring Applications] Applications KPI
includes infra funcs (#3422)
---
.../monitoringApplicationCounters.util.jsx | 21 ++++++++-----------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx
index 332d2f62af..77a1572441 100644
--- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx
+++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx
@@ -37,10 +37,7 @@ export const generateCountersContent = (params, monitoringApplicationsStore) =>
counterData: [
{
id: 'applications',
- title: monitoringApplicationError
- ? null
- : monitoringApplications.operatingFunctions.length +
- monitoringApplications.applications.length
+ title: monitoringApplicationError ? null : monitoringApplications.applications.length
}
]
},
@@ -151,13 +148,13 @@ export const generateCountersContent = (params, monitoringApplicationsStore) =>
return params.name
? {
- content: applicationCountersContent,
- loading: monitoringApplicationIsLoading,
- error: monitoringApplicationError
- }
+ content: applicationCountersContent,
+ loading: monitoringApplicationIsLoading,
+ error: monitoringApplicationError
+ }
: {
- content: applicationsCountersContent,
- loading: applicationsSummary.loading,
- error: applicationsSummary.error
- }
+ content: applicationsCountersContent,
+ loading: applicationsSummary.loading,
+ error: applicationsSummary.error
+ }
}
From f6c2839b788b62e6c2e56b8e889f77d24c0b00c4 Mon Sep 17 00:00:00 2001
From: illia-prokopchuk <78905712+illia-prokopchuk@users.noreply.github.com>
Date: Tue, 9 Sep 2025 12:28:07 +0300
Subject: [PATCH 144/228] Impl [Monitoring app] In application UI add useful
links (#3423)
---
src/api/modelEndpoints-api.js | 9 +++++++++
.../FilterMenu/filterMenu.settings.js | 19 ++++++++++++++++++-
.../ModelEndpoints/ModelEndpointsFilters.jsx | 8 ++++++--
.../ModelEndpoints/modelEndpoints.util.jsx | 9 ++++++++-
.../MonitoringApplicationCard.jsx | 3 +++
.../monitoringApplicationCounters.scss | 7 +++++++
.../monitoringApplicationCounters.util.jsx | 12 ++++++++++--
src/constants.js | 3 +++
.../ApplicationTableRow.jsx | 2 +-
.../applicationTableRow.scss | 2 ++
10 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/src/api/modelEndpoints-api.js b/src/api/modelEndpoints-api.js
index eac2ab097c..d28f4c92e6 100644
--- a/src/api/modelEndpoints-api.js
+++ b/src/api/modelEndpoints-api.js
@@ -18,6 +18,7 @@ under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/
import { mainHttpClient } from '../httpClient'
+import { BATCH_FILTER, FILTER_ALL_ITEMS, ME_MODE_FILTER, REAL_TIME_FILTER } from '../constants'
const modelEndpointsApi = {
getModelEndpoint: (project, name, uid) =>
@@ -25,6 +26,10 @@ const modelEndpointsApi = {
`/projects/${project}/model-endpoints/${name}?endpoint_id=${uid}&feature_analysis=true`
),
getModelEndpoints: (project, filters, config = {}, params = {}) => {
+ const modesMap = {
+ [REAL_TIME_FILTER]: 0,
+ [BATCH_FILTER]: 1
+ }
const newConfig = {
...config,
params
@@ -34,6 +39,10 @@ const modelEndpointsApi = {
newConfig.params.label = filters.labels?.split(',')
}
+ if (filters[ME_MODE_FILTER] && filters[ME_MODE_FILTER] !== FILTER_ALL_ITEMS) {
+ newConfig.params.mode = modesMap[filters[ME_MODE_FILTER]]
+ }
+
return mainHttpClient.get(`/projects/${project}/model-endpoints`, newConfig)
},
getModelEndpointMetrics: (project, uid, type = 'all') =>
diff --git a/src/components/FilterMenu/filterMenu.settings.js b/src/components/FilterMenu/filterMenu.settings.js
index 977a474d26..406fe98cf3 100644
--- a/src/components/FilterMenu/filterMenu.settings.js
+++ b/src/components/FilterMenu/filterMenu.settings.js
@@ -42,7 +42,9 @@ import {
SORT_BY,
STATUS_FILTER,
TAG_FILTER_ALL_ITEMS,
- TAG_FILTER_LATEST
+ TAG_FILTER_LATEST,
+ REAL_TIME_FILTER,
+ BATCH_FILTER
} from '../../constants'
export const jobsStatuses = [
@@ -107,6 +109,21 @@ export const generateTypeFilter = tab => {
]
}
+export const modelEndpointsModesList = [
+ {
+ id: FILTER_ALL_ITEMS,
+ label: 'All'
+ },
+ {
+ id: REAL_TIME_FILTER,
+ label: 'Real-time'
+ },
+ {
+ id: BATCH_FILTER,
+ label: 'Batch'
+ }
+]
+
export const filterSelectOptions = {
[STATUS_FILTER]: generateStatusFilter(false),
[GROUP_BY_FILTER]: [
diff --git a/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx b/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx
index 7505a6a7b7..e4134e48ca 100644
--- a/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx
+++ b/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx
@@ -17,9 +17,10 @@ such restriction.
import React from 'react'
import { useForm } from 'react-final-form'
-import { FormInput, FormOnChange } from 'igz-controls/components'
+import { FormInput, FormOnChange, FormSelect } from 'igz-controls/components'
-import { LABELS_FILTER } from '../../../constants'
+import { modelEndpointsModesList } from '../../FilterMenu/filterMenu.settings'
+import { LABELS_FILTER, ME_MODE_FILTER } from '../../../constants'
const ModelEndpointsFilters = () => {
const form = useForm()
@@ -30,6 +31,9 @@ const ModelEndpointsFilters = () => {
return (