Skip to content

Commit b37f870

Browse files
antonin77usfalami
andauthored
DateTimePicker on search session view for lower data (#76)
* custom datetime picker * DateTimePicker for SearchRestSession * DateTimePicker with custom date range strategy * gestion url * clean code --------- Co-authored-by: u$f <usf.alami@gmail.com>
1 parent e61995e commit b37f870

17 files changed

+231
-77
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {NativeDateAdapter} from "@angular/material/core";
2+
import {Injectable} from "@angular/core";
3+
4+
@Injectable()
5+
export class CustomDateAdapter extends NativeDateAdapter {
6+
parse(value: any, parseFormat?: any): Date | null {
7+
if (typeof value === 'string') {
8+
// Custom parsing logic to handle both date and time.
9+
const dateTimeRegex = /^([0-9][1-9])\/(0[1-9]|1[0-2])\/(\d{4}) ([0-1][0-9]|2[0-3]):([0-5]\d)$/;
10+
const match = value.match(dateTimeRegex);
11+
if (match) {
12+
return new Date(
13+
parseInt(match[3], 10),
14+
parseInt(match[2], 10) - 1, // Month is 0-based
15+
parseInt(match[1], 10),
16+
parseInt(match[4], 10),
17+
parseInt(match[5], 10)
18+
);
19+
}
20+
}
21+
return null;
22+
}
23+
24+
compareDate(first: Date, second: Date): number {
25+
return (
26+
this.getYear(first) - this.getYear(second) ||
27+
this.getMonth(first) - this.getMonth(second) ||
28+
this.getDate(first) - this.getDate(second) ||
29+
this.getHours(first) - this.getHours(second) ||
30+
this.getMinutes(first) - this.getMinutes(second)
31+
);
32+
}
33+
34+
getHours(date: Date): number {
35+
return date.getHours();
36+
}
37+
38+
getMinutes(date: Date): number {
39+
return date.getMinutes();
40+
}
41+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {DateRange, MatDateRangeSelectionStrategy} from "@angular/material/datepicker";
2+
import {Injectable} from "@angular/core";
3+
import {DateAdapter} from "@angular/material/core";
4+
5+
@Injectable()
6+
export class CustomDateRangeSelectionStrategy implements MatDateRangeSelectionStrategy<Date> {
7+
constructor(private _dateAdapter: DateAdapter<Date>) {}
8+
9+
selectionFinished(date: Date, currentRange: DateRange<Date>) {
10+
let {start, end} = currentRange;
11+
12+
if (start == null) {
13+
start = date;
14+
} else if (end == null && date && this._dateAdapter.compareDate(date, start) >= 0) {
15+
end = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59);
16+
} else {
17+
start = date;
18+
end = null;
19+
}
20+
21+
return new DateRange<Date>(start, end);
22+
}
23+
24+
createPreview(activeDate: Date | null, currentRange: DateRange<Date>) {
25+
let start: Date | null = null;
26+
let end: Date | null = null;
27+
28+
if (currentRange.start && !currentRange.end && activeDate) {
29+
start = currentRange.start;
30+
end = activeDate;
31+
}
32+
33+
return new DateRange<Date>(start, end);
34+
}
35+
}

src/app/shared/material/material.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ import {MatTreeModule} from '@angular/material/tree';
4646
import {OverlayModule} from '@angular/cdk/overlay';
4747
import {CdkMenuModule} from '@angular/cdk/menu';
4848
import {DialogModule} from '@angular/cdk/dialog';
49-
import {BrowserAnimationsModule} from
50-
'@angular/platform-browser/animations';
49+
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
5150
import {LabelIconComponent} from "./_component/label-icon/label-icon.component";
5251
import {CommonModule} from "@angular/common";
52+
5353
@NgModule({
5454
imports: [CommonModule, MatIconModule],
5555
declarations: [LabelIconComponent],

src/app/shared/shared.module.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ import { DurationPipe } from './pipe/duration.pipe';
1111
import { SizePipe } from './pipe/size.pipe';
1212
import {TitleCasePipe} from "./pipe/title-case.pipe";
1313

14+
export const MY_DATE_FORMATS = {
15+
parse: {
16+
dateInput: 'MM/YYYY',
17+
},
18+
display: {
19+
dateInput: {
20+
year: "numeric",
21+
month: "numeric",
22+
day: "numeric",
23+
hour: "numeric",
24+
minute: "numeric"
25+
}
26+
}
27+
};
28+
1429
@NgModule({
1530
imports: [
1631
CommonModule,

src/app/views/architecture/architecture.view.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {FormControl, FormGroup, Validators} from "@angular/forms";
55
import {EnvRouter} from "../../service/router.service";
66
import {ActivatedRoute, Params} from "@angular/router";
77
import {combineLatest, finalize, forkJoin, fromEvent, map, Subscription} from "rxjs";
8-
import {application, makePeriod} from "../../../environments/environment";
8+
import {application, makeDatePeriod} from "../../../environments/environment";
99
import {Location} from "@angular/common";
1010
import {TreeService} from "../../service/tree.service";
1111
import {mxCell} from "mxgraph";
@@ -188,8 +188,8 @@ export class ArchitectureView implements OnInit, AfterViewInit, OnDestroy {
188188
}).subscribe({
189189
next: (v: { params: Params, queryParams: Params }) => {
190190
this.params.env = v.queryParams.env || application.default_env;
191-
this.params.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start;
192-
this.params.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end;
191+
this.params.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.api.default_period || application.dashboard.default_period || makeDatePeriod(6)).start;
192+
this.params.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.api.default_period || application.dashboard.default_period || makeDatePeriod(6, 1)).end;
193193
this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1));
194194
this.init();
195195
this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`);

src/app/views/dashboard/dashboard.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AfterViewInit, Component, inject, ViewChild } from '@angular/core';
22
import { ActivatedRoute, Params } from '@angular/router';
33
import { combineLatest, finalize, forkJoin, map, Observable, Subscription, take } from 'rxjs';
44
import { DatePipe, Location } from '@angular/common';
5-
import { application, makePeriod } from 'src/environments/environment';
5+
import { application, makeDatePeriod } from 'src/environments/environment';
66
import { EnvRouter } from "../../service/router.service";
77
import { FormControl, FormGroup, Validators } from '@angular/forms';
88
import { Constants } from '../constants';
@@ -86,8 +86,8 @@ export class DashboardComponent implements AfterViewInit {
8686
}).subscribe({
8787
next: (v: { params: Params, queryParams: Params }) => {
8888
this.params.env = v.queryParams.env || application.default_env;
89-
this.params.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.home.default_period || makePeriod(0, 1)).start;
90-
this.params.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.home.default_period || makePeriod(0, 1)).end;
89+
this.params.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.home.default_period || makeDatePeriod(0, 1)).start;
90+
this.params.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.home.default_period || makeDatePeriod(0, 1)).end;
9191
this.params.serveurs = Array.isArray(v.queryParams['appname']) ? v.queryParams['appname'] : v.queryParams['appname'] ? [v.queryParams['appname']] : []
9292
if (this.params.serveurs.length > 0) {
9393
this.patchServerValue(this.params.serveurs);

src/app/views/search/main/search-main.view.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<form [formGroup]="serverFilterForm" class="header-filter md-2">
33
<advanced-filter-recap [filters]="advancedParams" (filterRemoved)="handleRemovedFilter($event)"
44
(focusField)="focusField($event)"></advanced-filter-recap>
5-
<mat-form-field class="no-subscript" appearance="outline">
5+
<mat-form-field style="width: 360px" class="no-subscript" appearance="outline">
66
<mat-label>Période</mat-label>
77
<mat-date-range-input [formGroup]="serverFilterForm.controls.dateRangePicker" [rangePicker]="picker">
8-
<input matStartDate formControlName="start" placeholder="Start date">
9-
<input matEndDate formControlName="end" placeholder="End date">
8+
<input matStartDate formControlName="start" placeholder="Start date" (dateChange)="onChangeStart($event)">
9+
<input matEndDate formControlName="end" placeholder="End date" (dateChange)="onChangeEnd($event)">
1010
</mat-date-range-input>
1111
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
1212
<mat-date-range-picker #picker></mat-date-range-picker>

src/app/views/search/main/search-main.view.ts

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,33 @@ import {combineLatest, finalize, Subscription} from 'rxjs';
88
import {Location} from '@angular/common';
99
import {Utils} from 'src/app/shared/util';
1010
import {TraceService} from 'src/app/service/trace.service';
11-
import {application, makePeriod} from 'src/environments/environment';
11+
import {application, makeDatePeriod, makeDateTimePeriod} from 'src/environments/environment';
1212
import {Constants, Filter, FilterConstants, FilterMap, FilterPreset} from '../../constants';
1313
import {FilterService} from 'src/app/service/filter.service';
1414
import {InstanceMainSession} from 'src/app/model/trace.model';
1515
import {EnvRouter} from "../../../service/router.service";
1616
import {InstanceService} from "../../../service/jquery/instance.service";
17+
import {DateAdapter, MAT_DATE_FORMATS} from "@angular/material/core";
18+
import {CustomDateAdapter} from "../../../shared/material/custom-date-adapter";
19+
import {MY_DATE_FORMATS} from "../../../shared/shared.module";
20+
import {MAT_DATE_RANGE_SELECTION_STRATEGY} from "@angular/material/datepicker";
21+
import {CustomDateRangeSelectionStrategy} from "../../../shared/material/custom-date-range-selection-strategy";
1722

1823

1924
@Component({
2025
templateUrl: './search-main.view.html',
2126
styleUrls: ['./search-main.view.scss'],
27+
providers: [
28+
{
29+
provide: DateAdapter, useClass: CustomDateAdapter
30+
},
31+
{
32+
provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS
33+
},
34+
{
35+
provide: MAT_DATE_RANGE_SELECTION_STRATEGY, useClass: CustomDateRangeSelectionStrategy
36+
}
37+
]
2238
})
2339
export class SearchMainView implements OnInit, OnDestroy {
2440
private _router = inject(EnvRouter);
@@ -50,6 +66,9 @@ export class SearchMainView implements OnInit, OnDestroy {
5066
filter: string = '';
5167
params: Partial<{ env: string, start: Date, end: Date, type: string, serveurs: string[] }> = {};
5268

69+
subscriptionServer: Subscription;
70+
subscriptionSession: Subscription;
71+
5372
@ViewChild(MatPaginator) paginator: MatPaginator;
5473
@ViewChild(MatSort) sort: MatSort;
5574

@@ -60,17 +79,16 @@ export class SearchMainView implements OnInit, OnDestroy {
6079
this._activatedRoute.queryParams
6180
]).subscribe({
6281
next: ([params, queryParams]) => {
63-
console.log(params.type_main, 'test')
6482
this.params.env = queryParams['env'] || application.default_env;
6583
this.params.type = params.type_main;
66-
this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makePeriod(0, 1)).start;
67-
this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makePeriod(0, 1)).end;
84+
this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makeDateTimePeriod(1)).start;
85+
this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makeDateTimePeriod(1)).end;
6886
this.params.serveurs = Array.isArray(queryParams['appname']) ? queryParams['appname'] : [queryParams['appname'] || ''];
6987
if (this.params.serveurs[0] != '') {
7088
this.patchServerValue(this.params.serveurs)
7189
}
72-
this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1));
73-
this.subscriptions.push(this._instanceService.getApplications(this.params.type == 'view' ? 'CLIENT' : 'SERVER' )
90+
this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate(), this.params.end.getHours(), this.params.end.getMinutes(), this.params.end.getSeconds(), this.params.end.getMilliseconds() - 1));
91+
this.subscriptionServer = this._instanceService.getApplications(this.params.type == 'view' ? 'CLIENT' : 'SERVER' )
7492
.pipe(finalize(()=> this.serverNameIsLoading = false))
7593
.subscribe({
7694
next: res => {
@@ -79,20 +97,28 @@ export class SearchMainView implements OnInit, OnDestroy {
7997
}, error: (e) => {
8098
console.log(e)
8199
}
82-
}));
100+
});
83101
this.getMainRequests();
84102
this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}${this.params.serveurs[0] !== '' ? '&' + this.params.serveurs.map(name => `appname=${name}`).join('&') : ''}`)
85103
}
86104
});
87105
}
88106

