Sharable Error dialog 68/168/9
authorSarkar, Anand (as0481) <as0481@att.com>
Wed, 15 May 2019 20:50:48 +0000 (16:50 -0400)
committerLott, Christopher (cl778h) <cl778h@att.com>
Wed, 22 May 2019 15:45:04 +0000 (11:45 -0400)
Signed-off-by: Sarkar, Anand (as0481) <as0481@att.com>
Issue-Id: RICPLT-1313
Change-Id: Ib464c340545fc618321cca95838a37a7fcb2a44c
Signed-off-by: Lott, Christopher (cl778h) <cl778h@att.com>
webapp-frontend/src/app/app.module.ts
webapp-frontend/src/app/services/ui/error-dialog.service.ts [new file with mode: 0644]
webapp-frontend/src/app/signal/signal.component.ranconnect-dialog.ts [new file with mode: 0644]
webapp-frontend/src/app/signal/signal.component.spec.ts
webapp-frontend/src/app/signal/signal.component.ts
webapp-frontend/src/app/ui/error-dialog/error-dialog.component.html [new file with mode: 0644]
webapp-frontend/src/app/ui/error-dialog/error-dialog.component.scss [new file with mode: 0644]
webapp-frontend/src/app/ui/error-dialog/error-dialog.component.ts [new file with mode: 0644]

index 353e127..f249df5 100644 (file)
@@ -42,7 +42,8 @@ import { DashboardService } from './services/dashboard/dashboard.service';
 import { E2ManagerService } from './services/e2-mgr/e2-mgr.service';
 import { SidenavListComponent } from './navigation/sidenav-list/sidenav-list.component';
 import { ControlComponent } from './control/control.component';
-import { SignalComponent, RANConnectDialogComponent } from './signal/signal.component';
+import { SignalComponent } from './signal/signal.component';
+import { AppRANConnectDialogComponent } from './signal/signal.component.ranconnect-dialog';
 import { StatsComponent } from './stats/stats.component';
 import { AdminComponent } from './admin/admin.component';
 import { CatalogCardComponent } from './ui/catalog-card/catalog-card.component';
@@ -54,7 +55,8 @@ import { ConfigEventComponent } from './ui/config-event/config-event.component';
 import { ConfirmDialogComponent } from './ui/confirm-dialog/confirm-dialog.component';
 import { FooterComponent } from './footer/footer.component';
 import { AnrXappComponent } from './anr-xapp/anr-xapp.component';
-
+import { ErrorDialogComponent } from './ui/error-dialog/error-dialog.component';
+import { ErrorDialogService } from './services/ui/error-dialog.service';
 
 @NgModule({
   declarations: [
@@ -72,10 +74,11 @@ import { AnrXappComponent } from './anr-xapp/anr-xapp.component';
     ModalEventComponent,
     XappComponent,
     ConfigEventComponent,
-    RANConnectDialogComponent,
+    AnrXappComponent,
+    AppRANConnectDialogComponent,
     ConfirmDialogComponent,
     FooterComponent,
-    AnrXappComponent,
+    ErrorDialogComponent
   ],
     imports: [
     BrowserModule,
@@ -118,18 +121,22 @@ import { AnrXappComponent } from './anr-xapp/anr-xapp.component';
     MatTabsModule,
     MatFormFieldModule,
     MatButtonModule,
-    MatInputModule
+    MatInputModule,
+    AppRANConnectDialogComponent,
+    ErrorDialogComponent
     ],
     entryComponents: [
+    AppRANConnectDialogComponent,
     ConfirmDialogComponent,
-    RANConnectDialogComponent
+    ErrorDialogComponent
     ],
   providers: [
       UiService,
       AdminService,
       XappMgrService,
       DashboardService,
-      E2ManagerService
+      E2ManagerService,
+      ErrorDialogService
     ],
   bootstrap: [AppComponent]
 })
