From 5f25128366bcbbb533a91c24e36b41e804bf22f7 Mon Sep 17 00:00:00 2001 From: Yves Peter Date: Fri, 27 Nov 2020 15:53:08 +0100 Subject: [PATCH 1/4] use moment to parse time in date-time-picker to fix parsing bugs --- .../deployments/deployments-list.component.ts | 1 - .../date-time-picker.component.html | 2 +- .../date-time-picker.component.ts | 30 +++-------- .../date-time-picker/date-time.model.ts | 54 +++---------------- 4 files changed, 15 insertions(+), 72 deletions(-) diff --git a/AMW_angular/io/src/app/deployments/deployments-list.component.ts b/AMW_angular/io/src/app/deployments/deployments-list.component.ts index fb78f0b4b..34d84ee40 100644 --- a/AMW_angular/io/src/app/deployments/deployments-list.component.ts +++ b/AMW_angular/io/src/app/deployments/deployments-list.component.ts @@ -87,7 +87,6 @@ export class DeploymentsListComponent { } doDateChange() { - debugger; if (this.deployment) { this.errorMessage = ''; const dateTime = moment(this.deploymentDate, DATE_FORMAT); diff --git a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html index abbefe545..4a0a25385 100644 --- a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html +++ b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html @@ -3,7 +3,7 @@ [ngClass]="ngControl?.valid ? 'ng-valid' : 'ng-invalid'" class="form-control" (blur)="inputBlur($event)" - [ngModel]="dateString | date: inputDatetimeFormat" + [ngModel]="dateString" (change)="onInputChange($event)" [disabled]="disabled" /> diff --git a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts index 1941ad50a..67390f7b3 100644 --- a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts +++ b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts @@ -40,8 +40,9 @@ export class DateTimePickerComponent @Input() dateString: string; + // moment js format @Input() - inputDatetimeFormat = 'dd.MM.yyyy HH:mm'; + dateStringFormat = 'DD.MM.yyyy HH:mm'; @Input() hourStep = 1; @Input() @@ -88,7 +89,7 @@ export class DateTimePickerComponent if (newModel) { this.datetime = Object.assign( this.datetime, - DateTimeModel.fromLocalString(newModel) + DateTimeModel.fromLocalString(newModel, this.dateStringFormat) ); this.dateString = newModel; this.setDateStringModel(); @@ -116,7 +117,7 @@ export class DateTimePickerComponent onInputChange($event: any) { const value = $event.target.value; - const dt = DateTimeModel.fromLocalString(value); + const dt = DateTimeModel.fromLocalString(value, this.dateStringFormat); if (dt) { this.datetime = dt; @@ -131,24 +132,9 @@ export class DateTimePickerComponent } onDateChange($event) { - if ($event.year) { - $event = `${$event.year}-${$event.month}-${$event.day}`; - } - - const date = DateTimeModel.fromLocalString($event); - - if (!date) { - this.dateString = this.dateString; - return; - } - - if (!this.datetime) { - this.datetime = date; - } - - this.datetime.year = date.year; - this.datetime.month = date.month; - this.datetime.day = date.day; + this.datetime.year = $event.year; + this.datetime.month = $event.month; + this.datetime.day = $event.day; this.dp.navigateTo({ year: this.datetime.year, @@ -166,7 +152,7 @@ export class DateTimePickerComponent } setDateStringModel() { - this.dateString = this.datetime.toString(); + this.dateString = this.datetime.toString(this.dateStringFormat); this.onChange(this.dateString); } diff --git a/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts b/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts index 18060e749..852e169d4 100644 --- a/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts +++ b/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts @@ -1,5 +1,5 @@ import { NgbTimeStruct, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; -import { DatePipe } from '@angular/common'; +import * as moment from 'moment'; export interface NgbDateTimeStruct extends NgbDateStruct, NgbTimeStruct {} @@ -17,9 +17,8 @@ export class DateTimeModel implements NgbDateTimeStruct { Object.assign(this, init); } - public static fromLocalString(dateString: string): DateTimeModel { - const date = new Date(dateString); - + public static fromLocalString(dateString: string, format: string): DateTimeModel { + const date = moment(dateString, format).toDate(); const isValidDate = !isNaN(date.valueOf()); if (!dateString || !isValidDate) { @@ -45,49 +44,8 @@ export class DateTimeModel implements NgbDateTimeStruct { ); } - public toString(): string { - if ( - this.isInteger(this.year) && - this.isInteger(this.month) && - this.isInteger(this.day) - ) { - const year = this.year.toString().padStart(2, '0'); - const month = this.month.toString().padStart(2, '0'); - const day = this.day.toString().padStart(2, '0'); - - if (!this.hour) { - this.hour = 0; - } - if (!this.minute) { - this.minute = 0; - } - if (!this.second) { - this.second = 0; - } - - this.timeZoneOffset = new Date( - this.year, - this.month - 1, // javascript has zero-based months - this.day - ).getTimezoneOffset(); - - const hour = this.hour.toString().padStart(2, '0'); - const minute = this.minute.toString().padStart(2, '0'); - const second = this.second.toString().padStart(2, '0'); - - const tzo = -this.timeZoneOffset; - const dif = tzo >= 0 ? '+' : '-'; - const pad = (num) => { - const norm = Math.floor(Math.abs(num)); - return (norm < 10 ? '0' : '') + norm; - }; - - const isoString = `${pad(year)}-${pad(month)}-${pad(day)}T${pad( - hour - )}:${pad(minute)}:${pad(second)}${dif}${pad(tzo / 60)}:${pad(tzo % 60)}`; - return isoString; - } - - return null; + public toString(format: string): string { + const m = moment({ year: this.year, month: this.month - 1, day: this.day, hour: this.hour, minute: this.minute, second: this.second}); + return m.format(format); } } From 3cc31f826a0496c9a48e54b8d683a6b716f4fdbc Mon Sep 17 00:00:00 2001 From: Yves Peter Date: Mon, 30 Nov 2020 10:13:20 +0100 Subject: [PATCH 2/4] switch ngModel from timepicker from string to struct --- .../deployments/deployments-list.component.ts | 17 +++++----- .../date-time-picker.component.html | 3 +- .../date-time-picker.component.ts | 33 +++++++++---------- .../date-time-picker/date-time.model.ts | 23 +++++++++---- 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/AMW_angular/io/src/app/deployments/deployments-list.component.ts b/AMW_angular/io/src/app/deployments/deployments-list.component.ts index 34d84ee40..0a561572d 100644 --- a/AMW_angular/io/src/app/deployments/deployments-list.component.ts +++ b/AMW_angular/io/src/app/deployments/deployments-list.component.ts @@ -3,8 +3,7 @@ import { Deployment } from '../deployment/deployment'; import { DeploymentFilter } from '../deployment/deployment-filter'; import { ResourceService } from '../resource/resource.service'; import * as _ from 'lodash'; -import * as moment from 'moment'; -import { DATE_FORMAT } from '../core/amw-constants'; +import { DateTimeModel } from '../shared/date-time-picker/date-time.model'; @Component({ selector: 'amw-deployments-list', @@ -34,7 +33,7 @@ export class DeploymentsListComponent { deployment: Deployment; - deploymentDate: number; + deploymentDate: DateTimeModel = new DateTimeModel(); hasPermissionShakedownTest: boolean = null; @@ -62,6 +61,7 @@ export class DeploymentsListComponent { showDateChange(deploymentId: number) { this.deployment = _.find(this.deployments, ['id', deploymentId]); + this.deploymentDate = DateTimeModel.fromEpoch(this.deployment.deploymentDate); $('#deploymentDateChange').modal('show'); } @@ -89,16 +89,17 @@ export class DeploymentsListComponent { doDateChange() { if (this.deployment) { this.errorMessage = ''; - const dateTime = moment(this.deploymentDate, DATE_FORMAT); - if (!dateTime || !dateTime.isValid()) { - this.errorMessage = 'Invalid date'; - } else { + const dateTime = this.deploymentDate.toEpoch(); + // todo: move to timepicker + // if (!dateTime || !dateTime.isValid()) { + // this.errorMessage = 'Invalid date'; + // } else { this.deployment.deploymentDate = dateTime.valueOf(); this.editDeploymentDate.emit(this.deployment); $('#deploymentDateChange').modal('hide'); delete this.deployment; delete this.deploymentDate; - } + // } } } diff --git a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html index 4a0a25385..74c761a2c 100644 --- a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html +++ b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.html @@ -4,8 +4,9 @@ class="form-control" (blur)="inputBlur($event)" [ngModel]="dateString" - (change)="onInputChange($event)" + (change)="onDateStringChange($event)" [disabled]="disabled" + placeholder="{{ dateStringFormat }}" />
diff --git a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts index 67390f7b3..ec85655d1 100644 --- a/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts +++ b/AMW_angular/io/src/app/shared/date-time-picker/date-time-picker.component.ts @@ -51,12 +51,10 @@ export class DateTimePickerComponent secondStep = 30; @Input() seconds = false; - @Input() disabled = false; showTimePickerToggle = false; - datetime = new DateTimeModel(); @ViewChild(NgbDatepicker) @@ -85,14 +83,12 @@ export class DateTimePickerComponent }); } - writeValue(newModel: string) { + writeValue(newModel: DateTimeModel) { + debugger; if (newModel) { - this.datetime = Object.assign( - this.datetime, - DateTimeModel.fromLocalString(newModel, this.dateStringFormat) - ); - this.dateString = newModel; - this.setDateStringModel(); + this.datetime = Object.assign(this.datetime, newModel) + //this.datetime = newModel; + this.setDateString(); } else { this.datetime = new DateTimeModel(); } @@ -115,23 +111,24 @@ export class DateTimePickerComponent this.disabled = isDisabled; } - onInputChange($event: any) { + // called when user updates the datestring directly + onDateStringChange($event: any) { const value = $event.target.value; const dt = DateTimeModel.fromLocalString(value, this.dateStringFormat); + //todo: handle invalid datestring if (dt) { this.datetime = dt; - this.setDateStringModel(); + this.onChange(dt); } else if (value.trim() === '') { this.datetime = new DateTimeModel(); this.dateString = ''; - this.onChange(this.dateString); - } else { - this.onChange(value); + this.onChange(this.datetime); } } onDateChange($event) { + debugger; this.datetime.year = $event.year; this.datetime.month = $event.month; this.datetime.day = $event.day; @@ -140,7 +137,7 @@ export class DateTimePickerComponent year: this.datetime.year, month: this.datetime.month, }); - this.setDateStringModel(); + this.setDateString(); } onTimeChange(event: NgbTimeStruct) { @@ -148,12 +145,12 @@ export class DateTimePickerComponent this.datetime.minute = event.minute; this.datetime.second = event.second; - this.setDateStringModel(); + this.setDateString(); } - setDateStringModel() { + setDateString() { this.dateString = this.datetime.toString(this.dateStringFormat); - this.onChange(this.dateString); + this.onChange(this.datetime); } inputBlur($event) { diff --git a/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts b/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts index 852e169d4..3261d37f9 100644 --- a/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts +++ b/AMW_angular/io/src/app/shared/date-time-picker/date-time.model.ts @@ -36,16 +36,27 @@ export class DateTimeModel implements NgbDateTimeStruct { }); } - private isInteger(value: any): value is number { - return ( - typeof value === 'number' && - isFinite(value) && - Math.floor(value) === value - ); + public static fromEpoch(epoch: number) { + debugger; + const date = moment(epoch).toDate(); + return new DateTimeModel({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + timeZoneOffset: date.getTimezoneOffset(), + }); } public toString(format: string): string { const m = moment({ year: this.year, month: this.month - 1, day: this.day, hour: this.hour, minute: this.minute, second: this.second}); return m.format(format); } + + public toEpoch(): number { + const m = moment({ year: this.year, month: this.month - 1, day: this.day, hour: this.hour, minute: this.minute, second: this.second}); + return m.valueOf(); + } } From b16ac58b29765c26058d6adbbca946c2d0dc5d36 Mon Sep 17 00:00:00 2001 From: Yves Peter Date: Mon, 30 Nov 2020 17:45:58 +0100 Subject: [PATCH 3/4] Cleanup DateTimeModel, move error message to datetimepicker, better null handling, set start date for datepicker, remove consoel.log() --- .../auditview-table.service.ts | 1 - .../app/deployment/deployment.component.ts | 13 ++--- .../deployments-list.component.html | 15 ------ .../deployments/deployments-list.component.ts | 20 ++----- .../app/permission/permission.component.ts | 1 - .../date-time-picker.component.html | 7 +++ .../date-time-picker.component.ts | 32 ++++++----- .../date-time-picker/date-time.model.ts | 54 ++++++++++--------- 8 files changed, 58 insertions(+), 85 deletions(-) diff --git a/AMW_angular/io/src/app/auditview/auditview-table/auditview-table.service.ts b/AMW_angular/io/src/app/auditview/auditview-table/auditview-table.service.ts index d6c3201b2..67a723eb9 100644 --- a/AMW_angular/io/src/app/auditview/auditview-table/auditview-table.service.ts +++ b/AMW_angular/io/src/app/auditview/auditview-table/auditview-table.service.ts @@ -75,7 +75,6 @@ export class AuditviewTableService { tap(() => this._loading$.next(true)), debounceTime(200), map(([searchTerm, sortColumn, sortDirection, auditlogEntries]) => { - console.log('mapping it'); return this._search( searchTerm, sortColumn, diff --git a/AMW_angular/io/src/app/deployment/deployment.component.ts b/AMW_angular/io/src/app/deployment/deployment.component.ts index 819dd9874..d881543f5 100644 --- a/AMW_angular/io/src/app/deployment/deployment.component.ts +++ b/AMW_angular/io/src/app/deployment/deployment.component.ts @@ -19,6 +19,7 @@ import * as moment from 'moment'; import * as $ from 'jquery'; // this needs to be here... import { NavigationStoreService } from '../navigation/navigation-store.service'; import { DATE_FORMAT } from '../core/amw-constants'; +import { DateTimeModel } from '../shared/date-time-picker/date-time.model'; @Component({ selector: 'amw-deployment', @@ -46,7 +47,7 @@ export class DeploymentComponent implements OnInit, AfterViewInit { runtime: Relation = null; resourceTags: ResourceTag[] = [this.defaultResourceTag]; selectedResourceTag: ResourceTag = this.defaultResourceTag; - deploymentDate: string = ''; + deploymentDate: DateTimeModel = new DateTimeModel(); appsWithVersion: AppWithVersion[] = []; transDeploymentParameter: DeploymentParameter = {} as DeploymentParameter; transDeploymentParameters: DeploymentParameter[] = []; @@ -134,7 +135,6 @@ export class DeploymentComponent implements OnInit, AfterViewInit { if (!this.selectedRelease) { this.selectedRelease = this.releases[0]; } - console.log('selected release is ' + this.selectedRelease.release); this.getRelatedForRelease(); this.goTo(this.selectedAppserver.name + '/' + this.selectedRelease.release); } @@ -171,13 +171,11 @@ export class DeploymentComponent implements OnInit, AfterViewInit { requestDeployment() { this.requestOnly = true; - console.log('requestDeployment()'); this.prepareDeployment(); } createDeployment() { this.requestOnly = false; - console.log('createDeployment()'); this.prepareDeployment(); } @@ -418,10 +416,7 @@ export class DeploymentComponent implements OnInit, AfterViewInit { : new Date().getTime(); } if (this.deploymentDate) { - const dateTime = moment(this.deploymentDate, DATE_FORMAT); - if (dateTime && dateTime.isValid()) { - deploymentRequest.deploymentDate = dateTime.valueOf(); - } + deploymentRequest.deploymentDate = this.deploymentDate.toEpoch(); } if (this.transDeploymentParameters.length > 0) { deploymentRequest.deploymentParameters = this.transDeploymentParameters; @@ -487,7 +482,6 @@ export class DeploymentComponent implements OnInit, AfterViewInit { // for url params only private setPreselected() { if (this.appserverName) { - console.log('pre-selected server is ' + this.appserverName); this.selectedAppserver = _.find(this.appservers, { name: this.appserverName, }); @@ -521,7 +515,6 @@ export class DeploymentComponent implements OnInit, AfterViewInit { // for url params only private setRelease() { if (this.releaseName) { - console.log('pre-selected release is ' + this.releaseName); this.selectedRelease = this.releases.find( (release) => release.release === this.releaseName ); diff --git a/AMW_angular/io/src/app/deployments/deployments-list.component.html b/AMW_angular/io/src/app/deployments/deployments-list.component.html index 8359251d5..063d4f3d2 100644 --- a/AMW_angular/io/src/app/deployments/deployments-list.component.html +++ b/AMW_angular/io/src/app/deployments/deployments-list.component.html @@ -309,21 +309,6 @@