Skip to content

Commit 764621e

Browse files
authored
Merge branch 'master' into 210-fix-event
2 parents 270bf69 + 50022d9 commit 764621e

15 files changed

+111
-52
lines changed

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,24 @@ Install the following extensions:
5252
- `Prettier - Code formatter`.
5353
- Go to user settings (`settings.json`) and enable formatting on save: `"editor.formatOnSave": true`.
5454

55-
### Commit message format
56-
A commit message needs to start with one of the following words to bump the application version
57-
properly (This application is following a semver strategy for versioning https://semver.org/)
58-
### Sumary
59-
- **fix** is equal to Patch Release example: 1.0.1
60-
- **feat** is equal to Feature Release example: 1.1.0
61-
- **perf** is equal to Breaking Release example: 2.0.0
55+
### Commit messages format
56+
Commit messages' format follows the [Conventional Commits guidelines](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification,
57+
and specifically we are relying on the [Angular commit specifications](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines) to bump the [semantic version](https://semver.org/) and generate app change log.
58+
59+
Below there are some common examples you can use for your commit messages:
60+
61+
- **feat**: A new feature.
62+
- **fix**: A bug fix.
63+
- **perf**: A code change that improves performance.
64+
- **build**: Changes that affect the build system or external dependencies (example scopes: npm, ts configuration).
65+
- **ci**: Changes to our CI or CD configuration files and scripts (example scopes: Azure devops, github actions).
66+
- **docs**: Documentation only changes.
67+
- **refactor**: A code change that neither fixes a bug nor adds a feature.
68+
- **style**: Changes that do not affect the meaning of the code (typos, white-space, formatting, missing semi-colons, etc).
69+
It is important to mention that this key is not related to css styles.
70+
- **test**: Adding missing tests or correcting existing tests.
6271
### Example
63-
fix: #48 implement semantic version.
72+
fix: #48 implement semantic versioning.
6473

6574
## Code scaffolding
6675
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
},
7676
"config": {
7777
"commit-message-validator": {
78-
"pattern": "^(fix: #|feat: #|perf: #)[0-9].*",
78+
"pattern": "^(fix: #|feat: #|perf: #|build: #|ci: #|docs: #|refactor: #|style: #|test: #)[0-9].*",
7979
"errorMessage": "Your commit message needs to start with fix:, feat:, or perf: followed by issue number, e.g. fix: #43 any commit message"
8080
}
8181
},

src/app/modules/time-clock/components/entry-fields/entry-fields.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
</div>
2121
<input
2222
(keyup)="getTechnologies($event.target.value)"
23+
id="technology"
24+
formControlName="technology"
2325
type="text"
2426
class="form-control"
2527
aria-label="Small"

src/app/modules/time-clock/components/entry-fields/entry-fields.component.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ describe('EntryFieldsComponent', () => {
5656
project_id: 'project-id-15',
5757
description: 'description for active entry',
5858
uri: 'abc',
59+
technology: '',
5960
};
6061

6162
beforeEach(async(() => {

src/app/modules/time-clock/components/entry-fields/entry-fields.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export class EntryFieldsComponent implements OnInit {
4242
this.entryForm = this.formBuilder.group({
4343
description: '',
4444
uri: '',
45+
technology: '',
4546
});
4647
}
4748

@@ -102,6 +103,8 @@ export class EntryFieldsComponent implements OnInit {
102103
this.store.dispatch(
103104
new entryActions.UpdateActiveEntry({ ...this.newData, technologies: this.selectedTechnology })
104105
);
106+
this.showlist = false;
107+
this.entryForm.get('technology').reset();
105108
}
106109
}
107110

src/app/modules/time-clock/pages/time-clock.component.html

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1+
<app-notification [notificationMsg]="message | async" [isError]="isError" *ngIf="showNotification"></app-notification>
12
<div class="text-center mt-3">
2-
<div class="alert alert-danger" role="alert">
3-
{{message}}
4-
</div>
5-
63
<div class="card">
74
<div class="card-body">
85
<h6 class="text-left"><strong>Summary</strong></h6>

src/app/modules/time-clock/pages/time-clock.component.spec.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
import { StopTimeEntryRunning } from './../store/entry.actions';
1+
import {EntryActionTypes, StopTimeEntryRunning } from './../store/entry.actions';
22
import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
33
import { HttpClientTestingModule } from '@angular/common/http/testing';
44
import { provideMockStore, MockStore } from '@ngrx/store/testing';
55

66
import { TimeClockComponent } from './time-clock.component';
77
import { ProjectState } from '../../customer-management/components/projects/components/store/project.reducer';
88
import { ProjectListHoverComponent } from '../components';
9-
import { ProjectService } from '../../customer-management/components/projects/components/services/project.service';
109
import { FilterProjectPipe } from '../../shared/pipes';
1110
import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service';
11+
import {ActionsSubject} from '@ngrx/store';
1212

1313
describe('TimeClockComponent', () => {
1414
let component: TimeClockComponent;
1515
let fixture: ComponentFixture<TimeClockComponent>;
1616
let store: MockStore<ProjectState>;
17-
let projectService: ProjectService;
1817
let azureAdB2CService: AzureAdB2CService;
18+
const actionSub: ActionsSubject = new ActionsSubject();
1919
const state = {
2020
projects: {
2121
projects: [{ id: 'id', name: 'name', project_type_id: '' }],
@@ -44,7 +44,10 @@ describe('TimeClockComponent', () => {
4444
TestBed.configureTestingModule({
4545
imports: [HttpClientTestingModule],
4646
declarations: [TimeClockComponent, ProjectListHoverComponent, FilterProjectPipe],
47-
providers: [ProjectService, AzureAdB2CService, provideMockStore({ initialState: state })],
47+
providers: [
48+
AzureAdB2CService,
49+
{ provide: ActionsSubject, useValue: actionSub },
50+
provideMockStore({ initialState: state })],
4851
}).compileComponents();
4952
store = TestBed.inject(MockStore);
5053
}));
@@ -53,7 +56,6 @@ describe('TimeClockComponent', () => {
5356
fixture = TestBed.createComponent(TimeClockComponent);
5457
component = fixture.componentInstance;
5558
fixture.detectChanges();
56-
projectService = TestBed.inject(ProjectService);
5759
azureAdB2CService = TestBed.inject(AzureAdB2CService);
5860
});
5961

@@ -77,13 +79,6 @@ describe('TimeClockComponent', () => {
7779
expect(azureAdB2CService.getName).toHaveBeenCalledTimes(0);
7880
});
7981

80-
it('Service injected via inject(...) and TestBed.get(...) should be the same instance', inject(
81-
[ProjectService],
82-
(injectService: ProjectService) => {
83-
expect(injectService).toBe(projectService);
84-
}
85-
));
86-
8782
it('clockOut dispatch a StopTimeEntryRunning action', () => {
8883
spyOn(store, 'dispatch');
8984

@@ -92,4 +87,22 @@ describe('TimeClockComponent', () => {
9287
expect(store.dispatch).toHaveBeenCalledWith(new StopTimeEntryRunning('id'));
9388
});
9489

90+
it('on success create entry, the notification is shown', () => {
91+
const actionSubject = TestBed.get(ActionsSubject) as ActionsSubject;
92+
const action = {
93+
type: EntryActionTypes.CREATE_ENTRY_SUCCESS
94+
};
95+
actionSubject.next(action);
96+
expect(component.showNotification).toEqual(true);
97+
});
98+
99+
it('on success stop entry, the notification is shown', () => {
100+
const actionSubject = TestBed.get(ActionsSubject) as ActionsSubject;
101+
const action = {
102+
type: EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS
103+
};
104+
actionSubject.next(action);
105+
expect(component.showNotification).toEqual(true);
106+
});
107+
95108
});
Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
1-
import { getStatusMessage } from './../../customer-management/store/customer-management.selectors';
2-
import { getActiveTimeEntry } from './../store/entry.selectors';
3-
import { StopTimeEntryRunning } from './../store/entry.actions';
4-
import { Entry } from './../../shared/models/entry.model';
5-
import { Store, select } from '@ngrx/store';
6-
import { Component, OnInit } from '@angular/core';
7-
import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service';
1+
import {getStatusMessage} from './../../time-clock/store/entry.selectors';
2+
import {getActiveTimeEntry} from './../store/entry.selectors';
3+
import {EntryActionTypes, StopTimeEntryRunning} from './../store/entry.actions';
4+
import {Entry} from './../../shared/models/entry.model';
5+
import {Store, select, ActionsSubject} from '@ngrx/store';
6+
import {Component, OnInit} from '@angular/core';
7+
import {AzureAdB2CService} from '../../login/services/azure.ad.b2c.service';
8+
import {Observable, Subscription} from 'rxjs';
9+
import {filter} from 'rxjs/operators';
810

911
@Component({
1012
selector: 'app-time-clock',
1113
templateUrl: './time-clock.component.html',
1214
styleUrls: ['./time-clock.component.scss'],
1315
})
1416
export class TimeClockComponent implements OnInit {
15-
1617
username: string;
1718
areFieldsVisible = false;
1819
activeTimeEntry: Entry;
19-
message: string;
20+
message: Observable<string>;
21+
showNotification = false;
22+
isError = false;
23+
actionsSubscription: Subscription;
2024

21-
constructor(private azureAdB2CService: AzureAdB2CService, private store: Store<Entry>) {
25+
constructor(private azureAdB2CService: AzureAdB2CService, private store: Store<Entry>, private actionsSubject$: ActionsSubject) {
2226
}
2327

2428
ngOnInit() {
29+
this.message = this.store.pipe(select(getStatusMessage));
2530
this.username = this.azureAdB2CService.isLogin() ? this.azureAdB2CService.getName() : '';
2631
this.store.pipe(select(getActiveTimeEntry)).subscribe((activeTimeEntry) => {
2732
this.activeTimeEntry = activeTimeEntry;
@@ -31,8 +36,12 @@ export class TimeClockComponent implements OnInit {
3136
this.areFieldsVisible = false;
3237
}
3338
});
34-
this.store.pipe(select(getStatusMessage)).subscribe((valueMessage) => {
35-
this.message = valueMessage;
39+
40+
this.actionsSubscription = this.actionsSubject$.pipe(
41+
filter((action: any) => (action.type === EntryActionTypes.CREATE_ENTRY_SUCCESS) ||
42+
action.type === EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS)
43+
).subscribe((action) => {
44+
this.displayNotification();
3645
});
3746
}
3847

@@ -41,4 +50,8 @@ export class TimeClockComponent implements OnInit {
4150
this.areFieldsVisible = false;
4251
}
4352

53+
displayNotification() {
54+
this.showNotification = true;
55+
setTimeout(() => ((this.showNotification = false), (this.isError = false)), 3000);
56+
}
4457
}

src/app/modules/time-clock/store/entry.actions.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ describe('Actions for Entries', () => {
2929
project_id: '1',
3030
description: 'It is good for learning',
3131
});
32-
expect(updateActiveEntrySuccess.type).toEqual(actions.EntryActionTypes.UDPATE_ACTIVE_ENTRY_SUCCESS);
32+
expect(updateActiveEntrySuccess.type).toEqual(actions.EntryActionTypes.UPDATE_ACTIVE_ENTRY_SUCCESS);
3333
});
3434

3535
it('UpdateActiveEntryFail type is EntryActionTypes.UDPATE_ACTIVE_ENTRY_FAIL', () => {
3636
const updateActiveEntryFail = new actions.UpdateActiveEntryFail('error');
37-
expect(updateActiveEntryFail.type).toEqual(actions.EntryActionTypes.UDPATE_ACTIVE_ENTRY_FAIL);
37+
expect(updateActiveEntryFail.type).toEqual(actions.EntryActionTypes.UPDATE_ACTIVE_ENTRY_FAIL);
3838
});
3939
});

src/app/modules/time-clock/store/entry.actions.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export enum EntryActionTypes {
88
CREATE_ENTRY = '[Entry] CREATE_ENTRY',
99
CREATE_ENTRY_SUCCESS = '[Entry] CREATE_ENTRY_SUCCESS',
1010
CREATE_ENTRY_FAIL = '[Entry] CREATE_ENTRY_FAIL',
11-
UDPATE_ACTIVE_ENTRY = '[Entry] UDPATE_ACTIVE_ENTRY',
12-
UDPATE_ACTIVE_ENTRY_SUCCESS = '[Entry] UDPATE_ACTIVE_ENTRY_SUCCESS',
13-
UDPATE_ACTIVE_ENTRY_FAIL = '[Entry] UDPATE_ACTIVE_ENTRY_FAIL',
11+
UPDATE_ACTIVE_ENTRY = '[Entry] UPDATE_ACTIVE_ENTRY',
12+
UPDATE_ACTIVE_ENTRY_SUCCESS = '[Entry] UPDATE_ACTIVE_ENTRY_SUCCESS',
13+
UPDATE_ACTIVE_ENTRY_FAIL = '[Entry] UPDATE_ACTIVE_ENTRY_FAIL',
1414
STOP_TIME_ENTRY_RUNNING = '[Entry] STOP_TIME_ENTRIES_RUNNING',
1515
STOP_TIME_ENTRY_RUNNING_SUCCESS = '[Entry] STOP_TIME_ENTRIES_RUNNING_SUCCESS',
1616
STOP_TIME_ENTRY_RUNNING_FAILED = '[Entry] STOP_TIME_ENTRIES_RUNNING_FAILED',
@@ -50,19 +50,19 @@ export class CreateEntryFail implements Action {
5050
}
5151

5252
export class UpdateActiveEntry implements Action {
53-
public readonly type = EntryActionTypes.UDPATE_ACTIVE_ENTRY;
53+
public readonly type = EntryActionTypes.UPDATE_ACTIVE_ENTRY;
5454

5555
constructor(public payload: NewEntry) {}
5656
}
5757

5858
export class UpdateActiveEntrySuccess implements Action {
59-
public readonly type = EntryActionTypes.UDPATE_ACTIVE_ENTRY_SUCCESS;
59+
public readonly type = EntryActionTypes.UPDATE_ACTIVE_ENTRY_SUCCESS;
6060

6161
constructor(public payload: NewEntry) {}
6262
}
6363

6464
export class UpdateActiveEntryFail implements Action {
65-
public readonly type = EntryActionTypes.UDPATE_ACTIVE_ENTRY_FAIL;
65+
public readonly type = EntryActionTypes.UPDATE_ACTIVE_ENTRY_FAIL;
6666

6767
constructor(public error: string) {}
6868
}

0 commit comments

Comments
 (0)