@forcecalendar/interface 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -669,11 +669,13 @@ export class ForceCalendar extends BaseComponent {
|
|
|
669
669
|
// Create a simple view renderer that bypasses custom elements
|
|
670
670
|
// This is necessary for Salesforce Locker Service compatibility
|
|
671
671
|
const self = this;
|
|
672
|
+
const currentViewName = viewName;
|
|
672
673
|
|
|
673
674
|
return {
|
|
674
675
|
stateManager: null,
|
|
675
676
|
container: null,
|
|
676
677
|
_listeners: [],
|
|
678
|
+
_scrolled: false,
|
|
677
679
|
|
|
678
680
|
cleanup() {
|
|
679
681
|
this._listeners.forEach(({ element, event, handler }) => {
|
|
@@ -688,26 +690,37 @@ export class ForceCalendar extends BaseComponent {
|
|
|
688
690
|
},
|
|
689
691
|
|
|
690
692
|
render() {
|
|
691
|
-
console.log('[ViewRenderer] render called, container:', !!this.container, 'stateManager:', !!this.stateManager);
|
|
692
693
|
if (!this.container || !this.stateManager) return;
|
|
693
694
|
|
|
694
695
|
const viewData = this.stateManager.getViewData();
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
if (!viewData || !viewData.weeks) {
|
|
699
|
-
this.container.innerHTML = '<div style="padding: 20px; text-align: center; background: #fee; color: #c00;">No viewData.weeks available. viewData keys: ' + (viewData ? Object.keys(viewData).join(', ') : 'null') + '</div>';
|
|
696
|
+
if (!viewData) {
|
|
697
|
+
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">Loading...</div>';
|
|
700
698
|
return;
|
|
701
699
|
}
|
|
702
700
|
|
|
703
701
|
this.cleanup();
|
|
704
702
|
const config = this.stateManager.getState().config;
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
703
|
+
let html = '';
|
|
704
|
+
|
|
705
|
+
switch (currentViewName) {
|
|
706
|
+
case 'week':
|
|
707
|
+
html = this._renderWeekView(viewData, config);
|
|
708
|
+
break;
|
|
709
|
+
case 'day':
|
|
710
|
+
html = this._renderDayView(viewData, config);
|
|
711
|
+
break;
|
|
712
|
+
case 'month':
|
|
713
|
+
default:
|
|
714
|
+
if (!viewData.weeks) {
|
|
715
|
+
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No data available for month view.</div>';
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
html = this._renderMonthView(viewData, config);
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
721
|
+
|
|
708
722
|
this.container.innerHTML = html;
|
|
709
|
-
|
|
710
|
-
this._attachEventHandlers();
|
|
723
|
+
this._attachEventHandlers(currentViewName);
|
|
711
724
|
},
|
|
712
725
|
|
|
713
726
|
_renderMonthView(viewData, config) {
|
|
@@ -718,7 +731,6 @@ export class ForceCalendar extends BaseComponent {
|
|
|
718
731
|
dayNames.push(['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][dayIndex]);
|
|
719
732
|
}
|
|
720
733
|
|
|
721
|
-
// Using inline styles for Locker Service compatibility
|
|
722
734
|
let html = `
|
|
723
735
|
<div class="fc-month-view" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: #fff; border: 1px solid #e5e7eb;">
|
|
724
736
|
<div class="fc-month-header" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb;">
|
|
@@ -762,10 +774,265 @@ export class ForceCalendar extends BaseComponent {
|
|
|
762
774
|
return html;
|
|
763
775
|
},
|
|
764
776
|
|
|
765
|
-
|
|
777
|
+
_renderWeekView(viewData, config) {
|
|
778
|
+
const days = viewData.days || [];
|
|
779
|
+
if (days.length === 0) {
|
|
780
|
+
return '<div style="padding: 20px; text-align: center; color: #666;">No data available for week view.</div>';
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
const weekStartsOn = config.weekStartsOn || 0;
|
|
784
|
+
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
785
|
+
const hours = Array.from({ length: 24 }, (_, i) => i);
|
|
786
|
+
|
|
787
|
+
// Process days to add events
|
|
788
|
+
const processedDays = days.map(day => {
|
|
789
|
+
const dayDate = new Date(day.date);
|
|
790
|
+
const events = day.events || [];
|
|
791
|
+
return {
|
|
792
|
+
...day,
|
|
793
|
+
date: dayDate,
|
|
794
|
+
dayName: dayNames[dayDate.getDay()],
|
|
795
|
+
dayOfMonth: dayDate.getDate(),
|
|
796
|
+
isToday: this._isToday(dayDate),
|
|
797
|
+
timedEvents: events.filter(e => !e.allDay),
|
|
798
|
+
allDayEvents: events.filter(e => e.allDay)
|
|
799
|
+
};
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
let html = `
|
|
803
|
+
<div class="fc-week-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
|
|
804
|
+
<!-- Header -->
|
|
805
|
+
<div style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
|
|
806
|
+
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
807
|
+
${processedDays.map(day => `
|
|
808
|
+
<div style="padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;">
|
|
809
|
+
<div style="font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">${day.dayName}</div>
|
|
810
|
+
<div style="font-size: 16px; font-weight: 500; margin-top: 4px; ${day.isToday ? 'background: #dc2626; color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;' : 'color: #111827;'}">${day.dayOfMonth}</div>
|
|
811
|
+
</div>
|
|
812
|
+
`).join('')}
|
|
813
|
+
</div>
|
|
814
|
+
|
|
815
|
+
<!-- All Day Row -->
|
|
816
|
+
<div style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 32px; flex-shrink: 0;">
|
|
817
|
+
<div style="font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;">All day</div>
|
|
818
|
+
${processedDays.map(day => `
|
|
819
|
+
<div style="border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;">
|
|
820
|
+
${day.allDayEvents.map(evt => `
|
|
821
|
+
<div class="fc-event" data-event-id="${evt.id}" style="background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
|
822
|
+
${evt.title}
|
|
823
|
+
</div>
|
|
824
|
+
`).join('')}
|
|
825
|
+
</div>
|
|
826
|
+
`).join('')}
|
|
827
|
+
</div>
|
|
828
|
+
|
|
829
|
+
<!-- Time Grid Body -->
|
|
830
|
+
<div id="week-scroll-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
831
|
+
<div style="display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: 1440px;">
|
|
832
|
+
<!-- Time Gutter -->
|
|
833
|
+
<div style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
834
|
+
${hours.map(h => `
|
|
835
|
+
<div style="height: 60px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;">
|
|
836
|
+
${h === 0 ? '' : this._formatHour(h)}
|
|
837
|
+
</div>
|
|
838
|
+
`).join('')}
|
|
839
|
+
</div>
|
|
840
|
+
|
|
841
|
+
<!-- Day Columns -->
|
|
842
|
+
${processedDays.map(day => `
|
|
843
|
+
<div class="fc-week-day-column" data-date="${day.date.toISOString()}" style="border-right: 1px solid #e5e7eb; position: relative; cursor: pointer;">
|
|
844
|
+
<!-- Hour grid lines -->
|
|
845
|
+
${hours.map(() => `<div style="height: 60px; border-bottom: 1px solid #f3f4f6;"></div>`).join('')}
|
|
846
|
+
|
|
847
|
+
<!-- Now indicator for today -->
|
|
848
|
+
${day.isToday ? this._renderNowIndicator() : ''}
|
|
849
|
+
|
|
850
|
+
<!-- Timed events -->
|
|
851
|
+
${day.timedEvents.map(evt => this._renderTimedEvent(evt)).join('')}
|
|
852
|
+
</div>
|
|
853
|
+
`).join('')}
|
|
854
|
+
</div>
|
|
855
|
+
</div>
|
|
856
|
+
</div>
|
|
857
|
+
`;
|
|
858
|
+
|
|
859
|
+
return html;
|
|
860
|
+
},
|
|
861
|
+
|
|
862
|
+
_renderDayView(viewData, config) {
|
|
863
|
+
// Day view from core has: type, date, dayName, isToday, allDayEvents, hours
|
|
864
|
+
// We need to handle both the core structure and enriched structure
|
|
865
|
+
const currentDate = this.stateManager?.getState()?.currentDate || new Date();
|
|
866
|
+
|
|
867
|
+
let dayDate, dayName, isToday, allDayEvents, timedEvents;
|
|
868
|
+
|
|
869
|
+
if (viewData.type === 'day' && viewData.date) {
|
|
870
|
+
// Core day view structure
|
|
871
|
+
dayDate = new Date(viewData.date);
|
|
872
|
+
dayName = viewData.dayName || ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayDate.getDay()];
|
|
873
|
+
isToday = viewData.isToday !== undefined ? viewData.isToday : this._isToday(dayDate);
|
|
874
|
+
allDayEvents = viewData.allDayEvents || [];
|
|
875
|
+
|
|
876
|
+
// Extract timed events from hours array or get from stateManager
|
|
877
|
+
if (viewData.hours && Array.isArray(viewData.hours)) {
|
|
878
|
+
// Collect unique events from hours (events can span multiple hours)
|
|
879
|
+
const eventMap = new Map();
|
|
880
|
+
viewData.hours.forEach(hour => {
|
|
881
|
+
(hour.events || []).forEach(evt => {
|
|
882
|
+
if (!eventMap.has(evt.id)) {
|
|
883
|
+
eventMap.set(evt.id, evt);
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
timedEvents = Array.from(eventMap.values());
|
|
888
|
+
} else {
|
|
889
|
+
timedEvents = [];
|
|
890
|
+
}
|
|
891
|
+
} else if (viewData.days && viewData.days.length > 0) {
|
|
892
|
+
// Enriched structure with days array
|
|
893
|
+
const dayData = viewData.days.find(d => this._isSameDay(new Date(d.date), currentDate)) || viewData.days[0];
|
|
894
|
+
dayDate = new Date(dayData.date);
|
|
895
|
+
dayName = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayDate.getDay()];
|
|
896
|
+
isToday = this._isToday(dayDate);
|
|
897
|
+
const events = dayData.events || [];
|
|
898
|
+
allDayEvents = events.filter(e => e.allDay);
|
|
899
|
+
timedEvents = events.filter(e => !e.allDay);
|
|
900
|
+
} else {
|
|
901
|
+
return '<div style="padding: 20px; text-align: center; color: #666;">No data available for day view.</div>';
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
const hours = Array.from({ length: 24 }, (_, i) => i);
|
|
905
|
+
|
|
906
|
+
let html = `
|
|
907
|
+
<div class="fc-day-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
|
|
908
|
+
<!-- Header -->
|
|
909
|
+
<div style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
|
|
910
|
+
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
911
|
+
<div style="padding: 16px 24px;">
|
|
912
|
+
<div style="font-size: 12px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">${dayName}</div>
|
|
913
|
+
<div style="font-size: 24px; font-weight: 600; margin-top: 4px; ${isToday ? 'color: #dc2626;' : 'color: #111827;'}">${dayDate.getDate()}</div>
|
|
914
|
+
</div>
|
|
915
|
+
</div>
|
|
916
|
+
|
|
917
|
+
<!-- All Day Row -->
|
|
918
|
+
<div style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 36px; flex-shrink: 0;">
|
|
919
|
+
<div style="font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;">All day</div>
|
|
920
|
+
<div style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
|
|
921
|
+
${allDayEvents.map(evt => `
|
|
922
|
+
<div class="fc-event" data-event-id="${evt.id}" style="background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
|
|
923
|
+
${evt.title}
|
|
924
|
+
</div>
|
|
925
|
+
`).join('')}
|
|
926
|
+
</div>
|
|
927
|
+
</div>
|
|
928
|
+
|
|
929
|
+
<!-- Time Grid Body -->
|
|
930
|
+
<div id="day-scroll-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
931
|
+
<div style="display: grid; grid-template-columns: 60px 1fr; position: relative; height: 1440px;">
|
|
932
|
+
<!-- Time Gutter -->
|
|
933
|
+
<div style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
934
|
+
${hours.map(h => `
|
|
935
|
+
<div style="height: 60px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;">
|
|
936
|
+
${h === 0 ? '' : this._formatHour(h)}
|
|
937
|
+
</div>
|
|
938
|
+
`).join('')}
|
|
939
|
+
</div>
|
|
940
|
+
|
|
941
|
+
<!-- Day Column -->
|
|
942
|
+
<div class="fc-day-column" data-date="${dayDate.toISOString()}" style="position: relative; cursor: pointer;">
|
|
943
|
+
<!-- Hour grid lines -->
|
|
944
|
+
${hours.map(() => `<div style="height: 60px; border-bottom: 1px solid #f3f4f6;"></div>`).join('')}
|
|
945
|
+
|
|
946
|
+
<!-- Now indicator for today -->
|
|
947
|
+
${isToday ? this._renderNowIndicator() : ''}
|
|
948
|
+
|
|
949
|
+
<!-- Timed events -->
|
|
950
|
+
${timedEvents.map(evt => this._renderTimedEventDay(evt)).join('')}
|
|
951
|
+
</div>
|
|
952
|
+
</div>
|
|
953
|
+
</div>
|
|
954
|
+
</div>
|
|
955
|
+
`;
|
|
956
|
+
|
|
957
|
+
return html;
|
|
958
|
+
},
|
|
959
|
+
|
|
960
|
+
_renderTimedEvent(event) {
|
|
961
|
+
const start = new Date(event.start);
|
|
962
|
+
const end = new Date(event.end);
|
|
963
|
+
const startMinutes = start.getHours() * 60 + start.getMinutes();
|
|
964
|
+
const durationMinutes = Math.max((end - start) / (1000 * 60), 20);
|
|
965
|
+
const color = event.backgroundColor || '#2563eb';
|
|
966
|
+
|
|
967
|
+
return `
|
|
968
|
+
<div class="fc-event" data-event-id="${event.id}"
|
|
969
|
+
style="position: absolute; top: ${startMinutes}px; height: ${durationMinutes}px; left: 2px; right: 2px;
|
|
970
|
+
background-color: ${color}; border-radius: 4px; padding: 4px 8px; font-size: 11px;
|
|
971
|
+
font-weight: 500; color: white; overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
|
972
|
+
cursor: pointer; z-index: 5;">
|
|
973
|
+
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${event.title}</div>
|
|
974
|
+
<div style="font-size: 10px; opacity: 0.9;">${this._formatTime(start)}</div>
|
|
975
|
+
</div>
|
|
976
|
+
`;
|
|
977
|
+
},
|
|
978
|
+
|
|
979
|
+
_renderTimedEventDay(event) {
|
|
980
|
+
const start = new Date(event.start);
|
|
981
|
+
const end = new Date(event.end);
|
|
982
|
+
const startMinutes = start.getHours() * 60 + start.getMinutes();
|
|
983
|
+
const durationMinutes = Math.max((end - start) / (1000 * 60), 30);
|
|
984
|
+
const color = event.backgroundColor || '#2563eb';
|
|
985
|
+
|
|
986
|
+
return `
|
|
987
|
+
<div class="fc-event" data-event-id="${event.id}"
|
|
988
|
+
style="position: absolute; top: ${startMinutes}px; height: ${durationMinutes}px; left: 12px; right: 24px;
|
|
989
|
+
background-color: ${color}; border-radius: 6px; padding: 8px 12px; font-size: 13px;
|
|
990
|
+
font-weight: 500; color: white; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
991
|
+
cursor: pointer; z-index: 5;">
|
|
992
|
+
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${event.title}</div>
|
|
993
|
+
<div style="font-size: 11px; opacity: 0.9;">${this._formatTime(start)} - ${this._formatTime(end)}</div>
|
|
994
|
+
</div>
|
|
995
|
+
`;
|
|
996
|
+
},
|
|
997
|
+
|
|
998
|
+
_renderNowIndicator() {
|
|
999
|
+
const now = new Date();
|
|
1000
|
+
const minutes = now.getHours() * 60 + now.getMinutes();
|
|
1001
|
+
return `<div style="position: absolute; left: 0; right: 0; top: ${minutes}px; height: 2px; background: #dc2626; z-index: 15; pointer-events: none;"></div>`;
|
|
1002
|
+
},
|
|
1003
|
+
|
|
1004
|
+
_formatHour(hour) {
|
|
1005
|
+
const period = hour >= 12 ? 'PM' : 'AM';
|
|
1006
|
+
const displayHour = hour % 12 || 12;
|
|
1007
|
+
return `${displayHour} ${period}`;
|
|
1008
|
+
},
|
|
1009
|
+
|
|
1010
|
+
_formatTime(date) {
|
|
1011
|
+
const hours = date.getHours();
|
|
1012
|
+
const minutes = date.getMinutes();
|
|
1013
|
+
const period = hours >= 12 ? 'PM' : 'AM';
|
|
1014
|
+
const displayHour = hours % 12 || 12;
|
|
1015
|
+
return minutes === 0 ? `${displayHour} ${period}` : `${displayHour}:${minutes.toString().padStart(2, '0')} ${period}`;
|
|
1016
|
+
},
|
|
1017
|
+
|
|
1018
|
+
_isToday(date) {
|
|
1019
|
+
const today = new Date();
|
|
1020
|
+
return date.getDate() === today.getDate() &&
|
|
1021
|
+
date.getMonth() === today.getMonth() &&
|
|
1022
|
+
date.getFullYear() === today.getFullYear();
|
|
1023
|
+
},
|
|
1024
|
+
|
|
1025
|
+
_isSameDay(date1, date2) {
|
|
1026
|
+
return date1.getDate() === date2.getDate() &&
|
|
1027
|
+
date1.getMonth() === date2.getMonth() &&
|
|
1028
|
+
date1.getFullYear() === date2.getFullYear();
|
|
1029
|
+
},
|
|
1030
|
+
|
|
1031
|
+
_attachEventHandlers(viewType) {
|
|
766
1032
|
const stateManager = this.stateManager;
|
|
1033
|
+
const self = this;
|
|
767
1034
|
|
|
768
|
-
// Day click handlers
|
|
1035
|
+
// Day click handlers (for month view)
|
|
769
1036
|
this.container.querySelectorAll('.fc-month-day').forEach(dayEl => {
|
|
770
1037
|
this.addListener(dayEl, 'click', (e) => {
|
|
771
1038
|
const date = new Date(dayEl.dataset.date);
|
|
@@ -773,6 +1040,32 @@ export class ForceCalendar extends BaseComponent {
|
|
|
773
1040
|
});
|
|
774
1041
|
});
|
|
775
1042
|
|
|
1043
|
+
// Week view day column click handlers
|
|
1044
|
+
this.container.querySelectorAll('.fc-week-day-column').forEach(dayEl => {
|
|
1045
|
+
this.addListener(dayEl, 'click', (e) => {
|
|
1046
|
+
if (e.target.closest('.fc-event')) return;
|
|
1047
|
+
const date = new Date(dayEl.dataset.date);
|
|
1048
|
+
const rect = dayEl.getBoundingClientRect();
|
|
1049
|
+
const scrollContainer = this.container.querySelector('#week-scroll-container');
|
|
1050
|
+
const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);
|
|
1051
|
+
date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);
|
|
1052
|
+
stateManager.selectDate(date);
|
|
1053
|
+
});
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
// Day view column click handlers
|
|
1057
|
+
this.container.querySelectorAll('.fc-day-column').forEach(dayEl => {
|
|
1058
|
+
this.addListener(dayEl, 'click', (e) => {
|
|
1059
|
+
if (e.target.closest('.fc-event')) return;
|
|
1060
|
+
const date = new Date(dayEl.dataset.date);
|
|
1061
|
+
const rect = dayEl.getBoundingClientRect();
|
|
1062
|
+
const scrollContainer = this.container.querySelector('#day-scroll-container');
|
|
1063
|
+
const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);
|
|
1064
|
+
date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);
|
|
1065
|
+
stateManager.selectDate(date);
|
|
1066
|
+
});
|
|
1067
|
+
});
|
|
1068
|
+
|
|
776
1069
|
// Event click handlers
|
|
777
1070
|
this.container.querySelectorAll('.fc-event').forEach(eventEl => {
|
|
778
1071
|
this.addListener(eventEl, 'click', (e) => {
|
|
@@ -784,6 +1077,16 @@ export class ForceCalendar extends BaseComponent {
|
|
|
784
1077
|
}
|
|
785
1078
|
});
|
|
786
1079
|
});
|
|
1080
|
+
|
|
1081
|
+
// Scroll to 8 AM for week and day views
|
|
1082
|
+
if (viewType === 'week' || viewType === 'day') {
|
|
1083
|
+
const scrollContainerId = viewType === 'week' ? '#week-scroll-container' : '#day-scroll-container';
|
|
1084
|
+
const scrollContainer = this.container.querySelector(scrollContainerId);
|
|
1085
|
+
if (scrollContainer && !this._scrolled) {
|
|
1086
|
+
scrollContainer.scrollTop = 8 * 60 - 50;
|
|
1087
|
+
this._scrolled = true;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
787
1090
|
}
|
|
788
1091
|
};
|
|
789
1092
|
}
|