diff --git a/angular.json b/angular.json index 98e35a34a..09f0ed075 100644 --- a/angular.json +++ b/angular.json @@ -1,132 +1,130 @@ { - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "projects", - "projects": { - "time-tracker": { - "projectType": "application", - "schematics": {}, - "root": "", - "sourceRoot": "src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/time-tracker", - "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.app.json", - "aot": true, - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "./node_modules/bootstrap/dist/css/bootstrap.min.css", - "src/styles.css" - ], - "scripts": [ - "./node_modules/jquery/dist/jquery.min.js", - "./node_modules/bootstrap/dist/js/bootstrap.min.js" - ] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "time-tracker": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/time-tracker", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "aot": true, + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "./node_modules/bootstrap/dist/css/bootstrap.min.css", + "src/styles.css" + ], + "scripts": [ + "./node_modules/jquery/dist/jquery.min.js", + "./node_modules/bootstrap/dist/js/bootstrap.min.js" + ] + }, + "configurations": { + "production": { + "fileReplacements": [{ + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + }], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [{ + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "time-tracker:build" + }, + "configurations": { + "production": { + "browserTarget": "time-tracker:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "time-tracker:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "codeCoverage": true, + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.css" + ], + "scripts": [] + } }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "tsconfig.app.json", + "tsconfig.spec.json", + "e2e/tsconfig.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + }, + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "time-tracker:serve" + }, + "configurations": { + "production": { + "devServerTarget": "time-tracker:serve:production" + } + } } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "time-tracker:build" - }, - "configurations": { - "production": { - "browserTarget": "time-tracker:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "time-tracker:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "src/styles.css" - ], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "tsconfig.app.json", - "tsconfig.spec.json", - "e2e/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" - ] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "e2e/protractor.conf.js", - "devServerTarget": "time-tracker:serve" - }, - "configurations": { - "production": { - "devServerTarget": "time-tracker:serve:production" } - } } - } + }, + "defaultProject": "time-tracker", + "cli": { + "analytics": false } - }, - "defaultProject": "time-tracker", - "cli": { - "analytics": false - } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 506884b07..14cc4f915 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6846,10 +6846,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { "version": "3.1.1", diff --git a/package.json b/package.json index f838c048b..27b88bce8 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@angular/router": "~9.0.3", "bootstrap": "^4.4.1", "jquery": "^3.4.1", + "minimist": "^1.2.5", "rxjs": "~6.5.4", "tslib": "^1.10.0", "zone.js": "~0.10.2" diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6365744e7..4aeaf92c6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,3 +1,4 @@ +import { CommonModule } from '@angular/common'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -11,6 +12,10 @@ import { ClockComponent } from './components/shared/clock/clock.component'; import { ProjectManagementComponent } from './components/options-sidebar/project-management/project-management.component'; import { ProjectListComponent } from './components/shared/project-list/project-list.component'; import { CreateProjectComponent } from './components/shared/create-project/create-project.component'; +import { TimeClockComponent } from './components/options-sidebar/time-clock/time-clock.component'; +import { DetailsFieldsComponent } from './components/shared/details-fields/details-fields.component'; +import { ProjectListHoverComponent } from './components/shared/project-list-hover/project-list-hover.component'; + @NgModule({ declarations: [ AppComponent, @@ -20,9 +25,13 @@ import { CreateProjectComponent } from './components/shared/create-project/creat ClockComponent, ProjectManagementComponent, ProjectListComponent, - CreateProjectComponent + CreateProjectComponent, + TimeClockComponent, + DetailsFieldsComponent, + ProjectListHoverComponent, ], imports: [ + CommonModule, BrowserModule, AppRoutingModule, FormsModule, diff --git a/src/app/components/options-sidebar/getting-started/getting-started.component.spec.ts b/src/app/components/options-sidebar/getting-started/getting-started.component.spec.ts index d36756064..5bb8ecb36 100644 --- a/src/app/components/options-sidebar/getting-started/getting-started.component.spec.ts +++ b/src/app/components/options-sidebar/getting-started/getting-started.component.spec.ts @@ -6,6 +6,13 @@ describe('GettingStartedComponent', () => { let component: GettingStartedComponent; let fixture: ComponentFixture; + function setup() { + // tslint:disable-next-line: no-shadowed-variable + const fixture = TestBed.createComponent(GettingStartedComponent); + const app = fixture.debugElement.componentInstance; + return { fixture, app }; + } + beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ GettingStartedComponent ] @@ -22,4 +29,15 @@ describe('GettingStartedComponent', () => { it('should be created', () => { expect(component).toBeTruthy(); }); + + it('should have p tag as \'getting-started works!\'', async(() => { + // tslint:disable-next-line: no-shadowed-variable + const { app, fixture } = setup(); + fixture.detectChanges(); + const compile = fixture.debugElement.nativeElement; + const h1tag = compile.querySelector('p'); + expect(h1tag.textContent).toBe('getting-started works!'); + })); + + }); diff --git a/src/app/components/options-sidebar/reports/reports.component.spec.ts b/src/app/components/options-sidebar/reports/reports.component.spec.ts index 8b8ed574f..45b9dbdf9 100644 --- a/src/app/components/options-sidebar/reports/reports.component.spec.ts +++ b/src/app/components/options-sidebar/reports/reports.component.spec.ts @@ -6,6 +6,13 @@ describe('ReportsComponent', () => { let component: ReportsComponent; let fixture: ComponentFixture; + function setup() { + // tslint:disable-next-line: no-shadowed-variable + const fixture = TestBed.createComponent(ReportsComponent); + const app = fixture.debugElement.componentInstance; + return { fixture, app }; + } + beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ ReportsComponent ] @@ -22,4 +29,14 @@ describe('ReportsComponent', () => { it('should be created', () => { expect(component).toBeTruthy(); }); + + it('should have p tag as \'reports works!\'', async(() => { + // tslint:disable-next-line: no-shadowed-variable + const { app, fixture } = setup(); + fixture.detectChanges(); + const compile = fixture.debugElement.nativeElement; + const h1tag = compile.querySelector('p'); + expect(h1tag.textContent).toBe('reports works!'); + })); + }); diff --git a/src/app/components/options-sidebar/time-clock/time-clock.component.css b/src/app/components/options-sidebar/time-clock/time-clock.component.css index e69de29bb..0e808f74e 100644 --- a/src/app/components/options-sidebar/time-clock/time-clock.component.css +++ b/src/app/components/options-sidebar/time-clock/time-clock.component.css @@ -0,0 +1,10 @@ +.content-ClockIn { + padding: 2.1rem 1rem; +} + +.timer { + align-items: center; + display: flex; + height: 100%; + justify-content: center; +} 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 80644640c..1474cef3e 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,5 +1,20 @@ -
- -

time-clock works!

- -
\ No newline at end of file +
+
+
+
PROJECTS
+ +
+
+ +
+
+
+
+
Timer Here!
+
+
+
+
diff --git a/src/app/components/options-sidebar/time-clock/time-clock.component.spec.ts b/src/app/components/options-sidebar/time-clock/time-clock.component.spec.ts index 1c55547bb..a6f8761a5 100644 --- a/src/app/components/options-sidebar/time-clock/time-clock.component.spec.ts +++ b/src/app/components/options-sidebar/time-clock/time-clock.component.spec.ts @@ -1,25 +1,67 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { DebugElement } from "@angular/core"; -import { TimeClockComponent } from './time-clock.component'; +import { TimeClockComponent } from "./time-clock.component"; +import { ProjectListHoverComponent } from "../../shared/project-list-hover/project-list-hover.component"; -describe('TimeClockComponent', () => { +describe("TimeClockComponent", () => { let component: TimeClockComponent; let fixture: ComponentFixture; + let de: DebugElement; + + function setup() { + // tslint:disable-next-line: no-shadowed-variable + const fixture = TestBed.createComponent(TimeClockComponent); + const app = fixture.debugElement.componentInstance; + return { fixture, app }; + } beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ TimeClockComponent ] - }) - .compileComponents(); + declarations: [TimeClockComponent, ProjectListHoverComponent] + }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(TimeClockComponent); component = fixture.componentInstance; + de = fixture.debugElement; fixture.detectChanges(); }); - it('should be created', () => { + it("should be created", () => { expect(component).toBeTruthy(); }); + + it("should have p tag as 'time-clock works!'", async(() => { + // tslint:disable-next-line: no-shadowed-variable + const { app, fixture } = setup(); + fixture.detectChanges(); + const compile = fixture.debugElement.nativeElement; + const h1tag = compile.querySelector("p"); + expect(h1tag.textContent).toBe("time-clock works!"); + })); + + it("should set showfileds as true", () => { + const show = true; + component.setShowFields(show); + expect(component.showFields).toBe(true); + }); + + it('should be called the setShowFields event #1', () => { + spyOn(component, 'setShowFields'); + const showFields = de.query(By.directive(ProjectListHoverComponent)); + const cmp = showFields.componentInstance; + cmp.showFields.emit(true); + expect(component.setShowFields).toHaveBeenCalledWith(true); + }); + + it('should be called the setShowFields event #2', () => { + spyOn(component, 'setShowFields'); + const showFields = de.query(By.directive(ProjectListHoverComponent)); + const li = showFields.query(By.css('li')); + li.nativeElement.click(); + expect(component.setShowFields).toHaveBeenCalledWith(true); + }); }); diff --git a/src/app/components/options-sidebar/time-clock/time-clock.component.ts b/src/app/components/options-sidebar/time-clock/time-clock.component.ts index f34bb7b11..1a9be2774 100644 --- a/src/app/components/options-sidebar/time-clock/time-clock.component.ts +++ b/src/app/components/options-sidebar/time-clock/time-clock.component.ts @@ -1,15 +1,25 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-time-clock', - templateUrl: './time-clock.component.html', - styleUrls: ['./time-clock.component.css'] + selector: "app-time-clock", + templateUrl: "./time-clock.component.html", + styleUrls: ["./time-clock.component.css"] }) export class TimeClockComponent implements OnInit { + projects = [ + { id: "P1", name: "Project 1" }, + { id: "P2", name: "Project 2" }, + { id: "P3", name: "Project 3" }, + { id: "P4", name: "Project 4" } + ]; - constructor() { } + showFields: boolean; - ngOnInit(): void { - } + constructor() {} + + ngOnInit(): void {} + setShowFields(show: boolean) { + this.showFields = show; + } } 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 2ed82ad2e..ee057a38e 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 @@ -6,6 +6,13 @@ describe('TimeEntriesComponent', () => { let component: TimeEntriesComponent; let fixture: ComponentFixture; + function setup() { + // tslint:disable-next-line: no-shadowed-variable + const fixture = TestBed.createComponent(TimeEntriesComponent); + const app = fixture.debugElement.componentInstance; + return { fixture, app }; + } + beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TimeEntriesComponent ] @@ -22,4 +29,14 @@ describe('TimeEntriesComponent', () => { it('should be created', () => { expect(component).toBeTruthy(); }); + + 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 h1tag = compile.querySelector('p'); + expect(h1tag.textContent).toBe('time-entries works!'); + })); + }); diff --git a/src/app/components/options-sidebar/time-off/time-off.component.spec.ts b/src/app/components/options-sidebar/time-off/time-off.component.spec.ts index dfa074f03..4035649cd 100644 --- a/src/app/components/options-sidebar/time-off/time-off.component.spec.ts +++ b/src/app/components/options-sidebar/time-off/time-off.component.spec.ts @@ -6,6 +6,13 @@ describe('TimeOffComponent', () => { let component: TimeOffComponent; let fixture: ComponentFixture; + function setup() { + // tslint:disable-next-line: no-shadowed-variable + const fixture = TestBed.createComponent(TimeOffComponent); + const app = fixture.debugElement.componentInstance; + return { fixture, app }; + } + beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TimeOffComponent ] @@ -22,4 +29,13 @@ describe('TimeOffComponent', () => { it('should be created', () => { expect(component).toBeTruthy(); }); + + it('should have p tag as \'time-off works!\'', async(() => { + // tslint:disable-next-line: no-shadowed-variable + const { app, fixture } = setup(); + fixture.detectChanges(); + const compile = fixture.debugElement.nativeElement; + const h1tag = compile.querySelector('p'); + expect(h1tag.textContent).toBe('time-off works!'); + })); }); diff --git a/src/app/components/shared/details-fields/details-fields.component.css b/src/app/components/shared/details-fields/details-fields.component.css new file mode 100644 index 000000000..82869783c --- /dev/null +++ b/src/app/components/shared/details-fields/details-fields.component.css @@ -0,0 +1,3 @@ +.span-width { + width: 6rem; +} diff --git a/src/app/components/shared/details-fields/details-fields.component.html b/src/app/components/shared/details-fields/details-fields.component.html new file mode 100644 index 000000000..7365bc192 --- /dev/null +++ b/src/app/components/shared/details-fields/details-fields.component.html @@ -0,0 +1,44 @@ +
+
+
+ +
+ +
+
+
+ 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 new file mode 100644 index 000000000..18266ca45 --- /dev/null +++ b/src/app/components/shared/details-fields/details-fields.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DetailsFieldsComponent } from './details-fields.component'; + +describe('DetailsFieldsComponent', () => { + let component: DetailsFieldsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DetailsFieldsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DetailsFieldsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/details-fields/details-fields.component.ts b/src/app/components/shared/details-fields/details-fields.component.ts new file mode 100644 index 000000000..eea5de70b --- /dev/null +++ b/src/app/components/shared/details-fields/details-fields.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-details-fields', + templateUrl: './details-fields.component.html', + styleUrls: ['./details-fields.component.css'] +}) +export class DetailsFieldsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/components/shared/project-list-hover/project-list-hover.component.css b/src/app/components/shared/project-list-hover/project-list-hover.component.css new file mode 100644 index 000000000..4bdee70fe --- /dev/null +++ b/src/app/components/shared/project-list-hover/project-list-hover.component.css @@ -0,0 +1,15 @@ +.content-projects { + max-height: 10rem; + overflow-x: auto; +} + +.content-projects > li { + cursor: pointer; + font-size: 0.8rem; + padding: 0.5rem 0.8rem; +} + +.button-clockIn { + font-size: 0.7rem; + padding: 0 0.3rem; +} diff --git a/src/app/components/shared/project-list-hover/project-list-hover.component.html b/src/app/components/shared/project-list-hover/project-list-hover.component.html new file mode 100644 index 000000000..212bf4d2d --- /dev/null +++ b/src/app/components/shared/project-list-hover/project-list-hover.component.html @@ -0,0 +1,17 @@ +
    +
  • + {{ item.name }} + Clock In +
  • +
diff --git a/src/app/components/shared/project-list-hover/project-list-hover.component.spec.ts b/src/app/components/shared/project-list-hover/project-list-hover.component.spec.ts new file mode 100644 index 000000000..85024d03a --- /dev/null +++ b/src/app/components/shared/project-list-hover/project-list-hover.component.spec.ts @@ -0,0 +1,38 @@ +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; + +import { ProjectListHoverComponent } from "./project-list-hover.component"; + +describe("ProjectListHoverComponent", () => { + let component: ProjectListHoverComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ProjectListHoverComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProjectListHoverComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); + + it("should set selectedId with Id", () => { + const id: string = "P1"; + component.clockIn(id); + expect(component.selectedId).toBe(id); + }); + + it("should emit showFields event", () => { + const id: string = "P1"; + component.showFields.subscribe((showFields: boolean) => + expect(showFields).toEqual(true) + ); + component.clockIn(id); + }); +}); diff --git a/src/app/components/shared/project-list-hover/project-list-hover.component.ts b/src/app/components/shared/project-list-hover/project-list-hover.component.ts new file mode 100644 index 000000000..caf0c8b4c --- /dev/null +++ b/src/app/components/shared/project-list-hover/project-list-hover.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core"; + +@Component({ + selector: "app-project-list-hover", + templateUrl: "./project-list-hover.component.html", + styleUrls: ["./project-list-hover.component.css"] +}) +export class ProjectListHoverComponent implements OnInit { + @Input() projects: any; + @Output() showFields = new EventEmitter(); + + selectedId: string; + showButton: number; + + constructor() { + this.showButton = -1; + } + + ngOnInit(): void {} + + clockIn(id: string) { + this.selectedId = id; + this.showFields.emit(true); + } +}