foreman_host_reports 0.0.4 → 1.0.0

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +67 -447
  3. data/app/controllers/api/v2/host_reports_controller.rb +39 -20
  4. data/app/controllers/concerns/foreman_host_reports/controller/hosts_controller_extensions.rb +18 -0
  5. data/app/controllers/concerns/foreman_host_reports/controller/parameters/host_report.rb +1 -1
  6. data/app/controllers/host_reports_controller.rb +32 -2
  7. data/app/helpers/concerns/foreman_host_reports/hosts_helper_extensions.rb +25 -0
  8. data/app/models/concerns/foreman_host_reports/host_extensions.rb +6 -0
  9. data/app/models/host_report.rb +15 -0
  10. data/app/models/host_status/host_report_status.rb +185 -0
  11. data/app/views/api/v2/host_reports/main.json.rabl +1 -2
  12. data/config/routes.rb +2 -4
  13. data/db/migrate/20220113064436_rename_status_summaries.rb +12 -0
  14. data/lib/foreman_host_reports/engine.rb +11 -5
  15. data/lib/foreman_host_reports/version.rb +1 -1
  16. data/test/controllers/api/v2/host_reports_controller_test.rb +30 -67
  17. data/test/factories/foreman_host_reports_factories.rb +13 -5
  18. data/test/model/host_report_status_test.rb +204 -0
  19. data/test/test_plugin_helper.rb +4 -2
  20. data/webpack/__mocks__/foremanReact/components/Pagination/index.js +2 -0
  21. data/webpack/fills.js +23 -0
  22. data/webpack/global_index.js +2 -0
  23. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/statusFormatter.js +3 -4
  24. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.js +1 -1
  25. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTable.js +2 -10
  26. data/webpack/src/Router/HostReports/IndexPage/IndexPage.js +0 -1
  27. data/webpack/src/Router/HostReports/IndexPage/IndexPageActions.js +5 -4
  28. data/webpack/src/Router/HostReports/IndexPage/IndexPageHelpers.js +1 -1
  29. data/webpack/src/Router/HostReports/IndexPage/__tests__/HostReportsIndexPage.test.js +3 -4
  30. data/webpack/src/Router/HostReports/IndexPage/__tests__/__snapshots__/HostReportsIndexPage.test.js.snap +4 -6
  31. data/webpack/src/Router/HostReports/IndexPage/constants.js +4 -3
  32. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Ansible.js +62 -27
  33. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Components/EmptyLogsRow.js +27 -0
  34. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Components/RawMsgModal.js +41 -0
  35. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Puppet.js +38 -37
  36. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/index.js +10 -3
  37. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogsFilter/index.js +56 -65
  38. data/webpack/src/Router/HostReports/ShowPage/ShowPage.js +34 -8
  39. data/webpack/src/Router/HostReports/constants.js +2 -0
  40. data/webpack/src/components/ReportsTab/ReportsTable.js +117 -0
  41. data/webpack/src/components/ReportsTab/helpers.js +155 -0
  42. data/webpack/src/components/ReportsTab/index.js +132 -0
  43. metadata +18 -19
  44. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -4
