Merge "RIFT-15943 - Debug tab presented no content and download button broken - the...
[osm/UI.git] / skyquake / plugins / launchpad / src / launchpad_card / nsrConfigPrimitives.jsx
1
2 /*
3  * 
4  *   Copyright 2016 RIFT.IO Inc
5  *
6  *   Licensed under the Apache License, Version 2.0 (the "License");
7  *   you may not use this file except in compliance with the License.
8  *   You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *   Unless required by applicable law or agreed to in writing, software
13  *   distributed under the License is distributed on an "AS IS" BASIS,
14  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *   See the License for the specific language governing permissions and
16  *   limitations under the License.
17  *
18  */
19 import React from 'react';
20 import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
21 import RecordViewStore from '../recordViewer/recordViewStore.js';
22 import Button from 'widgets/button/rw.button.js';
23 import './nsConfigPrimitives.scss';
24 import TextInput from 'widgets/form_controls/textInput.jsx';
25 import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
26
27 class NsrConfigPrimitives extends React.Component {
28     constructor(props) {
29         super(props);
30         this.state = {};
31         this.state.vnfrMap = null;
32         this.state.nsConfigPrimitives = null;
33     }
34
35     componentWillReceiveProps(props) {
36         let vnfrs = props.data['vnfrs'];
37         let vnfrMap = {};
38         let nsConfigPrimitives = [];
39         let vnfList = [];
40         if (vnfrs &&  !this.state.nsConfigPrimitives) {
41             vnfrs.map((vnfr) => {
42                 let vnfrConfigPrimitive = {};
43                 vnfrConfigPrimitive.name = vnfr['short-name'];
44                 vnfrConfigPrimitive['vnfr-id-ref'] = vnfr['id'];
45                 //input references
46                 let configPrimitives = vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'];
47                 //input references by key
48                 let vnfrConfigPrimitives = {}
49
50                 if (configPrimitives) {
51                     let vnfPrimitiveList = [];
52                     configPrimitives.map((configPrimitive) => {
53                         vnfrConfigPrimitives[configPrimitive.name] = configPrimitive;
54                         vnfPrimitiveList.push({
55                             name: configPrimitive.name,
56                             parameter: configPrimitive.parameter
57                         })
58                     });
59                     vnfrConfigPrimitive['service-primitives'] = vnfrConfigPrimitives;
60                     vnfrMap[vnfr['member-vnf-index-ref']] = vnfrConfigPrimitive;
61                 }
62             });
63             //nsr service-primitives
64             props.data['service-primitive'] && props.data['service-primitive'].map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
65                  //Add optional field to group. Necessary for driving state.
66                 let optionalizedNsConfigPrimitiveGroup = nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup)=>{
67                     if(parameterGroup && parameterGroup.mandatory != "true") {
68                         parameterGroup.optionalChecked = true;
69                     };
70                     return parameterGroup;
71                 });
72                 let nscp = {
73                     name: nsConfigPrimitive.name,
74                     'nsr_id_ref': props.data.id,
75                     'parameter': nsConfigPrimitive.parameter,
76                     'parameter-group': optionalizedNsConfigPrimitiveGroup,
77                     'vnf-primitive-group':[]
78                 }
79
80                 nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfPrimitiveGroup, vnfPrimitiveGroupIndex) => {
81                     let vnfMap = vnfrMap[vnfPrimitiveGroup['member-vnf-index-ref']];
82                     let vnfGroup = {};
83                     vnfGroup.name = vnfMap.name;
84                     vnfGroup['member-vnf-index-ref'] = vnfPrimitiveGroup['member-vnf-index-ref'];
85                     vnfGroup['vnfr-id-ref'] = vnfMap['vnfr-id-ref'];
86                     vnfGroup.inputs = [];
87                     vnfPrimitiveGroup.primitive.map((primitive, primitiveIndex) => {
88                         console.log(primitive);
89                         primitive.index = primitiveIndex;
90                         primitive.parameter = [];
91                         vnfMap['service-primitives'][primitive.name].parameter.map(function(p) {
92                             p.index = primitiveIndex;
93                             let paramCopy = p;
94                             paramCopy.value = undefined;
95                             primitive.parameter.push(paramCopy);
96                         });
97                         vnfGroup.inputs.push(primitive);
98                     });
99                     nscp['vnf-primitive-group'].push(vnfGroup);
100                 });
101                 nsConfigPrimitives.push(nscp);
102             });
103             this.setState({
104                 vnfrMap: vnfrMap,
105                 data: props.data,
106                 nsConfigPrimitives: nsConfigPrimitives
107             });
108         }
109     }
110
111     handleParamChange = (parameterIndex, vnfPrimitiveIndex, vnfListIndex, nsConfigPrimitiveIndex, event) => {
112         let nsConfigPrimitives = this.state.nsConfigPrimitives;
113         nsConfigPrimitives[nsConfigPrimitiveIndex]['vnf-primitive-group'][vnfListIndex]['inputs'][vnfPrimitiveIndex]['parameter'][parameterIndex]['value'] = event.target.value;
114         this.setState({
115             nsConfigPrimitives: nsConfigPrimitives
116         });
117     }
118
119     handleNsParamChange = (parameterIndex, nsConfigPrimitiveIndex, event) => {
120         let nsConfigPrimitives = this.state.nsConfigPrimitives;
121         nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter'][parameterIndex]['value'] = event.target.value;
122         this.setState({
123             nsConfigPrimitives: nsConfigPrimitives
124         });
125     }
126
127     handleNsParamGroupParamChange = (parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex, event) => {
128         let nsConfigPrimitives = this.state.nsConfigPrimitives;
129         nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex]['parameter'][parameterIndex]['value'] = event.target.value;
130         this.setState({
131             nsConfigPrimitives: nsConfigPrimitives
132         });
133     }
134
135     handleExecuteClick = (nsConfigPrimitiveIndex, event) => {
136         var isValid = RecordViewStore.validateInputs({
137             nsConfigPrimitives: this.state.nsConfigPrimitives,
138             nsConfigPrimitiveIndex: nsConfigPrimitiveIndex
139         });
140         if(isValid) {
141             RecordViewStore.constructAndTriggerNsConfigPrimitive({
142                 nsConfigPrimitives: this.state.nsConfigPrimitives,
143                 nsConfigPrimitiveIndex: nsConfigPrimitiveIndex
144              });
145             //Need a better way to reset
146             //Reset disabled per TEF request
147             // this.setState({
148             //     nsConfigPrimitives: null
149             // })
150         } else {
151                 this.props.actions.showNotification('Could not execute service config. Please review your parameters');
152         }
153     }
154     handleOptionalCheck = (parameterGroupIndex, nsConfigPrimitiveIndex, event) => {
155         let nsConfigPrimitives = this.state.nsConfigPrimitives;
156         let optionalChecked = nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex].optionalChecked;
157         nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex].optionalChecked = !optionalChecked;
158         console.log(nsConfigPrimitives)
159         this.setState({
160             nsConfigPrimitives: nsConfigPrimitives
161         });
162     }
163     constructConfigPrimitiveTabs = (tabList, tabPanels) => {
164         let self = this;
165         let defaultFromRpc = '';
166         //coded here for dev purposes
167         let mandatoryFieldValue = 'true';
168         if (self.state.vnfrMap) {
169             this.state.nsConfigPrimitives && this.state.nsConfigPrimitives.map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
170                 tabList.push(
171                     <Tab key={nsConfigPrimitiveIndex}>{nsConfigPrimitive.name}</Tab>
172                 );
173                 tabPanels.push(
174                     (
175                         <TabPanel key={nsConfigPrimitiveIndex + '-panel'}>
176                             <h4>{nsConfigPrimitive.name}</h4>
177                             <div className="noticeSubText noticeSubText_right">
178                                 * required
179                             </div>
180                             {nsConfigPrimitive['parameter'] && nsConfigPrimitive['parameter'].map((parameter, parameterIndex) => {
181                                 let optionalField = '';
182                                 let displayField = '';
183                                                                 let defaultValue = parameter['default-value'] || '';
184                                 let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
185                                 let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
186                                 if (parameter.mandatory == mandatoryFieldValue) {
187                                     optionalField = <span className="required">*</span>
188                                 }
189                                 if (isFieldReadOnly) {
190                                     displayField = (
191                                         <label data-required={(parameter.mandatory == mandatoryFieldValue)}>
192                                             {parameter.name}
193                                             <div className='readonly'>
194                                                 {parameter.value || defaultValue}
195                                             </div>
196                                         </label>
197                                     )
198                                 } else {
199                                     displayField = <TextInput label={parameter.name} required={(parameter.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamChange.bind(this, parameterIndex, nsConfigPrimitiveIndex)} />;
200                                 }
201                                 return (
202                                     <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
203                                         <ul>
204                                         {
205                                             <li key={parameterIndex} className="">
206                                                     {displayField}
207                                             </li>
208                                         }
209                                         </ul>
210                                     </div>
211                                 )
212                             })}
213                             {nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup, parameterGroupIndex) => {
214                                 let optionalField = '';
215                                 let overlayGroup = null;
216                                 let isOptionalGroup = parameterGroup.mandatory != mandatoryFieldValue;
217                                 let optionalChecked = parameterGroup.optionalChecked;
218                                 let inputIsDiabled = (!optionalChecked && isOptionalGroup);
219                                 if (isOptionalGroup) {
220                                     optionalField = <input type="checkbox" name="" checked={optionalChecked} onChange={self.handleOptionalCheck.bind(null, parameterGroupIndex, nsConfigPrimitiveIndex)} />;
221                                     // overlayGroup = <div className="configGroupOverlay"></div>
222                                 }
223                                 return (
224                                     <div key={parameterGroupIndex} className="nsConfigPrimitiveParameterGroupParameters">
225                                     <h2>{parameterGroup.name} {optionalField}</h2>
226                                     <div className="parameterGroup">
227                                         {overlayGroup}
228                                         <ul className="">
229                                                 <li className="">
230
231                                                     {parameterGroup['parameter'] && parameterGroup['parameter'].map((parameter, parameterIndex) => {
232                                                         let optionalField = '';
233                                                         let displayField = '';
234                                                         let defaultValue = parameter['default-value'] || '';
235                                                         let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
236                                                         let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
237                                                         if (parameter.mandatory == mandatoryFieldValue) {
238                                                             optionalField = <span className="required">*</span>
239                                                         }
240                                                         if (isFieldReadOnly) {
241                                                             displayField = <div className='readonly'>{parameter.value || defaultValue}</div>
242                                                         } else {
243                                                             displayField = <input required={(parameter.mandatory == mandatoryFieldValue)} className="" disabled={inputIsDiabled} type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamGroupParamChange.bind(this, parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex)} />
244                                                         }
245                                                         if (parameter.mandatory == mandatoryFieldValue) {
246                                                             optionalField = <span className="required">*</span>
247                                                         }
248                                                         return (
249                                                             <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
250                                                                 <ul>
251                                                                 {
252                                                                     <li key={parameterIndex} className="">
253                                                                         <label className={inputIsDiabled && 'disabled'} data-required={(parameter.mandatory == mandatoryFieldValue)}>
254                                                                             {parameter.name}
255                                                                             {displayField}
256                                                                         </label>
257
258                                                                     </li>
259                                                                 }
260                                                                 </ul>
261                                                             </div>
262                                                         )
263                                                     })}
264                                                 </li>
265                                             </ul>
266                                         </div>
267                                     </div>
268                                 );
269                             })}
270                             {nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfGroup, vnfGroupIndex) => {
271                                 return (
272                                     <div key={vnfGroupIndex} className="vnfParamGroup">
273                                         <h2>{vnfGroup.name}</h2>
274
275                                             {vnfGroup.inputs.map((inputGroup, inputGroupIndex) => {
276                                                 return (
277                                                     <div key={inputGroupIndex}>
278                                                         <h3>{inputGroup.name}</h3>
279                                                         <ul className="parameterGroup">
280                                                         {
281                                                             inputGroup.parameter.map((input, inputIndex) => {
282                                                                 let optionalField = '';
283                                                                 let displayField = '';
284                                                                                                                                 let defaultValue = input['default-value'] || '';
285                                                                 let isFieldHidden = (input['hidden'] && input['hidden'] == 'true') || false;
286                                                                 let isFieldReadOnly = (input['read-only'] && input['read-only'] == 'true') || false;
287                                                                 if (input.mandatory == mandatoryFieldValue) {
288                                                                     optionalField = <span className="required">*</span>
289                                                                 }
290                                                                 if (isFieldReadOnly) {
291                                                                     displayField = <div className='readonly'>{input.value || defaultValue}</div>
292                                                                 } else {
293                                                                     displayField = <TextInput label={input.name} type="text" required={(input.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={input.value} onChange={this.handleParamChange.bind(this, inputIndex, inputGroupIndex, vnfGroupIndex, nsConfigPrimitiveIndex)}/>
294                                                                 }
295                                                                 return (
296                                                                     <li key={inputIndex} style={{display: isFieldHidden ? 'none':'inherit'}}>
297                                                                         {displayField}
298                                                                     </li>
299                                                                 )
300                                                             })
301                                                         }
302                                                         </ul>
303                                                     </div>
304                                                 )
305                                             })}
306
307                                     </div>
308                                 )
309                             })}
310                             <Button label="Submit" isLoading={this.state.isSaving} onClick={this.handleExecuteClick.bind(this, nsConfigPrimitiveIndex)} className="dark"/>
311                         </TabPanel>
312                     )
313                 );
314             });
315         }
316     }
317
318     handleSelect = (index, last) => {
319         // console.log('Selected tab is', index, 'last index is', last);
320     }
321     render() {
322
323         let tabList = [];
324         let tabPanels = [];
325         let isConfiguring = (this.props.data['config-status'] && this.props.data['config-status'] != 'configured') || false;
326         let displayConfigStatus = isConfiguring ? '(Disabled - Configuring)': '';
327
328         this.constructConfigPrimitiveTabs(tabList, tabPanels);
329
330         return (
331             <div className="nsConfigPrimitives">
332                 <div className="launchpadCard_title">
333                   SERVICE-PRIMITIVES {displayConfigStatus}
334                 </div>
335                 <div className={isConfiguring ? 'configuring': '' + 'nsConfigPrimitiveTabs'}>
336                     <Tabs onSelect={this.handleSelect}>
337                         <TabList>
338                             {tabList}
339                         </TabList>
340                         {tabPanels}
341                     </Tabs>
342                 </div>
343             </div>
344
345         );
346     }
347 }
348
349
350 function deepCopy (toCopy, copyObj) {
351     for (let k in toCopy) {
352         switch (toCopy[k].constructor.name) {
353             case "String":
354                 copyObj[k] = toCopy[k];
355                 break;
356             case "Array":
357                 copyObj[k] = [];
358                 toCopy[k].map((v) => {
359                     copyObj[k].push(v)
360                 });
361                 break;
362             case "Object":
363                 deepCopy(toCopy[k], copyObj[k]);
364                 break;
365             default:
366                 copyObj[k] = toCopy[k]
367         }
368     }
369     return copyObj;
370 }
371 export default SkyquakeComponent(NsrConfigPrimitives);