diff options
Diffstat (limited to 'ui-react')
12 files changed, 175 insertions, 79 deletions
diff --git a/ui-react/src/LoopUI.js b/ui-react/src/LoopUI.js index bc3f2355..5e2da79c 100644 --- a/ui-react/src/LoopUI.js +++ b/ui-react/src/LoopUI.js @@ -109,7 +109,8 @@ export default class LoopUI extends React.Component { userName: null, loopName: OnapConstants.defaultLoopName, loopCache: new LoopCache({}), - showAlert: false + showSucAlert: false, + showFailAlert: false }; constructor() { @@ -119,7 +120,8 @@ export default class LoopUI extends React.Component { this.updateLoopCache = this.updateLoopCache.bind(this); this.loadLoop = this.loadLoop.bind(this); this.closeLoop = this.closeLoop.bind(this); - this.showAlert = this.showAlert.bind(this); + this.showSucAlert = this.showSucAlert.bind(this); + this.showFailAlert = this.showFailAlert.bind(this); this.disableAlert = this.disableAlert.bind(this); } @@ -168,9 +170,14 @@ export default class LoopUI extends React.Component { renderAlertBar() { return ( - <Alert variant="danger" show={this.state.showAlert} onClose={this.disableAlert} dismissible> + <div> + <Alert variant="success" show={this.state.showSucAlert} onClose={this.disableAlert} dismissible> {this.state.showMessage} </Alert> + <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible> + {this.state.showMessage} + </Alert> + </div> ); } @@ -223,12 +230,16 @@ export default class LoopUI extends React.Component { console.info(this.state.loopName+" loop loaded successfully"); } - showAlert(message) { - this.setState ({ showAlert: true, showMessage:message }); + showSucAlert(message) { + this.setState ({ showSucAlert: true, showMessage:message }); } + showFailAlert(message) { + this.setState ({ showFailAlert: true, showMessage:message }); + } + disableAlert() { - this.setState ({ showAlert: false }); + this.setState ({ showSucAlert: false, showFailAlert: false }); } loadLoop(loopName) { @@ -258,7 +269,7 @@ export default class LoopUI extends React.Component { <Route path="/ViewLoopTemplatesModal" render={(routeProps) => (<ViewLoopTemplatesModal {...routeProps} />)} /> <Route path="/ManageDictionaries" render={(routeProps) => (<ManageDictionaries {...routeProps} />)} /> <Route path="/operationalPolicyModal" - render={(routeProps) => (<OperationalPolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> + render={(routeProps) => (<OperationalPolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> <Route path="/policyModal/:policyInstanceType/:policyName" render={(routeProps) => (<PolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop}/>)} /> <Route path="/configurationPolicyModal/:policyName" render={(routeProps) => (<ConfigurationPolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop}/>)} /> <Route path="/createLoop" render={(routeProps) => (<CreateLoopModal {...routeProps} loadLoopFunction={this.loadLoop} />)} /> @@ -268,13 +279,13 @@ export default class LoopUI extends React.Component { <Route path="/userInfo" render={(routeProps) => (<UserInfoModal {...routeProps} />)} /> <Route path="/closeLoop" render={this.closeLoop} /> - <Route path="/submit" render={(routeProps) => (<PerformAction {...routeProps} loopAction="submit" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> - <Route path="/stop" render={(routeProps) => (<PerformAction {...routeProps} loopAction="stop" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> - <Route path="/restart" render={(routeProps) => (<PerformAction {...routeProps} loopAction="restart" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> - <Route path="/delete" render={(routeProps) => (<PerformAction {...routeProps} loopAction="delete" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> - <Route path="/undeploy" render={(routeProps) => (<PerformAction {...routeProps} loopAction="undeploy" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> - <Route path="/deploy" render={(routeProps) => (<DeployLoopModal {...routeProps} loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> - <Route path="/refreshStatus" render={(routeProps) => (<RefreshStatus {...routeProps} loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} /> + <Route path="/submit" render={(routeProps) => (<PerformAction {...routeProps} loopAction="submit" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> + <Route path="/stop" render={(routeProps) => (<PerformAction {...routeProps} loopAction="stop" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> + <Route path="/restart" render={(routeProps) => (<PerformAction {...routeProps} loopAction="restart" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> + <Route path="/delete" render={(routeProps) => (<PerformAction {...routeProps} loopAction="delete" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> + <Route path="/undeploy" render={(routeProps) => (<PerformAction {...routeProps} loopAction="undeploy" loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> + <Route path="/deploy" render={(routeProps) => (<DeployLoopModal {...routeProps} loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> + <Route path="/refreshStatus" render={(routeProps) => (<RefreshStatus {...routeProps} loopCache={this.getLoopCache()} updateLoopFunction={this.updateLoopCache} showSucAlert={this.showSucAlert} showFailAlert={this.showFailAlert}/>)} /> <Route path="/logout" render={this.logout} /> <GlobalClampStyle /> {this.renderAlertBar()} diff --git a/ui-react/src/LoopUI.test.js b/ui-react/src/LoopUI.test.js index d1b76aa9..6885e793 100644 --- a/ui-react/src/LoopUI.test.js +++ b/ui-react/src/LoopUI.test.js @@ -66,7 +66,8 @@ describe('Verify LoopUI', () => { const component = shallow(<LoopUI />) component.setState({ loopName: "testLoopName", - showAlert: false + showSucAlert: false, + showFailAlert: false }); await flushPromises(); expect(component).toMatchSnapshot(); @@ -158,15 +159,22 @@ describe('Verify LoopUI', () => { test('Test alert methods', () => { const component = shallow(<LoopUI />) - expect(component.state('showAlert')).toEqual(false); + expect(component.state('showSucAlert')).toEqual(false); const instance = component.instance(); - instance.showAlert("testAlert"); - expect(component.state('showAlert')).toEqual(true); + instance.showSucAlert("testAlert"); + expect(component.state('showSucAlert')).toEqual(true); + expect(component.state('showFailAlert')).toEqual(false); expect(component.state('showMessage')).toEqual("testAlert"); instance.disableAlert(); - expect(component.state('showAlert')).toEqual(false); + expect(component.state('showSucAlert')).toEqual(false); + expect(component.state('showFailAlert')).toEqual(false); + + instance.showFailAlert("testAlert2"); + expect(component.state('showSucAlert')).toEqual(false); + expect(component.state('showFailAlert')).toEqual(true); + expect(component.state('showMessage')).toEqual("testAlert2"); }) }); diff --git a/ui-react/src/__snapshots__/LoopUI.test.js.snap b/ui-react/src/__snapshots__/LoopUI.test.js.snap index 9de232dd..e523de94 100644 --- a/ui-react/src/__snapshots__/LoopUI.test.js.snap +++ b/ui-react/src/__snapshots__/LoopUI.test.js.snap @@ -89,27 +89,50 @@ exports[`Verify LoopUI Test the render method 1`] = ` render={[Function]} /> <GlobalStyleComponent /> - <Alert - closeLabel="Close alert" - dismissible={true} - onClose={[Function]} - show={false} - transition={ - Object { - "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "appear": false, - "in": false, - "mountOnEnter": false, - "timeout": 300, - "unmountOnExit": false, - }, - "displayName": "Fade", - "render": [Function], + <div> + <Alert + closeLabel="Close alert" + dismissible={true} + onClose={[Function]} + show={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } } - } - variant="danger" - /> + variant="success" + /> + <Alert + closeLabel="Close alert" + dismissible={true} + onClose={[Function]} + show={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + /> + </div> <Navbar collapseOnSelect={false} expand={true} diff --git a/ui-react/src/__snapshots__/OnapClamp.test.js.snap b/ui-react/src/__snapshots__/OnapClamp.test.js.snap index 91812b7c..23518532 100644 --- a/ui-react/src/__snapshots__/OnapClamp.test.js.snap +++ b/ui-react/src/__snapshots__/OnapClamp.test.js.snap @@ -114,27 +114,50 @@ exports[`Verify OnapClamp Test the render method 1`] = ` render={[Function]} /> <GlobalStyleComponent /> - <Alert - closeLabel="Close alert" - dismissible={true} - onClose={[Function]} - show={false} - transition={ - Object { - "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "appear": false, - "in": false, - "mountOnEnter": false, - "timeout": 300, - "unmountOnExit": false, - }, - "displayName": "Fade", - "render": [Function], + <div> + <Alert + closeLabel="Close alert" + dismissible={true} + onClose={[Function]} + show={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } } - } - variant="danger" - /> + variant="success" + /> + <Alert + closeLabel="Close alert" + dismissible={true} + onClose={[Function]} + show={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + /> + </div> <Navbar collapseOnSelect={false} expand={true} diff --git a/ui-react/src/components/dialogs/Loop/DeployLoopModal.js b/ui-react/src/components/dialogs/Loop/DeployLoopModal.js index d034ee5d..6e743703 100644 --- a/ui-react/src/components/dialogs/Loop/DeployLoopModal.js +++ b/ui-react/src/components/dialogs/Loop/DeployLoopModal.js @@ -29,6 +29,12 @@ import Form from 'react-bootstrap/Form'; import Tabs from 'react-bootstrap/Tabs'; import Tab from 'react-bootstrap/Tab'; import styled from 'styled-components'; +import Spinner from 'react-bootstrap/Spinner' + +const StyledSpinnerDiv = styled.div` + justify-content: center !important; + display: flex !important; +`; const ModalStyled = styled(Modal)` background-color: transparent; @@ -48,6 +54,7 @@ export default class DeployLoopModal extends React.Component { this.handleChange = this.handleChange.bind(this); this.refreshStatus = this.refreshStatus.bind(this); this.renderDeployParam = this.renderDeployParam.bind(this); + this.renderSpinner = this.renderSpinner.bind(this); const propertiesJson = JSON.parse(JSON.stringify(this.props.loopCache.getGlobalProperties())); this.state = { @@ -79,31 +86,48 @@ export default class DeployLoopModal extends React.Component { this.props.history.push('/'); } + renderSpinner() { + if (this.state.deploying) { + return ( + <StyledSpinnerDiv> + <Spinner animation="border" role="status"> + <span className="sr-only">Loading...</span> + </Spinner> + </StyledSpinnerDiv> + ); + } else { + return (<div></div>); + } + } + handleSave() { const loopName = this.props.loopCache.getLoopName(); // save the global propserties + this.setState({ deploying: true }); LoopService.updateGlobalProperties(loopName, this.state.temporaryPropertiesJson).then(resp => { LoopActionService.performAction(loopName, "deploy").then(pars => { - this.props.showAlert("Action deploy successfully performed"); + this.props.showSucAlert("Action deploy successfully performed"); // refresh status and update loop logs this.refreshStatus(loopName); }) .catch(error => { - this.props.showAlert("Action deploy failed"); + this.props.showFailAlert("Action deploy failed"); // refresh status and update loop logs this.refreshStatus(loopName); }); }); - this.setState({ show: false }); - this.props.history.push('/'); } refreshStatus(loopName) { LoopActionService.refreshStatus(loopName).then(data => { this.props.updateLoopFunction(data); + this.setState({ show: false, deploying: false }); + this.props.history.push('/'); }) .catch(error => { - this.props.showAlert("Refresh status failed"); + this.props.showFailAlert("Refresh status failed"); + this.setState({ show: false, deploying: false }); + this.props.history.push('/'); }); } handleChange(event) { @@ -144,6 +168,7 @@ export default class DeployLoopModal extends React.Component { <Tabs id="controlled-tab-example" activeKey={this.state.key} onSelect={key => this.setState({ key })}> {this.renderDeployParamTabs()} </Tabs> + {this.renderSpinner()} <Modal.Footer> <Button variant="secondary" type="null" onClick={this.handleClose}>Cancel</Button> <Button variant="primary" type="submit" onClick={this.handleSave}>Deploy</Button> diff --git a/ui-react/src/components/dialogs/Loop/DeployLoopModal.test.js b/ui-react/src/components/dialogs/Loop/DeployLoopModal.test.js index 5f1dcd5f..84dbfd1f 100644 --- a/ui-react/src/components/dialogs/Loop/DeployLoopModal.test.js +++ b/ui-react/src/components/dialogs/Loop/DeployLoopModal.test.js @@ -63,7 +63,8 @@ describe('Verify DeployLoopModal', () => { const flushPromises = () => new Promise(setImmediate); const historyMock = { push: jest.fn() }; const updateLoopFunction = jest.fn(); - const showAlert = jest.fn(); + const showSucAlert = jest.fn(); + const showFailAlert = jest.fn(); const handleSave = jest.spyOn(DeployLoopModal.prototype,'handleSave'); LoopService.updateGlobalProperties = jest.fn().mockImplementation(() => { return Promise.resolve({ @@ -88,7 +89,7 @@ describe('Verify DeployLoopModal', () => { }); const component = shallow(<DeployLoopModal history={historyMock} - loopCache={loopCache} updateLoopFunction={updateLoopFunction} showAlert={showAlert} />) + loopCache={loopCache} updateLoopFunction={updateLoopFunction} showSucAlert={showSucAlert} showFailAlert={showFailAlert} />) component.find('[variant="primary"]').prop('onClick')(); await flushPromises(); diff --git a/ui-react/src/components/dialogs/Loop/__snapshots__/DeployLoopModal.test.js.snap b/ui-react/src/components/dialogs/Loop/__snapshots__/DeployLoopModal.test.js.snap index 0f86aa34..d7beecd0 100644 --- a/ui-react/src/components/dialogs/Loop/__snapshots__/DeployLoopModal.test.js.snap +++ b/ui-react/src/components/dialogs/Loop/__snapshots__/DeployLoopModal.test.js.snap @@ -56,6 +56,7 @@ exports[`Verify DeployLoopModal Test the render method 1`] = ` </Styled(FormGroup)> </Tab> </Tabs> + <div /> <ModalFooter> <Button active={false} diff --git a/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js b/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js index 89e70795..149639cb 100644 --- a/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js +++ b/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js @@ -56,7 +56,7 @@ export default class OperationalPolicyModal extends React.Component { if (errors.length !== 0) { console.error("Errors detected during config policy data validation ", errors); - this.props.showAlert(errors); + this.props.showFailAlert(errors); } else { console.info("NO validation errors found in config policy data"); diff --git a/ui-react/src/components/dialogs/PerformActions.js b/ui-react/src/components/dialogs/PerformActions.js index 66b19286..cf5a3c20 100644 --- a/ui-react/src/components/dialogs/PerformActions.js +++ b/ui-react/src/components/dialogs/PerformActions.js @@ -52,12 +52,12 @@ export default class PerformActions extends React.Component { const loopName = this.state.loopName; LoopActionService.performAction(loopName, action).then(pars => { - this.props.showAlert("Action " + action + " successfully performed"); + this.props.showSucAlert("Action " + action + " successfully performed"); // refresh status and update loop logs this.refreshStatus(loopName); }) .catch(error => { - this.props.showAlert("Action " + action + " failed"); + this.props.showFailAlert("Action " + action + " failed"); // refresh status and update loop logs this.refreshStatus(loopName); }); diff --git a/ui-react/src/components/dialogs/PerformActions.test.js b/ui-react/src/components/dialogs/PerformActions.test.js index 0b078629..b833a929 100644 --- a/ui-react/src/components/dialogs/PerformActions.test.js +++ b/ui-react/src/components/dialogs/PerformActions.test.js @@ -36,7 +36,8 @@ describe('Verify PerformActions', () => { const flushPromises = () => new Promise(setImmediate); const historyMock = { push: jest.fn() }; const updateLoopFunction = jest.fn(); - const showAlert = jest.fn(); + const showSucAlert = jest.fn(); + const showFailAlert = jest.fn(); LoopActionService.refreshStatus = jest.fn().mockImplementation(() => { return Promise.resolve({ @@ -46,7 +47,7 @@ describe('Verify PerformActions', () => { }); }); const component = shallow(<PerformActions loopCache={loopCache} - loopAction="submit" history={historyMock} updateLoopFunction={updateLoopFunction} showAlert={showAlert} />) + loopAction="submit" history={historyMock} updateLoopFunction={updateLoopFunction} showSucAlert={showSucAlert} showFailAlert={showFailAlert} />) await flushPromises(); component.update(); @@ -57,7 +58,8 @@ describe('Verify PerformActions', () => { const flushPromises = () => new Promise(setImmediate); const historyMock = { push: jest.fn() }; const updateLoopFunction = jest.fn(); - const showAlert = jest.fn(); + const showSucAlert = jest.fn(); + const showFailAlert = jest.fn(); LoopActionService.performAction = jest.fn().mockImplementation(() => { return Promise.resolve({ @@ -74,7 +76,7 @@ describe('Verify PerformActions', () => { }); }); const component = shallow(<PerformActions loopCache={loopCache} - loopAction="submit" history={historyMock} updateLoopFunction={updateLoopFunction} showAlert={showAlert} />) + loopAction="submit" history={historyMock} updateLoopFunction={updateLoopFunction} showSucAlert={showSucAlert} showFailAlert={showFailAlert} />) await flushPromises(); component.update(); diff --git a/ui-react/src/components/dialogs/RefreshStatus.js b/ui-react/src/components/dialogs/RefreshStatus.js index 64b35d99..bb093915 100644 --- a/ui-react/src/components/dialogs/RefreshStatus.js +++ b/ui-react/src/components/dialogs/RefreshStatus.js @@ -44,12 +44,12 @@ export default class RefreshStatus extends React.Component { componentDidMount() { // refresh status and update loop logs LoopActionService.refreshStatus(this.state.loopName).then(data => { - this.props.showAlert("Status successfully refreshed"); + this.props.showSucAlert("Status successfully refreshed"); this.props.updateLoopFunction(data); this.props.history.push('/'); }) .catch(error => { - this.props.showAlert("Status refreshing failed"); + this.props.showFailAlert("Status refreshing failed"); this.props.history.push('/'); }); } diff --git a/ui-react/src/components/dialogs/RefreshStatus.test.js b/ui-react/src/components/dialogs/RefreshStatus.test.js index 3038eb32..e08c50d2 100644 --- a/ui-react/src/components/dialogs/RefreshStatus.test.js +++ b/ui-react/src/components/dialogs/RefreshStatus.test.js @@ -35,9 +35,10 @@ describe('Verify RefreshStatus', () => { it('Test refresh status failed', async () => { const flushPromises = () => new Promise(setImmediate); const historyMock = { push: jest.fn() }; - const showAlert = jest.fn(); + const showSucAlert = jest.fn(); + const showFailAlert = jest.fn(); - const component = shallow(<RefreshStatus loopCache={loopCache} history={historyMock} showAlert={showAlert} />) + const component = shallow(<RefreshStatus loopCache={loopCache} history={historyMock} showSucAlert={showSucAlert} showFailAlert={showFailAlert} />) await flushPromises(); component.update(); @@ -48,7 +49,8 @@ describe('Verify RefreshStatus', () => { const flushPromises = () => new Promise(setImmediate); const historyMock = { push: jest.fn() }; const updateLoopFunction = jest.fn(); - const showAlert = jest.fn(); + const showSucAlert = jest.fn(); + const showFailAlert = jest.fn(); LoopActionService.refreshStatus = jest.fn().mockImplementation(() => { return Promise.resolve({ @@ -59,7 +61,7 @@ describe('Verify RefreshStatus', () => { }); const component = shallow(<RefreshStatus loopCache={loopCache} - loopAction="submit" history={historyMock} updateLoopFunction={updateLoopFunction} showAlert={showAlert} />) + loopAction="submit" history={historyMock} updateLoopFunction={updateLoopFunction} showSucAlert={showSucAlert} showFailAlert={showFailAlert} />) await flushPromises(); component.update(); |