foreman_rh_cloud 4.0.25 → 5.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/rh_cloud/inventory_controller.rb +4 -1
- data/app/controllers/concerns/inventory_upload/report_actions.rb +1 -1
- data/app/controllers/foreman_inventory_upload/cloud_status_controller.rb +26 -0
- data/app/controllers/foreman_inventory_upload/reports_controller.rb +1 -1
- data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +18 -4
- data/app/controllers/insights_cloud/hits_controller.rb +0 -1
- data/app/models/setting/rh_cloud.rb +0 -1
- data/app/models/task_output_line.rb +2 -0
- data/app/models/task_output_status.rb +2 -0
- data/app/services/foreman_rh_cloud/cloud_ping_service.rb +83 -0
- data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +15 -3
- data/config/Gemfile.lock.gh_test +169 -160
- data/config/database.yml.example +2 -2
- data/config/package-lock.json.plugin +10551 -7500
- data/config/rh_cert-api_chain.pem +74 -0
- data/config/routes.rb +3 -1
- data/db/migrate/20211027000001_create_task_output.foreman_rh_cloud.rb +18 -0
- data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +11 -7
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +24 -12
- data/lib/foreman_inventory_upload/async/progress_output.rb +5 -28
- data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +20 -5
- data/lib/foreman_inventory_upload/async/shell_process.rb +17 -4
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +22 -13
- data/lib/foreman_inventory_upload/generators/queries.rb +0 -16
- data/lib/foreman_inventory_upload/generators/tags.rb +1 -2
- data/lib/foreman_rh_cloud/engine.rb +4 -11
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +16 -1
- data/lib/insights_cloud/async/insights_client_status_aging.rb +4 -0
- data/lib/insights_cloud/async/insights_full_sync.rb +4 -0
- data/lib/insights_cloud/async/insights_generate_notifications.rb +4 -0
- data/lib/insights_cloud/async/insights_resolutions_sync.rb +7 -2
- data/lib/insights_cloud/async/insights_rules_sync.rb +10 -2
- data/lib/insights_cloud/async/insights_scheduled_sync.rb +11 -7
- data/lib/insights_cloud.rb +4 -0
- data/lib/inventory_sync/async/inventory_full_sync.rb +4 -0
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +4 -0
- data/lib/inventory_sync/async/inventory_scheduled_sync.rb +4 -0
- data/lib/inventory_sync/async/inventory_self_host_sync.rb +4 -0
- data/lib/inventory_sync/async/query_inventory_job.rb +4 -0
- data/lib/tasks/rh_cloud_inventory.rake +4 -11
- data/package.json +7 -12
- data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +20 -39
- data/test/controllers/inventory_upload/cloud_status_controller_test.rb +44 -0
- data/test/factories/inventory_upload_factories.rb +14 -0
- data/test/jobs/insights_resolutions_sync_test.rb +10 -1
- data/test/jobs/upload_report_job_test.rb +5 -3
- data/test/test_plugin_helper.rb +53 -0
- data/test/unit/foreman_rh_cloud_self_host_test.rb +28 -0
- data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +29 -34
- data/test/unit/services/foreman_rh_cloud/cloud_status_service_test.rb +66 -0
- data/test/unit/shell_process_job_test.rb +3 -1
- data/test/unit/slice_generator_test.rb +24 -4
- data/test/unit/tags_generator_test.rb +16 -16
- data/webpack/ForemanInventoryUpload/Components/AccountList/accountList.scss +8 -0
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettings.scss +0 -4
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.scss +17 -4
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +36 -12
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +58 -37
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +144 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.scss +5 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +12 -10
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +10 -10
- data/webpack/ForemanInventoryUpload/ForemanInventoryConstants.js +2 -0
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +1 -1
- data/webpack/InsightsCloudSync/Components/InsightsHeader/InsightsHeader.scss +5 -1
- data/webpack/InsightsCloudSync/Components/InsightsHeader/index.js +6 -6
- data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +9 -5
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettings.test.js.snap +6 -6
- data/webpack/InsightsCloudSync/Components/InsightsSettings/insightsSettings.scss +1 -14
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +5 -24
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +11 -4
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +0 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/Pagination.js +51 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +7 -69
- data/webpack/InsightsCloudSync/Components/InsightsTable/table.scss +10 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +11 -10
- data/webpack/InsightsCloudSync/Components/RemediationModal/index.js +0 -2
- data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +32 -0
- data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap +5 -5
- data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap +24 -13
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +19 -13
- data/webpack/InsightsCloudSync/InsightsCloudSync.scss +82 -2
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +16 -6
- data/webpack/__mocks__/foremanReact/components/Head.js +11 -0
- data/webpack/common/Switcher/HelpLabel.js +1 -1
- data/webpack/common/Switcher/SwitcherPF4.js +1 -1
- data/webpack/common/Switcher/SwitcherPF4.scss +6 -7
- data/webpack/common/Switcher/__tests__/__snapshots__/HelpLabel.test.js.snap +1 -1
- data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +2 -1
- metadata +20 -24
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.fixtures.js +0 -1
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.js +0 -45
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/__tests__/InsightsSyncSwitcher.test.js +0 -17
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/__tests__/__snapshots__/InsightsSyncSwitcher.test.js.snap +0 -38
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/index.js +0 -1
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/insightsSyncSwitcher.scss +0 -3
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediateButton.js +0 -59
@@ -1,17 +1,4 @@
|
|
1
1
|
.insights_settings {
|
2
|
-
margin-left: 10px;
|
3
|
-
border: 1px solid #ededed;
|
4
|
-
border-radius: 4px;
|
5
|
-
padding: 10px;
|
6
|
-
margin-bottom: 15px;
|
7
2
|
float: right;
|
8
|
-
|
9
|
-
h3 {
|
10
|
-
margin-top: 0;
|
11
|
-
font-weight: 600;
|
12
|
-
}
|
13
|
-
|
14
|
-
.bootstrap-switch {
|
15
|
-
float: right;
|
16
|
-
}
|
3
|
+
margin-top: 22px;
|
17
4
|
}
|
@@ -1,17 +1,13 @@
|
|
1
1
|
/* eslint-disable react-hooks/exhaustive-deps */
|
2
2
|
import React, { useEffect } from 'react';
|
3
3
|
import PropTypes from 'prop-types';
|
4
|
-
import { Pagination, PaginationVariant } from '@patternfly/react-core';
|
5
4
|
import { Table, TableHeader, TableBody } from '@patternfly/react-table';
|
6
5
|
import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
|
7
6
|
import SelectAllAlert from './SelectAllAlert';
|
8
|
-
import { columns
|
7
|
+
import { columns } from './InsightsTableConstants';
|
9
8
|
import TableEmptyState from '../../../common/table/EmptyState';
|
10
|
-
import {
|
11
|
-
|
12
|
-
getSortColumnIndex,
|
13
|
-
getPerPageOptions,
|
14
|
-
} from './InsightsTableHelpers';
|
9
|
+
import { modifySelectedRows, getSortColumnIndex } from './InsightsTableHelpers';
|
10
|
+
import Pagination from './Pagination';
|
15
11
|
import './table.scss';
|
16
12
|
|
17
13
|
const InsightsTable = ({
|
@@ -22,10 +18,7 @@ const InsightsTable = ({
|
|
22
18
|
sortOrder,
|
23
19
|
hits,
|
24
20
|
query,
|
25
|
-
itemCount,
|
26
21
|
fetchInsights,
|
27
|
-
onTableSetPage,
|
28
|
-
onTablePerPageSelect,
|
29
22
|
onTableSort,
|
30
23
|
onTableSelect,
|
31
24
|
selectedIds,
|
@@ -68,22 +61,13 @@ const InsightsTable = ({
|
|
68
61
|
onSort={onTableSort}
|
69
62
|
cells={columns}
|
70
63
|
rows={rows}
|
64
|
+
variant="compact"
|
71
65
|
>
|
72
66
|
<TableHeader />
|
73
67
|
<TableBody />
|
74
68
|
</Table>
|
75
69
|
<TableEmptyState status={status} error={error} />
|
76
|
-
<Pagination
|
77
|
-
itemCount={itemCount}
|
78
|
-
widgetId="recommendation-pagination"
|
79
|
-
perPage={perPage}
|
80
|
-
page={page}
|
81
|
-
variant={PaginationVariant.bottom}
|
82
|
-
onSetPage={onTableSetPage}
|
83
|
-
onPerPageSelect={onTablePerPageSelect}
|
84
|
-
perPageOptions={getPerPageOptions(urlPerPage, appPerPage)}
|
85
|
-
titles={paginationTitles}
|
86
|
-
/>
|
70
|
+
<Pagination variant="bottom" />
|
87
71
|
</React.Fragment>
|
88
72
|
);
|
89
73
|
};
|
@@ -95,9 +79,6 @@ InsightsTable.propTypes = {
|
|
95
79
|
sortBy: PropTypes.string,
|
96
80
|
sortOrder: PropTypes.string,
|
97
81
|
hits: PropTypes.array.isRequired,
|
98
|
-
itemCount: PropTypes.number.isRequired,
|
99
|
-
onTableSetPage: PropTypes.func.isRequired,
|
100
|
-
onTablePerPageSelect: PropTypes.func.isRequired,
|
101
82
|
onTableSort: PropTypes.func.isRequired,
|
102
83
|
onTableSelect: PropTypes.func.isRequired,
|
103
84
|
selectedIds: PropTypes.object,
|
@@ -5,7 +5,7 @@ import {
|
|
5
5
|
Section,
|
6
6
|
} from '@redhat-cloud-services/frontend-components';
|
7
7
|
import { sortable, cellWidth } from '@patternfly/react-table';
|
8
|
-
import {
|
8
|
+
import { AnsibeTowerIcon } from '@patternfly/react-icons';
|
9
9
|
import { translate as __ } from 'foremanReact/common/I18n';
|
10
10
|
import { foremanUrl } from '../../../ForemanRhCloudHelpers';
|
11
11
|
|
@@ -18,7 +18,14 @@ export const totalRiskFormatter = ({ title: totalRisk }) => ({
|
|
18
18
|
});
|
19
19
|
|
20
20
|
export const hasPlaybookFormatter = ({ title: hasPlaybook }) => ({
|
21
|
-
children: hasPlaybook ?
|
21
|
+
children: hasPlaybook ? (
|
22
|
+
<span className="td-insights-remediate-playbook">
|
23
|
+
<AnsibeTowerIcon />
|
24
|
+
{__('Playbook')}
|
25
|
+
</span>
|
26
|
+
) : (
|
27
|
+
<span className="td-insights-remediate-manual">{__('Manual')}</span>
|
28
|
+
),
|
22
29
|
});
|
23
30
|
|
24
31
|
export const columns = [
|
@@ -34,12 +41,12 @@ export const columns = [
|
|
34
41
|
},
|
35
42
|
{
|
36
43
|
sortKey: 'total_risk',
|
37
|
-
title: __('Total
|
44
|
+
title: __('Total risk'),
|
38
45
|
transforms: [cellWidth(15), sortable],
|
39
46
|
cellTransforms: [totalRiskFormatter],
|
40
47
|
},
|
41
48
|
{
|
42
|
-
title: __('
|
49
|
+
title: __('Remediate'),
|
43
50
|
transforms: [cellWidth(15)],
|
44
51
|
cellTransforms: [hasPlaybookFormatter],
|
45
52
|
},
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { useDispatch, useSelector } from 'react-redux';
|
4
|
+
import {
|
5
|
+
Pagination as PfPagination,
|
6
|
+
PaginationVariant,
|
7
|
+
} from '@patternfly/react-core';
|
8
|
+
import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
|
9
|
+
import { onTablePerPageSelect, onTableSetPage } from './InsightsTableActions';
|
10
|
+
import { getPerPageOptions } from './InsightsTableHelpers';
|
11
|
+
import {
|
12
|
+
selectItemCount,
|
13
|
+
selectPage,
|
14
|
+
selectPerPage,
|
15
|
+
} from './InsightsTableSelectors';
|
16
|
+
|
17
|
+
const Pagination = ({ variant, ...props }) => {
|
18
|
+
const dispatch = useDispatch();
|
19
|
+
const onSetPage = (e, pageNumber) => dispatch(onTableSetPage(e, pageNumber));
|
20
|
+
const onPerPageSelect = (e, perPageNumber) =>
|
21
|
+
dispatch(onTablePerPageSelect(e, perPageNumber));
|
22
|
+
const itemCount = useSelector(state => selectItemCount(state));
|
23
|
+
const urlPerPage = useSelector(state => selectPerPage(state));
|
24
|
+
const page = useSelector(state => selectPage(state));
|
25
|
+
const { perPage: appPerPage } = useForemanSettings();
|
26
|
+
const perPage = urlPerPage || appPerPage;
|
27
|
+
|
28
|
+
return (
|
29
|
+
<PfPagination
|
30
|
+
itemCount={itemCount}
|
31
|
+
widgetId={`recommendation-pagination-${variant}`}
|
32
|
+
perPage={perPage}
|
33
|
+
page={page}
|
34
|
+
variant={PaginationVariant[variant]}
|
35
|
+
onSetPage={onSetPage}
|
36
|
+
onPerPageSelect={onPerPageSelect}
|
37
|
+
perPageOptions={getPerPageOptions(urlPerPage, appPerPage)}
|
38
|
+
{...props}
|
39
|
+
/>
|
40
|
+
);
|
41
|
+
};
|
42
|
+
|
43
|
+
Pagination.propTypes = {
|
44
|
+
variant: PropTypes.string,
|
45
|
+
};
|
46
|
+
|
47
|
+
Pagination.defaultProps = {
|
48
|
+
variant: 'top',
|
49
|
+
};
|
50
|
+
|
51
|
+
export default Pagination;
|
@@ -37,7 +37,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
|
|
37
37
|
[Function],
|
38
38
|
],
|
39
39
|
"sortKey": "total_risk",
|
40
|
-
"title": "Total
|
40
|
+
"title": "Total risk",
|
41
41
|
"transforms": Array [
|
42
42
|
[Function],
|
43
43
|
[Function],
|
@@ -47,7 +47,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
|
|
47
47
|
"cellTransforms": Array [
|
48
48
|
[Function],
|
49
49
|
],
|
50
|
-
"title": "
|
50
|
+
"title": "Remediate",
|
51
51
|
"transforms": Array [
|
52
52
|
[Function],
|
53
53
|
],
|
@@ -60,7 +60,10 @@ exports[`InsightsTable rendering render with Props 1`] = `
|
|
60
60
|
dropdownPosition="right"
|
61
61
|
expandId="expandable-toggle"
|
62
62
|
gridBreakPoint="grid-md"
|
63
|
+
isHeaderSelectDisabled={false}
|
64
|
+
isNested={false}
|
63
65
|
isStickyHeader={false}
|
66
|
+
isTreeTable={false}
|
64
67
|
onSelect={[Function]}
|
65
68
|
onSort={[Function]}
|
66
69
|
ouiaSafe={true}
|
@@ -74,82 +77,17 @@ exports[`InsightsTable rendering render with Props 1`] = `
|
|
74
77
|
"index": 3,
|
75
78
|
}
|
76
79
|
}
|
77
|
-
variant=
|
80
|
+
variant="compact"
|
78
81
|
>
|
79
82
|
<TableHeader />
|
80
|
-
<
|
83
|
+
<TableBody />
|
81
84
|
</Table>
|
82
85
|
<TableEmptyState
|
83
86
|
error={null}
|
84
87
|
status="RESOLVED"
|
85
88
|
/>
|
86
89
|
<Pagination
|
87
|
-
className=""
|
88
|
-
defaultToFullPage={false}
|
89
|
-
firstPage={1}
|
90
|
-
isCompact={false}
|
91
|
-
isDisabled={false}
|
92
|
-
isSticky={false}
|
93
|
-
itemCount={2}
|
94
|
-
itemsEnd={null}
|
95
|
-
itemsStart={null}
|
96
|
-
offset={0}
|
97
|
-
onFirstClick={[Function]}
|
98
|
-
onLastClick={[Function]}
|
99
|
-
onNextClick={[Function]}
|
100
|
-
onPageInput={[Function]}
|
101
|
-
onPerPageSelect={[Function]}
|
102
|
-
onPreviousClick={[Function]}
|
103
|
-
onSetPage={[Function]}
|
104
|
-
ouiaSafe={true}
|
105
|
-
page={1}
|
106
|
-
perPage={5}
|
107
|
-
perPageOptions={
|
108
|
-
Array [
|
109
|
-
Object {
|
110
|
-
"title": "5",
|
111
|
-
"value": 5,
|
112
|
-
},
|
113
|
-
Object {
|
114
|
-
"title": "10",
|
115
|
-
"value": 10,
|
116
|
-
},
|
117
|
-
Object {
|
118
|
-
"title": "15",
|
119
|
-
"value": 15,
|
120
|
-
},
|
121
|
-
Object {
|
122
|
-
"title": "20",
|
123
|
-
"value": 20,
|
124
|
-
},
|
125
|
-
Object {
|
126
|
-
"title": "25",
|
127
|
-
"value": 25,
|
128
|
-
},
|
129
|
-
Object {
|
130
|
-
"title": "50",
|
131
|
-
"value": 50,
|
132
|
-
},
|
133
|
-
]
|
134
|
-
}
|
135
|
-
titles={
|
136
|
-
Object {
|
137
|
-
"currPage": "Current page",
|
138
|
-
"items": "items",
|
139
|
-
"itemsPerPage": "Items per page",
|
140
|
-
"optionsToggle": "Items per page",
|
141
|
-
"page": "page",
|
142
|
-
"paginationTitle": "Pagination",
|
143
|
-
"perPageSuffix": "per page",
|
144
|
-
"toFirstPage": "Go to first page",
|
145
|
-
"toLastPage": "Go to last page",
|
146
|
-
"toNextPage": "Go to next page",
|
147
|
-
"toPreviousPage": "Go to previous page",
|
148
|
-
}
|
149
|
-
}
|
150
|
-
toggleTemplate={[Function]}
|
151
90
|
variant="bottom"
|
152
|
-
widgetId="recommendation-pagination"
|
153
91
|
/>
|
154
92
|
</Fragment>
|
155
93
|
`;
|
@@ -2,7 +2,8 @@
|
|
2
2
|
import React, { useEffect } from 'react';
|
3
3
|
import PropTypes from 'prop-types';
|
4
4
|
import { Table, TableHeader, TableBody } from '@patternfly/react-table';
|
5
|
-
import { Modal, ModalVariant } from '@patternfly/react-core';
|
5
|
+
import { Modal, ModalVariant, Button } from '@patternfly/react-core';
|
6
|
+
import { isEmpty } from 'lodash';
|
6
7
|
import { STATUS } from 'foremanReact/constants';
|
7
8
|
import { translate as __ } from 'foremanReact/common/I18n';
|
8
9
|
import { columns } from './RemediationTableConstants';
|
@@ -10,7 +11,6 @@ import { modifyRows } from './RemediationHelpers';
|
|
10
11
|
import ModalFooter from './RemediationModalFooter';
|
11
12
|
import TableEmptyState from '../../../common/table/EmptyState';
|
12
13
|
import './RemediationModal.scss';
|
13
|
-
import RemediateButton from './RemediateButton';
|
14
14
|
|
15
15
|
const RemediationModal = ({
|
16
16
|
selectedIds,
|
@@ -20,7 +20,6 @@ const RemediationModal = ({
|
|
20
20
|
error,
|
21
21
|
isAllSelected,
|
22
22
|
query,
|
23
|
-
isExperimentalMode,
|
24
23
|
}) => {
|
25
24
|
const [rows, setRows] = React.useState([]);
|
26
25
|
const [open, setOpen] = React.useState(false);
|
@@ -42,11 +41,15 @@ const RemediationModal = ({
|
|
42
41
|
|
43
42
|
return (
|
44
43
|
<React.Fragment>
|
45
|
-
<
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
<Button
|
45
|
+
variant="primary"
|
46
|
+
isDisabled={isEmpty(selectedIds)}
|
47
|
+
onClick={() => {
|
48
|
+
toggleModal();
|
49
|
+
}}
|
50
|
+
>
|
51
|
+
{__('Remediate')}
|
52
|
+
</Button>{' '}
|
50
53
|
<Modal
|
51
54
|
id="remediation-modal"
|
52
55
|
appendTo={document.body}
|
@@ -85,7 +88,6 @@ RemediationModal.propTypes = {
|
|
85
88
|
error: PropTypes.string,
|
86
89
|
isAllSelected: PropTypes.bool,
|
87
90
|
query: PropTypes.string,
|
88
|
-
isExperimentalMode: PropTypes.bool,
|
89
91
|
};
|
90
92
|
|
91
93
|
RemediationModal.defaultProps = {
|
@@ -95,7 +97,6 @@ RemediationModal.defaultProps = {
|
|
95
97
|
error: null,
|
96
98
|
isAllSelected: false,
|
97
99
|
query: null,
|
98
|
-
isExperimentalMode: false,
|
99
100
|
};
|
100
101
|
|
101
102
|
export default RemediationModal;
|
@@ -9,7 +9,6 @@ import * as actions from './RemediationActions';
|
|
9
9
|
import RemediationModal from './RemediationModal';
|
10
10
|
import { REMEDIATIONS_API_KEY } from './RemediationTableConstants';
|
11
11
|
import {
|
12
|
-
selectExperimental,
|
13
12
|
selectIsAllSelected,
|
14
13
|
selectSearch,
|
15
14
|
selectSelectedIds,
|
@@ -24,7 +23,6 @@ const mapStateToProps = state => ({
|
|
24
23
|
itemCount: selectAPIResponse(state, REMEDIATIONS_API_KEY).itemCount || 0,
|
25
24
|
isAllSelected: selectIsAllSelected(state),
|
26
25
|
query: selectSearch(state),
|
27
|
-
isExperimentalMode: selectExperimental(state),
|
28
26
|
});
|
29
27
|
|
30
28
|
// map action dispatchers to props
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
4
|
+
import { Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core';
|
5
|
+
|
6
|
+
const ToolbarDropdown = ({ onRecommendationSync }) => {
|
7
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
8
|
+
const dropdownItems = [
|
9
|
+
<DropdownItem
|
10
|
+
key="recommendation-manual-sync"
|
11
|
+
onClick={onRecommendationSync}
|
12
|
+
>
|
13
|
+
{__('Sync recommendations')}
|
14
|
+
</DropdownItem>,
|
15
|
+
];
|
16
|
+
return (
|
17
|
+
<Dropdown
|
18
|
+
className="title-dropdown"
|
19
|
+
onSelect={() => setIsDropdownOpen(false)}
|
20
|
+
toggle={<KebabToggle onToggle={isOpen => setIsDropdownOpen(isOpen)} />}
|
21
|
+
isOpen={isDropdownOpen}
|
22
|
+
isPlain
|
23
|
+
dropdownItems={dropdownItems}
|
24
|
+
/>
|
25
|
+
);
|
26
|
+
};
|
27
|
+
|
28
|
+
ToolbarDropdown.propTypes = {
|
29
|
+
onRecommendationSync: PropTypes.func.isRequired,
|
30
|
+
};
|
31
|
+
|
32
|
+
export default ToolbarDropdown;
|
data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap
CHANGED
@@ -4,10 +4,10 @@ exports[`InsightsHeader render 1`] = `
|
|
4
4
|
<div
|
5
5
|
className="insights-header"
|
6
6
|
>
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
</
|
7
|
+
<Text
|
8
|
+
component="p"
|
9
|
+
>
|
10
|
+
Insights synchronization process is used to provide Insights recommendations output for hosts managed here.
|
11
|
+
</Text>
|
12
12
|
</div>
|
13
13
|
`;
|
data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap
CHANGED
@@ -157,6 +157,7 @@ exports[`NoTokenEmptyState render 1`] = `
|
|
157
157
|
isReadOnly={false}
|
158
158
|
isRequired={false}
|
159
159
|
onChange={[Function]}
|
160
|
+
ouiaSafe={true}
|
160
161
|
type="password"
|
161
162
|
validated="default"
|
162
163
|
value=""
|
@@ -165,6 +166,9 @@ exports[`NoTokenEmptyState render 1`] = `
|
|
165
166
|
aria-invalid={false}
|
166
167
|
aria-label="input-cloud-token"
|
167
168
|
className="pf-c-form-control"
|
169
|
+
data-ouia-component-id="OUIA-Generated-TextInputBase-1"
|
170
|
+
data-ouia-component-type="PF4/TextInput"
|
171
|
+
data-ouia-safe={true}
|
168
172
|
disabled={false}
|
169
173
|
onBlur={[Function]}
|
170
174
|
onChange={[Function]}
|
@@ -190,21 +194,28 @@ exports[`NoTokenEmptyState render 1`] = `
|
|
190
194
|
onClick={[Function]}
|
191
195
|
variant="primary"
|
192
196
|
>
|
193
|
-
<
|
194
|
-
|
195
|
-
|
196
|
-
className="pf-c-button pf-m-primary pf-m-disabled"
|
197
|
-
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
198
|
-
data-ouia-component-type="PF4/Button"
|
199
|
-
data-ouia-safe={true}
|
200
|
-
disabled={true}
|
197
|
+
<ButtonBase
|
198
|
+
innerRef={null}
|
199
|
+
isDisabled={true}
|
201
200
|
onClick={[Function]}
|
202
|
-
|
203
|
-
tabIndex={null}
|
204
|
-
type="button"
|
201
|
+
variant="primary"
|
205
202
|
>
|
206
|
-
|
207
|
-
|
203
|
+
<button
|
204
|
+
aria-disabled={true}
|
205
|
+
aria-label={null}
|
206
|
+
className="pf-c-button pf-m-primary pf-m-disabled"
|
207
|
+
data-ouia-component-id="OUIA-Generated-Button-primary-1"
|
208
|
+
data-ouia-component-type="PF4/Button"
|
209
|
+
data-ouia-safe={true}
|
210
|
+
disabled={true}
|
211
|
+
onClick={[Function]}
|
212
|
+
role={null}
|
213
|
+
tabIndex={null}
|
214
|
+
type="button"
|
215
|
+
>
|
216
|
+
Save setting and sync recommendations
|
217
|
+
</button>
|
218
|
+
</ButtonBase>
|
208
219
|
</Button>
|
209
220
|
</div>
|
210
221
|
</div>
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { Button } from '@patternfly/react-core';
|
3
2
|
import PropTypes from 'prop-types';
|
4
|
-
import { translate as __ } from 'foremanReact/common/I18n';
|
5
3
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
6
4
|
import InsightsHeader from './Components/InsightsHeader';
|
7
5
|
import { NoTokenEmptyState } from './Components/NoTokenEmptyState';
|
@@ -12,6 +10,9 @@ import {
|
|
12
10
|
INSIGHTS_SEARCH_PROPS,
|
13
11
|
} from './InsightsCloudSyncConstants';
|
14
12
|
import './InsightsCloudSync.scss';
|
13
|
+
import Pagination from './Components/InsightsTable/Pagination';
|
14
|
+
import ToolbarDropdown from './Components/ToolbarDropdown';
|
15
|
+
import InsightsSettings from './Components/InsightsSettings';
|
15
16
|
|
16
17
|
const InsightsCloudSync = ({
|
17
18
|
syncInsights,
|
@@ -26,24 +27,29 @@ const InsightsCloudSync = ({
|
|
26
27
|
</PageLayout>
|
27
28
|
);
|
28
29
|
}
|
30
|
+
|
31
|
+
const onRecommendationSync = () => syncInsights(fetchInsights, query);
|
32
|
+
const toolbarButtons = (
|
33
|
+
<>
|
34
|
+
<span className="insights-toolbar-buttons">
|
35
|
+
<RemediationModal />
|
36
|
+
<ToolbarDropdown onRecommendationSync={onRecommendationSync} />
|
37
|
+
</span>
|
38
|
+
<span className="pull-right">
|
39
|
+
<Pagination variant="top" isCompact />
|
40
|
+
</span>
|
41
|
+
</>
|
42
|
+
);
|
43
|
+
|
29
44
|
return (
|
30
45
|
<div className="rh-cloud-insights">
|
46
|
+
<InsightsSettings />
|
31
47
|
<PageLayout
|
32
48
|
searchable
|
33
49
|
searchProps={INSIGHTS_SEARCH_PROPS}
|
34
50
|
onSearch={nextQuery => fetchInsights({ query: nextQuery, page: 1 })}
|
35
51
|
header={INSIGHTS_SYNC_PAGE_TITLE}
|
36
|
-
toolbarButtons={
|
37
|
-
<>
|
38
|
-
<RemediationModal />
|
39
|
-
<Button
|
40
|
-
variant="secondary"
|
41
|
-
onClick={() => syncInsights(fetchInsights, query)}
|
42
|
-
>
|
43
|
-
{__('Start recommendations sync')}
|
44
|
-
</Button>
|
45
|
-
</>
|
46
|
-
}
|
52
|
+
toolbarButtons={toolbarButtons}
|
47
53
|
searchQuery={query}
|
48
54
|
beforeToolbarComponent={<InsightsHeader />}
|
49
55
|
>
|
@@ -1,5 +1,85 @@
|
|
1
1
|
.rh-cloud-insights {
|
2
|
-
|
3
|
-
|
2
|
+
#main {
|
3
|
+
padding: 4px;
|
4
|
+
|
5
|
+
#breadcrumb .form-group {
|
6
|
+
margin-bottom: 0;
|
7
|
+
|
8
|
+
h1 {
|
9
|
+
font-family: 'RedHatDisplay';
|
10
|
+
font-weight: 400;
|
11
|
+
margin-bottom: 8px;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
.title_filter {
|
16
|
+
width: 520px;
|
17
|
+
}
|
18
|
+
|
19
|
+
#title_action {
|
20
|
+
width: calc(100% - 520px);
|
21
|
+
}
|
22
|
+
|
23
|
+
@media (max-width: 1138px) {
|
24
|
+
#title_action {
|
25
|
+
width: 70%;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
.search-bar {
|
30
|
+
// Giving pf3 search bar a pf4 look
|
31
|
+
width: 500px;
|
32
|
+
.search-bar {
|
33
|
+
display: block;
|
34
|
+
}
|
35
|
+
.input-group {
|
36
|
+
display: table;
|
37
|
+
}
|
38
|
+
.input-group-btn {
|
39
|
+
.btn-group {
|
40
|
+
z-index: unset; // so the bookmarks drop down will be above other search boxes
|
41
|
+
}
|
42
|
+
.autocomplete-search-btn {
|
43
|
+
display: none;
|
44
|
+
}
|
45
|
+
.dropdown-toggle {
|
46
|
+
font-size: 16px;
|
47
|
+
background-color: white;
|
48
|
+
background-image: none;
|
49
|
+
padding-bottom: 4px;
|
50
|
+
padding-top: 4px;
|
51
|
+
}
|
52
|
+
.scrollable-dropdown {
|
53
|
+
max-width: 250px;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
li {
|
57
|
+
font-size: 16px;
|
58
|
+
}
|
59
|
+
input {
|
60
|
+
font-size: 16px;
|
61
|
+
height: 36px;
|
62
|
+
}
|
63
|
+
.foreman-autocomplete .autocomplete-focus-shortcut {
|
64
|
+
top: 8px;
|
65
|
+
font-size: 16px;
|
66
|
+
}
|
67
|
+
.foreman-autocomplete .autocomplete-aux {
|
68
|
+
top: 8px;
|
69
|
+
font-size: 16px;
|
70
|
+
.autocomplete-clear-button {
|
71
|
+
font-size: 16px;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
.btn-toolbar {
|
77
|
+
display: inherit;
|
78
|
+
width: 100%;
|
79
|
+
}
|
80
|
+
|
81
|
+
.pf-c-pagination {
|
82
|
+
padding-right: 0;
|
83
|
+
}
|
4
84
|
}
|
5
85
|
}
|
@@ -4,6 +4,7 @@ exports[`InsightsCloudSync render 1`] = `
|
|
4
4
|
<div
|
5
5
|
className="rh-cloud-insights"
|
6
6
|
>
|
7
|
+
<Connect(InsightsSettings) />
|
7
8
|
<PageLayout
|
8
9
|
beforeToolbarComponent={<InsightsHeader />}
|
9
10
|
header="Red Hat Insights"
|
@@ -28,13 +29,22 @@ exports[`InsightsCloudSync render 1`] = `
|
|
28
29
|
searchable={true}
|
29
30
|
toolbarButtons={
|
30
31
|
<React.Fragment>
|
31
|
-
<
|
32
|
-
|
33
|
-
onClick={[Function]}
|
34
|
-
variant="secondary"
|
32
|
+
<span
|
33
|
+
className="insights-toolbar-buttons"
|
35
34
|
>
|
36
|
-
|
37
|
-
|
35
|
+
<Memo(Connect(RemediationModal)) />
|
36
|
+
<ToolbarDropdown
|
37
|
+
onRecommendationSync={[Function]}
|
38
|
+
/>
|
39
|
+
</span>
|
40
|
+
<span
|
41
|
+
className="pull-right"
|
42
|
+
>
|
43
|
+
<Pagination
|
44
|
+
isCompact={true}
|
45
|
+
variant="top"
|
46
|
+
/>
|
47
|
+
</span>
|
38
48
|
</React.Fragment>
|
39
49
|
}
|
40
50
|
>
|