Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# UTMStack 10.9.0 Release Notes
# UTMStack 10.9.1 Release Notes

- Added New Suricata Integration.
-- Dashboard Rendering with Time Filters
Resolved performance issues affecting dashboard responsiveness when applying time-based filters.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<div class="container-fluid dashboard-container pr-3 pl-3 pt-2">
<div class="container-fluid dashboard-container px-1 pt-2">
<div *ngIf="!pdfExport" class="d-flex justify-content-between align-items-center mb-2">
<h5 class="card-title label-header mb-0 text-uppercase label-header">Overview</h5>
<div class="header-elements d-flex justify-content-end align-items-center">
<app-refresh-filter></app-refresh-filter>
<app-elastic-filter-time [invertContent]="true"
[isEmitter]="true"
container="body"></app-elastic-filter-time>
Expand All @@ -20,14 +21,10 @@ <h5 class="card-title label-header mb-0 text-uppercase label-header">Overview</h
</div>
<div class="row">
<div class="col-lg-4 col-md-12 col-sm-12">
<app-chart-alert-daily-week [refreshInterval]="refreshInterval"
(loaded)="onRun()">
</app-chart-alert-daily-week>
<app-chart-alert-daily-week (loaded)="onRun()"></app-chart-alert-daily-week>
</div>
<div class="col-lg-8 col-md-12 col-sm-12">
<app-chart-alert-by-status [refreshInterval]="refreshInterval"
(loaded)="onRun()">
</app-chart-alert-by-status>
<app-chart-alert-by-status (loaded)="onRun()"></app-chart-alert-by-status>
</div>
</div>

Expand All @@ -39,8 +36,8 @@ <h5 class="card-title label-header mb-0 text-uppercase label-header">Overview</h
[navigateUrl]="ALERT_ROUTE"
[paramClick]="paramAlertSeverityCLick"
[params]="paramsAlertSeverity"
(loaded)="onRun()"
[refreshInterval]="refreshInterval">
[type]="RefreshType.CHART_COMMON_PIE_SEVERITY"
(loaded)="onRun()">
</app-chart-common-pie>
</div>
<div class="col-lg-5 col-md-12 col-sm-12">
Expand All @@ -54,8 +51,8 @@ <h5 class="card-title label-header mb-0 text-uppercase label-header">Overview</h
[navigateUrl]="ALERT_ROUTE"
[paramClick]="tableTopAlertsParamsClick"
[params]="tableTopAlertsParams"
(loaded)="onRun()"
[refreshInterval]="refreshInterval">
[type]="RefreshType.CHART_COMMON_TABLE_TOP_ALERT"
(loaded)="onRun()">
</app-chart-common-table>
</div>
</div>
Expand All @@ -74,10 +71,10 @@ <h5 class="card-title label-header mb-0 text-uppercase label-header">Overview</h
[paramClick]="paramEventByTypeCLick"
[params]="paramsEventByType"
(loaded)="onRun()"
[refreshInterval]="refreshInterval"></app-chart-common-pie>
[type]="RefreshType.CHART_COMMON_PIE_EVENT"></app-chart-common-pie>
</div>
<div class="col-lg-5 col-md-12 col-sm-12">
<app-chart-event-in-time [refreshInterval]="refreshInterval"
<app-chart-event-in-time [type]="RefreshType.CHART_EVENT_IN_TIME"
(loaded)="onRun()"></app-chart-event-in-time>
</div>
<div class="col-lg-4 col-md-12 col-sm-12">
Expand All @@ -86,8 +83,8 @@ <h5 class="card-title label-header mb-0 text-uppercase label-header">Overview</h
[navigateUrl]="LOG_ANALYZER_ROUTE"
[paramClick]="paramEvenTopCLick"
[params]="paramsTopEvent"
(loaded)="onRun()"
[refreshInterval]="refreshInterval">
[type]="RefreshType.CHART_COMMON_TABLE_TOP_EVENT"
(loaded)="onRun()">
</app-chart-common-table>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {OverviewAlertDashboardService} from '../../shared/services/charts-overvi
import {IndexPatternService} from '../../shared/services/elasticsearch/index-pattern.service';
import {LocalFieldService} from '../../shared/services/elasticsearch/local-field.service';
import {ExportPdfService} from '../../shared/services/util/export-pdf.service';
import {RefreshService, RefreshType} from '../../shared/services/util/refresh.service';
import {ChartSerieValueType} from '../../shared/types/chart-reponse/chart-serie-value.type';
import {ElasticFilterType} from '../../shared/types/filter/elastic-filter.type';
import {UtmIndexPatternFields} from '../../shared/types/index-pattern/utm-index-pattern-fields';
Expand Down Expand Up @@ -66,9 +67,6 @@ export class DashboardOverviewComponent implements OnInit, OnDestroy {
indexPattern: IndexPatternSystemEnumName.LOG
};
paramEvenTopCLick = 'logx.wineventlog.event_name.keyword';

