4 * Copyright 2016 RIFT.IO Inc
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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'
31 import '../styles/CatalogItems.scss'
32 import imgFile
from 'file!../images/vendor-riftio.png'
34 const CatalogItems
= React
.createClass({
35 mixins
: [PureRenderMixin
],
37 return CatalogDataStore
.getState();
44 componentWillMount() {
45 CatalogDataStore
.listen(this.onChange
);
48 // async actions creator will dispatch loadCatalogsSuccess and loadCatalogsError messages
49 CatalogDataStore
.loadCatalogs().catch(e
=> console
.warn('unable to load catalogs', e
));
51 componentWillUnmount() {
52 CatalogDataStore
.unlisten(this.onChange
);
57 renderVersion(version
) {
59 return (<span className
='version'>{version
}</span
>);
60 } // else return null by default
63 console
.log('Bad logo path, using default');
64 e
.target
.src
= require('style/img/catalog-default.svg');
68 const onDragStart = function(event
) {
69 const data
= {type
: 'catalog-item', item
: this};
70 event
.dataTransfer
.effectAllowed
= 'copy';
71 event
.dataTransfer
.setData('text', JSON
.stringify(data
));
72 ComposerAppActions
.setDragState(data
);
74 const onDblClickCatalogItem = function () {
75 CatalogItemsActions
.editCatalogItem(this);
77 const onClickCatalogItem = function () {
78 // single clicking an item is handled by ComposerApp::onClick handler
79 //CatalogItemsActions.selectCatalogItem(this);
81 const cleanDataURI
= this.cleanDataURI
;
82 const items
= this.getCatalogItems().map(function (d
) {
83 const isNSD
= d
.uiState
.type
=== 'nsd';
84 const isVNFD
= d
.uiState
.type
=== 'vnfd';
85 const isDeleted
= d
.uiState
.deleted
;
86 const isModified
= d
.uiState
.modified
;
87 const isSelected
= SelectionManager
.isSelected(d
);
88 const isOpenForEdit
= d
.uiState
.isOpenForEdit
;
89 const spanClassNames
= ClassNames({'-is-selected': isSelected
, '-is-open-for-edit': isOpenForEdit
});
90 const sectionClassNames
= ClassNames('catalog-item', {'-is-modified': isModified
, '-is-deleted': isDeleted
});
91 const instanceCount
= d
.uiState
['instance-ref-count'];
92 const instanceCountLabel
= isNSD
&& instanceCount
? <span
>({instanceCount
})</span
> : null;
101 <li key
={d
.id
} data
-uid
={UID
.from(d
)} onClick
={onClickCatalogItem
.bind(d
)} onDoubleClick
={onDblClickCatalogItem
.bind(d
)}>
102 <div className
={spanClassNames
+ ' ' + type
}>
103 <div className
={sectionClassNames
} id
={d
.id
} draggable
="true" onDragStart
={onDragStart
.bind(d
)}>
104 {isModified
? <div className
="-is-modified-indicator" title
="This descriptor has changes."></div
> : null}
105 <div className
="type-header">{type
}</div
>
107 <dt className
="name">{d
.name
} {instanceCountLabel
}</dt
>
108 <dd className
="logo">
109 <img className
="logo" src
={cleanDataURI(d
['logo'], type
, d
.id
)} draggable
="false" onError
={self
.handleImageError
} />
111 <dd className
="short-name" title
={d
.name
}>{d
['short-name']}</dd
>
112 <dd className
="description">{d
.description
}</dd
>
113 <dd className
="vendor">{d
.vendor
|| d
.provider
} {self
.renderVersion(d
.version
)}</dd
>
117 {isOpenForEdit
? <div className
="-is-open-for-edit-indicator" title
="This descriptor is open in the canvas."></div
> : null}
122 <div className
="CatalogItems">
123 <ul data
-offset
-parent
="true">
124 {items
.length
? items
: messages
.catalogWelcome
}
129 cleanDataURI(imageString
, type
, id
) {
130 if (/\bbase64\b/g.test(imageString
)) {
132 } else if (/<\?xml\b/g.test(imageString
)) {
133 const imgStr
= imageString
.substring(imageString
.indexOf('<?xml'));
134 return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(imgStr
);
135 } else if (/\.(svg|png|gif|jpeg|jpg)$/.test(imageString
)) {
136 return 'assets/logos/' + type
+ '/' + id
+ '/' + imageString
;
137 // return require('../images/logos/' + imageString);
139 if(type
== 'nsd' || type
== 'vnfd') {
140 return require('style/img/catalog-'+type
+'-default.svg');
142 return require('style/img/catalog-default.svg');
145 const catalogFilter
= (d
) => {return d
.type
=== this.props
.filterByType
};
146 return this.state
.catalogs
.filter(catalogFilter
).reduce((result
, catalog
) => {
147 return result
.concat(catalog
.descriptors
);
152 export default CatalogItems
;