Commit c69fddda authored by MAGHOUZ's avatar MAGHOUZ
Browse files

Replacing agGrid with material table + Custom datasource

parent ebca46f5
......@@ -5348,6 +5348,11 @@
}
}
},
"emitter-component": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz",
"integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
......@@ -11961,6 +11966,11 @@
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
"dev": true
},
"preact": {
"version": "10.5.13",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.5.13.tgz",
"integrity": "sha512-q/vlKIGNwzTLu+jCcvywgGrt+H/1P/oIRSD6mV4ln3hmlC+Aa34C7yfPI4+5bzW8pONyVXYS7SvXosy2dKKtWQ=="
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
......@@ -12536,6 +12546,15 @@
}
}
},
"react": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
......@@ -14079,6 +14098,14 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"stream": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz",
"integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=",
"requires": {
"emitter-component": "^1.1.1"
}
},
"stream-browserify": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
......
......@@ -34,6 +34,7 @@ import {BrowserModule} from '@angular/platform-browser';
import {APOLLO_OPTIONS} from 'apollo-angular';
import {HttpLink} from 'apollo-angular/http';
import {InMemoryCache} from '@apollo/client/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
......@@ -54,7 +55,8 @@ import {InMemoryCache} from '@apollo/client/core';
MatButtonModule,
MatFormFieldModule,
MatInputModule,
MatTabsModule
MatTabsModule,
CommonModule,
],
declarations: [
AppComponent,
......
......@@ -21,14 +21,16 @@ import {MessageListComponent} from '../../messages/message-list.component';
import { AgGridModule } from 'ag-grid-angular';
import {Monitored_items_listComponent} from '../../monitored_items/monitored_items_list.component';
import {ActionsCellRenderer} from '../../monitored_items/actions-cell-renderer/actions-cell-renderer.component';
import {TicketsCellRenderer} from '../../monitored_items/tickets-cell-renderer/tickets-cell-renderer.component';
import {ElementCellRenderer} from '../../monitored_items/element-cell-renderer/element-cell-renderer.component';
import {Monitored_events_listComponent} from '../../monitored_events/monitored_events_list.component';
import {Monitored_Item_Details_Component} from '../../monitored_events/monitored_item_details/monitored_item_details.component';
import {NgxJsonViewerModule} from 'ngx-json-viewer';
import {MatListModule} from '@angular/material/list';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatTableModule} from '@angular/material/table';
import {MatSortModule} from '@angular/material/sort';
import {MatPaginatorModule} from '@angular/material/paginator';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
@NgModule({
imports: [
......@@ -45,7 +47,12 @@ import {MatSidenavModule} from '@angular/material/sidenav';
AgGridModule.withComponents([ActionsCellRenderer]),
NgxJsonViewerModule,
MatListModule,
MatSidenavModule
MatSidenavModule,
MatTableModule,
MatSortModule,
MatPaginatorModule,
MatCheckboxModule,
MatProgressSpinnerModule
],
declarations: [
DashboardComponent,
......@@ -60,9 +67,6 @@ import {MatSidenavModule} from '@angular/material/sidenav';
Monitored_items_listComponent,
Monitored_events_listComponent,
Monitored_Item_Details_Component,
ActionsCellRenderer,
TicketsCellRenderer,
ElementCellRenderer
]
})
......
<a [routerLink]="" (click)="goToLink(monitored_item_id)">
{{element}}&nbsp;&nbsp;
</a>
import { Component } from "@angular/core";
import {ICellRendererParams} from 'ag-grid-community';
import {AgRendererComponent} from 'ag-grid-angular';
import {Router} from '@angular/router';
@Component({
selector: 'element-cell-renderer',
templateUrl: './element-cell-renderer.component.html'
})
export class ElementCellRenderer implements AgRendererComponent {
private params: any;
element: string;
monitored_item_id: any;
constructor(private router: Router) { }
refresh(params: ICellRendererParams): boolean {
this.params = params;
return true;
}
agInit(params: ICellRendererParams): void {
this.params = params;
this.element = params.data.logicalPath;
this.monitored_item_id = params.data.id;
}
ngOnDestroy() {
// no need to remove the button click handler
// https://stackoverflow.com/questions/49083993/does-angular-automatically-remove-template-event-listeners
}
goToLink(url: any) {
this.router.navigate(['cops/monitored_item', url]);
}
}
\ No newline at end of file
export class MonitoredItem {
export interface MonitoredItem {
id: string;
type: string;
logicalPath: string;
......@@ -7,15 +7,4 @@ export class MonitoredItem {
creationDate: Date;
updateDate: Date;
tickets: Array<string>;
constructor(id, type, logicalPath, logicalGroup, statusFk, creationDate, updateDate, tickets) {
this.id = id;
this.type = type;
this.logicalPath = logicalPath;
this.logicalGroup = logicalGroup;
this.statusFk = statusFk;
this.creationDate = creationDate;
this.updateDate = updateDate;
this.tickets = tickets;
}
}
......@@ -10,11 +10,6 @@ import {Apollo, gql} from 'apollo-angular';
})
export class Monitored_itemsService {
// Observable string sources
private monitoredItemsSource = new Subject<MonitoredItem>();
// Observable string streams
monitoredItems$ = this.monitoredItemsSource.asObservable();
// Observable string sources
private updatedMonitoredItemsSource = new Subject<MonitoredItem>();
// Observable string streams
......@@ -29,13 +24,10 @@ export class Monitored_itemsService {
private monitoredItemDetailsSource = new Subject<MonitoredItem>();
// Observable string streams
monitoredItemDetails$ = this.monitoredItemDetailsSource.asObservable();
constructor(private http: HttpClient, private apollo: Apollo) { }
searchMessages(type: string) {
console.log("searchMessages")
this.apollo
searchMessages(type: string): Observable<any>{
return this.apollo
.query({
query: gql`
{
......@@ -53,13 +45,7 @@ export class Monitored_itemsService {
data
}
}`,
})
.subscribe((result: any) => {
for (var i = 0; i<this.result2MI(result?.data.allMonitoredItems).length; i++){
this.monitoredItemsSource.next(this.result2MI(result?.data.allMonitoredItems)[i])
}
})
;
});
}
/**
......@@ -84,26 +70,6 @@ export class Monitored_itemsService {
};
}
result2MI(monitoredItemsList: Array<any>): MonitoredItem[] {
let resultMonitoredItemsList: MonitoredItem[] = [];
for(let i = 0; i<monitoredItemsList.length; i++) {
let monitoredItem: MonitoredItem;
monitoredItem = new MonitoredItem(
monitoredItemsList[i].id,
monitoredItemsList[i].type,
monitoredItemsList[i].logicalPath,
monitoredItemsList[i].logicalGroup,
monitoredItemsList[i].statusFk,
monitoredItemsList[i].creationDate,
monitoredItemsList[i].updateDate,
monitoredItemsList[i].tickets,
);
resultMonitoredItemsList.push(monitoredItem);
};
return resultMonitoredItemsList;
}
addTicketsToMonitoredItem(monitoredItemId, tickets: string[]) {
const ADD_TICKETS_TO_MONITORED_ITEM_POST = gql`
mutation updateMonitoredItem($id: String!, $tickets: [String!]) {
......@@ -126,31 +92,18 @@ export class Monitored_itemsService {
}
`;
this.apollo.mutate({
return this.apollo.mutate({
mutation: ADD_TICKETS_TO_MONITORED_ITEM_POST,
variables: {
id: monitoredItemId,
tickets: tickets
}
}).subscribe(({ data }) => {
// @ts-ignore
let mi = data.updateMonitoredItem.monitoredItem
let monitoredItem: MonitoredItem;
monitoredItem = new MonitoredItem(
mi.id,
mi.type,
mi.logicalPath,
mi.logicalGroup,
mi.statusFk,
mi.creationDate,
mi.updateDate,
mi.tickets,
);
this.updatedMonitoredItemsSource.next(monitoredItem)
},(error) => {
console.log('there was an error sending the query', error);
});
}).pipe(
map(
(data: any)=>{
return data.updateMonitoredItem.monitoredItem as MonitoredItem;
}
));
}
deleteTicketsFromMonitoredItem(monitoredItemId, tickets: string[]) {
......@@ -184,19 +137,8 @@ export class Monitored_itemsService {
}).subscribe(({ data }) => {
// @ts-ignore
let mi = data.removeTicketsFromMonitoredItem.monitoredItem
let monitoredItem: MonitoredItem;
monitoredItem = new MonitoredItem(
mi.id,
mi.type,
mi.logicalPath,
mi.logicalGroup,
mi.statusFk,
mi.creationDate,
mi.updateDate,
mi.tickets,
);
this.deletedMonitoredItemsSource.next(monitoredItem)
this.deletedMonitoredItemsSource.next(mi as MonitoredItem)
},(error) => {
console.log('there was an error sending the query', error);
});
......@@ -228,20 +170,8 @@ export class Monitored_itemsService {
variables:{monitored_item_id:monitored_item_id},
})
.subscribe((result: any) => {
let mi = result?.data.monitoredItemById[0]
let monitoredItem: MonitoredItem;
monitoredItem = new MonitoredItem(
mi.id,
mi.type,
mi.logicalPath,
mi.logicalGroup,
mi.statusFk,
mi.creationDate,
mi.updateDate,
mi.tickets,
);
console.log("getMonitoredItemData result",monitoredItem)
this.monitoredItemDetailsSource.next(monitoredItem)
let mi = result?.data?.monitoredItemById[0]
this.monitoredItemDetailsSource.next(mi as MonitoredItem)
})
;
}
......
.slide-button {
margin: 10px;
}
/* Structure */
.example-container {
position: relative;
min-height: 200px;
}
.example-table-container {
position: relative;
overflow: auto;
}
table {
width: 100%;
}
.mat-table{
font-size: 13px;
font-family: "Roboto Light",serif;
}
td.mat-cell{
padding: 0 10px 0 10px;
}
th.mat-header-cell{
padding: 0 10px 0 10px;
}
.example-loading-shade {
position: absolute;
top: 0;
left: 0;
bottom: 56px;
right: 0;
background: rgba(0, 0, 0, 0.15);
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
}
.example-rate-limit-reached {
color: #980000;
max-width: 360px;
text-align: center;
}
/* Column Widths */
.mat-column-number,
.mat-column-state {
max-width: 64px;
}
.mat-column-created {
max-width: 124px;
}
.mat-column-tickets a{
background-color: #c178ce;
box-shadow: 0 2px 0 #550f61;
color: black;
padding: 2px 3px;
margin-right: 5px;
position: relative;
text-decoration: none;
text-transform: uppercase;
border-radius: 50%;
}
.mat-column-tickets a:hover{
background-color: #9c28b0;
}
.mat-column-tickets a:active{
box-shadow: none;
top: 5px;
}
.mat-column-logicalPath{
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
}
\ No newline at end of file
......@@ -14,28 +14,132 @@
</span>
</button>
</div>
<ag-grid-angular
#agGrid
class="ag-theme-material"
domLayout='autoHeight'
rowHeight="40"
headerHeight="50"
[rowData]="rowData"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[suppressRowClickSelection]="true"
rowSelection="multiple"
enableRangeSelection="true"
rowMultiSelectWithClick="true"
(firstDataRendered)="onFirstDataRendered($event)"
(gridReady)="onGridReady($event)"
[frameworkComponents]="frameworkComponents"
(cellClicked)="onCellClicked($event)"
[gridOptions]="gridOptions"
[isRowSelectable]="isRowSelectable"
></ag-grid-angular>
</div>
<div class="example-container mat-elevation-z8">
<div class="spinner-container" *ngIf="dataSource.loading$ | async">
<mat-spinner></mat-spinner>
</div>
<div class="example-table-container">
<table mat-table [dataSource]=dataSource class="example-table" matSort
matSortActive="updateDate" matSortDisableClear matSortDirection="desc">
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()"
[aria-label]="checkboxLabel()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<div *ngIf="row.type == 'processrunner' && row.statusFk == 'ERROR'">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="toggleMonitoredItem($event, row)"
[checked]="selection.isSelected(row)"
[aria-label]="checkboxLabel(row)">
</mat-checkbox>
</div>
</td>
</ng-container>
<!-- Number Column -->
<ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef>Creation date</th>
<td mat-cell *matCellDef="let row">{{row.creationDate}}</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="logicalPath">
<th mat-header-cell *matHeaderCellDef>Element</th>
<td mat-cell *matCellDef="let row">
<a [routerLink]="" (click)="goToMonitoredItemDetails(row.id)">
{{row.logicalPath}}&nbsp;&nbsp;
</a>
</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef>Type</th>
<td mat-cell *matCellDef="let row">{{row.type}}</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="groupPath">
<th mat-header-cell *matHeaderCellDef>Group</th>
<td mat-cell *matCellDef="let row">{{row.logicalGroup}}</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="tickets">
<th mat-header-cell *matHeaderCellDef>Tickets</th>
<td mat-cell *matCellDef="let row">
<a class="tickets" *ngFor="let ticket of row.tickets" [routerLink]="" (click)="goToLink(ticket)" [class.ticket_link]=true>
{{ticket.split("/").pop()}}
</a>&nbsp;&nbsp;
</td>
</ng-container>
<!-- State Column -->
<ng-container matColumnDef="statusFk">
<th mat-header-cell *matHeaderCellDef>State</th>
<td mat-cell *matCellDef="let row">{{row.statusFk}}</td>
</ng-container>
<!-- Created Column -->
<ng-container matColumnDef="updateDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
Update date
</th>
<td mat-cell *matCellDef="let row">{{row.updateDate | 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;"></tr>
</table>
</div>
<!-- <mat-paginator [length]="resultsLength" [pageSize]="30"></mat-paginator>-->
</div>
</div>
</div>
<!-- <div class="row">-->
<!-- <div class="col-md-12">-->
<!-- <div class="slide-button">-->
<!-- <button-->
<!-- mat-raised-button-->
<!-- class="btn btn-primary"-->
<!-- matTooltip="Unlock selected files"-->
<!-- [style.visibility]="visibility_unlock_button"-->
<!-- >-->
<!-- <span class="material-icons">-->
<!-- lock_open-->
<!-- </span>-->
<!-- </button>-->
<!-- </div>-->
<!-- <ag-grid-angular-->
<!-- #agGrid-->
<!-- class="ag-theme-material"-->
<!-- domLayout='autoHeight'-->
<!-- rowHeight="40"-->
<!-- headerHeight="50"-->
<!-- [rowData]="rowData$ | async | transformToMi"-->
<!-- [columnDefs]="columnDefs"-->
<!-- [defaultColDef]="defaultColDef"-->
<!-- [suppressRowClickSelection]="true"-->
<!-- rowSelection="multiple"-->
<!-- enableRangeSelection="true"-->
<!-- rowMultiSelectWithClick="true"-->
<!-- (firstDataRendered)="onFirstDataRendered($event)"-->
<!-- (gridReady)="onGridReady($event)"-->
<!-- [frameworkComponents]="frameworkComponents"-->
<!-- (cellClicked)="onCellClicked($event)"-->
<!-- [gridOptions]="gridOptions"-->
<!-- [isRowSelectable]="isRowSelectable"-->
<!-- ></ag-grid-angular>-->
<!-- </div>-->
<!-- </div>-->
</div>
</div>
import {Component, OnInit, ViewChild} from '@angular/core';
import {AgGridAngular} from 'ag-grid-angular';
import { Monitored_itemsService } from './monitored_items.service';
import {Monitored_itemsService } from './monitored_items.service';
import {MonitoredItem} from './monitored_item.model';
import {ActionsCellRenderer} from './actions-cell-renderer/actions-cell-renderer.component';
import {TicketsCellRenderer} from './tickets-cell-renderer/tickets-cell-renderer.component';
import {MatDialog} from '@angular/material/dialog';
import {Subscription} from 'rxjs/Subscription';
import {Router} from '@angular/router';
import {ElementCellRenderer} from './element-cell-renderer/element-cell-renderer.component';
import {shareReplay} from 'rxjs/operators';
import {Observable} from 'rxjs';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {HttpClient} from '@angular/common/http';
import {SelectionModel} from '@angular/cdk/collections';