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/default-catalog-icon.svg'
30 import imgFG
from '../../../../node_modules/open-iconic/svg/infinity.svg'
31 import imgRemove
from '../../../../node_modules/open-iconic/svg/trash.svg'
32 import imgAdd
from '../../../../node_modules/open-iconic/svg/plus.svg'
33 import imgConnection
from '../../../../node_modules/open-iconic/svg/random.svg'
34 import imgClassifier
from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
35 import imgReorder
from '../../../../node_modules/open-iconic/svg/menu.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" />