rework admin table 01/401/3
authorjh245g <jh245g@att.com>
Fri, 21 Jun 2019 19:59:28 +0000 (15:59 -0400)
committerjh245g <jh245g@att.com>
Mon, 24 Jun 2019 13:42:05 +0000 (09:42 -0400)
Change-Id: Ie7f475c2fc4254e6b6c7cfcf1f9143b8be9d455c
Signed-off-by: Jun (Nicolas) Hu <jh245g@att.com>
Issue-ID: RICPLT-1375

16 files changed:
docs/release-notes.rst
webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.html [new file with mode: 0644]
webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.scss [new file with mode: 0644]
webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.ts [new file with mode: 0644]
webapp-frontend/src/app/admin/admin.component.html [deleted file]
webapp-frontend/src/app/admin/admin.component.ts [deleted file]
webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.html [new file with mode: 0644]
webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.scss [new file with mode: 0644]
webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.ts [new file with mode: 0644]
webapp-frontend/src/app/admin/user.component.css [moved from webapp-frontend/src/app/admin/admin.component.css with 73% similarity]
webapp-frontend/src/app/admin/user.component.html [new file with mode: 0644]
webapp-frontend/src/app/admin/user.component.spec.ts [moved from webapp-frontend/src/app/admin/admin.component.spec.ts with 83% similarity]
webapp-frontend/src/app/admin/user.component.ts [new file with mode: 0644]
webapp-frontend/src/app/admin/user.datasource.ts [new file with mode: 0644]
webapp-frontend/src/app/app-routing.module.ts
webapp-frontend/src/app/app.module.ts

index c1d2e00..91a71d0 100644 (file)
@@ -39,6 +39,7 @@ Version 1.0.4, 21 June 2019
 * Add build number to dashboard version string
 * Move mock admin screen user data to backend
 * Update App manager client to spec version 0.1.5
+* Rework admin table
 
 Version 1.0.3, 28 May 2019
 --------------------------
