2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 import {connect} from 'react-redux';
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';
22 import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
23 import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
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';
31 import HeatSetupActionHelper from './attachments/setup/HeatSetupActionHelper.js';
32 import { actionsEnum as versionControllerActions } from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
34 function getActiveNavigationId(screen, componentId) {
35 let activeItemId = componentId ? mapScreenToNavigationItem[screen] + '|' + componentId : mapScreenToNavigationItem[screen];
39 const buildComponentNavigationBarGroups = ({componentId, meta, hasImages}) => {
42 id: navigationItems.GENERAL + '|' + componentId,
43 name: i18n('General'),
47 id: navigationItems.COMPUTE + '|' + componentId,
48 name: i18n('Compute'),
52 id: navigationItems.LOAD_BALANCING + '|' + componentId,
53 name: i18n('High Availability & Load Balancing'),
57 id: navigationItems.NETWORKS + '|' + componentId,
58 name: i18n('Networks'),
62 id: navigationItems.STORAGE + '|' + componentId,
63 name: i18n('Storage'),
67 id: navigationItems.IMAGES + '|' + componentId,
73 id: navigationItems.PROCESS_DETAILS + '|' + componentId,
74 name: i18n('Process Details'),
78 id: navigationItems.MONITORING + '|' + componentId,
79 name: i18n('Monitoring'),
88 const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds, imagesNavigationList}) => {
89 const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct;
90 const {id, name, onboardingMethod} = currentSoftwareProduct;
96 id: navigationItems.VENDOR_SOFTWARE_PRODUCT,
97 name: i18n('Overview'),
101 id: navigationItems.GENERAL,
102 name: i18n('General'),
107 id: navigationItems.DEPLOYMENT_FLAVORS,
108 name: i18n('Deployment Flavors'),
110 hidden: onboardingMethod !== onboardingMethodTypes.MANUAL,
113 id: navigationItems.PROCESS_DETAILS,
114 name: i18n('Process Details'),
118 id: navigationItems.NETWORKS,
119 name: i18n('Networks'),
123 id: navigationItems.ATTACHMENTS,
124 name: i18n('Attachments'),
126 hidden: !doesHeatDataExist(meta.heatSetup),
129 id: navigationItems.ACTIVITY_LOG,
130 name: i18n('Activity Log'),
134 id: navigationItems.DEPENDENCIES,
135 name: i18n('Component Dependencies'),
136 hidden: componentsList.length <= 1,
140 id: navigationItems.COMPONENTS,
141 name: i18n('Components'),
142 hidden: componentsList.length <= 0,
144 expanded: mapOfExpandedIds[navigationItems.COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
146 ...componentsList.map(({id, displayName}) => ({
147 id: navigationItems.COMPONENTS + '|' + id,
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)})
158 let activeItemId = getActiveNavigationId(screen, componentId);
164 const buildVersionControllerProps = (softwareProduct) => {
165 const {softwareProductEditor} = softwareProduct;
166 const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor;
168 const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct;
169 const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser);
172 status, isCheckedOut, version, viewableVersions,
173 isFormDataValid: isValidityData
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 = {};
186 const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents;
187 currentComponentMeta = {componentData, componentQdata};
189 const meta = {softwareProduct: currentSoftwareProduct, qdata, version, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies};
193 const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
194 const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct;
195 const {mapOfExpandedIds = []} = softwareProductEditor;
196 const {componentsList = [], images: {imagesNavigationList}} = softwareProductComponents;
198 const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies});
200 versionControllerProps: buildVersionControllerProps(softwareProduct),
201 navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds, imagesNavigationList}),
206 const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId,
207 meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies,
208 currentComponentMeta: {componentData, componentQdata}}}) => {
210 if (isReadOnlyMode) {
211 promise = Promise.resolve();
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});
219 case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
220 promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
221 {softwareProductId, version, vspComponentId: componentId, componentData, qdata: componentQdata});
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});
231 promise = Promise.resolve();
239 const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentComponentId}) => {
240 const [nextScreen, nextComponentId] = id.split('|');
242 case navigationItems.COMPONENTS:
243 if(nextComponentId === currentComponentId) {
244 OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId});
246 OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
249 case navigationItems.GENERAL:
250 OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
252 case navigationItems.COMPUTE:
253 OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version});
255 case navigationItems.LOAD_BALANCING:
256 OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version});
258 case navigationItems.NETWORKS:
259 OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version});
261 case navigationItems.IMAGES:
262 OnboardingActionHelper.navigateToComponentImages(dispatch, {softwareProductId, componentId: nextComponentId, version});
264 case navigationItems.STORAGE:
265 OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version});
267 case navigationItems.PROCESS_DETAILS:
268 OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version});
270 case navigationItems.MONITORING:
271 OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version});
276 const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => {
279 onVersionSwitching: (version, meta) => {
280 SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
281 props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), meta, version});
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}) :
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(() => {
293 case navigationItems.VENDOR_SOFTWARE_PRODUCT:
294 OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
296 case navigationItems.GENERAL:
297 OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version});
299 case navigationItems.DEPLOYMENT_FLAVORS:
300 OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version});
302 case navigationItems.PROCESS_DETAILS:
303 OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version});
305 case navigationItems.NETWORKS:
306 OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version});
308 case navigationItems.DEPENDENCIES:
309 OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version});
311 case navigationItems.ATTACHMENTS:
312 OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version});
314 case navigationItems.COMPONENTS:
315 OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version});
317 case navigationItems.ACTIVITY_LOG:
318 OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version});
321 onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId});
324 }).catch((e) => {console.error(e);});
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();
344 props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
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}) :
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});
361 }).catch((e) => {console.error(e);});
366 export default connect(mapStateToProps, mapActionsToProps)(TabulatedEditor);