-
Notifications
You must be signed in to change notification settings - Fork 1
refactor: TTA-49 change date picker #886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
MarcoAguirre
merged 3 commits into
master
from
TTA-49-change-time-selection-for-reports-page
Jun 22, 2022
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
src/app/modules/reports/components/time-range-custom/time-range-custom.component.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<form (ngSubmit)="onSubmit()" class="date-range-form"> | ||
<label class="col-form-label my-1">Select your Date Range:</label> | ||
<mat-form-field appearance="fill"> | ||
<mat-label>Enter a date range</mat-label> | ||
<mat-date-range-input [formGroup]="range" [rangePicker]="picker"> | ||
<input matStartDate formControlName="start" placeholder="Start date" /> | ||
<input matEndDate formControlName="end" placeholder="End date" /> | ||
</mat-date-range-input> | ||
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle> | ||
<mat-date-range-picker | ||
#picker | ||
[calendarHeaderComponent]="TimeRangeHeader" | ||
></mat-date-range-picker> | ||
</mat-form-field> | ||
<div class="col-12 col-md-2 my-1"> | ||
<button type="submit" class="btn btn-primary">Search</button> | ||
</div> | ||
</form> |
14 changes: 14 additions & 0 deletions
14
src/app/modules/reports/components/time-range-custom/time-range-custom.component.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
:host { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
height: 100%; | ||
} | ||
|
||
.date-range-form{ | ||
display: flex; | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
|
138 changes: 138 additions & 0 deletions
138
src/app/modules/reports/components/time-range-custom/time-range-custom.component.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import { SimpleChange } from '@angular/core'; | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; | ||
import { MockStore, provideMockStore } from '@ngrx/store/testing'; | ||
import * as moment from 'moment'; | ||
import { ToastrService } from 'ngx-toastr'; | ||
import { EntryState } from 'src/app/modules/time-clock/store/entry.reducer'; | ||
import * as entryActions from '../../../time-clock/store/entry.actions'; | ||
import { TimeRangeCustomComponent } from './time-range-custom.component'; | ||
|
||
|
||
describe('TimeRangeCustomComponent', () => { | ||
let component: TimeRangeCustomComponent; | ||
let fixture: ComponentFixture<TimeRangeCustomComponent>; | ||
let store: MockStore<EntryState>; | ||
const toastrServiceStub = { | ||
error: () => {} | ||
}; | ||
|
||
const timeEntry = { | ||
id: '1', | ||
start_date: new Date(), | ||
end_date: new Date(), | ||
activity_id: '1', | ||
technologies: ['react', 'redux'], | ||
comments: 'any comment', | ||
uri: 'TT-123', | ||
project_id: '1' | ||
}; | ||
|
||
const state = { | ||
active: timeEntry, | ||
entryList: [timeEntry], | ||
isLoading: false, | ||
message: 'test', | ||
createError: false, | ||
updateError: false, | ||
timeEntriesSummary: null, | ||
entriesForReport: [timeEntry], | ||
}; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [FormsModule, ReactiveFormsModule], | ||
declarations: [ TimeRangeCustomComponent ], | ||
providers: [ | ||
provideMockStore({ initialState: state }), | ||
{ provide: ToastrService, useValue: toastrServiceStub } | ||
], | ||
}) | ||
.compileComponents(); | ||
store = TestBed.inject(MockStore); | ||
}); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(TimeRangeCustomComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
|
||
it('setInitialDataOnScreen on ngOnInit', () => { | ||
spyOn(component, 'setInitialDataOnScreen'); | ||
|
||
component.ngOnInit(); | ||
|
||
expect(component.setInitialDataOnScreen).toHaveBeenCalled(); | ||
}); | ||
|
||
it('LoadEntriesByTimeRange action is triggered when start date is before end date', () => { | ||
const end = moment(new Date()).subtract(1, 'days'); | ||
const start = moment(new Date()); | ||
spyOn(store, 'dispatch'); | ||
component.range.controls.start.setValue(end); | ||
component.range.controls.end.setValue(start); | ||
|
||
component.onSubmit(); | ||
|
||
expect(store.dispatch).toHaveBeenCalledWith(new entryActions.LoadEntriesByTimeRange({ | ||
start_date: end.startOf('day'), | ||
end_date: start.endOf('day') | ||
})); | ||
}); | ||
|
||
it('shows an error when the end date is before the start date', () => { | ||
spyOn(toastrServiceStub, 'error'); | ||
const yesterday = moment(new Date()).subtract(2, 'days'); | ||
const today = moment(new Date()); | ||
spyOn(store, 'dispatch'); | ||
component.range.controls.start.setValue(today); | ||
component.range.controls.end.setValue(yesterday); | ||
|
||
component.onSubmit(); | ||
|
||
expect(toastrServiceStub.error).toHaveBeenCalled(); | ||
}); | ||
|
||
it('setInitialDataOnScreen sets dates in form', () => { | ||
spyOn(component.range.controls.start, 'setValue'); | ||
spyOn(component.range.controls.end, 'setValue'); | ||
|
||
component.setInitialDataOnScreen(); | ||
|
||
expect(component.range.controls.start.setValue).toHaveBeenCalled(); | ||
expect(component.range.controls.end.setValue).toHaveBeenCalled(); | ||
|
||
}); | ||
|
||
it('triggers onSubmit to set initial data', () => { | ||
spyOn(component, 'onSubmit'); | ||
|
||
component.setInitialDataOnScreen(); | ||
|
||
expect(component.onSubmit).toHaveBeenCalled(); | ||
}); | ||
|
||
it('When the ngOnChanges method is called, the onSubmit method is called', () => { | ||
const userIdCalled = 'test-user-1'; | ||
spyOn(component, 'onSubmit'); | ||
|
||
component.ngOnChanges({userId: new SimpleChange(null, userIdCalled, false)}); | ||
|
||
expect(component.onSubmit).toHaveBeenCalled(); | ||
}); | ||
|
||
it('When the ngOnChanges method is the first change, the onSubmit method is not called', () => { | ||
const userIdNotCalled = 'test-user-2'; | ||
spyOn(component, 'onSubmit'); | ||
|
||
component.ngOnChanges({userId: new SimpleChange(null, userIdNotCalled, true)}); | ||
|
||
expect(component.onSubmit).not.toHaveBeenCalled(); | ||
}); | ||
|
||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a white space at the end of the file |
61 changes: 61 additions & 0 deletions
61
src/app/modules/reports/components/time-range-custom/time-range-custom.component.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { OnChanges, SimpleChanges, Component, OnInit, Input } from '@angular/core'; | ||
import { FormControl, FormGroup } from '@angular/forms'; | ||
import { TimeRangeHeaderComponent } from './time-range-header/time-range-header.component'; | ||
import { DATE_FORMAT } from 'src/environments/environment'; | ||
import { formatDate } from '@angular/common'; | ||
import { Store } from '@ngrx/store'; | ||
import { EntryState } from '../../../time-clock/store/entry.reducer'; | ||
import { ToastrService } from 'ngx-toastr'; | ||
import * as entryActions from '../../../time-clock/store/entry.actions'; | ||
import * as moment from 'moment'; | ||
|
||
|
||
@Component({ | ||
selector: 'app-time-range-custom', | ||
templateUrl: './time-range-custom.component.html', | ||
styleUrls: ['./time-range-custom.component.scss'] | ||
}) | ||
export class TimeRangeCustomComponent implements OnInit, OnChanges { | ||
@Input() userId: string; | ||
|
||
readonly TimeRangeHeader = TimeRangeHeaderComponent; | ||
|
||
range = new FormGroup({ | ||
start: new FormControl(), | ||
end: new FormControl(), | ||
}); | ||
|
||
constructor(private store: Store<EntryState>, private toastrService: ToastrService) { | ||
} | ||
ngOnInit(): void { | ||
this.setInitialDataOnScreen(); | ||
} | ||
|
||
ngOnChanges(changes: SimpleChanges){ | ||
if (!changes.userId.firstChange){ | ||
this.onSubmit(); | ||
} | ||
} | ||
|
||
setInitialDataOnScreen() { | ||
this.range.setValue({ | ||
start: formatDate(moment().startOf('isoWeek').format('l'), DATE_FORMAT, 'en'), | ||
end: formatDate(moment().format('l'), DATE_FORMAT, 'en') | ||
}); | ||
this.onSubmit(); | ||
} | ||
|
||
onSubmit() { | ||
const startDate = moment(this.range.getRawValue().start).startOf('day'); | ||
const endDate = moment(this.range.getRawValue().end).endOf('day'); | ||
if (endDate.isBefore(startDate)) { | ||
this.toastrService.error('The end date should be after the start date'); | ||
} else { | ||
this.store.dispatch(new entryActions.LoadEntriesByTimeRange({ | ||
start_date: moment(this.range.getRawValue().start).startOf('day'), | ||
end_date: moment(this.range.getRawValue().end).endOf('day'), | ||
}, this.userId)); | ||
} | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
...s/reports/components/time-range-custom/time-range-header/time-range-header.component.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<app-time-range-panel></app-time-range-panel> | ||
|
||
<div class="time-range-header"> | ||
<button | ||
mat-icon-button | ||
class="time-range-double-arrow" | ||
(click)="previousClicked('year')" | ||
> | ||
<mat-icon>keyboard_arrow_left</mat-icon> | ||
<mat-icon>keyboard_arrow_left</mat-icon> | ||
</button> | ||
<button mat-icon-button class="time-range-month" (click)="previousClicked('month')"> | ||
<mat-icon>keyboard_arrow_left</mat-icon> | ||
</button> | ||
|
||
<span class="time-range-header-label">{{ periodLabel }}</span> | ||
|
||
<button mat-icon-button class="time-range-month-next" (click)="nextClicked('month')"> | ||
<mat-icon>keyboard_arrow_right</mat-icon> | ||
</button> | ||
<button | ||
mat-icon-button | ||
class="time-range-double-arrow time-range-double-arrow-next" | ||
(click)="nextClicked('year')" | ||
> | ||
<mat-icon>keyboard_arrow_right</mat-icon> | ||
<mat-icon>keyboard_arrow_right</mat-icon> | ||
</button> | ||
</div> |
16 changes: 16 additions & 0 deletions
16
...s/reports/components/time-range-custom/time-range-header/time-range-header.component.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
.time-range-header { | ||
display: flex; | ||
align-items: center; | ||
padding: 0.5em; | ||
} | ||
|
||
.time-range-header-label { | ||
flex: 1; | ||
height: 1em; | ||
font-weight: 500; | ||
text-align: center; | ||
} | ||
|
||
.time-range-double-arrow .mat-icon { | ||
margin: -22%; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add one aditional whitespace after imports