foreman_rh_cloud 4.0.31 → 5.0.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/inventory_upload/report_actions.rb +1 -1
  3. data/app/controllers/foreman_inventory_upload/reports_controller.rb +1 -1
  4. data/app/controllers/insights_cloud/hits_controller.rb +1 -1
  5. data/app/models/insights_hit.rb +4 -0
  6. data/app/models/setting/rh_cloud.rb +0 -1
  7. data/app/models/task_output_line.rb +2 -0
  8. data/app/models/task_output_status.rb +2 -0
  9. data/config/Gemfile.lock.gh_test +204 -168
  10. data/config/package-lock.json.gh_test +14336 -7973
  11. data/config/package-lock.json.plugin +10551 -7500
  12. data/config/routes.rb +1 -1
  13. data/db/migrate/20211027000001_create_task_output.foreman_rh_cloud.rb +18 -0
  14. data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +11 -7
  15. data/lib/foreman_inventory_upload/async/generate_report_job.rb +24 -12
  16. data/lib/foreman_inventory_upload/async/progress_output.rb +5 -28
  17. data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +20 -5
  18. data/lib/foreman_inventory_upload/async/shell_process.rb +17 -4
  19. data/lib/foreman_inventory_upload/async/upload_report_job.rb +22 -13
  20. data/lib/foreman_rh_cloud/engine.rb +12 -11
  21. data/lib/foreman_rh_cloud/version.rb +1 -1
  22. data/lib/insights_cloud/async/insights_scheduled_sync.rb +11 -7
  23. data/lib/tasks/rh_cloud_inventory.rake +2 -2
  24. data/package.json +7 -12
  25. data/test/controllers/insights_sync/settings_controller_test.rb +2 -2
  26. data/test/controllers/uploads_settings_controller_test.rb +2 -2
  27. data/test/jobs/insights_full_sync_test.rb +2 -2
  28. data/test/jobs/insights_resolutions_sync_test.rb +1 -1
  29. data/test/jobs/insights_rules_sync_test.rb +2 -2
  30. data/test/jobs/inventory_full_sync_test.rb +3 -3
  31. data/test/jobs/inventory_hosts_sync_test.rb +1 -1
  32. data/test/jobs/inventory_scheduled_sync_test.rb +2 -2
  33. data/test/jobs/inventory_self_host_sync_test.rb +1 -1
  34. data/test/jobs/upload_report_job_test.rb +6 -4
  35. data/test/test_plugin_helper.rb +0 -2
  36. data/test/unit/rh_cloud_http_proxy_test.rb +1 -1
  37. data/test/unit/rh_cloud_permissions_test.rb +14 -0
  38. data/test/unit/services/foreman_rh_cloud/branch_info_test.rb +1 -1
  39. data/test/unit/services/foreman_rh_cloud/template_renderer_helper_test.rb +1 -1
  40. data/test/unit/shell_process_job_test.rb +3 -1
  41. data/test/unit/slice_generator_test.rb +3 -3
  42. data/test/unit/tags_generator_test.rb +2 -2
  43. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListActions.js +1 -1
  44. data/webpack/ForemanInventoryUpload/Components/AccountList/accountList.scss +8 -0
  45. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +3 -3
  46. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/index.js +0 -2
  47. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.scss +17 -4
  48. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +29 -17
  49. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +58 -47
  50. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +12 -10
  51. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +10 -10
  52. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +1 -1
  53. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +1 -1
  54. data/webpack/ForemanRhCloudFills.js +14 -0
  55. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js +1 -1
  56. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +22 -6
  57. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +23 -16
  58. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +49 -2
  59. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js +31 -14
  60. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +19 -2
  61. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +0 -1
  62. data/webpack/InsightsCloudSync/Components/InsightsTable/table.scss +11 -13
  63. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.scss +0 -14
  64. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +13 -0
  65. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap +24 -13
  66. data/webpack/InsightsCloudSync/InsightsCloudSyncHelpers.js +8 -0
  67. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +1 -1
  68. data/webpack/InsightsHostDetailsTab/InsightsTab.scss +4 -0
  69. data/webpack/InsightsHostDetailsTab/InsightsTabActions.js +1 -1
  70. data/webpack/InsightsHostDetailsTab/InsightsTabConstants.js +75 -0
  71. data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +147 -0
  72. data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +103 -0
  73. data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +1 -0
  74. data/webpack/__mocks__/foremanReact/components/Head.js +11 -0
  75. data/webpack/__mocks__/foremanReact/{redux/actions/toasts.js → components/ToastsList/index.js} +0 -0
  76. data/webpack/common/DropdownToggle.js +24 -0
  77. data/webpack/common/ForemanTasks/ForemanTasksActions.js +1 -1
  78. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +1 -0
  79. metadata +11 -3
  80. data/webpack/__mocks__/foremanReact/components/Layout/LayoutSelectors.js +0 -1
