@forcecalendar/interface 1.0.26 → 1.0.28
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/README.md +9 -0
- package/dist/force-calendar-interface.esm.js +217 -112
- package/dist/force-calendar-interface.esm.js.map +1 -1
- package/dist/force-calendar-interface.umd.js +11 -11
- package/dist/force-calendar-interface.umd.js.map +1 -1
- package/package.json +3 -1
- package/src/components/EventForm.js +180 -176
- package/src/components/ForceCalendar.js +414 -392
- package/src/core/BaseComponent.js +146 -144
- package/src/core/EventBus.js +197 -197
- package/src/core/StateManager.js +405 -399
- package/src/index.js +3 -3
- package/src/renderers/BaseViewRenderer.js +195 -192
- package/src/renderers/DayViewRenderer.js +133 -118
- package/src/renderers/MonthViewRenderer.js +74 -72
- package/src/renderers/WeekViewRenderer.js +118 -96
- package/src/utils/DOMUtils.js +277 -277
- package/src/utils/DateUtils.js +164 -164
- package/src/utils/StyleUtils.js +286 -249
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @forcecalendar/interface
|
|
2
|
+
|
|
3
|
+
[](https://github.com/forceCalendar/interface/actions/workflows/test.yml)
|
|
4
|
+
[](https://github.com/forceCalendar/interface/actions/workflows/code-quality.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@forcecalendar/interface)
|
|
6
|
+
[](https://www.npmjs.com/package/@forcecalendar/interface)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
Official interface layer for forceCalendar Core — enterprise calendar components for Salesforce and the web.
|
|
@@ -55,11 +55,13 @@ class O extends HTMLElement {
|
|
|
55
55
|
e.addEventListener(t, i), this._listeners.push({ element: e, event: t, handler: i });
|
|
56
56
|
}
|
|
57
57
|
emit(e, t = {}) {
|
|
58
|
-
this.dispatchEvent(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
this.dispatchEvent(
|
|
59
|
+
new CustomEvent(e, {
|
|
60
|
+
detail: t,
|
|
61
|
+
bubbles: !0,
|
|
62
|
+
composed: !0
|
|
63
|
+
})
|
|
64
|
+
);
|
|
63
65
|
}
|
|
64
66
|
// Style management
|
|
65
67
|
getStyles() {
|
|
@@ -738,7 +740,7 @@ class C {
|
|
|
738
740
|
*/
|
|
739
741
|
getTimezoneOffset(e, t) {
|
|
740
742
|
t = this.database.resolveAlias(t);
|
|
741
|
-
const s = `${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}`;
|
|
743
|
+
const s = `${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}_${e.getHours()}`;
|
|
742
744
|
if (this.offsetCache.has(s))
|
|
743
745
|
return this.cacheHits++, this._manageCacheSize(), this.offsetCache.get(s);
|
|
744
746
|
if (this.cacheMisses++, typeof Intl < "u" && Intl.DateTimeFormat)
|
|
@@ -1022,6 +1024,12 @@ class w {
|
|
|
1022
1024
|
} catch {
|
|
1023
1025
|
throw new Error(`Invalid timezone: ${e.timeZone}`);
|
|
1024
1026
|
}
|
|
1027
|
+
if (e.endTimeZone)
|
|
1028
|
+
try {
|
|
1029
|
+
new Intl.DateTimeFormat("en-US", { timeZone: e.endTimeZone });
|
|
1030
|
+
} catch {
|
|
1031
|
+
throw new Error(`Invalid end timezone: ${e.endTimeZone}`);
|
|
1032
|
+
}
|
|
1025
1033
|
}
|
|
1026
1034
|
/**
|
|
1027
1035
|
* Create a new Event instance
|
|
@@ -1056,8 +1064,8 @@ class w {
|
|
|
1056
1064
|
categories: U,
|
|
1057
1065
|
// Support plural categories (no default)
|
|
1058
1066
|
attachments: Y = [],
|
|
1059
|
-
conferenceData:
|
|
1060
|
-
metadata:
|
|
1067
|
+
conferenceData: P = null,
|
|
1068
|
+
metadata: N = {},
|
|
1061
1069
|
...V
|
|
1062
1070
|
// Capture any extra properties
|
|
1063
1071
|
}) {
|
|
@@ -1088,8 +1096,8 @@ class w {
|
|
|
1088
1096
|
categories: U,
|
|
1089
1097
|
// Pass categories to normalize
|
|
1090
1098
|
attachments: Y,
|
|
1091
|
-
conferenceData:
|
|
1092
|
-
metadata:
|
|
1099
|
+
conferenceData: P,
|
|
1100
|
+
metadata: N,
|
|
1093
1101
|
...V
|
|
1094
1102
|
// Pass any extra properties
|
|
1095
1103
|
});
|
|
@@ -1768,8 +1776,10 @@ let f = class y {
|
|
|
1768
1776
|
* @returns {number}
|
|
1769
1777
|
*/
|
|
1770
1778
|
static getWeekNumber(e) {
|
|
1771
|
-
const t = new Date(e
|
|
1772
|
-
|
|
1779
|
+
const t = new Date(e);
|
|
1780
|
+
t.setHours(0, 0, 0, 0), t.setDate(t.getDate() + 4 - (t.getDay() || 7));
|
|
1781
|
+
const s = new Date(t.getFullYear(), 0, 1);
|
|
1782
|
+
return Math.ceil(((t - s) / 864e5 + 1) / 7);
|
|
1773
1783
|
}
|
|
1774
1784
|
/**
|
|
1775
1785
|
* Get the day of week for a date
|
|
@@ -2261,7 +2271,39 @@ class K {
|
|
|
2261
2271
|
if (n.count && d >= n.count)
|
|
2262
2272
|
break;
|
|
2263
2273
|
}
|
|
2264
|
-
return a;
|
|
2274
|
+
return n.bySetPos && n.bySetPos.length > 0 && n.freq !== "MONTHLY" ? this._applyBySetPos(a, n) : a;
|
|
2275
|
+
}
|
|
2276
|
+
/**
|
|
2277
|
+
* Apply BYSETPOS to filter occurrences within each frequency period
|
|
2278
|
+
* @param {Array} occurrences - Generated occurrences
|
|
2279
|
+
* @param {Object} rule - Recurrence rule
|
|
2280
|
+
* @returns {Array} Filtered occurrences
|
|
2281
|
+
* @private
|
|
2282
|
+
*/
|
|
2283
|
+
static _applyBySetPos(e, t) {
|
|
2284
|
+
if (e.length === 0) return e;
|
|
2285
|
+
const s = /* @__PURE__ */ new Map();
|
|
2286
|
+
for (const r of e) {
|
|
2287
|
+
let n;
|
|
2288
|
+
switch (t.freq) {
|
|
2289
|
+
case "YEARLY":
|
|
2290
|
+
n = r.start.getFullYear();
|
|
2291
|
+
break;
|
|
2292
|
+
case "WEEKLY":
|
|
2293
|
+
n = `${r.start.getFullYear()}-W${f.getWeekNumber(r.start)}`;
|
|
2294
|
+
break;
|
|
2295
|
+
default:
|
|
2296
|
+
n = `${r.start.getFullYear()}-${r.start.getMonth()}`;
|
|
2297
|
+
}
|
|
2298
|
+
s.has(n) || s.set(n, []), s.get(n).push(r);
|
|
2299
|
+
}
|
|
2300
|
+
const i = [];
|
|
2301
|
+
for (const r of s.values())
|
|
2302
|
+
for (const n of t.bySetPos) {
|
|
2303
|
+
const a = n > 0 ? n - 1 : r.length + n;
|
|
2304
|
+
a >= 0 && a < r.length && i.push(r[a]);
|
|
2305
|
+
}
|
|
2306
|
+
return i.sort((r, n) => r.start - n.start);
|
|
2265
2307
|
}
|
|
2266
2308
|
/**
|
|
2267
2309
|
* Parse an RRULE string into a rule object
|
|
@@ -2281,6 +2323,15 @@ class K {
|
|
|
2281
2323
|
static getNextOccurrence(e, t, s = "UTC") {
|
|
2282
2324
|
const i = new Date(e);
|
|
2283
2325
|
switch (t.freq) {
|
|
2326
|
+
case "SECONDLY":
|
|
2327
|
+
i.setSeconds(i.getSeconds() + t.interval);
|
|
2328
|
+
break;
|
|
2329
|
+
case "MINUTELY":
|
|
2330
|
+
i.setMinutes(i.getMinutes() + t.interval);
|
|
2331
|
+
break;
|
|
2332
|
+
case "HOURLY":
|
|
2333
|
+
i.setHours(i.getHours() + t.interval);
|
|
2334
|
+
break;
|
|
2284
2335
|
case "DAILY":
|
|
2285
2336
|
i.setDate(i.getDate() + t.interval);
|
|
2286
2337
|
break;
|
|
@@ -2297,8 +2348,15 @@ class K {
|
|
|
2297
2348
|
case "MONTHLY":
|
|
2298
2349
|
if (t.byMonthDay && t.byMonthDay.length > 0) {
|
|
2299
2350
|
const r = i.getMonth();
|
|
2300
|
-
i.setMonth(r + t.interval)
|
|
2301
|
-
|
|
2351
|
+
i.setMonth(r + t.interval);
|
|
2352
|
+
const n = new Date(i.getFullYear(), i.getMonth() + 1, 0).getDate();
|
|
2353
|
+
i.setDate(Math.min(t.byMonthDay[0], n));
|
|
2354
|
+
} else if (t.byDay && t.byDay.length > 0) {
|
|
2355
|
+
i.setMonth(i.getMonth() + t.interval);
|
|
2356
|
+
const n = t.byDay[0].match(/^(-?\d+)?([A-Z]{2})$/), o = (n && n[1] ? parseInt(n[1], 10) : null) || t.bySetPos && t.bySetPos[0] || 1;
|
|
2357
|
+
this.setToWeekdayOfMonth(i, t.byDay[0], o);
|
|
2358
|
+
} else
|
|
2359
|
+
i.setMonth(i.getMonth() + t.interval);
|
|
2302
2360
|
break;
|
|
2303
2361
|
case "YEARLY":
|
|
2304
2362
|
t.byMonth && t.byMonth.length > 0 ? (i.setFullYear(i.getFullYear() + t.interval), i.setMonth(t.byMonth[0] - 1)) : i.setFullYear(i.getFullYear() + t.interval);
|
|
@@ -2373,10 +2431,11 @@ class K {
|
|
|
2373
2431
|
const i = e.toDateString(), r = e.getTime();
|
|
2374
2432
|
return t.exceptions.some((n) => {
|
|
2375
2433
|
if (typeof n == "object" && n.date) {
|
|
2376
|
-
const
|
|
2377
|
-
return n.matchTime ? Math.abs(
|
|
2434
|
+
const c = n.date instanceof Date ? n.date : new Date(n.date);
|
|
2435
|
+
return n.matchTime ? Math.abs(c.getTime() - r) < 1e3 : c.toDateString() === i;
|
|
2378
2436
|
}
|
|
2379
|
-
|
|
2437
|
+
const a = n instanceof Date ? n : new Date(n);
|
|
2438
|
+
return a.getHours() !== 0 || a.getMinutes() !== 0 || a.getSeconds() !== 0 ? Math.abs(a.getTime() - r) < 1e3 : a.toDateString() === i;
|
|
2380
2439
|
});
|
|
2381
2440
|
}
|
|
2382
2441
|
/**
|
|
@@ -3403,7 +3462,7 @@ class X {
|
|
|
3403
3462
|
throw new Error(`Event with id ${e} not found`);
|
|
3404
3463
|
this._unindexEvent(s);
|
|
3405
3464
|
const i = s.clone(t);
|
|
3406
|
-
return this.events.set(e, i), this._indexEvent(i), this._notifyChange({
|
|
3465
|
+
return this.events.set(e, i), this.optimizer.cache(e, i, "event"), this.optimizer.queryCache.clear(), this.optimizer.dateRangeCache.clear(), this._indexEvent(i), this._notifyChange({
|
|
3407
3466
|
type: "update",
|
|
3408
3467
|
event: i,
|
|
3409
3468
|
oldEvent: s,
|
|
@@ -3417,7 +3476,7 @@ class X {
|
|
|
3417
3476
|
*/
|
|
3418
3477
|
removeEvent(e) {
|
|
3419
3478
|
const t = this.events.get(e);
|
|
3420
|
-
return t ? (this.events.delete(e), this._unindexEvent(t), this._notifyChange({
|
|
3479
|
+
return t ? (this.events.delete(e), this.optimizer.eventCache.delete(e), this.optimizer.queryCache.clear(), this.optimizer.dateRangeCache.clear(), this._unindexEvent(t), this._notifyChange({
|
|
3421
3480
|
type: "remove",
|
|
3422
3481
|
event: t,
|
|
3423
3482
|
version: ++this.version
|
|
@@ -3554,21 +3613,15 @@ class X {
|
|
|
3554
3613
|
*/
|
|
3555
3614
|
getOverlapGroups(e, t = !0) {
|
|
3556
3615
|
let s = this.getEventsForDate(e);
|
|
3557
|
-
t && (s = s.filter((
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
s.forEach((l) => {
|
|
3567
|
-
!r.has(l.id) && c.overlaps(l) && (a.push(l), r.add(l.id));
|
|
3568
|
-
}), o++;
|
|
3569
|
-
}
|
|
3570
|
-
i.push(a);
|
|
3571
|
-
}), i;
|
|
3616
|
+
if (t && (s = s.filter((a) => !a.allDay)), s.length === 0) return [];
|
|
3617
|
+
s.sort((a, o) => a.start - o.start || o.end - a.end);
|
|
3618
|
+
const i = [];
|
|
3619
|
+
let r = [s[0]], n = s[0].end;
|
|
3620
|
+
for (let a = 1; a < s.length; a++) {
|
|
3621
|
+
const o = s[a];
|
|
3622
|
+
o.start < n ? (r.push(o), o.end > n && (n = o.end)) : (i.push(r), r = [o], n = o.end);
|
|
3623
|
+
}
|
|
3624
|
+
return i.push(r), i;
|
|
3572
3625
|
}
|
|
3573
3626
|
/**
|
|
3574
3627
|
* Calculate positions for overlapping events (for rendering)
|
|
@@ -3602,29 +3655,31 @@ class X {
|
|
|
3602
3655
|
* Get events for a date range
|
|
3603
3656
|
* @param {Date} start - Start date
|
|
3604
3657
|
* @param {Date} end - End date
|
|
3605
|
-
* @param {boolean|
|
|
3606
|
-
*
|
|
3658
|
+
* @param {boolean|Object} [expandRecurringOrOptions=true] - Boolean to expand recurring events,
|
|
3659
|
+
* or options object: { expandRecurring?: boolean, timezone?: string }
|
|
3660
|
+
* @param {string} [timezone] - Timezone for the query
|
|
3607
3661
|
* @returns {Event[]}
|
|
3608
3662
|
*/
|
|
3609
3663
|
getEventsInRange(e, t, s = !0, i = null) {
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3664
|
+
let r = !0;
|
|
3665
|
+
typeof s == "object" && s !== null ? (r = s.expandRecurring !== !1, i = s.timezone || i) : typeof s == "string" ? (i = s, r = !0) : r = s, i = i || this.defaultTimezone;
|
|
3666
|
+
const n = this.timezoneManager.toUTC(e, i), a = this.timezoneManager.toUTC(t, i), o = this.queryEvents({
|
|
3667
|
+
start: n,
|
|
3668
|
+
end: a,
|
|
3614
3669
|
sort: "start"
|
|
3615
3670
|
});
|
|
3616
|
-
if (!
|
|
3617
|
-
return
|
|
3618
|
-
const
|
|
3619
|
-
return
|
|
3620
|
-
if (
|
|
3621
|
-
const
|
|
3622
|
-
|
|
3671
|
+
if (!r)
|
|
3672
|
+
return o;
|
|
3673
|
+
const c = [];
|
|
3674
|
+
return o.forEach((l) => {
|
|
3675
|
+
if (l.recurring && l.recurrenceRule) {
|
|
3676
|
+
const h = this.expandRecurringEvent(l, e, t, i);
|
|
3677
|
+
c.push(...h);
|
|
3623
3678
|
} else
|
|
3624
|
-
|
|
3625
|
-
}),
|
|
3626
|
-
const
|
|
3627
|
-
return
|
|
3679
|
+
c.push(l);
|
|
3680
|
+
}), c.sort((l, h) => {
|
|
3681
|
+
const d = l.getStartInTimezone(i), p = h.getStartInTimezone(i);
|
|
3682
|
+
return d - p;
|
|
3628
3683
|
});
|
|
3629
3684
|
}
|
|
3630
3685
|
/**
|
|
@@ -3860,7 +3915,7 @@ class X {
|
|
|
3860
3915
|
*/
|
|
3861
3916
|
addEvents(e) {
|
|
3862
3917
|
return this.optimizer.measure("addEvents", () => {
|
|
3863
|
-
this.startBatch();
|
|
3918
|
+
this.startBatch(!0);
|
|
3864
3919
|
const t = [], s = [];
|
|
3865
3920
|
for (const i of e)
|
|
3866
3921
|
try {
|
|
@@ -3868,7 +3923,7 @@ class X {
|
|
|
3868
3923
|
} catch (r) {
|
|
3869
3924
|
s.push({ event: i, error: r.message });
|
|
3870
3925
|
}
|
|
3871
|
-
return this.commitBatch(), s.length > 0 && console.warn(`Failed to add ${s.length} events:`, s), t;
|
|
3926
|
+
return s.length > 0 && t.length === 0 ? this.rollbackBatch() : this.commitBatch(), s.length > 0 && console.warn(`Failed to add ${s.length} events:`, s), t;
|
|
3872
3927
|
});
|
|
3873
3928
|
}
|
|
3874
3929
|
/**
|
|
@@ -3878,7 +3933,7 @@ class X {
|
|
|
3878
3933
|
*/
|
|
3879
3934
|
updateEvents(e) {
|
|
3880
3935
|
return this.optimizer.measure("updateEvents", () => {
|
|
3881
|
-
this.startBatch();
|
|
3936
|
+
this.startBatch(!0);
|
|
3882
3937
|
const t = [], s = [];
|
|
3883
3938
|
for (const { id: i, updates: r } of e)
|
|
3884
3939
|
try {
|
|
@@ -3886,7 +3941,7 @@ class X {
|
|
|
3886
3941
|
} catch (n) {
|
|
3887
3942
|
s.push({ id: i, error: n.message });
|
|
3888
3943
|
}
|
|
3889
|
-
return this.commitBatch(), s.length > 0 && console.warn(`Failed to update ${s.length} events:`, s), t;
|
|
3944
|
+
return s.length > 0 && t.length === 0 ? this.rollbackBatch() : this.commitBatch(), s.length > 0 && console.warn(`Failed to update ${s.length} events:`, s), t;
|
|
3890
3945
|
});
|
|
3891
3946
|
}
|
|
3892
3947
|
/**
|
|
@@ -3896,11 +3951,11 @@ class X {
|
|
|
3896
3951
|
*/
|
|
3897
3952
|
removeEvents(e) {
|
|
3898
3953
|
return this.optimizer.measure("removeEvents", () => {
|
|
3899
|
-
this.startBatch();
|
|
3954
|
+
this.startBatch(!0);
|
|
3900
3955
|
let t = 0;
|
|
3901
3956
|
for (const s of e)
|
|
3902
3957
|
this.removeEvent(s) && t++;
|
|
3903
|
-
return this.commitBatch(), t;
|
|
3958
|
+
return t === 0 && e.length > 0 ? this.rollbackBatch() : this.commitBatch(), t;
|
|
3904
3959
|
});
|
|
3905
3960
|
}
|
|
3906
3961
|
// ============ Performance Methods ============
|
|
@@ -4125,7 +4180,7 @@ let ee = class {
|
|
|
4125
4180
|
*/
|
|
4126
4181
|
setState(e) {
|
|
4127
4182
|
const t = this.state;
|
|
4128
|
-
typeof e == "function" && (e = e(t));
|
|
4183
|
+
typeof e == "function" && (e = e(t)), e && typeof e == "object" && (delete e.__proto__, delete e.constructor, delete e.prototype);
|
|
4129
4184
|
const s = {
|
|
4130
4185
|
...t,
|
|
4131
4186
|
...e,
|
|
@@ -4946,9 +5001,14 @@ class te {
|
|
|
4946
5001
|
* Destroy the calendar and clean up
|
|
4947
5002
|
*/
|
|
4948
5003
|
destroy() {
|
|
4949
|
-
this.listeners.clear(), this.eventStore.destroy(), this.plugins.forEach((e) => {
|
|
4950
|
-
typeof e.uninstall == "function"
|
|
4951
|
-
|
|
5004
|
+
this._emit("destroy"), this.listeners.clear(), this.eventStore.destroy(), this.plugins.forEach((e) => {
|
|
5005
|
+
if (typeof e.uninstall == "function")
|
|
5006
|
+
try {
|
|
5007
|
+
e.uninstall(this);
|
|
5008
|
+
} catch (t) {
|
|
5009
|
+
console.error("Error uninstalling plugin:", t);
|
|
5010
|
+
}
|
|
5011
|
+
}), this.plugins.clear(), this.views.clear();
|
|
4952
5012
|
}
|
|
4953
5013
|
}
|
|
4954
5014
|
class se {
|
|
@@ -5169,9 +5229,7 @@ class ie {
|
|
|
5169
5229
|
});
|
|
5170
5230
|
}
|
|
5171
5231
|
emitStateChange(e, t) {
|
|
5172
|
-
const s = Object.keys(t).filter(
|
|
5173
|
-
(i) => e[i] !== t[i]
|
|
5174
|
-
);
|
|
5232
|
+
const s = Object.keys(t).filter((i) => e[i] !== t[i]);
|
|
5175
5233
|
s.forEach((i) => {
|
|
5176
5234
|
u.emit(`state:${i}:changed`, {
|
|
5177
5235
|
oldValue: e[i],
|
|
@@ -5214,7 +5272,12 @@ class ie {
|
|
|
5214
5272
|
updateEvent(e, t) {
|
|
5215
5273
|
this._syncEventsFromCore({ silent: !0 });
|
|
5216
5274
|
const s = this.calendar.updateEvent(e, t);
|
|
5217
|
-
return s ? (this._syncEventsFromCore(), u.emit("event:update", { event: s }), u.emit("event:updated", { event: s }), s) : (console.error(`Failed to update event: ${e}`), u.emit("event:error", {
|
|
5275
|
+
return s ? (this._syncEventsFromCore(), u.emit("event:update", { event: s }), u.emit("event:updated", { event: s }), s) : (console.error(`Failed to update event: ${e}`), u.emit("event:error", {
|
|
5276
|
+
action: "update",
|
|
5277
|
+
eventId: e,
|
|
5278
|
+
updates: t,
|
|
5279
|
+
error: "Event not found in calendar"
|
|
5280
|
+
}), null);
|
|
5218
5281
|
}
|
|
5219
5282
|
deleteEvent(e) {
|
|
5220
5283
|
return this._syncEventsFromCore({ silent: !0 }), this.calendar.removeEvent(e) ? (this._syncEventsFromCore(), u.emit("event:remove", { eventId: e }), u.emit("event:deleted", { eventId: e }), !0) : (console.error(`Failed to delete event: ${e}`), u.emit("event:error", { action: "delete", eventId: e, error: "Event not found" }), !1);
|
|
@@ -5429,7 +5492,7 @@ class E extends f {
|
|
|
5429
5492
|
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;
|
|
5430
5493
|
}
|
|
5431
5494
|
}
|
|
5432
|
-
class
|
|
5495
|
+
class H {
|
|
5433
5496
|
/**
|
|
5434
5497
|
* Create element with attributes and children
|
|
5435
5498
|
*/
|
|
@@ -6070,7 +6133,7 @@ I(D, "breakpoints", {
|
|
|
6070
6133
|
xl: "1200px",
|
|
6071
6134
|
"2xl": "1400px"
|
|
6072
6135
|
});
|
|
6073
|
-
class
|
|
6136
|
+
class F {
|
|
6074
6137
|
/**
|
|
6075
6138
|
* @param {HTMLElement} container - The DOM element to render into
|
|
6076
6139
|
* @param {StateManager} stateManager - The state manager instance
|
|
@@ -6109,7 +6172,7 @@ class H {
|
|
|
6109
6172
|
* @returns {string}
|
|
6110
6173
|
*/
|
|
6111
6174
|
escapeHTML(e) {
|
|
6112
|
-
return e == null ? "" :
|
|
6175
|
+
return e == null ? "" : H.escapeHTML(String(e));
|
|
6113
6176
|
}
|
|
6114
6177
|
/**
|
|
6115
6178
|
* Check if a date is today
|
|
@@ -6219,7 +6282,7 @@ class H {
|
|
|
6219
6282
|
});
|
|
6220
6283
|
}
|
|
6221
6284
|
}
|
|
6222
|
-
class S extends
|
|
6285
|
+
class S extends F {
|
|
6223
6286
|
constructor(e, t) {
|
|
6224
6287
|
super(e, t), this.maxEventsToShow = 3;
|
|
6225
6288
|
}
|
|
@@ -6294,7 +6357,7 @@ class S extends H {
|
|
|
6294
6357
|
}), this.attachCommonEventHandlers();
|
|
6295
6358
|
}
|
|
6296
6359
|
}
|
|
6297
|
-
class z extends
|
|
6360
|
+
class z extends F {
|
|
6298
6361
|
constructor(e, t) {
|
|
6299
6362
|
super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
|
|
6300
6363
|
}
|
|
@@ -6334,7 +6397,8 @@ class z extends H {
|
|
|
6334
6397
|
return `
|
|
6335
6398
|
<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;">
|
|
6336
6399
|
<div style="border-right: 1px solid #e5e7eb;"></div>
|
|
6337
|
-
${e.map(
|
|
6400
|
+
${e.map(
|
|
6401
|
+
(t) => `
|
|
6338
6402
|
<div style="padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;">
|
|
6339
6403
|
<div style="font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">
|
|
6340
6404
|
${t.dayName}
|
|
@@ -6343,7 +6407,8 @@ class z extends H {
|
|
|
6343
6407
|
${t.dayOfMonth}
|
|
6344
6408
|
</div>
|
|
6345
6409
|
</div>
|
|
6346
|
-
`
|
|
6410
|
+
`
|
|
6411
|
+
).join("")}
|
|
6347
6412
|
</div>
|
|
6348
6413
|
`;
|
|
6349
6414
|
}
|
|
@@ -6353,16 +6418,20 @@ class z extends H {
|
|
|
6353
6418
|
<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;">
|
|
6354
6419
|
All day
|
|
6355
6420
|
</div>
|
|
6356
|
-
${e.map(
|
|
6421
|
+
${e.map(
|
|
6422
|
+
(t) => `
|
|
6357
6423
|
<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;">
|
|
6358
|
-
${t.allDayEvents.map(
|
|
6424
|
+
${t.allDayEvents.map(
|
|
6425
|
+
(s) => `
|
|
6359
6426
|
<div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(s.id)}"
|
|
6360
6427
|
style="background-color: ${this.getEventColor(s)}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
|
6361
6428
|
${this.escapeHTML(s.title)}
|
|
6362
6429
|
</div>
|
|
6363
|
-
`
|
|
6430
|
+
`
|
|
6431
|
+
).join("")}
|
|
6364
6432
|
</div>
|
|
6365
|
-
`
|
|
6433
|
+
`
|
|
6434
|
+
).join("")}
|
|
6366
6435
|
</div>
|
|
6367
6436
|
`;
|
|
6368
6437
|
}
|
|
@@ -6379,11 +6448,13 @@ class z extends H {
|
|
|
6379
6448
|
_renderTimeGutter(e) {
|
|
6380
6449
|
return `
|
|
6381
6450
|
<div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
6382
|
-
${e.map(
|
|
6451
|
+
${e.map(
|
|
6452
|
+
(t) => `
|
|
6383
6453
|
<div style="height: ${this.hourHeight}px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;">
|
|
6384
6454
|
${t === 0 ? "" : this.formatHour(t)}
|
|
6385
6455
|
</div>
|
|
6386
|
-
`
|
|
6456
|
+
`
|
|
6457
|
+
).join("")}
|
|
6387
6458
|
</div>
|
|
6388
6459
|
`;
|
|
6389
6460
|
}
|
|
@@ -6406,7 +6477,12 @@ class z extends H {
|
|
|
6406
6477
|
const t = e.target.closest(".fc-week-day-column");
|
|
6407
6478
|
if (!t || !this.container.contains(t) || e.target.closest(".fc-event")) return;
|
|
6408
6479
|
const s = new Date(t.dataset.date), i = t.getBoundingClientRect(), r = this.container.querySelector("#week-scroll-container"), n = e.clientY - i.top + (r ? r.scrollTop : 0);
|
|
6409
|
-
s.setHours(
|
|
6480
|
+
s.setHours(
|
|
6481
|
+
Math.floor(n / this.hourHeight),
|
|
6482
|
+
Math.floor(n % this.hourHeight / (this.hourHeight / 60)),
|
|
6483
|
+
0,
|
|
6484
|
+
0
|
|
6485
|
+
), this.stateManager.selectDate(s);
|
|
6410
6486
|
}), this.attachCommonEventHandlers();
|
|
6411
6487
|
}
|
|
6412
6488
|
_scrollToCurrentTime() {
|
|
@@ -6415,7 +6491,7 @@ class z extends H {
|
|
|
6415
6491
|
e && (e.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
|
|
6416
6492
|
}
|
|
6417
6493
|
}
|
|
6418
|
-
class L extends
|
|
6494
|
+
class L extends F {
|
|
6419
6495
|
constructor(e, t) {
|
|
6420
6496
|
super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
|
|
6421
6497
|
}
|
|
@@ -6488,12 +6564,14 @@ class L extends H {
|
|
|
6488
6564
|
All day
|
|
6489
6565
|
</div>
|
|
6490
6566
|
<div class="fc-all-day-cell" data-date="${t.toISOString()}" style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
|
|
6491
|
-
${e.map(
|
|
6567
|
+
${e.map(
|
|
6568
|
+
(s) => `
|
|
6492
6569
|
<div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(s.id)}"
|
|
6493
6570
|
style="background-color: ${this.getEventColor(s)}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
|
|
6494
6571
|
${this.escapeHTML(s.title)}
|
|
6495
6572
|
</div>
|
|
6496
|
-
`
|
|
6573
|
+
`
|
|
6574
|
+
).join("")}
|
|
6497
6575
|
</div>
|
|
6498
6576
|
</div>
|
|
6499
6577
|
`;
|
|
@@ -6511,11 +6589,13 @@ class L extends H {
|
|
|
6511
6589
|
_renderTimeGutter(e) {
|
|
6512
6590
|
return `
|
|
6513
6591
|
<div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
|
|
6514
|
-
${e.map(
|
|
6592
|
+
${e.map(
|
|
6593
|
+
(t) => `
|
|
6515
6594
|
<div style="height: ${this.hourHeight}px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;">
|
|
6516
6595
|
${t === 0 ? "" : this.formatHour(t)}
|
|
6517
6596
|
</div>
|
|
6518
|
-
`
|
|
6597
|
+
`
|
|
6598
|
+
).join("")}
|
|
6519
6599
|
</div>
|
|
6520
6600
|
`;
|
|
6521
6601
|
}
|
|
@@ -6538,7 +6618,12 @@ class L extends H {
|
|
|
6538
6618
|
const t = e.target.closest(".fc-day-column");
|
|
6539
6619
|
if (!t || !this.container.contains(t) || e.target.closest(".fc-event")) return;
|
|
6540
6620
|
const s = new Date(t.dataset.date), i = t.getBoundingClientRect(), r = this.container.querySelector("#day-scroll-container"), n = e.clientY - i.top + (r ? r.scrollTop : 0);
|
|
6541
|
-
s.setHours(
|
|
6621
|
+
s.setHours(
|
|
6622
|
+
Math.floor(n / this.hourHeight),
|
|
6623
|
+
Math.floor(n % this.hourHeight / (this.hourHeight / 60)),
|
|
6624
|
+
0,
|
|
6625
|
+
0
|
|
6626
|
+
), this.stateManager.selectDate(s);
|
|
6542
6627
|
}), this.attachCommonEventHandlers();
|
|
6543
6628
|
}
|
|
6544
6629
|
_scrollToCurrentTime() {
|
|
@@ -6782,7 +6867,8 @@ class re extends O {
|
|
|
6782
6867
|
<div class="form-group">
|
|
6783
6868
|
<label id="color-label">Color</label>
|
|
6784
6869
|
<div class="color-options" id="color-picker" role="radiogroup" aria-labelledby="color-label">
|
|
6785
|
-
${this.config.colors.map(
|
|
6870
|
+
${this.config.colors.map(
|
|
6871
|
+
(e) => `
|
|
6786
6872
|
<button type="button"
|
|
6787
6873
|
class="color-btn ${e.color === this._formData.color ? "selected" : ""}"
|
|
6788
6874
|
style="background-color: ${e.color}"
|
|
@@ -6791,7 +6877,8 @@ class re extends O {
|
|
|
6791
6877
|
aria-label="${e.label}"
|
|
6792
6878
|
aria-checked="${e.color === this._formData.color ? "true" : "false"}"
|
|
6793
6879
|
role="radio"></button>
|
|
6794
|
-
`
|
|
6880
|
+
`
|
|
6881
|
+
).join("")}
|
|
6795
6882
|
</div>
|
|
6796
6883
|
</div>
|
|
6797
6884
|
</div>
|
|
@@ -6821,7 +6908,7 @@ class re extends O {
|
|
|
6821
6908
|
});
|
|
6822
6909
|
}
|
|
6823
6910
|
open(e = /* @__PURE__ */ new Date()) {
|
|
6824
|
-
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 =
|
|
6911
|
+
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 = H.trapFocus(this.modalContent));
|
|
6825
6912
|
}
|
|
6826
6913
|
close() {
|
|
6827
6914
|
this.removeAttribute("open"), this._cleanupFocusTrap && (this._cleanupFocusTrap(), this._cleanupFocusTrap = null);
|
|
@@ -6869,29 +6956,47 @@ class ne extends O {
|
|
|
6869
6956
|
this.stateManager = new ie(e), this.stateManager.subscribe(this.handleStateChange.bind(this)), this.setupEventListeners();
|
|
6870
6957
|
}
|
|
6871
6958
|
setupEventListeners() {
|
|
6872
|
-
this._busUnsubscribers.forEach((t) => t()), this._busUnsubscribers = [], this._busUnsubscribers.push(
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6959
|
+
this._busUnsubscribers.forEach((t) => t()), this._busUnsubscribers = [], this._busUnsubscribers.push(
|
|
6960
|
+
u.on("navigation:*", (t, s) => {
|
|
6961
|
+
this.emit("calendar-navigate", { action: s.split(":")[1], ...t });
|
|
6962
|
+
})
|
|
6963
|
+
), this._busUnsubscribers.push(
|
|
6964
|
+
u.on("view:changed", (t) => {
|
|
6965
|
+
this.emit("calendar-view-change", t);
|
|
6966
|
+
})
|
|
6967
|
+
);
|
|
6877
6968
|
const e = (t, s) => {
|
|
6878
6969
|
this.emit(`calendar-event-${t}`, s);
|
|
6879
6970
|
};
|
|
6880
|
-
this._busUnsubscribers.push(
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6971
|
+
this._busUnsubscribers.push(
|
|
6972
|
+
u.on("event:add", (t) => {
|
|
6973
|
+
e("add", t);
|
|
6974
|
+
})
|
|
6975
|
+
), this._busUnsubscribers.push(
|
|
6976
|
+
u.on("event:update", (t) => {
|
|
6977
|
+
e("update", t);
|
|
6978
|
+
})
|
|
6979
|
+
), this._busUnsubscribers.push(
|
|
6980
|
+
u.on("event:remove", (t) => {
|
|
6981
|
+
e("remove", t);
|
|
6982
|
+
})
|
|
6983
|
+
), this._busUnsubscribers.push(
|
|
6984
|
+
u.on("event:added", (t) => {
|
|
6985
|
+
e("add", t), this.emit("calendar-event-added", t);
|
|
6986
|
+
})
|
|
6987
|
+
), this._busUnsubscribers.push(
|
|
6988
|
+
u.on("event:updated", (t) => {
|
|
6989
|
+
e("update", t), this.emit("calendar-event-updated", t);
|
|
6990
|
+
})
|
|
6991
|
+
), this._busUnsubscribers.push(
|
|
6992
|
+
u.on("event:deleted", (t) => {
|
|
6993
|
+
e("remove", t), this.emit("calendar-event-deleted", t);
|
|
6994
|
+
})
|
|
6995
|
+
), this._busUnsubscribers.push(
|
|
6996
|
+
u.on("date:selected", (t) => {
|
|
6997
|
+
this.emit("calendar-date-select", t);
|
|
6998
|
+
})
|
|
6999
|
+
);
|
|
6895
7000
|
}
|
|
6896
7001
|
handleStateChange(e, t) {
|
|
6897
7002
|
var o, c;
|
|
@@ -7361,7 +7466,7 @@ class ne extends O {
|
|
|
7361
7466
|
return `
|
|
7362
7467
|
<div class="force-calendar">
|
|
7363
7468
|
<div class="fc-error">
|
|
7364
|
-
<p><strong>Error:</strong> ${
|
|
7469
|
+
<p><strong>Error:</strong> ${H.escapeHTML(r.message || "An error occurred")}</p>
|
|
7365
7470
|
</div>
|
|
7366
7471
|
</div>
|
|
7367
7472
|
`;
|
|
@@ -7552,8 +7657,8 @@ customElements.get("forcecal-main") || customElements.define("forcecal-main", ne
|
|
|
7552
7657
|
typeof window < "u" && typeof customElements < "u" && console.log("Force Calendar Interface loading...");
|
|
7553
7658
|
export {
|
|
7554
7659
|
O as BaseComponent,
|
|
7555
|
-
|
|
7556
|
-
|
|
7660
|
+
F as BaseViewRenderer,
|
|
7661
|
+
H as DOMUtils,
|
|
7557
7662
|
E as DateUtils,
|
|
7558
7663
|
L as DayViewRenderer,
|
|
7559
7664
|
se as EventBus,
|