diff --git a/webapp-frontend/src/app/services/ui/error-dialog.service.ts b/webapp-frontend/src/app/services/ui/error-dialog.service.ts
new file mode 100644 (file)
index 0000000..87c3815
--- /dev/null
@@ -0,0 +1,38 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * %%
+ * 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 { ErrorDialogComponent } from '../../ui/error-dialog/error-dialog.component';
+import { HttpErrorResponse } from '@angular/common/http';
+import { MatDialog } from '@angular/material/dialog';
+import { Injectable } from '@angular/core';
+@Injectable()
+export class ErrorDialogService {
+
+  public errorMessage: string = '';
+  constructor(private dialog: MatDialog) { }
+  public displayError(error: string){
+    return this.dialog.open(ErrorDialogComponent, {
+            width: '400px',
+            position: { top: '100px' },
+            disableClose: true,
+            data: {'errorMessage': error}
+        });
+  }
+}
diff --git a/webapp-frontend/src/app/signal/signal.component.ranconnect-dialog.ts b/webapp-frontend/src/app/signal/signal.component.ranconnect-dialog.ts
new file mode 100644 (file)
index 0000000..b927f4d
--- /dev/null
@@ -0,0 +1,109 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * %%
+ * 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 { Component, OnInit, Inject } from '@angular/core';
+import { FormGroup, FormControl, Validators } from '@angular/forms';
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { E2ManagerService } from '../services/e2-mgr/e2-mgr.service';
+import { ErrorDialogService } from '../services/ui/error-dialog.service';
+import { E2SetupRequest } from '../interfaces/e2-mgr.types';
+import { HttpErrorResponse } from '@angular/common/http';
+
+@Component({
+    selector: 'app-signal-ranconnect-dialog',
+    templateUrl: './signal.component.ranconnect-dialog.html',
+    styleUrls: ['./signal.component.css']
+})
+
+export class AppRANConnectDialogComponent implements OnInit {
+
+    private ranDialogForm: FormGroup;
+
+    constructor(
+        public dialogRef: MatDialogRef<AppRANConnectDialogComponent>,
+        private service: E2ManagerService, private errorService: ErrorDialogService,
+        @Inject(MAT_DIALOG_DATA) public data: E2SetupRequest) {
+    }
+
+    ngOnInit() {
+        const namePattern = /^([A-Z]){4}([0-9]){6}$/;
+        // tslint:disable-next-line:max-line-length
+        const ipPattern = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;
+        const portPattern = /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/;
+        this.ranDialogForm = new FormGroup({
+            ranType: new FormControl('endc'),
+            ranName: new FormControl('', [Validators.required, Validators.pattern(namePattern)]),
+            ranIp: new FormControl('', [Validators.required, Validators.pattern(ipPattern)]),
+            ranPort: new FormControl('', [Validators.required, Validators.pattern(portPattern)])
+        });
+
+    }
+
+    onCancel() {
+        this.dialogRef.close();
+    }
+
+    public setupConnection = (ranFormValue) => {
+
+        if (this.ranDialogForm.valid) {
+            this.executeSetupConnection(ranFormValue);
+        }
+    }
+
+    private executeSetupConnection = (ranFormValue) => {
+        let httpErrRes: HttpErrorResponse;
+        const aboutError = 'RAN Connection Failed: ';
+        const setupRequest: E2SetupRequest = {
+            ranName: ranFormValue.ranName,
+            ranIp: ranFormValue.ranIp,
+            ranPort: ranFormValue.ranPort
+        };
+        if (ranFormValue.ranType === 'endc') {
+            this.service.endcSetup(setupRequest).subscribe((val: any[]) => {},
+                (error => {
+                    httpErrRes = error;
+                    this.errorService.displayError(aboutError + httpErrRes.message);
+                })
+            );
+        } else {
+            this.service.x2Setup(setupRequest).subscribe((val: any[]) => {},
+                (error => {
+                    httpErrRes = error;
+                    this.errorService.displayError(aboutError + httpErrRes.message);
+                })
+            );
+        }
+        this.dialogRef.close();
+    }
+
+    public hasError(controlName: string, errorName: string) {
+        if (this.ranDialogForm.controls[controlName].hasError(errorName)) {
+          return true;
+        }
+        return false;
+    }
+
+    public validateControl(controlName: string) {
+        if (this.ranDialogForm.controls[controlName].invalid && this.ranDialogForm.controls[controlName].touched) {
+            return true;
+        }
+        return false;
+    }
+
+} // class AppRANConnectDialog
index a0d2914..7f11ce5 100644 (file)
@@ -7,9 +7,9 @@
  * 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.
