From 4a496355b5f785318448992090bd4dc0d1e918a6 Mon Sep 17 00:00:00 2001 From: Diego Tinitana Date: Mon, 22 Jun 2020 15:41:55 -0500 Subject: [PATCH 01/11] fix: #395 Make the activity required when clocking-out --- .../entry-fields/entry-fields.component.html | 35 +++++++++++++------ .../entry-fields/entry-fields.component.ts | 35 +++++++++++-------- .../pages/time-clock.component.spec.ts | 28 +++++++++++++-- .../time-clock/pages/time-clock.component.ts | 25 ++++++++++--- .../pages/time-entries.component.ts | 2 +- 5 files changed, 92 insertions(+), 33 deletions(-) diff --git a/src/app/modules/time-clock/components/entry-fields/entry-fields.component.html b/src/app/modules/time-clock/components/entry-fields/entry-fields.component.html index cfa427c84..272e9d57e 100644 --- a/src/app/modules/time-clock/components/entry-fields/entry-fields.component.html +++ b/src/app/modules/time-clock/components/entry-fields/entry-fields.component.html @@ -3,24 +3,39 @@
Activity
- - +
Ticket URI
- +
- + -
Description @@ -31,8 +46,8 @@ formControlName="description" class="form-control" id="NotesTextarea" - rows="2"> + rows="2" + >
- diff --git a/src/app/modules/time-clock/components/entry-fields/entry-fields.component.ts b/src/app/modules/time-clock/components/entry-fields/entry-fields.component.ts index 0b1e2f556..b119c4a59 100644 --- a/src/app/modules/time-clock/components/entry-fields/entry-fields.component.ts +++ b/src/app/modules/time-clock/components/entry-fields/entry-fields.component.ts @@ -1,12 +1,12 @@ -import {getActiveTimeEntry} from './../../store/entry.selectors'; -import {Component, OnInit} from '@angular/core'; -import {FormBuilder, FormGroup} from '@angular/forms'; -import {select, Store} from '@ngrx/store'; +import { getActiveTimeEntry } from './../../store/entry.selectors'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { select, Store } from '@ngrx/store'; -import {Activity, NewEntry} from '../../../shared/models'; -import {ProjectState} from '../../../customer-management/components/projects/components/store/project.reducer'; -import {TechnologyState} from '../../../shared/store/technology.reducers'; -import {ActivityState, allActivities, LoadActivities} from '../../../activities-management/store'; +import { Activity, NewEntry } from '../../../shared/models'; +import { ProjectState } from '../../../customer-management/components/projects/components/store/project.reducer'; +import { TechnologyState } from '../../../shared/store/technology.reducers'; +import { ActivityState, allActivities, LoadActivities } from '../../../activities-management/store'; import * as entryActions from '../../store/entry.actions'; @@ -18,7 +18,6 @@ type Merged = TechnologyState & ProjectState & ActivityState; styleUrls: ['./entry-fields.component.scss'], }) export class EntryFieldsComponent implements OnInit { - entryForm: FormGroup; selectedTechnologies: string[] = []; activities: Activity[] = []; @@ -29,7 +28,7 @@ export class EntryFieldsComponent implements OnInit { this.entryForm = this.formBuilder.group({ description: '', uri: '', - activity_id: '-1' + activity_id: '-1', }); } @@ -58,6 +57,10 @@ export class EntryFieldsComponent implements OnInit { }); } + get activity_id() { + return this.entryForm.get('activity_id'); + } + setDataToUpdate(entryData: NewEntry) { if (entryData) { this.entryForm.patchValue({ @@ -73,17 +76,19 @@ export class EntryFieldsComponent implements OnInit { } } + entryFormIsValidate() { + return this.entryForm.valid; + } + onSubmit() { - this.store.dispatch(new entryActions.UpdateEntryRunning({...this.newData, ...this.entryForm.value})); + this.store.dispatch(new entryActions.UpdateEntryRunning({ ...this.newData, ...this.entryForm.value })); } onTechnologyAdded($event: string[]) { - this.store.dispatch(new entryActions.UpdateEntryRunning({...this.newData, technologies: $event}) - ); + this.store.dispatch(new entryActions.UpdateEntryRunning({ ...this.newData, technologies: $event })); } onTechnologyRemoved($event: string[]) { - this.store.dispatch(new entryActions.UpdateEntryRunning({...this.newData, technologies: $event})); + this.store.dispatch(new entryActions.UpdateEntryRunning({ ...this.newData, technologies: $event })); } - } diff --git a/src/app/modules/time-clock/pages/time-clock.component.spec.ts b/src/app/modules/time-clock/pages/time-clock.component.spec.ts index b77631a4c..5ff044c4b 100644 --- a/src/app/modules/time-clock/pages/time-clock.component.spec.ts +++ b/src/app/modules/time-clock/pages/time-clock.component.spec.ts @@ -8,12 +8,18 @@ import { ProjectState } from '../../customer-management/components/projects/comp import { ProjectListHoverComponent } from '../components'; import { FilterProjectPipe } from '../../shared/pipes'; import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service'; +import { EntryFieldsComponent } from '../components/entry-fields/entry-fields.component'; +import { ToastrService } from 'ngx-toastr'; describe('TimeClockComponent', () => { let component: TimeClockComponent; let fixture: ComponentFixture; let store: MockStore; let azureAdB2CService: AzureAdB2CService; + let injectedToastrService; + const toastrService = { + error: () => {}, + }; const state = { projects: { projects: [{ id: 'id', name: 'name', project_type_id: '' }], @@ -41,11 +47,12 @@ describe('TimeClockComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], - declarations: [TimeClockComponent, ProjectListHoverComponent, FilterProjectPipe], + declarations: [TimeClockComponent, ProjectListHoverComponent, FilterProjectPipe, EntryFieldsComponent], providers: [ FormBuilder, AzureAdB2CService, provideMockStore({ initialState: state }), + { provide: ToastrService, useValue: toastrService }, ], }).compileComponents(); store = TestBed.inject(MockStore); @@ -56,6 +63,7 @@ describe('TimeClockComponent', () => { component = fixture.componentInstance; fixture.detectChanges(); azureAdB2CService = TestBed.inject(AzureAdB2CService); + injectedToastrService = TestBed.inject(ToastrService); }); it('should be created', () => { @@ -78,11 +86,27 @@ describe('TimeClockComponent', () => { expect(azureAdB2CService.getName).toHaveBeenCalledTimes(0); }); - it('clockOut dispatch a StopTimeEntryRunning action', () => { + it('stopEntry dispatch a StopTimeEntryRunning action', () => { spyOn(store, 'dispatch'); + component.stopEntry(); + expect(store.dispatch).toHaveBeenCalledWith(new StopTimeEntryRunning('id')); + }); + + it('clockOut dispatch a StopTimeEntryRunning action', () => { + spyOn(store, 'dispatch'); + spyOn(component.entryFieldsComponent, 'entryFormIsValidate').and.returnValue(true); component.clockOut(); expect(store.dispatch).toHaveBeenCalledWith(new StopTimeEntryRunning('id')); }); + + it('clockOut set error Activity is required', () => { + spyOn(store, 'dispatch'); + spyOn(injectedToastrService, 'error'); + spyOn(component.entryFieldsComponent, 'entryFormIsValidate').and.returnValue(false); + component.clockOut(); + + expect(injectedToastrService.error).toHaveBeenCalled(); + }); }); diff --git a/src/app/modules/time-clock/pages/time-clock.component.ts b/src/app/modules/time-clock/pages/time-clock.component.ts index bf98bfee4..cd64153dc 100644 --- a/src/app/modules/time-clock/pages/time-clock.component.ts +++ b/src/app/modules/time-clock/pages/time-clock.component.ts @@ -2,23 +2,29 @@ import { getActiveTimeEntry } from './../store/entry.selectors'; import { StopTimeEntryRunning } from './../store/entry.actions'; import { Entry } from './../../shared/models/entry.model'; import { Store, select } from '@ngrx/store'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service'; import { Subscription } from 'rxjs'; - +import { EntryFieldsComponent } from '../components/entry-fields/entry-fields.component'; +import { ToastrService } from 'ngx-toastr'; @Component({ selector: 'app-time-clock', templateUrl: './time-clock.component.html', styleUrls: ['./time-clock.component.scss'], }) export class TimeClockComponent implements OnInit { + @ViewChild(EntryFieldsComponent) + entryFieldsComponent: EntryFieldsComponent; username: string; areFieldsVisible = false; activeTimeEntry: Entry; actionsSubscription: Subscription; - constructor(private azureAdB2CService: AzureAdB2CService, private store: Store) { - } + constructor( + private azureAdB2CService: AzureAdB2CService, + private store: Store, + private toastrService: ToastrService + ) {} ngOnInit() { this.username = this.azureAdB2CService.isLogin() ? this.azureAdB2CService.getName() : ''; @@ -32,8 +38,17 @@ export class TimeClockComponent implements OnInit { }); } - clockOut() { + stopEntry() { this.store.dispatch(new StopTimeEntryRunning(this.activeTimeEntry.id)); this.areFieldsVisible = false; } + + clockOut() { + if (this.entryFieldsComponent.entryFormIsValidate()) { + this.stopEntry(); + } else { + this.entryFieldsComponent.entryForm.get('activity_id').markAsTouched(); + this.toastrService.error('Activity is required'); + } + } } 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 e2bf668f2..78baaee09 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -92,7 +92,7 @@ export class TimeEntriesComponent implements OnInit { openModal(item: any) { this.idToDelete = item.id; - this.message = `Are you sure you want to delete ${item.activity_name}`; + this.message = `Are you sure you want to delete ${item.activity_name}?`; this.showModal = true; } } From 5ef5e287f2f8bf1f76e98d5ecdb7f9d7a9dcc8b3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 24 Jun 2020 06:20:55 +0000 Subject: [PATCH 02/11] chore(release): 1.9.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 ea9d58f98..c1c3e9696 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.1", + "version": "1.9.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f7a5dc4aa..5b3575248 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.1", + "version": "1.9.2", "scripts": { "ng": "ng", "start": "ng serve", From 07d5f9dcc7755e1d9ef322b29070c10b85f1b30d Mon Sep 17 00:00:00 2001 From: Rene Enriquez Date: Wed, 24 Jun 2020 02:10:41 -0500 Subject: [PATCH 03/11] fix: #320 reload time worked summary after clocking-out --- .../substract-date.pipe.spec.ts | 9 +++++ .../substract-date/substract-date.pipe.ts | 4 +-- .../time-entries-summary.component.ts | 2 +- .../pages/time-clock.component.spec.ts | 34 ++++++++++++++++++- .../time-clock/pages/time-clock.component.ts | 32 +++++++++++++---- 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/app/modules/shared/pipes/substract-date/substract-date.pipe.spec.ts b/src/app/modules/shared/pipes/substract-date/substract-date.pipe.spec.ts index a9ec16b14..b2db647e2 100644 --- a/src/app/modules/shared/pipes/substract-date/substract-date.pipe.spec.ts +++ b/src/app/modules/shared/pipes/substract-date/substract-date.pipe.spec.ts @@ -15,6 +15,15 @@ describe('SubstractDatePipe', () => { expect(diff).toBe('02:20'); }); + it('returns the date diff using hh:mm:ss for a diff < 1 min when displaySeconds is true', () => { + const fromDate = new Date('2011-04-11T10:22:40Z'); + const substractDate = new Date('2011-04-11T10:20:30Z'); + + const diff = new SubstractDatePipe().transform(fromDate, substractDate, true); + + expect(diff).toBe('00:02:10'); + }); + it('returns the date diff including seconds if difference is less than a minute', () => { const fromDate = new Date('2011-04-11T10:20:40Z'); const substractDate = new Date('2011-04-11T10:20:30Z'); diff --git a/src/app/modules/shared/pipes/substract-date/substract-date.pipe.ts b/src/app/modules/shared/pipes/substract-date/substract-date.pipe.ts index 8791d3741..6ca03db08 100644 --- a/src/app/modules/shared/pipes/substract-date/substract-date.pipe.ts +++ b/src/app/modules/shared/pipes/substract-date/substract-date.pipe.ts @@ -6,7 +6,7 @@ import * as moment from 'moment'; }) export class SubstractDatePipe implements PipeTransform { - transform(fromDate: Date, substractDate: Date): string { + transform(fromDate: Date, substractDate: Date, displaySeconds: boolean = false): string { if (fromDate === null || substractDate === null ) { return '--:--'; @@ -16,7 +16,7 @@ export class SubstractDatePipe implements PipeTransform { let endDate = moment(fromDate, 'YYYY-MM-DD HH:mm:ss'); let duration: moment.Duration = moment.duration(endDate.diff(startDate)); - if (duration.asSeconds() > 60) { + if (duration.asSeconds() > 60 && !displaySeconds) { endDate = endDate.add(1, 'minute').startOf('minute'); duration = moment.duration(endDate.diff(startDate)); return `${ this.formatTime(duration.hours())}:${this.formatTime(duration.minutes()) }`; diff --git a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts index d8e56404e..9150d0128 100644 --- a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts +++ b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts @@ -91,7 +91,7 @@ export class TimeEntriesSummaryComponent implements OnInit, OnDestroy { this.timeInterval = interval(1000).pipe( takeUntil(this.destroyed$) ).subscribe(() => { - this.currentWorkingTime = new SubstractDatePipe().transform(new Date(), new Date(entry.start_date)); + this.currentWorkingTime = new SubstractDatePipe().transform(new Date(), new Date(entry.start_date), true); }); } } diff --git a/src/app/modules/time-clock/pages/time-clock.component.spec.ts b/src/app/modules/time-clock/pages/time-clock.component.spec.ts index b77631a4c..0d4e455fc 100644 --- a/src/app/modules/time-clock/pages/time-clock.component.spec.ts +++ b/src/app/modules/time-clock/pages/time-clock.component.spec.ts @@ -1,5 +1,5 @@ import { FormBuilder } from '@angular/forms'; -import { StopTimeEntryRunning } from './../store/entry.actions'; +import { StopTimeEntryRunning, EntryActionTypes, LoadEntriesSummary } from './../store/entry.actions'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing'; import { provideMockStore, MockStore } from '@ngrx/store/testing'; @@ -8,12 +8,15 @@ import { ProjectState } from '../../customer-management/components/projects/comp import { ProjectListHoverComponent } from '../components'; import { FilterProjectPipe } from '../../shared/pipes'; import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service'; +import { ActionsSubject } from '@ngrx/store'; describe('TimeClockComponent', () => { let component: TimeClockComponent; let fixture: ComponentFixture; let store: MockStore; let azureAdB2CService: AzureAdB2CService; + const actionSub: ActionsSubject = new ActionsSubject(); + const state = { projects: { projects: [{ id: 'id', name: 'name', project_type_id: '' }], @@ -46,6 +49,7 @@ describe('TimeClockComponent', () => { FormBuilder, AzureAdB2CService, provideMockStore({ initialState: state }), + { provide: ActionsSubject, useValue: actionSub }, ], }).compileComponents(); store = TestBed.inject(MockStore); @@ -62,6 +66,34 @@ describe('TimeClockComponent', () => { expect(component).toBeTruthy(); }); + it('on STOP_TIME_ENTRY_RUNNING_SUCCESS summaries are reloaded', () => { + const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject; + const action = { + type: EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS + }; + spyOn(store, 'dispatch'); + + actionSubject.next(action); + + expect(store.dispatch).toHaveBeenCalledWith(new LoadEntriesSummary()); + }); + + it('register reloadSummaries on ngOnInit', () => { + spyOn(component, 'reloadSummariesOnClockOut'); + + component.ngOnInit(); + + expect(component.reloadSummariesOnClockOut).toHaveBeenCalled(); + }); + + it('unsubscribe clockOutSubscription onDestroy', () => { + spyOn(component.clockOutSubscription, 'unsubscribe'); + + component.ngOnDestroy(); + + expect(component.clockOutSubscription.unsubscribe).toHaveBeenCalled(); + }); + it('onInit checks if isLogin and gets the userName', () => { spyOn(azureAdB2CService, 'isLogin').and.returnValue(true); spyOn(azureAdB2CService, 'getName').and.returnValue('Name'); diff --git a/src/app/modules/time-clock/pages/time-clock.component.ts b/src/app/modules/time-clock/pages/time-clock.component.ts index bf98bfee4..4a7ee697d 100644 --- a/src/app/modules/time-clock/pages/time-clock.component.ts +++ b/src/app/modules/time-clock/pages/time-clock.component.ts @@ -1,8 +1,9 @@ +import { filter } from 'rxjs/operators'; import { getActiveTimeEntry } from './../store/entry.selectors'; -import { StopTimeEntryRunning } from './../store/entry.actions'; +import { StopTimeEntryRunning, EntryActionTypes, LoadEntriesSummary } from './../store/entry.actions'; import { Entry } from './../../shared/models/entry.model'; -import { Store, select } from '@ngrx/store'; -import { Component, OnInit } from '@angular/core'; +import { Store, select, ActionsSubject } from '@ngrx/store'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service'; import { Subscription } from 'rxjs'; @@ -11,13 +12,18 @@ import { Subscription } from 'rxjs'; templateUrl: './time-clock.component.html', styleUrls: ['./time-clock.component.scss'], }) -export class TimeClockComponent implements OnInit { +export class TimeClockComponent implements OnInit, OnDestroy { username: string; areFieldsVisible = false; activeTimeEntry: Entry; - actionsSubscription: Subscription; + clockOutSubscription: Subscription; - constructor(private azureAdB2CService: AzureAdB2CService, private store: Store) { + constructor(private azureAdB2CService: AzureAdB2CService, private store: Store, + private actionsSubject$: ActionsSubject) { + } + + ngOnDestroy(): void { + this.clockOutSubscription.unsubscribe(); } ngOnInit() { @@ -30,6 +36,20 @@ export class TimeClockComponent implements OnInit { this.areFieldsVisible = false; } }); + + this.reloadSummariesOnClockOut(); + + } + + reloadSummariesOnClockOut() { + this.clockOutSubscription = this.actionsSubject$.pipe( + filter((action) => ( + action.type === EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS + ) + ) + ).subscribe( (action) => { + this.store.dispatch(new LoadEntriesSummary()); + }); } clockOut() { From 2f96be4a9b8ec57dc107efadc1f76a848896224f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 24 Jun 2020 07:20:19 +0000 Subject: [PATCH 04/11] chore(release): 1.9.3 [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 c1c3e9696..00ca4c825 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.2", + "version": "1.9.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5b3575248..5a6095124 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.2", + "version": "1.9.3", "scripts": { "ng": "ng", "start": "ng serve", From 733351f940c98f0aa02be4766dbb13270cbe55fe Mon Sep 17 00:00:00 2001 From: Rene Enriquez Date: Wed, 24 Jun 2020 11:57:43 -0500 Subject: [PATCH 05/11] fix: #410 Trigger deployment From 07ae428488909f9778d2e14de249300aca6dacaf Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 24 Jun 2020 17:09:17 +0000 Subject: [PATCH 06/11] chore(release): 1.9.4 [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 00ca4c825..800cd5893 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.3", + "version": "1.9.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5a6095124..0faddcbba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.3", + "version": "1.9.4", "scripts": { "ng": "ng", "start": "ng serve", From 9c43d41db78e400e25aed4bd291ae5dba35facb9 Mon Sep 17 00:00:00 2001 From: Rene Enriquez Date: Wed, 24 Jun 2020 12:22:46 -0500 Subject: [PATCH 07/11] fix: #420 csv support --- .../time-entries-table.component.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/modules/reports/components/time-entries-table/time-entries-table.component.ts b/src/app/modules/reports/components/time-entries-table/time-entries-table.component.ts index 43c903778..9a6c7dd28 100644 --- a/src/app/modules/reports/components/time-entries-table/time-entries-table.component.ts +++ b/src/app/modules/reports/components/time-entries-table/time-entries-table.component.ts @@ -21,7 +21,16 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn buttons: [ 'colvis', 'print', - 'excel' + { + extend: 'excel', + text: 'Excel', + filename: `time-entries-${ new Date() }` + }, + { + extend: 'csv', + text: 'CSV', + filename: `time-entries-${ new Date() }` + } ] }; From 086601b5dc96e5f5d31040652d98269f8e93e49e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 24 Jun 2020 17:29:38 +0000 Subject: [PATCH 08/11] chore(release): 1.9.5 [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 800cd5893..30a17ef4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.4", + "version": "1.9.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 0faddcbba..0d4e51438 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "time-tracker", - "version": "1.9.4", + "version": "1.9.5", "scripts": { "ng": "ng", "start": "ng serve", From 1d5a8a5dc6c2791f26e1e858329743d9958dc195 Mon Sep 17 00:00:00 2001 From: roberto Date: Tue, 23 Jun 2020 14:47:38 -0500 Subject: [PATCH 09/11] fix: update doSave function #399 --- .../pages/time-entries.component.ts | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) 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 93bddeb5f..6e1a14d6d 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -62,17 +62,40 @@ export class TimeEntriesComponent implements OnInit { } doSave(event: SaveEntryEvent) { - event.entry.start_date = new Date(event.entry.start_date).toISOString(); - if (event.entry.end_date !== null && event.entry.end_date !== undefined) { - event.entry.end_date = new Date(event.entry.end_date).toISOString(); - } if (this.entryId) { + const startDateChanged = this.entry.start_date !== event.entry.start_date; + const endDateChanged = this.entry.end_date !== event.entry.end_date; + + if (startDateChanged) { + const startDate = new Date(event.entry.start_date); + startDate.setSeconds(1, 0); + event.entry.start_date = startDate.toISOString(); + } + + if (endDateChanged) { + if (event.entry.end_date !== null && event.entry.end_date !== undefined) { + const endDate = new Date(event.entry.end_date); + endDate.setSeconds(0, 0); + event.entry.end_date = endDate.toISOString(); + } + } + event.entry.id = this.entryId; this.store.dispatch(new entryActions.UpdateEntry(event.entry)); if (event.shouldRestartEntry) { this.store.dispatch(new entryActions.RestartEntry(event.entry)); } } else { + const startDate = new Date(event.entry.start_date); + startDate.setSeconds(1, 0); + event.entry.start_date = startDate.toISOString(); + + if (event.entry.end_date !== null && event.entry.end_date !== undefined) { + const endDate = new Date(event.entry.end_date); + endDate.setSeconds(0, 0); + event.entry.end_date = endDate.toISOString(); + } + this.store.dispatch(new entryActions.CreateEntry(event.entry)); } } From c0193b2708d669aceda849c87b2a601e338aad16 Mon Sep 17 00:00:00 2001 From: roberto Date: Tue, 23 Jun 2020 15:29:42 -0500 Subject: [PATCH 10/11] fix: add flag to check end_date is defined #399 --- .../time-entries/pages/time-entries.component.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 6e1a14d6d..7def706cd 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -62,18 +62,18 @@ export class TimeEntriesComponent implements OnInit { } doSave(event: SaveEntryEvent) { + const endDateIsDefined = event.entry.end_date !== null && event.entry.end_date !== undefined; if (this.entryId) { const startDateChanged = this.entry.start_date !== event.entry.start_date; - const endDateChanged = this.entry.end_date !== event.entry.end_date; - if (startDateChanged) { const startDate = new Date(event.entry.start_date); startDate.setSeconds(1, 0); event.entry.start_date = startDate.toISOString(); } - if (endDateChanged) { - if (event.entry.end_date !== null && event.entry.end_date !== undefined) { + if (endDateIsDefined) { + const endDateChanged = this.entry.end_date !== event.entry.end_date; + if (endDateChanged) { const endDate = new Date(event.entry.end_date); endDate.setSeconds(0, 0); event.entry.end_date = endDate.toISOString(); @@ -90,7 +90,7 @@ export class TimeEntriesComponent implements OnInit { startDate.setSeconds(1, 0); event.entry.start_date = startDate.toISOString(); - if (event.entry.end_date !== null && event.entry.end_date !== undefined) { + if (endDateIsDefined) { const endDate = new Date(event.entry.end_date); endDate.setSeconds(0, 0); event.entry.end_date = endDate.toISOString(); From 82a4ff93bbf5e068f27a166ff40f34461962cefb Mon Sep 17 00:00:00 2001 From: roberto Date: Wed, 24 Jun 2020 12:40:01 -0500 Subject: [PATCH 11/11] fix: extract method to adjust seconds #399 --- .../pages/time-entries.component.ts | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) 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 7def706cd..620bdea2b 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -66,17 +66,13 @@ export class TimeEntriesComponent implements OnInit { if (this.entryId) { const startDateChanged = this.entry.start_date !== event.entry.start_date; if (startDateChanged) { - const startDate = new Date(event.entry.start_date); - startDate.setSeconds(1, 0); - event.entry.start_date = startDate.toISOString(); + event.entry.start_date = this.adjustDateSecs(event.entry.start_date, 1); } if (endDateIsDefined) { const endDateChanged = this.entry.end_date !== event.entry.end_date; if (endDateChanged) { - const endDate = new Date(event.entry.end_date); - endDate.setSeconds(0, 0); - event.entry.end_date = endDate.toISOString(); + event.entry.end_date = this.adjustDateSecs(event.entry.end_date, 0); } } @@ -86,14 +82,9 @@ export class TimeEntriesComponent implements OnInit { this.store.dispatch(new entryActions.RestartEntry(event.entry)); } } else { - const startDate = new Date(event.entry.start_date); - startDate.setSeconds(1, 0); - event.entry.start_date = startDate.toISOString(); - + event.entry.start_date = this.adjustDateSecs(event.entry.start_date, 1); if (endDateIsDefined) { - const endDate = new Date(event.entry.end_date); - endDate.setSeconds(0, 0); - event.entry.end_date = endDate.toISOString(); + event.entry.end_date = this.adjustDateSecs(event.entry.end_date, 0); } this.store.dispatch(new entryActions.CreateEntry(event.entry)); @@ -123,4 +114,10 @@ export class TimeEntriesComponent implements OnInit { this.message = `Are you sure you want to delete ${item.activity_name}?`; this.showModal = true; } + + adjustDateSecs(date: string, sec: number): string { + const newDate = new Date(date); + newDate.setSeconds(sec, 0); + return newDate.toISOString(); + } }