12f68a2afea192bab27f53f9fc18777ef32a6fbc
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / SoftwareProduct.js
1 /*!
2  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13  * or implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 import {connect} from 'react-redux';
17
18 import i18n from 'nfvo-utils/i18n/i18n.js';
19 import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
20 import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx';
21
22 import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
23 import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
24
25 import {navigationItems, mapScreenToNavigationItem} from './SoftwareProductConstants.js';
26 import SoftwareProductActionHelper from './SoftwareProductActionHelper.js';
27 import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
28 import SoftwareProductDependenciesActionHelper from './dependencies/SoftwareProductDependenciesActionHelper.js';
29 import {doesHeatDataExist} from './attachments/SoftwareProductAttachmentsUtils.js';
30
31 import HeatSetupActionHelper from './attachments/setup/HeatSetupActionHelper.js';
32 import { actionsEnum as versionControllerActions } from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
33
34 function getActiveNavigationId(screen, componentId) {
35         let activeItemId = componentId ? mapScreenToNavigationItem[screen] + '|' + componentId : mapScreenToNavigationItem[screen];
36         return activeItemId;
37 }
38
39 const buildComponentNavigationBarGroups = ({componentId, meta}) => {
40         const groups = ([
41                 {
42                         id: navigationItems.GENERAL + '|' + componentId,
43                         name: i18n('General'),
44                         disabled: false,
45                         meta
46                 }, {
47                         id: navigationItems.COMPUTE + '|' + componentId,
48                         name: i18n('Compute'),
49                         disabled: false,
50                         meta
51                 }, {
52                         id: navigationItems.LOAD_BALANCING + '|' + componentId,
53                         name: i18n('High Availability & Load Balancing'),
54                         disabled: false,
55                         meta
56                 }, {
57                         id: navigationItems.NETWORKS + '|' + componentId,
58                         name: i18n('Networks'),
59                         disabled: false,
60                         meta
61                 }, {
62                         id: navigationItems.STORAGE + '|' + componentId,
63                         name: i18n('Storage'),
64                         disabled: false,
65                         meta
66                 }, {
67                         id: navigationItems.PROCESS_DETAILS + '|' + componentId,
68                         name: i18n('Process Details'),
69                         disabled: false,
70                         meta
71                 }, {
72                         id: navigationItems.MONITORING + '|' + componentId,
73                         name: i18n('Monitoring'),
74                         disabled: false,
75                         meta
76                 }
77         ]);
78
79         return groups;
80 };
81
82 const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}) => {
83         const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct;
84         const {id, name} = currentSoftwareProduct;
85         const groups = [{
86                 id: id,
87                 name: name,
88                 items: [
89                         {
90                                 id: navigationItems.VENDOR_SOFTWARE_PRODUCT,
91                                 name: i18n('Overview'),
92                                 disabled: false,
93                                 meta
94                         }, {
95                                 id: navigationItems.GENERAL,
96                                 name: i18n('General'),
97                                 disabled: false,
98                                 meta
99                         }, {
100                                 id: navigationItems.PROCESS_DETAILS,
101                                 name: i18n('Process Details'),
102                                 disabled: false,
103                                 meta
104                         }, {
105                                 id: navigationItems.NETWORKS,
106                                 name: i18n('Networks'),
107                                 disabled: false,
108                                 meta
109                         }, {
110                                 id: navigationItems.ATTACHMENTS,
111                                 name: i18n('Attachments'),
112                                 disabled: false,
113                                 hidden: !doesHeatDataExist(meta.heatSetup),
114                                 meta
115                         }, {
116                                 id: navigationItems.ACTIVITY_LOG,
117                                 name: i18n('Activity Log'),
118                                 disabled: false,
119                                 meta
120                         }, {
121                                 id: navigationItems.DEPENDENCIES,
122                                 name: i18n('Component Dependencies'),
123                                 hidden: componentsList.length <= 1,
124                                 disabled: false,
125                                 meta
126                         }, {
127                                 id: navigationItems.COMPONENTS,
128                                 name: i18n('Components'),
129                                 hidden: componentsList.length <= 0,
130                                 meta,
131                                 expanded: mapOfExpandedIds[navigationItems.COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
132                                 items: [
133                                         ...componentsList.map(({id, displayName}) => ({
134                                                 id: navigationItems.COMPONENTS + '|' + id,
135                                                 name: displayName,
136                                                 meta,
137                                                 expanded: mapOfExpandedIds[navigationItems.COMPONENTS + '|' + id] === true  && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
138                                                 items: buildComponentNavigationBarGroups({componentId: id, meta})
139                                         }))
140                                 ]
141                         }
142                 ]
143         }];
144         let activeItemId = getActiveNavigationId(screen, componentId);
145         return {
146                 activeItemId, groups
147         };
148 };
149
150 const buildVersionControllerProps = (softwareProduct) => {
151         const {softwareProductEditor} = softwareProduct;
152         const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor;
153
154         const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct;
155         const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser);
156
157         return {
158                 status, isCheckedOut, version, viewableVersions,
159                 isFormDataValid: isValidityData
160         };
161 };
162
163 function buildMeta({softwareProduct, componentId, softwareProductDependencies}) {
164         const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire, softwareProductAttachments} = softwareProduct;
165         const {data: currentSoftwareProduct = {}} = softwareProductEditor;
166         const {version} = currentSoftwareProduct;
167         const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
168         const {qdata} = softwareProductQuestionnaire;
169         const {heatSetup, heatSetupCache} = softwareProductAttachments;
170         let currentComponentMeta = {};
171         if(componentId) {
172                 const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents;
173                 currentComponentMeta = {componentData, componentQdata};
174         }
175         const meta = {softwareProduct: currentSoftwareProduct, qdata, version, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies};
176         return meta;
177 }
178
179 const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
180         const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct;
181         const {mapOfExpandedIds = []} = softwareProductEditor;
182         const {componentsList = []} = softwareProductComponents;
183         const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies});
184         return {
185                 versionControllerProps: buildVersionControllerProps(softwareProduct),
186                 navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}),
187                 meta
188         };
189 };
190
191 const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, 
192                 meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies, 
193                 currentComponentMeta: {componentData, componentQdata}}}) => {
194         let promise;
195         if (isReadOnlyMode) {
196                 promise = Promise.resolve();
197         } else {
198                 switch(screen) {
199                         case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
200                                 promise = SoftwareProductDependenciesActionHelper.saveDependencies(dispatch,{softwareProductId, version, dependenciesList: softwareProductDependencies});
201                         case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
202                                 promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
203                                 break;
204                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
205                                 promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
206                                         {softwareProductId, version, vspComponentId: componentId, componentData, qdata: componentQdata});
207                                 break;
208                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
209                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
210                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
211                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
212                                 promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata: componentQdata});
213                                 break;
214                         default:
215                                 promise = Promise.resolve();
216                                 break;
217                 }
218         }
219         return promise;
220 };
221
222
223 const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentComponentId}) => {
224         const [nextScreen, nextComponentId] = id.split('|');
225         switch(nextScreen) {
226                 case navigationItems.COMPONENTS:
227                         if(nextComponentId === currentComponentId) {
228                                 OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId});
229                         } else {
230                                 OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
231                         }
232                         break;
233                 case navigationItems.GENERAL:
234                         OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
235                         break;
236                 case navigationItems.COMPUTE:
237                         OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version});
238                         break;
239                 case navigationItems.LOAD_BALANCING:
240                         OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version});
241                         break;
242                 case navigationItems.NETWORKS:
243                         OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version});
244                         break;
245                 case navigationItems.STORAGE:
246                         OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version});
247                         break;
248                 case navigationItems.PROCESS_DETAILS:
249                         OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version});
250                         break;
251                 case navigationItems.MONITORING:
252                         OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version});
253                         break;
254         }
255 };
256
257 const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => {
258
259         const props = {
260                 onVersionSwitching: (version, meta) => {
261                         SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
262                         props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), meta, version});
263                 },
264                 onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})),
265                 onNavigate: ({id, meta, version}) => {
266                         let {heatSetup, heatSetupCache} = meta;
267                         let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ?
268                                                                 HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
269                                                                 Promise.resolve();                                              
270                         let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}) : Promise.resolve();
271                         version = version || (meta ? meta.version : undefined);
272                         Promise.all([preNavigate, heatSetupPopupPromise]).then(() => {
273                                 switch(id) {
274                                         case navigationItems.VENDOR_SOFTWARE_PRODUCT:
275                                                 OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
276                                                 break;
277                                         case navigationItems.GENERAL:
278                                                 OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version});
279                                                 break;
280                                         case navigationItems.PROCESS_DETAILS:
281                                                 OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version});
282                                                 break;
283                                         case navigationItems.NETWORKS:
284                                                 OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version});
285                                                 break;
286                                         case navigationItems.DEPENDENCIES:
287                                                 OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version});
288                                                 break;
289                                         case navigationItems.ATTACHMENTS:
290                                                 OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version});
291                                                 break;
292                                         case navigationItems.COMPONENTS:
293                                                 OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version});
294                                                 break;
295                                         case navigationItems.ACTIVITY_LOG:
296                                                 OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version});
297                                                 break;
298                                         default:
299                                                 onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId});
300                                                 break;
301                                 }
302                         }).catch(() => {});
303                 }
304         };
305
306         switch (screen) {
307                 case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE:
308                 case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
309                 case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
310                 case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
311                 case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
312                 case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
313                 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
314                 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
315                 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
316                         props.onSave = () => {
317                                 return Promise.resolve();
318                         };
319                         break;
320                 default:
321                         props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
322                         break;
323         }
324
325
326         props.onVersionControllerAction = (action, version, meta) => {
327                 let {heatSetup, heatSetupCache} = meta;
328                 let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.CHECK_IN ?
329                                                                 HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
330                                                                 Promise.resolve();
331                 heatSetupPopupPromise.then(() => {
332                         return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version}).then(({newVersion}) => {
333                                 //props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), version});
334                                 if(screen === enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG) {
335                                         OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: newVersion});
336                                 }
337                         });
338                 }).catch(() => {});
339         };
340         return props;
341 };
342
343 export default connect(mapStateToProps, mapActionsToProps)(TabulatedEditor);