2 * Copyright 2016 RIFT.IO Inc
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * STANDARD_RIFT_IO_COPYRIGHT
21 * Created by onvelocity on 2/4/16.
27 import React from 'react'
28 import Range from '../Range'
29 import Button from '../Button'
30 import ClassNames from 'classnames'
31 import changeCase from 'change-case'
32 import LayoutRow from '../LayoutRow'
33 import SelectionManager from '../../libraries/SelectionManager'
34 import PureRenderMixin from 'react-addons-pure-render-mixin'
35 import CatalogItemsActions from '../../actions/CatalogItemsActions'
36 import CanvasEditorActions from '../../actions/CanvasEditorActions'
37 import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
38 import ComposerAppActions from '../../actions/ComposerAppActions'
39 import DescriptorModelMetaFactory from '../../libraries/model/DescriptorModelMetaFactory'
40 import ComposerAppStore from '../../stores/ComposerAppStore'
41 import DeletionManager from '../../libraries/DeletionManager'
42 import ContentEditableDiv from '../ContentEditableDiv'
43 import TooltipManager from '../../libraries/TooltipManager'
44 import HighlightRecordServicePaths from '../../libraries/graph/HighlightRecordServicePaths'
45 import mapClassifier from './mapClassifier'
46 import mapRecordServicePath from './mapRecordServicePath'
47 import onCutDelegateToRemove from './onCutDelegateToRemove'
48 import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
50 import '../../styles/EditForwardingGraphPaths.scss'
52 import imgNSD from '../../images/default-catalog-icon.svg'
53 import imgFG from '../../../../node_modules/open-iconic/svg/infinity.svg'
54 import imgRemove from '../../../../node_modules/open-iconic/svg/trash.svg'
55 import imgAdd from '../../../../node_modules/open-iconic/svg/plus.svg'
56 import imgConnection from '../../../../node_modules/open-iconic/svg/random.svg'
57 import imgClassifier from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
58 import imgReorder from '../../../../node_modules/open-iconic/svg/menu.svg'
60 function mapFG(fg, i) {
65 const colors = fg.colors;
66 const stylePrimary = {borderColor: colors.primary};
67 const styleSecondary = {borderColor: colors.secondary};
69 context.stylePrimary = stylePrimary;
70 context.styleSecondary = styleSecondary;
72 const rspMap = fg.rsp.reduce((map, rsp) => {
78 fg.classifier.forEach(classifier => {
79 const rsp = rspMap[classifier.model['rsp-id-ref']];
81 rsp.classifier.push(classifier);
85 function onClickRemoveForwardingGraph(fg, event) {
86 event.preventDefault();
87 const root = fg.getRoot();
89 CatalogItemsActions.catalogItemDescriptorChanged(root);
92 function onClickAddClassifier(context, fg, event) {
93 event.preventDefault();
94 fg.createClassifier();
95 CatalogItemsActions.catalogItemDescriptorChanged(fg.getRoot());
98 function onClickToggleShowAllFGPaths(fg, event) {
99 //event.preventDefault();
100 event.stopPropagation();
101 fg.uiState.showPaths = event.target.checked;
102 fg.rsp.forEach(rsp => rsp.uiState.showPath = event.target.checked);
103 CatalogItemsActions.catalogItemMetaDataChanged(fg.getRoot().model);
106 if (!fg.uiState.hasOwnProperty('showPaths')) {
107 fg.uiState.showPaths = true;
108 fg.rsp.forEach(d => d.uiState.showPath = true);
111 const toggleSelectAllPaths = (
112 <input type="checkbox" name={'show-path' + fg.uid} checked={fg.uiState.showPaths} onChange={() => {}} onClick={onClickToggleShowAllFGPaths.bind(null, fg)} />
115 const srpFactory = DescriptorModelFactory.newRecordServicePathFactory({}, fg);
116 srpFactory.uid = fg.uid + i;
118 const hasServiceFunctionVNFDs = context.containers.filter(d => DescriptorModelFactory.isConstituentVnfdWithServiceChain(d, 'SF')).length > 0;
121 <div key={i} className={fg.className} data-uid={fg.uid} data-offset-width="true" onClick={onClickSelectAndShowInDetailsPanel.bind(null, fg)} onCut={onCutDelegateToRemove.bind(null, fg)}>
122 <div key="outline-indicator" data-outline-indicator="true"></div>
123 <div className="header-actions">
124 <Button className="remove-forwarding-graph" title="Remove" onClick={onClickRemoveForwardingGraph.bind(null, fg)} src={imgRemove}/>
126 <LayoutRow primaryActionColumn={toggleSelectAllPaths} secondaryActionColumn={<img className="fg-icon" src={imgFG} width="20px" />}>
127 <small>{fg.title}</small>
130 <h4>Record Service Paths</h4>
131 {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 Record Service Paths.</small>}
135 {fg.classifier.map(mapClassifier.bind(null, context))}
136 <div className="footer-actions">
137 <div className="row-action-column">
138 <Button className="create-new-classifier" src={imgAdd} width="20px" onClick={onClickAddClassifier.bind(null, context, fg)} label="Add Classifier" />
147 function mapNSD(nsd, i) {
149 const context = this;
152 function onClickAddForwardingGraph(nsd, event) {
153 event.preventDefault();
155 CatalogItemsActions.catalogItemDescriptorChanged(nsd.getRoot());
158 const forwardingGraphs = nsd.forwardingGraphs.map(mapFG.bind(context));
159 if (forwardingGraphs.length === 0) {
160 forwardingGraphs.push(
161 <div key="1" className="welcome-message">
162 No Forwarding Graphs to model.
168 <div key={i} className={nsd.className}>
170 <div className="footer-actions">
171 <div className="row-action-column">
172 <Button className="create-new-forwarding-graph" src={imgAdd} width="20px" onClick={onClickAddForwardingGraph.bind(null, nsd)} label="Add new Forwarding Graph" />
180 const EditForwardingGraphPaths = React.createClass({
181 mixins: [PureRenderMixin],
182 getInitialState: function () {
183 return ComposerAppStore.getState();
185 getDefaultProps: function () {
190 componentWillMount: function () {
192 componentDidMount: function () {
194 componentDidUpdate: function () {
196 componentWillUnmount: function () {
200 const containers = this.props.containers;
203 containers: containers
206 const networkService = containers.filter(d => d.type === 'nsd');
207 if (networkService.length === 0) {
208 return <p className="welcome-message">No <img src={imgNSD} width="20px" /> NSD open in the canvas. Try opening an NSD.</p>;
212 <div className="EditForwardingGraphPaths -with-transitions" data-offset-parent="true">
213 <div key="outline-indicator" data-outline-indicator="true"></div>
214 {containers.filter(d => d.type === 'nsd').map(mapNSD.bind(context))}
221 export default EditForwardingGraphPaths;