107+
onChangeStart(event) {
108+
this.serverFilterForm.controls.dateRangePicker.controls.end.updateValueAndValidity({onlySelf: true})
109+
}
110+
111+
onChangeEnd(event) {
112+
this.serverFilterForm.controls.dateRangePicker.controls.start.updateValueAndValidity({onlySelf: true})
113+
}
89114

90115
ngOnInit(): void {
91116

92117
}
93118

94119
ngOnDestroy(): void {
95-
this.subscriptions.forEach(s => s.unsubscribe());
120+
if(this.subscriptionSession) this.subscriptionSession.unsubscribe();
121+
if(this.subscriptionServer) this.subscriptionServer.unsubscribe();
96122
}
97123

98124
getMainRequests() {
@@ -110,7 +136,7 @@ export class SearchMainView implements OnInit, OnDestroy {
110136

111137
this.isLoading = true;
112138
this.dataSource.data = [];
113-
this.subscriptions.push(this._traceService.getMainSessions(params).subscribe((d: InstanceMainSession[]) => {
139+
this.subscriptionSession = this._traceService.getMainSessions(params).subscribe((d: InstanceMainSession[]) => {
114140
if (d) {
115141
this.dataSource = new MatTableDataSource(d);
116142
this.dataSource.paginator = this.paginator;
@@ -148,24 +174,25 @@ export class SearchMainView implements OnInit, OnDestroy {
148174
}
149175
}, error => {
150176
this.isLoading = false;
151-
}));
177+
});
152178
}
153179

154180

155181
search() {
156182
if (this.serverFilterForm.valid) {
183+
if(this.subscriptionSession) this.subscriptionSession.unsubscribe();
157184
let appname = this.serverFilterForm.getRawValue().appname;
158185
let start = this.serverFilterForm.getRawValue().dateRangePicker.start;
159-
let end = this.serverFilterForm.getRawValue().dateRangePicker.end
160-
let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1)
186+
let end = this.serverFilterForm.getRawValue().dateRangePicker.end;
187+
let _end = new Date(end.getFullYear(), end.getMonth(), end.getDate(), end.getHours(), end.getMinutes(), 59, 1000);
161188
if (this.params.start.toISOString() != start.toISOString()
162-
|| this.params.end.toISOString() != excludedEnd.toISOString()
189+
|| this.params.end.toISOString() != end.toISOString()
163190
|| !this.params?.serveurs?.every((element, index) => element === appname[index])
164191
|| appname.length != this.params?.serveurs?.length) {
165192
this._router.navigate([], {
166193
relativeTo: this._activatedRoute,
167194
queryParamsHandling: 'merge',
168-
queryParams: { ...(appname !== undefined && { appname }), start: start.toISOString(), end: excludedEnd }
195+
queryParams: { ...(appname !== undefined && { appname }), start: start.toISOString(), end: _end.toISOString() }
169196
})
170197
} else {
171198
this.getMainRequests();
@@ -214,7 +241,7 @@ export class SearchMainView implements OnInit, OnDestroy {
214241
}
215242

216243
resetFilters() {
217-
this.patchDateValue((application.session.api.default_period || makePeriod(0)).start, (application.session.api.default_period || makePeriod(0, 1)).end);
244+
this.patchDateValue((application.session.api.default_period || makeDatePeriod(0)).start, (application.session.api.default_period || makeDatePeriod(0, 1)).end);
218245
this.advancedParams = {};
219246
this._filter.setFilterMap({})
220247
}

src/app/views/search/rest/search-rest.view.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<header-page [titleIcon]="MAPPING_TYPE['rest'].icon" [ui-title]="MAPPING_TYPE['rest'].title">
22
<form [formGroup]="serverFilterForm" class="header-filter md-2">
3-
<advanced-filter-recap [filters]="advancedParams" (filterRemoved)="handleRemovedFilter($event)" (focusField)="focusField($event)"></advanced-filter-recap>
4-
<mat-form-field class="no-subscript" appearance="outline" >
3+
<advanced-filter-recap [filters]="advancedParams" (filterRemoved)="handleRemovedFilter($event)" (focusField)="focusField($event)"></advanced-filter-recap>
4+
<mat-form-field style="width: 360px" class="no-subscript" appearance="outline" >
55
<mat-label>Période</mat-label>
66
<mat-date-range-input [formGroup]="serverFilterForm.controls.dateRangePicker" [rangePicker]="picker">
7-
<input matStartDate formControlName="start" placeholder="Start date">
8-
<input matEndDate formControlName="end" placeholder="End date">
7+
<input matStartDate formControlName="start" placeholder="Start date" (dateChange)="onChangeStart($event)">
8+
<input matEndDate formControlName="end" placeholder="End date" (dateChange)="onChangeEnd($event)">
99
</mat-date-range-input>
1010
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
1111
<mat-date-range-picker #picker></mat-date-range-picker>

0 commit comments

Comments
 (0)