From ca05fa446a966c8b02a0929e37620cbf0b8bca7c Mon Sep 17 00:00:00 2001 From: Artem Dychenko <s192441@student.pg.edu.pl> Date: Sat, 1 Mar 2025 18:00:53 +0100 Subject: [PATCH] Implement dashboard statistics API part, add d. statistics model and make initial html --- src/app/api/dashboard.api.ts | 23 ++++++-- .../dashboard-statistics.component.html | 47 ++++++++++++++-- .../dashboard-statistics.component.ts | 47 ++++++++++++++-- .../mocks/dashboard-statistics.json | 2 +- src/app/models/dashboard-statistics.ts | 53 +++++++++++++++++++ 5 files changed, 160 insertions(+), 12 deletions(-) create mode 100644 src/app/models/dashboard-statistics.ts diff --git a/src/app/api/dashboard.api.ts b/src/app/api/dashboard.api.ts index 3f08285..498536d 100644 --- a/src/app/api/dashboard.api.ts +++ b/src/app/api/dashboard.api.ts @@ -1,8 +1,25 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { map, Observable, tap } from 'rxjs'; +import { + DashboardStatistics, + DashboardStatisticsDto, + dashboardStatisticsToDto, + dtoToDashboardStatistics, +} from '../models/dashboard-statistics'; +import { ApiResponse } from '../models/api-response'; -export const DASHBOARD_API_URL = '/api/v1/dashboard'; +export const DASHBOARD_API_URL = '/api/v1/dashboard/statistics'; @Injectable({ providedIn: 'root', }) -export class DashboardApi {} +export class DashboardApi { + private readonly httpClient = inject(HttpClient); + + fetch(): Observable<DashboardStatistics> { + return this.httpClient + .get<ApiResponse<DashboardStatisticsDto>>(DASHBOARD_API_URL) + .pipe(map(dto => dtoToDashboardStatistics(dto.data))); + } +} diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.html b/src/app/components/dashboard-statistics/dashboard-statistics.component.html index 2eaf5d2..7da5152 100644 --- a/src/app/components/dashboard-statistics/dashboard-statistics.component.html +++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.html @@ -1,5 +1,42 @@ - - - - -<ngx-skeleton-loader count="10" /> +<div class="statistics"> + @if (isLoading()) { + <div class="statistics__loader"> + <div eth class="statistics__eth"> + <div class="statistics__eth-content"> + <ngx-skeleton-loader count="7" /> + </div> + </div> + <div protocols class="statistics__prot"> + <div class="statistics__prot-content"> + <ngx-skeleton-loader count="7" /> + </div> + </div> + <div ir> + <ngx-skeleton-loader count="10" /> + </div> + </div> + } + @else { + <div class="statistics__content"> + <p>Total time {{ dashboardStatistic()?.total_time }} </p> +<!-- @for (mac of configuration()?.mac_source; track $index) {--> +<!-- <app-pill>{{ mac }}</app-pill>--> +<!-- } @empty {--> +<!-- <app-pill>All addresses</app-pill>--> +<!-- }--> + <div eth class="statistics__eth"> + <div class="statistics__eth-content"> +<!-- <p>ETH Price: {{ statistics.ethPrice }} USD</p>--> + </div> + </div> + <div protocols class="statistics__prot"> + <div class="statistics__prot-content"> +<!-- <p>Number of active protocols: {{ statistics.protocols }}</p>--> + </div> + </div> + <div ir> +<!-- <p>Other data: {{ statistics.otherData }}</p>--> + </div> + </div> + } +</div> diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.ts b/src/app/components/dashboard-statistics/dashboard-statistics.component.ts index 4f88f14..56a83da 100644 --- a/src/app/components/dashboard-statistics/dashboard-statistics.component.ts +++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.ts @@ -1,10 +1,51 @@ -import { Component } from '@angular/core'; +import { + afterNextRender, + Component, + effect, + inject, + signal, +} from '@angular/core'; import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader'; +import { NgTemplateOutlet } from '@angular/common'; +import { DashboardApi } from '../../api/dashboard.api'; +import { map, Observable, tap } from 'rxjs'; +import { DashboardStatistics } from '../../models/dashboard-statistics'; +import { PillComponent } from '../pill/pill.component'; @Component({ selector: 'app-dashboard-statistics', - imports: [NgxSkeletonLoaderComponent], + imports: [NgxSkeletonLoaderComponent, NgTemplateOutlet, PillComponent], templateUrl: './dashboard-statistics.component.html', styleUrl: './dashboard-statistics.component.scss', }) -export class DashboardStatisticsComponent {} +export class DashboardStatisticsComponent { + dashboardApi = inject(DashboardApi); + + isLoading = signal<boolean>(false); + dashboardStatistic = signal<DashboardStatistics | undefined>(undefined); + + constructor() { + effect(() => { + this.isLoading.set(true); + + this.dashboardApi.fetch().subscribe(data => { + this.isLoading.set(false); + this.dashboardStatistic.set(data); + }); + }); + } + + private fetchConfigurationOptions(): Observable<DashboardStatistics> { + this.isLoading.set(true); + return this.dashboardApi.fetch().pipe( + map(dashboardStatistics => { + return { + total_time: dashboardStatistics.total_time, + protocols: dashboardStatistics.protocols, + information_rate: dashboardStatistics.information_rate, + }; + }), + tap(() => this.isLoading.set(false)) + ); + } +} diff --git a/src/app/interceptor/mocks/dashboard-statistics.json b/src/app/interceptor/mocks/dashboard-statistics.json index 073d63b..65334a5 100644 --- a/src/app/interceptor/mocks/dashboard-statistics.json +++ b/src/app/interceptor/mocks/dashboard-statistics.json @@ -1,7 +1,7 @@ { "data": { "id": "statistics", - "total_time": "01:05:30", + "total-time": "1740770761000", "protocols": [ { "name": "ETH", diff --git a/src/app/models/dashboard-statistics.ts b/src/app/models/dashboard-statistics.ts new file mode 100644 index 0000000..8d07d36 --- /dev/null +++ b/src/app/models/dashboard-statistics.ts @@ -0,0 +1,53 @@ +export type DashboardStatistics = DashboardStatisticsDto; + +export interface ProtocolStatistics { + name: string; + total_packets: number; + total_bytes: number; +} + +export interface InformationRate { + min: number; + max: number; + current: number; +} + +export interface DashboardStatisticsDto { + total_time: string; + protocols: ProtocolStatistics[]; + information_rate: InformationRate; +} + +export function dtoToDashboardStatistics(dto: any): DashboardStatistics { + return { + total_time: dto['total-time'], + protocols: dto.protocols.map((protocol: any) => ({ + name: protocol.name, + total_packets: protocol['total-packets'], + total_bytes: protocol['total-bytes'], + })), + information_rate: { + min: dto['information-rate'].min, + max: dto['information-rate'].max, + current: dto['information-rate'].current, + }, + }; +} + +export function dashboardStatisticsToDto( + dashboardStatistics: DashboardStatistics +): any { + return { + 'total-time': dashboardStatistics.total_time, + protocols: dashboardStatistics.protocols.map(protocol => ({ + name: protocol.name, + 'total-packets': protocol.total_packets, + 'total-bytes': protocol.total_bytes, + })), + 'information-rate': { + min: dashboardStatistics.information_rate.min, + max: dashboardStatistics.information_rate.max, + current: dashboardStatistics.information_rate.current, + }, + }; +} -- GitLab