katello 3.7.0.rc2 → 3.7.0
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/repository_sets_controller.rb +10 -1
- data/app/models/katello/glue/candlepin/owner.rb +0 -8
- data/app/models/katello/product_content.rb +4 -1
- data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +3 -1
- data/app/views/overrides/activation_keys/_host_environment_select.html.erb +1 -1
- data/lib/katello/version.rb +1 -1
- data/package.json +2 -1
- data/webpack/__mocks__/foremanReact/components/BreadcrumbBar.js +3 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +6 -0
- data/webpack/mockRequest.js +3 -3
- data/webpack/move_to_foreman/common/helpers.js +45 -8
- data/webpack/redux/actions/RedHatRepositories/sets.js +1 -1
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +2 -7
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +1 -1
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +44 -6
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailReducer.test.js +3 -1
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +0 -1
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +22 -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/ManifestActions.js +5 -24
- data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +1 -1
- 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__/manifest.fixtures.js +9 -16
- data/webpack/scenes/Subscriptions/SubscriptionActions.js +5 -26
- data/webpack/scenes/Subscriptions/SubscriptionReducer.js +6 -2
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +13 -10
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +3 -12
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +55 -20
- 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 +18 -5
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js +5 -8
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +9 -3
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +1 -0
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +10 -14
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +16 -39
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +2 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +1 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +349 -355
- data/webpack/scenes/Subscriptions/index.js +1 -2
- data/webpack/services/api/testHelpers.js +28 -0
- metadata +7 -5
- data/webpack/services/api/fixtures.js +0 -353
@@ -38,7 +38,7 @@ export default (state = initialState, action) => {
|
|
38
38
|
|
39
39
|
case UPSTREAM_SUBSCRIPTIONS_FAILURE:
|
40
40
|
return state.merge({
|
41
|
-
error: action.
|
41
|
+
error: action.payload.message,
|
42
42
|
loading: false,
|
43
43
|
});
|
44
44
|
|
@@ -49,8 +49,7 @@ export default (state = initialState, action) => {
|
|
49
49
|
return state.set('task', action.response).set('loading', false);
|
50
50
|
|
51
51
|
case SAVE_UPSTREAM_SUBSCRIPTIONS_FAILURE: {
|
52
|
-
|
53
|
-
return state.set('error', error).set('loading', false);
|
52
|
+
return state.set('error', action.payload.message).set('loading', false);
|
54
53
|
}
|
55
54
|
|
56
55
|
default:
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { FormGroup, FormControl, ControlLabel } from 'react-bootstrap';
|
2
|
+
import { FormGroup, FormControl, ControlLabel, HelpBlock } from 'react-bootstrap';
|
3
3
|
import helpers from '../../../move_to_foreman/common/helpers';
|
4
4
|
import {
|
5
5
|
headerFormatter,
|
@@ -71,7 +71,7 @@ export const columns = (controller, selectionController) => [
|
|
71
71
|
},
|
72
72
|
},
|
73
73
|
{
|
74
|
-
property: '
|
74
|
+
property: 'available',
|
75
75
|
header: {
|
76
76
|
label: __('Available Entitlements'),
|
77
77
|
formatters: [headerFormatter],
|
@@ -96,22 +96,27 @@ export const columns = (controller, selectionController) => [
|
|
96
96
|
formatters: [
|
97
97
|
(value, { rowData }) => (
|
98
98
|
<td>
|
99
|
-
<FormGroup
|
99
|
+
<FormGroup
|
100
|
+
validationState={controller.quantityValidationInput(rowData)}
|
101
|
+
>
|
100
102
|
<ControlLabel srOnly>{__('Number to Allocate')}</ControlLabel>
|
101
103
|
<FormControl
|
102
104
|
type="text"
|
103
105
|
onBlur={e => controller.onChange(e.target.value, rowData)}
|
104
106
|
defaultValue={rowData.updatedQuantity}
|
107
|
+
onChange={(e) => {
|
108
|
+
controller.onChange(e.target.value, rowData);
|
109
|
+
}}
|
105
110
|
onKeyDown={(e) => {
|
106
111
|
const key = e.charCode ? e.charCode : e.keyCode;
|
107
112
|
if (key === 13) {
|
108
|
-
controller.onChange(e.target.value, rowData);
|
109
113
|
controller.saveUpstreamSubscriptions();
|
110
114
|
e.preventDefault();
|
111
115
|
}
|
112
116
|
}}
|
113
117
|
/>
|
114
|
-
|
118
|
+
{controller.quantityValidationInput(rowData) === 'error' &&
|
119
|
+
<HelpBlock>{controller.quantityValidation(rowData)[1]}</HelpBlock>}
|
115
120
|
</FormGroup>
|
116
121
|
</td>
|
117
122
|
),
|
@@ -1,5 +1,3 @@
|
|
1
|
-
import axios from 'axios';
|
2
|
-
import MockAdapter from 'axios-mock-adapter';
|
3
1
|
import configureMockStore from 'redux-mock-store';
|
4
2
|
import thunk from 'redux-thunk';
|
5
3
|
import Immutable from 'seamless-immutable';
|
@@ -13,10 +11,10 @@ import {
|
|
13
11
|
import { getTaskSuccessResponse } from '../../../Tasks/__tests__/task.fixtures';
|
14
12
|
|
15
13
|
import { loadUpstreamSubscriptions, saveUpstreamSubscriptions } from '../UpstreamSubscriptionsActions';
|
14
|
+
import { mock as mockApi, mockErrorRequest } from '../../../../mockRequest';
|
16
15
|
|
17
16
|
const mockStore = configureMockStore([thunk]);
|
18
17
|
const store = mockStore({ subscriptions: Immutable({}) });
|
19
|
-
const mockApi = new MockAdapter(axios);
|
20
18
|
|
21
19
|
afterEach(() => {
|
22
20
|
store.clearActions();
|
@@ -28,7 +26,10 @@ describe('upstream subscription actions', () => {
|
|
28
26
|
|
29
27
|
describe('creates UPSTREAM_SUBSCRIPTIONS_REQUEST', () => {
|
30
28
|
it('and then fails with 422', () => {
|
31
|
-
|
29
|
+
mockErrorRequest({
|
30
|
+
url,
|
31
|
+
status: 422,
|
32
|
+
});
|
32
33
|
|
33
34
|
return store.dispatch(loadUpstreamSubscriptions())
|
34
35
|
.then(() => expect(store.getActions()).toEqual(getFailureActions));
|
@@ -48,7 +49,11 @@ describe('upstream subscription actions', () => {
|
|
48
49
|
};
|
49
50
|
|
50
51
|
it('and then fails with 422', () => {
|
51
|
-
|
52
|
+
mockErrorRequest({
|
53
|
+
url,
|
54
|
+
status: 422,
|
55
|
+
method: 'POST',
|
56
|
+
});
|
52
57
|
|
53
58
|
return store.dispatch(saveUpstreamSubscriptions(subscriptionData))
|
54
59
|
.then(() => expect(store.getActions()).toEqual(saveFailureActions));
|
data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js
CHANGED
@@ -6,17 +6,62 @@ import { successState } from './upstreamSubscriptions.fixtures';
|
|
6
6
|
import { loadUpstreamSubscriptions, saveUpstreamSubscriptions } from '../UpstreamSubscriptionsActions';
|
7
7
|
|
8
8
|
jest.mock('../../../../move_to_foreman/foreman_toast_notifications');
|
9
|
+
jest.mock('foremanReact/components/BreadcrumbBar');
|
9
10
|
|
10
11
|
describe('upstream subscriptions page', () => {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
const page = shallow(<UpstreamSubscriptionsPage
|
12
|
+
let shallowWrapper;
|
13
|
+
beforeEach(() => {
|
14
|
+
shallowWrapper = shallow(<UpstreamSubscriptionsPage
|
15
15
|
upstreamSubscriptions={successState}
|
16
16
|
loadUpstreamSubscriptions={loadUpstreamSubscriptions}
|
17
17
|
saveUpstreamSubscriptions={saveUpstreamSubscriptions}
|
18
18
|
history={mockHistory}
|
19
19
|
/>);
|
20
|
-
|
20
|
+
});
|
21
|
+
const mockHistory = { push: () => {} };
|
22
|
+
|
23
|
+
it('should render', async () => {
|
24
|
+
expect(toJson(shallowWrapper)).toMatchSnapshot();
|
25
|
+
});
|
26
|
+
|
27
|
+
it('should validate correct subscription quantities', async () => {
|
28
|
+
const validPools = [
|
29
|
+
{ available: 10, updatedQuantity: 5 },
|
30
|
+
{ available: 10, updatedQuantity: '5' },
|
31
|
+
{ available: 10, updatedQuantity: '10' },
|
32
|
+
{ available: 10, updatedQuantity: '1' },
|
33
|
+
{ available: -1, updatedQuantity: '1000' },
|
34
|
+
];
|
35
|
+
validPools.forEach((pool, i) => {
|
36
|
+
// using object with index attribute to print out index on failure,
|
37
|
+
// jest doesn't support messages on failure :(
|
38
|
+
const result = shallowWrapper.instance().quantityValidation(pool)[0];
|
39
|
+
expect({ index: i, result }).toEqual({ index: i, result: true });
|
40
|
+
});
|
41
|
+
});
|
42
|
+
|
43
|
+
it('should invalidate incorrect subscription quantities', async () => {
|
44
|
+
const invalidPools = [
|
45
|
+
{ available: 10, updatedQuantity: 11 },
|
46
|
+
{ available: 10, updatedQuantity: 'foo' },
|
47
|
+
{ available: 10, updatedQuantity: 0 },
|
48
|
+
{ available: 10, updatedQuantity: '0' },
|
49
|
+
{ available: 10, updatedQuantity: '11' },
|
50
|
+
{ available: 10, updatedQuantity: '2.0' },
|
51
|
+
{ available: 10, updatedQuantity: '2/3' },
|
52
|
+
{ available: -1, updatedQuantity: '-1' },
|
53
|
+
{ available: -1, updatedQuantity: '0' },
|
54
|
+
{ available: -1, updatedQuantity: 'foo' },
|
55
|
+
{ available: -1, updatedQuantity: '2/3' },
|
56
|
+
{ available: -1, updatedQuantity: '2.0' },
|
57
|
+
{ available: -1, updatedQuantity: '99999999999' },
|
58
|
+
];
|
59
|
+
|
60
|
+
invalidPools.forEach((pool, i) => {
|
61
|
+
// using object with index attribute to print out index on failure,
|
62
|
+
// jest doesn't support messages on failure :(
|
63
|
+
const result = shallowWrapper.instance().quantityValidation(pool)[0];
|
64
|
+
expect({ index: i, result }).toEqual({ index: i, result: false });
|
65
|
+
});
|
21
66
|
});
|
22
67
|
});
|
@@ -37,7 +37,9 @@ describe('upstream subscriptions reducer', () => {
|
|
37
37
|
it('should have error on UPSTREAM_SUBSCRIPTIONS_FAILURE', () => {
|
38
38
|
expect(reducer(initialState, {
|
39
39
|
type: types.UPSTREAM_SUBSCRIPTIONS_FAILURE,
|
40
|
-
|
40
|
+
payload: {
|
41
|
+
message: 'Unable to process request.',
|
42
|
+
},
|
41
43
|
})).toEqual(errorState);
|
42
44
|
});
|
43
45
|
|
@@ -48,10 +50,13 @@ describe('upstream subscriptions reducer', () => {
|
|
48
50
|
})).toEqual(saveSuccessState);
|
49
51
|
});
|
50
52
|
|
51
|
-
it('should have error on
|
53
|
+
it('should have error on SAVE_UPSTREAM_SUBSCRIPTIONS_FAILURE', () => {
|
52
54
|
expect(reducer(initialSaveState, {
|
53
55
|
type: types.SAVE_UPSTREAM_SUBSCRIPTIONS_FAILURE,
|
54
|
-
|
56
|
+
payload: {
|
57
|
+
message: 'Unable to process request.',
|
58
|
+
result: errorResult,
|
59
|
+
},
|
55
60
|
})).toEqual(saveErrorState);
|
56
61
|
});
|
57
62
|
});
|
@@ -6,9 +6,22 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
6
6
|
componentClass="div"
|
7
7
|
fluid={false}
|
8
8
|
>
|
9
|
-
<
|
10
|
-
|
11
|
-
|
9
|
+
<BreadcrumbsBar
|
10
|
+
data={
|
11
|
+
Object {
|
12
|
+
"breadcrumbItems": Array [
|
13
|
+
Object {
|
14
|
+
"caption": "Subscriptions",
|
15
|
+
"onClick": [Function],
|
16
|
+
},
|
17
|
+
Object {
|
18
|
+
"caption": "Add Subscriptions",
|
19
|
+
},
|
20
|
+
],
|
21
|
+
"isSwitchable": false,
|
22
|
+
}
|
23
|
+
}
|
24
|
+
/>
|
12
25
|
<LoadingState
|
13
26
|
loading={false}
|
14
27
|
loadingText="Loading"
|
@@ -107,7 +120,7 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
107
120
|
],
|
108
121
|
"label": "Available Entitlements",
|
109
122
|
},
|
110
|
-
"property": "
|
123
|
+
"property": "available",
|
111
124
|
},
|
112
125
|
Object {
|
113
126
|
"cell": Object {
|
@@ -193,7 +206,7 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
193
206
|
block={false}
|
194
207
|
bsClass="btn"
|
195
208
|
bsStyle="primary"
|
196
|
-
disabled={
|
209
|
+
disabled={true}
|
197
210
|
onClick={[Function]}
|
198
211
|
type="submit"
|
199
212
|
>
|
data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import Immutable from 'seamless-immutable';
|
2
2
|
import { getTaskSuccessResponse } from '../../../Tasks/__tests__/task.fixtures';
|
3
|
+
import { toastErrorAction, failureAction } from '../../../../services/api/testHelpers';
|
3
4
|
|
4
5
|
export const initialState = Immutable({
|
5
6
|
loading: true,
|
@@ -135,10 +136,8 @@ export const getFailureActions = [
|
|
135
136
|
{
|
136
137
|
type: 'UPSTREAM_SUBSCRIPTIONS_REQUEST',
|
137
138
|
},
|
138
|
-
|
139
|
-
|
140
|
-
type: 'UPSTREAM_SUBSCRIPTIONS_FAILURE',
|
141
|
-
},
|
139
|
+
failureAction('UPSTREAM_SUBSCRIPTIONS_FAILURE'),
|
140
|
+
toastErrorAction(),
|
142
141
|
];
|
143
142
|
|
144
143
|
export const saveSuccessActions = [
|
@@ -155,8 +154,6 @@ export const saveFailureActions = [
|
|
155
154
|
{
|
156
155
|
type: 'SAVE_UPSTREAM_SUBSCRIPTIONS_REQUEST',
|
157
156
|
},
|
158
|
-
|
159
|
-
|
160
|
-
type: 'SAVE_UPSTREAM_SUBSCRIPTIONS_FAILURE',
|
161
|
-
},
|
157
|
+
failureAction('SAVE_UPSTREAM_SUBSCRIPTIONS_FAILURE'),
|
158
|
+
toastErrorAction(),
|
162
159
|
];
|
@@ -34,14 +34,18 @@ describe('subscriptions reducer', () => {
|
|
34
34
|
it('should have error on SUBSCRIPTIONS_FAILURE', () => {
|
35
35
|
expect(reducer(initialState, {
|
36
36
|
type: types.SUBSCRIPTIONS_FAILURE,
|
37
|
-
|
37
|
+
payload: {
|
38
|
+
message: 'Unable to process request.',
|
39
|
+
},
|
38
40
|
})).toEqual(errorState);
|
39
41
|
});
|
40
42
|
|
41
43
|
it('should have error on UPDATE_QUANTITY_FAILURE', () => {
|
42
44
|
expect(reducer(initialState, {
|
43
45
|
type: types.UPDATE_QUANTITY_FAILURE,
|
44
|
-
|
46
|
+
payload: {
|
47
|
+
message: 'Unable to process request.',
|
48
|
+
},
|
45
49
|
})).toEqual(errorState);
|
46
50
|
});
|
47
51
|
|
@@ -61,7 +65,9 @@ describe('subscriptions reducer', () => {
|
|
61
65
|
it('should have error on SUBSCRIPTIONS_QUANTITIES_FAILURE', () => {
|
62
66
|
expect(reducer(successState, {
|
63
67
|
type: types.SUBSCRIPTIONS_QUANTITIES_FAILURE,
|
64
|
-
|
68
|
+
payload: {
|
69
|
+
message: 'Unable to process request.',
|
70
|
+
},
|
65
71
|
})).toEqual(quantitiesErrorState);
|
66
72
|
});
|
67
73
|
});
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import Immutable from 'seamless-immutable';
|
2
|
+
import { toastErrorAction, failureAction } from '../../../services/api/testHelpers';
|
2
3
|
|
3
4
|
export const initialState = Immutable({
|
4
5
|
loading: true,
|
@@ -10,6 +11,7 @@ export const initialState = Immutable({
|
|
10
11
|
itemCount: 0,
|
11
12
|
quantitiesLoading: false,
|
12
13
|
availableQuantities: {},
|
14
|
+
tasks: [],
|
13
15
|
});
|
14
16
|
|
15
17
|
export const loadingState = Immutable({
|
@@ -242,11 +244,11 @@ export const successState = Immutable({
|
|
242
244
|
itemCount: 81,
|
243
245
|
quantitiesLoading: false,
|
244
246
|
availableQuantities: {},
|
247
|
+
tasks: [],
|
245
248
|
});
|
246
249
|
|
247
250
|
export const errorState = Immutable({
|
248
251
|
loading: false,
|
249
|
-
error: 'Unable to process request.',
|
250
252
|
pagination: {
|
251
253
|
page: 0,
|
252
254
|
perPage: 20,
|
@@ -255,6 +257,7 @@ export const errorState = Immutable({
|
|
255
257
|
results: [],
|
256
258
|
quantitiesLoading: false,
|
257
259
|
availableQuantities: {},
|
260
|
+
tasks: [],
|
258
261
|
});
|
259
262
|
|
260
263
|
export const quantitiesSuccessState = Immutable({
|
@@ -275,7 +278,6 @@ export const loadingQuantitiesState = Immutable({
|
|
275
278
|
export const quantitiesErrorState = Immutable({
|
276
279
|
...successState,
|
277
280
|
quantitiesLoading: false,
|
278
|
-
quantitiesError: 'Unable to process request.',
|
279
281
|
});
|
280
282
|
|
281
283
|
export const successActions = [
|
@@ -307,10 +309,8 @@ export const failureActions = [
|
|
307
309
|
{
|
308
310
|
type: 'SUBSCRIPTIONS_REQUEST',
|
309
311
|
},
|
310
|
-
|
311
|
-
|
312
|
-
type: 'SUBSCRIPTIONS_FAILURE',
|
313
|
-
},
|
312
|
+
failureAction('SUBSCRIPTIONS_FAILURE'),
|
313
|
+
toastErrorAction(),
|
314
314
|
];
|
315
315
|
|
316
316
|
export const poolsUpdate = [{
|
@@ -337,20 +337,16 @@ export const updateQuantityFailureActions = [
|
|
337
337
|
type: 'UPDATE_QUANTITY_REQUEST',
|
338
338
|
quantities: poolsUpdate,
|
339
339
|
},
|
340
|
-
|
341
|
-
|
342
|
-
type: 'UPDATE_QUANTITY_FAILURE',
|
343
|
-
},
|
340
|
+
failureAction('UPDATE_QUANTITY_FAILURE'),
|
341
|
+
toastErrorAction(),
|
344
342
|
];
|
345
343
|
|
346
344
|
export const loadQuantitiesFailureActions = [
|
347
345
|
{
|
348
346
|
type: 'SUBSCRIPTIONS_QUANTITIES_REQUEST',
|
349
347
|
},
|
350
|
-
|
351
|
-
|
352
|
-
type: 'SUBSCRIPTIONS_QUANTITIES_FAILURE',
|
353
|
-
},
|
348
|
+
failureAction('SUBSCRIPTIONS_QUANTITIES_FAILURE', 'Request failed with status code 500'),
|
349
|
+
toastErrorAction('Request failed with status code 500'),
|
354
350
|
];
|
355
351
|
|
356
352
|
export const loadQuantitiesSuccessActions = [
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import classNames from 'classnames';
|
4
4
|
import { sprintf } from 'jed';
|
5
5
|
import { cloneDeep, findIndex, isEqual } from 'lodash';
|
6
|
-
import { Table
|
6
|
+
import { Table } from 'patternfly-react';
|
7
7
|
import { LoadingState } from '../../../../move_to_pf/LoadingState';
|
8
8
|
import { Table as ForemanTable, TableBody as ForemanTableBody } from '../../../../move_to_foreman/components/common/table';
|
9
9
|
import ConfirmDialog from '../../../../move_to_foreman/components/common/ConfirmDialog';
|
@@ -25,23 +25,6 @@ const emptyStateData = {
|
|
25
25
|
},
|
26
26
|
};
|
27
27
|
|
28
|
-
const ErrorAlerts = ({ errors }) => {
|
29
|
-
const alerts = errors.filter(Boolean).map(e => (
|
30
|
-
<Alert type={Alert.ALERT_TYPE_ERROR} key={e}>
|
31
|
-
<span>{e}</span>
|
32
|
-
</Alert>
|
33
|
-
));
|
34
|
-
|
35
|
-
return (
|
36
|
-
<div>
|
37
|
-
{alerts}
|
38
|
-
</div>
|
39
|
-
);
|
40
|
-
};
|
41
|
-
ErrorAlerts.propTypes = {
|
42
|
-
errors: PropTypes.arrayOf(PropTypes.string).isRequired,
|
43
|
-
};
|
44
|
-
|
45
28
|
class SubscriptionsTable extends Component {
|
46
29
|
constructor(props) {
|
47
30
|
super(props);
|
@@ -49,7 +32,7 @@ class SubscriptionsTable extends Component {
|
|
49
32
|
this.state = {
|
50
33
|
rows: undefined,
|
51
34
|
subscriptions: undefined,
|
52
|
-
|
35
|
+
groupedSubscriptions: undefined,
|
53
36
|
updatedQuantity: {},
|
54
37
|
editing: false,
|
55
38
|
showUpdateConfirmDialog: false,
|
@@ -64,14 +47,14 @@ class SubscriptionsTable extends Component {
|
|
64
47
|
nextProps.subscriptions !== undefined &&
|
65
48
|
!isEqual(nextProps.subscriptions, prevState.subscriptions)
|
66
49
|
) {
|
67
|
-
const
|
50
|
+
const groupedSubscriptions = groupSubscriptionsByProductId(nextProps.subscriptions);
|
68
51
|
const rows = buildTableRows(
|
69
|
-
|
52
|
+
groupedSubscriptions,
|
70
53
|
nextProps.subscriptions.availableQuantities,
|
71
54
|
prevState.updatedQuantity,
|
72
55
|
);
|
73
56
|
|
74
|
-
return { rows,
|
57
|
+
return { rows, groupedSubscriptions, subscriptions: nextProps.subscriptions };
|
75
58
|
}
|
76
59
|
|
77
60
|
return null;
|
@@ -79,19 +62,19 @@ class SubscriptionsTable extends Component {
|
|
79
62
|
|
80
63
|
toggleSubscriptionGroup(groupId) {
|
81
64
|
const { subscriptions } = this.props;
|
82
|
-
const {
|
83
|
-
const { open } =
|
65
|
+
const { groupedSubscriptions, updatedQuantity } = this.state;
|
66
|
+
const { open } = groupedSubscriptions[groupId];
|
84
67
|
|
85
|
-
|
68
|
+
groupedSubscriptions[groupId].open = !open;
|
86
69
|
|
87
70
|
|
88
71
|
const rows = buildTableRows(
|
89
|
-
|
72
|
+
groupedSubscriptions,
|
90
73
|
subscriptions.availableQuantities,
|
91
74
|
updatedQuantity,
|
92
75
|
);
|
93
76
|
|
94
|
-
this.setState({ rows,
|
77
|
+
this.setState({ rows, groupedSubscriptions });
|
95
78
|
}
|
96
79
|
|
97
80
|
enableEditing(editingState) {
|
@@ -102,11 +85,11 @@ class SubscriptionsTable extends Component {
|
|
102
85
|
}
|
103
86
|
|
104
87
|
updateRows(updatedQuantity) {
|
105
|
-
const {
|
88
|
+
const { groupedSubscriptions } = this.state;
|
106
89
|
const { subscriptions } = this.props;
|
107
90
|
|
108
91
|
const rows = buildTableRows(
|
109
|
-
|
92
|
+
groupedSubscriptions,
|
110
93
|
subscriptions.availableQuantities,
|
111
94
|
updatedQuantity,
|
112
95
|
);
|
@@ -158,15 +141,15 @@ class SubscriptionsTable extends Component {
|
|
158
141
|
|
159
142
|
render() {
|
160
143
|
const { subscriptions } = this.props;
|
161
|
-
const {
|
144
|
+
const { groupedSubscriptions } = this.state;
|
162
145
|
|
163
146
|
const groupingController = {
|
164
147
|
isCollapseable: ({ rowData }) =>
|
165
148
|
// it is the first subscription in the group
|
166
|
-
rowData.id ===
|
149
|
+
rowData.id === groupedSubscriptions[rowData.product_id].subscriptions[0].id &&
|
167
150
|
// the group contains more then one subscription
|
168
|
-
|
169
|
-
isCollapsed: ({ rowData }) => !
|
151
|
+
groupedSubscriptions[rowData.product_id].subscriptions.length > 1,
|
152
|
+
isCollapsed: ({ rowData }) => !groupedSubscriptions[rowData.product_id].open,
|
170
153
|
toggle: ({ rowData }) => this.toggleSubscriptionGroup(rowData.product_id),
|
171
154
|
};
|
172
155
|
|
@@ -258,12 +241,6 @@ class SubscriptionsTable extends Component {
|
|
258
241
|
|
259
242
|
return (
|
260
243
|
<LoadingState loading={subscriptions.loading} loadingText={__('Loading')}>
|
261
|
-
<ErrorAlerts
|
262
|
-
errors={[
|
263
|
-
subscriptions.error,
|
264
|
-
subscriptions.quantitiesError,
|
265
|
-
]}
|
266
|
-
/>
|
267
244
|
<ForemanTable
|
268
245
|
columns={columnsDefinition}
|
269
246
|
emptyState={emptyStateData}
|