@forcecalendar/interface 1.0.27 → 1.0.29

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.
@@ -7,63 +7,66 @@
7
7
  import { BaseViewRenderer } from './BaseViewRenderer.js';
8
8
 
9
9
  export class WeekViewRenderer extends BaseViewRenderer {
10
- constructor(container, stateManager) {
11
- super(container, stateManager);
12
- this.hourHeight = 60; // pixels per hour
13
- this.totalHeight = 24 * this.hourHeight; // 1440px for 24 hours
10
+ constructor(container, stateManager) {
11
+ super(container, stateManager);
12
+ this.hourHeight = 60; // pixels per hour
13
+ this.totalHeight = 24 * this.hourHeight; // 1440px for 24 hours
14
+ }
15
+
16
+ render() {
17
+ if (!this.container || !this.stateManager) return;
18
+
19
+ const viewData = this.stateManager.getViewData();
20
+ if (!viewData || !viewData.days || viewData.days.length === 0) {
21
+ this.container.innerHTML =
22
+ '<div style="padding: 20px; text-align: center; color: #666;">No data available for week view.</div>';
23
+ return;
14
24
  }
15
25
 
16
- render() {
17
- if (!this.container || !this.stateManager) return;
18
-
19
- const viewData = this.stateManager.getViewData();
20
- if (!viewData || !viewData.days || viewData.days.length === 0) {
21
- this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No data available for week view.</div>';
22
- return;
23
- }
24
-
25
- this.cleanup();
26
- const config = this.stateManager.getState().config;
27
- const html = this._renderWeekView(viewData, config);
28
- this.container.innerHTML = html;
29
- this._attachEventHandlers();
30
- this._scrollToCurrentTime();
31
- }
32
-
33
- _renderWeekView(viewData, config) {
34
- const days = viewData.days;
35
- const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
36
- const hours = Array.from({ length: 24 }, (_, i) => i);
37
-
38
- // Process days to categorize events
39
- const processedDays = days.map(day => {
40
- const dayDate = new Date(day.date);
41
- const events = day.events || [];
42
- return {
43
- ...day,
44
- date: dayDate,
45
- dayName: dayNames[dayDate.getDay()],
46
- dayOfMonth: dayDate.getDate(),
47
- isToday: this.isToday(dayDate),
48
- timedEvents: events.filter(e => !e.allDay),
49
- allDayEvents: events.filter(e => e.allDay)
50
- };
51
- });
52
-
53
- return `
26
+ this.cleanup();
27
+ const config = this.stateManager.getState().config;
28
+ const html = this._renderWeekView(viewData, config);
29
+ this.container.innerHTML = html;
30
+ this._attachEventHandlers();
31
+ this._scrollToCurrentTime();
32
+ }
33
+
34
+ _renderWeekView(viewData, _config) {
35
+ const days = viewData.days;
36
+ const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
37
+ const hours = Array.from({ length: 24 }, (_, i) => i);
38
+
39
+ // Process days to categorize events
40
+ const processedDays = days.map(day => {
41
+ const dayDate = new Date(day.date);
42
+ const events = day.events || [];
43
+ return {
44
+ ...day,
45
+ date: dayDate,
46
+ dayName: dayNames[dayDate.getDay()],
47
+ dayOfMonth: dayDate.getDate(),
48
+ isToday: this.isToday(dayDate),
49
+ timedEvents: events.filter(e => !e.allDay),
50
+ allDayEvents: events.filter(e => e.allDay)
51
+ };
52
+ });
53
+
54
+ return `
54
55
  <div class="fc-week-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
55
56
  ${this._renderHeader(processedDays)}
56
57
  ${this._renderAllDayRow(processedDays)}
57
58
  ${this._renderTimeGrid(processedDays, hours)}
58
59
  </div>
59
60
  `;
60
- }
61
+ }
61
62
 
62
- _renderHeader(days) {
63
- return `
63
+ _renderHeader(days) {
64
+ return `
64
65
  <div class="fc-week-header" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
65
66
  <div style="border-right: 1px solid #e5e7eb;"></div>
66
- ${days.map(day => `
67
+ ${days
68
+ .map(
69
+ day => `
67
70
  <div style="padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;">
68
71
  <div style="font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">
69
72
  ${day.dayName}
@@ -72,33 +75,43 @@ export class WeekViewRenderer extends BaseViewRenderer {
72
75
  ${day.dayOfMonth}
73
76
  </div>
74
77
  </div>
75
- `).join('')}
78
+ `
79
+ )
80
+ .join('')}
76
81
  </div>
77
82
  `;
78
- }
83
+ }
79
84
 
80
- _renderAllDayRow(days) {
81
- return `
85
+ _renderAllDayRow(days) {
86
+ return `
82
87
  <div class="fc-all-day-row" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 32px; flex-shrink: 0;">
83
88
  <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;">
84
89
  All day
85
90
  </div>
86
- ${days.map(day => `
91
+ ${days
92
+ .map(
93
+ day => `
87
94
  <div class="fc-all-day-cell" data-date="${day.date.toISOString()}" style="border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;">
88
- ${day.allDayEvents.map(evt => `
95
+ ${day.allDayEvents
96
+ .map(
97
+ evt => `
89
98
  <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(evt.id)}"
90
99
  style="background-color: ${this.getEventColor(evt)}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
91
100
  ${this.escapeHTML(evt.title)}
92
101
  </div>
93
- `).join('')}
102
+ `
103
+ )
104
+ .join('')}
94
105
  </div>
95
- `).join('')}
106
+ `
107
+ )
108
+ .join('')}
96
109
  </div>
97
110
  `;
98
- }
111
+ }
99
112
 
100
- _renderTimeGrid(days, hours) {
101
- return `
113
+ _renderTimeGrid(days, hours) {
114
+ return `
102
115
  <div id="week-scroll-container" class="fc-time-grid-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
103
116
  <div class="fc-time-grid" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: ${this.totalHeight}px;">
104
117
  ${this._renderTimeGutter(hours)}
@@ -106,22 +119,26 @@ export class WeekViewRenderer extends BaseViewRenderer {
106
119
  </div>
107
120
  </div>
108
121
  `;
109
- }
122
+ }
110
123
 
111
- _renderTimeGutter(hours) {
112
- return `
124
+ _renderTimeGutter(hours) {
125
+ return `
113
126
  <div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
114
- ${hours.map(h => `
127
+ ${hours
128
+ .map(
129
+ h => `
115
130
  <div style="height: ${this.hourHeight}px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;">
116
131
  ${h === 0 ? '' : this.formatHour(h)}
117
132
  </div>
118
- `).join('')}
133
+ `
134
+ )
135
+ .join('')}
119
136
  </div>
120
137
  `;
121
- }
138
+ }
122
139
 
123
- _renderDayColumn(day, hours) {
124
- return `
140
+ _renderDayColumn(day, hours) {
141
+ return `
125
142
  <div class="fc-week-day-column" data-date="${day.date.toISOString()}" style="border-right: 1px solid #e5e7eb; position: relative; cursor: pointer;">
126
143
  <!-- Hour grid lines -->
127
144
  ${hours.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid #f3f4f6;"></div>`).join('')}
@@ -133,38 +150,43 @@ export class WeekViewRenderer extends BaseViewRenderer {
133
150
  ${day.timedEvents.map(evt => this.renderTimedEvent(evt, { compact: true })).join('')}
134
151
  </div>
135
152
  `;
153
+ }
154
+
155
+ _attachEventHandlers() {
156
+ this.addListener(this.container, 'click', e => {
157
+ const dayEl = e.target.closest('.fc-week-day-column');
158
+ if (!dayEl || !this.container.contains(dayEl)) return;
159
+ if (e.target.closest('.fc-event')) return;
160
+
161
+ const date = new Date(dayEl.dataset.date);
162
+ const rect = dayEl.getBoundingClientRect();
163
+ const scrollContainer = this.container.querySelector('#week-scroll-container');
164
+ const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);
165
+
166
+ // Calculate time from click position
167
+ date.setHours(
168
+ Math.floor(y / this.hourHeight),
169
+ Math.floor((y % this.hourHeight) / (this.hourHeight / 60)),
170
+ 0,
171
+ 0
172
+ );
173
+ this.stateManager.selectDate(date);
174
+ });
175
+
176
+ // Common event handlers (event clicks)
177
+ this.attachCommonEventHandlers();
178
+ }
179
+
180
+ _scrollToCurrentTime() {
181
+ if (this._scrolled) return;
182
+
183
+ const scrollContainer = this.container.querySelector('#week-scroll-container');
184
+ if (scrollContainer) {
185
+ // Scroll to 8 AM, minus some offset for visibility
186
+ scrollContainer.scrollTop = 8 * this.hourHeight - 50;
187
+ this._scrolled = true;
136
188
  }
137
-
138
- _attachEventHandlers() {
139
- this.addListener(this.container, 'click', (e) => {
140
- const dayEl = e.target.closest('.fc-week-day-column');
141
- if (!dayEl || !this.container.contains(dayEl)) return;
142
- if (e.target.closest('.fc-event')) return;
143
-
144
- const date = new Date(dayEl.dataset.date);
145
- const rect = dayEl.getBoundingClientRect();
146
- const scrollContainer = this.container.querySelector('#week-scroll-container');
147
- const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);
148
-
149
- // Calculate time from click position
150
- date.setHours(Math.floor(y / this.hourHeight), Math.floor((y % this.hourHeight) / (this.hourHeight / 60)), 0, 0);
151
- this.stateManager.selectDate(date);
152
- });
153
-
154
- // Common event handlers (event clicks)
155
- this.attachCommonEventHandlers();
156
- }
157
-
158
- _scrollToCurrentTime() {
159
- if (this._scrolled) return;
160
-
161
- const scrollContainer = this.container.querySelector('#week-scroll-container');
162
- if (scrollContainer) {
163
- // Scroll to 8 AM, minus some offset for visibility
164
- scrollContainer.scrollTop = 8 * this.hourHeight - 50;
165
- this._scrolled = true;
166
- }
167
- }
189
+ }
168
190
  }
169
191
 
170
192
  export default WeekViewRenderer;