foreman_rh_cloud 3.0.14 → 3.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -0
  3. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +11 -0
  4. data/app/controllers/insights_cloud/hits_controller.rb +24 -0
  5. data/app/controllers/insights_cloud/settings_controller.rb +8 -0
  6. data/app/models/insights_hit.rb +5 -1
  7. data/app/models/setting/rh_cloud.rb +8 -6
  8. data/app/overrides/layouts/base/styles.html.erb.deface +2 -0
  9. data/app/services/foreman_rh_cloud/cloud_connector.rb +59 -0
  10. data/app/views/layouts/foreman_rh_cloud/application.html.erb +0 -4
  11. data/config/Gemfile.lock.gh_test +830 -0
  12. data/config/database.yml.example +17 -0
  13. data/config/package-lock.json.gh_test +35653 -0
  14. data/config/routes.rb +12 -3
  15. data/lib/foreman_inventory_upload.rb +1 -1
  16. data/lib/foreman_inventory_upload/generators/archived_report.rb +1 -1
  17. data/lib/foreman_rh_cloud/engine.rb +15 -5
  18. data/lib/foreman_rh_cloud/version.rb +1 -1
  19. data/lib/tasks/rh_cloud_inventory.rake +23 -0
  20. data/package.json +18 -17
  21. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.js +3 -2
  22. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListActions.js +1 -1
  23. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/ListItem.js +33 -15
  24. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/__snapshots__/ListItem.test.js.snap +43 -43
  25. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/ListItemStatus.js +6 -7
  26. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/ListItemStatusHelper.js +5 -4
  27. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/__snapshots__/ListItemStatus.test.js.snap +19 -34
  28. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListActions.test.js +2 -2
  29. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountList.test.js.snap +3 -3
  30. data/webpack/ForemanInventoryUpload/Components/AccountList/accountList.scss +28 -5
  31. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcher.js +6 -9
  32. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherActions.js +1 -1
  33. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/AutoUploadSwitcherActions.test.js +2 -2
  34. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/__snapshots__/AutoUploadSwitcher.test.js.snap +5 -28
  35. data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardActions.js +1 -1
  36. data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardActions.test.js +2 -2
  37. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/ExcludePackagesSwitcher.js +6 -9
  38. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/ExcludePackagesSwitcherActions.js +1 -1
  39. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/ExcludePackagesSwitcherActions.test.js +2 -2
  40. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/__snapshots__/ExcludePackagesSwitcher.test.js.snap +5 -28
  41. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/__snapshots__/integration.test.js.snap +5 -0
  42. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/integration.test.js +2 -2
  43. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcher.js +6 -9
  44. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcherActions.js +1 -1
  45. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/__tests__/HostObfuscationSwitcherActions.test.js +2 -2
  46. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/__tests__/__snapshots__/HostObfuscationSwitcher.test.js.snap +5 -28
  47. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilterReducer.js +6 -3
  48. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/integration.test.js.snap +5 -0
  49. data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettings.js +2 -2
  50. data/webpack/ForemanInventoryUpload/Components/InventorySettings/{inventorySettings.scss → InventorySettings.scss} +2 -5
  51. data/webpack/ForemanInventoryUpload/Components/InventorySettings/__tests__/__snapshots__/InventorySettings.test.js.snap +1 -1
  52. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/IpsObfuscationSwitcher.js +6 -8
  53. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/IpsObfuscationSwitcherActions.js +1 -1
  54. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/__tests__/IpsObfuscationSwitcherActions.test.js +2 -2
  55. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/__tests__/__snapshots__/IpsObfuscationSwitcher.test.js.snap +5 -28
  56. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +10 -18
  57. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.scss +19 -0
  58. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +53 -0
  59. data/webpack/ForemanInventoryUpload/Components/PageHeader/{components/DocsButton/__tests__/DocsButton.test.js → __tests__/PageTitle.test.js} +3 -3
  60. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +12 -38
  61. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +43 -0
  62. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorActions.js +27 -0
  63. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +51 -0
  64. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorConstants.js +6 -0
  65. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorSelectors.js +14 -0
  66. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorActions.test.js +9 -0
  67. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorButton.test.js +22 -0
  68. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorActions.test.js.snap +11 -0
  69. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +48 -0
  70. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/index.js +27 -0
  71. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +7 -9
  72. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +1 -1
  73. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonActions.test.js +2 -2
  74. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +7 -9
  75. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/ToolbarButtons.js +2 -4
  76. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/__tests__/__snapshots__/ToolbarButtons.test.js.snap +1 -2
  77. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/toolbarButtons.scss +1 -2
  78. data/webpack/ForemanInventoryUpload/Components/Terminal/terminal.scss +1 -0
  79. data/webpack/ForemanInventoryUpload/ForemanInventoryConstants.js +2 -2
  80. data/webpack/ForemanInventoryUpload/ForemanInventoryUpload.js +8 -14
  81. data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryUpload.test.js.snap +7 -10
  82. data/webpack/ForemanRhCloudPages.js +19 -0
  83. data/webpack/InsightsCloudSync/Components/InsightsHeader/InsightsHeader.scss +4 -0
  84. data/webpack/InsightsCloudSync/Components/InsightsHeader/index.js +16 -0
  85. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js +1 -1
  86. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsActions.test.js +2 -2
  87. data/webpack/InsightsCloudSync/Components/InsightsSettings/insightsSettings.scss +1 -0
  88. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +121 -0
  89. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +129 -0
  90. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +55 -0
  91. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js +31 -0
  92. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableReducer.js +28 -0
  93. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +74 -0
  94. data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +65 -0
  95. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +13 -0
  96. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableSelectors.test.js +58 -0
  97. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +168 -0
  98. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableSelectors.test.js.snap +88 -0
  99. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/fixtures.js +104 -0
  100. data/webpack/InsightsCloudSync/Components/InsightsTable/components/EmptyState.js +53 -0
  101. data/webpack/InsightsCloudSync/Components/InsightsTable/index.js +45 -0
  102. data/webpack/InsightsCloudSync/Components/InsightsTable/table.scss +1 -0
  103. data/webpack/InsightsCloudSync/Components/NoTokenEmptyState.js +79 -0
  104. data/webpack/InsightsCloudSync/Components/__tests__/InsightsHeader.test.js +10 -0
  105. data/webpack/InsightsCloudSync/Components/__tests__/NoTokenEmptyState.test.js +19 -0
  106. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap +13 -0
  107. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap +214 -0
  108. data/webpack/InsightsCloudSync/InsightsCloudSync.js +45 -44
  109. data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +10 -2
  110. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +1 -1
  111. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +15 -1
  112. data/webpack/InsightsCloudSync/InsightsCloudSyncHelpers.js +7 -0
  113. data/webpack/InsightsCloudSync/InsightsCloudSyncReducers.js +2 -0
  114. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +45 -62
  115. data/webpack/InsightsCloudSync/index.js +11 -3
  116. data/webpack/InsightsHostDetailsTab/InsightsTabActions.js +1 -1
  117. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabActions.test.js +2 -2
  118. data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +1 -0
  119. data/webpack/__mocks__/foremanReact/constants.js +19 -0
  120. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +24 -0
  121. data/webpack/__mocks__/foremanReact/redux/API/index.js +11 -0
  122. data/webpack/__mocks__/foremanReact/routes/RouterSelector.js +2 -0
  123. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
  124. data/webpack/common/Switcher/HelpLabel.js +30 -0
  125. data/webpack/common/Switcher/SwitcherPF4.js +36 -0
  126. data/webpack/common/Switcher/SwitcherPF4.scss +10 -0
  127. data/webpack/common/Switcher/__tests__/HelpLabel.test.js +13 -0
  128. data/webpack/common/Switcher/__tests__/SwitcherPF4.test.js +14 -0
  129. data/webpack/common/Switcher/__tests__/__snapshots__/HelpLabel.test.js.snap +20 -0
  130. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +22 -0
  131. data/webpack/global_index.js +2 -0
  132. metadata +96 -34
  133. data/app/controllers/foreman_rh_cloud/react_controller.rb +0 -11
  134. data/app/views/foreman_rh_cloud/react/insights_cloud.html.erb +0 -1
  135. data/app/views/foreman_rh_cloud/react/inventory_upload.html.erb +0 -1
  136. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/listItem.scss +0 -0
  137. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/listItemStatus.scss +0 -16
  138. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/autoUploadSwitcher.scss +0 -3
  139. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/excludePackagesSwitcher.scss +0 -3
  140. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcher.scss +0 -3
  141. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/DocsButton/DocsButton.js +0 -18
  142. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/DocsButton/__tests__/__snapshots__/DocsButton.test.js.snap +0 -21
  143. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/DocsButton/index.js +0 -1
  144. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/HistoryButton/HistoryButton.js +0 -19
  145. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/HistoryButton/__tests__/HistoryButton.test.js +0 -12
  146. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/HistoryButton/__tests__/__snapshots__/HistoryButton.test.js.snap +0 -22
  147. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/HistoryButton/index.js +0 -1
  148. data/webpack/ForemanInventoryUpload/Components/PageHeader/pageHeader.scss +0 -3
  149. data/webpack/__mocks__/foremanReact/API.js +0 -7
