Loading js-apps/meep-frontend/src/js/components/helper-components/cancel-apply-triplet.js 0 → 100644 +63 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * 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 { Grid, GridInner, GridCell } from '@rmwc/grid'; import { Button } from '@rmwc/button'; import { MEEP_BTN_CANCEL, MEEP_BTN_APPLY, MEEP_BTN_DUPLICATE } from '../../meep-constants'; const buttonStyles = { marginRight: 10 }; const CancelApplyTriplet = props => { return ( <Grid style={{ marginTop: 10 }}> <GridInner align={'right'}> <GridCell span={12}> <Button outlined style={buttonStyles} onClick={props.onCancel} data-cy={MEEP_BTN_CANCEL} > {props.cancelText ? props.cancelText : 'Cancel'} </Button> <Button outlined style={buttonStyles} onClick={props.onApply} disabled={props.saveDisabled} data-cy={MEEP_BTN_APPLY} > {props.applyText ? props.applyText : 'Apply'} </Button> <Button outlined style={buttonStyles} onClick={props.onDuplicate} disabled={props.duplicateDisabled} data-cy={MEEP_BTN_DUPLICATE} > {props.duplicateText ? props.duplicateText : 'Duplicate'} </Button> </GridCell> </GridInner> </Grid> ); }; export default CancelApplyTriplet; js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js +35 −5 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ import { Checkbox } from '@rmwc/checkbox'; import { Typography } from '@rmwc/typography'; import { updateObject } from '../../util/object-util'; import { createUniqueName } from '../../util/elem-utils'; import IDSelect from '../../components/helper-components/id-select'; import CancelApplyPair from '../../components/helper-components/cancel-apply-pair'; import CancelApplyTriplet from '../../components/helper-components/cancel-apply-triplet'; import NCGroup from '../../components/helper-components/nc-group'; import { Loading Loading @@ -56,7 +58,12 @@ import { setElemFieldErr } from '../../util/elem-utils'; import { CFG_ELEM_MODE_EDIT, cfgElemUpdate } from '../../state/cfg'; import { CFG_ELEM_MODE_EDIT, CFG_ELEM_MODE_DUPLICATE, cfgElemUpdate, cfgElemDuplicate } from '../../state/cfg'; import { TYPE_CFG, Loading Loading @@ -1016,6 +1023,17 @@ export class CfgNetworkElementContainer extends Component { this.props.cfgElemUpdate(updatedElem); } // Element duplicate handler onDuplicateElement(newName) { var duplicatedElem = updateObject({}, this.props.configuredElement); setElemFieldVal(duplicatedElem, FIELD_NAME, newName); setElemFieldVal(duplicatedElem, FIELD_PARENT, null); var elementType = getElemFieldVal(duplicatedElem, FIELD_TYPE); duplicatedElem.parentElements = this.elementsOfType(getParentTypes(elementType)); this.props.cfgElemDuplicate(duplicatedElem); } // Retrieve names of elements with matching type elementsOfType(types) { return _.chain(this.props.tableData) Loading Loading @@ -1094,11 +1112,21 @@ export class CfgNetworkElementContainer extends Component { {this.props.errorMessage} </div> <CancelApplyPair <CancelApplyTriplet duplicateDisabled={ (element && this.props.configMode === CFG_ELEM_MODE_EDIT && this.props.isModified === false) ? false : true } saveDisabled={(this.props.isModified === false) ? true : false} onCancel={this.props.onCancelElement} onApply={() => { this.props.onSaveElement(element); (this.props.configMode === CFG_ELEM_MODE_DUPLICATE) ? this.props.onDuplicateElement(element) : this.props.onSaveElement(element); }} onDuplicate={() => { this.onDuplicateElement(createUniqueName(this.props.tableData, getElemFieldVal(element, FIELD_NAME) + '-copy')); }} /> </> )} Loading Loading @@ -1131,13 +1159,15 @@ const mapStateToProps = state => { tableData: state.cfg.table.entries, configuredElement: state.cfg.elementConfiguration.configuredElement, configMode: state.cfg.elementConfiguration.configurationMode, isModified: state.cfg.elementConfiguration.isModified, errorMessage: state.cfg.elementConfiguration.errorMessage }; }; const mapDispatchToProps = dispatch => { return { cfgElemUpdate: element => dispatch(cfgElemUpdate(element)) cfgElemUpdate: element => dispatch(cfgElemUpdate(element)), cfgElemDuplicate: element => dispatch(cfgElemDuplicate(element)) }; }; Loading js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js +132 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import { Elevation } from '@rmwc/elevation'; import IDCVis from '../idc-vis'; import CfgNetworkElementContainer from './cfg-network-element-container'; import CfgPageScenarioButtons from './cfg-page-scenario-buttons'; import { deepCopy } from '../../util/object-util'; import { getElementFromScenario } from '../../util/scenario-utils'; import HeadlineBar from '../../components/headline-bar'; import CfgTable from './cfg-table'; Loading @@ -40,7 +42,8 @@ import { cfgChangeScenario, cfgChangeScenarioList, cfgChangeState, CFG_ELEM_MODE_NEW CFG_ELEM_MODE_NEW, CFG_ELEM_MODE_EDIT } from '../../state/cfg'; import { Loading @@ -58,7 +61,9 @@ import { CFG_STATE_NEW, CFG_STATE_IDLE, PAGE_CONFIGURE, ELEMENT_TYPE_SCENARIO ELEMENT_TYPE_SCENARIO, COMMON_ZONE_TYPE_STR, DEFAULT_NL_TYPE_STR } from '../../meep-constants'; import { Loading @@ -69,7 +74,9 @@ import { FIELD_EXT_PORT, FIELD_GPU_COUNT, FIELD_GPU_TYPE, getElemFieldVal getElemFieldVal, setElemFieldVal, createUniqueName } from '../../util/elem-utils'; import { pipe, filter } from '../../util/functional'; Loading Loading @@ -141,6 +148,125 @@ class CfgPageContainer extends Component { this.props.cfgElemClear(); } // DUPLICATE ELEMENT, return new element name duplicateElement(element, newParentName, isRoot) { let newElement = deepCopy(element); var name = getElemFieldVal(element, FIELD_NAME); if (isRoot === false) { name = createUniqueName(this.props.cfg.table.entries, name + '-copy'); setElemFieldVal(newElement, FIELD_NAME, name); } setElemFieldVal(newElement, FIELD_PARENT, newParentName); // add new element to scenario // new id and label will be created as part of the addNewElementToScenario called by newScenarioElem this.props.newScenarioElem(newElement); return name; } // DUPLICATE onDuplicateElement(element) { // Validate network element if (this.validateNetworkElement(element) === false) { return; } // browse to find the root of the tree to duplicate var inDuplicateBranch = false; var newZoneRootParentName = ''; var newNlRootParentName = ''; var newPlRootParentName = ''; var newProcessRootParentName = ''; var elementFromScenario; var scenario = this.props.cfg.scenario; // Domains for (var i in scenario.deployment.domains) { var domain = scenario.deployment.domains[i]; // Add domain to graph and table (ignore public domain) if (domain.id === element.id) { newZoneRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT), true); inDuplicateBranch = true; } // Zones for (var j in domain.zones) { var zone = domain.zones[j]; if (inDuplicateBranch) { if (zone.name.indexOf(COMMON_ZONE_TYPE_STR) !== -1) { newNlRootParentName = newZoneRootParentName + COMMON_ZONE_TYPE_STR; } else { elementFromScenario = getElementFromScenario(scenario, zone.name); newNlRootParentName = this.duplicateElement(elementFromScenario, newZoneRootParentName, false); } } else { if (zone.id === element.id) { newNlRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT), true); inDuplicateBranch = true; } } // Network Locations for (var k in zone.networkLocations) { var nl = zone.networkLocations[k]; if (inDuplicateBranch) { if (nl.name.indexOf(DEFAULT_NL_TYPE_STR) !== -1) { newPlRootParentName = newNlRootParentName; } else { elementFromScenario = getElementFromScenario(scenario, nl.name); newPlRootParentName = this.duplicateElement(elementFromScenario, newNlRootParentName, false); } } else { if (nl.id === element.id) { newPlRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT, true)); inDuplicateBranch = true; } } // Physical Locations for (var l in nl.physicalLocations) { var pl = nl.physicalLocations[l]; if (inDuplicateBranch) { elementFromScenario = getElementFromScenario(scenario, pl.name); newProcessRootParentName = this.duplicateElement(elementFromScenario, newPlRootParentName, false); } else { if (pl.id === element.id) { newProcessRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT, true)); inDuplicateBranch = true; } } // Processes for (var m in pl.processes) { var proc = pl.processes[m]; if (inDuplicateBranch) { elementFromScenario = getElementFromScenario(scenario, proc.name); this.duplicateElement(elementFromScenario, newProcessRootParentName, false); } else { if (proc.id === element.id) { this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT, true)); } } } } } } if(inDuplicateBranch) { break; } } this.props.cfgElemClear(); } // DELETE onDeleteElement(element) { this.props.deleteScenarioElem(element); Loading Loading @@ -193,8 +319,9 @@ class CfgPageContainer extends Component { this.props.cfgElemSetErrMsg('Missing element name'); return false; } if ( configMode === CFG_ELEM_MODE_NEW && configMode !== CFG_ELEM_MODE_EDIT && this.findIndexByKeyValue(data, FIELD_NAME, name) !== -1 ) { this.props.cfgElemSetErrMsg('Element name already exists'); Loading Loading @@ -614,6 +741,7 @@ class CfgPageContainer extends Component { onNewElement={() => this.onNewElement()} onSaveElement={elem => this.onSaveElement(elem)} onDeleteElement={elem => this.onDeleteElement(elem)} onDuplicateElement={elem => this.onDuplicateElement(elem)} onCancelElement={() => this.onCancelElement()} /> </Elevation> Loading js-apps/meep-frontend/src/js/meep-constants.js +2 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ export const MEEP_TAB_SET = 'meep-tab-set'; export const MEEP_LBL_SCENARIO_NAME = 'meep-lbl-scenario-name'; export const MEEP_BTN_CANCEL = 'meep-btn-cancel'; export const MEEP_BTN_APPLY = 'meep-btn-apply'; export const MEEP_BTN_DUPLICATE = 'meep-btn-duplicate'; // Dialog IDs export const MEEP_DLG_NEW_SCENARIO = 'meep-dlg-new-scenario'; Loading Loading @@ -157,7 +158,7 @@ export const DEFAULT_PACKET_LOSS_INTRA_ZONE = 0; export const DEFAULT_LATENCY_TERMINAL_LINK = 1; export const DEFAULT_LATENCY_JITTER_TERMINAL_LINK = 1; export const DEFAULT_THROUGHPUT_TERMINAL_LINK = 1000; export const DEFAULT_PACKET_LOSS_TERMINAL_LINK = 1; export const DEFAULT_PACKET_LOSS_TERMINAL_LINK = 0; export const DEFAULT_LATENCY_LINK = 0; export const DEFAULT_LATENCY_JITTER_LINK = 0; export const DEFAULT_THROUGHPUT_LINK = 1000; Loading js-apps/meep-frontend/src/js/state/cfg/element-configuration.js +26 −3 Original line number Diff line number Diff line Loading @@ -19,12 +19,14 @@ import { createElem } from '../../util/elem-utils'; const CFG_ELEM_NEW = 'CFG_ELEM_NEW'; const CFG_ELEM_EDIT = 'CFG_ELEM_EDIT'; const CFG_ELEM_DUPLICATE = 'CFG_ELEM_DUPLICATE'; const CFG_ELEM_CLEAR = 'CFG_ELEM_CLEAR'; const CFG_ELEM_UPDATE = 'CFG_ELEM_UPDATE'; const CFG_ELEM_SET_ERR_MSG = 'CFG_ELEM_SET_ERR_MSG'; const CFG_ELEM_MODE_NEW = 'CFG_ELEM_MODE_NEW'; const CFG_ELEM_MODE_EDIT = 'CFG_ELEM_MODE_EDIT'; const CFG_ELEM_MODE_DUPLICATE = 'CFG_ELEM_MODE_DUPLICATE'; function cfgElemNew() { return { Loading @@ -39,6 +41,13 @@ function cfgElemEdit(elem) { }; } function cfgElemDuplicate(elem) { return { type: CFG_ELEM_DUPLICATE, payload: elem }; } function cfgElemClear() { return { type: CFG_ELEM_CLEAR Loading @@ -62,16 +71,19 @@ function cfgElemSetErrMsg(msg) { export { cfgElemNew, cfgElemEdit, cfgElemDuplicate, cfgElemClear, cfgElemUpdate, cfgElemSetErrMsg, CFG_ELEM_MODE_NEW, CFG_ELEM_MODE_EDIT CFG_ELEM_MODE_EDIT, CFG_ELEM_MODE_DUPLICATE }; const initialState = { configuredElement: null, configurationMode: null, isModified: false, errorMessage: '' }; Loading @@ -87,12 +99,23 @@ export function cfgElementConfigurationReducer(state = initialState, action) { return updateObject(state, { configuredElement: action.payload, configurationMode: CFG_ELEM_MODE_EDIT, errorMessage: '' errorMessage: '', isModified: false }); case CFG_ELEM_DUPLICATE: return updateObject(state, { configuredElement: action.payload, configurationMode: CFG_ELEM_MODE_DUPLICATE, errorMessage: '', isModified: true }); case CFG_ELEM_CLEAR: return updateObject(state, initialState); case CFG_ELEM_UPDATE: return updateObject(state, { configuredElement: action.payload }); return updateObject(state, { configuredElement: action.payload, isModified: true }); case CFG_ELEM_SET_ERR_MSG: return updateObject(state, { errorMessage: action.payload }); default: Loading Loading
js-apps/meep-frontend/src/js/components/helper-components/cancel-apply-triplet.js 0 → 100644 +63 −0 Original line number Diff line number Diff line /* * Copyright (c) 2019 InterDigital Communications, Inc * * 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 { Grid, GridInner, GridCell } from '@rmwc/grid'; import { Button } from '@rmwc/button'; import { MEEP_BTN_CANCEL, MEEP_BTN_APPLY, MEEP_BTN_DUPLICATE } from '../../meep-constants'; const buttonStyles = { marginRight: 10 }; const CancelApplyTriplet = props => { return ( <Grid style={{ marginTop: 10 }}> <GridInner align={'right'}> <GridCell span={12}> <Button outlined style={buttonStyles} onClick={props.onCancel} data-cy={MEEP_BTN_CANCEL} > {props.cancelText ? props.cancelText : 'Cancel'} </Button> <Button outlined style={buttonStyles} onClick={props.onApply} disabled={props.saveDisabled} data-cy={MEEP_BTN_APPLY} > {props.applyText ? props.applyText : 'Apply'} </Button> <Button outlined style={buttonStyles} onClick={props.onDuplicate} disabled={props.duplicateDisabled} data-cy={MEEP_BTN_DUPLICATE} > {props.duplicateText ? props.duplicateText : 'Duplicate'} </Button> </GridCell> </GridInner> </Grid> ); }; export default CancelApplyTriplet;
js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js +35 −5 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ import { Checkbox } from '@rmwc/checkbox'; import { Typography } from '@rmwc/typography'; import { updateObject } from '../../util/object-util'; import { createUniqueName } from '../../util/elem-utils'; import IDSelect from '../../components/helper-components/id-select'; import CancelApplyPair from '../../components/helper-components/cancel-apply-pair'; import CancelApplyTriplet from '../../components/helper-components/cancel-apply-triplet'; import NCGroup from '../../components/helper-components/nc-group'; import { Loading Loading @@ -56,7 +58,12 @@ import { setElemFieldErr } from '../../util/elem-utils'; import { CFG_ELEM_MODE_EDIT, cfgElemUpdate } from '../../state/cfg'; import { CFG_ELEM_MODE_EDIT, CFG_ELEM_MODE_DUPLICATE, cfgElemUpdate, cfgElemDuplicate } from '../../state/cfg'; import { TYPE_CFG, Loading Loading @@ -1016,6 +1023,17 @@ export class CfgNetworkElementContainer extends Component { this.props.cfgElemUpdate(updatedElem); } // Element duplicate handler onDuplicateElement(newName) { var duplicatedElem = updateObject({}, this.props.configuredElement); setElemFieldVal(duplicatedElem, FIELD_NAME, newName); setElemFieldVal(duplicatedElem, FIELD_PARENT, null); var elementType = getElemFieldVal(duplicatedElem, FIELD_TYPE); duplicatedElem.parentElements = this.elementsOfType(getParentTypes(elementType)); this.props.cfgElemDuplicate(duplicatedElem); } // Retrieve names of elements with matching type elementsOfType(types) { return _.chain(this.props.tableData) Loading Loading @@ -1094,11 +1112,21 @@ export class CfgNetworkElementContainer extends Component { {this.props.errorMessage} </div> <CancelApplyPair <CancelApplyTriplet duplicateDisabled={ (element && this.props.configMode === CFG_ELEM_MODE_EDIT && this.props.isModified === false) ? false : true } saveDisabled={(this.props.isModified === false) ? true : false} onCancel={this.props.onCancelElement} onApply={() => { this.props.onSaveElement(element); (this.props.configMode === CFG_ELEM_MODE_DUPLICATE) ? this.props.onDuplicateElement(element) : this.props.onSaveElement(element); }} onDuplicate={() => { this.onDuplicateElement(createUniqueName(this.props.tableData, getElemFieldVal(element, FIELD_NAME) + '-copy')); }} /> </> )} Loading Loading @@ -1131,13 +1159,15 @@ const mapStateToProps = state => { tableData: state.cfg.table.entries, configuredElement: state.cfg.elementConfiguration.configuredElement, configMode: state.cfg.elementConfiguration.configurationMode, isModified: state.cfg.elementConfiguration.isModified, errorMessage: state.cfg.elementConfiguration.errorMessage }; }; const mapDispatchToProps = dispatch => { return { cfgElemUpdate: element => dispatch(cfgElemUpdate(element)) cfgElemUpdate: element => dispatch(cfgElemUpdate(element)), cfgElemDuplicate: element => dispatch(cfgElemDuplicate(element)) }; }; Loading
js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js +132 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import { Elevation } from '@rmwc/elevation'; import IDCVis from '../idc-vis'; import CfgNetworkElementContainer from './cfg-network-element-container'; import CfgPageScenarioButtons from './cfg-page-scenario-buttons'; import { deepCopy } from '../../util/object-util'; import { getElementFromScenario } from '../../util/scenario-utils'; import HeadlineBar from '../../components/headline-bar'; import CfgTable from './cfg-table'; Loading @@ -40,7 +42,8 @@ import { cfgChangeScenario, cfgChangeScenarioList, cfgChangeState, CFG_ELEM_MODE_NEW CFG_ELEM_MODE_NEW, CFG_ELEM_MODE_EDIT } from '../../state/cfg'; import { Loading @@ -58,7 +61,9 @@ import { CFG_STATE_NEW, CFG_STATE_IDLE, PAGE_CONFIGURE, ELEMENT_TYPE_SCENARIO ELEMENT_TYPE_SCENARIO, COMMON_ZONE_TYPE_STR, DEFAULT_NL_TYPE_STR } from '../../meep-constants'; import { Loading @@ -69,7 +74,9 @@ import { FIELD_EXT_PORT, FIELD_GPU_COUNT, FIELD_GPU_TYPE, getElemFieldVal getElemFieldVal, setElemFieldVal, createUniqueName } from '../../util/elem-utils'; import { pipe, filter } from '../../util/functional'; Loading Loading @@ -141,6 +148,125 @@ class CfgPageContainer extends Component { this.props.cfgElemClear(); } // DUPLICATE ELEMENT, return new element name duplicateElement(element, newParentName, isRoot) { let newElement = deepCopy(element); var name = getElemFieldVal(element, FIELD_NAME); if (isRoot === false) { name = createUniqueName(this.props.cfg.table.entries, name + '-copy'); setElemFieldVal(newElement, FIELD_NAME, name); } setElemFieldVal(newElement, FIELD_PARENT, newParentName); // add new element to scenario // new id and label will be created as part of the addNewElementToScenario called by newScenarioElem this.props.newScenarioElem(newElement); return name; } // DUPLICATE onDuplicateElement(element) { // Validate network element if (this.validateNetworkElement(element) === false) { return; } // browse to find the root of the tree to duplicate var inDuplicateBranch = false; var newZoneRootParentName = ''; var newNlRootParentName = ''; var newPlRootParentName = ''; var newProcessRootParentName = ''; var elementFromScenario; var scenario = this.props.cfg.scenario; // Domains for (var i in scenario.deployment.domains) { var domain = scenario.deployment.domains[i]; // Add domain to graph and table (ignore public domain) if (domain.id === element.id) { newZoneRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT), true); inDuplicateBranch = true; } // Zones for (var j in domain.zones) { var zone = domain.zones[j]; if (inDuplicateBranch) { if (zone.name.indexOf(COMMON_ZONE_TYPE_STR) !== -1) { newNlRootParentName = newZoneRootParentName + COMMON_ZONE_TYPE_STR; } else { elementFromScenario = getElementFromScenario(scenario, zone.name); newNlRootParentName = this.duplicateElement(elementFromScenario, newZoneRootParentName, false); } } else { if (zone.id === element.id) { newNlRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT), true); inDuplicateBranch = true; } } // Network Locations for (var k in zone.networkLocations) { var nl = zone.networkLocations[k]; if (inDuplicateBranch) { if (nl.name.indexOf(DEFAULT_NL_TYPE_STR) !== -1) { newPlRootParentName = newNlRootParentName; } else { elementFromScenario = getElementFromScenario(scenario, nl.name); newPlRootParentName = this.duplicateElement(elementFromScenario, newNlRootParentName, false); } } else { if (nl.id === element.id) { newPlRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT, true)); inDuplicateBranch = true; } } // Physical Locations for (var l in nl.physicalLocations) { var pl = nl.physicalLocations[l]; if (inDuplicateBranch) { elementFromScenario = getElementFromScenario(scenario, pl.name); newProcessRootParentName = this.duplicateElement(elementFromScenario, newPlRootParentName, false); } else { if (pl.id === element.id) { newProcessRootParentName = this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT, true)); inDuplicateBranch = true; } } // Processes for (var m in pl.processes) { var proc = pl.processes[m]; if (inDuplicateBranch) { elementFromScenario = getElementFromScenario(scenario, proc.name); this.duplicateElement(elementFromScenario, newProcessRootParentName, false); } else { if (proc.id === element.id) { this.duplicateElement(element, getElemFieldVal(element, FIELD_PARENT, true)); } } } } } } if(inDuplicateBranch) { break; } } this.props.cfgElemClear(); } // DELETE onDeleteElement(element) { this.props.deleteScenarioElem(element); Loading Loading @@ -193,8 +319,9 @@ class CfgPageContainer extends Component { this.props.cfgElemSetErrMsg('Missing element name'); return false; } if ( configMode === CFG_ELEM_MODE_NEW && configMode !== CFG_ELEM_MODE_EDIT && this.findIndexByKeyValue(data, FIELD_NAME, name) !== -1 ) { this.props.cfgElemSetErrMsg('Element name already exists'); Loading Loading @@ -614,6 +741,7 @@ class CfgPageContainer extends Component { onNewElement={() => this.onNewElement()} onSaveElement={elem => this.onSaveElement(elem)} onDeleteElement={elem => this.onDeleteElement(elem)} onDuplicateElement={elem => this.onDuplicateElement(elem)} onCancelElement={() => this.onCancelElement()} /> </Elevation> Loading
js-apps/meep-frontend/src/js/meep-constants.js +2 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ export const MEEP_TAB_SET = 'meep-tab-set'; export const MEEP_LBL_SCENARIO_NAME = 'meep-lbl-scenario-name'; export const MEEP_BTN_CANCEL = 'meep-btn-cancel'; export const MEEP_BTN_APPLY = 'meep-btn-apply'; export const MEEP_BTN_DUPLICATE = 'meep-btn-duplicate'; // Dialog IDs export const MEEP_DLG_NEW_SCENARIO = 'meep-dlg-new-scenario'; Loading Loading @@ -157,7 +158,7 @@ export const DEFAULT_PACKET_LOSS_INTRA_ZONE = 0; export const DEFAULT_LATENCY_TERMINAL_LINK = 1; export const DEFAULT_LATENCY_JITTER_TERMINAL_LINK = 1; export const DEFAULT_THROUGHPUT_TERMINAL_LINK = 1000; export const DEFAULT_PACKET_LOSS_TERMINAL_LINK = 1; export const DEFAULT_PACKET_LOSS_TERMINAL_LINK = 0; export const DEFAULT_LATENCY_LINK = 0; export const DEFAULT_LATENCY_JITTER_LINK = 0; export const DEFAULT_THROUGHPUT_LINK = 1000; Loading
js-apps/meep-frontend/src/js/state/cfg/element-configuration.js +26 −3 Original line number Diff line number Diff line Loading @@ -19,12 +19,14 @@ import { createElem } from '../../util/elem-utils'; const CFG_ELEM_NEW = 'CFG_ELEM_NEW'; const CFG_ELEM_EDIT = 'CFG_ELEM_EDIT'; const CFG_ELEM_DUPLICATE = 'CFG_ELEM_DUPLICATE'; const CFG_ELEM_CLEAR = 'CFG_ELEM_CLEAR'; const CFG_ELEM_UPDATE = 'CFG_ELEM_UPDATE'; const CFG_ELEM_SET_ERR_MSG = 'CFG_ELEM_SET_ERR_MSG'; const CFG_ELEM_MODE_NEW = 'CFG_ELEM_MODE_NEW'; const CFG_ELEM_MODE_EDIT = 'CFG_ELEM_MODE_EDIT'; const CFG_ELEM_MODE_DUPLICATE = 'CFG_ELEM_MODE_DUPLICATE'; function cfgElemNew() { return { Loading @@ -39,6 +41,13 @@ function cfgElemEdit(elem) { }; } function cfgElemDuplicate(elem) { return { type: CFG_ELEM_DUPLICATE, payload: elem }; } function cfgElemClear() { return { type: CFG_ELEM_CLEAR Loading @@ -62,16 +71,19 @@ function cfgElemSetErrMsg(msg) { export { cfgElemNew, cfgElemEdit, cfgElemDuplicate, cfgElemClear, cfgElemUpdate, cfgElemSetErrMsg, CFG_ELEM_MODE_NEW, CFG_ELEM_MODE_EDIT CFG_ELEM_MODE_EDIT, CFG_ELEM_MODE_DUPLICATE }; const initialState = { configuredElement: null, configurationMode: null, isModified: false, errorMessage: '' }; Loading @@ -87,12 +99,23 @@ export function cfgElementConfigurationReducer(state = initialState, action) { return updateObject(state, { configuredElement: action.payload, configurationMode: CFG_ELEM_MODE_EDIT, errorMessage: '' errorMessage: '', isModified: false }); case CFG_ELEM_DUPLICATE: return updateObject(state, { configuredElement: action.payload, configurationMode: CFG_ELEM_MODE_DUPLICATE, errorMessage: '', isModified: true }); case CFG_ELEM_CLEAR: return updateObject(state, initialState); case CFG_ELEM_UPDATE: return updateObject(state, { configuredElement: action.payload }); return updateObject(state, { configuredElement: action.payload, isModified: true }); case CFG_ELEM_SET_ERR_MSG: return updateObject(state, { errorMessage: action.payload }); default: Loading