Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / plugins / launchpad / src / launchpad_card / nsrConfigPrimitives.jsx
diff --git a/skyquake/plugins/launchpad/src/launchpad_card/nsrConfigPrimitives.jsx b/skyquake/plugins/launchpad/src/launchpad_card/nsrConfigPrimitives.jsx
new file mode 100644 (file)
index 0000000..b44b3d9
--- /dev/null
@@ -0,0 +1,371 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+import React from 'react';
+import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
+import RecordViewStore from '../recordViewer/recordViewStore.js';
+import Button from 'widgets/button/rw.button.js';
+import './nsConfigPrimitives.scss';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+
+class NsrConfigPrimitives extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.vnfrMap = null;
+        this.state.nsConfigPrimitives = null;
+    }
+
+    componentWillReceiveProps(props) {
+        let vnfrs = props.data['vnfrs'];
+        let vnfrMap = {};
+        let nsConfigPrimitives = [];
+        let vnfList = [];
+        if (vnfrs &&  !this.state.nsConfigPrimitives) {
+            vnfrs.map((vnfr) => {
+                let vnfrConfigPrimitive = {};
+                vnfrConfigPrimitive.name = vnfr['short-name'];
+                vnfrConfigPrimitive['vnfr-id-ref'] = vnfr['id'];
+                //input references
+                let configPrimitives = vnfr['vnf-configuration']['service-primitive'];
+                //input references by key
+                let vnfrConfigPrimitives = {}
+
+                if (configPrimitives) {
+                    let vnfPrimitiveList = [];
+                    configPrimitives.map((configPrimitive) => {
+                        vnfrConfigPrimitives[configPrimitive.name] = configPrimitive;
+                        vnfPrimitiveList.push({
+                            name: configPrimitive.name,
+                            parameter: configPrimitive.parameter
+                        })
+                    });
+                    vnfrConfigPrimitive['service-primitives'] = vnfrConfigPrimitives;
+                    vnfrMap[vnfr['member-vnf-index-ref']] = vnfrConfigPrimitive;
+                }
+            });
+            //nsr service-primitives
+            props.data['service-primitive'] && props.data['service-primitive'].map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
+                 //Add optional field to group. Necessary for driving state.
+                let optionalizedNsConfigPrimitiveGroup = nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup)=>{
+                    if(parameterGroup && parameterGroup.mandatory != "true") {
+                        parameterGroup.optionalChecked = true;
+                    };
+                    return parameterGroup;
+                });
+                let nscp = {
+                    name: nsConfigPrimitive.name,
+                    'nsr_id_ref': props.data.id,
+                    'parameter': nsConfigPrimitive.parameter,
+                    'parameter-group': optionalizedNsConfigPrimitiveGroup,
+                    'vnf-primitive-group':[]
+                }
+
+                nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfPrimitiveGroup, vnfPrimitiveGroupIndex) => {
+                    let vnfMap = vnfrMap[vnfPrimitiveGroup['member-vnf-index-ref']];
+                    let vnfGroup = {};
+                    vnfGroup.name = vnfMap.name;
+                    vnfGroup['member-vnf-index-ref'] = vnfPrimitiveGroup['member-vnf-index-ref'];
+                    vnfGroup['vnfr-id-ref'] = vnfMap['vnfr-id-ref'];
+                    vnfGroup.inputs = [];
+                    vnfPrimitiveGroup.primitive.map((primitive, primitiveIndex) => {
+                        console.log(primitive);
+                        primitive.index = primitiveIndex;
+                        primitive.parameter = [];
+                        vnfMap['service-primitives'][primitive.name].parameter.map(function(p) {
+                            p.index = primitiveIndex;
+                            let paramCopy = p;
+                            paramCopy.value = undefined;
+                            primitive.parameter.push(paramCopy);
+                        });
+                        vnfGroup.inputs.push(primitive);
+                    });
+                    nscp['vnf-primitive-group'].push(vnfGroup);
+                });
+                nsConfigPrimitives.push(nscp);
+            });
+            this.setState({
+                vnfrMap: vnfrMap,
+                data: props.data,
+                nsConfigPrimitives: nsConfigPrimitives
+            });
+        }
+    }
+
+    handleParamChange = (parameterIndex, vnfPrimitiveIndex, vnfListIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['vnf-primitive-group'][vnfListIndex]['inputs'][vnfPrimitiveIndex]['parameter'][parameterIndex]['value'] = event.target.value;
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+
+    handleNsParamChange = (parameterIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter'][parameterIndex]['value'] = event.target.value;
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+
+    handleNsParamGroupParamChange = (parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex]['parameter'][parameterIndex]['value'] = event.target.value;
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+
+    handleExecuteClick = (nsConfigPrimitiveIndex, event) => {
+        var isValid = RecordViewStore.validateInputs({
+            nsConfigPrimitives: this.state.nsConfigPrimitives,
+            nsConfigPrimitiveIndex: nsConfigPrimitiveIndex
+        });
+        if(isValid) {
+            RecordViewStore.constructAndTriggerNsConfigPrimitive({
+                nsConfigPrimitives: this.state.nsConfigPrimitives,
+                nsConfigPrimitiveIndex: nsConfigPrimitiveIndex
+             });
+            //Need a better way to reset
+            //Reset disabled per TEF request
+            // this.setState({
+            //     nsConfigPrimitives: null
+            // })
+        } else {
+                this.props.actions.showNotification('Could not execute service config. Please review your parameters');
+        }
+    }
+    handleOptionalCheck = (parameterGroupIndex, nsConfigPrimitiveIndex, event) => {
+        let nsConfigPrimitives = this.state.nsConfigPrimitives;
+        let optionalChecked = nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex].optionalChecked;
+        nsConfigPrimitives[nsConfigPrimitiveIndex]['parameter-group'][parameterGroupIndex].optionalChecked = !optionalChecked;
+        console.log(nsConfigPrimitives)
+        this.setState({
+            nsConfigPrimitives: nsConfigPrimitives
+        });
+    }
+    constructConfigPrimitiveTabs = (tabList, tabPanels) => {
+        let self = this;
+        let defaultFromRpc = '';
+        //coded here for dev purposes
+        let mandatoryFieldValue = 'true';
+        if (self.state.vnfrMap) {
+            this.state.nsConfigPrimitives && this.state.nsConfigPrimitives.map((nsConfigPrimitive, nsConfigPrimitiveIndex) => {
+                tabList.push(
+                    <Tab key={nsConfigPrimitiveIndex}>{nsConfigPrimitive.name}</Tab>
+                );
+                tabPanels.push(
+                    (
+                        <TabPanel key={nsConfigPrimitiveIndex + '-panel'}>
+                            <h4>{nsConfigPrimitive.name}</h4>
+                            <div className="noticeSubText noticeSubText_right">
+                                * required
+                            </div>
+                            {nsConfigPrimitive['parameter'] && nsConfigPrimitive['parameter'].map((parameter, parameterIndex) => {
+                                let optionalField = '';
+                                let displayField = '';
+                                                               let defaultValue = parameter['default-value'] || '';
+                                let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
+                                let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
+                                if (parameter.mandatory == mandatoryFieldValue) {
+                                    optionalField = <span className="required">*</span>
+                                }
+                                if (isFieldReadOnly) {
+                                    displayField = (
+                                        <label data-required={(parameter.mandatory == mandatoryFieldValue)}>
+                                            {parameter.name}
+                                            <div className='readonly'>
+                                                {parameter.value || defaultValue}
+                                            </div>
+                                        </label>
+                                    )
+                                } else {
+                                    displayField = <TextInput label={parameter.name} required={(parameter.mandatory == mandatoryFieldValue)} className="" type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamChange.bind(this, parameterIndex, nsConfigPrimitiveIndex)} />;
+                                }
+                                return (
+                                    <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
+                                        <ul>
+                                        {
+                                            <li key={parameterIndex} className="">
+                                                    {displayField}
+                                            </li>
+                                        }
+                                        </ul>
+                                    </div>
+                                )
+                            })}
+                            {nsConfigPrimitive['parameter-group'] && nsConfigPrimitive['parameter-group'].map((parameterGroup, parameterGroupIndex) => {
+                                let optionalField = '';
+                                let overlayGroup = null;
+                                let isOptionalGroup = parameterGroup.mandatory != mandatoryFieldValue;
+                                let optionalChecked = parameterGroup.optionalChecked;
+                                let inputIsDiabled = (!optionalChecked && isOptionalGroup);
+                                if (isOptionalGroup) {
+                                    optionalField = <input type="checkbox" name="" checked={optionalChecked} onChange={self.handleOptionalCheck.bind(null, parameterGroupIndex, nsConfigPrimitiveIndex)} />;
+                                    // overlayGroup = <div className="configGroupOverlay"></div>
+                                }
+                                return (
+                                    <div key={parameterGroupIndex} className="nsConfigPrimitiveParameterGroupParameters">
+                                    <h2>{parameterGroup.name} {optionalField}</h2>
+                                    <div className="parameterGroup">
+                                        {overlayGroup}
+                                        <ul className="">
+                                                <li className="">
+
+                                                    {parameterGroup['parameter'] && parameterGroup['parameter'].map((parameter, parameterIndex) => {
+                                                        let optionalField = '';
+                                                        let displayField = '';
+                                                        let defaultValue = parameter['default-value'] || '';
+                                                        let isFieldHidden = (parameter['hidden'] && parameter['hidden'] == 'true') || false;
+                                                        let isFieldReadOnly = (parameter['read-only'] && parameter['read-only'] == 'true') || false;
+                                                        if (parameter.mandatory == mandatoryFieldValue) {
+                                                            optionalField = <span className="required">*</span>
+                                                        }
+                                                        if (isFieldReadOnly) {
+                                                            displayField = <div className='readonly'>{parameter.value || defaultValue}</div>
+                                                        } else {
+                                                            displayField = <input required={(parameter.mandatory == mandatoryFieldValue)} className="" disabled={inputIsDiabled} type="text" defaultValue={defaultValue} value={parameter.value} onChange={this.handleNsParamGroupParamChange.bind(this, parameterIndex, parameterGroupIndex, nsConfigPrimitiveIndex)} />
+                                                        }
+                                                        if (parameter.mandatory == mandatoryFieldValue) {
+                                                            optionalField = <span className="required">*</span>
+                                                        }
+                                                        return (
+                                                            <div key={parameterIndex} className="nsConfigPrimitiveParameters" style={{display: isFieldHidden ? 'none':'inherit'}}>
+                                                                <ul>
+                                                                {
+                                                                    <li key={parameterIndex} className="">
+                                                                        <label className={inputIsDiabled && 'disabled'} data-required={(parameter.mandatory == mandatoryFieldValue)}>
+                                                                            {parameter.name}
+                                                                            {displayField}
+                                                                        </label>
+
+                                                                    </li>
+                                                                }
+                                                                </ul>
+                                                            </div>
+                                                        )
+                                                    })}
+                                                </li>
+                                            </ul>
+                                        </div>
+                                    </div>
+                                );
+                            })}
+                            {nsConfigPrimitive['vnf-primitive-group'] && nsConfigPrimitive['vnf-primitive-group'].map((vnfGroup, vnfGroupIndex) => {
+                                return (
+                                    <div key={vnfGroupIndex} className="vnfParamGroup">
+                                        <h2>{vnfGroup.name}</h2>
+
+                                            {vnfGroup.inputs.map((inputGroup, inputGroupIndex) => {
+                                                return (
+                                                    <div key={inputGroupIndex}>
+                                                        <h3>{inputGroup.name}</h3>
+                                                        <ul className="parameterGroup">
+                                                        {
+                                                            inputGroup.parameter.map((input, inputIndex) => {
+                                                                let optionalField = '';
+                                                                let displayField = '';
+                                                                                                                               let defaultValue = input['default-value'] || '';
+                                                                let isFieldHidden = (input['hidden'] && input['hidden'] == 'true') || false;
+                                                                let isFieldReadOnly = (input['read-only'] && input['read-only'] == 'true') || false;
+                                                                if (input.mandatory == mandatoryFieldValue) {
+                                                                    optionalField = <span className="required">*</span>
+                                                                }
+                                                                if (isFieldReadOnly) {
+                                                                    displayField = <div className='readonly'>{input.value || defaultValue}</div>
+                                                                } else {
+                                                                    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)}/>
+                                                                }
+                                                                return (
+                                                                    <li key={inputIndex} style={{display: isFieldHidden ? 'none':'inherit'}}>
+                                                                        {displayField}
+                                                                    </li>
+                                                                )
+                                                            })
+                                                        }
+                                                        </ul>
+                                                    </div>
+                                                )
+                                            })}
+
+                                    </div>
+                                )
+                            })}
+                            <Button label="Submit" isLoading={this.state.isSaving} onClick={this.handleExecuteClick.bind(this, nsConfigPrimitiveIndex)} className="dark"/>
+                        </TabPanel>
+                    )
+                );
+            });
+        }
+    }
+
+    handleSelect = (index, last) => {
+        // console.log('Selected tab is', index, 'last index is', last);
+    }
+    render() {
+
+        let tabList = [];
+        let tabPanels = [];
+        let isConfiguring = (this.props.data['config-status'] && this.props.data['config-status'] != 'configured') || false;
+        let displayConfigStatus = isConfiguring ? '(Disabled - Configuring)': '';
+
+        this.constructConfigPrimitiveTabs(tabList, tabPanels);
+
+        return (
+            <div className="nsConfigPrimitives">
+                <div className="launchpadCard_title">
+                  SERVICE-PRIMITIVES {displayConfigStatus}
+                </div>
+                <div className={isConfiguring ? 'configuring': '' + 'nsConfigPrimitiveTabs'}>
+                    <Tabs onSelect={this.handleSelect}>
+                        <TabList>
+                            {tabList}
+                        </TabList>
+                        {tabPanels}
+                    </Tabs>
+                </div>
+            </div>
+
+        );
+    }
+}
+
+
+function deepCopy (toCopy, copyObj) {
+    for (let k in toCopy) {
+        switch (toCopy[k].constructor.name) {
+            case "String":
+                copyObj[k] = toCopy[k];
+                break;
+            case "Array":
+                copyObj[k] = [];
+                toCopy[k].map((v) => {
+                    copyObj[k].push(v)
+                });
+                break;
+            case "Object":
+                deepCopy(toCopy[k], copyObj[k]);
+                break;
+            default:
+                copyObj[k] = toCopy[k]
+        }
+    }
+    return copyObj;
+}
+export default SkyquakeComponent(NsrConfigPrimitives);