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.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +545 -0
- data/app/controllers/api/v2/host_reports_controller.rb +98 -0
- data/app/controllers/concerns/foreman_host_reports/controller/parameters/host_report.rb +25 -0
- data/app/controllers/host_reports_controller.rb +46 -0
- data/app/models/concerns/foreman_host_reports/host_extensions.rb +9 -0
- data/app/models/concerns/foreman_host_reports/smart_proxy_extensions.rb +9 -0
- data/app/models/host_report.rb +85 -0
- data/app/models/report_keyword.rb +11 -0
- data/app/views/api/v2/host_reports/base.json.rabl +5 -0
- data/app/views/api/v2/host_reports/create.json.rabl +5 -0
- data/app/views/api/v2/host_reports/index.json.rabl +5 -0
- data/app/views/api/v2/host_reports/main.json.rabl +15 -0
- data/app/views/api/v2/host_reports/show.json.rabl +11 -0
- data/config/routes.rb +33 -0
- data/db/migrate/20210112183526_add_host_reports.rb +36 -0
- data/db/migrate/20210616133601_create_report_keywords.rb +12 -0
- data/lib/foreman_host_reports/engine.rb +68 -0
- data/lib/foreman_host_reports/version.rb +3 -0
- data/lib/foreman_host_reports.rb +4 -0
- data/lib/tasks/foreman_host_reports_tasks.rake +50 -0
- data/locale/Makefile +60 -0
- data/locale/en/foreman_host_reports.po +19 -0
- data/locale/foreman_host_reports.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/package.json +45 -0
- data/test/controllers/api/v2/host_reports_controller_test.rb +278 -0
- data/test/factories/foreman_host_reports_factories.rb +21 -0
- data/test/snapshots/foreman-web.json +918 -0
- data/test/test_plugin_helper.rb +11 -0
- data/test/unit/foreman_host_reports_test.rb +9 -0
- data/webpack/global_index.js +4 -0
- data/webpack/global_test_setup.js +11 -0
- data/webpack/index.js +0 -0
- data/webpack/src/Router/HostReports/Components/HostReportDeleteModal.js +50 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.js +53 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.scss +4 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/formatCellFormatter.js +6 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/hostReportsToShowFormatter.js +13 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/index.js +4 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/reportToShowFormatter.js +13 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/statusFormatter.js +9 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/HostReportsToShowCell.js +32 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/ReportToShowCell.js +27 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.js +77 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.scss +9 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/formatImages.js +7 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/ansible.png +0 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/puppet.png +0 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTable.js +85 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTableSchema.js +65 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/index.js +28 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPage.js +88 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPageActions.js +55 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPageHelpers.js +50 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPageSelectors.js +86 -0
- data/webpack/src/Router/HostReports/IndexPage/constants.js +14 -0
- data/webpack/src/Router/HostReports/IndexPage/index.js +98 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/HostReportMetrics.scss +3 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/index.js +100 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Ansible.js +77 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Puppet.js +79 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/helpers.js +17 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/index.js +29 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogsFilter/index.js +109 -0
- data/webpack/src/Router/HostReports/ShowPage/ShowPage.js +160 -0
- data/webpack/src/Router/HostReports/ShowPage/ShowPageSelectors.js +51 -0
- data/webpack/src/Router/HostReports/ShowPage/index.js +75 -0
- data/webpack/src/Router/HostReports/constants.js +15 -0
- data/webpack/src/Router/routes.js +23 -0
- data/webpack/test_setup.js +17 -0
- 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,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;
|
data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.js
ADDED
|
@@ -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,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,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;
|
data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.js
ADDED
|
@@ -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;
|
|
Binary file
|
|
Binary file
|
|
@@ -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;
|
data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTableSchema.js
ADDED
|
@@ -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;
|