1- import { Component , EventEmitter , Input , OnInit , Output } from '@angular/core' ;
21import {
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' ;
612import { Observable } from 'rxjs' ;
713import * as moment from 'moment' ;
814import { DataSource } from '../../../shared/models/data-source.model' ;
915import { Entry } from 'src/app/modules/shared/models' ;
1016import { map } from 'rxjs/operators' ;
1117import { SubstractDatePipe } from 'src/app/modules/shared/pipes/substract-date/substract-date.pipe' ;
18+ import { differenceInMinutes , startOfDay , startOfHour } from 'date-fns' ;
1219
1320@Component ( {
1421 selector : 'app-calendar' ,
1522 templateUrl : './calendar.component.html' ,
1623 styleUrls : [ './calendar.component.scss' ] ,
1724} )
1825export 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 > > ) {
2032 this . castEntryToCalendarEvent ( timeEntries ) ;
2133 }
2234 @Input ( ) calendarView : CalendarView = CalendarView . Month ;
@@ -25,7 +37,7 @@ export class CalendarComponent implements OnInit {
2537 @Output ( ) viewModal : EventEmitter < any > = new EventEmitter < string > ( ) ;
2638 @Output ( ) deleteTimeEntry : EventEmitter < any > = new EventEmitter < string > ( ) ;
2739 @Output ( ) changeDate : EventEmitter < any > = new EventEmitter < {
28- date : Date
40+ date : Date ;
2941 } > ( ) ;
3042
3143 initialDate : Date ;
@@ -34,97 +46,113 @@ export class CalendarComponent implements OnInit {
3446 timeEntriesAsEvent : CalendarEvent [ ] ;
3547 nextDateDisabled : boolean ;
3648
37- constructor ( ) {
49+ constructor ( private referenceChangeDetector : ChangeDetectorRef ) {
3850 this . initialDate = new Date ( ) ;
3951 this . previusDate = new Date ( ) ;
4052 this . isToday = false ;
4153 this . timeEntriesAsEvent = [ ] ;
4254 this . nextDateDisabled = true ;
43- }
55+ }
4456
4557 ngOnInit ( ) : void {
4658 this . isToday = this . isVisibleForCurrentDate ( ) ;
4759 this . navigationEnable ( this . calendarView ) ;
4860 }
4961
50- get CalendarViewEnum ( ) : typeof CalendarView {
62+ get CalendarViewEnum ( ) : typeof CalendarView {
5163 return CalendarView ;
5264 }
5365
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+
5474 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+ )
6488 )
6589 )
66- )
67- . subscribe ( ( timeEntriesAsEvent ) => {
90+ . subscribe ( ( timeEntriesAsEvent ) => {
6891 this . timeEntriesAsEvent = [ ...timeEntriesAsEvent ] . reverse ( ) ;
69- } ) ;
92+ } ) ;
7093 }
7194
7295 handleEditEvent ( timeEntryAsEvent : CalendarEvent ) : void {
73- this . viewModal . emit ( {
74- id : timeEntryAsEvent . id
96+ this . viewModal . emit ( {
97+ id : timeEntryAsEvent . id ,
7598 } ) ;
7699 }
77100
78101 handleDeleteEvent ( timeEntryAsEvent : CalendarEvent ) : void {
79102 this . deleteTimeEntry . emit ( {
80- timeEntry : timeEntryAsEvent . meta
103+ timeEntry : timeEntryAsEvent . meta ,
81104 } ) ;
82105 }
83106
84- handleChangeDateEvent ( ) : void {
107+ handleChangeDateEvent ( ) : void {
85108 const date = this . currentDate ;
86109 this . isToday = this . isVisibleForCurrentDate ( ) ;
87110 this . navigationEnable ( this . calendarView ) ;
88- this . changeDate . emit ( { date} ) ;
111+ this . changeDate . emit ( { date } ) ;
89112 }
90113
91- changeCalendarView ( calendarView : CalendarView ) {
114+ changeCalendarView ( calendarView : CalendarView ) {
92115 this . calendarView = calendarView ;
116+ this . scrollContainer . nativeElement . scrollTop = 0 ;
117+ if ( this . calendarView !== CalendarView . Month ) {
118+ this . referenceChangeDetector . detectChanges ( ) ;
119+ this . scrollToCurrentTimeMarker ( ) ;
120+ }
93121 }
94122
95- navigationEnable ( calendarView : CalendarView ) {
123+ navigationEnable ( calendarView : CalendarView ) {
96124 let enable = false ;
97125 const currentDate = moment ( this . currentDate ) ;
98126 const initialDate = moment ( this . initialDate ) ;
99- if ( calendarView === CalendarView . Month ) {
127+ if ( calendarView === CalendarView . Month ) {
100128 if ( currentDate . month ( ) === initialDate . month ( ) && currentDate . year ( ) === initialDate . year ( ) ) {
101129 enable = true ;
102130 }
103131 }
104132 currentDate . add ( 1 , 'day' ) ;
105- if ( currentDate > initialDate ) {
133+ if ( currentDate > initialDate ) {
106134 enable = true ;
107135 }
108136 this . nextDateDisabled = enable ;
109137 }
110138
111- getTimeWork ( startDate : Date , endDate : Date ) : number {
112- if ( ! endDate ) {
139+ getTimeWork ( startDate : Date , endDate : Date ) : number {
140+ if ( ! endDate ) {
113141 return 30 ;
114142 }
115- return new SubstractDatePipe ( ) . transformInMinutes ( endDate , startDate ) ;
143+ return new SubstractDatePipe ( ) . transformInMinutes ( endDate , startDate ) ;
116144 }
117145
118- timeIsGreaterThan ( startDate : Date , endDate : Date , timeRange : number ) : boolean {
146+ timeIsGreaterThan ( startDate : Date , endDate : Date , timeRange : number ) : boolean {
119147 const timeWorkInMinutes = this . getTimeWork ( startDate , endDate ) ;
120148 return timeWorkInMinutes > timeRange ;
121149 }
122150
123- isVisibleForCurrentView ( currentCalendarView : CalendarView , desiredView : CalendarView ) : boolean {
151+ isVisibleForCurrentView ( currentCalendarView : CalendarView , desiredView : CalendarView ) : boolean {
124152 return currentCalendarView === desiredView ;
125153 }
126154
127- isVisibleForCurrentDate ( ) : boolean {
155+ isVisibleForCurrentDate ( ) : boolean {
128156 const currentDate : Date = new Date ( this . currentDate ) ;
129157 const initialDate : Date = new Date ( this . initialDate ) ;
130158 return currentDate . setHours ( 0 , 0 , 0 , 0 ) === initialDate . setHours ( 0 , 0 , 0 , 0 ) ;
0 commit comments