2 * Created by onvelocity on 3/2/16.
8 import React from 'react'
9 import Button from '../Button'
10 import LayoutRow from '../LayoutRow'
11 import ContentEditableDiv from '../ContentEditableDiv'
12 import changeCase from 'change-case'
13 import ClassNames from 'classnames'
14 import DescriptorModelFactory from '../../libraries/model/DescriptorModelFactory'
15 import DescriptorModelMetaFactory from '../../libraries/model/DescriptorModelMetaFactory'
16 import HighlightRecordServicePaths from '../../libraries/graph/HighlightRecordServicePaths'
17 import ComposerAppActions from '../../actions/ComposerAppActions'
18 import CatalogItemsActions from '../../actions/CatalogItemsActions'
19 import SelectionManager from '../../libraries/SelectionManager'
20 import DeletionManager from '../../libraries/DeletionManager'
21 import TooltipManager from '../../libraries/TooltipManager'
22 import ConnectionPointSelector from './ConnectionPointSelector'
23 import mapConnectionPoint from './mapConnectionPoint'
24 import EditableProperty from './EditableProperty'
25 import onCutDelegateToRemove from './onCutDelegateToRemove'
26 import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
27 import onFormInputChangedModifyContainerAndNotify from './onFormInputChangedModifyContainerAndNotify'
29 import imgNSD from '../../images/iconmonstr-network-6-icon.svg'
30 import imgFG from '../../images/iconmonstr-infinity-4-icon.svg'
31 import imgRemove from '../../images/recycle69.svg'
32 import imgAdd from '../../images/iconmonstr-plus-5-icon-256.png'
33 import imgConnection from '../../images/connection.svg'
34 import imgClassifier from '../../images/iconmonstr-control-panel-4.svg'
35 import imgReorder from '../../images/menu51.svg'
37 export default function mapClassifier(context, classifier, i) {
39 // todo if a classifier is linked to an rsp then highlight it
40 //rsp.uiState.showPath = rsp.uiState.hasOwnProperty('showPath') ? rsp.uiState.showPath : true;
42 function onInputUpdateModel(context, attr, name, event) {
43 event.preventDefault();
44 attr.setFieldValue(name, event.target.value);
45 CatalogItemsActions.catalogItemDescriptorChanged(attr.getRoot());
48 function onClickAddNewMatchAttributes(context, classifier) {
49 event.preventDefault();
50 event.stopPropagation();
51 const newMatchAttr = classifier.createMatchAttributes();
52 SelectionManager.disableOutlineChanges();
53 CatalogItemsActions.catalogItemDescriptorChanged(classifier.getRoot());
55 SelectionManager.enableOutlineChanges();
56 SelectionManager.select(newMatchAttr);
57 SelectionManager.refreshOutline();
58 const input = Array.from(document.querySelectorAll(`tr[data-uid="${newMatchAttr.uid}"] input`)).forEach((element, index) => {
59 // index 0 is hidden id field
67 function mapClassifierMatchAttributes(context, matchAttributes, key) {
68 const fields = matchAttributes.fieldNames.map((name, i) => {
70 <td key={i} className={name + '-property'}>
71 <div className="match-attr-name">{name}</div>
72 <ContentEditableDiv value={matchAttributes.getFieldValue(name)}
73 onBlur={() => DeletionManager.addEventListeners()}
75 event.preventDefault();
76 SelectionManager.select(matchAttributes);
77 SelectionManager.refreshOutline();
80 event.stopPropagation();
82 onChange={onInputUpdateModel.bind(null, context, matchAttributes, name)}
83 className="match-attr-value"/>
89 data-uid={matchAttributes.uid}
91 event.stopPropagation();
92 matchAttributes.remove();
93 CatalogItemsActions.catalogItemDescriptorChanged(matchAttributes.getRoot());
94 SelectionManager.refreshOutline();
101 function buildRecordServicePathSelector(classifier) {
102 const rspId = classifier.model['rsp-id-ref'];
103 const options = [{}].concat(classifier.parent.recordServicePaths).map((rsp, i) => {
105 <option key={i} name="rsp-id-ref" value={rsp.id}>{rsp.title}</option>
109 <select name="rsp-id-ref" value={rspId} onChange={onFormInputChangedModifyContainerAndNotify.bind(null, classifier)}>{options}</select>
113 function onClickExitPathEdithMode(component, event) {
114 event.preventDefault();
115 component.setState({editClassifierConnectionPointRef: false});
118 function onClickAddConnectionPointRef(component, classifier, connector, event) {
119 event.preventDefault();
120 classifier.addVnfdConnectionPoint(connector);
121 CatalogItemsActions.catalogItemDescriptorChanged(classifier.getRoot());
124 function onClickOpenConnectionPointSelector(component, classifier, event) {
125 component.setState({editClassifierConnectionPointRef: classifier.uid});
126 function closeAndRemoveHandler() {
127 component.setState({editClassifierConnectionPointRef: false});
128 document.body.removeEventListener('click', closeAndRemoveHandler, true);
130 document.body.addEventListener('click', closeAndRemoveHandler, true);
133 const attributeNames = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.vnffgd.classifier.match-attributes');
135 const selectedConnectionPoint = classifier.uiState.vnfdRef ? `${classifier.uiState.vnfdRef.name}/${classifier.vnfdConnectionPointRef.vnfdIndex}/${classifier.vnfdConnectionPointRef.vnfdConnectionPointName}` : '';
137 const isEditClassifierConnectionPointRef = context.component.state.editClassifierConnectionPointRef === classifier.uid;
139 const hasClassifierServiceFunctionVNFDs = context.containers.filter(d => DescriptorModelFactory.isConstituentVnfdWithServiceChain(d, 'CLASSIFIER')).length > 0;
142 <LayoutRow key={classifier.uid}
143 data-uid={classifier.uid}
144 data-offset-width="true"
145 className={ClassNames('fg-classifier', classifier.className, {'-is-edit-classifier-connection-point-ref': isEditClassifierConnectionPointRef})}
146 onClick={onClickSelectAndShowInDetailsPanel.bind(null, classifier)}>
147 <div className="classifier-properties">
148 <div className="classifier-property">
149 <EditableProperty title="name">
150 <ContentEditableDiv name="name"
151 value={classifier.name}
153 onBlur={() => DeletionManager.addEventListeners()}
154 onChange={onFormInputChangedModifyContainerAndNotify.bind(null, classifier)}
155 className="classifier-name" />
158 <div className="classifier-property">
159 <EditableProperty title="path">
160 {buildRecordServicePathSelector(classifier)}
163 <div className="classifier-property">
164 <EditableProperty title="connection point ref" disabled={!hasClassifierServiceFunctionVNFDs}>
165 <ContentEditableDiv autoPadRight="true"
166 value={selectedConnectionPoint}
167 disabled={!hasClassifierServiceFunctionVNFDs}
169 onClick={onClickOpenConnectionPointSelector.bind(null, context.component, classifier)} />
171 <div className="select-connection-point-ref">
172 <ConnectionPointSelector containers={context.containers}
173 style={context.styleSecondary}
174 serviceChain="CLASSIFIER"
175 isDisabled={!hasClassifierServiceFunctionVNFDs}
176 onExitEditPathMode={onClickExitPathEdithMode.bind(null, context.component)}
177 onAddConnectionPointRef={onClickAddConnectionPointRef.bind(null, context.component, classifier)}
180 {!hasClassifierServiceFunctionVNFDs ? <div className="hint">A VNFD with the chain CLASSIFIER is required to add a connection point ref.</div> : ''}
183 <table className="classifier-match-attributes">
186 {attributeNames.map((name, i) => <th key={i} className={ClassNames(name + '-property')}>{changeCase.title(name)}</th>)}
190 {classifier.matchAttributes.map(mapClassifierMatchAttributes.bind(null, context))}
193 <tr className="xfooter-actions">
194 <th colSpan={attributeNames.length} className="row-action-column">
195 <Button className="create-new-match-attributes" src={imgAdd} width="20px" onClick={onClickAddNewMatchAttributes.bind(null, context, classifier)} label="Add Match Attributes" />