foreman_rh_cloud 14.1.3 → 14.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +157 -5
  3. data/lib/foreman_rh_cloud/plugin.rb +16 -5
  4. data/lib/foreman_rh_cloud/version.rb +1 -1
  5. data/package.json +1 -1
  6. data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +240 -4
  7. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.fixtures.js +0 -6
  8. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListReducer.js +0 -2
  9. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/EmptyResults.js +15 -6
  10. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/emptyResults.scss +1 -5
  11. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/EmptyState.js +15 -7
  12. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/__tests__/EmptyState.test.js +1 -3
  13. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/emptyState.scss +1 -5
  14. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ErrorState/ErrorState.js +2 -2
  15. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/ListItem.test.js +0 -1
  16. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountList.test.js +2 -6
  17. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListReducer.test.js +0 -2
  18. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/Components/ClearButton/ClearButton.js +13 -10
  19. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +30 -11
  20. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/integration.test.js +3 -1
  21. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/inventoryFilter.scss +28 -22
  22. data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettings.js +4 -4
  23. data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettings.scss +16 -3
  24. data/webpack/ForemanInventoryUpload/Components/InventorySettings/MinimalInventoryDropdown.js +13 -14
  25. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +7 -9
  26. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.scss +3 -3
  27. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +65 -42
  28. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageHeader.test.js +4 -12
  29. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageTitle.test.js +110 -6
  30. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +31 -38
  31. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButton.test.js +3 -1
  32. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/ToolbarButtons.js +0 -4
  33. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/__tests__/ToolbarButtons.test.js +18 -47
  34. data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +4 -4
  35. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +29 -22
  36. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/InventoryAutoUpload.test.js +6 -2
  37. data/webpack/ForemanInventoryUpload/__tests__/ForemanInventoryHelpers.test.js +19 -1
  38. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +90 -23
  39. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +1 -2
  40. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +24 -30
  41. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js +5 -6
  42. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +193 -8
  43. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableActions.test.js +4 -1
  44. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +8 -9
  45. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +26 -13
  46. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationTableConstants.js +12 -10
  47. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +21 -9
  48. data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +12 -19
  49. data/webpack/InsightsCloudSync/__tests__/InsightsCloudSyncActions.test.js +0 -1
  50. data/webpack/common/DropdownToggle.js +20 -6
  51. metadata +2 -54
  52. data/webpack/ForemanInventoryUpload/Components/FileDownload/FileDownload.fixtures.js +0 -0
  53. data/webpack/ForemanInventoryUpload/Components/FileDownload/FileDownload.js +0 -25
  54. data/webpack/ForemanInventoryUpload/Components/FileDownload/FileDownloadHelper.js +0 -0
  55. data/webpack/ForemanInventoryUpload/Components/FileDownload/__tests__/FileDownload.test.js +0 -17
  56. data/webpack/ForemanInventoryUpload/Components/FileDownload/fileDownload.scss +0 -5
  57. data/webpack/ForemanInventoryUpload/Components/FileDownload/index.js +0 -1
  58. data/webpack/ForemanInventoryUpload/Components/NavContainer/NavContainer.fixtures.js +0 -20
  59. data/webpack/ForemanInventoryUpload/Components/NavContainer/NavContainer.js +0 -66
  60. data/webpack/ForemanInventoryUpload/Components/NavContainer/NavContainerHelper.js +0 -0
  61. data/webpack/ForemanInventoryUpload/Components/NavContainer/__tests__/NavContainer.test.js +0 -69
  62. data/webpack/ForemanInventoryUpload/Components/NavContainer/index.js +0 -1
  63. data/webpack/ForemanInventoryUpload/Components/NavContainer/navContainer.scss +0 -9
  64. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorActions.js +0 -21
  65. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +0 -59
  66. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorConstants.js +0 -6
  67. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorSelectors.js +0 -19
  68. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorButton.test.js +0 -51
  69. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/index.js +0 -34
  70. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.js +0 -66
  71. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.test.js +0 -61
  72. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/index.js +0 -25
  73. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/ScheduledRun.fixtures.js +0 -4
  74. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/ScheduledRun.js +0 -29
  75. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/ScheduledRunHelper.js +0 -0
  76. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/ScheduledRun.test.js +0 -33
  77. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/index.js +0 -12
  78. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/scheduledRun.scss +0 -13
  79. data/webpack/ForemanInventoryUpload/Components/StatusChart/StatusChart.fixtures.js +0 -0
  80. data/webpack/ForemanInventoryUpload/Components/StatusChart/StatusChart.js +0 -57
  81. data/webpack/ForemanInventoryUpload/Components/StatusChart/StatusChartHelper.js +0 -0
  82. data/webpack/ForemanInventoryUpload/Components/StatusChart/__tests__/StatusChart.test.js +0 -30
  83. data/webpack/ForemanInventoryUpload/Components/StatusChart/index.js +0 -1
  84. data/webpack/ForemanInventoryUpload/Components/StatusChart/statusChart.scss +0 -10
  85. data/webpack/ForemanInventoryUpload/Components/TabContainer/TabContainer.fixtures.js +0 -0
  86. data/webpack/ForemanInventoryUpload/Components/TabContainer/TabContainer.js +0 -24
  87. data/webpack/ForemanInventoryUpload/Components/TabContainer/TabContainerHelper.js +0 -0
  88. data/webpack/ForemanInventoryUpload/Components/TabContainer/__tests__/TabContainer.test.js +0 -15
  89. data/webpack/ForemanInventoryUpload/Components/TabContainer/index.js +0 -1
  90. data/webpack/ForemanInventoryUpload/Components/TabContainer/tabContainer.scss +0 -10
  91. data/webpack/ForemanInventoryUpload/Components/TabFooter/TabFooter.fixtures.js +0 -0
  92. data/webpack/ForemanInventoryUpload/Components/TabFooter/TabFooter.js +0 -19
  93. data/webpack/ForemanInventoryUpload/Components/TabFooter/TabFooterHelper.js +0 -0
  94. data/webpack/ForemanInventoryUpload/Components/TabFooter/__tests__/TabFooter.test.js +0 -15
  95. data/webpack/ForemanInventoryUpload/Components/TabFooter/index.js +0 -1
  96. data/webpack/ForemanInventoryUpload/Components/TabFooter/tabFooter.scss +0 -0
  97. data/webpack/ForemanInventoryUpload/Components/TabHeader/TabHeader.fixtures.js +0 -0
  98. data/webpack/ForemanInventoryUpload/Components/TabHeader/TabHeader.js +0 -85
  99. data/webpack/ForemanInventoryUpload/Components/TabHeader/TabHeaderHelper.js +0 -0
  100. data/webpack/ForemanInventoryUpload/Components/TabHeader/__tests__/TabHeader.test.js +0 -114
  101. data/webpack/ForemanInventoryUpload/Components/TabHeader/index.js +0 -1
  102. data/webpack/ForemanInventoryUpload/Components/TabHeader/tabHeader.scss +0 -23
  103. data/webpack/common/Switcher/index.js +0 -80
