update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / plugins / composer / src / src / components / CatalogItems.js
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 'use strict';
20
21 import UID from '../libraries/UniqueId'
22 import React from 'react'
23 import messages from './messages'
24 import ClassNames from 'classnames'
25 import PureRenderMixin from 'react-addons-pure-render-mixin'
26 import CatalogDataStore from '../stores/CatalogDataStore'
27 import CatalogItemsActions from '../actions/CatalogItemsActions'
28 import ComposerAppActions from '../actions/ComposerAppActions'
29 import SelectionManager from '../libraries/SelectionManager'
30
31 import '../styles/CatalogItems.scss'
32 import imgFile from 'file!../images/vendor-riftio.png'
33
34 const DEFAULT_NSD_ICON = require('style/img/catalog-nsd-default.svg');
35 const DEFAULT_VNFD_ICON = require('style/img/catalog-vnfd-default.svg');
36 const DEFAULT_ICON = require('style/img/catalog-default.svg');
37
38 function renderVersion (version) {
39 if (version) {
40 return (<span className='version'>{version}</span>);
41 } // else return null by default
42 };
43 function getImageErrorHandler (type) {
44 return type === 'nsd' ? handleNsdImageError : type === 'vnfd' ? handleVnfdImageError : handleImageError;
45 }
46 function handleImageError (e, image) {
47 console.log('Bad logo path, using default');
48 e.target.src = image || DEFAULT_ICON;
49 };
50 function handleNsdImageError (e) {
51 handleImageError(e, DEFAULT_NSD_ICON);
52 };
53 function handleVnfdImageError (e) {
54 handleImageError(e, DEFAULT_VNFD_ICON);
55 };
56
57 const CatalogItems = React.createClass({
58 mixins: [PureRenderMixin],
59 getInitialState() {
60 return CatalogDataStore.getState();
61 },
62 getDefaultProps() {
63 return {
64 filterByType: 'nsd'
65 };
66 },
67 componentWillMount() {
68 CatalogDataStore.listen(this.onChange);
69 },
70 componentDidMount() {
71 // async actions creator will dispatch loadCatalogsSuccess and loadCatalogsError messages
72 CatalogDataStore.loadCatalogs().catch(e => console.warn('unable to load catalogs', e));
73 },
74 componentWillUnmount() {
75 CatalogDataStore.unlisten(this.onChange);
76 },
77 onChange(state) {
78 this.setState(state);
79 },
80 render() {
81 const onDragStart = function(event) {
82 const data = {type: 'catalog-item', item: this};
83 event.dataTransfer.effectAllowed = 'copy';
84 event.dataTransfer.setData('text', JSON.stringify(data));
85 ComposerAppActions.setDragState(data);
86 };
87 const onDblClickCatalogItem = function () {
88 CatalogItemsActions.editCatalogItem(this);
89 };
90 const onClickCatalogItem = function () {
91 // single clicking an item is handled by ComposerApp::onClick handler
92 //CatalogItemsActions.selectCatalogItem(this);
93 };
94 const cleanDataURI = function (imageString, type, id) {
95 if (/\bbase64\b/g.test(imageString)) {
96 return imageString;
97 } else if (/<\?xml\b/g.test(imageString)) {
98 const imgStr = imageString.substring(imageString.indexOf('<?xml'));
99 return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr);
100 } else if (/\.(svg|png|gif|jpeg|jpg)$/.test(imageString)) {
101 return 'assets/logos/' + type + '/' + id + '/' + imageString;
102 // return require('../images/logos/' + imageString);
103 }
104 return type === 'nsd' ? DEFAULT_NSD_ICON : type === 'vnfd' ? DEFAULT_VNFD_ICON : DEFAULT_ICON;
105 }
106 const items = this.getCatalogItems().map(function (d) {
107 const isNSD = d.uiState.type === 'nsd';
108 const isVNFD = d.uiState.type === 'vnfd';
109 const isDeleted = d.uiState.deleted;
110 const isModified = d.uiState.modified;
111 const isSelected = SelectionManager.isSelected(d);
112 const isOpenForEdit = d.uiState.isOpenForEdit;
113 const spanClassNames = ClassNames({'-is-selected': isSelected, '-is-open-for-edit': isOpenForEdit});
114 const sectionClassNames = ClassNames('catalog-item', {'-is-modified': isModified, '-is-deleted': isDeleted});
115 let type;
116 if(isNSD) {
117 type = 'nsd';
118 }
119 if(isVNFD) {
120 type = 'vnfd';
121 }
122 return (
123 <li key={d.id} data-uid={UID.from(d)} onClick={onClickCatalogItem.bind(d)} onDoubleClick={onDblClickCatalogItem.bind(d)}>
124 <div className={spanClassNames + ' ' + type}>
125 <div className={sectionClassNames} id={d.id} draggable="true" onDragStart={onDragStart.bind(d)}>
126 {isModified ? <div className="-is-modified-indicator" title="This descriptor has changes."></div> : null}
127 <div className="type-header">{type}</div>
128 <dl>
129 <dt className="name">{d.name}</dt>
130 <dd className="logo">
131 <img className="logo" src={cleanDataURI(d['logo'], type, d.id)} draggable="false" onError={getImageErrorHandler(type)} />
132 </dd>
133 <dd className="short-name" title={d.name}>{d['short-name']}</dd>
134 <dd className="description">{d.description}</dd>
135 <dd className="vendor">{d.vendor || d.provider} {renderVersion(d.version)}</dd>
136 </dl>
137 </div>
138 </div>
139 {isOpenForEdit ? <div className="-is-open-for-edit-indicator" title="This descriptor is open in the canvas."></div> : null}
140 </li>
141 );
142 });
143 return (
144 <div className="CatalogItems">
145 <ul data-offset-parent="true">
146 {items.length ? items : messages.catalogWelcome}
147 </ul>
148 </div>
149 );
150 },
151 getCatalogItems() {
152 const catalogFilter = (d) => {return d.type === this.props.filterByType};
153 return this.state.catalogs.filter(catalogFilter).reduce((result, catalog) => {
154 return result.concat(catalog.descriptors);
155 }, []);
156 }
157 });
158
159 export default CatalogItems;