Config Parameter Map easier flow
[osm/UI.git] / skyquake / plugins / composer / src / src / components / ConfigPrimitiveParameters / ConfigPrimitiveParameters.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
20
21 'use strict';
22
23 import _ from 'lodash'
24 import d3 from 'd3'
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
44 import '../../styles/EditForwardingGraphPaths.scss'
45
46 import imgNSD from '../../images/default-catalog-icon.svg'
47 import imgFG from '../../../../node_modules/open-iconic/svg/infinity.svg'
48 import imgRemove from '../../../../node_modules/open-iconic/svg/trash.svg'
49 import imgAdd from '../../../../node_modules/open-iconic/svg/plus.svg'
50 import imgConnection from '../../../../node_modules/open-iconic/svg/random.svg'
51 import imgClassifier from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
52 import imgReorder from '../../../../node_modules/open-iconic/svg/menu.svg'
53 import CatalogDataStore from '../../stores/CatalogDataStore'
54 import utils from '../../libraries/utils'
55 import getEventPath from '../../libraries/getEventPath'
56 import guid from '../../libraries/guid'
57
58 import '../../styles/EditDescriptorModelProperties.scss'
59 import '../../styles/EditConfigParameterMap.scss';
60
61 function configParameterMapMap(ap, i) {
62
63 const context = this;
64 context.vnfapMap = ap;
65 return (
66 <div key={i}>
67 <div>{ap.id}</div>
68 <div>{ap.capability['member-vnf-index']}</div>
69 <div>{ap.capability['capability-ref']}</div>
70
71 </div>
72 )
73
74 }
75
76 function mapNSD(nsd, i) {
77
78 const context = this;
79 context.nsd = nsd;
80
81 function onClickAddConfigParameterMap(nsd, event) {
82 event.preventDefault();
83 nsd.createConfigParameterMap();
84 CatalogItemsActions.catalogItemDescriptorChanged(nsd.getRoot());
85 }
86
87 const forwardingGraphs = nsd.configParameterMap.map(configParameterMap.bind(context));
88 if (forwardingGraphs.length === 0) {
89 forwardingGraphs.push(
90 <div key="1" className="welcome-message">
91 No Forwarding Graphs to model.
92 </div>
93 );
94 }
95
96 return (
97 <div key={i} className={nsd.className}>
98 {forwardingGraphs}
99 <div className="footer-actions">
100 <div className="row-action-column">
101 <Button className="create-new-forwarding-graph" src={imgAdd} width="20px" onClick={onClickAddConfigParameterMap.bind(null, nsd)} label="Add new Access Point" />
102 </div>
103 </div>
104 </div>
105 );
106
107 }
108
109
110 function startEditing() {
111 event.stopPropagation();
112 DeletionManager.removeEventListeners();
113 }
114
115 function endEditing() {
116 DeletionManager.addEventListeners();
117 }
118
119
120 const ConfigPrimitiveParameters = React.createClass({
121 mixins: [PureRenderMixin],
122 getInitialState: function () {
123 return ComposerAppStore.getState();
124 },
125 getDefaultProps: function () {
126 return {
127 containers: []
128 };
129 },
130 componentWillMount: function () {
131 },
132 componentDidMount: function () {
133 },
134 componentDidUpdate: function () {
135 },
136 componentWillUnmount: function () {
137 },
138 render() {
139 const self = this;
140 const containers = this.props.containers;
141 let NSContainer = containers.filter(function(c) {
142 return c.className == "NetworkService"
143 })[0]
144 const context = {
145 component: this,
146 containers: containers
147 };
148
149 const networkService = containers.filter(d => d.type === 'nsd');
150 if (networkService.length === 0) {
151 return <p className="welcome-message">No <img src={imgNSD} width="20px" /> NSD open in the canvas. Try opening an NSD.</p>;
152 }
153 let MapData = constructRequestSourceData(containers);
154 let mapCounter = 1;
155
156
157
158 return (
159 <div className="ConfigParameterMap">
160 <div className="config-parameter-map">
161 <div className="config-parameter-titles">
162 <div className="config-parameter">
163 Request
164 </div>
165 <div className="config-parameter">
166 Source
167 </div>
168 </div>
169 <div className="config-parameter-map">
170 {
171 MapData.Requests.map(function(r, i) {
172 let currentValue = {};
173 let SourceOptions = [<option value={JSON.stringify({
174 requestValue: r.name,
175 requestIndex: r.vnfdIndex
176 })} key="reset">No Source Selected</option>]
177 MapData.Sources.map(function(s, j) {
178 let value = {
179 value: s.name,
180 index: s.vnfdIndex,
181 requestValue: r.name,
182 requestIndex: r.vnfdIndex
183 }
184 SourceOptions.push(<option value={JSON.stringify(value)} key={`${j}-${i}`} >{`${s.vnfdName} (${s.vnfdIndex}) / ${s.name}`}</option>)
185 })
186 //Finds current value
187 NSContainer.model['config-parameter-map'] && NSContainer.model['config-parameter-map'].map((c)=>{
188 if(
189 c['config-parameter-request'] &&
190 (c['config-parameter-request']['config-parameter-request-ref'] == r.name)
191 && (c['config-parameter-request']['member-vnf-index-ref'] == r.vnfdIndex)
192 ) {
193 currentValue = {
194 value: c['config-parameter-source']['config-parameter-source-ref'],
195 index: c['config-parameter-source']['member-vnf-index-ref'],
196 requestValue: r.name,
197 requestIndex: r.vnfdIndex
198 };
199 }
200 })
201 currentValue.hasOwnProperty('value') ? mapCounter++ : mapCounter--;
202 let currentMapIndex = (mapCounter > 0) ? (mapCounter) - 1: 0;
203 return (
204 <div key={i} className="EditDescriptorModelProperties -is-tree-view config-parameter config-parameter-group">
205 <div className="config-parameter-request" >{`${r.vnfdName} (${r.vnfdIndex}) / ${r.parameter && r.parameter[0]['config-primitive-name-ref']} / ${r.parameter && r.parameter[0]['config-primitive-parameter-ref']}`}</div>
206 <div className="config-parameter-source">
207 <select
208 onChange={onFormFieldValueChanged.bind(NSContainer, i)}
209 onBlur={endEditing}
210 onMouseDown={startEditing}
211 onMouseOver={startEditing}
212 value={JSON.stringify(currentValue)}
213 >
214 }
215 {SourceOptions}
216 </select>
217 </div>
218 </div>
219 )
220 })
221 }
222 </div>
223 </div>
224 </div>
225 )
226 }
227 });
228
229 function onFormFieldValueChanged(index, event) {
230 if (DescriptorModelFactory.isContainer(this)) {
231 event.preventDefault();
232 const name = event.target.name;
233 const value = JSON.parse(event.target.value);
234
235 let ConfigMap = utils.resolvePath(this.model, 'config-parameter-map');
236 let ConfigMapIndex = false;
237 let id = guid().substring(0, 8);
238 //Check current map, if request is present, assign map index.
239 ConfigMap.map(function(c, i) {
240 let req = c['config-parameter-request'];
241 if((req['config-parameter-request-ref'] == value.requestValue) &&
242 (req['member-vnf-index-ref'] == value.requestIndex)) {
243 ConfigMapIndex = i;
244 id = c.id;
245 }
246 });
247 if(!ConfigMapIndex && _.isBoolean(ConfigMapIndex)) {
248 ConfigMapIndex = ConfigMap.length;
249 }
250 if(value.value) {
251 utils.assignPathValue(this.model, 'config-parameter-map.' + ConfigMapIndex + '.config-parameter-source.config-parameter-source-ref', value.value);
252 utils.assignPathValue(this.model, 'config-parameter-map.' + ConfigMapIndex + '.config-parameter-source.member-vnf-index-ref', value.index);
253 utils.assignPathValue(this.model, 'config-parameter-map.' + ConfigMapIndex + '.config-parameter-request.config-parameter-request-ref', value.requestValue);
254 utils.assignPathValue(this.model, 'config-parameter-map.' + ConfigMapIndex + '.config-parameter-request.member-vnf-index-ref', value.requestIndex);
255 utils.assignPathValue(this.model, 'config-parameter-map.' + ConfigMapIndex + '.id', id);
256 CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
257 } else {
258 utils.removePathValue(this.model, 'config-parameter-map.' + ConfigMapIndex)
259 CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
260
261 }
262 }
263 }
264
265
266 //Values from
267 //
268
269 //To update
270 //Container:NSD
271 //path
272 //["config-parameter", "config-parameter-source"]
273 //{config-parameter-source-ref: "service_port", member-vnf-index-ref: 2}
274
275 function constructRequestSourceData(containers) {
276 let cds = CatalogDataStore;
277 let catalogs = cds.getTransientCatalogs();
278 let Requests = [];
279 let Sources = [];
280 let vnfdData = {
281 index:[],
282 vnfdIDs:[],
283 indexRefs: {},
284 vnfdRefs:{}
285 };
286
287 //Init VNFD map
288 //{
289 //
290 // index:[1], //member-vnfd-index-ref
291 // vnfdIDs:[],
292 // indexRefs: {
293 // 1: vnfdID
294 // },
295 // vnfdRefs: {
296 // {1.id} : {...}
297 // }
298 //}
299
300 containers.map(function(c, i) {
301 if(c.className == 'ConstituentVnfd') {
302 vnfdData.index.push(c.vnfdIndex);
303 vnfdData.vnfdIDs.push(c.vnfdId);
304 vnfdData.indexRefs[c.vnfdIndex] = c.vnfdId;
305 vnfdData.vnfdRefs[c.vnfdId] = {
306 id: c.vnfdId,
307 name: c.name,
308 'short-name': c['short-name']
309 };
310 }
311 });
312
313 //Decorate VNFDMap with descriptor data;
314 catalogs[1].descriptors
315 .filter((v) => vnfdData.vnfdIDs.indexOf(v.id) > -1)
316 .map(constructVnfdMap.bind(this, vnfdData));
317
318
319 vnfdData.index.map(function(vnfdIndex) {
320 let vnfdId = vnfdData.indexRefs[vnfdIndex];
321 let vnfd = vnfdData.vnfdRefs[vnfdId];
322 let vnfdShortName = vnfd['short-name'];
323 vnfd.requests && vnfd.requests.map(function(request) {
324 Requests.push(_.merge({
325 id: vnfdId,
326 vnfdIndex: vnfdIndex,
327 vnfdName: vnfdShortName,
328 }, request))
329 });
330 vnfd.sources && vnfd.sources.map(function(source) {
331 Sources.push(_.merge({
332 id: vnfdId,
333 vnfdIndex: vnfdIndex,
334 vnfdName: vnfdShortName,
335 }, source));
336 });
337 })
338
339 return {Requests, Sources};
340
341 function constructVnfdMap(vnfdData, vnfd) {
342 let data = {
343 requests: vnfd['config-parameter']['config-parameter-request'],
344 sources: vnfd['config-parameter']['config-parameter-source']
345 };
346 vnfdData.vnfdRefs[vnfd.id] = _.merge(vnfdData.vnfdRefs[vnfd.id], data);
347 }
348
349 }
350
351
352
353 export default ConfigPrimitiveParameters;