@@ -1,15 +1,23 @@
1
1
  import React from 'react';
2
- import { EmptyState, Spinner } from 'patternfly-react';
2
+ import {
3
+ EmptyState,
4
+ EmptyStateHeader,
5
+ EmptyStateIcon,
6
+ EmptyStateBody,
7
+ EmptyStateVariant,
8
+ Spinner,
9
+ } from '@patternfly/react-core';
3
10
  import { translate as __ } from 'foremanReact/common/I18n';
4
11
  import './emptyState.scss';
5
12
 
6
13
  const inventoryEmptyState = () => (
7
- <EmptyState>
8
- <Spinner loading inline size="lg" />
9
- <EmptyState.Title>
10
- {__('Fetching data about your accounts')}
11
- </EmptyState.Title>
12
- <EmptyState.Info>{__('Loading...')}</EmptyState.Info>
14
+ <EmptyState variant={EmptyStateVariant.lg}>
15
+ <EmptyStateIcon icon={Spinner} />
16
+ <EmptyStateHeader
17
+ titleText={<>{__('Fetching data about your accounts')}</>}
18
+ headingLevel="h2"
19
+ />
20
+ <EmptyStateBody>{__('Loading...')}</EmptyStateBody>
13
21
  </EmptyState>
14
22
  );
