0ee6e6e24c41bbba224a376dd111ecf07faa6938
[clamp.git] / ui-react / src / LoopUI.js
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * ===================================================================
21  *
22  */
23
24 import React from 'react';
25 import styled from 'styled-components';
26 import MenuBar from './components/menu/MenuBar';
27 import Navbar from 'react-bootstrap/Navbar';
28 import logo from './logo.png';
29 import { GlobalClampStyle } from './theme/globalStyle.js';
30 import OnapConstants from './utils/OnapConstants';
31
32 import SvgGenerator from './components/loop_viewer/svg/SvgGenerator';
33 import LoopLogs from './components/loop_viewer/logs/LoopLogs';
34 import LoopStatus from './components/loop_viewer/status/LoopStatus';
35 import UserService from './api/UserService';
36 import LoopCache from './api/LoopCache';
37 import LoopActionService from './api/LoopActionService';
38
39 import { Route } from 'react-router-dom'
40 import CreateLoopModal from './components/dialogs/Loop/CreateLoopModal';
41 import OpenLoopModal from './components/dialogs/Loop/OpenLoopModal';
42 import ModifyLoopModal from './components/dialogs/Loop/ModifyLoopModal';
43 import PolicyModal from './components/dialogs/Policy/PolicyModal';
44 import LoopPropertiesModal from './components/dialogs/Loop/LoopPropertiesModal';
45 import UserInfoModal from './components/dialogs/UserInfoModal';
46 import LoopService from './api/LoopService';
47 import UploadToscaPolicyModal from './components/dialogs/Tosca/UploadToscaPolicyModal';
48 import ViewToscaPolicyModal from './components/dialogs/Tosca/ViewToscaPolicyModal';
49 import ViewLoopTemplatesModal from './components/dialogs/Tosca/ViewLoopTemplatesModal';
50 import ManageDictionaries from './components/dialogs/ManageDictionaries/ManageDictionaries';
51 import PerformAction from './components/dialogs/PerformActions';
52 import RefreshStatus from './components/dialogs/RefreshStatus';
53 import DeployLoopModal from './components/dialogs/Loop/DeployLoopModal';
54 import Alert from 'react-bootstrap/Alert';
55 import Spinner from 'react-bootstrap/Spinner';
56
57 import { Link } from 'react-router-dom';
58
59 const StyledMainDiv = styled.div`
60         background-color: ${props => props.theme.backgroundColor};
61 `
62
63 const StyledSpinnerDiv = styled.div`
64         justify-content: center !important;
65         display: flex !important;
66 `;
67
68 const ProjectNameStyled = styled.a`
69         vertical-align: middle;
70         padding-left: 30px;
71         font-size: 36px;
72         font-weight: bold;
73 `
74
75 const StyledRouterLink = styled(Link)`
76         color: ${props => props.theme.menuFontColor};
77         background-color: ${props => props.theme.backgroundColor};
78 `
79
80 const StyledLoginInfo = styled.a`
81         color: ${props => props.theme.menuFontColor};
82         background-color: ${props => props.theme.backgroundColor};
83 `
84
85 const LoopViewDivStyled = styled.div`
86         height: 100%;
87         overflow: hidden;
88         margin-left: 10px;
89         margin-right: 10px;
90         margin-bottom: 10px;
91         color: ${props => props.theme.loopViewerFontColor};
92         background-color: ${props => props.theme.loopViewerBackgroundColor};
93         border: 1px solid transparent;
94         border-color: ${props => props.theme.loopViewerHeaderBackgroundColor};
95 `
96
97 const LoopViewHeaderDivStyled = styled.div`
98         background-color: ${props => props.theme.loopViewerHeaderBackgroundColor};
99         padding: 10px 10px;
100         color: ${props => props.theme.loopViewerHeaderFontColor};
101 `
102
103 const LoopViewBodyDivStyled = styled.div`
104         background-color: ${props => (props.theme.loopViewerBackgroundColor)};
105         padding: 10px 10px;
106         color: ${props => (props.theme.loopViewerHeaderFontColor)};
107         height: 95%;
108 `
109
110 export default class LoopUI extends React.Component {
111
112         state = {
113                 userName: null,
114                 loopName: OnapConstants.defaultLoopName,
115                 loopCache: new LoopCache({}),
116                 showSucAlert: false,
117                 showFailAlert: false,
118                 busyLoadingCount: 0
119         };
120
121         constructor() {
122                 super();
123                 this.getUser = this.getUser.bind(this);
124                 this.updateLoopCache = this.updateLoopCache.bind(this);
125                 this.loadLoop = this.loadLoop.bind(this);
126                 this.closeLoop = this.closeLoop.bind(this);
127                 this.showSucAlert =  this.showSucAlert.bind(this);
128                 this.showFailAlert =  this.showFailAlert.bind(this);
129                 this.disableAlert =  this.disableAlert.bind(this);
130                 this.setBusyLoading = this.setBusyLoading.bind(this);
131                 this.clearBusyLoading = this.clearBusyLoading.bind(this);
132                 this.isBusyLoading = this.isBusyLoading.bind(this);
133         }
134
135         componentWillMount() {
136                 this.getUser();
137         }
138
139         getUser() {
140                 UserService.login().then(user => {
141                         this.setState({ userName: user })
142                 });
143         }
144
145         renderMenuNavBar() {
146                 return (
147                         <MenuBar loopName={this.state.loopName}/>
148                 );
149         }
150
151         renderUserLoggedNavBar() {
152                 return (
153                         <Navbar.Text>
154                         <StyledLoginInfo>Signed in as: </StyledLoginInfo>
155                                 <StyledRouterLink to="/userInfo">{this.state.userName}</StyledRouterLink>
156                         </Navbar.Text>
157                 );
158         }
159
160         renderLogoNavBar() {
161                 return (
162                         <Navbar.Brand>
163                                 <img height="50px" width="234px" src={logo} alt="" />
164                                 <ProjectNameStyled>CLAMP</ProjectNameStyled>
165                         </Navbar.Brand>
166                 );
167         }
168
169         renderAlertBar() {
170                 return (
171                         <div>
172                                 <Alert variant="success" show={this.state.showSucAlert} onClose={this.disableAlert} dismissible>
173                                         {this.state.showMessage}
174                                 </Alert>
175                                 <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
176                                         {this.state.showMessage}
177                                 </Alert>
178                         </div>
179                 );
180         }
181
182         renderNavBar() {
183                 return (
184                         <Navbar >
185                                 {this.renderLogoNavBar()}
186                                 <Navbar.Toggle aria-controls="responsive-navbar-nav" />
187                                 {this.renderMenuNavBar()}
188                                 {this.renderUserLoggedNavBar()}
189                         </Navbar>
190                 );
191         }
192
193         renderLoopViewHeader() {
194                 return (
195                         <LoopViewHeaderDivStyled>
196                                 Loop Viewer - {this.state.loopName} - ({this.state.loopCache.getTemplateName()})
197                         </LoopViewHeaderDivStyled>
198                 );
199         }
200
201         renderLoopViewBody() {
202                 return (
203                         <LoopViewBodyDivStyled>
204                                 <SvgGenerator loopCache={this.state.loopCache} clickable={true} generatedFrom={SvgGenerator.GENERATED_FROM_INSTANCE} isBusyLoading={this.isBusyLoading}/>
205                                 <LoopStatus loopCache={this.state.loopCache}/>
206                                 <LoopLogs loopCache={this.state.loopCache} />
207                         </LoopViewBodyDivStyled>
208                 );
209         }
210
211         getLoopCache() {
212                 return this.state.loopCache;
213
214         }
215
216         renderLoopViewer() {
217                 return (
218                         <LoopViewDivStyled>
219                                 {this.renderLoopViewHeader()}
220                                 {this.renderLoopViewBody()}
221                         </LoopViewDivStyled>
222                 );
223         }
224
225         updateLoopCache(loopJson) {
226                 this.setState({ loopCache: new LoopCache(loopJson) });
227                 this.setState({ loopName: this.state.loopCache.getLoopName() });
228                 console.info(this.state.loopName+" loop loaded successfully");
229         }
230
231         showSucAlert(message) {
232                 this.setState ({ showSucAlert: true, showMessage:message });
233         }
234
235         showFailAlert(message) {
236                 this.setState ({ showFailAlert: true, showMessage:message });
237         }
238
239         disableAlert() {
240                 this.setState ({ showSucAlert: false, showFailAlert: false });
241         }
242
243         loadLoop(loopName) {
244                 this.setBusyLoading();
245                 LoopService.getLoop(loopName).then(loop => {
246                         console.debug("Updating loopCache");
247                         LoopActionService.refreshStatus(loopName).then(data => {
248                                 this.updateLoopCache(data);
249                                 this.clearBusyLoading();
250                                 this.props.history.push('/');
251                         })
252                         .catch(error => {
253                                 this.updateLoopCache(loop);
254                                 this.clearBusyLoading();
255                                 this.props.history.push('/');
256                         });
257                 });
258         }
259
260         setBusyLoading() {
261                 this.setState((state,props) => ({ busyLoadingCount: ++state.busyLoadingCount }));
262         }
263
264         clearBusyLoading() {
265                 this.setState((state,props) => ({ busyLoadingCount: --state.busyLoadingCount }));
266         }
267
268         isBusyLoading() {
269                 if (this.state.busyLoadingCount === 0) {
270                         return false;
271                 } else {
272                         return true;
273                 }
274         }
275
276         closeLoop() {
277                 this.setState({ loopCache: new LoopCache({}), loopName: OnapConstants.defaultLoopName });
278                 this.props.history.push('/');
279         }
280
281         renderRoutes() {
282                 return(
283                         <React.Fragment>
284                                 <Route path="/uploadToscaPolicyModal" render={(routeProps) => (<UploadToscaPolicyModal {...routeProps} />)} />
285                                 <Route path="/viewToscaPolicyModal" render={(routeProps) => (<ViewToscaPolicyModal {...routeProps} />)} />
286                                 <Route path="/ViewLoopTemplatesModal" render={(routeProps) => (<ViewLoopTemplatesModal {...routeProps} />)} />
287                                 <Route path="/ManageDictionaries" render={(routeProps) => (<ManageDictionaries {...routeProps} />)} />
288
289                                 <Route path="/policyModal/:policyInstanceType/:policyName" render={(routeProps) => (<PolicyModal {...routeProps}
290                                         loopCache={this.getLoopCache()}
291                                         loadLoopFunction={this.loadLoop}/>)}
292                                 />
293                                 <Route path="/createLoop" render={(routeProps) => (<CreateLoopModal {...routeProps}
294                                         loadLoopFunction={this.loadLoop} />)}
295                                 />
296                                 <Route path="/openLoop" render={(routeProps) => (<OpenLoopModal {...routeProps}
297                                         loadLoopFunction={this.loadLoop} />)}
298                                 />
299                                 <Route path="/loopProperties" render={(routeProps) => (<LoopPropertiesModal {...routeProps}
300                                         loopCache={this.getLoopCache()}
301                                         loadLoopFunction={this.loadLoop}/>)}
302                                 />
303                                 <Route path="/modifyLoop" render={(routeProps) => (<ModifyLoopModal {...routeProps}
304                                         loopCache={this.getLoopCache()}
305                                         loadLoopFunction={this.loadLoop}/>)}
306                                 />
307
308                                 <Route path="/userInfo" render={(routeProps) => (<UserInfoModal {...routeProps} />)} />
309                                 <Route path="/closeLoop" render={this.closeLoop} />
310
311                                 <Route path="/submit" render={(routeProps) => (<PerformAction {...routeProps}
312                                         loopAction="submit"
313                                         loopCache={this.getLoopCache()}
314                                         updateLoopFunction={this.updateLoopCache}
315                                         showSucAlert={this.showSucAlert}
316                                         showFailAlert={this.showFailAlert}
317                                         setBusyLoading={this.setBusyLoading}
318                                         clearBusyLoading={this.clearBusyLoading}/>)}
319                                 />
320                                 <Route path="/stop" render={(routeProps) => (<PerformAction {...routeProps}
321                                         loopAction="stop"
322                                         loopCache={this.getLoopCache()}
323                                         updateLoopFunction={this.updateLoopCache}
324                                         showSucAlert={this.showSucAlert}
325                                         showFailAlert={this.showFailAlert}
326                                         setBusyLoading={this.setBusyLoading}
327                                         clearBusyLoading={this.clearBusyLoading}/>)}
328                                 />
329                                 <Route path="/restart" render={(routeProps) => (<PerformAction {...routeProps}
330                                         loopAction="restart"
331                                         loopCache={this.getLoopCache()}
332                                         updateLoopFunction={this.updateLoopCache}
333                                         showSucAlert={this.showSucAlert}
334                                         showFailAlert={this.showFailAlert}
335                                         setBusyLoading={this.setBusyLoading}
336                                         clearBusyLoading={this.clearBusyLoading}/>)}
337                                 />
338                                 <Route path="/delete" render={(routeProps) => (<PerformAction {...routeProps}
339                                         loopAction="delete"
340                                         loopCache={this.getLoopCache()}
341                                         updateLoopFunction={this.updateLoopCache}
342                                         showSucAlert={this.showSucAlert}
343                                         showFailAlert={this.showFailAlert}
344                                         setBusyLoading={this.setBusyLoading}
345                                         clearBusyLoading={this.clearBusyLoading}/>)}
346                                 />
347                                 <Route path="/undeploy" render={(routeProps) => (<PerformAction {...routeProps}
348                                         loopAction="undeploy"
349                                         loopCache={this.getLoopCache()}
350                                         updateLoopFunction={this.updateLoopCache}
351                                         showSucAlert={this.showSucAlert}
352                                         showFailAlert={this.showFailAlert}
353                                         setBusyLoading={this.setBusyLoading}
354                                         clearBusyLoading={this.clearBusyLoading}/>)}
355                                 />
356                                 <Route path="/deploy" render={(routeProps) => (<DeployLoopModal {...routeProps}
357                                         loopCache={this.getLoopCache()}
358                                         updateLoopFunction={this.updateLoopCache}
359                                         showSucAlert={this.showSucAlert}
360                                         showFailAlert={this.showFailAlert}/>)}
361                                 />
362                                 <Route path="/refreshStatus" render={(routeProps) => (<RefreshStatus {...routeProps}
363                                         loopCache={this.getLoopCache()}
364                                         updateLoopFunction={this.updateLoopCache}
365                                         showSucAlert={this.showSucAlert}
366                                         showFailAlert={this.showFailAlert}/>)}
367                                 />
368                         </React.Fragment>
369                 );
370         }
371
372         renderSpinner() {
373                 if (this.isBusyLoading()) {
374                         return (
375                                 <StyledSpinnerDiv>
376                                         <Spinner animation="border" role="status">
377                                                 <span className="sr-only">Loading...</span>
378                                         </Spinner>
379                                 </StyledSpinnerDiv>
380                         );
381                 } else {
382                         return (<div></div>);
383                 }
384         }
385
386         render() {
387                 return (
388                                 <StyledMainDiv id="main_div">
389                                         <GlobalClampStyle />
390                                         {this.renderRoutes()}
391                                         {this.renderSpinner()}
392                                         {this.renderAlertBar()}
393                                         {this.renderNavBar()}
394                                         {this.renderLoopViewer()}
395                                 </StyledMainDiv>
396                 );
397         }
398 }