@@ -4,7 +4,10 @@ import PropTypes from 'prop-types';
4
4
  import { Table, TableHeader, TableBody } from '@patternfly/react-table';
5
5
  import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
6
6
  import SelectAllAlert from './SelectAllAlert';
7
- import { columns } from './InsightsTableConstants';
7
+ import {
8
+ columns as defaultColumns,
9
+ getColumnsWithoutHostname,
10
+ } from './InsightsTableConstants';
8
11
  import TableEmptyState from '../../../common/table/EmptyState';
9
12
  import { modifySelectedRows, getSortColumnIndex } from './InsightsTableHelpers';
10
13
  import Pagination from './Pagination';
@@ -27,10 +30,12 @@ const InsightsTable = ({
27
30
  clearAllSelection,
28
31
  error,
29
32
  isAllSelected,
33
+ hideHost,
30
34
  }) => {
31
35
  const { perPage: appPerPage } = useForemanSettings();
32
36
  const perPage = urlPerPage || appPerPage;
33
37
  const [rows, setRows] = React.useState([]);
38
+ const [columns, setColumns] = React.useState(defaultColumns);
34
39
 
35
40
  // acts as componentDidMount
36
41
  useEffect(() => {
@@ -38,8 +43,12 @@ const InsightsTable = ({
38
43
  }, []);
39
44
 
40
45
  useEffect(() => {
41
- setRows(modifySelectedRows(hits, selectedIds, showSelectAllAlert));
42
- }, [hits, selectedIds]);
46
+ setRows(
47
+ modifySelectedRows(hits, selectedIds, showSelectAllAlert, hideHost)
48
+ );
49
+
50
+ if (hideHost) setColumns(getColumnsWithoutHostname());
51
+ }, [hits, selectedIds, hideHost]);
43
52
 
44
53
  return (
45
54
  <React.Fragment>
@@ -51,14 +60,19 @@ const InsightsTable = ({
51
60
  isAllSelected={isAllSelected}
52
61
  />
53
62
  <Table
54
- className="recommendations-table"
63
+ className="rh-cloud-recommendations-table"
55
64
  aria-label="Recommendations Table"
56
65
  onSelect={(_event, isSelected, rowId) =>
57
66
  onTableSelect(isSelected, rowId, rows, selectedIds)
58
67
  }
59
68
  canSelectAll
60
- sortBy={{ index: getSortColumnIndex(sortBy), direction: sortOrder }}
61
- onSort={onTableSort}
69
+ sortBy={{
70
+ index: getSortColumnIndex(columns, sortBy),
71
+ direction: sortOrder,
72
+ }}
73
+ onSort={(_event, index, direction) =>
74
+ onTableSort(columns, index, direction)
75
+ }
62
76
  cells={columns}
63
77
  rows={rows}
64
78
  variant="compact"
@@ -89,6 +103,7 @@ InsightsTable.propTypes = {
89
103
  query: PropTypes.string,
90
104
  error: PropTypes.string,
91
105
  isAllSelected: PropTypes.bool,
106
+ hideHost: PropTypes.bool,
92
107
  };
93
108
 
94
109
  InsightsTable.defaultProps = {
@@ -102,6 +117,7 @@ InsightsTable.defaultProps = {
102
117
  query: '',
103
118
  error: '',
104
119
  isAllSelected: false,
120
+ hideHost: false,
105
121
  };
106
122
 
107
123
  export default InsightsTable;
@@ -2,14 +2,13 @@ import URI from 'urijs';
2
2
  import { push } from 'connected-react-router';
3
3
  import { get } from 'foremanReact/redux/API';
4
4
  import { selectQueryParams } from './InsightsTableSelectors';
5
- import { INSIGHTS_PATH } from '../../InsightsCloudSyncConstants';
6
5
  import {
7
- columns,
8
6
  INSIGHTS_HITS_API_KEY,
9
7
  INSIGHTS_HITS_PATH,
10
8
  INSIGHTS_SET_SELECTED_IDS,
11
9
  INSIGHTS_SET_SELECT_ALL_ALERT,
12
10
  INSIGHTS_SET_SELECT_ALL,
11
+ NEW_HOST_PATH,
13
12
  } from './InsightsTableConstants';
14
13
 
15
14
  export const fetchInsights = (queryParams = {}) => (dispatch, getState) => {
@@ -29,17 +28,20 @@ export const fetchInsights = (queryParams = {}) => (dispatch, getState) => {
29
28
  select_all: isSelectAll,
30
29
  });
31
30
 
32
- dispatch(
33
- push({
34
- pathname: INSIGHTS_PATH,
35
- search: uri.search(),
36
- })
37
- );
31
+ updateUrl(uri, dispatch);
38
32
 
39
33
  if (!isSelectAll) {
40
34
  dispatch(setSelectAllAlert(false));
41
35
  }
42
36
 
37
+ let search = query;
38
+ if (isNewHostPage(uri)) {
39
+ const hostname = uri.pathname().split('/new/hosts/')[1];
40
+ const hostQuery = `hostname = ${hostname}`;
41
+ const q = query?.trim();
42
+ search = q ? `${hostQuery} AND (${q})` : hostQuery;
43
+ }
44
+
43
45
  return dispatch(
44
46
  get({
45
47
  key: INSIGHTS_HITS_API_KEY,
@@ -47,7 +49,7 @@ export const fetchInsights = (queryParams = {}) => (dispatch, getState) => {
47
49
  params: {
48
50
  page,
49
51
  per_page: perPage,
50
- search: query,
52
+ search,
51
53
  order: `${sortBy} ${sortOrder}`,
52
54
  },
53
55
  handleSuccess: response => {
@@ -96,7 +98,7 @@ export const clearAllSelection = () => dispatch => {
96
98
  dispatch(setSelectAll(false));
97
99
  };
98
100
 
99
- export const onTableSort = (_event, index, direction) => {
101
+ export const onTableSort = (columns, index, direction) => {
100
102
  // The checkbox column shifts the data columns by 1;
101
103
  const { sortKey } = columns[index - 1];
102
104
  return fetchInsights({
@@ -144,11 +146,16 @@ export const onTableSelect = (
144
146
  const setSelectAllUrl = selectAllValue => dispatch => {
145
147
  const uri = new URI();
146
148
  uri.setSearch({ select_all: selectAllValue });
149
+ updateUrl(uri, dispatch);
150
+ };
147
151
 
148
- dispatch(
149
- push({
150
- pathname: INSIGHTS_PATH,
151
- search: uri.search(),
152
- })
153
- );
152
+ const updateUrl = (uri, dispatch) => {
153
+ const nextUrlParams = { search: uri.search() };
154
+ if (isNewHostPage(uri)) {
155
+ // we need to keep the hash so the insights tab will remain selected in the new host details page.
156
+ nextUrlParams.hash = '/Insights';
157
+ }
158
+ dispatch(push(nextUrlParams));
154
159
  };
160
+
161
+ const isNewHostPage = uri => uri.pathname().includes(NEW_HOST_PATH);
@@ -4,10 +4,12 @@ import {
4
4
  InsightsLabel,
5
5
  Section,
6
6
  } from '@redhat-cloud-services/frontend-components';
7
+ import { DropdownItem } from '@patternfly/react-core';
7
8
  import { sortable, cellWidth } from '@patternfly/react-table';
8
- import { AnsibeTowerIcon } from '@patternfly/react-icons';
9
+ import { AnsibeTowerIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
9
10
  import { translate as __ } from 'foremanReact/common/I18n';
10
11
  import { foremanUrl } from '../../../ForemanRhCloudHelpers';
12
+ import DropdownToggle from '../../../common/DropdownToggle';
11
13
 
12
14
  export const totalRiskFormatter = ({ title: totalRisk }) => ({
13
15
  children: (
@@ -28,30 +30,73 @@ export const hasPlaybookFormatter = ({ title: hasPlaybook }) => ({
28
30
  ),
29
31
  });
30
32
 
33
+ export const actionsFormatter = (props, { rowData = {} }) => {
34
+ const { recommendationUrl, accessRHUrl } = rowData;
35
+ const dropdownItems = [];
36
+
37
+ recommendationUrl &&
38
+ dropdownItems.push(
39
+ <DropdownItem key="recommendation-url">
40
+ <a href={recommendationUrl} target="_blank" rel="noopener noreferrer">
41
+ {__('View in Red Hat Insights')} <ExternalLinkAltIcon />
42
+ </a>
43
+ </DropdownItem>
44
+ );
45
+
46
+ accessRHUrl &&
47
+ dropdownItems.push(
48
+ <DropdownItem key="access-url">
49
+ <a href={accessRHUrl} target="_blank" rel="noopener noreferrer">
50
+ {__('Knowledgebase article')} <ExternalLinkAltIcon />
51
+ </a>
52
+ </DropdownItem>
53
+ );
54
+
55
+ return {
56
+ children: <DropdownToggle items={dropdownItems} />,
57
+ };
58
+ };
59
+
31
60
  export const columns = [
32
61
  {
62
+ id: 'hostname',
33
63
  sortKey: 'hostname',
34
64
  title: __('Hostname'),
35
65
  transforms: [cellWidth(20), sortable],
36
66
  },
37
67
  {
68
+ id: 'recommendation',
38
69
  sortKey: 'title',
39
70
  title: __('Recommendation'),
40
71
  transforms: [cellWidth(50), sortable],
41
72
  },
42
73
  {
74
+ id: 'total risk',
43
75
  sortKey: 'total_risk',
44
76
  title: __('Total risk'),
45
77
  transforms: [cellWidth(15), sortable],
46
78
  cellTransforms: [totalRiskFormatter],
47
79
  },
48
80
  {
81
+ id: 'remediate',
49
82
  title: __('Remediate'),
50
- transforms: [cellWidth(15)],
83
+ transforms: [cellWidth(10)],
51
84
  cellTransforms: [hasPlaybookFormatter],
52
85
  },
86
+ {
87
+ id: 'actions',
88
+ title: '',
89
+ transforms: [cellWidth(5)],
90
+ cellTransforms: [actionsFormatter],
91
+ },
53
92
  ];
54
93
 
94
+ export const getColumnsWithoutHostname = () => {
95
+ const nextCols = columns.slice(1);
96
+ nextCols[0].transforms = [cellWidth(70), sortable];
97
+ return nextCols;
98
+ };
99
+
55
100
  export const paginationTitles = {
56
101
  items: __('items'),
57
102
  page: __('page'),
@@ -75,3 +120,5 @@ export const INSIGHTS_SET_SELECTED_IDS = 'INSIGHTS_SET_SELECTED_IDS';
75
120
  export const INSIGHTS_SET_SELECT_ALL_ALERT = 'INSIGHTS_SET_SELECT_ALL_ALERT';
76
121
 
77
122
  export const INSIGHTS_SET_SELECT_ALL = 'INSIGHTS_SET_SELECT_ALL';
123
+
124
+ export const NEW_HOST_PATH = '/new/hosts/';
@@ -1,25 +1,42 @@
1
1
  /* eslint-disable camelcase */
2
- import { columns } from './InsightsTableConstants';
3
-
4
- export const modifySelectedRows = (hits, selectedIds, showSelectAllAlert) => {
2
+ export const modifySelectedRows = (
3
+ hits,
4
+ selectedIds,
5
+ showSelectAllAlert,
6
+ hideHost
7
+ ) => {
5
8
  if (hits.length === 0) return [];
6
9
 
7
10
  return hits
8
11
  .asMutable()
9
- .map(({ id, hostname, title, total_risk, has_playbook }) => {
10
- const disableCheckbox = !has_playbook;
11
- return {
12
- cells: [hostname, title, total_risk, has_playbook],
13
- disableCheckbox,
12
+ .map(
13
+ ({
14
14
  id,
15
- /** The main table checkbox will be seen as selected only if all rows are selected,
16
- * in this case we need to select also the disabled once and hide it with css */
17
- selected: selectedIds[id] || (disableCheckbox && showSelectAllAlert),
18
- };
19
- });
15
+ hostname,
16
+ title,
17
+ total_risk,
18
+ has_playbook,
19
+ results_url,
20
+ solution_url,
21
+ }) => {
22
+ const disableCheckbox = !has_playbook;
23
+ const cells = [hostname, title, total_risk, has_playbook, results_url];
24
+ if (hideHost) cells.shift();
25
+ return {
26
+ cells,
27
+ disableCheckbox,
28
+ id,
29
+ /** The main table checkbox will be seen as selected only if all rows are selected,
30
+ * in this case we need to select also the disabled once and hide it with css */
31
+ selected: selectedIds[id] || (disableCheckbox && showSelectAllAlert),
32
+ recommendationUrl: results_url,
33
+ accessRHUrl: solution_url,
34
+ };
35
+ }
36
+ );
20
37
  };
21
38
 
22
- export const getSortColumnIndex = sortBy => {
39
+ export const getSortColumnIndex = (columns, sortBy) => {
23
40
  let colIndex = 0;
24
41
  columns.forEach((col, index) => {
25
42
  if (col.sortKey === sortBy) {
@@ -17,6 +17,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
17
17
  cells={
18
18
  Array [
19
19
  Object {
20
+ "id": "hostname",
20
21
  "sortKey": "hostname",
21
22
  "title": "Hostname",
22
23
  "transforms": Array [
@@ -25,6 +26,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
25
26
  ],
26
27
  },
27
28
  Object {
29
+ "id": "recommendation",
28
30
  "sortKey": "title",
29
31
  "title": "Recommendation",
30
32
  "transforms": Array [
@@ -36,6 +38,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
36
38
  "cellTransforms": Array [
37
39
  [Function],
38
40
  ],
41
+ "id": "total risk",
39
42
  "sortKey": "total_risk",
40
43
  "title": "Total risk",
41
44
  "transforms": Array [
@@ -47,20 +50,34 @@ exports[`InsightsTable rendering render with Props 1`] = `
47
50
  "cellTransforms": Array [
48
51
  [Function],
49
52
  ],
53
+ "id": "remediate",
50
54
  "title": "Remediate",
51
55
  "transforms": Array [
52
56
  [Function],
53
57
  ],
54
58
  },
59
+ Object {
60
+ "cellTransforms": Array [
61
+ [Function],
62
+ ],
63
+ "id": "actions",
64
+ "title": "",
65
+ "transforms": Array [
66
+ [Function],
67
+ ],
68
+ },
55
69
  ]
56
70
  }
57
- className="recommendations-table"
71
+ className="rh-cloud-recommendations-table"
58
72
  contentId="expanded-content"
59
73
  dropdownDirection="down"
60
74
  dropdownPosition="right"
61
75
  expandId="expandable-toggle"
62
76
  gridBreakPoint="grid-md"
77
+ isHeaderSelectDisabled={false}
78
+ isNested={false}
63
79
  isStickyHeader={false}
80
+ isTreeTable={false}
64
81
  onSelect={[Function]}
65
82
  onSort={[Function]}
66
83
  ouiaSafe={true}
@@ -77,7 +94,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
77
94
  variant="compact"
78
95
  >
79
96
  <TableHeader />
80
- <Component />
97
+ <TableBody />
81
98
  </Table>
82
99
  <TableEmptyState
83
100
  error={null}
@@ -31,7 +31,6 @@ Array [
31
31
  "payload": Object {
32
32
  "args": Array [
33
33
  Object {
34
- "pathname": "/foreman_rh_cloud/insights_cloud",
35
34
  "search": "?page=2&per_page=7&search=&sort_by=&sort_order=&select_all=true",
36
35
  },
37
36
  ],
@@ -1,21 +1,19 @@
1
1
  @import '~@redhat-cloud-services/frontend-components/index.css';
2
2
 
3
- .rh-cloud-insights {
4
- .recommendations-table {
5
- .pf-c-table__check {
6
- input:disabled {
7
- display: none;
8
- }
3
+ .rh-cloud-recommendations-table {
4
+ .pf-c-table__check {
5
+ input:disabled {
6
+ display: none;
9
7
  }
8
+ }
10
9
 
11
- .td-insights-remediate-playbook {
12
- svg {
13
- margin-right: 5px;
14
- }
10
+ .td-insights-remediate-playbook {
11
+ svg {
12
+ margin-right: 5px;
15
13
  }
14
+ }
16
15
 
17
- .td-insights-remediate-manual {
18
- padding-left: 18px;
19
- }
16
+ .td-insights-remediate-manual {
17
+ padding-left: 18px;
20
18
  }
21
19
  }
@@ -6,18 +6,4 @@
6
6
  margin-top: 5px;
7
7
  }
8
8
  }
9
-
10
- // applies to the backdrop parent of the modal
11
- @at-root .pf-c-backdrop {
12
- width: calc(100% - 200px);
13
- left: 200px;
14
- }
15
-
16
- // where the vertical nav breaks: https://github.com/theforeman/foreman/blob/3347fa49d500964f0209122d8d36c920d1feafcc/webpack/assets/javascripts/react_app/components/Layout/components/Toolbar/HeaderToolbar.scss#L26
17
- @media (max-width: 768px) {
18
- @at-root .pf-c-backdrop {
19
- width: 100%;
20
- left: 0;
21
- }
22
- }
23
9
  }
@@ -2,6 +2,8 @@ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { translate as __ } from 'foremanReact/common/I18n';
4
4
  import { Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core';
5
+ import { ExternalLinkAltIcon } from '@patternfly/react-icons';
6
+ import { redHatAdvisorSystems } from '../InsightsCloudSyncHelpers';
5
7
 
6
8
  const ToolbarDropdown = ({ onRecommendationSync }) => {
7
9
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
@@ -12,6 +14,17 @@ const ToolbarDropdown = ({ onRecommendationSync }) => {
12
14
  >
13
15
  {__('Sync recommendations')}
14
16
  </DropdownItem>,
17
+ <DropdownItem key="cloud-advisor-systems-link">
18
+ <a
19
+ href={redHatAdvisorSystems()}
20
+ target="_blank"
21
+ rel="noopener noreferrer"
22
+ >
23
+ {__('View in Red Hat Insights')}
24
+ {' '}
25
+ <ExternalLinkAltIcon />
26
+ </a>
27
+ </DropdownItem>,
15
28
  ];
16
29
  return (
17
30
  <Dropdown
@@ -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
- <button
194
- aria-disabled={true}
195
- aria-label={null}
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
- role={null}
203
- tabIndex={null}
204
- type="button"
201
+ variant="primary"
205
202
  >
206
- Save setting and sync recommendations
207
- </button>
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>
@@ -8,3 +8,11 @@ export const cloudTokenSettingUrl = () => {
8
8
  settingsUrl.setSearch({ search: 'name = rh_cloud_token' });
9
9
  return settingsUrl.toString();
10
10
  };
11
+
12
+ export const redHatConsole = path => `https://console.redhat.com/${path || ''}`;
13
+ export const redHatInsights = path => redHatConsole(`insights/${path || ''}`);
14
+ export const redHatInventory = path =>
15
+ redHatInsights(`inventory/${path || ''}`);
16
+ export const redHatAdvisor = path => redHatInsights(`advisor/${path || ''}`);
17
+ export const redHatAdvisorSystems = path =>
18
+ redHatAdvisor(`systems/${path || ''}`);
@@ -32,7 +32,7 @@ exports[`InsightsCloudSync render 1`] = `
32
32
  <span
33
33
  className="insights-toolbar-buttons"
34
34
  >
35
- <UNDEFINED />
35
+ <Memo(Connect(RemediationModal)) />
36
36
  <ToolbarDropdown
37
37
  onRecommendationSync={[Function]}
38
38
  />
@@ -84,3 +84,7 @@
84
84
  }
85
85
  }
86
86
  }
87
+
88
+ #new_host_details_insights_tab {
89
+ padding: 24px;
90
+ }
@@ -1,5 +1,5 @@
1
1
  import { API } from 'foremanReact/redux/API';
2
- import { addToast } from 'foremanReact/redux/actions/toasts';
2
+ import { addToast } from 'foremanReact/components/ToastsList';
3
3
  import { insightsCloudUrl } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
4
4
  import {
5
5
  INSIGHTS_HITS_REQUEST,
@@ -1,2 +1,77 @@
1
+ import { translate as __ } from 'foremanReact/common/I18n';
2
+
1
3
  export const INSIGHTS_HITS_REQUEST = 'INSIGHTS_HITS_REQUEST';
2
4
  export const INSIGHTS_HITS_SUCCESS = 'INSIGHTS_HITS_SUCCESS';
5
+
6
+ export const getInitialRisks = () => ({
7
+ 1: {
8
+ value: 0,
9
+ title: __('Low'),
10
+ hoverFill: '#2b9af3',
11
+ },
12
+ 2: {
13
+ value: 0,
14
+ title: __('Moderate'),
15
+ hoverFill: '#d5a632',
16
+ },
17
+ 3: {
18
+ value: 0,
19
+ title: __('Important'),
20
+ hoverFill: '#ec7a08',
21
+ },
22
+ 4: {
23
+ value: 0,
24
+ title: __('Critical'),
25
+ hoverFill: '#7d1007',
26
+ },
27
+ total: 0,
28
+ });
29
+
30
+ const colorScale = ['#bee1f4', '#f4c145', '#f4b678', '#c9190b'];
31
+
32
+ export const theme = {
33
+ legend: {
34
+ gutter: 20,
35
+ orientation: 'horizontal',
36
+ titleOrientation: 'top',
37
+ style: {
38
+ data: {
39
+ type: 'square',
40
+ },
41
+ labels: {
42
+ fontFamily: 'RedHatText',
43
+ fontSize: 14,
44
+ letterSpacing: 'normal',
45
+ padding: 10,
46
+ stroke: 'transparent',
47
+ fill: '#06c',
48
+ textDecorationColor: '#06c',
49
+ },
50
+ title: {
51
+ fontFamily: 'RedHatText',
52
+ fontSize: 14,
53
+ letterSpacing: 'normal',
54
+ padding: 2,
55
+ stroke: 'transparent',
56
+ },
57
+ },
58
+ colorScale,
59
+ },
60
+ pie: {
61
+ colorScale,
62
+ height: 230,
63
+ padAngle: 1,
64
+ padding: 20,
65
+ style: {
66
+ data: { padding: 8, stroke: 'transparent', strokeWidth: 1 },
67
+ labels: {
68
+ fontFamily: 'RedHatText',
69
+ fontSize: 14,
70
+ letterSpacing: 'normal',
71
+ padding: 8,
72
+ stroke: 'transparent',
73
+ },
74
+ },
75
+ width: 230,
76
+ },
77
+ };