Skip to content

Commit 00da30b

Browse files
authored
Merge pull request #2715 from JaySoni1/WEB-185-made-on-date-and-checked-on-date-should-show-full-datetime-with-timezone-information-or-explicitly-convert-the-epoch-time-to-utc
WEB-185-made-on-date-and-checked-on-date-should-show-full-datetime-with-timezone-information-or-explicitly-convert-the-epoch-time-to-utc
2 parents bddeb56 + 94e929a commit 00da30b

File tree

6 files changed

+196
-68
lines changed

6 files changed

+196
-68
lines changed
Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
import { Pipe, PipeTransform } from '@angular/core';
2-
import { SettingsService } from 'app/settings/settings.service';
3-
import moment from 'moment';
2+
import moment, { Moment } from 'moment';
43

5-
@Pipe({ name: 'datetimeFormat' })
4+
@Pipe({ name: 'datetimeFormat', standalone: true })
65
export class DatetimeFormatPipe implements PipeTransform {
7-
constructor(private settingsService: SettingsService) {}
8-
9-
transform(value: any, datetimeFormat?: string): any {
10-
const defaultDateFormat = this.settingsService.dateFormat.replace('dd', 'DD');
11-
if (typeof value === 'undefined') {
12-
return '';
13-
}
14-
let dateVal;
15-
if (value instanceof Array) {
16-
dateVal = moment(value.join('-'), 'YYYY-MM-DD HH:mm:ss');
6+
transform(value: unknown, datetimeFormat?: string): string {
7+
if (value == null || value === '') return '';
8+
let dateVal: Moment;
9+
if (Array.isArray(value)) {
10+
const [
11+
y,
12+
m,
13+
d,
14+
hh,
15+
mm,
16+
ss
17+
] = value as number[];
18+
if (hh != null) {
19+
dateVal = moment({ year: y, month: (m ?? 1) - 1, date: d, hour: hh, minute: mm ?? 0, second: ss ?? 0 });
20+
} else {
21+
dateVal = moment({ year: y, month: (m ?? 1) - 1, date: d });
22+
}
23+
} else if (typeof value === 'number' && value < 1e12) {
24+
// epoch seconds
25+
dateVal = moment.unix(value);
1726
} else {
18-
dateVal = moment(value);
19-
}
20-
if (datetimeFormat == null) {
21-
return dateVal.format(defaultDateFormat + ' HH:mm:ss');
27+
dateVal = moment(value as any);
2228
}
23-
return dateVal.format(datetimeFormat);
29+
const fmt = datetimeFormat ?? 'YYYY-MM-DDTHH:mm:ssZ';
30+
return dateVal.format(fmt);
2431
}
2532
}

src/app/system/audit-trails/audit-trails.component.html

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</button>
66
</div>
77

8-
<div class="container layout-row-wrap gap-2px responsive-column">
8+
<div class="container layout-row-wrap gap-8px responsive-column">
99
<mat-form-field class="flex-48">
1010
<mat-label>{{ 'labels.inputs.Resource ID' | translate }}</mat-label>
1111
<input matInput [formControl]="resourceId" />
@@ -43,45 +43,89 @@
4343
<input matInput [formControl]="checker" [matAutocomplete]="checkerAutocomplete" />
4444
</mat-form-field>
4545

46-
<mat-form-field class="flex-48" (click)="fromDatePicker.open()">
47-
<mat-label>{{ 'labels.inputs.Maker From Date' | translate }}</mat-label>
48-
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="fromDatePicker" [formControl]="fromDate" />
49-
<mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
50-
<mat-datepicker #fromDatePicker></mat-datepicker>
51-
</mat-form-field>
46+
<div class="flex-48 layout-row-wrap gap-8px">
47+
<mat-form-field class="flex-60" (click)="fromDatePicker.open()">
48+
<mat-label>{{ 'labels.inputs.Maker From Date' | translate }}</mat-label>
49+
<input
50+
matInput
51+
[min]="minDate"
52+
[max]="maxDate"
53+
[matDatepicker]="fromDatePicker"
54+
[formControl]="fromDate"
55+
placeholder="YYYY-MM-DD"
56+
/>
57+
<mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
58+
<mat-datepicker #fromDatePicker></mat-datepicker>
59+
</mat-form-field>
60+
61+
<mat-form-field class="flex-38">
62+
<mat-label>{{ 'labels.inputs.Time' | translate }}</mat-label>
63+
<input matInput type="time" step="1" [formControl]="fromTime" placeholder="HH:MM:SS" class="time-input" />
64+
</mat-form-field>
65+
</div>
5266

53-
<mat-form-field class="flex-48" (click)="toDatePicker.open()">
54-
<mat-label>{{ 'labels.inputs.Maker To Date' | translate }}</mat-label>
55-
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="toDatePicker" [formControl]="toDate" />
56-
<mat-datepicker-toggle matSuffix [for]="toDatePicker"></mat-datepicker-toggle>
57-
<mat-datepicker #toDatePicker></mat-datepicker>
58-
</mat-form-field>
67+
<div class="flex-48 layout-row-wrap gap-8px">
68+
<mat-form-field class="flex-60" (click)="toDatePicker.open()">
69+
<mat-label>{{ 'labels.inputs.Maker To Date' | translate }}</mat-label>
70+
<input
71+
matInput
72+
[min]="minDate"
73+
[max]="maxDate"
74+
[matDatepicker]="toDatePicker"
75+
[formControl]="toDate"
76+
placeholder="YYYY-MM-DD"
77+
/>
78+
<mat-datepicker-toggle matSuffix [for]="toDatePicker"></mat-datepicker-toggle>
79+
<mat-datepicker #toDatePicker></mat-datepicker>
80+
</mat-form-field>
81+
82+
<mat-form-field class="flex-38">
83+
<mat-label>{{ 'labels.inputs.Time' | translate }}</mat-label>
84+
<input matInput type="time" step="1" [formControl]="toTime" placeholder="HH:MM:SS" class="time-input" />
85+
</mat-form-field>
86+
</div>
5987

60-
<mat-form-field class="flex-48" (click)="checkedFromDatePicker.open()">
61-
<mat-label>{{ 'labels.inputs.Checker From Date' | translate }}</mat-label>
62-
<input
63-
matInput
64-
[min]="minDate"
65-
[max]="maxDate"
66-
[matDatepicker]="checkedFromDatePicker"
67-
[formControl]="checkedFromDate"
68-
/>
69-
<mat-datepicker-toggle matSuffix [for]="checkedFromDatePicker"></mat-datepicker-toggle>
70-
<mat-datepicker #checkedFromDatePicker></mat-datepicker>
71-
</mat-form-field>
88+
<div class="flex-48 layout-row-wrap gap-8px">
89+
<mat-form-field class="flex-60" (click)="checkedFromDatePicker.open()">
90+
<mat-label>{{ 'labels.inputs.Checker From Date' | translate }}</mat-label>
91+
<input
92+
matInput
93+
[min]="minDate"
94+
[max]="maxDate"
95+
[matDatepicker]="checkedFromDatePicker"
96+
[formControl]="checkedFromDate"
97+
placeholder="YYYY-MM-DD"
98+
/>
99+
<mat-datepicker-toggle matSuffix [for]="checkedFromDatePicker"></mat-datepicker-toggle>
100+
<mat-datepicker #checkedFromDatePicker></mat-datepicker>
101+
</mat-form-field>
102+
103+
<mat-form-field class="flex-38">
104+
<mat-label>{{ 'labels.inputs.Time' | translate }}</mat-label>
105+
<input matInput type="time" step="1" [formControl]="checkedFromTime" placeholder="HH:MM:SS" class="time-input" />
106+
</mat-form-field>
107+
</div>
72108

73-
<mat-form-field class="flex-48" (click)="checkedToDatePicker.open()">
74-
<mat-label>{{ 'labels.inputs.Checked To Date' | translate }}</mat-label>
75-
<input
76-
matInput
77-
[min]="minDate"
78-
[max]="maxDate"
79-
[matDatepicker]="checkedToDatePicker"
80-
[formControl]="checkedToDate"
81-
/>
82-
<mat-datepicker-toggle matSuffix [for]="checkedToDatePicker"></mat-datepicker-toggle>
83-
<mat-datepicker #checkedToDatePicker></mat-datepicker>
84-
</mat-form-field>
109+
<div class="flex-48 layout-row-wrap gap-8px">
110+
<mat-form-field class="flex-60" (click)="checkedToDatePicker.open()">
111+
<mat-label>{{ 'labels.inputs.Checked To Date' | translate }}</mat-label>
112+
<input
113+
matInput
114+
[min]="minDate"
115+
[max]="maxDate"
116+
[matDatepicker]="checkedToDatePicker"
117+
[formControl]="checkedToDate"
118+
placeholder="YYYY-MM-DD"
119+
/>
120+
<mat-datepicker-toggle matSuffix [for]="checkedToDatePicker"></mat-datepicker-toggle>
121+
<mat-datepicker #checkedToDatePicker></mat-datepicker>
122+
</mat-form-field>
123+
124+
<mat-form-field class="flex-38">
125+
<mat-label>{{ 'labels.inputs.Time' | translate }}</mat-label>
126+
<input matInput type="time" step="1" [formControl]="checkedToTime" placeholder="HH:MM:SS" class="time-input" />
127+
</mat-form-field>
128+
</div>
85129
</div>
86130

87131
<!-- Autocomplete data -->
@@ -151,7 +195,7 @@
151195

152196
<ng-container matColumnDef="madeOnDate">
153197
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Made Date' | translate }}</th>
154-
<td mat-cell *matCellDef="let auditTrail">{{ auditTrail.madeOnDate | dateFormat }}</td>
198+
<td mat-cell *matCellDef="let auditTrail">{{ auditTrail.madeOnDate | datetimeFormat }}</td>
155199
</ng-container>
156200

157201
<ng-container matColumnDef="checker">
@@ -161,7 +205,7 @@
161205

162206
<ng-container matColumnDef="checkedOnDate">
163207
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Checked Date' | translate }}</th>
164-
<td mat-cell *matCellDef="let auditTrail">{{ auditTrail.checkedOnDate | dateFormat }}</td>
208+
<td mat-cell *matCellDef="let auditTrail">{{ auditTrail.checkedOnDate | datetimeFormat }}</td>
165209
</ng-container>
166210

167211
<ng-container matColumnDef="clientIp">

src/app/system/audit-trails/audit-trails.component.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,14 @@ table {
55
cursor: pointer;
66
}
77
}
8+
9+
.flex-38 {
10+
.time-input {
11+
font-size: 14px;
12+
width: 100%;
13+
}
14+
}
15+
16+
.gap-8px {
17+
gap: 8px;
18+
}

src/app/system/audit-trails/audit-trails.component.ts

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
MatRowDef,
3333
MatRow
3434
} from '@angular/material/table';
35-
import { DateFormatPipe } from '../../pipes/date-format.pipe';
35+
import { DatetimeFormatPipe } from '../../pipes/datetime-format.pipe';
3636
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
3737

