Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / plugins / launchpad / src / instantiate / catalogCard.jsx
diff --git a/skyquake/plugins/launchpad/src/instantiate/catalogCard.jsx b/skyquake/plugins/launchpad/src/instantiate/catalogCard.jsx
new file mode 100644 (file)
index 0000000..d44bd2e
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * 
+ *   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 './catalogCard.scss';
+import 'style/common.scss';
+import React, {Component} from 'react';
+export default class CatalogCard extends Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+        this.state.isExpanded = false;
+    }
+    hideIt = (e) => {
+        document.querySelector('body').removeEventListener('click', this.hideIt);
+        if(e.target.parentElement.classList.contains('CatalogCard-info--expanded') || e.target.classList.contains('CatalogCard-info--expanded')) {
+            e.stopPropagation();
+        }
+        this.setState({
+            isExpanded: false
+        });
+    }
+    handleImageError = (e) => {
+        console.log('Bad logo path, using default');
+        e.target.src = require('style/img/catalog-default.svg');
+    }
+    toggleDetailsDisplay = (e) => {
+        let self = this;
+        let isExpanded = this.state.isExpanded;
+        e.stopPropagation();
+        if(!isExpanded) {
+            document.querySelector('body').addEventListener('click', this.hideIt);
+             self.setState({
+                isExpanded: true
+            });
+        }
+    }
+    detailsHTML = (descriptor) => {
+        let self = this;
+        return (
+            <dd className="details">
+                <div className="details-section">
+                    <div className="details-section-title">
+                        VNFDs
+                    </div>
+                    {
+                        (
+                         descriptor['constituent-vnfd'] &&
+                         (descriptor['constituent-vnfd'].length > 0)
+                         ) ?
+                            descriptor['constituent-vnfd'] && descriptor['constituent-vnfd'].map(function(v,i) {
+                                return (
+                                    <div key={i} className="details-section-item">
+                                        <img
+                                            onError={self.handleImageError}
+                                            src={cleanDataURI(descriptor.logo, 'vnfd', descriptor.id)}
+                                        />
+                                        {v['name']}
+                                    </div>
+                                    )
+                            })
+                            : 'None'
+                    }
+                </div>
+                <div className="details-section">
+                    <div className="details-section-title">
+                        VLDs
+                    </div>
+                    {
+                        (
+                         descriptor['vld'] &&
+                         (descriptor['vld'].length > 0)
+                         ) ?
+                            descriptor['vld'] && descriptor['vld'].map(function(v,i) {
+                                return (
+                                    <div key={i} className="details-section-item">
+                                        {v['short-name']}
+                                    </div>
+                                    )
+                            })
+                            : 'None'
+                    }
+                </div>
+                <div className="details-section">
+                    <div className="details-section-title">
+                        VNFFGDs
+                    </div>
+                    {
+                        (
+                         descriptor['vnffgd'] &&
+                         (descriptor['vnffgd'].length > 0)
+                         ) ?
+                            descriptor['vnffgd'] && descriptor['vnffgd'].map(function(v,i) {
+                                return (
+                                    <div key={i} className="details-section-item">
+                                        {v['short-name']}
+                                    </div>
+                                    )
+                            })
+                            : 'None'
+                    }
+                </div>
+            </dd>
+        );
+    }
+    componentWillUnmount() {
+        document.querySelector('body').removeEventListener('click', this.hideIt);
+    }
+    render() {
+        let {className, descriptor, isActive, isOpen, onCloseCard,...props} = this.props;
+        let openTool = isOpen ? null : <span className="oi CatalogCard-button" data-glyph={isActive ? "circle-x" : "arrow-circle-right"} onClick={isActive ?  onCloseCard : props.onPreviewDescriptor(descriptor)}></span>
+        className = "CatalogCard " + buildClass(this.props);
+        return (
+            <div className={className} onClick={props.onClick} onDoubleClick={props.onDoubleClick}>
+                <img className="CatalogCard-thumbnail"  onError={this.handleImageError} src={cleanDataURI(descriptor.logo, 'nsd', descriptor.id)} />
+                <div className="CatalogCard-body">
+                    <div className="CatalogCard-header">
+                        <div className="CatalogCard-name">
+                            {descriptor.name}
+                        </div>
+                        <div className="CatalogCard-subtitle">
+                            {descriptor['short-name']}
+                        </div>
+                        <div className="CatalogCard-subtitle">
+                            {descriptor['vendor']} / {descriptor['version']}
+                        </div>
+                    </div>
+                    <div className="CatalogCard-description">
+                        {descriptor['description']}
+                    </div>
+                    <dl className={"CatalogCard-info " + (this.state.isExpanded ? "CatalogCard-info--expanded" : "")} onClick={this.toggleDetailsDisplay}>
+                        <dt>VNFDs:</dt>
+                        <dd>{descriptor['constituent-vnfd'] && descriptor['constituent-vnfd'].length || 0}</dd>
+                        <dt>VLDs:</dt>
+                        <dd>{descriptor['vld'] && descriptor['vld'].length || 0}</dd>
+                        <dt>VNFFGDs:</dt>
+                        <dd>{descriptor['vnffgd'] && descriptor['vnffgd'].length || 0}</dd>
+                        <dd className="arrow-black--down"></dd>
+                        {this.detailsHTML(descriptor)}
+                    </dl>
+                </div>
+                {openTool}
+            </div>
+        )
+    }
+}
+CatalogCard.defaultProps = {
+    className: null,
+    descriptor: {}
+}
+
+function buildClass(props) {
+    let className = '';
+    if(props.isSelected) {
+        className += ' CatalogCard-is-selected';
+    }
+    if(props.isActive) {
+        className += ' CatalogCard-is-active';
+    }
+    return className;
+}
+
+function cardHandler(element) {
+    this.handleEvent = function(e) {
+        ''
+    }
+}
+
+function cleanDataURI(imageString, type, id) {
+        if (/\bbase64\b/g.test(imageString)) {
+            return imageString;
+        } else if (/<\?xml\b/g.test(imageString)) {
+            const imgStr = imageString.substring(imageString.indexOf('<?xml'));
+            return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr);
+        } else if (/\.(svg|png|gif|jpeg|jpg)$/.test(imageString)) {
+            return '/composer/assets/logos/' + type + '/' + id + '/' + imageString;
+            // return require('../images/logos/' + imageString);
+        }
+        if(type == 'nsd' || type == 'vnfd') {
+            return require('style/img/catalog-'+type+'-default.svg');
+        }
+        return require('style/img/catalog-default.svg');
+    }