katello 3.8.0.rc1 → 3.8.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/katello/common/index.js +1 -0
- data/app/assets/javascripts/katello/sync_management/index.js +1 -0
- data/app/controllers/katello/api/registry/registry_proxies_controller.rb +1 -1
- data/app/controllers/katello/api/v2/environments_controller.rb +0 -1
- data/app/controllers/katello/api/v2/ostree_branches_controller.rb +1 -1
- data/app/controllers/katello/api/v2/repository_sets_controller.rb +10 -1
- data/app/controllers/katello/remote_execution_controller.rb +6 -6
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +37 -9
- data/app/lib/katello/resources/registry.rb +4 -4
- data/app/models/katello/authorization/repository.rb +2 -1
- data/app/models/katello/content_view.rb +12 -4
- data/app/models/katello/glue/candlepin/owner.rb +0 -8
- data/app/models/katello/glue/candlepin/pool.rb +11 -11
- data/app/models/katello/kt_environment.rb +0 -6
- data/app/models/katello/product_content.rb +4 -1
- data/app/models/katello/rpm.rb +13 -5
- data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +3 -1
- data/app/views/overrides/activation_keys/_host_environment_select.html.erb +2 -3
- data/config/katello.yaml.example +5 -0
- data/config/routes.rb +1 -0
- data/db/seeds.d/75-job_templates.rb +5 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-details.html +43 -8
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +17 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery.html +1 -1
- data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +5 -0
- data/lib/katello/version.rb +1 -1
- data/package.json +11 -7
- data/webpack/__mocks__/foremanReact/components/BreadcrumbBar.js +3 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
- data/webpack/__mocks__/foremanReact/redux.js +3 -0
- data/webpack/components/Search/Search.test.js +3 -1
- data/webpack/components/SelectOrg/SelectOrg.scss +3 -0
- data/webpack/components/SelectOrg/SelectOrgAction.js +41 -0
- data/webpack/components/SelectOrg/SelectOrgReducer.js +33 -0
- data/webpack/components/SelectOrg/SetOrganization.js +116 -0
- data/webpack/components/WithOrganization/withOrganization.js +28 -0
- data/webpack/containers/Application/config.js +9 -2
- data/webpack/containers/Application/index.js +4 -2
- data/webpack/global_test_setup.js +6 -0
- data/webpack/helpers/caret.js +6 -0
- data/webpack/mockRequest.js +3 -3
- data/webpack/move_to_foreman/common/helpers.js +45 -8
- data/webpack/move_to_foreman/components/common/{emptyState → EmptyState}/index.js +16 -3
- data/webpack/move_to_foreman/components/common/table/components/Table.js +1 -1
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/CollapseSubscriptionGroupButton.test.js.snap +2 -2
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionCell.test.js.snap +1 -1
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionHeaderCell.test.js.snap +1 -1
- data/webpack/move_to_pf/LoadingState/LoadingState.js +27 -14
- data/webpack/move_to_pf/LoadingState/LoadingState.test.js +8 -4
- data/webpack/move_to_pf/Select/Select.js +40 -0
- data/webpack/move_to_pf/react-bootstrap-select/index.js +12 -1
- data/webpack/redux/actions/RedHatRepositories/enabled.js +0 -1
- data/webpack/redux/actions/RedHatRepositories/helpers.js +5 -5
- data/webpack/redux/actions/RedHatRepositories/sets.js +1 -1
- data/webpack/redux/consts.js +6 -0
- data/webpack/redux/reducers/index.js +2 -0
- data/webpack/scenes/RedHatRepositories/components/EnabledRepository.js +14 -23
- data/webpack/scenes/RedHatRepositories/components/EnabledRepositoryContent.js +34 -0
- data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +1 -1
- data/webpack/scenes/RedHatRepositories/components/SearchBar.js +1 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/EnabledRepository.test.js +36 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/EnabledRepositoryContent.test.js +27 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepository.test.js.snap +25 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +47 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RecommendedRepositorySetsToggler.test.js.snap +3 -1
- data/webpack/scenes/RedHatRepositories/index.js +7 -3
- data/webpack/scenes/RedHatRepositories/index.scss +1 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +3 -8
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +5 -3
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +1 -1
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +44 -6
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +4 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailReducer.test.js +3 -1
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +2 -1
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailProducts.test.js.snap +113 -23
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +23 -14
- data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +3 -4
- data/webpack/scenes/Subscriptions/Details/index.js +2 -2
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +78 -34
- data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +5 -24
- data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +9 -1
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +3 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestActions.test.js +20 -8
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestHistoryReducer.test.js +3 -1
- data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +34 -7
- data/webpack/scenes/Subscriptions/Manifest/__tests__/manifest.fixtures.js +9 -16
- data/webpack/scenes/Subscriptions/Manifest/index.js +1 -0
- data/webpack/scenes/Subscriptions/SubscriptionActions.js +5 -26
- data/webpack/scenes/Subscriptions/SubscriptionConstants.js +1 -0
- data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +3 -0
- data/webpack/scenes/Subscriptions/SubscriptionReducer.js +11 -4
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +31 -36
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +3 -12
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +57 -27
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +2 -3
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +10 -5
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsActions.test.js +10 -5
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +50 -5
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsReducer.test.js +8 -3
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +21 -11
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js +5 -8
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +2 -0
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +9 -3
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +14 -2
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +11 -17
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/EntitlementsInlineEditFormatter.js +8 -5
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +45 -58
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +11 -4
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +2 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/EntitlementsInlineEditFormatter.test.js +110 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +16 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/EntitlementsInlineEditFormatter.test.js.snap +228 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +392 -365
- data/webpack/scenes/Subscriptions/index.js +1 -0
- data/webpack/scenes/Tasks/helpers.js +52 -0
- data/webpack/services/api/index.js +17 -1
- data/webpack/services/api/testHelpers.js +28 -0
- data/webpack/test_setup.js +2 -0
- metadata +24 -5
- data/config/katello.yaml +0 -89
- data/webpack/services/api/fixtures.js +0 -353
@@ -1,9 +1,9 @@
|
|
1
1
|
const repoTypeSearchQueryMap = {
|
2
|
-
rpm: '(name
|
3
|
-
sourceRpm: 'name ~ source rpm',
|
4
|
-
debugRpm: 'name ~ debug rpm',
|
5
|
-
kickstart: '
|
6
|
-
ostree: '
|
2
|
+
rpm: '(name !~ source rpm) and (name !~ debug rpm) and (content_type = yum)',
|
3
|
+
sourceRpm: '(name ~ source rpm) and (content_type = yum)',
|
4
|
+
debugRpm: '(name ~ debug rpm) and (content_type = yum)',
|
5
|
+
kickstart: 'content_type = kickstart',
|
6
|
+
ostree: 'content_type = ostree',
|
7
7
|
beta: 'name ~ beta',
|
8
8
|
};
|
9
9
|
|
@@ -28,7 +28,7 @@ export const loadRepositorySets = (extendedParams = {}) => (dispatch, getState)
|
|
28
28
|
]);
|
29
29
|
|
30
30
|
const params = {
|
31
|
-
...{ organization_id: orgId() },
|
31
|
+
...{ organization_id: orgId(), with_active_subscription: true },
|
32
32
|
...propsToSnakeCase(extendedParams),
|
33
33
|
search,
|
34
34
|
};
|
data/webpack/redux/consts.js
CHANGED
@@ -17,3 +17,9 @@ export const REPOSITORY_SETS_UPDATE_RECOMMENDED = 'REPOSITORY_SETS_UPDATE_RECOMM
|
|
17
17
|
|
18
18
|
export const REPOSITORY_ENABLED = 'REPOSITORY_ENABLED';
|
19
19
|
export const REPOSITORY_DISABLED = 'REPOSITORY_DISABLED';
|
20
|
+
|
21
|
+
export const GET_ORGANIZATIONS_LIST_SUCCESS = 'GET_ORGANIZATIONS_LIST_SUCCESS';
|
22
|
+
export const GET_ORGANIZATIONS_LIST_FAILURE = 'GET_ORGANIZATIONS_LIST_FAILURE';
|
23
|
+
export const CHANGE_CURRENT_ORGANIZATION_SUCCESS = 'CHANGE_CURRENT_ORGANIZATION_SUCCESS';
|
24
|
+
export const CHANGE_CURRENT_ORGANIZATION_FAILURE = 'CHANGE_CURRENT_ORGANIZATION_FAILURE';
|
25
|
+
export const GET_ORGANIZATIONS_LIST_REQUEST = 'GET_ORGANIZATIONS_LIST_REQUEST';
|
@@ -5,6 +5,7 @@ import { subscriptions } from '../../scenes/Subscriptions';
|
|
5
5
|
import { upstreamSubscriptions } from '../../scenes/Subscriptions/UpstreamSubscriptions';
|
6
6
|
import { manifestHistory } from '../../scenes/Subscriptions/Manifest';
|
7
7
|
import { subscriptionDetails } from '../../scenes/Subscriptions/Details';
|
8
|
+
import { setOrganization } from '../../components/SelectOrg/SetOrganization';
|
8
9
|
|
9
10
|
export default combineReducers({
|
10
11
|
organization,
|
@@ -13,4 +14,5 @@ export default combineReducers({
|
|
13
14
|
upstreamSubscriptions,
|
14
15
|
manifestHistory,
|
15
16
|
subscriptionDetails,
|
17
|
+
setOrganization,
|
16
18
|
});
|
@@ -1,12 +1,14 @@
|
|
1
1
|
import React, { Component } from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
-
import
|
4
|
-
import { ListView, Spinner, OverlayTrigger, Tooltip } from 'patternfly-react';
|
3
|
+
import { ListView } from 'patternfly-react';
|
5
4
|
import { connect } from 'react-redux';
|
6
5
|
|
7
6
|
import RepositoryTypeIcon from './RepositoryTypeIcon';
|
8
7
|
import { setRepositoryDisabled } from '../../../redux/actions/RedHatRepositories/enabled';
|
9
8
|
import api from '../../../services/api';
|
9
|
+
import { notify } from '../../../move_to_foreman/foreman_toast_notifications';
|
10
|
+
import { getResponseErrorMsgs } from '../../../move_to_foreman/common/helpers';
|
11
|
+
import EnabledRepositoryContent from './EnabledRepositoryContent';
|
10
12
|
|
11
13
|
class EnabledRepository extends Component {
|
12
14
|
constructor(props) {
|
@@ -49,9 +51,12 @@ class EnabledRepository extends Component {
|
|
49
51
|
api
|
50
52
|
.put(url, data)
|
51
53
|
.then(this.setDisabled)
|
52
|
-
.catch(() => {
|
54
|
+
.catch(({ response }) => {
|
55
|
+
const errors = getResponseErrorMsgs(response);
|
56
|
+
errors.forEach((error) => {
|
57
|
+
notify({ message: error, type: 'error' });
|
58
|
+
});
|
53
59
|
this.setState({ loading: false });
|
54
|
-
// TODO: Add error component
|
55
60
|
});
|
56
61
|
};
|
57
62
|
|
@@ -67,25 +72,11 @@ class EnabledRepository extends Component {
|
|
67
72
|
<ListView.Item
|
68
73
|
key={id}
|
69
74
|
actions={
|
70
|
-
<
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
rootClose={false}
|
76
|
-
>
|
77
|
-
<button
|
78
|
-
onClick={this.disableRepository}
|
79
|
-
style={{
|
80
|
-
backgroundColor: 'initial',
|
81
|
-
border: 'none',
|
82
|
-
color: '#0388ce',
|
83
|
-
}}
|
84
|
-
>
|
85
|
-
<i className={cx('fa-2x', 'fa fa-minus-circle')} />
|
86
|
-
</button>
|
87
|
-
</OverlayTrigger>
|
88
|
-
</Spinner>
|
75
|
+
<EnabledRepositoryContent
|
76
|
+
loading={this.state.loading}
|
77
|
+
disableTooltipId={this.disableTooltipId}
|
78
|
+
disableRepository={this.disableRepository}
|
79
|
+
/>
|
89
80
|
}
|
90
81
|
leftContent={<RepositoryTypeIcon id={id} type={type} />}
|
91
82
|
heading={name}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import cx from 'classnames';
|
4
|
+
import { Spinner, OverlayTrigger, Tooltip } from 'patternfly-react';
|
5
|
+
|
6
|
+
const EnabledRepositoryContent = ({ loading, disableTooltipId, disableRepository }) => (
|
7
|
+
<Spinner loading={loading} inline>
|
8
|
+
<OverlayTrigger
|
9
|
+
overlay={<Tooltip id={disableTooltipId}>{__('Disable')}</Tooltip>}
|
10
|
+
placement="bottom"
|
11
|
+
trigger={['hover', 'focus']}
|
12
|
+
rootClose={false}
|
13
|
+
>
|
14
|
+
<button
|
15
|
+
onClick={disableRepository}
|
16
|
+
style={{
|
17
|
+
backgroundColor: 'initial',
|
18
|
+
border: 'none',
|
19
|
+
color: '#0388ce',
|
20
|
+
}}
|
21
|
+
>
|
22
|
+
<i className={cx('fa-2x', 'fa fa-minus-circle')} />
|
23
|
+
</button>
|
24
|
+
</OverlayTrigger>
|
25
|
+
</Spinner>
|
26
|
+
);
|
27
|
+
|
28
|
+
EnabledRepositoryContent.propTypes = {
|
29
|
+
loading: PropTypes.bool.isRequired,
|
30
|
+
disableTooltipId: PropTypes.string.isRequired,
|
31
|
+
disableRepository: PropTypes.func.isRequired,
|
32
|
+
};
|
33
|
+
|
34
|
+
export default EnabledRepositoryContent;
|
@@ -50,7 +50,7 @@ class RepositorySetRepository extends Component {
|
|
50
50
|
const data = {
|
51
51
|
id: contentId,
|
52
52
|
product_id: productId,
|
53
|
-
basearch: arch
|
53
|
+
basearch: arch === UNSPECIFIED_ARCH ? undefined : arch,
|
54
54
|
releasever: releasever || undefined,
|
55
55
|
};
|
56
56
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import thunk from 'redux-thunk';
|
3
|
+
import { shallow } from 'enzyme';
|
4
|
+
import toJson from 'enzyme-to-json';
|
5
|
+
import configureMockStore from 'redux-mock-store';
|
6
|
+
import EnabledRepository from '../EnabledRepository';
|
7
|
+
|
8
|
+
jest.mock('../../../../move_to_foreman/foreman_toast_notifications');
|
9
|
+
|
10
|
+
const mockStore = configureMockStore([thunk]);
|
11
|
+
const store = mockStore({});
|
12
|
+
|
13
|
+
describe('Enabled Repositories Component', () => {
|
14
|
+
let shallowWrapper;
|
15
|
+
beforeEach(() => {
|
16
|
+
shallowWrapper = shallow(<EnabledRepository
|
17
|
+
store={store}
|
18
|
+
id={1}
|
19
|
+
contentId={1}
|
20
|
+
productId={1}
|
21
|
+
name="foo"
|
22
|
+
type="foo"
|
23
|
+
arch="foo"
|
24
|
+
releaseVer="1.1.1"
|
25
|
+
setRepositoryDisabled={() => {}}
|
26
|
+
/>);
|
27
|
+
});
|
28
|
+
|
29
|
+
afterEach(() => {
|
30
|
+
store.clearActions();
|
31
|
+
});
|
32
|
+
|
33
|
+
it('should render', async () => {
|
34
|
+
expect(toJson(shallowWrapper)).toMatchSnapshot();
|
35
|
+
});
|
36
|
+
});
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { shallow } from 'enzyme';
|
3
|
+
import toJson from 'enzyme-to-json';
|
4
|
+
import EnabledRepositoryContent from '../EnabledRepositoryContent';
|
5
|
+
|
6
|
+
describe('Enabled Repositories Content Component', () => {
|
7
|
+
const mockCallBack = jest.fn();
|
8
|
+
|
9
|
+
let shallowWrapper;
|
10
|
+
beforeEach(() => {
|
11
|
+
shallowWrapper = shallow(<EnabledRepositoryContent
|
12
|
+
loading
|
13
|
+
disableTooltipId="disable-1"
|
14
|
+
disableRepository={mockCallBack}
|
15
|
+
/>);
|
16
|
+
});
|
17
|
+
|
18
|
+
it('should render', async () => {
|
19
|
+
expect(toJson(shallowWrapper)).toMatchSnapshot();
|
20
|
+
});
|
21
|
+
|
22
|
+
it('should run disableRepository on click', async () => {
|
23
|
+
expect(mockCallBack).not.toHaveBeenCalled();
|
24
|
+
shallowWrapper.find('button').at(0).simulate('click');
|
25
|
+
expect(mockCallBack).toHaveBeenCalled();
|
26
|
+
});
|
27
|
+
});
|
@@ -0,0 +1,25 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`Enabled Repositories Component should render 1`] = `
|
4
|
+
<EnabledRepository
|
5
|
+
arch="foo"
|
6
|
+
contentId={1}
|
7
|
+
id={1}
|
8
|
+
name="foo"
|
9
|
+
productId={1}
|
10
|
+
releaseVer="1.1.1"
|
11
|
+
releasever=""
|
12
|
+
setRepositoryDisabled={[Function]}
|
13
|
+
store={
|
14
|
+
Object {
|
15
|
+
"clearActions": [Function],
|
16
|
+
"dispatch": [Function],
|
17
|
+
"getActions": [Function],
|
18
|
+
"getState": [Function],
|
19
|
+
"replaceReducer": [Function],
|
20
|
+
"subscribe": [Function],
|
21
|
+
}
|
22
|
+
}
|
23
|
+
type="foo"
|
24
|
+
/>
|
25
|
+
`;
|
@@ -0,0 +1,47 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`Enabled Repositories Content Component should render 1`] = `
|
4
|
+
<Spinner
|
5
|
+
className=""
|
6
|
+
inline={true}
|
7
|
+
inverse={false}
|
8
|
+
loading={true}
|
9
|
+
size="md"
|
10
|
+
>
|
11
|
+
<OverlayTrigger
|
12
|
+
defaultOverlayShown={false}
|
13
|
+
overlay={
|
14
|
+
<Tooltip
|
15
|
+
bsClass="tooltip"
|
16
|
+
id="disable-1"
|
17
|
+
placement="right"
|
18
|
+
>
|
19
|
+
Disable
|
20
|
+
</Tooltip>
|
21
|
+
}
|
22
|
+
placement="bottom"
|
23
|
+
rootClose={false}
|
24
|
+
trigger={
|
25
|
+
Array [
|
26
|
+
"hover",
|
27
|
+
"focus",
|
28
|
+
]
|
29
|
+
}
|
30
|
+
>
|
31
|
+
<button
|
32
|
+
onClick={[MockFunction]}
|
33
|
+
style={
|
34
|
+
Object {
|
35
|
+
"backgroundColor": "initial",
|
36
|
+
"border": "none",
|
37
|
+
"color": "#0388ce",
|
38
|
+
}
|
39
|
+
}
|
40
|
+
>
|
41
|
+
<i
|
42
|
+
className="fa-2x fa fa-minus-circle"
|
43
|
+
/>
|
44
|
+
</button>
|
45
|
+
</OverlayTrigger>
|
46
|
+
</Spinner>
|
47
|
+
`;
|
@@ -7,7 +7,6 @@ import PropTypes from 'prop-types';
|
|
7
7
|
import { connect } from 'react-redux';
|
8
8
|
import { Grid, Row, Col } from 'react-bootstrap';
|
9
9
|
import { LoadingState } from '../../move_to_pf/LoadingState';
|
10
|
-
|
11
10
|
import { createEnabledRepoParams, loadEnabledRepos } from '../../redux/actions/RedHatRepositories/enabled';
|
12
11
|
import { loadRepositorySets, updateRecommendedRepositorySets } from '../../redux/actions/RedHatRepositories/sets';
|
13
12
|
import SearchBar from './components/SearchBar';
|
@@ -31,7 +30,6 @@ class RedHatRepositoriesPage extends Component {
|
|
31
30
|
return (
|
32
31
|
<Grid id="redhatRepositoriesPage" bsClass="container-fluid">
|
33
32
|
<h1>{__('Red Hat Repositories')}</h1>
|
34
|
-
|
35
33
|
<Row className="toolbar-pf">
|
36
34
|
<Col sm={12}>
|
37
35
|
<SearchBar repoParams={repoParams} />
|
@@ -87,9 +85,15 @@ RedHatRepositoriesPage.propTypes = {
|
|
87
85
|
updateRecommendedRepositorySets: PropTypes.func.isRequired,
|
88
86
|
enabledRepositories: PropTypes.shape({}).isRequired,
|
89
87
|
repositorySets: PropTypes.shape({}).isRequired,
|
88
|
+
history: PropTypes.shape({}).isRequired,
|
89
|
+
location: PropTypes.shape({}).isRequired,
|
90
90
|
};
|
91
91
|
|
92
|
-
const mapStateToProps = ({
|
92
|
+
const mapStateToProps = ({
|
93
|
+
katello: {
|
94
|
+
redHatRepositories: { enabled, sets },
|
95
|
+
},
|
96
|
+
}) => ({
|
93
97
|
enabledRepositories: enabled,
|
94
98
|
repositorySets: sets,
|
95
99
|
});
|
@@ -4,9 +4,9 @@ import {
|
|
4
4
|
SUBSCRIPTION_DETAILS_SUCCESS,
|
5
5
|
SUBSCRIPTION_DETAILS_FAILURE,
|
6
6
|
} from './SubscriptionDetailConstants';
|
7
|
-
import {
|
7
|
+
import { apiError } from '../../../move_to_foreman/common/helpers.js';
|
8
8
|
|
9
|
-
export const loadSubscriptionDetails = subscriptionId => (dispatch) => {
|
9
|
+
export const loadSubscriptionDetails = subscriptionId => (dispatch, getState) => {
|
10
10
|
dispatch({ type: SUBSCRIPTION_DETAILS_REQUEST });
|
11
11
|
|
12
12
|
return api
|
@@ -17,12 +17,7 @@ export const loadSubscriptionDetails = subscriptionId => (dispatch) => {
|
|
17
17
|
response: data,
|
18
18
|
});
|
19
19
|
})
|
20
|
-
.catch(
|
21
|
-
dispatch({
|
22
|
-
type: SUBSCRIPTION_DETAILS_FAILURE,
|
23
|
-
error: getResponseError(result.response),
|
24
|
-
});
|
25
|
-
});
|
20
|
+
.catch(result => dispatch(apiError(SUBSCRIPTION_DETAILS_FAILURE, result)));
|
26
21
|
};
|
27
22
|
|
28
23
|
export default loadSubscriptionDetails;
|
@@ -1,15 +1,17 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
+
import { ListGroup, ListGroupItem } from 'patternfly-react';
|
4
|
+
import './SubscriptionDetails.scss';
|
3
5
|
|
4
6
|
const SubscriptionDetailProducts = ({ subscriptionDetails }) => (
|
5
7
|
<div>
|
6
8
|
<h2>{__('Provided Products')}</h2>
|
7
|
-
<
|
9
|
+
<ListGroup className="scrolld-list">
|
8
10
|
{subscriptionDetails.provided_products &&
|
9
11
|
subscriptionDetails.provided_products.map(prod => (
|
10
|
-
<
|
12
|
+
<ListGroupItem key={prod.id}> {prod.name} </ListGroupItem>
|
11
13
|
))}
|
12
|
-
</
|
14
|
+
</ListGroup>
|
13
15
|
</div>
|
14
16
|
);
|
15
17
|
|
@@ -1,33 +1,70 @@
|
|
1
1
|
import React, { Component } from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { Grid, Row, Col } from 'patternfly-react';
|
4
|
+
import BreadcrumbsBar from 'foremanReact/components/BreadcrumbBar';
|
4
5
|
import SubscriptionDetailInfo from './SubscriptionDetailInfo';
|
5
6
|
import SubscriptionDetailAssociations from './SubscriptionDetailAssociations';
|
6
7
|
import SubscriptionDetailProducts from './SubscriptionDetailProducts';
|
7
8
|
import { LoadingState } from '../../../move_to_pf/LoadingState';
|
8
9
|
import { notify } from '../../../move_to_foreman/foreman_toast_notifications';
|
10
|
+
import api from '../../../services/api';
|
9
11
|
|
10
12
|
class SubscriptionDetails extends Component {
|
13
|
+
constructor() {
|
14
|
+
super();
|
15
|
+
this.handleBreadcrumbSwitcherItem = this.handleBreadcrumbSwitcherItem.bind(this);
|
16
|
+
}
|
11
17
|
componentDidMount() {
|
12
18
|
// eslint-disable-next-line react/prop-types
|
13
19
|
const routerParams = this.props.match.params;
|
14
20
|
this.props.loadSubscriptionDetails(parseInt(routerParams.id, 10));
|
15
21
|
}
|
16
22
|
|
23
|
+
componentDidUpdate(prevProps) {
|
24
|
+
const routerParams = this.props.match.params;
|
25
|
+
if (routerParams.id !== prevProps.match.params.id) {
|
26
|
+
this.props.loadSubscriptionDetails(parseInt(routerParams.id, 10));
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
handleBreadcrumbSwitcherItem(e, url) {
|
31
|
+
this.props.history.push(url);
|
32
|
+
e.preventDefault();
|
33
|
+
}
|
34
|
+
|
17
35
|
render() {
|
18
36
|
const { subscriptionDetails } = this.props;
|
37
|
+
const resource = {
|
38
|
+
nameField: 'name',
|
39
|
+
resourceUrl: api.getApiUrl('/subscriptions'),
|
40
|
+
switcherItemUrl: '/subscriptions/:id',
|
41
|
+
};
|
19
42
|
|
20
|
-
if (subscriptionDetails.error) {
|
43
|
+
if (subscriptionDetails.error) {
|
44
|
+
notify({ message: subscriptionDetails.error });
|
45
|
+
}
|
21
46
|
|
22
47
|
return (
|
23
48
|
<Grid bsClass="container-fluid">
|
49
|
+
{!subscriptionDetails.loading && <BreadcrumbsBar
|
50
|
+
onSwitcherItemClick={(e, url) => this.handleBreadcrumbSwitcherItem(e, url)}
|
51
|
+
data={{
|
52
|
+
isSwitchable: true,
|
53
|
+
breadcrumbItems: [
|
54
|
+
{
|
55
|
+
caption: __('Subscriptions'),
|
56
|
+
onClick: () =>
|
57
|
+
this.props.history.push('/subscriptions'),
|
58
|
+
},
|
59
|
+
{
|
60
|
+
caption: String(subscriptionDetails.name),
|
61
|
+
},
|
62
|
+
],
|
63
|
+
resource,
|
64
|
+
}}
|
65
|
+
/>}
|
24
66
|
<div>
|
25
67
|
<LoadingState loading={subscriptionDetails.loading} loadingText={__('Loading')}>
|
26
|
-
<Row>
|
27
|
-
<Col sm={12}>
|
28
|
-
<h1>{subscriptionDetails.name}</h1>
|
29
|
-
</Col>
|
30
|
-
</Row>
|
31
68
|
<Row>
|
32
69
|
<Col sm={6}>
|
33
70
|
<SubscriptionDetailInfo
|
@@ -53,6 +90,7 @@ class SubscriptionDetails extends Component {
|
|
53
90
|
SubscriptionDetails.propTypes = {
|
54
91
|
loadSubscriptionDetails: PropTypes.func.isRequired,
|
55
92
|
subscriptionDetails: PropTypes.shape({}).isRequired,
|
93
|
+
history: PropTypes.shape({ push: PropTypes.func.isRequired }).isRequired,
|
56
94
|
};
|
57
95
|
|
58
96
|
export default SubscriptionDetails;
|
@@ -13,13 +13,14 @@ jest.mock('../../../../move_to_foreman/foreman_toast_notifications');
|
|
13
13
|
describe('subscriptions details page', () => {
|
14
14
|
it('should render and contain appropiate components', async () => {
|
15
15
|
const match = { params: { id: 1 } };
|
16
|
+
const noop = () => {};
|
16
17
|
|
17
18
|
const wrapper = shallow(<SubscriptionDetails
|
18
19
|
loadSubscriptionDetails={loadSubscriptionDetails}
|
19
20
|
subscriptionDetails={successState}
|
21
|
+
history={{ push: noop }}
|
20
22
|
match={match}
|
21
23
|
/>);
|
22
|
-
expect(wrapper.find('h1').text()).toEqual(successState.name);
|
23
24
|
expect(wrapper.find(SubscriptionDetailAssociations)).toHaveLength(1);
|
24
25
|
expect(wrapper.find(SubscriptionDetailInfo)).toHaveLength(1);
|
25
26
|
expect(wrapper.find(SubscriptionDetailProducts)).toHaveLength(1);
|