blob: 8dc3bdb03b32a476accf9b850b6ba0e6320a1e11 [file] [log] [blame]
sebdetc8d61302019-07-04 15:50:34 +02001/*-
2 * ============LICENSE_START=======================================================
3 * ONAP CLAMP
4 * ================================================================================
sebdeteb8e3f12021-01-24 18:12:36 +01005 * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights
sebdetc8d61302019-07-04 15:50:34 +02006 * 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
24import React from 'react';
25import styled from 'styled-components';
sebdete44fdb12019-07-12 12:25:56 +020026import MenuBar from './components/menu/MenuBar';
sebdetc8d61302019-07-04 15:50:34 +020027import Navbar from 'react-bootstrap/Navbar';
28import logo from './logo.png';
sebdete44fdb12019-07-12 12:25:56 +020029import { GlobalClampStyle } from './theme/globalStyle.js';
Ted Humphrey01e5fde2020-01-27 18:57:39 -050030import OnapConstants from './utils/OnapConstants';
sebdetc8d61302019-07-04 15:50:34 +020031
sebdetc0ec0fc2020-05-18 12:31:11 +020032import SvgGenerator from './components/loop_viewer/svg/SvgGenerator';
sebdet493c3832019-07-15 17:26:18 +020033import LoopLogs from './components/loop_viewer/logs/LoopLogs';
34import LoopStatus from './components/loop_viewer/status/LoopStatus';
sebdete44fdb12019-07-12 12:25:56 +020035import UserService from './api/UserService';
sebdet493c3832019-07-15 17:26:18 +020036import LoopCache from './api/LoopCache';
xuegaoac42c4b2019-10-09 16:12:37 +020037import LoopActionService from './api/LoopActionService';
sebdet493c3832019-07-15 17:26:18 +020038
xuegao691e2b72019-08-16 11:07:24 +020039import { Route } from 'react-router-dom'
sebdetd2a4df02020-02-26 15:47:30 -080040import CreateLoopModal from './components/dialogs/Loop/CreateLoopModal';
sebdet67c76a42019-11-15 17:33:44 +010041import OpenLoopModal from './components/dialogs/Loop/OpenLoopModal';
sebdetaa486be2020-02-18 02:00:11 -080042import ModifyLoopModal from './components/dialogs/Loop/ModifyLoopModal';
sebdetd2a4df02020-02-26 15:47:30 -080043import PolicyModal from './components/dialogs/Policy/PolicyModal';
sebdeteb8e3f12021-01-24 18:12:36 +010044import ViewAllPolicies from './components/dialogs/Policy/ViewAllPolicies';
sebdetb13a7902019-11-15 17:26:45 +010045import LoopPropertiesModal from './components/dialogs/Loop/LoopPropertiesModal';
sebdet4dc849f2019-11-15 17:49:42 +010046import UserInfoModal from './components/dialogs/UserInfoModal';
sebdet83ce0762019-08-02 14:53:59 +020047import LoopService from './api/LoopService';
sebdet3b7f6692020-02-17 06:03:31 -080048import ViewLoopTemplatesModal from './components/dialogs/Tosca/ViewLoopTemplatesModal';
drveerendra50320952020-03-04 20:30:44 -050049import ManageDictionaries from './components/dialogs/ManageDictionaries/ManageDictionaries';
sebdetf9e2cee2019-08-09 18:36:09 +020050import PerformAction from './components/dialogs/PerformActions';
51import RefreshStatus from './components/dialogs/RefreshStatus';
sebdet2e9ae122019-11-15 16:28:55 +010052import DeployLoopModal from './components/dialogs/Loop/DeployLoopModal';
xuegao0efeb6b2019-10-07 14:36:34 +020053import Alert from 'react-bootstrap/Alert';
Ted Humphrey4fb32392020-07-06 16:59:47 -040054import Spinner from 'react-bootstrap/Spinner';
sebdetc8d61302019-07-04 15:50:34 +020055
sebdetd0d65632019-08-26 05:47:01 -070056import { Link } from 'react-router-dom';
57
58const StyledMainDiv = styled.div`
sebdeteb8e3f12021-01-24 18:12:36 +010059 background-color: ${props => props.theme.backgroundColor};
sebdetd0d65632019-08-26 05:47:01 -070060`
61
Ted Humphrey4fb32392020-07-06 16:59:47 -040062const StyledSpinnerDiv = styled.div`
sebdeteb8e3f12021-01-24 18:12:36 +010063 justify-content: center !important;
64 display: flex !important;
Ted Humphrey4fb32392020-07-06 16:59:47 -040065`;
66
sebdet4946e5b2019-07-10 12:32:36 +020067const ProjectNameStyled = styled.a`
sebdeteb8e3f12021-01-24 18:12:36 +010068 vertical-align: middle;
69 padding-left: 30px;
70 font-size: 36px;
71 font-weight: bold;
sebdetc8d61302019-07-04 15:50:34 +020072`
sebdetd0d65632019-08-26 05:47:01 -070073
74const StyledRouterLink = styled(Link)`
sebdeteb8e3f12021-01-24 18:12:36 +010075 color: ${props => props.theme.menuFontColor};
76 background-color: ${props => props.theme.backgroundColor};
sebdetd0d65632019-08-26 05:47:01 -070077`
78
79const StyledLoginInfo = styled.a`
sebdeteb8e3f12021-01-24 18:12:36 +010080 color: ${props => props.theme.menuFontColor};
81 background-color: ${props => props.theme.backgroundColor};
sebdetd0d65632019-08-26 05:47:01 -070082`
83
sebdet4946e5b2019-07-10 12:32:36 +020084const LoopViewDivStyled = styled.div`
sebdeteb8e3f12021-01-24 18:12:36 +010085 height: 100%;
86 overflow: hidden;
87 margin-left: 10px;
88 margin-right: 10px;
89 margin-bottom: 10px;
90 color: ${props => props.theme.loopViewerFontColor};
91 background-color: ${props => props.theme.loopViewerBackgroundColor};
92 border: 1px solid transparent;
93 border-color: ${props => props.theme.loopViewerHeaderBackgroundColor};
sebdetc8d61302019-07-04 15:50:34 +020094`
95
sebdet4946e5b2019-07-10 12:32:36 +020096const LoopViewHeaderDivStyled = styled.div`
sebdeteb8e3f12021-01-24 18:12:36 +010097 background-color: ${props => props.theme.loopViewerHeaderBackgroundColor};
98 padding: 10px 10px;
99 color: ${props => props.theme.loopViewerHeaderFontColor};
sebdetc8d61302019-07-04 15:50:34 +0200100`
101
sebdet4946e5b2019-07-10 12:32:36 +0200102const LoopViewBodyDivStyled = styled.div`
sebdeteb8e3f12021-01-24 18:12:36 +0100103 background-color: ${props => (props.theme.loopViewerBackgroundColor)};
104 padding: 10px 10px;
105 color: ${props => (props.theme.loopViewerHeaderFontColor)};
106 height: 95%;
sebdetc8d61302019-07-04 15:50:34 +0200107`
108
sebdetc8d61302019-07-04 15:50:34 +0200109export default class LoopUI extends React.Component {
sebdet493c3832019-07-15 17:26:18 +0200110
sebdeteb8e3f12021-01-24 18:12:36 +0100111 state = {
112 userName: null,
113 loopName: OnapConstants.defaultLoopName,
114 loopCache: new LoopCache({}),
115 showSucAlert: false,
116 showFailAlert: false,
117 busyLoadingCount: 0
118 };
xuegao7c7323d2019-07-09 11:52:20 +0200119
sebdeteb8e3f12021-01-24 18:12:36 +0100120 constructor() {
121 super();
122 this.getUser = this.getUser.bind(this);
123 this.updateLoopCache = this.updateLoopCache.bind(this);
124 this.loadLoop = this.loadLoop.bind(this);
125 this.closeLoop = this.closeLoop.bind(this);
126 this.showSucAlert = this.showSucAlert.bind(this);
127 this.showFailAlert = this.showFailAlert.bind(this);
128 this.disableAlert = this.disableAlert.bind(this);
129 this.setBusyLoading = this.setBusyLoading.bind(this);
130 this.clearBusyLoading = this.clearBusyLoading.bind(this);
131 this.isBusyLoading = this.isBusyLoading.bind(this);
132 this.renderGlobalStyle = this.renderGlobalStyle.bind(this);
133 this.renderSvg = this.renderSvg.bind(this);
134 }
sebdet493c3832019-07-15 17:26:18 +0200135
sebdeteb8e3f12021-01-24 18:12:36 +0100136 componentWillMount() {
137 this.getUser();
138 }
sebdet4946e5b2019-07-10 12:32:36 +0200139
sebdeteb8e3f12021-01-24 18:12:36 +0100140 getUser() {
141 UserService.login().then(user => {
142 this.setState({ userName: user })
143 });
144 }
sebdet493c3832019-07-15 17:26:18 +0200145
sebdeteb8e3f12021-01-24 18:12:36 +0100146 renderMenuNavBar() {
147 return (
148 <MenuBar loopName={this.state.loopName}/>
149 );
150 }
sebdet4946e5b2019-07-10 12:32:36 +0200151
sebdeteb8e3f12021-01-24 18:12:36 +0100152 renderUserLoggedNavBar() {
153 return (
154 <Navbar.Text>
155 <StyledLoginInfo>Signed in as: </StyledLoginInfo>
156 <StyledRouterLink to="/userInfo">{this.state.userName}</StyledRouterLink>
157 </Navbar.Text>
158 );
159 }
sebdet4946e5b2019-07-10 12:32:36 +0200160
sebdeteb8e3f12021-01-24 18:12:36 +0100161 renderLogoNavBar() {
162 return (
163 <Navbar.Brand>
164 <img height="50px" width="234px" src={logo} alt="" />
165 <ProjectNameStyled>CLAMP</ProjectNameStyled>
166 </Navbar.Brand>
167 );
168 }
sebdet4946e5b2019-07-10 12:32:36 +0200169
sebdeteb8e3f12021-01-24 18:12:36 +0100170 renderAlertBar() {
171 return (
172 <div>
173 <Alert variant="success" show={this.state.showSucAlert} onClose={this.disableAlert} dismissible>
174 {this.state.showMessage}
175 </Alert>
176 <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
177 {this.state.showMessage}
178 </Alert>
179 </div>
180 );
181 }
xuegao0efeb6b2019-10-07 14:36:34 +0200182
sebdeteb8e3f12021-01-24 18:12:36 +0100183 renderNavBar() {
184 return (
185 <Navbar >
186 {this.renderLogoNavBar()}
187 <Navbar.Toggle aria-controls="responsive-navbar-nav" />
188 {this.renderMenuNavBar()}
189 {this.renderUserLoggedNavBar()}
190 </Navbar>
191 );
192 }
sebdet493c3832019-07-15 17:26:18 +0200193
sebdeteb8e3f12021-01-24 18:12:36 +0100194 renderLoopViewHeader() {
195 return (
196 <LoopViewHeaderDivStyled>
197 Loop Viewer - {this.state.loopName} - ({this.state.loopCache.getTemplateName()})
198 </LoopViewHeaderDivStyled>
199 );
200 }
sebdet493c3832019-07-15 17:26:18 +0200201
sebdeteb8e3f12021-01-24 18:12:36 +0100202 renderSvg() {
203 return (
204 <SvgGenerator loopCache={this.state.loopCache} clickable={true} generatedFrom={SvgGenerator.GENERATED_FROM_INSTANCE} isBusyLoading={this.isBusyLoading}/>
205 )
206 }
207 renderLoopViewBody() {
208 return (
209 <LoopViewBodyDivStyled>
210 {this.renderSvg()}
211 <LoopStatus loopCache={this.state.loopCache}/>
212 <LoopLogs loopCache={this.state.loopCache} />
213 </LoopViewBodyDivStyled>
214 );
215 }
sebdet493c3832019-07-15 17:26:18 +0200216
sebdeteb8e3f12021-01-24 18:12:36 +0100217 getLoopCache() {
218 return this.state.loopCache;
xuegaoe52d5722019-07-25 15:43:06 +0200219
sebdeteb8e3f12021-01-24 18:12:36 +0100220 }
xuegao5fe750c2019-08-06 13:03:53 +0200221
sebdeteb8e3f12021-01-24 18:12:36 +0100222 renderLoopViewer() {
223 return (
224 <LoopViewDivStyled>
225 {this.renderLoopViewHeader()}
226 {this.renderLoopViewBody()}
227 </LoopViewDivStyled>
228 );
229 }
sebdet493c3832019-07-15 17:26:18 +0200230
sebdeteb8e3f12021-01-24 18:12:36 +0100231 updateLoopCache(loopJson) {
Ted Humphrey083e5a22020-07-08 16:48:40 -0400232
sebdeteb8e3f12021-01-24 18:12:36 +0100233 // If call with an empty object for loopJson, this is a reset to empty
234 // from someplace like PerformActions for the case where we are "deleting"
235 // a Control Loop model. Set the loopName to the default.
Ted Humphrey083e5a22020-07-08 16:48:40 -0400236
sebdeteb8e3f12021-01-24 18:12:36 +0100237 if (loopJson === null) {
238 this.setState({ loopName: OnapConstants.defaultLoopName });
239 this.setState({ loopCache: new LoopCache({}) });
240 } else {
241 this.setState({ loopCache: new LoopCache(loopJson) });
242 this.setState({ loopName: this.state.loopCache.getLoopName() });
243 }
244 console.info(this.state.loopName+" loop loaded successfully");
Ted Humphrey083e5a22020-07-08 16:48:40 -0400245 }
xuegao5fe750c2019-08-06 13:03:53 +0200246
sebdeteb8e3f12021-01-24 18:12:36 +0100247 showSucAlert(message) {
248 this.setState ({ showSucAlert: true, showMessage:message });
249 }
xuegao0efeb6b2019-10-07 14:36:34 +0200250
sebdeteb8e3f12021-01-24 18:12:36 +0100251 showFailAlert(message) {
252 this.setState ({ showFailAlert: true, showMessage:message });
253 }
Ted Humphrey4fb32392020-07-06 16:59:47 -0400254
sebdeteb8e3f12021-01-24 18:12:36 +0100255 disableAlert() {
256 this.setState ({ showSucAlert: false, showFailAlert: false });
257 }
xuegao0efeb6b2019-10-07 14:36:34 +0200258
sebdeteb8e3f12021-01-24 18:12:36 +0100259 loadLoop(loopName) {
260 this.setBusyLoading();
261 LoopService.getLoop(loopName).then(loop => {
262 console.debug("Updating loopCache");
263 LoopActionService.refreshStatus(loopName).then(data => {
264 this.updateLoopCache(data);
265 this.clearBusyLoading();
266 this.props.history.push('/');
267 })
268 .catch(error => {
269 this.updateLoopCache(loop);
270 this.clearBusyLoading();
271 this.props.history.push('/');
272 });
273 });
274 }
sebdet493c3832019-07-15 17:26:18 +0200275
sebdeteb8e3f12021-01-24 18:12:36 +0100276 setBusyLoading() {
277 this.setState((state,props) => ({ busyLoadingCount: ++state.busyLoadingCount }));
278 }
Ted Humphrey4fb32392020-07-06 16:59:47 -0400279
sebdeteb8e3f12021-01-24 18:12:36 +0100280 clearBusyLoading() {
281 this.setState((state,props) => ({ busyLoadingCount: --state.busyLoadingCount }));
282 }
Ted Humphrey4fb32392020-07-06 16:59:47 -0400283
sebdeteb8e3f12021-01-24 18:12:36 +0100284 isBusyLoading() {
285 if (this.state.busyLoadingCount === 0) {
286 return false;
287 } else {
288 return true;
289 }
290 }
Ted Humphrey4fb32392020-07-06 16:59:47 -0400291
sebdeteb8e3f12021-01-24 18:12:36 +0100292 closeLoop() {
293 this.setState({ loopCache: new LoopCache({}), loopName: OnapConstants.defaultLoopName });
294 this.props.history.push('/');
295 }
sebdet687b8de2019-08-26 14:29:11 -0700296
sebdeteb8e3f12021-01-24 18:12:36 +0100297 renderRoutes() {
298 return(
299 <React.Fragment>
sebdeteb8e3f12021-01-24 18:12:36 +0100300 <Route path="/viewLoopTemplatesModal" render={(routeProps) => (<ViewLoopTemplatesModal {...routeProps} />)} />
301 <Route path="/manageDictionaries" render={(routeProps) => (<ManageDictionaries {...routeProps} />)} />
302 <Route path="/viewAllPolicies" render={(routeProps) => (<ViewAllPolicies {...routeProps} />)} />
303 <Route path="/policyModal/:policyInstanceType/:policyName" render={(routeProps) => (<PolicyModal {...routeProps}
304 loopCache={this.getLoopCache()}
305 loadLoopFunction={this.loadLoop}/>)}
306 />
307 <Route path="/createLoop" render={(routeProps) => (<CreateLoopModal {...routeProps}
308 loadLoopFunction={this.loadLoop} />)}
309 />
310 <Route path="/openLoop" render={(routeProps) => (<OpenLoopModal {...routeProps}
311 loadLoopFunction={this.loadLoop} />)}
312 />
313 <Route path="/loopProperties" render={(routeProps) => (<LoopPropertiesModal {...routeProps}
314 loopCache={this.getLoopCache()}
315 loadLoopFunction={this.loadLoop}/>)}
316 />
317 <Route path="/modifyLoop" render={(routeProps) => (<ModifyLoopModal {...routeProps}
318 loopCache={this.getLoopCache()}
319 loadLoopFunction={this.loadLoop}/>)}
320 />
Ted Humphrey4fb32392020-07-06 16:59:47 -0400321
sebdeteb8e3f12021-01-24 18:12:36 +0100322 <Route path="/userInfo" render={(routeProps) => (<UserInfoModal {...routeProps} />)} />
323 <Route path="/closeLoop" render={this.closeLoop} />
sebdetaa486be2020-02-18 02:00:11 -0800324
sebdeteb8e3f12021-01-24 18:12:36 +0100325 <Route path="/submit" render={(routeProps) => (<PerformAction {...routeProps}
326 loopAction="submit"
327 loopCache={this.getLoopCache()}
328 updateLoopFunction={this.updateLoopCache}
329 showSucAlert={this.showSucAlert}
330 showFailAlert={this.showFailAlert}
331 setBusyLoading={this.setBusyLoading}
332 clearBusyLoading={this.clearBusyLoading}/>)}
333 />
334 <Route path="/stop" render={(routeProps) => (<PerformAction {...routeProps}
335 loopAction="stop"
336 loopCache={this.getLoopCache()}
337 updateLoopFunction={this.updateLoopCache}
338 showSucAlert={this.showSucAlert}
339 showFailAlert={this.showFailAlert}
340 setBusyLoading={this.setBusyLoading}
341 clearBusyLoading={this.clearBusyLoading}/>)}
342 />
343 <Route path="/restart" render={(routeProps) => (<PerformAction {...routeProps}
344 loopAction="restart"
345 loopCache={this.getLoopCache()}
346 updateLoopFunction={this.updateLoopCache}
347 showSucAlert={this.showSucAlert}
348 showFailAlert={this.showFailAlert}
349 setBusyLoading={this.setBusyLoading}
350 clearBusyLoading={this.clearBusyLoading}/>)}
351 />
352 <Route path="/delete" render={(routeProps) => (<PerformAction {...routeProps}
353 loopAction="delete"
354 loopCache={this.getLoopCache()}
355 updateLoopFunction={this.updateLoopCache}
356 showSucAlert={this.showSucAlert}
357 showFailAlert={this.showFailAlert}
358 setBusyLoading={this.setBusyLoading}
359 clearBusyLoading={this.clearBusyLoading}/>)}
360 />
361 <Route path="/undeploy" render={(routeProps) => (<PerformAction {...routeProps}
362 loopAction="undeploy"
363 loopCache={this.getLoopCache()}
364 updateLoopFunction={this.updateLoopCache}
365 showSucAlert={this.showSucAlert}
366 showFailAlert={this.showFailAlert}
367 setBusyLoading={this.setBusyLoading}
368 clearBusyLoading={this.clearBusyLoading}/>)}
369 />
370 <Route path="/deploy" render={(routeProps) => (<DeployLoopModal {...routeProps}
371 loopCache={this.getLoopCache()}
372 updateLoopFunction={this.updateLoopCache}
373 showSucAlert={this.showSucAlert}
374 showFailAlert={this.showFailAlert}/>)}
375 />
376 <Route path="/refreshStatus" render={(routeProps) => (<RefreshStatus {...routeProps}
377 loopCache={this.getLoopCache()}
378 updateLoopFunction={this.updateLoopCache}
379 showSucAlert={this.showSucAlert}
380 showFailAlert={this.showFailAlert}/>)}
381 />
382 </React.Fragment>
383 );
384 }
Ted Humphrey4fb32392020-07-06 16:59:47 -0400385
Ted Humphrey083e5a22020-07-08 16:48:40 -0400386 renderGlobalStyle() {
387 return (
388 <GlobalClampStyle />
389 );
390 };
391
392
sebdeteb8e3f12021-01-24 18:12:36 +0100393 renderSpinner() {
394 if (this.isBusyLoading()) {
395 return (
396 <StyledSpinnerDiv>
397 <Spinner animation="border" role="status">
398 <span className="sr-only">Loading...</span>
399 </Spinner>
400 </StyledSpinnerDiv>
401 );
402 } else {
403 return (<div></div>);
404 }
405 }
Ted Humphrey4fb32392020-07-06 16:59:47 -0400406
sebdeteb8e3f12021-01-24 18:12:36 +0100407 render() {
408 return (
409 <StyledMainDiv id="main_div">
410 {this.renderGlobalStyle()}
411 {this.renderRoutes()}
412 {this.renderSpinner()}
413 {this.renderAlertBar()}
414 {this.renderNavBar()}
415 {this.renderLoopViewer()}
416 </StyledMainDiv>
417 );
418 }
sebdetc8d61302019-07-04 15:50:34 +0200419}