update configure workflow
[portal/ric-dashboard.git] / dashboard / webapp-frontend / src / app / app-control / app-control.component.ts
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2019 AT&T Intellectual Property
6  * %%
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================LICENSE_END===================================
19  */
20 import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
21 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
22 import { MatDialog } from '@angular/material/dialog';
23 import { MatSort } from '@angular/material/sort';
24 import { Router } from '@angular/router';
25 import { Subscription } from 'rxjs';
26 import { finalize } from 'rxjs/operators';
27 import { XappControlRow } from '../interfaces/app-mgr.types';
28 import { RicInstance } from '../interfaces/dashboard.types';
29 import { AppMgrService } from '../services/app-mgr/app-mgr.service';
30 import { InstanceSelectorService } from '../services/instance-selector/instance-selector.service';
31 import { ConfirmDialogService } from '../services/ui/confirm-dialog.service';
32 import { ErrorDialogService } from '../services/ui/error-dialog.service';
33 import { LoadingDialogService } from '../services/ui/loading-dialog.service';
34 import { NotificationService } from '../services/ui/notification.service';
35 import { UiService } from '../services/ui/ui.service';
36 import { AppConfigurationComponent } from './../app-configuration/app-configuration.component';
37 import { AppControlAnimations } from './app-control.animations';
38 import { AppControlDataSource } from './app-control.datasource';
39
40 @Component({
41   selector: 'rd-app-control',
42   templateUrl: './app-control.component.html',
43   styleUrls: ['./app-control.component.scss'],
44   animations: [AppControlAnimations.messageTrigger]
45 })
46 export class AppControlComponent implements OnInit, OnDestroy {
47
48   darkMode: boolean;
49   panelClass: string;
50   displayedColumns: string[] = ['xapp', 'name', 'status', 'ip', 'port', 'action'];
51   dataSource: AppControlDataSource;
52   @ViewChild(MatSort, { static: true }) sort: MatSort;
53   private instanceChange: Subscription;
54   private instanceKey: string;
55
56   constructor(
57     private appMgrSvc: AppMgrService,
58     private router: Router,
59     private dialog: MatDialog,
60     private confirmDialogService: ConfirmDialogService,
61     private errorDialogService: ErrorDialogService,
62     private loadingDialogService: LoadingDialogService,
63     public instanceSelectorService: InstanceSelectorService,
64     private notificationService: NotificationService,
65     public ui: UiService
66     ) { }
67
68
69   ngOnInit() {
70     this.dataSource = new AppControlDataSource(this.appMgrSvc, this.sort, this.notificationService);
71     this.ui.darkModeState.subscribe((isDark) => {
72       this.darkMode = isDark;
73     });
74     this.instanceChange = this.instanceSelectorService.getSelectedInstance().subscribe((instance: RicInstance) => {
75       if (instance.key) {
76         this.instanceKey = instance.key;
77         this.dataSource.loadTable(instance.key);
78       }
79     });
80   }
81
82   ngOnDestroy() {
83     this.instanceChange.unsubscribe();
84   }
85
86   controlApp(app: XappControlRow): void {
87     // TODO: identify apps without hardcoding to names
88     this.errorDialogService.displayError('No control available for ' + app.xapp + ' (yet)');
89   }
90
91   onConfigureApp(xappRow: XappControlRow): void {
92     if (this.darkMode) {
93       this.panelClass = 'dark-theme';
94     } else {
95       this.panelClass = '';
96     }
97     const dialogRef = this.dialog.open(AppConfigurationComponent, {
98       panelClass: this.panelClass,
99       width: '80%',
100       maxHeight: '70%',
101       position: {
102         top: '10%'
103       },
104       data: {
105         xapp: xappRow.xapp,
106         instanceKey: this.instanceKey
107       }
108
109     });
110   }
111
112   onUndeployApp(app: XappControlRow): void {
113     this.confirmDialogService.openConfirmDialog('Are you sure you want to undeploy App ' + app.xapp + '?')
114       .afterClosed().subscribe((res: boolean) => {
115         if (res) {
116           this.loadingDialogService.startLoading('Undeploying ' + app.xapp);
117           this.appMgrSvc.undeployXapp(this.instanceKey, app.xapp)
118             .pipe(
119               finalize(() => this.loadingDialogService.stopLoading())
120             )
121             .subscribe(
122               (httpResponse: HttpResponse<Object>) => {
123                 // Answers 204/No content on success
124                 this.notificationService.success('App undeployed successfully!');
125                 this.dataSource.loadTable(this.instanceKey);
126               },
127               ((her: HttpErrorResponse) => {
128                 // the error field should have an ErrorTransport object
129                 let msg = her.message;
130                 if (her.error && her.error.message) {
131                   msg = her.error.message;
132                 }
133                 this.notificationService.warn('App undeploy failed: ' + msg);
134               })
135             );
136         }
137       });
138   }
139
140 }