adActive: boolean;
vulActive: boolean;
alertSeverityColorMap: { value: string, color: string }[] = [
{color: '#42A5F5', value: LOW_TEXT},
{color: '#FF9800', value: MEDIUM_TEXT},
Expand All @@ -81,6 +79,8 @@ export class DashboardOverviewComponent implements OnInit, OnDestroy {
runList = 0;
visualizationRender = 8;
preparingPrint = true;
RefreshType = RefreshType;
timeOutId: any;


constructor(private overviewAlertDashboardService: OverviewAlertDashboardService,
Expand All @@ -92,7 +92,8 @@ export class DashboardOverviewComponent implements OnInit, OnDestroy {
private exportPdfService: ExportPdfService,
private activatedRoute: ActivatedRoute,
private timeFilterBehavior: TimeFilterBehavior,
private utmToastService: UtmToastService) {
private utmToastService: UtmToastService,
private refreshService: RefreshService) {
}

ngOnInit() {
Expand Down Expand Up @@ -129,7 +130,7 @@ export class DashboardOverviewComponent implements OnInit, OnDestroy {
// }
// });

setTimeout(() => {
this.timeOutId = setTimeout(() => {
this.synchronizeFields();
}, 100000);

Expand Down Expand Up @@ -266,6 +267,7 @@ export class DashboardOverviewComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
this.refreshService.stopInterval();
clearTimeout(this.timeOutId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ <h5 class="card-title mb-0 label-header">{{dashboard.name}}
</h5>
<div class="header-elements d-flex justify-content-end align-items-center">
<app-dashboard-filter-view [filters]="filters"></app-dashboard-filter-view>
<app-refresh-filter></app-refresh-filter>
<app-elastic-filter-time [invertContent]="true"
[isEmitter]="true"
class="ml-3"
container="body"></app-elastic-filter-time>
<button (click)="exportToPdf()" [disabled]="pdfExport || !visualizationRender || loadingVisualizations"
<button (click)="exportToPdf()" [disabled]="pdfExport || loadingVisualizations"
class="btn utm-button utm-button-primary ml-2">
<i [ngClass]="pdfExport?'icon-download10':'icon-file-pdf'" class="mr-1"></i>
{{pdfExport ? 'Generating...' : 'Save to PDF'}}
Expand All @@ -17,21 +17,20 @@ <h5 class="card-title mb-0 label-header">{{dashboard.name}}
</div>
</div>
<div class="w-100 h-100 mb-3">
<gridster *ngIf="layout.length>0 && !loadingVisualizations"
[options]="options" style="background-color: #f1f1f1;z-index: 0; margin-bottom: 15px">
<gridster [options]="options" style="background-color: #f1f1f1;z-index: 0; margin-bottom: 15px">
<gridster-item #gridsterItem
*ngFor="let item of layout; let index = index" [item]="item.grid"
*ngFor="let item of layout$ | async; trackBy: trackByFn; let index = index" [item]="item.grid"
(mouseenter)="activeTimeGridster=item.visualization.id"
[ngStyle]="{'z-index':(activeTimeGridster===item.visualization.id?100:0)+''}">
<app-utm-viewer [building]="false"
style="z-index: 10"
[chart]="item.visualization.chartType"
[chartId]="item.visualization.id"
[height]="(gridsterItem.height-38)+'px'"
[showTime]="timeEnable.includes(item.visualization.id)"
[visualization]="item.visualization"
[width]="gridsterItem.width+'px'">
</app-utm-viewer>
<app-utm-viewer [building]="false"
style="z-index: 10"
[chart]="item.visualization.chartType"
[chartId]="item.visualization.id"
[height]="(gridsterItem.height-38)+'px'"
[showTime]="item.visualization.showTime"
[visualization]="item.visualization"
[width]="gridsterItem.width+'px'">
</app-utm-viewer>
</gridster-item>
</gridster>
<div style="height: 15px"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {CompactType, GridsterConfig, GridsterItem, GridType} from 'angular-gridster2';
import {UUID} from 'angular2-uuid';
import {NgxSpinnerService} from 'ngx-spinner';
import {Observable} from 'rxjs';
import {map, tap} from 'rxjs/operators';
import {IComponent} from '../../graphic-builder/dashboard-builder/shared/services/layout.service';
import {rebuildVisualizationFilterTime} from '../../graphic-builder/shared/util/chart-filter/chart-filter.util';
import {DashboardBehavior} from '../../shared/behaviors/dashboard.behavior';
Expand All @@ -11,20 +13,20 @@ import {UtmDashboardVisualizationType} from '../../shared/chart/types/dashboard/
import {UtmDashboardType} from '../../shared/chart/types/dashboard/utm-dashboard.type';
import {VisualizationType} from '../../shared/chart/types/visualization.type';
import {ChartTypeEnum} from '../../shared/enums/chart-type.enum';
import {ExportPdfService} from '../../shared/services/util/export-pdf.service';
import {RefreshService} from '../../shared/services/util/refresh.service';
import {DashboardFilterType} from '../../shared/types/filter/dashboard-filter.type';
import {ElasticFilterType} from '../../shared/types/filter/elastic-filter.type';
import {mergeParams, sanitizeFilters} from '../../shared/util/elastic-filter.util';
import {filtersToStringParam} from '../../shared/util/query-params-to-filter.util';
import {normalizeString} from '../../shared/util/string-util';
import {RenderLayoutService} from '../shared/services/render-layout.service';
import {UtmRenderVisualization} from '../shared/services/utm-render-visualization.service';
import {ExportPdfService} from "../../shared/services/util/export-pdf.service";
import {NgxSpinnerService} from "ngx-spinner";

@Component({
selector: 'app-dashboard-render',
templateUrl: './dashboard-render.component.html',
styleUrls: ['./dashboard-render.component.scss']
styleUrls: ['./dashboard-render.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewInit {
dashboardId: number;
Expand Down Expand Up @@ -59,25 +61,37 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni
swap: false
};
filtersValues: ElasticFilterType[] = [];
timeEnable: number[] = [];
layout$: Observable<{ grid: GridsterItem, visualization: VisualizationType } []>;

constructor(private activatedRoute: ActivatedRoute,
private layoutService: RenderLayoutService,
private cdr: ChangeDetectorRef,
private modalService: NgbModal,
private dashboardBehavior: DashboardBehavior,
private timeFilterBehavior: TimeFilterBehavior,
private utmRenderVisualization: UtmRenderVisualization,
private exportPdfService: ExportPdfService,
private spinner: NgxSpinnerService) {
private spinner: NgxSpinnerService,
private refreshService: RefreshService,
private router: Router) {
}

ngOnInit() {
console.log('Init dashboard');

document.body.classList.add('overflow-hidden');
this.loadingVisualizations = true;
this.activatedRoute.params.subscribe(params => {
this.layout$ = this.activatedRoute.data
.pipe(
tap((visualizations) => {
this.dashboard = this.layoutService.dashboard;
this.filters = this.dashboard && this.dashboard.filters ? JSON.parse(this.dashboard.filters) : [];
/* if (this.dashboard.refreshTime) {
console.log(this.dashboard.refreshTime);
this.onRefreshTime(this.dashboard.refreshTime);
}*/
this.loadingVisualizations = false;
}),
map(data => data.response)
);

/*this.activatedRoute.params.subscribe(params => {
this.dashboardId = params.id;
if (this.dashboardId) {
const request = {
Expand Down Expand Up @@ -105,14 +119,15 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni
this.loadingVisualizations = false;
});
}
});
});*/
this.dashboardBehavior.$filterDashboard.subscribe(dashboardFilter => {
if (dashboardFilter) {
mergeParams(dashboardFilter.filter, this.filtersValues).then(newFilters => {
this.filtersValues = sanitizeFilters(newFilters);
});
}
});

this.timeFilterBehavior.$time.subscribe(time => {
if (time) {
rebuildVisualizationFilterTime({timeFrom: time.from, timeTo: time.to}, this.filtersValues).then(filters => {
Expand Down Expand Up @@ -146,9 +161,7 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni
ngOnDestroy(): void {
document.body.classList.remove('overflow-hidden');
clearInterval(this.interval);
this.visualizationRender = [];
this.layoutService.layout = [];
this.timeEnable = [];
this.layoutService.clearLayout();
this.dashboardBehavior.$filterDashboard.next(null);
}

Expand All @@ -164,7 +177,7 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni
exportToPdf() {
filtersToStringParam(this.filtersValues).then(queryParams => {
this.spinner.show('buildPrintPDF');
const url = '/dashboard/export/' + this.dashboardId + '/' + normalizeString(this.dashboard.name) + '?' + queryParams;
const url = '/dashboard/export/' + this.dashboard.id + '/' + normalizeString(this.dashboard.name) + '?' + queryParams;
// window.open('/dashboard/export/' + this.dashboardId + '/' + normalizeString(this.dashboard.name) + '?' + queryParams, '_blank');
this.exportPdfService.getPdf(url, this.dashboard.name, 'PDF_TYPE_TOKEN').subscribe(response => {
this.spinner.hide('buildPrintPDF').then(() =>
Expand All @@ -175,5 +188,9 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni
});
});
}

trackByFn(index: number, item: { grid: GridsterItem, visualization: VisualizationType }) {
return item.visualization.id;
}
}

6 changes: 5 additions & 1 deletion frontend/src/app/dashboard/dashboard-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {DashboardOverviewComponent} from './dashboard-overview/dashboard-overvie
import {DashboardRenderComponent} from './dashboard-render/dashboard-render.component';
import {DashboardViewComponent} from './dashboard-view/dashboard-view.component';
import {ReportExportComponent} from './report-export/report-export.component';
import {DashboardResolverService} from './shared/services/dashboard-resolver.service';

const routes: Routes = [
{path: '', redirectTo: 'overview', pathMatch: 'full'},
Expand All @@ -35,7 +36,10 @@ const routes: Routes = [
path: 'render/:id/:dashboard',
component: DashboardRenderComponent,
canActivate: [UserRouteAccessService],
data: {authorities: [USER_ROLE, ADMIN_ROLE]}
data: {authorities: [USER_ROLE, ADMIN_ROLE]},
resolve: {
response: DashboardResolverService
}
},
{
path: 'export/:id/:dashboard',
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/dashboard/dashboard.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {DashboardRoutingModule} from './dashboard-routing.module';
import {DashboardViewComponent} from './dashboard-view/dashboard-view.component';
import {ReportExportComponent} from './report-export/report-export.component';
import {UtmDashboardSharedModule} from './shared/utm-dashboard-shared.module';
import {DashboardResolverService} from "./shared/services/dashboard-resolver.service";

@NgModule({
declarations: [DashboardViewComponent,
Expand All @@ -43,6 +44,9 @@ import {UtmDashboardSharedModule} from './shared/utm-dashboard-shared.module';
VulnerabilitySharedModule,
GridsterModule
],
providers: [
DashboardResolverService
],
entryComponents: [DashboardExportPreviewComponent],
exports: [
DashboardViewComponent
Expand Down
Loading