foreman_host_reports 0.0.3

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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +545 -0
  4. data/app/controllers/api/v2/host_reports_controller.rb +98 -0
  5. data/app/controllers/concerns/foreman_host_reports/controller/parameters/host_report.rb +25 -0
  6. data/app/controllers/host_reports_controller.rb +46 -0
  7. data/app/models/concerns/foreman_host_reports/host_extensions.rb +9 -0
  8. data/app/models/concerns/foreman_host_reports/smart_proxy_extensions.rb +9 -0
  9. data/app/models/host_report.rb +85 -0
  10. data/app/models/report_keyword.rb +11 -0
  11. data/app/views/api/v2/host_reports/base.json.rabl +5 -0
  12. data/app/views/api/v2/host_reports/create.json.rabl +5 -0
  13. data/app/views/api/v2/host_reports/index.json.rabl +5 -0
  14. data/app/views/api/v2/host_reports/main.json.rabl +15 -0
  15. data/app/views/api/v2/host_reports/show.json.rabl +11 -0
  16. data/config/routes.rb +33 -0
  17. data/db/migrate/20210112183526_add_host_reports.rb +36 -0
  18. data/db/migrate/20210616133601_create_report_keywords.rb +12 -0
  19. data/lib/foreman_host_reports/engine.rb +68 -0
  20. data/lib/foreman_host_reports/version.rb +3 -0
  21. data/lib/foreman_host_reports.rb +4 -0
  22. data/lib/tasks/foreman_host_reports_tasks.rake +50 -0
  23. data/locale/Makefile +60 -0
  24. data/locale/en/foreman_host_reports.po +19 -0
  25. data/locale/foreman_host_reports.pot +19 -0
  26. data/locale/gemspec.rb +2 -0
  27. data/package.json +45 -0
  28. data/test/controllers/api/v2/host_reports_controller_test.rb +278 -0
  29. data/test/factories/foreman_host_reports_factories.rb +21 -0
  30. data/test/snapshots/foreman-web.json +918 -0
  31. data/test/test_plugin_helper.rb +11 -0
  32. data/test/unit/foreman_host_reports_test.rb +9 -0
  33. data/webpack/global_index.js +4 -0
  34. data/webpack/global_test_setup.js +11 -0
  35. data/webpack/index.js +0 -0
  36. data/webpack/src/Router/HostReports/Components/HostReportDeleteModal.js +50 -0
  37. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.js +53 -0
  38. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.scss +4 -0
  39. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/formatCellFormatter.js +6 -0
  40. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/hostReportsToShowFormatter.js +13 -0
  41. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/index.js +4 -0
  42. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/reportToShowFormatter.js +13 -0
  43. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/statusFormatter.js +9 -0
  44. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/HostReportsToShowCell.js +32 -0
  45. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/ReportToShowCell.js +27 -0
  46. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.js +77 -0
  47. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.scss +9 -0
  48. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/formatImages.js +7 -0
  49. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/ansible.png +0 -0
  50. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/puppet.png +0 -0
  51. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTable.js +85 -0
  52. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTableSchema.js +65 -0
  53. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/index.js +28 -0
  54. data/webpack/src/Router/HostReports/IndexPage/IndexPage.js +88 -0
  55. data/webpack/src/Router/HostReports/IndexPage/IndexPageActions.js +55 -0
  56. data/webpack/src/Router/HostReports/IndexPage/IndexPageHelpers.js +50 -0
  57. data/webpack/src/Router/HostReports/IndexPage/IndexPageSelectors.js +86 -0
  58. data/webpack/src/Router/HostReports/IndexPage/constants.js +14 -0
  59. data/webpack/src/Router/HostReports/IndexPage/index.js +98 -0
  60. data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/HostReportMetrics.scss +3 -0
  61. data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/index.js +100 -0
  62. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Ansible.js +77 -0
  63. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Puppet.js +79 -0
  64. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/helpers.js +17 -0
  65. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/index.js +29 -0
  66. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogsFilter/index.js +109 -0
  67. data/webpack/src/Router/HostReports/ShowPage/ShowPage.js +160 -0
  68. data/webpack/src/Router/HostReports/ShowPage/ShowPageSelectors.js +51 -0
  69. data/webpack/src/Router/HostReports/ShowPage/index.js +75 -0
  70. data/webpack/src/Router/HostReports/constants.js +15 -0
  71. data/webpack/src/Router/routes.js +23 -0
  72. data/webpack/test_setup.js +17 -0
  73. metadata +133 -0
