foreman_webhooks 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +30 -0
- data/Rakefile +49 -0
- data/app/controllers/api/v2/webhook_templates_controller.rb +110 -0
- data/app/controllers/api/v2/webhooks_controller.rb +61 -0
- data/app/controllers/concerns/foreman_webhooks/controller/parameters/webhook.rb +34 -0
- data/app/controllers/concerns/foreman_webhooks/controller/parameters/webhook_template.rb +34 -0
- data/app/controllers/webhook_templates_controller.rb +5 -0
- data/app/controllers/webhooks_controller.rb +39 -0
- data/app/jobs/foreman_webhooks/deliver_webhook_job.rb +27 -0
- data/app/lib/foreman_webhooks/renderer/scope/webhook_template.rb +36 -0
- data/app/models/webhook.rb +141 -0
- data/app/models/webhook_template.rb +59 -0
- data/app/services/foreman_webhooks/webhook_service.rb +111 -0
- data/app/subscribers/foreman_webhooks/event_subscriber.rb +9 -0
- data/app/views/api/v2/webhook_templates/base.json.rabl +5 -0
- data/app/views/api/v2/webhook_templates/create.json.rabl +5 -0
- data/app/views/api/v2/webhook_templates/index.json.rabl +5 -0
- data/app/views/api/v2/webhook_templates/main.json.rabl +7 -0
- data/app/views/api/v2/webhook_templates/show.json.rabl +11 -0
- data/app/views/api/v2/webhook_templates/update.json.rabl +5 -0
- data/app/views/api/v2/webhooks/base.json.rabl +5 -0
- data/app/views/api/v2/webhooks/create.json.rabl +5 -0
- data/app/views/api/v2/webhooks/index.json.rabl +5 -0
- data/app/views/api/v2/webhooks/main.json.rabl +8 -0
- data/app/views/api/v2/webhooks/show.json.rabl +17 -0
- data/app/views/api/v2/webhooks/update.json.rabl +5 -0
- data/app/views/foreman_webhooks/webhook_templates/ansible_tower_-_host_in_inventory.erb +20 -0
- data/app/views/foreman_webhooks/webhook_templates/empty_payload.erb +6 -0
- data/app/views/foreman_webhooks/webhook_templates/webhook_template_-_payload_default.erb +11 -0
- data/app/views/webhook_templates/_alerts.html.erb +3 -0
- data/app/views/webhook_templates/_custom_tab_headers.html.erb +1 -0
- data/app/views/webhook_templates/_custom_tabs.html.erb +5 -0
- data/app/views/webhook_templates/edit.html.erb +3 -0
- data/app/views/webhook_templates/index.html.erb +29 -0
- data/app/views/webhook_templates/new.html.erb +3 -0
- data/app/views/webhooks/_form.html.erb +37 -0
- data/app/views/webhooks/_templates.html.erb +5 -0
- data/app/views/webhooks/edit.html.erb +3 -0
- data/app/views/webhooks/new.html.erb +3 -0
- data/config/routes.rb +45 -0
- data/db/migrate/20191016100128_create_webhook_targets.rb +13 -0
- data/db/migrate/20200831194208_rename_webhook_targets_to_webhooks.rb +7 -0
- data/db/migrate/20200831194514_add_template_to_webhooks.rb +7 -0
- data/db/migrate/20200907232758_rename_webhook_permissions.rb +22 -0
- data/db/migrate/20200908004234_add_columns_to_webhooks.rb +13 -0
- data/db/migrate/20201014115147_rename_ca_file_column.rb +7 -0
- data/db/migrate/20201109135301_add_http_headers.rb +8 -0
- data/db/seeds.d/95_webhook_templates.rb +7 -0
- data/lib/foreman_webhooks.rb +6 -0
- data/lib/foreman_webhooks/engine.rb +80 -0
- data/lib/foreman_webhooks/version.rb +5 -0
- data/lib/tasks/foreman_webhooks_tasks.rake +47 -0
- data/package.json +45 -0
- data/test/controllers/api/v2/webhook_templates_controller_test.rb +200 -0
- data/test/controllers/api/v2/webhooks_controller_test.rb +108 -0
- data/test/factories/webhook.rb +20 -0
- data/test/factories/webhook_target.rb +9 -0
- data/test/factories/webhook_template.rb +16 -0
- data/test/jobs/foreman_webhooks/deliver_webhook_job_test.rb +17 -0
- data/test/models/webhook_test.rb +38 -0
- data/test/test_plugin_helper.rb +8 -0
- data/test/unit/foreman_webhooks/webhook_service_test.rb +53 -0
- data/webpack/ForemanWebhooks/Routes/ForemanWebhooksRoutes.js +12 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/EmptyWebhooksTable/index.js +29 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookDeleteModal.js +43 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/EnabledCell.js +16 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/__tests__/__snapshots__/enabledCellFormatter.test.js.snap +7 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/__tests__/enabledCellFormatter.test.js +7 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/enabledCellFormatter.js +6 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/index.js +1 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/__tests__/EnabledCell.test.js +14 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/__tests__/__snapshots__/EnabledCell.test.js.snap +17 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTable.js +75 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTableSchema.js +41 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/WebhooksTable.test.js +57 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/__snapshots__/WebhooksTable.test.js.snap +115 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/index.js +25 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/WebhooksIndexPage.js +87 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/WebhooksIndexPage.fixtures.js +74 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/WebhooksIndexPage.test.js +21 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/__tests__/__snapshots__/WebhooksIndexPage.test.js.snap +68 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/index.js +51 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksPageActions.js +51 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksPageHelpers.js +29 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksPageSelectors.js +85 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/__tests__/WebhooksPageHelpers.test.js +20 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/__tests__/WebhooksPageSelectors.test.js +45 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/__tests__/__snapshots__/WebhooksPageSelectors.test.js.snap +50 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/constants.js +13 -0
- data/webpack/__mocks__/foremanReact/common/HOC.js +2 -0
- data/webpack/__mocks__/foremanReact/common/I18n.js +7 -0
- data/webpack/__mocks__/foremanReact/common/helpers.js +7 -0
- data/webpack/__mocks__/foremanReact/common/urlHelpers.js +1 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +2 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +10 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +18 -0
- data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +5 -0
- data/webpack/__mocks__/foremanReact/components/common/table.js +5 -0
- data/webpack/__mocks__/foremanReact/constants.js +24 -0
- data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +6 -0
- data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
- data/webpack/index.js +0 -0
- data/webpack/routes_index.js +4 -0
- metadata +195 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import { Table } from 'foremanReact/components/common/table';
|
6
|
+
import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
|
7
|
+
import { withRenderHandler } from 'foremanReact/common/HOC';
|
8
|
+
|
9
|
+
import WebhookDeleteModal from '../WebhookDeleteModal';
|
10
|
+
import EmptyWebhooksTable from '../EmptyWebhooksTable';
|
11
|
+
|
12
|
+
import createWebhooksTableSchema from './WebhooksTableSchema';
|
13
|
+
|
14
|
+
const WebhooksTable = ({
|
15
|
+
fetchAndPush,
|
16
|
+
itemCount,
|
17
|
+
results,
|
18
|
+
sort,
|
19
|
+
pagination,
|
20
|
+
toDelete,
|
21
|
+
onDeleteClick,
|
22
|
+
message,
|
23
|
+
}) => {
|
24
|
+
const onSuccess = () => {
|
25
|
+
const currentPage = pagination.page;
|
26
|
+
const maxPage = Math.ceil((itemCount - 1) / pagination.perPage);
|
27
|
+
fetchAndPush({ page: maxPage < currentPage ? maxPage : currentPage });
|
28
|
+
};
|
29
|
+
return (
|
30
|
+
<React.Fragment>
|
31
|
+
<WebhookDeleteModal toDelete={toDelete} onSuccess={onSuccess} />
|
32
|
+
<Table
|
33
|
+
key="webhooks-table"
|
34
|
+
columns={createWebhooksTableSchema(
|
35
|
+
fetchAndPush,
|
36
|
+
sort.by,
|
37
|
+
sort.order,
|
38
|
+
onDeleteClick
|
39
|
+
)}
|
40
|
+
rows={results}
|
41
|
+
id="webhooks-table"
|
42
|
+
style={{ marginBottom: -6 }}
|
43
|
+
/>
|
44
|
+
<Pagination
|
45
|
+
viewType="list"
|
46
|
+
itemCount={itemCount}
|
47
|
+
pagination={pagination}
|
48
|
+
onChange={fetchAndPush}
|
49
|
+
dropdownButtonId="webhooks-page-pagination-dropdown"
|
50
|
+
/>
|
51
|
+
</React.Fragment>
|
52
|
+
);
|
53
|
+
};
|
54
|
+
|
55
|
+
WebhooksTable.propTypes = {
|
56
|
+
results: PropTypes.array.isRequired,
|
57
|
+
fetchAndPush: PropTypes.func.isRequired,
|
58
|
+
onDeleteClick: PropTypes.func.isRequired,
|
59
|
+
itemCount: PropTypes.number.isRequired,
|
60
|
+
sort: PropTypes.object,
|
61
|
+
pagination: PropTypes.object.isRequired,
|
62
|
+
toDelete: PropTypes.object.isRequired,
|
63
|
+
message: PropTypes.object,
|
64
|
+
};
|
65
|
+
|
66
|
+
WebhooksTable.defaultProps = {
|
67
|
+
sort: { by: '', order: '' },
|
68
|
+
message: { type: 'empty', text: __('Try to create a new Webhook') },
|
69
|
+
};
|
70
|
+
|
71
|
+
export default withRenderHandler({
|
72
|
+
Component: WebhooksTable,
|
73
|
+
EmptyComponent: EmptyWebhooksTable,
|
74
|
+
ErrorComponent: EmptyWebhooksTable,
|
75
|
+
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
2
|
+
import {
|
3
|
+
column,
|
4
|
+
sortableColumn,
|
5
|
+
headerFormatterWithProps,
|
6
|
+
nameCellFormatter,
|
7
|
+
deleteActionCellFormatter,
|
8
|
+
cellFormatter,
|
9
|
+
} from 'foremanReact/components/common/table';
|
10
|
+
|
11
|
+
import { enabledCellFormatter } from './Components/Formatters';
|
12
|
+
|
13
|
+
const sortControllerFactory = (apiCall, sortBy, sortOrder) => ({
|
14
|
+
apply: (by, order) => {
|
15
|
+
apiCall({ sort: { by, order } });
|
16
|
+
},
|
17
|
+
property: sortBy,
|
18
|
+
order: sortOrder,
|
19
|
+
});
|
20
|
+
|
21
|
+
const createWebhooksTableSchema = (apiCall, by, order, onDeleteClick) => {
|
22
|
+
const sortController = sortControllerFactory(apiCall, by, order);
|
23
|
+
|
24
|
+
return [
|
25
|
+
sortableColumn('name', __('Name'), 4, sortController, [
|
26
|
+
nameCellFormatter('webhooks'),
|
27
|
+
]),
|
28
|
+
sortableColumn('targetUrl', __('Target URL'), 4, sortController),
|
29
|
+
sortableColumn('enabled', __('Enabled'), 2, sortController, [
|
30
|
+
enabledCellFormatter(),
|
31
|
+
]),
|
32
|
+
column(
|
33
|
+
'actions',
|
34
|
+
__('Actions'),
|
35
|
+
[headerFormatterWithProps],
|
36
|
+
[deleteActionCellFormatter(onDeleteClick), cellFormatter]
|
37
|
+
),
|
38
|
+
];
|
39
|
+
};
|
40
|
+
|
41
|
+
export default createWebhooksTableSchema;
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
|
2
|
+
|
3
|
+
import {
|
4
|
+
propsFactory,
|
5
|
+
webhooks,
|
6
|
+
} from '../../../__tests__/WebhooksIndexPage.fixtures';
|
7
|
+
import WrappedWebhooksTable from '../index';
|
8
|
+
|
9
|
+
const props = {
|
10
|
+
fetchAndPush: () => {},
|
11
|
+
onDeleteClick: () => {},
|
12
|
+
setToDelete: () => {},
|
13
|
+
itemCount: 0,
|
14
|
+
canCreate: true,
|
15
|
+
};
|
16
|
+
|
17
|
+
const fixtures = {
|
18
|
+
'should render when loading': propsFactory({
|
19
|
+
...props,
|
20
|
+
isLoading: true,
|
21
|
+
hasData: false,
|
22
|
+
hasError: false,
|
23
|
+
toasts: [],
|
24
|
+
}),
|
25
|
+
'should render with no data': propsFactory({
|
26
|
+
...props,
|
27
|
+
isLoading: false,
|
28
|
+
hasData: false,
|
29
|
+
hasError: false,
|
30
|
+
toasts: [],
|
31
|
+
}),
|
32
|
+
'should render with error': propsFactory({
|
33
|
+
isLoading: false,
|
34
|
+
hasData: false,
|
35
|
+
hasError: true,
|
36
|
+
message: {
|
37
|
+
type: 'error',
|
38
|
+
text: 'this is error',
|
39
|
+
},
|
40
|
+
...props,
|
41
|
+
toasts: [],
|
42
|
+
}),
|
43
|
+
'should render with webhooks': propsFactory({
|
44
|
+
...props,
|
45
|
+
isLoading: false,
|
46
|
+
hasError: false,
|
47
|
+
hasData: true,
|
48
|
+
toasts: [],
|
49
|
+
webhooks,
|
50
|
+
itemCount: webhooks.length,
|
51
|
+
}),
|
52
|
+
};
|
53
|
+
|
54
|
+
describe('WebhooksTable', () => {
|
55
|
+
describe('rendering', () =>
|
56
|
+
testComponentSnapshotsWithFixtures(WrappedWebhooksTable, fixtures));
|
57
|
+
});
|
@@ -0,0 +1,115 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`WebhooksTable rendering should render when loading 1`] = `
|
4
|
+
<Component
|
5
|
+
canCreate={true}
|
6
|
+
fetchAndPush={[Function]}
|
7
|
+
hasData={false}
|
8
|
+
hasError={false}
|
9
|
+
isLoading={true}
|
10
|
+
itemCount={0}
|
11
|
+
onDeleteClick={[Function]}
|
12
|
+
page={5}
|
13
|
+
perPage={42}
|
14
|
+
search="name=foo"
|
15
|
+
sort={
|
16
|
+
Object {
|
17
|
+
"by": "defaultName",
|
18
|
+
"order": "ASC",
|
19
|
+
}
|
20
|
+
}
|
21
|
+
toasts={Array []}
|
22
|
+
/>
|
23
|
+
`;
|
24
|
+
|
25
|
+
exports[`WebhooksTable rendering should render with error 1`] = `
|
26
|
+
<Component
|
27
|
+
canCreate={true}
|
28
|
+
fetchAndPush={[Function]}
|
29
|
+
hasData={false}
|
30
|
+
hasError={true}
|
31
|
+
isLoading={false}
|
32
|
+
itemCount={0}
|
33
|
+
message={
|
34
|
+
Object {
|
35
|
+
"text": "this is error",
|
36
|
+
"type": "error",
|
37
|
+
}
|
38
|
+
}
|
39
|
+
onDeleteClick={[Function]}
|
40
|
+
page={5}
|
41
|
+
perPage={42}
|
42
|
+
search="name=foo"
|
43
|
+
sort={
|
44
|
+
Object {
|
45
|
+
"by": "defaultName",
|
46
|
+
"order": "ASC",
|
47
|
+
}
|
48
|
+
}
|
49
|
+
toasts={Array []}
|
50
|
+
/>
|
51
|
+
`;
|
52
|
+
|
53
|
+
exports[`WebhooksTable rendering should render with no data 1`] = `
|
54
|
+
<Component
|
55
|
+
canCreate={true}
|
56
|
+
fetchAndPush={[Function]}
|
57
|
+
hasData={false}
|
58
|
+
hasError={false}
|
59
|
+
isLoading={false}
|
60
|
+
itemCount={0}
|
61
|
+
onDeleteClick={[Function]}
|
62
|
+
page={5}
|
63
|
+
perPage={42}
|
64
|
+
search="name=foo"
|
65
|
+
sort={
|
66
|
+
Object {
|
67
|
+
"by": "defaultName",
|
68
|
+
"order": "ASC",
|
69
|
+
}
|
70
|
+
}
|
71
|
+
toasts={Array []}
|
72
|
+
/>
|
73
|
+
`;
|
74
|
+
|
75
|
+
exports[`WebhooksTable rendering should render with webhooks 1`] = `
|
76
|
+
<Component
|
77
|
+
canCreate={true}
|
78
|
+
fetchAndPush={[Function]}
|
79
|
+
hasData={true}
|
80
|
+
hasError={false}
|
81
|
+
isLoading={false}
|
82
|
+
itemCount={2}
|
83
|
+
onDeleteClick={[Function]}
|
84
|
+
page={5}
|
85
|
+
perPage={42}
|
86
|
+
search="name=foo"
|
87
|
+
sort={
|
88
|
+
Object {
|
89
|
+
"by": "defaultName",
|
90
|
+
"order": "ASC",
|
91
|
+
}
|
92
|
+
}
|
93
|
+
toasts={Array []}
|
94
|
+
webhooks={
|
95
|
+
Array [
|
96
|
+
Object {
|
97
|
+
"canDelete": true,
|
98
|
+
"canEdit": true,
|
99
|
+
"enabled": true,
|
100
|
+
"id": 1,
|
101
|
+
"name": "my-webhook",
|
102
|
+
"targetUrl": "https://my-machine.example.com",
|
103
|
+
},
|
104
|
+
Object {
|
105
|
+
"canDelete": false,
|
106
|
+
"canEdit": false,
|
107
|
+
"enabled": false,
|
108
|
+
"id": 2,
|
109
|
+
"name": "your-webhook",
|
110
|
+
"targetUrl": "https://your-machine.example.com",
|
111
|
+
},
|
112
|
+
]
|
113
|
+
}
|
114
|
+
/>
|
115
|
+
`;
|
data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/index.js
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
|
5
|
+
|
6
|
+
import WebhooksTable from './WebhooksTable';
|
7
|
+
import { WEBHOOK_DELETE_MODAL_ID } from '../../../constants';
|
8
|
+
|
9
|
+
const WrappedWebhooksTable = props => {
|
10
|
+
const { setModalOpen } = useForemanModal({ id: WEBHOOK_DELETE_MODAL_ID });
|
11
|
+
const { setToDelete, ...rest } = props;
|
12
|
+
|
13
|
+
const onDeleteClick = rowData => {
|
14
|
+
setToDelete(rowData);
|
15
|
+
setModalOpen();
|
16
|
+
};
|
17
|
+
|
18
|
+
return <WebhooksTable {...rest} onDeleteClick={onDeleteClick} />;
|
19
|
+
};
|
20
|
+
|
21
|
+
WrappedWebhooksTable.propTypes = {
|
22
|
+
setToDelete: PropTypes.func.isRequired,
|
23
|
+
};
|
24
|
+
|
25
|
+
export default WrappedWebhooksTable;
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { Link } from 'react-router-dom';
|
4
|
+
import { Button } from 'patternfly-react';
|
5
|
+
|
6
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
7
|
+
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
8
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
9
|
+
|
10
|
+
import { WEBHOOKS_SEARCH_PROPS, WEBHOOKS_PATH } from '../constants';
|
11
|
+
import WebhooksTable from './Components/WebhooksTable';
|
12
|
+
|
13
|
+
const WebhooksIndexPage = ({
|
14
|
+
fetchAndPush,
|
15
|
+
search,
|
16
|
+
isLoading,
|
17
|
+
hasData,
|
18
|
+
webhooks,
|
19
|
+
page,
|
20
|
+
perPage,
|
21
|
+
sort,
|
22
|
+
hasError,
|
23
|
+
itemCount,
|
24
|
+
message,
|
25
|
+
canCreate,
|
26
|
+
toasts,
|
27
|
+
}) => {
|
28
|
+
const handleSearch = query => fetchAndPush({ searchQuery: query, page: 1 });
|
29
|
+
const [toDelete, setToDelete] = useState({});
|
30
|
+
const createBtn = (
|
31
|
+
<Link to={foremanUrl(`${WEBHOOKS_PATH}/new`)}>
|
32
|
+
<Button bsStyle="primary">{__('Create Webhook')}</Button>
|
33
|
+
</Link>
|
34
|
+
);
|
35
|
+
return (
|
36
|
+
<PageLayout
|
37
|
+
header={__('Webhooks')}
|
38
|
+
searchable={!isLoading}
|
39
|
+
searchProps={WEBHOOKS_SEARCH_PROPS}
|
40
|
+
searchQuery={search}
|
41
|
+
isLoading={isLoading && hasData}
|
42
|
+
onSearch={handleSearch}
|
43
|
+
onBookmarkClick={handleSearch}
|
44
|
+
toastNotifications={toasts}
|
45
|
+
toolbarButtons={canCreate && createBtn}
|
46
|
+
>
|
47
|
+
<WebhooksTable
|
48
|
+
results={webhooks}
|
49
|
+
fetchAndPush={fetchAndPush}
|
50
|
+
pagination={{ page, perPage }}
|
51
|
+
itemCount={itemCount}
|
52
|
+
sort={sort}
|
53
|
+
toDelete={toDelete}
|
54
|
+
setToDelete={setToDelete}
|
55
|
+
message={message}
|
56
|
+
hasData={hasData}
|
57
|
+
hasError={hasError}
|
58
|
+
isLoading={isLoading}
|
59
|
+
/>
|
60
|
+
</PageLayout>
|
61
|
+
);
|
62
|
+
};
|
63
|
+
|
64
|
+
WebhooksIndexPage.propTypes = {
|
65
|
+
fetchAndPush: PropTypes.func.isRequired,
|
66
|
+
search: PropTypes.string,
|
67
|
+
isLoading: PropTypes.bool.isRequired,
|
68
|
+
hasData: PropTypes.bool.isRequired,
|
69
|
+
webhooks: PropTypes.array.isRequired,
|
70
|
+
page: PropTypes.number,
|
71
|
+
perPage: PropTypes.number,
|
72
|
+
sort: PropTypes.object.isRequired,
|
73
|
+
hasError: PropTypes.bool.isRequired,
|
74
|
+
itemCount: PropTypes.number.isRequired,
|
75
|
+
message: PropTypes.object,
|
76
|
+
canCreate: PropTypes.bool.isRequired,
|
77
|
+
toasts: PropTypes.array.isRequired,
|
78
|
+
};
|
79
|
+
|
80
|
+
WebhooksIndexPage.defaultProps = {
|
81
|
+
page: null,
|
82
|
+
perPage: null,
|
83
|
+
search: '',
|
84
|
+
message: { type: 'empty', text: __('Try to create a new Webhook') },
|
85
|
+
};
|
86
|
+
|
87
|
+
export default WebhooksIndexPage;
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { WEBHOOKS_API_REQUEST_KEY } from '../../constants';
|
2
|
+
|
3
|
+
export const pickedQuery = { by: 'default_name', order: 'ASC' };
|
4
|
+
|
5
|
+
const searchString = 'name=foo';
|
6
|
+
|
7
|
+
const stateSearch = { search: searchString };
|
8
|
+
|
9
|
+
const querySearch = { searchQuery: searchString };
|
10
|
+
|
11
|
+
export const querySort = {
|
12
|
+
sort: {
|
13
|
+
by: 'defaultName',
|
14
|
+
order: 'ASC',
|
15
|
+
},
|
16
|
+
};
|
17
|
+
|
18
|
+
const pageParams = {
|
19
|
+
page: 5,
|
20
|
+
perPage: 42,
|
21
|
+
};
|
22
|
+
|
23
|
+
const stateParams = {
|
24
|
+
...pageParams,
|
25
|
+
...stateSearch,
|
26
|
+
...querySort,
|
27
|
+
};
|
28
|
+
|
29
|
+
export const resultParams = {
|
30
|
+
...pageParams,
|
31
|
+
...querySearch,
|
32
|
+
sort: pickedQuery,
|
33
|
+
};
|
34
|
+
|
35
|
+
export const queryParams = {
|
36
|
+
...pageParams,
|
37
|
+
...querySearch,
|
38
|
+
...querySort,
|
39
|
+
};
|
40
|
+
|
41
|
+
export const stateFactory = state => ({
|
42
|
+
API: {
|
43
|
+
[WEBHOOKS_API_REQUEST_KEY]: {
|
44
|
+
response: {
|
45
|
+
...stateParams,
|
46
|
+
...state,
|
47
|
+
},
|
48
|
+
},
|
49
|
+
},
|
50
|
+
});
|
51
|
+
|
52
|
+
export const propsFactory = (state = {}) => ({
|
53
|
+
...stateParams,
|
54
|
+
...state,
|
55
|
+
});
|
56
|
+
|
57
|
+
export const webhooks = [
|
58
|
+
{
|
59
|
+
id: 1,
|
60
|
+
name: 'my-webhook',
|
61
|
+
targetUrl: 'https://my-machine.example.com',
|
62
|
+
canEdit: true,
|
63
|
+
canDelete: true,
|
64
|
+
enabled: true,
|
65
|
+
},
|
66
|
+
{
|
67
|
+
id: 2,
|
68
|
+
name: 'your-webhook',
|
69
|
+
targetUrl: 'https://your-machine.example.com',
|
70
|
+
canEdit: false,
|
71
|
+
canDelete: false,
|
72
|
+
enabled: false,
|
73
|
+
},
|
74
|
+
];
|