3838
/**
@@ -62,7 +62,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
6262
MatRow,
6363
MatPaginator,
6464
AsyncPipe,
65-
DateFormatPipe
65+
DatetimeFormatPipe
6666
]
6767
})
6868
export class AuditTrailsComponent implements OnInit, AfterViewInit {
@@ -153,8 +153,12 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
153153
user = new UntypedFormControl('');
154154
/** From date form control. */
155155
fromDate = new UntypedFormControl();
156+
/** From time form control. */
157+
fromTime = new UntypedFormControl();
156158
/** Checked from date form control. */
157159
checkedFromDate = new UntypedFormControl();
160+
/** Checked from time form control. */
161+
checkedFromTime = new UntypedFormControl();
158162
/** Processing result form control. */
159163
processingResult = new UntypedFormControl();
160164
/** Action name form control. */
@@ -163,8 +167,12 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
163167
resourceId = new UntypedFormControl('');
164168
/** To date form control. */
165169
toDate = new UntypedFormControl();
170+
/** To time form control. */
171+
toTime = new UntypedFormControl();
166172
/** Checked to date form control. */
167173
checkedToDate = new UntypedFormControl();
174+
/** Checked to time form control. */
175+
checkedToTime = new UntypedFormControl();
168176
/** Entity name form control. */
169177
entityName = new UntypedFormControl();
170178
/** Checker form control. */
@@ -230,7 +238,17 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
230238
debounceTime(500),
231239
distinctUntilChanged(),
232240
tap((filterValue) => {
233-
this.applyFilter(this.getDate(filterValue), 'makerDateTimeFrom');
241+
this.applyFilter(this.getDateTime(filterValue, this.fromTime.value), 'makerDateTimeFrom');
242+
})
243+
)
244+
.subscribe();
245+
246+
this.fromTime.valueChanges
247+
.pipe(
248+
debounceTime(500),
249+
distinctUntilChanged(),
250+
tap((timeValue) => {
251+
this.applyFilter(this.getDateTime(this.fromDate.value, timeValue), 'makerDateTimeFrom');
234252
})
235253
)
236254
.subscribe();
@@ -240,7 +258,17 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
240258
debounceTime(500),
241259
distinctUntilChanged(),
242260
tap((filterValue) => {
243-
this.applyFilter(this.getDate(filterValue), 'makerDateTimeTo');
261+
this.applyFilter(this.getDateTime(filterValue, this.toTime.value), 'makerDateTimeTo');
262+
})
263+
)
264+
.subscribe();
265+
266+
this.toTime.valueChanges
267+
.pipe(
268+
debounceTime(500),
269+
distinctUntilChanged(),
270+
tap((timeValue) => {
271+
this.applyFilter(this.getDateTime(this.toDate.value, timeValue), 'makerDateTimeTo');
244272
})
245273
)
246274
.subscribe();
@@ -250,7 +278,17 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
250278
debounceTime(500),
251279
distinctUntilChanged(),
252280
tap((filterValue) => {
253-
this.applyFilter(this.getDate(filterValue), 'checkerDateTimeFrom');
281+
this.applyFilter(this.getDateTime(filterValue, this.checkedFromTime.value), 'checkerDateTimeFrom');
282+
})
283+
)
284+
.subscribe();
285+
286+
this.checkedFromTime.valueChanges
287+
.pipe(
288+
debounceTime(500),
289+
distinctUntilChanged(),
290+
tap((timeValue) => {
291+
this.applyFilter(this.getDateTime(this.checkedFromDate.value, timeValue), 'checkerDateTimeFrom');
254292
})
255293
)
256294
.subscribe();
@@ -260,7 +298,17 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
260298
debounceTime(500),
261299
distinctUntilChanged(),
262300
tap((filterValue) => {
263-
this.applyFilter(this.getDate(filterValue), 'checkerDateTimeTo');
301+
this.applyFilter(this.getDateTime(filterValue, this.checkedToTime.value), 'checkerDateTimeTo');
302+
})
303+
)
304+
.subscribe();
305+
306+
this.checkedToTime.valueChanges
307+
.pipe(
308+
debounceTime(500),
309+
distinctUntilChanged(),
310+
tap((timeValue) => {
311+
this.applyFilter(this.getDateTime(this.checkedToDate.value, timeValue), 'checkerDateTimeTo');
264312
})
265313
)
266314
.subscribe();
@@ -502,8 +550,9 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
502550
let csv = response.pageItems.map((row: any) =>
503551
headerCode.map((fieldName) =>
504552
(fieldName === 'madeOnDate' || fieldName === 'checkedOnDate') &&
505-
JSON.stringify(row[fieldName], replacer) !== '""'
506-
? this.dateUtils.formatDate(JSON.stringify(row[fieldName], replacer), dateFormat)
553+
row[fieldName] != null &&
554+
row[fieldName] !== ''
555+
? JSON.stringify(this.dateUtils.formatDate(row[fieldName], 'YYYY-MM-DDTHH:mm:ssZ'))
507556
: JSON.stringify(row[fieldName], replacer)
508557
)
509558
);
@@ -530,4 +579,21 @@ export class AuditTrailsComponent implements OnInit, AfterViewInit {
530579
const dateFormat = this.settingsService.dateFormat;
531580
return this.dateUtils.formatDate(timestamp, dateFormat);
532581
}
582+
private getDateTime(date: Date, timeStr: string): string {
583+
if (!date) {
584+
return '';
585+
}
586+
const result = new Date(date);
587+
if (timeStr) {
588+
const [
589+
hours,
590+
minutes,
591+
seconds
592+
] = timeStr.split(':').map(Number);
593+
result.setHours(hours || 0);
594+
result.setMinutes(minutes || 0);
595+
result.setSeconds(seconds || 0);
596+
}
597+
return this.dateUtils.formatDate(result, 'YYYY-MM-DDTHH:mm:ssZ');
598+
}
533599
}

src/app/system/audit-trails/view-audit/view-audit.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
</div>
5858

5959
<div class="flex-50">
60-
{{ auditTrailData.madeOnDate | dateFormat }}
60+
{{ auditTrailData.madeOnDate | datetimeFormat }}
6161
</div>
6262

6363
<div class="flex-50 mat-body-strong" *ngIf="auditTrailData.officeName">

src/app/system/audit-trails/view-audit/view-audit.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
MatRowDef,
1717
MatRow
1818
} from '@angular/material/table';
19-
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
19+
import { DatetimeFormatPipe } from '../../../pipes/datetime-format.pipe';
2020
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
2121

2222
/**
@@ -40,7 +40,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
4040
MatHeaderRow,
4141
MatRowDef,
4242
MatRow,
43-
DateFormatPipe
43+
DatetimeFormatPipe
4444
]
4545
})
4646
export class ViewAuditComponent implements OnInit {

0 commit comments

Comments
 (0)