@@ -0,0 +1,11 @@
1
+ # This calls the main test_helper in Foreman-core
2
+ require 'test_helper'
3
+
4
+ # Add plugin to FactoryBot's paths
5
+ FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
6
+ FactoryBot.reload
7
+
8
+ def read_report(file)
9
+ json = File.expand_path(File.join('..', 'snapshots', file), __FILE__)
10
+ File.read(json)
11
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class ForemanHostReportsTest < ActiveSupport::TestCase
4
+ test 'should find host reports by keyword' do
5
+ report = FactoryBot.create(:host_report, :with_keyword)
6
+ result = HostReport.search_for("keyword= HasError").pluck(:id)
7
+ assert_include result, report.id
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ import { registerRoutes } from 'foremanReact/routes/RoutingService';
2
+ import ForemanHostReportsRoutes from './src/Router/routes';
3
+
4
+ registerRoutes('foreman_host_reports', ForemanHostReportsRoutes);
@@ -0,0 +1,11 @@
1
+ // runs before each test to make sure console.error output will
2
+ // fail a test (i.e. default PropType missing). Check the error
3
+ // output and traceback for actual error.
4
+ global.console.error = (error, stack) => {
5
+ /* eslint-disable-next-line no-console */
6
+ if (stack) console.log(stack); // Prints out original stack trace
7
+ throw new Error(error);
8
+ };
9
+
10
+ // Increase jest timeout as some tests using multiple http mocks can time out on CI systems.
11
+ jest.setTimeout(10000);
data/webpack/index.js ADDED
File without changes
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { sprintf, translate as __ } from 'foremanReact/common/I18n';
5
+ import ForemanModal from 'foremanReact/components/ForemanModal';
6
+ import { foremanUrl } from 'foremanReact/common/helpers';
7
+
8
+ import { HOST_REPORT_DELETE_MODAL_ID } from '../constants';
9
+
10
+ const HostReportDeleteModal = ({ toDelete, onSuccess }) => {
11
+ const { id, hostName } = toDelete;
12
+
13
+ return (
14
+ <ForemanModal
15
+ id={HOST_REPORT_DELETE_MODAL_ID}
16
+ title={__('Confirm report deletion')}
17
+ backdrop="static"
18
+ enforceFocus
19
+ submitProps={{
20
+ url: foremanUrl(`/api/v2/host_reports/${id}`),
21
+ message: sprintf(
22
+ __('Report for %s was successfully deleted'),
23
+ hostName
24
+ ),
25
+ onSuccess,
26
+ submitBtnProps: {
27
+ bsStyle: 'danger',
28
+ btnText: __('Delete'),
29
+ },
30
+ }}
31
+ >
32
+ {sprintf(
33
+ __('You are about to delete a report for %s. Are you sure?'),
34
+ hostName
35
+ )}
36
+ <ForemanModal.Footer />
37
+ </ForemanModal>
38
+ );
39
+ };
40
+
41
+ HostReportDeleteModal.propTypes = {
42
+ toDelete: PropTypes.object,
43
+ onSuccess: PropTypes.func.isRequired,
44
+ };
45
+
46
+ HostReportDeleteModal.defaultProps = {
47
+ toDelete: {},
48
+ };
49
+
50
+ export default HostReportDeleteModal;
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { UnknownIcon } from '@patternfly/react-icons';
4
+
5
+ import { sprintf, translate as __ } from 'foremanReact/common/I18n';
6
+
7
+ import formats from './formatImages';
8
+
9
+ import './FormatCell.scss';
10
+
11
+ const FormatCell = ({ format }) => {
12
+ switch (format) {
13
+ case 'plain':
14
+ return (
15
+ <UnknownIcon
16
+ size="md"
17
+ title={__('Obsolete or custom report formats')}
18
+ />
19
+ );
20
+ case 'puppet':
21
+ return (
22
+ <img
23
+ className="format-img"
24
+ src={formats.puppet}
25
+ alt="Puppet"
26
+ title={sprintf(__('Reported by %s'), 'Puppet')}
27
+ />
28
+ );
29
+ case 'ansible':
30
+ return (
31
+ <img
32
+ className="format-img"
33
+ src={formats.ansible}
34
+ alt="Ansible"
35
+ title={sprintf(__('Reported by %s'), 'Ansible')}
36
+ />
37
+ );
38
+ default:
39
+ return (
40
+ <UnknownIcon size="md" title={sprintf(__('Reported by %s'), format)} />
41
+ );
42
+ }
43
+ };
44
+
45
+ FormatCell.propTypes = {
46
+ format: PropTypes.string,
47
+ };
48
+
49
+ FormatCell.defaultProps = {
50
+ format: 'plain',
51
+ };
52
+
53
+ export default FormatCell;
@@ -0,0 +1,4 @@
1
+ .format-img {
2
+ max-width: 21px;
3
+ max-height: 21px;
4
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import FormatCell from '../FormatCell';
3
+
4
+ const formatCellFormatter = () => value => <FormatCell format={value} />;
5
+
6
+ export default formatCellFormatter;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import HostReportsToShowCell from '../HostReportsToShowCell';
3
+
4
+ const hostReportsToShowFormatter = () => (
5
+ value,
6
+ { rowData: { canEdit, hostId } }
7
+ ) => (
8
+ <HostReportsToShowCell active={canEdit} id={hostId}>
9
+ {value}
10
+ </HostReportsToShowCell>
11
+ );
12
+
13
+ export default hostReportsToShowFormatter;
@@ -0,0 +1,4 @@
1
+ export { default as formatCellFormatter } from './formatCellFormatter';
2
+ export { default as reportToShowFormatter } from './reportToShowFormatter';
3
+ export { default as hostReportsToShowFormatter } from './hostReportsToShowFormatter';
4
+ export { default as statusFormatter } from './statusFormatter';
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
4
+
5
+ import ReportToShowCell from '../ReportToShowCell';
6
+
7
+ const reportToShowFormatter = () => (value, { rowData: { canEdit, id } }) => (
8
+ <ReportToShowCell active={canEdit} id={id}>
9
+ <RelativeDateTime date={value} />
10
+ </ReportToShowCell>
11
+ );
12
+
13
+ export default reportToShowFormatter;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+
3
+ import StatusCell from '../StatusCell';
4
+
5
+ const statusFormatter = () => (value, { rowData: { format, status } }) => (
6
+ <StatusCell format={format} value={value} />
7
+ );
8
+
9
+ export default statusFormatter;
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Button } from '@patternfly/react-core';
4
+
5
+ const HostReportsToShowCell = ({ active, id, children }) =>
6
+ active ? (
7
+ <Button
8
+ variant="link"
9
+ isInline
10
+ component="a"
11
+ href={`/hosts/${id}/host_reports`}
12
+ >
13
+ {children}
14
+ </Button>
15
+ ) : (
16
+ <Button variant="link" isInline isDisabled component="a">
17
+ {children}
18
+ </Button>
19
+ );
20
+
21
+ HostReportsToShowCell.propTypes = {
22
+ active: PropTypes.bool,
23
+ id: PropTypes.number.isRequired,
24
+ children: PropTypes.node,
25
+ };
26
+
27
+ HostReportsToShowCell.defaultProps = {
28
+ active: false,
29
+ children: null,
30
+ };
31
+
32
+ export default HostReportsToShowCell;
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Button } from '@patternfly/react-core';
4
+
5
+ const ReportToShowCell = ({ active, id, children }) =>
6
+ active ? (
7
+ <Button variant="link" isInline component="a" href={`/host_reports/${id}`}>
8
+ {children}
9
+ </Button>
10
+ ) : (
11
+ <Button variant="link" isInline isDisabled component="a">
12
+ {children}
13
+ </Button>
14
+ );
15
+
16
+ ReportToShowCell.propTypes = {
17
+ active: PropTypes.bool,
18
+ id: PropTypes.number.isRequired,
19
+ children: PropTypes.node,
20
+ };
21
+
22
+ ReportToShowCell.defaultProps = {
23
+ active: false,
24
+ children: null,
25
+ };
26
+
27
+ export default ReportToShowCell;
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { capitalize } from 'lodash';
4
+
5
+ import './StatusCell.scss';
6
+
7
+ const StatusCell = ({ format, value }) => {
8
+ switch (format) {
9
+ case 'puppet':
10
+ return (
11
+ <td>
12
+ <ul className="status-list">
13
+ {value.map(status => {
14
+ let style = '';
15
+ switch (status[0]) {
16
+ case 'failed':
17
+ style = 'label-danger';
18
+ break;
19
+ case 'failed_to_restart':
20
+ style = 'label-warning';
21
+ break;
22
+ default:
23
+ style = 'label-info';
24
+ }
25
+ if (!status[2]) style = 'label-default';
26
+ return (
27
+ <li key={status[0]}>
28
+ {`${status[1]}: `}
29
+ <span className={`label ${style}`}>{status[2]}</span>
30
+ </li>
31
+ );
32
+ })}
33
+ </ul>
34
+ </td>
35
+ );
36
+ case 'ansible':
37
+ return (
38
+ <td>
39
+ <ul className="status-list">
40
+ {Object.keys(value).map(status => {
41
+ let style = '';
42
+ switch (status) {
43
+ case 'failed':
44
+ style = 'label-danger';
45
+ break;
46
+ case 'skipped':
47
+ style = 'label-warning';
48
+ break;
49
+ default:
50
+ style = 'label-info';
51
+ }
52
+ if (!value[status]) style = 'label-default';
53
+ return (
54
+ <li key={status}>
55
+ {`${capitalize(status)}: `}
56
+ <span className={`label ${style}`}>{value[status]}</span>
57
+ </li>
58
+ );
59
+ })}
60
+ </ul>
61
+ </td>
62
+ );
63
+ default:
64
+ return <td>N/A</td>;
65
+ }
66
+ };
67
+
68
+ StatusCell.propTypes = {
69
+ format: PropTypes.string,
70
+ value: PropTypes.any.isRequired,
71
+ };
72
+
73
+ StatusCell.defaultProps = {
74
+ format: 'plain',
75
+ };
76
+
77
+ export default StatusCell;
@@ -0,0 +1,9 @@
1
+ .status-list {
2
+ display: flex;
3
+ flex-wrap: wrap;
4
+ margin-bottom: 0px;
5
+
6
+ li {
7
+ margin-right: 0.5em;
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ import puppet from './images/puppet.png';
2
+ import ansible from './images/ansible.png';
3
+
4
+ export default {
5
+ puppet,
6
+ ansible,
7
+ };
@@ -0,0 +1,85 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { Table } from 'foremanReact/components/common/table';
5
+ import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
6
+ import DefaultEmptyState from 'foremanReact/components/common/EmptyState';
7
+ import { translate as __ } from 'foremanReact/common/I18n';
8
+
9
+ import HostReportDeleteModal from '../../../Components/HostReportDeleteModal';
10
+
11
+ import createHostReportsTableSchema from './HostReportsTableSchema';
12
+
13
+ const HostReportsTable = ({
14
+ fetchAndPush,
15
+ itemCount,
16
+ results,
17
+ sort,
18
+ pagination,
19
+ toDelete,
20
+ onDeleteClick,
21
+ reloadWithSearch,
22
+ hostId,
23
+ }) => {
24
+ const onDeleteSuccess = () => {
25
+ const currentPage = pagination.page;
26
+ const maxPage = Math.ceil((itemCount - 1) / pagination.perPage);
27
+ fetchAndPush({ page: maxPage < currentPage ? maxPage : currentPage });
28
+ };
29
+
30
+ const body =
31
+ itemCount > 0 ? (
32
+ <Table
33
+ key="host-reports-table"
34
+ columns={createHostReportsTableSchema(
35
+ fetchAndPush,
36
+ sort.by,
37
+ sort.order,
38
+ onDeleteClick,
39
+ hostId
40
+ )}
41
+ rows={results}
42
+ id="host-reports-table"
43
+ />
44
+ ) : (
45
+ <DefaultEmptyState
46
+ icon="add-circle-o"
47
+ header={__('No Results')}
48
+ description=""
49
+ documentation={null}
50
+ />
51
+ );
52
+
53
+ return (
54
+ <React.Fragment>
55
+ <HostReportDeleteModal toDelete={toDelete} onSuccess={onDeleteSuccess} />
56
+ {body}
57
+ <Pagination
58
+ viewType="list"
59
+ itemCount={itemCount}
60
+ pagination={pagination}
61
+ onChange={fetchAndPush}
62
+ dropdownButtonId="host-reports-page-pagination-dropdown"
63
+ />
64
+ </React.Fragment>
65
+ );
66
+ };
67
+
68
+ HostReportsTable.propTypes = {
69
+ results: PropTypes.array.isRequired,
70
+ fetchAndPush: PropTypes.func.isRequired,
71
+ onDeleteClick: PropTypes.func.isRequired,
72
+ itemCount: PropTypes.number.isRequired,
73
+ sort: PropTypes.object,
74
+ pagination: PropTypes.object.isRequired,
75
+ toDelete: PropTypes.object.isRequired,
76
+ reloadWithSearch: PropTypes.func.isRequired,
77
+ hostId: PropTypes.string,
78
+ };
79
+
80
+ HostReportsTable.defaultProps = {
81
+ sort: { by: '', order: '' },
82
+ hostId: null,
83
+ };
84
+
85
+ export default HostReportsTable;
@@ -0,0 +1,65 @@
1
+ import { translate as __ } from 'foremanReact/common/I18n';
2
+ import {
3
+ column,
4
+ sortableColumn,
5
+ headerFormatterWithProps,
6
+ deleteActionCellFormatter,
7
+ cellFormatter,
8
+ } from 'foremanReact/components/common/table';
9
+
10
+ import {
11
+ formatCellFormatter,
12
+ reportToShowFormatter,
13
+ hostReportsToShowFormatter,
14
+ statusFormatter,
15
+ } from './Components/Formatters';
16
+
17
+ const sortControllerFactory = (apiCall, sortBy, sortOrder) => ({
18
+ apply: (by, order) => {
19
+ apiCall({ sort: { by, order } });
20
+ },
21
+ property: sortBy,
22
+ order: sortOrder,
23
+ });
24
+
25
+ const createHostReportsTableSchema = (
26
+ apiCall,
27
+ by,
28
+ order,
29
+ onDeleteClick,
30
+ hostId
31
+ ) => {
32
+ const sortController = sortControllerFactory(apiCall, by, order);
33
+ const hostColumn = hostId
34
+ ? []
35
+ : [
36
+ sortableColumn('hostName', __('Host'), 3, sortController, [
37
+ hostReportsToShowFormatter(),
38
+ ]),
39
+ ];
40
+
41
+ return hostColumn.concat([
42
+ sortableColumn('reportedAt', __('Last report'), 1, sortController, [
43
+ reportToShowFormatter(),
44
+ ]),
45
+ sortableColumn('format', __('Format'), 1, sortController, [
46
+ formatCellFormatter(),
47
+ ]),
48
+ column(
49
+ 'status',
50
+ __('Overall status'),
51
+ [headerFormatterWithProps],
52
+ [statusFormatter()],
53
+ { className: `col-lg-auto` }
54
+ ),
55
+ column(
56
+ 'actions',
57
+ __('Actions'),
58
+ [headerFormatterWithProps],
59
+ [deleteActionCellFormatter(onDeleteClick), cellFormatter],
60
+ { className: `col-md-1` }
61
+ ),
62
+ ]);
63
+ };
64
+
65
+ export default createHostReportsTableSchema;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
5
+
6
+ import HostReportsTable from './HostReportsTable';
7
+ import { HOST_REPORT_DELETE_MODAL_ID } from '../../constants';
8
+
9
+ const WrappedHostReportsTable = props => {
10
+ const { setModalOpen: setDeleteModalOpen } = useForemanModal({
11
+ id: HOST_REPORT_DELETE_MODAL_ID,
12
+ });
13
+
14
+ const { setToDelete, ...rest } = props;
15
+
16
+ const onDeleteClick = rowData => {
17
+ setToDelete(rowData);
18
+ setDeleteModalOpen();
19
+ };
20
+
21
+ return <HostReportsTable onDeleteClick={onDeleteClick} {...rest} />;
22
+ };
23
+
24
+ WrappedHostReportsTable.propTypes = {
25
+ setToDelete: PropTypes.func.isRequired,
26
+ };
27
+
28
+ export default WrappedHostReportsTable;
@@ -0,0 +1,88 @@
1
+ import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
5
+ import ExportButton from 'foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton';
6
+ import { translate as __ } from 'foremanReact/common/I18n';
7
+ import { getURIQuery } from 'foremanReact/common/helpers';
8
+
9
+ import {
10
+ HOST_REPORTS_SEARCH_PROPS,
11
+ HOST_REPORTS_API_PLAIN_PATH,
12
+ } from './constants';
13
+
14
+ import HostReportsTable from './Components/HostReportsTable';
15
+
16
+ import { getExportUrl } from './IndexPageHelpers';
17
+
18
+ const HostReportsIndexPage = ({
19
+ fetchAndPush,
20
+ search,
21
+ isLoading,
22
+ hasData,
23
+ reports,
24
+ page,
25
+ perPage,
26
+ sort,
27
+ itemCount,
28
+ reloadWithSearch,
29
+ history,
30
+ hostId,
31
+ }) => {
32
+ const [toDelete, setToDelete] = useState({});
33
+
34
+ const url = HOST_REPORTS_API_PLAIN_PATH + history.location.search;
35
+ const uriQuery = getURIQuery(url);
36
+ const exportBtn = (
37
+ <ExportButton url={getExportUrl(url, uriQuery)} title={__('Export')} />
38
+ );
39
+
40
+ return (
41
+ <PageLayout
42
+ header={__('Host Reports')}
43
+ searchable={!isLoading}
44
+ searchProps={HOST_REPORTS_SEARCH_PROPS}
45
+ searchQuery={search}
46
+ isLoading={isLoading && hasData}
47
+ onSearch={reloadWithSearch}
48
+ onBookmarkClick={reloadWithSearch}
49
+ toolbarButtons={exportBtn}
50
+ >
51
+ <HostReportsTable
52
+ results={reports}
53
+ fetchAndPush={fetchAndPush}
54
+ pagination={{ page, perPage }}
55
+ itemCount={itemCount}
56
+ sort={sort}
57
+ toDelete={toDelete}
58
+ setToDelete={setToDelete}
59
+ reloadWithSearch={reloadWithSearch}
60
+ hostId={hostId}
61
+ />
62
+ </PageLayout>
63
+ );
64
+ };
65
+
66
+ HostReportsIndexPage.propTypes = {
67
+ fetchAndPush: PropTypes.func.isRequired,
68
+ search: PropTypes.string,
69
+ isLoading: PropTypes.bool.isRequired,
70
+ hasData: PropTypes.bool.isRequired,
71
+ reports: PropTypes.array.isRequired,
72
+ page: PropTypes.number,
73
+ perPage: PropTypes.number,
74
+ sort: PropTypes.object.isRequired,
75
+ itemCount: PropTypes.number.isRequired,
76
+ reloadWithSearch: PropTypes.func.isRequired,
77
+ history: PropTypes.object.isRequired,
78
+ hostId: PropTypes.string,
79
+ };
80
+
81
+ HostReportsIndexPage.defaultProps = {
82
+ page: null,
83
+ perPage: null,
84
+ search: '',
85
+ hostId: null,
86
+ };
87
+
88
+ export default HostReportsIndexPage;