Commit 5be39628 authored by MAGHOUZ's avatar MAGHOUZ
Browse files

Events page works with with material table + usage of ws version 14/04/2021

parent 5ecaa158
......@@ -4,7 +4,7 @@
<div class="sidebar-background" style="background-image: url(./assets/img/sidebar-4.jpg)"></div>
</div>-->
<div class="main-panel">
<app-navbar></app-navbar>
<!-- <app-navbar></app-navbar>-->
<router-outlet></router-outlet>
<div *ngIf="isMaps('maps')">
<app-footer></app-footer>
......
import {CollectionViewer, DataSource} from '@angular/cdk/collections';
import {MonitoredEvent} from './monitored_event.model';
import {BehaviorSubject, Observable, of} from 'rxjs'
import {Monitored_eventsService} from './monitored_events.service';
import {catchError, finalize} from 'rxjs/operators';
export class MonitoredEventsDataSource implements DataSource<MonitoredEvent> {
private monitoredEventsSubject = new BehaviorSubject<MonitoredEvent[]>([]);
private loadingSubject = new BehaviorSubject<boolean>(false);
public loading$ = this.loadingSubject.asObservable();
public displayedData : any[] = [];
public totalCount : number = 0;
public startCursor : string;
public endCursor : string;
public firstDisplayedRow : any
constructor(private monitoredEventsService: Monitored_eventsService) {}
connect(collectionViewer: CollectionViewer): Observable<MonitoredEvent[] | ReadonlyArray<MonitoredEvent>> {
return this.monitoredEventsSubject;
}
disconnect(collectionViewer: CollectionViewer): void {
this.monitoredEventsSubject.complete()
this.loadingSubject.complete();
}
loadEvents(monitored_item_id: string = "", sort: string = "", pageSize: number = 10, after: string = null, before: string = null) {
this.loadingSubject.next(true);
this.monitoredEventsService.searchEvents(monitored_item_id, sort, pageSize, after, before).pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
).subscribe(monitoredEvents => {
this.monitoredEventsSubject.next(monitoredEvents.data.events.edges);
this.displayedData = monitoredEvents.data.events.edges
this.totalCount = monitoredEvents.data.events.totalCount
this.startCursor = monitoredEvents.data.events.pageInfo.startCursor
this.endCursor = monitoredEvents.data.events.pageInfo.endCursor
this.firstDisplayedRow = monitoredEvents.data.events.edges[0]
});
}
}
import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable, of, Subject} from 'rxjs';
import {catchError, map} from 'rxjs/operators';
import {MonitoredEvent} from './monitored_event.model';
import {Observable} from 'rxjs';
import {Apollo, gql} from 'apollo-angular';
import {MonitoredItem} from '../monitored_items/monitored_item.model';
@Injectable({
providedIn: 'root'
})
export class Monitored_eventsService {
// Observable string sources
private monitoredEventsSource = new Subject<MonitoredEvent>();
// Observable string streams
monitoredEvents$ = this.monitoredEventsSource.asObservable();
constructor(private apollo: Apollo) { }
searchEvents(monitored_item_id) {
this.apollo
.query({
query: gql`
query eventsByMonitoredItemId($monitored_item_id: String!)
{
eventsByMonitoredItemId(q: $monitored_item_id){
edges {
node {
id
creationDate
eventDate
levelFk
subject
message
monitoredItemFk
}
}
}
}
`,
variables:{monitored_item_id:monitored_item_id},
})
.subscribe((result: any) => {
for (var i = 0; i<this.result2ME(result?.data.eventsByMonitoredItemId.edges).length; i++){
this.monitoredEventsSource.next(this.result2ME(result?.data.eventsByMonitoredItemId.edges)[i])
}
})
;
}
result2ME(monitoredEventsList: Array<any>): MonitoredEvent[] {
let resultMonitoredEventsList: MonitoredEvent[] = [];
for(let i = 0; i<monitoredEventsList.length; i++) {
let monitoredEvent: MonitoredEvent;
monitoredEvent = new MonitoredEvent(
monitoredEventsList[i].node.id,
monitoredEventsList[i].node.creationDate,
monitoredEventsList[i].node.eventDate,
monitoredEventsList[i].node.levelFk,
monitoredEventsList[i].node.subject,
monitoredEventsList[i].node.message,
monitoredEventsList[i].node.monitoredItemFk,
);
resultMonitoredEventsList.push(monitoredEvent);
};
return resultMonitoredEventsList;
searchEvents(monitored_item_id: string, sort: string, pageSize: number, after: string = null, before: string): Observable<any>{
let pageCursorString = ""
if(after !== null){
pageCursorString = "first: $pageSize, after:\""+ after +"\""
}
else if(before !== null){
pageCursorString = "last: $pageSize, before:\"" + before + "\""
}
else{
pageCursorString = "first: $pageSize"
}
const SELECT_EVENTS_BY_MONITORED_ITEM_ID = "" +
"query eventsByMonitoredItemId($monitored_item_id: String!, $pageSize: Int!)"+
"{"+
" events(filters: {monitoredItemFk: $monitored_item_id}, sort: ["+ sort +"], "+ pageCursorString +"){"+
" pageInfo {"+
" startCursor"+
" endCursor"+
" hasNextPage"+
" hasPreviousPage"+
" }"+
" totalCount"+
" edgeCount"+
" edges {"+
" cursor"+
" node {"+
" id"+
" eventDate"+
" levelFk"+
" subject"+
" message"+
" }"+
" }"+
" }"+
"}";
return this.apollo.query({
query: gql(SELECT_EVENTS_BY_MONITORED_ITEM_ID),
variables: {
monitored_item_id:monitored_item_id,
pageSize:pageSize
},
errorPolicy: 'all'
});
}
}
......@@ -7,6 +7,7 @@ mat-drawer-content {
display: flex;
flex-direction: column;
align-items: flex-start;
height: calc(100vh - 123px);
}
.drawer-container {
......@@ -22,11 +23,25 @@ mat-drawer-content {
border: none;
}
td.mat-cell{
padding: 0 10px 0 10px;
}
th.mat-header-cell{
padding: 0 10px 0 10px;
}
.slide-button {
width: 100%;
text-align: end;
}
.events {
max-height: 33vh;
overflow: auto;
max-height: 41vh;
min-height: 33vh;
}
table {
width: 100%;
}
\ No newline at end of file
......@@ -14,33 +14,58 @@
</button>
</div>
<!-- List of events -->
<div class="card">
<div class="card events">
<div class="card-body">
<ag-grid-angular style="height: 40vh;"
#agGrid
class="ag-theme-material"
domLayout='normal'
rowHeight="40"
headerHeight="50"
[rowData]="rowData"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[rowSelection]="rowSelection"
(firstDataRendered)="onFirstDataRendered($event)"
(gridReady)="onGridReady($event)"
[getRowNodeId]="getRowNodeId"
(selectionChanged)="onSelectionChanged($event)"
></ag-grid-angular>
<div class="spinner-container" *ngIf="dataSource.loading$ | async">
<mat-spinner></mat-spinner>
</div>
<!-- ['select','EVENT_DATE','LEVEL_FK','SUBJECT'];-->
<div class="example-table-container">
<table mat-table [dataSource]="dataSource" class="example-table" matSort
matSortActive="EVENT_DATE" matSortDirection="desc" matSortDisableClear="true">
<!-- Group Column -->
<ng-container matColumnDef="SUBJECT">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Subject</th>
<td mat-cell *matCellDef="let row">{{row.node.subject}}</td>
</ng-container>
<!-- Level Column -->
<ng-container matColumnDef="LEVEL_FK">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Level</th>
<td mat-cell *matCellDef="let row">{{row.node.levelFk}}</td>
</ng-container>
<!-- Event date Column -->
<ng-container matColumnDef="EVENT_DATE" start="desc">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
Event date
</th>
<td mat-cell *matCellDef="let row">
{{row.node.eventDate | date:"yyyy-MM-ddTHH:mm:ss.SSSSSS"}}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"
[style.background]="row.node.id==selectedId?'#eee':'inherit'"
(click)="$event.stopPropagation();toggleEvent(row.node);"
></tr>
</table>
</div>
<mat-paginator [length]="dataSource.totalCount" [pageSize]="page_size" ></mat-paginator>
</div>
</div>
<!-- Message -->
<div class="card">
<div class="card-header card-header-primary">
<h4 class="card-title">Message: </h4>
<h4 class="card-title" *ngIf="selectedEventSubject">Message: </h4>
<h4 style="text-align: center" class="card-title" *ngIf="!selectedEventSubject">Select an event from the table above for more information</h4>
<p class="card-category">{{selectedEventSubject}}</p>
<!-- <p class="card-category">sub title</p>-->
</div>
<div class="card-body">
<div class="card-body" *ngIf="selectedEventMessage">
<ngx-json-viewer [json]="selectedEventMessage"></ngx-json-viewer>
</div>
</div>
......
import {Component, OnInit, ViewChild} from '@angular/core';
import {AgGridAngular} from 'ag-grid-angular';
import {Monitored_eventsService} from './monitored_events.service';
import {MonitoredEvent} from './monitored_event.model';
import {MatDialog} from '@angular/material/dialog';
import {Subscription} from 'rxjs/Subscription';
import {ActivatedRoute, Router} from '@angular/router';
import {MonitoredItem} from '../monitored_items/monitored_item.model';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {SelectionModel} from '@angular/cdk/collections';
import {MonitoredEventsDataSource} from './monitored-events-data-source';
import {merge} from 'rxjs';
import {tap} from 'rxjs/operators';
@Component({
selector: 'monitored-events-list',
......@@ -15,63 +16,26 @@ import {MonitoredItem} from '../monitored_items/monitored_item.model';
providers: [Monitored_eventsService]
})
export class Monitored_events_listComponent implements OnInit {
@ViewChild('agGrid') agGrid: AgGridAngular;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
public monitored_eventsService: Monitored_eventsService;
private gridApi;
private gridColumnApi;
columnDefs = [
{
field: 'eventDate',
headerName: 'Event date',
sortable: true,
filter: 'agDateColumnFilter',
maxWidth: 200,
sort: 'desc'
},
{
field: 'levelFk',
headerName: 'Level',
sortable: true,
filter: 'agTextColumnFilter',
maxWidth: 200
},
{
field: 'subject',
headerName: 'Subject',
sortable: true,
filter: 'agTextColumnFilter',
},
];
defaultColDef = {
flex: 1,
minWidth: 250,
sortable: true,
filter: true,
resizable: true
};
rowData: MonitoredEvent[] = [];
rowSelection='single'
messageType = '1';
public sort_gql : string = "EVENT_DATE_DESC";
public page_size : number = 10;
private pageIndex : number = 0;
selectedRows: string[];
getRowNodeId = function(data) {
return data.id;
};
selectAllSubscription: Subscription;
MonitoredItemSubscription: Subscription;
dataSource: MonitoredEventsDataSource;
displayedColumns: string[] = ['EVENT_DATE','LEVEL_FK','SUBJECT'];
selection = new SelectionModel<MonitoredEvent>(false, []);
sub: any;
mi_id: string
private selectedEventMessage: any;
private selectedEventSubject: any;
selectedId:string
constructor(private route: ActivatedRoute, public monitoredeventsService: Monitored_eventsService,public dialog: MatDialog) {
constructor(private route: ActivatedRoute, public monitoredeventsService: Monitored_eventsService) {
this.monitored_eventsService = monitoredeventsService;
}
......@@ -79,48 +43,64 @@ export class Monitored_events_listComponent implements OnInit {
this.sub = this.route.params.subscribe(params => {
this.mi_id = params.monitored_item_id;
});
this.selectAllSubscription = this.monitored_eventsService.monitoredEvents$.subscribe(
monitored_event => {
console.log(monitored_event)
this.rowData.push(monitored_event)
//this.gridApi.applyTransactionAsync({ add: [monitored_event] })
}
);
this.monitored_eventsService.searchEvents(this.mi_id);
}
onFirstDataRendered(params) {
this.gridColumnApi.sizeColumnsToFit();
this.gridApi.getDisplayedRowAtIndex(0).setSelected(true);
this.dataSource = new MonitoredEventsDataSource(this.monitored_eventsService);
this.dataSource.loadEvents(this.mi_id, this.sort_gql,this.page_size);
}
onGridReady(params) {
console.log("onGridReady")
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.sizeToFit()
//this.autoSizeAll(true)
}
ngAfterViewInit() {
this.sort.sortChange.subscribe(() => {
this.paginator.pageIndex = 0;
this.sort_gql = this.sort.active+'_'+this.sort.direction.toUpperCase()
});
onSelectionChanged($event: any) {
var selectedRows = this.gridApi.getSelectedRows();
this.selectedEventMessage = selectedRows.length === 1 ? JSON.parse(selectedRows[0].message) : '';
this.selectedEventSubject = selectedRows.length === 1 ? selectedRows[0].subject : '';
merge(this.sort.sortChange, this.paginator.page)
.pipe(
tap(() => this.loadEventsPage())
)
.subscribe();
}
autoSizeAll(skipHeader) {
var allColumnIds = [];
this.gridColumnApi.getAllColumns().forEach(function (column) {
allColumnIds.push(column.colId);
});
this.gridColumnApi.autoSizeColumns(allColumnIds, skipHeader);
loadEventsPage() {
if(this.paginator.pageIndex == 0){
this.dataSource.loadEvents(
this.mi_id,
this.sort_gql,
this.paginator.pageSize,
);
}
else if(this.paginator.pageIndex > this.pageIndex){
this.dataSource.loadEvents(
this.mi_id,
this.sort_gql,
this.paginator.pageSize,
this.dataSource.endCursor
);
}
else{
this.dataSource.loadEvents(
this.mi_id,
this.sort_gql,
this.paginator.pageSize,
null,
this.dataSource.startCursor
);
}
this.pageIndex = this.paginator.pageIndex
}
sizeToFit() {
this.gridApi.sizeColumnsToFit();
/** The label for the checkbox on the passed row */
checkboxLabel(row?: MonitoredEvent): string {
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.id + 1}`;
}
ngOnDestroy() {
this.selectAllSubscription.unsubscribe();
toggleEvent(row) {
if(this.selection.selected[0]?.id !== row.id)
this.selectedId = row.id
else
this.selectedId = ""
this.selection.toggle(row)
var selectedRows = this.selection.selected;
this.selectedEventMessage = selectedRows.length === 1 ? JSON.parse(selectedRows[0].message) : '';
this.selectedEventSubject = selectedRows.length === 1 ? selectedRows[0].subject : '';
}
}
......@@ -5,7 +5,7 @@
</div>
<!-- <div *ngIf="monitored_item != undefined">-->
<div class="card-body">
<mat-list>
<mat-list *ngIf="monitored_item">
<mat-list-item>Monitored item:</mat-list-item>
<mat-list-item> {{monitored_item.logicalPath}}</mat-list-item>
<mat-divider></mat-divider>
......
......@@ -26,7 +26,6 @@ export class Monitored_Item_Details_Component implements OnInit {
ngOnInit(): void {
this.monitoredItemDetailsSubscription = this.monitored_itemService.monitoredItemDetails$.subscribe(
monitored_item => {
console.log(monitored_item)
this.monitored_item = monitored_item
}
);
......
......@@ -37,11 +37,11 @@ export class MonitoredItemsDataSource implements DataSource<MonitoredItem> {
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
).subscribe(monitoredItems => {
this.monitoredItemsSubject.next(monitoredItems.data.allMonitoredItems.edges);
this.displayedData = monitoredItems.data.allMonitoredItems.edges
this.totalCount = monitoredItems.data.allMonitoredItems.totalCount
this.startCursor = monitoredItems.data.allMonitoredItems.pageInfo.startCursor
this.endCursor = monitoredItems.data.allMonitoredItems.pageInfo.endCursor
this.monitoredItemsSubject.next(monitoredItems.data.monitoredItems.edges);
this.displayedData = monitoredItems.data.monitoredItems.edges
this.totalCount = monitoredItems.data.monitoredItems.totalCount
this.startCursor = monitoredItems.data.monitoredItems.pageInfo.startCursor
this.endCursor = monitoredItems.data.monitoredItems.pageInfo.endCursor
});
}
......
import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable, of, Subject} from 'rxjs';
import {catchError, map} from 'rxjs/operators';
import {Observable, Subject} from 'rxjs';
import {MonitoredItem} from './monitored_item.model';
import {Apollo, gql} from 'apollo-angular';
......@@ -16,7 +14,7 @@ export class Monitored_itemsService {
monitoredItemDetails$ = this.monitoredItemDetailsSource.asObservable();
constructor(private apollo: Apollo) { }
searchMessages(sort: string, pageSize: number, after: string = null, before: string): Observable<any>{//sort: string[], pageSize: number, startCursor: string = null
searchMessages(sort: string, pageSize: number, after: string = null, before: string): Observable<any>{
let pageCursorString = ""
if(after !== null){
pageCursorString = "first: $pageSize, after:\""+ after +"\""
......@@ -29,7 +27,7 @@ export class Monitored_itemsService {
}
const SELECT_ALL_MONITORED_ITEMS = "" +
"query allMonitoredItems($pageSize: Int!){" +
"allMonitoredItems(sort: ["+ sort +"], "+ pageCursorString +") {" +
"monitoredItems(sort: ["+ sort +"], "+ pageCursorString +") {" +
"pageInfo {" +
"startCursor endCursor hasNextPage hasPreviousPage" +
"} " +
......@@ -53,7 +51,6 @@ export class Monitored_itemsService {
}
addTicketsToMonitoredItem(monitoredItemId, tickets: string[]) {
console.log("addTicketsToMonitoredItem",monitoredItemId,tickets)
const ADD_TICKETS_TO_MONITORED_ITEM_POST = gql`
mutation updateMonitoredItem($id: String!, $tickets: [String!]) {
updateMonitoredItem (id: $id, tickets: $tickets)
......@@ -97,7 +94,6 @@ export class Monitored_itemsService {
}
}
`;
console.log("deleteTicketsFromMonitoredItem",monitoredItemId,tickets)
return this.apollo.mutate({
mutation: DELETE_TICKETS_FROM_MONITORED_ITEM_POST,
variables: {
......@@ -109,13 +105,12 @@ export class Monitored_itemsService {
getMonitoredItemData(monitored_item_id) {
console.log("getMonitoredItemData",monitored_item_id)
this.apollo
.query({
query: gql`
query monitoredItemById($monitored_item_id: String!)
{
monitoredItemById(q: $monitored_item_id){
monitoredItems(filters: {id: $monitored_item_id}){
edges {
node {
id
......@@ -137,8 +132,7 @@ export class Monitored_itemsService {
variables:{monitored_item_id:monitored_item_id},
})
.subscribe((result: any) => {
console.log(result)
let mi = result?.data?.monitoredItemById.edges[0].node
let mi = result?.data?.monitoredItems.edges[0].node
this.monitoredItemDetailsSource.next(mi as MonitoredItem)
})
;
......