diff options
author | xuegao <xg353y@intl.att.com> | 2019-07-09 11:52:20 +0200 |
---|---|---|
committer | xuegao <xg353y@intl.att.com> | 2019-07-10 11:58:56 +0200 |
commit | 7c7323d8ec54e65ac7a9a5e8c7cd8bdc755ea70a (patch) | |
tree | 7f77ec10c6f9bd3b13f6c94978477ee3323b9a41 /ui-react/src | |
parent | c8d6130e6355a6f8f460c114ed7bac0221eb0020 (diff) |
Create login page and add wiki/contact item
Create the login page for Clamp Ui; Add wiki/contact page which chould
be selected from the menu bar.
Issue-ID: CLAMP-416, CLAMP-417
Change-Id: Idddafd9c59a1e4d2897e962c831060e55083025c
Signed-off-by: xuegao <xg353y@intl.att.com>
Diffstat (limited to 'ui-react/src')
-rw-r--r-- | ui-react/src/components/app/LoopUI.js | 5 | ||||
-rw-r--r-- | ui-react/src/components/app/NotFound.js | 36 | ||||
-rw-r--r-- | ui-react/src/components/app/login/BasicAuthLogin.js | 117 | ||||
-rw-r--r-- | ui-react/src/components/app/login/LoginFailedPage.js | 35 | ||||
-rw-r--r-- | ui-react/src/components/app/login/LoginPage.js | 48 | ||||
-rw-r--r-- | ui-react/src/components/backend_communication/LoopActionService.js | 56 | ||||
-rw-r--r-- | ui-react/src/components/backend_communication/LoopService.js | 66 | ||||
-rw-r--r-- | ui-react/src/components/menu/MenuBar.js | 11 | ||||
-rw-r--r-- | ui-react/src/components/route/LoginRoute.js | 36 | ||||
-rw-r--r-- | ui-react/src/index.js | 24 |
10 files changed, 426 insertions, 8 deletions
diff --git a/ui-react/src/components/app/LoopUI.js b/ui-react/src/components/app/LoopUI.js index d0f5aa32..7de6ad01 100644 --- a/ui-react/src/components/app/LoopUI.js +++ b/ui-react/src/components/app/LoopUI.js @@ -70,8 +70,7 @@ const LoopViewLoopNameSpanStyle = styled.span` ` export default class LoopUI extends React.Component { - - user = "testuser"; + loopName="Empty (NO loop loaded yet)"; renderMenuNavBar() { @@ -83,7 +82,7 @@ export default class LoopUI extends React.Component { renderUserLoggedNavBar() { return ( <Navbar.Text> - Signed in as: <a href="login">{this.user}</a> + Signed in as: <a href="login">{localStorage.getItem('user')}</a> </Navbar.Text> ); } diff --git a/ui-react/src/components/app/NotFound.js b/ui-react/src/components/app/NotFound.js new file mode 100644 index 00000000..d4b53fd7 --- /dev/null +++ b/ui-react/src/components/app/NotFound.js @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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 React from 'react' + + +export default class NotFound extends React.Component { + render () { + return ( + <div id='main'> + <div class="divRow"><b>Page Not Found!</b></div> + <div class="divRow">Please cick <a href="/">here</a> to go back to the main page.</div> + </div> + + ); + } +} diff --git a/ui-react/src/components/app/login/BasicAuthLogin.js b/ui-react/src/components/app/login/BasicAuthLogin.js new file mode 100644 index 00000000..994255cd --- /dev/null +++ b/ui-react/src/components/app/login/BasicAuthLogin.js @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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 React from 'react'; +import styled from 'styled-components'; +import LoopService from '../../backend_communication/LoopService'; + +const LoginHeaderStyle = styled.span` + font-size: 20px; + font-weight: bold; + padding-left: 10px; + color: ${props => props.theme.loopViewerHeaderFontColor}; +` +const LoginDivStyle = styled.div` + font-size: 12px; + background-color: ${props => props.theme.loopViewerHeaderBackgroundColor}; + padding: 10px 10px; + color: ${props => props.theme.loopViewerHeaderFontColor}; +` +const LoginSubmitButtonStyle = styled.button` + font-size: 12px; + padding: 5px 10px; + color: ${props => props.theme.loopViewerHeaderFontColor}; + border: 2px solid; + border-radius: 8px; +` +const LoginTextInputStyle = styled.input` + padding: 10px 10px; + margin-left: 20px; + border: 1px solid #ced4da; + border-radius: 3px; + color: ${props => props.theme.loopViewerHeaderFontColor}; +` + +export default class BasicAuthLogin extends React.Component { + constructor(props) { + super(props); + this.handleSubmit = this.handleSubmit.bind(this); + this.handleChange = this.handleChange.bind(this); + console.log('BasicAuthLogin'); + this.state = { + username: '', + password: '', + submitted: 'false' + }; + } + + handleChange(e) { + const { name, value } = e.target; + this.setState({ [name]: value }); + } + + handleSubmit(e) { + e.preventDefault(); + this.setState({ submitted: true }); + const { username, password } = this.state; + LoopService.login(username, password) + .then( + user => { + const { from } = { from: { pathname: "/" } }; + this.props.history.push(from); + }, + error => { + const { from } = { from: { pathname: "/loginFailed" } }; + this.props.history.push(from); + console.log ("Basic login failed"); + } + ); + } + + render() { + const { username, password, submitted} = this.state; + return ( + <div> + <LoginHeaderStyle>Login</LoginHeaderStyle> + <form name="form" onSubmit={this.handleSubmit}> + <LoginDivStyle className={(submitted && !username ? ' has-error' : '')}> + <label htmlFor="username">Username</label> + <LoginTextInputStyle name="username" value={username} onChange={this.handleChange} /> + {submitted && !username && + <div className="help-block">Username is required</div> + } + </LoginDivStyle> + <LoginDivStyle className={(submitted && !password ? ' has-error' : '')}> + <label htmlFor="password">Password</label> + <LoginTextInputStyle type="password" name="password" value={password} onChange={this.handleChange} /> + {submitted && !password && + <div className="help-block">Password is required</div> + } + </LoginDivStyle> + <LoginDivStyle> + <LoginSubmitButtonStyle className="btn btn-primary">Login</LoginSubmitButtonStyle> + </LoginDivStyle> + </form> + </div> + ); + } +} diff --git a/ui-react/src/components/app/login/LoginFailedPage.js b/ui-react/src/components/app/login/LoginFailedPage.js new file mode 100644 index 00000000..fb398efd --- /dev/null +++ b/ui-react/src/components/app/login/LoginFailedPage.js @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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 React from 'react' + + +export default class LoginFailedPage extends React.Component { + render () { + return ( + <div id='main'> + <div class="divRow"><b>Login Failed!</b></div> + <div class="divRow">Please cick <a href="/">here</a> to go back to the main page.</div> + </div> + ); + } +} diff --git a/ui-react/src/components/app/login/LoginPage.js b/ui-react/src/components/app/login/LoginPage.js new file mode 100644 index 00000000..5169435c --- /dev/null +++ b/ui-react/src/components/app/login/LoginPage.js @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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 React from 'react'; + +import LoopService from '../../backend_communication/LoopService'; + +export default class LoginPage extends React.Component { + constructor(props) { + super(props); + console.log('LoginPage') + LoopService.login().then( + user => { + const { from } = { from: { pathname: "/" } }; + this.props.history.push(from); + }, + error => { + const { from } = { from: { pathname: "/" } }; + this.props.history.push(from); + console.log ("Certification login failed"); + } + ); + } + render() { + return ( + <div> + </div>); +} +} diff --git a/ui-react/src/components/backend_communication/LoopActionService.js b/ui-react/src/components/backend_communication/LoopActionService.js new file mode 100644 index 00000000..027243be --- /dev/null +++ b/ui-react/src/components/backend_communication/LoopActionService.js @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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============================================ + * =================================================================== + * + */ +const clActionService = { + submit +}; + +function submit(uiAction) { + const cl_name = ""; + console.log("clActionServices perform action: " + uiAction + " closedloopName=" + + cl_name); + const svcAction = uiAction.toLowerCase(); + const svcUrl = "/restservices/clds/v2/loop/" + svcAction + "/" + cl_name; + + let options = { + method: 'GET' + }; + return sendRequest (svcUrl, svcAction, options); +} + + + +function sendRequest (svcUrl, svcAction) { + fetch(svcUrl, options) + .then( + response => { + alertService.alertMessage("Action Successful: " + svcAction, 1) + }).error( error => { + alertService.alertMessage("Action Failure: " + svcAction, 2); + return Promise.reject(error); + }); + + return response.json(); + }); +} + +export default clActionService; diff --git a/ui-react/src/components/backend_communication/LoopService.js b/ui-react/src/components/backend_communication/LoopService.js new file mode 100644 index 00000000..982180df --- /dev/null +++ b/ui-react/src/components/backend_communication/LoopService.js @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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============================================ + * =================================================================== + * + */ + +const LoopService = { + login +}; + +function login(username, password) { + let options = { + method: 'GET' + }; + if (username && password) { + options = { + method: 'GET', + credentials: 'include', + headers: { + 'Authorization': "Basic " + new Buffer(username + ":" + password).toString("base64") + } + }; + } + + return fetch(`/restservices/clds/v1/user/getUser`, options) + .then(response => handleResponse(response)) + .then(function(data) { + localStorage.setItem('user', data); + console.log(data); +}); +} + +function handleResponse(response) { + if (!response.ok || response.redirected === true) { + if (response.status === 401 || response.status === 500 || response.redirected === true) { + if (localStorage.getItem('tryBasicAuth')) { + // login failed, go to invalud login page + localStorage.removeItem('user'); + } else { + // try to login with username and password + localStorage.setItem('tryBasicAuth', true); + } + } + const error = response.statusText; + return Promise.reject(error); + } + return response.text(); +} +export default LoopService; diff --git a/ui-react/src/components/menu/MenuBar.js b/ui-react/src/components/menu/MenuBar.js index 3077bde6..34854196 100644 --- a/ui-react/src/components/menu/MenuBar.js +++ b/ui-react/src/components/menu/MenuBar.js @@ -36,6 +36,13 @@ const StyledNavDropdownItem = styled(NavDropdown.Item)` export default class MenuBar extends React.Component { + openEmailConsole() { + console.log("contactUs"); + var link = "mailto:onap-discuss@lists.onap.org?subject=CLAMP&body=Please " + + "send us suggestions or feature enhancements or defect. If possible, please send us the steps to replicate any defect."; + window.location.href = link; + }; + render () { return ( <Navbar.Collapse id="basic-navbar-nav" className="justify-content-center"> @@ -56,8 +63,8 @@ export default class MenuBar extends React.Component { <StyledNavDropdownItem href="#action/3.1">Refresh Status</StyledNavDropdownItem> </NavDropdown> <NavDropdown title="Help" id="basic-nav-dropdown"> - <StyledNavDropdownItem href="#action/3.1">Wiki</StyledNavDropdownItem> - <StyledNavDropdownItem href="#action/3.2">Contact Us</StyledNavDropdownItem> + <NavDropdown.Item onClick={()=> window.open("https://wiki.onap.org/", "_blank")}>Wiki</NavDropdown.Item> + <NavDropdown.Item onClick={()=> this.openEmailConsole()}>Contact Us</NavDropdown.Item> <StyledNavDropdownItem href="#action/3.3">User Info</StyledNavDropdownItem> </NavDropdown> </Navbar.Collapse> diff --git a/ui-react/src/components/route/LoginRoute.js b/ui-react/src/components/route/LoginRoute.js new file mode 100644 index 00000000..f24e31b4 --- /dev/null +++ b/ui-react/src/components/route/LoginRoute.js @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 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 React from 'react'; +import { Route, Redirect } from 'react-router-dom'; + +const LoginRoute = ({ component: Component, ...rest }) => ( + <Route {...rest} render={props => ( + localStorage.getItem('user') + ? <Component {...props} /> + : localStorage.getItem('tryBasicAuth') + ? <Redirect to={{ pathname: '/basicAuthLogin', state: { from: props.location } }} /> + : <Redirect to={{ pathname: '/login', state: { from: props.location } }} /> + )} /> +) + +export default LoginRoute; diff --git a/ui-react/src/index.js b/ui-react/src/index.js index b2fc3b0f..8236eb15 100644 --- a/ui-react/src/index.js +++ b/ui-react/src/index.js @@ -22,10 +22,28 @@ */ import React from 'react'; import ReactDOM from 'react-dom'; + +import { Route, Switch, BrowserRouter } from 'react-router-dom' import OnapClamp from './OnapClamp'; +import NotFound from './components/app/NotFound'; +import LoginPage from './components/app/login/LoginPage'; +import LoginFailedPage from './components/app/login/LoginFailedPage'; +import BasicAuthLogin from './components/app/login/BasicAuthLogin'; +import LoginRoute from './components/route/LoginRoute'; -ReactDOM.render( - <OnapClamp/>, - document.getElementById('root') +const routing = ( + <BrowserRouter> + <div> + <Switch> + <LoginRoute exact path="/" component={OnapClamp} /> + <Route path="/basicAuthLogin" component={BasicAuthLogin} /> + <Route path="/login" component={LoginPage} /> + <Route path="/loginFailed" component={LoginFailedPage} /> + <Route component={NotFound} /> + </Switch> + </div> + </BrowserRouter> ) + +ReactDOM.render(routing, document.getElementById('root')) |