index 77593ec..9e08f6f 100644 (file)
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
-import { Component, OnInit, Inject } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 import { LocalDataSource } from 'ng2-smart-table';
-import { Router } from '@angular/router';
-import { MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
-import { MatFormFieldModule } from '@angular/material';
-import { MatRadioModule } from '@angular/material/radio';
-import { FormGroup, FormControl, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
-import { HttpClient } from '@angular/common/http';
+import { MatDialog} from '@angular/material/dialog';
+import { AppRANConnectDialogComponent } from './signal.component.ranconnect-dialog';
 import { E2ManagerService } from '../services/e2-mgr/e2-mgr.service';
 import { E2SetupRequest } from '../interfaces/e2-mgr.types';
 
-@Component({
-  selector: 'app-signal-ranconnect-dialog',
-  templateUrl: 'signal.component.ranconnect-dialog.html',
-  styleUrls: ['signal.component.css']
-})
-
-export class RANConnectDialogComponent implements OnInit {
-
-  public ranDialogForm: FormGroup;
-
-  constructor(
-      public dialogRef: MatDialogRef<RANConnectDialogComponent>,
-      private service: E2ManagerService
-    ,
-      @Inject(MAT_DIALOG_DATA) public data: E2SetupRequest) {  }
-
-  ngOnInit() {
-    const namePattern = /^([A-Z]){4}([0-9]){6}$/;
-    const ipPattern = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;
-    const portPattern = /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/;
-    this.ranDialogForm = new FormGroup({
-      ranType: new FormControl('endc'),
-      ranName: new FormControl('', [Validators.required, Validators.pattern(namePattern)]),
-      ranIp: new FormControl('', [Validators.required, Validators.pattern(ipPattern)]),
-      ranPort: new FormControl('', [Validators.required, Validators.pattern(portPattern)])
-    });
-  }
-
-  onCancel() {
-    this.dialogRef.close();
-  }
-
-  public setupConnection = (ranFormValue) => {
-    if (this.ranDialogForm.valid) {
-      this.executeSetupConnection(ranFormValue);
-    }
-  }
-
-  private executeSetupConnection = (ranFormValue) => {
-    const setupRequest: E2SetupRequest = {
-      ranName: ranFormValue.ranName,
-      ranIp:   ranFormValue.ranIp,
-      ranPort: ranFormValue.ranPort
-    };
-    if (ranFormValue.ranType === 'endc') {
-      this.service.endcSetup(setupRequest).subscribe((val: any[]) => {});
-    } else {
-      this.service.x2Setup(setupRequest).subscribe((val: any[]) => {});
-    }
-    this.dialogRef.close();
-  }
-
-  public hasError(controlName: string, errorName: string) {
-    if (this.ranDialogForm.controls[controlName].hasError(errorName)) { return true; }
-    return false;
-  }
-
-  public validateControl(controlName: string) {
-    if (this.ranDialogForm.controls[controlName].invalid && this.ranDialogForm.controls[controlName].touched) { return true; }
-    return false;
-  }
-
-} // class RANConnectDialogComponent
-
 @Component({
   selector: 'app-signal',
   templateUrl: 'signal.component.html',
   styleUrls: ['signal.component.css']
 })
 
-export class SignalComponent {
+export class SignalComponent implements OnInit {
   settings = {
     hideSubHeader: true,
     actions: {
@@ -138,20 +70,20 @@ export class SignalComponent {
 
   source: LocalDataSource = new LocalDataSource();
 
-  constructor(private service: E2ManagerService
-  , public dialog: MatDialog, private http: HttpClient) {
-    this.service.getAll().subscribe((val: any[]) => this.source.load(val));
+  constructor(private service: E2ManagerService, public dialog: MatDialog) { }
+
+  ngOnInit() {
+    this.service.getAll().subscribe((val: E2SetupRequest[]) => this.source.load(val));
   }
 
   openRanConnectDialog() {
-    const dialogRef = this.dialog.open(RANConnectDialogComponent, {
+    const dialogRef = this.dialog.open(AppRANConnectDialogComponent, {
       width: '450px',
-      data: { }
+      data: {}
     });
     dialogRef.afterClosed().subscribe(result => {
       this.service.getAll().subscribe((val: any[]) => this.source.load(val));
     });
   }
 
-}// class SignalComponent
-
+} // class SignalComponent
diff --git a/webapp-frontend/src/app/ui/error-dialog/error-dialog.component.html b/webapp-frontend/src/app/ui/error-dialog/error-dialog.component.html
new file mode 100644 (file)
index 0000000..abca2c7
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  ========================LICENSE_START=================================
+  O-RAN-SC
+  %%
+  Copyright (C) 2019 AT&T Intellectual Property and Nokia
+  %%
+  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===================================
+  -->
+  
+  <div mat-dialog-content style="overflow-y: hidden;overflow:auto;">
+    <div class="error_message_text">{{data.errorMessage}}</div>    
+  </div>
+  <div mat-dialog-actions class="justify-content-center">
+    <button mat-button class="mat-raised-button mat-primary" (click)="closeDialog()">Close</button>
+  </div> 
+
diff --git a/webapp-frontend/src/app/ui/error-dialog/error-dialog.component.scss b/webapp-frontend/src/app/ui/error-dialog/error-dialog.component.scss
new file mode 100644 (file)
index 0000000..ea1a6ea
--- /dev/null
@@ -0,0 +1,25 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * %%
+ * 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===================================
+ */
+
+ .error_message_text {
+    overflow-y: overlay; 
+    max-height: 150px;
+ }
\ No newline at end of file
diff --git a/webapp-frontend/src/app/ui/error-dialog/error-dialog.component.ts b/webapp-frontend/src/app/ui/error-dialog/error-dialog.component.ts
new file mode 100644 (file)
index 0000000..85df9c3
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * %%
+ * 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 { Component, OnInit, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
+
+export interface ErrorData {
+  errorMessage: string;
+}
+
+@Component({
+  selector: 'app-error-dialog',
+  templateUrl: './error-dialog.component.html',
+  styleUrls: ['./error-dialog.component.scss']
+})
+
+export class ErrorDialogComponent {
+
+  constructor(private dialogRef: MatDialogRef<ErrorDialogComponent>,
+    @Inject(MAT_DIALOG_DATA) public data: ErrorData) { }
+
+  public closeDialog = () => {
+    this.dialogRef.close();
+  }
+}