fix(console): Timestamp to date Pipe type coercion (#10588)

# Which Problems Are Solved
Correctly display timestamps even if the seconds or nanos property is 0.

# How the Problems Are Solved
Instead of relying on javascript type coercion correctly check explictly
for undefined.

# Additional Changes

Use TypeSafeCellDefModule in personal-access-tokens component.

# Additional Context

- Closes #10032

Co-authored-by: Max Peintner <[email protected]>
Co-authored-by: Livio Spring <[email protected]>
This commit is contained in:
Ramon
2025-09-01 06:02:35 +00:00
committed by GitHub
co-authored by Max Peintner Livio Spring
parent a9ebc06c77
commit 93fd27aebe
4 changed files with 11 additions and 10 deletions
@@ -29,7 +29,7 @@
>
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let key">
<td mat-cell *cnslCellDef="let key; dataSource: dataSource">
<mat-checkbox
color="primary"
(click)="$event.stopPropagation()"
@@ -42,26 +42,26 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef>{{ 'USER.PERSONALACCESSTOKEN.ID' | translate }}</th>
<td mat-cell *matCellDef="let key">{{ key?.id }}</td>
<td mat-cell *cnslCellDef="let key; dataSource: dataSource">{{ key?.id }}</td>
</ng-container>
<ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MACHINE.CREATIONDATE' | translate }}</th>
<td mat-cell *matCellDef="let key">
<td mat-cell *cnslCellDef="let key; dataSource: dataSource">
{{ key.details?.creationDate | timestampToDate | localizedDate: 'fromNow' }}
</td>
</ng-container>
<ng-container matColumnDef="expirationDate">
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MACHINE.EXPIRATIONDATE' | translate }}</th>
<td mat-cell *matCellDef="let key">
<td mat-cell *cnslCellDef="let key; dataSource: dataSource">
{{ key.expirationDate | timestampToDate | localizedDate: 'EEE dd. MMM yyyy, HH:mm' }}
</td>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let key">
<td mat-cell *cnslCellDef="let key; dataSource: dataSource">
<cnsl-table-actions>
<button
actions
@@ -6,7 +6,6 @@ import { TranslateService } from '@ngx-translate/core';
import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';
import { Moment } from 'moment';
import { BehaviorSubject, Observable } from 'rxjs';
import { Key } from 'src/app/proto/generated/zitadel/auth_n_key_pb';
import { ListPersonalAccessTokensResponse } from 'src/app/proto/generated/zitadel/management_pb';
import { PersonalAccessToken } from 'src/app/proto/generated/zitadel/user_pb';
import { ManagementService } from 'src/app/services/mgmt.service';
@@ -52,7 +51,7 @@ export class PersonalAccessTokensComponent implements OnInit {
}
public ngOnInit(): void {
this.getData(10, 0);
this.getData(10, 0).then();
}
public isAllSelected(): boolean {
@@ -69,7 +68,7 @@ export class PersonalAccessTokensComponent implements OnInit {
this.getData(event.pageSize, event.pageIndex * event.pageSize);
}
public deleteKey(key: Key.AsObject): void {
public deleteKey(key: PersonalAccessToken.AsObject): void {
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.DELETE',
@@ -86,7 +85,7 @@ export class PersonalAccessTokensComponent implements OnInit {
.then(() => {
this.selection.clear();
this.toast.showInfo('USER.PERSONALACCESSTOKEN.DELETED', true);
this.getData(10, 0);
this.getData(10, 0).then();
})
.catch((error) => {
this.toast.showError(error);
@@ -14,6 +14,7 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { TypeSafeCellDefModule } from 'src/app/directives/type-safe-cell-def/type-safe-cell-def.module';
import { AddTokenDialogModule } from '../add-token-dialog/add-token-dialog.module';
import { CardModule } from '../card/card.module';
@@ -51,6 +52,7 @@ import { PersonalAccessTokensComponent } from './personal-access-tokens.componen
ShowTokenDialogModule,
WarnDialogModule,
AddTokenDialogModule,
TypeSafeCellDefModule,
],
exports: [PersonalAccessTokensComponent],
})
@@ -7,7 +7,7 @@ import { Timestamp } from 'src/app/proto/generated/google/protobuf/timestamp_pb'
})
export class TimestampToDatePipe implements PipeTransform {
transform(date: BufTimestamp | Timestamp.AsObject | undefined): Date | undefined {
if (date?.seconds && date.nanos) {
if (date?.seconds !== undefined && date.nanos !== undefined) {
return new Date(Number(date.seconds) * 1000 + date.nanos / 1000 / 1000);
}
return undefined;