This is an automated email from the ASF dual-hosted git repository. sardell pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/metron.git
The following commit(s) were added to refs/heads/master by this push: new ee1b2c3 METRON-1253 Manual pasting of timestamps into the timestamp picker (ruffle1986 via sardell) closes apache/metron#1380 ee1b2c3 is described below commit ee1b2c34d329a4fffbb6e900fe06112eda7bc8cd Author: ruffle1986 <ftamas.m...@gmail.com> AuthorDate: Tue Jun 18 10:30:10 2019 +0200 METRON-1253 Manual pasting of timestamps into the timestamp picker (ruffle1986 via sardell) closes apache/metron#1380 --- .../cypress/integration/pcap/pcap.spec.js | 2 +- .../shared/date-picker/date-picker.component.html | 13 ++++- .../date-picker/date-picker.component.spec.ts | 39 +++++++++++++++ .../shared/date-picker/date-picker.component.ts | 56 ++++++++++++++-------- 4 files changed, 87 insertions(+), 23 deletions(-) diff --git a/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js b/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js index fa0cd51..c5811a4 100644 --- a/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js +++ b/metron-interface/metron-alerts/cypress/integration/pcap/pcap.spec.js @@ -222,7 +222,7 @@ context('PCAP Tab', () => { it('showing date validation messages', () => { cy.contains('PCAP').click(); - cy.get('[data-qe-id="end-time"]').click(); + cy.get('[data-qe-id="end-time"] .input-group-text.calendar').click(); cy.get('.pika-select-year').select('2015'); cy.get('[data-day="11"] > .pika-button').click(); diff --git a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.html b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.html index 05840df..cb5fbc5 100644 --- a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.html +++ b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.html @@ -12,8 +12,17 @@ the specific language governing permissions and limitations under the License. --> <div #inputText class="input-group"> - <input class="form-control" [(ngModel)]="dateStr" (click)="toggleDatePicker($event)"> + <input + class="form-control" + [(ngModel)]="dateStr" + (focus)="onFocus()" + (blur)="onBlur($event)" + (keyup)="onKeyup($event)" + > <div class="input-group-append"> - <span class="input-group-text calendar"></span> + <span + #calendarIcon + class="input-group-text calendar" + ></span> </div> </div> diff --git a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.spec.ts b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.spec.ts index a7765e0..ab656c0 100644 --- a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.spec.ts +++ b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.spec.ts @@ -20,6 +20,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { DatePickerComponent } from './date-picker.component'; import { FormsModule } from '@angular/forms'; +import { By } from '@angular/platform-browser'; describe('DatePickerComponent', () => { let component: DatePickerComponent; @@ -44,4 +45,42 @@ describe('DatePickerComponent', () => { it('should be created', () => { expect(component).toBeTruthy(); }); + + it('should set the date on blur', () => { + const input = fixture.debugElement.query(By.css('input')).nativeElement; + input.value = '2019-04-30'; + expect(component.dateStr).toBe('now'); + input.dispatchEvent(new Event('blur')); + expect(component.dateStr).toBe('2019-04-30'); + }); + + it('should not set the date on blur if value is invalid', () => { + const input = fixture.debugElement.query(By.css('input')).nativeElement; + input.value = 'invalid date'; + expect(component.dateStr).toBe('now'); + input.dispatchEvent(new Event('blur')); + expect(component.dateStr).toBe('now'); + }); + + it('should set the date on enter', () => { + const input = fixture.debugElement.query(By.css('input')).nativeElement; + input.value = '2019-04-30'; + expect(component.dateStr).toBe('now'); + const e = new KeyboardEvent('keyup', { + code: 'Enter', + }); + input.dispatchEvent(e); + expect(component.dateStr).toBe('2019-04-30'); + }); + + it('should not set the date on enter if value is invalid', () => { + const input = fixture.debugElement.query(By.css('input')).nativeElement; + input.value = 'invalid date'; + expect(component.dateStr).toBe('now'); + const e = new KeyboardEvent('keyup', { + code: 'Enter', + }); + input.dispatchEvent(e); + expect(component.dateStr).toBe('now'); + }); }); diff --git a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts index 9014058..d7d1418 100644 --- a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts +++ b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Component, OnInit, ViewChild, ElementRef, OnChanges, SimpleChanges, Input, Output, EventEmitter } from '@angular/core'; +import { Component, ViewChild, ElementRef, OnChanges, SimpleChanges, Input, Output, EventEmitter, OnInit } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import * as moment from 'moment/moment'; import * as Pikaday from 'pikaday-time'; @@ -37,34 +37,62 @@ export class DatePickerComponent implements OnInit, OnChanges, ControlValueAcces private onChange: Function; private onTouched: Function; + private isManualMode = false; @Input() date = ''; @Input() minDate = ''; @Output() dateChange = new EventEmitter<string>(); @ViewChild('inputText') inputText: ElementRef; + @ViewChild('calendarIcon') calendarIcon: ElementRef; constructor(private elementRef: ElementRef) {} ngOnInit() { let _datePickerComponent = this; let pikadayConfig = { + trigger: this.calendarIcon.nativeElement, field: this.elementRef.nativeElement, showSeconds: true, use24hour: true, onSelect: function() { - _datePickerComponent.dateStr = this.getMoment().format('YYYY-MM-DD HH:mm:ss'); - setTimeout(() => { - _datePickerComponent.dateChange.emit(_datePickerComponent.dateStr); - if (_datePickerComponent.onChange) { - _datePickerComponent.onChange(_datePickerComponent.dateStr); - } - }, 0); + if (_datePickerComponent.isManualMode) { + return; + } + _datePickerComponent.performChange.call(_datePickerComponent, this.getMoment().format('YYYY-MM-DD HH:mm:ss')); } }; this.picker = new Pikaday(pikadayConfig); this.setDate(); } + performChange(date: string) { + this.dateStr = date; + setTimeout(() => { + this.dateChange.emit(this.dateStr); + if (this.onChange) { + this.onChange(this.dateStr); + } + }, 0); + } + + onKeyup(e) { + if (e.code === 'Enter' && new Date(e.target.value).toString() !== 'Invalid Date') { + this.performChange(e.target.value); + this.picker.hide(); + } + } + + onFocus() { + this.isManualMode = true; + } + + onBlur(e) { + if (new Date(e.target.value).toString() !== 'Invalid Date') { + this.performChange(e.target.value); + } + this.isManualMode = false; + } + ngOnChanges(changes: SimpleChanges) { if (changes && changes['minDate'] && this.picker) { this.setMinDate(); @@ -106,16 +134,4 @@ export class DatePickerComponent implements OnInit, OnChanges, ControlValueAcces this.picker.setMinDate(new Date(this.minDate)); this.picker.setDate(moment(this.minDate).endOf('day').format('YYYY-MM-DD HH:mm:ss')); } - - toggleDatePicker($event) { - if (this.picker) { - if (this.picker.isVisible()) { - this.picker.hide(); - } else { - this.picker.show(); - } - - $event.stopPropagation(); - } - } }