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()">×</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