From 0edaff1c20791cb0ae79960fa9ccf9adb438372e Mon Sep 17 00:00:00 2001 From: Jorge Flores Date: Mon, 23 Mar 2020 13:28:04 -0500 Subject: [PATCH 1/3] Time Entries Section --- src/app/app.module.ts | 16 +++- .../time-clock/time-clock.component.html | 2 +- .../time-entries/time-entries.component.css | 46 +++++++++ .../time-entries/time-entries.component.html | 69 +++++++++++++- .../time-entries.component.spec.ts | 59 +++++++++++- .../time-entries/time-entries.component.ts | 95 ++++++++++++++++++- .../shared/clock/clock.component.spec.ts | 18 ++-- .../create-project.component.ts | 6 +- .../details-fields.component.css | 4 + .../details-fields.component.html | 50 +++++----- .../details-fields.component.spec.ts | 42 +++++++- .../details-fields.component.ts | 35 ++++++- .../empty-state/empty-state.component.css | 8 ++ .../empty-state/empty-state.component.html | 4 + .../empty-state/empty-state.component.spec.ts | 25 +++++ .../empty-state/empty-state.component.ts | 15 +++ .../shared/modal/modal.component.html | 6 +- .../shared/modal/modal.component.ts | 26 +++-- .../month-picker/month-picker.component.css | 16 ++++ .../month-picker/month-picker.component.html | 10 ++ .../month-picker.component.spec.ts | 32 +++++++ .../month-picker/month-picker.component.ts | 23 +++++ .../group-by-date/group-by-date.pipe.spec.ts | 8 ++ .../pipes/group-by-date/group-by-date.pipe.ts | 40 ++++++++ .../project-list/project-list.component.html | 4 +- src/app/interfaces/entry.ts | 11 +++ src/app/interfaces/index.ts | 2 + src/app/interfaces/project.ts | 1 + 28 files changed, 598 insertions(+), 75 deletions(-) create mode 100644 src/app/components/shared/empty-state/empty-state.component.css create mode 100644 src/app/components/shared/empty-state/empty-state.component.html create mode 100644 src/app/components/shared/empty-state/empty-state.component.spec.ts create mode 100644 src/app/components/shared/empty-state/empty-state.component.ts create mode 100644 src/app/components/shared/month-picker/month-picker.component.css create mode 100644 src/app/components/shared/month-picker/month-picker.component.html create mode 100644 src/app/components/shared/month-picker/month-picker.component.spec.ts create mode 100644 src/app/components/shared/month-picker/month-picker.component.ts create mode 100644 src/app/components/shared/pipes/group-by-date/group-by-date.pipe.spec.ts create mode 100644 src/app/components/shared/pipes/group-by-date/group-by-date.pipe.ts create mode 100644 src/app/interfaces/entry.ts create mode 100644 src/app/interfaces/index.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b611dc7bc..3ca3c7755 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,7 +3,6 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; - import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -13,11 +12,17 @@ import { SidebarComponent } from './components/shared/sidebar/sidebar.component' import { ClockComponent } from './components/shared/clock/clock.component'; import { TimeClockComponent } from './components/options-sidebar/time-clock/time-clock.component'; import { ProjectManagementComponent } from './components/options-sidebar/project-management/project-management.component'; +import { TimeEntriesComponent } from "./components/options-sidebar/time-entries/time-entries.component"; import { ProjectListComponent } from './components/shared/project-list/project-list.component'; import { CreateProjectComponent } from './components/shared/create-project/create-project.component'; import { DetailsFieldsComponent } from './components/shared/details-fields/details-fields.component'; import { ProjectListHoverComponent } from './components/shared/project-list-hover/project-list-hover.component'; import { ModalComponent } from './components/shared/modal/modal.component'; +import { MonthPickerComponent } from './components/shared/month-picker/month-picker.component'; +import { EmptyStateComponent } from './components/shared/empty-state/empty-state.component'; +import { GroupByDatePipe } from './components/shared/pipes/group-by-date/group-by-date.pipe'; + + @NgModule({ declarations: [ AppComponent, @@ -32,7 +37,11 @@ import { ModalComponent } from './components/shared/modal/modal.component'; TimeClockComponent, DetailsFieldsComponent, ProjectListHoverComponent, - ModalComponent + ModalComponent, + TimeEntriesComponent, + MonthPickerComponent, + EmptyStateComponent, + GroupByDatePipe ], imports: [ CommonModule, @@ -45,5 +54,4 @@ import { ModalComponent } from './components/shared/modal/modal.component'; providers: [], bootstrap: [AppComponent] }) -export class AppModule { } - +export class AppModule {} diff --git a/src/app/components/options-sidebar/time-clock/time-clock.component.html b/src/app/components/options-sidebar/time-clock/time-clock.component.html index 50337aca9..f5be01851 100644 --- a/src/app/components/options-sidebar/time-clock/time-clock.component.html +++ b/src/app/components/options-sidebar/time-clock/time-clock.component.html @@ -81,4 +81,4 @@
Technology fie - \ No newline at end of file + diff --git a/src/app/components/options-sidebar/time-entries/time-entries.component.css b/src/app/components/options-sidebar/time-entries/time-entries.component.css index e69de29bb..4b6e05eb5 100644 --- a/src/app/components/options-sidebar/time-entries/time-entries.component.css +++ b/src/app/components/options-sidebar/time-entries/time-entries.component.css @@ -0,0 +1,46 @@ +.container-time-entries { + padding: 1rem; +} + +.header-entries { + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} + +.accordion-container { + max-height: 25rem; + overflow-y: auto; +} + +.accordion-container::-webkit-scrollbar { + display: none; +} + +.date-header { + background-color: #e6e6e6; + border-radius: 0; + border-bottom: 1px solid rgba(0, 0, 0, 0.125); + font-size: small; + padding: 0 0.9rem; +} + +.date-header > a { + color: #000000; +} + +.btn-small > i { + font-size: 0.8rem; + opacity: 0.7; +} + +.entries { + align-items: center; + border-bottom: 1px solid rgba(0, 0, 0, 0.125); + display: flex; + font-size: small; +} + +.entries:hover { + background-color: #d5edf0; + cursor: pointer; +} diff --git a/src/app/components/options-sidebar/time-entries/time-entries.component.html b/src/app/components/options-sidebar/time-entries/time-entries.component.html index f4ee1f815..401cb29e0 100644 --- a/src/app/components/options-sidebar/time-entries/time-entries.component.html +++ b/src/app/components/options-sidebar/time-entries/time-entries.component.html @@ -1,5 +1,66 @@ -
+
+
+
Time Entries
+ +
+
Project
+
Duration
+
Actions
+
+ +
+
+ + -

time-entries works!

- -
\ No newline at end of file + +
+
+
+ {{ item.project }} +
+
+ {{ item.duration }} +
+
+ + +
+
+
+
+
+ + + +
+
+ + diff --git a/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts b/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts index 304646888..8215f896b 100644 --- a/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts +++ b/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts @@ -1,10 +1,21 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TimeEntriesComponent } from './time-entries.component'; +import { GroupByDatePipe } from '../../shared/pipes/group-by-date/group-by-date.pipe'; describe('TimeEntriesComponent', () => { let component: TimeEntriesComponent; let fixture: ComponentFixture; + const entry = { + id: "entry_1", + project: "Mido - 05 de Febrero", + startDate: "2020-02-05T15:36:15.887Z", + endDate: "2020-02-05T18:36:15.887Z", + activity: "development", + technology: "Angular, TypeScript", + comments: "No comments", + ticket: "EY-25" + }; function setup() { // tslint:disable-next-line: no-shadowed-variable @@ -15,7 +26,7 @@ describe('TimeEntriesComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ TimeEntriesComponent ] + declarations: [ TimeEntriesComponent, GroupByDatePipe ] }) .compileComponents(); })); @@ -30,13 +41,55 @@ describe('TimeEntriesComponent', () => { expect(component).toBeTruthy(); }); - it('should have p tag as \'time-entries works!\'', async(() => { + /* it('should have p tag as \'time-entries works!\'', async(() => { // tslint:disable-next-line: no-shadowed-variable const { app, fixture } = setup(); fixture.detectChanges(); const compile = fixture.debugElement.nativeElement; const ptag = compile.querySelector('p'); expect(ptag.textContent).toBe('time-entries works!'); + })); */ + + it('should call filter entry', async(() => { + component.ngOnInit(); + expect(component.dataByMonth.length).toEqual(3); })); -}); \ No newline at end of file + it('should open Delete Modal', () => { + component.openModal(entry); + expect(component.entryToDelete).toBe(entry); + expect(component.showModal).toBe(true); + }); + + it('should filter the Entry to edit', () => { + const entryId = "entry_1" + component.editEntry(entryId); + expect(component.entry.project).toBe(entry.project); + expect(component.entry.startDate).toBe(entry.startDate); + expect(component.entry.endDate).toBe(entry.endDate); + expect(component.entry.activity).toBe(entry.activity); + expect(component.entry.technology).toBe(entry.technology); + }); + + it('should save an Entry', () => { + component.entryId = 'entry_1'; + component.saveEntry(entry); + expect(component.entryList[0].project).toBe('Mido - 05 de Febrero'); + expect(component.entryList[0].startDate).toBe('2020-02-05T15:36:15.887Z'); + expect(component.entryList[0].endDate).toBe('2020-02-05T18:36:15.887Z'); + expect(component.entryList[0].activity).toBe('development'); + expect(component.entryList[0].technology).toBe('Angular, TypeScript'); + }); + + it('should delete a Entry', () => { + const entryId = "entry_2"; + component.removeEntry(entryId); + expect(component.dataByMonth.length).toBe(2); + }); + + it('should get the entry List by Month', () => { + const month = 3; + component.getMonth(month); + expect(component.dataByMonth.length).toEqual(1); + }); +}); diff --git a/src/app/components/options-sidebar/time-entries/time-entries.component.ts b/src/app/components/options-sidebar/time-entries/time-entries.component.ts index 17ea41840..b13ce1cbe 100644 --- a/src/app/components/options-sidebar/time-entries/time-entries.component.ts +++ b/src/app/components/options-sidebar/time-entries/time-entries.component.ts @@ -1,15 +1,102 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; +import { Entry } from '../../../interfaces/entry'; @Component({ - selector: 'app-time-entries', - templateUrl: './time-entries.component.html', - styleUrls: ['./time-entries.component.css'] + selector: "app-time-entries", + templateUrl: "./time-entries.component.html", + styleUrls: ["./time-entries.component.css"] }) export class TimeEntriesComponent implements OnInit { + showModal: boolean = false; + entryId: string; + entry: Entry; + entryToDelete: Entry; + dataByMonth: Entry[]; + + entryList = [ + { + id: "entry_1", + project: "Mido - 05 de Febrero", + startDate: "2020-02-05T15:36:15.887Z", + endDate: "2020-02-05T18:36:15.887Z", + activity: "development", + technology: "Angular, TypeScript", + comments: "No comments", + ticket: "EY-25" + }, + { + id: "entry_2", + project: "Mido 15 de Marzo", + startDate: "2020-03-15T20:36:15.887Z", + endDate: "2020-03-15T23:36:15.887Z", + activity: "development", + technology: "Angular, TypeScript", + comments: "No comments", + ticket: "EY-38" + }, + { + id: "entry_3", + project: "GoSpace 15 y 16 de Marzo", + startDate: "2020-03-15T23:36:15.887Z", + endDate: "2020-03-16T05:36:15.887Z", + activity: "development", + technology: "Angular, TypeScript", + comments: "No comments", + ticket: "EY-225" + }, + { + id: "entry_4", + project: "Mido 16 de Marzo", + startDate: "2020-03-16T15:36:15.887Z", + endDate: "2020-03-16T18:36:15.887Z", + activity: "development", + technology: "Angular, TypeScript", + comments: "No comments", + ticket: "EY-89" + }, + { + id: "entry_5", + project: "Ernst&Young 01 de Abril", + startDate: "2020-04-01T09:36:15.887Z", + endDate: "2020-04-01T15:36:15.887Z", + activity: "development", + technology: "Angular, TypeScript", + comments: "No comments", + ticket: "EY-59" + } + ]; + constructor() { } ngOnInit(): void { + this.dataByMonth = this.entryList.filter(entry => new Date(entry.startDate).getMonth() === new Date().getMonth()); + } + + openModal(itemToDelete: Entry) { + this.entryToDelete = itemToDelete; + this.showModal = true; + } + + editEntry(entryId: string) { + this.entryId = entryId; + this.entry = this.entryList.find((entry) => entry.id === entryId); } + saveEntry(newData): void { + const entryIndex = this.entryList.findIndex((entry => entry.id === this.entryId)); + this.entryList[entryIndex].project = newData.project; + this.entryList[entryIndex].activity = newData.activity; + this.entryList[entryIndex].technology = newData.technology; + this.entryList[entryIndex].ticket = newData.jiraTicket; + this.entryList[entryIndex].comments = newData.notes; + } + + removeEntry(entryId: string) { + this.dataByMonth = this.dataByMonth.filter((entry: Entry) => entry.id !== entryId); + } + + getMonth(month: number) { + this.dataByMonth = this.entryList.filter(entry => new Date(entry.startDate).getMonth() === month); + } } diff --git a/src/app/components/shared/clock/clock.component.spec.ts b/src/app/components/shared/clock/clock.component.spec.ts index 658511272..cf30c912a 100644 --- a/src/app/components/shared/clock/clock.component.spec.ts +++ b/src/app/components/shared/clock/clock.component.spec.ts @@ -31,15 +31,15 @@ describe('ClockComponent', () => { expect(component).toBeTruthy(); }); - it('should show the current hour of day', () => { - const currentDate: Date = new Date(); - expect(component.currentDate.getHours()).toEqual(currentDate.getHours()); - }); - - it('should show the current minutes of day', () => { - const currentDate: Date = new Date(); - expect(component.currentDate.getMinutes()).toEqual(currentDate.getMinutes()); - }); + /* it('should show the current hour of day', () => { + const currentHour = 11; + expect(component.currentDate.getHours()).toEqual(currentHour); + }); */ + + /* it('should show the current minutes of day', () => { + const currenMinutes = 5; + expect(component.currentDate.getMinutes()).toEqual(currenMinutes); + }); */ it('should show the current seconds of day', () => { const currentDate: Date = new Date(); diff --git a/src/app/components/shared/create-project/create-project.component.ts b/src/app/components/shared/create-project/create-project.component.ts index c31de6dbc..d00bc6d9c 100644 --- a/src/app/components/shared/create-project/create-project.component.ts +++ b/src/app/components/shared/create-project/create-project.component.ts @@ -34,8 +34,10 @@ export class CreateProjectComponent implements OnInit { ngOnChanges(): void { if (this.projectToEdit) { this.editProjectId = this.projectToEdit.id; - this.projectForm.setValue({name: this.projectToEdit.name, details: this.projectToEdit.details, - status: this.projectToEdit.status, completed: this.projectToEdit.completed}); + this.projectForm.setValue({ + name: this.projectToEdit.name, details: this.projectToEdit.details, + status: this.projectToEdit.status, completed: this.projectToEdit.completed + }); } } diff --git a/src/app/components/shared/details-fields/details-fields.component.css b/src/app/components/shared/details-fields/details-fields.component.css index 82869783c..06b6e01f5 100644 --- a/src/app/components/shared/details-fields/details-fields.component.css +++ b/src/app/components/shared/details-fields/details-fields.component.css @@ -1,3 +1,7 @@ .span-width { width: 6rem; } + +.hidden { + display: none; +} diff --git a/src/app/components/shared/details-fields/details-fields.component.html b/src/app/components/shared/details-fields/details-fields.component.html index 7365bc192..fd89befb5 100644 --- a/src/app/components/shared/details-fields/details-fields.component.html +++ b/src/app/components/shared/details-fields/details-fields.component.html @@ -1,44 +1,40 @@ -
+ +
+
+ Project +
+ +
- + Activity
- +
- Jira Ticket + Jira Ticket
- +
Technology
- +
- + +
+
- diff --git a/src/app/components/shared/details-fields/details-fields.component.spec.ts b/src/app/components/shared/details-fields/details-fields.component.spec.ts index 18266ca45..65f3971b0 100644 --- a/src/app/components/shared/details-fields/details-fields.component.spec.ts +++ b/src/app/components/shared/details-fields/details-fields.component.spec.ts @@ -1,16 +1,34 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormBuilder } from '@angular/forms'; import { DetailsFieldsComponent } from './details-fields.component'; describe('DetailsFieldsComponent', () => { let component: DetailsFieldsComponent; let fixture: ComponentFixture; + const initialData = { + project: '', + activity: '', + ticket: '', + technology: '', + comments: '' + } + + const newData = { + project: 'Ernst&Young', + activity: 'development', + ticket: 'WA-15', + technology: 'Angular', + comments: 'No notes' + } beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ DetailsFieldsComponent ] - }) - .compileComponents(); + declarations: [DetailsFieldsComponent], + providers: [ + FormBuilder + ], + }).compileComponents(); })); beforeEach(() => { @@ -22,4 +40,22 @@ describe('DetailsFieldsComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should emit saveEntry event', () => { + spyOn(component.saveEntry, 'emit'); + component.onSubmit(); + expect(component.saveEntry.emit).toHaveBeenCalledWith(initialData); + }); + + it('should emit ngOnChange without data', () => { + component.entryToEdit = null; + component.ngOnChanges(); + expect(component.entryForm.value).toEqual(initialData); + }); + + it('should emit ngOnChange with new data', () => { + component.entryToEdit = newData; + component.ngOnChanges(); + expect(component.entryForm.value).toEqual(newData); + }); }); diff --git a/src/app/components/shared/details-fields/details-fields.component.ts b/src/app/components/shared/details-fields/details-fields.component.ts index eea5de70b..93547a015 100644 --- a/src/app/components/shared/details-fields/details-fields.component.ts +++ b/src/app/components/shared/details-fields/details-fields.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-details-fields', @@ -6,10 +7,38 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./details-fields.component.css'] }) export class DetailsFieldsComponent implements OnInit { + @Input() entryToEdit; + @Input() formType: string; + @Output() saveEntry = new EventEmitter(); + @ViewChild('closeModal') closeModal: ElementRef; + entryForm: FormGroup; - constructor() { } + constructor(private formBuilder: FormBuilder) { + this.entryForm = this.formBuilder.group({ + project: '', + activity: '', + ticket: '', + technology: '', + comments: '' + }); + } + + ngOnInit(): void { } - ngOnInit(): void { + ngOnChanges(): void { + if (this.entryToEdit) { + this.entryForm.setValue({ + project: this.entryToEdit.project, + activity: this.entryToEdit.activity, + ticket: this.entryToEdit.ticket, + technology: this.entryToEdit.technology, + comments: this.entryToEdit.comments + }); + } } + onSubmit() { + this.saveEntry.emit(this.entryForm.value); + this.closeModal.nativeElement.click(); + } } diff --git a/src/app/components/shared/empty-state/empty-state.component.css b/src/app/components/shared/empty-state/empty-state.component.css new file mode 100644 index 000000000..597443547 --- /dev/null +++ b/src/app/components/shared/empty-state/empty-state.component.css @@ -0,0 +1,8 @@ +.container-empty-state { + opacity: 0.3; + padding: 5rem; +} + +.container-empty-state i { + font-size: 5rem; +} diff --git a/src/app/components/shared/empty-state/empty-state.component.html b/src/app/components/shared/empty-state/empty-state.component.html new file mode 100644 index 000000000..1c536d61e --- /dev/null +++ b/src/app/components/shared/empty-state/empty-state.component.html @@ -0,0 +1,4 @@ +
+ +

no data to display

+
diff --git a/src/app/components/shared/empty-state/empty-state.component.spec.ts b/src/app/components/shared/empty-state/empty-state.component.spec.ts new file mode 100644 index 000000000..c5cd9ed4e --- /dev/null +++ b/src/app/components/shared/empty-state/empty-state.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EmptyStateComponent } from './empty-state.component'; + +describe('EmptyStateComponent', () => { + let component: EmptyStateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EmptyStateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EmptyStateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/empty-state/empty-state.component.ts b/src/app/components/shared/empty-state/empty-state.component.ts new file mode 100644 index 000000000..0e58e14a1 --- /dev/null +++ b/src/app/components/shared/empty-state/empty-state.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-empty-state', + templateUrl: './empty-state.component.html', + styleUrls: ['./empty-state.component.css'] +}) +export class EmptyStateComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/components/shared/modal/modal.component.html b/src/app/components/shared/modal/modal.component.html index 8e07addaa..05e9a29e1 100644 --- a/src/app/components/shared/modal/modal.component.html +++ b/src/app/components/shared/modal/modal.component.html @@ -1,5 +1,5 @@ diff --git a/src/app/interfaces/entry.ts b/src/app/interfaces/entry.ts new file mode 100644 index 000000000..62904c0b3 --- /dev/null +++ b/src/app/interfaces/entry.ts @@ -0,0 +1,11 @@ +export interface Entry { + id: string, + project: string, + startDate: string, + endDate: string, + activity: string, + technology: string, + comments?: string, + ticket?: string +} + diff --git a/src/app/interfaces/index.ts b/src/app/interfaces/index.ts new file mode 100644 index 000000000..e41e3fb3d --- /dev/null +++ b/src/app/interfaces/index.ts @@ -0,0 +1,2 @@ +export * from './project'; +export * from './entry'; diff --git a/src/app/interfaces/project.ts b/src/app/interfaces/project.ts index 1c7f6c435..74a01539e 100644 --- a/src/app/interfaces/project.ts +++ b/src/app/interfaces/project.ts @@ -5,3 +5,4 @@ export interface Project { status: string; completed: boolean; } + From ed3eaf04eb54dec3a057cc9ff0ea4607fa580232 Mon Sep 17 00:00:00 2001 From: Jorge Flores Date: Mon, 23 Mar 2020 13:58:45 -0500 Subject: [PATCH 2/3] Fix id type to string --- src/app/app.module.ts | 6 +- .../project-management.component.spec.ts | 21 +-- .../project-management.component.ts | 4 +- .../time-clock/time-clock.component.html | 165 +++++++++--------- .../time-entries.component.spec.ts | 40 +++-- .../time-entries/time-entries.component.ts | 90 +++++----- .../shared/clock/clock.component.spec.ts | 13 +- .../create-project.component.ts | 2 +- .../details-fields.component.spec.ts | 7 +- .../shared/modal/modal.component.spec.ts | 19 +- .../month-picker/month-picker.component.ts | 2 +- .../pipes/group-by-date/group-by-date.pipe.ts | 7 - .../project-list.component.spec.ts | 6 +- .../project-list/project-list.component.ts | 2 +- src/app/interfaces/project.ts | 2 +- src/app/services/project.service.spec.ts | 8 +- src/app/services/project.service.ts | 2 +- 17 files changed, 206 insertions(+), 190 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3ca3c7755..b39b40bbd 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,8 +3,8 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; -import { AppRoutingModule } from './app-routing.module'; +import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { NavbarComponent } from './components/shared/navbar/navbar.component'; import { UserComponent } from './components/shared/user/user.component'; @@ -12,7 +12,7 @@ import { SidebarComponent } from './components/shared/sidebar/sidebar.component' import { ClockComponent } from './components/shared/clock/clock.component'; import { TimeClockComponent } from './components/options-sidebar/time-clock/time-clock.component'; import { ProjectManagementComponent } from './components/options-sidebar/project-management/project-management.component'; -import { TimeEntriesComponent } from "./components/options-sidebar/time-entries/time-entries.component"; +import { TimeEntriesComponent } from './components/options-sidebar/time-entries/time-entries.component'; import { ProjectListComponent } from './components/shared/project-list/project-list.component'; import { CreateProjectComponent } from './components/shared/create-project/create-project.component'; import { DetailsFieldsComponent } from './components/shared/details-fields/details-fields.component'; @@ -54,4 +54,4 @@ import { GroupByDatePipe } from './components/shared/pipes/group-by-date/group-b providers: [], bootstrap: [AppComponent] }) -export class AppModule {} +export class AppModule { } diff --git a/src/app/components/options-sidebar/project-management/project-management.component.spec.ts b/src/app/components/options-sidebar/project-management/project-management.component.spec.ts index 1674699b8..642bcb2fa 100644 --- a/src/app/components/options-sidebar/project-management/project-management.component.spec.ts +++ b/src/app/components/options-sidebar/project-management/project-management.component.spec.ts @@ -1,11 +1,12 @@ import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + import { ProjectManagementComponent } from './project-management.component'; -import { Project } from '../../../interfaces/project'; +import { Project } from '../../../interfaces'; import { ProjectService } from '../../../services/project.service'; import { of } from 'rxjs'; import { CreateProjectComponent } from '../../../components/shared/create-project/create-project.component'; import { ProjectListComponent } from '../../../components/shared/project-list/project-list.component'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; describe('ProjectManagementComponent', () => { let component: ProjectManagementComponent; @@ -13,21 +14,21 @@ describe('ProjectManagementComponent', () => { let projectService: ProjectService; const projects: Project[] = [{ - id: 1, + id: '1', name: 'app 1', details: 'It is a good app', status: 'inactive', completed: true }, { - id: 2, + id: '2', name: 'app 2', details: 'It is a good app', status: 'inactive', completed: false }, { - id: 3, + id: '3', name: 'app 3', details: 'It is a good app', status: 'active', @@ -89,14 +90,14 @@ describe('ProjectManagementComponent', () => { it('should edit a project #updateProject', () => { const project = { - id: 1, + id: '1', name: 'app test', details: 'It is a excelent app', status: 'inactive', completed: true }; - component.editedProjectId = 1; + component.editedProjectId = '1'; component.updateProject(project); expect(component.projects.length).toEqual(3); expect(component.projects[0].name).toBe('app test'); @@ -106,14 +107,14 @@ describe('ProjectManagementComponent', () => { }); it('should filter the project to edit #editProject', () => { - const editProjectId = 2; + const editProjectId = '2'; component.editProject(editProjectId); expect(component.project.name).toBe('app 2'); }); it('should clean the project #cancelForm', () => { const project = { - id: 1, + id: '1', name: 'app 1', details: 'It is a good app', status: 'inactive', @@ -149,7 +150,7 @@ describe('ProjectManagementComponent', () => { })); it('should delete a project #deleteProject', () => { - const projectId = 1; + const projectId = '1'; component.deleteProject(projectId); expect(component.projects.length).toEqual(2); diff --git a/src/app/components/options-sidebar/project-management/project-management.component.ts b/src/app/components/options-sidebar/project-management/project-management.component.ts index f11ec63fb..bb8051352 100644 --- a/src/app/components/options-sidebar/project-management/project-management.component.ts +++ b/src/app/components/options-sidebar/project-management/project-management.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { Project } from '../../../interfaces/project'; +import { Project } from '../../../interfaces'; import { ProjectService } from '../../../services/project.service'; @Component({ @@ -30,7 +30,7 @@ export class ProjectManagementComponent implements OnInit { this.projects[projectIndex].status = projectData.status; this.projects[projectIndex].completed = projectData.completed; } else { - const newProject: Project = { id: this.projects.length + 1, name: projectData.name, + const newProject: Project = { id: (this.projects.length + 1).toString(), name: projectData.name, details: projectData.details, status: projectData.status, completed: false }; this.projects = this.projects.concat(newProject); diff --git a/src/app/components/options-sidebar/time-clock/time-clock.component.html b/src/app/components/options-sidebar/time-clock/time-clock.component.html index f5be01851..e3a306492 100644 --- a/src/app/components/options-sidebar/time-clock/time-clock.component.html +++ b/src/app/components/options-sidebar/time-clock/time-clock.component.html @@ -1,84 +1,91 @@ -
-
-
-
-
- Time clock -
-
- -
-
+
+ + + +
+
+
+
+ Time clock +
+
+
+
+
-
-

{{ username }} clocked in at {{ hour | number: '2.0-2' }}:{{ minute | number: '2.0-2' }}:{{ seconds | number: '2.0-2' }}

-

{{ username }} clocked out at {{ hour | number: '2.0-2' }}:{{ minute | number: '2.0-2' }}:{{ seconds | number: '2.0-2' }}

-
Totals
-
-
-
-
Current
-

{{ hourCounterRealTime | number: '2.0-2' }}:{{ minuteCounterRealTime | number: '2.0-2' }}:{{ secondsCounterRealTime | number: '2.0-2' }}

-
-
-
Day
-

00:00

-
-
-
Week
-

00:00

-
-
-
Projects
-
-
- -
-
-

Top

-
    - -
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- - -
-
Technology field is required. Enter this field to clock out.
-
-
-
-
-
-
-
-
- -
-
- - -
-
-
+
+

{{ username }} clocked in at {{ clockInUsername }}

+

{{ username }} clocked out at {{ clockOutUsername }}

+
Totals
+
+
+
+
Current
+

{{ hour | number: '2.0-2' }}:{{ minute | number: '2.0-2' }}:{{ seconds | number: '2.0-2' }}

+
+
+
Day
+

4:22

+
+
+
Week
+

14:00

+
+
+
Projects
+
+
+ +
+
+

Top

+
    + +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ +
+
+ + +
+
+
diff --git a/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts b/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts index 8215f896b..fddcd9cac 100644 --- a/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts +++ b/src/app/components/options-sidebar/time-entries/time-entries.component.spec.ts @@ -1,20 +1,25 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { TimeEntriesComponent } from './time-entries.component'; import { GroupByDatePipe } from '../../shared/pipes/group-by-date/group-by-date.pipe'; +import { MonthPickerComponent } from '../../shared/month-picker/month-picker.component'; +import { DetailsFieldsComponent } from '../../shared/details-fields/details-fields.component'; +import { EmptyStateComponent } from '../../shared/empty-state/empty-state.component'; +import { ModalComponent } from '../../shared/modal/modal.component'; describe('TimeEntriesComponent', () => { let component: TimeEntriesComponent; let fixture: ComponentFixture; const entry = { - id: "entry_1", - project: "Mido - 05 de Febrero", - startDate: "2020-02-05T15:36:15.887Z", - endDate: "2020-02-05T18:36:15.887Z", - activity: "development", - technology: "Angular, TypeScript", - comments: "No comments", - ticket: "EY-25" + id: 'entry_1', + project: 'Mido - 05 de Febrero', + startDate: '2020-02-05T15:36:15.887Z', + endDate: '2020-02-05T18:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', + comments: 'No comments', + ticket: 'EY-25' }; function setup() { @@ -26,7 +31,18 @@ describe('TimeEntriesComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ TimeEntriesComponent, GroupByDatePipe ] + declarations: [ + EmptyStateComponent, + DetailsFieldsComponent, + GroupByDatePipe, + ModalComponent, + MonthPickerComponent, + TimeEntriesComponent + ], + imports: [ + FormsModule, + ReactiveFormsModule + ] }) .compileComponents(); })); @@ -41,16 +57,16 @@ describe('TimeEntriesComponent', () => { expect(component).toBeTruthy(); }); - /* it('should have p tag as \'time-entries works!\'', async(() => { + it('should have p tag as \'time-entries works!\'', async(() => { // tslint:disable-next-line: no-shadowed-variable const { app, fixture } = setup(); fixture.detectChanges(); const compile = fixture.debugElement.nativeElement; const ptag = compile.querySelector('p'); expect(ptag.textContent).toBe('time-entries works!'); - })); */ + })); - it('should call filter entry', async(() => { + it('should call dataByMonth in ngOnInit()', async(() => { component.ngOnInit(); expect(component.dataByMonth.length).toEqual(3); })); diff --git a/src/app/components/options-sidebar/time-entries/time-entries.component.ts b/src/app/components/options-sidebar/time-entries/time-entries.component.ts index b13ce1cbe..55b231c1c 100644 --- a/src/app/components/options-sidebar/time-entries/time-entries.component.ts +++ b/src/app/components/options-sidebar/time-entries/time-entries.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit } from "@angular/core"; -import { Entry } from '../../../interfaces/entry'; +import { Component, OnInit } from '@angular/core'; +import { Entry } from '../../../interfaces'; @Component({ - selector: "app-time-entries", - templateUrl: "./time-entries.component.html", - styleUrls: ["./time-entries.component.css"] + selector: 'app-time-entries', + templateUrl: './time-entries.component.html', + styleUrls: ['./time-entries.component.css'] }) export class TimeEntriesComponent implements OnInit { @@ -16,54 +16,54 @@ export class TimeEntriesComponent implements OnInit { entryList = [ { - id: "entry_1", - project: "Mido - 05 de Febrero", - startDate: "2020-02-05T15:36:15.887Z", - endDate: "2020-02-05T18:36:15.887Z", - activity: "development", - technology: "Angular, TypeScript", - comments: "No comments", - ticket: "EY-25" + id: 'entry_1', + project: 'Mido - 05 de Febrero', + startDate: '2020-02-05T15:36:15.887Z', + endDate: '2020-02-05T18:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', + comments: 'No comments', + ticket: 'EY-25' }, { - id: "entry_2", - project: "Mido 15 de Marzo", - startDate: "2020-03-15T20:36:15.887Z", - endDate: "2020-03-15T23:36:15.887Z", - activity: "development", - technology: "Angular, TypeScript", - comments: "No comments", - ticket: "EY-38" + id: 'entry_2', + project: 'Mido 15 de Marzo', + startDate: '2020-03-15T20:36:15.887Z', + endDate: '2020-03-15T23:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', + comments: 'No comments', + ticket: 'EY-38' }, { - id: "entry_3", - project: "GoSpace 15 y 16 de Marzo", - startDate: "2020-03-15T23:36:15.887Z", - endDate: "2020-03-16T05:36:15.887Z", - activity: "development", - technology: "Angular, TypeScript", - comments: "No comments", - ticket: "EY-225" + id: 'entry_3', + project: 'GoSpace 15 y 16 de Marzo', + startDate: '2020-03-15T23:36:15.887Z', + endDate: '2020-03-16T05:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', + comments: 'No comments', + ticket: 'EY-225' }, { - id: "entry_4", - project: "Mido 16 de Marzo", - startDate: "2020-03-16T15:36:15.887Z", - endDate: "2020-03-16T18:36:15.887Z", - activity: "development", - technology: "Angular, TypeScript", - comments: "No comments", - ticket: "EY-89" + id: 'entry_4', + project: 'Mido 16 de Marzo', + startDate: '2020-03-16T15:36:15.887Z', + endDate: '2020-03-16T18:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', + comments: 'No comments', + ticket: 'EY-89' }, { - id: "entry_5", - project: "Ernst&Young 01 de Abril", - startDate: "2020-04-01T09:36:15.887Z", - endDate: "2020-04-01T15:36:15.887Z", - activity: "development", - technology: "Angular, TypeScript", - comments: "No comments", - ticket: "EY-59" + id: 'entry_5', + project: 'Ernst&Young 01 de Abril', + startDate: '2020-04-01T09:36:15.887Z', + endDate: '2020-04-01T15:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', + comments: 'No comments', + ticket: 'EY-59' } ]; diff --git a/src/app/components/shared/clock/clock.component.spec.ts b/src/app/components/shared/clock/clock.component.spec.ts index cf30c912a..9566bfa6b 100644 --- a/src/app/components/shared/clock/clock.component.spec.ts +++ b/src/app/components/shared/clock/clock.component.spec.ts @@ -31,20 +31,13 @@ describe('ClockComponent', () => { expect(component).toBeTruthy(); }); - /* it('should show the current hour of day', () => { + it('should show the current hour of day', () => { const currentHour = 11; expect(component.currentDate.getHours()).toEqual(currentHour); - }); */ + }); - /* it('should show the current minutes of day', () => { + it('should show the current minutes of day', () => { const currenMinutes = 5; expect(component.currentDate.getMinutes()).toEqual(currenMinutes); - }); */ - - it('should show the current seconds of day', () => { - const currentDate: Date = new Date(); - expect(component.currentDate.getSeconds()).toEqual(currentDate.getSeconds()); }); - - }); diff --git a/src/app/components/shared/create-project/create-project.component.ts b/src/app/components/shared/create-project/create-project.component.ts index d00bc6d9c..389a9a41d 100644 --- a/src/app/components/shared/create-project/create-project.component.ts +++ b/src/app/components/shared/create-project/create-project.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, Input, SimpleChanges } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; -import { Project } from '../../../interfaces/project'; +import { Project } from '../../../interfaces'; import { Output, EventEmitter } from '@angular/core'; import { ProjectListComponent } from '../project-list/project-list.component'; diff --git a/src/app/components/shared/details-fields/details-fields.component.spec.ts b/src/app/components/shared/details-fields/details-fields.component.spec.ts index 65f3971b0..7d7c2019d 100644 --- a/src/app/components/shared/details-fields/details-fields.component.spec.ts +++ b/src/app/components/shared/details-fields/details-fields.component.spec.ts @@ -1,5 +1,5 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormBuilder } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DetailsFieldsComponent } from './details-fields.component'; @@ -25,8 +25,9 @@ describe('DetailsFieldsComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [DetailsFieldsComponent], - providers: [ - FormBuilder + imports: [ + FormsModule, + ReactiveFormsModule ], }).compileComponents(); })); diff --git a/src/app/components/shared/modal/modal.component.spec.ts b/src/app/components/shared/modal/modal.component.spec.ts index 986c9587b..01154738d 100644 --- a/src/app/components/shared/modal/modal.component.spec.ts +++ b/src/app/components/shared/modal/modal.component.spec.ts @@ -24,19 +24,24 @@ describe('ModalComponent', () => { }); it('should emit removeProject event #removedProject', () => { - const project = { - id: 1, + const merged = { + id: '1', name: 'app 4', details: 'It is a good app', status: 'inactive', - completed: true + completed: true, + project: 'ErnstYoung', + startDate: '2020-02-05T15:36:15.887Z', + endDate: '2020-02-05T18:36:15.887Z', + activity: 'development', + technology: 'Angular, TypeScript', }; - spyOn(component.removeProject, 'emit'); - component.project = project; + spyOn(component.removeList, 'emit'); + component.list = merged; fixture.detectChanges(); - component.removedProject(project.id); - expect(component.removeProject.emit).toHaveBeenCalled(); + component.removeListById(merged.id); + expect(component.removeList.emit).toHaveBeenCalled(); component.cancelDeleteModal.nativeElement.click(); }); }); diff --git a/src/app/components/shared/month-picker/month-picker.component.ts b/src/app/components/shared/month-picker/month-picker.component.ts index 5b8de8c14..bc43dbc9e 100644 --- a/src/app/components/shared/month-picker/month-picker.component.ts +++ b/src/app/components/shared/month-picker/month-picker.component.ts @@ -8,7 +8,7 @@ import { Component, OnInit, Output, EventEmitter } from '@angular/core'; export class MonthPickerComponent implements OnInit { @Output() monthSelected = new EventEmitter(); activeMonth: number; - months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; constructor() { } diff --git a/src/app/components/shared/pipes/group-by-date/group-by-date.pipe.ts b/src/app/components/shared/pipes/group-by-date/group-by-date.pipe.ts index 2046f5efd..5c9346750 100644 --- a/src/app/components/shared/pipes/group-by-date/group-by-date.pipe.ts +++ b/src/app/components/shared/pipes/group-by-date/group-by-date.pipe.ts @@ -15,15 +15,8 @@ export class GroupByDatePipe implements PipeTransform { const endDate = this.getDate(current.endDate); const startDate = this.getDate(current.startDate); - // console.log("previous[endDate] >>", previous[endDate]); - // console.log("previous[startDate] >>", previous[startDate]); - if (!previous[endDate]) previous[endDate] = []; if (!previous[startDate]) previous[startDate] = [] - /* if (!previous[endDate] || !previous[startDate]) { - previous[endDate] = []; - previous[startDate] = [] - } */ if (startDate !== endDate) previous[startDate].push(current); previous[endDate].push(current); diff --git a/src/app/components/shared/project-list/project-list.component.spec.ts b/src/app/components/shared/project-list/project-list.component.spec.ts index 438257e77..71168eb8a 100644 --- a/src/app/components/shared/project-list/project-list.component.spec.ts +++ b/src/app/components/shared/project-list/project-list.component.spec.ts @@ -25,7 +25,7 @@ describe('ProjectListComponent', () => { it('should emit deleteProject event #removeProject', () => { const project = { - id: 1, + id: '1', name: 'app 4', details: 'It is a good app', status: 'inactive', @@ -41,7 +41,7 @@ describe('ProjectListComponent', () => { it('should open delete modal #openModal', () => { const project = { - id: 1, + id: '1', name: 'app 4', details: 'It is a good app', status: 'inactive', @@ -49,7 +49,7 @@ describe('ProjectListComponent', () => { }; component.openModal(project); - expect(component.projectToDelete.id).toBe(1); + expect(component.projectToDelete.id).toBe('1'); expect(component.projectToDelete.name).toBe('app 4'); expect(component.projectToDelete.details).toBe('It is a good app'); expect(component.projectToDelete.status).toBe('inactive'); diff --git a/src/app/components/shared/project-list/project-list.component.ts b/src/app/components/shared/project-list/project-list.component.ts index 6fc799c95..3c696ccfe 100644 --- a/src/app/components/shared/project-list/project-list.component.ts +++ b/src/app/components/shared/project-list/project-list.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Input } from '@angular/core'; import { Output, EventEmitter } from '@angular/core'; -import { Project } from '../../../interfaces/project'; +import { Project } from '../../../interfaces'; @Component({ selector: 'app-project-list', diff --git a/src/app/interfaces/project.ts b/src/app/interfaces/project.ts index 74a01539e..d5eb3b8ed 100644 --- a/src/app/interfaces/project.ts +++ b/src/app/interfaces/project.ts @@ -1,5 +1,5 @@ export interface Project { - id: number; + id: string; name: string; details: string; status: string; diff --git a/src/app/services/project.service.spec.ts b/src/app/services/project.service.spec.ts index 3648b5b41..6e36e632b 100644 --- a/src/app/services/project.service.spec.ts +++ b/src/app/services/project.service.spec.ts @@ -1,6 +1,6 @@ import { TestBed, inject, async } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; -import { Project } from '../interfaces/project'; +import { Project } from '../interfaces'; import { ProjectService } from './project.service'; describe('ProjectService', () => { @@ -8,21 +8,21 @@ describe('ProjectService', () => { let httpMock: HttpTestingController; const projects: Project[] = [{ - id: 1, + id: '1', name: 'app 1', details: 'It is a good app', status: 'inactive', completed: true }, { - id: 2, + id: '2', name: 'app 2', details: 'It is a good app', status: 'inactive', completed: false }, { - id: 3, + id: '3', name: 'app 3', details: 'It is a good app', status: 'active', diff --git a/src/app/services/project.service.ts b/src/app/services/project.service.ts index 33a2395b9..3e04f2862 100644 --- a/src/app/services/project.service.ts +++ b/src/app/services/project.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Project } from '../interfaces/project'; +import { Project } from '../interfaces'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; From 7d86a717a663ae38d3799733c90b514f92840706 Mon Sep 17 00:00:00 2001 From: Jorge Flores Date: Tue, 24 Mar 2020 18:25:19 -0500 Subject: [PATCH 3/3] Fix variable --- .../options-sidebar/time-clock/time-clock.component.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/components/options-sidebar/time-clock/time-clock.component.html b/src/app/components/options-sidebar/time-clock/time-clock.component.html index e3a306492..b7dfb02f9 100644 --- a/src/app/components/options-sidebar/time-clock/time-clock.component.html +++ b/src/app/components/options-sidebar/time-clock/time-clock.component.html @@ -17,10 +17,8 @@
-

{{ username }} clocked in at {{ clockInUsername }}

-

{{ username }} clocked out at {{ clockOutUsername }}

+

{{ username }} clocked in at {{ hour | number: '2.0-2' }}:{{ minute | number: '2.0-2' }}:{{ seconds | number: '2.0-2' }}

+

{{ username }} clocked out at {{ hour | number: '2.0-2' }}:{{ minute | number: '2.0-2' }}:{{ seconds | number: '2.0-2' }}

Totals