aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment')
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js52
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js101
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js28
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx94
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js88
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx137
8 files changed, 569 insertions, 0 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js
new file mode 100644
index 0000000000..98f773b465
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js
@@ -0,0 +1,52 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import SoftwareProductDeploymentView from './SoftwareProductDeploymentView.jsx';
+import SoftwareProductDeploymentActionHelper from './SoftwareProductDeploymentActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export function mapStateToProps({softwareProduct}) {
+ let {softwareProductEditor: {data: currentSoftwareProduct = {}},softwareProductComponents: {componentsList}, softwareProductDeployment: {deploymentFlavors}} = softwareProduct;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ return {
+ isReadOnlyMode,
+ deploymentFlavors,
+ componentsList
+ };
+}
+
+function mapActionToProps(dispatch, {softwareProductId, version}) {
+ let modalClassName = 'deployment-flavor-editor';
+ return {
+ onAddDeployment: componentsList => SoftwareProductDeploymentActionHelper.openDeploymentFlavorEditor(dispatch, {softwareProductId, modalClassName, componentsList, version}),
+ onDeleteDeployment: ({id, model}) => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n(`Are you sure you want to delete "${model}"?`),
+ onConfirmed: () => SoftwareProductDeploymentActionHelper.deleteDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId: id, version})
+ }
+ }),
+ onEditDeployment: (deploymentFlavor, componentsList) =>
+ SoftwareProductDeploymentActionHelper.fetchDeploymentFlavor({softwareProductId, deploymentFlavorId: deploymentFlavor.id, version}).then(response =>
+ SoftwareProductDeploymentActionHelper
+ .openDeploymentFlavorEditor(dispatch, {softwareProductId, componentsList, modalClassName, deploymentFlavor: {...response.data, id: response.id}, isEdit: true, version}),
+ )
+ };
+}
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(SoftwareProductDeploymentView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js
new file mode 100644
index 0000000000..bd802b38f4
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js
@@ -0,0 +1,101 @@
+import {actionTypes} from './SoftwareProductDeploymentConstants.js';
+import {actionTypes as GlobalModalActions} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import pickBy from 'lodash/pickBy';
+
+function baseUrl(vspId, version) {
+ const versionId = version.id;
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/deployment-flavors`;
+}
+
+function fetchDeploymentFlavorsList({softwareProductId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`);
+}
+
+function fetchDeploymentFlavor({softwareProductId, deploymentFlavorId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}/${deploymentFlavorId}`);
+}
+
+function deleteDeploymentFlavor({softwareProductId, deploymentFlavorId, version}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${deploymentFlavorId}`);
+}
+
+function createDeploymentFlavor({softwareProductId, data, version}) {
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, data);
+}
+
+function editDeploymentFlavor({softwareProductId, deploymentFlavorId, data, version}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${deploymentFlavorId}`, data);
+}
+
+const SoftwareProductDeploymentActionHelper = {
+ fetchDeploymentFlavorsList(dispatch, {softwareProductId, version}) {
+ return fetchDeploymentFlavorsList({softwareProductId, version}).then(response => {
+ dispatch({
+ type: actionTypes.FETCH_SOFTWARE_PRODUCT_DEPLOYMENT_FLAVORS,
+ deploymentFlavors: response.results
+ });
+ });
+ },
+
+ fetchDeploymentFlavor({softwareProductId, deploymentFlavorId, version}) {
+ return fetchDeploymentFlavor({softwareProductId, deploymentFlavorId, version});
+ },
+
+ deleteDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId, version}) {
+ return deleteDeploymentFlavor({softwareProductId, deploymentFlavorId, version}).then(() => {
+ return SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ });
+ },
+
+ createDeploymentFlavor(dispatch, {softwareProductId, data, version}) {
+ return createDeploymentFlavor({softwareProductId, data, version}).then(() => {
+ return SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ });
+ },
+
+ editDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId, data, version}) {
+ let dataWithoutId = pickBy(data, (val, key) => key !== 'id');
+ return editDeploymentFlavor({softwareProductId, deploymentFlavorId, data: dataWithoutId, version}).then(() => {
+ return SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ });
+ },
+
+ closeDeploymentFlavorEditor(dispatch) {
+ dispatch({
+ type: actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_CLEAR_DATA
+ });
+ dispatch({
+ type: GlobalModalActions.GLOBAL_MODAL_CLOSE
+ });
+ },
+
+ openDeploymentFlavorEditor(dispatch, {softwareProductId, modalClassName, deploymentFlavor = {}, componentsList, isEdit = false, version}) {
+ let alteredDeploymentFlavor = {...deploymentFlavor};
+ if (componentsList.length) {
+ alteredDeploymentFlavor = {...alteredDeploymentFlavor, componentComputeAssociations: deploymentFlavor.componentComputeAssociations ?
+ [{...deploymentFlavor.componentComputeAssociations[0], componentId: componentsList[0].id}]
+ :
+ [{componentId: componentsList[0].id, computeFlavorId: null}]
+ };
+ }
+ dispatch({
+ type: actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_FILL_DATA,
+ deploymentFlavor: alteredDeploymentFlavor
+ });
+ dispatch({
+ type: GlobalModalActions.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.DEPLOYMENT_FLAVOR_EDITOR,
+ modalComponentProps: {softwareProductId, version},
+ modalClassName,
+ title: isEdit ? 'Edit Deployment Flavor' : 'Create a New Deployment Flavor'
+ }
+ });
+ },
+};
+
+export default SoftwareProductDeploymentActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js
new file mode 100644
index 0000000000..51469b461c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js
@@ -0,0 +1,28 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ FETCH_SOFTWARE_PRODUCT_DEPLOYMENT_FLAVORS: null,
+
+ deploymentFlavorEditor: {
+ DATA_CHANGED: null,
+ SOFTWARE_PRODUCT_DEPLOYMENT_FILL_DATA: null,
+ SOFTWARE_PRODUCT_DEPLOYMENT_CLEAR_DATA: null
+ }
+});
+
+export const DEPLOYMENT_FLAVORS_FORM_NAME = 'DEPLOYMENT_FLAVORS_FORM_NAME';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js
new file mode 100644
index 0000000000..8eb91e8fcb
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js
@@ -0,0 +1,25 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes} from './SoftwareProductDeploymentConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.FETCH_SOFTWARE_PRODUCT_DEPLOYMENT_FLAVORS:
+ return [...action.deploymentFlavors];
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx
new file mode 100644
index 0000000000..81477ecff7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx
@@ -0,0 +1,94 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
+
+export default class SoftwareProductDeployment extends React.Component {
+ state = {
+ localFilter: ''
+ };
+
+ static propTypes = {
+ onAddDeployment: React.PropTypes.func.isRequired,
+ onDeleteDeployment: React.PropTypes.func.isRequired,
+ onEditDeployment: React.PropTypes.func.isRequired,
+ isReadOnlyMode: React.PropTypes.bool.isRequired
+ };
+
+ render() {
+ return (
+ <div>
+ {this.renderList()}
+ </div>
+ );
+ }
+
+ renderList() {
+ let {onAddDeployment, isReadOnlyMode, componentsList} = this.props;
+ return (
+ <ListEditorView
+ plusButtonTitle={i18n('Add Deployment Flavor')}
+ filterValue={this.state.localFilter}
+ placeholder={i18n('Filter Deployment')}
+ onAdd={() => onAddDeployment(componentsList)}
+ isReadOnlyMode={isReadOnlyMode}
+ title={i18n('Deployment Flavors')}
+ onFilter={value => this.setState({localFilter: value})}
+ twoColumns>
+ {this.filterList().map(deploymentFlavor => this.renderListItem(deploymentFlavor, isReadOnlyMode))}
+ </ListEditorView>
+ );
+ }
+
+ renderListItem(deploymentFlavor, isReadOnlyMode) {
+ let {id, model, description} = deploymentFlavor;
+ let {onEditDeployment, onDeleteDeployment, componentsList} = this.props;
+ return (
+ <ListEditorItemView
+ key={id}
+ className='list-editor-item-view'
+ isReadOnlyMode={isReadOnlyMode}
+ onSelect={() => onEditDeployment(deploymentFlavor, componentsList)}
+ onDelete={() => onDeleteDeployment(deploymentFlavor)}>
+ <ListEditorItemViewField>
+ <div className='model'>{model}</div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
+ <div className='description'>{description}</div>
+ </ListEditorItemViewField>
+ </ListEditorItemView>
+ );
+ }
+
+ filterList() {
+ let {deploymentFlavors} = this.props;
+ let {localFilter} = this.state;
+
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return deploymentFlavors.filter(({model = '', description = ''}) => {
+ return escape(model).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return deploymentFlavors;
+ }
+ }
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js
new file mode 100644
index 0000000000..6b924a2816
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js
@@ -0,0 +1,88 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import SoftwareProductDeploymentEditorView from './SoftwareProductDeploymentEditorView.jsx';
+import SoftwareProdcutDeploymentActionHelper from '../SoftwareProductDeploymentActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+
+import {DEPLOYMENT_FLAVORS_FORM_NAME} from '../SoftwareProductDeploymentConstants.js';
+
+export function mapStateToProps({licenseModel, softwareProduct}) {
+ let {
+ softwareProductEditor: {
+ data: currentSoftwareProduct = {}
+ },
+ softwareProductComponents: {
+ componentsList,
+ computeFlavor: {
+ computesList
+ }
+ },
+ softwareProductDeployment: {
+ deploymentFlavors,
+ deploymentFlavorEditor: {
+ data = {},
+ genericFieldInfo,
+ formReady
+ }
+ }
+ } = softwareProduct;
+
+ let {
+ featureGroup: {
+ featureGroupsList
+ }
+ } = licenseModel;
+
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+ let selectedFeatureGroupsIds = currentSoftwareProduct.licensingData ? currentSoftwareProduct.licensingData.featureGroups || [] : [];
+ let selectedFeatureGroupsList = featureGroupsList
+ .filter(featureGroup => selectedFeatureGroupsIds.includes(featureGroup.id))
+ .map(featureGroup => ({value: featureGroup.id, label: featureGroup.name}));
+
+ let DFNames = {};
+
+ deploymentFlavors.map(deployment => {
+ DFNames[deployment.model] = deployment.id;
+ });
+
+ return {
+ data,
+ selectedFeatureGroupsList,
+ genericFieldInfo,
+ DFNames,
+ isFormValid,
+ formReady,
+ isReadOnlyMode,
+ componentsList,
+ computesList,
+ isEdit: Boolean(data.id)
+ };
+}
+
+function mapActionsToProps(dispatch, {softwareProductId, version}) {
+ return {
+ onDataChanged: (deltaData, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: DEPLOYMENT_FLAVORS_FORM_NAME, customValidations}),
+ onClose: () => SoftwareProdcutDeploymentActionHelper.closeDeploymentFlavorEditor(dispatch),
+ onCreate: data => SoftwareProdcutDeploymentActionHelper.createDeploymentFlavor(dispatch, {softwareProductId, data, version}),
+ onEdit: data => SoftwareProdcutDeploymentActionHelper.editDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId: data.id, data, version}),
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, DEPLOYMENT_FLAVORS_FORM_NAME)
+ };
+}
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductDeploymentEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js
new file mode 100644
index 0000000000..70836e8ff9
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js
@@ -0,0 +1,44 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes, DEPLOYMENT_FLAVORS_FORM_NAME} from '../SoftwareProductDeploymentConstants.js';;
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_FILL_DATA:
+ return {
+ ...state,
+ data: action.deploymentFlavor,
+ formReady: null,
+ formName: DEPLOYMENT_FLAVORS_FORM_NAME,
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 500}]
+ },
+ 'model' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
+ }
+ };
+ case actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_CLEAR_DATA:
+ return {};
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx
new file mode 100644
index 0000000000..2d621cd2f5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx
@@ -0,0 +1,137 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import SelectInput from 'nfvo-components/input/SelectInput.jsx';
+import SelectActionTable from 'nfvo-components/table/SelectActionTable.jsx';
+import SelectActionTableRow from 'nfvo-components/table/SelectActionTableRow.jsx';
+import SelectActionTableCell from 'nfvo-components/table/SelectActionTableCell.jsx';
+import Validator from 'nfvo-utils/Validator.js';
+
+export default class SoftwareProductDeploymentEditorView extends React.Component {
+ render() {
+ let {data, isEdit, onClose, onDataChanged, isReadOnlyMode, selectedFeatureGroupsList, componentsList, computesList, genericFieldInfo} = this.props;
+ let {model, description, featureGroupId, componentComputeAssociations = []} = data;
+ let featureGroupsExist = selectedFeatureGroupsList.length > 0;
+ return (
+ <div>
+ {genericFieldInfo && <Form
+ ref='validationForm'
+ hasButtons={true}
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ onSubmit={ () => this.submit() }
+ submitButtonText={isEdit ? i18n('Save') : i18n('Create')}
+ onReset={ () => onClose() }
+ onValidateForm={() => this.validate() }
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ className='vsp-deployment-editor'>
+ <GridSection>
+ <GridItem colSpan={1}>
+ <Input
+ onChange={model => onDataChanged({model}, {model: model => this.validateName(model)})}
+ label={i18n('Model')}
+ value={model}
+ data-test-id='deployment-model'
+ isValid={genericFieldInfo.model.isValid}
+ errorText={genericFieldInfo.model.errorText}
+ isRequired={true}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={3}>
+ <Input
+ onChange={description => onDataChanged({description})}
+ label={i18n('Description')}
+ value={description}
+ data-test-id='deployment-description'
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ type='text'/>
+ </GridItem>
+ </GridSection>
+ <GridSection className={`deployment-feature-groups-section${!featureGroupsExist ? ' no-feature-groups' : ''}`} title={i18n('License Details')}>
+ <GridItem colSpan={1}>
+ <SelectInput
+ data-test-id='deployment-feature-groups'
+ label={i18n('Feature Group')}
+ value={featureGroupId}
+ onChange={featureGroup => onDataChanged({featureGroupId: featureGroup ? featureGroup.value : null})}
+ type='select'
+ clearable={true}
+ disabled={isReadOnlyMode || !featureGroupsExist}
+ className='field-section'
+ options={selectedFeatureGroupsList}/>
+ </GridItem>
+ </GridSection>
+ {!featureGroupsExist && <GridSection className='deployment-feature-group-warning-section'>
+ <GridItem colSpan={3}>
+ <span>{i18n('Please assign Feature Groups in VSP General')}</span>
+ </GridItem>
+ </GridSection>}
+ <GridSection title={i18n('Assign VFCs and Compute Flavors')} className='vfc-table'>
+ <GridItem colSpan={4}>
+ <SelectActionTable
+ columns={['Virtual Function Components', 'Compute Flavors']}
+ numOfIcons={0}>
+ {componentComputeAssociations.map( (association, index) =>
+ <SelectActionTableRow key={association.componentId}>
+ <SelectActionTableCell
+ options={
+ componentsList
+ .map(component => ({value: component.id, label: component.displayName}) )
+ }
+ selected={association.componentId}
+ onChange={componentId => {
+ let newAssociations = [...componentComputeAssociations];
+ newAssociations[index] = {...newAssociations[index], componentId};
+ onDataChanged({componentComputeAssociations: newAssociations});
+ }}
+ disabled={true}/>
+ <SelectActionTableCell
+ options={
+ computesList
+ .filter(compute => compute.componentId === association.componentId)
+ .map(compute => ({value: compute.computeFlavorId, label: compute.name}) )
+ }
+ selected={association.computeFlavorId}
+ onChange={computeFlavorId => {
+ let newAssociations = [...componentComputeAssociations];
+ newAssociations[index] = {...newAssociations[index], computeFlavorId};
+ onDataChanged({componentComputeAssociations: newAssociations});
+ }}
+ disabled={isReadOnlyMode}/>
+ </SelectActionTableRow>
+ )}
+ </SelectActionTable>
+ </GridItem>
+ </GridSection>
+ </Form>}
+ </div>
+ );
+ }
+
+ validateName(value) {
+ const {data: {id = ''}, DFNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: DFNames});
+
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('Deployment flavor by the name \'' + value + '\' already exists. Deployment flavor name must be unique')};
+ }
+
+ submit(){
+ let {isEdit, onCreate, onEdit, onClose, data} = this.props;
+ if (isEdit) {
+ onEdit(data);
+ } else {
+ onCreate(data);
+ }
+ onClose();
+ }
+
+ validate() {
+ this.props.onValidateForm();
+ }
+}