From f2dfb96402236c77b997295f9f3bca43ca654521 Mon Sep 17 00:00:00 2001 From: Kevin Lopez Date: Mon, 28 Jun 2021 12:55:44 -0500 Subject: [PATCH] fix: TT-282 added conditions in method onSubmit and added array of activities in component project-list-hover --- .../entry-fields/entry-fields.component.html | 3 +- .../entry-fields.component.spec.ts | 33 +++++++++++++++++++ .../entry-fields/entry-fields.component.ts | 31 ++++++++++------- .../project-list-hover.component.spec.ts | 8 ++++- .../project-list-hover.component.ts | 13 ++++++++ 5 files changed, 75 insertions(+), 13 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 5f8e30751..827dd040a 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 @@ -6,8 +6,9 @@ class="form-control" formControlName="activity_id" [class.is-invalid]="activity_id.invalid && activity_id.touched" + #autofocus required> - + diff --git a/src/app/modules/time-clock/components/entry-fields/entry-fields.component.spec.ts b/src/app/modules/time-clock/components/entry-fields/entry-fields.component.spec.ts index c1b7e1add..45fed5730 100644 --- a/src/app/modules/time-clock/components/entry-fields/entry-fields.component.spec.ts +++ b/src/app/modules/time-clock/components/entry-fields/entry-fields.component.spec.ts @@ -323,10 +323,12 @@ describe('EntryFieldsComponent', () => { }); it('dispatches an action when onSubmit is called', () => { + const isEntryFormValid = spyOn(component, 'entryFormIsValidate').and.returnValue(true); spyOn(store, 'dispatch'); component.onSubmit(); + expect(isEntryFormValid).toHaveBeenCalled(); expect(store.dispatch).toHaveBeenCalled(); }); @@ -555,6 +557,37 @@ describe('EntryFieldsComponent', () => { expect(featureToggleGeneralService.isActivated).toHaveBeenCalled(); }); }); + + it('when a activity is not register in DB should show activatefocus in select activity', () => { + const activitiesMock = [{ + id: 'xyz', + name: 'test', + description : 'test1' + }]; + const data = { + activity_id: 'xyz', + description: '', + start_date: moment().format(DATE_FORMAT_YEAR), + start_hour: moment().format('HH:mm'), + uri: '' + }; + component.activities = activitiesMock; + component.entryForm.patchValue({ + description: data.description, + uri: data.uri, + activity_id: data.activity_id, + start_date: data.start_date, + start_hour: data.start_hour, + }); + component.ngOnInit(); + component.activateFocus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + const autofocus = fixture.nativeElement.querySelector('select'); + expect(autofocus).toHaveBeenCalled(); + }); + }); }); 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 deb7ca104..9dcad89d9 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,9 +1,8 @@ -import { AzureAdB2CService } from './../../../login/services/azure.ad.b2c.service'; import { FeatureToggleGeneralService } from './../../../shared/feature-toggles/feature-toggle-general/feature-toggle-general.service'; import { ActivityManagementActionTypes } from './../../../activities-management/store/activity-management.actions'; import { EntryActionTypes, LoadActiveEntry, UpdateCurrentOrLastEntry, UpdateEntry, UpdateEntryRunning } from './../../store/entry.actions'; -import { filter, map } from 'rxjs/operators'; -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { filter} from 'rxjs/operators'; +import { Component, OnDestroy, OnInit, ElementRef, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { Store, ActionsSubject, select } from '@ngrx/store'; import { Activity, NewEntry } from '../../../shared/models'; @@ -11,14 +10,13 @@ import { ProjectState } from '../../../customer-management/components/projects/c import { TechnologyState } from '../../../shared/store/technology.reducers'; import { ActivityState, LoadActivities } from '../../../activities-management/store'; import * as entryActions from '../../store/entry.actions'; -import { get } from 'lodash'; +import { get, head } from 'lodash'; import * as moment from 'moment'; import { ToastrService } from 'ngx-toastr'; import { formatDate } from '@angular/common'; import { getTimeEntriesDataSource } from '../../store/entry.selectors'; import { DATE_FORMAT } from 'src/environments/environment'; -import { Subscription, Observable } from 'rxjs'; -import { FeatureManagerService } from './../../../shared/feature-toggles/feature-toggle-manager.service'; +import { Subscription, } from 'rxjs'; import { FeatureToggle } from './../../../../../environments/enum'; import { CookieService } from 'ngx-cookie-service'; @@ -30,6 +28,9 @@ type Merged = TechnologyState & ProjectState & ActivityState; styleUrls: ['./entry-fields.component.scss'], }) export class EntryFieldsComponent implements OnInit, OnDestroy { + + @ViewChild('autofocus') autofocus!: ElementRef; + entryForm: FormGroup; selectedTechnologies: string[] = []; activities: Activity[] = []; @@ -42,14 +43,13 @@ export class EntryFieldsComponent implements OnInit, OnDestroy { actionSetDateSubscription: Subscription; isCookieFeatureToggleActive: boolean; isFeatureToggleActive: boolean; - constructor( private formBuilder: FormBuilder, private store: Store, private actionsSubject$: ActionsSubject, private toastrService: ToastrService, private featureToggleGeneralService: FeatureToggleGeneralService, - private cookiesService: CookieService + private cookiesService: CookieService, ) { this.entryForm = this.formBuilder.group({ description: '', @@ -63,7 +63,7 @@ export class EntryFieldsComponent implements OnInit, OnDestroy { ngOnInit(): void { this.store.dispatch(new LoadActivities()); this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1, new Date().getFullYear())); - this.loadActivitiesSubscription = this.actionsSubject$ + this.loadActivitiesSubscription = this.actionsSubject$ .pipe(filter((action: any) => action.type === ActivityManagementActionTypes.LOAD_ACTIVITIES_SUCCESS)) .subscribe((action) => { this.activities = action.payload.filter((item) => item.status !== 'inactive'); @@ -81,7 +81,6 @@ export class EntryFieldsComponent implements OnInit, OnDestroy { this.isFeatureToggleActive = flag; }); } - this.loadActiveEntrySubscription = this.actionsSubject$ .pipe( filter( @@ -113,6 +112,7 @@ export class EntryFieldsComponent implements OnInit, OnDestroy { start_date: this.activeEntry.start_date, start_hour: formatDate(this.activeEntry.start_date, 'HH:mm', 'en'), }; + this.activateFocus(); }); } get activity_id() { @@ -121,6 +121,13 @@ export class EntryFieldsComponent implements OnInit, OnDestroy { get start_hour() { return this.entryForm.get('start_hour'); } + + activateFocus(){ + if ((this.activities.length > 0) && (this.entryForm.value.activity_id === head(this.activities).id)){ + this.autofocus.nativeElement.focus(); + } + } + setDataToUpdate(entryData: NewEntry) { if (entryData) { this.entryForm.patchValue({ @@ -143,7 +150,9 @@ export class EntryFieldsComponent implements OnInit, OnDestroy { } onSubmit() { - this.store.dispatch(new entryActions.UpdateEntryRunning({ ...this.newData, ...this.entryForm.value })); + if (this.entryFormIsValidate()){ + this.store.dispatch(new entryActions.UpdateEntryRunning({ ...this.newData, ...this.entryForm.value })); + } } onUpdateStartHour() { diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts index a53977ce8..7b3eddd27 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts @@ -39,8 +39,8 @@ describe('ProjectListHoverComponent', () => { isLoading: false, message: '', }, - }; + }; beforeEach( waitForAsync(() => { TestBed.configureTestingModule({ @@ -69,6 +69,12 @@ describe('ProjectListHoverComponent', () => { it('dispatchs a CreateEntry action on clockIn', () => { component.activeEntry = null; + const activitiesMock = [{ + id: 'xyz', + name: 'test', + description : 'test1' + }]; + component.activities = activitiesMock; spyOn(store, 'dispatch'); component.clockIn(1, 'customer', 'project'); diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index 9ef22dcdd..7647fb44e 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -14,6 +14,11 @@ import { } from './../../../customer-management/components/projects/components/store/project.selectors'; import { EntryActionTypes } from './../../store/entry.actions'; import { getActiveTimeEntry } from './../../store/entry.selectors'; +import { Activity, } from '../../../shared/models'; +import { LoadActivities } from './../../../activities-management/store/activity-management.actions'; +import { allActivities } from 'src/app/modules/activities-management/store/activity-management.selectors'; +import { head } from 'lodash'; + @Component({ selector: 'app-project-list-hover', templateUrl: './project-list-hover.component.html', @@ -22,6 +27,7 @@ import { getActiveTimeEntry } from './../../store/entry.selectors'; export class ProjectListHoverComponent implements OnInit, OnDestroy { keyword = 'search_field'; listProjects: Project[] = []; + activities: Activity[] = []; activeEntry; projectsForm: FormGroup; showClockIn: boolean; @@ -29,6 +35,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { isLoading$: Observable; projectsSubscription: Subscription; activeEntrySubscription: Subscription; + loadActivitiesSubscription: Subscription; constructor( private formBuilder: FormBuilder, @@ -52,6 +59,11 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { }); this.loadActiveTimeEntry(); }); + this.store.dispatch(new LoadActivities()); + const activities$ = this.store.pipe(select(allActivities)); + activities$.subscribe((response) => { + this.activities = response; + }); this.updateEntrySubscription = this.actionsSubject$ .pipe(filter((action: any) => action.type === EntryActionTypes.UPDATE_ENTRY_SUCCESS)) .subscribe((action) => { @@ -88,6 +100,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { start_date: new Date().toISOString(), timezone_offset: new Date().getTimezoneOffset(), technologies: [], + activity_id: head(this.activities).id, }; this.store.dispatch(new entryActions.ClockIn(entry)); this.projectsForm.setValue({ project_id: `${customerName} - ${name}` });