Add plan description to plan cards

Change-Id: I79e3d8025276974317cf905e6acce10dc23ccb98
Closes-bug: #1701277
This commit is contained in:
Ana Krivokapic 2017-06-30 21:07:15 +02:00
parent 1c665a1d50
commit 8c12f001aa
6 changed files with 66 additions and 14 deletions

View File

@ -0,0 +1,4 @@
fixes:
- |
Fixes `bug 1701277 <https://launchpad.net/bugs/1701277>`__
Display plan description on plan cards

View File

@ -137,17 +137,32 @@ describe('PlansActions', () => {
});
});
let apiResponse = {
let apiResponseMistral = {
output: '{ "result": [ "overcloud", "another-cloud" ] }'
};
let apiResponseSwift = [
{ responseText: `description: Default deployment plan\nname: overcloud` },
{ responseText: `description: My custom plan\nname: another-cloud` }
];
describe('fetchPlans', () => {
beforeEach(done => {
let swiftAlreadyCalled = false;
spyOn(PlansActions, 'requestPlans');
spyOn(PlansActions, 'receivePlans');
spyOn(MistralApiService, 'runAction').and.callFake(
createResolvingPromise(apiResponse)
createResolvingPromise(apiResponseMistral)
);
spyOn(SwiftApiService, 'getObject').and.callFake(() => {
if (swiftAlreadyCalled) {
return apiResponseSwift[1];
} else {
swiftAlreadyCalled = true;
return apiResponseSwift[0];
}
});
// Mock the service call.
// Call the action creator and the resulting action.
// In this case, dispatch and getState are just empty placeHolders.
@ -164,8 +179,8 @@ describe('PlansActions', () => {
it('dispatches receivePlans', () => {
expect(PlansActions.receivePlans).toHaveBeenCalledWith([
'overcloud',
'another-cloud'
{ name: 'overcloud', description: 'Default deployment plan' },
{ name: 'another-cloud', description: 'My custom plan' }
]);
});
});

View File

@ -95,7 +95,10 @@ describe('plansReducer state', () => {
isFetchingPlans: true,
all: List()
}),
PlansActions.receivePlans(['overcloud', 'another-cloud'])
PlansActions.receivePlans([
{ name: 'overcloud', description: 'Default deployment plan' },
{ name: 'another-cloud', description: 'My custom plan' }
])
);
});
@ -118,8 +121,14 @@ describe('plansReducer state', () => {
state = plansReducer(
Map({
all: Map({
'some-cloud': new Plan({ name: 'some-cloud' }),
overcloud: new Plan({ name: 'overcloud' })
'some-cloud': new Plan({
name: 'some-cloud',
description: 'some cloud desc'
}),
overcloud: new Plan({
name: 'overcloud',
description: 'Default deployment plan'
})
})
}),
PlansActions.receivePlan('overcloud', {

View File

@ -18,6 +18,7 @@ import { defineMessages } from 'react-intl';
import { fromJS } from 'immutable';
import { normalize, arrayOf } from 'normalizr';
import when from 'when';
import yaml from 'js-yaml';
import logger from '../services/logger';
import MistralApiService from '../services/MistralApiService';
@ -30,6 +31,7 @@ import SwiftApiErrorHandler from '../services/SwiftApiErrorHandler';
import SwiftApiService from '../services/SwiftApiService';
import MistralConstants from '../constants/MistralConstants';
import { getAppConfig } from '../services/utils';
import { PLAN_ENVIRONMENT } from '../constants/PlansConstants';
const messages = defineMessages({
planCreatedNotificationTitle: {
@ -85,8 +87,29 @@ export default {
dispatch(this.requestPlans());
MistralApiService.runAction(MistralConstants.PLAN_LIST)
.then(response => {
let plans = JSON.parse(response.output).result || [];
dispatch(this.receivePlans(plans));
const planNames = JSON.parse(response.output).result;
when
.all(
planNames.map(name =>
SwiftApiService.getObject(name, PLAN_ENVIRONMENT)
)
)
.then(responses => {
const plans = responses.map(response => {
const { name, description } = yaml.safeLoad(
response.responseText
);
return { name, description };
});
dispatch(this.receivePlans(plans));
})
.catch(error => {
logger.error(
'Error in PlansActions.fetchPlans',
error.stack || error
);
dispatch(this.receivePlans(planNames.map(name => ({ name }))));
});
})
.catch(error => {
logger.error(

View File

@ -41,3 +41,5 @@ export default keyMirror({
EXPORT_PLAN_SUCCESS: null,
EXPORT_PLAN_FAILED: null
});
export const PLAN_ENVIRONMENT = 'plan-environment.yaml';

View File

@ -42,14 +42,13 @@ export default function plansReducer(state = initialState, action) {
return state.set('isFetchingPlans', true);
case PlansConstants.RECEIVE_PLANS: {
let planData = {};
action.payload.forEach(name => {
planData[name] = new Plan({ name: name });
});
return state
.set('isFetchingPlans', false)
.set('plansLoaded', true)
.set('all', Map(planData));
.set(
'all',
Map(action.payload.map(plan => [plan.name, new Plan(plan)]))
);
}
case PlansConstants.PLAN_CHOSEN: