Files
SkydiveLogs/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.ts
2026-01-20 15:11:00 +01:00

296 lines
8.8 KiB
TypeScript

import { Component, OnInit } from "@angular/core";
import { RouterLink, RouterModule } from "@angular/router";
import { formatDate } from "@angular/common";
import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
import { CommonModule } from "@angular/common";
import { MatIconModule } from "@angular/material/icon";
import { MatListModule } from "@angular/material/list";
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
import { MatRadioModule } from "@angular/material/radio";
import { MatProgressBarModule } from "@angular/material/progress-bar";
import { FormsModule } from "@angular/forms";
import { MatButtonModule } from "@angular/material/button";
import { ChartConfiguration, ChartData, ChartType } from "chart.js";
import { from, groupBy, mergeMap, reduce, map } from "rxjs";
import { BaseChartDirective } from "ng2-charts";
import { ServiceComm } from "../../services/service-comm.service";
import { TunnelFlightService } from "../../services/tunnel-flight.service";
import { DateService } from "../../services/date.service";
import { TunnelFlight, TunnelFlightByMonth } from "../../models/tunnel-flight";
@Component({
selector: "app-list-of-tunnel-flights",
templateUrl: "./list-of-tunnel-flights.component.html",
styleUrls: ["./list-of-tunnel-flights.component.css"],
imports: [
TranslateModule,
BaseChartDirective,
CommonModule,
MatIconModule,
MatListModule,
MatProgressSpinnerModule,
RouterLink,
MatRadioModule,
MatProgressBarModule,
FormsModule,
RouterModule,
MatTableModule,
MatButtonModule,
],
})
export class ListOfTunnelFlightsComponent implements OnInit {
public barChartLegend = true;
public barChartData: ChartData<"bar">;
public barChartOptions: ChartConfiguration["options"];
public barChartType: ChartType;
public isLoading: boolean = false;
public selectedPeriod: string;
public dataSourceTable: MatTableDataSource<TunnelFlight> =
new MatTableDataSource();
public displayedColumns: Array<string> = [
"id",
"tunnel",
"jumpType",
"nbMinutes",
"notes",
"flightDate",
"actions",
];
public stats: Array<{ id: String | Number; values: String | Number }> = [];
constructor(
private serviceComm: ServiceComm,
private serviceTunnelFlight: TunnelFlightService,
private translateService: TranslateService,
private dateService: DateService,
) {}
ngOnInit() {
this.serviceComm.forceTranslateTitle.subscribe((data) => {
if (data === true) {
this.updateTitle();
}
});
this.updateTitle();
this.chartConfig();
this.selectedPeriod = "currentYear";
this.getDataForGraph();
}
public onPeriodChange() {
this.getDataForGraph();
if (this.dataSourceTable?.data.length > 0) {
this.getDataForTable();
}
}
public onLoadTable() {
this.getDataForTable();
}
private chartConfig() {
this.barChartType = "bar";
this.barChartOptions = {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: true,
},
tooltip: {
callbacks: {
footer: this.footer,
},
},
},
interaction: {
intersect: false,
mode: "nearest",
axis: "x",
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
},
},
};
}
private updateTitle() {
this.translateService
.get("ListTunnelFlight_Title")
.subscribe((data) => {
this.serviceComm.updatedComponentTitle(data);
});
}
private getDataForTable(): void {
this.isLoading = true;
// Get data to show in a table
let endDate = new Date();
endDate.setHours(0, 0, 0, 0);
let beginDate = this.computeBeginDateByPeriod(
this.selectedPeriod,
endDate,
);
this.serviceTunnelFlight
.getTunnelFlights(beginDate, endDate)
.subscribe((data) => {
this.dataSourceTable.data = data;
this.isLoading = false;
});
}
private getDataForGraph(): void {
this.isLoading = true;
// Get data to show in a table
let endDate = new Date();
endDate.setHours(0, 0, 0, 0);
let beginDate = this.computeBeginDateByPeriod(
this.selectedPeriod,
endDate,
);
this.serviceTunnelFlight
.getTunnelFlightsByMonth(beginDate, endDate)
.subscribe((data) => {
const allMonths = this.getMontsBetweenDates(beginDate, endDate);
const cumulatedTime = this.getCumulatedTimeByTypeByMonth(
data,
allMonths,
);
this.computeTimeByType(data);
this.barChartData = {
labels: allMonths,
datasets: cumulatedTime,
};
this.isLoading = false;
});
}
private computeTimeByType(stats: TunnelFlightByMonth[]) {
this.stats = [];
from(stats)
.pipe(
groupBy((type) => type.type, { element: (p) => p.nb }),
mergeMap((group$) =>
group$.pipe(
reduce((acc, cur) => [...acc, cur], [`${group$.key}`]),
),
),
map((arr) => ({
id: arr[0],
values: arr
.slice(1)
.reduce((a, b) => Number(a) + Number(b), 0),
})),
)
.subscribe((p) => {
console.log(p);
this.stats.push(p);
});
}
private getMontsBetweenDates(
beginDate: Date,
endDate: Date,
): Array<string> {
let results: Array<string> = [];
let tmpBeginDate = new Date(beginDate.getTime());
const tmpEndDate = new Date(endDate.getTime());
while (tmpBeginDate < tmpEndDate) {
results.push(formatDate(tmpBeginDate, "yy-MM", "en"));
tmpBeginDate.setMonth(tmpBeginDate.getMonth() + 1);
}
return results;
}
private getCumulatedTimeByTypeByMonth(
stats: TunnelFlightByMonth[],
allMonths: string[],
): Array<any> {
let tmpResults = new Map<string, number[]>();
const disctintType = Array.from(
new Set(stats.map((item) => item.type)),
);
disctintType.forEach((type) => {
tmpResults.set(
type,
Array.from({ length: allMonths.length }, (v, k) => 0),
);
});
for (let i = 0; i < allMonths.length; i++) {
const month = allMonths[i];
let filteredStats = stats.filter((d) => d.month == month);
if (filteredStats.length > 0) {
filteredStats.forEach((fs) => {
tmpResults.get(fs.type)[i] += fs.nb;
});
}
}
const results = Array.from(tmpResults, function (item) {
return { label: item[0], data: item[1] };
});
return results;
}
private footer = (tooltipItems: any) => {
let sum = 0;
tooltipItems.forEach(function (tooltipItem: any) {
sum += tooltipItem.parsed.y;
});
return "Sum: " + sum;
};
private computeBeginDateByPeriod(
selectedPeriod: String,
endDate: Date,
): Date {
let beginDate = new Date();
switch (selectedPeriod) {
case "currentYear":
beginDate = new Date(endDate.getFullYear(), 0, 1);
break;
case "12Months":
beginDate = this.dateService.addMonths(endDate, -12);
beginDate.setDate(1);
break;
case "all":
beginDate = this.dateService.addMonths(endDate, -120);
beginDate.setDate(1);
break;
}
return beginDate;
}
public delete(item: TunnelFlight) {
let data: Array<TunnelFlight> = this.dataSourceTable.data;
data = data.filter((d) => d.id !== item.id);
this.dataSourceTable.data = data;
this.serviceTunnelFlight.deleteTunnelFlight(item);
}
}