diff --git a/src/app/components/dashboard-settings/dashboard-settings.component.html b/src/app/components/dashboard-settings/dashboard-settings.component.html index 3f7c6f89925c53533849961ecf6f5da2fa961b94..bddf1679bc80f0f57914c73c1c3416b717ab8def 100644 --- a/src/app/components/dashboard-settings/dashboard-settings.component.html +++ b/src/app/components/dashboard-settings/dashboard-settings.component.html @@ -1,42 +1,41 @@ -<div class="dialog"> +<div class="dialog" [formGroup]="settingsForm"> <h2 mat-dialog-title class="dialog__header">Settings</h2> <mat-dialog-content class="dialog__content"> - <div class="dialog__content__statistics__columns"> + <div formGroupName="statisticsColumns" class="dialog__content__statistics__columns"> <div class="dialog__content__statistics__columns-title"> Statistics columns </div> <div class="dialog__content__statistics__columns-content"> - <app-slide-toggle>Total packets</app-slide-toggle> - <app-slide-toggle>Packets per seconds</app-slide-toggle> - <app-slide-toggle>Total bytes</app-slide-toggle> - <app-slide-toggle>Bytes per second</app-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showTotalPackets">Total packets</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showPacketsPerSec">Packets per seconds</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showTotalBytes">Total bytes</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showBytesPerSec">Bytes per second</mat-slide-toggle> </div> </div> - <div class="dialog__content__statistics__rows"> + <div formGroupName="statisticsRowsAndCharts" class="dialog__content__statistics__rows"> <div class="dialog__content__statistics__rows-title"> Statistics rows & charts </div> <div class="dialog__content__statistics__rows-content"> - <app-slide-toggle>ETH</app-slide-toggle> - <app-slide-toggle>IPv4</app-slide-toggle> - <app-slide-toggle >IPv6</app-slide-toggle> - <app-slide-toggle >TCP</app-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showETH">ETH</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showIPv4">IPv4</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showIPv6">IPv6</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showTCP">TCP</mat-slide-toggle> </div> </div> - <div class="dialog__content__statistics__ir"> + <div formGroupName="statisticsIR" class="dialog__content__statistics__ir"> <div class="dialog__content__statistics__ir-title"> Information Rate </div> <div class="dialog__content__statistics__ir-content"> - <app-slide-toggle class="custom" >Min value</app-slide-toggle> - <app-slide-toggle >Max value</app-slide-toggle> - <app-slide-toggle >Current value</app-slide-toggle> - + <mat-slide-toggle [hideIcon]="true" formControlName="showMinValue">Min value</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showMaxValue">Max value</mat-slide-toggle> + <mat-slide-toggle [hideIcon]="true" formControlName="showCurrentValue">Current value</mat-slide-toggle> </div> </div> </mat-dialog-content> <mat-dialog-actions class="dialog__actions"> - <app-button secondary class="cancel-button">CANCEL</app-button> - <app-button class="save-button">SAVE</app-button> + <app-button secondary class="cancel-button" (click)="onCancel()">CANCEL</app-button> + <app-button class="save-button" (click)="onSubmit()">SAVE</app-button> </mat-dialog-actions> </div> diff --git a/src/app/components/dashboard-settings/dashboard-settings.component.scss b/src/app/components/dashboard-settings/dashboard-settings.component.scss index ac32f2e75508cf89ae561728dae3cc35f34412f5..712cfb4d5c27dd878e838cb5b71f8b55e59ffb56 100644 --- a/src/app/components/dashboard-settings/dashboard-settings.component.scss +++ b/src/app/components/dashboard-settings/dashboard-settings.component.scss @@ -29,10 +29,8 @@ } } } - ::ng-deep app-slide-toggle { - mat-slide-toggle { + ::ng-deep mat-slide-toggle { width: 25% !important; - } } } &__actions { @@ -47,12 +45,22 @@ width: 450px; } margin: map.get(vars.$spacing, 'md') 0 0 0; - } } } +::ng-deep .mat-mdc-slide-toggle.mat-mdc-slide-toggle-checked:not(.mat-disabled) .mdc-switch__shadow { + background-color: map.get(vars.$grey, 10); +} + +::ng-deep .mat-mdc-slide-toggle.mat-mdc-slide-toggle-checked:not(.mat-disabled) .mdc-switch__track::after { + background-color: vars.$textPrimary !important; +} + +::ng-deep .mdc-switch__track::before { + background-color: map.get(vars.$grey, 30) !important; +} diff --git a/src/app/components/dashboard-settings/dashboard-settings.component.spec.ts b/src/app/components/dashboard-settings/dashboard-settings.component.spec.ts deleted file mode 100644 index 5a25de393e23c5ae25ff15bf18bbfe488841f508..0000000000000000000000000000000000000000 --- a/src/app/components/dashboard-settings/dashboard-settings.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DashboardSettingsComponent } from './dashboard-settings.component'; - -describe('DashboardSettingsComponent', () => { - let component: DashboardSettingsComponent; - let fixture: ComponentFixture<DashboardSettingsComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [DashboardSettingsComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(DashboardSettingsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/components/dashboard-settings/dashboard-settings.component.ts b/src/app/components/dashboard-settings/dashboard-settings.component.ts index f3df6d311ef0caccbd91e169b1aa3ced7ca7037e..dfff137bce5a781bbb888051d98733cf6fd446a8 100644 --- a/src/app/components/dashboard-settings/dashboard-settings.component.ts +++ b/src/app/components/dashboard-settings/dashboard-settings.component.ts @@ -1,10 +1,17 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + inject, + input, + OnInit, +} from '@angular/core'; import { MatDialogModule } from '@angular/material/dialog'; import { ToggleSwitchModule } from 'primeng/toggleswitch'; -import { FormsModule } from '@angular/forms'; +import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { ButtonComponent } from '../button/button.component'; -import { SlideToggleComponent } from '../slide-toggle/slide-toggle.component'; +import { SettingsService } from '../../service/settings.service'; +import { MatSlideToggle } from '@angular/material/slide-toggle'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -14,12 +21,49 @@ import { SlideToggleComponent } from '../slide-toggle/slide-toggle.component'; FormsModule, MatButtonModule, ButtonComponent, - SlideToggleComponent, + ReactiveFormsModule, + MatSlideToggle, ], selector: 'app-dashboard-settings', styleUrl: './dashboard-settings.component.scss', templateUrl: './dashboard-settings.component.html', }) -export class DashboardSettingsComponent { - isChecked: Boolean = true; +export class DashboardSettingsComponent implements OnInit { + private formBuilder = inject(FormBuilder); + + settingsForm = this.formBuilder.group({ + statisticsColumns: this.formBuilder.group({ + showTotalPackets: [true], + showPacketsPerSec: [true], + showTotalBytes: [true], + showBytesPerSec: [true], + }), + statisticsRowsAndCharts: this.formBuilder.group({ + showETH: [true], + showIPv4: [true], + showIPv6: [true], + showTCP: [true], + }), + statisticsIR: this.formBuilder.group({ + showMinValue: [true], + showMaxValue: [true], + showCurrentValue: [true], + }), + }); + + private settingsService = inject(SettingsService); + + ngOnInit() { + const currentSettings = this.settingsForm.value; + this.settingsForm.patchValue(currentSettings); + } + + onSubmit() { + this.settingsService.updateSettings(this.settingsForm.value); + } + + onCancel() { + const currentSettings = this.settingsService.getSettings(); + this.settingsForm.patchValue(currentSettings); + } } diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.html b/src/app/components/dashboard-statistics/dashboard-statistics.component.html index bd5d0df4699d5f06ed48f2a9e093d3c5bfcfa6ae..f40e325cd74cc1984c0ab7838d5a07634a8e02e8 100644 --- a/src/app/components/dashboard-statistics/dashboard-statistics.component.html +++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.html @@ -6,70 +6,111 @@ <ngx-skeleton-loader count="7" /> } </div> - } - @else { + } @else { <div class="statistics__table"> <div class="statistics__table__time"> <p>Total time: {{ statistics.total_time | time }} </p> </div> - <table class="statistics__table__header"> - <thead class="statistics__table__header-title"> + @if (settings?.statisticsRowsAndCharts?.showETH) { + <table class="statistics__table__header"> + <thead class="statistics__table__header-title"> <tr> <th></th> - <th>Total packets</th> - <th>Packets per second</th> - <th>Total bytes</th> - <th>Bytes per second</th> + @if (settings?.statisticsColumns?.showTotalPackets) { + <th>Total packets</th> + } + @if (settings?.statisticsColumns?.showPacketsPerSec) { + <th>Packets per second</th> + } + @if (settings?.statisticsColumns?.showTotalBytes) { + <th>Total bytes</th> + } + @if (settings?.statisticsColumns?.showBytesPerSec) { + <th>Bytes per second</th> + } </tr> - </thead> - <tbody> - @let protocolEth = getETHStatistics(statistics.protocols); + </thead> + <tbody> + @let protocolEth = getETHStatistics(statistics.protocols); <tr class="statistics__table__header-eth"> <td>{{ protocolEth.name }}</td> - <td>{{ protocolEth.total_packets | decimal }}</td> - <td> - {{ getPerSecond(protocolEth.total_packets, statistics.total_time) | decimal }} - </td> - <td>{{ protocolEth.total_bytes | decimal }}</td> - <td> - {{ getPerSecond(protocolEth.total_bytes, statistics.total_time) | decimal }} - </td> - </tr> - </tbody> - </table> - <table class="statistics__table__protocols"> - <tbody> - @for (protocol of getProtocols(statistics.protocols); track protocol.name) { - <tr> - <td>{{ protocol.name }}</td> - <td>{{ protocol.total_packets | decimal }}</td> + @if (settings?.statisticsColumns?.showTotalPackets) { + <td>{{ protocolEth.total_packets | decimal }}</td> + } + @if (settings?.statisticsColumns?.showPacketsPerSec) { <td> - {{ getPerSecond(protocol.total_packets, statistics.total_time) | decimal }} + {{ getPerSecond(protocolEth.total_packets, statistics.total_time) | decimal }} </td> - <td>{{ protocol.total_bytes | decimal }}</td> + } + @if (settings?.statisticsColumns?.showTotalBytes) { + <td>{{ protocolEth.total_bytes | decimal }}</td> + } + @if (settings?.statisticsColumns?.showBytesPerSec) { <td> - {{ getPerSecond(protocol.total_bytes, statistics.total_time) | decimal }} + {{ getPerSecond(protocolEth.total_bytes, statistics.total_time) | decimal }} </td> - </tr> - } + } + </tr> + </tbody> + </table> + } + <table class="statistics__table__protocols"> + <tbody> + @for (protocol of getProtocols(statistics.protocols); track protocol.name) { + @if (settings?.statisticsRowsAndCharts?.showIPv4 && protocol.name === 'IPv4' || + settings?.statisticsRowsAndCharts?.showIPv6 && protocol.name === 'IPv6' || + settings?.statisticsRowsAndCharts?.showTCP && protocol.name === 'TCP') { + <tr> + <td>{{ protocol.name }}</td> + @if (settings?.statisticsColumns?.showTotalPackets) { + <td>{{ protocol.total_packets | decimal }}</td> + } + @if (settings?.statisticsColumns?.showPacketsPerSec) { + <td> + {{ getPerSecond(protocol.total_packets, statistics.total_time) | decimal }} + </td> + } + @if (settings?.statisticsColumns?.showTotalBytes) { + <td>{{ protocol.total_bytes | decimal }}</td> + } + @if (settings?.statisticsColumns?.showBytesPerSec) { + <td> + {{ getPerSecond(protocol.total_bytes, statistics.total_time) | decimal }} + </td> + } + </tr> + } + } </tbody> </table> <table class="statistics__table__ir"> <thead class="statistics__table__ir-header"> <tr> <th></th> - <th>Min</th> - <th>Max</th> - <th>Current</th> + @if (settings?.statisticsIR?.showMinValue) { + <th>Min</th> + } + @if (settings?.statisticsIR?.showMaxValue) { + <th>Max</th> + } + @if (settings?.statisticsIR?.showCurrentValue) { + <th>Current</th> + } </tr> </thead> <tbody> - <tr class="statistics__table_ir-content"> - <td>Information Rate</td> + <tr class="statistics__table_ir-content"> + <td>Information Rate</td> + @if (settings?.statisticsIR?.showMinValue) { <td>{{ statistics.information_rate.min | decimal }}</td> + } + @if (settings?.statisticsIR?.showMaxValue) { <td>{{ statistics.information_rate.max | decimal }}</td> + } + @if (settings?.statisticsIR?.showCurrentValue) { <td>{{ statistics.information_rate.current | decimal }}</td> - </tr> + } + </tr> </tbody> </table> </div> diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.scss b/src/app/components/dashboard-statistics/dashboard-statistics.component.scss index e11b5db12cf23fcea68df59b4eba90d9989305d9..1814cde44062606f60a7b4b46d79c24358451e82 100644 --- a/src/app/components/dashboard-statistics/dashboard-statistics.component.scss +++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.scss @@ -74,6 +74,7 @@ margin-top: map.get(vars.$spacing, 'lg'); width: 100%; + tbody td { border-top: 1px solid map.get(vars.$grey, 30); } diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.ts b/src/app/components/dashboard-statistics/dashboard-statistics.component.ts index 2b6f6289f1cb04b49be36b8caebc8bea25d85bfa..46f5e53d3f47e9dbdc3a415a316b076da581824c 100644 --- a/src/app/components/dashboard-statistics/dashboard-statistics.component.ts +++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.ts @@ -1,27 +1,57 @@ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + inject, + Input, + OnInit, +} from '@angular/core'; import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader'; -import { AsyncPipe } from '@angular/common'; +import { AsyncPipe, NgIf } from '@angular/common'; import { DashboardApi } from '../../api/dashboard.api'; + import { interval, shareReplay, switchMap } from 'rxjs'; import { ProtocolStatistics } from '../../models/dashboard-statistics'; import { TimePipe } from '../../pipes/time.pipe'; import { DecimalPipe } from '../../pipes/decimal.pipe'; +import { FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { SettingsService } from '../../service/settings.service'; @Component({ selector: 'app-dashboard-statistics', - imports: [NgxSkeletonLoaderComponent, AsyncPipe, TimePipe, DecimalPipe], + imports: [ + NgxSkeletonLoaderComponent, + AsyncPipe, + TimePipe, + DecimalPipe, + ReactiveFormsModule, + NgIf, + ], templateUrl: './dashboard-statistics.component.html', styleUrl: './dashboard-statistics.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DashboardStatisticsComponent { +export class DashboardStatisticsComponent implements OnInit { dashboardApi = inject(DashboardApi); + settings: any; + + private settingsService = inject(SettingsService); + + ngOnInit() { + this.settingsService.settings$.subscribe(settings => { + this.settings = settings; + console.log('Settings received in Dashboard:', this.settings); + }); + } dashboardStatistics = interval(1000).pipe( switchMap(() => this.dashboardApi.fetchStatistics()), shareReplay(1) ); + get showETHSetting() { + return this.settings.value.statisticsRowsAndCharts.showETH; + } + getPerSecond(value: number, time: Date): number { const totalSeconds = time.getTime() / 1000; return value / totalSeconds; diff --git a/src/app/components/slide-toggle/slide-toggle.component.scss b/src/app/components/slide-toggle/slide-toggle.component.scss index 88ed7b52196ec5a5f84cf60fd9d5a8670652dc1a..2ef9c9c4a10931350ff2c3e5974d36d60ce0784a 100644 --- a/src/app/components/slide-toggle/slide-toggle.component.scss +++ b/src/app/components/slide-toggle/slide-toggle.component.scss @@ -13,7 +13,3 @@ background-color: map.get(vars.$grey, 30) !important; } -//.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb:before { -// content: "" !important; -// font: normal normal normal 14px/1 FontAwesome !important; -//} diff --git a/src/app/components/slide-toggle/slide-toggle.component.ts b/src/app/components/slide-toggle/slide-toggle.component.ts index 05f96f82e910c789889113c37421da36b117db0d..72ff66899bfb452cc81d2c815f64296a14610991 100644 --- a/src/app/components/slide-toggle/slide-toggle.component.ts +++ b/src/app/components/slide-toggle/slide-toggle.component.ts @@ -7,4 +7,4 @@ import { MatSlideToggle } from '@angular/material/slide-toggle'; templateUrl: './slide-toggle.component.html', styleUrl: './slide-toggle.component.scss', }) -export class SlideToggleComponent {} +export class SlideToggleComponent extends MatSlideToggle {} diff --git a/src/app/models/settings.ts b/src/app/models/settings.ts new file mode 100644 index 0000000000000000000000000000000000000000..94d2134af9aad342a5768a8e4c9b85b87bd6d794 --- /dev/null +++ b/src/app/models/settings.ts @@ -0,0 +1,29 @@ +export type Settings = SettingsDto; + +export interface SettingsDto { + statisticsColumns: { + showTotalPackets: true; + showPacketsPerSec: true; + showTotalBytes: true; + showBytesPerSec: true; + }; + statisticsRowsAndCharts: { + showETH: true; + showIPv4: true; + showIPv6: true; + showTCP: true; + }; + statisticsIR: { + showMinValue: true; + showMaxValue: true; + showCurrentValue: true; + }; +} + +export function dtoToSettings(dto: SettingsDto): Settings { + return dto; +} + +export function settingsToDto(settings: Settings): SettingsDto { + return settings; +} diff --git a/src/app/service/settings.service.ts b/src/app/service/settings.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..fb59cb2c691efecab8c75a2e02903904e9c4fb8b --- /dev/null +++ b/src/app/service/settings.service.ts @@ -0,0 +1,39 @@ +import { Injectable, OnInit } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { Settings } from '../models/settings'; + +@Injectable({ + providedIn: 'root', +}) +export class SettingsService implements OnInit { + private settingsSubject = new BehaviorSubject<any>({ + statisticsColumns: { + showTotalPackets: true, + showPacketsPerSec: true, + showTotalBytes: true, + showBytesPerSec: true, + }, + statisticsRowsAndCharts: { + showETH: true, + showIPv4: true, + showIPv6: true, + showTCP: true, + }, + statisticsIR: { + showMinValue: true, + showMaxValue: true, + showCurrentValue: true, + }, + }); + settings$ = this.settingsSubject.asObservable(); + + ngOnInit() {} + + updateSettings(settings: any) { + this.settingsSubject.next(settings); + } + + getSettings() { + return this.settingsSubject.value; + } +}