3 * Copyright 2016 RIFT.IO Inc
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * Created by onvelocity on 2/4/16.
25 import React
from 'react'
26 import Range
from '../Range'
27 import Button
from '../Button'
28 import ClassNames
from 'classnames'
29 import changeCase
from 'change-case'
30 import LayoutRow
from '../LayoutRow'
31 import SelectionManager
from '../../libraries/SelectionManager'
32 import PureRenderMixin
from 'react-addons-pure-render-mixin'
33 import CatalogItemsActions
from '../../actions/CatalogItemsActions'
34 import CanvasEditorActions
from '../../actions/CanvasEditorActions'
35 import DescriptorModelFactory
from '../../libraries/model/DescriptorModelFactory'
36 import ComposerAppActions
from '../../actions/ComposerAppActions'
37 import DescriptorModelMetaFactory
from '../../libraries/model/DescriptorModelMetaFactory'
38 import ComposerAppStore
from '../../stores/ComposerAppStore'
39 import DeletionManager
from '../../libraries/DeletionManager'
40 import ContentEditableDiv
from '../ContentEditableDiv'
41 import TooltipManager
from '../../libraries/TooltipManager'
42 import HighlightRecordServicePaths
from '../../libraries/graph/HighlightRecordServicePaths'
43 import mapClassifier
from './mapClassifier'
44 import mapRecordServicePath
from './mapRecordServicePath'
45 import onCutDelegateToRemove
from './onCutDelegateToRemove'
46 import onClickSelectAndShowInDetailsPanel
from './onClickSelectAndShowInDetailsPanel'
48 import '../../styles/EditForwardingGraphPaths.scss'
50 import imgNSD
from '../../images/default-catalog-icon.svg'
51 import imgFG
from '../../../../node_modules/open-iconic/svg/infinity.svg'
52 import imgRemove
from '../../../../node_modules/open-iconic/svg/trash.svg'
53 import imgAdd
from '../../../../node_modules/open-iconic/svg/plus.svg'
54 import imgConnection
from '../../../../node_modules/open-iconic/svg/random.svg'
55 import imgClassifier
from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
56 import imgReorder
from '../../../../node_modules/open-iconic/svg/menu.svg'
58 function mapFG(fg
, i
) {
63 const colors
= fg
.colors
;
64 const stylePrimary
= {borderColor
: colors
.primary
};
65 const styleSecondary
= {borderColor
: colors
.secondary
};
67 context
.stylePrimary
= stylePrimary
;
68 context
.styleSecondary
= styleSecondary
;
70 const rspMap
= fg
.rsp
.reduce((map
, rsp
) => {
76 fg
.classifier
.forEach(classifier
=> {
77 const rsp
= rspMap
[classifier
.model
['rsp-id-ref']];
79 rsp
.classifier
.push(classifier
);
83 function onClickRemoveForwardingGraph(fg
, event
) {
84 event
.preventDefault();
85 const root
= fg
.getRoot();
87 CatalogItemsActions
.catalogItemDescriptorChanged(root
);
90 function onClickAddClassifier(context
, fg
, event
) {
91 event
.preventDefault();
92 fg
.createClassifier();
93 CatalogItemsActions
.catalogItemDescriptorChanged(fg
.getRoot());
96 function onClickToggleShowAllFGPaths(fg
, event
) {
97 //event.preventDefault();
98 event
.stopPropagation();
99 fg
.uiState
.showPaths
= event
.target
.checked
;
100 fg
.rsp
.forEach(rsp
=> rsp
.uiState
.showPath
= event
.target
.checked
);
101 CatalogItemsActions
.catalogItemMetaDataChanged(fg
.getRoot().model
);
104 if (!fg
.uiState
.hasOwnProperty('showPaths')) {
105 fg
.uiState
.showPaths
= true;
106 fg
.rsp
.forEach(d
=> d
.uiState
.showPath
= true);
109 const toggleSelectAllPaths
= (
110 <input type
="checkbox" name
={'show-path' + fg
.uid
} checked
={fg
.uiState
.showPaths
} onChange
={() => {}} onClick
={onClickToggleShowAllFGPaths
.bind(null, fg
)} />
113 const srpFactory
= DescriptorModelFactory
.newRecordServicePathFactory({}, fg
);
114 srpFactory
.uid
= fg
.uid
+ i
;
116 const hasServiceFunctionVNFDs
= context
.containers
.filter(d
=> DescriptorModelFactory
.isConstituentVnfdWithServiceChain(d
, 'SF')).length
> 0;
119 <div key
={i
} className
={fg
.className
} data
-uid
={fg
.uid
} data
-offset
-width
="true" onClick
={onClickSelectAndShowInDetailsPanel
.bind(null, fg
)} onCut
={onCutDelegateToRemove
.bind(null, fg
)}>
120 <div key
="outline-indicator" data
-outline
-indicator
="true"></div
>
121 <div className
="header-actions">
122 <Button className
="remove-forwarding-graph" title
="Remove" onClick
={onClickRemoveForwardingGraph
.bind(null, fg
)} src
={imgRemove
}/>
124 <LayoutRow primaryActionColumn
={toggleSelectAllPaths
} secondaryActionColumn
={<img className
="fg-icon" src
={imgFG
} width
="20px" />}>
125 <small
>{fg
.title
}</small
>
128 <h4
>Rendered Service Paths
</h4
>
129 {hasServiceFunctionVNFDs
? fg
.recordServicePaths
.concat(srpFactory
).map(mapRecordServicePath
.bind(null, context
)) : <small className
="no-service-function-chain-msg hint">A VNFD
with the chain SF is required to build Rendered Service Paths
.</small
>}
133 {fg
.classifier
.map(mapClassifier
.bind(null, context
))}
134 <div className
="footer-actions">
135 <div className
="row-action-column">
136 <Button className
="create-new-classifier" src
={imgAdd
} width
="20px" onClick
={onClickAddClassifier
.bind(null, context
, fg
)} label
="Add Classifier" />
145 function mapNSD(nsd
, i
) {
147 const context
= this;
150 function onClickAddForwardingGraph(nsd
, event
) {
151 event
.preventDefault();
153 CatalogItemsActions
.catalogItemDescriptorChanged(nsd
.getRoot());
156 const forwardingGraphs
= nsd
.forwardingGraphs
.map(mapFG
.bind(context
));
157 if (forwardingGraphs
.length
=== 0) {
158 forwardingGraphs
.push(
159 <div key
="1" className
="welcome-message">
160 No Forwarding Graphs to model
.
166 <div key
={i
} className
={nsd
.className
}>
168 <div className
="footer-actions">
169 <div className
="row-action-column">
170 <Button className
="create-new-forwarding-graph" src
={imgAdd
} width
="20px" onClick
={onClickAddForwardingGraph
.bind(null, nsd
)} label
="Add new Forwarding Graph" />
178 const EditForwardingGraphPaths
= React
.createClass({
179 mixins
: [PureRenderMixin
],
180 getInitialState: function () {
181 return ComposerAppStore
.getState();
183 getDefaultProps: function () {
188 componentWillMount: function () {
190 componentDidMount: function () {
192 componentDidUpdate: function () {
194 componentWillUnmount: function () {
198 const containers
= this.props
.containers
;
201 containers
: containers
204 const networkService
= containers
.filter(d
=> d
.type
=== 'nsd');
205 if (networkService
.length
=== 0) {
206 return <p className
="welcome-message">No
<img src
={imgNSD
} width
="20px" /> NSD open in the canvas. Try opening an NSD.</p>;
210 <div className
="EditForwardingGraphPaths -with-transitions" data
-offset
-parent
="true">
211 <div key
="outline-indicator" data
-outline
-indicator
="true"></div
>
212 {containers
.filter(d
=> d
.type
=== 'nsd').map(mapNSD
.bind(context
))}
219 export default EditForwardingGraphPaths
;