foreman_ansible 2.3.2 → 2.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/foreman_ansible/foreman-ansible.css +4 -0
  3. data/app/controllers/ansible_variables_controller.rb +28 -6
  4. data/app/controllers/api/v2/ansible_variables_controller.rb +9 -1
  5. data/app/controllers/concerns/foreman/controller/parameters/ansible_variable.rb +2 -1
  6. data/app/controllers/ui_ansible_roles_controller.rb +14 -0
  7. data/app/helpers/foreman_ansible/ansible_roles_helper.rb +19 -1
  8. data/app/models/ansible_role.rb +1 -0
  9. data/app/models/ansible_variable.rb +8 -3
  10. data/app/services/foreman_ansible/variables_importer.rb +61 -30
  11. data/app/views/ansible_roles/welcome.html.erb +1 -1
  12. data/app/views/ansible_variables/_fields.erb +12 -5
  13. data/app/views/ansible_variables/import.html.erb +4 -1
  14. data/app/views/ansible_variables/index.html.erb +8 -3
  15. data/app/views/ansible_variables/new.html.erb +17 -0
  16. data/app/views/api/v2/ansible_variables/create.json.rabl +3 -0
  17. data/app/views/api/v2/ansible_variables/show.json.rabl +1 -1
  18. data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +13 -13
  19. data/app/views/ui_ansible_roles/index.json.rabl +3 -0
  20. data/app/views/ui_ansible_roles/main.json.rabl +3 -0
  21. data/app/views/ui_ansible_roles/show.json.rabl +3 -0
  22. data/config/routes.rb +4 -2
  23. data/db/migrate/20190318094437_add_imported_attr_to_ansible_variables.rb +15 -0
  24. data/lib/foreman_ansible/register.rb +13 -2
  25. data/lib/foreman_ansible/version.rb +1 -1
  26. data/package.json +50 -9
  27. data/test/factories/ansible_variables.rb +1 -0
  28. data/test/functional/ansible_variables_controller_test.rb +10 -0
  29. data/test/functional/api/v2/ansible_variables_controller_test.rb +10 -0
  30. data/test/functional/ui_ansible_roles_controller_test.rb +14 -0
  31. data/test/unit/services/ansible_variables_importer_test.rb +20 -3
  32. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
  33. data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +5 -0
  34. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +140 -0
  35. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +45 -0
  36. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +69 -0
  37. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +7 -0
  38. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherHelpers.js +7 -0
  39. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +69 -0
  40. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +68 -0
  41. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesData.fixtures.js +20 -0
  42. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +36 -0
  43. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +30 -0
  44. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +73 -0
  45. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +43 -0
  46. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +79 -0
  47. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +399 -0
  48. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +60 -0
  49. data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.js +33 -0
  50. data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.test.js +9 -0
  51. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +56 -0
  52. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +26 -0
  53. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleActionButton.js +16 -0
  54. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRolesSwitcherError.js +32 -0
  55. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +67 -0
  56. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +19 -0
  57. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.js +52 -0
  58. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.test.js +22 -0
  59. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsiblePermissionDenied.test.js.snap +26 -0
  60. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRole.test.js.snap +108 -0
  61. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +64 -0
  62. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +54 -0
  63. data/webpack/components/AnsibleRolesSwitcher/components/withProtectedView.js +14 -0
  64. data/webpack/components/AnsibleRolesSwitcher/index.js +44 -0
  65. data/webpack/components/ReportJsonViewer.js +11 -7
  66. data/webpack/index.js +14 -1
  67. data/webpack/reducer.js +7 -0
  68. data/webpack/test_setup.js +11 -0
  69. metadata +46 -2
