foreman_ansible 7.1.8 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_ansible/api/v2/hostgroups_controller_extensions.rb +5 -1
  3. data/app/controllers/foreman_ansible/api/v2/hosts_controller_extensions.rb +3 -1
  4. data/app/helpers/foreman_ansible/ansible_reports_helper.rb +4 -0
  5. data/app/helpers/foreman_ansible/hosts_helper.rb +19 -0
  6. data/app/services/foreman_ansible/variables_importer.rb +9 -9
  7. data/app/views/api/v2/hostgroups/ansible_roles.json.rabl +9 -1
  8. data/app/views/api/v2/hosts/ansible_roles.json.rabl +9 -1
  9. data/lib/foreman_ansible/engine.rb +0 -1
  10. data/lib/foreman_ansible/register.rb +5 -1
  11. data/lib/foreman_ansible/version.rb +1 -1
  12. data/locale/action_names.rb +4 -3
  13. data/locale/ca/foreman_ansible.edit.po +1162 -0
  14. data/locale/ca/foreman_ansible.po +360 -45
  15. data/locale/ca/foreman_ansible.po.time_stamp +0 -0
  16. data/locale/cs_CZ/foreman_ansible.edit.po +1207 -0
  17. data/locale/cs_CZ/foreman_ansible.po +372 -57
  18. data/locale/cs_CZ/foreman_ansible.po.time_stamp +0 -0
  19. data/locale/de/foreman_ansible.edit.po +1148 -0
  20. data/locale/de/foreman_ansible.po +355 -40
  21. data/locale/de/foreman_ansible.po.time_stamp +0 -0
  22. data/locale/en/foreman_ansible.edit.po +1146 -0
  23. data/locale/en/foreman_ansible.po +355 -40
  24. data/locale/en/foreman_ansible.po.time_stamp +0 -0
  25. data/locale/en_GB/foreman_ansible.edit.po +1155 -0
  26. data/locale/en_GB/foreman_ansible.po +357 -42
  27. data/locale/en_GB/foreman_ansible.po.time_stamp +0 -0
  28. data/locale/es/foreman_ansible.edit.po +1148 -0
  29. data/locale/es/foreman_ansible.po +355 -40
  30. data/locale/es/foreman_ansible.po.time_stamp +0 -0
  31. data/locale/foreman_ansible.pot +767 -263
  32. data/locale/fr/foreman_ansible.edit.po +1148 -0
  33. data/locale/fr/foreman_ansible.po +355 -40
  34. data/locale/fr/foreman_ansible.po.time_stamp +0 -0
  35. data/locale/gl/foreman_ansible.edit.po +1156 -0
  36. data/locale/gl/foreman_ansible.po +358 -43
  37. data/locale/gl/foreman_ansible.po.time_stamp +0 -0
  38. data/locale/it/foreman_ansible.edit.po +1148 -0
  39. data/locale/it/foreman_ansible.po +355 -40
  40. data/locale/it/foreman_ansible.po.time_stamp +0 -0
  41. data/locale/ja/foreman_ansible.edit.po +1148 -0
  42. data/locale/ja/foreman_ansible.po +355 -40
  43. data/locale/ja/foreman_ansible.po.time_stamp +0 -0
  44. data/locale/ko/foreman_ansible.edit.po +1148 -0
  45. data/locale/ko/foreman_ansible.po +355 -40
  46. data/locale/ko/foreman_ansible.po.time_stamp +0 -0
  47. data/locale/nl_NL/foreman_ansible.edit.po +1168 -0
  48. data/locale/nl_NL/foreman_ansible.po +359 -44
  49. data/locale/nl_NL/foreman_ansible.po.time_stamp +0 -0
  50. data/locale/pl/foreman_ansible.edit.po +1180 -0
  51. data/locale/pl/foreman_ansible.po +363 -48
  52. data/locale/pl/foreman_ansible.po.time_stamp +0 -0
  53. data/locale/pt_BR/foreman_ansible.edit.po +1148 -0
  54. data/locale/pt_BR/foreman_ansible.po +355 -40
  55. data/locale/pt_BR/foreman_ansible.po.time_stamp +0 -0
  56. data/locale/ru/foreman_ansible.edit.po +1149 -0
  57. data/locale/ru/foreman_ansible.po +355 -40
  58. data/locale/ru/foreman_ansible.po.time_stamp +0 -0
  59. data/locale/sv_SE/foreman_ansible.edit.po +1180 -0
  60. data/locale/sv_SE/foreman_ansible.po +363 -48
  61. data/locale/sv_SE/foreman_ansible.po.time_stamp +0 -0
  62. data/locale/zh_CN/foreman_ansible.edit.po +1148 -0
  63. data/locale/zh_CN/foreman_ansible.po +355 -40
  64. data/locale/zh_CN/foreman_ansible.po.time_stamp +0 -0
  65. data/locale/zh_TW/foreman_ansible.edit.po +1148 -0
  66. data/locale/zh_TW/foreman_ansible.po +355 -40
  67. data/locale/zh_TW/foreman_ansible.po.time_stamp +0 -0
  68. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTableHelper.js +4 -13
  69. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverrides.test.js +1 -3
  70. data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js.orig +151 -0
  71. data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js +11 -1
  72. data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js +8 -10
  73. data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +1 -1
  74. data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +10 -1
  75. data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/EditRoles.test.js +1 -2
  76. data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.fixtures.js +30 -0
  77. data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.test.js +1 -3
  78. data/webpack/components/AnsibleHostDetail/components/RolesTab/index.js +2 -26
  79. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +3 -12
  80. data/webpack/components/AnsibleRolesSwitcher/components/OrderedRolesTooltip.js +11 -12
  81. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRole.test.js.snap +6 -20
  82. data/webpack/graphql/queries/allAnsibleRoles.gql +3 -0
  83. data/webpack/graphql/queries/hostAnsibleRoles.gql +3 -0
  84. data/webpack/testHelper.js +3 -12
  85. metadata +82 -45
  86. data/app/helpers/foreman_ansible/hosts_helper_extensions.rb +0 -30