diff --git a/webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.html b/webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.html
new file mode 100644 (file)
index 0000000..c58c022
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+  ========================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-title>
+  Add Dashboard User
+</div>
+
+<form [formGroup]="addUserDialogForm" novalidate autocomplete="off">
+  <div mat-dialog-content>
+    <mat-form-field class="input-display-block">
+      <input matInput type="text" placeholder="First Name" formControlName="firstName">
+    </mat-form-field>
+    <mat-form-field class="input-display-block">
+      <input matInput type="text" placeholder="Last Name" formControlName="lastName">
+    </mat-form-field>
+  </div>
+  <div name="status">
+    <label id="request-type-radio-group-label">Status:</label>
+    <mat-radio-group aria-label="status" formControlName="status">
+      <mat-radio-button value="Active">Active</mat-radio-button>
+      <mat-radio-button value="Inactive">Inactive</mat-radio-button>
+    </mat-radio-group>
+  </div>
+  <div mat-dialog-actions class="modal-footer justify-content-center">
+    <button class="mat-raised-button" (click)="onCancel()">Cancel</button>
+    <button class="mat-raised-button mat-primary" [disabled]="!addUserDialogForm.valid" (click)="addUser(addUserDialogForm.value)" >Add</button>
+  </div>
+</form>
diff --git a/webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.scss b/webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.scss
new file mode 100644 (file)
index 0000000..284be7b
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ========================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===================================
+ */
+
+.input-display-block {
+    display: block;
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.ts b/webapp-frontend/src/app/admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component.ts
new file mode 100644 (file)
index 0000000..00e295e
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ========================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 } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { MatDialogRef } from '@angular/material/dialog';
+import { DashboardService } from '../../services/dashboard/dashboard.service';
+import { ErrorDialogService } from '../../services/ui/error-dialog.service';
+
+@Component({
+  selector: 'add-dashboard-user-dialog',
+  templateUrl: './add-dashboard-user-dialog.component.html',
+  styleUrls: ['./add-dashboard-user-dialog.component.scss']
+})
+export class AddDashboardUserDialogComponent implements OnInit {
+
+  public addUserDialogForm: FormGroup;
+
+  constructor(
+    private dialogRef: MatDialogRef<AddDashboardUserDialogComponent>,
+    private dashSvc: DashboardService,
+    private errorService: ErrorDialogService) { }
+
+  ngOnInit() {
+    this.addUserDialogForm = new FormGroup({
+      firstName: new FormControl('', [Validators.required]),
+      lastName: new FormControl('', [Validators.required]),
+      status: new FormControl('', [Validators.required])
+    });
+  }
+
+  onCancel() {
+    this.dialogRef.close(false);
+  }
+
+  public addUser = (FormValue) => {
+    if (this.addUserDialogForm.valid) {
+      // send the request to backend when it's ready
+      const aboutError = 'Not implemented yet';
+      this.errorService.displayError(aboutError);
+    }
+  }
+
+}
diff --git a/webapp-frontend/src/app/admin/admin.component.html b/webapp-frontend/src/app/admin/admin.component.html
deleted file mode 100644 (file)
index 1cc9173..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-  ========================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 class="admin__section">
-    <h3 class="admin__header">Users</h3>
-    <ng2-smart-table [settings]="usersettings" [source]="usersource" (deleteConfirm)="onDeleteUserConfirm($event)">
-    </ng2-smart-table>
-</div>
diff --git a/webapp-frontend/src/app/admin/admin.component.ts b/webapp-frontend/src/app/admin/admin.component.ts
deleted file mode 100644 (file)
index 8f8a262..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- * ========================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 } from '@angular/core';
-import { LocalDataSource } from 'ng2-smart-table';
-import { DashboardService } from '../services/dashboard/dashboard.service';
-import { DashboardUser } from '../interfaces/dashboard.types';
-
-@Component({
-  selector: 'app-admin',
-  templateUrl: './admin.component.html',
-  styleUrls: ['./admin.component.css']
-})
-export class AdminComponent implements OnInit {
-
-  usersettings = {
-    columns: {
-      id: {
-        title: 'ID',
-        type: 'number',
-      },
-      firstName: {
-        title: 'First Name',
-        type: 'string',
-      },
-      lastName: {
-        title: 'Last Name',
-        type: 'string',
-      },
-      status: {
-        title: 'Status',
-        type: 'string',
-      },
-    },
-  };
-
-  usersource: LocalDataSource = new LocalDataSource();
-
-  constructor(private service: DashboardService) {
-  }
-
-  ngOnInit() {
-    this.service.getUsers().subscribe((res: DashboardUser[]) => this.usersource.load(res));
-  }
-
-  onDeleteUserConfirm(event): void {
-    if (window.confirm('Are you sure you want to delete?')) {
-      event.confirm.resolve();
-    } else {
-      event.confirm.reject();
-    }
-  }
-
-}
diff --git a/webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.html b/webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.html
new file mode 100644 (file)
index 0000000..3dc8a4b
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+  ========================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-title>
+  Edit Dashboard User
+</div>
+  
+<form [formGroup]="editUserDialogForm" novalidate autocomplete="off">
+  <div mat-dialog-content>
+    <mat-form-field class="input-display-block">
+      <input matInput type="text" placeholder="First Name" formControlName="firstName" >
+    </mat-form-field>
+    <mat-form-field class="input-display-block">
+      <input matInput type="text" placeholder="Last Name" formControlName="lastName" >
+    </mat-form-field>
+  </div>
+  <div name="status">
+    <label id="request-type-radio-group-label">Status:</label>
+    <mat-radio-group aria-label="status" formControlName="status">
+      <mat-radio-button value="Active">Active</mat-radio-button>
+      <mat-radio-button value="Inactive">Inactive</mat-radio-button>
+    </mat-radio-group>
+  </div>
+  <div mat-dialog-actions class="modal-footer justify-content-center">
+    <button class="mat-raised-button" (click)="onCancel()">Cancel</button>
+    <button class="mat-raised-button mat-primary" [disabled]="!editUserDialogForm.valid" (click)="editUser(editUserDialogForm.value)">Update</button>
+  </div>
+</form>
diff --git a/webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.scss b/webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.scss
new file mode 100644 (file)
index 0000000..284be7b
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ========================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===================================
+ */
+
+.input-display-block {
+    display: block;
+}
\ No newline at end of file
diff --git a/webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.ts b/webapp-frontend/src/app/admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component.ts
new file mode 100644 (file)
index 0000000..f8f50de
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ========================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, Inject, OnInit } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { DashboardService } from '../../services/dashboard/dashboard.service';
+import { ErrorDialogService } from '../../services/ui/error-dialog.service';
+
+
+@Component({
+  selector: 'edit-app-dashboard-user-dialog',
+  templateUrl: './edit-dashboard-user-dialog.component.html',
+  styleUrls: ['./edit-dashboard-user-dialog.component.scss']
+})
+export class EditDashboardUserDialogComponent implements OnInit {
+
+  public editUserDialogForm: FormGroup;
+
+  constructor(
+    @Inject(MAT_DIALOG_DATA) public data,
+    private dialogRef: MatDialogRef<EditDashboardUserDialogComponent>,
+    private dashSvc: DashboardService,
+    private errorService: ErrorDialogService) { }
+
+  ngOnInit() {
+    this.editUserDialogForm = new FormGroup({
+      firstName: new FormControl(this.data.firstName , [Validators.required]),
+      lastName: new FormControl(this.data.lastName, [Validators.required]),
+      status: new FormControl(this.data.status, [Validators.required])
+    });
+  }
+
+  onCancel() {
+    this.dialogRef.close(false);
+  }
+
+  public editUser = (FormValue) => {
+    if (this.editUserDialogForm.valid) {
+      // send the request to backend when it's ready
+      const aboutError = 'Not implemented yet';
+      this.errorService.displayError(aboutError);
+    }
+  }
+
+}
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
- .admin__section {
+.user__section {
 }
 
-.admin__header {
+.user__header {
     text-align: center;
     color: #432c85;
     font-size: 50px;
     transform: translate(149 56);
 }
 
-:host /deep/ ng2-smart-table tbody > tr > td{
-  text-align: center;
+.spinner-container {
+    height: 360px;
+    width: 390px;
+    position: fixed;
 }
 
-:host /deep/ ng2-smart-table thead th{
-  text-align: center;
+.spinner-container mat-spinner {
+    margin: 130px auto 0 auto;
+}
+
+.user-table {
+    width: 99%;
+    min-height: 150px;
+    margin-top: 10px;
+    background-color: transparent;
+}
+
+.user-button-row button {
+    margin-right: 5px;
 }
diff --git a/webapp-frontend/src/app/admin/user.component.html b/webapp-frontend/src/app/admin/user.component.html
new file mode 100644 (file)
index 0000000..e4b3047
--- /dev/null
@@ -0,0 +1,67 @@
+<!--
+  ========================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 class="user__section">
+    <h3 class="user__header">Users</h3>
+    <button mat-raised-button (click)="addUser()">Add User</button>
+    <div class="spinner-container" *ngIf="dataSource.loading$ | async">
+      <mat-spinner></mat-spinner>
+    </div>
+    <table mat-table [dataSource]="dataSource" matSort class="user-table mat-elevation-z8">
+
+      <ng-container matColumnDef="id">
+        <mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
+        <mat-cell *matCellDef="let element"> {{element.id}} </mat-cell>
+      </ng-container>
+
+      <ng-container matColumnDef="firstName">
+        <mat-header-cell *matHeaderCellDef mat-sort-header> First Name </mat-header-cell>
+        <mat-cell *matCellDef="let element"> {{element.firstName}} </mat-cell>
+      </ng-container>
+
+      <ng-container matColumnDef="lastName">
+        <mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </mat-header-cell>
+        <mat-cell *matCellDef="let element"> {{element.lastName}} </mat-cell>
+      </ng-container>
+
+      <ng-container matColumnDef="status">
+        <mat-header-cell *matHeaderCellDef mat-sort-header> Status </mat-header-cell>
+        <mat-cell *matCellDef="let element"> {{element.status}} </mat-cell>
+      </ng-container>
+
+      <ng-container matColumnDef="action">
+        <mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
+        <mat-cell *matCellDef="let element">
+          <div class="user-button-row">
+            <button mat-icon-button
+                    (click)="editUser(element)">
+              <mat-icon>edit</mat-icon>
+            </button>
+            <button mat-icon-button color="warn"
+                    (click)="deleteUser(element)">
+              <mat-icon>delete</mat-icon>
+            </button>
+          </div>
+        </mat-cell>
+      </ng-container>
+
+      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
+      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
+    </table>
+  </div>
  */
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { AdminComponent } from './admin.component';
+import { UserComponent } from './user.component';
 
-describe('AdminComponent', () => {
+describe('UserComponent', () => {
   let component: AdminComponent;
-  let fixture: ComponentFixture<AdminComponent>;
+  let fixture: ComponentFixture<UserComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ AdminComponent ]
+      declarations: [UserComponent]
     })
     .compileComponents();
   }));
 
   beforeEach(() => {
-    fixture = TestBed.createComponent(AdminComponent);
+    fixture = TestBed.createComponent(UserComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();
   });
diff --git a/webapp-frontend/src/app/admin/user.component.ts b/webapp-frontend/src/app/admin/user.component.ts
new file mode 100644 (file)
index 0000000..a0bd89b
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * ========================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, ViewChild } from '@angular/core';
+import { MatDialog } from '@angular/material/dialog';
+import { MatSort } from '@angular/material/sort';
+import { DashboardService } from '../services/dashboard/dashboard.service';
+import { ErrorDialogService } from '../services/ui/error-dialog.service';
+import { DashboardUser } from './../interfaces/dashboard.types';
+import { ConfirmDialogService } from './../services/ui/confirm-dialog.service';
+import { NotificationService } from './../services/ui/notification.service';
+import { UserDataSource } from './user.datasource';
+import { AddDashboardUserDialogComponent } from './add-dashboard-user-dialog/add-dashboard-user-dialog.component';
+import { EditDashboardUserDialogComponent } from './edit-dashboard-user-dialog/edit-dashboard-user-dialog.component';
+
+@Component({
+  selector: 'app-user',
+  templateUrl: './user.component.html',
+  styleUrls: ['./user.component.css']
+})
+
+export class UserComponent implements OnInit {
+
+  displayedColumns: string[] = ['id', 'firstName', 'lastName', 'status','action'];
+  dataSource: UserDataSource;
+  @ViewChild(MatSort) sort: MatSort;
+
+  constructor(
+    private dashboardSvc: DashboardService,
+    private confirmDialogService: ConfirmDialogService,
+    private errorService: ErrorDialogService,
+    private notification: NotificationService,
+    public dialog: MatDialog) { }
+
+  ngOnInit() {
+    this.dataSource = new UserDataSource(this.dashboardSvc, this.sort);
+    this.dataSource.loadTable();
+  }
+
+  editUser(user: DashboardUser) {
+    const dialogRef = this.dialog.open(EditDashboardUserDialogComponent, {
+      width: '450px',
+      data: user
+    });
+    dialogRef.afterClosed().subscribe(result => {
+      this.dataSource.loadTable();
+    });
+  }
+    
+
+  deleteUser() {
+    const aboutError = 'Not implemented yet';
+    this.errorService.displayError(aboutError);
+  }
+
+  addUser() {
+    const dialogRef = this.dialog.open(AddDashboardUserDialogComponent, {
+      width: '450px'
+    });
+    dialogRef.afterClosed().subscribe(result => {
+      this.dataSource.loadTable();
+    });
+  }
+}
+
diff --git a/webapp-frontend/src/app/admin/user.datasource.ts b/webapp-frontend/src/app/admin/user.datasource.ts
new file mode 100644 (file)
index 0000000..5b57d6b
--- /dev/null
@@ -0,0 +1,88 @@
+/*-
+ * ========================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 { CollectionViewer, DataSource } from '@angular/cdk/collections';
+import { MatSort } from '@angular/material';
+import { merge } from 'rxjs';
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { Observable } from 'rxjs/Observable';
+import { of } from 'rxjs/observable/of';
+import { catchError, finalize, map } from 'rxjs/operators';
+import { DashboardUser } from '../interfaces/dashboard.types';
+import { DashboardService } from '../services/dashboard/dashboard.service';
+
+export class UserDataSource extends DataSource<DashboardUser> {
+
+  private usersSubject = new BehaviorSubject<DashboardUser[]>([]);
+
+  private loadingSubject = new BehaviorSubject<boolean>(false);
+
+  public loading$ = this.loadingSubject.asObservable();
+
+  constructor(private dashboardSvc: DashboardService, private sort: MatSort) {
+    super();
+  };
+
+  loadTable() {
+    this.loadingSubject.next(true);
+    this.dashboardSvc.getUsers()
+      .pipe(
+        catchError(() => of([])),
+        finalize(() => this.loadingSubject.next(false))
+      )
+      .subscribe(Users => this.usersSubject.next(Users))
+  }
+
+  connect(collectionViewer: CollectionViewer): Observable<DashboardUser[]> {
+    const dataMutations = [
+      this.usersSubject.asObservable(),
+      this.sort.sortChange
+    ];
+    return merge(...dataMutations).pipe(map(() => {
+      return this.getSortedData([...this.usersSubject.getValue()]);
+    }));
+  }
+
+  disconnect(collectionViewer: CollectionViewer): void {
+    this.usersSubject.complete();
+    this.loadingSubject.complete();
+  }
+
+  private getSortedData(data: DashboardUser[]) {
+    if (!this.sort.active || this.sort.direction === '') {
+      return data;
+    }
+
+    return data.sort((a: DashboardUser, b: DashboardUser) => {
+      const isAsc = this.sort.direction === 'asc';
+      switch (this.sort.active) {
+        case 'id': return compare(a.id, b.id, isAsc);
+        case 'firstName': return compare(a.firstName, b.firstName, isAsc);
+        case 'lastName': return compare(a.lastName, b.lastName, isAsc);
+        case 'status': return compare(a.status, b.status, isAsc);
+        default: return 0;
+      }
+    });
+  }
+}
+
+function compare(a, b, isAsc: boolean) {
+  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
+}
index 10f329e..fc104e4 100644 (file)
@@ -25,7 +25,7 @@ import { CatalogComponent } from './catalog/catalog.component';
 import { ControlComponent } from './control/control.component';
 import { RANConnectionComponent } from './ran-connection/ran-connection.component';
 import { StatsComponent } from './stats/stats.component';
-import { AdminComponent } from './admin/admin.component';
+import { UserComponent } from './admin/user.component';
 import { AcXappComponent } from './ac-xapp/ac-xapp.component';
 import { AnrXappComponent } from './anr-xapp/anr-xapp.component';
 
@@ -36,7 +36,7 @@ const routes: Routes = [
     {path: 'control', component: ControlComponent},
     {path: 'ran-connection', component: RANConnectionComponent},
     {path: 'stats', component: StatsComponent},
-    {path: 'admin', component: AdminComponent},
+    {path: 'admin', component: UserComponent},
     {path: 'ac', component: AcXappComponent},
     {path: 'anr', component: AnrXappComponent},
 ];
index 35a2fa9..d1ab455 100644 (file)
@@ -49,7 +49,7 @@ import { RANConnectionDialogComponent } from './ran-connection/ran-connection-di
 import { RANConnectionComponent } from './ran-connection/ran-connection.component';
 import { ANREditNCRDialogComponent } from './anr-xapp/anr-edit-ncr-dialog.component';
 import { StatsComponent } from './stats/stats.component';
-import { AdminComponent } from './admin/admin.component';
+import { UserComponent } from './admin/user.component';
 import { CatalogCardComponent } from './ui/catalog-card/catalog-card.component';
 import { ControlCardComponent } from './ui/control-card/control-card.component';
 import { StatCardComponent } from './ui/stat-card/stat-card.component';
@@ -61,11 +61,14 @@ 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';
 import { AcXappComponent } from './ac-xapp/ac-xapp.component';
+import { AddDashboardUserDialogComponent } from './admin/add-dashboard-user-dialog/add-dashboard-user-dialog.component';
+import { EditDashboardUserDialogComponent } from './admin/edit-dashboard-user-dialog/edit-dashboard-user-dialog.component';
+
 
 @NgModule({
   declarations: [
     AcXappComponent,
-    AdminComponent,
+    UserComponent,
     ANREditNCRDialogComponent,
     AnrXappComponent,
     AppComponent,
@@ -83,7 +86,9 @@ import { AcXappComponent } from './ac-xapp/ac-xapp.component';
     RANConnectionDialogComponent,
     SidenavListComponent,
     StatCardComponent,
-    StatsComponent
+    StatsComponent,
+    AddDashboardUserDialogComponent,
+    EditDashboardUserDialogComponent
   ],
     imports: [
     AppRoutingModule,
@@ -140,7 +145,9 @@ import { AcXappComponent } from './ac-xapp/ac-xapp.component';
     RANConnectionDialogComponent,
     ANREditNCRDialogComponent,
     ConfirmDialogComponent,
-    ErrorDialogComponent
+    ErrorDialogComponent,
+    AddDashboardUserDialogComponent,
+    EditDashboardUserDialogComponent
     ],
   providers: [
       UiService,