@@ -0,0 +1,9 @@
1
+ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
2
+ import AnsiblePermissionDenied from './AnsiblePermissionDenied';
3
+
4
+ jest.mock('foremanReact/components/common/EmptyState');
5
+
6
+ describe('AnsiblePermissionDenied', () =>
7
+ testComponentSnapshotsWithFixtures(AnsiblePermissionDenied, {
8
+ 'should render': {},
9
+ }));
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { ListView, Tooltip, OverlayTrigger } from 'patternfly-react';
3
+ import classNames from 'classnames';
4
+
5
+ import AnsibleRoleActionButton from './AnsibleRoleActionButton';
6
+ import '../AnsibleRolesSwitcher.scss';
7
+
8
+ const AnsibleRole = ({ role, icon, onClick, resourceName }) => {
9
+ const text =
10
+ resourceName === 'hostgroup'
11
+ ? __('This Ansible role is inherited from parent host group')
12
+ : __('This Ansible role is inherited from host group');
13
+
14
+ const tooltip = (
15
+ <Tooltip id={role.id}>
16
+ <span>{text}</span>
17
+ </Tooltip>
18
+ );
19
+
20
+ const clickHandler = (onClickFn, ansibleRole) => event => {
21
+ event.preventDefault();
22
+ onClickFn(ansibleRole);
23
+ };
24
+
25
+ const listItem = (click = undefined) => (
26
+ <ListView.Item
27
+ id={role.id}
28
+ className={classNames('listViewItem--listItemVariants', {
29
+ 'ansible-role-disabled': role.inherited,
30
+ 'ansible-role-movable': !role.inherited,
31
+ })}
32
+ heading={role.name}
33
+ actions={
34
+ role.inherited ? (
35
+ ''
36
+ ) : (
37
+ <AnsibleRoleActionButton icon={icon} role={role} />
38
+ )
39
+ }
40
+ stacked
41
+ onClick={typeof click === 'function' ? click(onClick, role) : click}
42
+ />
43
+ );
44
+
45
+ if (role.inherited) {
46
+ return (
47
+ <OverlayTrigger overlay={tooltip} placement="top">
48
+ {listItem()}
49
+ </OverlayTrigger>
50
+ );
51
+ }
52
+
53
+ return listItem(clickHandler);
54
+ };
55
+
56
+ export default AnsibleRole;
@@ -0,0 +1,26 @@
1
+ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
2
+
3
+ import AnsibleRole from './AnsibleRole';
4
+
5
+ const noop = () => {};
6
+
7
+ const fixtures = {
8
+ 'should render a role to add': {
9
+ role: { name: 'test.role', id: 5 },
10
+ icon: 'fa fa-plus-circle',
11
+ onClick: noop,
12
+ },
13
+ 'should render a role to remove': {
14
+ role: { name: 'test.role', id: 5 },
15
+ icon: 'fa fa-minus-circle',
16
+ onClick: noop,
17
+ },
18
+ 'should render inherited role to remove': {
19
+ role: { name: 'test.role', id: 5, inherited: true },
20
+ icon: 'fa fa-minus-circle',
21
+ onClick: noop,
22
+ },
23
+ };
24
+
25
+ describe('AnsibleRole', () =>
26
+ testComponentSnapshotsWithFixtures(AnsibleRole, fixtures));
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { Icon } from 'patternfly-react';
5
+
6
+ const AnsibleRoleActionButton = ({ icon }) => (
7
+ <button href="#" className="role-add-remove-btn">
8
+ <Icon className="fa-2x" type="fa" name={icon} />
9
+ </button>
10
+ );
11
+
12
+ AnsibleRoleActionButton.propTypes = {
13
+ icon: PropTypes.string.isRequired,
14
+ };
15
+
16
+ export default AnsibleRoleActionButton;
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { Col, Alert } from 'patternfly-react';
3
+ import PropTypes from 'prop-types';
4
+
5
+ const ErrorMsg = ({ error }) => {
6
+ const status = error.statusText ? `${error.statusText}: ` : '';
7
+ return `${status}${error.errorMsg}`;
8
+ };
9
+
10
+ const AnsibleRolesSwitcherError = ({ error }) =>
11
+ error && error.errorMsg ? (
12
+ <Col sm={12}>
13
+ <Alert type="error">
14
+ <ErrorMsg error={error} />
15
+ </Alert>
16
+ </Col>
17
+ ) : (
18
+ ''
19
+ );
20
+
21
+ AnsibleRolesSwitcherError.propTypes = {
22
+ error: PropTypes.shape({
23
+ errorMsg: PropTypes.string,
24
+ statusText: PropTypes.string,
25
+ }),
26
+ };
27
+
28
+ AnsibleRolesSwitcherError.defaultProps = {
29
+ error: {},
30
+ };
31
+
32
+ export default AnsibleRolesSwitcherError;
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import { ListView } from 'patternfly-react';
3
+ import PaginationWrapper from 'foremanReact/components/Pagination/PaginationWrapper';
4
+ import { reject } from 'lodash';
5
+ import PropTypes from 'prop-types';
6
+
7
+ import AnsibleRole from './AnsibleRole';
8
+
9
+ const AssignedRolesList = ({
10
+ assignedRoles,
11
+ pagination,
12
+ itemCount,
13
+ onPaginationChange,
14
+ onRemoveRole,
15
+ resourceName,
16
+ }) => {
17
+ const directlyAssignedRoles = reject(assignedRoles, role => role.inherited);
18
+
19
+ return (
20
+ <div>
21
+ <ListView>
22
+ <div className="sticky-pagination sticky-pagination-grey">
23
+ <PaginationWrapper
24
+ viewType="list"
25
+ itemCount={itemCount}
26
+ pagination={pagination}
27
+ onChange={onPaginationChange}
28
+ dropdownButtonId="assigned-ansible-roles-pagination-row-dropdown"
29
+ />
30
+ </div>
31
+ {assignedRoles.map(role => (
32
+ <AnsibleRole
33
+ key={role.id}
34
+ role={role}
35
+ icon="fa fa-minus-circle"
36
+ onClick={onRemoveRole}
37
+ resourceName={resourceName}
38
+ />
39
+ ))}
40
+ </ListView>
41
+ <div>
42
+ {directlyAssignedRoles.map(role => (
43
+ <input
44
+ key={role.id}
45
+ type="hidden"
46
+ name={`${resourceName}[ansible_role_ids][]`}
47
+ value={role.id}
48
+ />
49
+ ))}
50
+ </div>
51
+ </div>
52
+ );
53
+ };
54
+
55
+ AssignedRolesList.propTypes = {
56
+ assignedRoles: PropTypes.arrayOf(PropTypes.object).isRequired,
57
+ pagination: PropTypes.shape({
58
+ page: PropTypes.number,
59
+ perPage: PropTypes.number,
60
+ }).isRequired,
61
+ itemCount: PropTypes.number.isRequired,
62
+ onPaginationChange: PropTypes.func.isRequired,
63
+ onRemoveRole: PropTypes.func.isRequired,
64
+ resourceName: PropTypes.string.isRequired,
65
+ };
66
+
67
+ export default AssignedRolesList;
@@ -0,0 +1,19 @@
1
+ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
2
+
3
+ import AssignedRolesList from './AssignedRolesList';
4
+
5
+ const noop = () => {};
6
+
7
+ const fixtures = {
8
+ 'should render': {
9
+ assignedRoles: [{ id: 1, name: 'fake.role' }, { id: 2, name: 'test.role' }],
10
+ pagination: { page: 1, perPage: 25 },
11
+ itemCount: 2,
12
+ onPaginationChange: noop,
13
+ onRemoveRole: noop,
14
+ resourceName: 'host',
15
+ },
16
+ };
17
+
18
+ describe('AssignedRolesList', () =>
19
+ testComponentSnapshotsWithFixtures(AssignedRolesList, fixtures));
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { ListView, LoadingState } from 'patternfly-react';
5
+ import PaginationWrapper from 'foremanReact/components/Pagination/PaginationWrapper';
6
+
7
+ import AnsibleRole from './AnsibleRole';
8
+
9
+ const AvailableRolesList = ({
10
+ unassignedRoles,
11
+ pagination,
12
+ itemCount,
13
+ onListingChange,
14
+ onAddRole,
15
+ loading,
16
+ }) => (
17
+ <ListView>
18
+ <div className="sticky-pagination">
19
+ <PaginationWrapper
20
+ viewType="list"
21
+ itemCount={itemCount}
22
+ pagination={pagination}
23
+ onChange={onListingChange}
24
+ dropdownButtonId="available-ansible-roles-pagination-row-dropdown"
25
+ />
26
+ </div>
27
+ <LoadingState loading={loading}>
28
+ {unassignedRoles.map(role => (
29
+ <AnsibleRole
30
+ key={role.id}
31
+ role={role}
32
+ icon="fa fa-plus-circle"
33
+ onClick={onAddRole}
34
+ />
35
+ ))}
36
+ </LoadingState>
37
+ </ListView>
38
+ );
39
+
40
+ AvailableRolesList.propTypes = {
41
+ unassignedRoles: PropTypes.arrayOf(PropTypes.object).isRequired,
42
+ pagination: PropTypes.shape({
43
+ page: PropTypes.number,
44
+ perPage: PropTypes.number,
45
+ }).isRequired,
46
+ itemCount: PropTypes.number.isRequired,
47
+ onListingChange: PropTypes.func.isRequired,
48
+ onAddRole: PropTypes.func.isRequired,
49
+ loading: PropTypes.bool.isRequired,
50
+ };
51
+
52
+ export default AvailableRolesList;
@@ -0,0 +1,22 @@
1
+ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
2
+
3
+ import AvailableRolesList from './AvailableRolesList';
4
+
5
+ const noop = () => {};
6
+
7
+ const fixtures = {
8
+ 'should render': {
9
+ unassignedRoles: [
10
+ { id: 1, name: 'fake.role' },
11
+ { id: 2, name: 'test.role' },
12
+ ],
13
+ pagination: { page: 1, perPage: 25 },
14
+ itemCount: 2,
15
+ onListingChange: noop,
16
+ onAddRole: noop,
17
+ loading: false,
18
+ },
19
+ };
20
+
21
+ describe('AvailableRolesList', () =>
22
+ testComponentSnapshotsWithFixtures(AvailableRolesList, fixtures));
@@ -0,0 +1,26 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AnsiblePermissionDenied should render 1`] = `
4
+ <EmptyStatePattern
5
+ description={
6
+ <span>
7
+ You are not authorized to perform this action.
8
+ <br />
9
+ Please request one of the required permissions listed below from a Foreman administrator:
10
+ <br />
11
+ </span>
12
+ }
13
+ documentation={
14
+ <ul
15
+ className="list-unstyled"
16
+ >
17
+ <li>
18
+ view_ansible_roles
19
+ </li>
20
+ </ul>
21
+ }
22
+ header="Permission Denied"
23
+ icon="lock"
24
+ iconType="fa"
25
+ />
26
+ `;
@@ -0,0 +1,108 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AnsibleRole should render a role to add 1`] = `
4
+ <ListViewItem
5
+ actions={
6
+ <AnsibleRoleActionButton
7
+ icon="fa fa-plus-circle"
8
+ role={
9
+ Object {
10
+ "id": 5,
11
+ "name": "test.role",
12
+ }
13
+ }
14
+ />
15
+ }
16
+ additionalInfo={null}
17
+ checkboxInput={null}
18
+ className="listViewItem--listItemVariants ansible-role-movable"
19
+ compoundExpand={false}
20
+ compoundExpanded={false}
21
+ description={null}
22
+ heading="test.role"
23
+ hideCloseIcon={false}
24
+ id={5}
25
+ initExpanded={false}
26
+ leftContent={null}
27
+ onClick={[Function]}
28
+ onCloseCompoundExpand={[Function]}
29
+ onExpand={[Function]}
30
+ onExpandClose={[Function]}
31
+ stacked={true}
32
+ />
33
+ `;
34
+
35
+ exports[`AnsibleRole should render a role to remove 1`] = `
36
+ <ListViewItem
37
+ actions={
38
+ <AnsibleRoleActionButton
39
+ icon="fa fa-minus-circle"
40
+ role={
41
+ Object {
42
+ "id": 5,
43
+ "name": "test.role",
44
+ }
45
+ }
46
+ />
47
+ }
48
+ additionalInfo={null}
49
+ checkboxInput={null}
50
+ className="listViewItem--listItemVariants ansible-role-movable"
51
+ compoundExpand={false}
52
+ compoundExpanded={false}
53
+ description={null}
54
+ heading="test.role"
55
+ hideCloseIcon={false}
56
+ id={5}
57
+ initExpanded={false}
58
+ leftContent={null}
59
+ onClick={[Function]}
60
+ onCloseCompoundExpand={[Function]}
61
+ onExpand={[Function]}
62
+ onExpandClose={[Function]}
63
+ stacked={true}
64
+ />
65
+ `;
66
+
67
+ exports[`AnsibleRole should render inherited role to remove 1`] = `
68
+ <OverlayTrigger
69
+ defaultOverlayShown={false}
70
+ overlay={
71
+ <Tooltip
72
+ bsClass="tooltip"
73
+ id={5}
74
+ placement="right"
75
+ >
76
+ <span>
77
+ This Ansible role is inherited from host group
78
+ </span>
79
+ </Tooltip>
80
+ }
81
+ placement="top"
82
+ trigger={
83
+ Array [
84
+ "hover",
85
+ "focus",
86
+ ]
87
+ }
88
+ >
89
+ <ListViewItem
90
+ actions=""
91
+ additionalInfo={null}
92
+ checkboxInput={null}
93
+ className="listViewItem--listItemVariants ansible-role-disabled"
94
+ compoundExpand={false}
95
+ compoundExpanded={false}
96
+ description={null}
97
+ heading="test.role"
98
+ hideCloseIcon={false}
99
+ id={5}
100
+ initExpanded={false}
101
+ leftContent={null}
102
+ onCloseCompoundExpand={[Function]}
103
+ onExpand={[Function]}
104
+ onExpandClose={[Function]}
105
+ stacked={true}
106
+ />
107
+ </OverlayTrigger>
108
+ `;
@@ -0,0 +1,64 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AssignedRolesList should render 1`] = `
4
+ <div>
5
+ <ListView
6
+ className=""
7
+ >
8
+ <div
9
+ className="sticky-pagination sticky-pagination-grey"
10
+ >
11
+ <PaginationWrapper
12
+ dropdownButtonId="assigned-ansible-roles-pagination-row-dropdown"
13
+ itemCount={2}
14
+ onChange={[Function]}
15
+ pagination={
16
+ Object {
17
+ "page": 1,
18
+ "perPage": 25,
19
+ }
20
+ }
21
+ viewType="list"
22
+ />
23
+ </div>
24
+ <AnsibleRole
25
+ icon="fa fa-minus-circle"
26
+ key="1"
27
+ onClick={[Function]}
28
+ resourceName="host"
29
+ role={
30
+ Object {
31
+ "id": 1,
32
+ "name": "fake.role",
33
+ }
34
+ }
35
+ />
36
+ <AnsibleRole
37
+ icon="fa fa-minus-circle"
38
+ key="2"
39
+ onClick={[Function]}
40
+ resourceName="host"
41
+ role={
42
+ Object {
43
+ "id": 2,
44
+ "name": "test.role",
45
+ }
46
+ }
47
+ />
48
+ </ListView>
49
+ <div>
50
+ <input
51
+ key="1"
52
+ name="host[ansible_role_ids][]"
53
+ type="hidden"
54
+ value={1}
55
+ />
56
+ <input
57
+ key="2"
58
+ name="host[ansible_role_ids][]"
59
+ type="hidden"
60
+ value={2}
61
+ />
62
+ </div>
63
+ </div>
64
+ `;
@@ -0,0 +1,54 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AvailableRolesList should render 1`] = `
4
+ <ListView
5
+ className=""
6
+ >
7
+ <div
8
+ className="sticky-pagination"
9
+ >
10
+ <PaginationWrapper
11
+ dropdownButtonId="available-ansible-roles-pagination-row-dropdown"
12
+ itemCount={2}
13
+ onChange={[Function]}
14
+ pagination={
15
+ Object {
16
+ "page": 1,
17
+ "perPage": 25,
18
+ }
19
+ }
20
+ viewType="list"
21
+ />
22
+ </div>
23
+ <LoadingState
24
+ additionalClasses=""
25
+ loading={false}
26
+ loadingText="Loading"
27
+ size="lg"
28
+ timeout={300}
29
+ >
30
+ <AnsibleRole
31
+ icon="fa fa-plus-circle"
32
+ key="1"
33
+ onClick={[Function]}
34
+ role={
35
+ Object {
36
+ "id": 1,
37
+ "name": "fake.role",
38
+ }
39
+ }
40
+ />
41
+ <AnsibleRole
42
+ icon="fa fa-plus-circle"
43
+ key="2"
44
+ onClick={[Function]}
45
+ role={
46
+ Object {
47
+ "id": 2,
48
+ "name": "test.role",
49
+ }
50
+ }
51
+ />
52
+ </LoadingState>
53
+ </ListView>
54
+ `;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+
3
+ const withProtectedView = (
4
+ ProtectedComponent,
5
+ ProtectionComponent,
6
+ protectionFn
7
+ ) => props =>
8
+ protectionFn(props) ? (
9
+ <ProtectedComponent {...props} />
10
+ ) : (
11
+ <ProtectionComponent {...props} />
12
+ );
13
+
14
+ export default withProtectedView;
@@ -0,0 +1,44 @@
1
+ import { connect } from 'react-redux';
2
+ import { bindActionCreators } from 'redux';
3
+
4
+ import AnsibleRolesSwitcher from './AnsibleRolesSwitcher';
5
+ import * as AnsibleRolesSwitcherActions from './AnsibleRolesSwitcherActions';
6
+ import AnsiblePermissionDenied from './components/AnsiblePermissionDenied';
7
+ import withProtectedView from './components/withProtectedView';
8
+ import {
9
+ selectUnassignedRoles,
10
+ selectAssignedRolesPage,
11
+ selectAssignedRoles,
12
+ selectAssignedRolesCount,
13
+ selectResults,
14
+ selectPaginationMemoized,
15
+ selectItemCount,
16
+ selectLoading,
17
+ selectAssignedPagination,
18
+ selectError,
19
+ } from './AnsibleRolesSwitcherSelectors';
20
+
21
+ const mapStateToProps = state => ({
22
+ results: selectResults(state),
23
+ pagination: selectPaginationMemoized(state),
24
+ itemCount: selectItemCount(state),
25
+ loading: selectLoading(state),
26
+ error: selectError(state),
27
+ assignedPagination: selectAssignedPagination(state),
28
+ assignedRolesCount: selectAssignedRolesCount(state),
29
+ assignedRoles: selectAssignedRolesPage(state),
30
+ allAssignedRoles: selectAssignedRoles(state),
31
+ unassignedRoles: selectUnassignedRoles(state),
32
+ });
33
+
34
+ const mapDispatchToProps = dispatch =>
35
+ bindActionCreators(AnsibleRolesSwitcherActions, dispatch);
36
+
37
+ export default withProtectedView(
38
+ connect(
39
+ mapStateToProps,
40
+ mapDispatchToProps
41
+ )(AnsibleRolesSwitcher),
42
+ AnsiblePermissionDenied,
43
+ props => props.data && props.data.canView
44
+ );
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import JSONTree from 'react-json-tree';
3
+ import PropTypes from 'prop-types';
3
4
 
