aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-02-19 12:57:33 +0200
committerMichael Lando <ml636r@att.com>2017-02-19 13:47:13 +0200
commitefa037d34be7b1570efdc767c79fad8d4005f10e (patch)
treecf1036ba2728dea8a61492b678fa91954e629403 /openecomp-ui/src/sdc-app/onboarding/softwareProduct/components
parentf5f13c4f6b6fe3b4d98e349dfd7db59339803436 (diff)
Add new code new version
Change-Id: Ic02a76313503b526f17c3df29eb387a29fe6a42a Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct/components')
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js129
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js46
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx89
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js52
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx129
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js52
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx186
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx103
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js59
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js110
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js38
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js54
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx117
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js54
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js49
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx322
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js129
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js86
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx136
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js145
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js34
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js54
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx124
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js54
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js37
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx125
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx124
36 files changed, 3015 insertions, 0 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
new file mode 100644
index 0000000000..3b8bc4f171
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.COMPONENT_UPDATE:
+ return {
+ ...state,
+ data: action.component
+ };
+ case actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE:
+ return {
+ ...state,
+ qdata: action.payload.qdata || state.qdata,
+ qschema: action.payload.qschema || state.qschema
+ };
+ case actionTypes.COMPONENT_DATA_CHANGED:
+ return {
+ ...state,
+ data: {
+ ...state.data,
+ ...action.deltaData
+ }
+ };
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
new file mode 100644
index 0000000000..e53b2ecafe
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import {actionTypes} from './SoftwareProductComponentsConstants.js';
+
+function baseUrl(softwareProductId) {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components`;
+}
+
+function fetchSoftwareProductComponents(softwareProductId, version) {
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+}
+
+function putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, vspComponent) {
+ return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire`, vspComponent);
+}
+
+function fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version){
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire${versionQuery}`);
+}
+
+function fetchSoftwareProductComponent(softwareProductId, vspComponentId, version){
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}${versionQuery}`);
+}
+
+function putSoftwareProductComponent(softwareProductId, vspComponentId, vspComponent) {
+ return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}`, {
+ name: vspComponent.name,
+ displayName: vspComponent.displayName,
+ description: vspComponent.description
+ });
+}
+
+const SoftwareProductComponentsActionHelper = {
+ fetchSoftwareProductComponents(dispatch, {softwareProductId, version}) {
+ return fetchSoftwareProductComponents(softwareProductId, version).then(response => {
+ dispatch({
+ type: actionTypes.COMPONENTS_LIST_UPDATE,
+ componentsList: response.results
+ });
+ });
+ },
+
+ componentDataChanged(dispatch, {deltaData}) {
+ dispatch({
+ type: actionTypes.COMPONENT_DATA_CHANGED,
+ deltaData
+ });
+ },
+
+
+ updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, componentData, qdata}) {
+ return Promise.all([
+ SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}),
+ SoftwareProductComponentsActionHelper.updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData})
+ ]);
+ },
+
+ updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}) {
+ return putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, qdata);
+ },
+
+ updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData}) {
+ return putSoftwareProductComponent(softwareProductId, vspComponentId, componentData).then(() => dispatch({
+ type: actionTypes.COMPONENTS_LIST_EDIT,
+ component: {
+ id: vspComponentId,
+ ...componentData
+ }
+ }));
+ },
+
+
+ fetchSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, version}) {
+ return fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version).then(response => {
+ dispatch({
+ type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE,
+ payload: {
+ qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)
+ }
+ });
+ });
+ },
+
+ fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, version}) {
+ return fetchSoftwareProductComponent(softwareProductId, vspComponentId, version).then(response => {
+ dispatch({
+ type: actionTypes.COMPONENT_UPDATE,
+ component: response.data
+ });
+ });
+ },
+
+ componentQuestionnaireUpdated(dispatch, {data}) {
+ dispatch({
+ type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE,
+ payload: {
+ qdata: data
+ }
+ });
+ },
+};
+
+export default SoftwareProductComponentsActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
new file mode 100644
index 0000000000..dee517e5d1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ COMPONENTS_LIST_UPDATE: null,
+ COMPONENTS_LIST_EDIT: null,
+ COMPONENT_UPDATE: null,
+ COMPONENT_DATA_CHANGED: null,
+ COMPONENT_QUESTIONNAIRE_UPDATE: null
+});
+
+export const storageConstants = keyMirror({
+ backupType: {
+ ON_SITE: 'OnSite',
+ OFF_SITE: 'OffSite'
+ }
+});
+
+export const navigationItems = keyMirror({
+ STORAGE: 'Storage',
+ PROCESS_DETAILS: 'Process Details',
+ MONITORING: 'Monitoring',
+ NETWORK: 'Network',
+ COMPUTE: 'Compute',
+ NETWORK: 'Network',
+ LOAD_BALANCING: 'High Availability & Load Balancing'
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
new file mode 100644
index 0000000000..f1c1ed1fcc
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentsListView from './SoftwareProductComponentsListView.jsx';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+
+const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductComponents} = softwareProduct;
+ let {componentsList} = softwareProductComponents;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+ return {
+ currentSoftwareProduct,
+ isReadOnlyMode,
+ componentsList
+ };
+};
+
+
+const mapActionToProps = (dispatch, {version}) => {
+ return {
+ onComponentSelect: ({id: softwareProductId, componentId}) => {
+ OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version });
+ }
+ };
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
new file mode 100644
index 0000000000..b91362a0cf
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.COMPONENTS_LIST_UPDATE:
+ return [...action.componentsList];
+ case actionTypes.COMPONENTS_LIST_EDIT:
+ const indexForEdit = state.findIndex(component => component.id === action.component.id);
+ return [...state.slice(0, indexForEdit), action.component, ...state.slice(indexForEdit + 1)];
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
new file mode 100644
index 0000000000..0c0ba0f646
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
@@ -0,0 +1,89 @@
+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';
+
+const ComponentPropType = React.PropTypes.shape({
+ id: React.PropTypes.string,
+ name: React.PropTypes.string,
+ displayName: React.PropTypes.string,
+ description: React.PropTypes.string
+});
+
+class SoftwareProductComponentsListView extends React.Component {
+
+ state = {
+ localFilter: ''
+ };
+
+ static propTypes = {
+ isReadOnlyMode: React.PropTypes.bool,
+ componentsList: React.PropTypes.arrayOf(ComponentPropType),
+ onComponentSelect: React.PropTypes.func
+ };
+
+ render() {
+ let {componentsList = []} = this.props;
+ return (
+ <div className=''>
+ {
+ componentsList.length > 0 && this.renderComponents()
+ }
+ </div>
+ );
+ }
+
+ renderComponents() {
+ const {localFilter} = this.state;
+ let {isReadOnlyMode} = this.props;
+
+ return (
+ <ListEditorView
+ title={i18n('Virtual Function Components')}
+ filterValue={localFilter}
+ placeholder={i18n('Filter Components')}
+ onFilter={filter => this.setState({localFilter: filter})}
+ isReadOnlyMode={isReadOnlyMode}>
+ {this.filterList().map(component => this.renderComponentsListItem(component))}
+ </ListEditorView>
+ );
+ }
+
+ renderComponentsListItem(component) {
+ let {id: componentId, name, displayName, description = ''} = component;
+ let {currentSoftwareProduct: {id}, onComponentSelect} = this.props;
+ return (
+ <ListEditorItemView
+ key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
+ className='list-editor-item-view'
+ onSelect={() => onComponentSelect({id, componentId})}>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Component')}</div>
+ <div className='name'>{displayName}</div>
+ </div>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Description')}</div>
+ <div className='description'>{description}</div>
+ </div>
+ </ListEditorItemView>
+ );
+ }
+
+ filterList() {
+ let {componentsList = []} = this.props;
+
+ let {localFilter} = this.state;
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return componentsList.filter(({displayName = '', description = ''}) => {
+ return escape(displayName).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return componentsList;
+ }
+ }
+}
+
+export default SoftwareProductComponentsListView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
new file mode 100644
index 0000000000..7ac1c707ab
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentComputeView from './SoftwareProductComponentComputeView.jsx';
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+
+const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+ let {componentEditor: {qdata, qschema}} = softwareProductComponents;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+ let minNumberOfVMsSelectedByUser = 0;
+ if(qdata && qdata.compute && qdata.compute.numOfVMs){
+ minNumberOfVMsSelectedByUser = qdata.compute.numOfVMs.minimum || 0;
+ }
+
+ return {
+ qdata,
+ qschema,
+ isReadOnlyMode,
+ minNumberOfVMsSelectedByUser
+ };
+};
+
+const mapActionToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+ onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+ };
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true}) (SoftwareProductComponentComputeView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
new file mode 100644
index 0000000000..3bad147117
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
@@ -0,0 +1,129 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+
+class SoftwareProductComponentComputeView extends React.Component {
+
+ static propTypes = {
+ qdata: React.PropTypes.object,
+ qschema: React.PropTypes.object,
+ isReadOnlyMode: React.PropTypes.bool,
+ minNumberOfVMsSelectedByUser: React.PropTypes.number,
+ onQDataChanged: React.PropTypes.func.isRequired,
+ onSubmit: React.PropTypes.func.isRequired
+ };
+
+ render() {
+ let {qdata, qschema, isReadOnlyMode, minNumberOfVMsSelectedByUser, onQDataChanged, onSubmit} = this.props;
+
+ return (
+ <div className='vsp-component-questionnaire-view'>
+ <ValidationForm
+ ref='computeValidationForm'
+ hasButtons={false}
+ onSubmit={() => onSubmit({qdata})}
+ className='component-questionnaire-validation-form'
+ isReadOnlyMode={isReadOnlyMode}
+ onDataChanged={onQDataChanged}
+ data={qdata}
+ schema={qschema}>
+
+ <div className='section-title'>{i18n('VM Sizing')}</div>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Number of CPUs')}
+ pointer={'/compute/vmSizing/numOfCPUs'}/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('File System Size (GB)')}
+ pointer={'/compute/vmSizing/fileSystemSizeGB'}/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Persistent Storage/Volume Size (GB)')}
+ pointer={'/compute/vmSizing/persistentStorageVolumeSize'}/>
+ </div>
+ <ValidationInput
+ type='text'
+ label={i18n('I/O Operations (per second)')}
+ pointer={'/compute/vmSizing/IOOperationsPerSec'}/>
+ </div>
+ </div>
+ <div className='section-title'>{i18n('Number of VMs')}</div>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Minimum')}
+ pointer={'/compute/numOfVMs/minimum'}/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Maximum')}
+ pointer={'/compute/numOfVMs/maximum'}
+ validations={{minValue: minNumberOfVMsSelectedByUser}}/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='select'
+ label={i18n('CPU Oversubscription Ratio')}
+ pointer={'/compute/numOfVMs/CpuOverSubscriptionRatio'}/>
+ </div>
+ <ValidationInput
+ type='select'
+ label={i18n('Memory - RAM')}
+ pointer={'/compute/numOfVMs/MemoryRAM'}/>
+ </div>
+ </div>
+
+ <div className='section-title'>{i18n('Guest OS')}</div>
+ <div className='rows-section'>
+ <div className='section-field row-flex-components input-row'>
+ <div className='two-col'>
+ <ValidationInput
+ label={i18n('Guest OS')}
+ type='text'
+ pointer={'/compute/guestOS/name'}/>
+ </div>
+ <div className='empty-two-col'/>
+ </div>
+ <div className='vertical-flex input-row'>
+ <label key='label' className='control-label'>{i18n('OS Bit Size')}</label>
+ <div className='radio-options-content-row input-row'>
+ <ValidationInput
+ type='radiogroup'
+ pointer={'/compute/guestOS/bitSize'}
+ className='radio-field'/>
+ </div>
+ </div>
+ <div className='section-field row-flex-components input-row'>
+ <div className='two-col'>
+ <ValidationInput
+ type='textarea'
+ label={i18n('Guest OS Tools:')}
+ pointer={'/compute/guestOS/tools'}/>
+ </div>
+ <div className='empty-two-col'/>
+ </div>
+ </div>
+ </ValidationForm>
+ </div>
+ );
+ }
+
+ save(){
+ return this.refs.computeValidationForm.handleFormSubmit(new Event('dummy'));
+ }
+}
+
+export default SoftwareProductComponentComputeView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
new file mode 100644
index 0000000000..e4c330bec8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentsGeneralView from './SoftwareProductComponentsGeneralView.jsx';
+import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+ let {componentEditor: {data: componentData = {} , qdata, qschema}} = softwareProductComponents;
+
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+ return {
+ componentData,
+ qdata,
+ qschema,
+ isReadOnlyMode
+ };
+};
+
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}),
+ onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+ onSubmit: ({componentData, qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
+ {softwareProductId, vspComponentId: componentId, componentData, qdata});
+ }
+ };
+
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsGeneralView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
new file mode 100644
index 0000000000..5d11e42cd3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
@@ -0,0 +1,186 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+
+class SoftwareProductComponentsGeneralView extends React.Component {
+
+ render() {
+ let {qdata, qschema, onQDataChanged, onDataChanged, componentData: {displayName, description}, isReadOnlyMode} = this.props;
+ return(
+ <div className='vsp-components-general'>
+ <div className='general-data'>
+ <ValidationForm
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
+ <div className=''>
+ <h3 className='section-title'>{i18n('General')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ {/** disabled until backend will be ready to implement it
+ <div className='validation-input-wrapper'>
+ <div className='form-group'>
+ <label className='control-label'>{i18n('Name')}</label>
+ <div>{name}</div>
+ </div>
+ </div>
+
+ */}
+ <div className='single-col'>
+ <ValidationInput label={i18n('Name')} value={displayName} disabled={true} type='text'/>
+ </div>
+ <div className='two-col'>
+ <ValidationInput
+ label={i18n('Description')}
+ onChange={description => onDataChanged({description})}
+ disabled={isReadOnlyMode}
+ value={description}
+ type='textarea'/>
+ </div>
+ <div className='empty-col' />
+ </div>
+ </div>
+ </div>
+ </ValidationForm>
+ {
+ qschema &&
+ <ValidationForm
+ onDataChanged={onQDataChanged}
+ data={qdata}
+ schema={qschema}
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
+ <h3 className='section-title additional-validation-form'>{i18n('Hypervisor')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ label={i18n('Supported Hypervisors')}
+ type='select'
+ pointer='/general/hypervisor/hypervisor'/>
+ </div>
+ <div className='two-col'>
+ <ValidationInput
+ label={i18n('Hypervisor Drivers')}
+ type='text'
+ pointer='/general/hypervisor/drivers'/>
+ </div>
+ <div className='empty-col' />
+ </div>
+ <div className='row-flex-components input-row'>
+ <div className='three-col'>
+ <ValidationInput
+ label={i18n('Describe Container Features')}
+ type='textarea'
+ pointer='/general/hypervisor/containerFeaturesDescription'/>
+ </div>
+ <div className='empty-col' />
+ </div>
+ </div>
+ <h3 className='section-title'>{i18n('Image')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ label={i18n('Image format')}
+ type='select'
+ pointer='/general/image/format'/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ label={i18n('Image provided by')}
+ type='select'
+ pointer='/general/image/providedBy'/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ label={i18n('Size of boot disk per VM (GB)')}
+ type='text'
+ pointer='/general/image/bootDiskSizePerVM'/>
+ </div>
+ <ValidationInput
+ label={i18n('Size of ephemeral disk per VM (GB)')}
+ type='text'
+ pointer='/general/image/ephemeralDiskSizePerVM'/>
+ </div>
+ </div>
+ <h3 className='section-title'>{i18n('Recovery')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ label={i18n('VM Recovery Point Objective (Minutes)')}
+ type='text'
+ pointer='/general/recovery/pointObjective'/>
+ </div>
+ <ValidationInput
+ label={i18n('VM Recovery Time Objective (Minutes)')}
+ type='text'
+ pointer='/general/recovery/timeObjective'/>
+ <div className='empty-two-col' />
+ </div>
+
+
+ <div className='row-flex-components input-row'>
+ <div className='two-col'>
+ <ValidationInput
+ className='textarea'
+ label={i18n('How are in VM process failures handled?')}
+ type='textarea'
+ pointer='/general/recovery/vmProcessFailuresHandling'/>
+ </div>
+ <div className='empty-two-col' />
+ {
+ /** disabled until backend will be ready to implement it
+ <div className='row'>
+ <div className='col-md-3'>
+ <ValidationInput
+ label={i18n('VM Recovery Document')}
+ type='text'
+ pointer='/general/recovery/VMRecoveryDocument'/>
+ </div>
+ </div>
+ */
+ }
+ </div>
+ </div>
+ <h3 className='section-title'>{i18n('DNS Configuration')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='two-col'>
+ <ValidationInput
+ label={i18n('Do you have a need for DNS as a Service? Please describe.')}
+ type='textarea'
+ pointer='/general/dnsConfiguration'/>
+ </div>
+ <div className='empty-two-col' />
+ </div>
+ </div>
+ <h3 className='section-title'>{i18n('Clone')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='two-col'>
+ <ValidationInput
+ label={i18n('Describe VM Clone Use')}
+ type='textarea'
+ pointer='/general/vmCloneUsage'/>
+ </div>
+ <div className='empty-two-col' />
+ </div>
+ </div>
+ </ValidationForm>
+ }
+ </div>
+ </div>
+ );
+ }
+
+ save() {
+ let {onSubmit, componentData, qdata} = this.props;
+ return onSubmit({componentData, qdata});
+ }
+}
+
+export default SoftwareProductComponentsGeneralView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
new file mode 100644
index 0000000000..4d4034de5b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentLoadBalancingView from './SoftwareProductComponentLoadBalancingRefView.jsx';
+import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+ let {componentEditor: {qdata, qschema}} = softwareProductComponents;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+ return {
+ qdata,
+ qschema,
+ isReadOnlyMode
+ };
+};
+
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+ onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+ };
+
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentLoadBalancingView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
new file mode 100644
index 0000000000..1aa2babc12
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
@@ -0,0 +1,103 @@
+import React from 'react';
+import FontAwesome from 'react-fontawesome';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+const prefix = '/highAvailabilityAndLoadBalancing/';
+
+const pointers = [
+ {
+ key: 'failureLoadDistribution',
+ description: 'How is load distributed across live vms in the event of a vm/host failure? please describe'
+ },
+ {
+ key: 'nkModelImplementation',
+ description: 'Does each VM implement the N+K model for redundancy and failure protection? Please describe.'
+ },
+ {
+ key: 'architectureChoice',
+ description: 'What architecture is being implemented: ACTIVE-ACTIVE and/or ACTIVE-PASSIVE. ',
+ added: 'Will the arrangement be 1-1 or N-M? Please describe.'
+ },
+ {key: 'slaRequirements', description: 'Specify application SLA requirements on Cloud platform.'},
+ {
+ key: 'horizontalScaling',
+ description: 'Is horizontal scaling the preferred solution for HA and resiliency? Please describe.'
+ },
+ {
+ key: 'loadDistributionMechanism',
+ description: 'Can load be distributed across VMs? If so, are special mechanisms needed to re-balance data across VMs?',
+ added: 'Please describe.'
+ }
+];
+
+class SoftwareProductComponentLoadBalancingView extends React.Component {
+ static propTypes = {
+ componentId: React.PropTypes.string.isRequired,
+ softwareProductId: React.PropTypes.string.isRequired,
+ qdata: React.PropTypes.object,
+ qschema: React.PropTypes.object,
+ currentSoftwareProduct: React.PropTypes.object
+ };
+
+ state = {
+ expanded: {}
+ };
+
+ renderTextAreaItem(item) {
+ return (
+ <div className='question'>
+ <div className={this.state.expanded[item.key] ? 'title' : 'title add-padding'}
+ onClick={() => this.toggle(item.key)}>
+ <FontAwesome name={this.state.expanded[item.key] ? 'chevron-up' : 'chevron-down'}/>
+ {i18n(item.description)}
+ {item.added && <div className='new-line'>{i18n(item.added)}</div>}
+ </div>
+ <div className={this.state.expanded[item.key] ? 'collapse in' : 'collapse'}>
+ <div className='row'>
+ <div className='col-md-9'>
+ <ValidationInput
+ type='textarea'
+ pointer={`${prefix}${item.key}`}
+ maxLength='1000' />
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+
+ render() {
+ let {qdata, qschema, onQDataChanged, isReadOnlyMode} = this.props;
+ return (
+ <div className='vsp-components-load-balancing'>
+ <div className='halb-data'>
+ <div className='load-balancing-page-title'>{i18n('High Availability & Load Balancing')}</div>
+ <ValidationForm
+ onDataChanged={onQDataChanged}
+ data={qdata} schema={qschema}
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
+ {pointers.map(pointer => this.renderTextAreaItem(pointer))}
+ </ValidationForm>
+ </div>
+ </div>
+ );
+ }
+
+ toggle(name) {
+ let st = this.state.expanded[name] ? true : false;
+ let newState = {...this.state};
+ newState.expanded[name] = !st;
+ this.setState(newState);
+ }
+
+ save() {
+ let {onSubmit, qdata} = this.props;
+ return onSubmit({qdata});
+ }
+}
+
+export default SoftwareProductComponentLoadBalancingView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js
new file mode 100644
index 0000000000..ed7c5a116a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductComponentsMonitoringView from './SoftwareProductComponentsMonitoringView.jsx';
+import SoftwareProductComponentsMonitoringAction from './SoftwareProductComponentsMonitoringActionHelper.js';
+
+
+export const mapStateToProps = ({softwareProduct}) => {
+
+ let {softwareProductEditor: {data:currentVSP = {}}, softwareProductComponents: {monitoring}} = softwareProduct;
+ let {trapFilename, pollFilename} = monitoring;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+ return {
+ isReadOnlyMode,
+ trapFilename,
+ pollFilename
+ };
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onDropMibFileToUpload: (formData, type) =>
+ SoftwareProductComponentsMonitoringAction.uploadSnmpFile(dispatch, {
+ softwareProductId,
+ componentId,
+ formData,
+ type
+ }),
+
+ onDeleteSnmpFile: type => SoftwareProductComponentsMonitoringAction.deleteSnmpFile(dispatch, {
+ softwareProductId,
+ componentId,
+ type
+ })
+
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsMonitoringView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
new file mode 100644
index 0000000000..3faf571c09
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import SoftwareProductComponentsMonitoringConstants, {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+
+const UPLOAD = true;
+
+function baseUrl(vspId, componentId) {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/components/${componentId}/monitors`;
+}
+
+function snmpTrapUrl(vspId, componentId, isUpload) {
+ return `${baseUrl(vspId, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`;
+}
+
+function snmpPollUrl(vspId, componentId, isUpload) {
+ return `${baseUrl(vspId, componentId)}/snmp${isUpload ? '/upload' : ''}`;
+}
+
+let onInvalidFileSizeUpload = (dispatch) => dispatch({
+ type: NotificationConstants.NOTIFY_ERROR,
+ data: {
+ title: i18n('Upload Failed'),
+ msg: i18n('no zip file was uploaded or zip file doesn\'t exist')
+ }
+});
+
+let uploadSnmpTrapFile = (dispatch, {softwareProductId, componentId, formData}) => {
+ RestAPIUtil.create(snmpTrapUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({
+ type: actionTypes.SNMP_TRAP_UPLOADED, data: {filename: formData.get('upload').name}
+ }));
+};
+
+let uploadSnmpPollFile = (dispatch, {softwareProductId, componentId, formData}) => {
+ RestAPIUtil.create(snmpPollUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({
+ type: actionTypes.SNMP_POLL_UPLOADED, data: {filename: formData.get('upload').name}
+ }));
+};
+
+let deleteSnmpTrapFile = (dispatch, {softwareProductId, componentId}) => {
+ RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({
+ type: actionTypes.SNMP_TRAP_DELETED
+ }));
+};
+
+let deleteSnmpPollFile = (dispatch, {softwareProductId, componentId}) => {
+ RestAPIUtil.destroy(snmpPollUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({
+ type: actionTypes.SNMP_POLL_DELETED
+ }));
+};
+
+const SoftwareProductComponentsMonitoringAction = {
+
+ fetchExistingFiles(dispatch, {softwareProductId, componentId}){
+ RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/snmp`).then(response =>
+ dispatch({
+ type: actionTypes.SNMP_FILES_DATA_CHANGE,
+ data: {trapFilename: response.snmpTrap, pollFilename: response.snmpPoll}
+ })
+ );
+ },
+
+ uploadSnmpFile(dispatch, {softwareProductId, componentId, formData, type}){
+ if (formData.get('upload').size) {
+ if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
+ uploadSnmpTrapFile(dispatch, {softwareProductId, componentId, formData});
+ }
+ else {
+ uploadSnmpPollFile(dispatch, {softwareProductId, componentId, formData});
+ }
+ }
+ else {
+ onInvalidFileSizeUpload(dispatch);
+ }
+ },
+
+ deleteSnmpFile(dispatch, {softwareProductId, componentId, type}){
+ if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
+ deleteSnmpTrapFile(dispatch, {softwareProductId, componentId});
+ }
+ else {
+ deleteSnmpPollFile(dispatch, {softwareProductId, componentId});
+ }
+ }
+
+};
+
+export default SoftwareProductComponentsMonitoringAction;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
new file mode 100644
index 0000000000..eeececb050
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+
+ SNMP_FILES_DATA_CHANGE: null,
+
+ SNMP_TRAP_UPLOADED: null,
+ SNMP_POLL_UPLOADED: null,
+
+ SNMP_TRAP_DELETED: null,
+ SNMP_POLL_DELETED: null
+});
+
+export default keyMirror({
+ SNMP_TRAP: null,
+ SNMP_POLL: null
+});
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
new file mode 100644
index 0000000000..72e0a85b10
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.SNMP_FILES_DATA_CHANGE:
+ return {
+ ...state,
+ trapFilename: action.data.trapFilename,
+ pollFilename: action.data.pollFilename
+ };
+ case actionTypes.SNMP_TRAP_UPLOADED:
+ return {
+ ...state,
+ trapFilename: action.data.filename
+ };
+ case actionTypes.SNMP_POLL_UPLOADED:
+ return {
+ ...state,
+ pollFilename: action.data.filename
+ };
+ case actionTypes.SNMP_TRAP_DELETED:
+ return {
+ ...state,
+ trapFilename: undefined
+ };
+ case actionTypes.SNMP_POLL_DELETED:
+ return {
+ ...state,
+ pollFilename: undefined
+ };
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
new file mode 100644
index 0000000000..ca090c5f2f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
@@ -0,0 +1,117 @@
+import React, {Component, PropTypes} from 'react';
+import Dropzone from 'react-dropzone';
+import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
+import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar.js';
+import Button from 'react-bootstrap/lib/Button.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SoftwareProductComponentsMonitoringConstants from './SoftwareProductComponentsMonitoringConstants.js';
+
+class SoftwareProductComponentsMonitoringView extends Component {
+
+ static propTypes = {
+ isReadOnlyMode: PropTypes.bool,
+ trapFilename: PropTypes.string,
+ pollFilename: PropTypes.string,
+ softwareProductId: PropTypes.string,
+
+ onDropMibFileToUpload: PropTypes.func,
+ onDeleteSnmpFile: PropTypes.func
+ };
+
+ state = {
+ dragging: false
+ };
+
+
+ render() {
+ return (
+ <div className='vsp-component-monitoring'>
+ {this.renderDropzoneWithType(SoftwareProductComponentsMonitoringConstants.SNMP_TRAP)}
+ {this.renderDropzoneWithType(SoftwareProductComponentsMonitoringConstants.SNMP_POLL)}
+ </div>
+ );
+ }
+
+ renderDropzoneWithType(type) {
+ let {isReadOnlyMode, trapFilename, pollFilename} = this.props;
+ let fileName;
+ if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
+ fileName = trapFilename;
+ }
+ else {
+ fileName = pollFilename;
+ }
+ let refAndName = `fileInput${type.toString()}`;
+ let typeDisplayName = this.getFileTypeDisplayName(type);
+ return (
+ <Dropzone
+ className={`snmp-dropzone ${this.state.dragging ? 'active-dragging' : ''}`}
+ onDrop={files => this.handleImport(files, {isReadOnlyMode, type, refAndName})}
+ onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)}
+ onDragLeave={() => this.setState({dragging:false})}
+ multiple={false}
+ disableClick={true}
+ ref={refAndName}
+ name={refAndName}
+ accept='.zip'
+ disabled>
+ <div className='draggable-wrapper'>
+ <div className='section-title'>{typeDisplayName}</div>
+ {fileName ? this.renderUploadedFileName(fileName, type) : this.renderUploadButton(refAndName)}
+ </div>
+ </Dropzone>
+ );
+ }
+
+ renderUploadButton(refAndName) {
+ let {isReadOnlyMode} = this.props;
+ return (
+ <div
+ className={`software-product-landing-view-top-block-col-upl${isReadOnlyMode ? ' disabled' : ''}`}>
+ <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+ <div className='or-text'>{i18n('or')}</div>
+ <div className='upload-btn primary-btn' onClick={() => this.refs[refAndName].open()}>
+ <span className='primary-btn-text'>{i18n('Select file')}</span>
+ </div>
+ </div>
+ );
+ }
+
+ renderUploadedFileName(filename, type) {
+ return (
+ <ButtonToolbar>
+ <ButtonGroup>
+ <Button disabled>{filename}</Button>
+ <Button className='delete-button' onClick={()=>this.props.onDeleteSnmpFile(type)}>X</Button>
+ </ButtonGroup>
+ </ButtonToolbar>
+ );
+ }
+
+
+ handleOnDragEnter(isReadOnlyMode) {
+ if (!isReadOnlyMode) {
+ this.setState({dragging: true});
+ }
+ }
+
+ handleImport(files, {isReadOnlyMode, type, refAndName}) {
+ if (isReadOnlyMode) {
+ return;
+ }
+
+ this.setState({dragging: false});
+ let file = files[0];
+ let formData = new FormData();
+ formData.append('upload', file);
+ this.refs[refAndName].value = '';
+ this.props.onDropMibFileToUpload(formData, type);
+ }
+
+ getFileTypeDisplayName(type) {
+ return type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP ? 'SNMP Trap' : 'SNMP Poll';
+ }
+
+}
+
+export default SoftwareProductComponentsMonitoringView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
new file mode 100644
index 0000000000..a412456e13
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
+import SoftwareProductComponentsNICEditorView from './SoftwareProductComponentsNICEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+
+ let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct;
+
+ let {network: {nicEditor = {}}} = softwareProductComponents;
+ let {data, qdata, qschema} = nicEditor;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+ return {
+ currentSoftwareProduct,
+ isValidityData,
+ data,
+ qdata,
+ qschema,
+ isReadOnlyMode
+ };
+
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onDataChanged: deltaData => SoftwareProductComponentsNetworkActionHelper.updateNICData(dispatch, {deltaData}),
+ onSubmit: ({data, qdata}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}),
+ onCancel: () => SoftwareProductComponentsNetworkActionHelper.closeNICEditor(dispatch),
+ onQDataChanged: ({data}) => SoftwareProductComponentsNetworkActionHelper.updateNICQuestionnaire(dispatch, {data})
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductComponentsNICEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
new file mode 100644
index 0000000000..d49f9ccb1e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.NICEditor.OPEN:
+ return {
+ ...state,
+ data: action.nic
+ };
+ case actionTypes.NICEditor.CLOSE:
+ return {};
+ case actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE:
+ return {
+ ...state,
+ qdata: action.payload.qdata || state.qdata,
+ qschema: action.payload.qschema || state.qschema
+ };
+ case actionTypes.NICEditor.DATA_CHANGED:
+ return {
+ ...state,
+ data: {
+ ...state.data,
+ ...action.deltaData
+ }
+ };
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
new file mode 100644
index 0000000000..7393a835dc
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
@@ -0,0 +1,322 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+
+class SoftwareProductComponentsNetworkEditorView extends React.Component {
+
+ render() {
+ let {onCancel, isReadOnlyMode} = this.props;
+ return (
+ <ValidationForm
+ ref='validationForm'
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ className='vsp-components-network-editor'>
+ {this.renderEditorFields()}
+ </ValidationForm>
+ );
+ }
+
+ renderEditorFields() {
+ let {data = {}, qdata = {}, qschema = {}, onQDataChanged, onDataChanged, isReadOnlyMode} = this.props;
+ let {name, description, networkName} = data;
+ let netWorkValues = [{
+ enum: networkName,
+ title: networkName
+ }];
+ return(
+ <div className='editor-data'>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Name')}
+ value={name}
+ disabled={true}
+ type='text'/>
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Purpose of NIC')}
+ value={description}
+ onChange={description => onDataChanged({description})}
+ disabled={isReadOnlyMode}
+ type='textarea'/>
+ </div>
+ </div>
+ <ValidationForm
+ onDataChanged={onQDataChanged}
+ data={qdata}
+ schema={qschema}
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
+ <div className='row'>
+ <div className='part-title'>{i18n('Protocols')}</div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Protocols')}
+ type='select'
+ pointer='/protocols/protocols'/>
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Protocol with Highest Traffic Profile')}
+ type='select'
+ pointer='/protocols/protocolWithHighestTrafficProfile'/>
+ </div>
+ </div>
+ <div className='row'>
+ <div className='part-title'>{i18n('IP Configuration')}</div>
+ <div className='col-md-3'>
+ <ValidationInput
+ label={i18n('IPv4 Required')}
+ type='checkbox'
+ pointer='/ipConfiguration/ipv4Required'/>
+ </div>
+ <div className='col-md-9'>
+ <ValidationInput
+ label={i18n('IPv6 Required')}
+ type='checkbox'
+ pointer='/ipConfiguration/ipv6Required'/>
+ </div>
+ </div>
+ </ValidationForm>
+ <div className='row'>
+ <div className='part-title'>{i18n('Network')}</div>
+ <div className='col-md-2'>
+ <ValidationInput
+ label={i18n('Internal')}
+ disabled
+ checked={true}
+ className='network-radio disabled'
+ type='radio'/>
+ </div>
+ <div className='col-md-4'>
+ <ValidationInput
+ label={i18n('External')}
+ disabled
+ checked={false}
+ className='network-radio disabled'
+ type='radio'/>
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Network')}
+ type='select'
+ disabled={true}
+ values={netWorkValues}/>
+ </div>
+ </div>
+ <ValidationForm
+ onDataChanged={onQDataChanged}
+ data={qdata}
+ schema={qschema}
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
+ <div className='row'>
+ <div className='part-title'>{i18n('Sizing')}</div>
+ <div className='col-md-12'>
+ <ValidationInput
+ label={i18n('Describe Quality of Service')}
+ type='textarea'
+ pointer='/sizing/describeQualityOfService'/>
+ </div>
+ </div>
+
+ <div className='row'>
+ <div className='part-title'>{i18n('Inflow Traffic per second')}</div>
+ </div>
+
+ <div className='row'>
+ <div className='col-md-6'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Packets')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Peak')}
+ type='text'
+ pointer='/sizing/inflowTrafficPerSecond/packets/peak'/>
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Avg')}
+ type='text'
+ pointer='/sizing/inflowTrafficPerSecond/packets/avg'/>
+ </div>
+ </div>
+ </div>
+ <div className='col-md-6'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Bytes')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Peak')}
+ type='text'
+ pointer='/sizing/inflowTrafficPerSecond/bytes/peak'/>
+
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Avg')}
+ type='text'
+ pointer='/sizing/inflowTrafficPerSecond/bytes/avg'/>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='row'>
+ <div className='part-title'>{i18n('Outflow Traffic per second')}</div>
+ </div>
+
+ <div className='row'>
+ <div className='col-md-6'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Packets')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Peak')}
+ type='text'
+ pointer='/sizing/outflowTrafficPerSecond/packets/peak'/>
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Avg')}
+ type='text'
+ pointer='/sizing/outflowTrafficPerSecond/packets/avg'/>
+
+ </div>
+ </div>
+ </div>
+ <div className='col-md-6'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Bytes')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Peak')}
+ type='text'
+ pointer='/sizing/outflowTrafficPerSecond/bytes/peak'/>
+
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Avg')}
+ type='text'
+ pointer='/sizing/outflowTrafficPerSecond/bytes/avg'/>
+
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='row'>
+ <div className='part-title'>{i18n('Flow Length')}</div>
+ </div>
+
+ <div className='row'>
+ <div className='col-md-6'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Packets')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Peak')}
+ type='text'
+ pointer='/sizing/flowLength/packets/peak'/>
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Avg')}
+ type='text'
+ pointer='/sizing/flowLength/packets/avg'/>
+ </div>
+ </div>
+ </div>
+ <div className='col-md-6'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Bytes')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Peak')}
+ type='text'
+ pointer='/sizing/flowLength/bytes/peak'/>
+
+ </div>
+ <div className='col-md-6'>
+ <ValidationInput
+ label={i18n('Avg')}
+ type='text'
+ pointer='/sizing/flowLength/bytes/avg'/>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='row'>
+ <div className='col-md-9'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Acceptable Jitter')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-4'>
+ <ValidationInput
+ label={i18n('Min')}
+ type='text'
+ pointer='/sizing/acceptableJitter/mean'/>
+ </div>
+ <div className='col-md-4'>
+ <ValidationInput
+ label={i18n('Max')}
+ type='text'
+ pointer='/sizing/acceptableJitter/max'/>
+ </div>
+ <div className='col-md-4'>
+ <ValidationInput
+ label={i18n('Var')}
+ type='text'
+ pointer='/sizing/acceptableJitter/variable'/>
+ </div>
+ </div>
+ </div>
+ <div className='col-md-3'>
+ <div className='row'>
+ <div className='part-title-small'>{i18n('Acceptable Packet Loss %')}</div>
+ </div>
+ <div className='row'>
+ <div className='col-md-12'>
+ <ValidationInput
+ label={i18n('In Percent')}
+ type='text'
+ pointer='/sizing/acceptablePacketLoss'/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </ValidationForm>
+ </div>
+
+ );
+ }
+ submit() {
+ let {data, qdata, onSubmit} = this.props;
+ onSubmit({data, qdata});
+ }
+}
+
+export default SoftwareProductComponentsNetworkEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
new file mode 100644
index 0000000000..bc53e1a7af
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.NIC_LIST_UPDATE:
+ return [...action.response];
+ case actionTypes.NIC_LIST_EDIT:
+ const indexForEdit = state.findIndex(nic => nic.id === action.nic.id);
+ return [...state.slice(0, indexForEdit), action.nic, ...state.slice(indexForEdit + 1)];
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
new file mode 100644
index 0000000000..8ff6b50189
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+
+function baseUrl(softwareProductId, componentId) {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics`;
+}
+
+
+function fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}) {
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire${versionQuery}`);
+}
+
+function fetchNIC({softwareProductId, componentId, nicId, version}) {
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}${versionQuery}`);
+}
+
+function fetchNICsList({softwareProductId, componentId, version}) {
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`);
+}
+
+function saveNIC({softwareProductId, componentId, nic: {id, name, description, networkId}}) {
+ return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${id}`,{
+ name,
+ description,
+ networkId
+ });
+}
+
+function saveNICQuestionnaire({softwareProductId, componentId, nicId, qdata}) {
+ return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire`, qdata);
+}
+
+const SoftwareProductComponentNetworkActionHelper = {
+
+ fetchNICsList(dispatch, {softwareProductId, componentId, version}) {
+ return fetchNICsList({softwareProductId, componentId, version}).then((response) => {
+ dispatch({
+ type: actionTypes.NIC_LIST_UPDATE,
+ response: response.results
+ });
+ });
+ },
+
+ openNICEditor(dispatch, {nic = {}, data = {}}) {
+ dispatch({
+ type: actionTypes.NICEditor.OPEN,
+ nic: {...data, id: nic.id}
+ });
+ },
+
+ closeNICEditor(dispatch) {
+ dispatch({
+ type: actionTypes.NICEditor.CLOSE
+ });
+ },
+
+ loadNICData({softwareProductId, componentId, nicId, version}) {
+ return fetchNIC({softwareProductId, componentId, nicId, version});
+ },
+
+ loadNICQuestionnaire(dispatch, {softwareProductId, componentId, nicId, version}) {
+ return fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}).then((response) => {
+ dispatch({
+ type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE,
+ payload: {
+ qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)
+ }
+ });
+ });
+ },
+
+ updateNICData(dispatch, {deltaData}) {
+ dispatch({
+ type: actionTypes.NICEditor.DATA_CHANGED,
+ deltaData
+ });
+ },
+
+ updateNICQuestionnaire(dispatch, {data}) {
+ dispatch({
+ type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE,
+ payload: {
+ qdata: data
+ }
+ });
+ },
+
+ saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}) {
+ SoftwareProductComponentNetworkActionHelper.closeNICEditor(dispatch);
+ return Promise.all([
+ saveNICQuestionnaire({softwareProductId, componentId, nicId: data.id, qdata}),
+ saveNIC({softwareProductId, componentId, nic: data}).then(() => {
+ dispatch({
+ type: actionTypes.NIC_LIST_EDIT,
+ nic: data
+ });
+ })
+ ]);
+ }
+};
+
+export default SoftwareProductComponentNetworkActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
new file mode 100644
index 0000000000..193f4b20b5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ NIC_LIST_EDIT: null,
+ NIC_LIST_UPDATE: null,
+
+ NICEditor: {
+ OPEN: null,
+ CLOSE: null,
+ NIC_QUESTIONNAIRE_UPDATE: null,
+ DATA_CHANGED: null
+ }
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
new file mode 100644
index 0000000000..9172dc691a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductComponentsNetworkListView from './SoftwareProductComponentsNetworkListView.jsx';
+import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
+
+
+export const mapStateToProps = ({softwareProduct}) => {
+
+ let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct;
+ let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, qschema}} = softwareProductComponents;
+ let {data} = nicEditor;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let {version} = currentSoftwareProduct;
+ let manualMode = nicList.length <= 0;
+ let isModalInEditMode = true;
+
+ return {
+ version,
+ componentData,
+ qdata,
+ qschema,
+ isValidityData,
+ nicList,
+ isDisplayModal: Boolean(data),
+ isModalInEditMode,
+ manualMode,
+ isReadOnlyMode
+ };
+
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+ onAddNIC: () => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch),
+ onEditNicClick: (nic, version) => {
+ Promise.all([
+ SoftwareProductComponentsNetworkActionHelper.loadNICData({
+ softwareProductId,
+ componentId,
+ nicId: nic.id,
+ version
+ }),
+ SoftwareProductComponentsNetworkActionHelper.loadNICQuestionnaire(dispatch, {
+ softwareProductId,
+ componentId,
+ nicId: nic.id,
+ version
+ })
+ ]).then(
+ ([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data})
+ );
+ },
+ onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch,
+ {softwareProductId,
+ vspComponentId: componentId,
+ qdata});
+ }
+
+
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsNetworkListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
new file mode 100644
index 0000000000..b3e17ff94b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
@@ -0,0 +1,136 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+
+import SoftwareProductComponentsNICEditor from './SoftwareProductComponentsNICEditor.js';
+
+class SoftwareProductComponentsNetworkView extends React.Component {
+
+ state = {
+ localFilter: ''
+ };
+
+ render() {
+ let {qdata, qschema, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props;
+
+ return(
+ <div className='vsp-components-network'>
+ <div className='network-data'>
+ <div>
+ <ValidationForm
+ onDataChanged={onQDataChanged}
+ data={qdata}
+ isReadOnlyMode={isReadOnlyMode}
+ schema={qschema}
+ hasButtons={false}>
+ <h3 className='section-title'>{i18n('Network Capacity')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ label={i18n('Protocol with Highest Traffic Profile across all NICs')}
+ type='select'
+ pointer='/network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'/>
+ </div>
+ <div className='single-col add-line-break'>
+ <ValidationInput
+ label={i18n('Network Transactions per Second')}
+ type='text'
+ pointer='/network/networkCapacity/networkTransactionsPerSecond'/>
+ </div>
+ <div className='empty-two-col' />
+ </div>
+ </div>
+
+ </ValidationForm>
+ </div>
+ {this.renderNicList()}
+ </div>
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className='network-nic-modal'>
+ <Modal.Header>
+ <Modal.Title>{isModalInEditMode ? i18n('Edit NIC') : i18n('Create New NIC')}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {
+ <SoftwareProductComponentsNICEditor
+ softwareProductId={softwareProductId}
+ componentId={componentId}
+ isReadOnlyMode={isReadOnlyMode}/>
+ }
+ </Modal.Body>
+ </Modal>
+ </div>
+ );
+ }
+
+ renderNicList() {
+ const {localFilter} = this.state;
+ let {onAddNIC, manualMode, isReadOnlyMode} = this.props;
+ let onAdd = manualMode ? onAddNIC : false;
+ return (
+ <ListEditorView
+ title={i18n('Interfaces')}
+ plusButtonTitle={i18n('Add NIC')}
+ filterValue={localFilter}
+ placeholder={i18n('Filter NICs by Name')}
+ onAdd={onAdd}
+ isReadOnlyMode={isReadOnlyMode}
+ onFilter={filter => this.setState({localFilter: filter})}>
+ {!manualMode && this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))}
+ </ListEditorView>
+ );
+ }
+
+ renderNicListItem(nic, isReadOnlyMode) {
+ let {id, name, description, networkName = ''} = nic;
+ let {onEditNicClick, version} = this.props;
+ return (
+ <ListEditorItemView
+ key={id}
+ className='list-editor-item-view'
+ isReadOnlyMode={isReadOnlyMode}
+ onSelect={() => onEditNicClick(nic, version)}>
+
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Name')}</div>
+ <div className='name'>{name}</div>
+ </div>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Purpose of NIC')}</div>
+ <div className='description'>{description}</div>
+ </div>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Network')}</div>
+ <div className='artifact-name'>{networkName}</div>
+ </div>
+
+ </ListEditorItemView>
+ );
+ }
+
+ filterList() {
+ let {nicList} = this.props;
+ let {localFilter} = this.state;
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return nicList.filter(({name = '', description = ''}) => {
+ return escape(name).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return nicList;
+ }
+ }
+
+ save() {
+ let {onSubmit, qdata} = this.props;
+ return onSubmit({qdata});
+ }
+}
+
+export default SoftwareProductComponentsNetworkView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
new file mode 100644
index 0000000000..d535a34a82
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+
+function baseUrl(softwareProductId, componentId) {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes`;
+}
+
+function fetchProcessesList({softwareProductId, componentId, version}) {
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`);
+}
+
+function deleteProcess({softwareProductId, componentId, processId}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, componentId)}/${processId}`);
+}
+
+function putProcess({softwareProductId, componentId, process}) {
+ return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${process.id}`, {
+ name: process.name,
+ description: process.description
+ });
+}
+
+function postProcess({softwareProductId,componentId, process}) {
+ return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}`, {
+ name: process.name,
+ description: process.description
+ });
+}
+
+function uploadFileToProcess({softwareProductId, processId, componentId, formData}) {
+ return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}/${processId}/upload`, formData);
+}
+
+
+
+const SoftwareProductComponentProcessesActionHelper = {
+ fetchProcessesList(dispatch, {softwareProductId, componentId, version}) {
+ dispatch({
+ type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES,
+ processesList: []
+ });
+
+ return fetchProcessesList({softwareProductId, componentId, version}).then(response => {
+ dispatch({
+ type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES,
+ processesList: response.results
+ });
+ });
+ },
+
+ deleteProcess(dispatch, {process, softwareProductId, componentId}) {
+ return deleteProcess({softwareProductId, processId:process.id, componentId}).then(() => {
+ dispatch({
+ type: actionTypes.DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
+ processId: process.id
+ });
+ });
+
+ },
+
+ saveProcess(dispatch, {softwareProductId, componentId, previousProcess, process}) {
+ if (previousProcess) {
+ return putProcess({softwareProductId,componentId, process}).then(() => {
+ if (process.formData && process.formData.name !== previousProcess.artifactName){
+ uploadFileToProcess({softwareProductId, processId: process.id, formData: process.formData, componentId});
+ }
+ dispatch({
+ type: actionTypes.EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
+ process
+ });
+ });
+ }
+ else {
+ return postProcess({softwareProductId, componentId, process}).then(response => {
+ if (process.formData) {
+ uploadFileToProcess({softwareProductId, processId: response.value, formData: process.formData, componentId});
+ }
+ dispatch({
+ type: actionTypes.ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
+ process: {
+ ...process,
+ id: response.value
+ }
+ });
+ });
+ }
+ },
+
+ hideDeleteConfirm(dispatch) {
+ dispatch({
+ type: actionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM,
+ processToDelete: false
+ });
+ },
+
+ openDeleteProcessesConfirm(dispatch, {process} ) {
+ dispatch({
+ type: actionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM,
+ processToDelete: process
+ });
+ },
+
+ openEditor(dispatch, process = {}) {
+ dispatch({
+ type: actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN,
+ process
+ });
+ },
+ closeEditor(dispatch) {
+ dispatch({
+ type:actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE
+ });
+ },
+ processEditorDataChanged(dispatch, {deltaData}) {
+ dispatch({
+ type: actionTypes.processEditor.DATA_CHANGED,
+ deltaData
+ });
+ }
+};
+
+export default SoftwareProductComponentProcessesActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
new file mode 100644
index 0000000000..78a111a426
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS: null,
+ EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS: null,
+ DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS: null,
+ SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN: null,
+ SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE: null,
+ FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES: null,
+ SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM: null,
+ processEditor: {
+ DATA_CHANGED: null
+ }
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
new file mode 100644
index 0000000000..0138023c30
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper';
+import SoftwareProductComponentProcessesEditorView from './SoftwareProductComponentProcessesEditorView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductComponents: {componentProcesses = {}}} = softwareProduct;
+ let {processesList = [], processesEditor = {}} = componentProcesses;
+ let {data} = processesEditor;
+
+ let previousData;
+ const processId = data ? data.id : null;
+ if(processId) {
+ previousData = processesList.find(process => process.id === processId);
+ }
+
+ return {
+ data,
+ previousData
+ };
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+
+ return {
+ onDataChanged: deltaData => SoftwareProductComponentProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}),
+ onCancel: () => SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch),
+ onSubmit: ({previousProcess, process}) => {
+ SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch);
+ SoftwareProductComponentProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, componentId, process});
+ }
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductComponentProcessesEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
new file mode 100644
index 0000000000..f859f690e8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN:
+ return {
+ ...state,
+ data: action.process
+ };
+ case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE:
+ return {};
+
+ case actionTypes.processEditor.DATA_CHANGED:
+ return {
+ ...state,
+ data: {
+ ...state.data,
+ ...action.deltaData
+ }
+ };
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
new file mode 100644
index 0000000000..ca6d843af7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
@@ -0,0 +1,124 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Dropzone from 'react-dropzone';
+
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+
+const SoftwareProductProcessEditorPropType = React.PropTypes.shape({
+ id: React.PropTypes.string,
+ name: React.PropTypes.string,
+ description: React.PropTypes.string,
+ artifactName: React.PropTypes.string
+});
+
+class SoftwareProductProcessesEditorView extends React.Component {
+
+ state = {
+ dragging: false,
+ files: []
+ };
+
+ static propTypes = {
+ data: SoftwareProductProcessEditorPropType,
+ previousData: SoftwareProductProcessEditorPropType,
+ isReadOnlyMode: React.PropTypes.bool,
+ onDataChanged: React.PropTypes.func,
+ onSubmit: React.PropTypes.func,
+ onCancel: React.PropTypes.func
+ };
+
+ render() {
+ let {isReadOnlyMode, onCancel, onDataChanged, data = {}} = this.props;
+ let {name, description, artifactName} = data;
+
+ return (
+ <div>
+ <ValidationForm
+ ref='validationForm'
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={true}
+ labledButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => onCancel() }
+ className='vsp-processes-editor'>
+ <div className={`vsp-processes-editor-data${isReadOnlyMode ? ' disabled' : '' }`}>
+ <Dropzone
+ className={`vsp-process-dropzone-view ${this.state.dragging ? 'active-dragging' : ''}`}
+ onDrop={files => this.handleImportSubmit(files)}
+ onDragEnter={() => this.setState({dragging:true})}
+ onDragLeave={() => this.setState({dragging:false})}
+ multiple={false}
+ disableClick={true}
+ ref='processEditorFileInput'
+ name='processEditorFileInput'
+ accept='*.*'>
+ <div className='row'>
+ <div className='col-md-6'>
+ <ValidationInput
+ onChange={name => onDataChanged({name})}
+ label={i18n('Name')}
+ value={name}
+ validations={{validateName: true, maxLength: 120, required: true}}
+ type='text'/>
+ <ValidationInput
+ label={i18n('Artifacts')}
+ value={artifactName}
+ type='text'
+ disabled/>
+ </div>
+ <div className='col-md-6'>
+ <div className='file-upload-box'>
+ <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+ <div className='or-text'>{i18n('or')}</div>
+ <div className='upload-btn primary-btn' onClick={() => this.refs.processEditorFileInput.open()}>
+ <span className='primary-btn-text'>{i18n('Select file')}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <ValidationInput
+ onChange={description => onDataChanged({description})}
+ label={i18n('Notes')}
+ value={description}
+ name='vsp-process-description'
+ className='vsp-process-description'
+ validations={{maxLength: 1000}}
+ type='textarea'/>
+ </Dropzone>
+ </div>
+ </ValidationForm>
+ </div>
+ );
+ }
+
+ submit() {
+ const {data: process, previousData: previousProcess} = this.props;
+ let {files} = this.state;
+ let formData = new FormData();
+ if (files.length) {
+ let file = files[0];
+ formData.append('upload', file);
+ }
+
+ let updatedProcess = {
+ ...process,
+ formData: files.length ? formData : false
+ };
+ this.props.onSubmit({process: updatedProcess, previousProcess});
+ }
+
+
+ handleImportSubmit(files) {
+ let {onDataChanged} = this.props;
+ this.setState({
+ dragging: false,
+ complete: '0',
+ files
+ });
+ onDataChanged({artifactName: files[0].name});
+ }
+}
+
+export default SoftwareProductProcessesEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
new file mode 100644
index 0000000000..5f6932897e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js';
+
+import SoftwareProductComponentsProcessesListView from './SoftwareProductComponentsProcessesListView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+
+ let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents: {componentProcesses = {}}} = softwareProduct;
+ let{processesList = [], processesEditor = {}} = componentProcesses;
+ let {data} = processesEditor;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+ return {
+ currentSoftwareProduct,
+ isValidityData,
+ processesList,
+ isDisplayModal: Boolean(data),
+ isModalInEditMode: Boolean(data && data.id),
+ isReadOnlyMode
+ };
+
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId}) => {
+
+ return {
+ onAddProcess: () => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch),
+ onEditProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process),
+ onDeleteProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId})
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsProcessesListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
new file mode 100644
index 0000000000..4bb124d52f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES:
+ return [...action.processesList];
+ case actionTypes.EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS:
+ const indexForEdit = state.findIndex(process => process.id === action.process.id);
+ return [...state.slice(0, indexForEdit), action.process, ...state.slice(indexForEdit + 1)];
+ case actionTypes.ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS:
+ return [...state, action.process];
+ case actionTypes.DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS:
+ return state.filter(process => process.id !== action.processId);
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx
new file mode 100644
index 0000000000..48fa862364
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(processToDelete) {
+ let name = processToDelete ? processToDelete.name : '';
+ let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+ return (
+ <div>
+ <p>{msg}</p>
+ </div>
+ );
+};
+
+const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor, softwareProductComponents} = softwareProduct;
+ let {componentProcesses} = softwareProductComponents;
+ let {processToDelete} = componentProcesses;
+ let softwareProductId = softwareProductEditor.data.id;
+ const show = processToDelete !== false;
+ return {
+ show,
+ title: 'Warning!',
+ type: 'warning',
+ msg: renderMsg(processToDelete),
+ confirmationDetails: {processToDelete, softwareProductId}
+ };
+};
+
+const mapActionsToProps = (dispatch,{componentId, softwareProductId}) => {
+ return {
+ onConfirmed: ({processToDelete}) => {
+ SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId, componentId});
+ SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch);
+ },
+ onDeclined: () => {
+ SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch);
+ }
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
new file mode 100644
index 0000000000..a8b07e9194
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
@@ -0,0 +1,125 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import SoftwareProductProcessesEditor from './SoftwareProductComponentProcessesEditor.js';
+import SoftwareProductComponentsProcessesConfirmationModal from './SoftwareProductComponentsProcessesConfirmationModal.jsx';
+
+class SoftwareProductProcessesView extends React.Component {
+
+ state = {
+ localFilter: ''
+ };
+
+ static propTypes = {
+ onAddProcess: React.PropTypes.func,
+ onEditProcessClick: React.PropTypes.func,
+ onDeleteProcessClick: React.PropTypes.func,
+ isDisplayModal: React.PropTypes.bool,
+ isModalInEditMode: React.PropTypes.bool,
+ onStorageSelect: React.PropTypes.func,
+ componentId: React.PropTypes.string,
+ softwareProductId: React.PropTypes.string
+ };
+
+ render() {
+ let { softwareProductId, componentId} = this.props;
+
+ return (
+ <div className='vsp-processes-page'>
+ <div className='software-product-view'>
+ <div className='software-product-landing-view-right-side flex-column'>
+ {this.renderEditor()}
+ {this.renderProcessList()}
+ </div>
+ <SoftwareProductComponentsProcessesConfirmationModal
+ componentId={componentId}
+ softwareProductId={softwareProductId}/>
+ </div>
+ </div>
+ );
+ }
+
+ renderEditor() {
+ let {softwareProductId, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+ return (
+ <Modal show={isDisplayModal} bsSize='large' animation={true}>
+ <Modal.Header>
+ <Modal.Title>{isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body className='edit-process-modal'>
+ <SoftwareProductProcessesEditor
+ componentId={componentId}
+ softwareProductId={softwareProductId}
+ isReadOnlyMode={isReadOnlyMode}/>
+ </Modal.Body>
+ </Modal>
+
+ );
+ }
+
+ renderProcessList() {
+ const {localFilter} = this.state;
+ let {onAddProcess, isReadOnlyMode} = this.props;
+ return (
+ <div className='processes-list'>
+ <ListEditorView
+ plusButtonTitle={i18n('Add Component Process Details')}
+ filterValue={localFilter}
+ placeholder={i18n('Filter Process')}
+ onAdd={onAddProcess}
+ isReadOnlyMode={isReadOnlyMode}
+ onFilter={filter => this.setState({localFilter: filter})}>
+ {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))}
+ </ListEditorView>
+ </div>
+ );
+ }
+
+ renderProcessListItem(process, isReadOnlyMode) {
+ let {id, name, description, artifactName = ''} = process;
+ let {onEditProcessClick, onDeleteProcessClick} = this.props;
+ return (
+ <ListEditorItemView
+ key={id}
+ className='list-editor-item-view'
+ isReadOnlyMode={isReadOnlyMode}
+ onSelect={() => onEditProcessClick(process)}
+ onDelete={() => onDeleteProcessClick(process)}>
+
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Name')}</div>
+ <div className='name'>{name}</div>
+ </div>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Artifact name')}</div>
+ <div className='artifact-name'>{artifactName}</div>
+ </div>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Notes')}</div>
+ <div className='description'>{description}</div>
+ </div>
+ </ListEditorItemView>
+ );
+ }
+
+
+ filterList() {
+ let {processesList} = this.props;
+ let {localFilter} = this.state;
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return processesList.filter(({name = '', description = ''}) => {
+ return escape(name).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return processesList;
+ }
+ }
+}
+
+export default SoftwareProductProcessesView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
new file mode 100644
index 0000000000..fbd3f81ec2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductComponentStorageView from './SoftwareProductComponentStorageView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+ let {componentEditor: {data: componentData , qdata, qschema}} = softwareProductComponents;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+ return {
+ componentData,
+ qdata,
+ qschema,
+ isReadOnlyMode
+ };
+};
+
+const mapActionToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+ onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+ };
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true}) (SoftwareProductComponentStorageView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
new file mode 100644
index 0000000000..9c9600c376
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
@@ -0,0 +1,124 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+
+class SoftwareProductComponentStorageView extends React.Component {
+
+ static propTypes = {
+ componentId: React.PropTypes.string,
+ onQDataChanged: React.PropTypes.func,
+ onSubmit: React.PropTypes.func,
+ isReadOnlyMode: React.PropTypes.bool
+ };
+
+ render() {
+ let {qdata, qschema, onQDataChanged, onSubmit, isReadOnlyMode} = this.props;
+
+ return(
+ <div className='vsp-component-questionnaire-view'>
+ <ValidationForm
+ ref='storageValidationForm'
+ hasButtons={false}
+ onSubmit={() => onSubmit({qdata})}
+ className='component-questionnaire-validation-form'
+ isReadOnlyMode={isReadOnlyMode}
+ onDataChanged={onQDataChanged}
+ data={qdata}
+ schema={qschema}>
+
+ <div className='section-title'>{i18n('Backup')}</div>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <div className='vertical-flex'>
+ <label key='label' className='control-label'>{i18n('Backup Type')}</label>
+ <div className='radio-options-content-row'>
+ <ValidationInput
+ label={i18n('On Site')}
+ type='radiogroup'
+ pointer={'/storage/backup/backupType'}
+ className='radio-field'/>
+ </div>
+ </div>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Backup Solution')}
+ pointer={'/storage/backup/backupSolution'}
+ className='section-field'/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Backup Storage Size (GB)')}
+ pointer={'/storage/backup/backupStorageSize'}
+ className='section-field'/>
+ </div>
+ <ValidationInput
+ type='select'
+ label={i18n('Backup NIC')}
+ pointer={'/storage/backup/backupNIC'}
+ className='section-field'/>
+ </div>
+ </div>
+
+ <div className='section-title'>{i18n('Snapshot Backup')}</div>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Snapshot Frequency (hours)')}
+ pointer={'/storage/snapshotBackup/snapshotFrequency'}
+ className='section-field'/>
+ </div>
+ <div className='empty-two-col' />
+ <div className='empty-col' />
+ </div>
+ </div>
+
+ <div className='section-title'>{i18n('Log Backup')}</div>
+ <div className='rows-section'>
+ <div className='row-flex-components input-row'>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Size of Log Files (GB)')}
+ pointer={'/storage/logBackup/sizeOfLogFiles'}
+ className='section-field'/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Log Retention Period (days)')}
+ pointer={'/storage/logBackup/logRetentionPeriod'}
+ className='section-field'/>
+ </div>
+ <div className='single-col'>
+ <ValidationInput
+ type='text'
+ label={i18n('Log Backup Frequency (days)')}
+ pointer={'/storage/logBackup/logBackupFrequency'}
+ className='section-field'/>
+ </div>
+ <ValidationInput
+ type='text'
+ label={i18n('Log File Location')}
+ pointer={'/storage/logBackup/logFileLocation'}
+ className='section-field'/>
+ </div>
+ </div>
+ </ValidationForm>
+ </div>
+ );
+ }
+
+ save(){
+ return this.refs.storageValidationForm.handleFormSubmit(new Event('dummy'));
+ }
+}
+
+export default SoftwareProductComponentStorageView;