d44bd2eca16b3a940fdeaa8ea6454b4b765ac8dc
[osm/UI.git] / skyquake / plugins / launchpad / src / instantiate / catalogCard.jsx
1 /*
2  * 
3  *   Copyright 2016 RIFT.IO Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  *
17  */
18 import './catalogCard.scss';
19 import 'style/common.scss';
20 import React, {Component} from 'react';
21 export default class CatalogCard extends Component {
22     constructor(props) {
23         super(props);
24         this.state = {};
25         this.state.isExpanded = false;
26     }
27     hideIt = (e) => {
28         document.querySelector('body').removeEventListener('click', this.hideIt);
29         if(e.target.parentElement.classList.contains('CatalogCard-info--expanded') || e.target.classList.contains('CatalogCard-info--expanded')) {
30             e.stopPropagation();
31         }
32         this.setState({
33             isExpanded: false
34         });
35     }
36     handleImageError = (e) => {
37         console.log('Bad logo path, using default');
38         e.target.src = require('style/img/catalog-default.svg');
39     }
40     toggleDetailsDisplay = (e) => {
41         let self = this;
42         let isExpanded = this.state.isExpanded;
43         e.stopPropagation();
44         if(!isExpanded) {
45             document.querySelector('body').addEventListener('click', this.hideIt);
46              self.setState({
47                 isExpanded: true
48             });
49         }
50     }
51     detailsHTML = (descriptor) => {
52         let self = this;
53         return (
54             <dd className="details">
55                 <div className="details-section">
56                     <div className="details-section-title">
57                         VNFDs
58                     </div>
59                     {
60                         (
61                          descriptor['constituent-vnfd'] &&
62                          (descriptor['constituent-vnfd'].length > 0)
63                          ) ?
64                             descriptor['constituent-vnfd'] && descriptor['constituent-vnfd'].map(function(v,i) {
65                                 return (
66                                     <div key={i} className="details-section-item">
67                                         <img
68                                             onError={self.handleImageError}
69                                             src={cleanDataURI(descriptor.logo, 'vnfd', descriptor.id)}
70                                         />
71                                         {v['name']}
72                                     </div>
73                                     )
74                             })
75                             : 'None'
76                     }
77                 </div>
78                 <div className="details-section">
79                     <div className="details-section-title">
80                         VLDs
81                     </div>
82                     {
83                         (
84                          descriptor['vld'] &&
85                          (descriptor['vld'].length > 0)
86                          ) ?
87                             descriptor['vld'] && descriptor['vld'].map(function(v,i) {
88                                 return (
89                                     <div key={i} className="details-section-item">
90                                         {v['short-name']}
91                                     </div>
92                                     )
93                             })
94                             : 'None'
95                     }
96                 </div>
97                 <div className="details-section">
98                     <div className="details-section-title">
99                         VNFFGDs
100                     </div>
101                     {
102                         (
103                          descriptor['vnffgd'] &&
104                          (descriptor['vnffgd'].length > 0)
105                          ) ?
106                             descriptor['vnffgd'] && descriptor['vnffgd'].map(function(v,i) {
107                                 return (
108                                     <div key={i} className="details-section-item">
109                                         {v['short-name']}
110                                     </div>
111                                     )
112                             })
113                             : 'None'
114                     }
115                 </div>
116             </dd>
117         );
118     }
119     componentWillUnmount() {
120         document.querySelector('body').removeEventListener('click', this.hideIt);
121     }
122     render() {
123         let {className, descriptor, isActive, isOpen, onCloseCard,...props} = this.props;
124         let openTool = isOpen ? null : <span className="oi CatalogCard-button" data-glyph={isActive ? "circle-x" : "arrow-circle-right"} onClick={isActive ?  onCloseCard : props.onPreviewDescriptor(descriptor)}></span>
125         className = "CatalogCard " + buildClass(this.props);
126         return (
127             <div className={className} onClick={props.onClick} onDoubleClick={props.onDoubleClick}>
128                 <img className="CatalogCard-thumbnail"  onError={this.handleImageError} src={cleanDataURI(descriptor.logo, 'nsd', descriptor.id)} />
129                 <div className="CatalogCard-body">
130                     <div className="CatalogCard-header">
131                         <div className="CatalogCard-name">
132                             {descriptor.name}
133                         </div>
134                         <div className="CatalogCard-subtitle">
135                             {descriptor['short-name']}
136                         </div>
137                         <div className="CatalogCard-subtitle">
138                             {descriptor['vendor']} / {descriptor['version']}
139                         </div>
140                     </div>
141                     <div className="CatalogCard-description">
142                         {descriptor['description']}
143                     </div>
144                     <dl className={"CatalogCard-info " + (this.state.isExpanded ? "CatalogCard-info--expanded" : "")} onClick={this.toggleDetailsDisplay}>
145                         <dt>VNFDs:</dt>
146                         <dd>{descriptor['constituent-vnfd'] && descriptor['constituent-vnfd'].length || 0}</dd>
147                         <dt>VLDs:</dt>
148                         <dd>{descriptor['vld'] && descriptor['vld'].length || 0}</dd>
149                         <dt>VNFFGDs:</dt>
150                         <dd>{descriptor['vnffgd'] && descriptor['vnffgd'].length || 0}</dd>
151                         <dd className="arrow-black--down"></dd>
152                         {this.detailsHTML(descriptor)}
153                     </dl>
154                 </div>
155                 {openTool}
156             </div>
157         )
158     }
159 }
160 CatalogCard.defaultProps = {
161     className: null,
162     descriptor: {}
163 }
164
165 function buildClass(props) {
166     let className = '';
167     if(props.isSelected) {
168         className += ' CatalogCard-is-selected';
169     }
170     if(props.isActive) {
171         className += ' CatalogCard-is-active';
172     }
173     return className;
174 }
175
176 function cardHandler(element) {
177     this.handleEvent = function(e) {
178         ''
179     }
180 }
181
182 function cleanDataURI(imageString, type, id) {
183         if (/\bbase64\b/g.test(imageString)) {
184             return imageString;
185         } else if (/<\?xml\b/g.test(imageString)) {
186             const imgStr = imageString.substring(imageString.indexOf('<?xml'));
187             return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr);
188         } else if (/\.(svg|png|gif|jpeg|jpg)$/.test(imageString)) {
189             return '/composer/assets/logos/' + type + '/' + id + '/' + imageString;
190             // return require('../images/logos/' + imageString);
191         }
192         if(type == 'nsd' || type == 'vnfd') {
193             return require('style/img/catalog-'+type+'-default.svg');
194         }
195         return require('style/img/catalog-default.svg');
196     }