@@ -0,0 +1,129 @@
1
+ import URI from 'urijs';
2
+ import { push } from 'connected-react-router';
3
+ import { get } from 'foremanReact/redux/API';
4
+ import {
5
+ selectIsAllSelected,
6
+ selectQueryParams,
7
+ } from './InsightsTableSelectors';
8
+ import { INSIGHTS_PATH } from '../../InsightsCloudSyncConstants';
9
+ import {
10
+ columns,
11
+ INSIGHTS_HITS_API_KEY,
12
+ INSIGHTS_HITS_PATH,
13
+ INSIGHTS_SET_SELECTED_IDS,
14
+ INSIGHTS_SET_SELECT_ALL_ALERT,
15
+ INSIGHTS_SET_SELECT_ALL,
16
+ } from './InsightsTableConstants';
17
+
18
+ export const fetchInsights = (queryParams = {}) => (dispatch, getState) => {
19
+ const state = getState();
20
+ const { page, perPage, query, sortBy, sortOrder } = {
21
+ ...selectQueryParams(state),
22
+ ...queryParams,
23
+ };
24
+
25
+ dispatch(
26
+ get({
27
+ key: INSIGHTS_HITS_API_KEY,
28
+ url: INSIGHTS_HITS_PATH,
29
+ params: {
30
+ page,
31
+ per_page: perPage,
32
+ search: query,
33
+ order: `${sortBy} ${sortOrder}`,
34
+ },
35
+ })
36
+ );
37
+
38
+ const uri = new URI();
39
+ uri.search({
40
+ page,
41
+ per_page: perPage,
42
+ search: query,
43
+ sort_by: sortBy,
44
+ sort_order: sortOrder,
45
+ });
46
+
47
+ dispatch(
48
+ push({
49
+ pathname: INSIGHTS_PATH,
50
+ search: uri.search(),
51
+ })
52
+ );
53
+
54
+ const isAllSelected = selectIsAllSelected(state);
55
+ if (isAllSelected) {
56
+ dispatch(clearAllSelection());
57
+ } else {
58
+ dispatch(setSelectAllAlert(false));
59
+ dispatch(setSelectAll(false));
60
+ }
61
+ };
62
+
63
+ export const setSelectAllAlert = showSelectAllAlert => ({
64
+ type: INSIGHTS_SET_SELECT_ALL_ALERT,
65
+ payload: { showSelectAllAlert },
66
+ });
67
+
68
+ export const selectByIds = selectedIds => ({
69
+ type: INSIGHTS_SET_SELECTED_IDS,
70
+ payload: { selectedIds },
71
+ });
72
+
73
+ export const setSelectAll = isAllSelected => ({
74
+ type: INSIGHTS_SET_SELECT_ALL,
75
+ payload: { isAllSelected },
76
+ });
77
+
78
+ export const selectAll = () => setSelectAll(true);
79
+
80
+ export const clearAllSelection = () => dispatch => {
81
+ dispatch(selectByIds({}));
82
+ dispatch(setSelectAllAlert(false));
83
+ dispatch(setSelectAll(false));
84
+ };
85
+
86
+ export const onTableSort = (_event, index, direction) => {
87
+ // The checkbox column shifts the data columns by 1;
88
+ const { sortKey } = columns[index - 1];
89
+ return fetchInsights({
90
+ sortBy: sortKey,
91
+ sortOrder: direction,
92
+ page: 1,
93
+ });
94
+ };
95
+
96
+ export const onTableSetPage = (_event, pageNumber) =>
97
+ fetchInsights({ page: pageNumber });
98
+
99
+ export const onTablePerPageSelect = (_event, perPageNumber) =>
100
+ fetchInsights({ perPage: perPageNumber });
101
+
102
+ export const onTableSelect = (
103
+ _event,
104
+ isSelected,
105
+ rowId,
106
+ results,
107
+ prevSelectedIds
108
+ ) => dispatch => {
109
+ const selectedIds = { ...prevSelectedIds };
110
+ let showSelectAllAlert = false;
111
+ // for select all
112
+ if (rowId === -1) {
113
+ if (!isSelected) return dispatch(clearAllSelection());
114
+
115
+ results.forEach(row => {
116
+ selectedIds[row.id] = true;
117
+ });
118
+
119
+ showSelectAllAlert = true;
120
+ } else {
121
+ isSelected
122
+ ? (selectedIds[results[rowId].id] = true)
123
+ : delete selectedIds[results[rowId].id];
124
+ }
125
+
126
+ dispatch(selectByIds(selectedIds));
127
+ dispatch(setSelectAllAlert(showSelectAllAlert));
128
+ return null;
129
+ };
@@ -0,0 +1,55 @@
1
+ /* eslint-disable camelcase */
2
+ import React from 'react';
3
+ import {
4
+ InsightsLabel,
5
+ Section,
6
+ } from '@redhat-cloud-services/frontend-components';
7
+ import { sortable, cellWidth } from '@patternfly/react-table';
8
+ import { translate as __ } from 'foremanReact/common/I18n';
9
+ import { foremanUrl } from '../../../ForemanRhCloudHelpers';
10
+
11
+ export const totalRiskFormatter = ({ title: totalRisk }) => ({
12
+ children: (
13
+ <Section className="insights-total-risk" type="icon-group">
14
+ <InsightsLabel value={totalRisk} />
15
+ </Section>
16
+ ),
17
+ });
18
+
19
+ export const columns = [
20
+ {
21
+ sortKey: 'hostname',
22
+ title: __('Hostname'),
23
+ transforms: [cellWidth(20), sortable],
24
+ },
25
+ {
26
+ sortKey: 'title',
27
+ title: __('Recommendation'),
28
+ transforms: [cellWidth(60), sortable],
29
+ },
30
+ {
31
+ sortKey: 'total_risk',
32
+ title: __('Total Risk'),
33
+ transforms: [cellWidth(20), sortable],
34
+ cellTransforms: [totalRiskFormatter],
35
+ },
36
+ ];
37
+
38
+ export const actions = [
39
+ {
40
+ title: __('Remediate'),
41
+ onClick: (event, rowId, rowData, extra) => {
42
+ alert('Remediate!');
43
+ },
44
+ },
45
+ ];
46
+
47
+ export const INSIGHTS_HITS_PATH = foremanUrl('/insights_cloud/hits');
48
+
49
+ export const INSIGHTS_HITS_API_KEY = 'INSIGHTS_HITS';
50
+
51
+ export const INSIGHTS_SET_SELECTED_IDS = 'INSIGHTS_SET_SELECTED_IDS';
52
+
53
+ export const INSIGHTS_SET_SELECT_ALL_ALERT = 'INSIGHTS_SET_SELECT_ALL_ALERT';
54
+
55
+ export const INSIGHTS_SET_SELECT_ALL = 'INSIGHTS_SET_SELECT_ALL';
@@ -0,0 +1,31 @@
1
+ /* eslint-disable camelcase */
2
+ import { columns } from './InsightsTableConstants';
3
+
4
+ export const modifySelectedRows = (hits, selectedIds) => {
5
+ if (hits.length === 0) return [];
6
+
7
+ return hits.asMutable().map(({ id, hostname, title, total_risk }) => {
8
+ const row = [hostname, title, total_risk];
9
+ row.selected = selectedIds[id];
10
+ return row;
11
+ });
12
+ };
13
+
14
+ export const getSortColumnIndex = sortBy => {
15
+ let colIndex = 0;
16
+ columns.forEach((col, index) => {
17
+ if (col.sortKey === sortBy) {
18
+ // The checkbox column shifts the data columns by 1;
19
+ colIndex = index + 1;
20
+ }
21
+ });
22
+ return colIndex;
23
+ };
24
+
25
+ export const getPerPageOptions = (urlPerPage, appPerPage) => {
26
+ const initialValues = new Set([5, 10, 15, 25, 50]);
27
+ initialValues.add(appPerPage);
28
+ urlPerPage && initialValues.add(urlPerPage);
29
+ const options = [...initialValues].sort((a, b) => a - b);
30
+ return options.map(value => ({ title: value.toString(), value }));
31
+ };
@@ -0,0 +1,28 @@
1
+ import Immutable from 'seamless-immutable';
2
+ import {
3
+ INSIGHTS_SET_SELECTED_IDS,
4
+ INSIGHTS_SET_SELECT_ALL_ALERT,
5
+ INSIGHTS_SET_SELECT_ALL,
6
+ } from './InsightsTableConstants';
7
+
8
+ const initialState = Immutable({
9
+ selectedIds: {},
10
+ showSelectAllAlert: false,
11
+ isAllSelected: false,
12
+ });
13
+
14
+ export default (
15
+ state = initialState,
16
+ { payload: { selectedIds, showSelectAllAlert, isAllSelected } = {}, type }
17
+ ) => {
18
+ switch (type) {
19
+ case INSIGHTS_SET_SELECTED_IDS:
20
+ return state.merge({ selectedIds });
21
+ case INSIGHTS_SET_SELECT_ALL_ALERT:
22
+ return state.merge({ showSelectAllAlert });
23
+ case INSIGHTS_SET_SELECT_ALL:
24
+ return state.merge({ isAllSelected });
25
+ default:
26
+ return state;
27
+ }
28
+ };
@@ -0,0 +1,74 @@
1
+ import URI from 'urijs';
2
+ import { STATUS } from 'foremanReact/constants';
3
+ import { selectRouterLocation } from 'foremanReact/routes/RouterSelector';
4
+ import {
5
+ selectAPIResponse,
6
+ selectAPIStatus,
7
+ selectAPIErrorMessage,
8
+ } from 'foremanReact/redux/API/APISelectors';
9
+ import { INSIGHTS_HITS_API_KEY } from './InsightsTableConstants';
10
+ import { selectInsightsCloudSync } from '../../../ForemanRhCloudSelectors';
11
+
12
+ export const selectQuery = state => selectRouterLocation(state).query;
13
+
14
+ export const selectSearch = state => {
15
+ const { search = '' } = selectQuery(state);
16
+ return URI.decodeQuery(search);
17
+ };
18
+
19
+ export const selectPage = state => {
20
+ const { page = '1' } = selectQuery(state);
21
+ return Number(page);
22
+ };
23
+
24
+ export const selectPerPage = state => {
25
+ const perPage = selectQuery(state).per_page;
26
+ return perPage && Number(perPage);
27
+ };
28
+
29
+ export const selectQueryParams = state => ({
30
+ page: selectPage(state),
31
+ perPage: selectPerPage(state),
32
+ query: selectSearch(state),
33
+ sortBy: selectSortBy(state),
34
+ sortOrder: selectSortOrder(state),
35
+ });
36
+
37
+ export const selectStatus = state =>
38
+ selectAPIStatus(state, INSIGHTS_HITS_API_KEY);
39
+
40
+ export const selectError = state =>
41
+ selectAPIErrorMessage(state, INSIGHTS_HITS_API_KEY);
42
+
43
+ export const selectSortBy = state => {
44
+ const sortBy = selectQuery(state).sort_by;
45
+ return sortBy ? URI.decodeQuery(sortBy) : '';
46
+ };
47
+
48
+ export const selectSortOrder = state => {
49
+ const sortOrder = selectQuery(state).sort_order;
50
+ return sortOrder ? URI.decodeQuery(sortOrder) : '';
51
+ };
52
+
53
+ export const selectHits = state => {
54
+ if (selectStatus(state) !== STATUS.RESOLVED) return [];
55
+ return selectAPIResponse(state, INSIGHTS_HITS_API_KEY).hits || [];
56
+ };
57
+
58
+ export const selectInsightsCloudTable = state =>
59
+ selectInsightsCloudSync(state).table || {};
60
+
61
+ export const selectSelectedIds = state =>
62
+ selectInsightsCloudTable(state).selectedIds || {};
63
+
64
+ export const selectIsAllSelected = state =>
65
+ selectInsightsCloudTable(state).isAllSelected || false;
66
+
67
+ export const selectShowSelectAllAlert = state =>
68
+ selectInsightsCloudTable(state).showSelectAllAlert || false;
69
+
70
+ export const selectItemCount = state =>
71
+ selectAPIResponse(state, INSIGHTS_HITS_API_KEY).itemCount || 0;
72
+
73
+ export const selectHasToken = state =>
74
+ selectAPIResponse(state, INSIGHTS_HITS_API_KEY).hasToken;
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Alert, AlertActionLink } from '@patternfly/react-core';
4
+ import { translate as __, sprintf } from 'foremanReact/common/I18n';
5
+
6
+ const SelectAllAlert = ({
7
+ selectedIds,
8
+ itemCount,
9
+ showSelectAllAlert,
10
+ selectAll,
11
+ clearAllSelection,
12
+ isAllSelected,
13
+ }) => {
14
+ if (!showSelectAllAlert) return null;
15
+ const selectedCount = Object.keys(selectedIds).length;
16
+ if (!selectedCount) return null;
17
+ if (!isAllSelected && selectedCount !== itemCount) {
18
+ return (
19
+ <Alert
20
+ isInline
21
+ variant="info"
22
+ title={sprintf(
23
+ 'All %s recommendations on this page are selected.',
24
+ selectedCount
25
+ )}
26
+ actionLinks={
27
+ <AlertActionLink onClick={selectAll}>
28
+ {sprintf('Select all %s recommendations', itemCount)}
29
+ </AlertActionLink>
30
+ }
31
+ />
32
+ );
33
+ }
34
+
35
+ return (
36
+ <Alert
37
+ isInline
38
+ variant="info"
39
+ title={sprintf('All %s recommendations are selected.', itemCount)}
40
+ actionLinks={
41
+ <AlertActionLink onClick={clearAllSelection}>
42
+ {__('Clear Selection')}
43
+ </AlertActionLink>
44
+ }
45
+ />
46
+ );
47
+ };
48
+
49
+ SelectAllAlert.propTypes = {
50
+ selectedIds: PropTypes.object,
51
+ itemCount: PropTypes.number,
52
+ showSelectAllAlert: PropTypes.bool,
53
+ selectAll: PropTypes.func.isRequired,
54
+ clearAllSelection: PropTypes.func.isRequired,
55
+ isAllSelected: PropTypes.bool,
56
+ };
57
+
58
+ SelectAllAlert.defaultProps = {
59
+ selectedIds: {},
60
+ itemCount: 0,
61
+ showSelectAllAlert: false,
62
+ isAllSelected: false,
63
+ };
64
+
65
+ export default SelectAllAlert;
@@ -0,0 +1,13 @@
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
+
3
+ import InsightsTable from '../InsightsTable';
4
+ import { tableProps } from './fixtures';
5
+
6
+ const fixtures = {
7
+ 'render with Props': tableProps,
8
+ };
9
+
10
+ describe('InsightsTable', () => {
11
+ describe('rendering', () =>
12
+ testComponentSnapshotsWithFixtures(InsightsTable, fixtures));
13
+ });
@@ -0,0 +1,58 @@
1
+ import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
2
+ import { insightsStateWrapper } from '../../../../ForemanRhCloudTestHelpers';
3
+ import { routerState, APIState, APIErrorState } from './fixtures';
4
+ import {
5
+ selectError,
6
+ selectHasToken,
7
+ selectHits,
8
+ selectInsightsCloudTable,
9
+ selectIsAllSelected,
10
+ selectItemCount,
11
+ selectPage,
12
+ selectPerPage,
13
+ selectQuery,
14
+ selectQueryParams,
15
+ selectSearch,
16
+ selectSelectedIds,
17
+ selectShowSelectAllAlert,
18
+ selectSortBy,
19
+ selectSortOrder,
20
+ selectStatus,
21
+ } from '../InsightsTableSelectors';
22
+
23
+ const state = {
24
+ ...routerState,
25
+ ...APIState,
26
+ ...insightsStateWrapper({
27
+ table: {
28
+ selectedIds: {
29
+ '51': true,
30
+ },
31
+ showSelectAllAlert: true,
32
+ isAllSelected: false,
33
+ },
34
+ }),
35
+ };
36
+
37
+ const fixtures = {
38
+ 'should return router query': () => selectQuery(state),
39
+ 'should return router search': () => selectSearch(state),
40
+ 'should return router page': () => selectPage(state),
41
+ 'should return router perPage': () => selectPerPage(state),
42
+ 'should return router sort by': () => selectSortBy(state),
43
+ 'should return router sort order': () => selectSortOrder(state),
44
+ 'should return queryParams': () => selectQueryParams(state),
45
+ 'should return API status': () => selectStatus(state),
46
+ 'should return API error': () => selectError({ ...state, ...APIErrorState }),
47
+ 'should return API hits': () => selectHits(state),
48
+ 'should return API item count': () => selectItemCount(state),
49
+ 'should return API has token': () => selectHasToken(state),
50
+ 'should return insights table': () => selectInsightsCloudTable(state),
51
+ 'should return insights selectedIds': () => selectSelectedIds(state),
52
+ 'should return insights isAllSelected': () => selectIsAllSelected(state),
53
+ 'should return insights showSelectAllAlert': () =>
54
+ selectShowSelectAllAlert(state),
55
+ };
56
+
57
+ describe('InsightsTable selectors', () =>
58
+ testSelectorsSnapshotWithFixtures(fixtures));