@@ -4,13 +4,8 @@ import { sprintf, translate as __ } from 'foremanReact/common/I18n';
4
4
 
5
5
  import { showToast } from '../../../../toastHelper';
6
6
 
7
- function formatSourceLink(currentValue) {
8
- const element =
9
- typeof currentValue.element !== 'string'
10
- ? currentValue.element.toString()
11
- : currentValue.element;
12
- return `${__(element)}: ${currentValue.elementName}`;
13
- }
7
+ const formatSourceLink = currentValue =>
8
+ `${__(currentValue.element)}: ${currentValue.elementName}`;
14
9
 
15
10
  export const formatSourceAttr = variable =>
16
11
  variable.currentValue
@@ -90,16 +85,12 @@ const validateRegexp = (variable, value) => {
90
85
  };
91
86
 
92
87
  const validateList = (variable, value) => {
93
- let { validatorRule } = variable;
94
- if (typeof validatorRule !== 'string') {
95
- validatorRule = validatorRule.toString();
96
- }
97
- if (validatorRule.split(',').find(item => item.trim() === value)) {
88
+ if (variable.validatorRule.split(',').find(item => item.trim() === value)) {
98
89
  return validationSuccess;
99
90
  }
100
91
  return {
101
92
  key: 'error',
102
- msg: sprintf(__('Invalid, expected one of: %s'), validatorRule),
93
+ msg: sprintf(__('Invalid, expected one of: %s'), variable.validatorRule),
103
94
  };
104
95
  };
105
96
 
@@ -19,7 +19,7 @@ import {
19
19
  const TestComponent = withRedux(withMockedProvider(AnsibleVariableOverrides));
20
20
 
21
21
  describe('AnsibleVariableOverrides', () => {
22
- it('should show skeleton when page is loading', async () => {
22
+ it('should show skeleton when page is loading', () => {
23
23
  const { container } = render(
24
24
  <TestComponent
25
25
  hostId={hostId}
@@ -31,8 +31,6 @@ describe('AnsibleVariableOverrides', () => {
31
31
  expect(
32
32
  container.getElementsByClassName('react-loading-skeleton')
33
33
  ).toHaveLength(5);
34
-
35
- await waitFor(tick);
36
34
  });
37
35
  it('should load', async () => {
38
36
  render(
@@ -0,0 +1,151 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import { usePaginationOptions } from 'foremanReact/components/Pagination/PaginationHooks';
5
+
6
+ import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
7
+
8
+ import {
9
+ TableComposable,
10
+ Thead,
11
+ Tbody,
12
+ Tr,
13
+ Th,
14
+ Td,
15
+ } from '@patternfly/react-table';
16
+ import { Flex, FlexItem, Pagination } from '@patternfly/react-core';
17
+
18
+ import { decodeId } from '../../../../globalIdHelper';
19
+ import withLoading from '../../../withLoading';
20
+ <<<<<<< HEAD
21
+ import { readableCron } from './JobsTabHelper';
22
+ import {
23
+ preparePerPageOptions,
24
+ refreshPage,
25
+ } from '../../../../helpers/paginationHelper';
26
+ =======
27
+ import { readableCron, readablePurpose } from './JobsTabHelper';
28
+ >>>>>>> 5b01704 (Fixes #34458 - Show Hostgroup jobs on the Host Detail page)
29
+
30
+ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
31
+ const columns = [
32
+ __('Description'),
33
+ __('Result'),
34
+ __('State'),
35
+ __('Executed at'),
36
+ __('Schedule'),
37
+ ];
38
+
39
+ const handlePerPageSelected = (event, perPage) => {
40
+ refreshPage(history, { page: 1, perPage });
41
+ };
42
+
43
+ const handlePageSelected = (event, page) => {
44
+ refreshPage(history, { ...pagination, page });
45
+ };
46
+
47
+ const perPageOptions = preparePerPageOptions(usePaginationOptions());
48
+
49
+ return (
50
+ <React.Fragment>
51
+ <h3>{__('Previously executed jobs')}</h3>
52
+ <<<<<<< HEAD
53
+ <Flex className="pf-u-pt-md">
54
+ =======
55
+ <Flex direction={{ default: 'column' }} className="pf-u-pt-md">
56
+ <FlexItem align={{ default: 'alignRight' }}>
57
+ <Pagination updateParamsByUrl itemCount={totalCount} variant="top" />
58
+ </FlexItem>
59
+ <FlexItem>
60
+ <TableComposable variant="compact">
61
+ <Thead>
62
+ <Tr>
63
+ {columns.map(col => (
64
+ <Th key={col}>{col}</Th>
65
+ ))}
66
+ </Tr>
67
+ </Thead>
68
+ <Tbody>
69
+ {jobs.map(job => (
70
+ <Tr key={job.id}>
71
+ <Td>
72
+ <a
73
+ onClick={() =>
74
+ window.tfm.nav.pushUrl(
75
+ `/job_invocations/${decodeId(job.id)}`
76
+ )
77
+ }
78
+ >
79
+ {job.description}
80
+ </a>
81
+ &nbsp;
82
+ {readablePurpose(job.recurringLogic.purpose)}
83
+ </Td>
84
+ <Td>{job.task.result}</Td>
85
+ <Td>{job.task.state}</Td>
86
+ <Td>
87
+ <RelativeDateTime date={job.startAt} />
88
+ </Td>
89
+ <Td>{readableCron(job.recurringLogic.cronLine)}</Td>
90
+ </Tr>
91
+ ))}
92
+ </Tbody>
93
+ </TableComposable>
94
+ </FlexItem>
95
+ >>>>>>> 5b01704 (Fixes #34458 - Show Hostgroup jobs on the Host Detail page)
96
+ <FlexItem align={{ default: 'alignRight' }}>
97
+ <Pagination
98
+ itemCount={totalCount}
99
+ page={pagination.page}
100
+ perPage={pagination.perPage}
101
+ onSetPage={handlePageSelected}
102
+ onPerPageSelect={handlePerPageSelected}
103
+ perPageOptions={perPageOptions}
104
+ variant="top"
105
+ />
106
+ </FlexItem>
107
+ </Flex>
108
+ <TableComposable variant="compact">
109
+ <Thead>
110
+ <Tr>
111
+ {columns.map(col => (
112
+ <Th key={col}>{col}</Th>
113
+ ))}
114
+ </Tr>
115
+ </Thead>
116
+ <Tbody>
117
+ {jobs.map(job => (
118
+ <Tr key={job.id}>
119
+ <Td>
120
+ <a
121
+ onClick={() =>
122
+ window.tfm.nav.pushUrl(
123
+ `/job_invocations/${decodeId(job.id)}`
124
+ )
125
+ }
126
+ >
127
+ {job.description}
128
+ </a>
129
+ </Td>
130
+ <Td>{job.task.result}</Td>
131
+ <Td>{job.task.state}</Td>
132
+ <Td>
133
+ <RelativeDateTime date={job.startAt} />
134
+ </Td>
135
+ <Td>{readableCron(job.recurringLogic.cronLine)}</Td>
136
+ </Tr>
137
+ ))}
138
+ </Tbody>
139
+ </TableComposable>
140
+ </React.Fragment>
141
+ );
142
+ };
143
+
144
+ PreviousJobsTable.propTypes = {
145
+ jobs: PropTypes.array.isRequired,
146
+ history: PropTypes.object.isRequired,
147
+ totalCount: PropTypes.number.isRequired,
148
+ pagination: PropTypes.object.isRequired,
149
+ };
150
+
151
+ export default withLoading(PreviousJobsTable);
@@ -15,7 +15,7 @@ import Pagination from 'foremanReact/components/Pagination';
15
15
  import withLoading from '../../../../withLoading';
16
16
 
17
17
  const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
18
- const columns = [__('Name'), __('Source')];
18
+ const columns = [__('Name'), __('Variables'), __('Source')];
19
19
 
20
20
  return (
21
21
  <React.Fragment>
@@ -37,6 +37,16 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
37
37
  <Tr key={`${role.id}-all`} id={role.id}>
38
38
  <Td />
39
39
  <Td>{role.name}</Td>
40
+ <Td>
41
+ <a
42
+ href={`/ansible/ansible_variables?search=ansible_role=${role.name}`}
43
+ target="_blank"
44
+ rel="noreferrer"
45
+ >
46
+ {role.ansibleVariables.totalCount}
47
+ </a>
48
+ </Td>
49
+
40
50
  <Td>
41
51
  {role.inherited
42
52
  ? __('Inherited from Hostgroup')
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
3
  import PropTypes from 'prop-types';
4
- import { isEqual } from 'lodash';
4
+
5
5
  import { useMutation } from '@apollo/client';
6
6
 
7
7
  import { Button, Modal, Spinner } from '@patternfly/react-core';
@@ -21,10 +21,12 @@ const EditRolesForm = props => {
21
21
  actions,
22
22
  } = props;
23
23
 
24
- const initAvailableOpt = availableRoles.map(item => item.name);
25
- const initChosenOpt = assignedRoles.map(item => item.name);
26
- const [availableOptions, setAvailableOptions] = useState(initAvailableOpt);
27
- const [chosenOptions, setChosenOptions] = useState(initChosenOpt);
24
+ const [availableOptions, setAvailableOptions] = useState(
25
+ availableRoles.map(item => item.name)
26
+ );
27
+ const [chosenOptions, setChosenOptions] = useState(
28
+ assignedRoles.map(item => item.name)
29
+ );
28
30
 
29
31
  const onListChange = (nextAvailable, nextChosen) => {
30
32
  setAvailableOptions(nextAvailable);
@@ -43,16 +45,12 @@ const EditRolesForm = props => {
43
45
  ansibleRoleIds: roleNamesToIds(allRoles, chosenOptions),
44
46
  };
45
47
 
46
- const didNotModifyOptions = () =>
47
- isEqual(initAvailableOpt.sort(), availableOptions.sort()) &&
48
- isEqual(initChosenOpt, chosenOptions); // The order of the chosen options is important.
49
-
50
48
  const formActions = [
51
49
  <Button
52
50
  key="confirm"
53
51
  variant="primary"
54
52
  onClick={() => callMutation({ variables })}
55
- isDisabled={loading || didNotModifyOptions()}
53
+ isDisabled={loading}
56
54
  aria-label="submit ansible roles"
57
55
  >
58
56
  {__('Confirm')}
@@ -20,7 +20,7 @@ const EditRolesModal = ({
20
20
  canEditHost,
21
21
  }) => {
22
22
  const baseModalProps = {
23
- width: '50%',
23
+ width: '70%',
24
24
  isOpen,
25
25
  className: 'foreman-modal',
26
26
  showClose: false,
@@ -27,7 +27,7 @@ const RolesTable = ({
27
27
  hostGlobalId,
28
28
  canEditHost,
29
29
  }) => {
30
- const columns = [__('Name')];
30
+ const columns = [__('Name'), __('Variables')];
31
31
 
32
32
  const editBtn = canEditHost ? (
33
33
  <FlexItem>
@@ -72,6 +72,15 @@ const RolesTable = ({
72
72
  <Td>
73
73
  <a href={role.path}>{role.name}</a>
74
74
  </Td>
75
+ <Td>
76
+ <a
77
+ href={`/ansible/ansible_variables?search=ansible_role=${role.name}`}
78
+ target="_blank"
79
+ rel="noreferrer"
80
+ >
81
+ {role.ansibleVariables.totalCount}
82
+ </a>
83
+ </Td>
75
84
  </Tr>
76
85
  ))}
77
86
  </Tbody>
@@ -21,8 +21,7 @@ import {
21
21
  assignRolesErrorMock,
22
22
  } from './RolesTab.fixtures';
23
23
 
24
- jest.mock('axios');
25
- const TestComponent = withRedux(withReactRouter(withMockedProvider(RolesTab)));
24
+ const TestComponent = withReactRouter(withRedux(withMockedProvider(RolesTab)));
26
25
 
27
26
  describe('assigning Ansible roles', () => {
28
27
  it('should assign Ansible roles', async () => {
@@ -35,6 +35,9 @@ const role1 = {
35
35
  id: 'MDE6QW5zaWJsZVJvbGUtMw==',
36
36
  name: 'aardvaark.cube',
37
37
  path: '/ansible/ansible_roles/search="name = aardvaark.cube"',
38
+ ansibleVariables: {
39
+ totalCount: 1,
40
+ },
38
41
  };
39
42
 
40
43
  const role2 = {
@@ -42,6 +45,9 @@ const role2 = {
42
45
  id: 'MDE6QW5zaWJsZVJvbGUtNQ==',
43
46
  name: 'aardvaark.sphere',
44
47
  path: '/ansible/ansible_roles/search="name = aardvaark.sphere"',
48
+ ansibleVariables: {
49
+ totalCount: 2,
50
+ },
45
51
  };
46
52
 
47
53
  const role3 = {
@@ -49,6 +55,9 @@ const role3 = {
49
55
  id: 'MDE6QW5zaWJsZVJvbGUtMzA=',
50
56
  name: 'another.role',
51
57
  path: '/ansible/ansible_roles/search="name = another.role"',
58
+ ansibleVariables: {
59
+ totalCount: 3,
60
+ },
52
61
  };
53
62
 
54
63
  const role4 = {
@@ -56,6 +65,9 @@ const role4 = {
56
65
  id: 'MDE6QW5zaWJsZVJvbGUtMzk=',
57
66
  name: 'geerlingguy.ceylon',
58
67
  path: '/ansible/ansible_roles/search="name = geerlingguy.ceylon"',
68
+ ansibleVariables: {
69
+ totalCount: 4,
70
+ },
59
71
  };
60
72
 
61
73
  const ansibleRolesMock = {
@@ -77,30 +89,45 @@ const availableRoles = {
77
89
  name: 'theforeman.foreman_scap_client',
78
90
  path:
79
91
  '/ansible/ansible_roles/search="name = theforeman.foreman_scap_client"',
92
+ ansibleVariables: {
93
+ totalCount: 23,
94
+ },
80
95
  },
81
96
  {
82
97
  __typename: 'AnsibleRole',
83
98
  id: 'MDE6QW5zaWJsZVJvbGUtMg==',
84
99
  name: 'adriagalin.motd',
85
100
  path: '/ansible/ansible_roles/search="name = adriagalin.motd"',
101
+ ansibleVariables: {
102
+ totalCount: 23,
103
+ },
86
104
  },
87
105
  {
88
106
  __typename: 'AnsibleRole',
89
107
  id: 'MDE6QW5zaWJsZVJvbGUtMjI=',
90
108
  name: 'geerlingguy.php',
91
109
  path: '/ansible/ansible_roles/search="name = geerlingguy.php"',
110
+ ansibleVariables: {
111
+ totalCount: 23,
112
+ },
92
113
  },
93
114
  {
94
115
  __typename: 'AnsibleRole',
95
116
  id: 'MDE6QW5zaWJsZVJvbGUtNTc=',
96
117
  name: 'robertdebock.epel',
97
118
  path: '/ansible/ansible_roles/search="name = robertdebock.epel"',
119
+ ansibleVariables: {
120
+ totalCount: 23,
121
+ },
98
122
  },
99
123
  {
100
124
  __typename: 'AnsibleRole',
101
125
  id: 'MDE6QW5zaWJsZVJvbGUtNTg=',
102
126
  name: 'geerlingguy.nfs',
103
127
  path: '/ansible/ansible_roles/search="name = geerlingguy.nfs"',
128
+ ansibleVariables: {
129
+ totalCount: 23,
130
+ },
104
131
  },
105
132
  ],
106
133
  };
@@ -118,6 +145,9 @@ export const allRolesMocks = allAnsibleRolesMockFactory(
118
145
  name: 'adriagalin.motd',
119
146
  path: '/ansible/ansible_roles/search="name = adriagalin.motd"',
120
147
  inherited: true,
148
+ ansibleVariables: {
149
+ totalCount: 23,
150
+ },
121
151
  },
122
152
  { ...role1, inherited: false },
123
153
  { ...role2, inherited: false },
@@ -6,7 +6,6 @@ import {
6
6
  tick,
7
7
  withMockedProvider,
8
8
  withReactRouter,
9
- withRedux,
10
9
  } from '../../../../../testHelper';
11
10
 
12
11
  import {
@@ -19,8 +18,7 @@ import {
19
18
 
20
19
  import RolesTab from '../';
21
20
 
22
- jest.mock('axios');
23
- const TestComponent = withRedux(withReactRouter(withMockedProvider(RolesTab)));
21
+ const TestComponent = withReactRouter(withMockedProvider(RolesTab));
24
22
 
25
23
  describe('RolesTab', () => {
26
24
  it('should load Ansible Roles as admin', async () => {
@@ -2,10 +2,7 @@ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useQuery } from '@apollo/client';
4
4
  import { Button } from '@patternfly/react-core';
5
- import { Link, Route } from 'react-router-dom';
6
5
  import { translate as __ } from 'foremanReact/common/I18n';
7
- import { foremanUrl } from 'foremanReact/common/helpers';
8
- import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
9
6
 
10
7
  import ansibleRolesQuery from '../../../../graphql/queries/hostAnsibleRoles.gql';
11
8
  import { encodeId } from '../../../../globalIdHelper';
@@ -15,7 +12,6 @@ import {
15
12
  useCurrentPagination,
16
13
  } from '../../../../helpers/pageParamsHelper';
17
14
  import EditRolesModal from './EditRolesModal';
18
- import AllRolesModal from './AllRolesModal';
19
15
 
20
16
  const RolesTab = ({ hostId, history, canEditHost }) => {
21
17
  const hostGlobalId = encodeId('Host', hostId);
@@ -37,28 +33,9 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
37
33
  onClick={() => setAssignModal(true)}
38
34
  aria-label="edit ansible roles"
39
35
  >
40
- {__('Assign roles directly to the host')}
36
+ {__('Assign Ansible roles')}
41
37
  </Button>
42
38
  ) : null;
43
-
44
- const url = hostId && foremanUrl(`/api/v2/hosts/${hostId}/ansible_roles`);
45
- const { response: allAnsibleRoles } = useAPI('get', url, {
46
- key: 'ANSIBLE_ROLES',
47
- });
48
- const emptyStateDescription = allAnsibleRoles.length > 0 && (
49
- <>
50
- <Route path="/Ansible/roles/all">
51
- <AllRolesModal
52
- onClose={() => history.push('/Ansible/roles')}
53
- isOpen
54
- hostGlobalId={hostGlobalId}
55
- history={history}
56
- />
57
- </Route>
58
- <Link to="/Ansible/roles/all">{__('View inherited roles')}</Link>
59
- </>
60
- );
61
-
62
39
  return (
63
40
  <>
64
41
  <RolesTable
@@ -69,9 +46,8 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
69
46
  history={history}
70
47
  hostGlobalId={hostGlobalId}
71
48
  emptyStateProps={{
72
- header: __('No roles assigned directly to the host'),
49
+ header: __('No Ansible roles assigned'),
73
50
  action: editBtn,
74
- description: emptyStateDescription,
75
51
  }}
76
52
  pagination={pagination}
77
53
  canEditHost={canEditHost}
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { ListView, Tooltip, OverlayTrigger } from 'patternfly-react';
3
+ import { ListView } from 'patternfly-react';
4
+ import { Tooltip } from '@patternfly/react-core';
4
5
  import classNames from 'classnames';
5
6
  import { translate as __ } from 'foremanReact/common/I18n';
6
7
 
@@ -13,12 +14,6 @@ const AnsibleRole = ({ role, icon, onClick, resourceName, index }) => {
13
14
  ? __('This Ansible role is inherited from parent host group')
14
15
  : __('This Ansible role is inherited from host group');
15
16
 
16
- const tooltip = (
17
- <Tooltip id={role.id}>
18
- <span>{text}</span>
19
- </Tooltip>
20
- );
21
-
22
17
  const clickHandler = (onClickFn, ansibleRole) => event => {
23
18
  event.preventDefault();
24
19
  onClickFn(ansibleRole);
@@ -48,11 +43,7 @@ const AnsibleRole = ({ role, icon, onClick, resourceName, index }) => {
48
43
  );
49
44
 
50
45
  if (role.inherited) {
51
- return (
52
- <OverlayTrigger overlay={tooltip} placement="top">
53
- {listItem()}
54
- </OverlayTrigger>
55
- );
46
+ return <Tooltip content={<span>{text}</span>}>{listItem()}</Tooltip>;
56
47
  }
57
48
 
58
49
  return listItem(clickHandler);
@@ -1,22 +1,21 @@
1
1
  import React from 'react';
2
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
- import { Tooltip, Icon, OverlayTrigger } from 'patternfly-react';
3
+ import { Tooltip } from '@patternfly/react-core';
4
+ import { InfoCircleIcon } from '@patternfly/react-icons';
4
5
 
5
6
  const OrderedRolesTooltip = props => {
6
- const tooltip = (
7
- <Tooltip id="assigned-ansible-roles-tooltip">
8
- <span>
9
- {__(
10
- 'Use drag and drop to change order of the roles. Ordering of roles is respected for Ansible runs, inherited roles are always before those assigned directly'
11
- )}
12
- </span>
13
- </Tooltip>
7
+ const content = (
8
+ <span>
9
+ {__(
10
+ 'Use drag and drop to change order of the roles. Ordering of roles is respected for Ansible runs, inherited roles are always before those assigned directly'
11
+ )}
12
+ </span>
14
13
  );
15
14
 
16
15
  return (
17
- <OverlayTrigger overlay={tooltip} trigger={['hover', 'focus']}>
18
- <Icon type="pf" name="info" style={{ 'margin-right': '10px' }} />
19
- </OverlayTrigger>
16
+ <Tooltip content={content}>
17
+ <InfoCircleIcon style={{ marginRight: '10px' }} />
18
+ </Tooltip>
20
19
  );
21
20
  };
22
21
 
@@ -65,25 +65,11 @@ exports[`AnsibleRole should render a role to remove 1`] = `
65
65
  `;
66
66
 
67
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
- ]
68
+ <Tooltip
69
+ content={
70
+ <span>
71
+ This Ansible role is inherited from host group
72
+ </span>
87
73
  }
88
74
  >
89
75
  <ListViewItem
@@ -104,5 +90,5 @@ exports[`AnsibleRole should render inherited role to remove 1`] = `
104
90
  onExpandClose={[Function]}
105
91
  stacked={true}
106
92
  />
107
- </OverlayTrigger>
93
+ </Tooltip>
108
94
  `;
@@ -7,6 +7,9 @@ query($id: String!, $first: Int, $last: Int){
7
7
  id
8
8
  name
9
9
  inherited
10
+ ansibleVariables {
11
+ totalCount
12
+ }
10
13
  }
11
14
  }
12
15
  }
@@ -9,6 +9,9 @@ query($id: String!, $first: Int, $last: Int) {
9
9
  id
10
10
  name
11
11
  path
12
+ ansibleVariables {
13
+ totalCount
14
+ }
12
15
  }
13
16
  }
14
17
  }
@@ -1,24 +1,15 @@
1
1
  import React from 'react';
2
2
  import { Provider } from 'react-redux';
3
- import thunk from 'redux-thunk';
4
- import { applyMiddleware, createStore, compose, combineReducers } from 'redux';
5
3
  import { MockedProvider } from '@apollo/react-testing';
6
4
  import { Router, MemoryRouter } from 'react-router-dom';
7
5
  import { createMemoryHistory } from 'history';
8
6
 
9
- import { reducers as apiReducer, APIMiddleware } from 'foremanReact/redux/API';
10
- import ConfirmModal, {
11
- reducers as confirmModalReducers,
12
- } from 'foremanReact/components/ConfirmModal';
7
+ import store from 'foremanReact/redux';
8
+ import ConfirmModal from 'foremanReact/components/ConfirmModal';
13
9
  import { getForemanContext } from 'foremanReact/Root/Context/ForemanContext';
14
10
 
15
- const reducers = combineReducers({ ...apiReducer, ...confirmModalReducers });
16
-
17
- export const generateStore = () =>
18
- createStore(reducers, compose(applyMiddleware(thunk, APIMiddleware)));
19
-
20
11
  export const withRedux = Component => props => (
21
- <Provider store={generateStore()}>
12
+ <Provider store={store}>
22
13
  <Component {...props} />
23
14
  <ConfirmModal />
24
15
  </Provider>