1
- import { Component , EventEmitter , Input , OnInit , Output } from '@angular/core' ;
2
1
import {
3
- CalendarEvent ,
4
- CalendarView ,
5
- } from 'angular-calendar' ;
2
+ ChangeDetectorRef ,
3
+ Component ,
4
+ ElementRef ,
5
+ EventEmitter ,
6
+ Input ,
7
+ OnInit ,
8
+ Output ,
9
+ ViewChild ,
10
+ } from '@angular/core' ;
11
+ import { CalendarEvent , CalendarView } from 'angular-calendar' ;
6
12
import { Observable } from 'rxjs' ;
7
13
import * as moment from 'moment' ;
8
14
import { DataSource } from '../../../shared/models/data-source.model' ;
9
15
import { Entry } from 'src/app/modules/shared/models' ;
10
16
import { map } from 'rxjs/operators' ;
11
17
import { SubstractDatePipe } from 'src/app/modules/shared/pipes/substract-date/substract-date.pipe' ;
18
+ import { differenceInMinutes , startOfDay , startOfHour } from 'date-fns' ;
12
19
13
20
@Component ( {
14
21
selector : 'app-calendar' ,
15
22
templateUrl : './calendar.component.html' ,
16
23
styleUrls : [ './calendar.component.scss' ] ,
17
24
} )
18
25
export class CalendarComponent implements OnInit {
19
- @Input ( ) set timeEntries$ ( timeEntries : Observable < DataSource < Entry > > ) {
26
+ readonly DEFAULT_HEADER_HEIGHT = 52 ;
27
+ readonly VARIATION_HEIGHT : number = 2 ;
28
+
29
+ @ViewChild ( 'scrollContainer' ) scrollContainer : ElementRef < HTMLElement > ;
30
+
31
+ @Input ( ) set timeEntries$ ( timeEntries : Observable < DataSource < Entry > > ) {
20
32
this . castEntryToCalendarEvent ( timeEntries ) ;
21
33
}
22
34
@Input ( ) calendarView : CalendarView = CalendarView . Month ;
@@ -25,7 +37,7 @@ export class CalendarComponent implements OnInit {
25
37
@Output ( ) viewModal : EventEmitter < any > = new EventEmitter < string > ( ) ;
26
38
@Output ( ) deleteTimeEntry : EventEmitter < any > = new EventEmitter < string > ( ) ;
27
39
@Output ( ) changeDate : EventEmitter < any > = new EventEmitter < {
28
- date : Date
40
+ date : Date ;
29
41
} > ( ) ;
30
42
31
43
initialDate : Date ;
@@ -34,97 +46,113 @@ export class CalendarComponent implements OnInit {
34
46
timeEntriesAsEvent : CalendarEvent [ ] ;
35
47
nextDateDisabled : boolean ;
36
48
37
- constructor ( ) {
49
+ constructor ( private referenceChangeDetector : ChangeDetectorRef ) {
38
50
this . initialDate = new Date ( ) ;
39
51
this . previusDate = new Date ( ) ;
40
52
this . isToday = false ;
41
53
this . timeEntriesAsEvent = [ ] ;
42
54
this . nextDateDisabled = true ;
43
- }
55
+ }
44
56
45
57
ngOnInit ( ) : void {
46
58
this . isToday = this . isVisibleForCurrentDate ( ) ;
47
59
this . navigationEnable ( this . calendarView ) ;
48
60
}
49
61
50
- get CalendarViewEnum ( ) : typeof CalendarView {
62
+ get CalendarViewEnum ( ) : typeof CalendarView {
51
63
return CalendarView ;
52
64
}
53
65
66
+ scrollToCurrentTimeMarker ( ) {
67
+ if ( this . calendarView === CalendarView . Week || CalendarView . Day ) {
68
+ const minutesSinceStartOfDay = differenceInMinutes ( startOfHour ( this . currentDate ) , startOfDay ( this . currentDate ) ) ;
69
+ const headerHeight = this . calendarView === CalendarView . Week ? this . DEFAULT_HEADER_HEIGHT : 0 ;
70
+ this . scrollContainer . nativeElement . scrollTop = minutesSinceStartOfDay * this . VARIATION_HEIGHT + headerHeight ;
71
+ }
72
+ }
73
+
54
74
castEntryToCalendarEvent ( timeEntries$ : Observable < DataSource < Entry > > ) {
55
- timeEntries$ . pipe (
56
- map ( ( timeEntriesDatasorce ) => timeEntriesDatasorce . data . map (
57
- ( timeEntries ) => ( {
58
- start : new Date ( timeEntries . start_date ) ,
59
- end : timeEntries . end_date ? new Date ( timeEntries . end_date ) : null ,
60
- title : timeEntries . description ,
61
- id : timeEntries . id ,
62
- meta : timeEntries
63
- } as CalendarEvent )
75
+ timeEntries$
76
+ . pipe (
77
+ map ( ( timeEntriesDatasorce ) =>
78
+ timeEntriesDatasorce . data . map (
79
+ ( timeEntries ) =>
80
+ ( {
81
+ start : new Date ( timeEntries . start_date ) ,
82
+ end : timeEntries . end_date ? new Date ( timeEntries . end_date ) : null ,
83
+ title : timeEntries . description ,
84
+ id : timeEntries . id ,
85
+ meta : timeEntries ,
86
+ } as CalendarEvent )
87
+ )
64
88
)
65
89
)
66
- )
67
- . subscribe ( ( timeEntriesAsEvent ) => {
90
+ . subscribe ( ( timeEntriesAsEvent ) => {
68
91
this . timeEntriesAsEvent = [ ...timeEntriesAsEvent ] . reverse ( ) ;
69
- } ) ;
92
+ } ) ;
70
93
}
71
94
72
95
handleEditEvent ( timeEntryAsEvent : CalendarEvent ) : void {
73
- this . viewModal . emit ( {
74
- id : timeEntryAsEvent . id
96
+ this . viewModal . emit ( {
97
+ id : timeEntryAsEvent . id ,
75
98
} ) ;
76
99
}
77
100
78
101
handleDeleteEvent ( timeEntryAsEvent : CalendarEvent ) : void {
79
102
this . deleteTimeEntry . emit ( {
80
- timeEntry : timeEntryAsEvent . meta
103
+ timeEntry : timeEntryAsEvent . meta ,
81
104
} ) ;
82
105
}
83
106
84
- handleChangeDateEvent ( ) : void {
107
+ handleChangeDateEvent ( ) : void {
85
108
const date = this . currentDate ;
86
109
this . isToday = this . isVisibleForCurrentDate ( ) ;
87
110
this . navigationEnable ( this . calendarView ) ;
88
- this . changeDate . emit ( { date} ) ;
111
+ this . changeDate . emit ( { date } ) ;
89
112
}
90
113
91
- changeCalendarView ( calendarView : CalendarView ) {
114
+ changeCalendarView ( calendarView : CalendarView ) {
92
115
this . calendarView = calendarView ;
116
+ this . scrollContainer . nativeElement . scrollTop = 0 ;
117
+ if ( this . calendarView !== CalendarView . Month ) {
118
+ this . referenceChangeDetector . detectChanges ( ) ;
119
+ this . scrollToCurrentTimeMarker ( ) ;
120
+ }
93
121
}
94
122
95
- navigationEnable ( calendarView : CalendarView ) {
123
+ navigationEnable ( calendarView : CalendarView ) {
96
124
let enable = false ;
97
125
const currentDate = moment ( this . currentDate ) ;
98
126
const initialDate = moment ( this . initialDate ) ;
99
- if ( calendarView === CalendarView . Month ) {
127
+ if ( calendarView === CalendarView . Month ) {
100
128
if ( currentDate . month ( ) === initialDate . month ( ) && currentDate . year ( ) === initialDate . year ( ) ) {
101
129
enable = true ;
102
130
}
103
131
}
104
132
currentDate . add ( 1 , 'day' ) ;
105
- if ( currentDate > initialDate ) {
133
+ if ( currentDate > initialDate ) {
106
134
enable = true ;
107
135
}
108
136
this . nextDateDisabled = enable ;
109
137
}
110
138
111
- getTimeWork ( startDate : Date , endDate : Date ) : number {
112
- if ( ! endDate ) {
139
+ getTimeWork ( startDate : Date , endDate : Date ) : number {
140
+ if ( ! endDate ) {
113
141
return 30 ;
114
142
}
115
- return new SubstractDatePipe ( ) . transformInMinutes ( endDate , startDate ) ;
143
+ return new SubstractDatePipe ( ) . transformInMinutes ( endDate , startDate ) ;
116
144
}
117
145
118
- timeIsGreaterThan ( startDate : Date , endDate : Date , timeRange : number ) : boolean {
146
+ timeIsGreaterThan ( startDate : Date , endDate : Date , timeRange : number ) : boolean {
119
147
const timeWorkInMinutes = this . getTimeWork ( startDate , endDate ) ;
120
148
return timeWorkInMinutes > timeRange ;
121
149
}
122
150
123
- isVisibleForCurrentView ( currentCalendarView : CalendarView , desiredView : CalendarView ) : boolean {
151
+ isVisibleForCurrentView ( currentCalendarView : CalendarView , desiredView : CalendarView ) : boolean {
124
152
return currentCalendarView === desiredView ;
125
153
}
126
154
127
- isVisibleForCurrentDate ( ) : boolean {
155
+ isVisibleForCurrentDate ( ) : boolean {
128
156
const currentDate : Date = new Date ( this . currentDate ) ;
129
157
const initialDate : Date = new Date ( this . initialDate ) ;
130
158
return currentDate . setHours ( 0 , 0 , 0 , 0 ) === initialDate . setHours ( 0 , 0 , 0 , 0 ) ;
0 commit comments