Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Time Entries Section
  • Loading branch information
jorgecod authored and enriquezrene committed Mar 24, 2020
commit 0edaff1c20791cb0ae79960fa9ccf9adb438372e
16 changes: 12 additions & 4 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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,
Expand All @@ -32,7 +37,11 @@ import { ModalComponent } from './components/shared/modal/modal.component';
TimeClockComponent,
DetailsFieldsComponent,
ProjectListHoverComponent,
ModalComponent
ModalComponent,
TimeEntriesComponent,
MonthPickerComponent,
EmptyStateComponent,
GroupByDatePipe
],
imports: [
CommonModule,
Expand All @@ -45,5 +54,4 @@ import { ModalComponent } from './components/shared/modal/modal.component';
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

export class AppModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ <h6 *ngIf="showAlertEnterTecnology" class="text-danger text-left">Technology fie
</div>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,66 @@
<div class="text-center mt-5">
<div class="container-time-entries">
<div class="card">
<div class="card-header">Time Entries</div>
<app-month-picker (monthSelected)="getMonth($event)"></app-month-picker>
<div class="row m-0 header-entries">
<div class="col">Project</div>
<div class="col">Duration</div>
<div class="col-2">Actions</div>
</div>
<!--Accordion wrapper-->
<div *ngIf="dataByMonth.length > 0; else emptyState" class="accordion accordion-container" role="tablist"
aria-multiselectable="true">
<div class="card" *ngFor="let entry of dataByMonth | groupByDate; let rowIndex = index">
<!-- Card header -->
<div class="date-header" role="tab" id="heading10">
<a data-toggle="collapse" [href]="'#entry' + rowIndex">
<div class="mb-0">
{{ entry.date }}
</div>
</a>
</div>

<p>time-entries works!</p>

</div>
<!-- Card body -->
<div *ngFor="let item of entry.details" [id]="'entry' + rowIndex" class="collapse show" role="tabpanel"
aria-labelledby="heading10">
<div class="row m-0 entries">
<div class="col">
{{ item.project }}
</div>
<div class="col">
{{ item.duration }}
</div>
<div class="col-2">
<button class="btn btn-sm btn-small" data-toggle="modal" data-target="#editRecordsByDate"
(click)="editEntry(item.id)">
<i class="fa fa-edit"></i>
</button>
<button class="btn btn-sm btn-small" data-toggle="modal" data-target="#deleteModal"
(click)="openModal(item)">
<i class="fa fa-trash"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<ng-template #emptyState>
<app-empty-state></app-empty-state>
</ng-template>
</div>
</div>
<div class="modal fade" id="editRecordsByDate" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Edit Entry</h5>
</div>
<div class="modal-body">
<app-details-fields [formType]='"entries"' [entryToEdit]="entry" (saveEntry)="saveEntry($event)"></app-details-fields>
</div>
</div>
</div>
</div>
<app-modal *ngIf="showModal" class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-hidden="true" [list]="entryToDelete"
(removeList)="removeEntry($event)">
</app-modal>
Original file line number Diff line number Diff line change
@@ -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<TimeEntriesComponent>;
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
Expand All @@ -15,7 +26,7 @@ describe('TimeEntriesComponent', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TimeEntriesComponent ]
declarations: [ TimeEntriesComponent, GroupByDatePipe ]
})
.compileComponents();
}));
Expand All @@ -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);
}));

});
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);
});
});
Original file line number Diff line number Diff line change
@@ -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);
}
}
18 changes: 9 additions & 9 deletions src/app/components/shared/clock/clock.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading