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,38 @@
|
|
1
|
+
@import '~patternfly/dist/sass/patternfly/variables';
|
2
|
+
@import '~patternfly-react/dist/sass/inline-edit';
|
3
|
+
|
4
|
+
.editable {
|
5
|
+
&.changed {
|
6
|
+
font-weight: bold;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
.pf-table-inline-edit {
|
11
|
+
tbody {
|
12
|
+
.form-group {
|
13
|
+
margin-bottom: 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
tr.open-grouped-row {
|
17
|
+
background-color: $table-bg-hover;
|
18
|
+
td {
|
19
|
+
border-bottom-color: $table-border-hover;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
.table-view-pf-select {
|
25
|
+
width: 50px;
|
26
|
+
|
27
|
+
.collapse-subscription-group-button {
|
28
|
+
margin-top: 4px;
|
29
|
+
cursor: pointer;
|
30
|
+
float: left;
|
31
|
+
font-weight: bold;
|
32
|
+
}
|
33
|
+
|
34
|
+
input[type="checkbox"] {
|
35
|
+
float: right;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
@@ -14,12 +14,12 @@ export const loadUpstreamSubscriptions = (extendedParams = {}) => (dispatch) =>
|
|
14
14
|
dispatch({ type: UPSTREAM_SUBSCRIPTIONS_REQUEST });
|
15
15
|
|
16
16
|
const params = {
|
17
|
-
...{ organization_id: orgId, attachable: true },
|
17
|
+
...{ organization_id: orgId(), attachable: true },
|
18
18
|
...propsToSnakeCase(extendedParams),
|
19
19
|
};
|
20
20
|
|
21
21
|
return api
|
22
|
-
.get(`/organizations/${orgId}/upstream_subscriptions`, {}, params)
|
22
|
+
.get(`/organizations/${orgId()}/upstream_subscriptions`, {}, params)
|
23
23
|
.then(({ data }) => {
|
24
24
|
dispatch({
|
25
25
|
type: UPSTREAM_SUBSCRIPTIONS_SUCCESS,
|
@@ -43,7 +43,7 @@ export const saveUpstreamSubscriptions = upstreamSubscriptions => (dispatch) =>
|
|
43
43
|
};
|
44
44
|
|
45
45
|
return api
|
46
|
-
.post(`/organizations/${orgId}/upstream_subscriptions`, params)
|
46
|
+
.post(`/organizations/${orgId()}/upstream_subscriptions`, params)
|
47
47
|
.then(({ data }) => {
|
48
48
|
dispatch({
|
49
49
|
type: SAVE_UPSTREAM_SUBSCRIPTIONS_SUCCESS,
|
@@ -4,7 +4,8 @@ import _ from 'lodash';
|
|
4
4
|
import PropTypes from 'prop-types';
|
5
5
|
import { LinkContainer } from 'react-router-bootstrap';
|
6
6
|
import { Grid, Row, Col } from 'react-bootstrap';
|
7
|
-
import { bindMethods, Button
|
7
|
+
import { bindMethods, Button } from 'patternfly-react';
|
8
|
+
import { LoadingState } from '../../../move_to_pf/LoadingState';
|
8
9
|
import { notify } from '../../../move_to_foreman/foreman_toast_notifications';
|
9
10
|
import helpers from '../../../move_to_foreman/common/helpers';
|
10
11
|
import { Table } from '../../../move_to_foreman/components/common/table';
|
@@ -33,7 +34,7 @@ class UpstreamSubscriptionsPage extends Component {
|
|
33
34
|
const newValue = parseInt(value, 10);
|
34
35
|
const pool = {
|
35
36
|
...rowData,
|
36
|
-
id: rowData.
|
37
|
+
id: rowData.id,
|
37
38
|
updatedQuantity: newValue,
|
38
39
|
selected: true,
|
39
40
|
};
|
@@ -86,7 +87,7 @@ class UpstreamSubscriptionsPage extends Component {
|
|
86
87
|
);
|
87
88
|
|
88
89
|
notify({ message: ReactDOMServer.renderToStaticMarkup(message), type: 'success' });
|
89
|
-
this.props.history.push('/
|
90
|
+
this.props.history.push('/subscriptions');
|
90
91
|
} else {
|
91
92
|
let errorMessages = [];
|
92
93
|
|
@@ -126,7 +127,7 @@ class UpstreamSubscriptionsPage extends Component {
|
|
126
127
|
{__('Submit')}
|
127
128
|
</Button>
|
128
129
|
|
129
|
-
<LinkContainer to="/
|
130
|
+
<LinkContainer to="/subscriptions">
|
130
131
|
<Button>
|
131
132
|
{__('Cancel')}
|
132
133
|
</Button>
|
@@ -213,7 +214,7 @@ class UpstreamSubscriptionsPage extends Component {
|
|
213
214
|
<Grid bsClass="container-fluid">
|
214
215
|
<h1>{__('Add Subscriptions')}</h1>
|
215
216
|
|
216
|
-
<
|
217
|
+
<LoadingState loading={upstreamSubscriptions.loading} loadingText={__('Loading')}>
|
217
218
|
<Row>
|
218
219
|
<Col sm={12}>
|
219
220
|
<Table
|
@@ -227,7 +228,7 @@ class UpstreamSubscriptionsPage extends Component {
|
|
227
228
|
</Col>
|
228
229
|
</Row>
|
229
230
|
{getSubscriptionActions()}
|
230
|
-
</
|
231
|
+
</LoadingState>
|
231
232
|
</Grid>
|
232
233
|
);
|
233
234
|
}
|
@@ -1,9 +1,11 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { FormGroup, FormControl, ControlLabel } from 'react-bootstrap';
|
3
|
-
import helpers
|
3
|
+
import helpers from '../../../move_to_foreman/common/helpers';
|
4
4
|
import {
|
5
|
-
|
6
|
-
|
5
|
+
headerFormatter,
|
6
|
+
cellFormatter,
|
7
|
+
selectionHeaderCellFormatter,
|
8
|
+
selectionCellFormatter,
|
7
9
|
} from '../../../move_to_foreman/components/common/table';
|
8
10
|
|
9
11
|
export const columns = (controller, selectionController) => [
|
@@ -14,15 +16,16 @@ export const columns = (controller, selectionController) => [
|
|
14
16
|
formatters: [label => selectionHeaderCellFormatter(selectionController, label)],
|
15
17
|
},
|
16
18
|
cell: {
|
17
|
-
formatters: [
|
18
|
-
selectionCellFormatter(selectionController,
|
19
|
+
formatters: [
|
20
|
+
(value, additionalData) => selectionCellFormatter(selectionController, additionalData),
|
21
|
+
],
|
19
22
|
},
|
20
23
|
},
|
21
24
|
{
|
22
25
|
property: 'id',
|
23
26
|
header: {
|
24
27
|
label: __('Subscription Name'),
|
25
|
-
formatters: [
|
28
|
+
formatters: [headerFormatter],
|
26
29
|
},
|
27
30
|
cell: {
|
28
31
|
formatters: [
|
@@ -40,10 +43,10 @@ export const columns = (controller, selectionController) => [
|
|
40
43
|
property: 'contract_number',
|
41
44
|
header: {
|
42
45
|
label: __('Contract'),
|
43
|
-
formatters: [
|
46
|
+
formatters: [headerFormatter],
|
44
47
|
},
|
45
48
|
cell: {
|
46
|
-
formatters: [
|
49
|
+
formatters: [cellFormatter],
|
47
50
|
},
|
48
51
|
},
|
49
52
|
// TODO: use date formatter from tomas' PR
|
@@ -51,27 +54,27 @@ export const columns = (controller, selectionController) => [
|
|
51
54
|
property: 'start_date',
|
52
55
|
header: {
|
53
56
|
label: __('Start Date'),
|
54
|
-
formatters: [
|
57
|
+
formatters: [headerFormatter],
|
55
58
|
},
|
56
59
|
cell: {
|
57
|
-
formatters: [
|
60
|
+
formatters: [cellFormatter],
|
58
61
|
},
|
59
62
|
},
|
60
63
|
{
|
61
64
|
property: 'end_date',
|
62
65
|
header: {
|
63
66
|
label: __('End Date'),
|
64
|
-
formatters: [
|
67
|
+
formatters: [headerFormatter],
|
65
68
|
},
|
66
69
|
cell: {
|
67
|
-
formatters: [
|
70
|
+
formatters: [cellFormatter],
|
68
71
|
},
|
69
72
|
},
|
70
73
|
{
|
71
74
|
property: 'quantity',
|
72
75
|
header: {
|
73
76
|
label: __('Available Entitlements'),
|
74
|
-
formatters: [
|
77
|
+
formatters: [headerFormatter],
|
75
78
|
},
|
76
79
|
cell: {
|
77
80
|
formatters: [
|
@@ -87,7 +90,7 @@ export const columns = (controller, selectionController) => [
|
|
87
90
|
property: 'consumed',
|
88
91
|
header: {
|
89
92
|
label: __('Quantity to Allocate'),
|
90
|
-
formatters: [
|
93
|
+
formatters: [headerFormatter],
|
91
94
|
},
|
92
95
|
cell: {
|
93
96
|
formatters: [
|
@@ -9,12 +9,9 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
9
9
|
<h1>
|
10
10
|
Add Subscriptions
|
11
11
|
</h1>
|
12
|
-
<
|
13
|
-
className="small-spacer"
|
14
|
-
inline={false}
|
15
|
-
inverse={false}
|
12
|
+
<LoadingState
|
16
13
|
loading={false}
|
17
|
-
|
14
|
+
loadingText="Loading"
|
18
15
|
>
|
19
16
|
<Row
|
20
17
|
bsClass="row"
|
@@ -157,7 +154,7 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
157
154
|
"consumed": 100,
|
158
155
|
"contract_number": "11480900",
|
159
156
|
"end_date": "2018-09-15T03:59:59+0000",
|
160
|
-
"
|
157
|
+
"id": "8a99f9815e718933015e85b19e1e11d7",
|
161
158
|
"product_id": "RH00284",
|
162
159
|
"product_name": "Red Hat Enterprise Linux for Power, LE, Premium (IFL, up to 4 LPARs)",
|
163
160
|
"quantity": 200,
|
@@ -166,16 +163,16 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
166
163
|
"subscription_id": "4753270",
|
167
164
|
},
|
168
165
|
Object {
|
169
|
-
"consumed":
|
170
|
-
"contract_number": "
|
166
|
+
"consumed": 125,
|
167
|
+
"contract_number": "11480898",
|
171
168
|
"end_date": "2018-09-15T03:59:59+0000",
|
172
|
-
"
|
173
|
-
"product_id": "
|
174
|
-
"product_name": "Red Hat Enterprise Linux for
|
175
|
-
"quantity":
|
169
|
+
"id": "8a99f9815e718933015e85b1bfd211db",
|
170
|
+
"product_id": "RH00447",
|
171
|
+
"product_name": "Red Hat Enterprise Linux Server for ATOM with Smart Management, Hyperscale, Standard (5 Physical Nodes)",
|
172
|
+
"quantity": 250,
|
176
173
|
"selected": false,
|
177
174
|
"start_date": "2017-09-15T04:00:00+0000",
|
178
|
-
"subscription_id": "
|
175
|
+
"subscription_id": "4753271",
|
179
176
|
},
|
180
177
|
]
|
181
178
|
}
|
@@ -207,7 +204,7 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
207
204
|
exact={false}
|
208
205
|
replace={false}
|
209
206
|
strict={false}
|
210
|
-
to="/
|
207
|
+
to="/subscriptions"
|
211
208
|
>
|
212
209
|
<Button
|
213
210
|
active={false}
|
@@ -221,6 +218,6 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
221
218
|
</LinkContainer>
|
222
219
|
</Col>
|
223
220
|
</Row>
|
224
|
-
</
|
221
|
+
</LoadingState>
|
225
222
|
</Grid>
|
226
223
|
`;
|
data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js
CHANGED
@@ -36,7 +36,7 @@ export const requestSuccessResponse = Immutable({
|
|
36
36
|
},
|
37
37
|
results: [
|
38
38
|
{
|
39
|
-
|
39
|
+
id: '8a99f9815e718933015e85b19e1e11d7',
|
40
40
|
quantity: 200,
|
41
41
|
start_date: '2017-09-15T04:00:00+0000',
|
42
42
|
end_date: '2018-09-15T03:59:59+0000',
|
@@ -47,7 +47,7 @@ export const requestSuccessResponse = Immutable({
|
|
47
47
|
subscription_id: '4753270',
|
48
48
|
},
|
49
49
|
{
|
50
|
-
|
50
|
+
id: '8a99f9815e718933015e85b1bfd211db',
|
51
51
|
quantity: 250,
|
52
52
|
start_date: '2017-09-15T04:00:00+0000',
|
53
53
|
end_date: '2018-09-15T03:59:59+0000',
|
@@ -65,7 +65,7 @@ export const successState = Immutable({
|
|
65
65
|
loading: false,
|
66
66
|
results: [
|
67
67
|
{
|
68
|
-
|
68
|
+
id: '8a99f9815e718933015e85b19e1e11d7',
|
69
69
|
quantity: 200,
|
70
70
|
start_date: '2017-09-15T04:00:00+0000',
|
71
71
|
end_date: '2018-09-15T03:59:59+0000',
|
@@ -76,7 +76,7 @@ export const successState = Immutable({
|
|
76
76
|
subscription_id: '4753270',
|
77
77
|
},
|
78
78
|
{
|
79
|
-
|
79
|
+
id: '8a99f9815e718933015e85b1bfd211db',
|
80
80
|
quantity: 250,
|
81
81
|
start_date: '2017-09-15T04:00:00+0000',
|
82
82
|
end_date: '2018-09-15T03:59:59+0000',
|
@@ -30,6 +30,11 @@ describe('validateQuantity', () => {
|
|
30
30
|
.toEqual(validationError('Has to be > 0'));
|
31
31
|
});
|
32
32
|
|
33
|
+
it('detects zero', () => {
|
34
|
+
expect(validateQuantity('0', 500))
|
35
|
+
.toEqual(validationError('Has to be > 0'));
|
36
|
+
});
|
37
|
+
|
33
38
|
it('detects too big quantity', () => {
|
34
39
|
expect(validateQuantity('501', 500))
|
35
40
|
.toEqual(validationError('Exceeds available quantity'));
|
@@ -135,7 +135,7 @@ export const requestSuccessResponseWithRHSubscriptions = Immutable({
|
|
135
135
|
export const quantitiesRequestSuccessResponse = Immutable({
|
136
136
|
results: [
|
137
137
|
{
|
138
|
-
|
138
|
+
id: '9a95f981519abf020151ab082c5e0313',
|
139
139
|
quantity: 10000,
|
140
140
|
available: 100,
|
141
141
|
start_date: '2016-12-15T05:00:00+0000',
|
@@ -151,7 +151,7 @@ export const quantitiesRequestSuccessResponse = Immutable({
|
|
151
151
|
],
|
152
152
|
},
|
153
153
|
{
|
154
|
-
|
154
|
+
id: '6b123381519abf020151ab082c5e4678',
|
155
155
|
quantity: 400,
|
156
156
|
available: 40,
|
157
157
|
start_date: '2016-12-15T05:00:00+0000',
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import { sprintf } from 'jed';
|
2
3
|
import { Table, FormControl, FormGroup, HelpBlock, Spinner } from 'patternfly-react';
|
3
|
-
import { validateQuantity } from '
|
4
|
-
import { KEY_CODES } from '
|
4
|
+
import { validateQuantity } from '../../SubscriptionValidations';
|
5
|
+
import { KEY_CODES } from '../../../../move_to_foreman/common/helpers';
|
5
6
|
|
6
7
|
export const entitlementsInlineEditFormatter =
|
7
8
|
inlineEditController => Table.inlineEditFormatterFactory({
|
@@ -39,10 +40,9 @@ export const entitlementsInlineEditFormatter =
|
|
39
40
|
? 'editable editing changed'
|
40
41
|
: 'editable editing';
|
41
42
|
|
42
|
-
const maxMessage =
|
43
|
-
__('
|
44
|
-
availableQuantity,
|
45
|
-
].join(' ');
|
43
|
+
const maxMessage = (availableQuantity < 1)
|
44
|
+
? __('Unlimited')
|
45
|
+
: sprintf(__('Max %(availableQuantity)s'), { availableQuantity });
|
46
46
|
|
47
47
|
const validation = validateQuantity(value, availableQuantity);
|
48
48
|
|
@@ -55,7 +55,7 @@ export const entitlementsInlineEditFormatter =
|
|
55
55
|
// The same issue prevents from correct switching inputs on TAB.
|
56
56
|
// See the reactabular code for details:
|
57
57
|
// https://github.com/reactabular/reactabular/blob/master/packages/reactabular-table/src/body-row.js#L58
|
58
|
-
<Spinner loading={
|
58
|
+
<Spinner loading={availableQuantity === undefined} size="xs">
|
59
59
|
<FormGroup
|
60
60
|
validationState={validation.state}
|
61
61
|
>
|
@@ -1,13 +1,16 @@
|
|
1
1
|
import React, { Component } from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
+
import classNames from 'classnames';
|
3
4
|
import { sprintf } from 'jed';
|
4
|
-
import { cloneDeep, findIndex } from 'lodash';
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import
|
8
|
-
import
|
9
|
-
import
|
10
|
-
import { recordsValid } from '
|
5
|
+
import { cloneDeep, findIndex, isEqual } from 'lodash';
|
6
|
+
import { Table, Alert } from 'patternfly-react';
|
7
|
+
import { LoadingState } from '../../../../move_to_pf/LoadingState';
|
8
|
+
import { Table as ForemanTable, TableBody as ForemanTableBody } from '../../../../move_to_foreman/components/common/table';
|
9
|
+
import ConfirmDialog from '../../../../move_to_foreman/components/common/ConfirmDialog';
|
10
|
+
import Dialog from '../../../../move_to_foreman/components/common/Dialog';
|
11
|
+
import { recordsValid } from '../../SubscriptionValidations';
|
12
|
+
import { createSubscriptionsTableSchema } from './SubscriptionsTableSchema';
|
13
|
+
import { buildTableRows, groupSubscriptionsByProductId, buildPools } from './SubscriptionsTableHelpers';
|
11
14
|
|
12
15
|
const emptyStateData = {
|
13
16
|
header: __('There are no Subscriptions to display'),
|
@@ -39,48 +42,16 @@ ErrorAlerts.propTypes = {
|
|
39
42
|
errors: PropTypes.arrayOf(PropTypes.string).isRequired,
|
40
43
|
};
|
41
44
|
|
42
|
-
const buildTableRows = (subscriptions, updatedQuantity) =>
|
43
|
-
subscriptions.results.map((subs) => {
|
44
|
-
if (updatedQuantity[subs.id]) {
|
45
|
-
return {
|
46
|
-
...subs,
|
47
|
-
entitlementsChanged: true,
|
48
|
-
quantity: updatedQuantity[subs.id],
|
49
|
-
availableQuantity: subscriptions.availableQuantities[subs.id],
|
50
|
-
};
|
51
|
-
}
|
52
|
-
return {
|
53
|
-
...subs,
|
54
|
-
availableQuantity: subscriptions.availableQuantities[subs.id],
|
55
|
-
};
|
56
|
-
});
|
57
|
-
|
58
|
-
const buildPools = updatedQuantity =>
|
59
|
-
Object.entries(updatedQuantity)
|
60
|
-
.map(([id, quantity]) => ({
|
61
|
-
id,
|
62
|
-
quantity,
|
63
|
-
}));
|
64
|
-
|
65
45
|
class SubscriptionsTable extends Component {
|
66
|
-
static getDerivedStateFromProps(nextProps, prevState) {
|
67
|
-
if (nextProps.subscriptions !== undefined) {
|
68
|
-
return {
|
69
|
-
rows: buildTableRows(
|
70
|
-
nextProps.subscriptions,
|
71
|
-
prevState.updatedQuantity,
|
72
|
-
),
|
73
|
-
};
|
74
|
-
}
|
75
|
-
return null;
|
76
|
-
}
|
77
|
-
|
78
46
|
constructor(props) {
|
79
47
|
super(props);
|
48
|
+
|
80
49
|
this.state = {
|
50
|
+
rows: undefined,
|
51
|
+
subscriptions: undefined,
|
52
|
+
groupdSubscriptions: undefined,
|
81
53
|
updatedQuantity: {},
|
82
54
|
editing: false,
|
83
|
-
rows: props.subscriptions.results,
|
84
55
|
showUpdateConfirmDialog: false,
|
85
56
|
showCancelConfirmDialog: false,
|
86
57
|
showErrorDialog: false,
|
@@ -88,6 +59,41 @@ class SubscriptionsTable extends Component {
|
|
88
59
|
};
|
89
60
|
}
|
90
61
|
|
62
|
+
static getDerivedStateFromProps(nextProps, prevState) {
|
63
|
+
if (
|
64
|
+
nextProps.subscriptions !== undefined &&
|
65
|
+
!isEqual(nextProps.subscriptions, prevState.subscriptions)
|
66
|
+
) {
|
67
|
+
const groupdSubscriptions = groupSubscriptionsByProductId(nextProps.subscriptions);
|
68
|
+
const rows = buildTableRows(
|
69
|
+
groupdSubscriptions,
|
70
|
+
nextProps.subscriptions.availableQuantities,
|
71
|
+
prevState.updatedQuantity,
|
72
|
+
);
|
73
|
+
|
74
|
+
return { rows, groupdSubscriptions, subscriptions: nextProps.subscriptions };
|
75
|
+
}
|
76
|
+
|
77
|
+
return null;
|
78
|
+
}
|
79
|
+
|
80
|
+
toggleSubscriptionGroup(groupId) {
|
81
|
+
const { subscriptions } = this.props;
|
82
|
+
const { groupdSubscriptions, updatedQuantity } = this.state;
|
83
|
+
const { open } = groupdSubscriptions[groupId];
|
84
|
+
|
85
|
+
groupdSubscriptions[groupId].open = !open;
|
86
|
+
|
87
|
+
|
88
|
+
const rows = buildTableRows(
|
89
|
+
groupdSubscriptions,
|
90
|
+
subscriptions.availableQuantities,
|
91
|
+
updatedQuantity,
|
92
|
+
);
|
93
|
+
|
94
|
+
this.setState({ rows, groupdSubscriptions });
|
95
|
+
}
|
96
|
+
|
91
97
|
enableEditing(editingState) {
|
92
98
|
this.setState({
|
93
99
|
updatedQuantity: {},
|
@@ -96,8 +102,12 @@ class SubscriptionsTable extends Component {
|
|
96
102
|
}
|
97
103
|
|
98
104
|
updateRows(updatedQuantity) {
|
105
|
+
const { groupdSubscriptions } = this.state;
|
106
|
+
const { subscriptions } = this.props;
|
107
|
+
|
99
108
|
const rows = buildTableRows(
|
100
|
-
|
109
|
+
groupdSubscriptions,
|
110
|
+
subscriptions.availableQuantities,
|
101
111
|
updatedQuantity,
|
102
112
|
);
|
103
113
|
this.setState({ rows, updatedQuantity });
|
@@ -148,6 +158,17 @@ class SubscriptionsTable extends Component {
|
|
148
158
|
|
149
159
|
render() {
|
150
160
|
const { subscriptions } = this.props;
|
161
|
+
const { groupdSubscriptions } = this.state;
|
162
|
+
|
163
|
+
const groupingController = {
|
164
|
+
isCollapseable: ({ rowData }) =>
|
165
|
+
// it is the first subscription in the group
|
166
|
+
rowData.id === groupdSubscriptions[rowData.product_id].subscriptions[0].id &&
|
167
|
+
// the group contains more then one subscription
|
168
|
+
groupdSubscriptions[rowData.product_id].subscriptions.length > 1,
|
169
|
+
isCollapsed: ({ rowData }) => !groupdSubscriptions[rowData.product_id].open,
|
170
|
+
toggle: ({ rowData }) => this.toggleSubscriptionGroup(rowData.product_id),
|
171
|
+
};
|
151
172
|
|
152
173
|
const inlineEditController = {
|
153
174
|
isEditing: ({ rowData }) => (this.state.editing && rowData.available >= 0),
|
@@ -229,10 +250,14 @@ class SubscriptionsTable extends Component {
|
|
229
250
|
bodyMessage = __('No subscriptions match your search criteria.');
|
230
251
|
}
|
231
252
|
|
232
|
-
const columnsDefinition =
|
253
|
+
const columnsDefinition = createSubscriptionsTableSchema(
|
254
|
+
inlineEditController,
|
255
|
+
selectionController,
|
256
|
+
groupingController,
|
257
|
+
);
|
233
258
|
|
234
259
|
return (
|
235
|
-
<
|
260
|
+
<LoadingState loading={subscriptions.loading} loadingText={__('Loading')}>
|
236
261
|
<ErrorAlerts
|
237
262
|
errors={[
|
238
263
|
subscriptions.error,
|
@@ -267,6 +292,9 @@ class SubscriptionsTable extends Component {
|
|
267
292
|
rows={this.state.rows}
|
268
293
|
rowKey="id"
|
269
294
|
message={bodyMessage}
|
295
|
+
onRow={rowData => ({
|
296
|
+
className: classNames({ 'open-grouped-row': !groupingController.isCollapsed({ rowData }) }),
|
297
|
+
})}
|
270
298
|
/>
|
271
299
|
</ForemanTable>
|
272
300
|
<ConfirmDialog
|
@@ -316,7 +344,7 @@ class SubscriptionsTable extends Component {
|
|
316
344
|
onConfirm={() => this.props.onDeleteSubscriptions(this.state.selectedRows)}
|
317
345
|
onCancel={this.props.onSubscriptionDeleteModalClose}
|
318
346
|
/>
|
319
|
-
</
|
347
|
+
</LoadingState>
|
320
348
|
);
|
321
349
|
}
|
322
350
|
}
|