From 61070c9c6b665fdea79b3ccdfeafc3a6b50d262e Mon Sep 17 00:00:00 2001 From: Avi Ziv Date: Wed, 26 Jul 2017 17:37:57 +0300 Subject: [SDC] Full OnBoard health-check and NFoD support Change-Id: I606f8a52c7e6d2bd5558f824957d890e552c5423 Signed-off-by: Avi Ziv --- .../onboarding/licenseModel/limits/LimitEditor.js | 25 +++ .../onboarding/licenseModel/limits/LimitEditor.jsx | 193 +++++++++++++++++++++ .../licenseModel/limits/LimitEditorActionHelper.js | 30 ++++ .../licenseModel/limits/LimitEditorConstants.js | 52 ++++++ .../licenseModel/limits/LimitEditorReducer.js | 70 ++++++++ .../onboarding/licenseModel/limits/Limits.jsx | 108 ++++++++++++ .../onboarding/licenseModel/limits/LimitsServer.js | 46 +++++ 7 files changed, 524 insertions(+) create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/Limits.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitsServer.js (limited to 'openecomp-ui/src/sdc-app/onboarding/licenseModel/limits') diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.js new file mode 100644 index 0000000000..d483383472 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.js @@ -0,0 +1,25 @@ +import {connect} from 'react-redux'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import LimitEditor from './LimitEditor.jsx'; + +const mapStateToProps = ({licenseModel: {limitEditor}}) => { + + let {data, genericFieldInfo, formReady} = limitEditor; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); + + return { + data, + genericFieldInfo, + isFormValid, + formReady + }; +}; + +const mapActionsToProps = (dispatch) => { + return { + onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), + onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(LimitEditor); \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx new file mode 100644 index 0000000000..f70f917725 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx @@ -0,0 +1,193 @@ +import React from 'react'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; +import {LIMITS_FORM_NAME, selectValues} from './LimitEditorConstants.js'; +import Button from 'sdc-ui/lib/react/Button.js'; +import Validator from 'nfvo-utils/Validator.js'; + +const LimitPropType = React.PropTypes.shape({ + id: React.PropTypes.string, + name: React.PropTypes.string, + description: React.PropTypes.string, + metric: React.PropTypes.string, + value: React.PropTypes.number, + aggregationFunction: React.PropTypes.string, + time: React.PropTypes.string, + unit: React.PropTypes.number +}); + +class LimitEditor extends React.Component { + static propTypes = { + data: LimitPropType, + limitsNames: React.PropTypes.object, + isReadOnlyMode: React.PropTypes.bool, + isFormValid: React.PropTypes.bool, + formReady: React.PropTypes.bool, + genericFieldInfo: React.PropTypes.object.isRequired, + onDataChanged: React.PropTypes.func.isRequired, + onSubmit: React.PropTypes.func.isRequired, + onValidateForm: React.PropTypes.func.isRequired, + onCancel: React.PropTypes.func.isRequired + }; + + componentDidUpdate(prevProps) { + if (this.props.formReady && this.props.formReady !== prevProps.formReady) { + this.submit(); + } + } + + render() { + let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo, onCancel, isFormValid, formReady, onValidateForm} = this.props; + let {name, description, metric, value, aggregationFunction, time, unit} = data; + return ( +
+ {!data.id && +
+ {data.name ? data.name : i18n('NEW LIMIT')} +
} + { + genericFieldInfo && +
onValidateForm(LIMITS_FORM_NAME) } + labledButtons={false} + isReadOnlyMode={isReadOnlyMode} + className='limit-editor-form'> + + + onDataChanged({name}, LIMITS_FORM_NAME, {name: () => this.validateName(name)})} + label={i18n('Name')} + data-test-id='limit-editor-name' + value={name} + isValid={genericFieldInfo.name.isValid} + errorText={genericFieldInfo.name.errorText} + isRequired={true} + type='text'/> + + + onDataChanged({description}, LIMITS_FORM_NAME)} + label={i18n('Description')} + data-test-id='limit-editor-description' + value={description} + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + isRequired={false} + type='text'/> + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onDataChanged({metric: val}, LIMITS_FORM_NAME);} + } + isRequired={true} + value={metric} + label={i18n('Metric')} + data-test-id='limit-editor-metric' + isValid={genericFieldInfo.metric.isValid} + errorText={genericFieldInfo.metric.errorText} + groupClassName='bootstrap-input-options' + className='input-options-select' + type='select' > + {selectValues.METRIC.map(mtype => + )} + + + + onDataChanged({value}, LIMITS_FORM_NAME)} + label={i18n('Metric value')} + data-test-id='limit-editor-metric-value' + value={value} + isValid={genericFieldInfo.value.isValid} + errorText={genericFieldInfo.value.errorText} + isRequired={true} + type='number'/> + + + onDataChanged({unit}, LIMITS_FORM_NAME)} + label={i18n('Units')} + data-test-id='limit-editor-units' + value={unit} + isValid={genericFieldInfo.unit.isValid} + errorText={genericFieldInfo.unit.errorText} + isRequired={false} + type='number'/> + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onDataChanged({aggregationFunction: val}, LIMITS_FORM_NAME);} + } + value={aggregationFunction} + label={i18n('Aggregation Function')} + data-test-id='limit-editor-aggregation-function' + isValid={genericFieldInfo.aggregationFunction.isValid} + errorText={genericFieldInfo.aggregationFunction.errorText} + groupClassName='bootstrap-input-options' + className='input-options-select' + type='select' > + {selectValues.AGGREGATION_FUNCTION.map(mtype => + )} + + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onDataChanged({time: val}, LIMITS_FORM_NAME);} + } + value={time} + label={i18n('Time')} + data-test-id='limit-editor-time' + isValid={genericFieldInfo.time.isValid} + errorText={genericFieldInfo.time.errorText} + groupClassName='bootstrap-input-options' + className='input-options-select' + type='select' > + {selectValues.TIME.map(mtype => + )} + + + + + + + +
+ } +
+ ); + } + + validateName(value) { + const {data: {id}, limitsNames} = this.props; + const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: limitsNames}); + + return !isExists ? {isValid: true, errorText: ''} : + {isValid: false, errorText: i18n('Limit by the name \'' + value + '\' already exists. Limit name must be unique')}; + } + + submit() { + if (!this.props.formReady) { + this.props.onValidateForm(LIMITS_FORM_NAME); + } else { + this.props.onSubmit(); + } + } +} + +export default LimitEditor; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorActionHelper.js new file mode 100644 index 0000000000..09c64ada62 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorActionHelper.js @@ -0,0 +1,30 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {actionTypes} from './LimitEditorConstants.js'; + + +const LimitEditorActionHelper = { + openLimitsEditor(dispatch, {limit}) { + dispatch({type: actionTypes.OPEN, limitItem: limit}); + }, + + closeLimitsEditor(dispatch) { + dispatch({type: actionTypes.CLOSE}); + } +}; + +export default LimitEditorActionHelper; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js new file mode 100644 index 0000000000..1bef286442 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js @@ -0,0 +1,52 @@ +import keyMirror from 'nfvo-utils/KeyMirror.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +// import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx'; + +export const actionTypes = keyMirror({ + OPEN: null, + CLOSE: null, + DATA_CHANGED: null, +}); + +export const LIMITS_FORM_NAME = 'LIMITSFORM'; + +export const selectValues = { + METRIC: [ + {enum: '', title: i18n('please select…')}, + {enum: 'Software_Instances_Count', title: 'Software Instances'}, + {enum: 'Core', title: 'Core'}, + {enum: 'CPU', title: 'CPU'}, + {enum: 'Trunks', title: 'Trunks'}, + {enum: 'User', title: 'User'}, + {enum: 'Subscribers', title: 'Subscribers'}, + {enum: 'Tenants', title: 'Tenants'}, + {enum: 'Tokens', title: 'Tokens'}, + {enum: 'Seats', title: 'Seats'}, + {enum: 'Units_TB', title: 'Units-TB'}, + {enum: 'Units_GB', title: 'Units-GB'}, + {enum: 'Units_MB', title: 'Units-MB'} + ], + AGGREGATION_FUNCTION: [ + {enum: '', title: i18n('please select…')}, + {enum: 'Peak', title: 'Peak'}, + {enum: 'Average', title: 'Average'} + ], + TIME: [ + {enum: '', title: i18n('please select…')}, + {enum: 'Hour', title: 'Hour'}, + {enum: 'Day', title: 'Day'}, + {enum: 'Month', title: 'Month'} + ] + +}; + +export const limitType = { + SERVICE_PROVIDER: 'ServiceProvider', + VENDOR: 'Vendor' +}; + +export const defaultState = { + LIMITS_EDITOR_DATA: {} +}; + +export const NEW_LIMIT_TEMP_ID = 'NEW_LIMIT_TEMP_ID'; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorReducer.js new file mode 100644 index 0000000000..2499093af2 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditorReducer.js @@ -0,0 +1,70 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {actionTypes, LIMITS_FORM_NAME, defaultState} from './LimitEditorConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.OPEN: + return { + ...state, + data: action.limitItem ? {...action.limitItem} : defaultState.LIMITS_EDITOR_DATA, + formReady: null, + formName: LIMITS_FORM_NAME, + genericFieldInfo: { + 'description' : { + isValid: true, + errorText: '', + validations: [{type: 'maxLength', data: 1000}] + }, + 'name' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}] + }, + 'metric' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + }, + 'value' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'numeric', data: true}, {type: 'minimum', data: 0}] + }, + 'unit' : { + isValid: true, + errorText: '', + validations: [{type: 'numeric', data: true}] + }, + 'aggregationFunction' : { + isValid: true, + errorText: '', + validations: [] + }, + 'time' : { + isValid: true, + errorText: '', + validations: [] + } + } + }; + case actionTypes.CLOSE: + return {}; + default: + return state; + } +}; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/Limits.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/Limits.jsx new file mode 100644 index 0000000000..ec5a1dff72 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/Limits.jsx @@ -0,0 +1,108 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; +import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; +import LimitEditor from './LimitEditor.js'; +import {NEW_LIMIT_TEMP_ID, selectValues} from './LimitEditorConstants.js'; + +const LimitItem = ({isReadOnlyMode, limit, onDelete, onSelect}) => { + const {name, description, metric, value, aggregationFunction = '', time = ''} = limit; + const timeLabel = time ? `per ${time}` : ''; + return ( + +
+
{name}
+
+ +
+
{description}
+
+ +
+
{`${selectValues.METRIC.find(item => item.enum === metric).title} ${value} ${aggregationFunction} ${timeLabel}`}
+
+
+ ); +}; + +class Limits extends React.Component { + + + state = { + localFilter: '' + }; + + render() { + const {isReadOnlyMode = false, limitEditor, limitsList = [], onCloseLimitEditor, selectedLimit} = this.props; + let limitsNames = {}; + for (let i = 0; i < limitsList.length; i++) { + limitsNames[limitsList[i].name.toLowerCase()] = limitsList[i].id; + } + return ( +
+ + {this.props.selectedLimit === NEW_LIMIT_TEMP_ID && limitEditor.data && + this.submit()}/> + } + {limitsList.length === 0 && !limitEditor.data &&
{i18n('There are no limits')}
} + {limitsList.map(limit => +
+ this.delete(limit)} + onSelect={selectedLimit ? undefined : () => this.props.onSelectLimit(limit)} + clickable={!selectedLimit} + isReadOnlyMode={isReadOnlyMode} + limit={limit}/> + {limit.id === selectedLimit && limitEditor.data && this.submit()}/>} +
)} +
+ +
+ ); + } + + submit() { + let {onSubmit, onCloseLimitEditor, parent, limitEditor, licenseModelId, version, limitType} = this.props; + onSubmit({type: limitType, ...limitEditor.data}, parent, licenseModelId, version).then(() => onCloseLimitEditor()); + } + + delete(limit) { + let {onDelete, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit} = this.props; + onDelete({limit, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit}); + } + + filterList() { + let {limitsList = []} = this.props; + let {localFilter} = this.state; + if (localFilter.trim()) { + const filter = new RegExp(escape(localFilter), 'i'); + return limitsList.filter(({name = '', description = ''}) => { + return escape(name).match(filter) || escape(description).match(filter); + }); + } + else { + return limitsList; + } + } +} + +export default Limits; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitsServer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitsServer.js new file mode 100644 index 0000000000..1b8ecb9d94 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitsServer.js @@ -0,0 +1,46 @@ +/*! + * 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. + */ + +// items/{itemId}/users + +let list = [ + +]; + +export default { + fetch() { + return Promise.resolve({ + listCount: list.length, + results: list + }); + }, + + put(url, payload) { + // let {removedUsers, addedUsers} = payload; + // users = users.filter(user => !removedUsers.map(user => user.userId).includes(user.userId)).concat(addedUsers); + payload.id = Math.random() * (1000 - 1) + 1; + list.push(payload); + return Promise.resolve(); + }, + + destroy(url) { + const parts = url.split('/'); + const id = parts[parts.length - 1]; + let newList = list.filter(item => item.id !== id); + list = newList; + return Promise.resolve(); + } +}; \ No newline at end of file -- cgit 1.2.3-korg