From 78a6502888d9f2ca5464a967cacd68089cdc3548 Mon Sep 17 00:00:00 2001 From: nk-hystax <128669932+nk-hystax@users.noreply.github.com> Date: Tue, 9 Dec 2025 09:08:15 +0300 Subject: [PATCH 1/6] OSN-1145. Fix other cloud type flavors in ri_breakdown --- .../controllers/ri_breakdown.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/rest_api/rest_api_server/controllers/ri_breakdown.py b/rest_api/rest_api_server/controllers/ri_breakdown.py index 16b8b72d5..021c50846 100644 --- a/rest_api/rest_api_server/controllers/ri_breakdown.py +++ b/rest_api/rest_api_server/controllers/ri_breakdown.py @@ -144,7 +144,7 @@ def get_flavors(self, cloud_accounts_map): FROM ri_sp_usage WHERE cloud_account_id IN cloud_account_ids AND date >= %(start_date)s AND date <= %(end_date)s AND - offer_type='ri' + offer_type='ri' AND instance_type != '' """, parameters={ 'start_date': datetime.fromtimestamp(self.start_date), @@ -176,6 +176,7 @@ def get_flavors(self, cloud_accounts_map): flavor_factor_map[flavor_name] = value cloud_type_flavors[cloud_type].add(flavor_name) break + cloud_type_flavors[cloud_type].add(flavor_name) return flavor_factor_map, cloud_type_flavors @staticmethod @@ -215,13 +216,14 @@ def format_cloud_account(cloud_account_id, cloud_accs_map): } def format_result(self, result, cloud_account_id, date_ts, total_stats, - ri_sp_stats, cloud_accs_map, flavors_map): + ri_sp_stats, cloud_accs_map, cloud_acc_flavor_rate): usage = ri_sp_stats.get('usage', 0) overprovision_hrs = ri_sp_stats.get('overprovision_hrs', {}) cost_with_offer = ri_sp_stats.get('cost_with_offer', 0) cost_without_offer = ri_sp_stats.get('cost_without_offer', 0) for flavor_name, hrs in overprovision_hrs.items(): overprovision_hrs[flavor_name] = round(hrs, 10) + flavors_map = cloud_acc_flavor_rate.get(cloud_account_id, {}) for flavor in flavors_map: if flavor not in overprovision_hrs: overprovision_hrs[flavor] = 0 @@ -245,7 +247,9 @@ def format_result(self, result, cloud_account_id, date_ts, total_stats, result[date_ts].append(result_dict) return result - def _empty_stats(self, cloud_account_id, cloud_accs_map, flavors_map): + def _empty_stats(self, cloud_account_id, cloud_accs_map, + cloud_acc_flavors_map): + flavors_map = cloud_acc_flavors_map.get(cloud_account_id, {}) result_dict = { 'cloud_account_id': cloud_account_id, 'total_usage_hrs': 0, @@ -264,7 +268,7 @@ def _empty_stats(self, cloud_account_id, cloud_accs_map, flavors_map): return result_dict def fill_empty_dates(self, result, dates, cloud_account_ids, aws_cloud_accs, - flavors_map): + cloud_acc_flavors_map): if not cloud_account_ids: return result for date_ts, date_result in result.items(): @@ -273,11 +277,13 @@ def fill_empty_dates(self, result, dates, cloud_account_ids, aws_cloud_accs, cloud_accs_to_fill = set(cloud_account_ids) - date_cloud_accs_ids for cloud_acc_id in cloud_accs_to_fill: date_result.append(self._empty_stats( - cloud_acc_id, aws_cloud_accs, flavors_map)) + cloud_acc_id, aws_cloud_accs, cloud_acc_flavors_map)) dates_to_fill = [x for x in dates if x not in result] for date in dates_to_fill: - result[date] = [self._empty_stats(x, aws_cloud_accs, flavors_map) - for x in cloud_account_ids] + result[date] = [ + self._empty_stats(x, aws_cloud_accs, cloud_acc_flavors_map) + for x in cloud_account_ids + ] return result def get_overprovision_ch_expenses( @@ -407,11 +413,11 @@ def get(self, organization_id, **params): ri_stats = date_ri_usage.get(date, {}) result = self.format_result( result, cloud_account_id, date_ts, total_stats, ri_stats, - cloud_accs_map, flavor_rate_map) + cloud_accs_map, cloud_acc_flavor_rate) breakdown_dates = self.breakdown_dates(self.start_date, self.end_date) result = self.fill_empty_dates( result, breakdown_dates, cloud_account_ids, cloud_accs_map, - flavor_rate_map) + cloud_acc_flavor_rate) return result From ee2cdd7f012a692e8b0d9226d558ffb8309073c5 Mon Sep 17 00:00:00 2001 From: Anton Sukhov Date: Wed, 10 Dec 2025 13:11:50 +0400 Subject: [PATCH 2/6] OSN-1226. Export chart download error ## Description Added wrapperRef for ResponsiveCanvasBarChart component --- ngui/ui/src/components/CanvasBarChart/CanvasBarChart.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ngui/ui/src/components/CanvasBarChart/CanvasBarChart.tsx b/ngui/ui/src/components/CanvasBarChart/CanvasBarChart.tsx index c39d4f51a..fd7f61c06 100644 --- a/ngui/ui/src/components/CanvasBarChart/CanvasBarChart.tsx +++ b/ngui/ui/src/components/CanvasBarChart/CanvasBarChart.tsx @@ -428,6 +428,7 @@ const CanvasBarChart = ({ const ResponsiveCanvasBarChart = ({ data, + wrapperRef, keys = [], style = {}, isLoading = false, @@ -454,6 +455,7 @@ const ResponsiveCanvasBarChart = ({ style={{ height: muiTheme.spacing(height) }} + ref={wrapperRef} > {({ width: wrapperWidth, height: wrapperHeight }) => { From 0841e293d67de20d11e855dd0de467c3f97c0761 Mon Sep 17 00:00:00 2001 From: ka-hystax Date: Wed, 10 Dec 2025 12:24:04 +0300 Subject: [PATCH 3/6] OSN-1194. Add TypeScript typings for WrapperCard component - added TS typings for WrapperCard --- ngui/ui/src/components/Button/Button.tsx | 2 +- .../components/WrapperCard/WrapperCard.tsx | 25 +++++---- ngui/ui/src/components/WrapperCard/types.ts | 54 +++++++++++++++++++ 3 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 ngui/ui/src/components/WrapperCard/types.ts diff --git a/ngui/ui/src/components/Button/Button.tsx b/ngui/ui/src/components/Button/Button.tsx index 7a2029d17..bdd14aa46 100644 --- a/ngui/ui/src/components/Button/Button.tsx +++ b/ngui/ui/src/components/Button/Button.tsx @@ -30,7 +30,7 @@ type ButtonText = ExclusiveUnion<{ pepega: string; }>; -type ButtonProps = MuiButtonProps & +export type ButtonProps = MuiButtonProps & ButtonText & NavProps & { dataTestId?: string; diff --git a/ngui/ui/src/components/WrapperCard/WrapperCard.tsx b/ngui/ui/src/components/WrapperCard/WrapperCard.tsx index 4784df525..e8ff4807f 100644 --- a/ngui/ui/src/components/WrapperCard/WrapperCard.tsx +++ b/ngui/ui/src/components/WrapperCard/WrapperCard.tsx @@ -9,31 +9,30 @@ import IconButton from "components/IconButton"; import Tooltip from "components/Tooltip"; import WidgetTitle from "components/WidgetTitle"; import WrapperCardTitlePdf from "components/WrapperCardTitlePdf/WrapperCardTitlePdf"; +import { TitleProps, WrapperCardProps } from "./types"; import useStyles from "./WrapperCard.styles"; -const renderButton = (type, buttonProps) => (type === "icon" ? :