Skip to content

Commit 77bc6b9

Browse files
authored
Merge pull request #333 from project-koku/release_prod-stable.51458
Deployment commit for prod-stable
2 parents ca90b0b + 322edfb commit 77bc6b9

32 files changed

+1909
-1759
lines changed

.archive/routes/optimizations/optimizationsBreakdown/data.ts

+819-79
Large diffs are not rendered by default.

docs/index.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Koku UI MFE Documentation Index #
2+
3+
Welcome to the Koku UI MFE documentation!

locales/data.json

+12
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,18 @@
14401440
"value": "value"
14411441
}
14421442
],
1443+
"optimizedStateDesc": [
1444+
{
1445+
"type": 0,
1446+
"value": "Good job optimizing the current configuration."
1447+
}
1448+
],
1449+
"optimizedStateTitle": [
1450+
{
1451+
"type": 0,
1452+
"value": "You have reached recommended state!"
1453+
}
1454+
],
14431455
"pageTitleDefault": [
14441456
{
14451457
"type": 0,

locales/translations.json

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
"optimizationsShortTerm": "Last 24 hrs",
6060
"optimizationsValue": "{value}{units}",
6161
"optimizationsValues": "{value, select, cluster {Cluster name} container {Container name} last_reported {Last reported} project {Project name} workload {Workload name} workload_type {Workload type} other {}}",
62+
"optimizedStateDesc": "Good job optimizing the current configuration.",
63+
"optimizedStateTitle": "You have reached recommended state!",
6264
"pageTitleDefault": "Cost Management MFE | OpenShift",
6365
"pageTitleOptimizations": "Optimizations - Cost Management | OpenShift",
6466
"paginationTitle": "{placement, select, top {{title} top pagination} bottom {{title} bottom pagination} other {{title} pagination}}",

mkdocs.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
docs_dir: docs/
2+
site_name: Koku UI MFE Documentation
3+
plugins:
4+
- techdocs-core

package-lock.json

+467-518
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+37-38
Original file line numberDiff line numberDiff line change
@@ -48,67 +48,66 @@
4848
"verify": "npm-run-all build lint test"
4949
},
5050
"dependencies": {
51-
"@patternfly/patternfly": "5.2.0",
52-
"@patternfly/react-charts": "7.2.2",
53-
"@patternfly/react-component-groups": "5.1.0",
54-
"@patternfly/react-core": "5.2.0",
55-
"@patternfly/react-icons": "5.2.0",
56-
"@patternfly/react-table": "5.2.0",
57-
"@patternfly/react-tokens": "5.2.0",
58-
"@redhat-cloud-services/frontend-components": "^4.2.6",
51+
"@patternfly/patternfly": "5.3.1",
52+
"@patternfly/react-charts": "7.3.0",
53+
"@patternfly/react-component-groups": "^5.1.0",
54+
"@patternfly/react-core": "5.3.3",
55+
"@patternfly/react-icons": "5.3.2",
56+
"@patternfly/react-table": "5.3.3",
57+
"@patternfly/react-tokens": "5.3.1",
58+
"@redhat-cloud-services/frontend-components": "^4.2.10",
5959
"@redhat-cloud-services/frontend-components-notifications": "^4.1.0",
6060
"@redhat-cloud-services/frontend-components-translations": "^3.2.7",
61-
"@redhat-cloud-services/frontend-components-utilities": "^4.0.10",
62-
"@redhat-cloud-services/rbac-client": "^1.3.3",
63-
"@reduxjs/toolkit": "^2.2.3",
64-
"@unleash/proxy-client-react": "^4.2.2",
65-
"axios": "^1.6.8",
61+
"@redhat-cloud-services/frontend-components-utilities": "^4.0.11",
62+
"@redhat-cloud-services/rbac-client": "^1.4.4",
63+
"@reduxjs/toolkit": "^2.2.5",
64+
"@unleash/proxy-client-react": "^4.2.4",
65+
"axios": "^1.7.2",
6666
"date-fns": "^3.6.0",
6767
"js-file-download": "^0.4.12",
6868
"lodash": "^4.17.21",
6969
"qs": "^6.12.1",
70-
"react": "^18.2.0",
70+
"react": "^18.3.1",
7171
"react-bootstrap": "^2.10.2",
72-
"react-dom": "^18.2.0",
73-
"react-intl": "^6.6.5",
74-
"react-redux": "^9.1.1",
75-
"react-router-dom": "^6.22.3",
72+
"react-dom": "^18.3.1",
73+
"react-intl": "^6.6.8",
74+
"react-redux": "^9.1.2",
75+
"react-router-dom": "^6.23.1",
7676
"redux": "^5.0.1",
7777
"redux-thunk": "^3.1.0",
7878
"typesafe-actions": "^5.1.0",
79-
"unleash-proxy-client": "^3.3.2",
8079
"victory-core": "^37.0.2",
81-
"yaml": "^2.4.1"
80+
"yaml": "^2.4.2"
8281
},
8382
"devDependencies": {
84-
"@formatjs/cli": "^6.2.9",
83+
"@formatjs/cli": "^6.2.12",
8584
"@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4",
86-
"@redhat-cloud-services/frontend-components-config": "^6.0.12",
87-
"@redhat-cloud-services/tsc-transform-imports": "^1.0.9",
88-
"@swc/core": "^1.4.14",
85+
"@redhat-cloud-services/frontend-components-config": "^6.0.14",
86+
"@redhat-cloud-services/tsc-transform-imports": "^1.0.10",
87+
"@swc/core": "^1.5.7",
8988
"@swc/jest": "^0.2.36",
90-
"@testing-library/jest-dom": "^6.4.2",
91-
"@testing-library/react": "^15.0.2",
89+
"@testing-library/jest-dom": "^6.4.5",
90+
"@testing-library/react": "^15.0.7",
9291
"@testing-library/user-event": "^14.5.2",
9392
"@types/jest": "^29.5.12",
9493
"@types/qs": "^6.9.15",
95-
"@types/react": "^18.2.79",
96-
"@types/react-dom": "^18.2.25",
94+
"@types/react": "^18.3.3",
95+
"@types/react-dom": "^18.3.0",
9796
"@types/react-redux": "^7.1.33",
9897
"@types/react-router-dom": "^5.3.3",
99-
"@typescript-eslint/eslint-plugin": "^7.7.0",
100-
"@typescript-eslint/parser": "^7.7.0",
98+
"@typescript-eslint/eslint-plugin": "^7.11.0",
99+
"@typescript-eslint/parser": "^7.11.0",
101100
"@xstate/test": "^0.5.1",
102101
"aphrodite": "^2.4.0",
103102
"copy-webpack-plugin": "^12.0.2",
104103
"eslint": "^8.57.0",
105-
"eslint-plugin-formatjs": "^4.13.0",
106-
"eslint-plugin-jest-dom": "^5.2.0",
107-
"eslint-plugin-jsdoc": "^48.2.3",
108-
"eslint-plugin-markdown": "^4.0.1",
109-
"eslint-plugin-patternfly-react": "^5.2.1",
104+
"eslint-plugin-formatjs": "^4.13.3",
105+
"eslint-plugin-jest-dom": "^5.4.0",
106+
"eslint-plugin-jsdoc": "^48.2.7",
107+
"eslint-plugin-markdown": "^5.0.0",
108+
"eslint-plugin-patternfly-react": "^5.3.0",
110109
"eslint-plugin-prettier": "^5.1.3",
111-
"eslint-plugin-react": "^7.34.1",
110+
"eslint-plugin-react": "^7.34.2",
112111
"eslint-plugin-simple-import-sort": "^12.1.0",
113112
"eslint-plugin-sort-keys-fix": "^1.1.2",
114113
"eslint-plugin-testing-library": "^6.2.2",
@@ -121,9 +120,9 @@
121120
"jws": "^4.0.0",
122121
"npm-run-all": "^4.1.5",
123122
"prettier": "^3.2.5",
124-
"rimraf": "^5.0.5",
123+
"rimraf": "^5.0.7",
125124
"swc_mut_cjs_exports": "^0.90.24",
126-
"ts-jest": "^29.1.2",
125+
"ts-jest": "^29.1.4",
127126
"ts-patch": "^3.1.2",
128127
"typescript": "^5.4.5",
129128
"webpack-bundle-analyzer": "^4.10.2"

src/api/ros/recommendations.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export interface RecommendationValues {
2727

2828
export interface RecommendationEngine {
2929
config: RecommendationValues;
30+
notifications?: {
31+
[key: string]: Notification;
32+
};
3033
pods_count?: number;
3134
variation: RecommendationValues;
3235
}
@@ -46,10 +49,6 @@ export interface RecommendationTerm {
4649
notifications?: {
4750
[key: string]: Notification;
4851
};
49-
recommendation_engines?: {
50-
cost: RecommendationEngine;
51-
performance: RecommendationEngine;
52-
};
5352
plots?: {
5453
datapoints?: number;
5554
plots_data?: {
@@ -59,6 +58,10 @@ export interface RecommendationTerm {
5958
};
6059
};
6160
};
61+
recommendation_engines?: {
62+
cost: RecommendationEngine;
63+
performance: RecommendationEngine;
64+
};
6265
}
6366

6467
export interface RecommendationTerms {
@@ -67,7 +70,7 @@ export interface RecommendationTerms {
6770
short_term?: RecommendationTerm;
6871
}
6972

70-
export interface RecommendationItems {
73+
export interface Recommendations {
7174
current?: RecommendationValues;
7275
monitoring_end_time?: string;
7376
notifications?: {
@@ -77,7 +80,7 @@ export interface RecommendationItems {
7780
}
7881

7982
export interface RecommendationReportData extends RosData {
80-
recommendations?: RecommendationItems;
83+
recommendations?: Recommendations;
8184
}
8285

8386
export interface RecommendationReportMeta extends RosMeta {

src/components/featureToggle/featureToggle.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,30 @@ import { featureToggleActions } from 'store/featureToggle';
66

77
// eslint-disable-next-line no-shadow
88
export const enum FeatureToggle {
9-
debug = 'cost-management.ui.mfe.debug',
10-
utilization = 'cost-management.ui.mfe.utilization', // https://issues.redhat.com/browse/COST-4619
9+
boxPlot = 'cost-management.mfe.box-plot', // https://issues.redhat.com/browse/COST-4619
10+
debug = 'cost-management.mfe.debug',
1111
}
1212

1313
const useIsToggleEnabled = (toggle: FeatureToggle) => {
1414
const client = useUnleashClient();
1515
return client.isEnabled(toggle);
1616
};
1717

18-
export const useIsDebugFlagEnabled = () => {
18+
export const useIsDebugToggleEnabled = () => {
1919
return useIsToggleEnabled(FeatureToggle.debug);
2020
};
2121

22-
export const useIsUtilizationFlagEnabled = () => {
23-
return useIsToggleEnabled(FeatureToggle.utilization) && insights?.chrome?.isBeta();
22+
export const useIsBoxPlotToggleEnabled = () => {
23+
return useIsToggleEnabled(FeatureToggle.boxPlot);
2424
};
2525

2626
// The FeatureToggle component saves feature toggles in store for places where Unleash hooks not available
2727
const useFeatureToggle = () => {
2828
const dispatch = useDispatch();
2929
const { auth } = useChrome();
3030

31-
const isDebugFlagEnabled = useIsDebugFlagEnabled();
32-
const isUtilizationFlagEnabled = useIsUtilizationFlagEnabled();
31+
const isDebugToggleEnabled = useIsDebugToggleEnabled();
32+
const isBoxPlotToggleEnabled = useIsBoxPlotToggleEnabled();
3333

3434
const fetchUser = callback => {
3535
auth.getUser().then(user => {
@@ -41,15 +41,15 @@ const useFeatureToggle = () => {
4141
// Workaround for code that doesn't use hooks
4242
dispatch(
4343
featureToggleActions.setFeatureToggle({
44-
isDebugFlagEnabled,
45-
isUtilizationFlagEnabled,
44+
isDebugToggleEnabled,
45+
isBoxPlotToggleEnabled,
4646
})
4747
);
48-
if (isDebugFlagEnabled) {
48+
if (isDebugToggleEnabled) {
4949
// eslint-disable-next-line no-console
5050
fetchUser(identity => console.log('User identity:', identity));
5151
}
52-
}, [isDebugFlagEnabled, isUtilizationFlagEnabled]);
52+
}, [isDebugToggleEnabled, isBoxPlotToggleEnabled]);
5353
};
5454

5555
export default useFeatureToggle;

src/locales/messages.ts

+10
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,16 @@ export default defineMessages({
419419
description: 'Selected items for export',
420420
id: 'optimizationsValues',
421421
},
422+
optimizedStateDesc: {
423+
defaultMessage: 'Good job optimizing the current configuration.',
424+
description: 'Good job optimizing the current configuration.',
425+
id: 'optimizedStateDesc',
426+
},
427+
optimizedStateTitle: {
428+
defaultMessage: 'You have reached recommended state!',
429+
description: 'You have reached recommended state!',
430+
id: 'optimizedStateTitle',
431+
},
422432
pageTitleDefault: {
423433
defaultMessage: 'Cost Management MFE | OpenShift',
424434
description: 'Cost Management MFE | OpenShift',

src/routes/components/charts/common/chartDatum.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,21 @@ export function getMaxMinValues(datums: ChartDatum[]) {
2525
datum.y0 !== undefined
2626
? Math.max(datum.y, datum.y0)
2727
: Array.isArray(datum.y)
28-
? Math.max(...(datum.y[0] !== null ? datum.y : [0]))
28+
? datum.y[0] !== null
29+
? Math.max(...datum.y)
30+
: (datum as any).yVal // For boxplot, which is hidden via `datum.y[0] = null` when all values are equal
31+
? (datum as any).yVal
32+
: 0
2933
: datum.y;
3034
const minY =
3135
datum.y0 !== undefined
3236
? Math.min(datum.y, datum.y0)
3337
: Array.isArray(datum.y)
34-
? Math.min(...(datum.y[0] !== null ? datum.y : [0]))
38+
? datum.y[0] !== null
39+
? Math.min(...datum.y)
40+
: (datum as any).yVal // For boxplot, which is hidden via `datum.y[0] = null` when all values are equal
41+
? (datum as any).yVal
42+
: 0
3543
: datum.y;
3644
if (maxY > max) {
3745
max = maxY;

src/routes/components/charts/common/chartUtils.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ export const getChartNames = (series: ChartSeries[]) => {
3838
return result as any;
3939
};
4040

41-
export const getDomain = (series: ChartSeries[], hiddenSeries: Set<number>) => {
41+
// Note: A series may be grouped in order to be hidden / shown together
42+
export const getDomain = (series: ChartSeries[], hiddenSeries: Set<number>, groupedSeriesCount = 0) => {
4243
const domain: { x?: DomainTuple; y?: DomainTuple } = { y: [0, 1] };
4344
let maxValue = -1;
4445
let minValue = -1;
4546

4647
if (series) {
4748
// Don't use zero domain
48-
if (series.length === hiddenSeries.size) {
49+
if (series.length - groupedSeriesCount === hiddenSeries.size) {
4950
domain.x = [0, 1];
5051
hiddenSeries = new Set();
5152
}
@@ -78,14 +79,17 @@ export const getLegendData = (series: ChartSeries[], hiddenSeries: Set<number>,
7879
if (!series) {
7980
return undefined;
8081
}
81-
const result = series.map((s, index) => {
82-
const data = {
83-
childName: s.childName,
84-
...s.legendItem, // name property
85-
...(tooltip && { name: s.legendItem.tooltip }), // Override name property for tooltip
86-
...getInteractiveLegendItemStyles(hiddenSeries.has(index)), // hidden styles
87-
};
88-
return data;
82+
const result = [];
83+
series.map((s, index) => {
84+
if (s.legendItem) {
85+
const data = {
86+
childName: s.childName,
87+
...s.legendItem, // name property
88+
...(tooltip && { name: s.legendItem.tooltip }), // Override name property for tooltip
89+
...getInteractiveLegendItemStyles(hiddenSeries.has(index)), // hidden styles
90+
};
91+
result.push(data);
92+
}
8993
});
9094
return result;
9195
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as OptimizedState } from './optimizedState';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { global_success_color_100 } from '@patternfly/react-tokens/dist/js/global_success_color_100';
2+
import type React from 'react';
3+
4+
export const styles = {
5+
icon: {
6+
color: global_success_color_100.var,
7+
},
8+
} as { [className: string]: React.CSSProperties };

0 commit comments

Comments
 (0)