From 1c67624e66477703e3aac95b4ae2d94d8cc4bd33 Mon Sep 17 00:00:00 2001 From: Sandro Castillo Date: Mon, 16 Aug 2021 10:02:13 -0500 Subject: [PATCH 1/6] Revert "fix: TT-304 Handle message: the data could not be load (#716)" (#723) This reverts commit d2fc2a0bb6fc9a0d4c1e1f5f1180d514a0e1e3f4. --- .../pages/time-entries.component.html | 2 +- .../pages/time-entries.component.spec.ts | 7 ---- .../pages/time-entries.component.ts | 36 ++----------------- 3 files changed, 4 insertions(+), 41 deletions(-) diff --git a/src/app/modules/time-entries/pages/time-entries.component.html b/src/app/modules/time-entries/pages/time-entries.component.html index df2e1869b..1711ea0b8 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.html +++ b/src/app/modules/time-entries/pages/time-entries.component.html @@ -42,7 +42,7 @@
- +
diff --git a/src/app/modules/time-entries/pages/time-entries.component.spec.ts b/src/app/modules/time-entries/pages/time-entries.component.spec.ts index 4ff687dd6..2406a1a59 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.spec.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.spec.ts @@ -668,11 +668,4 @@ describe('TimeEntriesComponent', () => { expect(HTMLTimeEntriesView).not.toBeNull(); }); - - it('after the component is initialized it should initialize the table', () => { - spyOn(component.dtTrigger, 'next'); - component.ngAfterViewInit(); - - expect(component.dtTrigger.next).toHaveBeenCalled(); - }); }); diff --git a/src/app/modules/time-entries/pages/time-entries.component.ts b/src/app/modules/time-entries/pages/time-entries.component.ts index 3fdc19aba..7ba274bbe 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -1,7 +1,7 @@ -import { Component, OnDestroy, OnInit, ViewChild, AfterViewInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActionsSubject, select, Store } from '@ngrx/store'; import { ToastrService } from 'ngx-toastr'; -import { Observable, Subscription, Subject } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; import { delay, filter } from 'rxjs/operators'; import { ProjectSelectedEvent } from '../../shared/components/details-fields/project-selected-event'; import { SaveEntryEvent } from '../../shared/components/details-fields/save-entry-event'; @@ -14,13 +14,12 @@ import { EntryActionTypes } from './../../time-clock/store/entry.actions'; import { getActiveTimeEntry, getTimeEntriesDataSource } from './../../time-clock/store/entry.selectors'; import { CookieService } from 'ngx-cookie-service'; import { FeatureToggle } from './../../../../environments/enum'; -import { DataTableDirective } from 'angular-datatables'; @Component({ selector: 'app-time-entries', templateUrl: './time-entries.component.html', styleUrls: ['./time-entries.component.scss'], }) -export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit { +export class TimeEntriesComponent implements OnInit, OnDestroy { entryId: string; entry: Entry; activeTimeEntry: Entry; @@ -39,11 +38,6 @@ export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit { selectedYear: number; selectedMonthAsText: string; isActiveEntryOverlapping = false; - dtOptions: any = {}; - dtTrigger: Subject = new Subject(); - @ViewChild(DataTableDirective, { static: false }) - dtElement: DataTableDirective; - rerenderTableSubscription: Subscription; constructor( private store: Store, private toastrService: ToastrService, @@ -55,18 +49,8 @@ export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit { } ngOnDestroy(): void { this.entriesSubscription.unsubscribe(); - this.rerenderTableSubscription.unsubscribe(); - this.dtTrigger.unsubscribe(); } ngOnInit(): void { - this.dtOptions = { - scrollY: '325px', - paging: false, - responsive: true, - }; - this.rerenderTableSubscription = this.timeEntriesDataSource$.subscribe((ds) => { - this.rerenderDataTable(); - }); this.loadActiveEntry(); this.isFeatureToggleCalendarActive = (this.cookiesService.get(FeatureToggle.TIME_TRACKER_CALENDAR) === 'true'); this.entriesSubscription = this.actionsSubject$.pipe( @@ -81,9 +65,6 @@ export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit { this.store.dispatch(new entryActions.LoadEntries(this.selectedMonth, this.selectedYear)); }); } - ngAfterViewInit(): void { - this.rerenderDataTable(); - } newEntry() { if (this.wasEditingExistingTimeEntry) { this.entry = null; @@ -235,15 +216,4 @@ export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit { }); } } - - private rerenderDataTable(): void { - if (this.dtElement && this.dtElement.dtInstance) { - this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => { - dtInstance.destroy(); - this.dtTrigger.next(); - }); - } else { - this.dtTrigger.next(); - } - } } From 3b8af2f3b954f97aa9dcac954f25a93515163d26 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 16 Aug 2021 15:03:40 +0000 Subject: [PATCH 2/6] chore(release): 1.47.2 [skip ci]nn --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f4a0bc73..99fbf6250 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.47.1", + "version": "1.47.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1c5667726..1b72fd6fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.47.1", + "version": "1.47.2", "scripts": { "preinstall": "npx npm-force-resolutions", "ng": "ng", From 523084e6c7cc948c708ea9af243c72f924f45159 Mon Sep 17 00:00:00 2001 From: jcalarcon98 Date: Fri, 13 Aug 2021 20:06:31 -0500 Subject: [PATCH 3/6] fix: TT-311 Can not update entries fixed --- .../details-fields.component.spec.ts | 95 +++++++++++++++---- .../details-fields.component.ts | 37 +++++++- 2 files changed, 106 insertions(+), 26 deletions(-) diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts index 2fa11b8af..116b1661d 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts @@ -141,8 +141,8 @@ describe('DetailsFieldsComponent', () => { uri: 'ticketUri', start_date: '', end_date: '', - start_hour: '00:00:10', - end_hour: '00:00:11', + start_hour: '00:00', + end_hour: '00:00', description: '', technology: '', }; @@ -176,22 +176,23 @@ describe('DetailsFieldsComponent', () => { expect(component.saveEntry.emit).toHaveBeenCalledTimes(0); }); - [{ actionType: EntryActionTypes.CREATE_ENTRY_SUCCESS }, { actionType: EntryActionTypes.UPDATE_ENTRY_SUCCESS }].forEach( - (param) => { - it(`cleanForm after an action type ${param.actionType} is received`, () => { - const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject; - const action = { - type: param.actionType, - }; - spyOn(component, 'cleanForm'); + [ + { actionType: EntryActionTypes.CREATE_ENTRY_SUCCESS }, + { actionType: EntryActionTypes.UPDATE_ENTRY_SUCCESS }, + ].forEach((param) => { + it(`cleanForm after an action type ${param.actionType} is received`, () => { + const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject; + const action = { + type: param.actionType, + }; + spyOn(component, 'cleanForm'); - component.ngOnInit(); - actionSubject.next(action); + component.ngOnInit(); + actionSubject.next(action); - expect(component.cleanForm).toHaveBeenCalled(); - }); - } - ); + expect(component.cleanForm).toHaveBeenCalled(); + }); + }); it('on cleanFieldsForm the project_id and project_name should be kept', () => { const entryFormValueExpected = { @@ -295,8 +296,8 @@ describe('DetailsFieldsComponent', () => { uri: '', start_date: '2020-02-05', end_date: '2020-02-05', - start_hour: '00:00:01', - end_hour: '00:01:01', + start_hour: '00:00', + end_hour: '00:01', description: '', technology: '', }); @@ -309,8 +310,8 @@ describe('DetailsFieldsComponent', () => { activity_id: 'a1', technologies: [], description: '', - start_date: new Date('2020-02-05T00:00:01').toISOString(), - end_date: new Date('2020-02-05T00:01:01').toISOString(), + start_date: new Date('2020-02-05T00:00:00').toISOString(), + end_date: new Date('2020-02-05T00:01:00').toISOString(), uri: '', timezone_offset: new Date().getTimezoneOffset(), }, @@ -408,7 +409,7 @@ describe('DetailsFieldsComponent', () => { activity_id: 'a1', technologies: [], description: '', - start_date: new Date('2020-06-11T00:00:10').toISOString(), + start_date: new Date('2020-06-11T00:00:00').toISOString(), uri: 'ticketUri', timezone_offset: new Date().getTimezoneOffset(), }, @@ -652,6 +653,58 @@ describe('DetailsFieldsComponent', () => { componentToTest.onSubmit(); expect(toastrServiceStub.error).not.toHaveBeenCalled(); }); + + it('Should return a date in ISO format given a date, hour, minute, second and milisecond', () => { + const fakeDates = [ + { + date: '2021-04-20', + hourAndMinutes: '10:00', + seconds: 20, + miliseconds: 10, + }, + { + date: '2020-09-21', + hourAndMinutes: '08:00', + seconds: 10, + miliseconds: 10, + }, + { + date: '2021-04-15', + hourAndMinutes: '23:00', + seconds: 0, + miliseconds: 0, + }, + { + date: '2019-03-29', + hourAndMinutes: '12:00', + seconds: 30, + miliseconds: 40, + }, + ]; + + const expectedISODates = [ + '2021-04-20T15:00:20.100Z', + '2020-09-21T13:00:10.100Z', + '2021-04-16T04:00:00.000Z', + '2019-03-29T17:00:30.400Z', + ]; + + fakeDates.forEach(({ date, hourAndMinutes, seconds, miliseconds }, fakeDateIndex) => { + const dateInISOFormat = component.getDateISOFormat(date, hourAndMinutes, seconds, miliseconds); + expect(dateInISOFormat).toBe(expectedISODates[fakeDateIndex]); + }); + }); + + it('should return a number in ISO format given a normal number', () => { + const numbersForTest = [1, 2, 3, 4, 20, 30, 40, 32, 45]; + + const expectedISOFormatNumbers = ['01', '02', '03', '04', '20', '30', '40', '32', '45']; + + numbersForTest.forEach((currentNumber, numberIndex) => { + const numberinISOFormat = component.getNumberInISOFornat(currentNumber); + expect(numberinISOFormat).toBe(expectedISOFormatNumbers[numberIndex]); + }); + }); /* TODO As part of https://github.com/ioet/time-tracker-ui/issues/424 a new parameter was added to the details-field-component, and now these couple of tests are failing. A solution to this error might be generate a Test Wrapper Component. More details here: diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.ts b/src/app/modules/shared/components/details-fields/details-fields.component.ts index 0a1b6f7da..0a707b911 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.ts @@ -264,12 +264,39 @@ export class DetailsFieldsComponent implements OnChanges, OnInit { return startDate >= endDate; } - dateToSubmit(date, hour) { - const entryFormDate = this.entryForm.value[date]; - const updatedHour = this.entryForm.value[hour]; - const updatedDate = new Date(`${entryFormDate}T${updatedHour.trim()}`).toISOString(); + getDateISOFormat(date: string, hourAndMinutes: string, seconds, miliseconds: number): string { + hourAndMinutes = hourAndMinutes.trim(); + const secondsInISOFormat: string = this.getNumberInISOFornat(seconds); + const milisecondsInISOFormat: string = this.getNumberInISOFornat(miliseconds); + const ISOFormat = `${date}T${hourAndMinutes}:${secondsInISOFormat}.${milisecondsInISOFormat}`; + const dateISOFormat: string = new Date(ISOFormat).toISOString(); + return dateISOFormat; + } + + getNumberInISOFornat(numberToFormat: number): string { + const limitSingleNumber = 9; + const isNumberGreaterThanLimitNumber = numberToFormat > limitSingleNumber; + const numberInISOFormat: string = isNumberGreaterThanLimitNumber ? numberToFormat.toString() : `0${numberToFormat}`; + return numberInISOFormat; + } + + dateToSubmit(date: string, hour: string) { + const timeEntryISODate: string = get(this.entryToEdit, date); + let seconds = 0; + let miliseconds = 0; + + if (timeEntryISODate) { + const timeEntryDate: Date = new Date(timeEntryISODate); + seconds = timeEntryDate.getSeconds(); + miliseconds = timeEntryDate.getMilliseconds(); + } + + const newEntryDate: string = this.entryForm.value[date]; + const newEntryHour: string = this.entryForm.value[hour]; + + const updatedDate: string = this.getDateISOFormat(newEntryDate, newEntryHour, seconds, miliseconds); const initialDate = get(this.entryToEdit, date, updatedDate); - const dateHasNotChanged = (initialDate === updatedDate); + const dateHasNotChanged = initialDate === updatedDate; const result = dateHasNotChanged ? initialDate : updatedDate; return result; } From 9e3c7a8e0ad883e3b6e497bfdbf00124044d364e Mon Sep 17 00:00:00 2001 From: jcalarcon98 Date: Sun, 15 Aug 2021 18:25:47 -0500 Subject: [PATCH 4/6] code-smell: TT-311 Code smells suggested by Sonarcloud fixed --- .../components/details-fields/details-fields.component.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.ts b/src/app/modules/shared/components/details-fields/details-fields.component.ts index 0a707b911..d91b66d54 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.ts @@ -269,15 +269,13 @@ export class DetailsFieldsComponent implements OnChanges, OnInit { const secondsInISOFormat: string = this.getNumberInISOFornat(seconds); const milisecondsInISOFormat: string = this.getNumberInISOFornat(miliseconds); const ISOFormat = `${date}T${hourAndMinutes}:${secondsInISOFormat}.${milisecondsInISOFormat}`; - const dateISOFormat: string = new Date(ISOFormat).toISOString(); - return dateISOFormat; + return new Date(ISOFormat).toISOString(); } getNumberInISOFornat(numberToFormat: number): string { const limitSingleNumber = 9; const isNumberGreaterThanLimitNumber = numberToFormat > limitSingleNumber; - const numberInISOFormat: string = isNumberGreaterThanLimitNumber ? numberToFormat.toString() : `0${numberToFormat}`; - return numberInISOFormat; + return isNumberGreaterThanLimitNumber ? numberToFormat.toString() : `0${numberToFormat}`; } dateToSubmit(date: string, hour: string) { From 72b6a606c0e821b0721801e692c2e82a5dbf0518 Mon Sep 17 00:00:00 2001 From: jcalarcon98 Date: Sun, 15 Aug 2021 19:42:38 -0500 Subject: [PATCH 5/6] fix: TT-311 Fix tests that fails on different timezone --- .../details-fields.component.spec.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts index 116b1661d..844df41a3 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts @@ -660,13 +660,13 @@ describe('DetailsFieldsComponent', () => { date: '2021-04-20', hourAndMinutes: '10:00', seconds: 20, - miliseconds: 10, + miliseconds: 100, }, { date: '2020-09-21', hourAndMinutes: '08:00', seconds: 10, - miliseconds: 10, + miliseconds: 100, }, { date: '2021-04-15', @@ -678,15 +678,15 @@ describe('DetailsFieldsComponent', () => { date: '2019-03-29', hourAndMinutes: '12:00', seconds: 30, - miliseconds: 40, + miliseconds: 400, }, ]; const expectedISODates = [ - '2021-04-20T15:00:20.100Z', - '2020-09-21T13:00:10.100Z', - '2021-04-16T04:00:00.000Z', - '2019-03-29T17:00:30.400Z', + new Date('2021-04-20T10:00:20.100').toISOString(), + new Date('2020-09-21T08:00:10.100').toISOString(), + new Date('2021-04-15T23:00:00.000').toISOString(), + new Date('2019-03-29T12:00:30.400').toISOString(), ]; fakeDates.forEach(({ date, hourAndMinutes, seconds, miliseconds }, fakeDateIndex) => { From db3c22dbda9866f22e12898fc97bac8f282daf6e Mon Sep 17 00:00:00 2001 From: jcalarcon98 Date: Mon, 16 Aug 2021 11:15:02 -0500 Subject: [PATCH 6/6] fix: TT-311 Spelling error on method fixed --- .../details-fields/details-fields.component.spec.ts | 2 +- .../components/details-fields/details-fields.component.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts index 844df41a3..0db557b09 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts @@ -701,7 +701,7 @@ describe('DetailsFieldsComponent', () => { const expectedISOFormatNumbers = ['01', '02', '03', '04', '20', '30', '40', '32', '45']; numbersForTest.forEach((currentNumber, numberIndex) => { - const numberinISOFormat = component.getNumberInISOFornat(currentNumber); + const numberinISOFormat = component.getNumberInISOFormat(currentNumber); expect(numberinISOFormat).toBe(expectedISOFormatNumbers[numberIndex]); }); }); diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.ts b/src/app/modules/shared/components/details-fields/details-fields.component.ts index d91b66d54..59b07a5ae 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.ts @@ -264,15 +264,15 @@ export class DetailsFieldsComponent implements OnChanges, OnInit { return startDate >= endDate; } - getDateISOFormat(date: string, hourAndMinutes: string, seconds, miliseconds: number): string { + getDateISOFormat(date: string, hourAndMinutes: string, seconds: number, miliseconds: number): string { hourAndMinutes = hourAndMinutes.trim(); - const secondsInISOFormat: string = this.getNumberInISOFornat(seconds); - const milisecondsInISOFormat: string = this.getNumberInISOFornat(miliseconds); + const secondsInISOFormat: string = this.getNumberInISOFormat(seconds); + const milisecondsInISOFormat: string = this.getNumberInISOFormat(miliseconds); const ISOFormat = `${date}T${hourAndMinutes}:${secondsInISOFormat}.${milisecondsInISOFormat}`; return new Date(ISOFormat).toISOString(); } - getNumberInISOFornat(numberToFormat: number): string { + getNumberInISOFormat(numberToFormat: number): string { const limitSingleNumber = 9; const isNumberGreaterThanLimitNumber = numberToFormat > limitSingleNumber; return isNumberGreaterThanLimitNumber ? numberToFormat.toString() : `0${numberToFormat}`;
Date