@@ -0,0 +1,117 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ TableComposable,
5
+ Thead,
6
+ Tbody,
7
+ Tr,
8
+ Th,
9
+ Td,
10
+ } from '@patternfly/react-table';
11
+ import {
12
+ EmptyState,
13
+ EmptyStateIcon,
14
+ Spinner,
15
+ Title,
16
+ Grid,
17
+ } from '@patternfly/react-core';
18
+ import { SearchIcon, ExclamationCircleIcon } from '@patternfly/react-icons';
19
+ import { STATUS } from 'foremanReact/constants';
20
+ import { translate as __ } from 'foremanReact/common/I18n';
21
+ import { getColumns } from './helpers';
22
+
23
+ const ReportsTable = ({ reports, status, fetchReports }) => {
24
+ const columns = getColumns(fetchReports);
25
+ let tableBody = null;
26
+ let tableHead = null;
27
+ let emptyState = null;
28
+
29
+ if (status === STATUS.RESOLVED) {
30
+ if (reports.length) {
31
+ tableHead = (
32
+ <Thead>
33
+ <Tr>
34
+ {columns.map(({ width, title }, columnIndex) => (
35
+ <Th key={columnIndex} width={width}>
36
+ {title}
37
+ </Th>
38
+ ))}
39
+ </Tr>
40
+ </Thead>
41
+ );
42
+ tableBody = (
43
+ <Tbody>
44
+ {reports.map((row, rowIndex) => (
45
+ <Tr key={rowIndex}>
46
+ {columns.map(({ title, formatter }, cellIndex) => (
47
+ <Td key={`${rowIndex}_${cellIndex}`} dataLabel={title}>
48
+ {formatter(row)}
49
+ </Td>
50
+ ))}
51
+ </Tr>
52
+ ))}
53
+ </Tbody>
54
+ );
55
+ } else {
56
+ emptyState = (
57
+ <Grid>
58
+ <EmptyState>
59
+ <EmptyStateIcon icon={SearchIcon} />
60
+ <Title size="lg" headingLevel="h4">
61
+ {__('No results found')}
62
+ </Title>
63
+ </EmptyState>
64
+ </Grid>
65
+ );
66
+ }
67
+ } else if (status === STATUS.FAILURE) {
68
+ emptyState = (
69
+ <Grid>
70
+ <EmptyState>
71
+ <EmptyStateIcon
72
+ icon={
73
+ <ExclamationCircleIcon color="var(--pf-global--palette--red-200)" />
74
+ }
75
+ />
76
+ <Title size="lg" headingLevel="h4">
77
+ {__('Something went wrong')}
78
+ </Title>
79
+ </EmptyState>
80
+ </Grid>
81
+ );
82
+ } else if (status === STATUS.PENDING) {
83
+ emptyState = (
84
+ <Grid>
85
+ <EmptyState>
86
+ <EmptyStateIcon variant="container" component={Spinner} />
87
+ <Title size="lg" headingLevel="h4">
88
+ {__('Loading')}
89
+ </Title>
90
+ </EmptyState>
91
+ </Grid>
92
+ );
93
+ }
94
+
95
+ return (
96
+ <React.Fragment>
97
+ <TableComposable aria-label="Reports table" variant="compact">
98
+ {tableHead}
99
+ {tableBody}
100
+ </TableComposable>
101
+ {emptyState}
102
+ </React.Fragment>
103
+ );
104
+ };
105
+
106
+ ReportsTable.propTypes = {
107
+ reports: PropTypes.array,
108
+ status: PropTypes.string,
109
+ fetchReports: PropTypes.func.isRequired,
110
+ };
111
+
112
+ ReportsTable.defaultProps = {
113
+ reports: [],
114
+ status: null,
115
+ };
116
+
117
+ export default ReportsTable;
@@ -0,0 +1,155 @@
1
+ /* eslint-disable camelcase */
2
+ /* eslint-disable react/prop-types */
3
+ import React, { useState } from 'react';
4
+ import { useDispatch } from 'react-redux';
5
+ import {
6
+ Dropdown,
7
+ DropdownItem,
8
+ KebabToggle,
9
+ FlexItem,
10
+ Flex,
11
+ Tooltip,
12
+ } from '@patternfly/react-core';
13
+ import {
14
+ ExclamationCircleIcon,
15
+ SyncAltIcon,
16
+ CheckCircleIcon,
17
+ BanIcon,
18
+ TagIcon,
19
+ } from '@patternfly/react-icons';
20
+ import { openConfirmModal } from 'foremanReact/components/ConfirmModal';
21
+ import { APIActions } from 'foremanReact/redux/API';
22
+ import { translate as __ } from 'foremanReact/common/I18n';
23
+ import { reportToShowFormatter } from '../../Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters';
24
+
25
+ const FailedIcon = ({ label, withMargin = false }) => (
26
+ <span style={withMargin ? { marginRight: '15px' } : {}}>
27
+ <ExclamationCircleIcon color="var(--pf-global--palette--red-100)" /> {label}
28
+ </span>
29
+ );
30
+
31
+ const ChangedIcon = ({ label, withMargin = false }) => (
32
+ <span style={withMargin ? { marginRight: '15px' } : {}}>
33
+ <SyncAltIcon color="var(--pf-global--palette--orange-300)" /> {label}
34
+ </span>
35
+ );
36
+
37
+ const NochangeIcon = ({ label }) => (
38
+ <>
39
+ <CheckCircleIcon color="var(--pf-global--success-color--100)" /> {label}
40
+ </>
41
+ );
42
+
43
+ export const statusSummaryFormatter = ({ change, nochange, failure }) => {
44
+ const summary = [];
45
+ if (failure)
46
+ summary.push(<FailedIcon key="failed" label={failure} withMargin />);
47
+ if (change)
48
+ summary.push(<ChangedIcon key="changed" label={change} withMargin />);
49
+ if (nochange) summary.push(<NochangeIcon key="nochange" label={nochange} />);
50
+ return summary.length ? summary : '--';
51
+ };
52
+
53
+ export const globalStatusFormatter = ({ status }) => {
54
+ switch (status) {
55
+ case 'failure':
56
+ return <FailedIcon label={__('Fail')} />;
57
+ case 'change':
58
+ return <ChangedIcon label={__('Changed')} />;
59
+ case 'nochange':
60
+ return <NochangeIcon label={__('Unchanged')} />;
61
+ default:
62
+ return (
63
+ <>
64
+ <BanIcon /> {__('Empty')}
65
+ </>
66
+ );
67
+ }
68
+ };
69
+
70
+ export const keywordsFormatter = ({ keywords = [] }) => (
71
+ <>
72
+ <Tooltip content={<div>{keywords.join(',\n')}</div>}>
73
+ <TagIcon color={keywords.length ? '#6a6e73' : '#d2d2d2'} />{' '}
74
+ {keywords.length}
75
+ </Tooltip>
76
+ </>
77
+ );
78
+
79
+ export const ActionFormatter = ({ id, can_delete }, fetchReports) => {
80
+ const [isOpen, setOpen] = useState(false);
81
+ const dispatch = useDispatch();
82
+ const dispatchConfirm = () => {
83
+ dispatch(
84
+ openConfirmModal({
85
+ isWarning: true,
86
+ title: __('Delete report?'),
87
+ confirmButtonText: __('Delete report'),
88
+ onConfirm: () =>
89
+ dispatch(
90
+ APIActions.delete({
91
+ url: `/api/v2/host_reports/${id}`,
92
+ key: `report-${id}-DELETE`,
93
+ successToast: success => __('Report was successfully deleted'),
94
+ errorToast: error =>
95
+ __(`There was some issue deleting the report: ${error}`),
96
+ handleSuccess: fetchReports,
97
+ })
98
+ ),
99
+ message: __(
100
+ 'Are you sure you want to delete this report? This action is irreversible.'
101
+ ),
102
+ })
103
+ );
104
+ };
105
+ const dropdownItems = [
106
+ <DropdownItem
107
+ key="action"
108
+ component="button"
109
+ onClick={dispatchConfirm}
110
+ disabled={!can_delete}
111
+ >
112
+ {__('Delete')}
113
+ </DropdownItem>,
114
+ ];
115
+ return (
116
+ <Flex>
117
+ <FlexItem align={{ default: 'alignRight' }}>
118
+ <Dropdown
119
+ onSelect={v => setOpen(!v)}
120
+ toggle={<KebabToggle onToggle={setOpen} id="toggle-action" />}
121
+ isOpen={isOpen}
122
+ isPlain
123
+ dropdownItems={dropdownItems}
124
+ />
125
+ </FlexItem>
126
+ </Flex>
127
+ );
128
+ };
129
+
130
+ export const getColumns = fetchReports => [
131
+ {
132
+ title: __('Reported at'),
133
+ formatter: ({ reported_at, can_view, id }) =>
134
+ reportToShowFormatter()(reported_at, {
135
+ rowData: { canEdit: can_view, id },
136
+ }),
137
+ width: 25,
138
+ },
139
+ {
140
+ title: __('Status'),
141
+ formatter: globalStatusFormatter,
142
+ width: 25,
143
+ },
144
+ {
145
+ title: __('Summary'),
146
+ formatter: statusSummaryFormatter,
147
+ width: 25,
148
+ },
149
+ { title: __('Keywords'), formatter: keywordsFormatter, width: 15 },
150
+ {
151
+ title: null,
152
+ formatter: data => ActionFormatter(data, fetchReports),
153
+ width: 10,
154
+ },
155
+ ];
@@ -0,0 +1,132 @@
1
+ /* eslint-disable camelcase */
2
+ import React, { useEffect, useCallback } from 'react';
3
+ import { useDispatch, useSelector } from 'react-redux';
4
+ import { useHistory } from 'react-router-dom';
5
+ import PropTypes from 'prop-types';
6
+ import URI from 'urijs';
7
+ import SearchBar from 'foremanReact/components/SearchBar';
8
+ import Pagination from 'foremanReact/components/Pagination';
9
+ import { get } from 'foremanReact/redux/API';
10
+ import { Grid, GridItem } from '@patternfly/react-core';
11
+ import {
12
+ selectAPIStatus,
13
+ selectAPIResponse,
14
+ } from 'foremanReact/redux/API/APISelectors';
15
+ import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
16
+ import { HOST_REPORTS_SEARCH_PROPS } from '../../Router/HostReports/IndexPage/constants';
17
+ import ReportsTable from './ReportsTable';
18
+
19
+ const ReportsTab = ({ hostName }) => {
20
+ const dispatch = useDispatch();
21
+ const history = useHistory();
22
+ const API_KEY = `get-reports-${hostName}`;
23
+ const { reports, itemCount } = useSelector(state =>
24
+ selectAPIResponse(state, API_KEY)
25
+ );
26
+ const { perPage: settingsPerPage = 20 } = useForemanSettings() || {};
27
+ const status = useSelector(state => selectAPIStatus(state, API_KEY));
28
+ const fetchReports = useCallback(
29
+ ({ search: searchParam, per_page: perPageParam, page: pageParam } = {}) => {
30
+ const {
31
+ page: urlPage,
32
+ perPage: urlPerPage,
33
+ search: urlSearch,
34
+ } = getUrlParams();
35
+ const search = searchParam !== undefined ? searchParam : urlSearch;
36
+ const page = pageParam || urlPage;
37
+ const per_page = perPageParam || urlPerPage;
38
+ dispatch(
39
+ get({
40
+ key: API_KEY,
41
+ url: '/host_reports',
42
+ params: {
43
+ page,
44
+ per_page,
45
+ search: getServerQuery(search),
46
+ },
47
+ })
48
+ );
49
+ updateUrl({ page, per_page, search });
50
+ },
51
+ [API_KEY, dispatch, getServerQuery, getUrlParams, updateUrl]
52
+ );
53
+
54
+ useEffect(() => {
55
+ fetchReports();
56
+ }, [fetchReports, history.location]);
57
+
58
+ const onPaginationChange = ({ page, per_page }) => {
59
+ const { search } = getUrlParams();
60
+ updateUrl({ page, per_page, search });
61
+ };
62
+
63
+ const getServerQuery = useCallback(
64
+ search => {
65
+ const serverQuery = [`host = ${hostName}`];
66
+ if (search) {
67
+ serverQuery.push(`AND (${search})`);
68
+ }
69
+ return serverQuery.join(' ').trim();
70
+ },
71
+ [hostName]
72
+ );
73
+
74
+ const getUrlParams = useCallback(() => {
75
+ const params = { page: 1, perPage: settingsPerPage, search: '' };
76
+ const urlSearch = history.location?.search;
77
+ const urlParams = urlSearch && new URLSearchParams(urlSearch);
78
+ if (urlParams) {
79
+ params.search = urlParams.get('search') || params.search;
80
+ params.page = Number(urlParams.get('page')) || params.page;
81
+ params.perPage = Number(urlParams.get('per_page')) || params.perPage;
82
+ }
83
+ return params;
84
+ }, [history.location, settingsPerPage]);
85
+
86
+ const updateUrl = useCallback(
87
+ ({ page, per_page, search = '' }) => {
88
+ const uri = new URI();
89
+ uri.search({ page, per_page, search });
90
+ history.push({ search: uri.search() });
91
+ },
92
+ [history]
93
+ );
94
+
95
+ return (
96
+ <Grid id="new_host_details_insights_tab" hasGutter>
97
+ <GridItem span={6}>
98
+ <SearchBar
99
+ data={HOST_REPORTS_SEARCH_PROPS}
100
+ onSearch={search => fetchReports({ search, page: 1 })}
101
+ />
102
+ </GridItem>
103
+ <GridItem span={6}>
104
+ <Pagination
105
+ variant="top"
106
+ itemCount={itemCount}
107
+ onChange={onPaginationChange}
108
+ />
109
+ </GridItem>
110
+ <GridItem>
111
+ <ReportsTable
112
+ reports={reports}
113
+ status={status}
114
+ fetchReports={fetchReports}
115
+ />
116
+ </GridItem>
117
+ <GridItem>
118
+ <Pagination
119
+ variant="bottom"
120
+ itemCount={itemCount}
121
+ onChange={onPaginationChange}
122
+ />
123
+ </GridItem>
124
+ </Grid>
125
+ );
126
+ };
127
+
128
+ ReportsTab.propTypes = {
129
+ hostName: PropTypes.string.isRequired,
130
+ };
131
+
132
+ export default ReportsTab;
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_host_reports
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Zapletal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-22 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rdoc
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
11
+ date: 2022-02-21 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: Fast and efficient reporting capabilities
28
14
  email:
