katello 3.7.0.rc1 → 3.7.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/controllers/katello/api/v2/content_views_controller.rb +5 -2
- data/app/controllers/katello/api/v2/environments_controller.rb +8 -3
- data/app/controllers/katello/api/v2/host_tracer_controller.rb +1 -1
- data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +4 -4
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +5 -22
- data/app/lib/actions/katello/host/update_content_overrides.rb +1 -0
- data/app/lib/actions/katello/product/content_create.rb +1 -0
- data/app/lib/actions/katello/product/repositories_certs_reset.rb +25 -0
- data/app/lib/actions/katello/product/update.rb +6 -0
- data/app/lib/katello/resources/candlepin/activation_key.rb +8 -4
- data/app/lib/katello/resources/candlepin/product.rb +2 -1
- data/app/lib/katello/util/cdn_var_substitutor.rb +5 -3
- data/app/lib/katello/util/package.rb +21 -13
- data/app/lib/katello/util/package_filter.rb +33 -31
- data/app/lib/katello/validators/prior_validator.rb +6 -10
- data/app/models/katello/concerns/host_managed_extensions.rb +2 -0
- data/app/models/katello/concerns/organization_extensions.rb +1 -0
- data/app/models/katello/concerns/subscription_facet_host_extensions.rb +10 -6
- data/app/models/katello/content.rb +23 -2
- data/app/models/katello/content_view_docker_filter.rb +1 -1
- data/app/models/katello/content_view_puppet_module.rb +3 -3
- data/app/models/katello/content_view_version.rb +4 -0
- data/app/models/katello/environment_prior.rb +7 -0
- data/app/models/katello/glue/candlepin/candlepin_object.rb +2 -2
- data/app/models/katello/glue/candlepin/pool.rb +10 -13
- data/app/models/katello/glue/candlepin/product.rb +19 -9
- data/app/models/katello/glue/candlepin/repository.rb +16 -0
- data/app/models/katello/glue/candlepin/subscription.rb +1 -1
- data/app/models/katello/glue/provider.rb +15 -81
- data/app/models/katello/host/subscription_facet.rb +1 -1
- data/app/models/katello/kt_environment.rb +39 -8
- data/app/models/katello/pool.rb +2 -1
- data/app/models/katello/rpm.rb +144 -2
- data/app/models/katello/upstream_pool.rb +7 -10
- data/app/services/katello/candlepin/pool_service.rb +18 -3
- data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +13 -16
- data/app/views/dashboard/_content_views_widget.html.erb +3 -3
- data/app/views/dashboard/_errata_widget.html.erb +2 -2
- data/app/views/dashboard/_host_collection_widget.html.erb +3 -3
- data/app/views/dashboard/_subscription_status_widget.html.erb +2 -2
- data/app/views/dashboard/_subscription_widget.html.erb +1 -1
- data/app/views/dashboard/_sync_widget.html.erb +3 -3
- data/app/views/katello/api/v2/subscriptions/base.json.rabl +1 -1
- data/app/views/katello/api/v2/upstream_subscriptions/base.json.rabl +2 -6
- data/app/views/katello/layouts/react.html.erb +3 -3
- data/config/katello.yaml +89 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20160302091113_change_environment_prior.rb +9 -0
- data/db/migrate/20180410140909_add_organization_id_to_pool.rb +2 -1
- data/db/migrate/20180612163403_add_foreign_key_to_hypervisor_id.rb +10 -0
- data/db/migrate/20180612164926_add_content_org_id.rb +39 -0
- data/db/migrate/20180612165011_remove_content_fields_from_host.rb +7 -0
- data/db/migrate/20180626160422_add_upstream_pool_id_to_katello_pool.rb +9 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment-content.controller.js +2 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment.html +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.controller.js +19 -14
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/new-environment.controller.js +18 -5
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/paths.service.js +51 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/views/new-environment.html +16 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/products-bulk-advanced-sync-modal.controller.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +2 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscriptions.routes.js +3 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/tasks.module.js +1 -6
- data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +4 -0
- data/engines/bastion_katello/lib/bastion_katello/engine.rb +1 -1
- data/lib/katello/plugin.rb +2 -11
- data/lib/katello/scheduled_jobs.rb +2 -14
- data/lib/katello/tasks/clean_backend_objects.rake +2 -0
- data/lib/katello/tasks/repository.rake +11 -2
- data/lib/katello/tasks/upgrades/3.7/import_pools.rake +12 -0
- data/lib/katello/version.rb +1 -1
- data/package.json +4 -3
- data/webpack/components/PaginationRow/index.js +6 -2
- data/webpack/containers/Application/config.js +7 -2
- data/webpack/index.js +3 -5
- data/webpack/move_to_foreman/common/helpers.js +5 -24
- data/webpack/move_to_foreman/components/common/emptyState/index.js +12 -7
- data/webpack/move_to_foreman/components/common/table/components/CollapseSubscriptionGroupButton.js +31 -0
- data/webpack/move_to_foreman/components/common/table/components/CollapseSubscriptionGroupButton.test.js +16 -0
- data/webpack/move_to_foreman/components/common/table/components/Table.js +76 -0
- data/webpack/move_to_foreman/components/common/table/components/Table.test.js +31 -0
- data/webpack/move_to_foreman/components/common/table/components/TableBody.js +27 -0
- data/webpack/move_to_foreman/components/common/table/components/TableBody.test.js +18 -0
- data/webpack/move_to_foreman/components/common/table/components/TableBodyMessage.js +18 -0
- data/webpack/move_to_foreman/components/common/table/components/TableBodyMessage.test.js +12 -0
- data/webpack/move_to_foreman/components/common/table/components/TableFixtures.js +14 -0
- data/webpack/move_to_foreman/components/common/table/components/TableSelectionCell.js +39 -0
- data/webpack/move_to_foreman/components/common/table/components/TableSelectionCell.test.js +16 -0
- data/webpack/move_to_foreman/components/common/table/components/TableSelectionHeaderCell.js +34 -0
- data/webpack/move_to_foreman/components/common/table/components/TableSelectionHeaderCell.test.js +14 -0
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/CollapseSubscriptionGroupButton.test.js.snap +19 -0
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/Table.test.js.snap +167 -0
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableBody.test.js.snap +28 -0
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableBodyMessage.test.js.snap +13 -0
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionCell.test.js.snap +16 -0
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionHeaderCell.test.js.snap +15 -0
- data/webpack/move_to_foreman/components/common/table/components/index.js +6 -0
- data/webpack/move_to_foreman/components/common/table/formatters/cellFormatter.js +4 -0
- data/webpack/move_to_foreman/components/common/table/formatters/collapseableAndSelectionCellFormatter.js +18 -0
- data/webpack/move_to_foreman/components/common/table/formatters/ellipsisCellFormatter.js +5 -0
- data/webpack/move_to_foreman/components/common/table/formatters/headerFormatter.js +4 -0
- data/webpack/move_to_foreman/components/common/table/formatters/index.js +6 -0
- data/webpack/move_to_foreman/components/common/table/formatters/selectionCellFormatter.js +17 -0
- data/webpack/move_to_foreman/components/common/table/formatters/selectionHeaderCellFormatter.js +10 -0
- data/webpack/move_to_foreman/components/common/table/index.js +2 -88
- data/webpack/move_to_pf/LoadingState/LoadingState.js +35 -0
- data/webpack/move_to_pf/LoadingState/LoadingState.scss +12 -0
- data/webpack/move_to_pf/LoadingState/LoadingState.test.js +28 -0
- data/webpack/move_to_pf/LoadingState/__snapshots__/LoadingState.test.js.snap +20 -0
- data/webpack/move_to_pf/LoadingState/index.js +3 -0
- data/webpack/move_to_pf/test-utils/testHelpers.js +71 -0
- data/webpack/redux/actions/RedHatRepositories/enabled.js +1 -1
- data/webpack/redux/actions/RedHatRepositories/helpers.js +34 -9
- data/webpack/redux/actions/RedHatRepositories/sets.js +28 -6
- data/webpack/redux/consts.js +1 -0
- data/webpack/redux/reducers/RedHatRepositories/sets.fixtures.js +12 -2
- data/webpack/redux/reducers/RedHatRepositories/sets.js +34 -27
- data/webpack/redux/reducers/RedHatRepositories/sets.test.js +10 -2
- data/webpack/redux/reducers/index.js +2 -0
- data/webpack/scenes/Organizations/OrganizationActions.js +3 -3
- data/webpack/scenes/RedHatRepositories/components/RecommendedRepositorySetsToggler.js +44 -0
- data/webpack/scenes/RedHatRepositories/components/RecommendedRepositorySetsToggler.scss +16 -0
- data/webpack/scenes/RedHatRepositories/components/RepositorySet.js +8 -2
- data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositories.js +5 -3
- data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +4 -2
- data/webpack/scenes/RedHatRepositories/components/Search.js +1 -1
- data/webpack/scenes/RedHatRepositories/components/SearchBar.js +1 -1
- data/webpack/scenes/RedHatRepositories/components/__tests__/RecommendedRepositorySetsToggler.test.js +17 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RecommendedRepositorySetsToggler.test.js.snap +37 -0
- data/webpack/scenes/RedHatRepositories/helpers.js +1 -1
- data/webpack/scenes/RedHatRepositories/index.js +17 -7
- data/webpack/scenes/RedHatRepositories/index.scss +16 -4
- data/webpack/scenes/Subscriptions/Details/SubscriptionAttributes.js +17 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +28 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailAssociations.js +47 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailConstants.js +3 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailInfo.js +65 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +20 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +37 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +58 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailActions.test.js +47 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailAssociations.test.js +16 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailInfo.test.js +15 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailProducts.test.js +16 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailReducer.test.js +39 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +28 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailAssociations.test.js.snap +53 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailInfo.test.js.snap +185 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailProducts.test.js.snap +77 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +432 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +167 -0
- data/webpack/scenes/Subscriptions/Details/index.js +19 -0
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +58 -12
- data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +6 -1
- data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +4 -4
- data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryTableSchema.js +7 -7
- data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +6 -9
- data/webpack/scenes/Subscriptions/Manifest/index.js +2 -2
- data/webpack/scenes/Subscriptions/SubscriptionActions.js +5 -6
- data/webpack/scenes/Subscriptions/SubscriptionReducer.js +2 -3
- data/webpack/scenes/Subscriptions/SubscriptionValidations.js +1 -1
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +46 -30
- data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +38 -0
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +3 -3
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +7 -6
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +17 -14
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +12 -15
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js +4 -4
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionValidations.test.js +5 -0
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +2 -2
- data/webpack/scenes/Subscriptions/{EntitlementsInlineEditFormatter.js → components/SubscriptionsTable/EntitlementsInlineEditFormatter.js} +7 -7
- data/webpack/scenes/Subscriptions/{SubscriptionsTable.js → components/SubscriptionsTable/SubscriptionsTable.js} +75 -47
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +60 -0
- data/webpack/scenes/Subscriptions/{SubscriptionsTableSchema.js → components/SubscriptionsTable/SubscriptionsTableSchema.js} +37 -26
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +56 -0
- data/webpack/scenes/Subscriptions/{__tests__ → components/SubscriptionsTable/__tests__}/__snapshots__/SubscriptionsTable.test.js.snap +16 -5
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/index.js +2 -0
- data/webpack/scenes/Subscriptions/index.js +2 -2
- data/webpack/scenes/Tasks/TaskActions.js +18 -11
- data/webpack/scenes/Tasks/__tests__/TaskActions.test.js +92 -9
- data/webpack/scenes/Tasks/__tests__/task.fixtures.js +19 -9
- data/webpack/services/api/index.js +2 -2
- data/webpack/test_setup.js +1 -0
- metadata +79 -10
- data/webpack/scenes/Subscriptions/Subscriptions.scss +0 -14
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsTable.test.js +0 -47
@@ -0,0 +1,19 @@
|
|
1
|
+
import { bindActionCreators } from 'redux';
|
2
|
+
import { connect } from 'react-redux';
|
3
|
+
|
4
|
+
import reducer from './SubscriptionDetailReducer';
|
5
|
+
import * as subscriptionDetailActions from './SubscriptionDetailActions';
|
6
|
+
import SubscriptionDetails from './SubscriptionDetails';
|
7
|
+
|
8
|
+
// map state to props
|
9
|
+
const mapStateToProps = state => ({
|
10
|
+
subscriptionDetails: state.katello.subscriptionDetails,
|
11
|
+
});
|
12
|
+
|
13
|
+
// map action dispatchers to props
|
14
|
+
const mapDispatchToProps = dispatch => bindActionCreators(subscriptionDetailActions, dispatch);
|
15
|
+
|
16
|
+
export const subscriptionDetails = reducer;
|
17
|
+
|
18
|
+
// export connected component
|
19
|
+
export default connect(mapStateToProps, mapDispatchToProps)(SubscriptionDetails);
|
@@ -2,11 +2,17 @@ import React, { Component } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { Col, Tabs, Tab, Form, FormGroup, FormControl, ControlLabel } from 'react-bootstrap';
|
4
4
|
import { bindMethods, Button, Icon, Modal, Spinner, OverlayTrigger, Tooltip } from 'patternfly-react';
|
5
|
+
import { isEqual } from 'lodash';
|
5
6
|
import TooltipButton from 'react-bootstrap-tooltip-button';
|
7
|
+
import { LoadingState } from '../../../move_to_pf/LoadingState';
|
6
8
|
import { Table } from '../../../move_to_foreman/components/common/table';
|
7
9
|
import { columns } from './ManifestHistoryTableSchema';
|
8
10
|
import ConfirmDialog from '../../../move_to_foreman/components/common/ConfirmDialog';
|
9
11
|
import DeleteManifestModalText from './DeleteManifestModalText';
|
12
|
+
import {
|
13
|
+
BLOCKING_FOREMAN_TASK_TYPES,
|
14
|
+
MANIFEST_TASKS_BULK_SEARCH_ID,
|
15
|
+
} from '../SubscriptionConstants';
|
10
16
|
|
11
17
|
class ManageManifestModal extends Component {
|
12
18
|
constructor(props) {
|
@@ -24,6 +30,8 @@ class ManageManifestModal extends Component {
|
|
24
30
|
'uploadManifest',
|
25
31
|
'refreshManifest',
|
26
32
|
'deleteManifest',
|
33
|
+
'manifestExists',
|
34
|
+
'disabledTooltipText',
|
27
35
|
]);
|
28
36
|
}
|
29
37
|
|
@@ -31,9 +39,25 @@ class ManageManifestModal extends Component {
|
|
31
39
|
this.loadData();
|
32
40
|
}
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
42
|
+
static getDerivedStateFromProps(newProps, prevState) {
|
43
|
+
if (
|
44
|
+
!isEqual(newProps.showModal, prevState.showModal) ||
|
45
|
+
!isEqual(newProps.taskInProgress, prevState.actionInProgress)
|
46
|
+
) {
|
47
|
+
return {
|
48
|
+
showModal: newProps.showModal,
|
49
|
+
actionInProgress: newProps.taskInProgress,
|
50
|
+
};
|
51
|
+
}
|
52
|
+
return null;
|
53
|
+
}
|
54
|
+
|
55
|
+
componentDidUpdate(prevProp, prevState) {
|
56
|
+
const { actionInProgress } = this.state;
|
57
|
+
|
58
|
+
if (prevState.actionInProgress && !actionInProgress) {
|
59
|
+
this.props.loadOrganization();
|
60
|
+
}
|
37
61
|
}
|
38
62
|
|
39
63
|
loadData() {
|
@@ -50,10 +74,10 @@ class ManageManifestModal extends Component {
|
|
50
74
|
}
|
51
75
|
|
52
76
|
uploadManifest(fileList) {
|
77
|
+
this.setState({ actionInProgress: true });
|
53
78
|
if (fileList.length > 0) {
|
54
|
-
this.props.uploadManifest(fileList[0])
|
79
|
+
this.props.uploadManifest(fileList[0]);
|
55
80
|
}
|
56
|
-
this.setState({ actionInProgress: true });
|
57
81
|
}
|
58
82
|
|
59
83
|
refreshManifest() {
|
@@ -62,8 +86,15 @@ class ManageManifestModal extends Component {
|
|
62
86
|
}
|
63
87
|
|
64
88
|
deleteManifest() {
|
65
|
-
this.props.deleteManifest().then(this.props.loadOrganization);
|
66
89
|
this.setState({ actionInProgress: true });
|
90
|
+
this.props.deleteManifest()
|
91
|
+
.then(() =>
|
92
|
+
this.props.bulkSearch({
|
93
|
+
search_id: MANIFEST_TASKS_BULK_SEARCH_ID,
|
94
|
+
type: 'all',
|
95
|
+
active_only: true,
|
96
|
+
action_types: BLOCKING_FOREMAN_TASK_TYPES,
|
97
|
+
}));
|
67
98
|
this.showDeleteManifestModal(false);
|
68
99
|
}
|
69
100
|
|
@@ -73,6 +104,19 @@ class ManageManifestModal extends Component {
|
|
73
104
|
});
|
74
105
|
}
|
75
106
|
|
107
|
+
disabledTooltipText() {
|
108
|
+
if (this.state.actionInProgress) {
|
109
|
+
return __('This is disabled because a manifest task is in progress');
|
110
|
+
}
|
111
|
+
return __('This is disabled because no manifest exists');
|
112
|
+
}
|
113
|
+
|
114
|
+
manifestExists() {
|
115
|
+
const { organization } = this.props;
|
116
|
+
|
117
|
+
return organization.owner_details && organization.owner_details.upstreamConsumer;
|
118
|
+
}
|
119
|
+
|
76
120
|
render() {
|
77
121
|
const {
|
78
122
|
manifestHistory, organization, disableManifestActions, disabledReason,
|
@@ -126,7 +170,7 @@ class ManageManifestModal extends Component {
|
|
126
170
|
<FormControl
|
127
171
|
id="cdnUrl"
|
128
172
|
type="text"
|
129
|
-
value={organization.redhat_repository_url}
|
173
|
+
value={organization.redhat_repository_url || ''}
|
130
174
|
onChange={this.saveOrganization}
|
131
175
|
/>
|
132
176
|
</Col>
|
@@ -169,16 +213,17 @@ class ManageManifestModal extends Component {
|
|
169
213
|
tooltipText={disabledReason}
|
170
214
|
tooltipPlacement="top"
|
171
215
|
title={__('Refresh')}
|
172
|
-
disabled={
|
216
|
+
disabled={!this.manifestExists() ||
|
217
|
+
actionInProgress || disableManifestActions}
|
173
218
|
/>
|
174
219
|
|
175
220
|
<TooltipButton
|
176
221
|
onClick={() => this.showDeleteManifestModal(true)}
|
177
222
|
tooltipId="delete-manifest-button-tooltip"
|
178
|
-
tooltipText={
|
223
|
+
tooltipText={this.disabledTooltipText()}
|
179
224
|
tooltipPlacement="top"
|
180
225
|
title={__('Delete')}
|
181
|
-
disabled={actionInProgress}
|
226
|
+
disabled={!this.manifestExists() || actionInProgress}
|
182
227
|
/>
|
183
228
|
|
184
229
|
<ConfirmDialog
|
@@ -198,13 +243,13 @@ class ManageManifestModal extends Component {
|
|
198
243
|
</Tab>
|
199
244
|
|
200
245
|
<Tab eventKey={2} title={__('Manifest History')}>
|
201
|
-
<
|
246
|
+
<LoadingState loading={manifestHistory.loading} loadingText={__('Loading')}>
|
202
247
|
<Table
|
203
248
|
rows={manifestHistory.results}
|
204
249
|
columns={columns}
|
205
250
|
emptyState={emptyStateData()}
|
206
251
|
/>
|
207
|
-
</
|
252
|
+
</LoadingState>
|
208
253
|
</Tab>
|
209
254
|
</Tabs>
|
210
255
|
</Modal.Body>
|
@@ -232,6 +277,7 @@ ManageManifestModal.propTypes = {
|
|
232
277
|
manifestHistory: PropTypes.shape({}).isRequired,
|
233
278
|
showModal: PropTypes.bool.isRequired,
|
234
279
|
onClose: PropTypes.func,
|
280
|
+
bulkSearch: PropTypes.func.isRequired,
|
235
281
|
};
|
236
282
|
|
237
283
|
ManageManifestModal.defaultProps = {
|
@@ -27,7 +27,7 @@ export const uploadManifest = file => (dispatch) => {
|
|
27
27
|
};
|
28
28
|
|
29
29
|
return api
|
30
|
-
.post(`/organizations/${orgId}/subscriptions/upload`, formData, config)
|
30
|
+
.post(`/organizations/${orgId()}/subscriptions/upload`, formData, config)
|
31
31
|
.then(({ data }) => {
|
32
32
|
dispatch({
|
33
33
|
type: UPLOAD_MANIFEST_SUCCESS,
|
@@ -50,7 +50,7 @@ export const refreshManifest = (extendedParams = {}) => (dispatch) => {
|
|
50
50
|
};
|
51
51
|
|
52
52
|
return api
|
53
|
-
.put(`/organizations/${orgId}/subscriptions/refresh_manifest`, {}, params)
|
53
|
+
.put(`/organizations/${orgId()}/subscriptions/refresh_manifest`, {}, params)
|
54
54
|
.then(({ data }) => {
|
55
55
|
dispatch({
|
56
56
|
type: REFRESH_MANIFEST_SUCCESS,
|
@@ -73,7 +73,7 @@ export const deleteManifest = (extendedParams = {}) => (dispatch) => {
|
|
73
73
|
};
|
74
74
|
|
75
75
|
return api
|
76
|
-
.post(`/organizations/${orgId}/subscriptions/delete_manifest`, {}, params)
|
76
|
+
.post(`/organizations/${orgId()}/subscriptions/delete_manifest`, {}, params)
|
77
77
|
.then(({ data }) => {
|
78
78
|
dispatch({
|
79
79
|
type: DELETE_MANIFEST_SUCCESS,
|
@@ -96,7 +96,7 @@ export const loadManifestHistory = (extendedParams = {}) => (dispatch) => {
|
|
96
96
|
};
|
97
97
|
|
98
98
|
return api
|
99
|
-
.get(`/organizations/${orgId}/subscriptions/manifest_history`, {}, params)
|
99
|
+
.get(`/organizations/${orgId()}/subscriptions/manifest_history`, {}, params)
|
100
100
|
.then(({ data }) => {
|
101
101
|
dispatch({
|
102
102
|
type: MANIFEST_HISTORY_SUCCESS,
|
@@ -1,30 +1,30 @@
|
|
1
|
-
import {
|
1
|
+
import { headerFormatter, cellFormatter } from '../../../move_to_foreman/components/common/table';
|
2
2
|
|
3
3
|
export const columns = [
|
4
4
|
{
|
5
5
|
property: 'status',
|
6
6
|
header: {
|
7
7
|
label: __('Status'),
|
8
|
-
formatters: [
|
8
|
+
formatters: [headerFormatter],
|
9
9
|
props: {
|
10
10
|
index: 0,
|
11
11
|
},
|
12
12
|
},
|
13
13
|
cell: {
|
14
|
-
formatters: [
|
14
|
+
formatters: [cellFormatter],
|
15
15
|
},
|
16
16
|
},
|
17
17
|
{
|
18
18
|
property: 'statusMessage',
|
19
19
|
header: {
|
20
20
|
label: __('Message'),
|
21
|
-
formatters: [
|
21
|
+
formatters: [headerFormatter],
|
22
22
|
props: {
|
23
23
|
index: 1,
|
24
24
|
},
|
25
25
|
},
|
26
26
|
cell: {
|
27
|
-
formatters: [
|
27
|
+
formatters: [cellFormatter],
|
28
28
|
},
|
29
29
|
},
|
30
30
|
// TODO: use date formatter from tomas' PR
|
@@ -32,13 +32,13 @@ export const columns = [
|
|
32
32
|
property: 'created',
|
33
33
|
header: {
|
34
34
|
label: __('Timestamp'),
|
35
|
-
formatters: [
|
35
|
+
formatters: [headerFormatter],
|
36
36
|
props: {
|
37
37
|
index: 2,
|
38
38
|
},
|
39
39
|
},
|
40
40
|
cell: {
|
41
|
-
formatters: [
|
41
|
+
formatters: [cellFormatter],
|
42
42
|
},
|
43
43
|
},
|
44
44
|
];
|
data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap
CHANGED
@@ -159,7 +159,7 @@ exports[`manage manifest modal should render 1`] = `
|
|
159
159
|
type="file"
|
160
160
|
/>
|
161
161
|
<TooltipButton
|
162
|
-
disabled={
|
162
|
+
disabled={true}
|
163
163
|
onClick={[Function]}
|
164
164
|
title="Refresh"
|
165
165
|
tooltipId="refresh-manifest-button-tooltip"
|
@@ -167,12 +167,12 @@ exports[`manage manifest modal should render 1`] = `
|
|
167
167
|
tooltipText=""
|
168
168
|
/>
|
169
169
|
<TooltipButton
|
170
|
-
disabled={
|
170
|
+
disabled={true}
|
171
171
|
onClick={[Function]}
|
172
172
|
title="Delete"
|
173
173
|
tooltipId="delete-manifest-button-tooltip"
|
174
174
|
tooltipPlacement="top"
|
175
|
-
tooltipText="This is disabled because
|
175
|
+
tooltipText="This is disabled because no manifest exists"
|
176
176
|
/>
|
177
177
|
<ConfirmDialog
|
178
178
|
active={false}
|
@@ -212,12 +212,9 @@ exports[`manage manifest modal should render 1`] = `
|
|
212
212
|
eventKey={2}
|
213
213
|
title="Manifest History"
|
214
214
|
>
|
215
|
-
<
|
216
|
-
className="small-spacer"
|
217
|
-
inline={false}
|
218
|
-
inverse={false}
|
215
|
+
<LoadingState
|
219
216
|
loading={false}
|
220
|
-
|
217
|
+
loadingText="Loading"
|
221
218
|
>
|
222
219
|
<Table
|
223
220
|
columns={
|
@@ -340,7 +337,7 @@ exports[`manage manifest modal should render 1`] = `
|
|
340
337
|
]
|
341
338
|
}
|
342
339
|
/>
|
343
|
-
</
|
340
|
+
</LoadingState>
|
344
341
|
</Tab>
|
345
342
|
</Uncontrolled(Tabs)>
|
346
343
|
</ModalBody>
|
@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
|
|
4
4
|
|
5
5
|
import * as manifestActions from './ManifestActions';
|
6
6
|
import * as organizationActions from '../../Organizations/OrganizationActions';
|
7
|
-
|
7
|
+
import * as tasksActions from '../../Tasks/TaskActions';
|
8
8
|
import history from './ManifestHistoryReducer';
|
9
9
|
|
10
10
|
import ManifestModal from './ManageManifestModal';
|
@@ -18,7 +18,7 @@ const mapStateToProps = state => ({
|
|
18
18
|
});
|
19
19
|
|
20
20
|
// map action dispatchers to props
|
21
|
-
const actions = { ...manifestActions, ...organizationActions };
|
21
|
+
const actions = { ...manifestActions, ...organizationActions, ...tasksActions };
|
22
22
|
const mapDispatchToProps = dispatch => bindActionCreators(actions, dispatch);
|
23
23
|
|
24
24
|
// export reducers
|
@@ -16,11 +16,10 @@ import {
|
|
16
16
|
DELETE_SUBSCRIPTIONS_FAILURE,
|
17
17
|
} from './SubscriptionConstants';
|
18
18
|
import { filterRHSubscriptions } from './SubscriptionHelpers.js';
|
19
|
-
|
20
|
-
const getResponseError = ({ data }) => data && (data.displayMessage || data.error);
|
19
|
+
import { getResponseError } from '../../move_to_foreman/common/helpers.js';
|
21
20
|
|
22
21
|
export const createSubscriptionParams = (extendedParams = {}) => ({
|
23
|
-
...{ organization_id: orgId },
|
22
|
+
...{ organization_id: orgId() },
|
24
23
|
...propsToSnakeCase(extendedParams),
|
25
24
|
});
|
26
25
|
|
@@ -29,7 +28,7 @@ export const loadAvailableQuantities = (extendedParams = {}) => (dispatch) => {
|
|
29
28
|
|
30
29
|
const params = createSubscriptionParams(extendedParams);
|
31
30
|
return api
|
32
|
-
.get(`/organizations/${orgId}/upstream_subscriptions`, {}, params)
|
31
|
+
.get(`/organizations/${orgId()}/upstream_subscriptions`, {}, params)
|
33
32
|
.then(({ data }) => {
|
34
33
|
dispatch({
|
35
34
|
type: SUBSCRIPTIONS_QUANTITIES_SUCCESS,
|
@@ -77,7 +76,7 @@ export const updateQuantity = (quantities = {}) => (dispatch) => {
|
|
77
76
|
};
|
78
77
|
|
79
78
|
return api
|
80
|
-
.put(`/organizations/${orgId}/upstream_subscriptions`, params)
|
79
|
+
.put(`/organizations/${orgId()}/upstream_subscriptions`, params)
|
81
80
|
.then(({ data }) => {
|
82
81
|
dispatch({
|
83
82
|
type: UPDATE_QUANTITY_SUCCESS,
|
@@ -100,7 +99,7 @@ export const deleteSubscriptions = poolIds => (dispatch) => {
|
|
100
99
|
};
|
101
100
|
|
102
101
|
return api
|
103
|
-
.delete(`/organizations/${orgId}/upstream_subscriptions`, {}, params)
|
102
|
+
.delete(`/organizations/${(orgId())}/upstream_subscriptions`, {}, params)
|
104
103
|
.then(({ data }) => {
|
105
104
|
dispatch({
|
106
105
|
type: DELETE_SUBSCRIPTIONS_SUCCESS,
|
@@ -97,15 +97,14 @@ export default (state = initialState, action) => {
|
|
97
97
|
}
|
98
98
|
|
99
99
|
case TASK_BULK_SEARCH_SUCCESS: {
|
100
|
-
let tasks
|
100
|
+
let tasks;
|
101
101
|
|
102
102
|
const search = find(action.response, bulkSearch =>
|
103
103
|
bulkSearch.search_params.search_id === MANIFEST_TASKS_BULK_SEARCH_ID);
|
104
104
|
|
105
|
-
if (search) {
|
105
|
+
if (search && search.results.length > 0) {
|
106
106
|
tasks = search.results;
|
107
107
|
}
|
108
|
-
|
109
108
|
return state.set('tasks', tasks);
|
110
109
|
}
|
111
110
|
|
@@ -8,7 +8,7 @@ export const validateQuantity = (quantity, availableQuantity) => {
|
|
8
8
|
if (Number.isNaN(numberValue)) {
|
9
9
|
state = 'error';
|
10
10
|
message = __('Not a number');
|
11
|
-
} else if (numberValue
|
11
|
+
} else if (numberValue <= 0) {
|
12
12
|
state = 'error';
|
13
13
|
message = __('Has to be > 0');
|
14
14
|
} else if (availableQuantity && availableQuantity >= 0 && numberValue > availableQuantity) {
|
@@ -9,7 +9,7 @@ import { notify } from '../../move_to_foreman/foreman_toast_notifications';
|
|
9
9
|
import helpers from '../../move_to_foreman/common/helpers';
|
10
10
|
import ModalProgressBar from '../../move_to_foreman/components/common/ModalProgressBar';
|
11
11
|
import ManageManifestModal from './Manifest/';
|
12
|
-
import SubscriptionsTable from './SubscriptionsTable';
|
12
|
+
import { SubscriptionsTable } from './components/SubscriptionsTable';
|
13
13
|
import Search from '../../components/Search/index';
|
14
14
|
import api, { orgId } from '../../services/api';
|
15
15
|
import { createSubscriptionParams } from './SubscriptionActions.js';
|
@@ -19,6 +19,7 @@ import {
|
|
19
19
|
BULK_TASK_SEARCH_INTERVAL,
|
20
20
|
} from './SubscriptionConstants';
|
21
21
|
|
22
|
+
import './SubscriptionsPage.scss';
|
22
23
|
|
23
24
|
class SubscriptionsPage extends Component {
|
24
25
|
constructor(props) {
|
@@ -27,7 +28,6 @@ class SubscriptionsPage extends Component {
|
|
27
28
|
manifestModalOpen: false,
|
28
29
|
subscriptionDeleteModalOpen: false,
|
29
30
|
disableDeleteButton: true,
|
30
|
-
polledTask: null,
|
31
31
|
showTaskModal: false,
|
32
32
|
searchQuery: '',
|
33
33
|
};
|
@@ -37,6 +37,35 @@ class SubscriptionsPage extends Component {
|
|
37
37
|
this.loadData();
|
38
38
|
}
|
39
39
|
|
40
|
+
static getDerivedStateFromProps(nextProps, prevState) {
|
41
|
+
const nextTaskId = nextProps.tasks[0] && nextProps.tasks[0].id;
|
42
|
+
|
43
|
+
if (nextProps.tasks.length === 0 && prevState.polledTask != null) {
|
44
|
+
return { showTaskModal: false, polledTask: undefined };
|
45
|
+
} else if (nextProps.tasks.length > 0 && nextTaskId !== prevState.polledTask) {
|
46
|
+
return {
|
47
|
+
showTaskModal: true,
|
48
|
+
manifestModalOpen: false,
|
49
|
+
polledTask: nextProps.tasks[0].id,
|
50
|
+
};
|
51
|
+
}
|
52
|
+
return null;
|
53
|
+
}
|
54
|
+
|
55
|
+
componentDidUpdate(prevProps) {
|
56
|
+
const { tasks } = this.props;
|
57
|
+
const numberOfTasks = tasks.length;
|
58
|
+
const numberOfPrevTasks = prevProps.tasks.length;
|
59
|
+
let task;
|
60
|
+
|
61
|
+
if (numberOfTasks > 0) {
|
62
|
+
if (numberOfPrevTasks === 0 || prevProps.tasks[0].id !== tasks[0].id) {
|
63
|
+
[task] = this.props.tasks;
|
64
|
+
this.handleDoneTask(task);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
40
69
|
getDisabledReason(deleteButton) {
|
41
70
|
const { tasks, subscriptions } = this.props;
|
42
71
|
const { disconnected } = subscriptions;
|
@@ -53,16 +82,6 @@ class SubscriptionsPage extends Component {
|
|
53
82
|
return disabledReason;
|
54
83
|
}
|
55
84
|
|
56
|
-
showTaskModal(show) {
|
57
|
-
if (this.state.showTaskModal !== show) {
|
58
|
-
this.setState({ showTaskModal: show });
|
59
|
-
|
60
|
-
if (show && this.state.manifestModalOpen) {
|
61
|
-
this.setState({ manifestModalOpen: false });
|
62
|
-
}
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
85
|
loadData() {
|
67
86
|
this.props.pollBulkSearch({
|
68
87
|
search_id: MANIFEST_TASKS_BULK_SEARCH_ID,
|
@@ -77,23 +96,25 @@ class SubscriptionsPage extends Component {
|
|
77
96
|
|
78
97
|
handleDoneTask(taskToPoll) {
|
79
98
|
const POLL_TASK_INTERVAL = 5000;
|
99
|
+
const { pollTaskUntilDone, loadSubscriptions } = this.props;
|
80
100
|
|
81
|
-
|
82
|
-
|
83
|
-
this.props.pollTaskUntilDone(taskToPoll.id, {}, POLL_TASK_INTERVAL).then((task) => {
|
101
|
+
pollTaskUntilDone(taskToPoll.id, {}, POLL_TASK_INTERVAL)
|
102
|
+
.then((task) => {
|
84
103
|
function getErrors() {
|
85
104
|
return (
|
86
105
|
<ul>
|
87
|
-
{
|
88
|
-
|
89
|
-
}
|
106
|
+
{task.humanized.errors.map(error => (
|
107
|
+
<li key={error}> {error} </li>
|
108
|
+
))}
|
90
109
|
</ul>
|
91
110
|
);
|
92
111
|
}
|
93
112
|
|
94
113
|
const message = (
|
95
114
|
<span>
|
96
|
-
<span>
|
115
|
+
<span>
|
116
|
+
{`${__(`Task ${task.humanized.action} completed with a result of ${task.result}.`)} `}
|
117
|
+
</span>
|
97
118
|
{task.errors ? getErrors() : ''}
|
98
119
|
<a href={helpers.urlBuilder('foreman_tasks/tasks', '', task.id)}>
|
99
120
|
{__('Click here to go to the tasks page for the task.')}
|
@@ -101,11 +122,13 @@ class SubscriptionsPage extends Component {
|
|
101
122
|
</span>
|
102
123
|
);
|
103
124
|
|
104
|
-
notify({
|
125
|
+
notify({
|
126
|
+
message: ReactDOMServer.renderToStaticMarkup(message),
|
127
|
+
type: task.result,
|
128
|
+
});
|
105
129
|
|
106
|
-
|
130
|
+
loadSubscriptions();
|
107
131
|
});
|
108
|
-
}
|
109
132
|
}
|
110
133
|
|
111
134
|
render() {
|
@@ -118,13 +141,6 @@ class SubscriptionsPage extends Component {
|
|
118
141
|
|
119
142
|
if (taskInProgress) {
|
120
143
|
[task] = tasks;
|
121
|
-
this.handleDoneTask(task);
|
122
|
-
}
|
123
|
-
|
124
|
-
if (task) {
|
125
|
-
this.showTaskModal(true);
|
126
|
-
} else {
|
127
|
-
this.showTaskModal(false);
|
128
144
|
}
|
129
145
|
|
130
146
|
const onSearch = (search) => {
|
@@ -134,7 +150,7 @@ class SubscriptionsPage extends Component {
|
|
134
150
|
const getAutoCompleteParams = search => ({
|
135
151
|
endpoint: '/subscriptions/auto_complete_search',
|
136
152
|
params: {
|
137
|
-
organization_id: orgId,
|
153
|
+
organization_id: orgId(),
|
138
154
|
search,
|
139
155
|
},
|
140
156
|
});
|