1 import React from 'react';
2 import ValidationTabs from 'nfvo-components/input/validation/ValidationTabs.jsx';
3 import ValidationTab from 'nfvo-components/input/validation/ValidationTab.jsx';
4 import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
5 import Button from 'react-bootstrap/lib/Button.js';
7 import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
8 import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx';
9 import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
10 import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
11 import ListEditorViewItem from 'nfvo-components/listEditor/ListEditorItemView.jsx';
12 import i18n from 'nfvo-utils/i18n/i18n.js';
14 import {state as FeatureGroupStateConstants} from './FeatureGroupsConstants.js';
16 const FeatureGroupsPropType = React.PropTypes.shape({
17 id: React.PropTypes.string,
18 name: React.PropTypes.string,
19 description: React.PropTypes.string,
20 partNumber: React.PropTypes.string,
21 entitlementPoolsIds: React.PropTypes.array(React.PropTypes.string),
22 licenseKeyGroupsIds: React.PropTypes.array(React.PropTypes.string)
25 class FeatureGroupEditorView extends React.Component {
29 data: FeatureGroupsPropType,
30 previousData: FeatureGroupsPropType,
31 isReadOnlyMode: React.PropTypes.bool,
33 onSubmit: React.PropTypes.func,
34 onCancel: React.PropTypes.func,
36 selectedTab: React.PropTypes.number,
37 onTabSelect: React.PropTypes.func,
39 selectedEntitlementPoolsButtonTab: React.PropTypes.number,
40 selectedLicenseKeyGroupsButtonTab: React.PropTypes.number,
41 onEntitlementPoolsButtonTabSelect: React.PropTypes.func,
42 onLicenseKeyGroupsButtonTabSelect: React.PropTypes.func,
44 entitlementPoolsList: DualListboxView.propTypes.availableList,
45 licenseKeyGroupsList: DualListboxView.propTypes.availableList
49 static defaultProps = {
51 selectedTab: FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL,
52 selectedEntitlementPoolsButtonTab: FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS,
53 selectedLicenseKeyGroupsButtonTab: FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS
57 localEntitlementPoolsListFilter: '',
58 localLicenseKeyGroupsListFilter: ''
63 let {selectedTab, onTabSelect, isReadOnlyMode} = this.props;
68 onSubmit={ () => this.submit() }
69 onReset={ () => this.props.onCancel() }
71 isReadOnlyMode={isReadOnlyMode}
72 name='feature-group-validation-form'
73 className='feature-group-form'>
74 <ValidationTabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect}>
75 {this.renderGeneralTab()}
76 {this.renderEntitlementPoolsTab()}
77 {this.renderLicenseKeyGroupsTab()}
85 const {data: featureGroup, previousData: previousFeatureGroup} = this.props;
86 this.props.onSubmit(previousFeatureGroup, featureGroup);
90 let {data = {}, onDataChanged} = this.props;
91 let {name, description, partNumber} = data;
93 <ValidationTab eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL} title={i18n('General')}>
96 groupClassName='field-section'
97 onChange={name => onDataChanged({name})}
101 name='feature-group-name'
102 validations={{maxLength: 120, required: true}}
105 groupClassName='field-section'
106 className='description-field'
107 onChange={description => onDataChanged({description})}
109 label={i18n('Description')}
111 name='feature-group-description'
112 validations={{maxLength: 1000, required: true}}
115 groupClassName='field-section'
116 onChange={partNumber => onDataChanged({partNumber})}
117 label={i18n('Part Number')}
119 validations={{required: true}}
126 renderEntitlementPoolsTab() {
127 let {selectedEntitlementPoolsButtonTab, onEntitlementPoolsButtonTabSelect, entitlementPoolsList} = this.props;
128 if (entitlementPoolsList.length > 0) {
131 eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
132 title={i18n('Entitlement Pools')}>
135 this.renderButtonsTab(
136 FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS,
137 selectedEntitlementPoolsButtonTab,
138 i18n('Associated Entitlement Pools'),
139 onEntitlementPoolsButtonTabSelect
143 this.renderButtonsTab(
144 FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.AVAILABLE_ENTITLEMENT_POOLS,
145 selectedEntitlementPoolsButtonTab,
146 i18n('Available Entitlement Pools'),
147 onEntitlementPoolsButtonTabSelect
151 {this.renderEntitlementPoolsButtonTabContent(selectedEntitlementPoolsButtonTab)}
157 eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
158 title={i18n('Entitlement Pools')}>
159 <p>{i18n('There is no available entitlement pools.')}</p>
165 renderLicenseKeyGroupsTab() {
166 let {selectedLicenseKeyGroupsButtonTab, onLicenseKeyGroupsButtonTabSelect, licenseKeyGroupsList} = this.props;
167 if (licenseKeyGroupsList.length > 0) {
170 eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS}
171 title={i18n('License Key Groups')}>
174 this.renderButtonsTab(
175 FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS,
176 selectedLicenseKeyGroupsButtonTab,
177 i18n('Associated License Key Groups'),
178 onLicenseKeyGroupsButtonTabSelect
182 this.renderButtonsTab(
183 FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.AVAILABLE_LICENSE_KEY_GROUPS,
184 selectedLicenseKeyGroupsButtonTab,
185 i18n('Available License Key Groups'),
186 onLicenseKeyGroupsButtonTabSelect
190 {this.renderLicenseKeyGroupsTabContent(selectedLicenseKeyGroupsButtonTab)}
196 eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS}
197 title={i18n('License Key Groups')}>
198 <p>{i18n('There is no available license key groups')}</p>
203 renderButtonsTab(buttonTab, selectedButtonTab, title, onClick) {
204 const isSelected = buttonTab === selectedButtonTab;
207 className='button-tab'
209 onClick={() => !isSelected && onClick(buttonTab)}>
215 renderEntitlementPoolsButtonTabContent(selectedFeatureGroupsButtonTab) {
216 const {entitlementPoolsList = [], data: {entitlementPoolsIds = []}} = this.props;
218 left: i18n('Available Entitlement Pools'),
219 right: i18n('Selected Entitlement Pools')
222 if (entitlementPoolsList.length) {
223 const {localEntitlementPoolsListFilter} = this.state;
224 let selectedEntitlementPools = entitlementPoolsIds.map(entitlementPoolId => entitlementPoolsList.find(entitlementPool => entitlementPool.id === entitlementPoolId));
226 switch (selectedFeatureGroupsButtonTab) {
227 case FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS:
228 if (selectedEntitlementPools.length) {
231 className='thinner-list'
232 filterValue={localEntitlementPoolsListFilter}
233 onFilter={localEntitlementPoolsListFilter => this.setState({localEntitlementPoolsListFilter})}>
234 {this.filterAssociatedItems(selectedEntitlementPools, localEntitlementPoolsListFilter)
235 .map(entitlementPool => this.renderAssociatedListItem(entitlementPool
236 , FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS))}
243 <br/>{i18n('There are currently no entitlement pools associated with this feature group. Click "Available Entitlement Pools" to associate.')}
247 case FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.AVAILABLE_ENTITLEMENT_POOLS:
250 filterTitle={dualBoxTitle}
251 selectedValuesList={entitlementPoolsIds}
252 availableList={entitlementPoolsList}
253 onChange={ selectedValuesList => this.props.onDataChanged( { entitlementPoolsIds: selectedValuesList } )}/>
259 renderLicenseKeyGroupsTabContent(selectedFeatureGroupsButtonTab) {
260 const {licenseKeyGroupsList = [], data: {licenseKeyGroupsIds = []}} = this.props;
261 let dualBoxFilterTitle = {
262 left: i18n('Available License Key Groups'),
263 right: i18n('Selected License Key Groups')
266 if (licenseKeyGroupsList.length) {
267 const {localLicenseKeyGroupsListFilter} = this.state;
268 let selectedLicenseKeyGroups = licenseKeyGroupsIds.map(licenseKeyGroupId => licenseKeyGroupsList.find(licenseKeyGroup => licenseKeyGroup.id === licenseKeyGroupId));
270 switch (selectedFeatureGroupsButtonTab) {
271 case FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS:
272 if (selectedLicenseKeyGroups.length) {
275 className='thinner-list'
276 filterValue={localLicenseKeyGroupsListFilter}
277 onFilter={localLicenseKeyGroupsListFilter => this.setState({localLicenseKeyGroupsListFilter})}>
278 {this.filterAssociatedItems(selectedLicenseKeyGroups, localLicenseKeyGroupsListFilter)
279 .map(licenseKeyGroup => this.renderAssociatedListItem(licenseKeyGroup
280 , FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS))}
285 <div className='no-items-msg'>
286 {i18n('There are currently no license key groups associated with this feature group. Click "Available License Key Groups" to associate.')}
290 case FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.AVAILABLE_LICENSE_KEY_GROUPS:
293 filterTitle={dualBoxFilterTitle}
294 selectedValuesList={this.props.data.licenseKeyGroupsIds}
295 availableList={this.props.licenseKeyGroupsList}
296 onChange={ selectedValuesList => this.props.onDataChanged( { licenseKeyGroupsIds: selectedValuesList } )}/>
303 renderAssociatedListItem(listItem, itemType) {
304 let {isReadOnlyMode} = this.props;
308 onDelete={() => this.deleteAssociatedItem(listItem.id, itemType)}
309 isReadOnlyMode={isReadOnlyMode}>
310 <div className='name'>{listItem.name}</div>
311 <div className='description'>{listItem.description}</div>
312 </ListEditorViewItem>
316 filterAssociatedItems(list, localList) {
318 const filter = new RegExp(escape(localList), 'i');
319 return list.filter(({name = '', description = ''}) => name.match(filter) || description.match(filter));
326 deleteAssociatedItem(id, type) {
327 const {data: {licenseKeyGroupsIds = [], entitlementPoolsIds = []}} = this.props;
328 if (type === FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS) {
329 this.props.onDataChanged({licenseKeyGroupsIds: licenseKeyGroupsIds.filter(listId => listId !== id)});
331 this.props.onDataChanged({entitlementPoolsIds: entitlementPoolsIds.filter(listId => listId !== id)});
338 export default FeatureGroupEditorView;