update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[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         const hasAccess = self.props.hasAccess;
166         let defaultFromRpc = '';
167         //coded here for dev purposes
168         let mandatoryFieldValue = 'true';
169         if (self.state.vnfrMap) {
170             this.state.nsConfigPrimitives && this.state.nsConfigPrimitives.map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
171                 tabList.push(
172                     <Tab key={nsConfigPrimitiveIndex}>{nsConfigPrimitive.name}</Tab>
173                 );
174                 tabPanels.push(
175                     (
176                         <TabPanel key={nsConfigPrimitiveIndex + '-panel'}>
177                             <h4>{nsConfigPrimitive.name}</h4>
178                             <div className="noticeSubText noticeSubText_right">
179                                 * required
180                             </div>
181                             {nsConfigPrimitive['parameter'] && nsConfigPrimitive['parameter'].map((parameter, parameterIndex) => {
182                                 let optionalField = '';
183                                 let displayField = '';
184                                                                 let defaultValue = parameter['default-value'] || '';
185                                 let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
186                                 let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
187                                 if (parameter.mandatory == mandatoryFieldValue) {
188                                     optionalField = <span className="required">*</span>
189                                 }
190                                 if (isFieldReadOnly) {
191                                     displayField = (
192                                         <label data-required={(parameter.mandatory == mandatoryFieldValue)}>
193                                             {parameter.name}
194                                             <div className='readonly'>
195                                                 {parameter.value || defaultValue}
196                                             </div>
197                                         </label>
198                                     )
199                                 } else {
200                                     displayField = <TextInput label={parameter.name} required={(parameter.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamChange.bind(this, parameterIndex, nsConfigPrimitiveIndex)} />;
201                                 }
202                                 return (
203                                     <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
204                                         <ul>
205                                         {
206                                             <li key={parameterIndex} className="">
207                                                     {displayField}
208                                             </li>
209                                         }
210                                         </ul>
211                                     </div>
212                                 )
213                             })}
214                             {nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup, parameterGroupIndex) => {
215                                 let optionalField = '';
216                                 let overlayGroup = null;
217                                 let isOptionalGroup = parameterGroup.mandatory != mandatoryFieldValue;
218                                 let optionalChecked = parameterGroup.optionalChecked;
219                                 let inputIsDiabled = (!optionalChecked && isOptionalGroup);
220                                 if (isOptionalGroup) {
221                                     optionalField = <input type="checkbox" name="" checked={optionalChecked} onChange={self.handleOptionalCheck.bind(null, parameterGroupIndex, nsConfigPrimitiveIndex)} />;
222                                     // overlayGroup = <div className="configGroupOverlay"></div>
223                                 }
224                                 return (
225                                     <div key={parameterGroupIndex} className="nsConfigPrimitiveParameterGroupParameters">
226                                     <h2>{parameterGroup.name} {optionalField}</h2>
227                                     <div className="parameterGroup">
228                                         {overlayGroup}
229                                         <ul className="">
230                                                 <li className="">
231
232                                                     {parameterGroup['parameter'] && parameterGroup['parameter'].map((parameter, parameterIndex) => {
233                                                         let optionalField = '';
234                                                         let displayField = '';
235                                                         let defaultValue = parameter['default-value'] || '';
236                                                         let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
237                                                         let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
238                                                         if (parameter.mandatory == mandatoryFieldValue) {
239                                                             optionalField = <span className="required">*</span>
240                                                         }
241                                                         if (isFieldReadOnly) {
242                                                             displayField = <div className='readonly'>{parameter.value || defaultValue}</div>
243                                                         } else {
244                                                             displayField = <input required={(parameter.mandatory == mandatoryFieldValue)} className="" disabled={inputIsDiabled} type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamGroupParamChange.bind(this, parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex)} />
245                                                         }
246                                                         if (parameter.mandatory == mandatoryFieldValue) {
247                                                             optionalField = <span className="required">*</span>
248                                                         }
249                                                         return (
250                                                             <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
251                                                                 <ul>
252                                                                 {
253                                                                     <li key={parameterIndex} className="">
254                                                                         <label className={inputIsDiabled && 'disabled'} data-required={(parameter.mandatory == mandatoryFieldValue)}>
255                                                                             {parameter.name}
256                                                                             {displayField}
257                                                                         </label>
258
259                                                                     </li>
260                                                                 }
261                                                                 </ul>
262                                                             </div>
263                                                         )
264                                                     })}
265                                                 </li>
266                                             </ul>
267                                         </div>
268                                     </div>
269                                 );
270                             })}
271                             {nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfGroup, vnfGroupIndex) => {
272                                 return (
273                                     <div key={vnfGroupIndex} className="vnfParamGroup">
274                                         <h2>{vnfGroup.name}</h2>
275
276                                             {vnfGroup.inputs.map((inputGroup, inputGroupIndex) => {
277                                                 return (
278                                                     <div key={inputGroupIndex}>
279                                                         <h3>{inputGroup.name}</h3>
280                                                         <ul className="parameterGroup">
281                                                         {
282                                                             inputGroup.parameter.map((input, inputIndex) => {
283                                                                 let optionalField = '';
284                                                                 let displayField = '';
285                                                                                                                                 let defaultValue = input['default-value'] || '';
286                                                                 let isFieldHidden = (input['hidden'] && input['hidden'] == 'true') || false;
287                                                                 let isFieldReadOnly = (input['read-only'] && input['read-only'] == 'true') || false;
288                                                                 if (input.mandatory == mandatoryFieldValue) {
289                                                                     optionalField = <span className="required">*</span>
290                                                                 }
291                                                                 if (isFieldReadOnly) {
292                                                                     displayField = <div className='readonly'>{input.value || defaultValue}</div>
293                                                                 } else {
294                                                                     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)}/>
295                                                                 }
296                                                                 return (
297                                                                     <li key={inputIndex} style={{display: isFieldHidden ? 'none':'inherit'}}>
298                                                                         {displayField}
299                                                                     </li>
300                                                                 )
301                                                             })
302                                                         }
303                                                         </ul>
304                                                     </div>
305                                                 )
306                                             })}
307
308                                     </div>
309                                 )
310                             })}
311                             {
312                                 hasAccess ?
313                                     <Button label="Submit" isLoading={this.state.isSaving} onClick={this.handleExecuteClick.bind(this, nsConfigPrimitiveIndex)} className="dark"/>
314                                 : null
315                             }
316                         </TabPanel>
317                     )
318                 );
319             });
320         }
321     }
322
323     handleSelect = (index, last) => {
324         // console.log('Selected tab is', index, 'last index is', last);
325     }
326     render() {
327
328         let tabList = [];
329         let tabPanels = [];
330         let isConfiguring = (this.props.data['config-status'] && this.props.data['config-status'] != 'configured') || false;
331         let displayConfigStatus = isConfiguring ? '(Disabled - Configuring)': '';
332
333         this.constructConfigPrimitiveTabs(tabList, tabPanels);
334
335         return (
336             <div className="nsConfigPrimitives">
337                 <div className="launchpadCard_title">
338                   SERVICE-PRIMITIVES {displayConfigStatus}
339                 </div>
340                 <div className={isConfiguring ? 'configuring': '' + 'nsConfigPrimitiveTabs'}>
341                     <Tabs onSelect={this.handleSelect}>
342                         <TabList>
343                             {tabList}
344                         </TabList>
345                         {tabPanels}
346                     </Tabs>
347                 </div>
348             </div>
349
350         );
351     }
352 }
353
354
355 function deepCopy (toCopy, copyObj) {
356     for (let k in toCopy) {
357         switch (toCopy[k].constructor.name) {
358             case "String":
359                 copyObj[k] = toCopy[k];
360                 break;
361             case "Array":
362                 copyObj[k] = [];
363                 toCopy[k].map((v) => {
364                     copyObj[k].push(v)
365                 });
366                 break;
367             case "Object":
368                 deepCopy(toCopy[k], copyObj[k]);
369                 break;
370             default:
371                 copyObj[k] = toCopy[k]
372         }
373     }
374     return copyObj;
375 }
376 export default SkyquakeComponent(NsrConfigPrimitives);