[SDC] Onboarding 1710 rebase.
[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, onboardingMethod as onboardingMethodTypes} 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, hasImages}) => {
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.IMAGES + '|' + componentId,
68                         name: i18n('Images'),
69                         disabled: false,
70                         hidden: (!hasImages),
71                         meta
72                 }, {
73                         id: navigationItems.PROCESS_DETAILS + '|' + componentId,
74                         name: i18n('Process Details'),
75                         disabled: false,
76                         meta
77                 }, {
78                         id: navigationItems.MONITORING + '|' + componentId,
79                         name: i18n('Monitoring'),
80                         disabled: false,
81                         meta
82                 }
83         ]);
84
85         return groups;
86 };
87
88 const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds, imagesNavigationList}) => {
89         const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct;
90         const {id, name, onboardingMethod} = currentSoftwareProduct;
91         const groups = [{
92                 id: id,
93                 name: name,
94                 items: [
95                         {
96                                 id: navigationItems.VENDOR_SOFTWARE_PRODUCT,
97                                 name: i18n('Overview'),
98                                 disabled: false,
99                                 meta
100                         }, {
101                                 id: navigationItems.GENERAL,
102                                 name: i18n('General'),
103                                 disabled: false,
104                                 meta
105                         },
106                         {
107                                 id: navigationItems.DEPLOYMENT_FLAVORS,
108                                 name: i18n('Deployment Flavors'),
109                                 disabled: false,
110                                 hidden: onboardingMethod !== onboardingMethodTypes.MANUAL,
111                                 meta
112                         }, {
113                                 id: navigationItems.PROCESS_DETAILS,
114                                 name: i18n('Process Details'),
115                                 disabled: false,
116                                 meta
117                         }, {
118                                 id: navigationItems.NETWORKS,
119                                 name: i18n('Networks'),
120                                 disabled: false,
121                                 meta
122                         }, {
123                                 id: navigationItems.ATTACHMENTS,
124                                 name: i18n('Attachments'),
125                                 disabled: false,
126                                 hidden: !doesHeatDataExist(meta.heatSetup),
127                                 meta
128                         }, {
129                                 id: navigationItems.ACTIVITY_LOG,
130                                 name: i18n('Activity Log'),
131                                 disabled: false,
132                                 meta
133                         }, {
134                                 id: navigationItems.DEPENDENCIES,
135                                 name: i18n('Component Dependencies'),
136                                 hidden: componentsList.length <= 1,
137                                 disabled: false,
138                                 meta
139                         }, {
140                                 id: navigationItems.COMPONENTS,
141                                 name: i18n('Components'),
142                                 hidden: componentsList.length <= 0,
143                                 meta,
144                                 expanded: mapOfExpandedIds[navigationItems.COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
145                                 items: [
146                                         ...componentsList.map(({id, displayName}) => ({
147                                                 id: navigationItems.COMPONENTS + '|' + id,
148                                                 name: displayName,
149                                                 meta,
150                                                 expanded: mapOfExpandedIds[navigationItems.COMPONENTS + '|' + id] === true  && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
151                                                 items: buildComponentNavigationBarGroups({componentId: id, meta,
152                                                         hasImages : (onboardingMethod === onboardingMethodTypes.MANUAL || imagesNavigationList[id] === true)})
153                                         }))
154                                 ]
155                         }
156                 ]
157         }];
158         let activeItemId = getActiveNavigationId(screen, componentId);
159         return {
160                 activeItemId, groups
161         };
162 };
163
164 const buildVersionControllerProps = (softwareProduct) => {
165         const {softwareProductEditor} = softwareProduct;
166         const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor;
167
168         const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct;
169         const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser);
170
171         return {
172                 status, isCheckedOut, version, viewableVersions,
173                 isFormDataValid: isValidityData
174         };
175 };
176
177 function buildMeta({softwareProduct, componentId, softwareProductDependencies}) {
178         const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire, softwareProductAttachments} = softwareProduct;
179         const {data: currentSoftwareProduct = {}} = softwareProductEditor;
180         const {version} = currentSoftwareProduct;
181         const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
182         const {qdata} = softwareProductQuestionnaire;
183         const {heatSetup, heatSetupCache} = softwareProductAttachments;
184         let currentComponentMeta = {};
185         if(componentId) {
186                 const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents;
187                 currentComponentMeta = {componentData, componentQdata};
188         }
189         const meta = {softwareProduct: currentSoftwareProduct, qdata, version, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies};
190         return meta;
191 }
192
193 const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
194         const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct;
195         const {mapOfExpandedIds = []} = softwareProductEditor;
196         const {componentsList = [], images: {imagesNavigationList}} = softwareProductComponents;
197
198         const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies});
199         return {
200                 versionControllerProps: buildVersionControllerProps(softwareProduct),
201                 navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds, imagesNavigationList}),
202                 meta
203         };
204 };
205
206 const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId,
207                 meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies,
208                 currentComponentMeta: {componentData, componentQdata}}}) => {
209         let promise;
210         if (isReadOnlyMode) {
211                 promise = Promise.resolve();
212         } else {
213                 switch(screen) {
214                         case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
215                                 promise = SoftwareProductDependenciesActionHelper.saveDependencies(dispatch,{softwareProductId, version, dependenciesList: softwareProductDependencies});
216                         case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
217                                 promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
218                                 break;
219                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
220                                 promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
221                                         {softwareProductId, version, vspComponentId: componentId, componentData, qdata: componentQdata});
222                                 break;
223                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
224                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
225                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
226                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES:
227                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
228                                 promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata: componentQdata});
229                                 break;
230                         default:
231                                 promise = Promise.resolve();
232                                 break;
233                 }
234         }
235         return promise;
236 };
237
238
239 const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentComponentId}) => {
240         const [nextScreen, nextComponentId] = id.split('|');
241         switch(nextScreen) {
242                 case navigationItems.COMPONENTS:
243                         if(nextComponentId === currentComponentId) {
244                                 OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId});
245                         } else {
246                                 OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
247                         }
248                         break;
249                 case navigationItems.GENERAL:
250                         OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
251                         break;
252                 case navigationItems.COMPUTE:
253                         OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version});
254                         break;
255                 case navigationItems.LOAD_BALANCING:
256                         OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version});
257                         break;
258                 case navigationItems.NETWORKS:
259                         OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version});
260                         break;
261                 case navigationItems.IMAGES:
262                         OnboardingActionHelper.navigateToComponentImages(dispatch, {softwareProductId, componentId: nextComponentId, version});
263                         break;
264                 case navigationItems.STORAGE:
265                         OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version});
266                         break;
267                 case navigationItems.PROCESS_DETAILS:
268                         OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version});
269                         break;
270                 case navigationItems.MONITORING:
271                         OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version});
272                         break;
273         }
274 };
275
276 const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => {
277
278         const props = {
279                 onVersionSwitching: (version, meta) => {
280                         SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
281                         props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), meta, version});
282                 },
283                 onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})),
284                 onNavigate: ({id, meta, version}) => {
285                         let {heatSetup, heatSetupCache} = meta;
286                         let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ?
287                                                                 HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
288                                                                 Promise.resolve();
289                         let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}) : Promise.resolve();
290                         version = version || (meta ? meta.version : undefined);
291                         Promise.all([preNavigate, heatSetupPopupPromise]).then(() => {
292                                 switch(id) {
293                                         case navigationItems.VENDOR_SOFTWARE_PRODUCT:
294                                                 OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
295                                                 break;
296                                         case navigationItems.GENERAL:
297                                                 OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version});
298                                                 break;
299                                         case navigationItems.DEPLOYMENT_FLAVORS:
300                                                 OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version});
301                                                 break;
302                                         case navigationItems.PROCESS_DETAILS:
303                                                 OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version});
304                                                 break;
305                                         case navigationItems.NETWORKS:
306                                                 OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version});
307                                                 break;
308                                         case navigationItems.DEPENDENCIES:
309                                                 OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version});
310                                                 break;
311                                         case navigationItems.ATTACHMENTS:
312                                                 OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version});
313                                                 break;
314                                         case navigationItems.COMPONENTS:
315                                                 OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version});
316                                                 break;
317                                         case navigationItems.ACTIVITY_LOG:
318                                                 OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version});
319                                                 break;
320                                         default:
321                                                 onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId});
322                                                 break;
323                                 }
324                         }).catch((e) => {console.error(e);});
325                 }
326         };
327
328         switch (screen) {
329                 case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE:
330                 case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
331                 case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
332                 case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
333                 case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
334                 case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
335                 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
336                 case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT:
337                 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
338                 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
339                         props.onSave = () => {
340                                 return Promise.resolve();
341                         };
342                         break;
343                 default:
344                         props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
345                         break;
346         }
347
348
349         props.onVersionControllerAction = (action, version, meta) => {
350                 let {heatSetup, heatSetupCache} = meta;
351                 let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.CHECK_IN ?
352                                                                 HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
353                                                                 Promise.resolve();
354                 heatSetupPopupPromise.then(() => {
355                         return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version}).then(({newVersion}) => {
356                                 //props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), version});
357                                 if(screen === enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG) {
358                                         OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: newVersion});
359                                 }
360                         });
361                 }).catch((e) => {console.error(e);});
362         };
363         return props;
364 };
365
366 export default connect(mapStateToProps, mapActionsToProps)(TabulatedEditor);