You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by dg...@apache.org on 2020/07/03 14:13:02 UTC

[incubator-dlab] branch develop updated: [DLAB-1917]: Fixed set of UI tasks in Audit (#809)

This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git


The following commit(s) were added to refs/heads/develop by this push:
     new dffcbb0  [DLAB-1917]: Fixed set of UI tasks in Audit (#809)
dffcbb0 is described below

commit dffcbb03c3ec1862d0a0721ffc3add1396693796
Author: Dmytro Gnatyshyn <42...@users.noreply.github.com>
AuthorDate: Fri Jul 3 17:12:56 2020 +0300

    [DLAB-1917]: Fixed set of UI tasks in Audit (#809)
---
 .../resources/ImageExploratoryResource.java        |   2 +-
 .../resources/LibExploratoryResource.java          |   2 +-
 .../audit/audit-grid/audit-grid.component.ts       | 136 ++++++++++++++-------
 .../cluster-details/cluster-details.component.ts   |   2 +-
 .../detail-dialog/detail-dialog.component.ts       |   2 +-
 .../resources/LibExploratoryResourceTest.java      |   2 +-
 6 files changed, 97 insertions(+), 49 deletions(-)

diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
index 80f5907..282e1c6 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
@@ -53,7 +53,7 @@ import java.util.List;
 @Produces(MediaType.APPLICATION_JSON)
 @Slf4j
 public class ImageExploratoryResource {
-	private final static String AUDIT_MESSAGE = "Image name: %s";
+	private final static String AUDIT_MESSAGE = "Create image: %s";
 
 	private final ImageExploratoryService imageExploratoryService;
 	private final RequestId requestId;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
index c6c13ac..8e81708 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
@@ -61,7 +61,7 @@ import java.util.stream.Collectors;
 @Slf4j
 public class LibExploratoryResource {
 	private static final String DROPWIZARD_ARTIFACT = "io.dropwizard:dropwizard-core:1.3.5";
-	private static final String AUDIT_MESSAGE = "Installed libs: %s";
+	private static final String AUDIT_MESSAGE = "Install libs: %s";
 
 	private final ExternalLibraryService externalLibraryService;
 	private final ExploratoryDAO exploratoryDAO;
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
index 0eeaa2a..92f9497 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
@@ -22,6 +22,18 @@ import {FilterAuditModel} from '../filter-audit.model';
 import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';
 import {AuditService} from '../../../core/services/audit.service';
 
+
+export interface AuditItem {
+  action: string;
+  info: string;
+  project: string;
+  resourceName: string;
+  timestamp: number;
+  type: string;
+  user: string;
+  _id: string;
+}
+
 @Component({
   selector: 'dlab-audit-grid',
   templateUrl: './audit-grid.component.html',
@@ -29,7 +41,7 @@ import {AuditService} from '../../../core/services/audit.service';
 
 })
 export class AuditGridComponent implements OnInit {
-  public auditData: Array<object>;
+  public auditData: Array<AuditItem>;
   public displayedColumns: string[] = ['date', 'user', 'action', 'project', 'resource-type', 'resource', 'buttons'];
   public displayedFilterColumns: string[] = ['action-filter', 'user-filter', 'actions-filter',  'project-filter', 'resource-type-filter', 'resource-filter', 'filter-buttons'];
   public collapseFilterRow: boolean = false;
@@ -41,7 +53,7 @@ export class AuditGridComponent implements OnInit {
   public lastItem: number;
   public allItems: number;
   private copiedFilterAuditData: FilterAuditModel;
-  public isNavigationDisabled;
+  public isNavigationDisabled: boolean;
 
 
   constructor(
@@ -53,7 +65,7 @@ export class AuditGridComponent implements OnInit {
 
   ngOnInit() {}
 
-  public buildAuditGrid(filter?) {
+  public buildAuditGrid(filter?: boolean): void {
     if (!this.showItemsPrPage) {
       if (window.localStorage.getItem('audit_per_page')) {
         this.showItemsPrPage = +window.localStorage.getItem('audit_per_page');
@@ -65,7 +77,7 @@ export class AuditGridComponent implements OnInit {
    this.getAuditData(filter);
   }
 
-  public getAuditData(filter?) {
+  public getAuditData(filter?: boolean): void {
     const page = filter ? 1 : Math.ceil(this.lastItem / this.showItemsPrPage);
     this.copiedFilterAuditData = JSON.parse(JSON.stringify(this.filterAuditData));
     this.auditService.getAuditData(this.filterAuditData, page, this.showItemsPrPage).subscribe(auditData => {
@@ -84,29 +96,33 @@ export class AuditGridComponent implements OnInit {
     });
   }
 
-  public refreshAuditPage() {
+  public refreshAuditPage(): void {
     this.filterAuditData = this.copiedFilterAuditData;
     this.getAuditData();
   }
 
-  public setAvaliblePeriod(period) {
+  public setAvaliblePeriod(period): void {
     this.filterAuditData.date_start = period.start_date;
     this.filterAuditData.date_end = period.end_date;
   }
 
-  toggleFilterRow(): void {
+  public toggleFilterRow(): void {
     this.collapseFilterRow = !this.collapseFilterRow;
   }
 
-  onUpdate($event): void {
+  public onUpdate($event): void {
     this.filterAuditData[$event.type] = $event.model;
   }
 
-  openActionInfo(element) {
-    this.dialog.open(AuditInfoDialogComponent, { data: {data: element.info, action: element.action}, panelClass: 'modal-xl-m' });
+  public openActionInfo(element: AuditItem): void {
+    if (element.type === 'GROUP' && element.info.indexOf('role') !== -1 || element.type === 'BUCKET') {
+      this.dialog.open(AuditInfoDialogComponent, { data: {element, dialogSize: 'big'}, panelClass: 'modal-xl-m' });
+    } else {
+      this.dialog.open(AuditInfoDialogComponent, { data: {element, dialogSize: 'small'}, panelClass: 'modal-md' });
+    }
   }
 
-  public setItemsPrPage(item: number) {
+  private setItemsPrPage(item: number): void {
     window.localStorage.setItem('audit_per_page', item.toString());
     this.firstItem = 1;
     if (this.lastItem !== item) {
@@ -115,7 +131,7 @@ export class AuditGridComponent implements OnInit {
     }
   }
 
-  private changePage(action) {
+  private changePage(action: string): void {
     if (action === 'first') {
       this.firstItem = 1;
       this.lastItem = this.showItemsPrPage;
@@ -134,17 +150,17 @@ export class AuditGridComponent implements OnInit {
     }
   }
 
-  public loadItemsForPage(action) {
+  public loadItemsForPage(action: string): void {
     this.changePage(action);
     this.buildAuditGrid();
   }
 
-  public resetFilterConfigurations() {
+  public resetFilterConfigurations(): void {
     this.filterAuditData = FilterAuditModel.getDefault();
     this.buildAuditGrid(true);
   }
 
-  public didFilterChanged() {
+  public didFilterChanged(): boolean {
     this.isNavigationDisabled = JSON.stringify(this.copiedFilterAuditData) !== JSON.stringify(this.filterAuditData);
     return this.isNavigationDisabled;
   }
@@ -156,35 +172,59 @@ export class AuditGridComponent implements OnInit {
   template: `
       <div id="dialog-box">
           <header class="dialog-header">
-              <h4 class="modal-title">{{data.action | convertaction}}</h4>
+              <h4 class="modal-title">{{data.element.action | convertaction}}</h4>
               <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
           </header>
           <div mat-dialog-content class="content audit-info-content" [ngClass]="{'pb-40': actionList[0].length > 1}">
-            <mat-list *ngIf="actionList[0].length > 1;else message">
-              <mat-list-item class="list-header">
-                <div class="info-item-title">Action</div>
-                <div class="info-item-data"> Description </div>
-              </mat-list-item>
-              <div class="scrolling-content mat-list-wrapper" id="scrolling">
-                <mat-list-item class="list-item" *ngFor="let action of actionList">
-                  <div *ngIf="(data.action === 'upload' && action[0] === 'File(s)') || (data.action === 'download' && action[0] === 'File(s)');else multiAction" class="info-item-title">File</div>
-                  <ng-template #multiAction>
-                     <div class="info-item-title">{{action[0]}}</div>
-                  </ng-template>
-                  <div class="info-item-data" *ngIf="action[0] === 'File(s)'">
-                    <div class="file-description ellipsis" *ngFor="let description of action[1]?.split(',')" [matTooltip]="description" matTooltipPosition="above">
-                      {{description}}
+            <mat-list *ngIf="actionList[0].length > 1 || data.element.info.indexOf('Update budget') !== -1;else message">
+              <ng-container *ngIf="data.element.info.indexOf('Update budget') === -1;else quotas">
+                <mat-list-item class="list-header">
+                  <div class="info-item-title" [ngClass]="{'same-column-width': data.dialogSize === 'small'}">Action</div>
+                  <div class="info-item-data" [ngClass]="{'same-column-width': data.dialogSize === 'small'}"> Description </div>
+                </mat-list-item>
+                <div class="scrolling-content mat-list-wrapper" id="scrolling">
+                  <mat-list-item class="list-item" *ngFor="let action of actionList">
+                    <div *ngIf="(data.element.action === 'upload' && action[0] === 'File(s)') || (data.element.action === 'download' && action[0] === 'File(s)');else multiAction" class="info-item-title">File</div>
+                    <ng-template #multiAction>
+                       <div class="info-item-title" [ngClass]="{'same-column-width': data.dialogSize === 'small'}">{{action[0]}}</div>
+                    </ng-template>
+                    <div class="info-item-data" [ngClass]="{'same-column-width': data.dialogSize === 'small'}" *ngIf="action[0] === 'File(s)'">
+                      <div class="file-description ellipsis" *ngFor="let description of action[1]?.split(',')" [matTooltip]="description" matTooltipPosition="above">
+                        {{description}}
+                      </div>
                     </div>
-                  </div>
-                  <div class="info-item-data" *ngIf="action[0] !== 'File(s)'">
-                     <div *ngFor="let description of action[1]?.split(',')">{{description}}</div>
-                  </div>
+                    <div class="info-item-data" [ngClass]="{'same-column-width': data.dialogSize === 'small'}" *ngIf="action[0] !== 'File(s)'">
+                       <div *ngFor="let description of action[1]?.split(',')">{{description}}</div>
+                    </div>
+                  </mat-list-item>
+                </div>
+              </ng-container>
+
+              <ng-template #quotas>
+                <mat-list-item class="list-header">
+                  <div class="same-column-width" >Action</div>
+                  <div class="info-item-quota-first" > Previous value </div>
+                  <div class="info-item-quota-last" > New value </div>
                 </mat-list-item>
-              </div>
+                <div class="scrolling-content mat-list-wrapper" id="scrolling">
+                  <mat-list-item class="list-item" *ngFor="let action of actionList">
+                    <div class="same-column-width">{{updateBudget[0]}}</div>
+                    <div class="info-item-quota-first">
+                      {{updateBudget[1]}}
+                    </div>
+                    <div class="info-item-quota-last">
+                      {{updateBudget[2]}}
+                    </div>
+                  </mat-list-item>
+                </div>
+              </ng-template>
             </mat-list>
             <ng-template #message>
               <div class="message-wrapper">
-                <p>{{data.data}}.</p>
+                <p *ngIf="data.element.type !== 'COMPUTATIONAL'; else computation">{{data.element.info}}.</p>
+                <ng-template #computation>
+                  <p > {{data.element.action | titlecase}} computational resource <span class="strong">{{data.element.resourceName}}</span>, requested for notebook <span class="strong">{{data.element.info.split(' ')[data.element.info.split(' ').length - 1] }}</span></p>
+                </ng-template>
               </div>
           </ng-template></div>
       </div>
@@ -203,23 +243,31 @@ export class AuditGridComponent implements OnInit {
     .mat-list-wrapper{padding-top: 5px;}
     .list-item{color: #718ba6; height: auto; line-height: 20px;}
     .info-item-title{width: 40%; padding: 10px 0}
+    .info-item-quota-first{width: 30%; padding: 10px 0}
+    .info-item-quota-last{width: 20%; padding: 10px 0}
     .list-header {padding-top: 5px;}
     .info-item-data{width: 60%; text-align: left; padding: 10px 0}
     .file-description{ overflow: hidden; display: block; direction: rtl;}
-
-
-
-
-
+    .same-column-width{width: 50%; padding: 10px 0}
   `]
 })
 export class AuditInfoDialogComponent {
-  actionList;
+  actionList: string[][];
+  updateBudget: string[] = [];
   constructor(
     public dialogRef: MatDialogRef<AuditInfoDialogComponent>,
     @Inject(MAT_DIALOG_DATA) public data: any
   ) {
-    this.actionList = data.data.split('\n').map(v => v.split(':')).filter(v => v[0] !== '');
+    if (data.element.info.indexOf('Update budget') !== -1) {
+      this.data.element.info.replace('->', ' ').split(' ').forEach((v, i, arr) => {
+        if (i === 1) {
+          this.updateBudget.push(`${arr[0]} ${arr[1]}`);
+        }
+        if (i > 1) {
+          this.updateBudget.push(arr[i]);
+        }
+      });
+    }
+    this.actionList = data.element.info.split('\n').map(v => v.split(':')).filter(v => v[0] !== '');
   }
-
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
index c61e91d..b026fb4 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
@@ -119,6 +119,6 @@ export class DetailComputationalResourcesComponent implements OnInit {
   }
 
   private logAction(name: any, description: string) {
-    this.auditService.sendDataToAudit({resource_name: name, info: `User followed ${description} link`}).subscribe();
+    this.auditService.sendDataToAudit({resource_name: name, info: `Follow ${description} link`}).subscribe();
   }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
index cceae69..0c9d4ad 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
@@ -161,6 +161,6 @@ export class DetailDialogComponent implements OnInit {
   }
 
   private logAction(name: any, description: string) {
-    this.auditService.sendDataToAudit({resource_name: name, info: `User followed ${description} link`}).subscribe();
+    this.auditService.sendDataToAudit({resource_name: name, info: `Follow ${description} link`}).subscribe();
   }
 }
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
index 1d43d8e..e0c7ed4 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
@@ -67,7 +67,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 public class LibExploratoryResourceTest extends TestBase {
-    private static final String AUDIT_MESSAGE = "Installed libs: %s";
+    private static final String AUDIT_MESSAGE = "Install libs: %s";
     private static final String LIB_GROUP = "group";
     private static final String LIB_NAME = "name";
     private static final String LIB_VERSION = "version";


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org