4
5
  const theme = {
5
6
  scheme: 'foreman',
@@ -7,11 +8,14 @@ const theme = {
7
8
  base00: 'rgba(0, 0, 0, 0)',
8
9
  };
9
10
 
10
- class ReportJsonViewer extends React.Component {
11
- render() {
12
- return <div className="report-json-viewer">
13
- <JSONTree data={this.props.data} hideRoot theme={theme} />
14
- </div>;
15
- }
16
- }
11
+ const ReportJsonViewer = ({ data }) => (
12
+ <div className="report-json-viewer">
13
+ <JSONTree data={this.props.data} hideRoot theme={theme} />
14
+ </div>
15
+ );
16
+
17
+ ReportJsonViewer.propTypes = {
18
+ data: PropTypes.object.isRequired,
19
+ };
20
+
17
21
  export default ReportJsonViewer;
data/webpack/index.js CHANGED
@@ -1,4 +1,17 @@
1
1
  import componentRegistry from 'foremanReact/components/componentRegistry';
2
+ import injectReducer from 'foremanReact/redux/reducers/registerReducer';
2
3
  import ReportJsonViewer from './components/ReportJsonViewer';
4
+ import AnsibleRolesSwitcher from './components/AnsibleRolesSwitcher';
3
5
 
4
- componentRegistry.register({ name: 'ReportJsonViewer', type: ReportJsonViewer });
6
+ import reducer from './reducer';
7
+
8
+ componentRegistry.register({
9
+ name: 'ReportJsonViewer',
10
+ type: ReportJsonViewer,
11
+ });
12
+ componentRegistry.register({
13
+ name: 'AnsibleRolesSwitcher',
14
+ type: AnsibleRolesSwitcher,
15
+ });
16
+
17
+ injectReducer('foremanAnsible', reducer);
@@ -0,0 +1,7 @@
1
+ import { combineReducers } from 'redux';
2
+
3
+ import ansibleRolesSwitcher from './components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer';
4
+
5
+ export default combineReducers({
6
+ ansibleRolesSwitcher,
7
+ });
@@ -0,0 +1,11 @@
1
+ import 'babel-polyfill';
2
+
3
+ import { configure } from 'enzyme';
4
+ import Adapter from 'enzyme-adapter-react-16';
5
+
6
+ configure({ adapter: new Adapter() });
7
+
8
+ // Mocking translation function
9
+ global.__ = str => str;
10
+ global.n__ = str => str;
11
+ global.Jed = { sprintf: str => str };