From c10a463899b63df14eb6e47830d0c3fd7b88ea45 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 18 Apr 2024 14:32:38 -0400 Subject: [PATCH 01/49] Create Unleash flags for new features; COST-4855, COST-4781, and COST-4855 --- .../featureToggle/featureToggle.tsx | 24 +++++++++++ .../__snapshots__/featureToggle.test.ts.snap | 3 ++ src/store/featureToggle/featureToggle.test.ts | 42 +++++++++++++++++++ .../featureToggle/featureToggleActions.ts | 3 ++ .../featureToggle/featureToggleReducer.ts | 9 ++++ .../featureToggle/featureToggleSelectors.ts | 6 +++ 6 files changed, 87 insertions(+) diff --git a/src/components/featureToggle/featureToggle.tsx b/src/components/featureToggle/featureToggle.tsx index 5cb1c139a..e936a0e4d 100644 --- a/src/components/featureToggle/featureToggle.tsx +++ b/src/components/featureToggle/featureToggle.tsx @@ -6,11 +6,14 @@ import { FeatureToggleActions } from 'store/featureToggle'; // eslint-disable-next-line no-shadow export const enum FeatureToggle { + awsEc2Instances = 'cost-management.ui.aws-ec2-instances', // https://issues.redhat.com/browse/COST-4855 clusterInfo = 'cost-management.ui.cluster.info', // https://issues.redhat.com/browse/COST-4559 debug = 'cost-management.ui.debug', exports = 'cost-management.ui.exports', // Async exports https://issues.redhat.com/browse/COST-2223 finsights = 'cost-management.ui.finsights', // RHEL support for FINsights https://issues.redhat.com/browse/COST-3306 ibm = 'cost-management.ui.ibm', // IBM https://issues.redhat.com/browse/COST-935 + ocpCloudNetworking = 'cost-management.ui.ocp-cloud-networking', // https://issues.redhat.com/browse/COST-4781 + ocpProjectStorage = 'cost-management.ui.ocp-project-storage', // https://issues.redhat.com/browse/COST-4856 ros = 'cost-management.ui.ros', // ROS support https://issues.redhat.com/browse/COST-3477 rosBeta = 'cost-management.ui.ros-beta', // ROS support https://issues.redhat.com/browse/COST-3477 settingsPlatform = 'cost-management.ui.settings.platform', // Platform projects https://issues.redhat.com/browse/COST-3818 @@ -22,6 +25,10 @@ const useIsToggleEnabled = (toggle: FeatureToggle) => { return client.isEnabled(toggle); }; +export const useIsAwsEc2InstancesToggleEnabled = () => { + return useIsToggleEnabled(FeatureToggle.awsEc2Instances); +}; + export const useIsDebugToggleEnabled = () => { return useIsToggleEnabled(FeatureToggle.debug); }; @@ -42,6 +49,14 @@ export const useIsIbmToggleEnabled = () => { return useIsToggleEnabled(FeatureToggle.ibm); }; +export const useIsOcpCloudNetworkingToggleEnabled = () => { + return useIsToggleEnabled(FeatureToggle.ocpCloudNetworking); +}; + +export const useIsOcpProjectStorageToggleEnabled = () => { + return useIsToggleEnabled(FeatureToggle.ocpProjectStorage); +}; + export const useIsRosToggleEnabled = () => { const { isBeta } = useChrome(); const isRosToggleEnabled = useIsToggleEnabled(FeatureToggle.ros); @@ -62,11 +77,14 @@ export const useFeatureToggle = () => { const dispatch = useDispatch(); const { auth } = useChrome(); + const isAwsEc2InstancesToggleEnabled = useIsAwsEc2InstancesToggleEnabled(); const isClusterInfoToggleEnabled = useIsClusterInfoToggleEnabled(); const isDebugToggleEnabled = useIsDebugToggleEnabled(); const isExportsToggleEnabled = useIsExportsToggleEnabled(); const isFinsightsToggleEnabled = useIsFinsightsToggleEnabled(); const isIbmToggleEnabled = useIsIbmToggleEnabled(); + const isOcpCloudNetworkingToggleEnabled = useIsOcpCloudNetworkingToggleEnabled(); + const isOcpProjectStorageToggleEnabled = useIsOcpProjectStorageToggleEnabled(); const isRosToggleEnabled = useIsRosToggleEnabled(); const isSettingsPlatformToggleEnabled = useIsSettingsPlatformToggleEnabled(); const isTagMappingToggleEnabled = useIsTagMappingToggleEnabled(); @@ -81,11 +99,14 @@ export const useFeatureToggle = () => { // Workaround for code that doesn't use hooks dispatch( FeatureToggleActions.setFeatureToggle({ + isAwsEc2InstancesToggleEnabled, isClusterInfoToggleEnabled, isDebugToggleEnabled, isExportsToggleEnabled, isFinsightsToggleEnabled, isIbmToggleEnabled, + isOcpCloudNetworkingToggleEnabled, + isOcpProjectStorageToggleEnabled, isRosToggleEnabled, isSettingsPlatformToggleEnabled, isTagMappingToggleEnabled, @@ -96,11 +117,14 @@ export const useFeatureToggle = () => { fetchUser(identity => console.log('User identity:', identity)); } }, [ + isAwsEc2InstancesToggleEnabled, isClusterInfoToggleEnabled, isDebugToggleEnabled, isExportsToggleEnabled, isFinsightsToggleEnabled, isIbmToggleEnabled, + isOcpCloudNetworkingToggleEnabled, + isOcpProjectStorageToggleEnabled, isRosToggleEnabled, isSettingsPlatformToggleEnabled, isTagMappingToggleEnabled, diff --git a/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap b/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap index 38f05a822..82b252c56 100644 --- a/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap +++ b/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap @@ -3,11 +3,14 @@ exports[`default state 1`] = ` { "hasFeatureToggle": false, + "isAwsEc2InstancesToggleEnabled": false, "isClusterInfoToggleEnabled": false, "isDebugToggleEnabled": false, "isExportsToggleEnabled": false, "isFinsightsToggleEnabled": false, "isIbmToggleEnabled": false, + "isOcpCloudNetworkingToggleEnabled": false, + "isOcpProjectStorageToggleEnabled": false, "isRosToggleEnabled": false, "isSettingsPlatformToggleEnabled": false, "isTagMappingToggleEnabled": false, diff --git a/src/store/featureToggle/featureToggle.test.ts b/src/store/featureToggle/featureToggle.test.ts index f5bab857c..8ce3f24a5 100644 --- a/src/store/featureToggle/featureToggle.test.ts +++ b/src/store/featureToggle/featureToggle.test.ts @@ -14,6 +14,24 @@ test('default state', async () => { expect(selectors.selectFeatureToggleState(store.getState())).toMatchSnapshot(); }); +test('AWS EC2 instances feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isAwsEc2InstancesToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsAwsEc2InstancesToggleEnabled(store.getState())).toBe(true); +}); + +test('Cloud info feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isClusterInfoToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsClusterInfoToggleEnabled(store.getState())).toBe(true); +}); + +test('Debug feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isDebugToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsDebugToggleEnabled(store.getState())).toBe(true); +}); + test('Exports feature is enabled', async () => { const store = createUIStore(); store.dispatch(actions.setFeatureToggle({ isExportsToggleEnabled: true })); @@ -32,8 +50,32 @@ test('IBM feature is enabled', async () => { expect(FeatureToggleSelectors.selectIsIbmToggleEnabled(store.getState())).toBe(true); }); +test('OCP on cloud networking feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isOcpCloudNetworkingToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsOcpCloudNetworkingToggleEnabled(store.getState())).toBe(true); +}); + +test('OCP project storage feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isOcpProjectStorageToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsOcpProjectStorageToggleEnabled(store.getState())).toBe(true); +}); + test('ROS feature is enabled', async () => { const store = createUIStore(); store.dispatch(actions.setFeatureToggle({ isRosToggleEnabled: true })); expect(FeatureToggleSelectors.selectIsRosToggleEnabled(store.getState())).toBe(true); }); + +test('Settings platform feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isSettingsPlatformToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsSettingsPlatformToggleEnabled(store.getState())).toBe(true); +}); + +test('Tag mapping feature is enabled', async () => { + const store = createUIStore(); + store.dispatch(actions.setFeatureToggle({ isTagMappingToggleEnabled: true })); + expect(FeatureToggleSelectors.selectIsTagMappingToggleEnabled(store.getState())).toBe(true); +}); diff --git a/src/store/featureToggle/featureToggleActions.ts b/src/store/featureToggle/featureToggleActions.ts index 6a7df2a8c..436f4fc21 100644 --- a/src/store/featureToggle/featureToggleActions.ts +++ b/src/store/featureToggle/featureToggleActions.ts @@ -1,11 +1,14 @@ import { createAction } from 'typesafe-actions'; export interface FeatureToggleActionMeta { + isAwsEc2InstancesToggleEnabled?: boolean; isClusterInfoToggleEnabled?: boolean; isDebugToggleEnabled?: boolean; isExportsToggleEnabled?: boolean; isFinsightsToggleEnabled?: boolean; isIbmToggleEnabled?: boolean; + isOcpCloudNetworkingToggleEnabled?: boolean; + isOcpProjectStorageToggleEnabled?: boolean; isRosToggleEnabled?: boolean; isSettingsPlatformToggleEnabled?: boolean; isTagMappingToggleEnabled?: boolean; diff --git a/src/store/featureToggle/featureToggleReducer.ts b/src/store/featureToggle/featureToggleReducer.ts index b2927f9a7..65a1dd56f 100644 --- a/src/store/featureToggle/featureToggleReducer.ts +++ b/src/store/featureToggle/featureToggleReducer.ts @@ -8,11 +8,14 @@ export type FeatureToggleAction = ActionType state[stateKey]; export const selectHasFeatureToggle = (state: RootState) => selectFeatureToggleState(state).hasFeatureToggle; +export const selectIsAwsEc2InstancesToggleEnabled = (state: RootState) => + selectFeatureToggleState(state).isAwsEc2InstancesToggleEnabled; export const selectIsClusterInfoToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isClusterInfoToggleEnabled; export const selectIsDebugToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isDebugToggleEnabled; @@ -14,6 +16,10 @@ export const selectIsExportsToggleEnabled = (state: RootState) => export const selectIsFinsightsToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isFinsightsToggleEnabled; export const selectIsIbmToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isIbmToggleEnabled; +export const selectIsOcpCloudNetworkingToggleEnabled = (state: RootState) => + selectFeatureToggleState(state).isOcpCloudNetworkingToggleEnabled; +export const selectIsOcpProjectStorageToggleEnabled = (state: RootState) => + selectFeatureToggleState(state).isOcpProjectStorageToggleEnabled; export const selectIsRosToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isRosToggleEnabled; export const selectIsSettingsPlatformToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isSettingsPlatformToggleEnabled; From a16e9347cd98889a8dcd1464b3a54f3b3d33e1f0 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 18 Apr 2024 14:49:17 -0400 Subject: [PATCH 02/49] Remove unused Unleash flags for settings platform, cluster info, and tag mapping --- .../featureToggle/featureToggle.tsx | 24 ------------------- .../components/breakdown/breakdownHeader.tsx | 12 ++++------ src/routes/settings/settings.tsx | 15 ++++-------- src/routes/settings/tagLabels/tagLabels.tsx | 8 +------ .../__snapshots__/featureToggle.test.ts.snap | 3 --- src/store/featureToggle/featureToggle.test.ts | 18 -------------- .../featureToggle/featureToggleActions.ts | 3 --- .../featureToggle/featureToggleReducer.ts | 9 ------- .../featureToggle/featureToggleSelectors.ts | 6 ----- 9 files changed, 10 insertions(+), 88 deletions(-) diff --git a/src/components/featureToggle/featureToggle.tsx b/src/components/featureToggle/featureToggle.tsx index e936a0e4d..a44ca2bba 100644 --- a/src/components/featureToggle/featureToggle.tsx +++ b/src/components/featureToggle/featureToggle.tsx @@ -7,7 +7,6 @@ import { FeatureToggleActions } from 'store/featureToggle'; // eslint-disable-next-line no-shadow export const enum FeatureToggle { awsEc2Instances = 'cost-management.ui.aws-ec2-instances', // https://issues.redhat.com/browse/COST-4855 - clusterInfo = 'cost-management.ui.cluster.info', // https://issues.redhat.com/browse/COST-4559 debug = 'cost-management.ui.debug', exports = 'cost-management.ui.exports', // Async exports https://issues.redhat.com/browse/COST-2223 finsights = 'cost-management.ui.finsights', // RHEL support for FINsights https://issues.redhat.com/browse/COST-3306 @@ -16,8 +15,6 @@ export const enum FeatureToggle { ocpProjectStorage = 'cost-management.ui.ocp-project-storage', // https://issues.redhat.com/browse/COST-4856 ros = 'cost-management.ui.ros', // ROS support https://issues.redhat.com/browse/COST-3477 rosBeta = 'cost-management.ui.ros-beta', // ROS support https://issues.redhat.com/browse/COST-3477 - settingsPlatform = 'cost-management.ui.settings.platform', // Platform projects https://issues.redhat.com/browse/COST-3818 - tagMapping = 'cost-management.ui.tag.mapping', // https://issues.redhat.com/browse/COST-3824 } const useIsToggleEnabled = (toggle: FeatureToggle) => { @@ -33,10 +30,6 @@ export const useIsDebugToggleEnabled = () => { return useIsToggleEnabled(FeatureToggle.debug); }; -export const useIsClusterInfoToggleEnabled = () => { - return useIsToggleEnabled(FeatureToggle.clusterInfo); -}; - export const useIsExportsToggleEnabled = () => { return useIsToggleEnabled(FeatureToggle.exports); }; @@ -64,21 +57,12 @@ export const useIsRosToggleEnabled = () => { return isRosToggleEnabled || isRosFeatureBetaEnabled; }; -export const useIsSettingsPlatformToggleEnabled = () => { - return useIsToggleEnabled(FeatureToggle.settingsPlatform); -}; - -export const useIsTagMappingToggleEnabled = () => { - return useIsToggleEnabled(FeatureToggle.tagMapping); -}; - // The FeatureToggle component saves feature toggles in store for places where Unleash hooks not available export const useFeatureToggle = () => { const dispatch = useDispatch(); const { auth } = useChrome(); const isAwsEc2InstancesToggleEnabled = useIsAwsEc2InstancesToggleEnabled(); - const isClusterInfoToggleEnabled = useIsClusterInfoToggleEnabled(); const isDebugToggleEnabled = useIsDebugToggleEnabled(); const isExportsToggleEnabled = useIsExportsToggleEnabled(); const isFinsightsToggleEnabled = useIsFinsightsToggleEnabled(); @@ -86,8 +70,6 @@ export const useFeatureToggle = () => { const isOcpCloudNetworkingToggleEnabled = useIsOcpCloudNetworkingToggleEnabled(); const isOcpProjectStorageToggleEnabled = useIsOcpProjectStorageToggleEnabled(); const isRosToggleEnabled = useIsRosToggleEnabled(); - const isSettingsPlatformToggleEnabled = useIsSettingsPlatformToggleEnabled(); - const isTagMappingToggleEnabled = useIsTagMappingToggleEnabled(); const fetchUser = callback => { auth.getUser().then(user => { @@ -100,7 +82,6 @@ export const useFeatureToggle = () => { dispatch( FeatureToggleActions.setFeatureToggle({ isAwsEc2InstancesToggleEnabled, - isClusterInfoToggleEnabled, isDebugToggleEnabled, isExportsToggleEnabled, isFinsightsToggleEnabled, @@ -108,8 +89,6 @@ export const useFeatureToggle = () => { isOcpCloudNetworkingToggleEnabled, isOcpProjectStorageToggleEnabled, isRosToggleEnabled, - isSettingsPlatformToggleEnabled, - isTagMappingToggleEnabled, }) ); if (isDebugToggleEnabled) { @@ -118,7 +97,6 @@ export const useFeatureToggle = () => { } }, [ isAwsEc2InstancesToggleEnabled, - isClusterInfoToggleEnabled, isDebugToggleEnabled, isExportsToggleEnabled, isFinsightsToggleEnabled, @@ -126,8 +104,6 @@ export const useFeatureToggle = () => { isOcpCloudNetworkingToggleEnabled, isOcpProjectStorageToggleEnabled, isRosToggleEnabled, - isSettingsPlatformToggleEnabled, - isTagMappingToggleEnabled, ]); }; diff --git a/src/routes/details/components/breakdown/breakdownHeader.tsx b/src/routes/details/components/breakdown/breakdownHeader.tsx index f57fd1d66..b8537e298 100644 --- a/src/routes/details/components/breakdown/breakdownHeader.tsx +++ b/src/routes/details/components/breakdown/breakdownHeader.tsx @@ -18,7 +18,6 @@ import { Currency } from 'routes/components/currency'; import { TagLink } from 'routes/details/components/tag'; import { getGroupByCostCategory, getGroupByOrgValue, getGroupByTagKey } from 'routes/utils/groupBy'; import { createMapStateToProps } from 'store/common'; -import { FeatureToggleSelectors } from 'store/featureToggle'; import { getTotalCostDateRangeString } from 'utils/dates'; import { formatCurrency } from 'utils/format'; import { awsCategoryKey, orgUnitIdKey, tagKey } from 'utils/props'; @@ -51,7 +50,7 @@ interface BreakdownHeaderOwnProps extends RouterComponentProps { } interface BreakdownHeaderStateProps { - isClusterInfoToggleEnabled?: boolean; + // TBD... } interface BreakdownHeaderDispatchProps { @@ -100,7 +99,6 @@ class BreakdownHeader extends React.Component { description, groupBy, intl, - isClusterInfoToggleEnabled, onCostDistributionSelect, onCostTypeSelect, onCurrencySelect, @@ -136,7 +134,7 @@ class BreakdownHeader extends React.Component { ? orgUnitIdKey : groupBy; - const showClusterInfo = clusterInfoComponent && isClusterInfoToggleEnabled; + const showClusterInfo = clusterInfoComponent; return (
@@ -176,7 +174,7 @@ class BreakdownHeader extends React.Component { ) : null} )} - {dataDetailsComponent && isClusterInfoToggleEnabled ? {dataDetailsComponent} : null} + {dataDetailsComponent ? {dataDetailsComponent} : null} {showCostDistribution && ( @@ -213,9 +211,9 @@ class BreakdownHeader extends React.Component { } } -const mapStateToProps = createMapStateToProps(state => { +const mapStateToProps = createMapStateToProps(() => { return { - isClusterInfoToggleEnabled: FeatureToggleSelectors.selectIsClusterInfoToggleEnabled(state), + // TBD... }; }); diff --git a/src/routes/settings/settings.tsx b/src/routes/settings/settings.tsx index 43a15d510..8dd92effc 100644 --- a/src/routes/settings/settings.tsx +++ b/src/routes/settings/settings.tsx @@ -19,7 +19,6 @@ import { PlatformProjects } from 'routes/settings/platformProjects'; import { TagLabels } from 'routes/settings/tagLabels'; import type { RootState } from 'store'; import { FetchStatus } from 'store/common'; -import { FeatureToggleSelectors } from 'store/featureToggle'; import { userAccessQuery, userAccessSelectors } from 'store/userAccess'; import type { ChromeComponentProps } from 'utils/chrome'; import { withChrome } from 'utils/chrome'; @@ -67,7 +66,6 @@ export interface SettingsMapProps { } export interface SettingsStateProps { - isSettingsPlatformEnabled?: boolean; userAccess: UserAccess; userAccessError: AxiosError; userAccessFetchStatus: FetchStatus; @@ -78,7 +76,7 @@ type SettingsProps = SettingsOwnProps; const Settings: React.FC = () => { const [activeTabKey, setActiveTabKey] = useState(0); - const { isSettingsPlatformEnabled, userAccess, userAccessFetchStatus } = useMapToProps(); + const { userAccess, userAccessFetchStatus } = useMapToProps(); const intl = useIntl(); const canWrite = () => { @@ -108,13 +106,11 @@ const Settings: React.FC = () => { contentRef: React.createRef(), tab: SettingsTab.costCategory, }, - ]; - if (isSettingsPlatformEnabled) { - availableTabs.push({ + { contentRef: React.createRef(), tab: SettingsTab.platformProjects, - }); - } + }, + ]; return availableTabs; }; @@ -236,9 +232,6 @@ const useMapToProps = (): SettingsStateProps => { ); return { - isSettingsPlatformEnabled: useSelector((state: RootState) => - FeatureToggleSelectors.selectIsSettingsPlatformToggleEnabled(state) - ), userAccess, userAccessError, userAccessFetchStatus, diff --git a/src/routes/settings/tagLabels/tagLabels.tsx b/src/routes/settings/tagLabels/tagLabels.tsx index 1325395d8..b11c7e622 100644 --- a/src/routes/settings/tagLabels/tagLabels.tsx +++ b/src/routes/settings/tagLabels/tagLabels.tsx @@ -1,5 +1,4 @@ import { Accordion, AccordionContent, AccordionItem, AccordionToggle, PageSection } from '@patternfly/react-core'; -import { useIsTagMappingToggleEnabled } from 'components/featureToggle'; import messages from 'locales/messages'; import React, { useState } from 'react'; import { useIntl } from 'react-intl'; @@ -36,7 +35,6 @@ type TagLabelsProps = TagLabelsOwnProps; const TagLabels: React.FC = ({ canWrite }) => { const [activeKey, setActiveKey] = useState(0); - const isTagMappingToggleEnabled = useIsTagMappingToggleEnabled(); const intl = useIntl(); const getAvailableItems = () => { @@ -104,11 +102,7 @@ const TagLabels: React.FC = ({ canWrite }) => { return (
- {isTagMappingToggleEnabled ? ( - {getAccordionItem(availableItems)} - ) : ( - - )} + {getAccordionItem(availableItems)}
); diff --git a/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap b/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap index 82b252c56..ce0f17673 100644 --- a/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap +++ b/src/store/featureToggle/__snapshots__/featureToggle.test.ts.snap @@ -4,7 +4,6 @@ exports[`default state 1`] = ` { "hasFeatureToggle": false, "isAwsEc2InstancesToggleEnabled": false, - "isClusterInfoToggleEnabled": false, "isDebugToggleEnabled": false, "isExportsToggleEnabled": false, "isFinsightsToggleEnabled": false, @@ -12,7 +11,5 @@ exports[`default state 1`] = ` "isOcpCloudNetworkingToggleEnabled": false, "isOcpProjectStorageToggleEnabled": false, "isRosToggleEnabled": false, - "isSettingsPlatformToggleEnabled": false, - "isTagMappingToggleEnabled": false, } `; diff --git a/src/store/featureToggle/featureToggle.test.ts b/src/store/featureToggle/featureToggle.test.ts index 8ce3f24a5..7ff31eb53 100644 --- a/src/store/featureToggle/featureToggle.test.ts +++ b/src/store/featureToggle/featureToggle.test.ts @@ -20,12 +20,6 @@ test('AWS EC2 instances feature is enabled', async () => { expect(FeatureToggleSelectors.selectIsAwsEc2InstancesToggleEnabled(store.getState())).toBe(true); }); -test('Cloud info feature is enabled', async () => { - const store = createUIStore(); - store.dispatch(actions.setFeatureToggle({ isClusterInfoToggleEnabled: true })); - expect(FeatureToggleSelectors.selectIsClusterInfoToggleEnabled(store.getState())).toBe(true); -}); - test('Debug feature is enabled', async () => { const store = createUIStore(); store.dispatch(actions.setFeatureToggle({ isDebugToggleEnabled: true })); @@ -67,15 +61,3 @@ test('ROS feature is enabled', async () => { store.dispatch(actions.setFeatureToggle({ isRosToggleEnabled: true })); expect(FeatureToggleSelectors.selectIsRosToggleEnabled(store.getState())).toBe(true); }); - -test('Settings platform feature is enabled', async () => { - const store = createUIStore(); - store.dispatch(actions.setFeatureToggle({ isSettingsPlatformToggleEnabled: true })); - expect(FeatureToggleSelectors.selectIsSettingsPlatformToggleEnabled(store.getState())).toBe(true); -}); - -test('Tag mapping feature is enabled', async () => { - const store = createUIStore(); - store.dispatch(actions.setFeatureToggle({ isTagMappingToggleEnabled: true })); - expect(FeatureToggleSelectors.selectIsTagMappingToggleEnabled(store.getState())).toBe(true); -}); diff --git a/src/store/featureToggle/featureToggleActions.ts b/src/store/featureToggle/featureToggleActions.ts index 436f4fc21..c5f487069 100644 --- a/src/store/featureToggle/featureToggleActions.ts +++ b/src/store/featureToggle/featureToggleActions.ts @@ -2,7 +2,6 @@ import { createAction } from 'typesafe-actions'; export interface FeatureToggleActionMeta { isAwsEc2InstancesToggleEnabled?: boolean; - isClusterInfoToggleEnabled?: boolean; isDebugToggleEnabled?: boolean; isExportsToggleEnabled?: boolean; isFinsightsToggleEnabled?: boolean; @@ -10,8 +9,6 @@ export interface FeatureToggleActionMeta { isOcpCloudNetworkingToggleEnabled?: boolean; isOcpProjectStorageToggleEnabled?: boolean; isRosToggleEnabled?: boolean; - isSettingsPlatformToggleEnabled?: boolean; - isTagMappingToggleEnabled?: boolean; } export const setFeatureToggle = createAction('feature/init_feature_toggle')(); diff --git a/src/store/featureToggle/featureToggleReducer.ts b/src/store/featureToggle/featureToggleReducer.ts index 65a1dd56f..68222df27 100644 --- a/src/store/featureToggle/featureToggleReducer.ts +++ b/src/store/featureToggle/featureToggleReducer.ts @@ -9,7 +9,6 @@ export type FeatureToggleAction = ActionType; export const defaultState: FeatureToggleState = { hasFeatureToggle: false, isAwsEc2InstancesToggleEnabled: false, - isClusterInfoToggleEnabled: false, isDebugToggleEnabled: false, isExportsToggleEnabled: false, isFinsightsToggleEnabled: false, @@ -32,8 +28,6 @@ export const defaultState: FeatureToggleState = { isOcpCloudNetworkingToggleEnabled: false, isOcpProjectStorageToggleEnabled: false, isRosToggleEnabled: false, - isSettingsPlatformToggleEnabled: false, - isTagMappingToggleEnabled: false, }; export const stateKey = 'FeatureToggle'; @@ -45,7 +39,6 @@ export function FeatureToggleReducer(state = defaultState, action: FeatureToggle ...state, hasFeatureToggle: true, isAwsEc2InstancesToggleEnabled: action.payload.isAwsEc2InstancesToggleEnabled, - isClusterInfoToggleEnabled: action.payload.isClusterInfoToggleEnabled, isDebugToggleEnabled: action.payload.isDebugToggleEnabled, isExportsToggleEnabled: action.payload.isExportsToggleEnabled, isFinsightsToggleEnabled: action.payload.isFinsightsToggleEnabled, @@ -53,8 +46,6 @@ export function FeatureToggleReducer(state = defaultState, action: FeatureToggle isOcpCloudNetworkingToggleEnabled: action.payload.isOcpCloudNetworkingToggleEnabled, isOcpProjectStorageToggleEnabled: action.payload.isOcpProjectStorageToggleEnabled, isRosToggleEnabled: action.payload.isRosToggleEnabled, - isSettingsPlatformToggleEnabled: action.payload.isSettingsPlatformToggleEnabled, - isTagMappingToggleEnabled: action.payload.isTagMappingToggleEnabled, }; default: diff --git a/src/store/featureToggle/featureToggleSelectors.ts b/src/store/featureToggle/featureToggleSelectors.ts index 7e3a5f813..3e5771cdd 100644 --- a/src/store/featureToggle/featureToggleSelectors.ts +++ b/src/store/featureToggle/featureToggleSelectors.ts @@ -8,8 +8,6 @@ export const selectHasFeatureToggle = (state: RootState) => selectFeatureToggleS export const selectIsAwsEc2InstancesToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isAwsEc2InstancesToggleEnabled; -export const selectIsClusterInfoToggleEnabled = (state: RootState) => - selectFeatureToggleState(state).isClusterInfoToggleEnabled; export const selectIsDebugToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isDebugToggleEnabled; export const selectIsExportsToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isExportsToggleEnabled; @@ -21,7 +19,3 @@ export const selectIsOcpCloudNetworkingToggleEnabled = (state: RootState) => export const selectIsOcpProjectStorageToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isOcpProjectStorageToggleEnabled; export const selectIsRosToggleEnabled = (state: RootState) => selectFeatureToggleState(state).isRosToggleEnabled; -export const selectIsSettingsPlatformToggleEnabled = (state: RootState) => - selectFeatureToggleState(state).isSettingsPlatformToggleEnabled; -export const selectIsTagMappingToggleEnabled = (state: RootState) => - selectFeatureToggleState(state).isTagMappingToggleEnabled; From 5f5f3e1f8cd3c8b301f5caf05465b8870072ee9d Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 18 Apr 2024 15:18:48 -0400 Subject: [PATCH 03/49] Ensure cluster info providers have unique keys --- .../providerDetails/clusterInfo/clusterInfoContent.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/details/ocpBreakdown/providerDetails/clusterInfo/clusterInfoContent.tsx b/src/routes/details/ocpBreakdown/providerDetails/clusterInfo/clusterInfoContent.tsx index 135b7b028..eb2403d69 100644 --- a/src/routes/details/ocpBreakdown/providerDetails/clusterInfo/clusterInfoContent.tsx +++ b/src/routes/details/ocpBreakdown/providerDetails/clusterInfo/clusterInfoContent.tsx @@ -92,11 +92,11 @@ const ClusterInfoContent: React.FC = ({ clusterId }: Cl {clusterProvider?.cost_models?.length ? ( - clusterProvider.cost_models.map(cm => ( - <> + clusterProvider.cost_models.map((cm, index) => ( + {intl.formatMessage(messages.costModel)} {cm.name} - + )) ) : ( {intl.formatMessage(messages.assignCostModel)} From 56fa7ca438a77b35d9d76833573b850fb7b01b86 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 3 Apr 2024 10:44:52 -0400 Subject: [PATCH 04/49] PatternFly milestone update --- package-lock.json | 183 ++++++++++++++++++++++------------------------ package.json | 20 ++--- 2 files changed, 99 insertions(+), 104 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce55ef877..e2ae1d50f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,14 +10,14 @@ "hasInstallScript": true, "license": "GNU AGPLv3", "dependencies": { - "@patternfly/patternfly": "5.2.0", - "@patternfly/react-charts": "7.2.2", - "@patternfly/react-component-groups": "5.1.0", - "@patternfly/react-core": "5.2.0", - "@patternfly/react-icons": "5.2.0", - "@patternfly/react-table": "5.2.0", - "@patternfly/react-tokens": "5.2.0", - "@redhat-cloud-services/frontend-components": "^4.2.6", + "@patternfly/patternfly": "^5.3.0", + "@patternfly/react-charts": "^7.3.0", + "@patternfly/react-component-groups": "^5.1.0", + "@patternfly/react-core": "^5.3.0", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-table": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", + "@redhat-cloud-services/frontend-components": "^4.2.7", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", @@ -47,7 +47,7 @@ "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.12", "@redhat-cloud-services/tsc-transform-imports": "^1.0.9", - "@swc/core": "^1.4.14", + "@swc/core": "^1.4.16", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^15.0.2", @@ -67,7 +67,7 @@ "eslint-plugin-jest-dom": "^5.2.0", "eslint-plugin-jsdoc": "^48.2.3", "eslint-plugin-markdown": "^4.0.1", - "eslint-plugin-patternfly-react": "^5.2.1", + "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-react": "^7.34.1", "eslint-plugin-simple-import-sort": "^12.1.0", @@ -2215,17 +2215,17 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@patternfly/patternfly": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.2.0.tgz", - "integrity": "sha512-phdsXcCRO+JICFXIKtORxSbOWoBr9zRCgtFTKTJ8hAIzm6wEUCdcHZrvsd+SXNR3q/4b/+KlmHUC4Q4KGUiuYw==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.3.0.tgz", + "integrity": "sha512-93uWA15bOJDgu8NF2iReWbbNtWdtM+v7iaDpK33mJChgej+whiFpGLtQPI2jFk1aVW3rDpbt4qm4OaNinpzSsg==" }, "node_modules/@patternfly/react-charts": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-7.2.2.tgz", - "integrity": "sha512-1PFuvXz3mm/o/O+BQ2/2e66ncvtV8XIYxFaimurslCLTygodOvjBDDu/D/5tNa3HLxvA+fm2Q58893POGZi+bw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-7.3.0.tgz", + "integrity": "sha512-J6d/bFolI3zUOvJoK4lEveNeXZeJNfBq+iXgQ/mImESyW0H7MSebMcVB4d+NC6JX0QykuaOEn/7YMJMU9K73tw==", "dependencies": { - "@patternfly/react-styles": "^5.2.1", - "@patternfly/react-tokens": "^5.2.1", + "@patternfly/react-styles": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "hoist-non-react-statics": "^3.3.0", "lodash": "^4.17.21", "tslib": "^2.5.0", @@ -2252,11 +2252,6 @@ "react-dom": "^17 || ^18" } }, - "node_modules/@patternfly/react-charts/node_modules/@patternfly/react-tokens": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.2.1.tgz", - "integrity": "sha512-8GYz/jnJTGAWUJt5eRAW5dtyiHPKETeFJBPGHaUQnvi/t1ZAkoy8i4Kd/RlHsDC7ktiu813SKCmlzwBwldAHKg==" - }, "node_modules/@patternfly/react-charts/node_modules/victory-core": { "version": "36.9.2", "resolved": "https://registry.npmjs.org/victory-core/-/victory-core-36.9.2.tgz", @@ -2287,13 +2282,13 @@ } }, "node_modules/@patternfly/react-core": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.2.0.tgz", - "integrity": "sha512-AUd7jccCgE2ZRwVtpEbJNF2Sq1A//ZhRaEQ/QHZiiq8mQRQM0Bkpnx0HdefToZT+TgUIjmPW4AXO3ooRJmt26w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.3.0.tgz", + "integrity": "sha512-nMf8yrul3u+4+ch7IMsE+/3Rzmor8/yEUk8zzD9bYGRxjwniu1RqCF8NdgPvMw2C7Hz7xtpwsgXDfG4n8qd12g==", "dependencies": { - "@patternfly/react-icons": "^5.2.0", - "@patternfly/react-styles": "^5.2.0", - "@patternfly/react-tokens": "^5.2.0", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-styles": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "focus-trap": "7.5.2", "react-dropzone": "^14.2.3", "tslib": "^2.5.0" @@ -2304,28 +2299,28 @@ } }, "node_modules/@patternfly/react-icons": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.2.0.tgz", - "integrity": "sha512-vklAF2unvtK0trwx9Kk8nf4Xa2+nie4zxaIaQdnjIL7kX6a5SdsewDjlavOC3cRxnibZLQ5HQtpDZ4EmuXm8DQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-oBdaK4Gz7yivNE7jQg46sPzfZakg7oxo5aSMLc0N6haOmDEegiTurNex+h+/z0oBPqzZC+cIQRaBeXEgXGwc9Q==", "peerDependencies": { "react": "^17 || ^18", "react-dom": "^17 || ^18" } }, "node_modules/@patternfly/react-styles": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.2.1.tgz", - "integrity": "sha512-GT96hzI1QenBhq6Pfc51kxnj9aVLjL1zSLukKZXcYVe0HPOy0BFm90bT1Fo4e/z7V9cDYw4SqSX1XLc3O4jsTw==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.3.0.tgz", + "integrity": "sha512-/EdkURW+v7Rzw/CiEqL+NfGtLvLMGIwOEyDhvlMDbRip2usGw4HLZv3Bep0cJe29zOeY27cDVZDM1HfyXLebtw==" }, "node_modules/@patternfly/react-table": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.2.0.tgz", - "integrity": "sha512-Pd+llSuAU9i1dvteQL1keEXmsQv6d8x4+F2arqGQS1umeOR3lvvycyFac1OboJ4oV2rAX97GVmtZdoJjaqxdhg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.3.0.tgz", + "integrity": "sha512-DuylKyUA/D6Jzk7t6VU8SzbABjaKra2+O4G99Zt7EyEuhcDP3dfb+AcL5yg7CLx4/v2fexzum+dLGZVMvqzSUQ==", "dependencies": { - "@patternfly/react-core": "^5.2.0", - "@patternfly/react-icons": "^5.2.0", - "@patternfly/react-styles": "^5.2.0", - "@patternfly/react-tokens": "^5.2.0", + "@patternfly/react-core": "^5.3.0", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-styles": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "lodash": "^4.17.19", "tslib": "^2.5.0" }, @@ -2335,9 +2330,9 @@ } }, "node_modules/@patternfly/react-tokens": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.2.0.tgz", - "integrity": "sha512-ZsrLpStHJQfvUJLIXT+cObJbA3jM4r9iWwULLva0s7DzznXJ6iIACQQfgwDtcSVyM95z5S1a/LHPj/wYgaqUIg==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.3.0.tgz", + "integrity": "sha512-24ZY5hgwt11InW3XtINM5p9Fo1hDiVor6Q4uphPZh8Mt89AsZZw1UweTaGg54I0Ah2Wzv6rkQy51LX7tZtIwjQ==" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -2472,9 +2467,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.6.tgz", - "integrity": "sha512-ErM9sWQUQpKwdKBOQlDBFI6IHyi3mRzTZ3wYJ57pouTzQzOhPozsIpPsPgB2gN/88khenjFEy+7SYuIZDaH5TA==", + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.7.tgz", + "integrity": "sha512-HHxkSep0HvkfZSD1ZvfzCVuw6u6rXPsznTyvkHIRJfeaoF5WkMCvGSw0+mwGA94tCj5jKkXgUjRSHAp94PFUfw==", "dependencies": { "@patternfly/react-component-groups": "^5.0.0", "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", @@ -3198,9 +3193,9 @@ } }, "node_modules/@swc/core": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.14.tgz", - "integrity": "sha512-tHXg6OxboUsqa/L7DpsCcFnxhLkqN/ht5pCwav1HnvfthbiNIJypr86rNx4cUnQDJepETviSqBTIjxa7pSpGDQ==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.16.tgz", + "integrity": "sha512-Xaf+UBvW6JNuV131uvSNyMXHn+bh6LyKN4tbv7tOUFQpXyz/t9YWRE04emtlUW9Y0qrm/GKFCbY8n3z6BpZbTA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3215,16 +3210,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.4.14", - "@swc/core-darwin-x64": "1.4.14", - "@swc/core-linux-arm-gnueabihf": "1.4.14", - "@swc/core-linux-arm64-gnu": "1.4.14", - "@swc/core-linux-arm64-musl": "1.4.14", - "@swc/core-linux-x64-gnu": "1.4.14", - "@swc/core-linux-x64-musl": "1.4.14", - "@swc/core-win32-arm64-msvc": "1.4.14", - "@swc/core-win32-ia32-msvc": "1.4.14", - "@swc/core-win32-x64-msvc": "1.4.14" + "@swc/core-darwin-arm64": "1.4.16", + "@swc/core-darwin-x64": "1.4.16", + "@swc/core-linux-arm-gnueabihf": "1.4.16", + "@swc/core-linux-arm64-gnu": "1.4.16", + "@swc/core-linux-arm64-musl": "1.4.16", + "@swc/core-linux-x64-gnu": "1.4.16", + "@swc/core-linux-x64-musl": "1.4.16", + "@swc/core-win32-arm64-msvc": "1.4.16", + "@swc/core-win32-ia32-msvc": "1.4.16", + "@swc/core-win32-x64-msvc": "1.4.16" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -3236,9 +3231,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.14.tgz", - "integrity": "sha512-8iPfLhYNspBl836YYsfv6ErXwDUqJ7IMieddV3Ey/t/97JAEAdNDUdtTKDtbyP0j/Ebyqyn+fKcqwSq7rAof0g==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.16.tgz", + "integrity": "sha512-UOCcH1GvjRnnM/LWT6VCGpIk0OhHRq6v1U6QXuPt5wVsgXnXQwnf5k3sG5Cm56hQHDvhRPY6HCsHi/p0oek8oQ==", "cpu": [ "arm64" ], @@ -3252,9 +3247,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.14.tgz", - "integrity": "sha512-9CqSj8uRZ92cnlgAlVaWMaJJBdxtNvCzJxaGj5KuIseeG6Q0l1g+qk8JcU7h9dAsH9saHTNwNFBVGKQo0W0ujg==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.16.tgz", + "integrity": "sha512-t3bgqFoYLWvyVtVL6KkFNCINEoOrIlyggT/kJRgi1y0aXSr0oVgcrQ4ezJpdeahZZ4N+Q6vT3ffM30yIunELNA==", "cpu": [ "x64" ], @@ -3268,9 +3263,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.14.tgz", - "integrity": "sha512-mfd5JArPITTzMjcezH4DwMw+BdjBV1y25Khp8itEIpdih9ei+fvxOOrDYTN08b466NuE2dF2XuhKtRLA7fXArQ==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.16.tgz", + "integrity": "sha512-DvHuwvEF86YvSd0lwnzVcjOTZ0jcxewIbsN0vc/0fqm9qBdMMjr9ox6VCam1n3yYeRtj4VFgrjeNFksqbUejdQ==", "cpu": [ "arm" ], @@ -3284,9 +3279,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.14.tgz", - "integrity": "sha512-3Lqlhlmy8MVRS9xTShMaPAp0oyUt0KFhDs4ixJsjdxKecE0NJSV/MInuDmrkij1C8/RQ2wySRlV9np5jK86oWw==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.16.tgz", + "integrity": "sha512-9Uu5YlPbyCvbidjKtYEsPpyZlu16roOZ5c2tP1vHfnU9bgf5Tz5q5VovSduNxPHx+ed2iC1b1URODHvDzbbDuQ==", "cpu": [ "arm64" ], @@ -3300,9 +3295,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.14.tgz", - "integrity": "sha512-n0YoCa64TUcJrbcXIHIHDWQjdUPdaXeMHNEu7yyBtOpm01oMGTKP3frsUXIABLBmAVWtKvqit4/W1KVKn5gJzg==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.16.tgz", + "integrity": "sha512-/YZq/qB1CHpeoL0eMzyqK5/tYZn/rzKoCYDviFU4uduSUIJsDJQuQA/skdqUzqbheOXKAd4mnJ1hT04RbJ8FPQ==", "cpu": [ "arm64" ], @@ -3316,9 +3311,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.14.tgz", - "integrity": "sha512-CGmlwLWbfG1dB4jZBJnp2IWlK5xBMNLjN7AR5kKA3sEpionoccEnChOEvfux1UdVJQjLRKuHNV9yGyqGBTpxfQ==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.16.tgz", + "integrity": "sha512-UUjaW5VTngZYDcA8yQlrFmqs1tLi1TxbKlnaJwoNhel9zRQ0yG1YEVGrzTvv4YApSuIiDK18t+Ip927bwucuVQ==", "cpu": [ "x64" ], @@ -3332,9 +3327,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.14.tgz", - "integrity": "sha512-xq4npk8YKYmNwmr8fbvF2KP3kUVdZYfXZMQnW425gP3/sn+yFQO8Nd0bGH40vOVQn41kEesSe0Z5O/JDor2TgQ==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.16.tgz", + "integrity": "sha512-aFhxPifevDTwEDKPi4eRYWzC0p/WYJeiFkkpNU5Uc7a7M5iMWPAbPFUbHesdlb9Jfqs5c07oyz86u+/HySBNPQ==", "cpu": [ "x64" ], @@ -3348,9 +3343,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.14.tgz", - "integrity": "sha512-imq0X+gU9uUe6FqzOQot5gpKoaC00aCUiN58NOzwp0QXEupn8CDuZpdBN93HiZswfLruu5jA1tsc15x6v9p0Yg==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.16.tgz", + "integrity": "sha512-bTD43MbhIHL2s5QgCwyleaGwl96Gk/scF2TaVKdUe4QlJCDV/YK9h5oIBAp63ckHtE8GHlH4c8dZNBiAXn4Org==", "cpu": [ "arm64" ], @@ -3364,9 +3359,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.14.tgz", - "integrity": "sha512-cH6QpXMw5D3t+lpx6SkErHrxN0yFzmQ0lgNAJxoDRiaAdDbqA6Col8UqUJwUS++Ul6aCWgNhCdiEYehPaoyDPA==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.16.tgz", + "integrity": "sha512-/lmZeAN/qV5XbK2SEvi8e2RkIg8FQNYiSA8y2/Zb4gTUMKVO5JMLH0BSWMiIKMstKDPDSxMWgwJaQHF8UMyPmQ==", "cpu": [ "ia32" ], @@ -3380,9 +3375,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.14.tgz", - "integrity": "sha512-FmZ4Tby4wW65K/36BKzmuu7mlq7cW5XOxzvufaSNVvQ5PN4OodAlqPjToe029oma4Av+ykJiif64scMttyNAzg==", + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.16.tgz", + "integrity": "sha512-BPAfFfODWXtUu6SwaTTftDHvcbDyWBSI/oanUeRbQR5vVWkXoQ3cxLTsDluc3H74IqXS5z1Uyoe0vNo2hB1opA==", "cpu": [ "x64" ], @@ -9770,9 +9765,9 @@ } }, "node_modules/eslint-plugin-patternfly-react": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-patternfly-react/-/eslint-plugin-patternfly-react-5.2.1.tgz", - "integrity": "sha512-eddeSWQcW9BKALW8Ft+7QA8xs3Hbf5YbW09CeOaD5Zdoc3K0PGwfinQkLAeShYQ4Q00266ZUV6jMGhG0pjzmvA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-patternfly-react/-/eslint-plugin-patternfly-react-5.3.0.tgz", + "integrity": "sha512-6i/13l7NLUcjTvtgvZ5GUF6b/jwcjKK97MkvsLU5sw66Vh2Bk/R+eC5AjMF9fz9g2saRB/wBt1PiZMlYo+QX6Q==", "dev": true, "dependencies": { "@babel/eslint-parser": "^7.19.1", diff --git a/package.json b/package.json index 0c0bc932e..f42ad39cb 100644 --- a/package.json +++ b/package.json @@ -50,14 +50,14 @@ "verify": "npm-run-all build lint test" }, "dependencies": { - "@patternfly/patternfly": "5.2.0", - "@patternfly/react-charts": "7.2.2", - "@patternfly/react-component-groups": "5.1.0", - "@patternfly/react-core": "5.2.0", - "@patternfly/react-icons": "5.2.0", - "@patternfly/react-table": "5.2.0", - "@patternfly/react-tokens": "5.2.0", - "@redhat-cloud-services/frontend-components": "^4.2.6", + "@patternfly/patternfly": "^5.3.0", + "@patternfly/react-charts": "^7.3.0", + "@patternfly/react-component-groups": "^5.1.0", + "@patternfly/react-core": "^5.3.0", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-table": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", + "@redhat-cloud-services/frontend-components": "^4.2.7", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", @@ -87,7 +87,7 @@ "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.12", "@redhat-cloud-services/tsc-transform-imports": "^1.0.9", - "@swc/core": "^1.4.14", + "@swc/core": "^1.4.16", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^15.0.2", @@ -107,7 +107,7 @@ "eslint-plugin-jest-dom": "^5.2.0", "eslint-plugin-jsdoc": "^48.2.3", "eslint-plugin-markdown": "^4.0.1", - "eslint-plugin-patternfly-react": "^5.2.1", + "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-react": "^7.34.1", "eslint-plugin-simple-import-sort": "^12.1.0", From 95e29b4a4367ed099ee98713da6eab3464c53d81 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Fri, 5 Apr 2024 21:39:57 -0400 Subject: [PATCH 05/49] Remove bulk select workaround https://issues.redhat.com/browse/COST-4596 --- .../dataToolbar/utils/bulkSelect.tsx | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/routes/components/dataToolbar/utils/bulkSelect.tsx b/src/routes/components/dataToolbar/utils/bulkSelect.tsx index 988a167e5..d3ae8a324 100644 --- a/src/routes/components/dataToolbar/utils/bulkSelect.tsx +++ b/src/routes/components/dataToolbar/utils/bulkSelect.tsx @@ -61,14 +61,11 @@ export const getBulkSelect = ({ ); } - // Todo: Work around to allow clicking on "10 selected" label shown in MenuToggleCheckbox - // See https://github.com/patternfly/patternfly-react/issues/10035 - const getSelectedLabel = () => { - return anySelected ? ( - onBulkSelectToggle(!isBulkSelectOpen)}> - {intl.formatMessage(messages.selected, { value: numSelected })} - - ) : null; + const handleOnBulkSelectClicked = (checked: boolean) => { + if (onBulkSelectClicked) { + checked ? onBulkSelectClicked('all') : onBulkSelectClicked('none'); + } + onBulkSelectToggle(false); }; const toggle = toggleRef => { @@ -87,15 +84,13 @@ export const getBulkSelect = ({ anySelected ? messages.toolBarBulkSelectAriaDeselect : messages.toolBarBulkSelectAriaSelect )} isChecked={isChecked} - onChange={() => { - anySelected ? onBulkSelectClicked('none') : onBulkSelectClicked('all'); - }} - > - {getSelectedLabel()} - , + onChange={handleOnBulkSelectClicked} + />, ], }} - /> + > + {anySelected ? intl.formatMessage(messages.selected, { value: numSelected }) : null} + ); }; From 87bde8d85bb11f3bf4d2b97cb03effdc176e4957 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Fri, 5 Apr 2024 21:41:39 -0400 Subject: [PATCH 06/49] Replace remaining deprecated PatternFly Select component https://issues.redhat.com/browse/COST-4585 --- .../selectWrapper/selectWrapper.tsx | 28 ++++-- .../components/addPriceList.test.tsx | 16 ++-- .../costModels/components/inputs/selector.tsx | 94 +++++++++---------- .../components/rateForm/rateForm.tsx | 6 +- .../costModels/costModel/addRateModal.tsx | 1 + .../costModels/costModel/updateCostModel.tsx | 4 +- .../costModel/updateRateModel.test.tsx | 10 +- .../costModels/costModel/updateRateModel.tsx | 4 +- .../costModelWizard/costModelWizard.tsx | 1 + .../costModelWizard/generalInformation.tsx | 8 +- 10 files changed, 96 insertions(+), 76 deletions(-) diff --git a/src/routes/components/selectWrapper/selectWrapper.tsx b/src/routes/components/selectWrapper/selectWrapper.tsx index 27f5245c6..42478553d 100644 --- a/src/routes/components/selectWrapper/selectWrapper.tsx +++ b/src/routes/components/selectWrapper/selectWrapper.tsx @@ -12,30 +12,40 @@ export interface SelectWrapperOption { } interface SelectWrapperOwnProps { + appendTo?: HTMLElement | (() => HTMLElement) | 'inline' | 'parent'; ariaLabel?: string; className?: string; + direction?: 'up' | 'down'; id?: string; isDisabled?: boolean; + maxMenuHeight?: string; onSelect?: (event, value: SelectWrapperOption) => void; placeholder?: string; options?: SelectWrapperOption[]; position?: 'right' | 'left' | 'center' | 'start' | 'end'; selection?: string | SelectWrapperOption; + status?: 'success' | 'warning' | 'danger'; + toggleAriaLabel?: string; toggleIcon?: React.ReactNode; } type SelectWrapperProps = SelectWrapperOwnProps; const SelectWrapper: React.FC = ({ + appendTo, ariaLabel, className, + direction, id, isDisabled, + maxMenuHeight, onSelect = () => {}, options, placeholder = null, position, selection, + status, + toggleAriaLabel, toggleIcon, }) => { const [isOpen, setIsOpen] = useState(false); @@ -72,28 +82,34 @@ const SelectWrapper: React.FC = ({ const toggle = toggleRef => ( {toggleIcon}} isDisabled={isDisabled} isExpanded={isOpen} + isFullWidth onClick={handleOnToggle} ref={toggleRef} + status={status} > {getPlaceholder()} ); return ( -
+
{ - setSelection(sel); - onChange(null, sel.value); - setIsOpen(false); - }} - onToggle={() => setIsOpen(!isOpen)} - selections={selection} - validated={isInvalid ? 'error' : 'default'} - > - {getSelectorOptions().map(opt => ( - - ))} - + /> {isInvalid && typeof helpText === 'object' && ( {intl.formatMessage(helpText)} diff --git a/src/routes/settings/costModels/components/rateForm/rateForm.tsx b/src/routes/settings/costModels/components/rateForm/rateForm.tsx index 69ec14508..cf0f47f4b 100644 --- a/src/routes/settings/costModels/components/rateForm/rateForm.tsx +++ b/src/routes/settings/costModels/components/rateForm/rateForm.tsx @@ -113,7 +113,7 @@ const RateFormBase: React.FC = ({ currencyUnits, intl = defaultIn label={intl.formatMessage(messages.metric)} placeholderText={intl.formatMessage(messages.select)} value={metric} - onChange={(_evt, value) => setMetric(value)} + onSelect={(_evt, value) => setMetric(value)} options={[ ...metricOptions.map(opt => { return { @@ -140,8 +140,8 @@ const RateFormBase: React.FC = ({ currencyUnits, intl = defaultIn ? measurement : getMeasurementLabel(measurement, metricsHash[metric][measurement].label_measurement_unit) } - onChange={(_evt, value) => setMeasurement(value)} - placeholderText="Select..." + onSelect={(_evt, value) => setMeasurement(value)} + placeholderText={intl.formatMessage(messages.select)} options={[ ...measurementOptions.map(opt => { const unit = metricsHash[metric][opt].label_measurement_unit; diff --git a/src/routes/settings/costModels/costModel/addRateModal.tsx b/src/routes/settings/costModels/costModel/addRateModal.tsx index d13ac5fcd..335c6de4e 100644 --- a/src/routes/settings/costModels/costModel/addRateModal.tsx +++ b/src/routes/settings/costModels/costModel/addRateModal.tsx @@ -60,6 +60,7 @@ export const AddRateModalBase: React.FC = ({ return ( this.setState({ currency: value })} + onSelect={(_evt, value) => this.setState({ currency: value })} id="currency-units-selector" options={currencyOptions.map(o => { return { diff --git a/src/routes/settings/costModels/costModel/updateRateModel.test.tsx b/src/routes/settings/costModels/costModel/updateRateModel.test.tsx index f0472967e..ca693373e 100644 --- a/src/routes/settings/costModels/costModel/updateRateModel.test.tsx +++ b/src/routes/settings/costModels/costModel/updateRateModel.test.tsx @@ -267,13 +267,17 @@ describe('update-rate', () => { test('Description', async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + render(); + const descInput = screen.getByDisplayValue('openshift-aws-node'); const saveButton = screen.getByText(regExp(messages.save)); expect(saveButton.getAttribute('disabled')).not.toBeNull(); + await act(async () => user.clear(descInput)); await act(async () => user.type(descInput, 'a new description')); expect(saveButton.getAttribute('disabled')).toBeNull(); + await act(async () => user.clear(descInput)); await act(async () => user.type(descInput, 'openshift-aws-node')); expect(saveButton.getAttribute('disabled')).not.toBeNull(); @@ -282,7 +286,9 @@ describe('update-rate', () => { test('Select Measurement', async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); let options = null; + render(); + const saveButton = screen.getByText(regExp(messages.save)); await act(async () => user.click(screen.getByLabelText('Select Measurement'))); @@ -303,7 +309,7 @@ describe('update-rate', () => { await act(async () => user.click(screen.getByLabelText('Select Measurement'))); options = await screen.findAllByRole('option'); - await act(async () => user.click(options[0])); + await act(async () => user.click(options[5])); // Previous select options are not being removed from page expect(saveButton.getAttribute('disabled')).toBeNull(); @@ -316,7 +322,7 @@ describe('update-rate', () => { await act(async () => user.click(options[0])); expect(saveButton.getAttribute('disabled')).not.toBeNull(); - }); + }, 7000); test('regular', async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); diff --git a/src/routes/settings/costModels/costModel/updateRateModel.tsx b/src/routes/settings/costModels/costModel/updateRateModel.tsx index f8ce9511e..b57dcf706 100644 --- a/src/routes/settings/costModels/costModel/updateRateModel.tsx +++ b/src/routes/settings/costModels/costModel/updateRateModel.tsx @@ -99,8 +99,10 @@ const UpdateRateModalBase: React.FC = ({ ) ); }, [isOpen]); + return ( = ({ key="proceed" variant="primary" onClick={onProceed} - isDisabled={!canSubmit || isProcessing || !gotDiffs} + isDisabled={isProcessing || !canSubmit || !gotDiffs} > {intl.formatMessage(messages.save)} , diff --git a/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx b/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx index 76a0bae82..0b300c5b4 100644 --- a/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx +++ b/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx @@ -93,6 +93,7 @@ const InternalWizardBase: React.FC = ({ return isOpen ? ( { id="source-type-selector" direction="up" appendMenuTo="inline" - maxHeight={styles.selector.maxHeight} + maxMenuHeight={styles.selector.maxHeight as string} label={messages.sourceType} toggleAriaLabel={intl.formatMessage(messages.costModelsWizardEmptySourceTypeLabel)} placeholderText={intl.formatMessage(messages.costModelsWizardEmptySourceTypeLabel)} value={getValueLabel(type, sourceTypeOptions)} - onChange={(_evt, value) => onTypeChange(value)} + onSelect={(_evt, value) => onTypeChange(value)} options={sourceTypeOptions} /> onCurrencyChange(value)} + onSelect={(_evt, value) => onCurrencyChange(value)} id="currency-units-selector" options={currencyOptions.map(o => { return { From 8a9c0626b6d79c5a1492de86568b1bea115b8212 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Sat, 20 Apr 2024 21:30:15 -0400 Subject: [PATCH 07/49] Update Unleash toggles --- src/components/featureToggle/featureToggle.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/featureToggle/featureToggle.tsx b/src/components/featureToggle/featureToggle.tsx index a44ca2bba..b0bc08853 100644 --- a/src/components/featureToggle/featureToggle.tsx +++ b/src/components/featureToggle/featureToggle.tsx @@ -14,7 +14,7 @@ export const enum FeatureToggle { ocpCloudNetworking = 'cost-management.ui.ocp-cloud-networking', // https://issues.redhat.com/browse/COST-4781 ocpProjectStorage = 'cost-management.ui.ocp-project-storage', // https://issues.redhat.com/browse/COST-4856 ros = 'cost-management.ui.ros', // ROS support https://issues.redhat.com/browse/COST-3477 - rosBeta = 'cost-management.ui.ros-beta', // ROS support https://issues.redhat.com/browse/COST-3477 + rosPreview = 'cost-management.ui.ros-preview', // ROS support https://issues.redhat.com/browse/COST-3477 } const useIsToggleEnabled = (toggle: FeatureToggle) => { @@ -53,8 +53,8 @@ export const useIsOcpProjectStorageToggleEnabled = () => { export const useIsRosToggleEnabled = () => { const { isBeta } = useChrome(); const isRosToggleEnabled = useIsToggleEnabled(FeatureToggle.ros); - const isRosFeatureBetaEnabled = useIsToggleEnabled(FeatureToggle.rosBeta) && isBeta(); // Enabled for prod-beta - return isRosToggleEnabled || isRosFeatureBetaEnabled; + const isRosFeaturePreviewEnabled = useIsToggleEnabled(FeatureToggle.rosPreview) && isBeta(); // Enabled for prod-beta + return isRosToggleEnabled || isRosFeaturePreviewEnabled; }; // The FeatureToggle component saves feature toggles in store for places where Unleash hooks not available From 77480c73b95d1287b3f48bbb68c19a944f10b8a1 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Sat, 20 Apr 2024 23:17:45 -0400 Subject: [PATCH 08/49] Added cost model support for network and storage costs https://issues.redhat.com/browse/COST-4781 https://issues.redhat.com/browse/COST-4856 --- locales/data.json | 111 ++++++++++++++++- locales/translations.json | 9 +- src/api/costModels.ts | 4 + src/locales/messages.ts | 39 +++++- .../costModels/components/rateForm/utils.tsx | 2 + .../costModels/costModel/distribution.tsx | 23 +++- .../costModel/updateDistributionDialog.tsx | 114 +++++++++++++++++- .../costModels/costModelWizard/context.ts | 4 + .../costModelWizard/costModelWizard.tsx | 20 +++ .../costModelWizard/distribution.tsx | 95 +++++++++++++-- .../costModels/costModelWizard/review.tsx | 37 +++++- 11 files changed, 427 insertions(+), 31 deletions(-) diff --git a/locales/data.json b/locales/data.json index d6f7e0a86..8d404f1a2 100644 --- a/locales/data.json +++ b/locales/data.json @@ -3439,6 +3439,91 @@ } ], "distributeCosts": [ + { + "options": { + "false": { + "value": [ + { + "type": 0, + "value": "Do not distribute " + }, + { + "options": { + "network": { + "value": [ + { + "type": 0, + "value": "network" + } + ] + }, + "other": { + "value": [] + }, + "storage": { + "value": [ + { + "type": 0, + "value": "storage" + } + ] + } + }, + "type": 5, + "value": "type" + }, + { + "type": 0, + "value": " costs" + } + ] + }, + "other": { + "value": [] + }, + "true": { + "value": [ + { + "type": 0, + "value": "Distribute " + }, + { + "options": { + "network": { + "value": [ + { + "type": 0, + "value": "network" + } + ] + }, + "other": { + "value": [] + }, + "storage": { + "value": [ + { + "type": 0, + "value": "storage" + } + ] + } + }, + "type": 5, + "value": "type" + }, + { + "type": 0, + "value": " costs" + } + ] + } + }, + "type": 5, + "value": "value" + } + ], + "distributeUnallocatedCapacity": [ { "options": { "false": { @@ -3526,7 +3611,7 @@ "distributionModelDesc": [ { "type": 0, - "value": "This choice is for users to direct how their raw costs are distributed either by CPU or Memory on the project level breakdowns." + "value": "Choose how your raw costs are distributed at the project level." } ], "distributionType": [ @@ -10317,6 +10402,18 @@ "value": "count" } ], + "network": [ + { + "type": 0, + "value": "Network" + } + ], + "networkDesc": [ + { + "type": 0, + "value": "Distribute the cost of network traffic to projects based on distribution type." + } + ], "next": [ { "type": 0, @@ -12102,12 +12199,24 @@ "value": "Status/Actions" } ], + "storage": [ + { + "type": 0, + "value": "Storage" + } + ], "storageClass": [ { "type": 0, "value": "StorageClass" } ], + "storageDesc": [ + { + "type": 0, + "value": "Distribute the cost of storage to projects based on distribution type." + } + ], "suggestions": [ { "type": 0, diff --git a/locales/translations.json b/locales/translations.json index 37747ff4b..c81287ad1 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -240,8 +240,9 @@ "disabled": "Disabled", "discountMinus": "Discount (-)", "distribute": "Distribute", - "distributeCosts": "{value, select, true {Distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}false {Do not distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}other {}}", - "distributionModelDesc": "This choice is for users to direct how their raw costs are distributed either by CPU or Memory on the project level breakdowns.", + "distributeCosts": "{value, select, true {Distribute {type, select, network {network} storage {storage} other {}} costs}false {Do not distribute {type, select, network {network} storage {storage} other {}} costs}other {}}", + "distributeUnallocatedCapacity": "{value, select, true {Distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}false {Do not distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}other {}}", + "distributionModelDesc": "Choose how your raw costs are distributed at the project level.", "distributionType": "Distribution type", "distributionTypeDesc": "{type, select, cpu {Distribute costs based on CPU usage}memory {Distribute costs based on memory usage}other {}}", "doNotDistribute": "Do not distribute", @@ -380,6 +381,8 @@ "metricsOperatorVersion": "Cost Management operator version", "monthOverMonthChange": "Month over month change", "names": "{count, plural, one {Name} other {Names}}", + "network": "Network", + "networkDesc": "Distribute the cost of network traffic to projects based on distribution type.", "next": "next", "no": "No", "noDataForDate": "No data available for {dateRange}", @@ -546,7 +549,9 @@ "start": "Start", "status": "{value, select, pending {Pending} running {Running} failed {Failed} other {}}", "statusActions": "Status/Actions", + "storage": "Storage", "storageClass": "StorageClass", + "storageDesc": "Distribute the cost of storage to projects based on distribution type.", "suggestions": "Suggestions", "sumPlatformCosts": "Sum platform costs", "summary": "Summary", diff --git a/src/api/costModels.ts b/src/api/costModels.ts index 3687b4951..bfe3d15cf 100644 --- a/src/api/costModels.ts +++ b/src/api/costModels.ts @@ -15,7 +15,9 @@ export interface CostModel { description: string; distribution_info?: { distribution_type?: string; + network_cost?: boolean; platform_cost?: boolean; + storage_cost?: boolean; worker_cost?: boolean; }; markup: { value: string; unit: string }; @@ -32,7 +34,9 @@ export interface CostModelRequest { description: string; distribution_info?: { distribution_type?: string; + network_cost?: boolean; platform_cost?: boolean; + storage_cost?: boolean; worker_cost?: boolean; }; markup: { value: string; unit: string }; diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 3d67d9700..872288913 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -1410,17 +1410,24 @@ export default defineMessages({ distributeCosts: { defaultMessage: '{value, select, ' + - 'true {Distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}' + - 'false {Do not distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}' + + 'true {Distribute {type, select, network {network} storage {storage} other {}} costs}' + + 'false {Do not distribute {type, select, network {network} storage {storage} other {}} costs}' + 'other {}}', description: 'distribute costs', id: 'distributeCosts', }, - distributionModelDesc: { + distributeUnallocatedCapacity: { defaultMessage: - 'This choice is for users to direct how their raw costs are distributed either by CPU or Memory on the project level breakdowns.', - description: - 'This choice is for users to direct how their raw costs are distributed either by CPU or Memory on the project level breakdowns.', + '{value, select, ' + + 'true {Distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}' + + 'false {Do not distribute {type, select, platform {platform} worker {worker} other {}} unallocated capacity}' + + 'other {}}', + description: 'distribute unallocated capacity', + id: 'distributeUnallocatedCapacity', + }, + distributionModelDesc: { + defaultMessage: 'Choose how your raw costs are distributed at the project level.', + description: 'Choose how your raw costs are distributed at the project level.', id: 'distributionModelDesc', }, distributionType: { @@ -2457,6 +2464,16 @@ export default defineMessages({ description: 'Name plural or singular', id: 'names', }, + network: { + defaultMessage: 'Network', + description: 'Network', + id: 'network', + }, + networkDesc: { + defaultMessage: 'Distribute the cost of network traffic to projects based on distribution type.', + description: 'Distribute the cost of network traffic to projects based on distribution type.', + id: 'networkDesc', + }, next: { defaultMessage: 'next', description: 'next', @@ -3364,11 +3381,21 @@ export default defineMessages({ description: 'Status/Actions', id: 'statusActions', }, + storage: { + defaultMessage: 'Storage', + description: 'Storage', + id: 'storage', + }, storageClass: { defaultMessage: 'StorageClass', description: 'StorageClass', id: 'storageClass', }, + storageDesc: { + defaultMessage: 'Distribute the cost of storage to projects based on distribution type.', + description: 'Distribute the cost of storage to projects based on distribution type.', + id: 'storageDesc', + }, suggestions: { defaultMessage: 'Suggestions', description: 'Suggestions', diff --git a/src/routes/settings/costModels/components/rateForm/utils.tsx b/src/routes/settings/costModels/components/rateForm/utils.tsx index a4f7ad582..1952cb985 100644 --- a/src/routes/settings/costModels/components/rateForm/utils.tsx +++ b/src/routes/settings/costModels/components/rateForm/utils.tsx @@ -173,7 +173,9 @@ export const mergeToRequest = ( description: costModel.description, distribution_info: { distribution_type: costModel.distribution_info ? costModel.distribution_info.distribution_type : undefined, + network_cost: costModel.distribution_info ? costModel.distribution_info.network_cost : undefined, platform_cost: costModel.distribution_info ? costModel.distribution_info.platform_cost : undefined, + storage_cost: costModel.distribution_info ? costModel.distribution_info.storage_cost : undefined, worker_cost: costModel.distribution_info ? costModel.distribution_info.worker_cost : undefined, }, source_uuids: costModel.sources.map(src => src.uuid), diff --git a/src/routes/settings/costModels/costModel/distribution.tsx b/src/routes/settings/costModels/costModel/distribution.tsx index 871d5d87f..4ef301fe3 100644 --- a/src/routes/settings/costModels/costModel/distribution.tsx +++ b/src/routes/settings/costModels/costModel/distribution.tsx @@ -1,5 +1,6 @@ import { Button, ButtonVariant, Card, CardBody, CardHeader, Title, TitleSizes } from '@patternfly/react-core'; import type { CostModel } from 'api/costModels'; +import { useIsOcpCloudNetworkingToggleEnabled, useIsOcpProjectStorageToggleEnabled } from 'components/featureToggle'; import messages from 'locales/messages'; import React from 'react'; import { useIntl } from 'react-intl'; @@ -26,6 +27,8 @@ const DistributionCardBase: React.FC = ({ isUpdateDialogOpen, }) => { const intl = useIntl(); + const isOcpCloudNetworkingToggleEnabled = useIsOcpCloudNetworkingToggleEnabled(); + const isOcpProjectStorageToggleEnabled = useIsOcpProjectStorageToggleEnabled(); return ( <> @@ -62,17 +65,33 @@ const DistributionCardBase: React.FC = ({ })}
- {intl.formatMessage(messages.distributeCosts, { + {intl.formatMessage(messages.distributeUnallocatedCapacity, { value: current.distribution_info.platform_cost, type: 'platform', })}
- {intl.formatMessage(messages.distributeCosts, { + {intl.formatMessage(messages.distributeUnallocatedCapacity, { value: current.distribution_info.worker_cost, type: 'worker', })}
+ {isOcpCloudNetworkingToggleEnabled && ( +
+ {intl.formatMessage(messages.distributeCosts, { + value: current.distribution_info.network_cost, + type: 'network', + })} +
+ )} + {isOcpProjectStorageToggleEnabled && ( +
+ {intl.formatMessage(messages.distributeCosts, { + value: current.distribution_info.storage_cost, + type: 'storage', + })} +
+ )} diff --git a/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx b/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx index 9f087123a..4db80b496 100644 --- a/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx +++ b/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx @@ -22,6 +22,7 @@ import { connect } from 'react-redux'; import { createMapStateToProps } from 'store/common'; import { costModelsActions, costModelsSelectors } from 'store/costModels'; +import { FeatureToggleSelectors } from '../../../../store/featureToggle'; import { styles } from './costCalc.styles'; interface UpdateDistributionDialogOwnProps extends WrappedComponentProps { @@ -31,6 +32,8 @@ interface UpdateDistributionDialogOwnProps extends WrappedComponentProps { interface UpdateDistributionDialogStateProps { error?: string; isLoading?: boolean; + isOcpCloudNetworkingToggleEnabled?: boolean; + isOcpProjectStorageToggleEnabled?: boolean; } interface UpdateDistributionDialogDispatchProps { @@ -40,7 +43,9 @@ interface UpdateDistributionDialogDispatchProps { interface UpdateDistributionDialogState { distribution?: string; + distributeNetwork?: boolean; distributePlatformUnallocated?: boolean; + distributeStorage?: boolean; distributeWorkerUnallocated?: boolean; } @@ -56,7 +61,9 @@ class UpdateDistributionDialogBase extends React.Component< super(props); this.state = { distribution: this.props.current.distribution_info.distribution_type, + distributeNetwork: this.props.current.distribution_info.network_cost === true, distributePlatformUnallocated: this.props.current.distribution_info.platform_cost === true, + distributeStorage: this.props.current.distribution_info.storage_cost === true, distributeWorkerUnallocated: this.props.current.distribution_info.worker_cost === true, }; } @@ -76,8 +83,27 @@ class UpdateDistributionDialogBase extends React.Component< this.setState({ distributeWorkerUnallocated: value === 'true' }); }; + private handleDistributeNetworkChange = event => { + const { value } = event.currentTarget; + this.setState({ distributeNetwork: value === 'true' }); + }; + + private handleDistributeStorageChange = event => { + const { value } = event.currentTarget; + this.setState({ distributeStorage: value === 'true' }); + }; + public render() { - const { error, current, intl, isLoading, onClose, updateCostModel } = this.props; + const { + error, + current, + intl, + isLoading, + isOcpCloudNetworkingToggleEnabled, + isOcpProjectStorageToggleEnabled, + onClose, + updateCostModel, + } = this.props; return ( + {isOcpCloudNetworkingToggleEnabled && ( + <> + + + {intl.formatMessage(messages.network)} + + + {intl.formatMessage(messages.networkDesc)} + + + +
+ + + + +
+
+ + )} + {isOcpProjectStorageToggleEnabled && ( + <> + + + {intl.formatMessage(messages.storage)} + + + {intl.formatMessage(messages.storageDesc)} + + + +
+ + + + +
+
+ + )}
); @@ -228,6 +328,8 @@ const mapStateToProps = createMapStateToProps { return { isLoading: costModelsSelectors.updateProcessing(state), + isOcpCloudNetworkingToggleEnabled: FeatureToggleSelectors.selectIsOcpCloudNetworkingToggleEnabled(state), + isOcpProjectStorageToggleEnabled: FeatureToggleSelectors.selectIsOcpProjectStorageToggleEnabled(state), error: costModelsSelectors.updateError(state), }; } diff --git a/src/routes/settings/costModels/costModelWizard/context.ts b/src/routes/settings/costModels/costModelWizard/context.ts index 8af17a7aa..501643864 100644 --- a/src/routes/settings/costModels/costModelWizard/context.ts +++ b/src/routes/settings/costModels/costModelWizard/context.ts @@ -15,7 +15,9 @@ export const defaultCostModelContext = { description: '', dirtyName: false, distribution: '', + distributeNetwork: true, distributePlatformUnallocated: true, + distributeStorage: true, distributeWorkerUnallocated: true, error: null, fetchSources: (type: string, query: any, page: number, perPage: number) => null, @@ -24,7 +26,9 @@ export const defaultCostModelContext = { isDiscount: false, handleMarkupDiscountChange: (...args: any[]) => null, handleDistributionChange: (...args: any[]) => null, + handleDistributeNetworkChange: (...args: any[]) => null, handleDistributePlatformUnallocatedChange: (...args: any[]) => null, + handleDistributeStorageChange: (...args: any[]) => null, handleDistributeWorkerUnallocatedChange: (...args: any[]) => null, handleSignChange: (...args: any[]) => null, loading: false, diff --git a/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx b/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx index 0b300c5b4..d5dfea849 100644 --- a/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx +++ b/src/routes/settings/costModels/costModelWizard/costModelWizard.tsx @@ -109,7 +109,9 @@ const InternalWizardBase: React.FC = ({ currency, description, distribution, + distributeNetwork, distributePlatformUnallocated, + distributeStorage, distributeWorkerUnallocated, isDiscount, markup, @@ -125,7 +127,9 @@ const InternalWizardBase: React.FC = ({ description, distribution_info: { distribution_type: distribution, + network_cost: distributeNetwork, platform_cost: distributePlatformUnallocated, + storage_cost: distributeStorage, worker_cost: distributeWorkerUnallocated, }, rates: tiers, @@ -166,7 +170,9 @@ interface CostModelWizardState { description?: string; dirtyName?: boolean; distribution?: string; + distributeNetwork?: boolean; distributePlatformUnallocated?: boolean; + distributeStorage?: boolean; distributeWorkerUnallocated?: boolean; error?: any; filterName?: string; @@ -207,7 +213,9 @@ class CostModelWizardBase extends React.Component { + const { value } = event.currentTarget; + this.setState({ distributeNetwork: value === 'true' }); + }, handleDistributePlatformUnallocatedChange: event => { const { value } = event.currentTarget; this.setState({ distributePlatformUnallocated: value === 'true' }); }, + handleDistributeStorageChange: event => { + const { value } = event.currentTarget; + this.setState({ distributeStorage: value === 'true' }); + }, handleDistributeWorkerUnallocatedChange: event => { const { value } = event.currentTarget; this.setState({ distributeWorkerUnallocated: value === 'true' }); @@ -531,7 +549,9 @@ class CostModelWizardBase extends React.Component { public render() { - const { intl } = this.props; + const { isOcpCloudNetworkingToggleEnabled, isOcpProjectStorageToggleEnabled, intl } = this.props; return ( {({ handleDistributionChange, + handleDistributeNetworkChange, handleDistributePlatformUnallocatedChange, + handleDistributeStorageChange, handleDistributeWorkerUnallocatedChange, distribution, + distributeNetwork, distributePlatformUnallocated, + distributeStorage, distributeWorkerUnallocated, }) => { return ( @@ -57,7 +63,7 @@ class DistributionBase extends React.Component + {isOcpCloudNetworkingToggleEnabled && ( + <> + + + {intl.formatMessage(messages.network)} + + + {intl.formatMessage(messages.networkDesc)} + + + +
+ + + + +
+
+ + )} + {isOcpProjectStorageToggleEnabled && ( + <> + + + {intl.formatMessage(messages.storage)} + + + {intl.formatMessage(messages.storageDesc)} + + + +
+ + + + +
+
+ + )} ); }} @@ -148,9 +226,10 @@ class DistributionBase extends React.Component(() => { +const mapStateToProps = createMapStateToProps(state => { return { - // TBD... + isOcpCloudNetworkingToggleEnabled: FeatureToggleSelectors.selectIsOcpCloudNetworkingToggleEnabled(state), + isOcpProjectStorageToggleEnabled: FeatureToggleSelectors.selectIsOcpProjectStorageToggleEnabled(state), }; }); diff --git a/src/routes/settings/costModels/costModelWizard/review.tsx b/src/routes/settings/costModels/costModelWizard/review.tsx index 338fee686..bccbc52ac 100644 --- a/src/routes/settings/costModels/costModelWizard/review.tsx +++ b/src/routes/settings/costModels/costModelWizard/review.tsx @@ -28,6 +28,7 @@ import { connect } from 'react-redux'; import { RateTable } from 'routes/settings/costModels/components/rateTable'; import { WarningIcon } from 'routes/settings/costModels/components/warningIcon'; import { createMapStateToProps } from 'store/common'; +import { FeatureToggleSelectors } from 'store/featureToggle'; import { CostModelContext } from './context'; @@ -66,12 +67,17 @@ interface ReviewDetailsOwnProps extends WrappedComponentProps { } interface ReviewDetailsStateProps { - // TBD... + isOcpCloudNetworkingToggleEnabled?: boolean; + isOcpProjectStorageToggleEnabled?: boolean; } type ReviewDetailsProps = ReviewDetailsOwnProps & ReviewDetailsStateProps; -const ReviewDetailsBase: React.FC = ({ intl }) => ( +const ReviewDetailsBase: React.FC = ({ + intl, + isOcpCloudNetworkingToggleEnabled, + isOcpProjectStorageToggleEnabled, +}) => ( {({ checked, @@ -79,7 +85,9 @@ const ReviewDetailsBase: React.FC = ({ intl }) => ( currencyUnits, description, distribution, + distributeNetwork, distributePlatformUnallocated, + distributeStorage, distributeWorkerUnallocated, isDiscount, markup, @@ -155,17 +163,33 @@ const ReviewDetailsBase: React.FC = ({ intl }) => ( {intl.formatMessage(messages.distributionTypeDesc, { type: distribution })} - {intl.formatMessage(messages.distributeCosts, { + {intl.formatMessage(messages.distributeUnallocatedCapacity, { value: distributePlatformUnallocated, type: 'platform', })} - {intl.formatMessage(messages.distributeCosts, { + {intl.formatMessage(messages.distributeUnallocatedCapacity, { value: distributeWorkerUnallocated, type: 'worker', })} + {isOcpCloudNetworkingToggleEnabled && ( + + {intl.formatMessage(messages.distributeCosts, { + value: distributeNetwork, + type: 'network', + })} + + )} + {isOcpProjectStorageToggleEnabled && ( + + {intl.formatMessage(messages.distributeCosts, { + value: distributeStorage, + type: 'storage', + })} + + )} )} @@ -187,9 +211,10 @@ const ReviewDetailsBase: React.FC = ({ intl }) => ( ); -const mapStateToProps = createMapStateToProps(() => { +const mapStateToProps = createMapStateToProps(state => { return { - // TBD... + isOcpCloudNetworkingToggleEnabled: FeatureToggleSelectors.selectIsOcpCloudNetworkingToggleEnabled(state), + isOcpProjectStorageToggleEnabled: FeatureToggleSelectors.selectIsOcpProjectStorageToggleEnabled(state), }; }); From 0bfc8e4d08942443658a0fb01a48b2e8b878a10c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 10:47:21 +0000 Subject: [PATCH 09/49] (chore): Bump eslint-plugin-jest-dom in the lint-dependencies group Bumps the lint-dependencies group with 1 update: [eslint-plugin-jest-dom](https://github.com/testing-library/eslint-plugin-jest-dom). Updates `eslint-plugin-jest-dom` from 5.2.0 to 5.4.0 - [Release notes](https://github.com/testing-library/eslint-plugin-jest-dom/releases) - [Commits](https://github.com/testing-library/eslint-plugin-jest-dom/compare/v5.2.0...v5.4.0) --- updated-dependencies: - dependency-name: eslint-plugin-jest-dom dependency-type: direct:development update-type: version-update:semver-minor dependency-group: lint-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index e2ae1d50f..907d43a28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,7 +64,7 @@ "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.0", - "eslint-plugin-jest-dom": "^5.2.0", + "eslint-plugin-jest-dom": "^5.4.0", "eslint-plugin-jsdoc": "^48.2.3", "eslint-plugin-markdown": "^4.0.1", "eslint-plugin-patternfly-react": "^5.3.0", @@ -9286,9 +9286,9 @@ } }, "node_modules/eslint-plugin-jest-dom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.2.0.tgz", - "integrity": "sha512-ctnCP0MsLmUvbCyhnOQ+/1OmsZj+e7V6kFunazIx5728Yq7TQnuKI8HOsgPTStB+9iYEpiEa+VfKB09Lq7/3fA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.4.0.tgz", + "integrity": "sha512-yBqvFsnpS5Sybjoq61cJiUsenRkC9K32hYQBFS9doBR7nbQZZ5FyO+X7MlmfM1C48Ejx/qTuOCgukDUNyzKZ7A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.3", @@ -9300,8 +9300,8 @@ "yarn": ">=1" }, "peerDependencies": { - "@testing-library/dom": "^8.0.0 || ^9.0.0", - "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0" + "@testing-library/dom": "^8.0.0 || ^9.0.0 || ^10.0.0", + "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" }, "peerDependenciesMeta": { "@testing-library/dom": { diff --git a/package.json b/package.json index f42ad39cb..d399ba5d9 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.0", - "eslint-plugin-jest-dom": "^5.2.0", + "eslint-plugin-jest-dom": "^5.4.0", "eslint-plugin-jsdoc": "^48.2.3", "eslint-plugin-markdown": "^4.0.1", "eslint-plugin-patternfly-react": "^5.3.0", From 720fa44f394add47ca73e53bd3b95b051831aa55 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Sun, 21 Apr 2024 01:22:51 -0400 Subject: [PATCH 10/49] Stubbed-out historical layout for network and storage features --- locales/data.json | 8 + locales/translations.json | 2 +- src/api/reports/ocpReports.ts | 1 + src/locales/messages.ts | 1 + .../historicalData/historicalDataBase.tsx | 65 ++++- .../historicalDataVolumeChart.tsx | 226 ++++++++++++++++++ .../details/ocpBreakdown/historicalData.tsx | 3 + .../costModel/updateDistributionDialog.tsx | 2 +- .../common/historicalDataCommon.ts | 2 + .../ocpHistoricalData.test.ts | 16 +- .../ocpHistoricalDataReducer.ts | 12 +- .../ocpHistoricalDataWidgets.ts | 16 ++ 12 files changed, 347 insertions(+), 7 deletions(-) create mode 100644 src/routes/details/components/historicalData/historicalDataVolumeChart.tsx diff --git a/locales/data.json b/locales/data.json index 8d404f1a2..7d9d3ce17 100644 --- a/locales/data.json +++ b/locales/data.json @@ -9799,6 +9799,14 @@ } ] }, + "network": { + "value": [ + { + "type": 0, + "value": "Network usage comparison" + } + ] + }, "other": { "value": [] }, diff --git a/locales/translations.json b/locales/translations.json index c81287ad1..a66dcbf17 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -339,7 +339,7 @@ "groupByValuesTitleCase": "{value, select, account {{count, plural, one {Account} other {Accounts}}} aws_category {{count, plural, one {Cost category} other {Cost categories}}} cluster {{count, plural, one {Cluster} other {Clusters}}} gcp_project {{count, plural, one {GCP project} other {GCP projects}}} node {{count, plural, one {Node} other {Node}}} org_unit_id {{count, plural, one {Organizational unit} other {Organizational units}}} payer_tenant_id {{count, plural, one {Account} other {Accounts}}} product_service {{count, plural, one {Service} other {Services}}} project {{count, plural, one {Project} other {Projects}}} region {{count, plural, one {Region} other {Regions}}} resource_location {{count, plural, one {Region} other {Regions}}} service {{count, plural, one {Service} other {Services}}} service_name {{count, plural, one {Service} other {Services}}} subscription_guid {{count, plural, one {Account} other {Accounts}}} tag {{count, plural, one {Tag} other {Tags}}} other {}}", "historicalChartCostLabel": "Cost ({units})", "historicalChartDayOfMonthLabel": "Day of Month", - "historicalChartTitle": "{value, select, cost {Cost comparison} cpu {CPU usage, request, and limit comparison} instance_type {Compute usage comparison}memory {Memory usage, request, and limit comparison} modal {{name} daily usage comparison} storage {Storage usage comparison} virtual_machine {Virtual machine usage comparison}other {}}", + "historicalChartTitle": "{value, select, cost {Cost comparison} cpu {CPU usage, request, and limit comparison} instance_type {Compute usage comparison}memory {Memory usage, request, and limit comparison} modal {{name} daily usage comparison} network {Network usage comparison} storage {Storage usage comparison} virtual_machine {Virtual machine usage comparison}other {}}", "historicalChartUsageLabel": "{value, select, instance_type {hrs} storage {gb-mo} other {}}", "ibm": "IBM Cloud", "ibmComputeTitle": "Compute instances usage", diff --git a/src/api/reports/ocpReports.ts b/src/api/reports/ocpReports.ts index c7eafab80..4360ad580 100644 --- a/src/api/reports/ocpReports.ts +++ b/src/api/reports/ocpReports.ts @@ -61,6 +61,7 @@ export const ReportTypePaths: Partial> = { [ReportType.cost]: 'reports/openshift/costs/', [ReportType.cpu]: 'reports/openshift/compute/', [ReportType.memory]: 'reports/openshift/memory/', + [ReportType.network]: 'reports/openshift/volumes/', // TBD: Use "network" when API is available [ReportType.volume]: 'reports/openshift/volumes/', }; diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 872288913..c5975ac44 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -2222,6 +2222,7 @@ export default defineMessages({ 'instance_type {Compute usage comparison}' + 'memory {Memory usage, request, and limit comparison} ' + 'modal {{name} daily usage comparison} ' + + 'network {Network usage comparison} ' + 'storage {Storage usage comparison} ' + 'virtual_machine {Virtual machine usage comparison}' + 'other {}}', diff --git a/src/routes/details/components/historicalData/historicalDataBase.tsx b/src/routes/details/components/historicalData/historicalDataBase.tsx index 92242e8cb..7c5b683e0 100644 --- a/src/routes/details/components/historicalData/historicalDataBase.tsx +++ b/src/routes/details/components/historicalData/historicalDataBase.tsx @@ -10,6 +10,7 @@ import { HistoricalDataWidgetType } from 'store/breakdown/historicalData/common/ import { HistoricalDataCostChart } from './historicalDataCostChart'; import { HistoricalDataTrendChart } from './historicalDataTrendChart'; import { HistoricalDataUsageChart } from './historicalDataUsageChart'; +import { HistoricalDataVolumeChart } from './historicalDataVolumeChart'; interface HistoricalDataOwnProps { costDistribution?: string; @@ -18,6 +19,8 @@ interface HistoricalDataOwnProps { } export interface HistoricalDataStateProps { + isOcpCloudNetworkingToggleEnabled?: boolean; + isOcpProjectStorageToggleEnabled?: boolean; selectWidgets?: Record; widgets: number[]; } @@ -26,7 +29,9 @@ type HistoricalDataProps = HistoricalDataOwnProps & HistoricalDataStateProps & W class HistoricalDatasBase extends React.Component { private getTitleKey = (reportPathsType, reportType) => { - if (reportPathsType === ReportPathsType.azure) { + if (reportPathsType === ReportPathsType.ocp) { + return reportType === ReportType.volume ? 'storage' : reportType; + } else if (reportPathsType === ReportPathsType.azure) { return reportType === ReportType.instanceType ? 'virtual_machine' : reportType; } return reportType === ReportType.instanceType ? 'instance_type' : reportType; @@ -59,6 +64,60 @@ class HistoricalDatasBase extends React.Component { ); }; + // Returns network chart + private getNetworkChart = (widget: HistoricalDataWidget) => { + const { intl, isOcpCloudNetworkingToggleEnabled } = this.props; + + if (widget.reportPathsType === ReportPathsType.ocp && !isOcpCloudNetworkingToggleEnabled) { + return null; + } + return ( + + + + {intl.formatMessage(messages.historicalChartTitle, { + value: this.getTitleKey(widget.reportPathsType, widget.reportType), + })} + + + + + + + ); + }; + + // Returns volume chart + private getVolumeChart = (widget: HistoricalDataWidget) => { + const { intl, isOcpProjectStorageToggleEnabled } = this.props; + + if (widget.reportPathsType === ReportPathsType.ocp && !isOcpProjectStorageToggleEnabled) { + return null; + } + return ( + + + + {intl.formatMessage(messages.historicalChartTitle, { + value: this.getTitleKey(widget.reportPathsType, widget.reportType), + })} + + + + + + + ); + }; + // Returns trend chart private getTrendChart = (widget: HistoricalDataWidget) => { const { costType, currency, intl } = this.props; @@ -114,10 +173,14 @@ class HistoricalDatasBase extends React.Component { switch (widget.type) { case HistoricalDataWidgetType.cost: return this.getCostChart(widget); + case HistoricalDataWidgetType.network: + return this.getNetworkChart(widget); case HistoricalDataWidgetType.trend: return this.getTrendChart(widget); case HistoricalDataWidgetType.usage: return this.getUsageChart(widget); + case HistoricalDataWidgetType.volume: + return this.getVolumeChart(widget); default: return null; } diff --git a/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx b/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx new file mode 100644 index 000000000..2a4be18a5 --- /dev/null +++ b/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx @@ -0,0 +1,226 @@ +import { Skeleton } from '@patternfly/react-core'; +import type { Query } from 'api/queries/query'; +import { getQuery, parseQuery } from 'api/queries/query'; +import type { Report, ReportPathsType } from 'api/reports/report'; +import { ReportType } from 'api/reports/report'; +import messages from 'locales/messages'; +import React from 'react'; +import type { WrappedComponentProps } from 'react-intl'; +import { injectIntl } from 'react-intl'; +import { connect } from 'react-redux'; +import { DatumType, transformReport } from 'routes/components/charts/common/chartDatum'; +import { HistoricalUsageChart } from 'routes/components/charts/historicalUsageChart'; +import { getGroupById, getGroupByOrgValue, getGroupByValue } from 'routes/utils/groupBy'; +import { getQueryState } from 'routes/utils/queryState'; +import { skeletonWidth } from 'routes/utils/skeleton'; +import { createMapStateToProps, FetchStatus } from 'store/common'; +import { reportActions, reportSelectors } from 'store/reports'; +import { formatUnits, unitsLookupKey } from 'utils/format'; +import { logicalAndPrefix, logicalOrPrefix, orgUnitIdKey, platformCategoryKey } from 'utils/props'; +import type { RouterComponentProps } from 'utils/router'; +import { withRouter } from 'utils/router'; + +import { chartStyles, styles } from './historicalChart.styles'; + +interface HistoricalDataVolumeChartOwnProps extends RouterComponentProps, WrappedComponentProps { + chartName?: string; + reportPathsType: ReportPathsType; + reportType: ReportType; +} + +interface HistoricalDataVolumeChartStateProps { + currentQuery?: Query; + currentQueryString?: string; + currentReport?: Report; + currentReportFetchStatus?: FetchStatus; + previousQuery?: Query; + previousQueryString?: string; + previousReport?: Report; + previousReportFetchStatus?: FetchStatus; +} + +interface HistoricalDataVolumeChartDispatchProps { + fetchReport?: typeof reportActions.fetchReport; +} + +type HistoricalDataVolumeChartProps = HistoricalDataVolumeChartOwnProps & + HistoricalDataVolumeChartStateProps & + HistoricalDataVolumeChartDispatchProps; + +class HistoricalDataVolumeChartBase extends React.Component { + public componentDidMount() { + this.updateReport(); + } + + public componentDidUpdate(prevProps: HistoricalDataVolumeChartProps) { + const { currentQueryString, previousQueryString } = this.props; + + if (prevProps.currentQueryString !== currentQueryString || prevProps.previousQueryString !== previousQueryString) { + this.updateReport(); + } + } + + private getSkeleton = () => { + return ( + <> + + + + ); + }; + + private updateReport = () => { + const { fetchReport, currentQueryString, previousQueryString, reportPathsType, reportType } = this.props; + fetchReport(reportPathsType, reportType, currentQueryString); + fetchReport(reportPathsType, reportType, previousQueryString); + }; + + public render() { + const { chartName, currentReport, currentReportFetchStatus, previousReport, previousReportFetchStatus, intl } = + this.props; + + // Current data + const currentLimitData = transformReport(currentReport, DatumType.rolling, 'date', 'limit'); + const currentRequestData = transformReport(currentReport, DatumType.rolling, 'date', 'request'); + const currentUsageData = transformReport(currentReport, DatumType.rolling, 'date', 'usage'); + + // Previous data + const previousLimitData = transformReport(previousReport, DatumType.rolling, 'date', 'limit'); + const previousRequestData = transformReport(previousReport, DatumType.rolling, 'date', 'request'); + const previousUsageData = transformReport(previousReport, DatumType.rolling, 'date', 'usage'); + + const usageUnits = currentReport?.meta?.total?.usage ? currentReport.meta.total.usage.units : ''; + + return ( +
+
+ {currentReportFetchStatus === FetchStatus.inProgress && + previousReportFetchStatus === FetchStatus.inProgress ? ( + this.getSkeleton() + ) : ( + + )} +
+
+ ); + } +} + +const mapStateToProps = createMapStateToProps( + (state, { reportPathsType, reportType, router }) => { + const queryFromRoute = parseQuery(router.location.search); + const queryState = getQueryState(router.location, 'details'); + + const groupByOrgValue = getGroupByOrgValue(queryFromRoute); + const groupBy = getGroupById(queryFromRoute); + const groupByValue = getGroupByValue(queryFromRoute); + + // instance-types and storage APIs must filter org units + const useFilter = reportType === ReportType.instanceType || reportType === ReportType.storage; + + const baseQuery: Query = { + filter_by: { + // Add filters here to apply logical OR/AND + ...(queryState?.filter_by && queryState.filter_by), + ...(queryFromRoute?.isPlatformCosts && { category: platformCategoryKey }), + ...(queryFromRoute?.filter?.account && { [`${logicalAndPrefix}account`]: queryFromRoute.filter.account }), + ...(groupByOrgValue && useFilter && { [orgUnitIdKey]: groupByOrgValue }), + // Workaround for https://issues.redhat.com/browse/COST-1189 + ...(queryState?.filter_by && + queryState.filter_by[orgUnitIdKey] && { + [`${logicalOrPrefix}${orgUnitIdKey}`]: queryState.filter_by[orgUnitIdKey], + [orgUnitIdKey]: undefined, + }), + }, + exclude: { + ...(queryState?.exclude && queryState.exclude), + }, + group_by: { + ...(groupByOrgValue && !useFilter && { [orgUnitIdKey]: groupByOrgValue }), + ...(groupBy && !groupByOrgValue && { [groupBy]: groupByValue }), + }, + }; + + // Current report + const currentQuery: Query = { + ...baseQuery, + filter: { + resolution: 'daily', + time_scope_units: 'month', + time_scope_value: -1, + }, + filter_by: { + ...baseQuery.filter_by, + // Omit filters associated with the current group_by -- see https://issues.redhat.com/browse/COST-1131 and https://issues.redhat.com/browse/COST-3642 + ...(groupBy && groupByValue !== '*' && { [groupBy]: undefined }), // Used by the "Platform" project + }, + }; + + const currentQueryString = getQuery(currentQuery); + const currentReport = reportSelectors.selectReport(state, reportPathsType, reportType, currentQueryString); + const currentReportFetchStatus = reportSelectors.selectReportFetchStatus( + state, + reportPathsType, + reportType, + currentQueryString + ); + + // Previous report + const previousQuery: Query = { + ...baseQuery, + filter: { + resolution: 'daily', + time_scope_units: 'month', + time_scope_value: -2, + }, + filter_by: { + ...baseQuery.filter_by, + // Omit filters associated with the current group_by -- see https://issues.redhat.com/browse/COST-1131 and https://issues.redhat.com/browse/COST-3642 + ...(groupBy && groupByValue !== '*' && { [groupBy]: undefined }), // Used by the "Platform" project + }, + }; + + const previousQueryString = getQuery(previousQuery); + const previousReport = reportSelectors.selectReport(state, reportPathsType, reportType, previousQueryString); + const previousReportFetchStatus = reportSelectors.selectReportFetchStatus( + state, + reportPathsType, + reportType, + previousQueryString + ); + + return { + currentQuery, + currentQueryString, + currentReport, + currentReportFetchStatus, + previousQuery, + previousQueryString, + previousReport, + previousReportFetchStatus, + }; + } +); + +const mapDispatchToProps: HistoricalDataVolumeChartDispatchProps = { + fetchReport: reportActions.fetchReport, +}; + +const HistoricalDataVolumeChart = injectIntl( + withRouter(connect(mapStateToProps, mapDispatchToProps)(HistoricalDataVolumeChartBase)) +); + +export { HistoricalDataVolumeChart }; diff --git a/src/routes/details/ocpBreakdown/historicalData.tsx b/src/routes/details/ocpBreakdown/historicalData.tsx index 4ec1caf74..0913d1b66 100644 --- a/src/routes/details/ocpBreakdown/historicalData.tsx +++ b/src/routes/details/ocpBreakdown/historicalData.tsx @@ -3,6 +3,7 @@ import type { HistoricalDataStateProps } from 'routes/details/components/histori import { HistoricalDataBase } from 'routes/details/components/historicalData'; import { ocpHistoricalDataSelectors } from 'store/breakdown/historicalData/ocpHistoricalData'; import { createMapStateToProps } from 'store/common'; +import { FeatureToggleSelectors } from 'store/featureToggle'; interface OcpHistoricalDataOwnProps { // TBD... @@ -11,6 +12,8 @@ interface OcpHistoricalDataOwnProps { // eslint-disable-next-line @typescript-eslint/no-unused-vars const mapStateToProps = createMapStateToProps((state, props) => { return { + isOcpCloudNetworkingToggleEnabled: FeatureToggleSelectors.selectIsOcpCloudNetworkingToggleEnabled(state), + isOcpProjectStorageToggleEnabled: FeatureToggleSelectors.selectIsOcpProjectStorageToggleEnabled(state), selectWidgets: ocpHistoricalDataSelectors.selectWidgets(state), widgets: ocpHistoricalDataSelectors.selectCurrentWidgets(state), }; diff --git a/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx b/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx index 4db80b496..1ef01e463 100644 --- a/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx +++ b/src/routes/settings/costModels/costModel/updateDistributionDialog.tsx @@ -21,8 +21,8 @@ import { injectIntl } from 'react-intl'; import { connect } from 'react-redux'; import { createMapStateToProps } from 'store/common'; import { costModelsActions, costModelsSelectors } from 'store/costModels'; +import { FeatureToggleSelectors } from 'store/featureToggle'; -import { FeatureToggleSelectors } from '../../../../store/featureToggle'; import { styles } from './costCalc.styles'; interface UpdateDistributionDialogOwnProps extends WrappedComponentProps { diff --git a/src/store/breakdown/historicalData/common/historicalDataCommon.ts b/src/store/breakdown/historicalData/common/historicalDataCommon.ts index 98ad275fa..05ca74bd5 100644 --- a/src/store/breakdown/historicalData/common/historicalDataCommon.ts +++ b/src/store/breakdown/historicalData/common/historicalDataCommon.ts @@ -3,8 +3,10 @@ import type { ReportPathsType, ReportType } from 'api/reports/report'; // eslint-disable-next-line no-shadow export const enum HistoricalDataWidgetType { cost = 'cost', // This type displays historical cost chart + network = 'network', // This type displays historical network chart trend = 'trend', // This type displays historical trend chart usage = 'usage', // This type displays historical usage chart + volume = 'volume', // This type displays historical volume chart } export interface HistoricalDataWidget { diff --git a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalData.test.ts b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalData.test.ts index 67a8ef645..9414178e7 100644 --- a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalData.test.ts +++ b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalData.test.ts @@ -6,7 +6,13 @@ import { reportActions } from 'store/reports'; import { ocpHistoricalDataStateKey } from './ocpHistoricalDataCommon'; import { ocpHistoricalDataReducer } from './ocpHistoricalDataReducer'; import * as selectors from './ocpHistoricalDataSelectors'; -import { costWidget, cpuUsageWidget, memoryUsageWidget } from './ocpHistoricalDataWidgets'; +import { + costWidget, + cpuUsageWidget, + memoryUsageWidget, + networkUsageWidget, + volumeUsageWidget, +} from './ocpHistoricalDataWidgets'; const createOcpHistoricalDataStore = createMockStoreCreator({ [ocpHistoricalDataStateKey]: ocpHistoricalDataReducer, @@ -21,6 +27,12 @@ beforeEach(() => { test('default state', () => { const store = createOcpHistoricalDataStore(); const state = store.getState(); - expect(selectors.selectCurrentWidgets(state)).toEqual([costWidget.id, cpuUsageWidget.id, memoryUsageWidget.id]); + expect(selectors.selectCurrentWidgets(state)).toEqual([ + costWidget.id, + cpuUsageWidget.id, + memoryUsageWidget.id, + networkUsageWidget.id, + volumeUsageWidget.id, + ]); expect(selectors.selectWidget(state, costWidget.id)).toEqual(costWidget); }); diff --git a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataReducer.ts b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataReducer.ts index 19f738a85..a6e572cfa 100644 --- a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataReducer.ts +++ b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataReducer.ts @@ -1,5 +1,11 @@ import type { OcpHistoricalDataWidget } from './ocpHistoricalDataCommon'; -import { costWidget, cpuUsageWidget, memoryUsageWidget } from './ocpHistoricalDataWidgets'; +import { + costWidget, + cpuUsageWidget, + memoryUsageWidget, + networkUsageWidget, + volumeUsageWidget, +} from './ocpHistoricalDataWidgets'; export type OcpHistoricalDataState = Readonly<{ widgets: Record; @@ -7,11 +13,13 @@ export type OcpHistoricalDataState = Readonly<{ }>; export const defaultState: OcpHistoricalDataState = { - currentWidgets: [costWidget.id, cpuUsageWidget.id, memoryUsageWidget.id], + currentWidgets: [costWidget.id, cpuUsageWidget.id, memoryUsageWidget.id, networkUsageWidget.id, volumeUsageWidget.id], widgets: { [costWidget.id]: costWidget, [cpuUsageWidget.id]: cpuUsageWidget, [memoryUsageWidget.id]: memoryUsageWidget, + [networkUsageWidget.id]: networkUsageWidget, + [volumeUsageWidget.id]: volumeUsageWidget, }, }; diff --git a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts index c8c9b9aa1..7ef8f2151 100644 --- a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts +++ b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts @@ -29,3 +29,19 @@ export const memoryUsageWidget: OcpHistoricalDataWidget = { reportType: ReportType.memory, type: HistoricalDataWidgetType.usage, }; + +export const networkUsageWidget: OcpHistoricalDataWidget = { + chartName: 'ocpNetworkChart', + id: getId(), + reportPathsType: ReportPathsType.ocp, + reportType: ReportType.network, + type: HistoricalDataWidgetType.network, +}; + +export const volumeUsageWidget: OcpHistoricalDataWidget = { + chartName: 'ocpVolumeChart', + id: getId(), + reportPathsType: ReportPathsType.ocp, + reportType: ReportType.volume, + type: HistoricalDataWidgetType.volume, +}; From 7681618bdb1f9c1c2e283a0ec04828e9633dcc39 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Mon, 22 Apr 2024 16:33:10 -0400 Subject: [PATCH 11/49] Refactored charts to support network API data --- src/api/reports/report.ts | 24 +- src/locales/messages.ts | 140 ++++++---- .../components/charts/common/chartDatum.ts | 34 ++- .../components/charts/common/chartUtils.ts | 2 +- .../components/charts/costChart/costChart.tsx | 20 +- .../charts/dailyCostChart/dailyCostChart.tsx | 20 +- .../dailyTrendChart/dailyTrendChart.tsx | 30 +-- .../historicalCostChart.tsx | 8 +- .../historicalTrendChart.tsx | 8 +- .../historicalUsageChart.tsx | 118 ++++---- .../charts/trendChart/trendChart.tsx | 30 +-- .../charts/usageChart/usageChart.tsx | 30 +-- .../details/components/historicalData/data.ts | 173 ++++++++++++ .../historicalData/historicalDataBase.tsx | 3 +- .../historicalDataCostChart.tsx | 6 +- .../historicalDataNetworkChart.tsx | 251 ++++++++++++++++++ .../historicalDataTrendChart.tsx | 6 +- .../historicalDataUsageChart.tsx | 12 +- .../historicalDataVolumeChart.tsx | 14 +- .../components/dashboardWidgetBase.tsx | 8 +- .../computedReport/getComputedReportItems.ts | 6 + src/store/reports/reportReducer.ts | 2 +- 22 files changed, 715 insertions(+), 230 deletions(-) create mode 100644 src/routes/details/components/historicalData/data.ts create mode 100644 src/routes/details/components/historicalData/historicalDataNetworkChart.tsx diff --git a/src/api/reports/report.ts b/src/api/reports/report.ts index e72a76eaa..a4e3db86d 100644 --- a/src/api/reports/report.ts +++ b/src/api/reports/report.ts @@ -74,10 +74,32 @@ export interface ReportOrgData { type?: string; // 'account' or 'organizational_unit' } +export interface ReportNetworkData { + date?: string; + data_transfer_in?: { + value?: number; + units?: string; + }; + data_transfer_out?: { + value?: number; + units?: string; + }; + resource_id?: string; + clusters?: string[]; + source_uuid?: string; + region?: string; +} + // Additional props for group_by[org_unit_id] export interface ReportData extends ReportOrgData { date?: string; - values?: ReportAwsItem[] | ReportAzureItem[] | ReportGcpItem[] | ReportOcpItem[] | ReportOrgItem[]; + values?: + | ReportAwsItem[] + | ReportAzureItem[] + | ReportGcpItem[] + | ReportOcpItem[] + | ReportOrgItem[] + | ReportNetworkData[]; } export interface ReportMeta extends PagedMetaData { diff --git a/src/locales/messages.ts b/src/locales/messages.ts index c5975ac44..453ab944a 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -205,90 +205,105 @@ export default defineMessages({ description: 'Cancel', id: 'cancel', }, - chartCostForecastConeLegendLabel: { + chartCostForecastConeLabel: { defaultMessage: 'Cost confidence ({dateRange})', description: 'Cost confidence (Jan 1-31)', - id: 'chartCostForecastConeLegendLabel', + id: 'chartCostForecastConeLabel', }, - chartCostForecastConeLegendNoDataLabel: { + chartCostForecastConeLabelNoData: { defaultMessage: 'Cost confidence (no data)', description: 'Cost confidence (no data)', - id: 'chartCostForecastConeLegendNoDataLabel', + id: 'chartCostForecastConeLabelNoData', }, - chartCostForecastConeLegendTooltip: { - defaultMessage: 'Cost confidence ({month})', - description: 'Cost confidence (Jan)', - id: 'chartCostForecastConeLegendTooltip', - }, - chartCostForecastConeTooltip: { + chartCostForecastConeRangeTooltip: { defaultMessage: '{value0} - {value1}', description: 'Cost forecast confidence min/max tooltip', + id: 'chartCostForecastConeRangeTooltip', + }, + chartCostForecastConeTooltip: { + defaultMessage: 'Cost confidence ({month})', + description: 'Cost confidence (Jan)', id: 'chartCostForecastConeTooltip', }, - chartCostForecastLegendLabel: { + chartCostForecastLabel: { defaultMessage: 'Cost forecast ({dateRange})', description: 'Cost forecast (Jan 1-31)', - id: 'chartCostForecastLegendLabel', + id: 'chartCostForecastLabel', }, - chartCostForecastLegendNoDataLabel: { + chartCostForecastLabelNoData: { defaultMessage: 'Cost forecast (no data)', description: 'Cost forecast (no data)', - id: 'chartCostForecastLegendNoDataLabel', + id: 'chartCostForecastLabelNoData', }, - chartCostForecastLegendTooltip: { + chartCostForecastTooltip: { defaultMessage: 'Cost forecast ({month})', description: 'Cost forecast (Jan 1-31)', - id: 'chartCostForecastLegendTooltip', + id: 'chartCostForecastTooltip', }, - chartCostLegendLabel: { + chartCostLabel: { defaultMessage: 'Cost ({dateRange})', description: 'Cost (Jan 1-31)', - id: 'chartCostLegendLabel', + id: 'chartCostLabel', }, - chartCostLegendNoDataLabel: { + chartCostLabelNoData: { defaultMessage: 'Cost (no data)', description: 'Cost (no data)', - id: 'chartCostLegendNoDataLabel', + id: 'chartCostLabelNoData', }, - chartCostLegendTooltip: { + chartCostTooltip: { defaultMessage: 'Cost ({month})', description: 'Cost (Jan)', - id: 'chartCostLegendTooltip', - }, - chartCostSupplementaryLegendLabel: { - defaultMessage: 'Supplementary cost ({dateRange})', - description: 'Supplementary cost (Jan 1-31)', - id: 'chartCostSupplementaryLegendLabel', - }, - chartCostSupplementaryLegendNoDataLabel: { - defaultMessage: 'Supplementary cost (no data)', - description: 'Supplementary cost (no data)', - id: 'chartCostSupplementaryLegendNoDataLabel', - }, - chartCostSupplementaryLegendTooltip: { - defaultMessage: 'Supplementary cost ({month})', - description: 'Supplementary cost (Jan)', - id: 'chartCostSupplementaryLegendTooltip', + id: 'chartCostTooltip', + }, + chartDataInLabel: { + defaultMessage: 'Data in ({dateRange})', + description: 'Data in ({dateRange})', + id: 'chartCostTooltip', + }, + chartDataInLabelNoData: { + defaultMessage: 'Data in (no data)', + description: 'Data in (no data)', + id: 'chartCostTooltip', + }, + chartDataInTooltip: { + defaultMessage: 'Data in ({month})', + description: 'Data in ({month})', + id: 'chartCostTooltip', + }, + chartDataOutLabel: { + defaultMessage: 'Data out ({dateRange})', + description: 'Data out ({dateRange})', + id: 'chartCostTooltip', + }, + chartDataOutLabelNoData: { + defaultMessage: 'Data out (no data)', + description: 'Data out (no data)', + id: 'chartCostTooltip', + }, + chartDataOutTooltip: { + defaultMessage: 'Data out ({month})', + description: 'Data out ({month})', + id: 'chartCostTooltip', }, chartDayOfTheMonth: { defaultMessage: 'Day {day}', description: 'The day of the month', id: 'chartDayOfTheMonth', }, - chartLimitLegendLabel: { + chartLimitLabel: { defaultMessage: 'Limit ({dateRange})', description: 'Limit (Jan 1-31)', - id: 'chartLimitLegendLabel', + id: 'chartLimitLabel', }, - chartLimitLegendNoDataLabel: { + chartLimitLabelNoData: { defaultMessage: 'Limit (no data)', description: 'Limit (no data)', - id: 'chartLimitLegendNoDataLabel', + id: 'chartLimitLabelNoData', }, - chartLimitLegendTooltip: { + chartLimitTooltip: { defaultMessage: 'Limit ({month})', description: 'Limit (Jan)', - id: 'chartLimitLegendTooltip', + id: 'chartLimitTooltip', }, chartNoData: { defaultMessage: 'no data', @@ -300,35 +315,50 @@ export default defineMessages({ description: 'Others category for top costliest', id: 'chartOthers', }, - chartRequestsLegendLabel: { + chartRequestsLabel: { defaultMessage: 'Requests ({dateRange})', description: 'Requests (Jan 1-31)', - id: 'chartRequestsLegendLabel', + id: 'chartRequestsLabel', }, - chartRequestsLegendNoDataLabel: { + chartRequestsLabelNoData: { defaultMessage: 'Requests (no data)', description: 'Requests (no data)', - id: 'chartRequestsLegendNoDataLabel', + id: 'chartRequestsLabelNoData', }, - chartRequestsLegendTooltip: { + chartRequestsTooltip: { defaultMessage: 'Requests ({month})', description: 'Requests (Jan)', - id: 'chartRequestsLegendTooltip', + id: 'chartRequestsTooltip', + }, + chartSupplementaryCostLabel: { + defaultMessage: 'Supplementary cost ({dateRange})', + description: 'Supplementary cost (Jan 1-31)', + id: 'chartSupplementaryCostLabel', + }, + chartSupplementaryCostLabelNoData: { + defaultMessage: 'Supplementary cost (no data)', + description: 'Supplementary cost (no data)', + id: 'chartSupplementaryCostLabelNoData', + }, + chartSupplementaryCostTooltip: { + defaultMessage: 'Supplementary cost ({month})', + description: 'Supplementary cost (Jan)', + id: 'chartSupplementaryCostTooltip', }, - chartUsageLegendLabel: { + chartUsageLabel: { defaultMessage: 'Usage ({dateRange})', description: 'Usage (Jan 1-31)', - id: 'chartUsageLegendLabel', + id: 'chartUsageLabel', }, - chartUsageLegendNoDataLabel: { + chartUsageLabelNoData: { defaultMessage: 'Usage (no data)', description: 'Usage (no data)', - id: 'chartUsageLegendNoDataLabel', + id: 'chartUsageLabelNoData', }, - chartUsageLegendTooltip: { + chartUsageTooltip: { defaultMessage: 'Usage ({month})', description: 'Usage (Jan)', - id: 'chartUsageLegendTooltip', + id: 'chartUsageTooltip', }, chooseKeyPlaceholder: { defaultMessage: 'Choose key', diff --git a/src/routes/components/charts/common/chartDatum.ts b/src/routes/components/charts/common/chartDatum.ts index 98f007662..bbfae5121 100644 --- a/src/routes/components/charts/common/chartDatum.ts +++ b/src/routes/components/charts/common/chartDatum.ts @@ -56,7 +56,7 @@ export function transformReport( datumType, idKey: any = 'date', reportItem: string = 'cost', - reportItemValue: string = 'total' // useful for infrastructure.usage values and cost distribution + reportItemValue: string // useful for infrastructure.usage values and cost distribution ): ChartDatum[] { if (!report) { return []; @@ -72,14 +72,24 @@ export function transformReport( if (datumType === DatumType.cumulative) { chartDatums = computedItems.reduce((acc, d) => { const prevValue = acc.length ? acc[acc.length - 1].y : 0; - const val = d[reportItem][reportItemValue] ? d[reportItem][reportItemValue].value : d[reportItem].value; - return [...acc, createReportDatum(prevValue + val, d, idKey, reportItem, reportItemValue)]; + if (reportItemValue) { + const val = d[reportItem][reportItemValue] ? d[reportItem][reportItemValue].value : d[reportItem].value; + return [...acc, createReportDatum(prevValue + val, d, idKey, reportItem, reportItemValue)]; + } else { + const val = d[reportItem] ? d[reportItem].value : d[reportItem].value; + return [...acc, createReportDatum(prevValue + val, d, idKey, reportItem, undefined)]; + } }, []); } else { chartDatums = computedItems.map(i => { if (i[reportItem]) { - const val = i[reportItem][reportItemValue] ? i[reportItem][reportItemValue].value : i[reportItem].value; - return createReportDatum(val, i, idKey, reportItem, reportItemValue); + if (reportItemValue) { + const val = i[reportItem][reportItemValue] ? i[reportItem][reportItemValue].value : i[reportItem].value; + return createReportDatum(val, i, idKey, reportItem, reportItemValue); + } else { + const val = i[reportItem] ? i[reportItem].value : i[reportItem].value; + return createReportDatum(val, i, idKey, reportItem, undefined); + } } }); } @@ -91,7 +101,7 @@ export function createReportDatum( computedItem: T, idKey = 'date', reportItem: string = 'cost', - reportItemValue: string = 'total' // useful for infrastructure.usage values + reportItemValue: string // useful for infrastructure.usage values ): ChartDatum { const xVal = idKey === 'date' ? getDate(new Date(computedItem.id + 'T00:00:00')) : computedItem.label; const yVal = isFloat(value) ? parseFloat(value.toFixed(2)) : isInt(value) ? value : 0; @@ -166,7 +176,7 @@ export function padChartDatums(datums: ChartDatum[], datumType): ChartDatum[] { for (let i = padDate.getDate(); i < firstDate.getDate(); i++) { padDate.setDate(i); const id = format(padDate, 'yyyy-MM-dd'); - result.push(createReportDatum(null, { id }, 'date', null)); + result.push(createReportDatum(null, { id }, 'date', undefined, undefined)); } // Fill middle with existing data @@ -177,7 +187,7 @@ export function padChartDatums(datums: ChartDatum[], datumType): ChartDatum[] { for (let i = padDate.getDate() + 1; i <= endOfMonth(lastDate).getDate(); i++) { padDate.setDate(i); const id = format(padDate, 'yyyy-MM-dd'); - result.push(createReportDatum(null, { id }, 'date', null)); + result.push(createReportDatum(null, { id }, 'date', undefined, undefined)); } return fillChartDatums(result, datumType); } @@ -282,7 +292,7 @@ export function getTooltipContent(formatter) { export function getCostRangeString( datums: ChartDatum[], - key: MessageDescriptor = messages.chartCostLegendLabel, + key: MessageDescriptor = messages.chartCostLabel, firstOfMonth: boolean = false, lastOfMonth: boolean = false, offset: number = 0, @@ -304,7 +314,7 @@ export function getCostRangeString( export function getCostRangeTooltip( datums: ChartDatum[], - key: MessageDescriptor = messages.chartCostLegendLabel, + key: MessageDescriptor = messages.chartCostLabel, firstOfMonth: boolean = false, lastOfMonth: boolean = false, offset: number = 0, @@ -325,7 +335,7 @@ export function getCostRangeTooltip( export function getUsageRangeString( datums: ChartDatum[], - key: MessageDescriptor = messages.chartUsageLegendLabel, + key: MessageDescriptor = messages.chartUsageLabel, firstOfMonth: boolean = false, lastOfMonth: boolean = false, offset: number = 0, @@ -336,7 +346,7 @@ export function getUsageRangeString( export function getUsageRangeTooltip( datums: ChartDatum[], - key: MessageDescriptor = messages.chartUsageLegendLabel, + key: MessageDescriptor = messages.chartUsageLabel, firstOfMonth: boolean = false, lastOfMonth: boolean = false, offset: number = 0, diff --git a/src/routes/components/charts/common/chartUtils.ts b/src/routes/components/charts/common/chartUtils.ts index 6c47b9503..2dd2819fd 100644 --- a/src/routes/components/charts/common/chartUtils.ts +++ b/src/routes/components/charts/common/chartUtils.ts @@ -97,7 +97,7 @@ export const getTooltipLabel = (datum: any, formatter: Formatter, formatOptions: datum.y0 !== undefined && datum.y0 !== null ? tooltipFormatter(datum.y0, datum.units, formatOptions) : undefined; if (dy !== undefined && dy0 !== undefined) { - return intl.formatMessage(messages.chartCostForecastConeTooltip, { value0: dy0, value1: dy }); + return intl.formatMessage(messages.chartCostForecastConeRangeTooltip, { value0: dy0, value1: dy }); } return dy !== undefined ? dy : intl.formatMessage(messages.chartNoData); }; diff --git a/src/routes/components/charts/costChart/costChart.tsx b/src/routes/components/charts/costChart/costChart.tsx index 672697766..07f36485c 100644 --- a/src/routes/components/charts/costChart/costChart.tsx +++ b/src/routes/components/charts/costChart/costChart.tsx @@ -93,8 +93,8 @@ class CostChartBase extends React.Component { private initDatum = () => { const { currentCostData, forecastConeData, forecastData, previousCostData, showForecast } = this.props; - const costKey = messages.chartCostLegendLabel; - const costTooltipKey = messages.chartCostLegendTooltip; + const costKey = messages.chartCostLabel; + const costTooltipKey = messages.chartCostTooltip; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -103,7 +103,7 @@ class CostChartBase extends React.Component { childName: 'previousCost', data: previousCostData, legendItem: { - name: getCostRangeString(previousCostData, costKey, true, true, 1, messages.chartCostLegendNoDataLabel), + name: getCostRangeString(previousCostData, costKey, true, true, 1, messages.chartCostLabelNoData), symbol: { fill: chartStyles.previousColorScale[0], type: 'minus', @@ -121,7 +121,7 @@ class CostChartBase extends React.Component { childName: 'currentCost', data: currentCostData, legendItem: { - name: getCostRangeString(currentCostData, costKey, true, false, 0, messages.chartCostLegendNoDataLabel), + name: getCostRangeString(currentCostData, costKey, true, false, 0, messages.chartCostLabelNoData), symbol: { fill: chartStyles.currentColorScale[0], type: 'minus', @@ -144,17 +144,17 @@ class CostChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastData, - messages.chartCostForecastLegendLabel, + messages.chartCostForecastLabel, false, false, 0, - messages.chartCostForecastLegendNoDataLabel + messages.chartCostForecastLabelNoData ), symbol: { fill: chartStyles.forecastDataColorScale[0], type: 'minus', }, - tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastTooltip, false, false), }, style: { data: { @@ -169,17 +169,17 @@ class CostChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastConeData, - messages.chartCostForecastConeLegendLabel, + messages.chartCostForecastConeLabel, false, false, 0, - messages.chartCostForecastConeLegendNoDataLabel + messages.chartCostForecastConeLabelNoData ), symbol: { fill: chartStyles.forecastConeDataColorScale[0], type: 'triangleLeft', }, - tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeTooltip, false, false), }, style: { data: { diff --git a/src/routes/components/charts/dailyCostChart/dailyCostChart.tsx b/src/routes/components/charts/dailyCostChart/dailyCostChart.tsx index 7ae5bcf50..f07a9d133 100644 --- a/src/routes/components/charts/dailyCostChart/dailyCostChart.tsx +++ b/src/routes/components/charts/dailyCostChart/dailyCostChart.tsx @@ -96,8 +96,8 @@ class DailyCostChartBase extends React.Component { private initDatum = () => { const { currentCostData, forecastConeData, forecastData, previousCostData, showForecast } = this.props; - const costKey = messages.chartCostLegendLabel; - const costTooltipKey = messages.chartCostLegendTooltip; + const costKey = messages.chartCostLabel; + const costTooltipKey = messages.chartCostTooltip; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -106,7 +106,7 @@ class DailyCostChartBase extends React.Component { childName: 'previousCost', data: this.initDatumChildName(previousCostData, 'previousCost'), legendItem: { - name: getCostRangeString(previousCostData, costKey, true, true, 1, messages.chartCostLegendNoDataLabel), + name: getCostRangeString(previousCostData, costKey, true, true, 1, messages.chartCostLabelNoData), symbol: { fill: chartStyles.previousColorScale[0], type: 'minus', @@ -124,7 +124,7 @@ class DailyCostChartBase extends React.Component { childName: 'currentCost', data: this.initDatumChildName(currentCostData, 'currentCost'), legendItem: { - name: getCostRangeString(currentCostData, costKey, true, false, 0, messages.chartCostLegendNoDataLabel), + name: getCostRangeString(currentCostData, costKey, true, false, 0, messages.chartCostLabelNoData), symbol: { fill: chartStyles.currentColorScale[0], type: 'minus', @@ -147,17 +147,17 @@ class DailyCostChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastData, - messages.chartCostForecastLegendLabel, + messages.chartCostForecastLabel, false, false, 0, - messages.chartCostForecastLegendNoDataLabel + messages.chartCostForecastLabelNoData ), symbol: { fill: chartStyles.forecastDataColorScale[0], type: 'minus', }, - tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastTooltip, false, false), }, isBar: true, isForecast: true, @@ -173,17 +173,17 @@ class DailyCostChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastConeData, - messages.chartCostForecastConeLegendLabel, + messages.chartCostForecastConeLabel, false, false, 0, - messages.chartCostForecastConeLegendNoDataLabel + messages.chartCostForecastConeLabelNoData ), symbol: { fill: chartStyles.forecastConeDataColorScale[0], type: 'triangleLeft', }, - tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeTooltip, false, false), }, isForecast: true, isLine: true, diff --git a/src/routes/components/charts/dailyTrendChart/dailyTrendChart.tsx b/src/routes/components/charts/dailyTrendChart/dailyTrendChart.tsx index 9bd4ef8b2..a5dbf4977 100644 --- a/src/routes/components/charts/dailyTrendChart/dailyTrendChart.tsx +++ b/src/routes/components/charts/dailyTrendChart/dailyTrendChart.tsx @@ -108,22 +108,22 @@ class DailyTrendChartBase extends React.Component { } = this.props; const key = showUsageLegendLabel - ? messages.chartUsageLegendLabel + ? messages.chartUsageLabel : showSupplementaryLabel - ? messages.chartCostSupplementaryLegendLabel - : messages.chartCostLegendLabel; + ? messages.chartSupplementaryCostLabel + : messages.chartCostLabel; const tooltipKey = showUsageLegendLabel - ? messages.chartUsageLegendTooltip + ? messages.chartUsageTooltip : showSupplementaryLabel - ? messages.chartCostSupplementaryLegendTooltip - : messages.chartCostLegendTooltip; + ? messages.chartSupplementaryCostTooltip + : messages.chartCostTooltip; const noDataKey = showUsageLegendLabel - ? messages.chartUsageLegendNoDataLabel + ? messages.chartUsageLabelNoData : showSupplementaryLabel - ? messages.chartCostSupplementaryLegendNoDataLabel - : messages.chartCostLegendNoDataLabel; + ? messages.chartSupplementaryCostLabelNoData + : messages.chartCostLabelNoData; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -173,17 +173,17 @@ class DailyTrendChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastData, - messages.chartCostForecastLegendLabel, + messages.chartCostForecastLabel, false, false, 0, - messages.chartCostForecastLegendNoDataLabel + messages.chartCostForecastLabelNoData ), symbol: { fill: chartStyles.forecastDataColorScale[0], type: 'minus', }, - tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastTooltip, false, false), }, isBar: true, isForecast: true, @@ -199,17 +199,17 @@ class DailyTrendChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastConeData, - messages.chartCostForecastConeLegendLabel, + messages.chartCostForecastConeLabel, false, false, 0, - messages.chartCostForecastConeLegendNoDataLabel + messages.chartCostForecastConeLabelNoData ), symbol: { fill: chartStyles.forecastConeDataColorScale[0], type: 'minus', }, - tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeTooltip, false, false), }, isForecast: true, isLine: true, diff --git a/src/routes/components/charts/historicalCostChart/historicalCostChart.tsx b/src/routes/components/charts/historicalCostChart/historicalCostChart.tsx index da0c4ed31..a612b872d 100644 --- a/src/routes/components/charts/historicalCostChart/historicalCostChart.tsx +++ b/src/routes/components/charts/historicalCostChart/historicalCostChart.tsx @@ -94,8 +94,8 @@ class HistoricalCostChartBase extends React.Component { const { currentCostData, previousCostData } = this.props; - const costKey = messages.chartCostLegendLabel; - const costTooltipKey = messages.chartCostLegendTooltip; + const costKey = messages.chartCostLabel; + const costTooltipKey = messages.chartCostTooltip; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -104,7 +104,7 @@ class HistoricalCostChartBase extends React.Component { const { currentData, previousData, showUsageLegendLabel = false } = this.props; - const key = showUsageLegendLabel ? messages.chartUsageLegendLabel : messages.chartCostLegendLabel; - const toolTipKey = showUsageLegendLabel ? messages.chartUsageLegendTooltip : messages.chartCostLegendTooltip; + const key = showUsageLegendLabel ? messages.chartUsageLabel : messages.chartCostLabel; + const toolTipKey = showUsageLegendLabel ? messages.chartUsageTooltip : messages.chartCostTooltip; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -99,7 +99,7 @@ class HistoricalTrendChartBase extends React.Component { } = this.props; const key = showUsageLegendLabel - ? messages.chartUsageLegendLabel + ? messages.chartUsageLabel : showSupplementaryLabel - ? messages.chartCostSupplementaryLegendLabel - : messages.chartCostLegendLabel; + ? messages.chartSupplementaryCostLabel + : messages.chartCostLabel; const tooltipKey = showUsageLegendLabel - ? messages.chartUsageLegendTooltip + ? messages.chartUsageTooltip : showSupplementaryLabel - ? messages.chartCostSupplementaryLegendTooltip - : messages.chartCostLegendTooltip; + ? messages.chartSupplementaryCostTooltip + : messages.chartCostTooltip; const noDataKey = showUsageLegendLabel - ? messages.chartUsageLegendNoDataLabel + ? messages.chartUsageLabelNoData : showSupplementaryLabel - ? messages.chartCostSupplementaryLegendNoDataLabel - : messages.chartCostLegendNoDataLabel; + ? messages.chartSupplementaryCostLabelNoData + : messages.chartCostLabelNoData; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -170,17 +170,17 @@ class TrendChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastData, - messages.chartCostForecastLegendLabel, + messages.chartCostForecastLabel, false, false, 0, - messages.chartCostForecastLegendNoDataLabel + messages.chartCostForecastLabelNoData ), symbol: { fill: chartStyles.forecastDataColorScale[0], type: 'minus', }, - tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastData, messages.chartCostForecastTooltip, false, false), }, style: { data: { @@ -195,17 +195,17 @@ class TrendChartBase extends React.Component { legendItem: { name: getCostRangeString( forecastConeData, - messages.chartCostForecastConeLegendLabel, + messages.chartCostForecastConeLabel, false, false, 0, - messages.chartCostForecastConeLegendNoDataLabel + messages.chartCostForecastConeLabelNoData ), symbol: { fill: chartStyles.forecastConeDataColorScale[0], type: 'triangleLeft', }, - tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeLegendTooltip, false, false), + tooltip: getCostRangeTooltip(forecastConeData, messages.chartCostForecastConeTooltip, false, false), }, style: { data: { diff --git a/src/routes/components/charts/usageChart/usageChart.tsx b/src/routes/components/charts/usageChart/usageChart.tsx index 0c34b6df4..74cb82b72 100644 --- a/src/routes/components/charts/usageChart/usageChart.tsx +++ b/src/routes/components/charts/usageChart/usageChart.tsx @@ -92,10 +92,10 @@ class UsageChartBase extends React.Component { private initDatum = () => { const { currentRequestData, currentUsageData, previousRequestData, previousUsageData } = this.props; - const usageKey = messages.chartUsageLegendLabel; - const usageTooltipKey = messages.chartUsageLegendTooltip; - const requestKey = messages.chartRequestsLegendLabel; - const requestTooltipKey = messages.chartRequestsLegendTooltip; + const usageKey = messages.chartUsageLabel; + const usageTooltipKey = messages.chartUsageTooltip; + const requestKey = messages.chartRequestsLabel; + const requestTooltipKey = messages.chartRequestsTooltip; // Show all legends, regardless of length -- https://github.com/project-koku/koku-ui/issues/248 @@ -104,7 +104,7 @@ class UsageChartBase extends React.Component { childName: 'previousUsage', data: previousUsageData, legendItem: { - name: getUsageRangeString(previousUsageData, usageKey, true, true, 1, messages.chartUsageLegendNoDataLabel), + name: getUsageRangeString(previousUsageData, usageKey, true, true, 1, messages.chartUsageLabelNoData), symbol: { fill: chartStyles.legendColorScale[0], type: 'minus', @@ -117,7 +117,7 @@ class UsageChartBase extends React.Component { childName: 'currentUsage', data: currentUsageData, legendItem: { - name: getUsageRangeString(currentUsageData, usageKey, true, false, 0, messages.chartUsageLegendNoDataLabel), + name: getUsageRangeString(currentUsageData, usageKey, true, false, 0, messages.chartUsageLabelNoData), symbol: { fill: chartStyles.legendColorScale[1], type: 'minus', @@ -130,14 +130,7 @@ class UsageChartBase extends React.Component { childName: 'previousRequest', data: previousRequestData, legendItem: { - name: getUsageRangeString( - previousRequestData, - requestKey, - true, - true, - 1, - messages.chartRequestsLegendNoDataLabel - ), + name: getUsageRangeString(previousRequestData, requestKey, true, true, 1, messages.chartRequestsLabelNoData), symbol: { fill: chartStyles.legendColorScale[2], type: 'dash', @@ -150,14 +143,7 @@ class UsageChartBase extends React.Component { childName: 'currentRequest', data: currentRequestData, legendItem: { - name: getUsageRangeString( - currentRequestData, - requestKey, - true, - false, - 0, - messages.chartRequestsLegendNoDataLabel - ), + name: getUsageRangeString(currentRequestData, requestKey, true, false, 0, messages.chartRequestsLabelNoData), symbol: { fill: chartStyles.legendColorScale[3], type: 'dash', diff --git a/src/routes/details/components/historicalData/data.ts b/src/routes/details/components/historicalData/data.ts new file mode 100644 index 000000000..ebcf37279 --- /dev/null +++ b/src/routes/details/components/historicalData/data.ts @@ -0,0 +1,173 @@ +/** + * Design doc https://docs.google.com/document/d/1b9JhMmFRvp0JL_wFkiOPzyyx72kG2_BZGjoRcyz8rq4/edit + */ + +export const currentData = { + meta: { + // usual count limit offset currency filter group by order by exclude + total: { + usage: { + value: 3.6801746441, + units: 'GB', + }, + data_transfer_in: { + value: 2.789192834, + units: 'GB', + }, + data_transfer_out: { + value: 0.8909818101, + units: 'GB', + }, + }, + } as any, + links: { + // usual links info + } as any, + data: [ + { + date: '2024-04-22', + values: [ + { + date: '2024-04-22', + data_transfer_in: { + value: 3.6801746441, + units: 'GB', + }, + data_transfer_out: { + value: 2.6866746441, + units: 'GB', + }, + resource_id: 'i-727f8dc9c567f1552', + clusters: ['Test OCP on AWS'], + source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', + region: 'us-east-1', + }, + ], + }, + { + date: '2024-04-23', + values: [ + { + date: '2024-04-23', + data_transfer_in: { + value: 13.6801746441, + units: 'GB', + }, + data_transfer_out: { + value: 12.6866746441, + units: 'GB', + }, + resource_id: 'i-727f8dc9c567f1552', + clusters: ['Test OCP on AWS'], + source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', + region: 'us-east-1', + }, + ], + }, + { + date: '2024-04-24', + values: [ + { + date: '2024-04-24', + data_transfer_in: { + value: 8.6801746441, + units: 'GB', + }, + data_transfer_out: { + value: 7.6866746441, + units: 'GB', + }, + resource_id: 'i-727f8dc9c567f1552', + clusters: ['Test OCP on AWS'], + source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', + region: 'us-east-1', + }, + ], + }, + ], +}; + +export const previousData = { + meta: { + // usual count limit offset currency filter group by order by exclude + total: { + usage: { + value: 3.6801746441, + units: 'GB', + }, + data_transfer_in: { + value: 2.789192834, + units: 'GB', + }, + data_transfer_out: { + value: 0.8909818101, + units: 'GB', + }, + }, + } as any, + links: { + // usual links info + } as any, + data: [ + { + date: '2024-04-22', + values: [ + { + date: '2024-04-22', + data_transfer_in: { + value: 2.6801746441, + units: 'GB', + }, + data_transfer_out: { + value: 1.6866746441, + units: 'GB', + }, + resource_id: 'i-727f8dc9c567f1552', + clusters: ['Test OCP on AWS'], + source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', + region: 'us-east-1', + }, + ], + }, + { + date: '2024-04-23', + values: [ + { + date: '2024-04-23', + data_transfer_in: { + value: 12.6801746441, + units: 'GB', + }, + data_transfer_out: { + value: 10.6866746441, + units: 'GB', + }, + resource_id: 'i-727f8dc9c567f1552', + clusters: ['Test OCP on AWS'], + source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', + region: 'us-east-1', + }, + ], + }, + { + date: '2024-04-24', + values: [ + { + date: '2024-04-24', + data_transfer_in: { + value: 10.6801746441, + units: 'GB', + }, + data_transfer_out: { + value: 9.6866746441, + units: 'GB', + }, + resource_id: 'i-727f8dc9c567f1552', + clusters: ['Test OCP on AWS'], + source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', + region: 'us-east-1', + }, + ], + }, + ], +}; diff --git a/src/routes/details/components/historicalData/historicalDataBase.tsx b/src/routes/details/components/historicalData/historicalDataBase.tsx index 7c5b683e0..27b08ddc0 100644 --- a/src/routes/details/components/historicalData/historicalDataBase.tsx +++ b/src/routes/details/components/historicalData/historicalDataBase.tsx @@ -8,6 +8,7 @@ import type { HistoricalDataWidget } from 'store/breakdown/historicalData/common import { HistoricalDataWidgetType } from 'store/breakdown/historicalData/common/historicalDataCommon'; import { HistoricalDataCostChart } from './historicalDataCostChart'; +import { HistoricalDataNetworkChart } from './historicalDataNetworkChart'; import { HistoricalDataTrendChart } from './historicalDataTrendChart'; import { HistoricalDataUsageChart } from './historicalDataUsageChart'; import { HistoricalDataVolumeChart } from './historicalDataVolumeChart'; @@ -81,7 +82,7 @@ class HistoricalDatasBase extends React.Component { - { + public componentDidMount() { + this.updateReport(); + } + + public componentDidUpdate(prevProps: HistoricalDataNetworkChartProps) { + const { currentQueryString, previousQueryString } = this.props; + + if (prevProps.currentQueryString !== currentQueryString || prevProps.previousQueryString !== previousQueryString) { + this.updateReport(); + } + } + + private getSkeleton = () => { + return ( + <> + + + + ); + }; + + private updateReport = () => { + const { fetchReport, currentQueryString, previousQueryString, reportPathsType, reportType } = this.props; + fetchReport(reportPathsType, reportType, currentQueryString); + fetchReport(reportPathsType, reportType, previousQueryString); + }; + + public render() { + const { chartName, currentReport, currentReportFetchStatus, previousReport, previousReportFetchStatus, intl } = + this.props; + + // Current data + const currentRequestData = transformReport(currentReport, DatumType.rolling, 'date', 'data_transfer_in', undefined); + const currentUsageData = transformReport(currentReport, DatumType.rolling, 'date', 'data_transfer_out', undefined); + + // Previous data + const previousRequestData = transformReport( + previousReport, + DatumType.rolling, + 'date', + 'data_transfer_in', + undefined + ); + const previousUsageData = transformReport( + previousReport, + DatumType.rolling, + 'date', + 'data_transfer_out', + undefined + ); + + const usageUnits = currentReport?.meta?.total?.usage ? currentReport.meta.total.usage.units : ''; + + return ( +
+
+ {currentReportFetchStatus === FetchStatus.inProgress && + previousReportFetchStatus === FetchStatus.inProgress ? ( + this.getSkeleton() + ) : ( + + )} +
+
+ ); + } +} + +const mapStateToProps = createMapStateToProps( + (state, { reportPathsType, reportType, router }) => { + const queryFromRoute = parseQuery(router.location.search); + const queryState = getQueryState(router.location, 'details'); + + const groupByOrgValue = getGroupByOrgValue(queryFromRoute); + const groupBy = getGroupById(queryFromRoute); + const groupByValue = getGroupByValue(queryFromRoute); + + // instance-types and storage APIs must filter org units + const useFilter = reportType === ReportType.instanceType || reportType === ReportType.storage; + + // Todo: group_by storage_class? + const baseQuery: Query = { + filter_by: { + // Add filters here to apply logical OR/AND + ...(queryState?.filter_by && queryState.filter_by), + ...(queryFromRoute?.isPlatformCosts && { category: platformCategoryKey }), + ...(queryFromRoute?.filter?.account && { [`${logicalAndPrefix}account`]: queryFromRoute.filter.account }), + ...(groupByOrgValue && useFilter && { [orgUnitIdKey]: groupByOrgValue }), + // Workaround for https://issues.redhat.com/browse/COST-1189 + ...(queryState?.filter_by && + queryState.filter_by[orgUnitIdKey] && { + [`${logicalOrPrefix}${orgUnitIdKey}`]: queryState.filter_by[orgUnitIdKey], + [orgUnitIdKey]: undefined, + }), + }, + exclude: { + ...(queryState?.exclude && queryState.exclude), + }, + group_by: { + ...(groupByOrgValue && !useFilter && { [orgUnitIdKey]: groupByOrgValue }), + ...(groupBy && !groupByOrgValue && { [groupBy]: groupByValue }), + }, + }; + + // Current report + const currentQuery: Query = { + ...baseQuery, + filter: { + resolution: 'daily', + time_scope_units: 'month', + time_scope_value: -1, + }, + filter_by: { + ...baseQuery.filter_by, + // Omit filters associated with the current group_by -- see https://issues.redhat.com/browse/COST-1131 and https://issues.redhat.com/browse/COST-3642 + ...(groupBy && groupByValue !== '*' && { [groupBy]: undefined }), // Used by the "Platform" project + }, + }; + + const currentQueryString = getQuery(currentQuery); + let currentReport = reportSelectors.selectReport(state, reportPathsType, reportType, currentQueryString); + const currentReportFetchStatus = reportSelectors.selectReportFetchStatus( + state, + reportPathsType, + reportType, + currentQueryString + ); + + // Previous report + const previousQuery: Query = { + ...baseQuery, + filter: { + resolution: 'daily', + time_scope_units: 'month', + time_scope_value: -2, + }, + filter_by: { + ...baseQuery.filter_by, + // Omit filters associated with the current group_by -- see https://issues.redhat.com/browse/COST-1131 and https://issues.redhat.com/browse/COST-3642 + ...(groupBy && groupByValue !== '*' && { [groupBy]: undefined }), // Used by the "Platform" project + }, + }; + + const previousQueryString = getQuery(previousQuery); + let previousReport = reportSelectors.selectReport(state, reportPathsType, reportType, previousQueryString); + const previousReportFetchStatus = reportSelectors.selectReportFetchStatus( + state, + reportPathsType, + reportType, + previousQueryString + ); + + // Todo: Update to use new API response + const isOcpCloudNetworkingToggleEnabled = FeatureToggleSelectors.selectIsOcpCloudNetworkingToggleEnabled(state); + if (isOcpCloudNetworkingToggleEnabled) { + currentReport = currentData; + previousReport = previousData; + } + + return { + currentQuery, + currentQueryString, + currentReport, + currentReportFetchStatus, + previousQuery, + previousQueryString, + previousReport, + previousReportFetchStatus, + }; + } +); + +const mapDispatchToProps: HistoricalDataNetworkChartDispatchProps = { + fetchReport: reportActions.fetchReport, +}; + +const HistoricalDataNetworkChart = injectIntl( + withRouter(connect(mapStateToProps, mapDispatchToProps)(HistoricalDataNetworkChartBase)) +); + +export { HistoricalDataNetworkChart }; diff --git a/src/routes/details/components/historicalData/historicalDataTrendChart.tsx b/src/routes/details/components/historicalData/historicalDataTrendChart.tsx index 9e7d55a6c..4310a4253 100644 --- a/src/routes/details/components/historicalData/historicalDataTrendChart.tsx +++ b/src/routes/details/components/historicalData/historicalDataTrendChart.tsx @@ -100,13 +100,15 @@ class HistoricalDataTrendChartBase extends React.Component @@ -131,6 +128,7 @@ const mapStateToProps = createMapStateToProps Date: Tue, 23 Apr 2024 13:58:23 -0400 Subject: [PATCH 12/49] Rename ocpBreakdownOptimizations as optimizations --- .../{ocpBreakdownOptimizations.tsx => optimizations.tsx} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename src/routes/details/ocpBreakdown/{ocpBreakdownOptimizations.tsx => optimizations.tsx} (88%) diff --git a/src/routes/details/ocpBreakdown/ocpBreakdownOptimizations.tsx b/src/routes/details/ocpBreakdown/optimizations.tsx similarity index 88% rename from src/routes/details/ocpBreakdown/ocpBreakdownOptimizations.tsx rename to src/routes/details/ocpBreakdown/optimizations.tsx index 153b59b3f..1aa4a56ab 100644 --- a/src/routes/details/ocpBreakdown/ocpBreakdownOptimizations.tsx +++ b/src/routes/details/ocpBreakdown/optimizations.tsx @@ -10,11 +10,11 @@ import { getGroupById, getGroupByValue } from 'routes/utils/groupBy'; import { getQueryState } from 'routes/utils/queryState'; import { formatPath } from 'utils/paths'; -interface OcpOptimizationsBreakdownOwnProps { +interface OptimizationsOwnProps { // TBD... } -type OcpOptimizationsBreakdownProps = OcpOptimizationsBreakdownOwnProps; +type OptimizationsProps = OptimizationsOwnProps; const useQueryFromRoute = () => { const location = useLocation(); @@ -26,7 +26,7 @@ const useQueryState = () => { return getQueryState(location, 'details'); }; -const OcpBreakdownOptimizations: React.FC = () => { +const Optimizations: React.FC = () => { const intl = useIntl(); const location = useLocation(); const queryFromRoute = useQueryFromRoute(); @@ -57,4 +57,4 @@ const OcpBreakdownOptimizations: React.FC = () = ); }; -export { OcpBreakdownOptimizations }; +export { Optimizations }; From 4bfebd4e094772c5fbe0effadd9e4ed552c30dd7 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Tue, 23 Apr 2024 14:01:06 -0400 Subject: [PATCH 13/49] Added default breadcrumb path --- src/routes/details/awsBreakdown/awsBreakdown.tsx | 1 + src/routes/details/azureBreakdown/azureBreakdown.tsx | 1 + src/routes/details/gcpBreakdown/gcpBreakdown.tsx | 1 + src/routes/details/ibmBreakdown/ibmBreakdown.tsx | 1 + src/routes/details/ociBreakdown/ociBreakdown.tsx | 1 + src/routes/details/rhelBreakdown/rhelBreakdown.tsx | 1 + 6 files changed, 6 insertions(+) diff --git a/src/routes/details/awsBreakdown/awsBreakdown.tsx b/src/routes/details/awsBreakdown/awsBreakdown.tsx index bfc6d5bbf..793994e89 100644 --- a/src/routes/details/awsBreakdown/awsBreakdown.tsx +++ b/src/routes/details/awsBreakdown/awsBreakdown.tsx @@ -105,6 +105,7 @@ const mapStateToProps = createMapStateToProps, currency, + defaultBreadcrumbPath: formatPath(routes.azureDetails.path), description: queryFromRoute[breakdownDescKey], detailsURL, emptyStateTitle: intl.formatMessage(messages.azureDetailsTitle), diff --git a/src/routes/details/gcpBreakdown/gcpBreakdown.tsx b/src/routes/details/gcpBreakdown/gcpBreakdown.tsx index a0987bdec..a34be53b6 100644 --- a/src/routes/details/gcpBreakdown/gcpBreakdown.tsx +++ b/src/routes/details/gcpBreakdown/gcpBreakdown.tsx @@ -90,6 +90,7 @@ const mapStateToProps = createMapStateToProps, currency, + defaultBreadcrumbPath: formatPath(routes.gcpDetails.path), description: queryFromRoute[breakdownDescKey], detailsURL, emptyStateTitle: intl.formatMessage(messages.gcpDetailsTitle), diff --git a/src/routes/details/ibmBreakdown/ibmBreakdown.tsx b/src/routes/details/ibmBreakdown/ibmBreakdown.tsx index 08382317b..c7bbe8b08 100644 --- a/src/routes/details/ibmBreakdown/ibmBreakdown.tsx +++ b/src/routes/details/ibmBreakdown/ibmBreakdown.tsx @@ -90,6 +90,7 @@ const mapStateToProps = createMapStateToProps, currency, + defaultBreadcrumbPath: formatPath(routes.ibmDetails.path), description: queryFromRoute[breakdownDescKey], detailsURL, emptyStateTitle: intl.formatMessage(messages.ibmDetailsTitle), diff --git a/src/routes/details/ociBreakdown/ociBreakdown.tsx b/src/routes/details/ociBreakdown/ociBreakdown.tsx index d23d3c77e..2c8cf44a7 100644 --- a/src/routes/details/ociBreakdown/ociBreakdown.tsx +++ b/src/routes/details/ociBreakdown/ociBreakdown.tsx @@ -90,6 +90,7 @@ const mapStateToProps = createMapStateToProps( return { costOverviewComponent: , currency, + defaultBreadcrumbPath: formatPath(routes.ociDetails.path), description: queryFromRoute[breakdownDescKey], detailsURL, emptyStateTitle: intl.formatMessage(messages.ociDetailsTitle), diff --git a/src/routes/details/rhelBreakdown/rhelBreakdown.tsx b/src/routes/details/rhelBreakdown/rhelBreakdown.tsx index f368248a0..451ff1ea6 100644 --- a/src/routes/details/rhelBreakdown/rhelBreakdown.tsx +++ b/src/routes/details/rhelBreakdown/rhelBreakdown.tsx @@ -92,6 +92,7 @@ const mapStateToProps = createMapStateToProps, currency, + defaultBreadcrumbPath: formatPath(routes.rhelDetails.path), description: queryFromRoute[breakdownDescKey], detailsURL, emptyStateTitle: intl.formatMessage(messages.rhelDetailsTitle), From a64e853a10eddd6a95379b23ee4bd36b7a226b31 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Tue, 23 Apr 2024 14:01:27 -0400 Subject: [PATCH 14/49] Stub-out instances tab https://issues.redhat.com/browse/COST-4855 --- src/locales/messages.ts | 10 +++++ .../components/breakdown/breakdownBase.tsx | 30 +++++++++++-- src/routes/details/ocpBreakdown/instances.tsx | 44 +++++++++++++++++++ .../details/ocpBreakdown/ocpBreakdown.tsx | 8 +++- 4 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 src/routes/details/ocpBreakdown/instances.tsx diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 453ab944a..0a16b46c6 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -2319,6 +2319,16 @@ export default defineMessages({ description: 'Infrastructure', id: 'infrastructure', }, + instanceNames: { + defaultMessage: 'Instance names', + description: 'Instance names', + id: 'instanceNames', + }, + instances: { + defaultMessage: 'Instances', + description: 'Instances', + id: 'instances', + }, lastProcessed: { defaultMessage: 'Last processed', description: 'Last processed', diff --git a/src/routes/details/components/breakdown/breakdownBase.tsx b/src/routes/details/components/breakdown/breakdownBase.tsx index 23953650d..4046fefed 100644 --- a/src/routes/details/components/breakdown/breakdownBase.tsx +++ b/src/routes/details/components/breakdown/breakdownBase.tsx @@ -34,6 +34,7 @@ import BreakdownHeader from './breakdownHeader'; const enum BreakdownTab { costOverview = 'cost-overview', historicalData = 'historical-data', + instances = 'instances', optimizations = 'optimizations', } @@ -43,6 +44,8 @@ export const getIdKeyForTab = (tab: BreakdownTab) => { return 'cost-overview'; case BreakdownTab.historicalData: return 'historical-data'; + case BreakdownTab.instances: + return 'instances'; case BreakdownTab.optimizations: return 'optimizations'; } @@ -59,12 +62,15 @@ export interface BreakdownStateProps { costType?: string; currency?: string; dataDetailsComponent?: React.ReactNode; + defaultBreadcrumbPath?: string; description?: string; detailsURL?: string; emptyStateTitle?: string; groupBy?: string; groupByValue?: string; historicalDataComponent?: React.ReactNode; + instancesComponent?: React.ReactNode; + isAwsEc2InstancesToggleEnabled?: boolean; isOptimizationsTab?: boolean; isRosToggleEnabled?: boolean; optimizationsBadgeComponent?: React.ReactNode; @@ -127,7 +133,14 @@ class BreakdownBase extends React.Component { } private getAvailableTabs = () => { - const { costOverviewComponent, historicalDataComponent, isRosToggleEnabled, optimizationsComponent } = this.props; + const { + costOverviewComponent, + historicalDataComponent, + instancesComponent, + isAwsEc2InstancesToggleEnabled, + isRosToggleEnabled, + optimizationsComponent, + } = this.props; const availableTabs = []; if (costOverviewComponent) { @@ -142,6 +155,12 @@ class BreakdownBase extends React.Component { tab: BreakdownTab.historicalData, }); } + if (instancesComponent && isAwsEc2InstancesToggleEnabled) { + availableTabs.push({ + contentRef: React.createRef(), + tab: BreakdownTab.instances, + }); + } if (optimizationsComponent && isRosToggleEnabled) { availableTabs.push({ contentRef: React.createRef(), @@ -199,7 +218,7 @@ class BreakdownBase extends React.Component { }; private getTabItem = (tab: BreakdownTab, index: number) => { - const { costOverviewComponent, historicalDataComponent, optimizationsComponent } = this.props; + const { costOverviewComponent, historicalDataComponent, instancesComponent, optimizationsComponent } = this.props; const { activeTabKey } = this.state; const emptyTab = <>; // Lazily load tabs @@ -211,6 +230,8 @@ class BreakdownBase extends React.Component { return costOverviewComponent; } else if (currentTab === BreakdownTab.historicalData) { return historicalDataComponent; + } else if (currentTab === BreakdownTab.instances) { + return instancesComponent; } else if (currentTab === BreakdownTab.optimizations) { return optimizationsComponent; } else { @@ -235,6 +256,8 @@ class BreakdownBase extends React.Component { return intl.formatMessage(messages.breakdownCostOverviewTitle); } else if (tab === BreakdownTab.historicalData) { return intl.formatMessage(messages.breakdownHistoricalDataTitle); + } else if (tab === BreakdownTab.instances) { + return intl.formatMessage(messages.instances); } else if (tab === BreakdownTab.optimizations) { return intl.formatMessage(messages.optimizations); } @@ -272,6 +295,7 @@ class BreakdownBase extends React.Component { costType, currency, dataDetailsComponent, + defaultBreadcrumbPath, description, detailsURL, emptyStateTitle, @@ -316,7 +340,7 @@ class BreakdownBase extends React.Component { breadcrumb={ router.location.state && router.location.state.details ? router.location.state.details.breadcrumbPath - : undefined + : defaultBreadcrumbPath } clusterInfoComponent={clusterInfoComponent} dataDetailsComponent={dataDetailsComponent} diff --git a/src/routes/details/ocpBreakdown/instances.tsx b/src/routes/details/ocpBreakdown/instances.tsx new file mode 100644 index 000000000..f00cfcc99 --- /dev/null +++ b/src/routes/details/ocpBreakdown/instances.tsx @@ -0,0 +1,44 @@ +// import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent'; +// import type { Query } from 'api/queries/query'; +// import { parseQuery } from 'api/queries/query'; +// import messages from 'locales/messages'; +import React from 'react'; +// import { useIntl } from 'react-intl'; +import { useLocation } from 'react-router-dom'; +// import { routes } from 'routes'; +// import { getGroupById, getGroupByValue } from 'routes/utils/groupBy'; +import { getQueryState } from 'routes/utils/queryState'; +// import { formatPath } from 'utils/paths'; + +interface InstancesOwnProps { + // TBD... +} + +type InstancesProps = InstancesOwnProps; + +// const useQueryFromRoute = () => { +// const location = useLocation(); +// return parseQuery(location.search); +// }; + +const useQueryState = () => { + const location = useLocation(); + return getQueryState(location, 'details'); +}; + +const Instances: React.FC = () => { + // const intl = useIntl(); + // const location = useLocation(); + // const queryFromRoute = useQueryFromRoute(); + const queryState = useQueryState(); + + // const groupBy = getGroupById(queryFromRoute); + // const groupByValue = getGroupByValue(queryFromRoute); + // const otimizationsTab = location.search.indexOf('optimizationsTab') === -1 ? '&optimizationsTab=true' : ''; + + const tagsFilter = queryState?.filter_by?.tags ? queryState.filter_by.tags : null; + + return <>Hello{tagsFilter}; +}; + +export { Instances }; diff --git a/src/routes/details/ocpBreakdown/ocpBreakdown.tsx b/src/routes/details/ocpBreakdown/ocpBreakdown.tsx index a6c4209d4..782274d0e 100644 --- a/src/routes/details/ocpBreakdown/ocpBreakdown.tsx +++ b/src/routes/details/ocpBreakdown/ocpBreakdown.tsx @@ -30,7 +30,8 @@ import { getCostDistribution, getCurrency } from 'utils/sessionStorage'; import { CostOverview } from './costOverview'; import { HistoricalData } from './historicalData'; -import { OcpBreakdownOptimizations } from './ocpBreakdownOptimizations'; +import { Instances } from './instances'; +import { Optimizations } from './optimizations'; interface OcpBreakdownDispatchProps { closeOptimizationsDrawer?: typeof uiActions.closeOptimizationsDrawer; @@ -112,15 +113,18 @@ const mapStateToProps = createMapStateToProps ), currency, + defaultBreadcrumbPath: formatPath(routes.ocpDetails.path), description: queryFromRoute[breakdownDescKey], detailsURL, emptyStateTitle: intl.formatMessage(messages.ocpDetailsTitle), groupBy, groupByValue, historicalDataComponent: , + instancesComponent: , isOptimizationsTab: queryFromRoute.optimizationsTab !== undefined, + isAwsEc2InstancesToggleEnabled: FeatureToggleSelectors.selectIsAwsEc2InstancesToggleEnabled(state), isRosToggleEnabled: FeatureToggleSelectors.selectIsRosToggleEnabled(state), - optimizationsComponent: groupBy === 'project' && groupByValue !== '*' ? : undefined, + optimizationsComponent: groupBy === 'project' && groupByValue !== '*' ? : undefined, providers: filterProviders(providers, ProviderType.ocp), providersFetchStatus, providerType: ProviderType.ocp, From 7ce4786a43511c9e78005730d82be7945df04d16 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 24 Apr 2024 17:27:52 -0400 Subject: [PATCH 15/49] Added sudo JSON to stub-out instances table https://issues.redhat.com/browse/COST-4855 --- locales/data.json | 408 ++++++++++++++--- locales/translations.json | 61 +-- src/api/reports/report.ts | 22 + src/locales/messages.ts | 40 +- .../historicalTrendChart.test.tsx.snap | 43 +- .../__snapshots__/trendChart.test.tsx.snap | 16 +- src/routes/components/export/exportModal.tsx | 4 +- .../Red_Hat-IT_Optimization-Gray.svg | 21 - .../icons/optimizationIcon/index.ts | 1 - .../optimizationIcon/optimizationIcon.scss | 5 - .../optimizationIcon/optimizationIcon.tsx | 25 -- .../components/page/noInstances/index.ts | 1 + .../noInstances.tsx} | 12 +- .../page/noInstances/noInstancesState.tsx | 39 ++ .../components/page/noOptimizations/index.ts | 1 - .../noOptimizations/noOptimizationsState.tsx | 39 -- .../details/awsBreakdown/awsBreakdown.tsx | 14 +- .../details/awsBreakdown/instances/data.ts | 101 +++++ .../details/awsBreakdown/instances/index.ts | 1 + .../awsBreakdown/instances/instances.tsx | 410 ++++++++++++++++++ .../awsBreakdown/instances/instancesTable.tsx | 238 ++++++++++ .../instances/instancesToolbar.tsx | 213 +++++++++ .../details/components/actions/actions.tsx | 10 +- .../components/breakdown/breakdownBase.tsx | 16 +- .../components/pvcChart/modal/pvcContent.tsx | 13 +- .../components/tag/modal/tagContent.tsx | 9 +- .../details/components/tag/modal/tagModal.tsx | 23 +- src/routes/details/components/tag/tagLink.tsx | 22 +- src/routes/details/ocpBreakdown/instances.tsx | 44 -- .../details/ocpBreakdown/ocpBreakdown.tsx | 3 - .../details/ocpBreakdown/optimizations.tsx | 14 +- .../details/ocpDetails/detailsTable.tsx | 2 - .../details/rhelDetails/detailsTable.tsx | 2 - .../optimizationsBreakdown.tsx | 9 +- .../computedReport/getComputedReportItems.ts | 265 +++++------ src/routes/utils/groupBy.ts | 15 + src/utils/hooks.ts | 14 + src/utils/props.ts | 3 + 38 files changed, 1688 insertions(+), 491 deletions(-) delete mode 100644 src/routes/components/icons/optimizationIcon/Red_Hat-IT_Optimization-Gray.svg delete mode 100644 src/routes/components/icons/optimizationIcon/index.ts delete mode 100644 src/routes/components/icons/optimizationIcon/optimizationIcon.scss delete mode 100644 src/routes/components/icons/optimizationIcon/optimizationIcon.tsx create mode 100644 src/routes/components/page/noInstances/index.ts rename src/routes/components/page/{noOptimizations/noOptimizations.tsx => noInstances/noInstances.tsx} (60%) create mode 100644 src/routes/components/page/noInstances/noInstancesState.tsx delete mode 100644 src/routes/components/page/noOptimizations/index.ts delete mode 100644 src/routes/components/page/noOptimizations/noOptimizationsState.tsx create mode 100644 src/routes/details/awsBreakdown/instances/data.ts create mode 100644 src/routes/details/awsBreakdown/instances/index.ts create mode 100644 src/routes/details/awsBreakdown/instances/instances.tsx create mode 100644 src/routes/details/awsBreakdown/instances/instancesTable.tsx create mode 100644 src/routes/details/awsBreakdown/instances/instancesToolbar.tsx delete mode 100644 src/routes/details/ocpBreakdown/instances.tsx diff --git a/locales/data.json b/locales/data.json index 7d9d3ce17..675aef241 100644 --- a/locales/data.json +++ b/locales/data.json @@ -671,7 +671,7 @@ "value": "Cancel" } ], - "chartCostForecastConeLegendLabel": [ + "chartCostForecastConeLabel": [ { "type": 0, "value": "Cost confidence (" @@ -685,27 +685,13 @@ "value": ")" } ], - "chartCostForecastConeLegendNoDataLabel": [ + "chartCostForecastConeLabelNoData": [ { "type": 0, "value": "Cost confidence (no data)" } ], - "chartCostForecastConeLegendTooltip": [ - { - "type": 0, - "value": "Cost confidence (" - }, - { - "type": 1, - "value": "month" - }, - { - "type": 0, - "value": ")" - } - ], - "chartCostForecastConeTooltip": [ + "chartCostForecastConeRangeTooltip": [ { "type": 1, "value": "value0" @@ -719,30 +705,10 @@ "value": "value1" } ], - "chartCostForecastLegendLabel": [ - { - "type": 0, - "value": "Cost forecast (" - }, - { - "type": 1, - "value": "dateRange" - }, - { - "type": 0, - "value": ")" - } - ], - "chartCostForecastLegendNoDataLabel": [ - { - "type": 0, - "value": "Cost forecast (no data)" - } - ], - "chartCostForecastLegendTooltip": [ + "chartCostForecastConeTooltip": [ { "type": 0, - "value": "Cost forecast (" + "value": "Cost confidence (" }, { "type": 1, @@ -753,10 +719,10 @@ "value": ")" } ], - "chartCostLegendLabel": [ + "chartCostForecastLabel": [ { "type": 0, - "value": "Cost (" + "value": "Cost forecast (" }, { "type": 1, @@ -767,16 +733,16 @@ "value": ")" } ], - "chartCostLegendNoDataLabel": [ + "chartCostForecastLabelNoData": [ { "type": 0, - "value": "Cost (no data)" + "value": "Cost forecast (no data)" } ], - "chartCostLegendTooltip": [ + "chartCostForecastTooltip": [ { "type": 0, - "value": "Cost (" + "value": "Cost forecast (" }, { "type": 1, @@ -787,10 +753,10 @@ "value": ")" } ], - "chartCostSupplementaryLegendLabel": [ + "chartCostLabel": [ { "type": 0, - "value": "Supplementary cost (" + "value": "Cost (" }, { "type": 1, @@ -801,16 +767,16 @@ "value": ")" } ], - "chartCostSupplementaryLegendNoDataLabel": [ + "chartCostLabelNoData": [ { "type": 0, - "value": "Supplementary cost (no data)" + "value": "Cost (no data)" } ], - "chartCostSupplementaryLegendTooltip": [ + "chartCostTooltip": [ { "type": 0, - "value": "Supplementary cost (" + "value": "Data out (" }, { "type": 1, @@ -831,7 +797,7 @@ "value": "day" } ], - "chartLimitLegendLabel": [ + "chartLimitLabel": [ { "type": 0, "value": "Limit (" @@ -845,13 +811,13 @@ "value": ")" } ], - "chartLimitLegendNoDataLabel": [ + "chartLimitLabelNoData": [ { "type": 0, "value": "Limit (no data)" } ], - "chartLimitLegendTooltip": [ + "chartLimitTooltip": [ { "type": 0, "value": "Limit (" @@ -905,7 +871,7 @@ "value": "count" } ], - "chartRequestsLegendLabel": [ + "chartRequestsLabel": [ { "type": 0, "value": "Requests (" @@ -919,13 +885,13 @@ "value": ")" } ], - "chartRequestsLegendNoDataLabel": [ + "chartRequestsLabelNoData": [ { "type": 0, "value": "Requests (no data)" } ], - "chartRequestsLegendTooltip": [ + "chartRequestsTooltip": [ { "type": 0, "value": "Requests (" @@ -939,7 +905,41 @@ "value": ")" } ], - "chartUsageLegendLabel": [ + "chartSupplementaryCostLabel": [ + { + "type": 0, + "value": "Supplementary cost (" + }, + { + "type": 1, + "value": "dateRange" + }, + { + "type": 0, + "value": ")" + } + ], + "chartSupplementaryCostLabelNoData": [ + { + "type": 0, + "value": "Supplementary cost (no data)" + } + ], + "chartSupplementaryCostTooltip": [ + { + "type": 0, + "value": "Supplementary cost (" + }, + { + "type": 1, + "value": "month" + }, + { + "type": 0, + "value": ")" + } + ], + "chartUsageLabel": [ { "type": 0, "value": "Usage (" @@ -953,13 +953,13 @@ "value": ")" } ], - "chartUsageLegendNoDataLabel": [ + "chartUsageLabelNoData": [ { "type": 0, "value": "Usage (no data)" } ], - "chartUsageLegendTooltip": [ + "chartUsageTooltip": [ { "type": 0, "value": "Usage (" @@ -2840,6 +2840,14 @@ } ] }, + "cpu": { + "value": [ + { + "type": 0, + "value": "CPU" + } + ] + }, "gcp_project": { "value": [ { @@ -2856,6 +2864,30 @@ } ] }, + "instance": { + "value": [ + { + "type": 0, + "value": "Instance names" + } + ] + }, + "instance_type": { + "value": [ + { + "type": 0, + "value": "Instance type" + } + ] + }, + "memory": { + "value": [ + { + "type": 0, + "value": "Memory" + } + ] + }, "name": { "value": [ { @@ -2872,6 +2904,14 @@ } ] }, + "operating_system": { + "value": [ + { + "type": 0, + "value": "Operating system" + } + ] + }, "org_unit_id": { "value": [ { @@ -2880,6 +2920,14 @@ } ] }, + "os": { + "value": [ + { + "type": 0, + "value": "OS" + } + ] + }, "other": { "value": [] }, @@ -2978,6 +3026,14 @@ "value": "Tag keys" } ] + }, + "tags": { + "value": [ + { + "type": 0, + "value": "Tags" + } + ] } }, "type": 5, @@ -4333,6 +4389,67 @@ } ] }, + "instance": { + "value": [ + { + "options": { + "daily": { + "value": [ + { + "type": 1, + "value": "provider" + }, + { + "type": 0, + "value": "_instances_daily_" + }, + { + "type": 1, + "value": "startDate" + }, + { + "type": 0, + "value": "_" + }, + { + "type": 1, + "value": "endDate" + } + ] + }, + "monthly": { + "value": [ + { + "type": 1, + "value": "provider" + }, + { + "type": 0, + "value": "_instances_monthly_" + }, + { + "type": 1, + "value": "startDate" + }, + { + "type": 0, + "value": "_" + }, + { + "type": 1, + "value": "endDate" + } + ] + }, + "other": { + "value": [] + } + }, + "type": 5, + "value": "resolution" + } + ] + }, "node": { "value": [ { @@ -5086,6 +5203,14 @@ } ] }, + "instance": { + "value": [ + { + "type": 0, + "value": "Aggregates of the following instances will be exported to a .csv file." + } + ] + }, "node": { "value": [ { @@ -5589,6 +5714,107 @@ } ] }, + "instance": { + "value": [ + { + "options": { + "aws": { + "value": [ + { + "type": 0, + "value": "Amazon Web Services grouped by instance" + } + ] + }, + "aws_ocp": { + "value": [ + { + "type": 0, + "value": "Amazon Web Services filtered by OpenShift grouped by instance" + } + ] + }, + "azure": { + "value": [ + { + "type": 0, + "value": "Microsoft Azure grouped by instance" + } + ] + }, + "azure_ocp": { + "value": [ + { + "type": 0, + "value": "Microsoft Azure filtered by OpenShift grouped by instance" + } + ] + }, + "gcp": { + "value": [ + { + "type": 0, + "value": "Google Cloud Platform grouped by instance" + } + ] + }, + "gcp_ocp": { + "value": [ + { + "type": 0, + "value": "Google Cloud Platform filtered by OpenShift grouped by instance" + } + ] + }, + "ibm": { + "value": [ + { + "type": 0, + "value": "IBM Cloud grouped by instance" + } + ] + }, + "ibm_ocp": { + "value": [ + { + "type": 0, + "value": "IBM Cloud filtered by OpenShift grouped by instance" + } + ] + }, + "oci": { + "value": [ + { + "type": 0, + "value": "Oracle Cloud Infrastructure grouped by instance" + } + ] + }, + "ocp": { + "value": [ + { + "type": 0, + "value": "OpenShift grouped by instance" + } + ] + }, + "ocp_cloud": { + "value": [ + { + "type": 0, + "value": "All cloud filtered by OpenShift grouped by instance" + } + ] + }, + "other": { + "value": [] + } + }, + "type": 5, + "value": "provider" + } + ] + }, "node": { "value": [ { @@ -6654,6 +6880,22 @@ } ] }, + "instance": { + "value": [ + { + "type": 0, + "value": "Selected instances (" + }, + { + "type": 1, + "value": "count" + }, + { + "type": 0, + "value": ")" + } + ] + }, "node": { "value": [ { @@ -7617,6 +7859,14 @@ } ] }, + "instance": { + "value": [ + { + "type": 0, + "value": "Instance" + } + ] + }, "name": { "value": [ { @@ -7633,6 +7883,14 @@ } ] }, + "operating_system": { + "value": [ + { + "type": 0, + "value": "Operating system" + } + ] + }, "org_unit_id": { "value": [ { @@ -9944,6 +10202,12 @@ "value": "Infrastructure" } ], + "instances": [ + { + "type": 0, + "value": "Instances" + } + ], "lastProcessed": [ { "type": 0, @@ -10468,6 +10732,18 @@ "value": "There are no export files available" } ], + "noInstancesDesc": [ + { + "type": 0, + "value": "Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances." + } + ], + "noInstancesTitle": [ + { + "type": 0, + "value": "No instances available" + } + ], "noMappedTags": [ { "type": 0, @@ -10498,18 +10774,6 @@ "value": "Tags must be enabled to be mapped." } ], - "noOptimizationsDesc": [ - { - "type": 0, - "value": "Resource Optimization is now available in preview for select customers. If your organization wants to participate, tell us through the Feedback button, which is purple and located on the right. Otherwise, there is not enough data available to generate an optimization." - } - ], - "noOptimizationsTitle": [ - { - "type": 0, - "value": "No optimizations available" - } - ], "noProvidersStateAwsDesc": [ { "type": 0, diff --git a/locales/translations.json b/locales/translations.json index a66dcbf17..4e5e58729 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -31,31 +31,31 @@ "breakdownTotalCostDate": "{value} total cost ({dateRange})", "calculationType": "Calculation type", "cancel": "Cancel", - "chartCostForecastConeLegendLabel": "Cost confidence ({dateRange})", - "chartCostForecastConeLegendNoDataLabel": "Cost confidence (no data)", - "chartCostForecastConeLegendTooltip": "Cost confidence ({month})", - "chartCostForecastConeTooltip": "{value0} - {value1}", - "chartCostForecastLegendLabel": "Cost forecast ({dateRange})", - "chartCostForecastLegendNoDataLabel": "Cost forecast (no data)", - "chartCostForecastLegendTooltip": "Cost forecast ({month})", - "chartCostLegendLabel": "Cost ({dateRange})", - "chartCostLegendNoDataLabel": "Cost (no data)", - "chartCostLegendTooltip": "Cost ({month})", - "chartCostSupplementaryLegendLabel": "Supplementary cost ({dateRange})", - "chartCostSupplementaryLegendNoDataLabel": "Supplementary cost (no data)", - "chartCostSupplementaryLegendTooltip": "Supplementary cost ({month})", + "chartCostForecastConeLabel": "Cost confidence ({dateRange})", + "chartCostForecastConeLabelNoData": "Cost confidence (no data)", + "chartCostForecastConeRangeTooltip": "{value0} - {value1}", + "chartCostForecastConeTooltip": "Cost confidence ({month})", + "chartCostForecastLabel": "Cost forecast ({dateRange})", + "chartCostForecastLabelNoData": "Cost forecast (no data)", + "chartCostForecastTooltip": "Cost forecast ({month})", + "chartCostLabel": "Cost ({dateRange})", + "chartCostLabelNoData": "Cost (no data)", + "chartCostTooltip": "Data out ({month})", "chartDayOfTheMonth": "Day {day}", - "chartLimitLegendLabel": "Limit ({dateRange})", - "chartLimitLegendNoDataLabel": "Limit (no data)", - "chartLimitLegendTooltip": "Limit ({month})", + "chartLimitLabel": "Limit ({dateRange})", + "chartLimitLabelNoData": "Limit (no data)", + "chartLimitTooltip": "Limit ({month})", "chartNoData": "no data", "chartOthers": "{count, plural, one {{count} Other} other {{count} Others}}", - "chartRequestsLegendLabel": "Requests ({dateRange})", - "chartRequestsLegendNoDataLabel": "Requests (no data)", - "chartRequestsLegendTooltip": "Requests ({month})", - "chartUsageLegendLabel": "Usage ({dateRange})", - "chartUsageLegendNoDataLabel": "Usage (no data)", - "chartUsageLegendTooltip": "Usage ({month})", + "chartRequestsLabel": "Requests ({dateRange})", + "chartRequestsLabelNoData": "Requests (no data)", + "chartRequestsTooltip": "Requests ({month})", + "chartSupplementaryCostLabel": "Supplementary cost ({dateRange})", + "chartSupplementaryCostLabelNoData": "Supplementary cost (no data)", + "chartSupplementaryCostTooltip": "Supplementary cost ({month})", + "chartUsageLabel": "Usage ({dateRange})", + "chartUsageLabelNoData": "Usage (no data)", + "chartUsageTooltip": "Usage ({month})", "chooseKeyPlaceholder": "Choose key", "chooseValuePlaceholder": "Choose value", "close": "Close", @@ -225,7 +225,7 @@ "detailsEmptyState": "Processing data to generate a list of all services that sums to a total cost...", "detailsMore": "{value} more...", "detailsMoreClusters": ", {value} more...", - "detailsResourceNames": "{value, select, account {Account names} aws_category {Cost category names} cluster {Cluster names} gcp_project {GCP project names} group {Group} name {Name} node {Node names} org_unit_id {Organizational unit names} payer_tenant_id {Account names} product_service {Service names} project {Project names} region {Region names} resource_location {Region names} service {Service names} service_name {Service names} status {Status} subscription_guid {Account names} source_type {Integration} tag {Tag names} tag_key {Tag keys} other {}}", + "detailsResourceNames": "{value, select, account {Account names} aws_category {Cost category names} cluster {Cluster names} cpu {CPU} gcp_project {GCP project names} group {Group} instance {Instance names} instance_type {Instance type} memory {Memory} name {Name} node {Node names} org_unit_id {Organizational unit names} os {OS} operating_system {Operating system} payer_tenant_id {Account names} product_service {Service names} project {Project names} region {Region names} resource_location {Region names} service {Service names} service_name {Service names} status {Status} subscription_guid {Account names} source_type {Integration} tag {Tag names} tags {Tags} tag_key {Tag keys} other {}}", "detailsSummaryModalTitle": "{groupBy, select, account {{name} accounts} aws_category {{name} cost categories} cluster {{name} clusters} gcp_project {{name} GCP projects} node {{name} nodes} org_unit_id {{name} organizational units} payer_tenant_id {{name} accounts} product_service {{name} services} project {{name} projects} region {{name} regions} resource_location {{name} regions} service {{name} services} service_name {{name} services} subscription_guid {{name} accounts} tag {{name} tags} other {}}", "detailsUnusedCapacityLabel": "Unused capacity", "detailsUnusedRequestsLabel": "Unrequested capacity", @@ -287,16 +287,16 @@ "exportAll": "Export all", "exportDesc": "The active selections from the table plus the values here will be used to generate an export file. When the file is available, download it from the {value} view.", "exportError": "Something went wrong, please try fewer selections", - "exportFileName": "{groupBy, select, account {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} aws_category {{resolution, select, daily {{provider}_cost_category_daily_{startDate}_{endDate}} monthly {{provider}_cost_category_monthly_{startDate}_{endDate}} other {}}} cluster {{resolution, select, daily {{provider}_clusters_daily_{startDate}_{endDate}} monthly {{provider}_clusters_monthly_{startDate}_{endDate}} other {}}} gcp_project {{resolution, select, daily {{provider}_gcp-projects_daily_{startDate}_{endDate}} monthly {{provider}_gcp-projects_monthly_{startDate}_{endDate}} other {}}} node {{resolution, select, daily {{provider}_node_daily_{startDate}_{endDate}} monthly {{provider}_node_monthly_{startDate}_{endDate}} other {}}} org_unit_id {{resolution, select, daily {{provider}_orgs_daily_{startDate}_{endDate}} monthly {{provider}_orgs_monthly_{startDate}_{endDate}} other {}}} payer_tenant_id {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} product_service {{resolution, select, daily {{provider}_services_daily_{startDate}_{endDate}} monthly {{provider}_services_monthly_{startDate}_{endDate}} other {}}} project {{resolution, select, daily {{provider}_projects_daily_{startDate}_{endDate}} monthly {{provider}_projects_monthly_{startDate}_{endDate}} other {}}} region {{resolution, select, daily {{provider}_regions_daily_{startDate}_{endDate}} monthly {{provider}_regions_monthly_{startDate}_{endDate}} other {}}} resource_location {{resolution, select, daily {{provider}_regions_daily_{startDate}_{endDate}} monthly {{provider}_regions_monthly_{startDate}_{endDate}} other {}}} service {{resolution, select, daily {{provider}_services_daily_{startDate}_{endDate}} monthly {{provider}_services_monthly_{startDate}_{endDate}} other {}}} service_name {{resolution, select, daily {{provider}_services_daily_{startDate}_{endDate}} monthly {{provider}_services_monthly_{startDate}_{endDate}} other {}}} subscription_guid {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} tag {{resolution, select, daily {{provider}_tags_daily_{startDate}_{endDate}} monthly {{provider}_tags_monthly_{startDate}_{endDate}} other {}}} other {}}", + "exportFileName": "{groupBy, select, account {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} aws_category {{resolution, select, daily {{provider}_cost_category_daily_{startDate}_{endDate}} monthly {{provider}_cost_category_monthly_{startDate}_{endDate}} other {}}} cluster {{resolution, select, daily {{provider}_clusters_daily_{startDate}_{endDate}} monthly {{provider}_clusters_monthly_{startDate}_{endDate}} other {}}} gcp_project {{resolution, select, daily {{provider}_gcp-projects_daily_{startDate}_{endDate}} monthly {{provider}_gcp-projects_monthly_{startDate}_{endDate}} other {}}} instance {{resolution, select, daily {{provider}_instances_daily_{startDate}_{endDate}} monthly {{provider}_instances_monthly_{startDate}_{endDate}} other {}}} node {{resolution, select, daily {{provider}_node_daily_{startDate}_{endDate}} monthly {{provider}_node_monthly_{startDate}_{endDate}} other {}}} org_unit_id {{resolution, select, daily {{provider}_orgs_daily_{startDate}_{endDate}} monthly {{provider}_orgs_monthly_{startDate}_{endDate}} other {}}} payer_tenant_id {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} product_service {{resolution, select, daily {{provider}_services_daily_{startDate}_{endDate}} monthly {{provider}_services_monthly_{startDate}_{endDate}} other {}}} project {{resolution, select, daily {{provider}_projects_daily_{startDate}_{endDate}} monthly {{provider}_projects_monthly_{startDate}_{endDate}} other {}}} region {{resolution, select, daily {{provider}_regions_daily_{startDate}_{endDate}} monthly {{provider}_regions_monthly_{startDate}_{endDate}} other {}}} resource_location {{resolution, select, daily {{provider}_regions_daily_{startDate}_{endDate}} monthly {{provider}_regions_monthly_{startDate}_{endDate}} other {}}} service {{resolution, select, daily {{provider}_services_daily_{startDate}_{endDate}} monthly {{provider}_services_monthly_{startDate}_{endDate}} other {}}} service_name {{resolution, select, daily {{provider}_services_daily_{startDate}_{endDate}} monthly {{provider}_services_monthly_{startDate}_{endDate}} other {}}} subscription_guid {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} tag {{resolution, select, daily {{provider}_tags_daily_{startDate}_{endDate}} monthly {{provider}_tags_monthly_{startDate}_{endDate}} other {}}} other {}}", "exportFormatType": "{value, select, csv {CSV} json {JSON} other {}}", "exportFormatTypeTitle": "Format type", "exportGenerate": "Generate export", - "exportHeading": "{groupBy, select, account {Aggregates of the following accounts will be exported to a .csv file.} aws_category {Aggregates of the following cost categories will be exported to a .csv file.} cluster {Aggregates of the following clusters will be exported to a .csv file.} gcp_project {Aggregates of the following GCP projects will be exported to a .csv file.} node {Aggregates of the following nodes will be exported to a .csv file.} org_unit_id {Aggregates of the following organizational units will be exported to a .csv file.} payer_tenant_id {Aggregates of the following accounts will be exported to a .csv file.} product_service {Aggregates of the following services will be exported to a .csv file.} project {Aggregates of the following projects will be exported to a .csv file.} region {Aggregates of the following regions will be exported to a .csv file.} resource_location {Aggregates of the regions will be exported to a .csv file.} service {Aggregates of the following services will be exported to a .csv file.} service_name {Aggregates of the following services will be exported to a .csv file.} subscription_guid {Aggregates of the following accounts will be exported to a .csv file.} tag {Aggregates of the following tags will be exported to a .csv file.} other {}}", - "exportName": "{groupBy, select, account {{provider, select, aws {Amazon Web Services grouped by Account} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Account} azure {Microsoft Azure grouped by Account} oci {Oracle Cloud Infrastructure grouped by Account} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Account} gcp {Google Cloud Platform grouped by Account} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Account} ibm {IBM Cloud grouped by Account} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Account} ocp {OpenShift grouped by Account} ocp_cloud {All cloud filtered by OpenShift grouped by Account} other {}}} aws_category {{provider, select, aws {Amazon Web Services grouped by Cost category} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Cost category} azure {Microsoft Azure grouped by Cost category} oci {Oracle Cloud Infrastructure grouped by Cost category} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Cost category} gcp {Google Cloud Platform grouped by Cost category} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Cost category} ibm {IBM Cloud grouped by Cost category} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Cost category} ocp {OpenShift grouped by Cost category} ocp_cloud {All cloud filtered by OpenShift grouped by Cost category} other {}}} cluster {{provider, select, aws {Amazon Web Services grouped by Cluster} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Cluster} azure {Microsoft Azure grouped by Cluster} oci {Oracle Cloud Infrastructure grouped by Cluster} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Cluster} gcp {Google Cloud Platform grouped by Cluster} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Cluster} ibm {IBM Cloud grouped by Cluster} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Cluster} ocp {OpenShift grouped by Cluster} ocp_cloud {All cloud filtered by OpenShift grouped by Cluster} other {}}} gcp_project {{provider, select, aws {Amazon Web Services grouped by GCP Project} aws_ocp {Amazon Web Services filtered by OpenShift grouped by GCP Project} azure {Microsoft Azure grouped by GCP Project} oci {Oracle Cloud Infrastructure grouped by GCP Project} azure_ocp {Microsoft Azure filtered by OpenShift grouped by GCP Project} gcp {Google Cloud Platform grouped by GCP Project} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by GCP Project} ibm {IBM Cloud grouped by GCP Project} ibm_ocp {IBM Cloud filtered by OpenShift grouped by GCP Project} ocp {OpenShift grouped by GCP Project} ocp_cloud {All cloud filtered by OpenShift grouped by GCP Project} other {}}} node {{provider, select, aws {Amazon Web Services grouped by Node} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Node} azure {Microsoft Azure grouped by Node} oci {Oracle Cloud Infrastructure grouped by Node} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Node} gcp {Google Cloud Platform grouped by Node} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Node} ibm {IBM Cloud grouped by Node} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Node} ocp {OpenShift grouped by Node} ocp_cloud {All cloud filtered by OpenShift grouped by Node} other {}}} org_unit_id {{provider, select, aws {Amazon Web Services grouped by Organizational unit} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Organizational unit} azure {Microsoft Azure grouped by Organizational unit} oci {Oracle Cloud Infrastructure grouped by Organizational unit} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Organizational unit} gcp {Google Cloud Platform grouped by Organizational unit} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Organizational unit} ibm {IBM Cloud grouped by Organizational unit} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Organizational unit} ocp {OpenShift grouped by Organizational unit} ocp_cloud {All cloud filtered by OpenShift grouped by Organizational unit} other {}}} payer_tenant_id {{provider, select, oci {Oracle Cloud Infrastructure grouped by Account} other {}}}product_service {{provider, select, oci {Oracle Cloud Infrastructure grouped by Service} other {}}}project {{provider, select, aws {Amazon Web Services grouped by Project} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Project} azure {Microsoft Azure grouped by Project} oci {Oracle Cloud Infrastructure grouped by Project} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Project} gcp {Google Cloud Platform grouped by Project} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Project} ibm {IBM Cloud grouped by Project} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Project} ocp {OpenShift grouped by Project} ocp_cloud {All cloud filtered by OpenShift grouped by Project} other {}}} region {{provider, select, aws {Amazon Web Services grouped by Region} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Region} azure {Microsoft Azure grouped by Region} oci {Oracle Cloud Infrastructure grouped by Region} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Region} gcp {Google Cloud Platform grouped by Region} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Region} ibm {IBM Cloud grouped by Region} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Region} ocp {OpenShift grouped by Region} ocp_cloud {All cloud filtered by OpenShift grouped by Region} other {}}} resource_location {{provider, select, aws {Amazon Web Services grouped by Region} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Region} azure {Microsoft Azure grouped by Region} oci {Oracle Cloud Infrastructure grouped by Region} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Region} gcp {Google Cloud Platform grouped by Region} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Region} ibm {IBM Cloud grouped by Region} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Region} ocp {OpenShift grouped by Region} ocp_cloud {All cloud filtered by OpenShift grouped by Region} other {}}} service {{provider, select, aws {Amazon Web Services grouped by Service} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Service} azure {Microsoft Azure grouped by Service} oci {Oracle Cloud Infrastructure grouped by Service} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Service} gcp {Google Cloud Platform grouped by Service} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Service} ibm {IBM Cloud grouped by Service} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Service} ocp {OpenShift grouped by Service} ocp_cloud {All cloud filtered by OpenShift grouped by Service} other {}}} service_name {{provider, select, aws {Amazon Web Services grouped by Service} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Service} azure {Microsoft Azure grouped by Service} oci {Oracle Cloud Infrastructure grouped by Service} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Service} gcp {Google Cloud Platform grouped by Service} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Service} ibm {IBM Cloud grouped by Service} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Service} ocp {OpenShift grouped by Service} ocp_cloud {All cloud filtered by OpenShift grouped by Service} other {}}} subscription_guid {{provider, select, aws {Amazon Web Services grouped by Account} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Account} azure {Microsoft Azure grouped by Account} oci {Oracle Cloud Infrastructure grouped by Account} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Account} gcp {Google Cloud Platform grouped by Account} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Account} ibm {IBM Cloud grouped by Account} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Account} ocp {OpenShift grouped by Account} ocp_cloud {All cloud filtered by OpenShift grouped by Account} other {}}} tag {{provider, select, aws {Amazon Web Services grouped by Tag} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Tag} azure {Microsoft Azure grouped by Tag} oci {Oracle Cloud Infrastructure grouped by Tag} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Tag} gcp {Google Cloud Platform grouped by Tag} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Tag} ibm {IBM Cloud grouped by Tag} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Tag} ocp {OpenShift grouped by Tag} ocp_cloud {All cloud filtered by OpenShift grouped by Tag} other {}}} other {}}", + "exportHeading": "{groupBy, select, account {Aggregates of the following accounts will be exported to a .csv file.} aws_category {Aggregates of the following cost categories will be exported to a .csv file.} cluster {Aggregates of the following clusters will be exported to a .csv file.} gcp_project {Aggregates of the following GCP projects will be exported to a .csv file.} instance {Aggregates of the following instances will be exported to a .csv file.} node {Aggregates of the following nodes will be exported to a .csv file.} org_unit_id {Aggregates of the following organizational units will be exported to a .csv file.} payer_tenant_id {Aggregates of the following accounts will be exported to a .csv file.} product_service {Aggregates of the following services will be exported to a .csv file.} project {Aggregates of the following projects will be exported to a .csv file.} region {Aggregates of the following regions will be exported to a .csv file.} resource_location {Aggregates of the regions will be exported to a .csv file.} service {Aggregates of the following services will be exported to a .csv file.} service_name {Aggregates of the following services will be exported to a .csv file.} subscription_guid {Aggregates of the following accounts will be exported to a .csv file.} tag {Aggregates of the following tags will be exported to a .csv file.} other {}}", + "exportName": "{groupBy, select, account {{provider, select, aws {Amazon Web Services grouped by Account} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Account} azure {Microsoft Azure grouped by Account} oci {Oracle Cloud Infrastructure grouped by Account} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Account} gcp {Google Cloud Platform grouped by Account} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Account} ibm {IBM Cloud grouped by Account} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Account} ocp {OpenShift grouped by Account} ocp_cloud {All cloud filtered by OpenShift grouped by Account} other {}}} aws_category {{provider, select, aws {Amazon Web Services grouped by Cost category} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Cost category} azure {Microsoft Azure grouped by Cost category} oci {Oracle Cloud Infrastructure grouped by Cost category} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Cost category} gcp {Google Cloud Platform grouped by Cost category} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Cost category} ibm {IBM Cloud grouped by Cost category} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Cost category} ocp {OpenShift grouped by Cost category} ocp_cloud {All cloud filtered by OpenShift grouped by Cost category} other {}}} cluster {{provider, select, aws {Amazon Web Services grouped by Cluster} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Cluster} azure {Microsoft Azure grouped by Cluster} oci {Oracle Cloud Infrastructure grouped by Cluster} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Cluster} gcp {Google Cloud Platform grouped by Cluster} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Cluster} ibm {IBM Cloud grouped by Cluster} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Cluster} ocp {OpenShift grouped by Cluster} ocp_cloud {All cloud filtered by OpenShift grouped by Cluster} other {}}} gcp_project {{provider, select, aws {Amazon Web Services grouped by GCP Project} aws_ocp {Amazon Web Services filtered by OpenShift grouped by GCP Project} azure {Microsoft Azure grouped by GCP Project} oci {Oracle Cloud Infrastructure grouped by GCP Project} azure_ocp {Microsoft Azure filtered by OpenShift grouped by GCP Project} gcp {Google Cloud Platform grouped by GCP Project} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by GCP Project} ibm {IBM Cloud grouped by GCP Project} ibm_ocp {IBM Cloud filtered by OpenShift grouped by GCP Project} ocp {OpenShift grouped by GCP Project} ocp_cloud {All cloud filtered by OpenShift grouped by GCP Project} other {}}} instance {{provider, select, aws {Amazon Web Services grouped by instance} aws_ocp {Amazon Web Services filtered by OpenShift grouped by instance} azure {Microsoft Azure grouped by instance} oci {Oracle Cloud Infrastructure grouped by instance} azure_ocp {Microsoft Azure filtered by OpenShift grouped by instance} gcp {Google Cloud Platform grouped by instance} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by instance} ibm {IBM Cloud grouped by instance} ibm_ocp {IBM Cloud filtered by OpenShift grouped by instance} ocp {OpenShift grouped by instance} ocp_cloud {All cloud filtered by OpenShift grouped by instance} other {}}} node {{provider, select, aws {Amazon Web Services grouped by Node} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Node} azure {Microsoft Azure grouped by Node} oci {Oracle Cloud Infrastructure grouped by Node} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Node} gcp {Google Cloud Platform grouped by Node} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Node} ibm {IBM Cloud grouped by Node} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Node} ocp {OpenShift grouped by Node} ocp_cloud {All cloud filtered by OpenShift grouped by Node} other {}}} org_unit_id {{provider, select, aws {Amazon Web Services grouped by Organizational unit} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Organizational unit} azure {Microsoft Azure grouped by Organizational unit} oci {Oracle Cloud Infrastructure grouped by Organizational unit} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Organizational unit} gcp {Google Cloud Platform grouped by Organizational unit} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Organizational unit} ibm {IBM Cloud grouped by Organizational unit} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Organizational unit} ocp {OpenShift grouped by Organizational unit} ocp_cloud {All cloud filtered by OpenShift grouped by Organizational unit} other {}}} payer_tenant_id {{provider, select, oci {Oracle Cloud Infrastructure grouped by Account} other {}}}product_service {{provider, select, oci {Oracle Cloud Infrastructure grouped by Service} other {}}}project {{provider, select, aws {Amazon Web Services grouped by Project} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Project} azure {Microsoft Azure grouped by Project} oci {Oracle Cloud Infrastructure grouped by Project} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Project} gcp {Google Cloud Platform grouped by Project} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Project} ibm {IBM Cloud grouped by Project} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Project} ocp {OpenShift grouped by Project} ocp_cloud {All cloud filtered by OpenShift grouped by Project} other {}}} region {{provider, select, aws {Amazon Web Services grouped by Region} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Region} azure {Microsoft Azure grouped by Region} oci {Oracle Cloud Infrastructure grouped by Region} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Region} gcp {Google Cloud Platform grouped by Region} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Region} ibm {IBM Cloud grouped by Region} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Region} ocp {OpenShift grouped by Region} ocp_cloud {All cloud filtered by OpenShift grouped by Region} other {}}} resource_location {{provider, select, aws {Amazon Web Services grouped by Region} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Region} azure {Microsoft Azure grouped by Region} oci {Oracle Cloud Infrastructure grouped by Region} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Region} gcp {Google Cloud Platform grouped by Region} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Region} ibm {IBM Cloud grouped by Region} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Region} ocp {OpenShift grouped by Region} ocp_cloud {All cloud filtered by OpenShift grouped by Region} other {}}} service {{provider, select, aws {Amazon Web Services grouped by Service} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Service} azure {Microsoft Azure grouped by Service} oci {Oracle Cloud Infrastructure grouped by Service} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Service} gcp {Google Cloud Platform grouped by Service} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Service} ibm {IBM Cloud grouped by Service} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Service} ocp {OpenShift grouped by Service} ocp_cloud {All cloud filtered by OpenShift grouped by Service} other {}}} service_name {{provider, select, aws {Amazon Web Services grouped by Service} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Service} azure {Microsoft Azure grouped by Service} oci {Oracle Cloud Infrastructure grouped by Service} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Service} gcp {Google Cloud Platform grouped by Service} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Service} ibm {IBM Cloud grouped by Service} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Service} ocp {OpenShift grouped by Service} ocp_cloud {All cloud filtered by OpenShift grouped by Service} other {}}} subscription_guid {{provider, select, aws {Amazon Web Services grouped by Account} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Account} azure {Microsoft Azure grouped by Account} oci {Oracle Cloud Infrastructure grouped by Account} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Account} gcp {Google Cloud Platform grouped by Account} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Account} ibm {IBM Cloud grouped by Account} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Account} ocp {OpenShift grouped by Account} ocp_cloud {All cloud filtered by OpenShift grouped by Account} other {}}} tag {{provider, select, aws {Amazon Web Services grouped by Tag} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Tag} azure {Microsoft Azure grouped by Tag} oci {Oracle Cloud Infrastructure grouped by Tag} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Tag} gcp {Google Cloud Platform grouped by Tag} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Tag} ibm {IBM Cloud grouped by Tag} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Tag} ocp {OpenShift grouped by Tag} ocp_cloud {All cloud filtered by OpenShift grouped by Tag} other {}}} other {}}", "exportNameRequired": "Please enter a name for the export", "exportNameTooLong": "Should not exceed 50 characters", "exportResolution": "{value, select, daily {Daily} monthly {Monthly} other {}}", - "exportSelected": "{groupBy, select, account {Selected accounts ({count})} aws_category {Selected cost categories ({count})} cluster {Selected clusters ({count})} gcp_project {Selected GCP projects ({count})} node {Selected nodes ({count})} org_unit_id {Selected organizational units ({count})} payer_tenant_id {Selected accounts ({count})} product_service {Selected services ({count})} project {Selected projects ({count})} region {Selected regions ({count})} resource_location {Selected regions ({count})} service {Selected services ({count})} service_name {Selected services ({count})} subscription_guid {Selected accounts ({count})} tag {Selected tags ({count})} other {}}", + "exportSelected": "{groupBy, select, account {Selected accounts ({count})} aws_category {Selected cost categories ({count})} cluster {Selected clusters ({count})} gcp_project {Selected GCP projects ({count})} instance {Selected instances ({count})} node {Selected nodes ({count})} org_unit_id {Selected organizational units ({count})} payer_tenant_id {Selected accounts ({count})} product_service {Selected services ({count})} project {Selected projects ({count})} region {Selected regions ({count})} resource_location {Selected regions ({count})} service {Selected services ({count})} service_name {Selected services ({count})} subscription_guid {Selected accounts ({count})} tag {Selected tags ({count})} other {}}", "exportTimeScope": "{value, select, current {Current ({date})} previous {Previous ({date})} other {}}", "exportTimeScopeTitle": "Month", "exportTitle": "Export", @@ -321,7 +321,7 @@ "filterByTagValueAriaLabel": "Tag values", "filterByTagValueButtonAriaLabel": "Filter button for tag value", "filterByValuePlaceholder": "Filter by value", - "filterByValues": "{value, select, account {Account} aws_category {Cost category} cluster {Cluster} container {Container} default {Default} gcp_project {GCP project} group {Group} name {Name} node {Node} org_unit_id {Organizational unit} payer_tenant_id {Account} persistent_volume_claim {Persistent volume claim} product_service {Service} project {Project} region {Region} resource_location {Region} service {Service} service_name {Service} source_type {Integration} status {Status} storage_class {StorageClass} subscription_guid {Account} tag {Tag} tag_key {Tag key} tag_key_child {Child tag Key} tag_key_parent {Parent tag Key} workload {Workload name} workload_type {Workload type} other {}}", + "filterByValues": "{value, select, account {Account} aws_category {Cost category} cluster {Cluster} container {Container} default {Default} gcp_project {GCP project} group {Group} instance {Instance} name {Name} node {Node} org_unit_id {Organizational unit} operating_system {Operating system} payer_tenant_id {Account} persistent_volume_claim {Persistent volume claim} product_service {Service} project {Project} region {Region} resource_location {Region} service {Service} service_name {Service} source_type {Integration} status {Status} storage_class {StorageClass} subscription_guid {Account} tag {Tag} tag_key {Tag key} tag_key_child {Child tag Key} tag_key_parent {Parent tag Key} workload {Workload name} workload_type {Workload type} other {}}", "filterByValuesAriaLabel": "Values", "forDate": "{value} for {dateRange}", "gcp": "Google Cloud Platform", @@ -352,6 +352,7 @@ "inactiveSourcesTitle": "A problem was detected with {value}", "inactiveSourcesTitleMultiplier": "A problem was detected with the following integrations", "infrastructure": "Infrastructure", + "instances": "Instances", "lastProcessed": "Last processed", "learnMore": "Learn more", "loadingStateDesc": "Searching for your integrations. Do not refresh the browser", @@ -390,11 +391,11 @@ "noDataStateRefresh": "Refresh this page", "noDataStateTitle": "Still processing the data", "noExportsStateTitle": "There are no export files available", + "noInstancesDesc": "Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances.", + "noInstancesTitle": "No instances available", "noMappedTags": "No mapped tags", "noMappedTagsDesc": "Map multiple tags across data sources to be used as a single tag key for report grouping and filtering. {warning} Changes will be reflected within 24 hours. {learnMore}", "noMappedTagsWarning": "Tags must be enabled to be mapped.", - "noOptimizationsDesc": "Resource Optimization is now available in preview for select customers. If your organization wants to participate, tell us through the Feedback button, which is purple and located on the right. Otherwise, there is not enough data available to generate an optimization.", - "noOptimizationsTitle": "No optimizations available", "noProvidersStateAwsDesc": "Add an Amazon Web Services account to see a total cost breakdown of your spend by accounts, organizational units, services, regions, or tags.", "noProvidersStateAwsTitle": "Track your Amazon Web Services spending!", "noProvidersStateAzureDesc": "Add a Microsoft Azure account to see a total cost breakdown of your spend by accounts, services, regions, or tags.", diff --git a/src/api/reports/report.ts b/src/api/reports/report.ts index a4e3db86d..33681a7f7 100644 --- a/src/api/reports/report.ts +++ b/src/api/reports/report.ts @@ -38,6 +38,27 @@ export interface ReportAwsItem extends ReportItem { service?: string; } +export interface ReportAwsInstancesItem { + account?: string; + account_alias?: string; + cost?: ReportValue; + instance_name?: string; + instance_type?: string; + memory?: ReportValue; + operating_system?: string; + region?: string; + resource_id?: string; + tags: [ + { + key?: string; + values?: string[]; + enabled?: boolean; + }, + ]; + usage?: ReportValue; + vcpu?: ReportValue; +} + export interface ReportGcpItem extends ReportItem { account?: string; project?: string; @@ -95,6 +116,7 @@ export interface ReportData extends ReportOrgData { date?: string; values?: | ReportAwsItem[] + | ReportAwsInstancesItem[] | ReportAzureItem[] | ReportGcpItem[] | ReportOcpItem[] diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 0a16b46c6..727a94f40 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -1312,11 +1312,17 @@ export default defineMessages({ 'account {Account names} ' + 'aws_category {Cost category names} ' + 'cluster {Cluster names} ' + + 'cpu {CPU} ' + 'gcp_project {GCP project names} ' + 'group {Group} ' + + 'instance {Instance names} ' + + 'instance_type {Instance type} ' + + 'memory {Memory} ' + 'name {Name} ' + 'node {Node names} ' + 'org_unit_id {Organizational unit names} ' + + 'os {OS} ' + + 'operating_system {Operating system} ' + 'payer_tenant_id {Account names} ' + 'product_service {Service names} ' + 'project {Project names} ' + @@ -1328,6 +1334,7 @@ export default defineMessages({ 'subscription_guid {Account names} ' + 'source_type {Integration} ' + 'tag {Tag names} ' + + 'tags {Tags} ' + 'tag_key {Tag keys} ' + 'other {}}', description: 'Details table resource names', @@ -1734,6 +1741,7 @@ export default defineMessages({ 'aws_category {{resolution, select, daily {{provider}_cost_category_daily_{startDate}_{endDate}} monthly {{provider}_cost_category_monthly_{startDate}_{endDate}} other {}}} ' + 'cluster {{resolution, select, daily {{provider}_clusters_daily_{startDate}_{endDate}} monthly {{provider}_clusters_monthly_{startDate}_{endDate}} other {}}} ' + 'gcp_project {{resolution, select, daily {{provider}_gcp-projects_daily_{startDate}_{endDate}} monthly {{provider}_gcp-projects_monthly_{startDate}_{endDate}} other {}}} ' + + 'instance {{resolution, select, daily {{provider}_instances_daily_{startDate}_{endDate}} monthly {{provider}_instances_monthly_{startDate}_{endDate}} other {}}} ' + 'node {{resolution, select, daily {{provider}_node_daily_{startDate}_{endDate}} monthly {{provider}_node_monthly_{startDate}_{endDate}} other {}}} ' + 'org_unit_id {{resolution, select, daily {{provider}_orgs_daily_{startDate}_{endDate}} monthly {{provider}_orgs_monthly_{startDate}_{endDate}} other {}}} ' + 'payer_tenant_id {{resolution, select, daily {{provider}_accounts_daily_{startDate}_{endDate}} monthly {{provider}_accounts_monthly_{startDate}_{endDate}} other {}}} ' + @@ -1771,6 +1779,7 @@ export default defineMessages({ 'aws_category {Aggregates of the following cost categories will be exported to a .csv file.} ' + 'cluster {Aggregates of the following clusters will be exported to a .csv file.} ' + 'gcp_project {Aggregates of the following GCP projects will be exported to a .csv file.} ' + + 'instance {Aggregates of the following instances will be exported to a .csv file.} ' + 'node {Aggregates of the following nodes will be exported to a .csv file.} ' + 'org_unit_id {Aggregates of the following organizational units will be exported to a .csv file.} ' + 'payer_tenant_id {Aggregates of the following accounts will be exported to a .csv file.} ' + @@ -1793,6 +1802,7 @@ export default defineMessages({ 'aws_category {{provider, select, aws {Amazon Web Services grouped by Cost category} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Cost category} azure {Microsoft Azure grouped by Cost category} oci {Oracle Cloud Infrastructure grouped by Cost category} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Cost category} gcp {Google Cloud Platform grouped by Cost category} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Cost category} ibm {IBM Cloud grouped by Cost category} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Cost category} ocp {OpenShift grouped by Cost category} ocp_cloud {All cloud filtered by OpenShift grouped by Cost category} other {}}} ' + 'cluster {{provider, select, aws {Amazon Web Services grouped by Cluster} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Cluster} azure {Microsoft Azure grouped by Cluster} oci {Oracle Cloud Infrastructure grouped by Cluster} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Cluster} gcp {Google Cloud Platform grouped by Cluster} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Cluster} ibm {IBM Cloud grouped by Cluster} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Cluster} ocp {OpenShift grouped by Cluster} ocp_cloud {All cloud filtered by OpenShift grouped by Cluster} other {}}} ' + 'gcp_project {{provider, select, aws {Amazon Web Services grouped by GCP Project} aws_ocp {Amazon Web Services filtered by OpenShift grouped by GCP Project} azure {Microsoft Azure grouped by GCP Project} oci {Oracle Cloud Infrastructure grouped by GCP Project} azure_ocp {Microsoft Azure filtered by OpenShift grouped by GCP Project} gcp {Google Cloud Platform grouped by GCP Project} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by GCP Project} ibm {IBM Cloud grouped by GCP Project} ibm_ocp {IBM Cloud filtered by OpenShift grouped by GCP Project} ocp {OpenShift grouped by GCP Project} ocp_cloud {All cloud filtered by OpenShift grouped by GCP Project} other {}}} ' + + 'instance {{provider, select, aws {Amazon Web Services grouped by instance} aws_ocp {Amazon Web Services filtered by OpenShift grouped by instance} azure {Microsoft Azure grouped by instance} oci {Oracle Cloud Infrastructure grouped by instance} azure_ocp {Microsoft Azure filtered by OpenShift grouped by instance} gcp {Google Cloud Platform grouped by instance} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by instance} ibm {IBM Cloud grouped by instance} ibm_ocp {IBM Cloud filtered by OpenShift grouped by instance} ocp {OpenShift grouped by instance} ocp_cloud {All cloud filtered by OpenShift grouped by instance} other {}}} ' + 'node {{provider, select, aws {Amazon Web Services grouped by Node} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Node} azure {Microsoft Azure grouped by Node} oci {Oracle Cloud Infrastructure grouped by Node} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Node} gcp {Google Cloud Platform grouped by Node} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Node} ibm {IBM Cloud grouped by Node} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Node} ocp {OpenShift grouped by Node} ocp_cloud {All cloud filtered by OpenShift grouped by Node} other {}}} ' + 'org_unit_id {{provider, select, aws {Amazon Web Services grouped by Organizational unit} aws_ocp {Amazon Web Services filtered by OpenShift grouped by Organizational unit} azure {Microsoft Azure grouped by Organizational unit} oci {Oracle Cloud Infrastructure grouped by Organizational unit} azure_ocp {Microsoft Azure filtered by OpenShift grouped by Organizational unit} gcp {Google Cloud Platform grouped by Organizational unit} gcp_ocp {Google Cloud Platform filtered by OpenShift grouped by Organizational unit} ibm {IBM Cloud grouped by Organizational unit} ibm_ocp {IBM Cloud filtered by OpenShift grouped by Organizational unit} ocp {OpenShift grouped by Organizational unit} ocp_cloud {All cloud filtered by OpenShift grouped by Organizational unit} other {}}} ' + 'payer_tenant_id {{provider, select, oci {Oracle Cloud Infrastructure grouped by Account} other {}}}' + @@ -1830,6 +1840,7 @@ export default defineMessages({ 'aws_category {Selected cost categories ({count})} ' + 'cluster {Selected clusters ({count})} ' + 'gcp_project {Selected GCP projects ({count})} ' + + 'instance {Selected instances ({count})} ' + 'node {Selected nodes ({count})} ' + 'org_unit_id {Selected organizational units ({count})} ' + 'payer_tenant_id {Selected accounts ({count})} ' + @@ -2049,9 +2060,11 @@ export default defineMessages({ 'default {Default} ' + 'gcp_project {GCP project} ' + 'group {Group} ' + + 'instance {Instance} ' + 'name {Name} ' + 'node {Node} ' + 'org_unit_id {Organizational unit} ' + + 'operating_system {Operating system} ' + 'payer_tenant_id {Account} ' + 'persistent_volume_claim {Persistent volume claim} ' + 'product_service {Service} ' + @@ -2319,11 +2332,6 @@ export default defineMessages({ description: 'Infrastructure', id: 'infrastructure', }, - instanceNames: { - defaultMessage: 'Instance names', - description: 'Instance names', - id: 'instanceNames', - }, instances: { defaultMessage: 'Instances', description: 'Instances', @@ -2551,6 +2559,16 @@ export default defineMessages({ description: 'There are no export files available', id: 'noExportsStateTitle', }, + noInstancesDesc: { + defaultMessage: 'Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances.', + description: 'Add an Amazon EC2 instance to see a total cost breakdown of your spend by instances.', + id: 'noInstancesDesc', + }, + noInstancesTitle: { + defaultMessage: 'No instances available', + description: 'No instances available', + id: 'noInstancesTitle', + }, noMappedTags: { defaultMessage: 'No mapped tags', description: 'No mapped tags', @@ -2568,18 +2586,6 @@ export default defineMessages({ description: 'Tags must be enabled to be mapped.', id: 'noMappedTagsWarning', }, - noOptimizationsDesc: { - defaultMessage: - 'Resource Optimization is now available in preview for select customers. If your organization wants to participate, tell us through the Feedback button, which is purple and located on the right. Otherwise, there is not enough data available to generate an optimization.', - description: - 'Resource Optimization is now available in preview for select customers. If your organization wants to participate, tell us through the Feedback button, which is purple and located on the right. Otherwise, there is not enough data available to generate an optimization.', - id: 'noOptimizationsDesc', - }, - noOptimizationsTitle: { - defaultMessage: 'No optimizations available', - description: 'No optimizations available', - id: 'noOptimizationsTitle', - }, noProvidersStateAwsDesc: { defaultMessage: 'Add an Amazon Web Services account to see a total cost breakdown of your spend by accounts, organizational units, services, regions, or tags.', diff --git a/src/routes/components/charts/historicalTrendChart/__snapshots__/historicalTrendChart.test.tsx.snap b/src/routes/components/charts/historicalTrendChart/__snapshots__/historicalTrendChart.test.tsx.snap index 23ec45050..f33121793 100644 --- a/src/routes/components/charts/historicalTrendChart/__snapshots__/historicalTrendChart.test.tsx.snap +++ b/src/routes/components/charts/historicalTrendChart/__snapshots__/historicalTrendChart.test.tsx.snap @@ -424,13 +424,13 @@ exports[`reports are formatted to datums 1`] = ` - 0.00000000005 + 1.0 @@ -588,7 +588,7 @@ exports[`reports are formatted to datums 1`] = ` dx="0" id="exampleTrendChart-ChartAxis-3-ChartLabel-1" x="-7" - y="16.5" + y="20.75" > - 0.00000000010 + 1.5 @@ -609,7 +609,7 @@ exports[`reports are formatted to datums 1`] = ` dx="0" id="exampleTrendChart-ChartAxis-3-ChartLabel-2" x="-7" - y="12.25" + y="16.5" > - 0.00000000015 + 2.0 @@ -630,6 +630,27 @@ exports[`reports are formatted to datums 1`] = ` dx="0" id="exampleTrendChart-ChartAxis-3-ChartLabel-3" x="-7" + y="12.25" + > + + 2.5 + + + + + - 0.00000000020 + 3.0 diff --git a/src/routes/components/charts/trendChart/__snapshots__/trendChart.test.tsx.snap b/src/routes/components/charts/trendChart/__snapshots__/trendChart.test.tsx.snap index b77aead75..f5f43266a 100644 --- a/src/routes/components/charts/trendChart/__snapshots__/trendChart.test.tsx.snap +++ b/src/routes/components/charts/trendChart/__snapshots__/trendChart.test.tsx.snap @@ -53,13 +53,13 @@ exports[`reports are formatted to datums 1`] = ` - 0.00000000005 + 0.5 @@ -226,7 +226,7 @@ exports[`reports are formatted to datums 1`] = ` text-anchor="end" x="-7" > - 0.00000000010 + 1.0 @@ -247,7 +247,7 @@ exports[`reports are formatted to datums 1`] = ` text-anchor="end" x="-7" > - 0.00000000015 + 1.5 @@ -268,7 +268,7 @@ exports[`reports are formatted to datums 1`] = ` text-anchor="end" x="-7" > - 0.00000000020 + 2.0 diff --git a/src/routes/components/export/exportModal.tsx b/src/routes/components/export/exportModal.tsx index b58123923..4571f4199 100644 --- a/src/routes/components/export/exportModal.tsx +++ b/src/routes/components/export/exportModal.tsx @@ -167,7 +167,7 @@ export class ExportModalBase extends React.Component - - - - - diff --git a/src/routes/components/icons/optimizationIcon/index.ts b/src/routes/components/icons/optimizationIcon/index.ts deleted file mode 100644 index e7b5d2e6f..000000000 --- a/src/routes/components/icons/optimizationIcon/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as OptimizationIcon } from './optimizationIcon'; diff --git a/src/routes/components/icons/optimizationIcon/optimizationIcon.scss b/src/routes/components/icons/optimizationIcon/optimizationIcon.scss deleted file mode 100644 index 81d67d428..000000000 --- a/src/routes/components/icons/optimizationIcon/optimizationIcon.scss +++ /dev/null @@ -1,5 +0,0 @@ -@import url("~@patternfly/patternfly/base/patternfly-variables.css"); - -.optimization-icon { - height: 54px; -} diff --git a/src/routes/components/icons/optimizationIcon/optimizationIcon.tsx b/src/routes/components/icons/optimizationIcon/optimizationIcon.tsx deleted file mode 100644 index 9ebe127f2..000000000 --- a/src/routes/components/icons/optimizationIcon/optimizationIcon.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import './optimizationIcon.scss'; - -import messages from 'locales/messages'; -import React from 'react'; -import type { WrappedComponentProps } from 'react-intl'; -import { injectIntl } from 'react-intl'; - -interface OptimizationIconProps extends WrappedComponentProps { - className?: string; -} - -const icon = require('./Red_Hat-IT_Optimization-Gray.svg'); - -const OptimizationIcon: React.FC = ({ className, intl }) => { - return ( - - ); -}; - -export default injectIntl(OptimizationIcon); diff --git a/src/routes/components/page/noInstances/index.ts b/src/routes/components/page/noInstances/index.ts new file mode 100644 index 000000000..8c0559e75 --- /dev/null +++ b/src/routes/components/page/noInstances/index.ts @@ -0,0 +1 @@ +export { default as NoInstances } from './noInstances'; diff --git a/src/routes/components/page/noOptimizations/noOptimizations.tsx b/src/routes/components/page/noInstances/noInstances.tsx similarity index 60% rename from src/routes/components/page/noOptimizations/noOptimizations.tsx rename to src/routes/components/page/noInstances/noInstances.tsx index 5fba9e195..627d33420 100644 --- a/src/routes/components/page/noOptimizations/noOptimizations.tsx +++ b/src/routes/components/page/noInstances/noInstances.tsx @@ -2,15 +2,15 @@ import { PageSection } from '@patternfly/react-core'; import { PageHeader, PageHeaderTitle } from '@redhat-cloud-services/frontend-components/PageHeader'; import React from 'react'; -import { NoOptimizationsState } from './noOptimizationsState'; +import { NoInstancesState } from './noInstancesState'; -interface NoProvidersOwnProps { +interface NoInstancesOwnProps { title?: string; } -type NoProvidersProps = NoProvidersOwnProps; +type NoInstancesProps = NoInstancesOwnProps; -const NoOptimizations = ({ title }: NoProvidersProps) => { +const NoInstances = ({ title }: NoInstancesProps) => { return ( <> {title && ( @@ -19,10 +19,10 @@ const NoOptimizations = ({ title }: NoProvidersProps) => { )} - + ); }; -export default NoOptimizations; +export default NoInstances; diff --git a/src/routes/components/page/noInstances/noInstancesState.tsx b/src/routes/components/page/noInstances/noInstancesState.tsx new file mode 100644 index 000000000..6847938ee --- /dev/null +++ b/src/routes/components/page/noInstances/noInstancesState.tsx @@ -0,0 +1,39 @@ +import { + EmptyState, + EmptyStateBody, + EmptyStateHeader, + EmptyStateIcon, + EmptyStateVariant, +} from '@patternfly/react-core'; +import { MinusIcon } from '@patternfly/react-icons/dist/esm/icons/minus-icon'; +import messages from 'locales/messages'; +import React from 'react'; +import type { WrappedComponentProps } from 'react-intl'; +import { injectIntl } from 'react-intl'; + +interface NoInstancesStateOwnProps { + // TBD... +} + +type NoInstancesStateProps = NoInstancesStateOwnProps & WrappedComponentProps; + +class NoInstancesStateBase extends React.Component { + public render() { + const { intl } = this.props; + + return ( + + } + headingLevel="h1" + /> + {intl.formatMessage(messages.noInstancesDesc)} + + ); + } +} + +const NoInstancesState = injectIntl(NoInstancesStateBase); + +export { NoInstancesState }; diff --git a/src/routes/components/page/noOptimizations/index.ts b/src/routes/components/page/noOptimizations/index.ts deleted file mode 100644 index a9e1caa71..000000000 --- a/src/routes/components/page/noOptimizations/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as NoOptimizations } from './noOptimizations'; diff --git a/src/routes/components/page/noOptimizations/noOptimizationsState.tsx b/src/routes/components/page/noOptimizations/noOptimizationsState.tsx deleted file mode 100644 index 4b78a7148..000000000 --- a/src/routes/components/page/noOptimizations/noOptimizationsState.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { - EmptyState, - EmptyStateBody, - EmptyStateHeader, - EmptyStateIcon, - EmptyStateVariant, -} from '@patternfly/react-core'; -import messages from 'locales/messages'; -import React from 'react'; -import type { WrappedComponentProps } from 'react-intl'; -import { injectIntl } from 'react-intl'; -import { OptimizationIcon } from 'routes/components/icons/optimizationIcon'; - -interface NoOptimizationsStateOwnProps { - // TBD... -} - -type NoOptimizationsStateProps = NoOptimizationsStateOwnProps & WrappedComponentProps; - -class NoOptimizationsStateBase extends React.Component { - public render() { - const { intl } = this.props; - - return ( - - } - headingLevel="h1" - /> - {intl.formatMessage(messages.noOptimizationsDesc)} - - ); - } -} - -const NoOptimizationsState = injectIntl(NoOptimizationsStateBase); - -export { NoOptimizationsState }; diff --git a/src/routes/details/awsBreakdown/awsBreakdown.tsx b/src/routes/details/awsBreakdown/awsBreakdown.tsx index 793994e89..d8917bc11 100644 --- a/src/routes/details/awsBreakdown/awsBreakdown.tsx +++ b/src/routes/details/awsBreakdown/awsBreakdown.tsx @@ -16,16 +16,25 @@ import { getGroupById, getGroupByOrgValue, getGroupByValue } from 'routes/utils/ import { filterProviders } from 'routes/utils/providers'; import { getQueryState } from 'routes/utils/queryState'; import { createMapStateToProps } from 'store/common'; +import { FeatureToggleSelectors } from 'store/featureToggle'; import { providersQuery, providersSelectors } from 'store/providers'; import { reportActions, reportSelectors } from 'store/reports'; import { formatPath } from 'utils/paths'; -import { breakdownDescKey, breakdownTitleKey, logicalAndPrefix, logicalOrPrefix, orgUnitIdKey } from 'utils/props'; +import { + breakdownDescKey, + breakdownTitleKey, + logicalAndPrefix, + logicalOrPrefix, + orgUnitIdKey, + serviceKey, +} from 'utils/props'; import type { RouterComponentProps } from 'utils/router'; import { withRouter } from 'utils/router'; import { getCostType, getCurrency } from 'utils/sessionStorage'; import { CostOverview } from './costOverview'; import { HistoricalData } from './historicalData'; +import { Instances } from './instances/'; interface AwsBreakdownDispatchProps { fetchReport?: typeof reportActions.fetchReport; @@ -45,6 +54,7 @@ const mapStateToProps = createMapStateToProps, + instancesComponent: groupBy === serviceKey ? : undefined, + isAwsEc2InstancesToggleEnabled: FeatureToggleSelectors.selectIsAwsEc2InstancesToggleEnabled(state), providers: filterProviders(providers, ProviderType.aws), providersError, providersFetchStatus, diff --git a/src/routes/details/awsBreakdown/instances/data.ts b/src/routes/details/awsBreakdown/instances/data.ts new file mode 100644 index 000000000..2687d0cf2 --- /dev/null +++ b/src/routes/details/awsBreakdown/instances/data.ts @@ -0,0 +1,101 @@ +/** + * Design doc https://docs.google.com/document/d/1b9JhMmFRvp0JL_wFkiOPzyyx72kG2_BZGjoRcyz8rq4/edit + */ + +export const data = { + meta: { + count: 2, + } as any, + links: { + // usual links info + } as any, + data: [ + { + date: '2024-04', + resource_ids: [ + { + account: 'example_account', + account_alias: 'Example Account', + // cost: 50.0, + // currency: 'USD', + cost: { + value: 50.0, + units: 'USD', + }, + instance_name: 'example-instance-1', + instance_type: 't2.micro', + // memory: 1, + memory: { + value: 8, + units: 'gib_hours', + }, + operating_system: 'Linux', + region: 'us-west-2', + resource_id: 'i-1234567890abcdef0', + // tags: { + // Environment: 'Production', + // Project: 'XYZ Project', + // }, + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + enabled: true, + }, + ], + // unit: 'Hrs', + // usage_amount: 100, + usage: { + value: 100, + units: 'Hrs', + }, + vcpu: { + value: 1, + units: 'core_hours', + }, + }, + { + // cost: 150.0, + // currency: 'USD', + cost: { + value: 100.0, + units: 'USD', + }, + account: 'another_account', + account_alias: 'Another Account', + instance_name: 'example-instance-2', + instance_type: 'm5.large', + // memory: 8, + memory: { + value: 8, + units: 'gib_hours', + }, + operating_system: 'Windows', + region: 'us-east-1', + resource_id: 'i-0987654321fedcba0', + // tags: { + // Environment: 'Development', + // Project: 'ABC Project', + // }, + tags: [ + { + key: 'version', + values: ['Antennae', 'master', 'orange'], + enabled: true, + }, + ], + // unit: 'Hrs', + // usage_hours: 200, + usage: { + value: 200, + units: 'Hrs', + }, + vcpu: { + value: 2, + units: 'core_hours', + }, + }, + ], + }, + ], +}; diff --git a/src/routes/details/awsBreakdown/instances/index.ts b/src/routes/details/awsBreakdown/instances/index.ts new file mode 100644 index 000000000..27ad02e77 --- /dev/null +++ b/src/routes/details/awsBreakdown/instances/index.ts @@ -0,0 +1 @@ +export { default as Instances } from './instances'; diff --git a/src/routes/details/awsBreakdown/instances/instances.tsx b/src/routes/details/awsBreakdown/instances/instances.tsx new file mode 100644 index 000000000..ed76c1d58 --- /dev/null +++ b/src/routes/details/awsBreakdown/instances/instances.tsx @@ -0,0 +1,410 @@ +import { Pagination, PaginationVariant } from '@patternfly/react-core'; +import type { Query } from 'api/queries/query'; +import { getQuery } from 'api/queries/query'; +import type { Report } from 'api/reports/report'; +import { ReportPathsType, ReportType } from 'api/reports/report'; +import type { AxiosError } from 'axios'; +import messages from 'locales/messages'; +import { cloneDeep } from 'lodash'; +import React, { useEffect, useState } from 'react'; +import { useIntl } from 'react-intl'; +import { useDispatch, useSelector } from 'react-redux'; +import type { AnyAction } from 'redux'; +import type { ThunkDispatch } from 'redux-thunk'; +import { ExportModal } from 'routes/components/export'; +import { Loading } from 'routes/components/page/loading'; +import { NoInstances } from 'routes/components/page/noInstances'; +import { NotAvailable } from 'routes/components/page/notAvailable'; +import type { ColumnManagementModalOption } from 'routes/details/components/columnManagement'; +import { ColumnManagementModal, initHiddenColumns } from 'routes/details/components/columnManagement'; +import { styles } from 'routes/optimizations/optimizationsBreakdown/optimizationsBreakdown.styles'; +import type { ComputedReportItem } from 'routes/utils/computedReport/getComputedReportItems'; +import { getUnsortedComputedReportItems } from 'routes/utils/computedReport/getComputedReportItems'; +import { getFilterByTagKey, getGroupById, getGroupByOrgValue, getGroupByValue } from 'routes/utils/groupBy'; +import * as queryUtils from 'routes/utils/query'; +import type { RootState } from 'store'; +import { FetchStatus } from 'store/common'; +import { reportActions, reportSelectors } from 'store/reports'; +import { useQueryFromRoute, useQueryState } from 'utils/hooks'; +import { accountKey, logicalAndPrefix, logicalOrPrefix, orgUnitIdKey, regionKey } from 'utils/props'; + +import { data } from './data'; +import { InstancesTable, InstanceTableColumnIds } from './instancesTable'; +import { InstancesToolbar } from './instancesToolbar'; + +interface InstancesOwnProps { + costType?: string; + currency?: string; +} + +export interface InstancesStateProps { + groupBy: string; + hasAccountFilter: boolean; + hasRegionFilter: boolean; + hasTagFilter: boolean; + report: Report; + reportError: AxiosError; + reportFetchStatus: FetchStatus; + reportQueryString: string; +} + +export interface InstancesMapProps { + // TBD... +} + +type InstancesProps = InstancesOwnProps; + +const baseQuery: Query = { + filter: { + limit: 10, + offset: 0, + }, + order_by: { + cost: 'desc', + }, +}; + +const defaultColumnOptions: ColumnManagementModalOption[] = [ + { + label: messages.cpuTitle, + value: InstanceTableColumnIds.cpu, + hidden: true, + }, + { + label: messages.memoryTitle, + value: InstanceTableColumnIds.memory, + hidden: true, + }, +]; + +const reportType = ReportType.cost as any; +const reportPathsType = ReportPathsType.aws as any; + +const Instances: React.FC = ({ costType, currency }) => { + const intl = useIntl(); + + const [hiddenColumns, setHiddenColumns] = useState(initHiddenColumns(defaultColumnOptions)); + const [isAllSelected, setIsAllSelected] = useState(false); + const [isColumnManagementModalOpen, setIsColumnManagementModalOpen] = useState(false); + const [isExportModalOpen, setIsExportModalOpen] = useState(false); + const [selectedItems, setSelectedItems] = useState([]); + + const [query, setQuery] = useState({ ...baseQuery }); + const { + groupBy, + hasAccountFilter, + hasRegionFilter, + hasTagFilter, + report, + reportError, + reportFetchStatus, + reportQueryString, + } = useMapToProps({ + costType, + currency, + query, + }); + + const getColumnManagementModal = () => { + const options = cloneDeep(defaultColumnOptions); + options.map(option => { + option.hidden = hiddenColumns.has(option.value); + }); + + return ( + + ); + }; + + const getComputedItems = () => { + return getUnsortedComputedReportItems({ + idKey: 'resource_id' as any, + isGroupBy: false, + report, + }); + }; + + const getExportModal = (computedItems: ComputedReportItem[]) => { + const itemsTotal = report?.meta ? report.meta.count : 0; + + // Omit items labeled 'no-project' + const items = []; + selectedItems.map(item => { + items.push(item); + }); + return ( + 0} + groupBy={groupBy} + isOpen={isExportModalOpen} + items={items} + onClose={handleOnExportModalClose} + reportPathsType={reportPathsType} + reportQueryString={reportQueryString} + showAggregateType={false} + /> + ); + }; + + const getPagination = (isDisabled = false, isBottom = false) => { + const count = report?.meta?.count || 0; + const limit = report?.meta?.limit || baseQuery.filter.limit; + const offset = report?.meta?.offset || baseQuery.filter.offset; + const page = Math.trunc(offset / limit + 1); + + return ( + handleOnPerPageSelect(perPage)} + onSetPage={(event, pageNumber) => handleOnSetPage(pageNumber)} + page={page} + perPage={limit} + titles={{ + paginationAriaLabel: intl.formatMessage(messages.paginationTitle, { + title: intl.formatMessage(messages.openShift), + placement: isBottom ? 'bottom' : 'top', + }), + }} + variant={isBottom ? PaginationVariant.bottom : PaginationVariant.top} + widgetId={`exports-pagination${isBottom ? '-bottom' : ''}`} + /> + ); + }; + + const getTable = () => { + return ( + handleOnSort(sortType, isSortAscending)} + orderBy={query.order_by} + query={query} + report={report} + reportPathsType={reportPathsType} + reportQueryString={reportQueryString} + selectedItems={selectedItems} + /> + ); + }; + + const getToolbar = (computedItems: ComputedReportItem[]) => { + const isDisabled = computedItems.length === 0; + const itemsTotal = report?.meta ? report.meta.count : 0; + + return ( + handleOnFilterAdded(filter)} + onFilterRemoved={filter => handleOnFilterRemoved(filter)} + pagination={getPagination(isDisabled)} + query={query} + selectedItems={selectedItems} + /> + ); + }; + + const handleOnBulkSelect = (action: string) => { + if (action === 'none') { + setIsAllSelected(false); + setSelectedItems([]); + } else if (action === 'page') { + const newSelectedItems = [...selectedItems]; + getComputedItems().map(val => { + if (!newSelectedItems.find(item => item.id === val.id)) { + newSelectedItems.push(val); + } + }); + setIsAllSelected(false); + setSelectedItems(newSelectedItems); + } else if (action === 'all') { + setIsAllSelected(!isAllSelected); + setSelectedItems([]); + } + }; + + const handleOnColumnManagementModalClose = (isOpen: boolean) => { + setIsColumnManagementModalOpen(isOpen); + }; + + const handleOnColumnManagementModalOpen = () => { + setIsColumnManagementModalOpen(true); + }; + + const handleOnColumnManagementModalSave = (newHiddenColumns: Set) => { + setHiddenColumns(newHiddenColumns); + }; + + const handleOnExportModalClose = (isOpen: boolean) => { + setIsExportModalOpen(isOpen); + }; + + const handleOnExportModalOpen = () => { + setIsExportModalOpen(true); + }; + + const handleOnFilterAdded = filter => { + const newQuery = queryUtils.handleOnFilterAdded(query, filter); + setQuery(newQuery); + }; + + const handleOnFilterRemoved = filter => { + const newQuery = queryUtils.handleOnFilterRemoved(query, filter); + setQuery(newQuery); + }; + + const handleOnPerPageSelect = perPage => { + const newQuery = queryUtils.handleOnPerPageSelect(query, perPage, false); + setQuery(newQuery); + }; + + const handleonSelect = (items: ComputedReportItem[], isSelected: boolean = false) => { + let newItems = [...(isAllSelected ? getComputedItems() : selectedItems)]; + if (items && items.length > 0) { + if (isSelected) { + items.map(item => newItems.push(item)); + } else { + items.map(item => { + newItems = newItems.filter(val => val.id !== item.id); + }); + } + } + setIsAllSelected(false); + setSelectedItems(newItems); + }; + + const handleOnSetPage = pageNumber => { + const newQuery = queryUtils.handleOnSetPage(query, report, pageNumber, false); + setQuery(newQuery); + }; + + const handleOnSort = (sortType, isSortAscending) => { + const newQuery = queryUtils.handleOnSort(query, sortType, isSortAscending); + setQuery(newQuery); + }; + + const itemsTotal = report?.meta ? report.meta.count : 0; + const isDisabled = itemsTotal === 0; + const hasInstances = report?.meta && report.meta.count > 0; + + if (reportError) { + return ; + } + if (!query.filter_by && !hasInstances && reportFetchStatus === FetchStatus.complete) { + return ; + } + const computedItems = getComputedItems(); + + return ( + <> + {getExportModal(computedItems)} + {getColumnManagementModal()} + {getToolbar(computedItems)} + {reportFetchStatus === FetchStatus.inProgress ? ( + + ) : ( + <> + {getTable()} +
{getPagination(isDisabled, true)}
+ + )} + + ); +}; + +// eslint-disable-next-line no-empty-pattern +const useMapToProps = ({ costType, currency, query }): InstancesStateProps => { + const dispatch: ThunkDispatch = useDispatch(); + const queryFromRoute = useQueryFromRoute(); + const queryState = useQueryState('details'); + + const groupByOrgValue = getGroupByOrgValue(queryFromRoute); + const groupBy = groupByOrgValue ? orgUnitIdKey : getGroupById(queryFromRoute); + const groupByValue = groupByOrgValue ? groupByOrgValue : getGroupByValue(queryFromRoute); + + const reportQuery = { + cost_type: costType, + currency, + filter: { + ...(query.filter || baseQuery.filter), + resolution: 'monthly', + time_scope_units: 'month', + time_scope_value: -1, + }, + filter_by: { + // Add filters here to apply logical OR/AND + ...(queryState?.filter_by && queryState.filter_by), + ...(queryFromRoute?.filter?.account && { [`${logicalAndPrefix}account`]: queryFromRoute.filter.account }), + // Omit filters associated with the current group_by -- see https://issues.redhat.com/browse/COST-1131 and https://issues.redhat.com/browse/COST-3642 + ...(groupBy && groupBy !== orgUnitIdKey && groupByValue !== '*' && { [groupBy]: undefined }), + // Workaround for https://issues.redhat.com/browse/COST-1189 + ...(queryState?.filter_by && + queryState.filter_by[orgUnitIdKey] && { + [`${logicalOrPrefix}${orgUnitIdKey}`]: queryState.filter_by[orgUnitIdKey], + [orgUnitIdKey]: undefined, + }), + ...(query.filter_by && query.filter_by), + }, + exclude: { + ...(queryState?.exclude && queryState.exclude), + ...(query.exclude && query.exclude), + }, + group_by: { + ...(groupBy && { [groupBy]: groupByValue }), + }, + order_by: query.order_by || baseQuery.order_by, + }; + const reportQueryString = getQuery(reportQuery); + let report = useSelector((state: RootState) => + reportSelectors.selectReport(state, reportPathsType, reportType, reportQueryString) + ); + const reportFetchStatus = useSelector((state: RootState) => + reportSelectors.selectReportFetchStatus(state, reportPathsType, reportType, reportQueryString) + ); + const reportError = useSelector((state: RootState) => + reportSelectors.selectReportError(state, reportPathsType, reportType, reportQueryString) + ); + + useEffect(() => { + if (!reportError && reportFetchStatus !== FetchStatus.inProgress) { + dispatch(reportActions.fetchReport(reportPathsType, reportType, reportQueryString)); + } + }, [currency, query]); + + // Todo: Update to use new API response + report = data; + + return { + groupBy, + hasAccountFilter: queryState?.filter_by?.[accountKey] !== undefined, + hasRegionFilter: queryState?.filter_by?.[regionKey] !== undefined, + hasTagFilter: getFilterByTagKey(queryState) !== undefined, + report, + reportError, + reportFetchStatus, + reportQueryString, + }; +}; + +export default Instances; diff --git a/src/routes/details/awsBreakdown/instances/instancesTable.tsx b/src/routes/details/awsBreakdown/instances/instancesTable.tsx new file mode 100644 index 000000000..37544fc73 --- /dev/null +++ b/src/routes/details/awsBreakdown/instances/instancesTable.tsx @@ -0,0 +1,238 @@ +import 'routes/components/dataTable/dataTable.scss'; + +import type { Query } from 'api/queries/query'; +import type { AwsReport, AwsReportItem } from 'api/reports/awsReports'; +import type { Report } from 'api/reports/report'; +import messages from 'locales/messages'; +import React, { useEffect, useState } from 'react'; +import { useIntl } from 'react-intl'; +import { DataTable } from 'routes/components/dataTable'; +import { styles } from 'routes/components/dataTable/dataTable.styles'; +import { NoInstancesState } from 'routes/components/page/noInstances/noInstancesState'; +import { Actions } from 'routes/details/components/actions'; +import { TagLink } from 'routes/details/components/tag'; +import type { ComputedReportItem } from 'routes/utils/computedReport/getComputedReportItems'; +import { getUnsortedComputedReportItems } from 'routes/utils/computedReport/getComputedReportItems'; +import { formatCurrency, unitsLookupKey } from 'utils/format'; + +interface InstancesTableOwnProps { + filterBy?: any; + hiddenColumns?: Set; + isAllSelected?: boolean; + isLoading?: boolean; + onSelect(items: ComputedReportItem[], isSelected: boolean); + onSort(value: string, isSortAscending: boolean); + orderBy?: any; + query?: Query; + report?: Report; + reportPathsType?: string; + reportQueryString?: string; + selectedItems?: ComputedReportItem[]; +} + +type InstancesTableProps = InstancesTableOwnProps; + +export const InstanceTableColumnIds = { + cpu: 'cpu', + memory: 'memory', +}; + +const InstancesTable: React.FC = ({ + filterBy, + hiddenColumns, + isAllSelected, + isLoading, + onSelect, + onSort, + orderBy, + report, + reportPathsType, + reportQueryString, + selectedItems, +}) => { + const intl = useIntl(); + const [columns, setColumns] = useState([]); + const [rows, setRows] = useState([]); + + const initDatum = () => { + if (!report) { + return; + } + + const newRows = []; + const computedItems = getUnsortedComputedReportItems({ + idKey: 'resource_id' as any, + isGroupBy: false, + report, + }); + + // Sorting with tag keys is not supported + const newColumns = [ + { + name: '', + }, + { + orderBy: 'instances', + name: intl.formatMessage(messages.detailsResourceNames, { value: 'instance' }), + ...(computedItems.length && { isSortable: true }), + }, + { + name: intl.formatMessage(messages.detailsResourceNames, { value: 'account' }), + ...(computedItems.length && { isSortable: true }), + }, + { + name: intl.formatMessage(messages.detailsResourceNames, { value: 'os' }), + ...(computedItems.length && { isSortable: true }), + }, + { + name: intl.formatMessage(messages.detailsResourceNames, { value: 'tags' }), + }, + { + name: intl.formatMessage(messages.detailsResourceNames, { value: 'instance_type' }), + ...(computedItems.length && { isSortable: true }), + }, + { + name: intl.formatMessage(messages.detailsResourceNames, { value: 'region' }), + ...(computedItems.length && { isSortable: true }), + }, + { + id: InstanceTableColumnIds.cpu, + name: intl.formatMessage(messages.detailsResourceNames, { value: 'cpu' }), + style: styles.managedColumn, + }, + { + id: InstanceTableColumnIds.memory, + name: intl.formatMessage(messages.detailsResourceNames, { value: 'memory' }), + style: styles.managedColumn, + }, + { + orderBy: 'cost', + name: intl.formatMessage(messages.cost), + style: styles.costColumn, + ...(computedItems.length && { isSortable: true }), + }, + { + name: '', + }, + ]; + + computedItems.map((item, index) => { + const cost = getTotalCost(item, index); + const actions = getActions(item); + + newRows.push({ + cells: [ + {}, // Empty cell for row selection + { + value: ( + <> +
{item.instance_name ? item.instance_name : null}
+
{item.resource_id ? item.resource_id : null}
+ + ), + }, + { + value: ( + <> +
{item.account_alias ? item.account_alias : null}
+
{item.account ? item.account : null}
+ + ), + }, + { value: item.operating_system ? item.operating_system : null }, + { value: }, + { value: item.instance_type ? item.instance_type : null }, + { value: item.region ? item.region : null }, + { + value: intl.formatMessage(messages.valueUnits, { + value: item.vcpu ? item.vcpu.value : '', + units: item.vcpu ? intl.formatMessage(messages.units, { units: unitsLookupKey(item.vcpu.units) }) : null, + }), + id: InstanceTableColumnIds.cpu, + style: styles.managedColumn, + }, + { + value: intl.formatMessage(messages.valueUnits, { + value: item.memory ? item.memory.value : '', + units: item.memory + ? intl.formatMessage(messages.units, { units: unitsLookupKey(item.memory.units) }) + : null, + }), + id: InstanceTableColumnIds.memory, + style: styles.managedColumn, + }, + { value: cost, style: styles.managedColumn }, + { value: actions }, + ], + item, + selected: isAllSelected || (selectedItems && selectedItems.find(val => val.id === item.id) !== undefined), + }); + }); + + const filteredColumns = (newColumns as any[]).filter(column => !hiddenColumns.has(column.id) && !column.hidden); + const filteredRows = newRows.map(({ ...row }) => { + row.cells = row.cells.filter(cell => !hiddenColumns.has(cell.id) && !cell.hidden); + return row; + }); + setColumns(filteredColumns); + setRows(filteredRows); + }; + + const getActions = (item: ComputedReportItem, isDisabled = false) => { + // There is no group by for instances, but we use it to format messages + return ( + + ); + }; + + const getTotalCost = (item: ComputedReportItem, index: number) => { + // Todo: add cost types to report + const cost = (report?.meta?.total?.cost as any)?.value || 0; + const value = (item.cost as any)?.value || 0; + const units = (item.cost as any)?.units || 'USD'; + const percentValue = cost === 0 ? cost.toFixed(2) : ((value / cost) * 100).toFixed(2); + return ( + <> + {formatCurrency(value, units)} +
+ {intl.formatMessage(messages.percentOfCost, { value: percentValue })} +
+ + ); + }; + + const handleOnSort = (value: string, isSortAscending: boolean) => { + if (onSort) { + onSort(value, isSortAscending); + } + }; + + useEffect(() => { + initDatum(); + }, [hiddenColumns, report, selectedItems]); + + return ( + } + filterBy={filterBy} + isActionsCell + isLoading={isLoading} + isSelectable + onSelect={onSelect} + onSort={handleOnSort} + orderBy={orderBy} + rows={rows} + selectedItems={selectedItems} + /> + ); +}; + +export { InstancesTable }; diff --git a/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx b/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx new file mode 100644 index 000000000..f685cdb1f --- /dev/null +++ b/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx @@ -0,0 +1,213 @@ +import type { ToolbarChipGroup } from '@patternfly/react-core'; +import type { AwsQuery } from 'api/queries/awsQuery'; +import { getQuery } from 'api/queries/query'; +import { ResourcePathsType } from 'api/resources/resource'; +import type { Tag } from 'api/tags/tag'; +import { TagPathsType, TagType } from 'api/tags/tag'; +import messages from 'locales/messages'; +import React from 'react'; +import type { WrappedComponentProps } from 'react-intl'; +import { injectIntl } from 'react-intl'; +import { connect } from 'react-redux'; +import { DataToolbar } from 'routes/components/dataToolbar'; +import type { ComputedReportItem } from 'routes/utils/computedReport/getComputedReportItems'; +import { isEqual } from 'routes/utils/equal'; +import type { Filter } from 'routes/utils/filter'; +import type { FetchStatus } from 'store/common'; +import { createMapStateToProps } from 'store/common'; +import { tagActions, tagSelectors } from 'store/tags'; +import { accountKey, regionKey, tagKey } from 'utils/props'; + +interface InstancesToolbarOwnProps { + hideAccount?: boolean; + hideRegion?: boolean; + hideTags?: boolean; + isAllSelected?: boolean; + isBulkSelectDisabled?: boolean; + isDisabled?: boolean; + isExportDisabled?: boolean; + items?: ComputedReportItem[]; + itemsPerPage?: number; + itemsTotal?: number; + groupBy: string; + onBulkSelect(action: string); + onColumnManagementClicked(); + onExportClicked(); + onFilterAdded(filter: Filter); + onFilterRemoved(filter: Filter); + pagination?: React.ReactNode; + query?: AwsQuery; + selectedItems?: ComputedReportItem[]; +} + +interface InstancesToolbarStateProps { + tagReport?: Tag; + tagReportFetchStatus?: FetchStatus; + tagQueryString?: string; +} + +interface InstancesToolbarDispatchProps { + fetchTag?: typeof tagActions.fetchTag; +} + +interface InstancesToolbarState { + categoryOptions?: ToolbarChipGroup[]; +} + +type InstancesToolbarProps = InstancesToolbarOwnProps & + InstancesToolbarStateProps & + InstancesToolbarDispatchProps & + WrappedComponentProps; + +const resourcePathsType = ResourcePathsType.aws; +const tagPathsType = TagPathsType.aws; +const tagType = TagType.tag; + +export class InstancesToolbarBase extends React.Component { + protected defaultState: InstancesToolbarState = {}; + public state: InstancesToolbarState = { ...this.defaultState }; + + public componentDidMount() { + this.setState( + { + categoryOptions: this.getCategoryOptions(), + }, + () => { + this.updateReport(); + } + ); + } + + public componentDidUpdate(prevProps: InstancesToolbarProps) { + const { query, tagReport } = this.props; + + if (!isEqual(tagReport, prevProps.tagReport)) { + this.setState( + { + categoryOptions: this.getCategoryOptions(), + }, + () => { + this.updateReport(); + } + ); + } else if (query && !isEqual(query, prevProps.query)) { + this.updateReport(); + } + } + + private getCategoryOptions = (): ToolbarChipGroup[] => { + const { hideAccount, hideRegion, hideTags, intl, tagReport } = this.props; + + const options = [ + { name: intl.formatMessage(messages.filterByValues, { value: 'instance' }), key: 'service' }, + { name: intl.formatMessage(messages.filterByValues, { value: 'account' }), key: 'account' }, + { name: intl.formatMessage(messages.filterByValues, { value: 'operating_system' }), key: 'os' }, + { name: intl.formatMessage(messages.filterByValues, { value: 'region' }), key: 'region' }, + ]; + if (!hideTags && tagReport?.data?.length) { + options.push({ name: intl.formatMessage(messages.filterByValues, { value: tagKey }), key: tagKey }); + } + const sortedOptions = options.sort((a, b) => { + if (a.name < b.name) { + return -1; + } + if (a.name > b.name) { + return 1; + } + return 0; + }); + const filteredOptions = hideRegion ? sortedOptions.filter(option => option.key !== regionKey) : sortedOptions; + return hideAccount ? filteredOptions.filter(option => option.key !== accountKey) : filteredOptions; + }; + + private updateReport = () => { + const { fetchTag, tagQueryString } = this.props; + fetchTag(tagPathsType, tagType, tagQueryString); + }; + + public render() { + const { + groupBy, + isAllSelected, + isBulkSelectDisabled, + isDisabled, + isExportDisabled, + itemsPerPage, + itemsTotal, + onBulkSelect, + onColumnManagementClicked, + onExportClicked, + onFilterAdded, + onFilterRemoved, + pagination, + query, + selectedItems, + tagReport, + } = this.props; + const { categoryOptions } = this.state; + + return ( + + ); + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const mapStateToProps = createMapStateToProps((state, props) => { + // Note: Omitting key_only would help to share a single, cached request. Only the toolbar requires key values; + // however, for better server-side performance, we chose to use key_only here. + const baseQuery = { + filter: { + resolution: 'monthly', + time_scope_units: 'month', + time_scope_value: -1, + }, + key_only: true, + limit: 1000, + }; + + const tagQueryString = getQuery({ + ...baseQuery, + }); + const tagReport = tagSelectors.selectTag(state, tagPathsType, tagType, tagQueryString); + const tagReportFetchStatus = tagSelectors.selectTagFetchStatus(state, tagPathsType, tagType, tagQueryString); + + return { + tagReport, + tagReportFetchStatus, + tagQueryString, + }; +}); + +const mapDispatchToProps: InstancesToolbarDispatchProps = { + fetchTag: tagActions.fetchTag, +}; + +const InstancesToolbarConnect = connect(mapStateToProps, mapDispatchToProps)(InstancesToolbarBase); +const InstancesToolbar = injectIntl(InstancesToolbarConnect); + +export { InstancesToolbar }; diff --git a/src/routes/details/components/actions/actions.tsx b/src/routes/details/components/actions/actions.tsx index 2606631f1..dba4731f3 100644 --- a/src/routes/details/components/actions/actions.tsx +++ b/src/routes/details/components/actions/actions.tsx @@ -1,4 +1,3 @@ -import type { ProviderType } from 'api/providers'; import type { ReportPathsType } from 'api/reports/report'; import messages from 'locales/messages'; import React from 'react'; @@ -16,12 +15,12 @@ import type { RouterComponentProps } from 'utils/router'; import { withRouter } from 'utils/router'; interface DetailsActionsOwnProps extends WrappedComponentProps, RouterComponentProps { - groupBy: string; + groupBy?: string; isDisabled?: boolean; item: ComputedReportItem; - providerType?: ProviderType; reportPathsType: ReportPathsType; reportQueryString: string; + showAggregateType?: boolean; showPriceListOption?: boolean; } @@ -52,7 +51,7 @@ class DetailsActionsBase extends React.Component { - const { groupBy, item, reportPathsType, reportQueryString } = this.props; + const { groupBy, item, reportPathsType, reportQueryString, showAggregateType } = this.props; const { isExportModalOpen } = this.state; return ( @@ -64,6 +63,7 @@ class DetailsActionsBase extends React.Component ); }; @@ -98,7 +98,7 @@ class DetailsActionsBase extends React.Component redirectToCostModel(source_uuid[0], router), toString: () => intl.formatMessage(messages.detailsActionsPriceList), }); diff --git a/src/routes/details/components/breakdown/breakdownBase.tsx b/src/routes/details/components/breakdown/breakdownBase.tsx index 4046fefed..756017622 100644 --- a/src/routes/details/components/breakdown/breakdownBase.tsx +++ b/src/routes/details/components/breakdown/breakdownBase.tsx @@ -23,7 +23,6 @@ import { } from 'routes/utils/queryNavigate'; import { FetchStatus } from 'store/common'; import type { reportActions } from 'store/reports'; -import type { uiActions } from 'store/ui'; import type { RouterComponentProps } from 'utils/router'; import { withRouter } from 'utils/router'; @@ -94,7 +93,6 @@ export interface BreakdownStateProps { } interface BreakdownDispatchProps { - closeOptimizationsDrawer?: typeof uiActions.closeOptimizationsDrawer; fetchReport?: typeof reportActions.fetchReport; } @@ -266,20 +264,12 @@ class BreakdownBase extends React.Component { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore private handleTabClick = (event, tabIndex) => { - const { closeOptimizationsDrawer } = this.props; const { activeTabKey } = this.state; if (activeTabKey !== tabIndex) { - this.setState( - { - activeTabKey: tabIndex, - }, - () => { - if (closeOptimizationsDrawer) { - closeOptimizationsDrawer(); - } - } - ); + this.setState({ + activeTabKey: tabIndex, + }); } }; diff --git a/src/routes/details/components/pvcChart/modal/pvcContent.tsx b/src/routes/details/components/pvcChart/modal/pvcContent.tsx index b6c59b70a..35ef101cb 100644 --- a/src/routes/details/components/pvcChart/modal/pvcContent.tsx +++ b/src/routes/details/components/pvcChart/modal/pvcContent.tsx @@ -1,7 +1,7 @@ import { Pagination, PaginationVariant } from '@patternfly/react-core'; import type { OcpQuery } from 'api/queries/ocpQuery'; import type { Query } from 'api/queries/query'; -import { getQuery, parseQuery } from 'api/queries/query'; +import { getQuery } from 'api/queries/query'; import type { OcpReport } from 'api/reports/ocpReports'; import { ReportPathsType } from 'api/reports/report'; import { ReportType } from 'api/reports/report'; @@ -21,6 +21,7 @@ import { getQueryState } from 'routes/utils/queryState'; import type { RootState } from 'store'; import { FetchStatus } from 'store/common'; import { reportActions, reportSelectors } from 'store/reports'; +import { useQueryFromRoute, useQueryState } from 'utils/hooks'; import { platformCategoryKey } from 'utils/props'; import { styles } from './pvcContent.styles'; @@ -176,16 +177,6 @@ const PvcContent: React.FC = () => { ); }; -const useQueryFromRoute = () => { - const location = useLocation(); - return parseQuery(location.search); -}; - -const useQueryState = () => { - const location = useLocation(); - return getQueryState(location, 'details'); -}; - // eslint-disable-next-line no-empty-pattern const useMapToProps = ({ query }: PvcContentMapProps): PvcContentStateProps => { const dispatch: ThunkDispatch = useDispatch(); diff --git a/src/routes/details/components/tag/modal/tagContent.tsx b/src/routes/details/components/tag/modal/tagContent.tsx index 815e477c2..eaff1b742 100644 --- a/src/routes/details/components/tag/modal/tagContent.tsx +++ b/src/routes/details/components/tag/modal/tagContent.tsx @@ -1,5 +1,6 @@ import { DataList, DataListCell, DataListItem, DataListItemCells, DataListItemRow } from '@patternfly/react-core'; import type { Tag } from 'api/tags/tag'; +import type { TagData } from 'api/tags/tag'; import messages from 'locales/messages'; import React from 'react'; import type { WrappedComponentProps } from 'react-intl'; @@ -11,6 +12,7 @@ import { styles } from './tagContent.styles'; interface TagContentOwnProps { groupBy: string; groupByValue: string | number; + tagData?: TagData[]; tagReport?: Tag; } @@ -18,11 +20,12 @@ type TagContentProps = TagContentOwnProps & WrappedComponentProps; class TagContentBase extends React.Component { private getDataListItems = () => { - const { tagReport } = this.props; + const { tagData, tagReport } = this.props; const result = []; - if (tagReport) { - for (const item of tagReport.data) { + if (tagData || tagReport) { + const tags = tagData || tagReport.data; + for (const item of tags) { for (const val of item.values) { const id = `${(item as any).key}:${val}`; result.push( diff --git a/src/routes/details/components/tag/modal/tagModal.tsx b/src/routes/details/components/tag/modal/tagModal.tsx index 048378884..4af7ee21d 100644 --- a/src/routes/details/components/tag/modal/tagModal.tsx +++ b/src/routes/details/components/tag/modal/tagModal.tsx @@ -1,7 +1,7 @@ import { Modal } from '@patternfly/react-core'; import type { Query } from 'api/queries/query'; import { getQuery, parseQuery } from 'api/queries/query'; -import type { Tag, TagPathsType } from 'api/tags/tag'; +import type { Tag, TagData, TagPathsType } from 'api/tags/tag'; import { TagType } from 'api/tags/tag'; import messages from 'locales/messages'; import React from 'react'; @@ -22,6 +22,7 @@ import { TagContent } from './tagContent'; interface TagModalOwnProps extends RouterComponentProps, WrappedComponentProps { isOpen: boolean; onClose(isOpen: boolean); + tagData?: TagData[]; tagPathsType: TagPathsType; } @@ -50,13 +51,15 @@ class TagModalBase extends React.Component { } public componentDidMount() { - const { fetchTag, tagPathsType, tagQueryString } = this.props; - fetchTag(tagPathsType, tagType, tagQueryString); + const { fetchTag, tagData, tagPathsType, tagQueryString } = this.props; + if (!tagData) { + fetchTag(tagPathsType, tagType, tagQueryString); + } } public componentDidUpdate(prevProps: TagModalProps) { - const { fetchTag, tagPathsType, tagQueryString } = this.props; - if (prevProps.tagQueryString !== tagQueryString) { + const { fetchTag, tagData, tagPathsType, tagQueryString } = this.props; + if (prevProps.tagQueryString !== tagQueryString && !tagData) { fetchTag(tagPathsType, tagType, tagQueryString); } } @@ -67,11 +70,12 @@ class TagModalBase extends React.Component { } private getTagValueCount = () => { - const { tagReport } = this.props; + const { tagData, tagReport } = this.props; let count = 0; - if (tagReport) { - for (const item of tagReport.data) { + if (tagData || tagReport) { + const tags = tagData || tagReport.data; + for (const item of tags) { if (item.values) { count += item.values.length; } @@ -85,7 +89,7 @@ class TagModalBase extends React.Component { }; public render() { - const { groupBy, intl, isOpen, query, tagReport } = this.props; + const { groupBy, intl, isOpen, query, tagData, tagReport } = this.props; // Match page header description const groupByValue = query && query.filter && query.filter.account ? query.filter.account : this.props.groupByValue; @@ -100,6 +104,7 @@ class TagModalBase extends React.Component { diff --git a/src/routes/details/components/tag/tagLink.tsx b/src/routes/details/components/tag/tagLink.tsx index 0136ba541..ac4599043 100644 --- a/src/routes/details/components/tag/tagLink.tsx +++ b/src/routes/details/components/tag/tagLink.tsx @@ -1,7 +1,7 @@ import { TagIcon } from '@patternfly/react-icons/dist/esm/icons/tag-icon'; import type { Query } from 'api/queries/query'; import { getQuery, parseQuery } from 'api/queries/query'; -import type { Tag, TagPathsType } from 'api/tags/tag'; +import type { Tag, TagData, TagPathsType } from 'api/tags/tag'; import { TagType } from 'api/tags/tag'; import React from 'react'; import type { WrappedComponentProps } from 'react-intl'; @@ -21,6 +21,7 @@ import { styles } from './tag.styles'; interface TagLinkOwnProps extends RouterComponentProps, WrappedComponentProps { id?: string; + tagData?: TagData[]; tagPathsType: TagPathsType; } @@ -55,13 +56,15 @@ class TagLinkBase extends React.Component { } public componentDidMount() { - const { fetchTag, tagPathsType, tagQueryString } = this.props; - fetchTag(tagPathsType, tagType, tagQueryString); + const { fetchTag, tagData, tagPathsType, tagQueryString } = this.props; + if (!tagData) { + fetchTag(tagPathsType, tagType, tagQueryString); + } } public componentDidUpdate(prevProps: TagLinkProps) { - const { fetchTag, tagPathsType, tagQueryString } = this.props; - if (prevProps.tagQueryString !== tagQueryString) { + const { fetchTag, tagData, tagPathsType, tagQueryString } = this.props; + if (prevProps.tagQueryString !== tagQueryString && !tagData) { fetchTag(tagPathsType, tagType, tagQueryString); } } @@ -77,12 +80,13 @@ class TagLinkBase extends React.Component { }; public render() { - const { id, tagReport, tagPathsType } = this.props; + const { id, tagData, tagReport, tagPathsType } = this.props; const { isOpen } = this.state; let count = 0; - if (tagReport) { - for (const item of tagReport.data) { + if (tagData || tagReport) { + const tags = tagData || tagReport.data; + for (const item of tags) { if (item.values) { count += item.values.length; } @@ -97,7 +101,7 @@ class TagLinkBase extends React.Component { {count} - +
); } diff --git a/src/routes/details/ocpBreakdown/instances.tsx b/src/routes/details/ocpBreakdown/instances.tsx deleted file mode 100644 index f00cfcc99..000000000 --- a/src/routes/details/ocpBreakdown/instances.tsx +++ /dev/null @@ -1,44 +0,0 @@ -// import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent'; -// import type { Query } from 'api/queries/query'; -// import { parseQuery } from 'api/queries/query'; -// import messages from 'locales/messages'; -import React from 'react'; -// import { useIntl } from 'react-intl'; -import { useLocation } from 'react-router-dom'; -// import { routes } from 'routes'; -// import { getGroupById, getGroupByValue } from 'routes/utils/groupBy'; -import { getQueryState } from 'routes/utils/queryState'; -// import { formatPath } from 'utils/paths'; - -interface InstancesOwnProps { - // TBD... -} - -type InstancesProps = InstancesOwnProps; - -// const useQueryFromRoute = () => { -// const location = useLocation(); -// return parseQuery(location.search); -// }; - -const useQueryState = () => { - const location = useLocation(); - return getQueryState(location, 'details'); -}; - -const Instances: React.FC = () => { - // const intl = useIntl(); - // const location = useLocation(); - // const queryFromRoute = useQueryFromRoute(); - const queryState = useQueryState(); - - // const groupBy = getGroupById(queryFromRoute); - // const groupByValue = getGroupByValue(queryFromRoute); - // const otimizationsTab = location.search.indexOf('optimizationsTab') === -1 ? '&optimizationsTab=true' : ''; - - const tagsFilter = queryState?.filter_by?.tags ? queryState.filter_by.tags : null; - - return <>Hello{tagsFilter}; -}; - -export { Instances }; diff --git a/src/routes/details/ocpBreakdown/ocpBreakdown.tsx b/src/routes/details/ocpBreakdown/ocpBreakdown.tsx index 782274d0e..b9e3a652f 100644 --- a/src/routes/details/ocpBreakdown/ocpBreakdown.tsx +++ b/src/routes/details/ocpBreakdown/ocpBreakdown.tsx @@ -30,7 +30,6 @@ import { getCostDistribution, getCurrency } from 'utils/sessionStorage'; import { CostOverview } from './costOverview'; import { HistoricalData } from './historicalData'; -import { Instances } from './instances'; import { Optimizations } from './optimizations'; interface OcpBreakdownDispatchProps { @@ -120,9 +119,7 @@ const mapStateToProps = createMapStateToProps, - instancesComponent: , isOptimizationsTab: queryFromRoute.optimizationsTab !== undefined, - isAwsEc2InstancesToggleEnabled: FeatureToggleSelectors.selectIsAwsEc2InstancesToggleEnabled(state), isRosToggleEnabled: FeatureToggleSelectors.selectIsRosToggleEnabled(state), optimizationsComponent: groupBy === 'project' && groupByValue !== '*' ? : undefined, providers: filterProviders(providers, ProviderType.ocp), diff --git a/src/routes/details/ocpBreakdown/optimizations.tsx b/src/routes/details/ocpBreakdown/optimizations.tsx index 1aa4a56ab..a6e446545 100644 --- a/src/routes/details/ocpBreakdown/optimizations.tsx +++ b/src/routes/details/ocpBreakdown/optimizations.tsx @@ -1,13 +1,11 @@ import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent'; -import type { Query } from 'api/queries/query'; -import { parseQuery } from 'api/queries/query'; import messages from 'locales/messages'; import React from 'react'; import { useIntl } from 'react-intl'; import { useLocation } from 'react-router-dom'; import { routes } from 'routes'; import { getGroupById, getGroupByValue } from 'routes/utils/groupBy'; -import { getQueryState } from 'routes/utils/queryState'; +import { useQueryFromRoute, useQueryState } from 'utils/hooks'; import { formatPath } from 'utils/paths'; interface OptimizationsOwnProps { @@ -16,16 +14,6 @@ interface OptimizationsOwnProps { type OptimizationsProps = OptimizationsOwnProps; -const useQueryFromRoute = () => { - const location = useLocation(); - return parseQuery(location.search); -}; - -const useQueryState = () => { - const location = useLocation(); - return getQueryState(location, 'details'); -}; - const Optimizations: React.FC = () => { const intl = useIntl(); const location = useLocation(); diff --git a/src/routes/details/ocpDetails/detailsTable.tsx b/src/routes/details/ocpDetails/detailsTable.tsx index b852ec99c..253fef687 100644 --- a/src/routes/details/ocpDetails/detailsTable.tsx +++ b/src/routes/details/ocpDetails/detailsTable.tsx @@ -2,7 +2,6 @@ import 'routes/components/dataTable/dataTable.scss'; import { Label, Tooltip } from '@patternfly/react-core'; import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent'; -import { ProviderType } from 'api/providers'; import type { Query } from 'api/queries/query'; import type { OcpReport, OcpReportItem } from 'api/reports/ocpReports'; import { ReportPathsType } from 'api/reports/report'; @@ -343,7 +342,6 @@ class DetailsTableBase extends React.Component { - const location = useLocation(); - return parseQuery(location.search); -}; - const OptimizationsBreakdown: React.FC = () => { const intl = useIntl(); const queryFromRoute = useQueryFromRoute(); diff --git a/src/routes/utils/computedReport/getComputedReportItems.ts b/src/routes/utils/computedReport/getComputedReportItems.ts index f36e1a402..80223c67d 100644 --- a/src/routes/utils/computedReport/getComputedReportItems.ts +++ b/src/routes/utils/computedReport/getComputedReportItems.ts @@ -50,6 +50,7 @@ export interface ComputedReportItem extends ComputedReportOcpItem, ComputedRepor export interface ComputedReportItemsParams { idKey: keyof T; isDateMap?: boolean; + isGroupBy?: boolean; report: R; sortKey?: keyof ComputedReportItem; sortDirection?: SortDirection; @@ -156,6 +157,10 @@ function getCostData(val, key, item?: any) { : defaultUnits, }, }), + ...(val.cost && { + value: val.cost.value + (item?.cost ? item.cost.value : 0), + units: val.cost.units ? val.cost.units : defaultUnits, + }), }; } @@ -209,9 +214,10 @@ function getUsageData(val, item?: any) { // Details pages typically use this function with filter[resolution]=monthly export function getUnsortedComputedReportItems({ + idKey, // Note: The idKey must use org_entities for reports, while group_by uses org_unit_id isDateMap = false, + isGroupBy = true, report, - idKey, // Note: The idKey must use org_entities for reports, while group_by uses org_unit_id }: ComputedReportItemsParams) { if (!report) { return []; @@ -223,139 +229,36 @@ export function getUnsortedComputedReportItems { const type = dataPoint.type; // Org unit type - if (dataPoint && dataPoint.values) { - dataPoint.values.forEach((val: any) => { - let id = val.id ? val.id : val[idKey]; - if (!id) { - id = val.date; - } - - // Ensure unique map IDs -- https://github.com/project-koku/koku-ui/issues/706 - const idSuffix = idKey !== 'date' && idKey !== 'cluster' && val.cluster ? `-${val.cluster}` : ''; - const mapId = `${id}${idSuffix}`; - - // 'clusters' will contain either the cluster alias or default cluster ID - const classification = val.classification; - const cluster_alias = val.clusters && val.clusters.length > 0 ? val.clusters[0] : undefined; - const cluster = cluster_alias || val.cluster; - const date = val.date; - const default_project = val.default_project && val.default_project.toLowerCase() === 'true'; - const delta_percent = val.delta_percent ? val.delta_percent : 0; - const delta_value = val.delta_value ? val.delta_value : 0; - const persistent_volume_claim = val.persistent_volume_claim ? val.persistent_volume_claim : []; - const storage_class = val.storage_class ? val.storage_class : []; - const source_uuid = val.source_uuid ? val.source_uuid : []; - - let label; - if (report.meta && report.meta.others && (id === 'Other' || id === 'Others')) { - // Add count to "Others" label - label = intl.formatMessage(messages.chartOthers, { count: report.meta.others }); - } else { - const itemLabelKey = getItemLabel({ report, idKey, value: val }); - if (itemLabelKey === 'org_entities' && val.alias) { - label = val.alias; - } else if (itemLabelKey === 'account' && val.account_alias) { - label = val.account_alias; - } else if (itemLabelKey === 'cluster' && cluster_alias) { - label = cluster_alias; - } else if (itemLabelKey === 'subscription_guid' && val.subscription_name) { - label = val.subscription_name; - } else if (val[itemLabelKey] instanceof Object) { - label = val[itemLabelKey].value; - } else { - label = val[itemLabelKey]; - } - if (label === undefined || label.trim().length === 0) { - label = val.alias && val.alias.trim().length > 0 ? val.alias : val[idKey]; - } + if (isGroupBy) { + dataPoint?.values?.forEach((val: any) => { + initReportItems({ + idKey, + isDateMap, + itemMap, + report, + type, + val, + }); + }); + for (const key in dataPoint) { + if (dataPoint[key] instanceof Array) { + return dataPoint[key].forEach(visitDataPoint); } - - if (isDateMap) { - const data = { - ...getUsageData(val), // capacity, limit, request, & usage - classification, - cluster, - clusters: getClusters(val), - cost: getCostData(val, 'cost'), - data_transfer_in: val.data_transfer_in, - data_transfer_out: val.data_transfer_out, - date, - default_project, - delta_percent, - delta_value, - id, - infrastructure: getCostData(val, 'infrastructure'), - label, - persistent_volume_claim, - source_uuid, - storage_class, - supplementary: getCostData(val, 'supplementary'), - type, - }; - const item = itemMap.get(mapId); - if (item) { - item.set(date, data); - } else { - const dateMap = new Map(); - dateMap.set(date, data); - itemMap.set(mapId, dateMap); - } - } else { - const item = itemMap.get(mapId); - if (item) { - // When applying multiple group_by params, costs may be split between regions. We need to sum those costs - // See https://issues.redhat.com/browse/COST-1131 - itemMap.set(mapId, { - ...item, - ...getUsageData(val, item), // capacity, limit, request, & usage - classification, - cluster, - clusters: getClusters(val, item), - cost: getCostData(val, 'cost', item), - data_transfer_in: val.data_transfer_in, - data_transfer_out: val.data_transfer_out, - date, - default_project, - delta_percent, - delta_value, - id, - infrastructure: getCostData(val, 'infrastructure', item), - label, - persistent_volume_claim, - source_uuid, - storage_class, - supplementary: getCostData(val, 'supplementary', item), - type, - }); - } else { - itemMap.set(mapId, { - ...getUsageData(val), // capacity, limit, request, & usage - classification, - cluster, - clusters: getClusters(val), - cost: getCostData(val, 'cost'), - data_transfer_in: val.data_transfer_in, - data_transfer_out: val.data_transfer_out, - date, - default_project, - delta_percent, - delta_value, - id, - infrastructure: getCostData(val, 'infrastructure'), - label, - persistent_volume_claim, - source_uuid, - storage_class, - supplementary: getCostData(val, 'supplementary'), + } + } else { + for (const key in dataPoint) { + if (dataPoint[key] instanceof Array) { + dataPoint[key].forEach(val => { + initReportItems({ + idKey, + isDateMap, + itemMap, + report, type, + val, }); - } + }); } - }); - } - for (const key in dataPoint) { - if (dataPoint[key] instanceof Array) { - return dataPoint[key].forEach(visitDataPoint); } } }; @@ -364,3 +267,105 @@ export function getUnsortedComputedReportItems 0 ? val.clusters[0] : undefined; + const cluster = cluster_alias || val.cluster; + const date = val.date; + const default_project = val.default_project && val.default_project.toLowerCase() === 'true'; + + let label; + if (report.meta && report.meta.others && (id === 'Other' || id === 'Others')) { + // Add count to "Others" label + label = intl.formatMessage(messages.chartOthers, { count: report.meta.others }); + } else { + const itemLabelKey = getItemLabel({ report, idKey, value: val }); + if (itemLabelKey === 'org_entities' && val.alias) { + label = val.alias; + } else if (itemLabelKey === 'account' && val.account_alias) { + label = val.account_alias; + } else if (itemLabelKey === 'cluster' && cluster_alias) { + label = cluster_alias; + } else if (itemLabelKey === 'subscription_guid' && val.subscription_name) { + label = val.subscription_name; + } else if (itemLabelKey === 'resource_id' && val.instance_name) { + label = val.instance_name; + } else if (val[itemLabelKey] instanceof Object) { + label = val[itemLabelKey].value; + } else { + label = val[itemLabelKey]; + } + if (label === undefined || label.trim().length === 0) { + label = val.alias && val.alias.trim().length > 0 ? val.alias : val[idKey]; + } + } + + if (isDateMap) { + const data = { + ...val, + ...getUsageData(val), // capacity, limit, request, & usage + cluster, + clusters: getClusters(val), + cost: getCostData(val, 'cost'), + default_project, + id, + infrastructure: getCostData(val, 'infrastructure'), + label, + supplementary: getCostData(val, 'supplementary'), + type, + }; + const item = itemMap.get(mapId); + if (item) { + item.set(date, data); + } else { + const dateMap = new Map(); + dateMap.set(date, data); + itemMap.set(mapId, dateMap); + } + } else { + const item = itemMap.get(mapId); + if (item) { + // When applying multiple group_by params, costs may be split between regions. We need to sum those costs + // See https://issues.redhat.com/browse/COST-1131 + itemMap.set(mapId, { + ...item, + ...getUsageData(val, item), // capacity, limit, request, & usage + cluster, + clusters: getClusters(val, item), + cost: getCostData(val, 'cost', item), + date, + default_project, + id, + infrastructure: getCostData(val, 'infrastructure', item), + label, + supplementary: getCostData(val, 'supplementary', item), + type, + }); + } else { + itemMap.set(mapId, { + ...val, + ...getUsageData(val), // capacity, limit, request, & usage + cluster, + clusters: getClusters(val), + cost: getCostData(val, 'cost'), + date, + default_project, + id, + infrastructure: getCostData(val, 'infrastructure'), + label, + supplementary: getCostData(val, 'supplementary'), + type, + }); + } + } +} diff --git a/src/routes/utils/groupBy.ts b/src/routes/utils/groupBy.ts index a8fd6a3bf..85d7d5672 100644 --- a/src/routes/utils/groupBy.ts +++ b/src/routes/utils/groupBy.ts @@ -54,3 +54,18 @@ export const getGroupByTagKey = (query: Query) => { } return groupByTagKey; }; + +export const getFilterByTagKey = (query: Query) => { + let filterByTagKey; + + if (query?.filter_by) { + for (const groupBy of Object.keys(query.filter_by)) { + const tagIndex = groupBy.indexOf(tagPrefix); + if (tagIndex !== -1) { + filterByTagKey = groupBy.substring(tagIndex + tagPrefix.length) as any; + break; + } + } + } + return filterByTagKey; +}; diff --git a/src/utils/hooks.ts b/src/utils/hooks.ts index 4a3fe3807..e112965da 100644 --- a/src/utils/hooks.ts +++ b/src/utils/hooks.ts @@ -1,5 +1,9 @@ // Hook +import type { Query } from 'api/queries/query'; +import { parseQuery } from 'api/queries/query'; import { useCallback, useEffect, useRef, useState } from 'react'; +import { useLocation } from 'react-router-dom'; +import { getQueryState } from 'routes/utils/queryState'; export const usePrevious = value => { // The ref object is a generic container whose current property is mutable ... @@ -34,3 +38,13 @@ export const useStateCallback = (initialState: T): [T, (state: T, cb?: (_stat return [state, setStateCallback]; }; + +export const useQueryFromRoute = () => { + const location = useLocation(); + return parseQuery(location.search); +}; + +export const useQueryState = (key = 'details') => { + const location = useLocation(); + return getQueryState(location, key); +}; diff --git a/src/utils/props.ts b/src/utils/props.ts index 82917e92a..0c42cd91a 100644 --- a/src/utils/props.ts +++ b/src/utils/props.ts @@ -4,6 +4,7 @@ export const logicalAndPrefix = 'and:'; // logical AND prefix for group_by export const noPrefix = 'No-'; // no-project, no-region, no- export const tagPrefix = 'tag:'; // Tag prefix for group_by +export const accountKey = 'account'; // Account key for group_by export const awsCategoryKey = 'aws_category'; // AWS category for group_by export const breadcrumbLabelKey = 'breadcrumb_label'; // Used to display a breadcrumb in the breakdown header export const breakdownDescKey = 'breakdown_desc'; // Used to display a description in the breakdown header @@ -11,6 +12,8 @@ export const breakdownTitleKey = 'breakdown_title'; // Used to display a title i export const orgUnitIdKey = 'org_unit_id'; // Org unit ID for group_by export const orgUnitNameKey = 'org_unit_name'; // Org unit name for group_by export const platformCategoryKey = 'Platform'; // Used to display platform costs +export const regionKey = 'region'; // Region key for group_by +export const serviceKey = 'service'; // Service key for group_by export const tagKey = 'tag'; // Tag key for group_by export const classificationDefault = 'default'; // Classification default costs From f9d848b27cf81f65d35e4464b3eedc38e7b3dd25 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 24 Apr 2024 17:57:16 -0400 Subject: [PATCH 16/49] Rename OCP bullet chart "unused capacity" label https://issues.redhat.com/browse/COST-4976 --- locales/data.json | 2 +- locales/translations.json | 2 +- src/locales/messages.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/data.json b/locales/data.json index 675aef241..4d278fba9 100644 --- a/locales/data.json +++ b/locales/data.json @@ -3240,7 +3240,7 @@ "detailsUnusedRequestsLabel": [ { "type": 0, - "value": "Unrequested capacity" + "value": "Unused requests" } ], "detailsUnusedUnits": [ diff --git a/locales/translations.json b/locales/translations.json index 4e5e58729..701007802 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -228,7 +228,7 @@ "detailsResourceNames": "{value, select, account {Account names} aws_category {Cost category names} cluster {Cluster names} cpu {CPU} gcp_project {GCP project names} group {Group} instance {Instance names} instance_type {Instance type} memory {Memory} name {Name} node {Node names} org_unit_id {Organizational unit names} os {OS} operating_system {Operating system} payer_tenant_id {Account names} product_service {Service names} project {Project names} region {Region names} resource_location {Region names} service {Service names} service_name {Service names} status {Status} subscription_guid {Account names} source_type {Integration} tag {Tag names} tags {Tags} tag_key {Tag keys} other {}}", "detailsSummaryModalTitle": "{groupBy, select, account {{name} accounts} aws_category {{name} cost categories} cluster {{name} clusters} gcp_project {{name} GCP projects} node {{name} nodes} org_unit_id {{name} organizational units} payer_tenant_id {{name} accounts} product_service {{name} services} project {{name} projects} region {{name} regions} resource_location {{name} regions} service {{name} services} service_name {{name} services} subscription_guid {{name} accounts} tag {{name} tags} other {}}", "detailsUnusedCapacityLabel": "Unused capacity", - "detailsUnusedRequestsLabel": "Unrequested capacity", + "detailsUnusedRequestsLabel": "Unused requests", "detailsUnusedUnits": "{units} ({percentage}% of capacity)", "detailsUsageCapacity": "Capacity - {value} {units}", "detailsUsageLimit": "Limit - {value} {units}", diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 727a94f40..374bc7558 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -1368,8 +1368,8 @@ export default defineMessages({ id: 'detailsUnusedCapacityLabel', }, detailsUnusedRequestsLabel: { - defaultMessage: 'Unrequested capacity', - description: 'Unrequested capacity', + defaultMessage: 'Unused requests', + description: 'Unused requests', id: 'detailsUnusedRequestsLabel', }, detailsUnusedUnits: { From c10425f3ef30f6304b7973ed2d1f8836f2c5edf7 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 24 Apr 2024 22:04:05 -0400 Subject: [PATCH 17/49] Show filter chips in details breakdown https://issues.redhat.com/browse/COST-4977 --- locales/data.json | 12 ++ locales/translations.json | 2 + src/locales/messages.ts | 10 ++ .../breakdown/breakdownHeader.styles.ts | 26 ++++- .../components/breakdown/breakdownHeader.tsx | 105 +++++++++++++++++- 5 files changed, 144 insertions(+), 11 deletions(-) diff --git a/locales/data.json b/locales/data.json index 4d278fba9..d22e4c08b 100644 --- a/locales/data.json +++ b/locales/data.json @@ -8057,6 +8057,18 @@ "value": "Values" } ], + "filteredBy": [ + { + "type": 0, + "value": "Filtered by" + } + ], + "filteredByWarning": [ + { + "type": 0, + "value": "This page shows filtered results. To undo filters, clear filters on the previous page." + } + ], "forDate": [ { "type": 1, diff --git a/locales/translations.json b/locales/translations.json index 701007802..3b5ed50cd 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -323,6 +323,8 @@ "filterByValuePlaceholder": "Filter by value", "filterByValues": "{value, select, account {Account} aws_category {Cost category} cluster {Cluster} container {Container} default {Default} gcp_project {GCP project} group {Group} instance {Instance} name {Name} node {Node} org_unit_id {Organizational unit} operating_system {Operating system} payer_tenant_id {Account} persistent_volume_claim {Persistent volume claim} product_service {Service} project {Project} region {Region} resource_location {Region} service {Service} service_name {Service} source_type {Integration} status {Status} storage_class {StorageClass} subscription_guid {Account} tag {Tag} tag_key {Tag key} tag_key_child {Child tag Key} tag_key_parent {Parent tag Key} workload {Workload name} workload_type {Workload type} other {}}", "filterByValuesAriaLabel": "Values", + "filteredBy": "Filtered by", + "filteredByWarning": "This page shows filtered results. To undo filters, clear filters on the previous page.", "forDate": "{value} for {dateRange}", "gcp": "Google Cloud Platform", "gcpComputeTitle": "Compute instances usage", diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 374bc7558..55473c0ef 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -2092,6 +2092,16 @@ export default defineMessages({ description: 'Values', id: 'filterByValuesAriaLabel', }, + filteredBy: { + defaultMessage: 'Filtered by', + description: 'Filtered by', + id: 'filteredBy', + }, + filteredByWarning: { + defaultMessage: 'This page shows filtered results. To undo filters, clear filters on the previous page.', + description: 'This page shows filtered results. To undo filters, clear filters on the previous page.', + id: 'filteredByWarning', + }, forDate: { defaultMessage: '{value} for {dateRange}', description: '{value} for {Jan 1-31}', diff --git a/src/routes/details/components/breakdown/breakdownHeader.styles.ts b/src/routes/details/components/breakdown/breakdownHeader.styles.ts index ffd866692..353da058f 100644 --- a/src/routes/details/components/breakdown/breakdownHeader.styles.ts +++ b/src/routes/details/components/breakdown/breakdownHeader.styles.ts @@ -13,10 +13,10 @@ export const styles = { }, costDistribution: { marginTop: global_spacer_sm.var, - paddingBottom: global_spacer_md.var, + paddingBottom: global_spacer_sm.var, }, costLabel: { - marginTop: global_spacer_xs.var, + marginTop: global_spacer_lg.var, }, costValue: { marginTop: 0, @@ -28,13 +28,30 @@ export const styles = { }, costType: { marginTop: global_spacer_sm.var, - paddingBottom: global_spacer_md.var, + paddingBottom: global_spacer_sm.var, }, description: { color: global_disabled_color_100.value, fontSize: global_FontSize_xs.value, marginBottom: 0, }, + filterChip: { + marginRight: global_spacer_md.var, + }, + filteredBy: { + marginRight: global_spacer_sm.var, + whiteSpace: 'nowrap', + }, + filteredByContainer: { + display: 'flex', + alignItems: 'center', + marginBottom: global_spacer_sm.var, + marginTop: global_spacer_sm.var, + }, + filteredByWarning: { + marginTop: global_spacer_sm.var, + marginBottom: global_spacer_md.var, + }, header: { backgroundColor: global_BackgroundColor_100.var, paddingLeft: global_spacer_lg.var, @@ -57,7 +74,4 @@ export const styles = { tag: { marginLeft: global_spacer_lg.var, }, - title: { - paddingTop: global_spacer_xs.var, - }, } as { [className: string]: React.CSSProperties }; diff --git a/src/routes/details/components/breakdown/breakdownHeader.tsx b/src/routes/details/components/breakdown/breakdownHeader.tsx index b8537e298..3300ff6a0 100644 --- a/src/routes/details/components/breakdown/breakdownHeader.tsx +++ b/src/routes/details/components/breakdown/breakdownHeader.tsx @@ -1,6 +1,15 @@ import './breakdownHeader.scss'; -import { Flex, FlexItem, Title, TitleSizes } from '@patternfly/react-core'; +import { + Alert, + AlertActionCloseButton, + Chip, + ChipGroup, + Flex, + FlexItem, + Title, + TitleSizes, +} from '@patternfly/react-core'; import { AngleLeftIcon } from '@patternfly/react-icons/dist/esm/icons/angle-left-icon'; import type { Query } from 'api/queries/query'; import type { Report } from 'api/reports/report'; @@ -15,6 +24,7 @@ import { ComputedReportItemValueType } from 'routes/components/charts/common'; import { CostDistribution } from 'routes/components/costDistribution'; import { CostType } from 'routes/components/costType'; import { Currency } from 'routes/components/currency'; +import { getActiveFilters, getChips } from 'routes/components/dataToolbar/utils/common'; import { TagLink } from 'routes/details/components/tag'; import { getGroupByCostCategory, getGroupByOrgValue, getGroupByTagKey } from 'routes/utils/groupBy'; import { createMapStateToProps } from 'store/common'; @@ -57,9 +67,18 @@ interface BreakdownHeaderDispatchProps { // TBD... } +interface BreakdownHeaderState { + showFilteredByAlert?: boolean; +} + type BreakdownHeaderProps = BreakdownHeaderOwnProps & BreakdownHeaderStateProps & WrappedComponentProps; class BreakdownHeader extends React.Component { + protected defaultState: BreakdownHeaderState = { + showFilteredByAlert: true, + }; + public state: BreakdownHeaderState = { ...this.defaultState }; + private getBackToLink = groupByKey => { const { breadcrumb, intl, router, tagPathsType } = this.props; @@ -76,6 +95,67 @@ class BreakdownHeader extends React.Component { ); }; + private hasFilterBy = () => { + const { router } = this.props; + const filterBy = router.location.state?.details?.filter_by; + return filterBy && Object.keys(filterBy).length > 0; + }; + + private getFilterChips = () => { + const { intl, router } = this.props; + + const filterBy = this.hasFilterBy() ? router.location.state?.details?.filter_by : undefined; + if (!filterBy) { + return null; + } + + const getLabel = value => { + const label = intl.formatMessage(messages.filterByValues, { value }); + return label !== '' ? label : value; + }; + + const filters = getActiveFilters(router.location.state?.details) as any; + const filterChips = Object.keys(filters).map(key => { + if (filters[key] instanceof Array) { + const chips: any[] = getChips(filters[key]); + return ( + + + {chips.map((chip, index) => ( + + {chip.node} + + ))} + + + ); + } else { + return Object.keys(filters[key]).map(key2 => { + const chips: any[] = getChips(filters[key][key2]); + return ( + + + {chips.map((chip, index) => ( + + {chip.node} + + ))} + + + ); + }); + } + }); + return ( +
+ + {intl.formatMessage(messages.filteredBy)} + + {filterChips} +
+ ); + }; + private getTotalCost = () => { const { costDistribution, report } = this.props; @@ -89,6 +169,10 @@ class BreakdownHeader extends React.Component { return cost; }; + private handleOnAlertClose = () => { + this.setState({ showFilteredByAlert: false }); + }; + public render() { const { clusterInfoComponent, @@ -110,6 +194,7 @@ class BreakdownHeader extends React.Component { tagPathsType, title, } = this.props; + const { showFilteredByAlert } = this.state; const filterByAccount = query && query.filter ? query.filter.account : undefined; const groupByCostCategory = getGroupByCostCategory(query); @@ -160,12 +245,12 @@ class BreakdownHeader extends React.Component {
)} - - {intl.formatMessage(messages.breakdownTitle, { value: title })} - + + {intl.formatMessage(messages.breakdownTitle, { value: title })} + {(description || showClusterInfo) && ( {description} @@ -174,7 +259,8 @@ class BreakdownHeader extends React.Component { ) : null} )} - {dataDetailsComponent ? {dataDetailsComponent} : null} + {dataDetailsComponent && {dataDetailsComponent}} + {this.hasFilterBy() && {this.getFilterChips()}} {showCostDistribution && ( @@ -200,6 +286,15 @@ class BreakdownHeader extends React.Component { + {this.hasFilterBy() && showFilteredByAlert && ( + } + isInline + style={styles.filteredByWarning} + title={intl.formatMessage(messages.filteredByWarning)} + variant="info" + /> + )}
{tabs} From aa2398996c03c850259611b1a9eb0efa3791c942 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 24 Apr 2024 22:32:15 -0400 Subject: [PATCH 18/49] Fix module path --- src/routes/details/awsBreakdown/awsBreakdown.tsx | 2 +- src/routes/settings/costModels/costModel/costCalc.styles.ts | 2 +- src/routes/settings/costModels/costModel/distribution.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/details/awsBreakdown/awsBreakdown.tsx b/src/routes/details/awsBreakdown/awsBreakdown.tsx index d8917bc11..047fc9f59 100644 --- a/src/routes/details/awsBreakdown/awsBreakdown.tsx +++ b/src/routes/details/awsBreakdown/awsBreakdown.tsx @@ -34,7 +34,7 @@ import { getCostType, getCurrency } from 'utils/sessionStorage'; import { CostOverview } from './costOverview'; import { HistoricalData } from './historicalData'; -import { Instances } from './instances/'; +import { Instances } from './instances'; interface AwsBreakdownDispatchProps { fetchReport?: typeof reportActions.fetchReport; diff --git a/src/routes/settings/costModels/costModel/costCalc.styles.ts b/src/routes/settings/costModels/costModel/costCalc.styles.ts index 16a1c9aa1..af2c0765d 100644 --- a/src/routes/settings/costModels/costModel/costCalc.styles.ts +++ b/src/routes/settings/costModels/costModel/costCalc.styles.ts @@ -4,7 +4,7 @@ import type React from 'react'; export const styles = { card: { - minHeight: 250, + minHeight: 310, }, cardDescription: { fontSize: global_FontSize_md.value, diff --git a/src/routes/settings/costModels/costModel/distribution.tsx b/src/routes/settings/costModels/costModel/distribution.tsx index 4ef301fe3..9f73b4a9b 100644 --- a/src/routes/settings/costModels/costModel/distribution.tsx +++ b/src/routes/settings/costModels/costModel/distribution.tsx @@ -79,7 +79,7 @@ const DistributionCardBase: React.FC = ({ {isOcpCloudNetworkingToggleEnabled && (
{intl.formatMessage(messages.distributeCosts, { - value: current.distribution_info.network_cost, + value: current.distribution_info.network_cost || false, type: 'network', })}
@@ -87,7 +87,7 @@ const DistributionCardBase: React.FC = ({ {isOcpProjectStorageToggleEnabled && (
{intl.formatMessage(messages.distributeCosts, { - value: current.distribution_info.storage_cost, + value: current.distribution_info.storage_cost || false, type: 'storage', })}
From a80a1c5fc05dafaa17a683f69ec64e8309b2f258 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 25 Apr 2024 09:20:53 -0400 Subject: [PATCH 19/49] Changed the filter-by alert to an info icon with a pop-over --- .../breakdown/breakdownHeader.styles.ts | 5 --- .../components/breakdown/breakdownHeader.tsx | 40 +++++++++---------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/routes/details/components/breakdown/breakdownHeader.styles.ts b/src/routes/details/components/breakdown/breakdownHeader.styles.ts index 353da058f..a971ab86e 100644 --- a/src/routes/details/components/breakdown/breakdownHeader.styles.ts +++ b/src/routes/details/components/breakdown/breakdownHeader.styles.ts @@ -39,7 +39,6 @@ export const styles = { marginRight: global_spacer_md.var, }, filteredBy: { - marginRight: global_spacer_sm.var, whiteSpace: 'nowrap', }, filteredByContainer: { @@ -48,10 +47,6 @@ export const styles = { marginBottom: global_spacer_sm.var, marginTop: global_spacer_sm.var, }, - filteredByWarning: { - marginTop: global_spacer_sm.var, - marginBottom: global_spacer_md.var, - }, header: { backgroundColor: global_BackgroundColor_100.var, paddingLeft: global_spacer_lg.var, diff --git a/src/routes/details/components/breakdown/breakdownHeader.tsx b/src/routes/details/components/breakdown/breakdownHeader.tsx index 3300ff6a0..45e08b670 100644 --- a/src/routes/details/components/breakdown/breakdownHeader.tsx +++ b/src/routes/details/components/breakdown/breakdownHeader.tsx @@ -1,16 +1,18 @@ import './breakdownHeader.scss'; import { - Alert, - AlertActionCloseButton, + Button, + ButtonVariant, Chip, ChipGroup, Flex, FlexItem, + Popover, Title, TitleSizes, } from '@patternfly/react-core'; import { AngleLeftIcon } from '@patternfly/react-icons/dist/esm/icons/angle-left-icon'; +import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon'; import type { Query } from 'api/queries/query'; import type { Report } from 'api/reports/report'; import type { TagPathsType } from 'api/tags/tag'; @@ -68,15 +70,13 @@ interface BreakdownHeaderDispatchProps { } interface BreakdownHeaderState { - showFilteredByAlert?: boolean; + // TBD... } type BreakdownHeaderProps = BreakdownHeaderOwnProps & BreakdownHeaderStateProps & WrappedComponentProps; class BreakdownHeader extends React.Component { - protected defaultState: BreakdownHeaderState = { - showFilteredByAlert: true, - }; + protected defaultState: BreakdownHeaderState = {}; public state: BreakdownHeaderState = { ...this.defaultState }; private getBackToLink = groupByKey => { @@ -151,6 +151,20 @@ class BreakdownHeader extends React.Component { {intl.formatMessage(messages.filteredBy)} + + {intl.formatMessage(messages.filteredByWarning)}

} + > + +
+
{filterChips}
); @@ -169,10 +183,6 @@ class BreakdownHeader extends React.Component { return cost; }; - private handleOnAlertClose = () => { - this.setState({ showFilteredByAlert: false }); - }; - public render() { const { clusterInfoComponent, @@ -194,7 +204,6 @@ class BreakdownHeader extends React.Component { tagPathsType, title, } = this.props; - const { showFilteredByAlert } = this.state; const filterByAccount = query && query.filter ? query.filter.account : undefined; const groupByCostCategory = getGroupByCostCategory(query); @@ -286,15 +295,6 @@ class BreakdownHeader extends React.Component {
- {this.hasFilterBy() && showFilteredByAlert && ( - } - isInline - style={styles.filteredByWarning} - title={intl.formatMessage(messages.filteredByWarning)} - variant="info" - /> - )}
{tabs} From 79518fc449785c5911c571cf1e7e1542fbd29fff Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 25 Apr 2024 10:55:27 -0400 Subject: [PATCH 20/49] Enable column management --- src/routes/details/awsBreakdown/instances/instancesToolbar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx b/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx index f685cdb1f..06021054d 100644 --- a/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx +++ b/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx @@ -166,6 +166,7 @@ export class InstancesToolbarBase extends React.Component Date: Thu, 25 Apr 2024 11:17:04 -0400 Subject: [PATCH 21/49] Increase timeout for tests --- src/routes/settings/costModels/components/addPriceList.test.tsx | 2 +- .../settings/costModels/costModel/updateRateModel.test.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/settings/costModels/components/addPriceList.test.tsx b/src/routes/settings/costModels/components/addPriceList.test.tsx index 73122ede9..20386186f 100644 --- a/src/routes/settings/costModels/components/addPriceList.test.tsx +++ b/src/routes/settings/costModels/components/addPriceList.test.tsx @@ -186,7 +186,7 @@ describe('add-a-new-rate', () => { expect(createButton.getAttribute('aria-disabled')).toBe('false'); await act(async () => user.click(createButton)); expect(submit).toHaveBeenCalled(); - }, 7000); + }, 10000); test('tag rates', async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); diff --git a/src/routes/settings/costModels/costModel/updateRateModel.test.tsx b/src/routes/settings/costModels/costModel/updateRateModel.test.tsx index ca693373e..060c62196 100644 --- a/src/routes/settings/costModels/costModel/updateRateModel.test.tsx +++ b/src/routes/settings/costModels/costModel/updateRateModel.test.tsx @@ -322,7 +322,7 @@ describe('update-rate', () => { await act(async () => user.click(options[0])); expect(saveButton.getAttribute('disabled')).not.toBeNull(); - }, 7000); + }, 10000); test('regular', async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); From 43f72784f91b2e42e35ca79811ea528cf404c70a Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Sat, 27 Apr 2024 18:38:08 -0400 Subject: [PATCH 22/49] Show network historical chart for cluster and node only --- locales/data.json | 68 +++++++++++++++++++ locales/translations.json | 8 ++- src/api/reports/ocpReports.ts | 2 +- src/locales/messages.ts | 12 ++-- .../historicalData/historicalDataBase.tsx | 17 ++++- .../details/ocpBreakdown/ocpBreakdown.tsx | 4 +- .../costOverview/common/costOverviewCommon.ts | 8 +-- .../common/historicalDataCommon.ts | 3 + .../ocpHistoricalDataWidgets.ts | 3 + 9 files changed, 109 insertions(+), 16 deletions(-) diff --git a/locales/data.json b/locales/data.json index d22e4c08b..dd66f198c 100644 --- a/locales/data.json +++ b/locales/data.json @@ -774,6 +774,74 @@ } ], "chartCostTooltip": [ + { + "type": 0, + "value": "Cost (" + }, + { + "type": 1, + "value": "month" + }, + { + "type": 0, + "value": ")" + } + ], + "chartDataInLabel": [ + { + "type": 0, + "value": "Data in (" + }, + { + "type": 1, + "value": "dateRange" + }, + { + "type": 0, + "value": ")" + } + ], + "chartDataInLabelNoData": [ + { + "type": 0, + "value": "Data in (no data)" + } + ], + "chartDataInTooltip": [ + { + "type": 0, + "value": "Data in (" + }, + { + "type": 1, + "value": "month" + }, + { + "type": 0, + "value": ")" + } + ], + "chartDataOutLabel": [ + { + "type": 0, + "value": "Data out (" + }, + { + "type": 1, + "value": "dateRange" + }, + { + "type": 0, + "value": ")" + } + ], + "chartDataOutLabelNoData": [ + { + "type": 0, + "value": "Data out (no data)" + } + ], + "chartDataOutTooltip": [ { "type": 0, "value": "Data out (" diff --git a/locales/translations.json b/locales/translations.json index 3b5ed50cd..70f56f3e9 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -40,7 +40,13 @@ "chartCostForecastTooltip": "Cost forecast ({month})", "chartCostLabel": "Cost ({dateRange})", "chartCostLabelNoData": "Cost (no data)", - "chartCostTooltip": "Data out ({month})", + "chartCostTooltip": "Cost ({month})", + "chartDataInLabel": "Data in ({dateRange})", + "chartDataInLabelNoData": "Data in (no data)", + "chartDataInTooltip": "Data in ({month})", + "chartDataOutLabel": "Data out ({dateRange})", + "chartDataOutLabelNoData": "Data out (no data)", + "chartDataOutTooltip": "Data out ({month})", "chartDayOfTheMonth": "Day {day}", "chartLimitLabel": "Limit ({dateRange})", "chartLimitLabelNoData": "Limit (no data)", diff --git a/src/api/reports/ocpReports.ts b/src/api/reports/ocpReports.ts index 4360ad580..56ec64c07 100644 --- a/src/api/reports/ocpReports.ts +++ b/src/api/reports/ocpReports.ts @@ -61,7 +61,7 @@ export const ReportTypePaths: Partial> = { [ReportType.cost]: 'reports/openshift/costs/', [ReportType.cpu]: 'reports/openshift/compute/', [ReportType.memory]: 'reports/openshift/memory/', - [ReportType.network]: 'reports/openshift/volumes/', // TBD: Use "network" when API is available + [ReportType.network]: 'reports/openshift/network/', [ReportType.volume]: 'reports/openshift/volumes/', }; diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 55473c0ef..020527b10 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -258,32 +258,32 @@ export default defineMessages({ chartDataInLabel: { defaultMessage: 'Data in ({dateRange})', description: 'Data in ({dateRange})', - id: 'chartCostTooltip', + id: 'chartDataInLabel', }, chartDataInLabelNoData: { defaultMessage: 'Data in (no data)', description: 'Data in (no data)', - id: 'chartCostTooltip', + id: 'chartDataInLabelNoData', }, chartDataInTooltip: { defaultMessage: 'Data in ({month})', description: 'Data in ({month})', - id: 'chartCostTooltip', + id: 'chartDataInTooltip', }, chartDataOutLabel: { defaultMessage: 'Data out ({dateRange})', description: 'Data out ({dateRange})', - id: 'chartCostTooltip', + id: 'chartDataOutLabel', }, chartDataOutLabelNoData: { defaultMessage: 'Data out (no data)', description: 'Data out (no data)', - id: 'chartCostTooltip', + id: 'chartDataOutLabelNoData', }, chartDataOutTooltip: { defaultMessage: 'Data out ({month})', description: 'Data out ({month})', - id: 'chartCostTooltip', + id: 'chartDataOutTooltip', }, chartDayOfTheMonth: { defaultMessage: 'Day {day}', diff --git a/src/routes/details/components/historicalData/historicalDataBase.tsx b/src/routes/details/components/historicalData/historicalDataBase.tsx index 27b08ddc0..86156425a 100644 --- a/src/routes/details/components/historicalData/historicalDataBase.tsx +++ b/src/routes/details/components/historicalData/historicalDataBase.tsx @@ -17,6 +17,7 @@ interface HistoricalDataOwnProps { costDistribution?: string; costType?: string; currency?: string; + groupBy?: string; } export interface HistoricalDataStateProps { @@ -67,9 +68,19 @@ class HistoricalDatasBase extends React.Component { // Returns network chart private getNetworkChart = (widget: HistoricalDataWidget) => { - const { intl, isOcpCloudNetworkingToggleEnabled } = this.props; + const { groupBy, intl, isOcpCloudNetworkingToggleEnabled } = this.props; - if (widget.reportPathsType === ReportPathsType.ocp && !isOcpCloudNetworkingToggleEnabled) { + let showWidget = false; + + if (widget.network?.showWidgetOnGroupBy) { + for (const groupById of widget.network.showWidgetOnGroupBy) { + if (groupById === groupBy) { + showWidget = true; + break; + } + } + } + if (!showWidget || !isOcpCloudNetworkingToggleEnabled) { return null; } return ( @@ -96,7 +107,7 @@ class HistoricalDatasBase extends React.Component { private getVolumeChart = (widget: HistoricalDataWidget) => { const { intl, isOcpProjectStorageToggleEnabled } = this.props; - if (widget.reportPathsType === ReportPathsType.ocp && !isOcpProjectStorageToggleEnabled) { + if (!isOcpProjectStorageToggleEnabled) { return null; } return ( diff --git a/src/routes/details/ocpBreakdown/ocpBreakdown.tsx b/src/routes/details/ocpBreakdown/ocpBreakdown.tsx index b9e3a652f..ec6d564af 100644 --- a/src/routes/details/ocpBreakdown/ocpBreakdown.tsx +++ b/src/routes/details/ocpBreakdown/ocpBreakdown.tsx @@ -118,7 +118,9 @@ const mapStateToProps = createMapStateToProps, + historicalDataComponent: ( + + ), isOptimizationsTab: queryFromRoute.optimizationsTab !== undefined, isRosToggleEnabled: FeatureToggleSelectors.selectIsRosToggleEnabled(state), optimizationsComponent: groupBy === 'project' && groupByValue !== '*' ? : undefined, diff --git a/src/store/breakdown/costOverview/common/costOverviewCommon.ts b/src/store/breakdown/costOverview/common/costOverviewCommon.ts index ef2b830fe..4d0c367ed 100644 --- a/src/store/breakdown/costOverview/common/costOverviewCommon.ts +++ b/src/store/breakdown/costOverview/common/costOverviewCommon.ts @@ -17,10 +17,10 @@ export interface CostOverviewWidget { id: number; cluster?: { reportGroupBy: string; // Report group_by - showWidgetOnGroupBy?: string[]; // Show widget when group_by is matched + showWidgetOnGroupBy?: string[]; // Show cluster card when group_by is matched }; pvc?: { - showWidgetOnGroupBy?: string[]; // Show widget when group_by is matched + showWidgetOnGroupBy?: string[]; // Show pvc chart when group_by is matched }; usage?: { showCapacityOnGroupBy?: string[]; // Show capacity when group_by is matched @@ -28,13 +28,13 @@ export interface CostOverviewWidget { reportSummary?: { reportGroupBy: string; // Report group_by showWidgetOnPlatformCategory?: string[]; - showWidgetOnGroupBy?: string[]; // Show widget when group_by is matched + showWidgetOnGroupBy?: string[]; // Show summary card when group_by is matched usePlaceholder?: boolean; // Use placeholder to keep card placement when widget is not shown }; reportPathsType: ReportPathsType; // Report URL path reportType: ReportType; // Report type; cost, storage, etc. type: CostOverviewWidgetType; volume?: { - showWidgetOnGroupBy?: string[]; // Show widget when group_by is matched + showWidgetOnGroupBy?: string[]; // Show volume usage chart when group_by is matched }; } diff --git a/src/store/breakdown/historicalData/common/historicalDataCommon.ts b/src/store/breakdown/historicalData/common/historicalDataCommon.ts index 05ca74bd5..7bdb0f9a2 100644 --- a/src/store/breakdown/historicalData/common/historicalDataCommon.ts +++ b/src/store/breakdown/historicalData/common/historicalDataCommon.ts @@ -12,6 +12,9 @@ export const enum HistoricalDataWidgetType { export interface HistoricalDataWidget { chartName: string; // Will be the prefix for ids within the chart id: number; + network?: { + showWidgetOnGroupBy?: string[]; // Show network chart when group_by is matched + }; reportPathsType: ReportPathsType; // Report URL path reportType: ReportType; // Report type; cost, storage, etc. type: HistoricalDataWidgetType; diff --git a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts index 7ef8f2151..7468b14ec 100644 --- a/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts +++ b/src/store/breakdown/historicalData/ocpHistoricalData/ocpHistoricalDataWidgets.ts @@ -33,6 +33,9 @@ export const memoryUsageWidget: OcpHistoricalDataWidget = { export const networkUsageWidget: OcpHistoricalDataWidget = { chartName: 'ocpNetworkChart', id: getId(), + network: { + showWidgetOnGroupBy: ['cluster', 'node'], + }, reportPathsType: ReportPathsType.ocp, reportType: ReportType.network, type: HistoricalDataWidgetType.network, From ec1abf58b4629d09b3d466bdee9b3765401fd124 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:12:51 +0000 Subject: [PATCH 23/49] (chore): Bump the lint-dependencies group with 2 updates Bumps the lint-dependencies group with 2 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) and [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser). Updates `@typescript-eslint/eslint-plugin` from 7.7.0 to 7.7.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.7.1/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 7.7.0 to 7.7.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.7.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 88 +++++++++++++++++++++++------------------------ package.json | 4 +-- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 907d43a28..7f404a686 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,8 +58,8 @@ "@types/react-dom": "^18.2.25", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.7.0", - "@typescript-eslint/parser": "^7.7.0", + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", @@ -4429,16 +4429,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", - "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", + "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.7.0", - "@typescript-eslint/type-utils": "7.7.0", - "@typescript-eslint/utils": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/type-utils": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.3.1", @@ -4497,15 +4497,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", - "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", + "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.7.0", - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/typescript-estree": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4" }, "engines": { @@ -4525,13 +4525,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", - "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", + "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4542,13 +4542,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", - "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", + "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.7.0", - "@typescript-eslint/utils": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/utils": "7.7.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -4569,9 +4569,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", - "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", + "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4582,13 +4582,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", - "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", + "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4658,17 +4658,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", - "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", + "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.15", "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.7.0", - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", "semver": "^7.6.0" }, "engines": { @@ -4716,12 +4716,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", - "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", + "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/types": "7.7.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { diff --git a/package.json b/package.json index d399ba5d9..42d17ae82 100644 --- a/package.json +++ b/package.json @@ -98,8 +98,8 @@ "@types/react-dom": "^18.2.25", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.7.0", - "@typescript-eslint/parser": "^7.7.0", + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", From fb53be020352c8f863d3c6706607c4fc81ab9d6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:13:53 +0000 Subject: [PATCH 24/49] (chore): Bump @testing-library/react in the test-dependencies group Bumps the test-dependencies group with 1 update: [@testing-library/react](https://github.com/testing-library/react-testing-library). Updates `@testing-library/react` from 15.0.2 to 15.0.5 - [Release notes](https://github.com/testing-library/react-testing-library/releases) - [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/react-testing-library/compare/v15.0.2...v15.0.5) --- updated-dependencies: - dependency-name: "@testing-library/react" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 907d43a28..4e145fa4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "@swc/core": "^1.4.16", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.2", - "@testing-library/react": "^15.0.2", + "@testing-library/react": "^15.0.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", @@ -3637,9 +3637,9 @@ } }, "node_modules/@testing-library/react": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.2.tgz", - "integrity": "sha512-5mzIpuytB1ctpyywvyaY2TAAUQVCZIGqwiqFQf6u9lvj/SJQepGUzNV18Xpk+NLCaCE2j7CWrZE0tEf9xLZYiQ==", + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.5.tgz", + "integrity": "sha512-ttodVWYA2i2w4hRa6krKrmS1vKxAEkwDz34y+CwbcrbZUxFzUYN3a5xZyFKo+K6LBseCRCUkwcjATpaNn/UsIA==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", diff --git a/package.json b/package.json index d399ba5d9..6588a75ef 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "@swc/core": "^1.4.16", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.2", - "@testing-library/react": "^15.0.2", + "@testing-library/react": "^15.0.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", From 35e2bd3584d4904e286ab852aa4907329460d7cb Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 1 May 2024 09:22:15 -0400 Subject: [PATCH 25/49] Dependency updates --- package-lock.json | 264 +++++++++++++++++++++++----------------------- package.json | 30 +++--- 2 files changed, 147 insertions(+), 147 deletions(-) diff --git a/package-lock.json b/package-lock.json index ebb728799..512d863e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,18 +10,18 @@ "hasInstallScript": true, "license": "GNU AGPLv3", "dependencies": { - "@patternfly/patternfly": "^5.3.0", - "@patternfly/react-charts": "^7.3.0", + "@patternfly/patternfly": "5.3.0", + "@patternfly/react-charts": "7.3.0", "@patternfly/react-component-groups": "^5.1.0", - "@patternfly/react-core": "^5.3.0", - "@patternfly/react-icons": "^5.3.0", - "@patternfly/react-table": "^5.3.0", - "@patternfly/react-tokens": "^5.3.0", + "@patternfly/react-core": "5.3.0", + "@patternfly/react-icons": "5.3.0", + "@patternfly/react-table": "5.3.0", + "@patternfly/react-tokens": "5.3.0", "@redhat-cloud-services/frontend-components": "^4.2.7", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", - "@redhat-cloud-services/rbac-client": "^1.3.3", + "@redhat-cloud-services/rbac-client": "^1.4.0", "@reduxjs/toolkit": "^2.2.3", "@unleash/proxy-client-react": "^4.2.2", "axios": "^1.6.8", @@ -29,11 +29,11 @@ "js-file-download": "^0.4.12", "lodash": "^4.17.21", "qs": "^6.12.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-intl": "^6.6.5", "react-redux": "^9.1.1", - "react-router-dom": "^6.22.3", + "react-router-dom": "^6.23.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "typesafe-actions": "^5.1.0", @@ -47,19 +47,19 @@ "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.12", "@redhat-cloud-services/tsc-transform-imports": "^1.0.9", - "@swc/core": "^1.4.16", + "@swc/core": "^1.4.17", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^15.0.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", - "@types/react": "^18.2.79", - "@types/react-dom": "^18.2.25", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.7.1", - "@typescript-eslint/parser": "^7.7.1", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", @@ -2946,9 +2946,9 @@ } }, "node_modules/@redhat-cloud-services/rbac-client": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.3.3.tgz", - "integrity": "sha512-tGKI10dEKbYBkZws9iPAzh5c0LpzNumqRVAQvE3tX+xqWgpwUs27r66QUst87Hv9/83O4ECQwy3hq2zopauyxA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.0.tgz", + "integrity": "sha512-gFwvrOi0MDYbRYwC5TZ4zff4QO/Ss0T+LngWiEYD5duNAEWfbNQft4i/RjvJwEVJ14lxz1xGiHU6WRHms7GeBQ==", "dependencies": { "axios": "^0.27.2", "tslib": "^2.6.2" @@ -3026,9 +3026,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", - "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", + "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", "engines": { "node": ">=14.0.0" } @@ -3193,9 +3193,9 @@ } }, "node_modules/@swc/core": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.16.tgz", - "integrity": "sha512-Xaf+UBvW6JNuV131uvSNyMXHn+bh6LyKN4tbv7tOUFQpXyz/t9YWRE04emtlUW9Y0qrm/GKFCbY8n3z6BpZbTA==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.17.tgz", + "integrity": "sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3210,16 +3210,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.4.16", - "@swc/core-darwin-x64": "1.4.16", - "@swc/core-linux-arm-gnueabihf": "1.4.16", - "@swc/core-linux-arm64-gnu": "1.4.16", - "@swc/core-linux-arm64-musl": "1.4.16", - "@swc/core-linux-x64-gnu": "1.4.16", - "@swc/core-linux-x64-musl": "1.4.16", - "@swc/core-win32-arm64-msvc": "1.4.16", - "@swc/core-win32-ia32-msvc": "1.4.16", - "@swc/core-win32-x64-msvc": "1.4.16" + "@swc/core-darwin-arm64": "1.4.17", + "@swc/core-darwin-x64": "1.4.17", + "@swc/core-linux-arm-gnueabihf": "1.4.17", + "@swc/core-linux-arm64-gnu": "1.4.17", + "@swc/core-linux-arm64-musl": "1.4.17", + "@swc/core-linux-x64-gnu": "1.4.17", + "@swc/core-linux-x64-musl": "1.4.17", + "@swc/core-win32-arm64-msvc": "1.4.17", + "@swc/core-win32-ia32-msvc": "1.4.17", + "@swc/core-win32-x64-msvc": "1.4.17" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -3231,9 +3231,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.16.tgz", - "integrity": "sha512-UOCcH1GvjRnnM/LWT6VCGpIk0OhHRq6v1U6QXuPt5wVsgXnXQwnf5k3sG5Cm56hQHDvhRPY6HCsHi/p0oek8oQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.17.tgz", + "integrity": "sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==", "cpu": [ "arm64" ], @@ -3247,9 +3247,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.16.tgz", - "integrity": "sha512-t3bgqFoYLWvyVtVL6KkFNCINEoOrIlyggT/kJRgi1y0aXSr0oVgcrQ4ezJpdeahZZ4N+Q6vT3ffM30yIunELNA==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.17.tgz", + "integrity": "sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA==", "cpu": [ "x64" ], @@ -3263,9 +3263,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.16.tgz", - "integrity": "sha512-DvHuwvEF86YvSd0lwnzVcjOTZ0jcxewIbsN0vc/0fqm9qBdMMjr9ox6VCam1n3yYeRtj4VFgrjeNFksqbUejdQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.17.tgz", + "integrity": "sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q==", "cpu": [ "arm" ], @@ -3279,9 +3279,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.16.tgz", - "integrity": "sha512-9Uu5YlPbyCvbidjKtYEsPpyZlu16roOZ5c2tP1vHfnU9bgf5Tz5q5VovSduNxPHx+ed2iC1b1URODHvDzbbDuQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.17.tgz", + "integrity": "sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q==", "cpu": [ "arm64" ], @@ -3295,9 +3295,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.16.tgz", - "integrity": "sha512-/YZq/qB1CHpeoL0eMzyqK5/tYZn/rzKoCYDviFU4uduSUIJsDJQuQA/skdqUzqbheOXKAd4mnJ1hT04RbJ8FPQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.17.tgz", + "integrity": "sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw==", "cpu": [ "arm64" ], @@ -3311,9 +3311,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.16.tgz", - "integrity": "sha512-UUjaW5VTngZYDcA8yQlrFmqs1tLi1TxbKlnaJwoNhel9zRQ0yG1YEVGrzTvv4YApSuIiDK18t+Ip927bwucuVQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.17.tgz", + "integrity": "sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA==", "cpu": [ "x64" ], @@ -3327,9 +3327,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.16.tgz", - "integrity": "sha512-aFhxPifevDTwEDKPi4eRYWzC0p/WYJeiFkkpNU5Uc7a7M5iMWPAbPFUbHesdlb9Jfqs5c07oyz86u+/HySBNPQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.17.tgz", + "integrity": "sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw==", "cpu": [ "x64" ], @@ -3343,9 +3343,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.16.tgz", - "integrity": "sha512-bTD43MbhIHL2s5QgCwyleaGwl96Gk/scF2TaVKdUe4QlJCDV/YK9h5oIBAp63ckHtE8GHlH4c8dZNBiAXn4Org==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.17.tgz", + "integrity": "sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w==", "cpu": [ "arm64" ], @@ -3359,9 +3359,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.16.tgz", - "integrity": "sha512-/lmZeAN/qV5XbK2SEvi8e2RkIg8FQNYiSA8y2/Zb4gTUMKVO5JMLH0BSWMiIKMstKDPDSxMWgwJaQHF8UMyPmQ==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.17.tgz", + "integrity": "sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g==", "cpu": [ "ia32" ], @@ -3375,9 +3375,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.4.16", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.16.tgz", - "integrity": "sha512-BPAfFfODWXtUu6SwaTTftDHvcbDyWBSI/oanUeRbQR5vVWkXoQ3cxLTsDluc3H74IqXS5z1Uyoe0vNo2hB1opA==", + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.17.tgz", + "integrity": "sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg==", "cpu": [ "x64" ], @@ -4192,18 +4192,18 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", - "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", + "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.2.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", - "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", "dev": true, "dependencies": { "@types/react": "*" @@ -4429,16 +4429,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", - "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", + "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.7.1", - "@typescript-eslint/type-utils": "7.7.1", - "@typescript-eslint/utils": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/type-utils": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.3.1", @@ -4497,15 +4497,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", - "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.7.1", - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/typescript-estree": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", "debug": "^4.3.4" }, "engines": { @@ -4525,13 +4525,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", - "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", + "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1" + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4542,13 +4542,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", - "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.7.1", - "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -4569,9 +4569,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", - "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", + "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4582,13 +4582,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", - "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", + "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4658,17 +4658,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", - "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", + "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.15", "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.7.1", - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", "semver": "^7.6.0" }, "engines": { @@ -4716,12 +4716,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", - "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", + "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/types": "7.8.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -18056,9 +18056,9 @@ } }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -18083,15 +18083,15 @@ "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==" }, "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/react-dropzone": { @@ -18203,11 +18203,11 @@ } }, "node_modules/react-router": { - "version": "6.22.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", - "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", + "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", "dependencies": { - "@remix-run/router": "1.15.3" + "@remix-run/router": "1.16.0" }, "engines": { "node": ">=14.0.0" @@ -18217,12 +18217,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.22.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", - "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", + "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", "dependencies": { - "@remix-run/router": "1.15.3", - "react-router": "6.22.3" + "@remix-run/router": "1.16.0", + "react-router": "6.23.0" }, "engines": { "node": ">=14.0.0" @@ -18858,9 +18858,9 @@ } }, "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } diff --git a/package.json b/package.json index a89aed468..3fcde4eba 100644 --- a/package.json +++ b/package.json @@ -50,18 +50,18 @@ "verify": "npm-run-all build lint test" }, "dependencies": { - "@patternfly/patternfly": "^5.3.0", - "@patternfly/react-charts": "^7.3.0", + "@patternfly/patternfly": "5.3.0", + "@patternfly/react-charts": "7.3.0", "@patternfly/react-component-groups": "^5.1.0", - "@patternfly/react-core": "^5.3.0", - "@patternfly/react-icons": "^5.3.0", - "@patternfly/react-table": "^5.3.0", - "@patternfly/react-tokens": "^5.3.0", + "@patternfly/react-core": "5.3.0", + "@patternfly/react-icons": "5.3.0", + "@patternfly/react-table": "5.3.0", + "@patternfly/react-tokens": "5.3.0", "@redhat-cloud-services/frontend-components": "^4.2.7", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", - "@redhat-cloud-services/rbac-client": "^1.3.3", + "@redhat-cloud-services/rbac-client": "^1.4.0", "@reduxjs/toolkit": "^2.2.3", "@unleash/proxy-client-react": "^4.2.2", "axios": "^1.6.8", @@ -69,11 +69,11 @@ "js-file-download": "^0.4.12", "lodash": "^4.17.21", "qs": "^6.12.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-intl": "^6.6.5", "react-redux": "^9.1.1", - "react-router-dom": "^6.22.3", + "react-router-dom": "^6.23.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "typesafe-actions": "^5.1.0", @@ -87,19 +87,19 @@ "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.12", "@redhat-cloud-services/tsc-transform-imports": "^1.0.9", - "@swc/core": "^1.4.16", + "@swc/core": "^1.4.17", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^15.0.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", - "@types/react": "^18.2.79", - "@types/react-dom": "^18.2.25", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.7.1", - "@typescript-eslint/parser": "^7.7.1", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", From 44b6d3339134de2e70c6ae60e3bb9d5a8355f8ea Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 1 May 2024 11:03:32 -0400 Subject: [PATCH 26/49] Add kebab tooltips https://issues.redhat.com/browse/COST-5008 --- locales/data.json | 6 ++++ locales/translations.json | 1 + src/locales/messages.ts | 5 +++ .../dropdownWrapper/dropdownWrapper.tsx | 33 ++++++++++++------- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/locales/data.json b/locales/data.json index dd66f198c..4ee07769c 100644 --- a/locales/data.json +++ b/locales/data.json @@ -10728,6 +10728,12 @@ "value": "Month over month change" } ], + "moreOptions": [ + { + "type": 0, + "value": "More options" + } + ], "names": [ { "offset": 0, diff --git a/locales/translations.json b/locales/translations.json index 70f56f3e9..5ff1d1f96 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -389,6 +389,7 @@ "metricValues": "{value, select, cpu {CPU} cluster {Cluster} memory {Memory} node {Node} persistent_volume_claims {Persistent volume claims} storage {Storage} other {}}", "metricsOperatorVersion": "Cost Management operator version", "monthOverMonthChange": "Month over month change", + "moreOptions": "More options", "names": "{count, plural, one {Name} other {Names}}", "network": "Network", "networkDesc": "Distribute the cost of network traffic to projects based on distribution type.", diff --git a/src/locales/messages.ts b/src/locales/messages.ts index 020527b10..f5c2e8e59 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -2518,6 +2518,11 @@ export default defineMessages({ description: 'Month over month change', id: 'monthOverMonthChange', }, + moreOptions: { + defaultMessage: 'More options', + description: 'More options', + id: 'moreOptions', + }, names: { defaultMessage: '{count, plural, one {Name} other {Names}}', description: 'Name plural or singular', diff --git a/src/routes/components/dropdownWrapper/dropdownWrapper.tsx b/src/routes/components/dropdownWrapper/dropdownWrapper.tsx index b3be23a35..4b7eb9e35 100644 --- a/src/routes/components/dropdownWrapper/dropdownWrapper.tsx +++ b/src/routes/components/dropdownWrapper/dropdownWrapper.tsx @@ -1,8 +1,10 @@ import './dropdownWrapper.scss'; -import { Dropdown, DropdownItem, DropdownList, MenuToggle } from '@patternfly/react-core'; +import { Dropdown, DropdownItem, DropdownList, MenuToggle, Tooltip } from '@patternfly/react-core'; import { EllipsisVIcon } from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; +import messages from 'locales/messages'; import React, { useState } from 'react'; +import { useIntl } from 'react-intl'; export interface DropdownWrapperItem { description?: string; // Item description @@ -33,6 +35,7 @@ const DropdownWrapper: React.FC = ({ placeholder = null, position, }) => { + const intl = useIntl(); const [isOpen, setIsOpen] = useState(false); const getDropdownItem = (item, index) => { @@ -58,17 +61,23 @@ const DropdownWrapper: React.FC = ({ setIsOpen(!isOpen); }; - const toggle = toggleRef => ( - - {isKebab ? : placeholder} - - ); + const toggle = toggleRef => { + const msg = intl.formatMessage(messages.moreOptions); + return ( + + + {isKebab ? : placeholder} + + + ); + }; return ( Date: Fri, 3 May 2024 10:15:56 -0400 Subject: [PATCH 27/49] Update network data --- .../details/components/historicalData/data.ts | 420 +++++++++++++++--- 1 file changed, 358 insertions(+), 62 deletions(-) diff --git a/src/routes/details/components/historicalData/data.ts b/src/routes/details/components/historicalData/data.ts index ebcf37279..669218277 100644 --- a/src/routes/details/components/historicalData/data.ts +++ b/src/routes/details/components/historicalData/data.ts @@ -4,31 +4,91 @@ export const currentData = { meta: { - // usual count limit offset currency filter group by order by exclude + count: 2, + limit: 100, + offset: 0, total: { usage: { value: 3.6801746441, units: 'GB', }, data_transfer_in: { - value: 2.789192834, + value: 12.82510775, units: 'GB', }, data_transfer_out: { - value: 0.8909818101, + value: 8.080656137, units: 'GB', }, + infrastructure: { + raw: { + value: 1945.51192915, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 1945.51192915, + units: 'USD', + }, + }, + supplementary: { + raw: { + value: 0.0, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 0.0, + units: 'USD', + }, + }, + cost: { + raw: { + value: 4863.77982288, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 4863.77982288, + units: 'USD', + }, + }, }, - } as any, + }, links: { - // usual links info - } as any, + first: + '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-1&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', + next: null, + previous: null, + last: '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-1&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', + }, data: [ { - date: '2024-04-22', + date: '2024-05-01', values: [ { - date: '2024-04-22', + date: '2024-05-01', data_transfer_in: { value: 3.6801746441, units: 'GB', @@ -41,46 +101,134 @@ export const currentData = { clusters: ['Test OCP on AWS'], source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', region: 'us-east-1', - }, - ], - }, - { - date: '2024-04-23', - values: [ - { - date: '2024-04-23', - data_transfer_in: { - value: 13.6801746441, - units: 'GB', + infrastructure: { + raw: { + value: 1945.51192915, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 1945.5119291598, + units: 'USD', + }, }, - data_transfer_out: { - value: 12.6866746441, - units: 'GB', + supplementary: { + raw: { + value: 0.0, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 0.0, + units: 'USD', + }, + }, + cost: { + raw: { + value: 1945.51192915, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 1945.51192915, + units: 'USD', + }, }, - resource_id: 'i-727f8dc9c567f1552', - clusters: ['Test OCP on AWS'], - source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', - region: 'us-east-1', }, ], }, { - date: '2024-04-24', + date: '2024-05-02', values: [ { - date: '2024-04-24', + date: '2024-05-02', data_transfer_in: { - value: 8.6801746441, + value: 9.1449331092, units: 'GB', }, data_transfer_out: { - value: 7.6866746441, + value: 5.3939814929, units: 'GB', }, resource_id: 'i-727f8dc9c567f1552', clusters: ['Test OCP on AWS'], source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', region: 'us-east-1', + infrastructure: { + raw: { + value: 2918.26789372, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 2918.26789372, + units: 'USD', + }, + }, + supplementary: { + raw: { + value: 0.0, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 0.0, + units: 'USD', + }, + }, + cost: { + raw: { + value: 2918.267893725, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 2918.267893725, + units: 'USD', + }, + }, }, ], }, @@ -89,83 +237,231 @@ export const currentData = { export const previousData = { meta: { - // usual count limit offset currency filter group by order by exclude + count: 2, + limit: 100, + offset: 0, total: { usage: { value: 3.6801746441, units: 'GB', }, data_transfer_in: { - value: 2.789192834, + value: 12.82510775, units: 'GB', }, data_transfer_out: { - value: 0.8909818101, + value: 8.080656137, units: 'GB', }, + infrastructure: { + raw: { + value: 1945.51192915, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 1945.51192915, + units: 'USD', + }, + }, + supplementary: { + raw: { + value: 0.0, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 0.0, + units: 'USD', + }, + }, + cost: { + raw: { + value: 4863.77982288, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 4863.77982288, + units: 'USD', + }, + }, }, - } as any, + }, links: { - // usual links info - } as any, + first: + '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-2&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', + next: null, + previous: null, + last: '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-2&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', + }, data: [ { - date: '2024-04-22', + date: '2024-04-01', values: [ { - date: '2024-04-22', + date: '2024-04-01', data_transfer_in: { - value: 2.6801746441, + value: 3.6801746441, units: 'GB', }, data_transfer_out: { - value: 1.6866746441, + value: 2.6866746441, units: 'GB', }, resource_id: 'i-727f8dc9c567f1552', clusters: ['Test OCP on AWS'], source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', region: 'us-east-1', - }, - ], - }, - { - date: '2024-04-23', - values: [ - { - date: '2024-04-23', - data_transfer_in: { - value: 12.6801746441, - units: 'GB', + infrastructure: { + raw: { + value: 1945.51192915, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 1945.5119291598, + units: 'USD', + }, }, - data_transfer_out: { - value: 10.6866746441, - units: 'GB', + supplementary: { + raw: { + value: 0.0, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 0.0, + units: 'USD', + }, + }, + cost: { + raw: { + value: 1945.51192915, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 1945.51192915, + units: 'USD', + }, }, - resource_id: 'i-727f8dc9c567f1552', - clusters: ['Test OCP on AWS'], - source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', - region: 'us-east-1', }, ], }, { - date: '2024-04-24', + date: '2024-04-02', values: [ { - date: '2024-04-24', + date: '2024-04-02', data_transfer_in: { - value: 10.6801746441, + value: 9.1449331092, units: 'GB', }, data_transfer_out: { - value: 9.6866746441, + value: 5.3939814929, units: 'GB', }, resource_id: 'i-727f8dc9c567f1552', clusters: ['Test OCP on AWS'], source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', region: 'us-east-1', + infrastructure: { + raw: { + value: 2918.26789372, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 2918.26789372, + units: 'USD', + }, + }, + supplementary: { + raw: { + value: 0.0, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 0.0, + units: 'USD', + }, + }, + cost: { + raw: { + value: 2918.267893725, + units: 'USD', + }, + markup: { + value: 0.0, + units: 'USD', + }, + usage: { + value: 0.0, + units: 'USD', + }, + total: { + value: 2918.267893725, + units: 'USD', + }, + }, }, ], }, From 3d06176667bd32324cba4a40e91cf92812451326 Mon Sep 17 00:00:00 2001 From: Luke Couzens Date: Fri, 3 May 2024 16:26:27 +0100 Subject: [PATCH 28/49] adding backstage support --- docs/index.md | 3 +++ mkdocs.yml | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 docs/index.md create mode 100644 mkdocs.yml diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..11c6e4d30 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,3 @@ +# Koku UI Documentation Index # + +Welcome to the Koku UI documentation! \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..3647e9f81 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,4 @@ +docs_dir: docs/ +site_name: Koku UI Documentation +plugins: + - techdocs-core From d2bad1689d7eb3a539b4e700ef9e9bfcc141ed21 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Fri, 3 May 2024 09:47:09 -0400 Subject: [PATCH 29/49] Refactor to support Postman API examples --- locales/data.json | 22 +- locales/translations.json | 3 +- src/api/api.ts | 4 +- src/api/apiDev.ts | 37 ++ src/api/reports/awsReports.ts | 7 + src/api/reports/report.ts | 1 + src/locales/messages.ts | 7 +- .../page/noInstances/noInstancesState.tsx | 4 +- .../details/awsBreakdown/awsBreakdown.tsx | 3 +- .../details/awsBreakdown/instances/data.ts | 444 +++++++++++++++--- .../awsBreakdown/instances/instances.tsx | 56 +-- .../awsBreakdown/instances/instancesTable.tsx | 33 +- .../instances/instancesToolbar.tsx | 3 - .../details/components/tag/modal/tagModal.tsx | 8 +- src/routes/details/components/tag/tagLink.tsx | 8 +- 15 files changed, 500 insertions(+), 140 deletions(-) create mode 100644 src/api/apiDev.ts diff --git a/locales/data.json b/locales/data.json index 4ee07769c..0969a8077 100644 --- a/locales/data.json +++ b/locales/data.json @@ -2908,14 +2908,6 @@ } ] }, - "cpu": { - "value": [ - { - "type": 0, - "value": "CPU" - } - ] - }, "gcp_project": { "value": [ { @@ -3102,6 +3094,14 @@ "value": "Tags" } ] + }, + "vcpu": { + "value": [ + { + "type": 0, + "value": "vCPU" + } + ] } }, "type": 5, @@ -13376,6 +13376,12 @@ "value": "Various" } ], + "vcpuTitle": [ + { + "type": 0, + "value": "vCPU" + } + ], "volumeTitle": [ { "type": 0, diff --git a/locales/translations.json b/locales/translations.json index 5ff1d1f96..b7074b27d 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -231,7 +231,7 @@ "detailsEmptyState": "Processing data to generate a list of all services that sums to a total cost...", "detailsMore": "{value} more...", "detailsMoreClusters": ", {value} more...", - "detailsResourceNames": "{value, select, account {Account names} aws_category {Cost category names} cluster {Cluster names} cpu {CPU} gcp_project {GCP project names} group {Group} instance {Instance names} instance_type {Instance type} memory {Memory} name {Name} node {Node names} org_unit_id {Organizational unit names} os {OS} operating_system {Operating system} payer_tenant_id {Account names} product_service {Service names} project {Project names} region {Region names} resource_location {Region names} service {Service names} service_name {Service names} status {Status} subscription_guid {Account names} source_type {Integration} tag {Tag names} tags {Tags} tag_key {Tag keys} other {}}", + "detailsResourceNames": "{value, select, account {Account names} aws_category {Cost category names} cluster {Cluster names} gcp_project {GCP project names} group {Group} instance {Instance names} instance_type {Instance type} memory {Memory} name {Name} node {Node names} org_unit_id {Organizational unit names} os {OS} operating_system {Operating system} payer_tenant_id {Account names} product_service {Service names} project {Project names} region {Region names} resource_location {Region names} service {Service names} service_name {Service names} status {Status} subscription_guid {Account names} source_type {Integration} tag {Tag names} tags {Tags} tag_key {Tag keys} vcpu {vCPU} other {}}", "detailsSummaryModalTitle": "{groupBy, select, account {{name} accounts} aws_category {{name} cost categories} cluster {{name} clusters} gcp_project {{name} GCP projects} node {{name} nodes} org_unit_id {{name} organizational units} payer_tenant_id {{name} accounts} product_service {{name} services} project {{name} projects} region {{name} regions} resource_location {{name} regions} service {{name} services} service_name {{name} services} subscription_guid {{name} accounts} tag {{name} tags} other {}}", "detailsUnusedCapacityLabel": "Unused capacity", "detailsUnusedRequestsLabel": "Unused requests", @@ -621,6 +621,7 @@ "usageSubtitle": "{value} {units} maximum", "valueUnits": "{value} {units}", "various": "Various", + "vcpuTitle": "vCPU", "volumeTitle": "Volume", "workerUnallocated": "Worker unallocated", "workerUnallocatedDesc": "Distribute unused and non-reserved resource costs to projects", diff --git a/src/api/api.ts b/src/api/api.ts index 003275c2e..703217d77 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -23,11 +23,11 @@ export interface PagedResponse { // axios.interceptors.request.use(authInterceptor); // } -export function authInterceptor(reqConfig: AxiosRequestConfig) { +function authInterceptor(reqConfig: AxiosRequestConfig) { return { ...reqConfig, headers: { - ...reqConfig.headers, + ...(reqConfig?.headers && reqConfig.headers), } as any, }; } diff --git a/src/api/apiDev.ts b/src/api/apiDev.ts new file mode 100644 index 000000000..92e11fe06 --- /dev/null +++ b/src/api/apiDev.ts @@ -0,0 +1,37 @@ +import type { AxiosInstance, AxiosRequestConfig } from 'axios'; +import axios from 'axios'; + +// For use with API development +// +// See https://www.postman.com/devteamkappa/workspace/rh-hccm/example/9135942-f404beb0-47df-4fe1-8ee5-2265ddcabed7 + +function devAuthInterceptor(reqConfig: AxiosRequestConfig) { + const insights = (window as any).insights; + const userToken = insights?.chrome?.auth?.getToken(); + + // For axios mock + if (!userToken?.then) { + return undefined; + } + return userToken.then(token => { + if (!token) { + return reqConfig; + } + return { + ...reqConfig, + headers: { + Accept: 'application/json', // Allow to be overridden + Authorization: `Bearer ${token}`, + ...(reqConfig?.headers && reqConfig.headers), + } as any, + }; + }); +} + +const axiosInstance: AxiosInstance = axios.create({ + baseURL: 'https://de907f1b-995c-4a3b-9c28-6bba63e190b7.mock.pstmn.io/api/cost-management/v1/', +}); + +axiosInstance.interceptors.request.use(devAuthInterceptor); + +export default axiosInstance; diff --git a/src/api/reports/awsReports.ts b/src/api/reports/awsReports.ts index 989f4391e..1fea4d336 100644 --- a/src/api/reports/awsReports.ts +++ b/src/api/reports/awsReports.ts @@ -1,4 +1,5 @@ import { axiosInstance } from 'api'; +import { default as devAxiosInstance } from 'api/apiDev'; import type { Report, ReportData, ReportItem, ReportItemValue, ReportMeta, ReportValue } from './report'; import { ReportType } from './report'; @@ -48,11 +49,17 @@ export const ReportTypePaths: Partial> = { [ReportType.cost]: 'reports/aws/costs/', [ReportType.database]: 'reports/aws/costs/', [ReportType.network]: 'reports/aws/costs/', + [ReportType.ec2Compute]: 'reports/aws/resources/ec2-compute/', [ReportType.storage]: 'reports/aws/storage/', [ReportType.instanceType]: 'reports/aws/instance-types/', }; export function runReport(reportType: ReportType, query: string) { const path = ReportTypePaths[reportType]; + + // For use with API development + if (reportType === ReportType.ec2Compute) { + return devAxiosInstance.get(`${path}?${query}`); + } return axiosInstance.get(`${path}?${query}`); } diff --git a/src/api/reports/report.ts b/src/api/reports/report.ts index 33681a7f7..9506fa601 100644 --- a/src/api/reports/report.ts +++ b/src/api/reports/report.ts @@ -163,6 +163,7 @@ export const enum ReportType { cost = 'cost', cpu = 'cpu', database = 'database', + ec2Compute = 'ec2Compute', instanceType = 'instance_type', memory = 'memory', network = 'network', diff --git a/src/locales/messages.ts b/src/locales/messages.ts index f5c2e8e59..bba7e8001 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -1312,7 +1312,6 @@ export default defineMessages({ 'account {Account names} ' + 'aws_category {Cost category names} ' + 'cluster {Cluster names} ' + - 'cpu {CPU} ' + 'gcp_project {GCP project names} ' + 'group {Group} ' + 'instance {Instance names} ' + @@ -1336,6 +1335,7 @@ export default defineMessages({ 'tag {Tag names} ' + 'tags {Tags} ' + 'tag_key {Tag keys} ' + + 'vcpu {vCPU} ' + 'other {}}', description: 'Details table resource names', id: 'detailsResourceNames', @@ -3806,6 +3806,11 @@ export default defineMessages({ description: 'Various', id: 'various', }, + vcpuTitle: { + defaultMessage: 'vCPU', + description: 'vCPU', + id: 'vcpuTitle', + }, volumeTitle: { defaultMessage: 'Volume', description: 'Volume', diff --git a/src/routes/components/page/noInstances/noInstancesState.tsx b/src/routes/components/page/noInstances/noInstancesState.tsx index 6847938ee..4a242d7b3 100644 --- a/src/routes/components/page/noInstances/noInstancesState.tsx +++ b/src/routes/components/page/noInstances/noInstancesState.tsx @@ -5,7 +5,7 @@ import { EmptyStateIcon, EmptyStateVariant, } from '@patternfly/react-core'; -import { MinusIcon } from '@patternfly/react-icons/dist/esm/icons/minus-icon'; +import { PlusCircleIcon } from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon'; import messages from 'locales/messages'; import React from 'react'; import type { WrappedComponentProps } from 'react-intl'; @@ -25,7 +25,7 @@ class NoInstancesStateBase extends React.Component { } + icon={} headingLevel="h1" /> {intl.formatMessage(messages.noInstancesDesc)} diff --git a/src/routes/details/awsBreakdown/awsBreakdown.tsx b/src/routes/details/awsBreakdown/awsBreakdown.tsx index 047fc9f59..847aa9e6e 100644 --- a/src/routes/details/awsBreakdown/awsBreakdown.tsx +++ b/src/routes/details/awsBreakdown/awsBreakdown.tsx @@ -122,7 +122,8 @@ const mapStateToProps = createMapStateToProps, - instancesComponent: groupBy === serviceKey ? : undefined, + instancesComponent: + groupBy === serviceKey && groupByValue === 'AmazonEC2' ? : undefined, isAwsEc2InstancesToggleEnabled: FeatureToggleSelectors.selectIsAwsEc2InstancesToggleEnabled(state), providers: filterProviders(providers, ProviderType.aws), providersError, diff --git a/src/routes/details/awsBreakdown/instances/data.ts b/src/routes/details/awsBreakdown/instances/data.ts index 2687d0cf2..9fb3f01f6 100644 --- a/src/routes/details/awsBreakdown/instances/data.ts +++ b/src/routes/details/awsBreakdown/instances/data.ts @@ -4,95 +4,423 @@ export const data = { meta: { - count: 2, - } as any, + count: 8, + limit: 10, + offset: 0, + currency: 'USD', + cost_type: 'unblended_cost', + filter: { + resolution: 'monthly', + time_scope_value: '-1', + time_scope_units: 'month', + }, + order_by: {}, + exclude: {}, + total: { + usage: { + value: 1215, + units: 'Hrs', + }, + cost: { + raw: { + value: 125, + units: 'USD', + }, + markup: { + value: 0, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 896, + units: 'USD', + }, + }, + }, + }, links: { - // usual links info - } as any, + first: '/api/v1/aws/resources/ec2-compute?limit=10&offset=0', + next: null, + previous: null, + last: '/api/v1/aws/resources/ec2-compute?limit=10&offset=50', + }, data: [ { date: '2024-04', resource_ids: [ { - account: 'example_account', - account_alias: 'Example Account', - // cost: 50.0, - // currency: 'USD', - cost: { - value: 50.0, - units: 'USD', + resource_id: 'i-456abc', + account: '9999999999991', + account_alias: 'account 001', + instance_name: 'prod-inst', + region: 'us-east-1', + operating_system: 'Windows Server', + instance_type: 't2.large', + vcpu: 4, + memory: '32 GiB', + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], + }, + ], + usage: { + value: 120, + units: 'Hrs', }, - instance_name: 'example-instance-1', - instance_type: 't2.micro', - // memory: 1, - memory: { - value: 8, - units: 'gib_hours', + cost: { + raw: { + value: 75, + units: 'USD', + }, + markup: { + value: 0, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 75, + units: 'USD', + }, }, - operating_system: 'Linux', + }, + { + resource_id: 'i-123xyz', + account: '9999999999993', + account_alias: 'account 003', + instance_name: 'dev-inst', region: 'us-west-2', - resource_id: 'i-1234567890abcdef0', - // tags: { - // Environment: 'Production', - // Project: 'XYZ Project', - // }, + operating_system: 'Ubuntu', + instance_type: 't2.micro', + vcpu: 3, + memory: '16 GiB', tags: [ { key: 'app', values: ['Antennae', 'master', 'season'], - enabled: true, + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], }, ], - // unit: 'Hrs', - // usage_amount: 100, usage: { value: 100, units: 'Hrs', }, - vcpu: { - value: 1, - units: 'core_hours', + cost: { + raw: { + value: 50, + units: 'USD', + }, + markup: { + value: 0, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 50, + units: 'USD', + }, }, }, { - // cost: 150.0, - // currency: 'USD', + resource_id: 'i-789def', + account: '9999999999992', + instance_name: 'test-inst', + region: 'eu-central-1', + operating_system: 'Red Hat Enterprise Linux', + instance_type: 'm5.xlarge', + vcpu: 8, + memory: '64 GiB', + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], + }, + ], + usage: { + value: 150, + units: 'Hrs', + }, cost: { - value: 100.0, - units: 'USD', - }, - account: 'another_account', - account_alias: 'Another Account', - instance_name: 'example-instance-2', - instance_type: 'm5.large', - // memory: 8, - memory: { - value: 8, - units: 'gib_hours', - }, - operating_system: 'Windows', - region: 'us-east-1', - resource_id: 'i-0987654321fedcba0', - // tags: { - // Environment: 'Development', - // Project: 'ABC Project', - // }, + raw: { + value: 100, + units: 'USD', + }, + markup: { + value: 10, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 110, + units: 'USD', + }, + }, + }, + { + resource_id: 'i-987xyz', + account: '9999999999994', + instance_name: 'stage-inst', + region: 'ap-southeast-1', + operating_system: 'Amazon Linux', + instance_type: 'c5.2xlarge', + vcpu: 16, + memory: '48 GiB', tags: [ { - key: 'version', - values: ['Antennae', 'master', 'orange'], - enabled: true, + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], }, ], - // unit: 'Hrs', - // usage_hours: 200, usage: { value: 200, units: 'Hrs', }, - vcpu: { - value: 2, - units: 'core_hours', + cost: { + raw: { + value: 150, + units: 'USD', + }, + markup: { + value: 15, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 165, + units: 'USD', + }, + }, + }, + { + resource_id: 'i-0ab1cd2e', + account: '9999999999995', + account_alias: null, + instance_name: 'batch-proc', + region: 'us-east-1', + operating_system: 'CentOS', + instance_type: 'r4.large', + vcpu: 4, + memory: '30 GiB', + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], + }, + ], + usage: { + value: 90, + units: 'Hrs', + }, + cost: { + raw: { + value: 60, + units: 'USD', + }, + markup: { + value: 0, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 60, + units: 'USD', + }, + }, + }, + { + resource_id: 'i-1cd2eab3', + account: '9999999999996', + account_alias: null, + instance_name: 'data-analysis', + region: 'us-west-2', + operating_system: 'Oracle Linux', + instance_type: 't3.medium', + vcpu: 2, + memory: '8 GiB', + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], + }, + ], + usage: { + value: 75, + units: 'Hrs', + }, + cost: { + raw: { + value: 40, + units: 'USD', + }, + markup: { + value: 0, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 40, + units: 'USD', + }, + }, + }, + { + resource_id: 'i-2eab31cd', + account: '9999999999997', + instance_name: 'web-server', + region: 'eu-central-1', + operating_system: 'Debian', + instance_type: 'm5.2xlarge', + vcpu: 8, + memory: '64 GiB', + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['prod-inst'], + }, + { + key: 'environment', + values: ['Prod'], + }, + ], + usage: { + value: 300, + units: 'Hrs', + }, + cost: { + raw: { + value: 250, + units: 'USD', + }, + markup: { + value: 25, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 275, + units: 'USD', + }, + }, + }, + { + resource_id: 'i-3ab1cd2e', + account: '9999999999998', + instance_name: 'mobile-api', + region: 'ap-northeast-1', + operating_system: 'Fedora', + instance_type: 'c5.large', + vcpu: 2, + memory: '16 GiB', + tags: [ + { + key: 'app', + values: ['Antennae', 'master', 'season'], + }, + { + key: 'Name', + values: ['mobile-api'], + }, + { + key: 'environment', + values: ['Dev'], + }, + ], + usage: { + value: 180, + units: 'Hrs', + }, + cost: { + raw: { + value: 110, + units: 'USD', + }, + markup: { + value: 11, + units: 'USD', + }, + usage: { + value: 0, + units: 'USD', + }, + total: { + value: 121, + units: 'USD', + }, }, }, ], diff --git a/src/routes/details/awsBreakdown/instances/instances.tsx b/src/routes/details/awsBreakdown/instances/instances.tsx index ed76c1d58..f81a14e2b 100644 --- a/src/routes/details/awsBreakdown/instances/instances.tsx +++ b/src/routes/details/awsBreakdown/instances/instances.tsx @@ -20,7 +20,7 @@ import { ColumnManagementModal, initHiddenColumns } from 'routes/details/compone import { styles } from 'routes/optimizations/optimizationsBreakdown/optimizationsBreakdown.styles'; import type { ComputedReportItem } from 'routes/utils/computedReport/getComputedReportItems'; import { getUnsortedComputedReportItems } from 'routes/utils/computedReport/getComputedReportItems'; -import { getFilterByTagKey, getGroupById, getGroupByOrgValue, getGroupByValue } from 'routes/utils/groupBy'; +import { getFilterByTagKey } from 'routes/utils/groupBy'; import * as queryUtils from 'routes/utils/query'; import type { RootState } from 'store'; import { FetchStatus } from 'store/common'; @@ -28,17 +28,15 @@ import { reportActions, reportSelectors } from 'store/reports'; import { useQueryFromRoute, useQueryState } from 'utils/hooks'; import { accountKey, logicalAndPrefix, logicalOrPrefix, orgUnitIdKey, regionKey } from 'utils/props'; -import { data } from './data'; +// import { data } from './data'; import { InstancesTable, InstanceTableColumnIds } from './instancesTable'; import { InstancesToolbar } from './instancesToolbar'; interface InstancesOwnProps { - costType?: string; currency?: string; } export interface InstancesStateProps { - groupBy: string; hasAccountFilter: boolean; hasRegionFilter: boolean; hasTagFilter: boolean; @@ -66,8 +64,8 @@ const baseQuery: Query = { const defaultColumnOptions: ColumnManagementModalOption[] = [ { - label: messages.cpuTitle, - value: InstanceTableColumnIds.cpu, + label: messages.vcpuTitle, + value: InstanceTableColumnIds.vcpu, hidden: true, }, { @@ -77,10 +75,10 @@ const defaultColumnOptions: ColumnManagementModalOption[] = [ }, ]; -const reportType = ReportType.cost as any; -const reportPathsType = ReportPathsType.aws as any; +const reportType = ReportType.ec2Compute; +const reportPathsType = ReportPathsType.aws; -const Instances: React.FC = ({ costType, currency }) => { +const Instances: React.FC = ({ currency }) => { const intl = useIntl(); const [hiddenColumns, setHiddenColumns] = useState(initHiddenColumns(defaultColumnOptions)); @@ -90,20 +88,11 @@ const Instances: React.FC = ({ costType, currency }) => { const [selectedItems, setSelectedItems] = useState([]); const [query, setQuery] = useState({ ...baseQuery }); - const { - groupBy, - hasAccountFilter, - hasRegionFilter, - hasTagFilter, - report, - reportError, - reportFetchStatus, - reportQueryString, - } = useMapToProps({ - costType, - currency, - query, - }); + const { hasAccountFilter, hasRegionFilter, hasTagFilter, report, reportError, reportFetchStatus, reportQueryString } = + useMapToProps({ + currency, + query, + }); const getColumnManagementModal = () => { const options = cloneDeep(defaultColumnOptions); @@ -137,11 +126,12 @@ const Instances: React.FC = ({ costType, currency }) => { selectedItems.map(item => { items.push(item); }); + // Todo: May need to adjust "instance" for group_by? return ( 0} - groupBy={groupBy} + groupBy="instance" isOpen={isExportModalOpen} items={items} onClose={handleOnExportModalClose} @@ -204,7 +194,6 @@ const Instances: React.FC = ({ costType, currency }) => { return ( = ({ costType, currency }) => { }; // eslint-disable-next-line no-empty-pattern -const useMapToProps = ({ costType, currency, query }): InstancesStateProps => { +const useMapToProps = ({ currency, query }): InstancesStateProps => { const dispatch: ThunkDispatch = useDispatch(); const queryFromRoute = useQueryFromRoute(); const queryState = useQueryState('details'); - const groupByOrgValue = getGroupByOrgValue(queryFromRoute); - const groupBy = groupByOrgValue ? orgUnitIdKey : getGroupById(queryFromRoute); - const groupByValue = groupByOrgValue ? groupByOrgValue : getGroupByValue(queryFromRoute); - const reportQuery = { - cost_type: costType, currency, filter: { ...(query.filter || baseQuery.filter), @@ -356,8 +340,6 @@ const useMapToProps = ({ costType, currency, query }): InstancesStateProps => { // Add filters here to apply logical OR/AND ...(queryState?.filter_by && queryState.filter_by), ...(queryFromRoute?.filter?.account && { [`${logicalAndPrefix}account`]: queryFromRoute.filter.account }), - // Omit filters associated with the current group_by -- see https://issues.redhat.com/browse/COST-1131 and https://issues.redhat.com/browse/COST-3642 - ...(groupBy && groupBy !== orgUnitIdKey && groupByValue !== '*' && { [groupBy]: undefined }), // Workaround for https://issues.redhat.com/browse/COST-1189 ...(queryState?.filter_by && queryState.filter_by[orgUnitIdKey] && { @@ -370,13 +352,10 @@ const useMapToProps = ({ costType, currency, query }): InstancesStateProps => { ...(queryState?.exclude && queryState.exclude), ...(query.exclude && query.exclude), }, - group_by: { - ...(groupBy && { [groupBy]: groupByValue }), - }, order_by: query.order_by || baseQuery.order_by, }; const reportQueryString = getQuery(reportQuery); - let report = useSelector((state: RootState) => + const report = useSelector((state: RootState) => reportSelectors.selectReport(state, reportPathsType, reportType, reportQueryString) ); const reportFetchStatus = useSelector((state: RootState) => @@ -393,10 +372,9 @@ const useMapToProps = ({ costType, currency, query }): InstancesStateProps => { }, [currency, query]); // Todo: Update to use new API response - report = data; + // report = data; return { - groupBy, hasAccountFilter: queryState?.filter_by?.[accountKey] !== undefined, hasRegionFilter: queryState?.filter_by?.[regionKey] !== undefined, hasTagFilter: getFilterByTagKey(queryState) !== undefined, diff --git a/src/routes/details/awsBreakdown/instances/instancesTable.tsx b/src/routes/details/awsBreakdown/instances/instancesTable.tsx index 37544fc73..5c16e1382 100644 --- a/src/routes/details/awsBreakdown/instances/instancesTable.tsx +++ b/src/routes/details/awsBreakdown/instances/instancesTable.tsx @@ -13,7 +13,7 @@ import { Actions } from 'routes/details/components/actions'; import { TagLink } from 'routes/details/components/tag'; import type { ComputedReportItem } from 'routes/utils/computedReport/getComputedReportItems'; import { getUnsortedComputedReportItems } from 'routes/utils/computedReport/getComputedReportItems'; -import { formatCurrency, unitsLookupKey } from 'utils/format'; +import { formatCurrency } from 'utils/format'; interface InstancesTableOwnProps { filterBy?: any; @@ -33,8 +33,8 @@ interface InstancesTableOwnProps { type InstancesTableProps = InstancesTableOwnProps; export const InstanceTableColumnIds = { - cpu: 'cpu', memory: 'memory', + vcpu: 'vcpu', }; const InstancesTable: React.FC = ({ @@ -96,8 +96,8 @@ const InstancesTable: React.FC = ({ ...(computedItems.length && { isSortable: true }), }, { - id: InstanceTableColumnIds.cpu, - name: intl.formatMessage(messages.detailsResourceNames, { value: 'cpu' }), + id: InstanceTableColumnIds.vcpu, + name: intl.formatMessage(messages.detailsResourceNames, { value: 'vcpu' }), style: styles.managedColumn, }, { @@ -144,20 +144,16 @@ const InstancesTable: React.FC = ({ { value: item.instance_type ? item.instance_type : null }, { value: item.region ? item.region : null }, { - value: intl.formatMessage(messages.valueUnits, { - value: item.vcpu ? item.vcpu.value : '', - units: item.vcpu ? intl.formatMessage(messages.units, { units: unitsLookupKey(item.vcpu.units) }) : null, - }), - id: InstanceTableColumnIds.cpu, + value: item.vcpu ? item.vcpu : '', + // value: intl.formatMessage(messages.valueUnits, { + // value: item.vcpu ? item.vcpu.value : '', + // units: item.vcpu ? intl.formatMessage(messages.units, { units: unitsLookupKey(item.vcpu.units) }) : null, + // }), + id: InstanceTableColumnIds.vcpu, style: styles.managedColumn, }, { - value: intl.formatMessage(messages.valueUnits, { - value: item.memory ? item.memory.value : '', - units: item.memory - ? intl.formatMessage(messages.units, { units: unitsLookupKey(item.memory.units) }) - : null, - }), + value: item.memory ? item.memory : '', // Not translatable id: InstanceTableColumnIds.memory, style: styles.managedColumn, }, @@ -193,10 +189,9 @@ const InstancesTable: React.FC = ({ }; const getTotalCost = (item: ComputedReportItem, index: number) => { - // Todo: add cost types to report - const cost = (report?.meta?.total?.cost as any)?.value || 0; - const value = (item.cost as any)?.value || 0; - const units = (item.cost as any)?.units || 'USD'; + const cost = report?.meta?.total?.cost?.total ? report.meta.total.cost.total.value : 0; + const value = item.cost?.total?.value || 0; + const units = item.cost?.total?.units || 'USD'; const percentValue = cost === 0 ? cost.toFixed(2) : ((value / cost) * 100).toFixed(2); return ( <> diff --git a/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx b/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx index 06021054d..28acc207c 100644 --- a/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx +++ b/src/routes/details/awsBreakdown/instances/instancesToolbar.tsx @@ -29,7 +29,6 @@ interface InstancesToolbarOwnProps { items?: ComputedReportItem[]; itemsPerPage?: number; itemsTotal?: number; - groupBy: string; onBulkSelect(action: string); onColumnManagementClicked(); onExportClicked(); @@ -127,7 +126,6 @@ export class InstancesToolbarBase extends React.Component { if (tagData || tagReport) { const tags = tagData || tagReport.data; - for (const item of tags) { - if (item.values) { - count += item.values.length; + if (tags instanceof Array) { + for (const item of tags) { + if (item.values) { + count += item.values.length; + } } } } diff --git a/src/routes/details/components/tag/tagLink.tsx b/src/routes/details/components/tag/tagLink.tsx index ac4599043..6f2c477ae 100644 --- a/src/routes/details/components/tag/tagLink.tsx +++ b/src/routes/details/components/tag/tagLink.tsx @@ -86,9 +86,11 @@ class TagLinkBase extends React.Component { let count = 0; if (tagData || tagReport) { const tags = tagData || tagReport.data; - for (const item of tags) { - if (item.values) { - count += item.values.length; + if (tags instanceof Array) { + for (const item of tags) { + if (item.values) { + count += item.values.length; + } } } } From e6af90d50f5a3e7049bec2ff60fb317b2e57702b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 10:59:53 +0000 Subject: [PATCH 30/49] (chore): Bump the lint-dependencies group with 2 updates Bumps the lint-dependencies group with 2 updates: [eslint-plugin-formatjs](https://github.com/formatjs/formatjs) and [eslint-plugin-markdown](https://github.com/eslint/eslint-plugin-markdown). Updates `eslint-plugin-formatjs` from 4.13.0 to 4.13.1 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/eslint-plugin-formatjs@4.13.0...eslint-plugin-formatjs@4.13.1) Updates `eslint-plugin-markdown` from 4.0.1 to 5.0.0 - [Release notes](https://github.com/eslint/eslint-plugin-markdown/releases) - [Changelog](https://github.com/eslint/eslint-plugin-markdown/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint-plugin-markdown/compare/v4.0.1...v5.0.0) --- updated-dependencies: - dependency-name: eslint-plugin-formatjs dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies - dependency-name: eslint-plugin-markdown dependency-type: direct:development update-type: version-update:semver-major dependency-group: lint-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 512d863e0..7a9b93a44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,10 +63,10 @@ "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", - "eslint-plugin-formatjs": "^4.13.0", + "eslint-plugin-formatjs": "^4.13.1", "eslint-plugin-jest-dom": "^5.4.0", "eslint-plugin-jsdoc": "^48.2.3", - "eslint-plugin-markdown": "^4.0.1", + "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-react": "^7.34.1", @@ -9020,9 +9020,9 @@ } }, "node_modules/eslint-plugin-formatjs": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.13.0.tgz", - "integrity": "sha512-sxgHQNyVclNRO7aydGwxohwxYR03/oRDW0uUXFWayNMPTlnb9sET3LCovBjvQF7qAHDGFDcLwg4ECSyui4nG8A==", + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.13.1.tgz", + "integrity": "sha512-QYXgrBYLwEcqN4Vvis18es1JFAY+6YAkjpyNmTZzAMpithZm9U7z6eWUD4gqFainWlk8cFKvkOOvSyQ4/LUgVA==", "dev": true, "dependencies": { "@formatjs/icu-messageformat-parser": "2.7.6", @@ -9590,9 +9590,9 @@ } }, "node_modules/eslint-plugin-markdown": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-4.0.1.tgz", - "integrity": "sha512-5/MnGvYU0i8MbHH5cg8S+Vl3DL+bqRNYshk1xUO86DilNBaxtTkhH+5FD0/yO03AmlI6+lfNFdk2yOw72EPzpA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-5.0.0.tgz", + "integrity": "sha512-kY2u9yDhzvfZ0kmRTsvgm3mTnvZgTSGIIPeHg3yesSx4R5CTCnITUjCPhzCD1MUhNcqHU5Tr6lzx+02EclVPbw==", "dev": true, "dependencies": { "mdast-util-from-markdown": "^0.8.5" diff --git a/package.json b/package.json index 3fcde4eba..2601043d5 100644 --- a/package.json +++ b/package.json @@ -103,10 +103,10 @@ "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", - "eslint-plugin-formatjs": "^4.13.0", + "eslint-plugin-formatjs": "^4.13.1", "eslint-plugin-jest-dom": "^5.4.0", "eslint-plugin-jsdoc": "^48.2.3", - "eslint-plugin-markdown": "^4.0.1", + "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-react": "^7.34.1", From ce403a08496e41b36cae2c65d6756a675f9f765c Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Mon, 6 May 2024 09:05:42 -0400 Subject: [PATCH 31/49] Dependency updates --- package-lock.json | 190 +++++++++++++++++++++++++++------------------- package.json | 28 +++---- 2 files changed, 124 insertions(+), 94 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a9b93a44..33ffde5df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,18 +10,18 @@ "hasInstallScript": true, "license": "GNU AGPLv3", "dependencies": { - "@patternfly/patternfly": "5.3.0", + "@patternfly/patternfly": "5.3.1", "@patternfly/react-charts": "7.3.0", "@patternfly/react-component-groups": "^5.1.0", - "@patternfly/react-core": "5.3.0", - "@patternfly/react-icons": "5.3.0", - "@patternfly/react-table": "5.3.0", - "@patternfly/react-tokens": "5.3.0", - "@redhat-cloud-services/frontend-components": "^4.2.7", + "@patternfly/react-core": "5.3.3", + "@patternfly/react-icons": "5.3.2", + "@patternfly/react-table": "5.3.3", + "@patternfly/react-tokens": "5.3.1", + "@redhat-cloud-services/frontend-components": "^4.2.8", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", - "@redhat-cloud-services/rbac-client": "^1.4.0", + "@redhat-cloud-services/rbac-client": "^1.4.2", "@reduxjs/toolkit": "^2.2.3", "@unleash/proxy-client-react": "^4.2.2", "axios": "^1.6.8", @@ -31,8 +31,8 @@ "qs": "^6.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-intl": "^6.6.5", - "react-redux": "^9.1.1", + "react-intl": "^6.6.6", + "react-redux": "^9.1.2", "react-router-dom": "^6.23.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", @@ -41,16 +41,16 @@ "victory-core": "^37.0.2" }, "devDependencies": { - "@formatjs/cli": "^6.2.9", + "@formatjs/cli": "^6.2.10", "@formatjs/ecma402-abstract": "^1.18.2", "@formatjs/icu-messageformat-parser": "^2.7.6", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", - "@redhat-cloud-services/frontend-components-config": "^6.0.12", - "@redhat-cloud-services/tsc-transform-imports": "^1.0.9", + "@redhat-cloud-services/frontend-components-config": "^6.0.13", + "@redhat-cloud-services/tsc-transform-imports": "^1.0.10", "@swc/core": "^1.4.17", "@swc/jest": "^0.2.36", - "@testing-library/jest-dom": "^6.4.2", - "@testing-library/react": "^15.0.5", + "@testing-library/jest-dom": "^6.4.5", + "@testing-library/react": "^15.0.6", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", @@ -877,9 +877,9 @@ } }, "node_modules/@formatjs/cli": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.2.9.tgz", - "integrity": "sha512-YH09kY6oufPdNDIwva/rC7wyg/ptJG6hRZ768eJEafiBR5R1VV1pKFmx106FV5WT7nzBm8Xf4Td+8+Mu+DtQsg==", + "version": "6.2.10", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.2.10.tgz", + "integrity": "sha512-JdFw5oqPNB4qahie2Mcg6yXxyUJouN60OaEaejjMtGsgoPbFjS7X/9/Nj5vW+rAUTi0UNbOW+JPW9XNx6EuoHw==", "dev": true, "bin": { "formatjs": "bin/formatjs" @@ -888,9 +888,37 @@ "node": ">= 16" }, "peerDependencies": { + "@glimmer/env": "^0.1.7", + "@glimmer/reference": "^0.91.1", + "@glimmer/syntax": "^0.91.1", + "@glimmer/validator": "^0.91.1", + "@vue/compiler-core": "^3.4.0", + "content-tag": "^2.0.1", + "ember-template-recast": "^6.1.4", "vue": "^3.4.0" }, "peerDependenciesMeta": { + "@glimmer/env": { + "optional": true + }, + "@glimmer/reference": { + "optional": true + }, + "@glimmer/syntax": { + "optional": true + }, + "@glimmer/validator": { + "optional": true + }, + "@vue/compiler-core": { + "optional": true + }, + "content-tag": { + "optional": true + }, + "ember-template-recast": { + "optional": true + }, "vue": { "optional": true } @@ -933,16 +961,16 @@ } }, "node_modules/@formatjs/intl": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.1.tgz", - "integrity": "sha512-dsLG15U7xDi8yzKf4hcAWSsCaez3XrjTO2oaRHPyHtXLm1aEzYbDw6bClo/HMHu+iwS5GbDqT3DV+hYP2ylScg==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.2.tgz", + "integrity": "sha512-raPGWr3JRv3neXV78SqPFrGC05fIbhhNzVghHNxFde27ls2KkXiMhtP7HBybjGpikVSjjhdhaZto+4p1vmm9bQ==", "dependencies": { "@formatjs/ecma402-abstract": "1.18.2", "@formatjs/fast-memoize": "2.2.0", "@formatjs/icu-messageformat-parser": "2.7.6", "@formatjs/intl-displaynames": "6.6.6", "@formatjs/intl-listformat": "7.5.5", - "intl-messageformat": "10.5.11", + "intl-messageformat": "10.5.12", "tslib": "^2.4.0" }, "peerDependencies": { @@ -2215,9 +2243,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@patternfly/patternfly": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.3.0.tgz", - "integrity": "sha512-93uWA15bOJDgu8NF2iReWbbNtWdtM+v7iaDpK33mJChgej+whiFpGLtQPI2jFk1aVW3rDpbt4qm4OaNinpzSsg==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.3.1.tgz", + "integrity": "sha512-KYIr9pKRTzHZNGuDuaa5j5CaZyLltvotPFGG1BiJalBDBGSOyk0BZCgHLowm4txKZXrLhorEuuv9XLrMQL8eoA==" }, "node_modules/@patternfly/react-charts": { "version": "7.3.0", @@ -2282,13 +2310,13 @@ } }, "node_modules/@patternfly/react-core": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.3.0.tgz", - "integrity": "sha512-nMf8yrul3u+4+ch7IMsE+/3Rzmor8/yEUk8zzD9bYGRxjwniu1RqCF8NdgPvMw2C7Hz7xtpwsgXDfG4n8qd12g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.3.3.tgz", + "integrity": "sha512-qq3j0M+Vi+Xmd+a/MhRhGgjdRh9Hnm79iA+L935HwMIVDcIWRYp6Isib/Ha4+Jk+f3Qdl0RT3dBDvr/4m6OpVQ==", "dependencies": { - "@patternfly/react-icons": "^5.3.0", - "@patternfly/react-styles": "^5.3.0", - "@patternfly/react-tokens": "^5.3.0", + "@patternfly/react-icons": "^5.3.2", + "@patternfly/react-styles": "^5.3.1", + "@patternfly/react-tokens": "^5.3.1", "focus-trap": "7.5.2", "react-dropzone": "^14.2.3", "tslib": "^2.5.0" @@ -2299,28 +2327,28 @@ } }, "node_modules/@patternfly/react-icons": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-oBdaK4Gz7yivNE7jQg46sPzfZakg7oxo5aSMLc0N6haOmDEegiTurNex+h+/z0oBPqzZC+cIQRaBeXEgXGwc9Q==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.3.2.tgz", + "integrity": "sha512-GEygYbl0H4zD8nZuTQy2dayKIrV2bMMeWKSOEZ16Y3EYNgYVUOUnN+J0naAEuEGH39Xb1DE9n+XUbE1PC4CxPA==", "peerDependencies": { "react": "^17 || ^18", "react-dom": "^17 || ^18" } }, "node_modules/@patternfly/react-styles": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.3.0.tgz", - "integrity": "sha512-/EdkURW+v7Rzw/CiEqL+NfGtLvLMGIwOEyDhvlMDbRip2usGw4HLZv3Bep0cJe29zOeY27cDVZDM1HfyXLebtw==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.3.1.tgz", + "integrity": "sha512-H6uBoFH3bJjD6PP75qZ4k+2TtF59vxf9sIVerPpwrGJcRgBZbvbMZCniSC3+S2LQ8DgXLnDvieq78jJzHz0hiA==" }, "node_modules/@patternfly/react-table": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.3.0.tgz", - "integrity": "sha512-DuylKyUA/D6Jzk7t6VU8SzbABjaKra2+O4G99Zt7EyEuhcDP3dfb+AcL5yg7CLx4/v2fexzum+dLGZVMvqzSUQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.3.3.tgz", + "integrity": "sha512-uaRmsJABvVPH8gYTh+EUcDz61knIxe9qor/VGUYDLONYBL5G3IaltwG42IsJ9jShxiwFmIPy+QARPpaadTpv5w==", "dependencies": { - "@patternfly/react-core": "^5.3.0", - "@patternfly/react-icons": "^5.3.0", - "@patternfly/react-styles": "^5.3.0", - "@patternfly/react-tokens": "^5.3.0", + "@patternfly/react-core": "^5.3.3", + "@patternfly/react-icons": "^5.3.2", + "@patternfly/react-styles": "^5.3.1", + "@patternfly/react-tokens": "^5.3.1", "lodash": "^4.17.19", "tslib": "^2.5.0" }, @@ -2330,9 +2358,9 @@ } }, "node_modules/@patternfly/react-tokens": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.3.0.tgz", - "integrity": "sha512-24ZY5hgwt11InW3XtINM5p9Fo1hDiVor6Q4uphPZh8Mt89AsZZw1UweTaGg54I0Ah2Wzv6rkQy51LX7tZtIwjQ==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.3.1.tgz", + "integrity": "sha512-VYK0uVP2/2RJ7ZshJCCLeq0Boih5I1bv+9Z/Bg6h12dCkLs85XsxAX9Ve+BGIo5DF54/mzcRHE1RKYap4ISXuw==" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -2467,9 +2495,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.7.tgz", - "integrity": "sha512-HHxkSep0HvkfZSD1ZvfzCVuw6u6rXPsznTyvkHIRJfeaoF5WkMCvGSw0+mwGA94tCj5jKkXgUjRSHAp94PFUfw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.8.tgz", + "integrity": "sha512-h9Zdl8JfS0X4EpUORAue6SR50M8xX0LOKMdnp7L9S34qix47YaJ+SydqloHQkmLhGicv6ZmI6ttbbDbEv0guLA==", "dependencies": { "@patternfly/react-component-groups": "^5.0.0", "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", @@ -2493,9 +2521,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components-config": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config/-/frontend-components-config-6.0.12.tgz", - "integrity": "sha512-KVFHCMwnzqv23KA27sLRsEexL0rxmiY3BRH5zPli2WpywYbE6iNLTjJrHnE+xogaHIRtW2wx3CgOLd+JMvnlFQ==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config/-/frontend-components-config-6.0.13.tgz", + "integrity": "sha512-fABmXUguiFAZp3DCun2cE1wpDaK1ZTYGVCs9f7fg0FB0rENaPK3B7twviLON3Y4OdOX9dHg/e7LYzNrbvH04MQ==", "dev": true, "dependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.8", @@ -2946,9 +2974,9 @@ } }, "node_modules/@redhat-cloud-services/rbac-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.0.tgz", - "integrity": "sha512-gFwvrOi0MDYbRYwC5TZ4zff4QO/Ss0T+LngWiEYD5duNAEWfbNQft4i/RjvJwEVJ14lxz1xGiHU6WRHms7GeBQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.2.tgz", + "integrity": "sha512-5IIAEt/t17JMwDSiXxGvvm0s5T/Vy2EvxZcwdUTCmOM/8w/FMb47GP+ABF5ygVWJSA7u+vEySvEW/Ay9Oow+tA==", "dependencies": { "axios": "^0.27.2", "tslib": "^2.6.2" @@ -2964,9 +2992,9 @@ } }, "node_modules/@redhat-cloud-services/tsc-transform-imports": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/tsc-transform-imports/-/tsc-transform-imports-1.0.9.tgz", - "integrity": "sha512-dodQMeAzeybaam5BlijrXuUA1Ycfy76MUGM+oVn5UUsO1Y2fkMfbuYMkYuOQznQ0N/NHJqCs9Q3nc77bo8KSlQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/tsc-transform-imports/-/tsc-transform-imports-1.0.10.tgz", + "integrity": "sha512-IzZsgGrpE3XaGk7UBVryjUftL/Pd2FKsjf92MhzD6z7FnvtKiQsx7CnLBi6wcaAAT1VWi5HuWIIziS6wVmLGbQ==", "dev": true, "dependencies": { "glob": "10.3.3" @@ -3519,9 +3547,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", - "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.5.tgz", + "integrity": "sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==", "dev": true, "dependencies": { "@adobe/css-tools": "^4.3.2", @@ -3530,7 +3558,7 @@ "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.15", + "lodash": "^4.17.21", "redent": "^3.0.0" }, "engines": { @@ -3637,9 +3665,9 @@ } }, "node_modules/@testing-library/react": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.5.tgz", - "integrity": "sha512-ttodVWYA2i2w4hRa6krKrmS1vKxAEkwDz34y+CwbcrbZUxFzUYN3a5xZyFKo+K6LBseCRCUkwcjATpaNn/UsIA==", + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.6.tgz", + "integrity": "sha512-UlbazRtEpQClFOiYp+1BapMT+xyqWMnE+hh9tn5DQ6gmlE7AIZWcGpzZukmDZuFk3By01oiqOf8lRedLS4k6xQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", @@ -3650,8 +3678,14 @@ "node": ">=18" }, "peerDependencies": { + "@types/react": "^18.0.0", "react": "^18.0.0", "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@testing-library/react/node_modules/@testing-library/dom": { @@ -12446,9 +12480,9 @@ } }, "node_modules/intl-messageformat": { - "version": "10.5.11", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz", - "integrity": "sha512-eYq5fkFBVxc7GIFDzpFQkDOZgNayNTQn4Oufe8jw6YY6OHVw70/4pA3FyCsQ0Gb2DnvEJEMmN2tOaXUGByM+kg==", + "version": "10.5.12", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.12.tgz", + "integrity": "sha512-izl0uxhy/melhw8gP2r8pGiVieviZmM4v5Oqx3c1/R7g9cwER2smmGfSjcIsp8Y3Q53bfciL/gkxacJRx/dUvg==", "dependencies": { "@formatjs/ecma402-abstract": "1.18.2", "@formatjs/fast-memoize": "2.2.0", @@ -18116,19 +18150,19 @@ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-intl": { - "version": "6.6.5", - "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.5.tgz", - "integrity": "sha512-OErDPbGqus0QKVj77MGCC9Plbnys3CDQrq6Lw41c60pmeTdn41AhoS1SIzXG6SUlyF7qNN2AVqfrrIvHUgSyLQ==", + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.6.tgz", + "integrity": "sha512-dKXQNUrhZTlCp8uelYW8PHiM4saNKyLmHCfsJYWK0N/kZ/Ien35wjPHB8x9yQcTJbeN/hBOmb4x16iKUrdL9MA==", "dependencies": { "@formatjs/ecma402-abstract": "1.18.2", "@formatjs/icu-messageformat-parser": "2.7.6", - "@formatjs/intl": "2.10.1", + "@formatjs/intl": "2.10.2", "@formatjs/intl-displaynames": "6.6.6", "@formatjs/intl-listformat": "7.5.5", "@types/hoist-non-react-statics": "^3.3.1", "@types/react": "16 || 17 || 18", "hoist-non-react-statics": "^3.3.2", - "intl-messageformat": "10.5.11", + "intl-messageformat": "10.5.12", "tslib": "^2.4.0" }, "peerDependencies": { @@ -18168,9 +18202,9 @@ } }, "node_modules/react-redux": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.1.tgz", - "integrity": "sha512-5ynfGDzxxsoV73+4czQM56qF43vsmgJsO22rmAvU5tZT2z5Xow/A2uhhxwXuGTxgdReF3zcp7A80gma2onRs1A==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", "dependencies": { "@types/use-sync-external-store": "^0.0.3", "use-sync-external-store": "^1.0.0" @@ -18178,16 +18212,12 @@ "peerDependencies": { "@types/react": "^18.2.25", "react": "^18.0", - "react-native": ">=0.69", "redux": "^5.0.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true }, - "react-native": { - "optional": true - }, "redux": { "optional": true } diff --git a/package.json b/package.json index 2601043d5..f2b834e32 100644 --- a/package.json +++ b/package.json @@ -50,18 +50,18 @@ "verify": "npm-run-all build lint test" }, "dependencies": { - "@patternfly/patternfly": "5.3.0", + "@patternfly/patternfly": "5.3.1", "@patternfly/react-charts": "7.3.0", "@patternfly/react-component-groups": "^5.1.0", - "@patternfly/react-core": "5.3.0", - "@patternfly/react-icons": "5.3.0", - "@patternfly/react-table": "5.3.0", - "@patternfly/react-tokens": "5.3.0", - "@redhat-cloud-services/frontend-components": "^4.2.7", + "@patternfly/react-core": "5.3.3", + "@patternfly/react-icons": "5.3.2", + "@patternfly/react-table": "5.3.3", + "@patternfly/react-tokens": "5.3.1", + "@redhat-cloud-services/frontend-components": "^4.2.8", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", - "@redhat-cloud-services/rbac-client": "^1.4.0", + "@redhat-cloud-services/rbac-client": "^1.4.2", "@reduxjs/toolkit": "^2.2.3", "@unleash/proxy-client-react": "^4.2.2", "axios": "^1.6.8", @@ -71,8 +71,8 @@ "qs": "^6.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-intl": "^6.6.5", - "react-redux": "^9.1.1", + "react-intl": "^6.6.6", + "react-redux": "^9.1.2", "react-router-dom": "^6.23.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", @@ -81,16 +81,16 @@ "victory-core": "^37.0.2" }, "devDependencies": { - "@formatjs/cli": "^6.2.9", + "@formatjs/cli": "^6.2.10", "@formatjs/ecma402-abstract": "^1.18.2", "@formatjs/icu-messageformat-parser": "^2.7.6", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", - "@redhat-cloud-services/frontend-components-config": "^6.0.12", - "@redhat-cloud-services/tsc-transform-imports": "^1.0.9", + "@redhat-cloud-services/frontend-components-config": "^6.0.13", + "@redhat-cloud-services/tsc-transform-imports": "^1.0.10", "@swc/core": "^1.4.17", "@swc/jest": "^0.2.36", - "@testing-library/jest-dom": "^6.4.2", - "@testing-library/react": "^15.0.5", + "@testing-library/jest-dom": "^6.4.5", + "@testing-library/react": "^15.0.6", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", From e04ddd5eae4ce390d78f7fbef83effc4c1765544 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Mon, 6 May 2024 10:33:05 -0400 Subject: [PATCH 32/49] Add tooltip for price list kebab https://issues.redhat.com/browse/COST-5008 --- .../costModels/components/rateTable.tsx | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/routes/settings/costModels/components/rateTable.tsx b/src/routes/settings/costModels/components/rateTable.tsx index da0cc9f57..5bbc3063f 100644 --- a/src/routes/settings/costModels/components/rateTable.tsx +++ b/src/routes/settings/costModels/components/rateTable.tsx @@ -1,3 +1,4 @@ +import { Tooltip } from '@patternfly/react-core'; import type { IActions, ThProps } from '@patternfly/react-table'; import { ActionsColumn, @@ -149,16 +150,18 @@ const RateTableBase: React.FC = ({ ))} {!!actions.length && ( - { - return { - ...a, - onClick: () => { - a.onClick(null, rowIndex, row, null); - }, - }; - })} - /> + + { + return { + ...a, + onClick: () => { + a.onClick(null, rowIndex, row, null); + }, + }; + })} + /> + )} From a34871db87d5641834f117440d85c8431057eaed Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Mon, 6 May 2024 12:30:18 -0400 Subject: [PATCH 33/49] Platform projects table wraps names incorrectly https://issues.redhat.com/browse/COST-5016 --- src/routes/components/dataTable/dataTable.tsx | 2 ++ .../settings/platformProjects/platformProjects.scss | 10 ++++++++++ .../platformProjects/platformProjects.styles.ts | 9 --------- .../platformProjects/platformProjectsTable.tsx | 9 ++++----- 4 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 src/routes/settings/platformProjects/platformProjects.scss diff --git a/src/routes/components/dataTable/dataTable.tsx b/src/routes/components/dataTable/dataTable.tsx index af3fe975f..4871f9f03 100644 --- a/src/routes/components/dataTable/dataTable.tsx +++ b/src/routes/components/dataTable/dataTable.tsx @@ -155,6 +155,7 @@ class DataTable extends React.Component { {row.cells.map((item, cellIndex) => cellIndex === 0 && isSelectable ? ( { /> ) : ( = ({ {}, // Empty cell for row selection { value: item.project ? item.project : '', - style: styles.nameColumn, }, { + className: 'defaultColumn', value: item.default ? : null, }, { + className: 'groupColumn', value: item.group === 'Platform' ? : null, - style: styles.defaultColumn, }, - { value: , style: styles.groupColumn }, + { value: }, ], item, selected: selectedItems && selectedItems.find(val => val.project === item.project) !== undefined, From 66284cfd2784183c5dd9d83c5ab17ffb21d28ab2 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 8 May 2024 15:19:26 -0400 Subject: [PATCH 34/49] Ensure excludes filter is shown in breakdown https://issues.redhat.com/browse/COST-4977 --- src/routes/details/components/breakdown/breakdownHeader.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/routes/details/components/breakdown/breakdownHeader.tsx b/src/routes/details/components/breakdown/breakdownHeader.tsx index 45e08b670..e7aba9e98 100644 --- a/src/routes/details/components/breakdown/breakdownHeader.tsx +++ b/src/routes/details/components/breakdown/breakdownHeader.tsx @@ -97,8 +97,9 @@ class BreakdownHeader extends React.Component { private hasFilterBy = () => { const { router } = this.props; + const exclude = router.location.state?.details?.exclude; const filterBy = router.location.state?.details?.filter_by; - return filterBy && Object.keys(filterBy).length > 0; + return (exclude && Object.keys(exclude).length > 0) || (filterBy && Object.keys(filterBy).length > 0); }; private getFilterChips = () => { From 211a451b7c8b0c101ebe990c8134305815c2ed2b Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 9 May 2024 15:44:26 -0400 Subject: [PATCH 35/49] Added storage cost card for breakdown page https://issues.redhat.com/browse/COST-4856 --- locales/data.json | 48 ++++++++++++------- locales/translations.json | 4 +- src/locales/messages.ts | 34 ++++++------- .../costOverview/costOverviewBase.tsx | 48 ++++++++++++------- .../historicalDataVolumeChart.tsx | 1 - .../components/summary/summaryCard.tsx | 3 +- .../details/ocpBreakdown/costOverview.tsx | 2 + .../ocpCostOverview/ocpCostOverview.test.ts | 4 +- .../ocpCostOverview/ocpCostOverviewReducer.ts | 7 ++- .../ocpCostOverview/ocpCostOverviewWidgets.ts | 12 +++++ 10 files changed, 106 insertions(+), 57 deletions(-) diff --git a/locales/data.json b/locales/data.json index 0969a8077..28e272f8d 100644 --- a/locales/data.json +++ b/locales/data.json @@ -503,7 +503,7 @@ "value": [ { "type": 0, - "value": "Cost by accounts" + "value": "Cost breakdown by accounts" } ] }, @@ -511,7 +511,7 @@ "value": [ { "type": 0, - "value": "Cost by category" + "value": "Cost breakdown by category" } ] }, @@ -519,7 +519,7 @@ "value": [ { "type": 0, - "value": "Cost by clusters" + "value": "Cost breakdown by clusters" } ] }, @@ -527,7 +527,7 @@ "value": [ { "type": 0, - "value": "Cost by GCP projects" + "value": "Cost breakdown by GCP projects" } ] }, @@ -535,7 +535,7 @@ "value": [ { "type": 0, - "value": "Cost by Node" + "value": "Cost breakdown by Node" } ] }, @@ -543,7 +543,7 @@ "value": [ { "type": 0, - "value": "Cost by organizational units" + "value": "Cost breakdown by organizational units" } ] }, @@ -554,7 +554,7 @@ "value": [ { "type": 0, - "value": "Cost by accounts" + "value": "Cost breakdown by accounts" } ] }, @@ -562,7 +562,7 @@ "value": [ { "type": 0, - "value": "Cost by default projects" + "value": "Cost breakdown by default projects" } ] }, @@ -570,7 +570,7 @@ "value": [ { "type": 0, - "value": "Cost by services" + "value": "Cost breakdown by services" } ] }, @@ -578,7 +578,7 @@ "value": [ { "type": 0, - "value": "Cost by projects" + "value": "Cost breakdown by projects" } ] }, @@ -586,7 +586,7 @@ "value": [ { "type": 0, - "value": "Cost by regions" + "value": "Cost breakdown by regions" } ] }, @@ -594,7 +594,7 @@ "value": [ { "type": 0, - "value": "Cost by regions" + "value": "Cost breakdown by regions" } ] }, @@ -602,7 +602,7 @@ "value": [ { "type": 0, - "value": "Cost by services" + "value": "Cost breakdown by services" } ] }, @@ -610,7 +610,15 @@ "value": [ { "type": 0, - "value": "Cost by services" + "value": "Cost breakdown by services" + } + ] + }, + "storageclass": { + "value": [ + { + "type": 0, + "value": "Storage cost breakdown by type" } ] }, @@ -618,7 +626,7 @@ "value": [ { "type": 0, - "value": "Cost by accounts" + "value": "Cost breakdown by accounts" } ] }, @@ -626,7 +634,7 @@ "value": [ { "type": 0, - "value": "Cost by tags" + "value": "Cost breakdown by tags" } ] } @@ -3511,6 +3519,14 @@ } ] }, + "storageclass": { + "value": [ + { + "type": 0, + "value": "View all storage types" + } + ] + }, "subscription_guid": { "value": [ { diff --git a/locales/translations.json b/locales/translations.json index b7074b27d..707544d7d 100644 --- a/locales/translations.json +++ b/locales/translations.json @@ -26,7 +26,7 @@ "breakdownBackToTitles": "{value, select, aws {Amazon Web Services} azure {Microsoft Azure} oci {Oracle Cloud Infrastructure} gcp {Google Cloud Platform} ibm {IBM Cloud - Top 5 Costliest} ocp {OpenShift} other {}}", "breakdownCostOverviewTitle": "Cost overview", "breakdownHistoricalDataTitle": "Historical data", - "breakdownSummaryTitle": "{value, select, account {Cost by accounts} aws_category {Cost by category} cluster {Cost by clusters} gcp_project {Cost by GCP projects} node {Cost by Node} org_unit_id {Cost by organizational units} payer_tenant_id {Cost by accounts} platform {Cost by default projects} product_service {Cost by services} project {Cost by projects} region {Cost by regions} resource_location {Cost by regions} service {Cost by services} service_name {Cost by services} subscription_guid {Cost by accounts} tag {Cost by tags} other {}}", + "breakdownSummaryTitle": "{value, select, account {Cost breakdown by accounts} aws_category {Cost breakdown by category} cluster {Cost breakdown by clusters} gcp_project {Cost breakdown by GCP projects} node {Cost breakdown by Node} org_unit_id {Cost breakdown by organizational units} payer_tenant_id {Cost breakdown by accounts} platform {Cost breakdown by default projects} product_service {Cost breakdown by services} project {Cost breakdown by projects} region {Cost breakdown by regions} resource_location {Cost breakdown by regions} service {Cost breakdown by services} service_name {Cost breakdown by services} storageclass {Storage cost breakdown by type} subscription_guid {Cost breakdown by accounts} tag {Cost breakdown by tags} other {}}", "breakdownTitle": "{value}", "breakdownTotalCostDate": "{value} total cost ({dateRange})", "calculationType": "Calculation type", @@ -240,7 +240,7 @@ "detailsUsageLimit": "Limit - {value} {units}", "detailsUsageRequests": "Requests - {value} {units}", "detailsUsageUsage": "Usage - {value} {units}", - "detailsViewAll": "{value, select, account {View all accounts} aws_category {View all cost categories} cluster {View all clusters} gcp_project {View all GCP projects} node {View all nodes} org_unit_id {View all organizational units} payer_tenant_id {View all accounts} product_service {View all services} project {View all projects} region {View all regions} resource_location {View all regions} service {View all Services} service_name {View all services} subscription_guid {View all accounts} tag {View all tags} other {}}", + "detailsViewAll": "{value, select, account {View all accounts} aws_category {View all cost categories} cluster {View all clusters} gcp_project {View all GCP projects} node {View all nodes} org_unit_id {View all organizational units} payer_tenant_id {View all accounts} product_service {View all services} project {View all projects} region {View all regions} resource_location {View all regions} service {View all Services} service_name {View all services} storageclass {View all storage types} subscription_guid {View all accounts} tag {View all tags} other {}}", "disableCategories": "Disable categories", "disableTags": "Disable tags", "disabled": "Disabled", diff --git a/src/locales/messages.ts b/src/locales/messages.ts index bba7e8001..fcd0578c9 100644 --- a/src/locales/messages.ts +++ b/src/locales/messages.ts @@ -165,22 +165,23 @@ export default defineMessages({ breakdownSummaryTitle: { defaultMessage: '{value, select, ' + - 'account {Cost by accounts} ' + - 'aws_category {Cost by category} ' + - 'cluster {Cost by clusters} ' + - 'gcp_project {Cost by GCP projects} ' + - 'node {Cost by Node} ' + - 'org_unit_id {Cost by organizational units} ' + - 'payer_tenant_id {Cost by accounts} ' + - 'platform {Cost by default projects} ' + - 'product_service {Cost by services} ' + - 'project {Cost by projects} ' + - 'region {Cost by regions} ' + - 'resource_location {Cost by regions} ' + - 'service {Cost by services} ' + - 'service_name {Cost by services} ' + - 'subscription_guid {Cost by accounts} ' + - 'tag {Cost by tags} ' + + 'account {Cost breakdown by accounts} ' + + 'aws_category {Cost breakdown by category} ' + + 'cluster {Cost breakdown by clusters} ' + + 'gcp_project {Cost breakdown by GCP projects} ' + + 'node {Cost breakdown by Node} ' + + 'org_unit_id {Cost breakdown by organizational units} ' + + 'payer_tenant_id {Cost breakdown by accounts} ' + + 'platform {Cost breakdown by default projects} ' + + 'product_service {Cost breakdown by services} ' + + 'project {Cost breakdown by projects} ' + + 'region {Cost breakdown by regions} ' + + 'resource_location {Cost breakdown by regions} ' + + 'service {Cost breakdown by services} ' + + 'service_name {Cost breakdown by services} ' + + 'storageclass {Storage cost breakdown by type} ' + + 'subscription_guid {Cost breakdown by accounts} ' + + 'tag {Cost breakdown by tags} ' + 'other {}}', description: 'Cost by {value}', id: 'breakdownSummaryTitle', @@ -1413,6 +1414,7 @@ export default defineMessages({ 'resource_location {View all regions} ' + 'service {View all Services} ' + 'service_name {View all services} ' + + 'storageclass {View all storage types} ' + 'subscription_guid {View all accounts} ' + 'tag {View all tags} ' + 'other {}}', diff --git a/src/routes/details/components/costOverview/costOverviewBase.tsx b/src/routes/details/components/costOverview/costOverviewBase.tsx index fbc88cd16..a9b16c0d8 100644 --- a/src/routes/details/components/costOverview/costOverviewBase.tsx +++ b/src/routes/details/components/costOverview/costOverviewBase.tsx @@ -15,6 +15,7 @@ import { import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon'; import type { Query } from 'api/queries/query'; import type { Report } from 'api/reports/report'; +import { ReportType } from 'api/reports/report'; import messages from 'locales/messages'; import React from 'react'; import type { WrappedComponentProps } from 'react-intl'; @@ -42,6 +43,7 @@ interface CostOverviewOwnProps { } export interface CostOverviewStateProps { + isOcpProjectStorageToggleEnabled?: boolean; selectWidgets?: Record; title?: string; widgets: number[]; @@ -234,8 +236,8 @@ class CostOverviewsBase extends React.Component { ); }; - // Returns summary card widget - private getSummaryCard = (widget: CostOverviewWidget) => { + // Returns report summary card + private getReportSummaryCard = (widget: CostOverviewWidget) => { const { costDistribution, costType, currency, groupBy, isPlatformCosts, query } = this.props; const groupByCostCategory = getGroupByCostCategory(query); @@ -260,10 +262,11 @@ class CostOverviewsBase extends React.Component { } } if (showWidget) { + const isVolumeWidget = widget.reportType === ReportType.volume; return ( { const { selectWidgets, widgets } = this.props; const visibleWidgets = []; + let chartWidgetCount = 0; + widgets.map(widgetId => { const widget = selectWidgets[widgetId]; const renderedWidget = this.renderWidget(widget); - if (renderedWidget !== null) { + if (renderedWidget !== null && renderedWidget !== PLACEHOLDER) { visibleWidgets.push(renderedWidget); + if ( + widget.type === CostOverviewWidgetType.cpuUsage || + widget.type === CostOverviewWidgetType.memoryUsage || + widget.type === CostOverviewWidgetType.pvc || + widget.type === CostOverviewWidgetType.volumeUsage + ) { + chartWidgetCount++; + } } }); + // Ensure all charts appear in the right column const rows = Math.floor(visibleWidgets.length / 2) + (visibleWidgets.length % 2); - const leftColumnWidgets = []; - const rightColumnWidgets = []; - for (let i = 0; i < rows; i++) { - if (visibleWidgets[i] !== PLACEHOLDER) { - leftColumnWidgets.push(visibleWidgets[i]); - } - if (i + rows < visibleWidgets.length) { - if (visibleWidgets[i + rows] !== PLACEHOLDER) { - rightColumnWidgets.push(visibleWidgets[i + rows]); - } - } - } + const midIndex = chartWidgetCount > 0 ? visibleWidgets.length - chartWidgetCount : rows; + + const leftColumnWidgets = visibleWidgets.slice(0, midIndex); + const rightColumnWidgets = visibleWidgets.slice(midIndex, visibleWidgets.length); + return { leftColumnWidgets, rightColumnWidgets }; }; // Returns rendered widget based on type private renderWidget(widget: CostOverviewWidget) { + const { isOcpProjectStorageToggleEnabled } = this.props; + switch (widget.type) { case CostOverviewWidgetType.cluster: return this.getClusterCard(widget); @@ -353,7 +362,10 @@ class CostOverviewsBase extends React.Component { case CostOverviewWidgetType.pvc: return this.getPvcChart(widget); case CostOverviewWidgetType.reportSummary: - return this.getSummaryCard(widget); + if (widget.reportType === ReportType.volume && !isOcpProjectStorageToggleEnabled) { + return null; + } + return this.getReportSummaryCard(widget); case CostOverviewWidgetType.volumeUsage: return this.getVolumeUsageChart(widget); default: diff --git a/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx b/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx index 02ad1a72e..46b191e6a 100644 --- a/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx +++ b/src/routes/details/components/historicalData/historicalDataVolumeChart.tsx @@ -128,7 +128,6 @@ const mapStateToProps = createMapStateToProps((state, { title }) => { return { + isOcpProjectStorageToggleEnabled: FeatureToggleSelectors.selectIsOcpProjectStorageToggleEnabled(state), selectWidgets: ocpCostOverviewSelectors.selectWidgets(state), widgets: ocpCostOverviewSelectors.selectCurrentWidgets(state), title, diff --git a/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverview.test.ts b/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverview.test.ts index f425aaa85..fbc3f0518 100644 --- a/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverview.test.ts +++ b/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverview.test.ts @@ -14,6 +14,7 @@ import { memoryUsageWidget, projectSummaryWidget, pvcWidget, + volumeSummaryWidget, volumeUsageWidget, } from './ocpCostOverviewWidgets'; @@ -33,8 +34,9 @@ test('default state', () => { expect(selectors.selectCurrentWidgets(state)).toEqual([ costWidget.id, costDistributionWidget.id, - clusterWidget.id, projectSummaryWidget.id, + volumeSummaryWidget.id, + clusterWidget.id, cpuUsageWidget.id, memoryUsageWidget.id, pvcWidget.id, diff --git a/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewReducer.ts b/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewReducer.ts index 44063eaee..e10eeaf2c 100644 --- a/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewReducer.ts +++ b/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewReducer.ts @@ -7,6 +7,7 @@ import { memoryUsageWidget, projectSummaryWidget, pvcWidget, + volumeSummaryWidget, volumeUsageWidget, } from './ocpCostOverviewWidgets'; @@ -19,8 +20,9 @@ export const defaultState: OcpCostOverviewState = { currentWidgets: [ costWidget.id, costDistributionWidget.id, - clusterWidget.id, projectSummaryWidget.id, + volumeSummaryWidget.id, + clusterWidget.id, cpuUsageWidget.id, memoryUsageWidget.id, pvcWidget.id, @@ -29,8 +31,9 @@ export const defaultState: OcpCostOverviewState = { widgets: { [costWidget.id]: costWidget, [costDistributionWidget.id]: costDistributionWidget, - [clusterWidget.id]: clusterWidget, [projectSummaryWidget.id]: projectSummaryWidget, + [volumeSummaryWidget.id]: volumeSummaryWidget, + [clusterWidget.id]: clusterWidget, [cpuUsageWidget.id]: cpuUsageWidget, [memoryUsageWidget.id]: memoryUsageWidget, [pvcWidget.id]: pvcWidget, diff --git a/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewWidgets.ts b/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewWidgets.ts index 20d422382..b30e70a91 100644 --- a/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewWidgets.ts +++ b/src/store/breakdown/costOverview/ocpCostOverview/ocpCostOverviewWidgets.ts @@ -80,6 +80,18 @@ export const pvcWidget: OcpCostOverviewWidget = { type: CostOverviewWidgetType.pvc, }; +export const volumeSummaryWidget: OcpCostOverviewWidget = { + id: getId(), + reportSummary: { + reportGroupBy: 'storageclass', + showWidgetOnGroupBy: ['cluster', 'node', 'project'], + usePlaceholder: true, + }, + reportType: ReportType.volume, + reportPathsType: ReportPathsType.ocp, + type: CostOverviewWidgetType.reportSummary, +}; + export const volumeUsageWidget: OcpCostOverviewWidget = { chartName: 'ocpVolumeWidget', id: getId(), From 9bddb01546ceff04d5b5e080fa0e0a5233145e34 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Fri, 10 May 2024 12:34:21 -0400 Subject: [PATCH 36/49] Update historical network chart to use API data https://issues.redhat.com/browse/COST-4781 --- .../costOverview/costOverviewBase.tsx | 61 +-- .../details/components/historicalData/data.ts | 469 ------------------ .../historicalData/historicalDataBase.tsx | 54 +- .../historicalDataNetworkChart.tsx | 13 +- .../components/summary/summaryCard.tsx | 3 +- 5 files changed, 62 insertions(+), 538 deletions(-) delete mode 100644 src/routes/details/components/historicalData/data.ts diff --git a/src/routes/details/components/costOverview/costOverviewBase.tsx b/src/routes/details/components/costOverview/costOverviewBase.tsx index a9b16c0d8..509aad557 100644 --- a/src/routes/details/components/costOverview/costOverviewBase.tsx +++ b/src/routes/details/components/costOverview/costOverviewBase.tsx @@ -81,7 +81,6 @@ class CostOverviewsBase extends React.Component { } else { return PLACEHOLDER; } - return null; }; // Returns cost breakdown chart @@ -219,21 +218,21 @@ class CostOverviewsBase extends React.Component { } } } - if (!showWidget) { - return null; + if (showWidget) { + return ( + + + + {intl.formatMessage(messages.pvcTitle)} + + + + + + + ); } - return ( - - - - {intl.formatMessage(messages.pvcTitle)} - - - - - - - ); + return null; }; // Returns report summary card @@ -294,21 +293,25 @@ class CostOverviewsBase extends React.Component { } } } - if (!showWidget) { - return null; + if (showWidget) { + return ( + + + + {intl.formatMessage(messages.volumeTitle)} + + + + + + + ); } - return ( - - - - {intl.formatMessage(messages.volumeTitle)} - - - - - - - ); + return null; }; // Helper to fill grid columns instead of rows, based on the order defined by the reducer diff --git a/src/routes/details/components/historicalData/data.ts b/src/routes/details/components/historicalData/data.ts deleted file mode 100644 index 669218277..000000000 --- a/src/routes/details/components/historicalData/data.ts +++ /dev/null @@ -1,469 +0,0 @@ -/** - * Design doc https://docs.google.com/document/d/1b9JhMmFRvp0JL_wFkiOPzyyx72kG2_BZGjoRcyz8rq4/edit - */ - -export const currentData = { - meta: { - count: 2, - limit: 100, - offset: 0, - total: { - usage: { - value: 3.6801746441, - units: 'GB', - }, - data_transfer_in: { - value: 12.82510775, - units: 'GB', - }, - data_transfer_out: { - value: 8.080656137, - units: 'GB', - }, - infrastructure: { - raw: { - value: 1945.51192915, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 1945.51192915, - units: 'USD', - }, - }, - supplementary: { - raw: { - value: 0.0, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 0.0, - units: 'USD', - }, - }, - cost: { - raw: { - value: 4863.77982288, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 4863.77982288, - units: 'USD', - }, - }, - }, - }, - links: { - first: - '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-1&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', - next: null, - previous: null, - last: '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-1&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', - }, - data: [ - { - date: '2024-05-01', - values: [ - { - date: '2024-05-01', - data_transfer_in: { - value: 3.6801746441, - units: 'GB', - }, - data_transfer_out: { - value: 2.6866746441, - units: 'GB', - }, - resource_id: 'i-727f8dc9c567f1552', - clusters: ['Test OCP on AWS'], - source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', - region: 'us-east-1', - infrastructure: { - raw: { - value: 1945.51192915, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 1945.5119291598, - units: 'USD', - }, - }, - supplementary: { - raw: { - value: 0.0, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 0.0, - units: 'USD', - }, - }, - cost: { - raw: { - value: 1945.51192915, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 1945.51192915, - units: 'USD', - }, - }, - }, - ], - }, - { - date: '2024-05-02', - values: [ - { - date: '2024-05-02', - data_transfer_in: { - value: 9.1449331092, - units: 'GB', - }, - data_transfer_out: { - value: 5.3939814929, - units: 'GB', - }, - resource_id: 'i-727f8dc9c567f1552', - clusters: ['Test OCP on AWS'], - source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', - region: 'us-east-1', - infrastructure: { - raw: { - value: 2918.26789372, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 2918.26789372, - units: 'USD', - }, - }, - supplementary: { - raw: { - value: 0.0, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 0.0, - units: 'USD', - }, - }, - cost: { - raw: { - value: 2918.267893725, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 2918.267893725, - units: 'USD', - }, - }, - }, - ], - }, - ], -}; - -export const previousData = { - meta: { - count: 2, - limit: 100, - offset: 0, - total: { - usage: { - value: 3.6801746441, - units: 'GB', - }, - data_transfer_in: { - value: 12.82510775, - units: 'GB', - }, - data_transfer_out: { - value: 8.080656137, - units: 'GB', - }, - infrastructure: { - raw: { - value: 1945.51192915, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 1945.51192915, - units: 'USD', - }, - }, - supplementary: { - raw: { - value: 0.0, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 0.0, - units: 'USD', - }, - }, - cost: { - raw: { - value: 4863.77982288, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 4863.77982288, - units: 'USD', - }, - }, - }, - }, - links: { - first: - '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-2&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', - next: null, - previous: null, - last: '/api/cost-management/v1/reports/openshift/network/?filter%5Bresolution%5D=daily&filter%5Btime_scope_units%5D=month&filter%5Btime_scope_value%5D=-2&group_by%5Bcluster%5D=a94ea9bc-9e4f-4b91-89c2-c7099ec08427&limit=100&offset=0', - }, - data: [ - { - date: '2024-04-01', - values: [ - { - date: '2024-04-01', - data_transfer_in: { - value: 3.6801746441, - units: 'GB', - }, - data_transfer_out: { - value: 2.6866746441, - units: 'GB', - }, - resource_id: 'i-727f8dc9c567f1552', - clusters: ['Test OCP on AWS'], - source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', - region: 'us-east-1', - infrastructure: { - raw: { - value: 1945.51192915, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 1945.5119291598, - units: 'USD', - }, - }, - supplementary: { - raw: { - value: 0.0, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 0.0, - units: 'USD', - }, - }, - cost: { - raw: { - value: 1945.51192915, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 1945.51192915, - units: 'USD', - }, - }, - }, - ], - }, - { - date: '2024-04-02', - values: [ - { - date: '2024-04-02', - data_transfer_in: { - value: 9.1449331092, - units: 'GB', - }, - data_transfer_out: { - value: 5.3939814929, - units: 'GB', - }, - resource_id: 'i-727f8dc9c567f1552', - clusters: ['Test OCP on AWS'], - source_uuid: '6795d5e6-951c-4382-a8d3-390515d7ec3d', - region: 'us-east-1', - infrastructure: { - raw: { - value: 2918.26789372, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 2918.26789372, - units: 'USD', - }, - }, - supplementary: { - raw: { - value: 0.0, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 0.0, - units: 'USD', - }, - }, - cost: { - raw: { - value: 2918.267893725, - units: 'USD', - }, - markup: { - value: 0.0, - units: 'USD', - }, - usage: { - value: 0.0, - units: 'USD', - }, - total: { - value: 2918.267893725, - units: 'USD', - }, - }, - }, - ], - }, - ], -}; diff --git a/src/routes/details/components/historicalData/historicalDataBase.tsx b/src/routes/details/components/historicalData/historicalDataBase.tsx index 86156425a..041de3ae5 100644 --- a/src/routes/details/components/historicalData/historicalDataBase.tsx +++ b/src/routes/details/components/historicalData/historicalDataBase.tsx @@ -68,10 +68,9 @@ class HistoricalDatasBase extends React.Component { // Returns network chart private getNetworkChart = (widget: HistoricalDataWidget) => { - const { groupBy, intl, isOcpCloudNetworkingToggleEnabled } = this.props; + const { groupBy, intl } = this.props; let showWidget = false; - if (widget.network?.showWidgetOnGroupBy) { for (const groupById of widget.network.showWidgetOnGroupBy) { if (groupById === groupBy) { @@ -80,36 +79,33 @@ class HistoricalDatasBase extends React.Component { } } } - if (!showWidget || !isOcpCloudNetworkingToggleEnabled) { - return null; + if (showWidget) { + return ( + + + + {intl.formatMessage(messages.historicalChartTitle, { + value: this.getTitleKey(widget.reportPathsType, widget.reportType), + })} + + + + + + + ); } - return ( - - - - {intl.formatMessage(messages.historicalChartTitle, { - value: this.getTitleKey(widget.reportPathsType, widget.reportType), - })} - - - - - - - ); + return null; }; // Returns volume chart private getVolumeChart = (widget: HistoricalDataWidget) => { - const { intl, isOcpProjectStorageToggleEnabled } = this.props; + const { intl } = this.props; - if (!isOcpProjectStorageToggleEnabled) { - return null; - } return ( @@ -182,17 +178,19 @@ class HistoricalDatasBase extends React.Component { // Returns rendered widget based on type private renderWidget(widget: HistoricalDataWidget) { + const { isOcpCloudNetworkingToggleEnabled, isOcpProjectStorageToggleEnabled } = this.props; + switch (widget.type) { case HistoricalDataWidgetType.cost: return this.getCostChart(widget); case HistoricalDataWidgetType.network: - return this.getNetworkChart(widget); + return isOcpCloudNetworkingToggleEnabled ? this.getNetworkChart(widget) : null; case HistoricalDataWidgetType.trend: return this.getTrendChart(widget); case HistoricalDataWidgetType.usage: return this.getUsageChart(widget); case HistoricalDataWidgetType.volume: - return this.getVolumeChart(widget); + return isOcpProjectStorageToggleEnabled ? this.getVolumeChart(widget) : null; default: return null; } diff --git a/src/routes/details/components/historicalData/historicalDataNetworkChart.tsx b/src/routes/details/components/historicalData/historicalDataNetworkChart.tsx index 090ae3e88..a15d38feb 100644 --- a/src/routes/details/components/historicalData/historicalDataNetworkChart.tsx +++ b/src/routes/details/components/historicalData/historicalDataNetworkChart.tsx @@ -14,14 +14,12 @@ import { getGroupById, getGroupByOrgValue, getGroupByValue } from 'routes/utils/ import { getQueryState } from 'routes/utils/queryState'; import { skeletonWidth } from 'routes/utils/skeleton'; import { createMapStateToProps, FetchStatus } from 'store/common'; -import { FeatureToggleSelectors } from 'store/featureToggle'; import { reportActions, reportSelectors } from 'store/reports'; import { formatUnits, unitsLookupKey } from 'utils/format'; import { logicalAndPrefix, logicalOrPrefix, orgUnitIdKey, platformCategoryKey } from 'utils/props'; import type { RouterComponentProps } from 'utils/router'; import { withRouter } from 'utils/router'; -import { currentData, previousData } from './data'; import { chartStyles, styles } from './historicalChart.styles'; interface HistoricalDataNetworkChartOwnProps extends RouterComponentProps, WrappedComponentProps { @@ -188,7 +186,7 @@ const mapStateToProps = createMapStateToProps { const title = intl.formatMessage(messages.breakdownSummaryTitle, { value: isPlatformCosts ? platformCategoryKey.toLowerCase() : reportGroupBy, }); + const viewAll = this.getViewAll(); return ( @@ -217,7 +218,7 @@ class SummaryBase extends React.Component { this.getSummary() )} - {this.getViewAll()} + {viewAll && {viewAll}} ); } From 3e532628823a9d7befea843a5c53ea79604f0d20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 10:28:44 +0000 Subject: [PATCH 37/49] (chore): Bump eslint-plugin-jsdoc in the lint-dependencies group Bumps the lint-dependencies group with 1 update: [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc). Updates `eslint-plugin-jsdoc` from 48.2.3 to 48.2.4 - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.2.3...v48.2.4) --- updated-dependencies: - dependency-name: eslint-plugin-jsdoc dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 19 +++++++++++-------- package.json | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33ffde5df..7f21649c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.1", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.3", + "eslint-plugin-jsdoc": "^48.2.4", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", @@ -746,11 +746,14 @@ "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", - "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "version": "0.43.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.0.tgz", + "integrity": "sha512-Q1CnsQrytI3TlCB1IVWXWeqUIPGVEKGaE7IbVdt13Nq/3i0JESAkQQERrfiQkmlpijl+++qyqPgaS31Bvc1jRQ==", "dev": true, "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" @@ -9489,12 +9492,12 @@ "dev": true }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.3.tgz", - "integrity": "sha512-r9DMAmFs66VNvNqRLLjHejdnJtILrt3xGi+Qx0op0oRfFGVpOR1Hb3BC++MacseHx93d8SKYPhyrC9BS7Os2QA==", + "version": "48.2.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.4.tgz", + "integrity": "sha512-3ebvVgCJFy06gpmuS2ynz13uh9iFSzZ1C1dDkgcSAqVVg82zlORKMk2fvjq708pAO6bwfs5YLttknFEbaoDiGw==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.42.0", + "@es-joy/jsdoccomment": "~0.43.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", diff --git a/package.json b/package.json index f2b834e32..a4ae11969 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.1", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.3", + "eslint-plugin-jsdoc": "^48.2.4", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", From 4fda58394995399f440598ce279edba19aa98270 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 10:29:20 +0000 Subject: [PATCH 38/49] (chore): Bump @testing-library/react in the test-dependencies group Bumps the test-dependencies group with 1 update: [@testing-library/react](https://github.com/testing-library/react-testing-library). Updates `@testing-library/react` from 15.0.6 to 15.0.7 - [Release notes](https://github.com/testing-library/react-testing-library/releases) - [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/react-testing-library/compare/v15.0.6...v15.0.7) --- updated-dependencies: - dependency-name: "@testing-library/react" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33ffde5df..b0c58a468 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "@swc/core": "^1.4.17", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.5", - "@testing-library/react": "^15.0.6", + "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", @@ -3665,9 +3665,9 @@ } }, "node_modules/@testing-library/react": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.6.tgz", - "integrity": "sha512-UlbazRtEpQClFOiYp+1BapMT+xyqWMnE+hh9tn5DQ6gmlE7AIZWcGpzZukmDZuFk3By01oiqOf8lRedLS4k6xQ==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", + "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", diff --git a/package.json b/package.json index f2b834e32..2656e42ac 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "@swc/core": "^1.4.17", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.5", - "@testing-library/react": "^15.0.6", + "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", From 1aabb60763686b0a21335b7c9f8969ddeaf48bbf Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 15 May 2024 09:31:41 -0400 Subject: [PATCH 39/49] Dependency updates --- package-lock.json | 352 +++++++++++++++++----------------------------- package.json | 18 +-- 2 files changed, 139 insertions(+), 231 deletions(-) diff --git a/package-lock.json b/package-lock.json index 11f1d759a..2a0f73230 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,8 +21,8 @@ "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", - "@redhat-cloud-services/rbac-client": "^1.4.2", - "@reduxjs/toolkit": "^2.2.3", + "@redhat-cloud-services/rbac-client": "^1.4.3", + "@reduxjs/toolkit": "^2.2.4", "@unleash/proxy-client-react": "^4.2.2", "axios": "^1.6.8", "date-fns": "^3.6.0", @@ -33,7 +33,7 @@ "react-dom": "^18.3.1", "react-intl": "^6.6.6", "react-redux": "^9.1.2", - "react-router-dom": "^6.23.0", + "react-router-dom": "^6.23.1", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "typesafe-actions": "^5.1.0", @@ -45,21 +45,21 @@ "@formatjs/ecma402-abstract": "^1.18.2", "@formatjs/icu-messageformat-parser": "^2.7.6", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", - "@redhat-cloud-services/frontend-components-config": "^6.0.13", + "@redhat-cloud-services/frontend-components-config": "^6.0.14", "@redhat-cloud-services/tsc-transform-imports": "^1.0.10", - "@swc/core": "^1.4.17", + "@swc/core": "^1.5.7", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", - "@types/react": "^18.3.1", + "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", @@ -82,7 +82,7 @@ "jws": "^4.0.0", "npm-run-all": "^4.1.5", "prettier": "^3.2.5", - "rimraf": "^5.0.5", + "rimraf": "^5.0.7", "swc_mut_cjs_exports": "^0.90.24", "ts-jest": "^29.1.2", "ts-patch": "^3.1.2", @@ -2524,9 +2524,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components-config": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config/-/frontend-components-config-6.0.13.tgz", - "integrity": "sha512-fABmXUguiFAZp3DCun2cE1wpDaK1ZTYGVCs9f7fg0FB0rENaPK3B7twviLON3Y4OdOX9dHg/e7LYzNrbvH04MQ==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config/-/frontend-components-config-6.0.14.tgz", + "integrity": "sha512-VBa2lFClKgrUdJVY/SsqYPIHzao0tf/j4hln6K1wxl9DmYH1D7mXSJaypnytuBjvQBYC5pRiScuLrmYBwUDRcA==", "dev": true, "dependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.8", @@ -2977,9 +2977,9 @@ } }, "node_modules/@redhat-cloud-services/rbac-client": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.2.tgz", - "integrity": "sha512-5IIAEt/t17JMwDSiXxGvvm0s5T/Vy2EvxZcwdUTCmOM/8w/FMb47GP+ABF5ygVWJSA7u+vEySvEW/Ay9Oow+tA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.3.tgz", + "integrity": "sha512-c/GD3szEY7Thh24VSO0WTZKFIC4BJQ14ujqA7cAc7fZQPXeo48RFPBEGiOGTU/iS16oG9OuQAMJrZYVrts/oCg==", "dependencies": { "axios": "^0.27.2", "tslib": "^2.6.2" @@ -3034,14 +3034,14 @@ "integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg==" }, "node_modules/@reduxjs/toolkit": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.3.tgz", - "integrity": "sha512-76dll9EnJXg4EVcI5YNxZA/9hSAmZsFqzMmNRHvIlzw2WS/twfcVX3ysYrWGJMClwEmChQFC4yRq74tn6fdzRA==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.4.tgz", + "integrity": "sha512-EoIC9iC2V/DLRBVMXRHrO/oM3QBT7RuJNeBRx8Cpnz/NHINeZBEqgI8YOxAYUjLp+KYxGgc4Wd6KoAKsaUBGhg==", "dependencies": { "immer": "^10.0.3", "redux": "^5.0.1", "redux-thunk": "^3.1.0", - "reselect": "^5.0.1" + "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18", @@ -3057,9 +3057,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", - "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz", + "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==", "engines": { "node": ">=14.0.0" } @@ -3224,14 +3224,14 @@ } }, "node_modules/@swc/core": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.17.tgz", - "integrity": "sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", + "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", "dev": true, "hasInstallScript": true, "dependencies": { "@swc/counter": "^0.1.2", - "@swc/types": "^0.1.5" + "@swc/types": "0.1.7" }, "engines": { "node": ">=10" @@ -3241,16 +3241,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.4.17", - "@swc/core-darwin-x64": "1.4.17", - "@swc/core-linux-arm-gnueabihf": "1.4.17", - "@swc/core-linux-arm64-gnu": "1.4.17", - "@swc/core-linux-arm64-musl": "1.4.17", - "@swc/core-linux-x64-gnu": "1.4.17", - "@swc/core-linux-x64-musl": "1.4.17", - "@swc/core-win32-arm64-msvc": "1.4.17", - "@swc/core-win32-ia32-msvc": "1.4.17", - "@swc/core-win32-x64-msvc": "1.4.17" + "@swc/core-darwin-arm64": "1.5.7", + "@swc/core-darwin-x64": "1.5.7", + "@swc/core-linux-arm-gnueabihf": "1.5.7", + "@swc/core-linux-arm64-gnu": "1.5.7", + "@swc/core-linux-arm64-musl": "1.5.7", + "@swc/core-linux-x64-gnu": "1.5.7", + "@swc/core-linux-x64-musl": "1.5.7", + "@swc/core-win32-arm64-msvc": "1.5.7", + "@swc/core-win32-ia32-msvc": "1.5.7", + "@swc/core-win32-x64-msvc": "1.5.7" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -3262,9 +3262,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.17.tgz", - "integrity": "sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", + "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", "cpu": [ "arm64" ], @@ -3278,9 +3278,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.17.tgz", - "integrity": "sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", + "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", "cpu": [ "x64" ], @@ -3294,9 +3294,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.17.tgz", - "integrity": "sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", + "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", "cpu": [ "arm" ], @@ -3310,9 +3310,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.17.tgz", - "integrity": "sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", + "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", "cpu": [ "arm64" ], @@ -3326,9 +3326,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.17.tgz", - "integrity": "sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", + "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", "cpu": [ "arm64" ], @@ -3342,9 +3342,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.17.tgz", - "integrity": "sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", + "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", "cpu": [ "x64" ], @@ -3358,9 +3358,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.17.tgz", - "integrity": "sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", + "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", "cpu": [ "x64" ], @@ -3374,9 +3374,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.17.tgz", - "integrity": "sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", + "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", "cpu": [ "arm64" ], @@ -3390,9 +3390,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.17.tgz", - "integrity": "sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", + "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", "cpu": [ "ia32" ], @@ -3406,9 +3406,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.17.tgz", - "integrity": "sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", + "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", "cpu": [ "x64" ], @@ -3445,9 +3445,9 @@ } }, "node_modules/@swc/types": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.6.tgz", - "integrity": "sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", + "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", "dev": true, "dependencies": { "@swc/counter": "^0.1.3" @@ -4229,9 +4229,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "version": "18.3.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", + "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4466,21 +4466,19 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -4500,49 +4498,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" }, "engines": { @@ -4562,13 +4527,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4579,13 +4544,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -4606,9 +4571,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4619,13 +4584,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4646,18 +4611,6 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -4674,13 +4627,10 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -4688,25 +4638,16 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4719,46 +4660,13 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -18236,11 +18144,11 @@ } }, "node_modules/react-router": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", - "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", + "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==", "dependencies": { - "@remix-run/router": "1.16.0" + "@remix-run/router": "1.16.1" }, "engines": { "node": ">=14.0.0" @@ -18250,12 +18158,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", - "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz", + "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==", "dependencies": { - "@remix-run/router": "1.16.0", - "react-router": "6.23.0" + "@remix-run/router": "1.16.1", + "react-router": "6.23.1" }, "engines": { "node": ">=14.0.0" @@ -18604,9 +18512,9 @@ "peer": true }, "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", + "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", "dev": true, "dependencies": { "glob": "^10.3.7" @@ -18615,7 +18523,7 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" diff --git a/package.json b/package.json index 409dbb2b2..de9f1c47a 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,8 @@ "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", - "@redhat-cloud-services/rbac-client": "^1.4.2", - "@reduxjs/toolkit": "^2.2.3", + "@redhat-cloud-services/rbac-client": "^1.4.3", + "@reduxjs/toolkit": "^2.2.4", "@unleash/proxy-client-react": "^4.2.2", "axios": "^1.6.8", "date-fns": "^3.6.0", @@ -73,7 +73,7 @@ "react-dom": "^18.3.1", "react-intl": "^6.6.6", "react-redux": "^9.1.2", - "react-router-dom": "^6.23.0", + "react-router-dom": "^6.23.1", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "typesafe-actions": "^5.1.0", @@ -85,21 +85,21 @@ "@formatjs/ecma402-abstract": "^1.18.2", "@formatjs/icu-messageformat-parser": "^2.7.6", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", - "@redhat-cloud-services/frontend-components-config": "^6.0.13", + "@redhat-cloud-services/frontend-components-config": "^6.0.14", "@redhat-cloud-services/tsc-transform-imports": "^1.0.10", - "@swc/core": "^1.4.17", + "@swc/core": "^1.5.7", "@swc/jest": "^0.2.36", "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", - "@types/react": "^18.3.1", + "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", @@ -122,7 +122,7 @@ "jws": "^4.0.0", "npm-run-all": "^4.1.5", "prettier": "^3.2.5", - "rimraf": "^5.0.5", + "rimraf": "^5.0.7", "swc_mut_cjs_exports": "^0.90.24", "ts-jest": "^29.1.2", "ts-patch": "^3.1.2", From 679f667d57b248e8fbe5b6dd6ab9b9fb516de29c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 10:10:49 +0000 Subject: [PATCH 40/49] (chore): Bump the lint-dependencies group with 2 updates Bumps the lint-dependencies group with 2 updates: [eslint-plugin-formatjs](https://github.com/formatjs/formatjs) and [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc). Updates `eslint-plugin-formatjs` from 4.13.1 to 4.13.3 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/eslint-plugin-formatjs@4.13.1...eslint-plugin-formatjs@4.13.3) Updates `eslint-plugin-jsdoc` from 48.2.4 to 48.2.5 - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.2.4...v48.2.5) --- updated-dependencies: - dependency-name: eslint-plugin-formatjs dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies - dependency-name: eslint-plugin-jsdoc dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 119 +++++++++++++++++++++++++++++++--------------- package.json | 4 +- 2 files changed, 82 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a0f73230..b2f46b650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,9 +63,9 @@ "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", - "eslint-plugin-formatjs": "^4.13.1", + "eslint-plugin-formatjs": "^4.13.3", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.4", + "eslint-plugin-jsdoc": "^48.2.5", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", @@ -1014,12 +1014,12 @@ } }, "node_modules/@formatjs/ts-transformer": { - "version": "3.13.12", - "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.13.12.tgz", - "integrity": "sha512-uf1+DgbsCrzHAg7uIf0QlzpIkHYxRSRig5iJa9FaoUNIDZzNEE2oW/uLLLq7I9Z2FLIPhbmgq8hbW40FoQv+Fg==", + "version": "3.13.14", + "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.13.14.tgz", + "integrity": "sha512-TP/R54lxQ9Drzzimxrrt6yBT/xBofTgYl5wSTpyKe3Aq9vIBVcFmS6EOqycj0X34KGu3EpDPGO0ng8ZQZGLIFg==", "dev": true, "dependencies": { - "@formatjs/icu-messageformat-parser": "2.7.6", + "@formatjs/icu-messageformat-parser": "2.7.8", "@types/json-stable-stringify": "^1.0.32", "@types/node": "14 || 16 || 17", "chalk": "^4.0.0", @@ -1036,6 +1036,37 @@ } } }, + "node_modules/@formatjs/ts-transformer/node_modules/@formatjs/ecma402-abstract": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", + "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==", + "dev": true, + "dependencies": { + "@formatjs/intl-localematcher": "0.5.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/ts-transformer/node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz", + "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "2.0.0", + "@formatjs/icu-skeleton-parser": "1.8.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/ts-transformer/node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz", + "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "2.0.0", + "tslib": "^2.4.0" + } + }, "node_modules/@formatjs/ts-transformer/node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", @@ -8965,13 +8996,13 @@ } }, "node_modules/eslint-plugin-formatjs": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.13.1.tgz", - "integrity": "sha512-QYXgrBYLwEcqN4Vvis18es1JFAY+6YAkjpyNmTZzAMpithZm9U7z6eWUD4gqFainWlk8cFKvkOOvSyQ4/LUgVA==", + "version": "4.13.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.13.3.tgz", + "integrity": "sha512-4j3IVwaLEXblnvH2/ZIOZwc9zaaZf2+zyn/b8oLJRt6kMCTu2rIs4UsIxy5nBRYZzsBSh7k34JJ5/ngGtJ3kYw==", "dev": true, "dependencies": { - "@formatjs/icu-messageformat-parser": "2.7.6", - "@formatjs/ts-transformer": "3.13.12", + "@formatjs/icu-messageformat-parser": "2.7.8", + "@formatjs/ts-transformer": "3.13.14", "@types/eslint": "7 || 8", "@types/picomatch": "^2.3.0", "@typescript-eslint/utils": "^6.18.1", @@ -8986,6 +9017,37 @@ "eslint": "7 || 8" } }, + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/ecma402-abstract": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", + "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==", + "dev": true, + "dependencies": { + "@formatjs/intl-localematcher": "0.5.4", + "tslib": "^2.4.0" + } + }, + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz", + "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "2.0.0", + "@formatjs/icu-skeleton-parser": "1.8.2", + "tslib": "^2.4.0" + } + }, + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz", + "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "2.0.0", + "tslib": "^2.4.0" + } + }, "node_modules/eslint-plugin-formatjs/node_modules/@typescript-eslint/scope-manager": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", @@ -9400,9 +9462,9 @@ "dev": true }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.4.tgz", - "integrity": "sha512-3ebvVgCJFy06gpmuS2ynz13uh9iFSzZ1C1dDkgcSAqVVg82zlORKMk2fvjq708pAO6bwfs5YLttknFEbaoDiGw==", + "version": "48.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.5.tgz", + "integrity": "sha512-ZeTfKV474W1N9niWfawpwsXGu+ZoMXu4417eBROX31d7ZuOk8zyG66SO77DpJ2+A9Wa2scw/jRqBPnnQo7VbcQ==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.43.0", @@ -9412,7 +9474,7 @@ "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "is-builtin-module": "^3.2.1", - "semver": "^7.6.0", + "semver": "^7.6.1", "spdx-expression-parse": "^4.0.0" }, "engines": { @@ -9434,26 +9496,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -9461,12 +9508,6 @@ "node": ">=10" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", diff --git a/package.json b/package.json index de9f1c47a..39b9422e8 100644 --- a/package.json +++ b/package.json @@ -103,9 +103,9 @@ "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", - "eslint-plugin-formatjs": "^4.13.1", + "eslint-plugin-formatjs": "^4.13.3", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.4", + "eslint-plugin-jsdoc": "^48.2.5", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", From aced12d4d778d1f5e0cd58247630b66bd2244051 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 13:28:38 +0000 Subject: [PATCH 41/49] (chore): Bump the ci-dependencies group across 1 directory with 8 updates Bumps the ci-dependencies group with 7 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@redhat-cloud-services/frontend-components](https://github.com/RedHatInsights/frontend-components) | `4.2.8` | `4.2.9` | | [@redhat-cloud-services/frontend-components-utilities](https://github.com/RedHatInsights/frontend-components) | `4.0.10` | `4.0.11` | | [@reduxjs/toolkit](https://github.com/reduxjs/redux-toolkit) | `2.2.4` | `2.2.5` | | [axios](https://github.com/axios/axios) | `1.6.8` | `1.7.0` | | [react-intl](https://github.com/formatjs/formatjs) | `6.6.6` | `6.6.8` | | [@formatjs/cli](https://github.com/formatjs/formatjs) | `6.2.10` | `6.2.12` | | [@formatjs/ecma402-abstract](https://github.com/formatjs/formatjs) | `1.18.2` | `2.0.0` | Updates `@redhat-cloud-services/frontend-components` from 4.2.8 to 4.2.9 - [Commits](https://github.com/RedHatInsights/frontend-components/commits) Updates `@redhat-cloud-services/frontend-components-utilities` from 4.0.10 to 4.0.11 - [Commits](https://github.com/RedHatInsights/frontend-components/commits) Updates `@reduxjs/toolkit` from 2.2.4 to 2.2.5 - [Release notes](https://github.com/reduxjs/redux-toolkit/releases) - [Commits](https://github.com/reduxjs/redux-toolkit/compare/v2.2.4...v2.2.5) Updates `axios` from 1.6.8 to 1.7.0 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.6.8...v1.7.0) Updates `react-intl` from 6.6.6 to 6.6.8 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/react-intl@6.6.6...react-intl@6.6.8) Updates `@formatjs/cli` from 6.2.10 to 6.2.12 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/@formatjs/cli@6.2.10...@formatjs/cli@6.2.12) Updates `@formatjs/ecma402-abstract` from 1.18.2 to 2.0.0 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/@formatjs/ecma402-abstract@1.18.2...@formatjs/ecma402-abstract@2.0.0) Updates `@formatjs/icu-messageformat-parser` from 2.7.6 to 2.7.8 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Changelog](https://github.com/formatjs/formatjs/blob/main/packages/icu-messageformat-parser/CHANGELOG.md) - [Commits](https://github.com/formatjs/formatjs/commits/@formatjs/icu-messageformat-parser@2.7.8/packages/icu-messageformat-parser) --- updated-dependencies: - dependency-name: "@redhat-cloud-services/frontend-components" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: "@redhat-cloud-services/frontend-components-utilities" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: "@reduxjs/toolkit" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ci-dependencies - dependency-name: react-intl dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: "@formatjs/cli" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: "@formatjs/ecma402-abstract" dependency-type: direct:development update-type: version-update:semver-major dependency-group: ci-dependencies - dependency-name: "@formatjs/icu-messageformat-parser" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: ci-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 215 ++++++++++++++++++---------------------------- package.json | 14 +-- 2 files changed, 89 insertions(+), 140 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2f46b650..3814ab903 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,21 +17,21 @@ "@patternfly/react-icons": "5.3.2", "@patternfly/react-table": "5.3.3", "@patternfly/react-tokens": "5.3.1", - "@redhat-cloud-services/frontend-components": "^4.2.8", + "@redhat-cloud-services/frontend-components": "^4.2.9", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", - "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", "@redhat-cloud-services/rbac-client": "^1.4.3", - "@reduxjs/toolkit": "^2.2.4", + "@reduxjs/toolkit": "^2.2.5", "@unleash/proxy-client-react": "^4.2.2", - "axios": "^1.6.8", + "axios": "^1.7.0", "date-fns": "^3.6.0", "js-file-download": "^0.4.12", "lodash": "^4.17.21", "qs": "^6.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-intl": "^6.6.6", + "react-intl": "^6.6.8", "react-redux": "^9.1.2", "react-router-dom": "^6.23.1", "redux": "^5.0.1", @@ -41,8 +41,8 @@ "victory-core": "^37.0.2" }, "devDependencies": { - "@formatjs/cli": "^6.2.10", - "@formatjs/ecma402-abstract": "^1.18.2", + "@formatjs/cli": "^6.2.12", + "@formatjs/ecma402-abstract": "^2.0.0", "@formatjs/icu-messageformat-parser": "^2.7.6", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.14", @@ -880,9 +880,9 @@ } }, "node_modules/@formatjs/cli": { - "version": "6.2.10", - "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.2.10.tgz", - "integrity": "sha512-JdFw5oqPNB4qahie2Mcg6yXxyUJouN60OaEaejjMtGsgoPbFjS7X/9/Nj5vW+rAUTi0UNbOW+JPW9XNx6EuoHw==", + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.2.12.tgz", + "integrity": "sha512-bt1NEgkeYN8N9zWcpsPu3fZ57vv+biA+NtIQBlyOZnCp1bcvh+vNTXvmwF4C5qxqDtCylpOIb3yi3Ktgp4v0JQ==", "dev": true, "bin": { "formatjs": "bin/formatjs" @@ -892,9 +892,9 @@ }, "peerDependencies": { "@glimmer/env": "^0.1.7", - "@glimmer/reference": "^0.91.1", - "@glimmer/syntax": "^0.91.1", - "@glimmer/validator": "^0.91.1", + "@glimmer/reference": "^0.91.1 || ^0.92.0", + "@glimmer/syntax": "^0.92.0", + "@glimmer/validator": "^0.92.0", "@vue/compiler-core": "^3.4.0", "content-tag": "^2.0.1", "ember-template-recast": "^6.1.4", @@ -928,9 +928,9 @@ } }, "node_modules/@formatjs/ecma402-abstract": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz", - "integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", + "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==", "dependencies": { "@formatjs/intl-localematcher": "0.5.4", "tslib": "^2.4.0" @@ -945,35 +945,35 @@ } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.6.tgz", - "integrity": "sha512-etVau26po9+eewJKYoiBKP6743I1br0/Ie00Pb/S/PtmYfmjTcOn2YCh2yNkSZI12h6Rg+BOgQYborXk46BvkA==", + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz", + "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==", "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", - "@formatjs/icu-skeleton-parser": "1.8.0", + "@formatjs/ecma402-abstract": "2.0.0", + "@formatjs/icu-skeleton-parser": "1.8.2", "tslib": "^2.4.0" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.0.tgz", - "integrity": "sha512-QWLAYvM0n8hv7Nq5BEs4LKIjevpVpbGLAJgOaYzg9wABEoX1j0JO1q2/jVkO6CVlq0dbsxZCngS5aXbysYueqA==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz", + "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==", "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/ecma402-abstract": "2.0.0", "tslib": "^2.4.0" } }, "node_modules/@formatjs/intl": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.2.tgz", - "integrity": "sha512-raPGWr3JRv3neXV78SqPFrGC05fIbhhNzVghHNxFde27ls2KkXiMhtP7HBybjGpikVSjjhdhaZto+4p1vmm9bQ==", + "version": "2.10.4", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.4.tgz", + "integrity": "sha512-56483O+HVcL0c7VucAS2tyH020mt9XTozZO67cwtGg0a7KWDukS/FzW3OnvaHmTHDuYsoPIzO+ZHVfU6fT/bJw==", "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/ecma402-abstract": "2.0.0", "@formatjs/fast-memoize": "2.2.0", - "@formatjs/icu-messageformat-parser": "2.7.6", - "@formatjs/intl-displaynames": "6.6.6", - "@formatjs/intl-listformat": "7.5.5", - "intl-messageformat": "10.5.12", + "@formatjs/icu-messageformat-parser": "2.7.8", + "@formatjs/intl-displaynames": "6.6.8", + "@formatjs/intl-listformat": "7.5.7", + "intl-messageformat": "10.5.14", "tslib": "^2.4.0" }, "peerDependencies": { @@ -986,21 +986,21 @@ } }, "node_modules/@formatjs/intl-displaynames": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-6.6.6.tgz", - "integrity": "sha512-Dg5URSjx0uzF8VZXtHb6KYZ6LFEEhCbAbKoYChYHEOnMFTw/ZU3jIo/NrujzQD2EfKPgQzIq73LOUvW6Z/LpFA==", + "version": "6.6.8", + "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-6.6.8.tgz", + "integrity": "sha512-Lgx6n5KxN16B3Pb05z3NLEBQkGoXnGjkTBNCZI+Cn17YjHJ3fhCeEJJUqRlIZmJdmaXQhjcQVDp6WIiNeRYT5g==", "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/ecma402-abstract": "2.0.0", "@formatjs/intl-localematcher": "0.5.4", "tslib": "^2.4.0" } }, "node_modules/@formatjs/intl-listformat": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-7.5.5.tgz", - "integrity": "sha512-XoI52qrU6aBGJC9KJddqnacuBbPlb/bXFN+lIFVFhQ1RnFHpzuFrlFdjD9am2O7ZSYsyqzYRpkVcXeT1GHkwDQ==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-7.5.7.tgz", + "integrity": "sha512-MG2TSChQJQT9f7Rlv+eXwUFiG24mKSzmF144PLb8m8OixyXqn4+YWU+5wZracZGCgVTVmx8viCf7IH3QXoiB2g==", "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/ecma402-abstract": "2.0.0", "@formatjs/intl-localematcher": "0.5.4", "tslib": "^2.4.0" } @@ -1036,37 +1036,6 @@ } } }, - "node_modules/@formatjs/ts-transformer/node_modules/@formatjs/ecma402-abstract": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", - "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==", - "dev": true, - "dependencies": { - "@formatjs/intl-localematcher": "0.5.4", - "tslib": "^2.4.0" - } - }, - "node_modules/@formatjs/ts-transformer/node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.7.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz", - "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==", - "dev": true, - "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "@formatjs/icu-skeleton-parser": "1.8.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@formatjs/ts-transformer/node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz", - "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==", - "dev": true, - "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "tslib": "^2.4.0" - } - }, "node_modules/@formatjs/ts-transformer/node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", @@ -2529,13 +2498,13 @@ } }, "node_modules/@redhat-cloud-services/frontend-components": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.8.tgz", - "integrity": "sha512-h9Zdl8JfS0X4EpUORAue6SR50M8xX0LOKMdnp7L9S34qix47YaJ+SydqloHQkmLhGicv6ZmI6ttbbDbEv0guLA==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.9.tgz", + "integrity": "sha512-6JEsxxp8xxBIthWxYmUIrHYbNVm+v4N7MfSxQdGr+XM6BLTp4RLUXvgFOVwWLatNxsJY88Uutoqoy0D8TM3cGw==", "dependencies": { "@patternfly/react-component-groups": "^5.0.0", "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", - "@redhat-cloud-services/types": "^0.0.24", + "@redhat-cloud-services/types": "^1.0.9", "@scalprum/core": "^0.7.0", "@scalprum/react-core": "^0.7.0", "classnames": "^2.2.5", @@ -2974,12 +2943,12 @@ "peer": true }, "node_modules/@redhat-cloud-services/frontend-components-utilities": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.10.tgz", - "integrity": "sha512-SAMXD9ciFk8aDXjt+9FnaY6VP+6RTuNswFn7a+TNROBIa0CNqb7O0x5y0gZs/Pc67xrbuxF9K5RG98qwLGdNOQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.11.tgz", + "integrity": "sha512-O4Az1B/27Cet/kHtwKtd1Pw9+zYp9XdnmYOUCypACTv9i4HJ+f6Ku7QT4VKO/9wWSGKmTu+Vq6+4ix3d5jdxrg==", "dependencies": { "@redhat-cloud-services/rbac-client": "^1.0.100", - "@redhat-cloud-services/types": "^0.0.24", + "@redhat-cloud-services/types": "^1.0.9", "@sentry/browser": "^5.30.0", "awesome-debounce-promise": "^2.1.0", "axios": "^0.28.1", @@ -2997,6 +2966,11 @@ "react-router-dom": "^5.0.0 || ^6.0.0" } }, + "node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/@redhat-cloud-services/types": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-1.0.9.tgz", + "integrity": "sha512-dKYYSLU0cwNkOSq5kSvdKWzgwFGBk45uwAwoHGi44PMQdWkuz+tXhYLrKKAXoSXVahR6VFjBDONlaxok8Lzkcw==" + }, "node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/axios": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz", @@ -3007,6 +2981,11 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/@redhat-cloud-services/frontend-components/node_modules/@redhat-cloud-services/types": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-1.0.9.tgz", + "integrity": "sha512-dKYYSLU0cwNkOSq5kSvdKWzgwFGBk45uwAwoHGi44PMQdWkuz+tXhYLrKKAXoSXVahR6VFjBDONlaxok8Lzkcw==" + }, "node_modules/@redhat-cloud-services/rbac-client": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.3.tgz", @@ -3062,12 +3041,13 @@ "node_modules/@redhat-cloud-services/types": { "version": "0.0.24", "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-0.0.24.tgz", - "integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg==" + "integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg==", + "optional": true }, "node_modules/@reduxjs/toolkit": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.4.tgz", - "integrity": "sha512-EoIC9iC2V/DLRBVMXRHrO/oM3QBT7RuJNeBRx8Cpnz/NHINeZBEqgI8YOxAYUjLp+KYxGgc4Wd6KoAKsaUBGhg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz", + "integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==", "dependencies": { "immer": "^10.0.3", "redux": "^5.0.1", @@ -5587,9 +5567,9 @@ } }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.0.tgz", + "integrity": "sha512-IiB0wQeKyPRdsFVhBgIo31FbzOyf2M6wYl7/NVutFwFBRMiAbjNiydJIHKeLmPugF4kJLfA1uWZ82Is2QzqqFA==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -9017,37 +8997,6 @@ "eslint": "7 || 8" } }, - "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/ecma402-abstract": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", - "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==", - "dev": true, - "dependencies": { - "@formatjs/intl-localematcher": "0.5.4", - "tslib": "^2.4.0" - } - }, - "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.7.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz", - "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==", - "dev": true, - "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "@formatjs/icu-skeleton-parser": "1.8.2", - "tslib": "^2.4.0" - } - }, - "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz", - "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==", - "dev": true, - "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "tslib": "^2.4.0" - } - }, "node_modules/eslint-plugin-formatjs/node_modules/@typescript-eslint/scope-manager": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", @@ -12432,13 +12381,13 @@ } }, "node_modules/intl-messageformat": { - "version": "10.5.12", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.12.tgz", - "integrity": "sha512-izl0uxhy/melhw8gP2r8pGiVieviZmM4v5Oqx3c1/R7g9cwER2smmGfSjcIsp8Y3Q53bfciL/gkxacJRx/dUvg==", + "version": "10.5.14", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.14.tgz", + "integrity": "sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==", "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/ecma402-abstract": "2.0.0", "@formatjs/fast-memoize": "2.2.0", - "@formatjs/icu-messageformat-parser": "2.7.6", + "@formatjs/icu-messageformat-parser": "2.7.8", "tslib": "^2.4.0" } }, @@ -18102,19 +18051,19 @@ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-intl": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.6.tgz", - "integrity": "sha512-dKXQNUrhZTlCp8uelYW8PHiM4saNKyLmHCfsJYWK0N/kZ/Ien35wjPHB8x9yQcTJbeN/hBOmb4x16iKUrdL9MA==", - "dependencies": { - "@formatjs/ecma402-abstract": "1.18.2", - "@formatjs/icu-messageformat-parser": "2.7.6", - "@formatjs/intl": "2.10.2", - "@formatjs/intl-displaynames": "6.6.6", - "@formatjs/intl-listformat": "7.5.5", + "version": "6.6.8", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.8.tgz", + "integrity": "sha512-M0pkhzcgV31h++2901BiRXWl69hp2zPyLxRrSwRjd1ErXbNoubz/f4M6DrRTd4OiSUrT4ajRQzrmtS5plG4FtA==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.0.0", + "@formatjs/icu-messageformat-parser": "2.7.8", + "@formatjs/intl": "2.10.4", + "@formatjs/intl-displaynames": "6.6.8", + "@formatjs/intl-listformat": "7.5.7", "@types/hoist-non-react-statics": "^3.3.1", "@types/react": "16 || 17 || 18", "hoist-non-react-statics": "^3.3.2", - "intl-messageformat": "10.5.12", + "intl-messageformat": "10.5.14", "tslib": "^2.4.0" }, "peerDependencies": { diff --git a/package.json b/package.json index 39b9422e8..73d9df3a4 100644 --- a/package.json +++ b/package.json @@ -57,21 +57,21 @@ "@patternfly/react-icons": "5.3.2", "@patternfly/react-table": "5.3.3", "@patternfly/react-tokens": "5.3.1", - "@redhat-cloud-services/frontend-components": "^4.2.8", + "@redhat-cloud-services/frontend-components": "^4.2.9", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", - "@redhat-cloud-services/frontend-components-utilities": "^4.0.10", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", "@redhat-cloud-services/rbac-client": "^1.4.3", - "@reduxjs/toolkit": "^2.2.4", + "@reduxjs/toolkit": "^2.2.5", "@unleash/proxy-client-react": "^4.2.2", - "axios": "^1.6.8", + "axios": "^1.7.0", "date-fns": "^3.6.0", "js-file-download": "^0.4.12", "lodash": "^4.17.21", "qs": "^6.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-intl": "^6.6.6", + "react-intl": "^6.6.8", "react-redux": "^9.1.2", "react-router-dom": "^6.23.1", "redux": "^5.0.1", @@ -81,8 +81,8 @@ "victory-core": "^37.0.2" }, "devDependencies": { - "@formatjs/cli": "^6.2.10", - "@formatjs/ecma402-abstract": "^1.18.2", + "@formatjs/cli": "^6.2.12", + "@formatjs/ecma402-abstract": "^2.0.0", "@formatjs/icu-messageformat-parser": "^2.7.6", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.14", From ac987c1d61a8fa8243c264271bdac547c81ca23f Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Mon, 20 May 2024 11:55:21 -0400 Subject: [PATCH 42/49] Dependency updates --- package-lock.json | 10 +++++----- package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3814ab903..c06dcd7bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "@redhat-cloud-services/rbac-client": "^1.4.3", "@reduxjs/toolkit": "^2.2.5", "@unleash/proxy-client-react": "^4.2.2", - "axios": "^1.7.0", + "axios": "^1.7.1", "date-fns": "^3.6.0", "js-file-download": "^0.4.12", "lodash": "^4.17.21", @@ -43,7 +43,7 @@ "devDependencies": { "@formatjs/cli": "^6.2.12", "@formatjs/ecma402-abstract": "^2.0.0", - "@formatjs/icu-messageformat-parser": "^2.7.6", + "@formatjs/icu-messageformat-parser": "^2.7.8", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.14", "@redhat-cloud-services/tsc-transform-imports": "^1.0.10", @@ -5567,9 +5567,9 @@ } }, "node_modules/axios": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.0.tgz", - "integrity": "sha512-IiB0wQeKyPRdsFVhBgIo31FbzOyf2M6wYl7/NVutFwFBRMiAbjNiydJIHKeLmPugF4kJLfA1uWZ82Is2QzqqFA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.1.tgz", + "integrity": "sha512-+LV37nQcd1EpFalkXksWNBiA17NZ5m5/WspmHGmZmdx1qBOg/VNq/c4eRJiA9VQQHBOs+N0ZhhdU10h2TyNK7Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 73d9df3a4..b2069e0f5 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@redhat-cloud-services/rbac-client": "^1.4.3", "@reduxjs/toolkit": "^2.2.5", "@unleash/proxy-client-react": "^4.2.2", - "axios": "^1.7.0", + "axios": "^1.7.1", "date-fns": "^3.6.0", "js-file-download": "^0.4.12", "lodash": "^4.17.21", @@ -83,7 +83,7 @@ "devDependencies": { "@formatjs/cli": "^6.2.12", "@formatjs/ecma402-abstract": "^2.0.0", - "@formatjs/icu-messageformat-parser": "^2.7.6", + "@formatjs/icu-messageformat-parser": "^2.7.8", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.4", "@redhat-cloud-services/frontend-components-config": "^6.0.14", "@redhat-cloud-services/tsc-transform-imports": "^1.0.10", From 7d4a17b7600c2e45aee5eff32aff481f03d8ff34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 10:06:44 +0000 Subject: [PATCH 43/49] (chore): Bump the lint-dependencies group with 3 updates Bumps the lint-dependencies group with 3 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc). Updates `@typescript-eslint/eslint-plugin` from 7.9.0 to 7.10.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.10.0/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 7.9.0 to 7.10.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.10.0/packages/parser) Updates `eslint-plugin-jsdoc` from 48.2.5 to 48.2.6 - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.2.5...v48.2.6) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: lint-dependencies - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: lint-dependencies - dependency-name: eslint-plugin-jsdoc dependency-type: direct:development update-type: version-update:semver-patch dependency-group: lint-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 99 ++++++++++++++++++++++++----------------------- package.json | 6 +-- 2 files changed, 53 insertions(+), 52 deletions(-) diff --git a/package-lock.json b/package-lock.json index c06dcd7bf..b5dd58d6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,14 +58,14 @@ "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.9.0", - "@typescript-eslint/parser": "^7.9.0", + "@typescript-eslint/eslint-plugin": "^7.10.0", + "@typescript-eslint/parser": "^7.10.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.3", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.5", + "eslint-plugin-jsdoc": "^48.2.6", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", @@ -4477,16 +4477,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", - "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz", + "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/type-utils": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/scope-manager": "7.10.0", + "@typescript-eslint/type-utils": "7.10.0", + "@typescript-eslint/utils": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -4510,15 +4510,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", - "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", + "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/scope-manager": "7.10.0", + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/typescript-estree": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0", "debug": "^4.3.4" }, "engines": { @@ -4538,13 +4538,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", - "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", + "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0" + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4555,13 +4555,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", - "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz", + "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/typescript-estree": "7.10.0", + "@typescript-eslint/utils": "7.10.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -4582,9 +4582,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", - "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", + "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4595,13 +4595,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", - "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", + "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4650,15 +4650,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", - "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0" + "@typescript-eslint/scope-manager": "7.10.0", + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/typescript-estree": "7.10.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4672,12 +4672,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", - "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", + "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/types": "7.10.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -6087,6 +6087,7 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, + "peer": true, "engines": { "node": ">=6" }, @@ -9411,9 +9412,9 @@ "dev": true }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.5.tgz", - "integrity": "sha512-ZeTfKV474W1N9niWfawpwsXGu+ZoMXu4417eBROX31d7ZuOk8zyG66SO77DpJ2+A9Wa2scw/jRqBPnnQo7VbcQ==", + "version": "48.2.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.6.tgz", + "integrity": "sha512-GNk9jtpYmoEVeD/U6yYYmd6T8vSOoPs7CL8ZeX85iD8P3qifDdLQGze6+cw9boobDthmYnnxvIoHrhuSffj09g==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.43.0", @@ -9422,7 +9423,6 @@ "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", - "is-builtin-module": "^3.2.1", "semver": "^7.6.1", "spdx-expression-parse": "^4.0.0" }, @@ -12522,6 +12522,7 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, + "peer": true, "dependencies": { "builtin-modules": "^3.3.0" }, diff --git a/package.json b/package.json index b2069e0f5..76c2a816f 100644 --- a/package.json +++ b/package.json @@ -98,14 +98,14 @@ "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.9.0", - "@typescript-eslint/parser": "^7.9.0", + "@typescript-eslint/eslint-plugin": "^7.10.0", + "@typescript-eslint/parser": "^7.10.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.3", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.5", + "eslint-plugin-jsdoc": "^48.2.6", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", From d69c192232dd4ec684a920ebcb08d33677715ebf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 10:07:21 +0000 Subject: [PATCH 44/49] (chore): Bump ts-jest in the test-dependencies group Bumps the test-dependencies group with 1 update: [ts-jest](https://github.com/kulshekhar/ts-jest). Updates `ts-jest` from 29.1.2 to 29.1.3 - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.2...v29.1.3) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++++----- package.json | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index c06dcd7bf..39cdc9b96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "prettier": "^3.2.5", "rimraf": "^5.0.7", "swc_mut_cjs_exports": "^0.90.24", - "ts-jest": "^29.1.2", + "ts-jest": "^29.1.3", "ts-patch": "^3.1.2", "typescript": "^5.4.5", "webpack-bundle-analyzer": "^4.10.2" @@ -20074,9 +20074,9 @@ } }, "node_modules/ts-jest": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", - "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "version": "29.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.3.tgz", + "integrity": "sha512-6L9qz3ginTd1NKhOxmkP0qU3FyKjj5CPoY+anszfVn6Pmv/RIKzhiMCsH7Yb7UvJR9I2A64rm4zQl531s2F1iw==", "dev": true, "dependencies": { "bs-logger": "0.x", @@ -20092,10 +20092,11 @@ "ts-jest": "cli.js" }, "engines": { - "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", @@ -20105,6 +20106,9 @@ "@babel/core": { "optional": true }, + "@jest/transform": { + "optional": true + }, "@jest/types": { "optional": true }, diff --git a/package.json b/package.json index b2069e0f5..7ee640e42 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "prettier": "^3.2.5", "rimraf": "^5.0.7", "swc_mut_cjs_exports": "^0.90.24", - "ts-jest": "^29.1.2", + "ts-jest": "^29.1.3", "ts-patch": "^3.1.2", "typescript": "^5.4.5", "webpack-bundle-analyzer": "^4.10.2" From c5d66c3ce8decd1007c27e96aeb0c688a99f9ebe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 10:08:54 +0000 Subject: [PATCH 45/49] (chore): Bump the ci-dependencies group with 4 updates Bumps the ci-dependencies group with 4 updates: [@redhat-cloud-services/frontend-components](https://github.com/RedHatInsights/frontend-components), [@unleash/proxy-client-react](https://github.com/Unleash/unleash-proxy-react), [axios](https://github.com/axios/axios) and [unleash-proxy-client](https://github.com/unleash/unleash-proxy-client-js). Updates `@redhat-cloud-services/frontend-components` from 4.2.9 to 4.2.10 - [Commits](https://github.com/RedHatInsights/frontend-components/commits) Updates `@unleash/proxy-client-react` from 4.2.2 to 4.2.4 - [Release notes](https://github.com/Unleash/unleash-proxy-react/releases) - [Changelog](https://github.com/Unleash/proxy-client-react/blob/main/Changelog.md) - [Commits](https://github.com/Unleash/unleash-proxy-react/compare/v4.2.2...v4.2.4) Updates `axios` from 1.7.1 to 1.7.2 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.7.1...v1.7.2) Updates `unleash-proxy-client` from 3.3.2 to 3.4.0 - [Release notes](https://github.com/unleash/unleash-proxy-client-js/releases) - [Commits](https://github.com/unleash/unleash-proxy-client-js/compare/v3.3.2...v3.4.0) --- updated-dependencies: - dependency-name: "@redhat-cloud-services/frontend-components" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: "@unleash/proxy-client-react" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ci-dependencies - dependency-name: unleash-proxy-client dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ci-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 32 ++++++++++++++++---------------- package.json | 6 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index c06dcd7bf..ee7151efa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,14 +17,14 @@ "@patternfly/react-icons": "5.3.2", "@patternfly/react-table": "5.3.3", "@patternfly/react-tokens": "5.3.1", - "@redhat-cloud-services/frontend-components": "^4.2.9", + "@redhat-cloud-services/frontend-components": "^4.2.10", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", "@redhat-cloud-services/rbac-client": "^1.4.3", "@reduxjs/toolkit": "^2.2.5", - "@unleash/proxy-client-react": "^4.2.2", - "axios": "^1.7.1", + "@unleash/proxy-client-react": "^4.2.4", + "axios": "^1.7.2", "date-fns": "^3.6.0", "js-file-download": "^0.4.12", "lodash": "^4.17.21", @@ -2498,9 +2498,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.9.tgz", - "integrity": "sha512-6JEsxxp8xxBIthWxYmUIrHYbNVm+v4N7MfSxQdGr+XM6BLTp4RLUXvgFOVwWLatNxsJY88Uutoqoy0D8TM3cGw==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.2.10.tgz", + "integrity": "sha512-4pAmnoVRkFS4h21KNnGmOZn1co4m4y8/GcCFxbnEp8nh8OWSyD2r16DPS95wG9mjcSYmPn9OQ+Ooh+PE6+/wWQ==", "dependencies": { "@patternfly/react-component-groups": "^5.0.0", "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", @@ -4707,14 +4707,14 @@ "dev": true }, "node_modules/@unleash/proxy-client-react": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@unleash/proxy-client-react/-/proxy-client-react-4.2.2.tgz", - "integrity": "sha512-KRg1dAQfxLSBe8O2i6GIGDM+7HUdUu/ntREy+JeYbmJ2b6ApFtLX/wt+3T/CjrTYjwRlZKZYJDx5E4fRDOQqpQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@unleash/proxy-client-react/-/proxy-client-react-4.2.4.tgz", + "integrity": "sha512-FWzKDqE28ZmogdXgL9caqMJTWnrVEMJWly8Ofbo1xNZHsk7R9jcWgozIXCWEPto/qijfyCBoat5xjsduT09l1g==", "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "unleash-proxy-client": "^3.2.0" + "unleash-proxy-client": "^3.4.0" } }, "node_modules/@webassemblyjs/ast": { @@ -5567,9 +5567,9 @@ } }, "node_modules/axios": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.1.tgz", - "integrity": "sha512-+LV37nQcd1EpFalkXksWNBiA17NZ5m5/WspmHGmZmdx1qBOg/VNq/c4eRJiA9VQQHBOs+N0ZhhdU10h2TyNK7Q==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -20689,9 +20689,9 @@ } }, "node_modules/unleash-proxy-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/unleash-proxy-client/-/unleash-proxy-client-3.3.2.tgz", - "integrity": "sha512-ccv+85nMJAhaaE3q4BJd4Sl894kCEbYr7CwMglvuFrBhdoOGAM5s61NXksk/aA7AGXLeAzNGH5zwY5dn0H9i9A==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/unleash-proxy-client/-/unleash-proxy-client-3.4.0.tgz", + "integrity": "sha512-ivCzm//z+S2T3gSBSZY7HN+5GfoLXZIovMyH6lIZRe2/vCicEdXtXD6cnLTQ2LAiXGV7DpoSM1m8WZGoiLRzkw==", "dependencies": { "tiny-emitter": "^2.1.0", "uuid": "^9.0.1" diff --git a/package.json b/package.json index b2069e0f5..b94fbe83b 100644 --- a/package.json +++ b/package.json @@ -57,14 +57,14 @@ "@patternfly/react-icons": "5.3.2", "@patternfly/react-table": "5.3.3", "@patternfly/react-tokens": "5.3.1", - "@redhat-cloud-services/frontend-components": "^4.2.9", + "@redhat-cloud-services/frontend-components": "^4.2.10", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", "@redhat-cloud-services/rbac-client": "^1.4.3", "@reduxjs/toolkit": "^2.2.5", - "@unleash/proxy-client-react": "^4.2.2", - "axios": "^1.7.1", + "@unleash/proxy-client-react": "^4.2.4", + "axios": "^1.7.2", "date-fns": "^3.6.0", "js-file-download": "^0.4.12", "lodash": "^4.17.21", From f6e911f8749dfebc1c12227280b3b5a527729c24 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 29 May 2024 11:02:20 -0400 Subject: [PATCH 46/49] Dependency updates --- package-lock.json | 278 ++++++++++++++++++++++++---------------------- package.json | 11 +- 2 files changed, 153 insertions(+), 136 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3061f6352..dfecdf53d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", - "@redhat-cloud-services/rbac-client": "^1.4.3", + "@redhat-cloud-services/rbac-client": "^1.4.4", "@reduxjs/toolkit": "^2.2.5", "@unleash/proxy-client-react": "^4.2.4", "axios": "^1.7.2", @@ -37,7 +37,6 @@ "redux": "^5.0.1", "redux-thunk": "^3.1.0", "typesafe-actions": "^5.1.0", - "unleash-proxy-client": "^3.3.2", "victory-core": "^37.0.2" }, "devDependencies": { @@ -54,12 +53,12 @@ "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", - "@types/react": "^18.3.2", + "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.10.0", + "@typescript-eslint/eslint-plugin": "^7.11.0", + "@typescript-eslint/parser": "^7.11.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", @@ -69,7 +68,7 @@ "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.34.1", + "eslint-plugin-react": "^7.34.2", "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-sort-keys-fix": "^1.1.2", "eslint-plugin-testing-library": "^6.2.2", @@ -2987,9 +2986,9 @@ "integrity": "sha512-dKYYSLU0cwNkOSq5kSvdKWzgwFGBk45uwAwoHGi44PMQdWkuz+tXhYLrKKAXoSXVahR6VFjBDONlaxok8Lzkcw==" }, "node_modules/@redhat-cloud-services/rbac-client": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.3.tgz", - "integrity": "sha512-c/GD3szEY7Thh24VSO0WTZKFIC4BJQ14ujqA7cAc7fZQPXeo48RFPBEGiOGTU/iS16oG9OuQAMJrZYVrts/oCg==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.4.4.tgz", + "integrity": "sha512-I5NE+Xllg8x1qxAorHK4s1CBairnLi4wq3kSIhMinlYrKWZRu/0j2JlDBTTWGmZfsVXAi1Tca0Z0N6u553iRTw==", "dependencies": { "axios": "^0.27.2", "tslib": "^2.6.2" @@ -4240,9 +4239,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.3.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", - "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4477,16 +4476,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz", - "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", + "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/type-utils": "7.10.0", - "@typescript-eslint/utils": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/type-utils": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -4510,15 +4509,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", - "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4" }, "engines": { @@ -4538,13 +4537,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", - "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0" + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4555,13 +4554,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz", - "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", + "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/utils": "7.10.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/utils": "7.11.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -4582,9 +4581,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", - "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4595,13 +4594,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", - "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4650,15 +4649,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", - "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", + "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0" + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -4672,12 +4671,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", - "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/types": "7.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -5228,15 +5227,16 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -5284,15 +5284,16 @@ } }, "node_modules/array.prototype.findlast": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz", - "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", + "es-abstract": "^1.23.2", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" }, "engines": { @@ -8450,9 +8451,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", - "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -8494,11 +8495,11 @@ "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.7", + "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.15" }, @@ -8555,14 +8556,14 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -9781,29 +9782,29 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", + "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" + "string.prototype.matchall": "^4.0.11" }, "engines": { "node": ">=4" @@ -16847,28 +16848,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -16891,27 +16893,31 @@ } }, "node_modules/object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -19501,20 +19507,26 @@ "devOptional": true }, "node_modules/string.prototype.matchall": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", - "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19570,14 +19582,17 @@ } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19940,7 +19955,8 @@ "node_modules/tiny-emitter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "peer": true }, "node_modules/tiny-warning": { "version": "1.0.3", @@ -20577,9 +20593,9 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -20697,6 +20713,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/unleash-proxy-client/-/unleash-proxy-client-3.4.0.tgz", "integrity": "sha512-ivCzm//z+S2T3gSBSZY7HN+5GfoLXZIovMyH6lIZRe2/vCicEdXtXD6cnLTQ2LAiXGV7DpoSM1m8WZGoiLRzkw==", + "peer": true, "dependencies": { "tiny-emitter": "^2.1.0", "uuid": "^9.0.1" @@ -20710,6 +20727,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "peer": true, "bin": { "uuid": "dist/bin/uuid" } diff --git a/package.json b/package.json index ca750545b..f2e3418a2 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-translations": "^3.2.7", "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", - "@redhat-cloud-services/rbac-client": "^1.4.3", + "@redhat-cloud-services/rbac-client": "^1.4.4", "@reduxjs/toolkit": "^2.2.5", "@unleash/proxy-client-react": "^4.2.4", "axios": "^1.7.2", @@ -77,7 +77,6 @@ "redux": "^5.0.1", "redux-thunk": "^3.1.0", "typesafe-actions": "^5.1.0", - "unleash-proxy-client": "^3.3.2", "victory-core": "^37.0.2" }, "devDependencies": { @@ -94,12 +93,12 @@ "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/qs": "^6.9.15", - "@types/react": "^18.3.2", + "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.10.0", + "@typescript-eslint/eslint-plugin": "^7.11.0", + "@typescript-eslint/parser": "^7.11.0", "aphrodite": "^2.4.0", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", @@ -109,7 +108,7 @@ "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.34.1", + "eslint-plugin-react": "^7.34.2", "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-sort-keys-fix": "^1.1.2", "eslint-plugin-testing-library": "^6.2.2", From 3fd1ed10635cb6b4f4acf39908996a90a8703b6e Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 29 May 2024 11:34:39 -0400 Subject: [PATCH 47/49] Tags link fix https://issues.redhat.com/browse/COST-4855 --- src/routes/details/components/tag/tagLink.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/details/components/tag/tagLink.tsx b/src/routes/details/components/tag/tagLink.tsx index 6f2c477ae..be581b635 100644 --- a/src/routes/details/components/tag/tagLink.tsx +++ b/src/routes/details/components/tag/tagLink.tsx @@ -56,15 +56,15 @@ class TagLinkBase extends React.Component { } public componentDidMount() { - const { fetchTag, tagData, tagPathsType, tagQueryString } = this.props; - if (!tagData) { + const { fetchTag, tagPathsType, tagQueryString } = this.props; + if (tagPathsType) { fetchTag(tagPathsType, tagType, tagQueryString); } } public componentDidUpdate(prevProps: TagLinkProps) { - const { fetchTag, tagData, tagPathsType, tagQueryString } = this.props; - if (prevProps.tagQueryString !== tagQueryString && !tagData) { + const { fetchTag, tagPathsType, tagQueryString } = this.props; + if (prevProps.tagQueryString !== tagQueryString && tagPathsType) { fetchTag(tagPathsType, tagType, tagQueryString); } } From 0b389c9024f1522ef6df608a9ee1d4424ba8f2f4 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 29 May 2024 11:37:25 -0400 Subject: [PATCH 48/49] Dependency update --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index dfecdf53d..4adc8f357 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "prettier": "^3.2.5", "rimraf": "^5.0.7", "swc_mut_cjs_exports": "^0.90.24", - "ts-jest": "^29.1.3", + "ts-jest": "^29.1.4", "ts-patch": "^3.1.2", "typescript": "^5.4.5", "webpack-bundle-analyzer": "^4.10.2" @@ -20091,9 +20091,9 @@ } }, "node_modules/ts-jest": { - "version": "29.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.3.tgz", - "integrity": "sha512-6L9qz3ginTd1NKhOxmkP0qU3FyKjj5CPoY+anszfVn6Pmv/RIKzhiMCsH7Yb7UvJR9I2A64rm4zQl531s2F1iw==", + "version": "29.1.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.4.tgz", + "integrity": "sha512-YiHwDhSvCiItoAgsKtoLFCuakDzDsJ1DLDnSouTaTmdOcOwIkSzbLXduaQ6M5DRVhuZC/NYaaZ/mtHbWMv/S6Q==", "dev": true, "dependencies": { "bs-logger": "0.x", diff --git a/package.json b/package.json index f2e3418a2..8463bbeb3 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "prettier": "^3.2.5", "rimraf": "^5.0.7", "swc_mut_cjs_exports": "^0.90.24", - "ts-jest": "^29.1.3", + "ts-jest": "^29.1.4", "ts-patch": "^3.1.2", "typescript": "^5.4.5", "webpack-bundle-analyzer": "^4.10.2" From b95ec8b0ad2cbe2b407eb17aa842a74cd00582c9 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Wed, 29 May 2024 13:30:32 -0400 Subject: [PATCH 49/49] Dependency updates --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4adc8f357..7af60a2b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,7 +64,7 @@ "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.3", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.6", + "eslint-plugin-jsdoc": "^48.2.7", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3", @@ -745,9 +745,9 @@ "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.0.tgz", - "integrity": "sha512-Q1CnsQrytI3TlCB1IVWXWeqUIPGVEKGaE7IbVdt13Nq/3i0JESAkQQERrfiQkmlpijl+++qyqPgaS31Bvc1jRQ==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "dependencies": { "@types/eslint": "^8.56.5", @@ -9413,18 +9413,18 @@ "dev": true }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.6.tgz", - "integrity": "sha512-GNk9jtpYmoEVeD/U6yYYmd6T8vSOoPs7CL8ZeX85iD8P3qifDdLQGze6+cw9boobDthmYnnxvIoHrhuSffj09g==", + "version": "48.2.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.7.tgz", + "integrity": "sha512-fYj3roTnkFL9OFFTB129rico8lerC5G8Vp2ZW9SjO9RNWG0exVvI+i/Y8Bpm1ufjR0uvT38xtoab/U0Hp8Ybog==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.43.0", + "@es-joy/jsdoccomment": "~0.43.1", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", - "semver": "^7.6.1", + "semver": "^7.6.2", "spdx-expression-parse": "^4.0.0" }, "engines": { diff --git a/package.json b/package.json index 8463bbeb3..f76f4345d 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.3", "eslint-plugin-jest-dom": "^5.4.0", - "eslint-plugin-jsdoc": "^48.2.6", + "eslint-plugin-jsdoc": "^48.2.7", "eslint-plugin-markdown": "^5.0.0", "eslint-plugin-patternfly-react": "^5.3.0", "eslint-plugin-prettier": "^5.1.3",