Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export as .pcap, .png and .txt #54

Merged
merged 8 commits into from
Mar 20, 2024
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
1 change: 1 addition & 0 deletions ngx-flow/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@angular/platform-browser": "~12.2.0",
"@angular/platform-browser-dynamic": "~12.2.0",
"@angular/router": "~12.2.0",
"html2canvas": "^1.4.1",
"document-register-element": "^1.7.2",
"is-in-subnet": "^4.0.1",
"moment": "^2.29.4",
Expand Down
24 changes: 20 additions & 4 deletions ngx-flow/projects/ngx-flow/src/lib/ngx-flow.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ import { FlowData } from '../models/flow.model';
[callid]="callid"
[isSimplify]="isSimplify"
></app-tab-flow>
<div style="position: relative; overflow: hidden; height: 1px; width: 1px;">
<div style="position: absolute;">
<app-tab-flow
[callid]="callid"
[dataItem]="{data: _formattedData}"
[exportAsPNG]="exportAsPNG"
[callIDColorList]='callIDColorList'
(pngReady)="exportAsPNG=false"
>
</app-tab-flow>
</div>
</div>
</div>`,
styles: [`
.wrapper-container {
Expand All @@ -30,8 +42,12 @@ export class NgxFlowComponent implements OnInit {
@Input() callid: any;
@Input() isSimplify: boolean = false;
@Input() isFilter: boolean = false;

constructor() { }
exportAsPNG: boolean = false;
constructor() {
document.addEventListener('export-flow-as-png', (e: any) => {
this.exportAsPNG = true
});
}

ngOnInit(): void {
console.log(this.data)
Expand Down Expand Up @@ -69,14 +85,14 @@ export class NgxFlowComponent implements OnInit {
const dist = hosts.find((i: any) => i.name === DIST);

return {
callid: hash((i.messageID || i.title)+''),
callid: hash((i.messageID || i.title) + ''),
codecData: ' ',
description: i.aboveArrow || '',
destination_ip: dist.ip,
destination_port: dist.port,
diff: ' ',
diff_absolute: i.subTitle || '',
diff_num: ' ',
diff_num: ' ',
dstAlias: DIST,
id: 0,
info_date: i.belowArrow || '... ',
Expand Down
137 changes: 61 additions & 76 deletions ngx-flow/projects/ngx-flow/src/tab-flow/tab-flow.component.html
Original file line number Diff line number Diff line change
@@ -1,91 +1,75 @@
<div
class="flowscreen"
[style.min-width.px]="pageWidth + 85"
data-comment="85 = 16 * 2 + 106 / 2"
[style.padding-top.px]="isExport ? 40 : 0"
[style.width]="isExport ? 'calc(100% + 20px)' : 'calc(100% - 1rem)'"
#flowscreen
>
<ng-container *ngIf="arrayItemsVisible?.length === 0">
<h1 style="text-align: center; padding: 8rem; color: #aaa">No Data</h1>
</ng-container>
<div class="flowscreen" [style.min-width.px]="pageWidth + 85" data-comment="85 = 16 * 2 + 106 / 2"
[style.padding-top.px]="isExport ? 40 : 0" [style.width]="isExport ? 'calc(100% + 20px)' : 'calc(100% - 1rem)'"
#flowscreen>
<ng-container *ngIf="arrayItemsVisible?.length === 0">
<h1 style="text-align: center; padding: 8rem; color: #aaa">No Data</h1>
</ng-container>

<div class="flow-grid-lines" [style.min-width.px]="pageWidth - 16 * 2">
<div *ngFor="let title of flowGridLines" class="line"></div>
</div>
<div class="flow-grid-lines" [style.min-width.px]="pageWidth - 16 * 2">
<div *ngFor="let title of flowGridLines" class="line"></div>
</div>

<!-- hosts -->
<!-- hosts -->

<div class="hosts" [style.top.px]="isExport ? 40 : 0">
<div class="hosts-wrapper">
<!-- host titles -->
<ng-template ngFor let-itemhost [ngForOf]="_isCombineByAlias ? hostsCA : hostsIPs">
<div *ngIf="!itemhost.hidden" [ngClass]="'item-wrapper' + (isSimplify ? ' big' : '')">
<!-- wrapper -->
<div class="hosts" [style.top.px]="isExport ? 40 : 0">
<div class="hosts-wrapper">
<!-- host titles -->
<ng-template ngFor let-itemhost [ngForOf]="_isCombineByAlias ? hostsCA : hostsIPs">
<div *ngIf="!itemhost.hidden" [ngClass]="'item-wrapper' + (isSimplify ? ' big' : '')">
<!-- wrapper -->

<div
class="item"
[id]="itemhost.alias && itemhost.alias !== itemhost.ip ? itemhost.alias : ''"
[style.border-color]="(itemhost.color && itemhost.color.border) || 'lightgray'"
>
<!-- container -->
<div class="item" [id]="itemhost.alias && itemhost.alias !== itemhost.ip ? itemhost.alias : ''"
[style.border-color]="(itemhost.color && itemhost.color.border) || 'lightgray'">
<!-- container -->

<div class="aliasfield" (mouseover)="showTooltip(itemhost)" (mouseout)="hideTooltip()">
<ng-template #noAlias> </ng-template>
<div class="alias-img"></div>
<div class="alias-name" *ngIf="!_isCombineByAliasGroup; else itemhostGroup">
{{ itemhost.alias && itemhost.alias !== itemhost.ip ? itemhost.alias : '' }}
</div>
<ng-template #itemhostGroup>
<div>Group:</div>
<div class="alias-name">
{{ itemhost.group || '...other...' }}
<div class="aliasfield" (mouseover)="showTooltip(itemhost)" (mouseout)="hideTooltip()">
<ng-template #noAlias> </ng-template>
<div class="alias-img"></div>
<div class="alias-name" *ngIf="!_isCombineByAliasGroup; else itemhostGroup">
{{ itemhost.alias && itemhost.alias !== itemhost.ip ? itemhost.alias : '' }}
</div>
<ng-template #itemhostGroup>
<div>Group:</div>
<div class="alias-name">
{{ itemhost.group || '...other...' }}
</div>
</ng-template>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</ng-template>
</div>
</ng-template>
</div>
</div>

<!-- flow packets -->
<!-- REAL TIME FLOW -->
<!-- flow packets -->
<!-- REAL TIME FLOW -->

<!-- EXPORT FLOW as PNG -->
<div
*ngIf="isExport"
class="flow-packets-wrapper"
[style.margin-right.rem]="0"
[style.min-width.px]="pageWidth + 100"
>
<div style="height: 92px"></div>
<app-flow-item
*ngFor="let item of arrayItemsVisible; let idx = index"
[isGroupByAlias]="_isCombineByAlias"
[item]="item"
[idx]="idx"
[isSimplify]="false"
>
</app-flow-item>
<div style="height: 40px"></div>
</div>
<!-- </div> -->
<div *ngIf="isExport" class="label-callid-container">
<div class="label-callid-wrapper" *ngFor="let itemLabel of labels" [style.color]="itemLabel.color">
* {{ itemLabel.callid }}
<!-- EXPORT FLOW as PNG -->
<div *ngIf="isExport" class="flow-packets-wrapper" [style.margin-right.rem]="0"
[style.min-width.px]="pageWidth + 100">
<div style="height: 92px"></div>
<app-flow-item *ngFor="let item of arrayItemsVisible; let idx = index" [isGroupByAlias]="_isCombineByAlias"
[item]="item" [idx]="idx" [isSimplify]="false">
</app-flow-item>
<div style="height: 40px"></div>
</div>
<!-- </div> -->
<div *ngIf="isExport" class="label-callid-container">
<div class="label-callid-wrapper" *ngFor="let itemLabel of labels" [style.color]="itemLabel.color">
* {{ itemLabel.callid }}
</div>
</div>
</div>
</div>
<div class="VS-Container-horizontal">
<div
*ngIf="isExport || isSafari"
class="VS-Container"
style="overflow: auto !important"
(scroll)="onScrollVScrollWrapper($event)"
>
<div
class="VS-Container"
style="height: initial; overflow: scroll !important"
style="height: initial; overflow: scroll !important; bottom:unset"
[style.min-width.px]="pageWidth + 100"
>
<div style="height: 92px"></div>
Expand All @@ -101,16 +85,17 @@ <h1 style="text-align: center; padding: 8rem; color: #aaa">No Data</h1>
<div style="height: 60px"></div>
</div>
</div>
<!-- <div
<div
class="VS-Container"
style="overflow-y: hidden !important"
(scroll)="onScrollVScrollWrapper($event)"
*ngIf="!isExport"
*ngIf="!isExport && !isSafari"
#VScrollWrapper
>
<cdk-virtual-scroll-viewport
class="VS-Container hidescroll"
(wheel)="cdkWheelScroll($event)"

(touchstart)="onEvent($event, 'touchstart')"
(touchmove)="onEvent($event, 'touchmove')"
[maxBufferPx]="500"
Expand Down Expand Up @@ -138,19 +123,19 @@ <h1 style="text-align: center; padding: 8rem; color: #aaa">No Data</h1>
</ng-template>
</ng-container>
</cdk-virtual-scroll-viewport>
</div> -->
</div>
</div>

<div id="download" style="display: none">
<img #canvas />
<a #downloadLink></a>
<img #canvas />
<a #downloadLink target="_blank"></a>
</div>
<!-- <div
<div
class="virtual-scrollbar"
*ngIf="!isExport"
*ngIf="!isExport && !isSafari"
(mousedown)="setScrollTarget('virtualScrollbar')"
(scroll)="setVirtualScrollHeight($event)"
#virtualScrollbar
>
<div [style.transform]="getVirtualScrollHeight" [style.padding.px]="1"></div>
</div> -->
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
box-shadow: inset 7px 10px 12px transparent;
}
}
::-webkit-scrollbar-corner { background: rgba(0,0,0,0.5); }


.flow-grid-lines {
display: flex;
Expand Down
67 changes: 46 additions & 21 deletions ngx-flow/projects/ngx-flow/src/tab-flow/tab-flow.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '../services/message-details.service';
import { Subscription } from 'rxjs';
import { isExternalUrl } from '../helpers/functions';
import * as html2canvas from 'html2canvas';

export class CustomVirtualScrollStrategy extends FixedSizeVirtualScrollStrategy {
constructor() {
Expand Down Expand Up @@ -93,6 +94,7 @@ export class TabFlowComponent
timeout: any;
_interval: any | null = null;
pathPrefix = './assets/';
isSafari = navigator.vendor === 'Apple Computer, Inc.'
outEventDelayOff = 0;
get outEventOff() {
//
Expand Down Expand Up @@ -123,7 +125,7 @@ export class TabFlowComponent
dataItemValue = {
data: JSON.parse(dataItemValueInput)
}
} catch (e) {
} catch (e) {
console.error("JSON PARSING ERROR", e, dataItemValueInput)
dataItemValue = {
data: null
Expand All @@ -137,7 +139,7 @@ export class TabFlowComponent
try {
console.log(JSON_parse(dataItemValueInput.data),JSON.parse(dataItemValueInput.data))
dataItemValue.data = JSON.parse(dataItemValueInput.data)
} catch (e) {
} catch (e) {
console.error("JSON PARSING ERROR", e, dataItemValueInput.data)
dataItemValue = {
data: null
Expand Down Expand Up @@ -216,7 +218,7 @@ export class TabFlowComponent
if (val) {
this.isExport = true;
this.cdr.detectChanges();
// setTimeout(this.onSavePng.bind(this), 500);
setTimeout(this.onSavePng.bind(this), 500);
}
}

Expand All @@ -235,7 +237,10 @@ export class TabFlowComponent
private messageDetailsService: MessageDetailsService,
private transactionFilterService: TransactionFilterService,
private cdr: ChangeDetectorRef,
) { }
) {
console.log('test constructor')

}
public isDataReady() {

}
Expand Down Expand Up @@ -589,8 +594,28 @@ export class TabFlowComponent
const arr = itemhost.arrip || [itemhost.IP];
return arr.join(', ');
}
// onSavePng() {

onSavePng() {
if (!this._flagAfterViewInit) {
setTimeout(this.onSavePng.bind(this), 1000);
return;
}
if (html2canvas && typeof html2canvas === 'function') {
this.cdr.detectChanges();
const f: Function = html2canvas as Function;
f(this.flowscreen.nativeElement).then((canvas: any) => {
this.canvas.nativeElement.src = canvas.toDataURL();
this.downloadLink.nativeElement.href = canvas.toDataURL('image/png');
const date = new Date();
this.downloadLink.nativeElement.download = `${date.toUTCString()}.png`;
console.log()
this.downloadLink.nativeElement.click();
console.log('%cpng ready', 'color:#ff4400; font-size: 50px;', this.downloadLink.nativeElement.href);
setTimeout(() => {
this.pngReady.emit({});
});
});
}
}
labelColor(callid: any, selected: any) {
if (selected) {
const color = this.callIDColorList?.find(
Expand Down Expand Up @@ -623,20 +648,20 @@ export class TabFlowComponent
this.copyTimer = Date.now();
}
copy(value: any) {
// const localTimer = Date.now();
// if (localTimer - this.copyTimer > 700) {
// this.copyService.copy(value.callid, {
// message: 'notifications.success.callidCopy',
// isTranslation: true,
// translationParams: {
// callid: value.callid,
// },
// });
// value.copySelected = true;
// this.timeout = setTimeout(() => {
// value.copySelected = false;
// }, 1800);
// }
// const localTimer = Date.now();
// if (localTimer - this.copyTimer > 700) {
// this.copyService.copy(value.callid, {
// message: 'notifications.success.callidCopy',
// isTranslation: true,
// translationParams: {
// callid: value.callid,
// },
// });
// value.copySelected = true;
// this.timeout = setTimeout(() => {
// value.copySelected = false;
// }, 1800);
// }
}
setScrollTarget(targetString: string) {
this.ScrollTarget = targetString;
Expand Down Expand Up @@ -677,7 +702,7 @@ export class TabFlowComponent
const scrollbar = this.virtualScrollbar?.nativeElement;
let movingAverageArray: any[] = [];
const ma = (p: any) => {
const valMA = 6;
const valMA = 3; // Adjust this to change virtual scroll speed. Lower = faster
if (movingAverageArray.length < valMA) {
movingAverageArray = Array.from({ length: valMA }, (x) => p);
}
Expand Down
Loading
Loading