29
15
  - lukas-x@zapletalovi.com
@@ -34,11 +20,14 @@ files:
34
20
  - LICENSE
35
21
  - README.md
36
22
  - app/controllers/api/v2/host_reports_controller.rb
23
+ - app/controllers/concerns/foreman_host_reports/controller/hosts_controller_extensions.rb
37
24
  - app/controllers/concerns/foreman_host_reports/controller/parameters/host_report.rb
38
25
  - app/controllers/host_reports_controller.rb
26
+ - app/helpers/concerns/foreman_host_reports/hosts_helper_extensions.rb
39
27
  - app/models/concerns/foreman_host_reports/host_extensions.rb
40
28
  - app/models/concerns/foreman_host_reports/smart_proxy_extensions.rb
41
29
  - app/models/host_report.rb
30
+ - app/models/host_status/host_report_status.rb
42
31
  - app/models/report_keyword.rb
43
32
  - app/views/api/v2/host_reports/base.json.rabl
44
33
  - app/views/api/v2/host_reports/create.json.rabl
@@ -49,6 +38,7 @@ files:
49
38
  - db/migrate/20210112183526_add_host_reports.rb
50
39
  - db/migrate/20210616133601_create_report_keywords.rb
51
40
  - db/migrate/20211011141813_change_status_column.rb
