@forcecalendar/interface 1.0.16 → 1.0.18
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/dist/force-calendar-interface.esm.js +788 -533
- package/dist/force-calendar-interface.esm.js.map +1 -1
- package/dist/force-calendar-interface.umd.js +200 -182
- package/dist/force-calendar-interface.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/EventForm.js +15 -10
- package/src/components/ForceCalendar.js +48 -451
- package/src/core/EventBus.js +66 -0
- package/src/core/StateManager.js +44 -3
- package/src/index.js +7 -1
- package/src/renderers/BaseViewRenderer.js +219 -0
- package/src/renderers/DayViewRenderer.js +199 -0
- package/src/renderers/MonthViewRenderer.js +125 -0
- package/src/renderers/WeekViewRenderer.js +171 -0
- package/src/renderers/index.js +11 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
class
|
|
1
|
+
var Y = Object.defineProperty;
|
|
2
|
+
var j = (u, e, t) => e in u ? Y(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
|
|
3
|
+
var z = (u, e, t) => j(u, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
class _ extends HTMLElement {
|
|
5
5
|
constructor() {
|
|
6
6
|
super(), this.attachShadow({ mode: "open" }), this._listeners = [], this._state = null, this._props = /* @__PURE__ */ new Map(), this._initialized = !1;
|
|
7
7
|
}
|
|
@@ -108,7 +108,7 @@ class $ extends HTMLElement {
|
|
|
108
108
|
this.setProp(e, s), this._initialized && this.render();
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
class
|
|
111
|
+
class W {
|
|
112
112
|
constructor() {
|
|
113
113
|
this.timezones = {
|
|
114
114
|
// UTC
|
|
@@ -673,7 +673,7 @@ class U {
|
|
|
673
673
|
};
|
|
674
674
|
}
|
|
675
675
|
}
|
|
676
|
-
let
|
|
676
|
+
let C = null;
|
|
677
677
|
class S {
|
|
678
678
|
/**
|
|
679
679
|
* Get the shared singleton instance of TimezoneManager
|
|
@@ -681,17 +681,17 @@ class S {
|
|
|
681
681
|
* @returns {TimezoneManager} The shared instance
|
|
682
682
|
*/
|
|
683
683
|
static getInstance() {
|
|
684
|
-
return
|
|
684
|
+
return C || (C = new S()), C;
|
|
685
685
|
}
|
|
686
686
|
/**
|
|
687
687
|
* Reset the singleton instance (useful for testing)
|
|
688
688
|
* @private
|
|
689
689
|
*/
|
|
690
690
|
static _resetInstance() {
|
|
691
|
-
|
|
691
|
+
C && C.clearCache(), C = null;
|
|
692
692
|
}
|
|
693
693
|
constructor() {
|
|
694
|
-
this.database = new
|
|
694
|
+
this.database = new W(), this.offsetCache = /* @__PURE__ */ new Map(), this.dstCache = /* @__PURE__ */ new Map(), this.maxCacheSize = 1e3, this.cacheHits = 0, this.cacheMisses = 0;
|
|
695
695
|
}
|
|
696
696
|
/**
|
|
697
697
|
* Convert date from one timezone to another
|
|
@@ -976,7 +976,7 @@ class S {
|
|
|
976
976
|
}
|
|
977
977
|
}
|
|
978
978
|
}
|
|
979
|
-
class
|
|
979
|
+
class D {
|
|
980
980
|
/**
|
|
981
981
|
* Normalize event data
|
|
982
982
|
* @param {import('../../types.js').EventData} data - Raw event data
|
|
@@ -1041,25 +1041,25 @@ class M {
|
|
|
1041
1041
|
borderColor: l = null,
|
|
1042
1042
|
textColor: d = null,
|
|
1043
1043
|
recurring: h = !1,
|
|
1044
|
-
recurrenceRule:
|
|
1045
|
-
timeZone:
|
|
1046
|
-
endTimeZone:
|
|
1047
|
-
status:
|
|
1048
|
-
visibility:
|
|
1049
|
-
organizer:
|
|
1050
|
-
attendees:
|
|
1044
|
+
recurrenceRule: m = null,
|
|
1045
|
+
timeZone: b = null,
|
|
1046
|
+
endTimeZone: x = null,
|
|
1047
|
+
status: A = "confirmed",
|
|
1048
|
+
visibility: k = "public",
|
|
1049
|
+
organizer: M = null,
|
|
1050
|
+
attendees: $ = [],
|
|
1051
1051
|
reminders: I = [],
|
|
1052
|
-
category:
|
|
1052
|
+
category: R,
|
|
1053
1053
|
// Support singular category (no default)
|
|
1054
|
-
categories:
|
|
1054
|
+
categories: B,
|
|
1055
1055
|
// Support plural categories (no default)
|
|
1056
|
-
attachments:
|
|
1057
|
-
conferenceData:
|
|
1058
|
-
metadata:
|
|
1059
|
-
...
|
|
1056
|
+
attachments: V = [],
|
|
1057
|
+
conferenceData: N = null,
|
|
1058
|
+
metadata: P = {},
|
|
1059
|
+
...U
|
|
1060
1060
|
// Capture any extra properties
|
|
1061
1061
|
}) {
|
|
1062
|
-
const
|
|
1062
|
+
const g = D.normalize({
|
|
1063
1063
|
id: e,
|
|
1064
1064
|
title: t,
|
|
1065
1065
|
start: s,
|
|
@@ -1072,25 +1072,25 @@ class M {
|
|
|
1072
1072
|
borderColor: l,
|
|
1073
1073
|
textColor: d,
|
|
1074
1074
|
recurring: h,
|
|
1075
|
-
recurrenceRule:
|
|
1076
|
-
timeZone:
|
|
1077
|
-
endTimeZone:
|
|
1078
|
-
status:
|
|
1079
|
-
visibility:
|
|
1080
|
-
organizer:
|
|
1081
|
-
attendees:
|
|
1075
|
+
recurrenceRule: m,
|
|
1076
|
+
timeZone: b,
|
|
1077
|
+
endTimeZone: x,
|
|
1078
|
+
status: A,
|
|
1079
|
+
visibility: k,
|
|
1080
|
+
organizer: M,
|
|
1081
|
+
attendees: $,
|
|
1082
1082
|
reminders: I,
|
|
1083
|
-
category:
|
|
1083
|
+
category: R,
|
|
1084
1084
|
// Pass category to normalize
|
|
1085
|
-
categories:
|
|
1085
|
+
categories: B,
|
|
1086
1086
|
// Pass categories to normalize
|
|
1087
|
-
attachments:
|
|
1088
|
-
conferenceData:
|
|
1089
|
-
metadata:
|
|
1090
|
-
...
|
|
1087
|
+
attachments: V,
|
|
1088
|
+
conferenceData: N,
|
|
1089
|
+
metadata: P,
|
|
1090
|
+
...U
|
|
1091
1091
|
// Pass any extra properties
|
|
1092
1092
|
});
|
|
1093
|
-
|
|
1093
|
+
D.validate(g), this.id = g.id, this.title = g.title, this._timezoneManager = S.getInstance(), this.timeZone = g.timeZone || this._timezoneManager.getSystemTimezone(), this.endTimeZone = g.endTimeZone || this.timeZone, this.start = g.start, this.end = g.end, this.startUTC = this._timezoneManager.toUTC(this.start, this.timeZone), this.endUTC = this._timezoneManager.toUTC(this.end, this.endTimeZone), this.allDay = g.allDay, this.description = g.description, this.location = g.location, this.color = g.color, this.backgroundColor = g.backgroundColor, this.borderColor = g.borderColor, this.textColor = g.textColor, this.recurring = g.recurring, this.recurrenceRule = g.recurrenceRule, this._originalTimeZone = g.timeZone || null, this.status = g.status, this.visibility = g.visibility, this.organizer = g.organizer, this.attendees = [...g.attendees], this.reminders = [...g.reminders], this.categories = g.categories ? [...g.categories] : [], this.attachments = [...g.attachments], this.conferenceData = g.conferenceData, this.metadata = { ...g.metadata }, this._cache = {}, this._validateAttendees(), this._validateReminders();
|
|
1094
1094
|
}
|
|
1095
1095
|
/**
|
|
1096
1096
|
* Get event duration in milliseconds
|
|
@@ -1180,7 +1180,7 @@ class M {
|
|
|
1180
1180
|
* @throws {Error} If otherEvent is not an Event instance or doesn't have start/end
|
|
1181
1181
|
*/
|
|
1182
1182
|
overlaps(e) {
|
|
1183
|
-
if (e instanceof
|
|
1183
|
+
if (e instanceof D)
|
|
1184
1184
|
return !(this.end <= e.start || this.start >= e.end);
|
|
1185
1185
|
if (e && e.start && e.end)
|
|
1186
1186
|
return !(this.end <= e.start || this.start >= e.end);
|
|
@@ -1200,7 +1200,7 @@ class M {
|
|
|
1200
1200
|
* @returns {Event} New Event instance with updated properties
|
|
1201
1201
|
*/
|
|
1202
1202
|
clone(e = {}) {
|
|
1203
|
-
return new
|
|
1203
|
+
return new D({
|
|
1204
1204
|
id: this.id,
|
|
1205
1205
|
title: this.title,
|
|
1206
1206
|
start: new Date(this.start),
|
|
@@ -1264,7 +1264,7 @@ class M {
|
|
|
1264
1264
|
* @returns {Event} New Event instance
|
|
1265
1265
|
*/
|
|
1266
1266
|
static fromObject(e) {
|
|
1267
|
-
return new
|
|
1267
|
+
return new D(e);
|
|
1268
1268
|
}
|
|
1269
1269
|
/**
|
|
1270
1270
|
* Compare events for equality
|
|
@@ -1272,7 +1272,7 @@ class M {
|
|
|
1272
1272
|
* @returns {boolean} True if events are equal
|
|
1273
1273
|
*/
|
|
1274
1274
|
equals(e) {
|
|
1275
|
-
return e instanceof
|
|
1275
|
+
return e instanceof D ? this.id === e.id && this.title === e.title && this.start.getTime() === e.start.getTime() && this.end.getTime() === e.end.getTime() && this.allDay === e.allDay && this.description === e.description && this.location === e.location && this.recurring === e.recurring && this.recurrenceRule === e.recurrenceRule && this.status === e.status : !1;
|
|
1276
1276
|
}
|
|
1277
1277
|
// ============ Attendee Management Methods ============
|
|
1278
1278
|
/**
|
|
@@ -1531,7 +1531,7 @@ class M {
|
|
|
1531
1531
|
return this.conferenceData !== null;
|
|
1532
1532
|
}
|
|
1533
1533
|
}
|
|
1534
|
-
let
|
|
1534
|
+
let f = class w {
|
|
1535
1535
|
/**
|
|
1536
1536
|
* Get the start of a day
|
|
1537
1537
|
* @param {Date} date - The date
|
|
@@ -1567,7 +1567,7 @@ let u = class D {
|
|
|
1567
1567
|
* @returns {Date}
|
|
1568
1568
|
*/
|
|
1569
1569
|
static endOfWeek(e, t = 0) {
|
|
1570
|
-
const s =
|
|
1570
|
+
const s = w.startOfWeek(e, t);
|
|
1571
1571
|
return s.setDate(s.getDate() + 6), s.setHours(23, 59, 59, 999), s;
|
|
1572
1572
|
}
|
|
1573
1573
|
/**
|
|
@@ -1619,7 +1619,7 @@ let u = class D {
|
|
|
1619
1619
|
* @returns {Date}
|
|
1620
1620
|
*/
|
|
1621
1621
|
static addWeeks(e, t) {
|
|
1622
|
-
return
|
|
1622
|
+
return w.addDays(e, t * 7);
|
|
1623
1623
|
}
|
|
1624
1624
|
/**
|
|
1625
1625
|
* Add months to a date
|
|
@@ -1701,7 +1701,7 @@ let u = class D {
|
|
|
1701
1701
|
* @returns {boolean}
|
|
1702
1702
|
*/
|
|
1703
1703
|
static isSameWeek(e, t, s = 0) {
|
|
1704
|
-
const i =
|
|
1704
|
+
const i = w.startOfWeek(e, s), r = w.startOfWeek(t, s);
|
|
1705
1705
|
return i.toDateString() === r.toDateString();
|
|
1706
1706
|
}
|
|
1707
1707
|
/**
|
|
@@ -1739,7 +1739,7 @@ let u = class D {
|
|
|
1739
1739
|
* @returns {number}
|
|
1740
1740
|
*/
|
|
1741
1741
|
static differenceInWeeks(e, t) {
|
|
1742
|
-
return Math.floor(
|
|
1742
|
+
return Math.floor(w.differenceInDays(e, t) / 7);
|
|
1743
1743
|
}
|
|
1744
1744
|
/**
|
|
1745
1745
|
* Get the difference in months between two dates
|
|
@@ -1795,7 +1795,7 @@ let u = class D {
|
|
|
1795
1795
|
* @returns {string}
|
|
1796
1796
|
*/
|
|
1797
1797
|
static getMonthName(e, t = "en-US", s = "long") {
|
|
1798
|
-
return
|
|
1798
|
+
return w.format(e, t, { month: s });
|
|
1799
1799
|
}
|
|
1800
1800
|
/**
|
|
1801
1801
|
* Get day name
|
|
@@ -1805,7 +1805,7 @@ let u = class D {
|
|
|
1805
1805
|
* @returns {string}
|
|
1806
1806
|
*/
|
|
1807
1807
|
static getDayName(e, t = "en-US", s = "long") {
|
|
1808
|
-
return
|
|
1808
|
+
return w.format(e, t, { weekday: s });
|
|
1809
1809
|
}
|
|
1810
1810
|
/**
|
|
1811
1811
|
* Format time
|
|
@@ -1815,7 +1815,7 @@ let u = class D {
|
|
|
1815
1815
|
* @returns {string}
|
|
1816
1816
|
*/
|
|
1817
1817
|
static formatTime(e, t = "en-US", s = !1) {
|
|
1818
|
-
return
|
|
1818
|
+
return w.format(e, t, {
|
|
1819
1819
|
hour: "numeric",
|
|
1820
1820
|
minute: "2-digit",
|
|
1821
1821
|
hour12: !s
|
|
@@ -1837,7 +1837,7 @@ let u = class D {
|
|
|
1837
1837
|
* @returns {Date}
|
|
1838
1838
|
*/
|
|
1839
1839
|
static setTime(e, t) {
|
|
1840
|
-
const s = new Date(e), { hours: i, minutes: r } =
|
|
1840
|
+
const s = new Date(e), { hours: i, minutes: r } = w.parseTime(t);
|
|
1841
1841
|
return s.setHours(i, r, 0, 0), s;
|
|
1842
1842
|
}
|
|
1843
1843
|
/**
|
|
@@ -1916,7 +1916,7 @@ let u = class D {
|
|
|
1916
1916
|
* @returns {boolean}
|
|
1917
1917
|
*/
|
|
1918
1918
|
static isDST(e, t) {
|
|
1919
|
-
const s = new Date(e.getFullYear(), 0, 1), i = new Date(e.getFullYear(), 6, 1), r =
|
|
1919
|
+
const s = new Date(e.getFullYear(), 0, 1), i = new Date(e.getFullYear(), 6, 1), r = w.getTimezoneOffset(s, t), n = w.getTimezoneOffset(i, t), a = w.getTimezoneOffset(e, t);
|
|
1920
1920
|
return Math.max(r, n) === a;
|
|
1921
1921
|
}
|
|
1922
1922
|
/**
|
|
@@ -1927,9 +1927,9 @@ let u = class D {
|
|
|
1927
1927
|
* @returns {Date}
|
|
1928
1928
|
*/
|
|
1929
1929
|
static addHoursWithDST(e, t, s) {
|
|
1930
|
-
const i = new Date(e), r =
|
|
1930
|
+
const i = new Date(e), r = w.getTimezoneOffset(e, s);
|
|
1931
1931
|
i.setTime(i.getTime() + t * 60 * 60 * 1e3);
|
|
1932
|
-
const n =
|
|
1932
|
+
const n = w.getTimezoneOffset(i, s);
|
|
1933
1933
|
if (r !== n) {
|
|
1934
1934
|
const a = (n - r) * 6e4;
|
|
1935
1935
|
i.setTime(i.getTime() + a);
|
|
@@ -1948,11 +1948,11 @@ let u = class D {
|
|
|
1948
1948
|
* @returns {Date}
|
|
1949
1949
|
*/
|
|
1950
1950
|
static createInTimeZone(e, t, s, i = 0, r = 0, n = 0, a) {
|
|
1951
|
-
const o = `${e}-${String(t + 1).padStart(2, "0")}-${String(s).padStart(2, "0")}`, c = `${String(i).padStart(2, "0")}:${String(r).padStart(2, "0")}:${String(n).padStart(2, "0")}`, l = /* @__PURE__ */ new Date(`${o}T${c}`), d =
|
|
1951
|
+
const o = `${e}-${String(t + 1).padStart(2, "0")}-${String(s).padStart(2, "0")}`, c = `${String(i).padStart(2, "0")}:${String(r).padStart(2, "0")}:${String(n).padStart(2, "0")}`, l = /* @__PURE__ */ new Date(`${o}T${c}`), d = w.getTimezoneOffset(l, a), h = l.getTime() + d * 6e4;
|
|
1952
1952
|
return new Date(h);
|
|
1953
1953
|
}
|
|
1954
1954
|
};
|
|
1955
|
-
class
|
|
1955
|
+
class Z {
|
|
1956
1956
|
/**
|
|
1957
1957
|
* Parse an RRULE string into a structured rule object
|
|
1958
1958
|
* @param {string|Object} rrule - RRULE string or rule object
|
|
@@ -2206,7 +2206,7 @@ class Y {
|
|
|
2206
2206
|
return e.count ? r += `, ${e.count} time${e.count > 1 ? "s" : ""}` : e.until && (r += `, until ${e.until.toLocaleDateString()}`), r;
|
|
2207
2207
|
}
|
|
2208
2208
|
}
|
|
2209
|
-
class
|
|
2209
|
+
class q {
|
|
2210
2210
|
/**
|
|
2211
2211
|
* Expand a recurring event into individual occurrences
|
|
2212
2212
|
* @param {import('./Event.js').Event} event - The recurring event
|
|
@@ -2222,31 +2222,31 @@ class N {
|
|
|
2222
2222
|
const n = this.parseRule(e.recurrenceRule), a = [], o = e.end - e.start, c = r || e.timeZone || "UTC", l = S.getInstance();
|
|
2223
2223
|
let d = new Date(e.start), h = 0;
|
|
2224
2224
|
n.until && n.until < s && (s = n.until);
|
|
2225
|
-
let
|
|
2226
|
-
const
|
|
2225
|
+
let m = l.getTimezoneOffset(d, c), b = 0;
|
|
2226
|
+
const x = 3;
|
|
2227
2227
|
for (; d <= s && h < i; ) {
|
|
2228
2228
|
if (d >= t) {
|
|
2229
|
-
const
|
|
2230
|
-
if (
|
|
2231
|
-
const I =
|
|
2232
|
-
|
|
2229
|
+
const k = new Date(d), M = new Date(d.getTime() + o), $ = l.getTimezoneOffset(k, c);
|
|
2230
|
+
if ($ !== m) {
|
|
2231
|
+
const I = m - $;
|
|
2232
|
+
k.setMinutes(k.getMinutes() + I), M.setMinutes(M.getMinutes() + I);
|
|
2233
2233
|
}
|
|
2234
|
-
|
|
2235
|
-
start:
|
|
2236
|
-
end:
|
|
2234
|
+
m = $, this.isException(k, n, e.id) || a.push({
|
|
2235
|
+
start: k,
|
|
2236
|
+
end: M,
|
|
2237
2237
|
recurringEventId: e.id,
|
|
2238
2238
|
timezone: c,
|
|
2239
2239
|
originalStart: e.start
|
|
2240
2240
|
});
|
|
2241
2241
|
}
|
|
2242
|
-
const
|
|
2243
|
-
if (d = this.getNextOccurrence(d, n, c), h++, d.getTime() ===
|
|
2244
|
-
if (
|
|
2242
|
+
const A = d.getTime();
|
|
2243
|
+
if (d = this.getNextOccurrence(d, n, c), h++, d.getTime() === A) {
|
|
2244
|
+
if (b++, b >= x) {
|
|
2245
2245
|
console.warn("RecurrenceEngine: Date not advancing, breaking to prevent infinite loop");
|
|
2246
2246
|
break;
|
|
2247
2247
|
}
|
|
2248
2248
|
} else
|
|
2249
|
-
|
|
2249
|
+
b = 0;
|
|
2250
2250
|
if (n.count && h >= n.count)
|
|
2251
2251
|
break;
|
|
2252
2252
|
}
|
|
@@ -2258,7 +2258,7 @@ class N {
|
|
|
2258
2258
|
* @returns {import('../../types.js').RecurrenceRule} Parsed rule object
|
|
2259
2259
|
*/
|
|
2260
2260
|
static parseRule(e) {
|
|
2261
|
-
return
|
|
2261
|
+
return Z.parse(e);
|
|
2262
2262
|
}
|
|
2263
2263
|
/**
|
|
2264
2264
|
* Calculate the next occurrence based on the rule
|
|
@@ -2446,7 +2446,7 @@ class N {
|
|
|
2446
2446
|
return r && (n = `${r === -1 ? "Last" : ["", "1st", "2nd", "3rd", "4th", "5th"][r] || `${r}th`} ${n}`), n;
|
|
2447
2447
|
}
|
|
2448
2448
|
}
|
|
2449
|
-
class
|
|
2449
|
+
class L {
|
|
2450
2450
|
/**
|
|
2451
2451
|
* Create a new LRU Cache
|
|
2452
2452
|
* @param {number} capacity - Maximum number of items in cache
|
|
@@ -2533,7 +2533,7 @@ class z {
|
|
|
2533
2533
|
return this.cache.size;
|
|
2534
2534
|
}
|
|
2535
2535
|
}
|
|
2536
|
-
class
|
|
2536
|
+
class K {
|
|
2537
2537
|
constructor(e = {}) {
|
|
2538
2538
|
this.config = {
|
|
2539
2539
|
checkInterval: 3e4,
|
|
@@ -2751,7 +2751,7 @@ class j {
|
|
|
2751
2751
|
this.stopMonitoring(), this.caches.clear();
|
|
2752
2752
|
}
|
|
2753
2753
|
}
|
|
2754
|
-
class
|
|
2754
|
+
class G {
|
|
2755
2755
|
constructor(e = {}) {
|
|
2756
2756
|
this.config = {
|
|
2757
2757
|
enableCache: !0,
|
|
@@ -2766,7 +2766,7 @@ class W {
|
|
|
2766
2766
|
enableAdaptiveMemory: !0,
|
|
2767
2767
|
// Enable adaptive memory management
|
|
2768
2768
|
...e
|
|
2769
|
-
}, this.eventCache = new
|
|
2769
|
+
}, this.eventCache = new L(this.config.cacheCapacity), this.queryCache = new L(Math.floor(this.config.cacheCapacity / 2)), this.dateRangeCache = new L(Math.floor(this.config.cacheCapacity / 4)), this.config.enableAdaptiveMemory && (this.memoryManager = new K({
|
|
2770
2770
|
checkInterval: 3e4,
|
|
2771
2771
|
memoryThreshold: 0.75,
|
|
2772
2772
|
criticalThreshold: 0.9
|
|
@@ -3056,7 +3056,7 @@ class W {
|
|
|
3056
3056
|
this.cleanupTimer && (clearInterval(this.cleanupTimer), this.cleanupTimer = null), this.batchTimer && (clearTimeout(this.batchTimer), this.batchTimer = null), this.eventCache.clear(), this.queryCache.clear(), this.dateRangeCache.clear(), this.lazyIndexes.clear(), this.pendingIndexes.clear();
|
|
3057
3057
|
}
|
|
3058
3058
|
}
|
|
3059
|
-
class
|
|
3059
|
+
class Q {
|
|
3060
3060
|
/**
|
|
3061
3061
|
* Create a new ConflictDetector
|
|
3062
3062
|
* @param {import('../events/EventStore.js').EventStore} eventStore - Event store instance
|
|
@@ -3343,7 +3343,7 @@ class Z {
|
|
|
3343
3343
|
return i >= n && r <= a;
|
|
3344
3344
|
}
|
|
3345
3345
|
}
|
|
3346
|
-
class
|
|
3346
|
+
class J {
|
|
3347
3347
|
constructor(e = {}) {
|
|
3348
3348
|
this.events = /* @__PURE__ */ new Map(), this.indices = {
|
|
3349
3349
|
/** @type {Map<string, Set<string>>} UTC Date string -> Set of event IDs */
|
|
@@ -3356,7 +3356,7 @@ class q {
|
|
|
3356
3356
|
byCategory: /* @__PURE__ */ new Map(),
|
|
3357
3357
|
/** @type {Map<string, Set<string>>} Status -> Set of event IDs */
|
|
3358
3358
|
byStatus: /* @__PURE__ */ new Map()
|
|
3359
|
-
}, this.timezoneManager = S.getInstance(), this.defaultTimezone = e.timezone || this.timezoneManager.getSystemTimezone(), this.optimizer = new
|
|
3359
|
+
}, this.timezoneManager = S.getInstance(), this.defaultTimezone = e.timezone || this.timezoneManager.getSystemTimezone(), this.optimizer = new G(e.performance), this.conflictDetector = new Q(this), this.isBatchMode = !1, this.batchNotifications = [], this.batchBackup = null, this.version = 0, this.listeners = /* @__PURE__ */ new Set();
|
|
3360
3360
|
}
|
|
3361
3361
|
/**
|
|
3362
3362
|
* Add an event to the store
|
|
@@ -3366,7 +3366,7 @@ class q {
|
|
|
3366
3366
|
*/
|
|
3367
3367
|
addEvent(e) {
|
|
3368
3368
|
return this.optimizer.measure("addEvent", () => {
|
|
3369
|
-
if (e instanceof
|
|
3369
|
+
if (e instanceof D || (e = new D(e)), this.events.has(e.id))
|
|
3370
3370
|
throw new Error(`Event with id ${e.id} already exists`);
|
|
3371
3371
|
return this.events.set(e.id, e), this.optimizer.cache(e.id, e, "event"), this._indexEvent(e), this.isBatchMode ? this.batchNotifications.push({
|
|
3372
3372
|
type: "add",
|
|
@@ -3478,13 +3478,13 @@ class q {
|
|
|
3478
3478
|
* @returns {Event[]} Events occurring on the date, sorted by start time
|
|
3479
3479
|
*/
|
|
3480
3480
|
getEventsForDate(e, t = null) {
|
|
3481
|
-
t = t || this.defaultTimezone,
|
|
3481
|
+
t = t || this.defaultTimezone, f.getLocalDateString(e);
|
|
3482
3482
|
const s = /* @__PURE__ */ new Set(), i = new Date(e);
|
|
3483
3483
|
for (let l = -1; l <= 1; l++) {
|
|
3484
3484
|
const d = new Date(i);
|
|
3485
3485
|
d.setDate(d.getDate() + l);
|
|
3486
|
-
const h =
|
|
3487
|
-
|
|
3486
|
+
const h = f.getLocalDateString(d), m = this.indices.byDate.get(h);
|
|
3487
|
+
m && m.forEach((b) => s.add(b));
|
|
3488
3488
|
}
|
|
3489
3489
|
const r = `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}`, n = this.indices.byMonth.get(r);
|
|
3490
3490
|
n && n.forEach((l) => s.add(l));
|
|
@@ -3495,13 +3495,13 @@ class q {
|
|
|
3495
3495
|
for (const l of s) {
|
|
3496
3496
|
const d = this.events.get(l);
|
|
3497
3497
|
if (d) {
|
|
3498
|
-
const h = d.getStartInTimezone(t),
|
|
3499
|
-
h <= c &&
|
|
3498
|
+
const h = d.getStartInTimezone(t), m = d.getEndInTimezone(t);
|
|
3499
|
+
h <= c && m >= o && a.push(d);
|
|
3500
3500
|
}
|
|
3501
3501
|
}
|
|
3502
3502
|
return a.sort((l, d) => {
|
|
3503
|
-
const h = l.getStartInTimezone(t),
|
|
3504
|
-
return
|
|
3503
|
+
const h = l.getStartInTimezone(t), m = d.getStartInTimezone(t), b = h - m;
|
|
3504
|
+
return b !== 0 ? b : d.duration - l.duration;
|
|
3505
3505
|
});
|
|
3506
3506
|
}
|
|
3507
3507
|
/**
|
|
@@ -3512,14 +3512,14 @@ class q {
|
|
|
3512
3512
|
* @returns {Event[]} Array of overlapping events
|
|
3513
3513
|
*/
|
|
3514
3514
|
getOverlappingEvents(e, t, s = null) {
|
|
3515
|
-
const i = [], r =
|
|
3515
|
+
const i = [], r = f.startOfDay(e), n = f.endOfDay(t), a = f.getDateRange(r, n), o = /* @__PURE__ */ new Set();
|
|
3516
3516
|
return a.forEach((c) => {
|
|
3517
|
-
const l =
|
|
3517
|
+
const l = f.getLocalDateString(c);
|
|
3518
3518
|
(this.indices.byDate.get(l) || /* @__PURE__ */ new Set()).forEach((h) => {
|
|
3519
3519
|
if (!o.has(h) && h !== s) {
|
|
3520
3520
|
o.add(h);
|
|
3521
|
-
const
|
|
3522
|
-
|
|
3521
|
+
const m = this.events.get(h);
|
|
3522
|
+
m && m.overlaps({ start: e, end: t }) && i.push(m);
|
|
3523
3523
|
}
|
|
3524
3524
|
});
|
|
3525
3525
|
}), i.sort((c, l) => c.start - l.start);
|
|
@@ -3629,7 +3629,7 @@ class q {
|
|
|
3629
3629
|
return [e];
|
|
3630
3630
|
i = i || this.defaultTimezone;
|
|
3631
3631
|
const r = e.timeZone || i;
|
|
3632
|
-
return
|
|
3632
|
+
return q.expandEvent(e, t, s).map((a, o) => e.clone({
|
|
3633
3633
|
id: `${e.id}_occurrence_${o}`,
|
|
3634
3634
|
start: a.start,
|
|
3635
3635
|
end: a.end,
|
|
@@ -3680,9 +3680,9 @@ class q {
|
|
|
3680
3680
|
this._indexEventLazy(e);
|
|
3681
3681
|
return;
|
|
3682
3682
|
}
|
|
3683
|
-
const t = e.getStartInTimezone(e.timeZone), s = e.getEndInTimezone(e.endTimeZone || e.timeZone), i =
|
|
3684
|
-
|
|
3685
|
-
const c =
|
|
3683
|
+
const t = e.getStartInTimezone(e.timeZone), s = e.getEndInTimezone(e.endTimeZone || e.timeZone), i = f.startOfDay(t), r = f.endOfDay(s);
|
|
3684
|
+
f.getDateRange(i, r).forEach((o) => {
|
|
3685
|
+
const c = f.getLocalDateString(o);
|
|
3686
3686
|
this.indices.byDate.has(c) || this.indices.byDate.set(c, /* @__PURE__ */ new Set()), this.indices.byDate.get(c).add(e.id);
|
|
3687
3687
|
}), `${i.getFullYear()}${String(i.getMonth() + 1).padStart(2, "0")}`, `${r.getFullYear()}${String(r.getMonth() + 1).padStart(2, "0")}`;
|
|
3688
3688
|
const a = new Date(i.getFullYear(), i.getMonth(), 1);
|
|
@@ -3700,20 +3700,20 @@ class q {
|
|
|
3700
3700
|
*/
|
|
3701
3701
|
_indexEventLazy(e) {
|
|
3702
3702
|
this.optimizer.createLazyIndexMarkers(e);
|
|
3703
|
-
const t = e.getStartInTimezone(e.timeZone), s = e.getEndInTimezone(e.endTimeZone || e.timeZone), i =
|
|
3704
|
-
if (n.setDate(n.getDate() + 7),
|
|
3703
|
+
const t = e.getStartInTimezone(e.timeZone), s = e.getEndInTimezone(e.endTimeZone || e.timeZone), i = f.startOfDay(t), r = f.endOfDay(s), n = new Date(i);
|
|
3704
|
+
if (n.setDate(n.getDate() + 7), f.getDateRange(
|
|
3705
3705
|
i,
|
|
3706
3706
|
n < r ? n : r
|
|
3707
3707
|
).forEach((c) => {
|
|
3708
|
-
const l =
|
|
3708
|
+
const l = f.getLocalDateString(c);
|
|
3709
3709
|
this.indices.byDate.has(l) || this.indices.byDate.set(l, /* @__PURE__ */ new Set()), this.indices.byDate.get(l).add(e.id);
|
|
3710
3710
|
}), r > n) {
|
|
3711
3711
|
const c = new Date(r);
|
|
3712
|
-
c.setDate(c.getDate() - 7),
|
|
3712
|
+
c.setDate(c.getDate() - 7), f.getDateRange(
|
|
3713
3713
|
c > i ? c : i,
|
|
3714
3714
|
r
|
|
3715
3715
|
).forEach((d) => {
|
|
3716
|
-
const h =
|
|
3716
|
+
const h = f.getLocalDateString(d);
|
|
3717
3717
|
this.indices.byDate.has(h) || this.indices.byDate.set(h, /* @__PURE__ */ new Set()), this.indices.byDate.get(h).add(e.id);
|
|
3718
3718
|
});
|
|
3719
3719
|
}
|
|
@@ -4023,7 +4023,7 @@ class q {
|
|
|
4023
4023
|
return t;
|
|
4024
4024
|
}
|
|
4025
4025
|
}
|
|
4026
|
-
let
|
|
4026
|
+
let X = class {
|
|
4027
4027
|
/**
|
|
4028
4028
|
* Create a new StateManager instance
|
|
4029
4029
|
* @param {Partial<import('../../types.js').CalendarState>} [initialState={}] - Initial state values
|
|
@@ -4404,7 +4404,7 @@ let K = class {
|
|
|
4404
4404
|
}
|
|
4405
4405
|
}
|
|
4406
4406
|
};
|
|
4407
|
-
class
|
|
4407
|
+
class ee {
|
|
4408
4408
|
/**
|
|
4409
4409
|
* Create a new Calendar instance
|
|
4410
4410
|
* @param {import('../../types.js').CalendarConfig} [config={}] - Configuration options
|
|
@@ -4425,7 +4425,7 @@ class G {
|
|
|
4425
4425
|
end: "17:00"
|
|
4426
4426
|
},
|
|
4427
4427
|
...e
|
|
4428
|
-
}, this.eventStore = new
|
|
4428
|
+
}, this.eventStore = new J({ timezone: this.config.timeZone }), this.state = new X({
|
|
4429
4429
|
view: this.config.view,
|
|
4430
4430
|
currentDate: this.config.date,
|
|
4431
4431
|
weekStartsOn: this.config.weekStartsOn,
|
|
@@ -4516,7 +4516,7 @@ class G {
|
|
|
4516
4516
|
* @returns {import('../events/Event.js').Event} The added event
|
|
4517
4517
|
*/
|
|
4518
4518
|
addEvent(e) {
|
|
4519
|
-
!(e instanceof
|
|
4519
|
+
!(e instanceof D) && !e.timeZone && (e = { ...e, timeZone: this.config.timeZone });
|
|
4520
4520
|
const t = this.eventStore.addEvent(e);
|
|
4521
4521
|
return this._emit("eventAdd", { event: t }), t;
|
|
4522
4522
|
}
|
|
@@ -4714,32 +4714,32 @@ class G {
|
|
|
4714
4714
|
* @private
|
|
4715
4715
|
*/
|
|
4716
4716
|
_getMonthViewData(e) {
|
|
4717
|
-
const t = e.getFullYear(), s = e.getMonth(), i = this.state.get("weekStartsOn"), r = this.state.get("fixedWeekCount"), n = new Date(t, s, 1), a = new Date(t, s + 1, 0), o =
|
|
4717
|
+
const t = e.getFullYear(), s = e.getMonth(), i = this.state.get("weekStartsOn"), r = this.state.get("fixedWeekCount"), n = new Date(t, s, 1), a = new Date(t, s + 1, 0), o = f.startOfWeek(n, i), c = [];
|
|
4718
4718
|
let l = new Date(o);
|
|
4719
|
-
const d = r ? 6 : Math.ceil((a.getDate() +
|
|
4719
|
+
const d = r ? 6 : Math.ceil((a.getDate() + f.getDayOfWeek(n, i)) / 7);
|
|
4720
4720
|
for (let h = 0; h < d; h++) {
|
|
4721
|
-
const
|
|
4722
|
-
weekNumber:
|
|
4721
|
+
const m = {
|
|
4722
|
+
weekNumber: f.getWeekNumber(l),
|
|
4723
4723
|
days: []
|
|
4724
4724
|
};
|
|
4725
|
-
for (let
|
|
4726
|
-
const
|
|
4727
|
-
|
|
4728
|
-
date:
|
|
4729
|
-
dayOfMonth:
|
|
4730
|
-
isCurrentMonth:
|
|
4731
|
-
isToday:
|
|
4732
|
-
isWeekend:
|
|
4733
|
-
events: this.getEventsForDate(
|
|
4734
|
-
}), l =
|
|
4725
|
+
for (let b = 0; b < 7; b++) {
|
|
4726
|
+
const x = new Date(l), A = x.getMonth() === s, k = f.isToday(x), M = x.getDay() === 0 || x.getDay() === 6;
|
|
4727
|
+
m.days.push({
|
|
4728
|
+
date: x,
|
|
4729
|
+
dayOfMonth: x.getDate(),
|
|
4730
|
+
isCurrentMonth: A,
|
|
4731
|
+
isToday: k,
|
|
4732
|
+
isWeekend: M,
|
|
4733
|
+
events: this.getEventsForDate(x)
|
|
4734
|
+
}), l = f.addDays(l, 1);
|
|
4735
4735
|
}
|
|
4736
|
-
c.push(
|
|
4736
|
+
c.push(m);
|
|
4737
4737
|
}
|
|
4738
4738
|
return {
|
|
4739
4739
|
type: "month",
|
|
4740
4740
|
year: t,
|
|
4741
4741
|
month: s,
|
|
4742
|
-
monthName:
|
|
4742
|
+
monthName: f.getMonthName(e, this.state.get("locale")),
|
|
4743
4743
|
weeks: c,
|
|
4744
4744
|
startDate: o,
|
|
4745
4745
|
endDate: new Date(l.getTime() - 1)
|
|
@@ -4751,15 +4751,15 @@ class G {
|
|
|
4751
4751
|
* @private
|
|
4752
4752
|
*/
|
|
4753
4753
|
_getWeekViewData(e) {
|
|
4754
|
-
const t = this.state.get("weekStartsOn"), s =
|
|
4754
|
+
const t = this.state.get("weekStartsOn"), s = f.startOfWeek(e, t), i = f.endOfWeek(e, t), r = [], n = new Date(s);
|
|
4755
4755
|
for (let a = 0; a < 7; a++) {
|
|
4756
4756
|
const o = new Date(n);
|
|
4757
4757
|
r.push({
|
|
4758
4758
|
date: o,
|
|
4759
4759
|
dayOfMonth: o.getDate(),
|
|
4760
4760
|
dayOfWeek: o.getDay(),
|
|
4761
|
-
dayName:
|
|
4762
|
-
isToday:
|
|
4761
|
+
dayName: f.getDayName(o, this.state.get("locale")),
|
|
4762
|
+
isToday: f.isToday(o),
|
|
4763
4763
|
isWeekend: o.getDay() === 0 || o.getDay() === 6,
|
|
4764
4764
|
events: this.getEventsForDate(o),
|
|
4765
4765
|
// Add overlap groups for positioning overlapping events
|
|
@@ -4769,7 +4769,7 @@ class G {
|
|
|
4769
4769
|
}
|
|
4770
4770
|
return {
|
|
4771
4771
|
type: "week",
|
|
4772
|
-
weekNumber:
|
|
4772
|
+
weekNumber: f.getWeekNumber(s),
|
|
4773
4773
|
startDate: s,
|
|
4774
4774
|
endDate: i,
|
|
4775
4775
|
days: r
|
|
@@ -4787,15 +4787,15 @@ class G {
|
|
|
4787
4787
|
const o = new Date(e);
|
|
4788
4788
|
o.setHours(n + 1, 0, 0, 0), r.push({
|
|
4789
4789
|
hour: n,
|
|
4790
|
-
time:
|
|
4790
|
+
time: f.formatTime(a, this.state.get("locale")),
|
|
4791
4791
|
events: i.filter((c) => c.start < o && c.end > a)
|
|
4792
4792
|
});
|
|
4793
4793
|
}
|
|
4794
4794
|
return {
|
|
4795
4795
|
type: "day",
|
|
4796
4796
|
date: e,
|
|
4797
|
-
dayName:
|
|
4798
|
-
isToday:
|
|
4797
|
+
dayName: f.getDayName(e, this.state.get("locale")),
|
|
4798
|
+
isToday: f.isToday(e),
|
|
4799
4799
|
allDayEvents: s,
|
|
4800
4800
|
hours: r
|
|
4801
4801
|
};
|
|
@@ -4819,8 +4819,8 @@ class G {
|
|
|
4819
4819
|
});
|
|
4820
4820
|
const n = Array.from(r.values()).sort((a, o) => a.date - o.date).map((a) => ({
|
|
4821
4821
|
...a,
|
|
4822
|
-
dayName:
|
|
4823
|
-
isToday:
|
|
4822
|
+
dayName: f.getDayName(a.date, this.state.get("locale")),
|
|
4823
|
+
isToday: f.isToday(a.date)
|
|
4824
4824
|
}));
|
|
4825
4825
|
return {
|
|
4826
4826
|
type: "list",
|
|
@@ -4925,7 +4925,7 @@ class G {
|
|
|
4925
4925
|
}), this.plugins.clear(), this.views.clear(), this._emit("destroy");
|
|
4926
4926
|
}
|
|
4927
4927
|
}
|
|
4928
|
-
class
|
|
4928
|
+
class te {
|
|
4929
4929
|
constructor() {
|
|
4930
4930
|
this.events = /* @__PURE__ */ new Map(), this.wildcardHandlers = /* @__PURE__ */ new Set();
|
|
4931
4931
|
}
|
|
@@ -4959,10 +4959,39 @@ class Q {
|
|
|
4959
4959
|
* Unsubscribe from an event
|
|
4960
4960
|
*/
|
|
4961
4961
|
off(e, t) {
|
|
4962
|
+
if (e.includes("*")) {
|
|
4963
|
+
for (const r of this.wildcardHandlers)
|
|
4964
|
+
if (r.pattern === e && r.handler === t) {
|
|
4965
|
+
this.wildcardHandlers.delete(r);
|
|
4966
|
+
return;
|
|
4967
|
+
}
|
|
4968
|
+
return;
|
|
4969
|
+
}
|
|
4962
4970
|
if (!this.events.has(e)) return;
|
|
4963
4971
|
const s = this.events.get(e), i = s.findIndex((r) => r.handler === t);
|
|
4964
4972
|
i > -1 && s.splice(i, 1), s.length === 0 && this.events.delete(e);
|
|
4965
4973
|
}
|
|
4974
|
+
/**
|
|
4975
|
+
* Remove all wildcard handlers matching a pattern
|
|
4976
|
+
* @param {string} pattern - Pattern to match (e.g., 'event:*')
|
|
4977
|
+
*/
|
|
4978
|
+
offWildcard(e) {
|
|
4979
|
+
for (const t of [...this.wildcardHandlers])
|
|
4980
|
+
t.pattern === e && this.wildcardHandlers.delete(t);
|
|
4981
|
+
}
|
|
4982
|
+
/**
|
|
4983
|
+
* Remove all handlers (regular and wildcard) for a specific handler function
|
|
4984
|
+
* Useful for cleanup when a component is destroyed
|
|
4985
|
+
* @param {Function} handler - Handler function to remove
|
|
4986
|
+
*/
|
|
4987
|
+
offAll(e) {
|
|
4988
|
+
for (const [t, s] of this.events) {
|
|
4989
|
+
const i = s.findIndex((r) => r.handler === e);
|
|
4990
|
+
i > -1 && s.splice(i, 1), s.length === 0 && this.events.delete(t);
|
|
4991
|
+
}
|
|
4992
|
+
for (const t of [...this.wildcardHandlers])
|
|
4993
|
+
t.handler === e && this.wildcardHandlers.delete(t);
|
|
4994
|
+
}
|
|
4966
4995
|
/**
|
|
4967
4996
|
* Emit an event
|
|
4968
4997
|
* @param {string} eventName - Event name
|
|
@@ -5022,11 +5051,26 @@ class Q {
|
|
|
5022
5051
|
getHandlerCount(e) {
|
|
5023
5052
|
return this.events.has(e) ? this.events.get(e).length : 0;
|
|
5024
5053
|
}
|
|
5054
|
+
/**
|
|
5055
|
+
* Get wildcard handler count
|
|
5056
|
+
*/
|
|
5057
|
+
getWildcardHandlerCount() {
|
|
5058
|
+
return this.wildcardHandlers.size;
|
|
5059
|
+
}
|
|
5060
|
+
/**
|
|
5061
|
+
* Get total handler count (for debugging/monitoring)
|
|
5062
|
+
*/
|
|
5063
|
+
getTotalHandlerCount() {
|
|
5064
|
+
let e = this.wildcardHandlers.size;
|
|
5065
|
+
for (const t of this.events.values())
|
|
5066
|
+
e += t.length;
|
|
5067
|
+
return e;
|
|
5068
|
+
}
|
|
5025
5069
|
}
|
|
5026
|
-
const
|
|
5027
|
-
class
|
|
5070
|
+
const p = new te();
|
|
5071
|
+
class se {
|
|
5028
5072
|
constructor(e = {}) {
|
|
5029
|
-
this.calendar = new
|
|
5073
|
+
this.calendar = new ee({
|
|
5030
5074
|
view: e.view || "month",
|
|
5031
5075
|
date: e.date || /* @__PURE__ */ new Date(),
|
|
5032
5076
|
weekStartsOn: e.weekStartsOn ?? 0,
|
|
@@ -5068,11 +5112,26 @@ class J {
|
|
|
5068
5112
|
const { silent: s = !1 } = t, i = { ...this.state };
|
|
5069
5113
|
return this.state = { ...this.state, ...e }, s || (this.notifySubscribers(i, this.state), this.emitStateChange(i, this.state)), this.state;
|
|
5070
5114
|
}
|
|
5071
|
-
subscribe(e) {
|
|
5072
|
-
return this.subscribers.add(e), () => this.unsubscribe(e);
|
|
5115
|
+
subscribe(e, t = null) {
|
|
5116
|
+
return this.subscribers.add(e), t && (this._subscriberIds || (this._subscriberIds = /* @__PURE__ */ new Map()), this._subscriberIds.set(t, e)), () => this.unsubscribe(e, t);
|
|
5117
|
+
}
|
|
5118
|
+
unsubscribe(e, t = null) {
|
|
5119
|
+
this.subscribers.delete(e), t && this._subscriberIds && this._subscriberIds.delete(t);
|
|
5073
5120
|
}
|
|
5074
|
-
|
|
5075
|
-
|
|
5121
|
+
/**
|
|
5122
|
+
* Unsubscribe by subscriber ID
|
|
5123
|
+
* @param {string} subscriberId - ID used when subscribing
|
|
5124
|
+
*/
|
|
5125
|
+
unsubscribeById(e) {
|
|
5126
|
+
if (!this._subscriberIds) return !1;
|
|
5127
|
+
const t = this._subscriberIds.get(e);
|
|
5128
|
+
return t ? (this.subscribers.delete(t), this._subscriberIds.delete(e), !0) : !1;
|
|
5129
|
+
}
|
|
5130
|
+
/**
|
|
5131
|
+
* Get subscriber count (for debugging/monitoring)
|
|
5132
|
+
*/
|
|
5133
|
+
getSubscriberCount() {
|
|
5134
|
+
return this.subscribers.size;
|
|
5076
5135
|
}
|
|
5077
5136
|
notifySubscribers(e, t) {
|
|
5078
5137
|
this.subscribers.forEach((s) => {
|
|
@@ -5088,51 +5147,51 @@ class J {
|
|
|
5088
5147
|
(i) => e[i] !== t[i]
|
|
5089
5148
|
);
|
|
5090
5149
|
s.forEach((i) => {
|
|
5091
|
-
|
|
5150
|
+
p.emit(`state:${i}:changed`, {
|
|
5092
5151
|
oldValue: e[i],
|
|
5093
5152
|
newValue: t[i],
|
|
5094
5153
|
state: t
|
|
5095
5154
|
});
|
|
5096
|
-
}), s.length > 0 &&
|
|
5155
|
+
}), s.length > 0 && p.emit("state:changed", { oldState: e, newState: t, changedKeys: s });
|
|
5097
5156
|
}
|
|
5098
5157
|
// Calendar operations
|
|
5099
5158
|
setView(e) {
|
|
5100
|
-
this.calendar.setView(e), this.setState({ view: e }),
|
|
5159
|
+
this.calendar.setView(e), this.setState({ view: e }), p.emit("view:changed", { view: e });
|
|
5101
5160
|
}
|
|
5102
5161
|
getView() {
|
|
5103
5162
|
return this.state.view;
|
|
5104
5163
|
}
|
|
5105
5164
|
setDate(e) {
|
|
5106
|
-
this.calendar.goToDate(e), this.setState({ currentDate: this.calendar.getCurrentDate() }),
|
|
5165
|
+
this.calendar.goToDate(e), this.setState({ currentDate: this.calendar.getCurrentDate() }), p.emit("date:changed", { date: this.state.currentDate });
|
|
5107
5166
|
}
|
|
5108
5167
|
getCurrentDate() {
|
|
5109
5168
|
return this.state.currentDate;
|
|
5110
5169
|
}
|
|
5111
5170
|
// Navigation
|
|
5112
5171
|
next() {
|
|
5113
|
-
this.calendar.next(), this.setState({ currentDate: this.calendar.getCurrentDate() }),
|
|
5172
|
+
this.calendar.next(), this.setState({ currentDate: this.calendar.getCurrentDate() }), p.emit("navigation:next", { date: this.state.currentDate });
|
|
5114
5173
|
}
|
|
5115
5174
|
previous() {
|
|
5116
|
-
this.calendar.previous(), this.setState({ currentDate: this.calendar.getCurrentDate() }),
|
|
5175
|
+
this.calendar.previous(), this.setState({ currentDate: this.calendar.getCurrentDate() }), p.emit("navigation:previous", { date: this.state.currentDate });
|
|
5117
5176
|
}
|
|
5118
5177
|
today() {
|
|
5119
|
-
this.calendar.today(), this.setState({ currentDate: this.calendar.getCurrentDate() }),
|
|
5178
|
+
this.calendar.today(), this.setState({ currentDate: this.calendar.getCurrentDate() }), p.emit("navigation:today", { date: this.state.currentDate });
|
|
5120
5179
|
}
|
|
5121
5180
|
goToDate(e) {
|
|
5122
|
-
this.calendar.goToDate(e), this.setState({ currentDate: this.calendar.getCurrentDate() }),
|
|
5181
|
+
this.calendar.goToDate(e), this.setState({ currentDate: this.calendar.getCurrentDate() }), p.emit("navigation:goto", { date: this.state.currentDate });
|
|
5123
5182
|
}
|
|
5124
5183
|
// Event management
|
|
5125
5184
|
addEvent(e) {
|
|
5126
5185
|
const t = this.calendar.addEvent(e);
|
|
5127
|
-
return t ? (this._syncEventsFromCore(),
|
|
5186
|
+
return t ? (this._syncEventsFromCore(), p.emit("event:added", { event: t }), t) : (console.error("Failed to add event to calendar"), p.emit("event:error", { action: "add", event: e, error: "Failed to add event" }), null);
|
|
5128
5187
|
}
|
|
5129
5188
|
updateEvent(e, t) {
|
|
5130
5189
|
this._syncEventsFromCore({ silent: !0 });
|
|
5131
5190
|
const s = this.calendar.updateEvent(e, t);
|
|
5132
|
-
return s ? (this._syncEventsFromCore(),
|
|
5191
|
+
return s ? (this._syncEventsFromCore(), p.emit("event:updated", { event: s }), s) : (console.error(`Failed to update event: ${e}`), p.emit("event:error", { action: "update", eventId: e, updates: t, error: "Event not found in calendar" }), null);
|
|
5133
5192
|
}
|
|
5134
5193
|
deleteEvent(e) {
|
|
5135
|
-
return this._syncEventsFromCore({ silent: !0 }), this.calendar.removeEvent(e) ? (this._syncEventsFromCore(),
|
|
5194
|
+
return this._syncEventsFromCore({ silent: !0 }), this.calendar.removeEvent(e) ? (this._syncEventsFromCore(), p.emit("event:deleted", { eventId: e }), !0) : (console.error(`Failed to delete event: ${e}`), p.emit("event:error", { action: "delete", eventId: e, error: "Event not found" }), !1);
|
|
5136
5195
|
}
|
|
5137
5196
|
getEvents() {
|
|
5138
5197
|
return this.calendar.getEvents() || [];
|
|
@@ -5183,20 +5242,20 @@ class J {
|
|
|
5183
5242
|
}
|
|
5184
5243
|
// Selection management
|
|
5185
5244
|
selectEvent(e) {
|
|
5186
|
-
this.setState({ selectedEvent: e }),
|
|
5245
|
+
this.setState({ selectedEvent: e }), p.emit("event:selected", { event: e });
|
|
5187
5246
|
}
|
|
5188
5247
|
selectEventById(e) {
|
|
5189
5248
|
const t = this.state.events.find((s) => s.id === e);
|
|
5190
5249
|
t && this.selectEvent(t);
|
|
5191
5250
|
}
|
|
5192
5251
|
deselectEvent() {
|
|
5193
|
-
this.setState({ selectedEvent: null }),
|
|
5252
|
+
this.setState({ selectedEvent: null }), p.emit("event:deselected", {});
|
|
5194
5253
|
}
|
|
5195
5254
|
selectDate(e) {
|
|
5196
|
-
this.setState({ selectedDate: e }),
|
|
5255
|
+
this.setState({ selectedDate: e }), p.emit("date:selected", { date: e });
|
|
5197
5256
|
}
|
|
5198
5257
|
deselectDate() {
|
|
5199
|
-
this.setState({ selectedDate: null }),
|
|
5258
|
+
this.setState({ selectedDate: null }), p.emit("date:deselected", {});
|
|
5200
5259
|
}
|
|
5201
5260
|
// Utility methods
|
|
5202
5261
|
isToday(e) {
|
|
@@ -5216,7 +5275,7 @@ class J {
|
|
|
5216
5275
|
}
|
|
5217
5276
|
// Error handling
|
|
5218
5277
|
setError(e) {
|
|
5219
|
-
this.setState({ error: e }), e &&
|
|
5278
|
+
this.setState({ error: e }), e && p.emit("error", { error: e });
|
|
5220
5279
|
}
|
|
5221
5280
|
clearError() {
|
|
5222
5281
|
this.setState({ error: null });
|
|
@@ -5227,10 +5286,10 @@ class J {
|
|
|
5227
5286
|
}
|
|
5228
5287
|
// Destroy
|
|
5229
5288
|
destroy() {
|
|
5230
|
-
this.subscribers.clear(), this.state = null, this.calendar = null;
|
|
5289
|
+
this.subscribers.clear(), this._subscriberIds && (this._subscriberIds.clear(), this._subscriberIds = null), this.state = null, this.calendar = null;
|
|
5231
5290
|
}
|
|
5232
5291
|
}
|
|
5233
|
-
class
|
|
5292
|
+
class v extends f {
|
|
5234
5293
|
/**
|
|
5235
5294
|
* Format date for display
|
|
5236
5295
|
*/
|
|
@@ -5344,7 +5403,7 @@ class x extends u {
|
|
|
5344
5403
|
return r && (r.toLowerCase() === "pm" && n < 12 ? o = n + 12 : r.toLowerCase() === "am" && n === 12 && (o = 0)), s.setHours(o, a || 0, 0, 0), s;
|
|
5345
5404
|
}
|
|
5346
5405
|
}
|
|
5347
|
-
class
|
|
5406
|
+
class T {
|
|
5348
5407
|
/**
|
|
5349
5408
|
* Create element with attributes and children
|
|
5350
5409
|
*/
|
|
@@ -5539,7 +5598,7 @@ class C {
|
|
|
5539
5598
|
return e.addEventListener("keydown", r), s == null || s.focus(), () => e.removeEventListener("keydown", r);
|
|
5540
5599
|
}
|
|
5541
5600
|
}
|
|
5542
|
-
class
|
|
5601
|
+
class y {
|
|
5543
5602
|
/**
|
|
5544
5603
|
* Get CSS variable value
|
|
5545
5604
|
*/
|
|
@@ -5876,7 +5935,7 @@ class v {
|
|
|
5876
5935
|
/**
|
|
5877
5936
|
* Default theme colors
|
|
5878
5937
|
*/
|
|
5879
|
-
|
|
5938
|
+
z(y, "colors", {
|
|
5880
5939
|
primary: "#3B82F6",
|
|
5881
5940
|
// Modern Blue
|
|
5882
5941
|
secondary: "#64748B",
|
|
@@ -5909,7 +5968,7 @@ _(v, "colors", {
|
|
|
5909
5968
|
}), /**
|
|
5910
5969
|
* Common CSS variables
|
|
5911
5970
|
*/
|
|
5912
|
-
|
|
5971
|
+
z(y, "cssVariables", {
|
|
5913
5972
|
// "Pro" Palette - Functional & Sharp
|
|
5914
5973
|
"--fc-primary-color": "#2563EB",
|
|
5915
5974
|
// International Blue (Focus)
|
|
@@ -5977,7 +6036,7 @@ _(v, "cssVariables", {
|
|
|
5977
6036
|
}), /**
|
|
5978
6037
|
* Get responsive breakpoints
|
|
5979
6038
|
*/
|
|
5980
|
-
|
|
6039
|
+
z(y, "breakpoints", {
|
|
5981
6040
|
xs: "320px",
|
|
5982
6041
|
sm: "576px",
|
|
5983
6042
|
md: "768px",
|
|
@@ -5985,7 +6044,479 @@ _(v, "breakpoints", {
|
|
|
5985
6044
|
xl: "1200px",
|
|
5986
6045
|
"2xl": "1400px"
|
|
5987
6046
|
});
|
|
5988
|
-
class
|
|
6047
|
+
class O {
|
|
6048
|
+
/**
|
|
6049
|
+
* @param {HTMLElement} container - The DOM element to render into
|
|
6050
|
+
* @param {StateManager} stateManager - The state manager instance
|
|
6051
|
+
*/
|
|
6052
|
+
constructor(e, t) {
|
|
6053
|
+
this.container = e, this.stateManager = t, this._listeners = [], this._scrolled = !1;
|
|
6054
|
+
}
|
|
6055
|
+
/**
|
|
6056
|
+
* Render the view into the container
|
|
6057
|
+
* Must be implemented by subclasses
|
|
6058
|
+
*/
|
|
6059
|
+
render() {
|
|
6060
|
+
throw new Error("render() must be implemented by subclass");
|
|
6061
|
+
}
|
|
6062
|
+
/**
|
|
6063
|
+
* Clean up event listeners
|
|
6064
|
+
*/
|
|
6065
|
+
cleanup() {
|
|
6066
|
+
this._listeners.forEach(({ element: e, event: t, handler: s }) => {
|
|
6067
|
+
e.removeEventListener(t, s);
|
|
6068
|
+
}), this._listeners = [];
|
|
6069
|
+
}
|
|
6070
|
+
/**
|
|
6071
|
+
* Add an event listener with automatic cleanup tracking
|
|
6072
|
+
* @param {HTMLElement} element
|
|
6073
|
+
* @param {string} event
|
|
6074
|
+
* @param {Function} handler
|
|
6075
|
+
*/
|
|
6076
|
+
addListener(e, t, s) {
|
|
6077
|
+
const i = s.bind(this);
|
|
6078
|
+
e.addEventListener(t, i), this._listeners.push({ element: e, event: t, handler: i });
|
|
6079
|
+
}
|
|
6080
|
+
/**
|
|
6081
|
+
* Escape HTML to prevent XSS
|
|
6082
|
+
* @param {string} str
|
|
6083
|
+
* @returns {string}
|
|
6084
|
+
*/
|
|
6085
|
+
escapeHTML(e) {
|
|
6086
|
+
return e == null ? "" : T.escapeHTML(String(e));
|
|
6087
|
+
}
|
|
6088
|
+
/**
|
|
6089
|
+
* Check if a date is today
|
|
6090
|
+
* @param {Date} date
|
|
6091
|
+
* @returns {boolean}
|
|
6092
|
+
*/
|
|
6093
|
+
isToday(e) {
|
|
6094
|
+
const t = /* @__PURE__ */ new Date();
|
|
6095
|
+
return e.getDate() === t.getDate() && e.getMonth() === t.getMonth() && e.getFullYear() === t.getFullYear();
|
|
6096
|
+
}
|
|
6097
|
+
/**
|
|
6098
|
+
* Check if two dates are the same day
|
|
6099
|
+
* @param {Date} date1
|
|
6100
|
+
* @param {Date} date2
|
|
6101
|
+
* @returns {boolean}
|
|
6102
|
+
*/
|
|
6103
|
+
isSameDay(e, t) {
|
|
6104
|
+
return e.getDate() === t.getDate() && e.getMonth() === t.getMonth() && e.getFullYear() === t.getFullYear();
|
|
6105
|
+
}
|
|
6106
|
+
/**
|
|
6107
|
+
* Format hour for display (e.g., "9 AM", "2 PM")
|
|
6108
|
+
* @param {number} hour - Hour in 24-hour format (0-23)
|
|
6109
|
+
* @returns {string}
|
|
6110
|
+
*/
|
|
6111
|
+
formatHour(e) {
|
|
6112
|
+
const t = e >= 12 ? "PM" : "AM";
|
|
6113
|
+
return `${e % 12 || 12} ${t}`;
|
|
6114
|
+
}
|
|
6115
|
+
/**
|
|
6116
|
+
* Format time for display (e.g., "9 AM", "2:30 PM")
|
|
6117
|
+
* @param {Date} date
|
|
6118
|
+
* @returns {string}
|
|
6119
|
+
*/
|
|
6120
|
+
formatTime(e) {
|
|
6121
|
+
const t = e.getHours(), s = e.getMinutes(), i = t >= 12 ? "PM" : "AM", r = t % 12 || 12;
|
|
6122
|
+
return s === 0 ? `${r} ${i}` : `${r}:${s.toString().padStart(2, "0")} ${i}`;
|
|
6123
|
+
}
|
|
6124
|
+
/**
|
|
6125
|
+
* Get contrasting text color for a background color
|
|
6126
|
+
* Uses WCAG luminance formula
|
|
6127
|
+
* @param {string} bgColor - Hex color string
|
|
6128
|
+
* @returns {string} 'black' or 'white'
|
|
6129
|
+
*/
|
|
6130
|
+
getContrastingTextColor(e) {
|
|
6131
|
+
if (!e || typeof e != "string") return "white";
|
|
6132
|
+
const t = e.charAt(0) === "#" ? e.substring(1) : e;
|
|
6133
|
+
if (!/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(t))
|
|
6134
|
+
return "white";
|
|
6135
|
+
const s = t.length === 3 ? t[0] + t[0] + t[1] + t[1] + t[2] + t[2] : t, i = parseInt(s.substring(0, 2), 16), r = parseInt(s.substring(2, 4), 16), n = parseInt(s.substring(4, 6), 16);
|
|
6136
|
+
if (isNaN(i) || isNaN(r) || isNaN(n))
|
|
6137
|
+
return "white";
|
|
6138
|
+
const o = [i / 255, r / 255, n / 255].map((l) => l <= 0.03928 ? l / 12.92 : Math.pow((l + 0.055) / 1.055, 2.4));
|
|
6139
|
+
return 0.2126 * o[0] + 0.7152 * o[1] + 0.0722 * o[2] > 0.179 ? "black" : "white";
|
|
6140
|
+
}
|
|
6141
|
+
/**
|
|
6142
|
+
* Render the "now" indicator line for time-based views
|
|
6143
|
+
* @returns {string} HTML string
|
|
6144
|
+
*/
|
|
6145
|
+
renderNowIndicator() {
|
|
6146
|
+
const e = /* @__PURE__ */ new Date();
|
|
6147
|
+
return `<div class="fc-now-indicator" style="position: absolute; left: 0; right: 0; top: ${e.getHours() * 60 + e.getMinutes()}px; height: 2px; background: #dc2626; z-index: 15; pointer-events: none;"></div>`;
|
|
6148
|
+
}
|
|
6149
|
+
/**
|
|
6150
|
+
* Render a timed event block
|
|
6151
|
+
* @param {Object} event - Event object
|
|
6152
|
+
* @param {Object} options - Rendering options
|
|
6153
|
+
* @returns {string} HTML string
|
|
6154
|
+
*/
|
|
6155
|
+
renderTimedEvent(e, t = {}) {
|
|
6156
|
+
const { compact: s = !0 } = t, i = new Date(e.start), r = new Date(e.end), n = i.getHours() * 60 + i.getMinutes(), a = Math.max((r - i) / (1e3 * 60), s ? 20 : 30), o = e.backgroundColor || "#2563eb", c = s ? "4px 8px" : "8px 12px", l = s ? "11px" : "13px", d = s ? "2px" : "12px", h = s ? "2px" : "24px", m = s ? "4px" : "6px";
|
|
6157
|
+
return `
|
|
6158
|
+
<div class="fc-event fc-timed-event" data-event-id="${this.escapeHTML(e.id)}"
|
|
6159
|
+
style="position: absolute; top: ${n}px; height: ${a}px;
|
|
6160
|
+
left: ${d}; right: ${h};
|
|
6161
|
+
background-color: ${o}; border-radius: ${m};
|
|
6162
|
+
padding: ${c}; font-size: ${l};
|
|
6163
|
+
font-weight: 500; color: white; overflow: hidden;
|
|
6164
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
|
6165
|
+
cursor: pointer; z-index: 5;">
|
|
6166
|
+
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
|
6167
|
+
${this.escapeHTML(e.title)}
|
|
6168
|
+
</div>
|
|
6169
|
+
<div style="font-size: ${s ? "10px" : "11px"}; opacity: 0.9;">
|
|
6170
|
+
${this.formatTime(i)}${s ? "" : " - " + this.formatTime(r)}
|
|
6171
|
+
</div>
|
|
6172
|
+
</div>
|
|
6173
|
+
`;
|
|
6174
|
+
}
|
|
6175
|
+
/**
|
|
6176
|
+
* Attach common event handlers for day/event clicks
|
|
6177
|
+
*/
|
|
6178
|
+
attachCommonEventHandlers() {
|
|
6179
|
+
this.container.querySelectorAll(".fc-event").forEach((e) => {
|
|
6180
|
+
this.addListener(e, "click", (t) => {
|
|
6181
|
+
t.stopPropagation();
|
|
6182
|
+
const s = e.dataset.eventId, i = this.stateManager.getEvents().find((r) => r.id === s);
|
|
6183
|
+
i && this.stateManager.selectEvent(i);
|
|
6184
|
+
});
|
|
6185
|
+
});
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
class E extends O {
|
|
6189
|
+
constructor(e, t) {
|
|
6190
|
+
super(e, t), this.maxEventsToShow = 3;
|
|
6191
|
+
}
|
|
6192
|
+
render() {
|
|
6193
|
+
if (!this.container || !this.stateManager) return;
|
|
6194
|
+
const e = this.stateManager.getViewData();
|
|
6195
|
+
if (!e || !e.weeks) {
|
|
6196
|
+
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No data available for month view.</div>';
|
|
6197
|
+
return;
|
|
6198
|
+
}
|
|
6199
|
+
this.cleanup();
|
|
6200
|
+
const t = this.stateManager.getState().config, s = this._renderMonthView(e, t);
|
|
6201
|
+
this.container.innerHTML = s, this._attachEventHandlers();
|
|
6202
|
+
}
|
|
6203
|
+
_renderMonthView(e, t) {
|
|
6204
|
+
const s = t.weekStartsOn || 0;
|
|
6205
|
+
let r = `
|
|
6206
|
+
<div class="fc-month-view" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: #fff; border: 1px solid #e5e7eb;">
|
|
6207
|
+
<div class="fc-month-header" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb;">
|
|
6208
|
+
${this._getDayNames(s).map((n) => `<div class="fc-month-header-cell" style="padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: #6b7280; text-transform: uppercase;">${n}</div>`).join("")}
|
|
6209
|
+
</div>
|
|
6210
|
+
<div class="fc-month-body" style="display: flex; flex-direction: column; flex: 1;">
|
|
6211
|
+
`;
|
|
6212
|
+
return e.weeks.forEach((n) => {
|
|
6213
|
+
r += this._renderWeek(n);
|
|
6214
|
+
}), r += "</div></div>", r;
|
|
6215
|
+
}
|
|
6216
|
+
_getDayNames(e) {
|
|
6217
|
+
const t = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], s = [];
|
|
6218
|
+
for (let i = 0; i < 7; i++) {
|
|
6219
|
+
const r = (e + i) % 7;
|
|
6220
|
+
s.push(t[r]);
|
|
6221
|
+
}
|
|
6222
|
+
return s;
|
|
6223
|
+
}
|
|
6224
|
+
_renderWeek(e) {
|
|
6225
|
+
let t = '<div class="fc-month-week" style="display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;">';
|
|
6226
|
+
return e.days.forEach((s) => {
|
|
6227
|
+
t += this._renderDay(s);
|
|
6228
|
+
}), t += "</div>", t;
|
|
6229
|
+
}
|
|
6230
|
+
_renderDay(e) {
|
|
6231
|
+
const t = !e.isCurrentMonth, s = e.isToday, i = t ? "#f3f4f6" : "#fff", r = t ? "#9ca3af" : "#111827", n = s ? "background: #2563eb; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;" : "", a = e.events || [], o = a.slice(0, this.maxEventsToShow), c = a.length - this.maxEventsToShow;
|
|
6232
|
+
return `
|
|
6233
|
+
<div class="fc-month-day" data-date="${e.date}"
|
|
6234
|
+
style="background: ${i}; border-right: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb; padding: 4px; min-height: 80px; cursor: pointer; display: flex; flex-direction: column;">
|
|
6235
|
+
<div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${r}; padding: 2px 4px; margin-bottom: 4px; ${n}">
|
|
6236
|
+
${e.dayOfMonth}
|
|
6237
|
+
</div>
|
|
6238
|
+
<div class="fc-day-events" style="display: flex; flex-direction: column; gap: 2px; flex: 1; overflow: hidden;">
|
|
6239
|
+
${o.map((l) => this._renderEvent(l)).join("")}
|
|
6240
|
+
${c > 0 ? `<div class="fc-more-events" style="font-size: 10px; color: #6b7280; padding: 2px 4px; font-weight: 500;">+${c} more</div>` : ""}
|
|
6241
|
+
</div>
|
|
6242
|
+
</div>
|
|
6243
|
+
`;
|
|
6244
|
+
}
|
|
6245
|
+
_renderEvent(e) {
|
|
6246
|
+
const t = e.backgroundColor || "#2563eb";
|
|
6247
|
+
return `
|
|
6248
|
+
<div class="fc-event" data-event-id="${this.escapeHTML(e.id)}"
|
|
6249
|
+
style="background-color: ${t}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
|
|
6250
|
+
${this.escapeHTML(e.title)}
|
|
6251
|
+
</div>
|
|
6252
|
+
`;
|
|
6253
|
+
}
|
|
6254
|
+
_attachEventHandlers() {
|
|
6255
|
+
this.container.querySelectorAll(".fc-month-day").forEach((e) => {
|
|
6256
|
+
this.addListener(e, "click", (t) => {
|
|
6257
|
+
if (t.target.closest(".fc-event")) return;
|
|
6258
|
+
const s = new Date(e.dataset.date);
|
|
6259
|
+
this.stateManager.selectDate(s);
|
|
6260
|
+
});
|
|
6261
|
+
}), this.attachCommonEventHandlers();
|
|
6262
|
+
}
|
|
6263
|
+
}
|
|
6264
|
+
class H extends O {
|
|
6265
|
+
constructor(e, t) {
|
|
6266
|
+
super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
|
|
6267
|
+
}
|
|
6268
|
+
render() {
|
|
6269
|
+
if (!this.container || !this.stateManager) return;
|
|
6270
|
+
const e = this.stateManager.getViewData();
|
|
6271
|
+
if (!e || !e.days || e.days.length === 0) {
|
|
6272
|
+
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No data available for week view.</div>';
|
|
6273
|
+
return;
|
|
6274
|
+
}
|
|
6275
|
+
this.cleanup();
|
|
6276
|
+
const t = this.stateManager.getState().config, s = this._renderWeekView(e, t);
|
|
6277
|
+
this.container.innerHTML = s, this._attachEventHandlers(), this._scrollToCurrentTime();
|
|
6278
|
+
}
|
|
6279
|
+
_renderWeekView(e, t) {
|
|
6280
|
+
const s = e.days, i = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], r = Array.from({ length: 24 }, (a, o) => o), n = s.map((a) => {
|
|
6281
|
+
const o = new Date(a.date), c = a.events || [];
|
|
6282
|
+
return {
|
|
6283
|
+
...a,
|
|
6284
|
+
date: o,
|
|
6285
|
+
dayName: i[o.getDay()],
|
|
6286
|
+
dayOfMonth: o.getDate(),
|
|
6287
|
+
isToday: this.isToday(o),
|
|
6288
|
+
timedEvents: c.filter((l) => !l.allDay),
|
|
6289
|
+
allDayEvents: c.filter((l) => l.allDay)
|
|
6290
|
+
};
|
|
6291
|
+
});
|
|
6292
|
+
return `
|
|
6293
|
+
<div class="fc-week-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
|
|
6294
|
+
${this._renderHeader(n)}
|
|
6295
|
+
${this._renderAllDayRow(n)}
|
|
6296
|
+
${this._renderTimeGrid(n, r)}
|
|
6297
|
+
</div>
|
|
6298
|
+
`;
|
|
6299
|
+
}
|
|
6300
|
+
_renderHeader(e) {
|
|
6301
|
+
return `
|
|
6302
|
+
<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;">
|
|
6303
|
+
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
6304
|
+
${e.map((t) => `
|
|
6305
|
+
<div style="padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;">
|
|
6306
|
+
<div style="font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">
|
|
6307
|
+
${t.dayName}
|
|
6308
|
+
</div>
|
|
6309
|
+
<div style="font-size: 16px; font-weight: 500; margin-top: 4px; ${t.isToday ? "background: #dc2626; color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;" : "color: #111827;"}">
|
|
6310
|
+
${t.dayOfMonth}
|
|
6311
|
+
</div>
|
|
6312
|
+
</div>
|
|
6313
|
+
`).join("")}
|
|
6314
|
+
</div>
|
|
6315
|
+
`;
|
|
6316
|
+
}
|
|
6317
|
+
_renderAllDayRow(e) {
|
|
6318
|
+
return `
|
|
6319
|
+
<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;">
|
|
6320
|
+
<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;">
|
|
6321
|
+
All day
|
|
6322
|
+
</div>
|
|
6323
|
+
${e.map((t) => `
|
|
6324
|
+
<div class="fc-all-day-cell" data-date="${t.date.toISOString()}" style="border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;">
|
|
6325
|
+
${t.allDayEvents.map((s) => `
|
|
6326
|
+
<div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(s.id)}"
|
|
6327
|
+
style="background-color: ${s.backgroundColor || "#2563eb"}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
|
6328
|
+
${this.escapeHTML(s.title)}
|
|
6329
|
+
</div>
|
|
6330
|
+
`).join("")}
|
|
6331
|
+
</div>
|
|
6332
|
+
`).join("")}
|
|
6333
|
+
</div>
|
|
6334
|
+
`;
|
|
6335
|
+
}
|
|
6336
|
+
_renderTimeGrid(e, t) {
|
|
6337
|
+
return `
|
|
6338
|
+
<div id="week-scroll-container" class="fc-time-grid-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
6339
|
+
<div class="fc-time-grid" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: ${this.totalHeight}px;">
|
|
6340
|
+
${this._renderTimeGutter(t)}
|
|
6341
|
+
${e.map((s) => this._renderDayColumn(s, t)).join("")}
|
|
6342
|
+
</div>
|
|
6343
|
+
</div>
|
|
6344
|
+
`;
|
|
6345
|
+
}
|
|
6346
|
+
_renderTimeGutter(e) {
|
|
6347
|
+
return `
|
|
6348
|
+
<div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
6349
|
+
${e.map((t) => `
|
|
6350
|
+
<div style="height: ${this.hourHeight}px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;">
|
|
6351
|
+
${t === 0 ? "" : this.formatHour(t)}
|
|
6352
|
+
</div>
|
|
6353
|
+
`).join("")}
|
|
6354
|
+
</div>
|
|
6355
|
+
`;
|
|
6356
|
+
}
|
|
6357
|
+
_renderDayColumn(e, t) {
|
|
6358
|
+
return `
|
|
6359
|
+
<div class="fc-week-day-column" data-date="${e.date.toISOString()}" style="border-right: 1px solid #e5e7eb; position: relative; cursor: pointer;">
|
|
6360
|
+
<!-- Hour grid lines -->
|
|
6361
|
+
${t.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid #f3f4f6;"></div>`).join("")}
|
|
6362
|
+
|
|
6363
|
+
<!-- Now indicator for today -->
|
|
6364
|
+
${e.isToday ? this.renderNowIndicator() : ""}
|
|
6365
|
+
|
|
6366
|
+
<!-- Timed events -->
|
|
6367
|
+
${e.timedEvents.map((s) => this.renderTimedEvent(s, { compact: !0 })).join("")}
|
|
6368
|
+
</div>
|
|
6369
|
+
`;
|
|
6370
|
+
}
|
|
6371
|
+
_attachEventHandlers() {
|
|
6372
|
+
this.container.querySelectorAll(".fc-week-day-column").forEach((e) => {
|
|
6373
|
+
this.addListener(e, "click", (t) => {
|
|
6374
|
+
if (t.target.closest(".fc-event")) return;
|
|
6375
|
+
const s = new Date(e.dataset.date), i = e.getBoundingClientRect(), r = this.container.querySelector("#week-scroll-container"), n = t.clientY - i.top + (r ? r.scrollTop : 0);
|
|
6376
|
+
s.setHours(Math.floor(n / this.hourHeight), Math.floor(n % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(s);
|
|
6377
|
+
});
|
|
6378
|
+
}), this.attachCommonEventHandlers();
|
|
6379
|
+
}
|
|
6380
|
+
_scrollToCurrentTime() {
|
|
6381
|
+
if (this._scrolled) return;
|
|
6382
|
+
const e = this.container.querySelector("#week-scroll-container");
|
|
6383
|
+
e && (e.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
|
|
6384
|
+
}
|
|
6385
|
+
}
|
|
6386
|
+
class F extends O {
|
|
6387
|
+
constructor(e, t) {
|
|
6388
|
+
super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
|
|
6389
|
+
}
|
|
6390
|
+
render() {
|
|
6391
|
+
if (!this.container || !this.stateManager) return;
|
|
6392
|
+
const e = this.stateManager.getViewData();
|
|
6393
|
+
if (!e) {
|
|
6394
|
+
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No data available for day view.</div>';
|
|
6395
|
+
return;
|
|
6396
|
+
}
|
|
6397
|
+
this.cleanup();
|
|
6398
|
+
const t = this.stateManager.getState().config, s = this._renderDayView(e, t);
|
|
6399
|
+
this.container.innerHTML = s, this._attachEventHandlers(), this._scrollToCurrentTime();
|
|
6400
|
+
}
|
|
6401
|
+
_renderDayView(e, t) {
|
|
6402
|
+
var d, h;
|
|
6403
|
+
const s = ((h = (d = this.stateManager) == null ? void 0 : d.getState()) == null ? void 0 : h.currentDate) || /* @__PURE__ */ new Date(), i = this._extractDayData(e, s);
|
|
6404
|
+
if (!i)
|
|
6405
|
+
return '<div style="padding: 20px; text-align: center; color: #666;">No data available for day view.</div>';
|
|
6406
|
+
const { dayDate: r, dayName: n, isToday: a, allDayEvents: o, timedEvents: c } = i, l = Array.from({ length: 24 }, (m, b) => b);
|
|
6407
|
+
return `
|
|
6408
|
+
<div class="fc-day-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
|
|
6409
|
+
${this._renderHeader(r, n, a)}
|
|
6410
|
+
${this._renderAllDayRow(o, r)}
|
|
6411
|
+
${this._renderTimeGrid(c, a, r, l)}
|
|
6412
|
+
</div>
|
|
6413
|
+
`;
|
|
6414
|
+
}
|
|
6415
|
+
_extractDayData(e, t) {
|
|
6416
|
+
let s, i, r, n, a;
|
|
6417
|
+
const o = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
6418
|
+
if (e.type === "day" && e.date)
|
|
6419
|
+
if (s = new Date(e.date), i = e.dayName || o[s.getDay()], r = e.isToday !== void 0 ? e.isToday : this.isToday(s), n = e.allDayEvents || [], e.hours && Array.isArray(e.hours)) {
|
|
6420
|
+
const c = /* @__PURE__ */ new Map();
|
|
6421
|
+
e.hours.forEach((l) => {
|
|
6422
|
+
(l.events || []).forEach((d) => {
|
|
6423
|
+
c.has(d.id) || c.set(d.id, d);
|
|
6424
|
+
});
|
|
6425
|
+
}), a = Array.from(c.values());
|
|
6426
|
+
} else
|
|
6427
|
+
a = [];
|
|
6428
|
+
else if (e.days && e.days.length > 0) {
|
|
6429
|
+
const c = e.days.find((d) => this.isSameDay(new Date(d.date), t)) || e.days[0];
|
|
6430
|
+
s = new Date(c.date), i = o[s.getDay()], r = this.isToday(s);
|
|
6431
|
+
const l = c.events || [];
|
|
6432
|
+
n = l.filter((d) => d.allDay), a = l.filter((d) => !d.allDay);
|
|
6433
|
+
} else
|
|
6434
|
+
return null;
|
|
6435
|
+
return { dayDate: s, dayName: i, isToday: r, allDayEvents: n, timedEvents: a };
|
|
6436
|
+
}
|
|
6437
|
+
_renderHeader(e, t, s) {
|
|
6438
|
+
return `
|
|
6439
|
+
<div class="fc-day-header" style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
|
|
6440
|
+
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
6441
|
+
<div style="padding: 16px 24px;">
|
|
6442
|
+
<div style="font-size: 12px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">
|
|
6443
|
+
${t}
|
|
6444
|
+
</div>
|
|
6445
|
+
<div style="font-size: 24px; font-weight: 600; margin-top: 4px; ${s ? "color: #dc2626;" : "color: #111827;"}">
|
|
6446
|
+
${e.getDate()}
|
|
6447
|
+
</div>
|
|
6448
|
+
</div>
|
|
6449
|
+
</div>
|
|
6450
|
+
`;
|
|
6451
|
+
}
|
|
6452
|
+
_renderAllDayRow(e, t) {
|
|
6453
|
+
return `
|
|
6454
|
+
<div class="fc-all-day-row" style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 36px; flex-shrink: 0;">
|
|
6455
|
+
<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;">
|
|
6456
|
+
All day
|
|
6457
|
+
</div>
|
|
6458
|
+
<div class="fc-all-day-cell" data-date="${t.toISOString()}" style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
|
|
6459
|
+
${e.map((s) => `
|
|
6460
|
+
<div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(s.id)}"
|
|
6461
|
+
style="background-color: ${s.backgroundColor || "#2563eb"}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
|
|
6462
|
+
${this.escapeHTML(s.title)}
|
|
6463
|
+
</div>
|
|
6464
|
+
`).join("")}
|
|
6465
|
+
</div>
|
|
6466
|
+
</div>
|
|
6467
|
+
`;
|
|
6468
|
+
}
|
|
6469
|
+
_renderTimeGrid(e, t, s, i) {
|
|
6470
|
+
return `
|
|
6471
|
+
<div id="day-scroll-container" class="fc-time-grid-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
6472
|
+
<div class="fc-time-grid" style="display: grid; grid-template-columns: 60px 1fr; position: relative; height: ${this.totalHeight}px;">
|
|
6473
|
+
${this._renderTimeGutter(i)}
|
|
6474
|
+
${this._renderDayColumn(e, t, s, i)}
|
|
6475
|
+
</div>
|
|
6476
|
+
</div>
|
|
6477
|
+
`;
|
|
6478
|
+
}
|
|
6479
|
+
_renderTimeGutter(e) {
|
|
6480
|
+
return `
|
|
6481
|
+
<div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
6482
|
+
${e.map((t) => `
|
|
6483
|
+
<div style="height: ${this.hourHeight}px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;">
|
|
6484
|
+
${t === 0 ? "" : this.formatHour(t)}
|
|
6485
|
+
</div>
|
|
6486
|
+
`).join("")}
|
|
6487
|
+
</div>
|
|
6488
|
+
`;
|
|
6489
|
+
}
|
|
6490
|
+
_renderDayColumn(e, t, s, i) {
|
|
6491
|
+
return `
|
|
6492
|
+
<div class="fc-day-column" data-date="${s.toISOString()}" style="position: relative; cursor: pointer;">
|
|
6493
|
+
<!-- Hour grid lines -->
|
|
6494
|
+
${i.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid #f3f4f6;"></div>`).join("")}
|
|
6495
|
+
|
|
6496
|
+
<!-- Now indicator for today -->
|
|
6497
|
+
${t ? this.renderNowIndicator() : ""}
|
|
6498
|
+
|
|
6499
|
+
<!-- Timed events -->
|
|
6500
|
+
${e.map((r) => this.renderTimedEvent(r, { compact: !1 })).join("")}
|
|
6501
|
+
</div>
|
|
6502
|
+
`;
|
|
6503
|
+
}
|
|
6504
|
+
_attachEventHandlers() {
|
|
6505
|
+
this.container.querySelectorAll(".fc-day-column").forEach((e) => {
|
|
6506
|
+
this.addListener(e, "click", (t) => {
|
|
6507
|
+
if (t.target.closest(".fc-event")) return;
|
|
6508
|
+
const s = new Date(e.dataset.date), i = e.getBoundingClientRect(), r = this.container.querySelector("#day-scroll-container"), n = t.clientY - i.top + (r ? r.scrollTop : 0);
|
|
6509
|
+
s.setHours(Math.floor(n / this.hourHeight), Math.floor(n % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(s);
|
|
6510
|
+
});
|
|
6511
|
+
}), this.attachCommonEventHandlers();
|
|
6512
|
+
}
|
|
6513
|
+
_scrollToCurrentTime() {
|
|
6514
|
+
if (this._scrolled) return;
|
|
6515
|
+
const e = this.container.querySelector("#day-scroll-container");
|
|
6516
|
+
e && (e.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
|
|
6517
|
+
}
|
|
6518
|
+
}
|
|
6519
|
+
class ie extends _ {
|
|
5989
6520
|
constructor() {
|
|
5990
6521
|
super(), this._stateManager = null, this.viewData = null, this.config = {
|
|
5991
6522
|
maxEventsToShow: 3
|
|
@@ -6330,7 +6861,7 @@ class X extends $ {
|
|
|
6330
6861
|
renderHeader() {
|
|
6331
6862
|
const { config: e } = this.stateManager.getState(), t = [], s = e.weekStartsOn || 0;
|
|
6332
6863
|
for (let i = 0; i < 7; i++) {
|
|
6333
|
-
const r = (s + i) % 7, n =
|
|
6864
|
+
const r = (s + i) % 7, n = v.getDayAbbreviation(r, e.locale);
|
|
6334
6865
|
t.push(`<div class="month-header-cell">${n}</div>`);
|
|
6335
6866
|
}
|
|
6336
6867
|
return `
|
|
@@ -6365,7 +6896,7 @@ class X extends $ {
|
|
|
6365
6896
|
renderDay(e) {
|
|
6366
6897
|
const { date: t, dayOfMonth: s, isOtherMonth: i, isToday: r, isSelected: n, isWeekend: a, events: o = [] } = e, c = s, l = ["month-day"];
|
|
6367
6898
|
i && l.push("other-month"), r && l.push("today"), n && l.push("selected"), a && l.push("weekend");
|
|
6368
|
-
const d = o.slice(0, this.config.maxEventsToShow), h = o.length - this.config.maxEventsToShow,
|
|
6899
|
+
const d = o.slice(0, this.config.maxEventsToShow), h = o.length - this.config.maxEventsToShow, m = d.map((x) => this.renderEvent(x)).join(""), b = h > 0 ? `<div class="more-events">+${h} more</div>` : "";
|
|
6369
6900
|
return `
|
|
6370
6901
|
<div class="${l.join(" ")}"
|
|
6371
6902
|
data-date="${t.toISOString()}"
|
|
@@ -6374,8 +6905,8 @@ class X extends $ {
|
|
|
6374
6905
|
<span class="day-number">${c}</span>
|
|
6375
6906
|
</div>
|
|
6376
6907
|
<div class="day-events">
|
|
6377
|
-
${
|
|
6378
|
-
${
|
|
6908
|
+
${m}
|
|
6909
|
+
${b}
|
|
6379
6910
|
</div>
|
|
6380
6911
|
</div>
|
|
6381
6912
|
`;
|
|
@@ -6384,19 +6915,19 @@ class X extends $ {
|
|
|
6384
6915
|
const { title: t, start: s, allDay: i, backgroundColor: r, textColor: n } = e;
|
|
6385
6916
|
let a = "";
|
|
6386
6917
|
if (r) {
|
|
6387
|
-
const l =
|
|
6918
|
+
const l = y.sanitizeColor(r), d = y.sanitizeColor(n, "white");
|
|
6388
6919
|
a += `background-color: ${l}; color: ${d};`;
|
|
6389
6920
|
}
|
|
6390
6921
|
let o = "";
|
|
6391
|
-
!i && s && (o =
|
|
6922
|
+
!i && s && (o = v.formatTime(new Date(s), !1, !1));
|
|
6392
6923
|
const c = ["event-item"];
|
|
6393
6924
|
return i && c.push("all-day"), `
|
|
6394
6925
|
<div class="${c.join(" ")}"
|
|
6395
6926
|
style="${a}"
|
|
6396
6927
|
data-event-id="${e.id}"
|
|
6397
|
-
title="${
|
|
6928
|
+
title="${T.escapeHTML(t)}">
|
|
6398
6929
|
${o ? `<span class="event-time">${o}</span>` : ""}
|
|
6399
|
-
<span class="event-title">${
|
|
6930
|
+
<span class="event-title">${T.escapeHTML(t)}</span>
|
|
6400
6931
|
</div>
|
|
6401
6932
|
`;
|
|
6402
6933
|
}
|
|
@@ -6428,7 +6959,7 @@ class X extends $ {
|
|
|
6428
6959
|
this.unsubscribe && this.unsubscribe();
|
|
6429
6960
|
}
|
|
6430
6961
|
}
|
|
6431
|
-
class
|
|
6962
|
+
class re extends _ {
|
|
6432
6963
|
constructor() {
|
|
6433
6964
|
super(), this._stateManager = null, this.viewData = null, this.hours = Array.from({ length: 24 }, (e, t) => t), this._registryCheckInterval = null;
|
|
6434
6965
|
}
|
|
@@ -6494,7 +7025,7 @@ class ee extends $ {
|
|
|
6494
7025
|
return {
|
|
6495
7026
|
...s,
|
|
6496
7027
|
date: i,
|
|
6497
|
-
isToday:
|
|
7028
|
+
isToday: v.isToday(i),
|
|
6498
7029
|
timedEvents: (s.events || []).filter((r) => !r.allDay),
|
|
6499
7030
|
allDayEvents: (s.events || []).filter((r) => r.allDay)
|
|
6500
7031
|
};
|
|
@@ -6691,7 +7222,7 @@ class ee extends $ {
|
|
|
6691
7222
|
<div class="time-gutter-header"></div>
|
|
6692
7223
|
${this.viewData.days.map((e) => `
|
|
6693
7224
|
<div class="day-column-header ${e.isToday ? "is-today" : ""}">
|
|
6694
|
-
<span class="day-name">${
|
|
7225
|
+
<span class="day-name">${v.getDayAbbreviation(e.date.getDay())}</span>
|
|
6695
7226
|
<span class="day-number">${e.date.getDate()}</span>
|
|
6696
7227
|
</div>
|
|
6697
7228
|
`).join("")}
|
|
@@ -6714,7 +7245,7 @@ class ee extends $ {
|
|
|
6714
7245
|
<div class="time-gutter">
|
|
6715
7246
|
${this.hours.map((e) => `
|
|
6716
7247
|
<div class="time-slot-label">
|
|
6717
|
-
${e === 0 ? "" :
|
|
7248
|
+
${e === 0 ? "" : v.formatTime((/* @__PURE__ */ new Date()).setHours(e, 0), !1)}
|
|
6718
7249
|
</div>
|
|
6719
7250
|
`).join("")}
|
|
6720
7251
|
</div>
|
|
@@ -6730,23 +7261,23 @@ class ee extends $ {
|
|
|
6730
7261
|
` : '<div class="week-view">Loading...</div>';
|
|
6731
7262
|
}
|
|
6732
7263
|
renderTimedEvent(e) {
|
|
6733
|
-
const t = new Date(e.start), s = new Date(e.end), i = t.getHours() * 60 + t.getMinutes(), r = (s - t) / (1e3 * 60), n = i, a = Math.max(r, 20), o =
|
|
7264
|
+
const t = new Date(e.start), s = new Date(e.end), i = t.getHours() * 60 + t.getMinutes(), r = (s - t) / (1e3 * 60), n = i, a = Math.max(r, 20), o = y.sanitizeColor(e.backgroundColor), c = y.sanitizeColor(y.getContrastColor(o), "white");
|
|
6734
7265
|
return `
|
|
6735
7266
|
<div class="event-container"
|
|
6736
7267
|
style="top: ${n}px; height: ${a}px; background-color: ${o}; color: ${c};"
|
|
6737
7268
|
data-event-id="${e.id}">
|
|
6738
|
-
<span class="event-title">${
|
|
6739
|
-
<span class="event-time">${
|
|
7269
|
+
<span class="event-title">${T.escapeHTML(e.title)}</span>
|
|
7270
|
+
<span class="event-time">${v.formatTime(t)}</span>
|
|
6740
7271
|
</div>
|
|
6741
7272
|
`;
|
|
6742
7273
|
}
|
|
6743
7274
|
renderAllDayEvent(e) {
|
|
6744
|
-
const t =
|
|
7275
|
+
const t = y.sanitizeColor(e.backgroundColor), s = y.sanitizeColor(y.getContrastColor(t), "white");
|
|
6745
7276
|
return `
|
|
6746
7277
|
<div class="event-item"
|
|
6747
7278
|
style="background-color: ${t}; color: ${s}; font-size: 10px; padding: 2px 4px; border-radius: 2px; cursor: pointer; margin-bottom: 2px;"
|
|
6748
7279
|
data-event-id="${e.id}">
|
|
6749
|
-
${
|
|
7280
|
+
${T.escapeHTML(e.title)}
|
|
6750
7281
|
</div>
|
|
6751
7282
|
`;
|
|
6752
7283
|
}
|
|
@@ -6773,7 +7304,7 @@ class ee extends $ {
|
|
|
6773
7304
|
this.unsubscribe && this.unsubscribe();
|
|
6774
7305
|
}
|
|
6775
7306
|
}
|
|
6776
|
-
class
|
|
7307
|
+
class ne extends _ {
|
|
6777
7308
|
constructor() {
|
|
6778
7309
|
super(), this._stateManager = null, this.viewData = null, this.hours = Array.from({ length: 24 }, (e, t) => t), this._registryCheckInterval = null;
|
|
6779
7310
|
}
|
|
@@ -6817,7 +7348,7 @@ class te extends $ {
|
|
|
6817
7348
|
updateSelection(e, t) {
|
|
6818
7349
|
const s = this.shadowRoot.querySelector(".day-column");
|
|
6819
7350
|
if (!s) return;
|
|
6820
|
-
((r) => r &&
|
|
7351
|
+
((r) => r && v.isSameDay(r, new Date(s.dataset.date)))(e) ? s.classList.add("selected") : s.classList.remove("selected");
|
|
6821
7352
|
}
|
|
6822
7353
|
loadViewData() {
|
|
6823
7354
|
if (!this.stateManager) return;
|
|
@@ -6830,10 +7361,10 @@ class te extends $ {
|
|
|
6830
7361
|
let t = null;
|
|
6831
7362
|
const s = (n = this.stateManager) == null ? void 0 : n.getState(), i = (s == null ? void 0 : s.currentDate) || /* @__PURE__ */ new Date();
|
|
6832
7363
|
if (e.days && Array.isArray(e.days) && e.days.length > 0)
|
|
6833
|
-
t = e.days.find((a) =>
|
|
7364
|
+
t = e.days.find((a) => v.isSameDay(new Date(a.date), i)) || e.days[0];
|
|
6834
7365
|
else if (e.weeks && Array.isArray(e.weeks) && e.weeks.length > 0) {
|
|
6835
7366
|
const a = e.weeks.flatMap((o) => o.days || []);
|
|
6836
|
-
t = a.find((o) =>
|
|
7367
|
+
t = a.find((o) => v.isSameDay(new Date(o.date), i)) || a[0];
|
|
6837
7368
|
} else e.date && (t = e);
|
|
6838
7369
|
if (!t) return null;
|
|
6839
7370
|
const r = new Date(t.date);
|
|
@@ -6842,7 +7373,7 @@ class te extends $ {
|
|
|
6842
7373
|
day: {
|
|
6843
7374
|
...t,
|
|
6844
7375
|
date: r,
|
|
6845
|
-
isToday:
|
|
7376
|
+
isToday: v.isToday(r),
|
|
6846
7377
|
timedEvents: (t.events || []).filter((a) => !a.allDay),
|
|
6847
7378
|
allDayEvents: (t.events || []).filter((a) => a.allDay)
|
|
6848
7379
|
}
|
|
@@ -7020,7 +7551,7 @@ class te extends $ {
|
|
|
7020
7551
|
var i, r, n;
|
|
7021
7552
|
if (!this.viewData || !this.viewData.day)
|
|
7022
7553
|
return '<div class="day-view" style="padding: 20px; color: var(--fc-text-light);">No data available.</div>';
|
|
7023
|
-
const { day: e } = this.viewData, t = ((n = (r = (i = this.stateManager) == null ? void 0 : i.state) == null ? void 0 : r.config) == null ? void 0 : n.locale) || "en-US", s =
|
|
7554
|
+
const { day: e } = this.viewData, t = ((n = (r = (i = this.stateManager) == null ? void 0 : i.state) == null ? void 0 : r.config) == null ? void 0 : n.locale) || "en-US", s = v.formatDate(e.date, "day", t).split(" ")[0];
|
|
7024
7555
|
return `
|
|
7025
7556
|
<div class="day-view">
|
|
7026
7557
|
<div class="day-header">
|
|
@@ -7046,7 +7577,7 @@ class te extends $ {
|
|
|
7046
7577
|
<div class="time-gutter">
|
|
7047
7578
|
${this.hours.map((a) => `
|
|
7048
7579
|
<div class="time-slot-label">
|
|
7049
|
-
${a === 0 ? "" :
|
|
7580
|
+
${a === 0 ? "" : v.formatTime((/* @__PURE__ */ new Date()).setHours(a, 0), !1)}
|
|
7050
7581
|
</div>
|
|
7051
7582
|
`).join("")}
|
|
7052
7583
|
</div>
|
|
@@ -7060,23 +7591,23 @@ class te extends $ {
|
|
|
7060
7591
|
`;
|
|
7061
7592
|
}
|
|
7062
7593
|
renderTimedEvent(e) {
|
|
7063
|
-
const t = new Date(e.start), s = new Date(e.end), i = t.getHours() * 60 + t.getMinutes(), r = (s - t) / (1e3 * 60), n = i, a = Math.max(r, 30), o =
|
|
7594
|
+
const t = new Date(e.start), s = new Date(e.end), i = t.getHours() * 60 + t.getMinutes(), r = (s - t) / (1e3 * 60), n = i, a = Math.max(r, 30), o = y.sanitizeColor(e.backgroundColor), c = y.sanitizeColor(y.getContrastColor(o), "white");
|
|
7064
7595
|
return `
|
|
7065
7596
|
<div class="event-container"
|
|
7066
7597
|
style="top: ${n}px; height: ${a}px; background-color: ${o}; color: ${c};"
|
|
7067
7598
|
data-event-id="${e.id}">
|
|
7068
|
-
<span class="event-title">${
|
|
7069
|
-
<span class="event-time">${
|
|
7599
|
+
<span class="event-title">${T.escapeHTML(e.title)}</span>
|
|
7600
|
+
<span class="event-time">${v.formatTime(t)} - ${v.formatTime(s)}</span>
|
|
7070
7601
|
</div>
|
|
7071
7602
|
`;
|
|
7072
7603
|
}
|
|
7073
7604
|
renderAllDayEvent(e) {
|
|
7074
|
-
const t =
|
|
7605
|
+
const t = y.sanitizeColor(e.backgroundColor), s = y.sanitizeColor(y.getContrastColor(t), "white");
|
|
7075
7606
|
return `
|
|
7076
7607
|
<div class="event-item"
|
|
7077
7608
|
style="background-color: ${t}; color: ${s}; font-size: 12px; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-weight: 500; margin-bottom: 2px;"
|
|
7078
7609
|
data-event-id="${e.id}">
|
|
7079
|
-
${
|
|
7610
|
+
${T.escapeHTML(e.title)}
|
|
7080
7611
|
</div>
|
|
7081
7612
|
`;
|
|
7082
7613
|
}
|
|
@@ -7103,7 +7634,7 @@ class te extends $ {
|
|
|
7103
7634
|
this.unsubscribe && this.unsubscribe();
|
|
7104
7635
|
}
|
|
7105
7636
|
}
|
|
7106
|
-
class
|
|
7637
|
+
class ae extends _ {
|
|
7107
7638
|
constructor() {
|
|
7108
7639
|
super(), this._isVisible = !1, this._cleanupFocusTrap = null, this.config = {
|
|
7109
7640
|
title: "New Event",
|
|
@@ -7133,8 +7664,8 @@ class se extends $ {
|
|
|
7133
7664
|
}
|
|
7134
7665
|
getStyles() {
|
|
7135
7666
|
return `
|
|
7136
|
-
${
|
|
7137
|
-
${
|
|
7667
|
+
${y.getBaseStyles()}
|
|
7668
|
+
${y.getButtonStyles()}
|
|
7138
7669
|
|
|
7139
7670
|
:host {
|
|
7140
7671
|
display: none;
|
|
@@ -7366,9 +7897,9 @@ class se extends $ {
|
|
|
7366
7897
|
});
|
|
7367
7898
|
}), this.addListener(this, "click", (e) => {
|
|
7368
7899
|
e.target === this && this.close();
|
|
7369
|
-
}), this.
|
|
7900
|
+
}), this._keydownListenerAdded || (this._handleKeyDown = (e) => {
|
|
7370
7901
|
e.key === "Escape" && this.hasAttribute("open") && this.close();
|
|
7371
|
-
}, window.addEventListener("keydown", this._handleKeyDown);
|
|
7902
|
+
}, window.addEventListener("keydown", this._handleKeyDown), this._keydownListenerAdded = !0);
|
|
7372
7903
|
}
|
|
7373
7904
|
updateColorSelection() {
|
|
7374
7905
|
this.colorContainer.querySelectorAll(".color-btn").forEach((t) => {
|
|
@@ -7377,7 +7908,7 @@ class se extends $ {
|
|
|
7377
7908
|
});
|
|
7378
7909
|
}
|
|
7379
7910
|
open(e = /* @__PURE__ */ new Date()) {
|
|
7380
|
-
this.hasAttribute("open") || this.setAttribute("open", ""), this.titleGroup.classList.remove("has-error"), this.endGroup.classList.remove("has-error"), this._formData.start = e, this._formData.end = new Date(e.getTime() + this.config.defaultDuration * 60 * 1e3), this._formData.title = "", this._formData.color = this.config.colors[0].color, this.startInput && (this.titleInput.value = "", this.startInput.value = this.formatDateForInput(this._formData.start), this.endInput.value = this.formatDateForInput(this._formData.end), this.updateColorSelection(), this._cleanupFocusTrap =
|
|
7911
|
+
this.hasAttribute("open") || this.setAttribute("open", ""), this.titleGroup.classList.remove("has-error"), this.endGroup.classList.remove("has-error"), this._formData.start = e, this._formData.end = new Date(e.getTime() + this.config.defaultDuration * 60 * 1e3), this._formData.title = "", this._formData.color = this.config.colors[0].color, this.startInput && (this.titleInput.value = "", this.startInput.value = this.formatDateForInput(this._formData.start), this.endInput.value = this.formatDateForInput(this._formData.end), this.updateColorSelection(), this._cleanupFocusTrap = T.trapFocus(this.modalContent));
|
|
7381
7912
|
}
|
|
7382
7913
|
close() {
|
|
7383
7914
|
this.removeAttribute("open"), this._cleanupFocusTrap && (this._cleanupFocusTrap(), this._cleanupFocusTrap = null);
|
|
@@ -7403,14 +7934,14 @@ class se extends $ {
|
|
|
7403
7934
|
return `${s}-${i}-${r}T${n}:${a}`;
|
|
7404
7935
|
}
|
|
7405
7936
|
unmount() {
|
|
7406
|
-
this._cleanupFocusTrap && this._cleanupFocusTrap(), window.removeEventListener("keydown", this._handleKeyDown);
|
|
7937
|
+
this._cleanupFocusTrap && this._cleanupFocusTrap(), this._handleKeyDown && (window.removeEventListener("keydown", this._handleKeyDown), this._handleKeyDown = null, this._keydownListenerAdded = !1);
|
|
7407
7938
|
}
|
|
7408
7939
|
}
|
|
7409
|
-
customElements.get("forcecal-event-form") || customElements.define("forcecal-event-form",
|
|
7410
|
-
customElements.get("forcecal-month") || customElements.define("forcecal-month",
|
|
7411
|
-
customElements.get("forcecal-week") || customElements.define("forcecal-week",
|
|
7412
|
-
customElements.get("forcecal-day") || customElements.define("forcecal-day",
|
|
7413
|
-
class
|
|
7940
|
+
customElements.get("forcecal-event-form") || customElements.define("forcecal-event-form", ae);
|
|
7941
|
+
customElements.get("forcecal-month") || customElements.define("forcecal-month", ie);
|
|
7942
|
+
customElements.get("forcecal-week") || customElements.define("forcecal-week", re);
|
|
7943
|
+
customElements.get("forcecal-day") || customElements.define("forcecal-day", ne);
|
|
7944
|
+
class oe extends _ {
|
|
7414
7945
|
static get observedAttributes() {
|
|
7415
7946
|
return ["view", "date", "locale", "timezone", "week-starts-on", "height"];
|
|
7416
7947
|
}
|
|
@@ -7425,16 +7956,16 @@ class ie extends $ {
|
|
|
7425
7956
|
timeZone: this.getAttribute("timezone") || Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
7426
7957
|
weekStartsOn: parseInt(this.getAttribute("week-starts-on") || "0")
|
|
7427
7958
|
};
|
|
7428
|
-
this.stateManager = new
|
|
7959
|
+
this.stateManager = new se(e), this.stateManager.subscribe(this.handleStateChange.bind(this)), this.setupEventListeners();
|
|
7429
7960
|
}
|
|
7430
7961
|
setupEventListeners() {
|
|
7431
|
-
|
|
7962
|
+
p.on("navigation:*", (e, t) => {
|
|
7432
7963
|
this.emit("calendar-navigate", { action: t.split(":")[1], ...e });
|
|
7433
|
-
}),
|
|
7964
|
+
}), p.on("view:changed", (e) => {
|
|
7434
7965
|
this.emit("calendar-view-change", e);
|
|
7435
|
-
}),
|
|
7966
|
+
}), p.on("event:*", (e, t) => {
|
|
7436
7967
|
this.emit(`calendar-event-${t.split(":")[1]}`, e);
|
|
7437
|
-
}),
|
|
7968
|
+
}), p.on("date:selected", (e) => {
|
|
7438
7969
|
this.emit("calendar-date-select", e);
|
|
7439
7970
|
});
|
|
7440
7971
|
}
|
|
@@ -7477,8 +8008,12 @@ class ie extends $ {
|
|
|
7477
8008
|
if (e) {
|
|
7478
8009
|
this._currentViewInstance && this._currentViewInstance.cleanup && this._currentViewInstance.cleanup();
|
|
7479
8010
|
try {
|
|
7480
|
-
const
|
|
7481
|
-
|
|
8011
|
+
const s = {
|
|
8012
|
+
month: E,
|
|
8013
|
+
week: H,
|
|
8014
|
+
day: F
|
|
8015
|
+
}[this.currentView] || E, i = new s(e, this.stateManager);
|
|
8016
|
+
i._viewType = this.currentView, this._currentViewInstance = i, i.render();
|
|
7482
8017
|
} catch (t) {
|
|
7483
8018
|
console.error("[ForceCalendar] Error switching view:", t);
|
|
7484
8019
|
}
|
|
@@ -7499,10 +8034,10 @@ class ie extends $ {
|
|
|
7499
8034
|
getStyles() {
|
|
7500
8035
|
const e = this.getAttribute("height") || "800px";
|
|
7501
8036
|
return `
|
|
7502
|
-
${
|
|
7503
|
-
${
|
|
7504
|
-
${
|
|
7505
|
-
${
|
|
8037
|
+
${y.getBaseStyles()}
|
|
8038
|
+
${y.getButtonStyles()}
|
|
8039
|
+
${y.getGridStyles()}
|
|
8040
|
+
${y.getAnimations()}
|
|
7506
8041
|
|
|
7507
8042
|
:host {
|
|
7508
8043
|
--calendar-height: ${e};
|
|
@@ -7891,7 +8426,7 @@ class ie extends $ {
|
|
|
7891
8426
|
return `
|
|
7892
8427
|
<div class="force-calendar">
|
|
7893
8428
|
<div class="fc-error">
|
|
7894
|
-
<p><strong>Error:</strong> ${
|
|
8429
|
+
<p><strong>Error:</strong> ${T.escapeHTML(r.message || "An error occurred")}</p>
|
|
7895
8430
|
</div>
|
|
7896
8431
|
</div>
|
|
7897
8432
|
`;
|
|
@@ -7957,8 +8492,12 @@ class ie extends $ {
|
|
|
7957
8492
|
return;
|
|
7958
8493
|
this._currentViewInstance && (this._currentViewInstance.cleanup && this._currentViewInstance.cleanup(), this._viewUnsubscribe && (this._viewUnsubscribe(), this._viewUnsubscribe = null));
|
|
7959
8494
|
try {
|
|
7960
|
-
const
|
|
7961
|
-
|
|
8495
|
+
const r = {
|
|
8496
|
+
month: E,
|
|
8497
|
+
week: H,
|
|
8498
|
+
day: F
|
|
8499
|
+
}[this.currentView] || E, n = new r(e, this.stateManager);
|
|
8500
|
+
n._viewType = this.currentView, this._currentViewInstance = n, n.render();
|
|
7962
8501
|
} catch (i) {
|
|
7963
8502
|
console.error("[ForceCalendar] Error creating/rendering view:", i);
|
|
7964
8503
|
}
|
|
@@ -7981,307 +8520,19 @@ class ie extends $ {
|
|
|
7981
8520
|
});
|
|
7982
8521
|
}), this._hasRendered = !0;
|
|
7983
8522
|
}
|
|
8523
|
+
/**
|
|
8524
|
+
* Create a view renderer instance for the given view type
|
|
8525
|
+
* Uses pure JavaScript renderer classes for Salesforce Locker Service compatibility
|
|
8526
|
+
* @param {string} viewName - 'month', 'week', or 'day'
|
|
8527
|
+
* @returns {BaseViewRenderer} Renderer instance
|
|
8528
|
+
*/
|
|
7984
8529
|
_createViewRenderer(e) {
|
|
7985
|
-
const
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
_escapeHTML(s) {
|
|
7992
|
-
return s == null ? "" : C.escapeHTML(String(s));
|
|
7993
|
-
},
|
|
7994
|
-
cleanup() {
|
|
7995
|
-
this._listeners.forEach(({ element: s, event: i, handler: r }) => {
|
|
7996
|
-
s.removeEventListener(i, r);
|
|
7997
|
-
}), this._listeners = [];
|
|
7998
|
-
},
|
|
7999
|
-
addListener(s, i, r) {
|
|
8000
|
-
s.addEventListener(i, r), this._listeners.push({ element: s, event: i, handler: r });
|
|
8001
|
-
},
|
|
8002
|
-
render() {
|
|
8003
|
-
if (!this.container || !this.stateManager) return;
|
|
8004
|
-
const s = this.stateManager.getViewData();
|
|
8005
|
-
if (!s) {
|
|
8006
|
-
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">Loading...</div>';
|
|
8007
|
-
return;
|
|
8008
|
-
}
|
|
8009
|
-
this.cleanup();
|
|
8010
|
-
const i = this.stateManager.getState().config;
|
|
8011
|
-
let r = "";
|
|
8012
|
-
switch (t) {
|
|
8013
|
-
case "week":
|
|
8014
|
-
r = this._renderWeekView(s, i);
|
|
8015
|
-
break;
|
|
8016
|
-
case "day":
|
|
8017
|
-
r = this._renderDayView(s, i);
|
|
8018
|
-
break;
|
|
8019
|
-
case "month":
|
|
8020
|
-
default:
|
|
8021
|
-
if (!s.weeks) {
|
|
8022
|
-
this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No data available for month view.</div>';
|
|
8023
|
-
return;
|
|
8024
|
-
}
|
|
8025
|
-
r = this._renderMonthView(s, i);
|
|
8026
|
-
break;
|
|
8027
|
-
}
|
|
8028
|
-
this.container.innerHTML = r, this._attachEventHandlers(t);
|
|
8029
|
-
},
|
|
8030
|
-
_renderMonthView(s, i) {
|
|
8031
|
-
const r = i.weekStartsOn || 0, n = [];
|
|
8032
|
-
for (let o = 0; o < 7; o++) {
|
|
8033
|
-
const c = (r + o) % 7;
|
|
8034
|
-
n.push(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][c]);
|
|
8035
|
-
}
|
|
8036
|
-
let a = `
|
|
8037
|
-
<div class="fc-month-view" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: #fff; border: 1px solid #e5e7eb;">
|
|
8038
|
-
<div class="fc-month-header" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb;">
|
|
8039
|
-
${n.map((o) => `<div class="fc-month-header-cell" style="padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: #6b7280; text-transform: uppercase;">${o}</div>`).join("")}
|
|
8040
|
-
</div>
|
|
8041
|
-
<div class="fc-month-body" style="display: flex; flex-direction: column; flex: 1;">
|
|
8042
|
-
`;
|
|
8043
|
-
return s.weeks.forEach((o) => {
|
|
8044
|
-
a += '<div class="fc-month-week" style="display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;">', o.days.forEach((c) => {
|
|
8045
|
-
const l = !c.isCurrentMonth, d = c.isToday, h = l ? "#f3f4f6" : "#fff", g = l ? "#9ca3af" : "#111827", w = d ? "background: #2563eb; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;" : "", f = c.events || [], k = f.slice(0, 3), b = f.length - 3;
|
|
8046
|
-
a += `
|
|
8047
|
-
<div class="fc-month-day" data-date="${c.date}" style="background: ${h}; border-right: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb; padding: 4px; min-height: 80px; cursor: pointer;">
|
|
8048
|
-
<div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${g}; padding: 2px 4px; margin-bottom: 4px; ${w}">${c.dayOfMonth}</div>
|
|
8049
|
-
<div class="fc-day-events" style="display: flex; flex-direction: column; gap: 2px;">
|
|
8050
|
-
${k.map((T) => `
|
|
8051
|
-
<div class="fc-event" data-event-id="${this._escapeHTML(T.id)}" style="background-color: ${T.backgroundColor || "#2563eb"}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
|
|
8052
|
-
${this._escapeHTML(T.title)}
|
|
8053
|
-
</div>
|
|
8054
|
-
`).join("")}
|
|
8055
|
-
${b > 0 ? `<div class="fc-more-events" style="font-size: 10px; color: #6b7280; padding: 2px 4px; font-weight: 500;">+${b} more</div>` : ""}
|
|
8056
|
-
</div>
|
|
8057
|
-
</div>
|
|
8058
|
-
`;
|
|
8059
|
-
}), a += "</div>";
|
|
8060
|
-
}), a += "</div></div>", a;
|
|
8061
|
-
},
|
|
8062
|
-
_renderWeekView(s, i) {
|
|
8063
|
-
const r = s.days || [];
|
|
8064
|
-
if (r.length === 0)
|
|
8065
|
-
return '<div style="padding: 20px; text-align: center; color: #666;">No data available for week view.</div>';
|
|
8066
|
-
i.weekStartsOn;
|
|
8067
|
-
const n = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], a = Array.from({ length: 24 }, (l, d) => d), o = r.map((l) => {
|
|
8068
|
-
const d = new Date(l.date), h = l.events || [];
|
|
8069
|
-
return {
|
|
8070
|
-
...l,
|
|
8071
|
-
date: d,
|
|
8072
|
-
dayName: n[d.getDay()],
|
|
8073
|
-
dayOfMonth: d.getDate(),
|
|
8074
|
-
isToday: this._isToday(d),
|
|
8075
|
-
timedEvents: h.filter((g) => !g.allDay),
|
|
8076
|
-
allDayEvents: h.filter((g) => g.allDay)
|
|
8077
|
-
};
|
|
8078
|
-
});
|
|
8079
|
-
return `
|
|
8080
|
-
<div class="fc-week-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
|
|
8081
|
-
<!-- Header -->
|
|
8082
|
-
<div style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
|
|
8083
|
-
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
8084
|
-
${o.map((l) => `
|
|
8085
|
-
<div style="padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;">
|
|
8086
|
-
<div style="font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">${l.dayName}</div>
|
|
8087
|
-
<div style="font-size: 16px; font-weight: 500; margin-top: 4px; ${l.isToday ? "background: #dc2626; color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;" : "color: #111827;"}">${l.dayOfMonth}</div>
|
|
8088
|
-
</div>
|
|
8089
|
-
`).join("")}
|
|
8090
|
-
</div>
|
|
8091
|
-
|
|
8092
|
-
<!-- All Day Row -->
|
|
8093
|
-
<div style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 32px; flex-shrink: 0;">
|
|
8094
|
-
<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>
|
|
8095
|
-
${o.map((l) => `
|
|
8096
|
-
<div style="border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;">
|
|
8097
|
-
${l.allDayEvents.map((d) => `
|
|
8098
|
-
<div class="fc-event" data-event-id="${this._escapeHTML(d.id)}" style="background-color: ${d.backgroundColor || "#2563eb"}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
|
8099
|
-
${this._escapeHTML(d.title)}
|
|
8100
|
-
</div>
|
|
8101
|
-
`).join("")}
|
|
8102
|
-
</div>
|
|
8103
|
-
`).join("")}
|
|
8104
|
-
</div>
|
|
8105
|
-
|
|
8106
|
-
<!-- Time Grid Body -->
|
|
8107
|
-
<div id="week-scroll-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
8108
|
-
<div style="display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: 1440px;">
|
|
8109
|
-
<!-- Time Gutter -->
|
|
8110
|
-
<div style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
8111
|
-
${a.map((l) => `
|
|
8112
|
-
<div style="height: 60px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;">
|
|
8113
|
-
${l === 0 ? "" : this._formatHour(l)}
|
|
8114
|
-
</div>
|
|
8115
|
-
`).join("")}
|
|
8116
|
-
</div>
|
|
8117
|
-
|
|
8118
|
-
<!-- Day Columns -->
|
|
8119
|
-
${o.map((l) => `
|
|
8120
|
-
<div class="fc-week-day-column" data-date="${l.date.toISOString()}" style="border-right: 1px solid #e5e7eb; position: relative; cursor: pointer;">
|
|
8121
|
-
<!-- Hour grid lines -->
|
|
8122
|
-
${a.map(() => '<div style="height: 60px; border-bottom: 1px solid #f3f4f6;"></div>').join("")}
|
|
8123
|
-
|
|
8124
|
-
<!-- Now indicator for today -->
|
|
8125
|
-
${l.isToday ? this._renderNowIndicator() : ""}
|
|
8126
|
-
|
|
8127
|
-
<!-- Timed events -->
|
|
8128
|
-
${l.timedEvents.map((d) => this._renderTimedEvent(d)).join("")}
|
|
8129
|
-
</div>
|
|
8130
|
-
`).join("")}
|
|
8131
|
-
</div>
|
|
8132
|
-
</div>
|
|
8133
|
-
</div>
|
|
8134
|
-
`;
|
|
8135
|
-
},
|
|
8136
|
-
_renderDayView(s, i) {
|
|
8137
|
-
var g, w;
|
|
8138
|
-
const r = ((w = (g = this.stateManager) == null ? void 0 : g.getState()) == null ? void 0 : w.currentDate) || /* @__PURE__ */ new Date();
|
|
8139
|
-
let n, a, o, c, l;
|
|
8140
|
-
if (s.type === "day" && s.date)
|
|
8141
|
-
if (n = new Date(s.date), a = s.dayName || ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][n.getDay()], o = s.isToday !== void 0 ? s.isToday : this._isToday(n), c = s.allDayEvents || [], s.hours && Array.isArray(s.hours)) {
|
|
8142
|
-
const f = /* @__PURE__ */ new Map();
|
|
8143
|
-
s.hours.forEach((k) => {
|
|
8144
|
-
(k.events || []).forEach((b) => {
|
|
8145
|
-
f.has(b.id) || f.set(b.id, b);
|
|
8146
|
-
});
|
|
8147
|
-
}), l = Array.from(f.values());
|
|
8148
|
-
} else
|
|
8149
|
-
l = [];
|
|
8150
|
-
else if (s.days && s.days.length > 0) {
|
|
8151
|
-
const f = s.days.find((b) => this._isSameDay(new Date(b.date), r)) || s.days[0];
|
|
8152
|
-
n = new Date(f.date), a = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][n.getDay()], o = this._isToday(n);
|
|
8153
|
-
const k = f.events || [];
|
|
8154
|
-
c = k.filter((b) => b.allDay), l = k.filter((b) => !b.allDay);
|
|
8155
|
-
} else
|
|
8156
|
-
return '<div style="padding: 20px; text-align: center; color: #666;">No data available for day view.</div>';
|
|
8157
|
-
const d = Array.from({ length: 24 }, (f, k) => k);
|
|
8158
|
-
return `
|
|
8159
|
-
<div class="fc-day-view" style="display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;">
|
|
8160
|
-
<!-- Header -->
|
|
8161
|
-
<div style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
|
|
8162
|
-
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
8163
|
-
<div style="padding: 16px 24px;">
|
|
8164
|
-
<div style="font-size: 12px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">${a}</div>
|
|
8165
|
-
<div style="font-size: 24px; font-weight: 600; margin-top: 4px; ${o ? "color: #dc2626;" : "color: #111827;"}">${n.getDate()}</div>
|
|
8166
|
-
</div>
|
|
8167
|
-
</div>
|
|
8168
|
-
|
|
8169
|
-
<!-- All Day Row -->
|
|
8170
|
-
<div style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 36px; flex-shrink: 0;">
|
|
8171
|
-
<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>
|
|
8172
|
-
<div style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
|
|
8173
|
-
${c.map((f) => `
|
|
8174
|
-
<div class="fc-event" data-event-id="${this._escapeHTML(f.id)}" style="background-color: ${f.backgroundColor || "#2563eb"}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
|
|
8175
|
-
${this._escapeHTML(f.title)}
|
|
8176
|
-
</div>
|
|
8177
|
-
`).join("")}
|
|
8178
|
-
</div>
|
|
8179
|
-
</div>
|
|
8180
|
-
|
|
8181
|
-
<!-- Time Grid Body -->
|
|
8182
|
-
<div id="day-scroll-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
8183
|
-
<div style="display: grid; grid-template-columns: 60px 1fr; position: relative; height: 1440px;">
|
|
8184
|
-
<!-- Time Gutter -->
|
|
8185
|
-
<div style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
8186
|
-
${d.map((f) => `
|
|
8187
|
-
<div style="height: 60px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;">
|
|
8188
|
-
${f === 0 ? "" : this._formatHour(f)}
|
|
8189
|
-
</div>
|
|
8190
|
-
`).join("")}
|
|
8191
|
-
</div>
|
|
8192
|
-
|
|
8193
|
-
<!-- Day Column -->
|
|
8194
|
-
<div class="fc-day-column" data-date="${n.toISOString()}" style="position: relative; cursor: pointer;">
|
|
8195
|
-
<!-- Hour grid lines -->
|
|
8196
|
-
${d.map(() => '<div style="height: 60px; border-bottom: 1px solid #f3f4f6;"></div>').join("")}
|
|
8197
|
-
|
|
8198
|
-
<!-- Now indicator for today -->
|
|
8199
|
-
${o ? this._renderNowIndicator() : ""}
|
|
8200
|
-
|
|
8201
|
-
<!-- Timed events -->
|
|
8202
|
-
${l.map((f) => this._renderTimedEventDay(f)).join("")}
|
|
8203
|
-
</div>
|
|
8204
|
-
</div>
|
|
8205
|
-
</div>
|
|
8206
|
-
</div>
|
|
8207
|
-
`;
|
|
8208
|
-
},
|
|
8209
|
-
_renderTimedEvent(s) {
|
|
8210
|
-
const i = new Date(s.start), r = new Date(s.end), n = i.getHours() * 60 + i.getMinutes(), a = Math.max((r - i) / (1e3 * 60), 20), o = s.backgroundColor || "#2563eb";
|
|
8211
|
-
return `
|
|
8212
|
-
<div class="fc-event" data-event-id="${this._escapeHTML(s.id)}"
|
|
8213
|
-
style="position: absolute; top: ${n}px; height: ${a}px; left: 2px; right: 2px;
|
|
8214
|
-
background-color: ${o}; border-radius: 4px; padding: 4px 8px; font-size: 11px;
|
|
8215
|
-
font-weight: 500; color: white; overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
|
8216
|
-
cursor: pointer; z-index: 5;">
|
|
8217
|
-
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${this._escapeHTML(s.title)}</div>
|
|
8218
|
-
<div style="font-size: 10px; opacity: 0.9;">${this._formatTime(i)}</div>
|
|
8219
|
-
</div>
|
|
8220
|
-
`;
|
|
8221
|
-
},
|
|
8222
|
-
_renderTimedEventDay(s) {
|
|
8223
|
-
const i = new Date(s.start), r = new Date(s.end), n = i.getHours() * 60 + i.getMinutes(), a = Math.max((r - i) / (1e3 * 60), 30), o = s.backgroundColor || "#2563eb";
|
|
8224
|
-
return `
|
|
8225
|
-
<div class="fc-event" data-event-id="${this._escapeHTML(s.id)}"
|
|
8226
|
-
style="position: absolute; top: ${n}px; height: ${a}px; left: 12px; right: 24px;
|
|
8227
|
-
background-color: ${o}; border-radius: 6px; padding: 8px 12px; font-size: 13px;
|
|
8228
|
-
font-weight: 500; color: white; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
8229
|
-
cursor: pointer; z-index: 5;">
|
|
8230
|
-
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${this._escapeHTML(s.title)}</div>
|
|
8231
|
-
<div style="font-size: 11px; opacity: 0.9;">${this._formatTime(i)} - ${this._formatTime(r)}</div>
|
|
8232
|
-
</div>
|
|
8233
|
-
`;
|
|
8234
|
-
},
|
|
8235
|
-
_renderNowIndicator() {
|
|
8236
|
-
const s = /* @__PURE__ */ new Date();
|
|
8237
|
-
return `<div style="position: absolute; left: 0; right: 0; top: ${s.getHours() * 60 + s.getMinutes()}px; height: 2px; background: #dc2626; z-index: 15; pointer-events: none;"></div>`;
|
|
8238
|
-
},
|
|
8239
|
-
_formatHour(s) {
|
|
8240
|
-
const i = s >= 12 ? "PM" : "AM";
|
|
8241
|
-
return `${s % 12 || 12} ${i}`;
|
|
8242
|
-
},
|
|
8243
|
-
_formatTime(s) {
|
|
8244
|
-
const i = s.getHours(), r = s.getMinutes(), n = i >= 12 ? "PM" : "AM", a = i % 12 || 12;
|
|
8245
|
-
return r === 0 ? `${a} ${n}` : `${a}:${r.toString().padStart(2, "0")} ${n}`;
|
|
8246
|
-
},
|
|
8247
|
-
_isToday(s) {
|
|
8248
|
-
const i = /* @__PURE__ */ new Date();
|
|
8249
|
-
return s.getDate() === i.getDate() && s.getMonth() === i.getMonth() && s.getFullYear() === i.getFullYear();
|
|
8250
|
-
},
|
|
8251
|
-
_isSameDay(s, i) {
|
|
8252
|
-
return s.getDate() === i.getDate() && s.getMonth() === i.getMonth() && s.getFullYear() === i.getFullYear();
|
|
8253
|
-
},
|
|
8254
|
-
_attachEventHandlers(s) {
|
|
8255
|
-
const i = this.stateManager;
|
|
8256
|
-
if (this.container.querySelectorAll(".fc-month-day").forEach((r) => {
|
|
8257
|
-
this.addListener(r, "click", (n) => {
|
|
8258
|
-
const a = new Date(r.dataset.date);
|
|
8259
|
-
i.selectDate(a);
|
|
8260
|
-
});
|
|
8261
|
-
}), this.container.querySelectorAll(".fc-week-day-column").forEach((r) => {
|
|
8262
|
-
this.addListener(r, "click", (n) => {
|
|
8263
|
-
if (n.target.closest(".fc-event")) return;
|
|
8264
|
-
const a = new Date(r.dataset.date), o = r.getBoundingClientRect(), c = this.container.querySelector("#week-scroll-container"), l = n.clientY - o.top + (c ? c.scrollTop : 0);
|
|
8265
|
-
a.setHours(Math.floor(l / 60), Math.floor(l % 60), 0, 0), i.selectDate(a);
|
|
8266
|
-
});
|
|
8267
|
-
}), this.container.querySelectorAll(".fc-day-column").forEach((r) => {
|
|
8268
|
-
this.addListener(r, "click", (n) => {
|
|
8269
|
-
if (n.target.closest(".fc-event")) return;
|
|
8270
|
-
const a = new Date(r.dataset.date), o = r.getBoundingClientRect(), c = this.container.querySelector("#day-scroll-container"), l = n.clientY - o.top + (c ? c.scrollTop : 0);
|
|
8271
|
-
a.setHours(Math.floor(l / 60), Math.floor(l % 60), 0, 0), i.selectDate(a);
|
|
8272
|
-
});
|
|
8273
|
-
}), this.container.querySelectorAll(".fc-event").forEach((r) => {
|
|
8274
|
-
this.addListener(r, "click", (n) => {
|
|
8275
|
-
n.stopPropagation();
|
|
8276
|
-
const a = r.dataset.eventId, o = i.getEvents().find((c) => c.id === a);
|
|
8277
|
-
o && i.selectEvent(o);
|
|
8278
|
-
});
|
|
8279
|
-
}), s === "week" || s === "day") {
|
|
8280
|
-
const r = s === "week" ? "#week-scroll-container" : "#day-scroll-container", n = this.container.querySelector(r);
|
|
8281
|
-
n && !this._scrolled && (n.scrollTop = 8 * 60 - 50, this._scrolled = !0);
|
|
8282
|
-
}
|
|
8283
|
-
}
|
|
8284
|
-
};
|
|
8530
|
+
const s = {
|
|
8531
|
+
month: E,
|
|
8532
|
+
week: H,
|
|
8533
|
+
day: F
|
|
8534
|
+
}[e] || E;
|
|
8535
|
+
return new s(null, null);
|
|
8285
8536
|
}
|
|
8286
8537
|
handleNavigation(e) {
|
|
8287
8538
|
switch (e.currentTarget.dataset.action) {
|
|
@@ -8304,14 +8555,14 @@ class ie extends $ {
|
|
|
8304
8555
|
const s = this.stateManager.state.config.locale;
|
|
8305
8556
|
switch (t) {
|
|
8306
8557
|
case "month":
|
|
8307
|
-
return
|
|
8558
|
+
return v.formatDate(e, "month", s);
|
|
8308
8559
|
case "week":
|
|
8309
|
-
const i =
|
|
8310
|
-
return
|
|
8560
|
+
const i = v.startOfWeek(e), r = v.endOfWeek(e);
|
|
8561
|
+
return v.formatDateRange(i, r, s);
|
|
8311
8562
|
case "day":
|
|
8312
|
-
return
|
|
8563
|
+
return v.formatDate(e, "long", s);
|
|
8313
8564
|
default:
|
|
8314
|
-
return
|
|
8565
|
+
return v.formatDate(e, "month", s);
|
|
8315
8566
|
}
|
|
8316
8567
|
}
|
|
8317
8568
|
getIcon(e) {
|
|
@@ -8362,22 +8613,26 @@ class ie extends $ {
|
|
|
8362
8613
|
this.stateManager.today();
|
|
8363
8614
|
}
|
|
8364
8615
|
destroy() {
|
|
8365
|
-
this.stateManager && this.stateManager.destroy(),
|
|
8616
|
+
this.stateManager && this.stateManager.destroy(), p.clear(), super.cleanup();
|
|
8366
8617
|
}
|
|
8367
8618
|
}
|
|
8368
|
-
customElements.get("forcecal-main") || customElements.define("forcecal-main",
|
|
8619
|
+
customElements.get("forcecal-main") || customElements.define("forcecal-main", oe);
|
|
8369
8620
|
typeof window < "u" && typeof customElements < "u" && console.log("Force Calendar Interface loading...");
|
|
8370
8621
|
export {
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8622
|
+
_ as BaseComponent,
|
|
8623
|
+
O as BaseViewRenderer,
|
|
8624
|
+
T as DOMUtils,
|
|
8625
|
+
v as DateUtils,
|
|
8626
|
+
ne as DayView,
|
|
8627
|
+
F as DayViewRenderer,
|
|
8628
|
+
te as EventBus,
|
|
8629
|
+
oe as ForceCalendar,
|
|
8630
|
+
ie as MonthView,
|
|
8631
|
+
E as MonthViewRenderer,
|
|
8632
|
+
se as StateManager,
|
|
8633
|
+
y as StyleUtils,
|
|
8634
|
+
re as WeekView,
|
|
8635
|
+
H as WeekViewRenderer,
|
|
8636
|
+
p as eventBus
|
|
8382
8637
|
};
|
|
8383
8638
|
//# sourceMappingURL=force-calendar-interface.esm.js.map
|