15
23
 
@@ -5,9 +5,7 @@ import EmptyState from '../EmptyState';
5
5
  describe('EmptyState', () => {
6
6
  it('renders fetching data message', () => {
7
7
  render(<EmptyState />);
8
- expect(
9
- screen.getByText('Fetching data about your accounts')
10
- ).toBeTruthy();
8
+ expect(screen.getByText('Fetching data about your accounts')).toBeTruthy();
11
9
  });
12
10
 
13
11
  it('renders loading indicator', () => {
@@ -1,9 +1,5 @@
1
1
  .rh-cloud-inventory-page {
2
- .blank-slate-pf {
2
+ .pf-v5-c-empty-state {
3
3
  margin-top: 100px;
4
-
5
- .spinner {
6
- float: none;
7
- }
8
4
  }
9
5
  }
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Icon } from 'patternfly-react';
3
+ import { TimesIcon } from '@patternfly/react-icons';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
  import './errorState.scss';
6
6
 
7
7
  const ErrorState = ({ error }) => (
8
8
  <div className="error_state">
9
- <Icon className="error_icon" name="times" size="2x" />
9
+ <TimesIcon className="error_icon" size="xl" />
10
10
  <p>{__('Encountered an error while trying to access the server:')}</p>
11
11
  <p className="error_description">{error}</p>
12
12
  </div>
@@ -32,5 +32,4 @@ describe('ListItem', () => {
32
32
  expect(screen.getByText('Generated')).toBeTruthy();
33
33
  expect(screen.getByText('Uploaded')).toBeTruthy();
34
34
  });
35
-
36
35
  });
@@ -3,9 +3,7 @@ import { render, screen } from '@testing-library/react';
3
3
  import AccountList from '../AccountList';
4
4
  import { accounts } from '../AccountList.fixtures';
5
5
 
6
- jest.mock('../Components/ListItem', () => ({ label }) => (
7
- <div>{label}</div>
8
- ));
6
+ jest.mock('../Components/ListItem', () => ({ label }) => <div>{label}</div>);
9
7
 
10
8
  describe('AccountList', () => {
11
9
  it('renders account labels', () => {
@@ -26,9 +24,7 @@ describe('AccountList', () => {
26
24
 
27
25
  it('shows empty state when accounts are empty', () => {
28
26
  render(<AccountList accounts={{}} />);
29
- expect(
30
- screen.getByText('Fetching data about your accounts')
31
- ).toBeTruthy();
27
+ expect(screen.getByText('Fetching data about your accounts')).toBeTruthy();
32
28
  });
33
29
 
34
30
  it('shows error state when error is present', () => {
@@ -13,7 +13,6 @@ import {
13
13
  processStatusName,
14
14
  pollingResponse,
15
15
  accounts,
16
- CloudConnectorStatus,
17
16
  } from '../AccountList.fixtures';
18
17
 
19
18
  describe('AccountList reducer', () => {
@@ -30,7 +29,6 @@ describe('AccountList reducer', () => {
30
29
  payload: pollingResponse,
31
30
  });
32
31
  expect(state.accounts).toEqual(accounts);
33
- expect(state.CloudConnectorStatus).toEqual(CloudConnectorStatus);
34
32
  expect(state.error).toBeNull();
35
33
  });
36
34
 
@@ -1,19 +1,22 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { noop } from 'foremanReact/common/helpers';
4
- import { Icon, OverlayTrigger, Tooltip } from 'patternfly-react';
4
+ import { Tooltip, Button } from '@patternfly/react-core';
5
+ import { TimesIcon } from '@patternfly/react-icons';
5
6
  import { translate as __ } from 'foremanReact/common/I18n';
6
7
 
7
8
  const ClearButton = ({ onClear }) => (
8
- <OverlayTrigger
9
- overlay={
10
- <Tooltip id="inventory_filter_clear_overlay">{__('Clear')}</Tooltip>
11
- }
12
- placement="top"
13
- trigger={['hover', 'focus']}
14
- >
15
- <Icon name="close" className="inventory-clear-button" onClick={onClear} />
16
- </OverlayTrigger>
9
+ <Tooltip content={__('Clear')} position="top">
10
+ <Button
11
+ variant="plain"
12
+ className="inventory-clear-button"
13
+ onClick={onClear}
14
+ aria-label={__('Clear')}
15
+ ouiaId="inventory-clear-button"
16
+ >
17
+ <TimesIcon />
18
+ </Button>
19
+ </Tooltip>
17
20
  );
18
21
 
19
22
  ClearButton.propTypes = {
@@ -1,11 +1,17 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
2
  import React, { useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { FormGroup, TextInput } from '@patternfly/react-core';
4
+ import {
5
+ FormGroup,
6
+ TextInput,
7
+ InputGroup,
8
+ InputGroupItem,
9
+ Button,
10
+ } from '@patternfly/react-core';
11
+ import { TimesIcon } from '@patternfly/react-icons';
5
12
  import { noop } from 'foremanReact/common/helpers';
6
13
  import { translate as __ } from 'foremanReact/common/I18n';
7
14
  import { useForemanOrganization } from 'foremanReact/Root/Context/ForemanContext';
8
- import ClearButton from './Components/ClearButton';
9
15
  import './inventoryFilter.scss';
10
16
  import { ANY_ORGANIZATION } from './InventoryFilterConstants';
11
17
 
@@ -24,15 +30,28 @@ const InventoryFilter = ({
24
30
  return (
25
31
  <form id="inventory_filter_form">
26
32
  <FormGroup>
27
- <TextInput
28
- id="inventory_filter_input"
29
- ouiaId="inventory_filter_input"
30
- value={filterTerm}
31
- type="text"
32
- placeholder={__('Filter..')}
33
- onChange={(e, v) => handleFilterChange(v)}
34
- />
35
- <ClearButton onClear={handleFilterClear} />
33
+ <InputGroup>
34
+ <InputGroupItem isFill>
35
+ <TextInput
36
+ id="inventory_filter_input"
37
+ ouiaId="inventory_filter_input"
38
+ value={filterTerm}
39
+ type="text"
40
+ placeholder={__('Filter..')}
41
+ onChange={(e, v) => handleFilterChange(v)}
42
+ />
43
+ </InputGroupItem>
44
+ <InputGroupItem>
45
+ <Button
46
+ ouiaId="inventory-filter-clear-button"
47
+ variant="plain"
48
+ aria-label={__('Clear')}
49
+ onClick={handleFilterClear}
50
+ >
51
+ <TimesIcon />
52
+ </Button>
53
+ </InputGroupItem>
54
+ </InputGroup>
36
55
  </FormGroup>
37
56
  </form>
38
57
  );
@@ -31,7 +31,9 @@ describe('InventoryFilter integration test', () => {
31
31
 
32
32
  const actions = store.getActions();
33
33
  const filterAction = actions.find(
34
- a => a.type === INVENTORY_FILTER_UPDATE && a.payload.filterTerm === 'some_new_filter'
34
+ a =>
35
+ a.type === INVENTORY_FILTER_UPDATE &&
36
+ a.payload.filterTerm === 'some_new_filter'
35
37
  );
36
38
  expect(filterAction).toBeTruthy();
37
39
  });
@@ -1,28 +1,34 @@
1
1
  #inventory_filter_form {
2
- .pf-v5-c-form__group-control {
3
- display: -ms-flexbox;
4
- display: -webkit-flex;
5
- display: flex;
6
- -webkit-flex-direction: row;
7
- -ms-flex-direction: row;
8
- flex-direction: row;
9
- -webkit-flex-wrap: nowrap;
10
- -ms-flex-wrap: nowrap;
11
- flex-wrap: nowrap;
12
- -webkit-justify-content: flex-end;
13
- -ms-flex-pack: end;
14
- justify-content: flex-end;
15
- -webkit-align-content: center;
16
- -ms-flex-line-pack: center;
17
- align-content: center;
18
- -webkit-align-items: center;
19
- -ms-flex-align: center;
20
- align-items: center;
2
+ .pf-v5-c-form__group {
21
3
  margin-bottom: 0;
4
+ }
5
+
6
+ .pf-v5-c-input-group {
7
+ width: 100%;
8
+ position: relative;
9
+
10
+ .pf-v5-c-input-group__item {
11
+ &:last-child {
12
+ position: absolute;
13
+ right: 0;
14
+ top: 0;
15
+ bottom: 0;
16
+ display: flex;
17
+ align-items: center;
18
+ pointer-events: auto;
19
+
20
+ .pf-v5-c-button {
21
+ margin-right: 8px;
22
+ }
23
+ }
24
+
25
+ &:first-child {
26
+ flex: 1;
22
27
 
23
- .inventory-clear-button {
24
- position: absolute;
25
- right: 27px;
28
+ .pf-v5-c-form-control {
29
+ padding-right: 40px;
30
+ }
31
+ }
26
32
  }
27
33
  }
28
34
  }
@@ -52,12 +52,12 @@ const InventorySettings = () => {
52
52
  })}
53
53
  <MinimalInventoryDropdown setChosenValue={setChosenValue} />
54
54
  {Object.keys(childSettingsDict).length > 0 && ( // Only render this section if there are child settings
55
- <div style={{ marginTop: '1.5em' }}>
55
+ <div className="child-settings">
56
56
  <Flex>
57
- <FlexItem>
58
- <span style={{ width: '6em' }} />
57
+ <FlexItem flex={{ default: 'flexNone' }}>
58
+ <span className="child-settings-spacer" />
59
59
  </FlexItem>
60
- <FlexItem>
60
+ <FlexItem flex={{ default: 'flex_1' }}>
61
61
  {Object.keys(childSettingsDict).map(key => (
62
62
  <AdvancedSetting
63
63
  key={key}
@@ -1,14 +1,27 @@
1
1
  .rh-cloud-inventory-page {
2
2
  .inventory-settings {
3
- border: 1px solid #ededed;
4
- border-radius: 4px;
3
+ border: 1px solid var(--pf-v5-global--BorderColor--100);
4
+ border-radius: var(--pf-v5-global--BorderRadius--sm);
5
5
  padding: 10px;
6
- margin-bottom: 15px;
6
+ margin-bottom: var(--pf-v5-global--spacer--md);
7
+ margin-left: 20px;
7
8
  float: right;
9
+ max-width: 450px;
8
10
 
9
11
  h3 {
10
12
  margin-top: 0;
13
+ margin-bottom: 10px;
11
14
  font-weight: 600;
15
+ font-size: var(--pf-v5-global--FontSize--md);
16
+ }
17
+
18
+ .child-settings {
19
+ margin-top: 10px;
20
+ margin-left: 0;
21
+
22
+ .child-settings-spacer {
23
+ display: none;
24
+ }
12
25
  }
13
26
  }
14
27
  }
@@ -72,6 +72,7 @@ const MinimalInventoryDropdown = ({ setChosenValue }) => {
72
72
  isOpen={isOpen}
73
73
  onSelect={onSelect}
74
74
  onOpenChange={val => setIsOpen(val)}
75
+ popperProps={{ width: '350px' }}
75
76
  toggle={toggleRef => (
76
77
  <MenuToggle
77
78
  ref={toggleRef}
@@ -84,20 +85,18 @@ const MinimalInventoryDropdown = ({ setChosenValue }) => {
84
85
  )}
85
86
  shouldFocusToggleOnSelect
86
87
  >
87
- <div style={{ maxWidth: '28em' }}>
88
- <DropdownList>
89
- {Object.entries(dropdownValues).map(([value, item]) => (
90
- <DropdownItem
91
- value={value}
92
- key={value}
93
- description={item.description}
94
- ouiaId={`inventory-dropdownItem-${value}`}
95
- >
96
- {item.title}
97
- </DropdownItem>
98
- ))}
99
- </DropdownList>
100
- </div>
88
+ <DropdownList>
89
+ {Object.entries(dropdownValues).map(([value, item]) => (
90
+ <DropdownItem
91
+ value={value}
92
+ key={value}
93
+ description={item.description}
94
+ ouiaId={`inventory-dropdownItem-${value}`}
95
+ >
96
+ {item.title}
97
+ </DropdownItem>
98
+ ))}
99
+ </DropdownList>
101
100
  </Dropdown>
102
101
  );
103
102
  };
@@ -1,10 +1,9 @@
1
1
  import React from 'react';
2
- import { Grid } from 'patternfly-react';
2
+ import { Grid, GridItem } from '@patternfly/react-core';
3
3
  import InventorySettings from '../InventorySettings';
4
4
  import PageDescription from './components/PageDescription';
5
5
  import InventoryFilter from '../InventoryFilter';
6
6
  import ToolbarButtons from './components/ToolbarButtons';
7
- import SettingsWarning from './components/SettingsWarning';
8
7
  import PageTitle from './PageTitle';
9
8
  import { useIopConfig } from '../../../common/Hooks/ConfigHooks';
10
9
  import './PageHeader.scss';
@@ -14,7 +13,6 @@ const PageHeader = () => {
14
13
 
15
14
  return (
16
15
  <div className="inventory-upload-header">
17
- <SettingsWarning />
18
16
  <PageTitle />
19
17
  {!isIop && (
20
18
  <div className="inventory-upload-header-description">
@@ -22,14 +20,14 @@ const PageHeader = () => {
22
20
  <PageDescription />
23
21
  </div>
24
22
  )}
25
- <Grid.Row>
26
- <Grid.Col xs={4}>
23
+ <Grid hasGutter>
24
+ <GridItem span={4}>
27
25
  <InventoryFilter />
28
- </Grid.Col>
29
- <Grid.Col xs={7} xsOffset={1}>
26
+ </GridItem>
27
+ <GridItem span={8}>
30
28
  <ToolbarButtons />
31
- </Grid.Col>
32
- </Grid.Row>
29
+ </GridItem>
30
+ </Grid>
33
31
  </div>
34
32
  );
35
33
  };
@@ -1,6 +1,6 @@
1
1
  .rh-cloud-inventory-page {
2
2
  .inventory-upload-header {
3
- margin-top: 35px;
3
+ padding: var(--pf-v5-global--spacer--md) 0 var(--pf-v5-global--spacer--lg) var(--pf-v5-global--spacer--lg);
4
4
 
5
5
  h1 {
6
6
  font-family: 'RedHatDisplay';
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  .pf-v5-c-dropdown__toggle {
16
- margin-right: -20px;
16
+ margin-right: 0;
17
17
  }
18
18
 
19
19
  .settings-alert {
@@ -33,12 +33,12 @@
33
33
  }
34
34
 
35
35
  .inventory-upload-header-title {
36
- margin-top: -15px;
37
36
  margin-bottom: 8px;
38
37
  }
39
38
 
40
39
  .title-dropdown {
41
40
  float: right;
41
+ margin-right: -24px;
42
42
  }
43
43
  }
44
44
  }
@@ -1,11 +1,14 @@
1
1
  import React, { useState } from 'react';
2
- import { Grid, GridItem } from '@patternfly/react-core';
3
2
  import {
3
+ Grid,
4
+ GridItem,
4
5
  Dropdown,
5
6
  DropdownItem,
6
- KebabToggle,
7
- DropdownPosition,
8
- } from '@patternfly/react-core/deprecated';
7
+ DropdownList,
8
+ MenuToggle,
9
+ } from '@patternfly/react-core';
10
+ import { EllipsisVIcon } from '@patternfly/react-icons';
11
+ import { translate as __ } from 'foremanReact/common/I18n';
9
12
  import Head from 'foremanReact/components/Head';
10
13
  import {
11
14
  INVENTORY_PAGE_TITLE,
@@ -18,38 +21,14 @@ import {
18
21
  getInventoryDocsUrl,
19
22
  } from '../../ForemanInventoryHelpers';
20
23
  import CloudPingModal from './components/CloudPingModal';
24
+ import { useIopConfig } from '../../../common/Hooks/ConfigHooks';
21
25
 
22
26
  const PageTitle = () => {
23
27
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
28
+ const isIop = useIopConfig();
24
29
  const [showPingModal, setPingModal] = useState(false);
25
30
  const togglePingModal = () => setPingModal(v => !v);
26
- const dropdownItems = [
27
- <DropdownItem
28
- key="tasks-history-button"
29
- ouiaId="tasks-history-button"
30
- href={getActionsHistoryUrl()}
31
- target="_blank"
32
- rel="noopener noreferrer"
33
- >
34
- {ACTIONS_HISTORY_BUTTON_TEXT}
35
- </DropdownItem>,
36
- <DropdownItem
37
- key="inventory-documentation-button"
38
- ouiaId="inventory-documentation-button"
39
- href={getInventoryDocsUrl()}
40
- target="_blank"
41
- rel="noopener noreferrer"
42
- >
43
- {DOCS_BUTTON_TEXT}
44
- </DropdownItem>,
45
- <DropdownItem
46
- key="cloud-ping"
47
- ouiaId="dropdownItem-cloud-ping"
48
- onClick={togglePingModal}
49
- >
50
- {CLOUD_PING_TITLE}
51
- </DropdownItem>,
52
- ];
31
+
53
32
  return (
54
33
  <Grid className="inventory-upload-header-title">
55
34
  <GridItem span={6}>
@@ -58,21 +37,65 @@ const PageTitle = () => {
58
37
  </Head>
59
38
  <h1>{INVENTORY_PAGE_TITLE}</h1>
60
39
  </GridItem>
61
- <GridItem span={6}>
40
+ <GridItem
41
+ span={6}
42
+ style={{
43
+ display: 'flex',
44
+ justifyContent: 'flex-end',
45
+ marginRight: '-16px',
46
+ }}
47
+ >
62
48
  <Dropdown
63
49
  className="title-dropdown"
64
50
  ouiaId="title-dropdown"
65
- onSelect={() => setIsDropdownOpen(false)}
66
- toggle={
67
- <KebabToggle
68
- onToggle={(_event, isOpen) => setIsDropdownOpen(isOpen)}
69
- />
70
- }
71
51
  isOpen={isDropdownOpen}
72
- isPlain
73
- dropdownItems={dropdownItems}
74
- position={DropdownPosition.right}
75
- />
52
+ onSelect={() => setIsDropdownOpen(false)}
53
+ onOpenChange={val => setIsDropdownOpen(val)}
54
+ popperProps={{ position: 'end' }}
55
+ toggle={toggleRef => (
56
+ <MenuToggle
57
+ ref={toggleRef}
58
+ aria-label={__('Actions')}
59
+ variant="plain"
60
+ onClick={() => setIsDropdownOpen(prev => !prev)}
61
+ isExpanded={isDropdownOpen}
62
+ >
63
+ <EllipsisVIcon />
64
+ </MenuToggle>
65
+ )}
66
+ >
67
+ <DropdownList>
68
+ <DropdownItem
69
+ key="tasks-history-button"
70
+ ouiaId="tasks-history-button"
71
+ to={getActionsHistoryUrl()}
72
+ component="a"
73
+ target="_blank"
74
+ rel="noopener noreferrer"
75
+ >
76
+ {ACTIONS_HISTORY_BUTTON_TEXT}
77
+ </DropdownItem>
78
+ <DropdownItem
79
+ key="inventory-documentation-button"
80
+ ouiaId="inventory-documentation-button"
81
+ to={getInventoryDocsUrl()}
82
+ component="a"
83
+ target="_blank"
84
+ rel="noopener noreferrer"
85
+ >
86
+ {DOCS_BUTTON_TEXT}
87
+ </DropdownItem>
88
+ {!isIop && (
89
+ <DropdownItem
90
+ key="cloud-ping"
91
+ ouiaId="dropdownItem-cloud-ping"
92
+ onClick={togglePingModal}
93
+ >
94
+ {CLOUD_PING_TITLE}
95
+ </DropdownItem>
96
+ )}
97
+ </DropdownList>
98
+ </Dropdown>
76
99
  <CloudPingModal
77
100
  isOpen={showPingModal}
78
101
  toggle={togglePingModal}
@@ -20,9 +20,6 @@ jest.mock('foremanReact/Root/Context/ForemanContext', () => ({
20
20
 
21
21
  // Mock child components to isolate PageHeader testing
22
22
  // This prevents child component complexity from affecting our tests
23
- jest.mock('../components/SettingsWarning', () => () => (
24
- <div data-testid="settings-warning">SettingsWarning</div>
25
- ));
26
23
  jest.mock('../PageTitle', () => () => (
27
24
  <div data-testid="page-title">PageTitle</div>
28
25
  ));
@@ -59,7 +56,6 @@ describe('PageHeader', () => {
59
56
  });
60
57
 
61
58
  // All components should be present when not in IoP mode
62
- expect(screen.getByTestId('settings-warning')).toBeTruthy();
63
59
  expect(screen.getByTestId('page-title')).toBeTruthy();
64
60
  expect(screen.getByTestId('inventory-settings')).toBeTruthy();
65
61
  expect(screen.getByTestId('page-description')).toBeTruthy();
@@ -83,7 +79,6 @@ describe('PageHeader', () => {
83
79
  });
84
80
 
85
81
  // Core components should still be present
86
- expect(screen.getByTestId('settings-warning')).toBeTruthy();
87
82
  expect(screen.getByTestId('page-title')).toBeTruthy();
88
83
  expect(screen.getByTestId('inventory-filter')).toBeTruthy();
89
84
  expect(screen.getByTestId('toolbar-buttons')).toBeTruthy();
@@ -126,14 +121,11 @@ describe('PageHeader', () => {
126
121
  },
127
122
  });
128
123
 
129
- const gridRow = container.querySelector('.row');
130
- expect(gridRow).toBeTruthy();
131
-
132
- const filterColumn = container.querySelector('.col-xs-4');
133
- expect(filterColumn).toBeTruthy();
124
+ const grid = container.querySelector('.pf-v5-l-grid');
125
+ expect(grid).toBeTruthy();
134
126
 
135
- const toolbarColumn = container.querySelector('.col-xs-7');
136
- expect(toolbarColumn).toBeTruthy();
127
+ expect(screen.getByTestId('inventory-filter')).toBeTruthy();
128
+ expect(screen.getByTestId('toolbar-buttons')).toBeTruthy();
137
129
  });
138
130
 
139
131
  test('renders description section only when not in IoP mode', () => {