41
+ - db/migrate/20220113064436_rename_status_summaries.rb
52
42
  - db/seeds.d/60-reports_feature.rb
53
43
  - lib/foreman_host_reports.rb
54
44
  - lib/foreman_host_reports/engine.rb
@@ -61,6 +51,7 @@ files:
61
51
  - package.json
62
52
  - test/controllers/api/v2/host_reports_controller_test.rb
63
53
  - test/factories/foreman_host_reports_factories.rb
54
+ - test/model/host_report_status_test.rb
64
55
  - test/snapshots/foreman-web.json
65
56
  - test/test_plugin_helper.rb
66
57
  - test/unit/foreman_host_reports_test.rb
@@ -71,7 +62,7 @@ files:
71
62
  - webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js
72
63
  - webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js
73
64
  - webpack/__mocks__/foremanReact/components/ForemanModal/index.js
74
- - webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js
65
+ - webpack/__mocks__/foremanReact/components/Pagination/index.js
75
66
  - webpack/__mocks__/foremanReact/components/common/EmptyState.js
76
67
  - webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js
77
68
  - webpack/__mocks__/foremanReact/components/common/forms/ForemanForm.js
@@ -84,6 +75,7 @@ files:
84
75
  - webpack/__mocks__/foremanReact/redux/actions/toasts.js
