Create new VSP, onboard from TOSCA file - UI
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / attachments / validation / HeatValidationReducer.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 {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
17 import {actionTypes, nodeFilters} from './HeatValidationConstants.js';
18
19 const mapVolumeData = ({fileName, env, errors}) => ({
20         name: fileName,
21         expanded: true,
22         type: 'volume',
23         children: env && [{
24                 name: env.fileName,
25                 errors: env.errors,
26                 type: 'env'
27         }],
28         errors
29 });
30
31 const mapNetworkData = ({fileName, env, errors}) => ({
32         name: fileName,
33         expanded: true,
34         type: 'network',
35         children: env && [{
36                 name: env.fileName,
37                 errors: env.errors,
38                 type: 'env'
39         }],
40         errors
41 });
42
43 const mapArtifactsData = ({fileName, errors}) => ({
44         name: fileName,
45         type: 'artifact',
46         errors
47 });
48
49 const mapOtherData = ({fileName, errors}) => ({
50         name: fileName,
51         type: 'other',
52         errors
53 });
54
55
56 const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors, other}) => ({
57         name: fileName,
58         expanded: true,
59         type: 'heat',
60         errors,
61         children: [
62                 ...(volume ? volume.map(mapVolumeData) : []),
63                 ...(network ? network.map(mapNetworkData) : []),
64                 ...(env ? [{
65                         name: env.fileName,
66                         errors: env.errors,
67                         type: 'env'
68                 }] : []),
69                 ...(artifacts ? artifacts.map(mapArtifactsData) : []),
70                 ...(other ? other.map(mapOtherData) : []),
71                 ...(nested ? nested.map(mapHeatData) : [])
72         ]
73 });
74
75 function createErrorList(node, parent, deep = 0, errorList = []) {
76         if (node.errors) {
77                 errorList.push(...node.errors.map((error) => ({
78                         level: error.level,
79                         errorMessage: error.message,
80                         name: node.name,
81                         hasParent: deep > 2,
82                         parentName: parent.name,
83                         type: node.type,
84                 })));
85         }
86         if (node.children && node.children.length) {
87                 node.children.map((child) => createErrorList(child, node, deep + 1, errorList));
88         }
89         return errorList;
90 }
91
92 const mapValidationDataToTree = (validationData, packageName) => {
93         let {heat, nested, volume, network, artifacts, other} = validationData.importStructure || {};
94         return {
95                 children: [
96                         {
97                                 name: packageName,
98                                 expanded: true,
99                                 type: 'heat',
100                                 header: true,
101                                 children: (heat ? heat.map(mapHeatData) : nested ? nested.map(mapHeatData) : [])
102                         },
103                         ...(artifacts ? [{
104                                 name: 'artifacts',
105                                 expanded: true,
106                                 type: 'artifact',
107                                 children: (artifacts ? artifacts.map(mapArtifactsData) : [])
108                         }] : []),
109                         ...(network ? [{
110                                 name: 'networks',
111                                 expanded: true,
112                                 type: 'network',
113                                 children: (network ? network.map(mapNetworkData) : []),
114                         }] : []),
115                         ...(volume ? [{
116                                 name: 'volume',
117                                 expanded: true,
118                                 type: 'volume',
119                                 children: (volume ? volume.map(mapVolumeData) : []),
120                         }] : []),
121                         ...(other ? [{
122                                 name: 'other',
123                                 expanded: true,
124                                 type: 'other',
125                                 children: (other ? other.map(mapOtherData) : []),
126                         }] : [])
127                 ]
128         };
129 };
130
131 const toggleExpanded = (node, path) => {
132         let newNode = {...node};
133         if (path.length === 0) {
134                 newNode.expanded = !node.expanded;
135         } else {
136                 let index = path[0];
137                 newNode.children = [
138                         ...node.children.slice(0, index),
139                         toggleExpanded(node.children[index], path.slice(1)),
140                         ...node.children.slice(index + 1)
141                 ];
142         }
143         return newNode;
144 };
145
146 const expandSelected = (node, selectedNode) => {
147         let shouldExpand = node.name === selectedNode;
148         let children = node.children && node.children.map(child => {
149                 let {shouldExpand: shouldExpandChild, node: newChild} = expandSelected(child, selectedNode);
150                 shouldExpand = shouldExpand || shouldExpandChild;
151                 return newChild;
152         });
153
154         return {
155                 node: {
156                         ...node,
157                         expanded: node.expanded || shouldExpand,
158                         children
159                 },
160                 shouldExpand
161         };
162 };
163
164 export default (state = {attachmentsTree: {}}, action) => {
165         switch (action.type) {
166                 case softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED:
167                         let currentSoftwareProduct = action.response;
168                         const packageName = currentSoftwareProduct.networkPackageName;
169                         let attachmentsTree = currentSoftwareProduct.validationData ? mapValidationDataToTree(currentSoftwareProduct.validationData, packageName) : {};
170                         let errorList = createErrorList(attachmentsTree);
171                         return {
172                                 ...state,
173                                 attachmentsTree,
174                                 errorList,
175                                 selectedNode: nodeFilters.ALL
176                         };
177                 case actionTypes.TOGGLE_EXPANDED:
178                         return {
179                                 ...state,
180                                 attachmentsTree: toggleExpanded(state.attachmentsTree, action.path)
181                         };
182                 case actionTypes.SELECTED_NODE:
183                         let selectedNode = action.nodeName;
184                         return {
185                                 ...state,
186                                 attachmentsTree: expandSelected(state.attachmentsTree, selectedNode).node,
187                                 selectedNode
188                         };
189                 case actionTypes.UNSELECTED_NODE:
190                         return {
191                                 ...state,
192                                 selectedNode: nodeFilters.ALL
193                         };
194                 default:
195                         return state;
196         }
197 };