Add new code new version
[sdc.git] / openecomp-ui / src / sdc-app / heatvalidation / attachments / AttachmentsReducer.js
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 import {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
22 import {actionTypes} from './AttachmentsConstants.js';
23
24 const mapVolumeData = ({fileName, env, errors}) => ({
25         name: fileName,
26         expanded: true,
27         type: 'volume',
28         children: env && [{
29                 name: env.fileName,
30                 errors: env.errors,
31                 type: 'env'
32         }],
33         errors
34 });
35
36 const mapNetworkData = ({fileName, env, errors}) => ({
37         name: fileName,
38         expanded: true,
39         type: 'network',
40         children: env && [{
41                 name: env.fileName,
42                 errors: env.errors,
43                 type: 'env'
44         }],
45         errors
46 });
47
48 const mapArtifactsData = ({fileName, errors}) => ({
49         name: fileName,
50         type: 'artifact',
51         errors
52 });
53
54 const mapOtherData = ({fileName, errors}) => ({
55         name: fileName,
56         type: 'other',
57         errors
58 });
59
60
61 const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors, other}) => ({
62         name: fileName,
63         expanded: true,
64         type: 'heat',
65         errors,
66         children: [
67                 ...(volume ? volume.map(mapVolumeData) : []),
68                 ...(network ? network.map(mapNetworkData) : []),
69                 ...(env ? [{
70                         name: env.fileName,
71                         errors: env.errors,
72                         type: 'env'
73                 }] : []),
74                 ...(artifacts ? artifacts.map(mapArtifactsData) : []),
75                 ...(other ? other.map(mapOtherData) : []),
76                 ...(nested ? nested.map(mapHeatData) : [])
77         ]
78 });
79
80 function createErrorList(node, parent, deep = 0, errorList = []) {
81         if (node.errors) {
82                 errorList.push(...node.errors.map((error) => ({
83                         errorLevel: error.level,
84                         errorMessage: error.message,
85                         name: node.name,
86                         hasParent: deep > 2,
87                         parentName: parent.name,
88                         type: node.type,
89                 })));
90         }
91         if (node.children && node.children.length) {
92                 node.children.map((child) => createErrorList(child, node, deep + 1, errorList));
93         }
94         return errorList;
95 }
96
97 const mapValidationDataToTree = validationData => {
98         let {HEAT, volume, network, artifacts, other} = validationData.importStructure || {};
99         return {
100                 children: [
101                         {
102                                 name: 'HEAT',
103                                 expanded: true,
104                                 type: 'heat',
105                                 children: (HEAT ? HEAT.map(mapHeatData) : [])
106                         },
107                         ...(artifacts ? [{
108                                 name: 'artifacts',
109                                 expanded: true,
110                                 type: 'artifact',
111                                 children: (artifacts ? artifacts.map(mapArtifactsData) : [])
112                         }] : []),
113                         ...(network ? [{
114                                 name: 'networks',
115                                 expanded: true,
116                                 type: 'network',
117                                 children: (network ? network.map(mapNetworkData) : []),
118                         }] : []),
119                         ...(volume ? [{
120                                 name: 'volume',
121                                 expanded: true,
122                                 type: 'volume',
123                                 children: (volume ? volume.map(mapVolumeData) : []),
124                         }] : []),
125                         ...(other ? [{
126                                 name: 'other',
127                                 expanded: true,
128                                 type: 'other',
129                                 children: (other ? other.map(mapOtherData) : []),
130                         }] : [])
131                 ]
132         };
133 };
134
135 const toggleExpanded = (node, path) => {
136         let newNode = {...node};
137         if (path.length === 0) {
138                 newNode.expanded = !node.expanded;
139         } else {
140                 let index = path[0];
141                 newNode.children = [
142                         ...node.children.slice(0, index),
143                         toggleExpanded(node.children[index], path.slice(1)),
144                         ...node.children.slice(index + 1)
145                 ];
146         }
147         return newNode;
148 };
149
150 const expandSelected = (node, selectedNode) => {
151         let shouldExpand = node.name === selectedNode;
152         let children = node.children && node.children.map(child => {
153                 let {shouldExpand: shouldExpandChild, node: newChild} = expandSelected(child, selectedNode);
154                 shouldExpand = shouldExpand || shouldExpandChild;
155                 return newChild;
156         });
157
158         return {
159                 node: {
160                         ...node,
161                         expanded: node.expanded || shouldExpand,
162                         children
163                 },
164                 shouldExpand
165         };
166 };
167
168 export default (state = {attachmentsTree: {}}, action) => {
169         switch (action.type) {
170                 case softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED:
171                         let currentSoftwareProduct = action.response;
172                         let attachmentsTree = currentSoftwareProduct.validationData ? mapValidationDataToTree(currentSoftwareProduct.validationData) : {};
173                         let errorList = createErrorList(attachmentsTree);
174                         return {
175                                 ...state,
176                                 attachmentsTree,
177                                 errorList
178                         };
179                 case actionTypes.TOGGLE_EXPANDED:
180                         return {
181                                 ...state,
182                                 attachmentsTree: toggleExpanded(state.attachmentsTree, action.path)
183                         };
184                 case actionTypes.SELECTED_NODE:
185                         let selectedNode = action.nodeName;
186                         return {
187                                 ...state,
188                                 attachmentsTree: expandSelected(state.attachmentsTree, selectedNode).node,
189                                 selectedNode
190                         };
191                 case actionTypes.UNSELECTED_NODE:
192                         return {
193                                 ...state,
194                                 selectedNode: undefined
195                         };
196                 default:
197                         return state;
198         }
199 };