85
76
  - webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js
86
77
  - webpack/__mocks__/foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton.js
78
+ - webpack/fills.js
87
79
  - webpack/global_index.js
88
80
  - webpack/global_test_setup.js
89
81
  - webpack/index.js
@@ -116,6 +108,8 @@ files:
116
108
  - webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/HostReportMetrics.scss
117
109
  - webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/index.js
118
110
  - webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Ansible.js
111
+ - webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Components/EmptyLogsRow.js
112
+ - webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Components/RawMsgModal.js
119
113
  - webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Puppet.js
120
114
  - webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/helpers.js
121
115
  - webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/index.js
@@ -125,10 +119,14 @@ files:
125
119
  - webpack/src/Router/HostReports/ShowPage/index.js
126
120
  - webpack/src/Router/HostReports/constants.js
127
121
  - webpack/src/Router/routes.js
122
+ - webpack/src/components/ReportsTab/ReportsTable.js
123
+ - webpack/src/components/ReportsTab/helpers.js
124
+ - webpack/src/components/ReportsTab/index.js
128
125
  homepage: https://github.com/theforeman/foreman_host_reports
129
126
  licenses:
130
127
  - GPL-3.0
131
- metadata: {}
128
+ metadata:
129
+ is_foreman_plugin: 'true'
132
130
  post_install_message:
133
131
  rdoc_options: []
134
132
  require_paths:
@@ -153,5 +151,6 @@ test_files:
153
151
  - test/unit/foreman_host_reports_test.rb
154
152
  - test/controllers/api/v2/host_reports_controller_test.rb
155
153
  - test/snapshots/foreman-web.json
154
+ - test/model/host_report_status_test.rb
156
155
  - test/test_plugin_helper.rb
157
156
  - webpack/src/Router/HostReports/IndexPage/__tests__/HostReportsIndexPage.test.js
@@ -1,4 +0,0 @@
1
- import React from 'react';
2
-
3
- const PaginationWrapper = () => <></>;
4
- export default PaginationWrapper;