@iamproperty/components 7.2.2--beta3 → 7.4.0
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/assets/css/components/actionbar.component.css +1 -1
- package/assets/css/components/actionbar.component.css.map +1 -1
- package/assets/css/components/actionbar.global.css +1 -1
- package/assets/css/components/actionbar.global.css.map +1 -1
- package/assets/css/components/barchart.component.css +1 -1
- package/assets/css/components/barchart.component.css.map +1 -1
- package/assets/css/components/bento-grid.global.css.map +1 -1
- package/assets/css/components/calendar.component.css +1 -0
- package/assets/css/components/calendar.component.css.map +1 -0
- package/assets/css/components/calendar.config.css +1 -0
- package/assets/css/components/calendar.config.css.map +1 -0
- package/assets/css/components/card.component.css +1 -1
- package/assets/css/components/card.component.css.map +1 -1
- package/assets/css/components/carousel.component.css +1 -1
- package/assets/css/components/carousel.component.css.map +1 -1
- package/assets/css/components/charts.module.css.map +1 -1
- package/assets/css/components/collapsible-side.css +1 -1
- package/assets/css/components/collapsible-side.css.map +1 -1
- package/assets/css/components/content.component.css +1 -0
- package/assets/css/components/content.component.css.map +1 -0
- package/assets/css/components/doughnutchart.component.css +1 -1
- package/assets/css/components/doughnutchart.component.css.map +1 -1
- package/assets/css/components/fileupload.css.map +1 -1
- package/assets/css/components/inline-edit.css +1 -1
- package/assets/css/components/inline-edit.css.map +1 -1
- package/assets/css/components/marketing.component.css +1 -0
- package/assets/css/components/marketing.component.css.map +1 -0
- package/assets/css/components/menu.component.css +1 -1
- package/assets/css/components/menu.component.css.map +1 -1
- package/assets/css/components/menu.css +1 -1
- package/assets/css/components/menu.css.map +1 -1
- package/assets/css/components/milestone.css +1 -0
- package/assets/css/components/milestone.css.map +1 -0
- package/assets/css/components/multiselect.css +1 -1
- package/assets/css/components/multiselect.css.map +1 -1
- package/assets/css/components/nav.component.css +1 -1
- package/assets/css/components/nav.component.css.map +1 -1
- package/assets/css/components/nav.global.css +1 -1
- package/assets/css/components/nav.global.css.map +1 -1
- package/assets/css/components/pagination.css.map +1 -1
- package/assets/css/components/rank.component.css +1 -1
- package/assets/css/components/rank.component.css.map +1 -1
- package/assets/css/components/rankings.component.css +1 -1
- package/assets/css/components/rankings.component.css.map +1 -1
- package/assets/css/components/rankings.global.css +1 -1
- package/assets/css/components/rankings.global.css.map +1 -1
- package/assets/css/components/slider.css.map +1 -1
- package/assets/css/components/split-button.component.css +1 -0
- package/assets/css/components/split-button.component.css.map +1 -0
- package/assets/css/components/table-basic.global.css.map +1 -1
- package/assets/css/components/table.global.css.map +1 -1
- package/assets/css/core.min.css +1 -1
- package/assets/css/core.min.css.map +1 -1
- package/assets/css/mobile-core.min.css +1 -1
- package/assets/css/mobile-core.min.css.map +1 -1
- package/assets/css/mobile.min.css +1 -1
- package/assets/css/mobile.min.css.map +1 -1
- package/assets/css/style.min.css +1 -1
- package/assets/css/style.min.css.map +1 -1
- package/assets/js/components/accordion/accordion.component.min.js +1 -1
- package/assets/js/components/actionbar/actionbar.component.js +51 -31
- package/assets/js/components/actionbar/actionbar.component.min.js +17 -17
- package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
- package/assets/js/components/address-lookup/address-lookup.component.min.js +1 -1
- package/assets/js/components/advanced-select/advanced-select.component.js +63 -0
- package/assets/js/components/advanced-select/advanced-select.component.min.js +23 -0
- package/assets/js/components/advanced-select/advanced-select.component.min.js.map +1 -0
- package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
- package/assets/js/components/barchart/barchart.component.min.js +2 -2
- package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
- package/assets/js/components/calendar/calendar.component.js +1083 -0
- package/assets/js/components/calendar/calendar.component.min.js +170 -0
- package/assets/js/components/calendar/calendar.component.min.js.map +1 -0
- package/assets/js/components/card/card.component.js +20 -8
- package/assets/js/components/card/card.component.min.js +10 -10
- package/assets/js/components/card/card.component.min.js.map +1 -1
- package/assets/js/components/carousel/carousel.component.min.js +2 -2
- package/assets/js/components/collapsible-side/collapsible-side.component.js +47 -12
- package/assets/js/components/collapsible-side/collapsible-side.component.min.js +6 -5
- package/assets/js/components/collapsible-side/collapsible-side.component.min.js.map +1 -1
- package/assets/js/components/content/content.component.js +66 -0
- package/assets/js/components/content/content.component.min.js +15 -0
- package/assets/js/components/content/content.component.min.js.map +1 -0
- package/assets/js/components/doughnutchart/doughnutchart.component.min.js +2 -2
- package/assets/js/components/fileupload/fileupload.component.min.js +1 -1
- package/assets/js/components/filter-card/filter-card.component.min.js +1 -1
- package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
- package/assets/js/components/header/header.component.min.js +1 -1
- package/assets/js/components/inline-edit/inline-edit.component.min.js +5 -5
- package/assets/js/components/marketing/marketing.component.js +1 -1
- package/assets/js/components/marketing/marketing.component.min.js +2 -2
- package/assets/js/components/marketing/marketing.component.min.js.map +1 -1
- package/assets/js/components/menu/menu.component.js +148 -161
- package/assets/js/components/menu/menu.component.min.js +4 -69
- package/assets/js/components/menu/menu.component.min.js.map +1 -1
- package/assets/js/components/milestone/milestone.component.js +38 -0
- package/assets/js/components/milestone/milestone.component.min.js +15 -0
- package/assets/js/components/milestone/milestone.component.min.js.map +1 -0
- package/assets/js/components/milestone-group/milestone-group.component.js +35 -0
- package/assets/js/components/milestone-group/milestone-group.component.min.js +13 -0
- package/assets/js/components/milestone-group/milestone-group.component.min.js.map +1 -0
- package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
- package/assets/js/components/multiselect/multiselect.component.js +54 -2
- package/assets/js/components/multiselect/multiselect.component.min.js +5 -5
- package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -1
- package/assets/js/components/nav/nav.component.js +19 -0
- package/assets/js/components/nav/nav.component.min.js +6 -6
- package/assets/js/components/nav/nav.component.min.js.map +1 -1
- package/assets/js/components/notification/notification.component.js +17 -11
- package/assets/js/components/notification/notification.component.min.js +4 -4
- package/assets/js/components/notification/notification.component.min.js.map +1 -1
- package/assets/js/components/pagination/pagination.component.min.js +1 -1
- package/assets/js/components/rank/rank.component.js +346 -210
- package/assets/js/components/rank/rank.component.min.js +346 -211
- package/assets/js/components/rank/rank.component.min.js.map +1 -1
- package/assets/js/components/rankings/rankings.component.js +17 -8
- package/assets/js/components/rankings/rankings.component.min.js +14 -8
- package/assets/js/components/rankings/rankings.component.min.js.map +1 -1
- package/assets/js/components/record-card/record-card.component.min.js +1 -1
- package/assets/js/components/search/search.component.js +5 -3
- package/assets/js/components/search/search.component.min.js +6 -6
- package/assets/js/components/search/search.component.min.js.map +1 -1
- package/assets/js/components/slider/slider.component.min.js +1 -1
- package/assets/js/components/split-button/split-button.component.js +60 -0
- package/assets/js/components/split-button/split-button.component.min.js +34 -0
- package/assets/js/components/split-button/split-button.component.min.js.map +1 -0
- package/assets/js/components/table/table.component.js +12 -0
- package/assets/js/components/table/table.component.min.js +3 -3
- package/assets/js/components/table/table.component.min.js.map +1 -1
- package/assets/js/components/table-ajax/table-ajax.component.js +12 -0
- package/assets/js/components/table-ajax/table-ajax.component.min.js +3 -3
- package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -1
- package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
- package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -1
- package/assets/js/components/table-no-submit/table-no-submit.component.js +12 -0
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js +3 -3
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -1
- package/assets/js/components/table-submit/table-submit.component.js +12 -0
- package/assets/js/components/table-submit/table-submit.component.min.js +3 -3
- package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -1
- package/assets/js/components/tabs/tabs.component.min.js +1 -1
- package/assets/js/components/video-card/video-card.component.min.js +1 -1
- package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
- package/assets/js/components.js +58 -0
- package/assets/js/modules/advanced-select.js +106 -0
- package/assets/js/modules/dialogs.js +53 -51
- package/assets/js/modules/dynamicEvents.js +7 -0
- package/assets/js/modules/milestone-group.js +30 -0
- package/assets/js/modules/milestone.js +89 -0
- package/assets/js/modules/table.js +11 -1
- package/assets/js/modules/videos.js +1 -1
- package/assets/js/scripts.bundle.js +3 -3
- package/assets/js/scripts.bundle.js.map +1 -1
- package/assets/js/scripts.bundle.min.js +2 -2
- package/assets/js/scripts.bundle.min.js.map +1 -1
- package/assets/js/scripts.js +4 -0
- package/assets/sass/_components.scss +11 -0
- package/assets/sass/_functions/utility-mixins.scss +41 -0
- package/assets/sass/_functions/variables.scss +11 -8
- package/assets/sass/components/actionbar.component.scss +3 -4
- package/assets/sass/components/actionbar.global.scss +4 -4
- package/assets/sass/components/bento-grid.global.scss +0 -1
- package/assets/sass/components/calendar.component.scss +1380 -0
- package/assets/sass/components/calendar.config.scss +476 -0
- package/assets/sass/components/card.component.scss +4 -34
- package/assets/sass/components/carousel.component.scss +5 -0
- package/assets/sass/components/charts.module.scss +0 -2
- package/assets/sass/components/collapsible-side.scss +91 -95
- package/assets/sass/components/content.component.scss +18 -0
- package/assets/sass/components/inline-edit.scss +2 -0
- package/assets/sass/components/{marketing.scss → marketing.component.scss} +2 -6
- package/assets/sass/components/menu.component.scss +118 -31
- package/assets/sass/components/menu.scss +68 -7
- package/assets/sass/components/milestone.scss +207 -0
- package/assets/sass/components/multiselect.scss +3 -0
- package/assets/sass/components/nav.component.scss +1 -0
- package/assets/sass/components/nav.global.scss +30 -0
- package/assets/sass/components/rank.component.scss +197 -33
- package/assets/sass/components/rankings.component.scss +39 -35
- package/assets/sass/components/rankings.global.scss +66 -10
- package/assets/sass/components/split-button.component.scss +77 -0
- package/assets/sass/components/table-basic.global.scss +2 -4
- package/assets/sass/components/table.global.scss +4 -4
- package/assets/sass/elements/badge-tag.scss +5 -1
- package/assets/sass/elements/buttons--compact.scss +4 -0
- package/assets/sass/elements/buttons--global.scss +1 -1
- package/assets/sass/elements/details.scss +0 -1
- package/assets/sass/elements/dialog.scss +1 -3
- package/assets/sass/elements/forms.scss +148 -22
- package/assets/sass/elements/links.scss +132 -4
- package/assets/sass/elements/lists.scss +61 -0
- package/assets/sass/elements/popover.scss +64 -10
- package/assets/sass/elements/toggle-button.scss +7 -8
- package/assets/sass/elements/type.scss +7 -10
- package/assets/sass/foundations/reboot.scss +3 -3
- package/assets/sass/templates/form.scss +0 -2
- package/assets/ts/components/actionbar/actionbar.component.ts +49 -23
- package/assets/ts/components/advanced-select/advanced-select.component.ts +74 -0
- package/assets/ts/components/calendar/calendar.component.ts +1460 -0
- package/assets/ts/components/card/card.component.ts +22 -14
- package/assets/ts/components/collapsible-side/collapsible-side.component.ts +53 -12
- package/assets/ts/components/content/content.component.ts +78 -0
- package/assets/ts/components/marketing/marketing.component.ts +1 -1
- package/assets/ts/components/menu/menu.component.ts +162 -173
- package/assets/ts/components/milestone/milestone.component.ts +45 -0
- package/assets/ts/components/milestone-group/milestone-group.component.ts +41 -0
- package/assets/ts/components/multiselect/multiselect.component.ts +69 -3
- package/assets/ts/components/nav/nav.component.ts +25 -0
- package/assets/ts/components/notification/notification.component.ts +34 -11
- package/assets/ts/components/rank/rank.component.ts +345 -214
- package/assets/ts/components/rankings/rankings.component.ts +28 -15
- package/assets/ts/components/search/search.component.ts +6 -4
- package/assets/ts/components/split-button/split-button.component.ts +69 -0
- package/assets/ts/components/table/table.component.ts +14 -0
- package/assets/ts/components/table-ajax/table-ajax.component.ts +14 -0
- package/assets/ts/components/table-no-submit/table-no-submit.component.ts +14 -0
- package/assets/ts/components/table-submit/table-submit.component.ts +14 -0
- package/assets/ts/components/video-card/video-card.component.ts +2 -3
- package/assets/ts/components.ts +63 -0
- package/assets/ts/modules/advanced-select.ts +125 -0
- package/assets/ts/modules/dialogs.ts +64 -61
- package/assets/ts/modules/dynamicEvents.ts +12 -1
- package/assets/ts/modules/milestone-group.ts +42 -0
- package/assets/ts/modules/milestone.ts +122 -0
- package/assets/ts/modules/table.ts +15 -1
- package/assets/ts/modules/videos.ts +19 -37
- package/assets/ts/scripts.ts +5 -3
- package/dist/components.es.js +41 -1923
- package/dist/components.umd.js +127 -171
- package/package.json +1 -1
- package/src/components/AdvancedSelect/AdvancedSelect.vue +23 -0
- package/src/components/Calendar/Calendar.vue +26 -0
- package/src/components/Card/Card.vue +1 -1
- package/src/components/CollapsibleSideMenu/CollapsibleSideMenu.vue +7 -13
- package/src/components/Content/Content.vue +23 -0
- package/src/components/Milestones/Milestone.vue +27 -0
- package/src/components/Milestones/MilestoneGroup.vue +27 -0
- package/src/components/Rank/Rank.vue +1 -2
- package/src/components/Rankings/Rankings.vue +9 -10
- package/src/components/SplitButton/README.md +19 -0
- package/src/components/SplitButton/SplitButton.vue +26 -0
- package/src/index.js +44 -41
- package/assets/css/components/marketing.css +0 -1
- package/assets/css/components/marketing.css.map +0 -1
- package/assets/css/components/nav.old.css +0 -1
- package/assets/css/components/nav.old.css.map +0 -1
- package/assets/sass/components/nav.old.scss +0 -891
|
@@ -0,0 +1,1083 @@
|
|
|
1
|
+
import { trackComponent, trackComponentRegistered } from '../_global.js';
|
|
2
|
+
import { uniqueID } from '../../modules/helpers.js';
|
|
3
|
+
trackComponentRegistered('iam-calendar');
|
|
4
|
+
class iamCalendar extends HTMLElement {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
this.attachShadow({ mode: 'open' });
|
|
8
|
+
const assetLocation = document.body.hasAttribute('data-assets-location')
|
|
9
|
+
? document.body.getAttribute('data-assets-location')
|
|
10
|
+
: '/assets';
|
|
11
|
+
const loadCSS = `@import "${assetLocation}/css/components/calendar.component.css";`;
|
|
12
|
+
const weekViewOnly = `<table class="table--day" role="presentation"><tbody>
|
|
13
|
+
<tr class="allday"><th>All day</th></tr>
|
|
14
|
+
<tr><th data-hour="0">00</th></tr>
|
|
15
|
+
<tr><th data-hour="1">01</th></tr>
|
|
16
|
+
<tr><th data-hour="2">02</th></tr>
|
|
17
|
+
<tr><th data-hour="3">03</th></tr>
|
|
18
|
+
<tr><th data-hour="4">04</th></tr>
|
|
19
|
+
<tr><th data-hour="5">05</th></tr>
|
|
20
|
+
<tr><th data-hour="6">06</th></tr>
|
|
21
|
+
<tr><th data-hour="7">07</th></tr>
|
|
22
|
+
<tr><th data-hour="8">08</th></tr>
|
|
23
|
+
<tr><th data-hour="9">09</th></tr>
|
|
24
|
+
<tr><th data-hour="10">10</th></tr>
|
|
25
|
+
<tr><th data-hour="11">11</th></tr>
|
|
26
|
+
<tr><th data-hour="12">12</th></tr>
|
|
27
|
+
<tr><th data-hour="13">13</th></tr>
|
|
28
|
+
<tr><th data-hour="14">14</th></tr>
|
|
29
|
+
<tr><th data-hour="15">15</th></tr>
|
|
30
|
+
<tr><th data-hour="16">16</th></tr>
|
|
31
|
+
<tr><th data-hour="17">17</th></tr>
|
|
32
|
+
<tr><th data-hour="18">18</th></tr>
|
|
33
|
+
<tr><th data-hour="19">19</th></tr>
|
|
34
|
+
<tr><th data-hour="20">20</th></tr>
|
|
35
|
+
<tr><th data-hour="21">21</th></tr>
|
|
36
|
+
<tr><th data-hour="22">22</th></tr>
|
|
37
|
+
<tr><th data-hour="23">23</th></tr>
|
|
38
|
+
</tbody></table>`;
|
|
39
|
+
const template = document.createElement('template');
|
|
40
|
+
template.innerHTML = `
|
|
41
|
+
<style>
|
|
42
|
+
${loadCSS}
|
|
43
|
+
${this.hasAttribute('css') ? `@import "${this.getAttribute('css')}";` : ``}
|
|
44
|
+
</style>
|
|
45
|
+
<div class="calendar__container">
|
|
46
|
+
|
|
47
|
+
<div class="calendar__controls">
|
|
48
|
+
<button id="today-button" class="btn btn-action">Today</button>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
<button id="prev-button" class="btn btn-action fa-chevron-left border-0"><span class="visually-hidden">previous</span></button>
|
|
52
|
+
<div class="calendar__datepicker">
|
|
53
|
+
<span class="calendar__title"></span>
|
|
54
|
+
<input type="date" id="date" name="date" />
|
|
55
|
+
</div>
|
|
56
|
+
<button id="next-button" class="btn btn-action fa-chevron-right border-0"><span class="visually-hidden">Next</span></button>
|
|
57
|
+
|
|
58
|
+
<hr/>
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
<select name="view" id="view" class="btn btn-action">
|
|
62
|
+
|
|
63
|
+
<button>
|
|
64
|
+
<selectedcontent></selectedcontent> <i class="fa-regular fa-chevron-down"></i>
|
|
65
|
+
</button>
|
|
66
|
+
|
|
67
|
+
<option value="month"><i class="fa-light fa-calendar-days"></i>Month</option>
|
|
68
|
+
<option value="week"><i class="fa-light fa-calendar-week"></i>Week</option>
|
|
69
|
+
<option value="day"><i class="fa-light fa-calendar-day"></i>Day</option>
|
|
70
|
+
<option value="list"><i class="fa-light fa-list"></i>List</option>
|
|
71
|
+
<option value="year"><i class="fa-light fa-calendars"></i>Year</option>
|
|
72
|
+
</select>
|
|
73
|
+
|
|
74
|
+
<label class="tag tag--toggle"><input type="checkbox" name="split" value="true">Split view</label>
|
|
75
|
+
|
|
76
|
+
<button id="filters-button" class="btn btn-action"><i class="fa-light fa-sliders"></i><span class="visually-hidden">Filters</span></button>
|
|
77
|
+
|
|
78
|
+
<button id="settings-button" class="btn btn-action"><i class="fa-light fa-gear"></i><span class="visually-hidden">Settings</span></button>
|
|
79
|
+
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<dialog id="settings">
|
|
83
|
+
<button class="dialog__close">Close</button>
|
|
84
|
+
<span class="h3">Calendar settings</span>
|
|
85
|
+
|
|
86
|
+
<fieldset id="workday" class="mb-5">
|
|
87
|
+
<label>Start time <span><input type="time" id="start-time" name="start-time" step="3600" value="08:00" /><span class="suffix fa-regular fa-clock" aria-hidden="true"></span></span></label>
|
|
88
|
+
<label>End time <span><input type="time" id="end-time" name="end-time" step="3600" value="18:00" /><span class="suffix fa-regular fa-clock" aria-hidden="true"></span></span></label>
|
|
89
|
+
|
|
90
|
+
</fieldset>
|
|
91
|
+
|
|
92
|
+
<hr/>
|
|
93
|
+
<fieldset>
|
|
94
|
+
<span class="label">Show weekends</span>
|
|
95
|
+
<input type="radio" name="weekends" id="weekends-yes" tabindex="-1">
|
|
96
|
+
<label for="weekends-yes" class="d-inline-block">Yes</label>
|
|
97
|
+
<input type="radio" name="weekends" id="weekends-no" tabindex="-1">
|
|
98
|
+
<label for="weekends-no" class="d-inline-block">No</label>
|
|
99
|
+
</fieldset>
|
|
100
|
+
<hr/>
|
|
101
|
+
<button class="btn btn-primary">Save settings</button>
|
|
102
|
+
<button class="btn btn-secondary">Cancel</button>
|
|
103
|
+
|
|
104
|
+
</dialog>
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
<div class="calendar__wrapper">
|
|
108
|
+
|
|
109
|
+
<div id="week-view-corner" class="calendar">
|
|
110
|
+
<table>
|
|
111
|
+
<thead>
|
|
112
|
+
<tr>
|
|
113
|
+
<th class="column-header">Empty</th>
|
|
114
|
+
</tr>
|
|
115
|
+
</thead>
|
|
116
|
+
<tbody>
|
|
117
|
+
<tr class="allday">
|
|
118
|
+
<th>All day</th>
|
|
119
|
+
</tr>
|
|
120
|
+
</tbody>
|
|
121
|
+
</table>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div id="week-view-header" class="calendar">
|
|
125
|
+
<table>
|
|
126
|
+
<thead>
|
|
127
|
+
</thead>
|
|
128
|
+
<tbody>
|
|
129
|
+
</tbody>
|
|
130
|
+
</table>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div id="week-view-side">${weekViewOnly}</div>
|
|
134
|
+
|
|
135
|
+
<div class="calendar month-wrapper" id="calendar" part="calendar">
|
|
136
|
+
<table>
|
|
137
|
+
<thead>
|
|
138
|
+
</thead>
|
|
139
|
+
<tbody>
|
|
140
|
+
</tbody>
|
|
141
|
+
</table>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<div id="year-view">
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
<slot></slot>
|
|
150
|
+
|
|
151
|
+
</div>
|
|
152
|
+
`;
|
|
153
|
+
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
|
154
|
+
this.monthArray = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
155
|
+
this.dayArray = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
156
|
+
this.english_ordinal_rules = new Intl.PluralRules("en", { type: "ordinal" });
|
|
157
|
+
this.suffixes = {
|
|
158
|
+
one: "st",
|
|
159
|
+
two: "nd",
|
|
160
|
+
few: "rd",
|
|
161
|
+
other: "th"
|
|
162
|
+
};
|
|
163
|
+
this.calendars = ['Default']; // TO DO allow for these to be set via the component data attributes
|
|
164
|
+
this.eventTypes = []; // TO DO allow for these to be set via the component data attributes
|
|
165
|
+
this.pauseObserver = false;
|
|
166
|
+
}
|
|
167
|
+
createThead(sundayFirst) {
|
|
168
|
+
if (sundayFirst)
|
|
169
|
+
return `<tr>
|
|
170
|
+
<th class="column-header sunday"><span class="long-day-name">Sunday</span><span class="short-day-name" role="presentation">Sun</span></th>
|
|
171
|
+
<th class="column-header monday"><span class="long-day-name">Monday</span><span class="short-day-name" role="presentation">Mon</span></th>
|
|
172
|
+
<th class="column-header tuesday"><span class="long-day-name">Tuesday</span><span class="short-day-name" role="presentation">Tues</span></th>
|
|
173
|
+
<th class="column-header wednesday"><span class="long-day-name">Wednesday</span><span class="short-day-name" role="presentation">Wed</span></th>
|
|
174
|
+
<th class="column-header thursday"><span class="long-day-name">Thursday</span><span class="short-day-name" role="presentation">Thurs</span></th>
|
|
175
|
+
<th class="column-header friday"><span class="long-day-name">Friday</span><span class="short-day-name" role="presentation">Fri</span></th>
|
|
176
|
+
<th class="column-header saturday"><span class="long-day-name">Saturday</span><span class="short-day-name" role="presentation">Sat</span></th>
|
|
177
|
+
</tr>`;
|
|
178
|
+
return `<tr>
|
|
179
|
+
<th class="column-header monday"><span class="long-day-name">Monday</span><span class="short-day-name" role="presentation">Mon</span></th>
|
|
180
|
+
<th class="column-header tuesday"><span class="long-day-name">Tuesday</span><span class="short-day-name" role="presentation">Tues</span></th>
|
|
181
|
+
<th class="column-header wednesday"><span class="long-day-name">Wednesday</span><span class="short-day-name" role="presentation">Wed</span></th>
|
|
182
|
+
<th class="column-header thursday"><span class="long-day-name">Thursday</span><span class="short-day-name" role="presentation">Thurs</span></th>
|
|
183
|
+
<th class="column-header friday"><span class="long-day-name">Friday</span><span class="short-day-name" role="presentation">Fri</span></th>
|
|
184
|
+
<th class="column-header saturday"><span class="long-day-name">Saturday</span><span class="short-day-name" role="presentation">Sat</span></th>
|
|
185
|
+
<th class="column-header sunday"><span class="long-day-name">Sunday</span><span class="short-day-name" role="presentation">Sun</span></th>
|
|
186
|
+
</tr>`;
|
|
187
|
+
}
|
|
188
|
+
numberDaysInMonth(year, month) {
|
|
189
|
+
return new Date(year, month, 0).getDate();
|
|
190
|
+
}
|
|
191
|
+
getOrdinalNumber(number) {
|
|
192
|
+
const category = this.english_ordinal_rules.select(number);
|
|
193
|
+
const suffix = this.suffixes[category];
|
|
194
|
+
return (number + suffix);
|
|
195
|
+
}
|
|
196
|
+
setToMonday(date) {
|
|
197
|
+
const day = date.getDay() || 7;
|
|
198
|
+
if (day !== 1)
|
|
199
|
+
date.setHours(-24 * (day - 1));
|
|
200
|
+
return date;
|
|
201
|
+
}
|
|
202
|
+
setToSunday(date) {
|
|
203
|
+
const monday = this.setToMonday(date);
|
|
204
|
+
const sunday = new Date(monday);
|
|
205
|
+
sunday.setDate(sunday.getDate() + 6);
|
|
206
|
+
return sunday;
|
|
207
|
+
}
|
|
208
|
+
getTitle(dateStr, view) {
|
|
209
|
+
const date = new Date(dateStr);
|
|
210
|
+
const month = date.getMonth();
|
|
211
|
+
const year = date.getFullYear();
|
|
212
|
+
const day = date.getDate();
|
|
213
|
+
const dayOfWeek = date.getDay() ? date.getDay() : 7;
|
|
214
|
+
if (view == "week") {
|
|
215
|
+
const monday = this.setToMonday(new Date(dateStr));
|
|
216
|
+
const sunday = this.setToSunday(new Date(dateStr));
|
|
217
|
+
const mondayMonth = monday.getMonth();
|
|
218
|
+
const mondayYear = monday.getFullYear();
|
|
219
|
+
const mondayDay = monday.getDate();
|
|
220
|
+
const sundayMonth = sunday.getMonth();
|
|
221
|
+
const sundayYear = sunday.getFullYear();
|
|
222
|
+
const sundayDay = sunday.getDate();
|
|
223
|
+
return `${this.getOrdinalNumber(mondayDay)} ${mondayMonth != sundayMonth ? this.monthArray[sundayMonth] : ''} ${mondayYear != sundayYear ? mondayYear : ''} - ${this.getOrdinalNumber(sundayDay)} ${this.monthArray[sundayMonth]} ${sundayYear}`;
|
|
224
|
+
}
|
|
225
|
+
else if (view == "day") {
|
|
226
|
+
return `${this.dayArray[dayOfWeek]} ${this.getOrdinalNumber(day)} ${this.monthArray[month]} ${year}`;
|
|
227
|
+
}
|
|
228
|
+
else if (view == "year") {
|
|
229
|
+
return `${year}`;
|
|
230
|
+
}
|
|
231
|
+
return `${this.monthArray[month]} ${year}`;
|
|
232
|
+
}
|
|
233
|
+
createCalendar(selectedDate, today, sundayFirst) {
|
|
234
|
+
const date = new Date(selectedDate);
|
|
235
|
+
const month = date.getMonth();
|
|
236
|
+
const year = date.getFullYear();
|
|
237
|
+
const day = date.getDate();
|
|
238
|
+
const selectedDateStr = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
239
|
+
const daysThisMonth = this.numberDaysInMonth(year, month + 1);
|
|
240
|
+
const startOfMonth = new Date(`${year}-${String(month + 1).padStart(2, "0")}-01`);
|
|
241
|
+
const endOfMonth = new Date(`${year}-${String(month + 1).padStart(2, "0")}-${daysThisMonth}`);
|
|
242
|
+
const startDay = startOfMonth.getDay() != 0 ? startOfMonth.getDay() : 7;
|
|
243
|
+
const endDay = endOfMonth.getDay() != 0 ? endOfMonth.getDay() : 7;
|
|
244
|
+
const loopDays = daysThisMonth + startDay + (7 - endDay - 1);
|
|
245
|
+
// Get the previous month
|
|
246
|
+
const prevMonthDate = new Date(selectedDate);
|
|
247
|
+
prevMonthDate.setMonth(prevMonthDate.getMonth() - 1);
|
|
248
|
+
const prevMonth = prevMonthDate.getMonth();
|
|
249
|
+
const prevMonthYear = prevMonthDate.getFullYear();
|
|
250
|
+
const daysPrevMonth = this.numberDaysInMonth(year, month);
|
|
251
|
+
// Get the next month
|
|
252
|
+
const nextMonthDate = new Date(selectedDate);
|
|
253
|
+
nextMonthDate.setMonth(nextMonthDate.getMonth() + 1);
|
|
254
|
+
const nextMonth = nextMonthDate.getMonth();
|
|
255
|
+
const nextMonthYear = nextMonthDate.getFullYear();
|
|
256
|
+
// Get calendars
|
|
257
|
+
if (!this.hasAttribute('data-calendars')) {
|
|
258
|
+
Array.from(this.querySelectorAll('button[data-calendar]')).forEach((element) => {
|
|
259
|
+
// Scan through the buttons and look forunique calendar names
|
|
260
|
+
if (!(this.calendars.includes(element.getAttribute('data-calendar'))))
|
|
261
|
+
this.calendars.push(element.getAttribute('data-calendar'));
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
// Create tbody string by looping through the number of days in month plus some days before and after
|
|
265
|
+
let tbodyContent = `<tr>`;
|
|
266
|
+
for (let i = (sundayFirst ? 0 : 1); i <= loopDays; i++) {
|
|
267
|
+
const loopDay = i - (startDay - 1);
|
|
268
|
+
const loopDate = `${year}-${String(month + 1).padStart(2, "0")}-${String(loopDay).padStart(2, "0")}`;
|
|
269
|
+
const dayOfWeek = i % 7;
|
|
270
|
+
tbodyContent += `<td class="day--${this.dayArray[dayOfWeek].toLowerCase()} ${loopDate == today ? 'today' : ''} ${loopDate == selectedDateStr ? 'selected' : ''} ${i < startDay ? 'prev-month' : ''} ${loopDay > daysThisMonth ? 'next-month' : ''}">`;
|
|
271
|
+
// prev month days
|
|
272
|
+
if (i < startDay) {
|
|
273
|
+
const adjustedLoopDay = daysPrevMonth - (startDay - 1 - i);
|
|
274
|
+
const adjustedLoopDate = `${prevMonthYear}-${String(prevMonth + 1).padStart(2, "0")}-${String(adjustedLoopDay).padStart(2, "0")}`;
|
|
275
|
+
tbodyContent += `<time class="column-header" datetime="${adjustedLoopDate}" title="${this.dayArray[dayOfWeek]} ${loopDay} ${this.monthArray[prevMonth]} ${year}"><span class="day-of-week">${this.dayArray[dayOfWeek]} </span><span class="day">${adjustedLoopDay}</span> <span class="month">${this.monthArray[prevMonth]}</span></time>`;
|
|
276
|
+
tbodyContent += this.addDay(adjustedLoopDate, this.calendars);
|
|
277
|
+
}
|
|
278
|
+
if (i >= startDay && loopDay <= daysThisMonth) {
|
|
279
|
+
tbodyContent += `<time class="column-header" datetime="${loopDate}" title="${this.dayArray[dayOfWeek]} ${loopDay} ${this.monthArray[month]} ${year}"><span class="day-of-week">${this.dayArray[dayOfWeek]} </span><span class="day">${loopDay}</span> <span class="month">${this.monthArray[month]}</span></time>`;
|
|
280
|
+
tbodyContent += this.addDay(loopDate, this.calendars);
|
|
281
|
+
}
|
|
282
|
+
// next month days
|
|
283
|
+
if (loopDay > daysThisMonth) {
|
|
284
|
+
const adjustedLoopDay = i - (startDay - 1) - daysThisMonth;
|
|
285
|
+
const adjustedLoopDate = `${nextMonthYear}-${String(nextMonth + 1).padStart(2, "0")}-${String(adjustedLoopDay).padStart(2, "0")}`;
|
|
286
|
+
tbodyContent += `<time class="column-header" datetime="${adjustedLoopDate}" title="${this.dayArray[dayOfWeek]} ${loopDay} ${this.monthArray[nextMonth]} ${year}"><span class="day-of-week">${this.dayArray[dayOfWeek]} </span><span class="day">${adjustedLoopDay}</span> <span class="month">${this.monthArray[nextMonth]}</span></time>`;
|
|
287
|
+
tbodyContent += this.addDay(adjustedLoopDate, this.calendars);
|
|
288
|
+
}
|
|
289
|
+
tbodyContent += '</td>';
|
|
290
|
+
// Close row and start a new one
|
|
291
|
+
if (((sundayFirst ? i + 1 : i) % 7) === 0 && i != loopDays) {
|
|
292
|
+
tbodyContent += `</tr><tr>`;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
tbodyContent += '</tr>';
|
|
296
|
+
return tbodyContent;
|
|
297
|
+
}
|
|
298
|
+
addDay(day, calendars) {
|
|
299
|
+
let htmlTable = '<table class="table--day">';
|
|
300
|
+
htmlTable += `<thead><tr><th>time</th>`;
|
|
301
|
+
calendars.forEach(calendarTitle => {
|
|
302
|
+
htmlTable += `<th class="column-header">${calendarTitle}</th>`;
|
|
303
|
+
});
|
|
304
|
+
htmlTable += `</tr></thead>`;
|
|
305
|
+
htmlTable += `<tbody>`;
|
|
306
|
+
htmlTable += `<tr class="allday"><th>All day</th>`;
|
|
307
|
+
calendars.forEach(calendarTitle => {
|
|
308
|
+
htmlTable += `<td datetime="${day}" data-calendar="${calendarTitle}"><span datetime="${day}"></span></td>`;
|
|
309
|
+
});
|
|
310
|
+
htmlTable += `</tr>`;
|
|
311
|
+
for (let i = 0; i < 24; i++) {
|
|
312
|
+
htmlTable += `<tr class="hour${i}"><th data-hour="${i}">${i}${i < 12 ? 'am' : 'pm'}</th>`;
|
|
313
|
+
calendars.forEach(calendarTitle => {
|
|
314
|
+
htmlTable += `<td datetime="${day}T${String(i).padStart(2, "0")}:00" data-calendar="${calendarTitle}"><span datetime="${day}T${String(i).padStart(2, "0")}:00"></span><span datetime="${day}T${String(i).padStart(2, "0")}:15"></span><span datetime="${day}T${String(i).padStart(2, "0")}:30"></span><span datetime="${day}T${String(i).padStart(2, "0")}:45"></span></td>`;
|
|
315
|
+
});
|
|
316
|
+
htmlTable += `</tr>`;
|
|
317
|
+
}
|
|
318
|
+
htmlTable += `</tbody>`;
|
|
319
|
+
htmlTable += '</table>';
|
|
320
|
+
return htmlTable;
|
|
321
|
+
}
|
|
322
|
+
addEvents() {
|
|
323
|
+
function setDefaultEventValues(component, element, index) {
|
|
324
|
+
const datetime = element.getAttribute('datetime');
|
|
325
|
+
const datetimeArr = datetime.split('T');
|
|
326
|
+
let id = element.getAttribute('id');
|
|
327
|
+
// Add ID
|
|
328
|
+
if (!element.hasAttribute('id')) {
|
|
329
|
+
id = `event${uniqueID(index)}`;
|
|
330
|
+
element.setAttribute('id', id);
|
|
331
|
+
}
|
|
332
|
+
// Wrap content in span for formatting in week/day view
|
|
333
|
+
if (!element.querySelector('span:not(.tooltip__content')) {
|
|
334
|
+
element.innerHTML = `<span>${element.innerHTML}</span>`;
|
|
335
|
+
}
|
|
336
|
+
// Add event type enum so we can set the correct colours
|
|
337
|
+
//if(!element.hasAttribute('data-event-type-enum') && element.hasAttribute('data-event-type')){
|
|
338
|
+
const eventType = element.getAttribute('data-event-type');
|
|
339
|
+
if (!component.eventTypes.includes(eventType))
|
|
340
|
+
component.eventTypes.push(eventType);
|
|
341
|
+
element.setAttribute('data-event-type-enum', component.eventTypes.indexOf(eventType) + 1);
|
|
342
|
+
//}
|
|
343
|
+
// Add calendar enum so we can set the correct colours
|
|
344
|
+
if (element.hasAttribute('data-calendar')) {
|
|
345
|
+
const calendar = element.getAttribute('data-calendar');
|
|
346
|
+
if (!component.calendars.includes(calendar))
|
|
347
|
+
component.calendars.push(calendar);
|
|
348
|
+
element.setAttribute('data-calendar-enum', component.calendars.indexOf(calendar) + 1);
|
|
349
|
+
}
|
|
350
|
+
if (!element.hasAttribute('data-calendar-enum')) {
|
|
351
|
+
element.setAttribute('data-calendar-enum', 1);
|
|
352
|
+
}
|
|
353
|
+
if (!element.hasAttribute('data-hours') && !element.hasAttribute('data-days')) {
|
|
354
|
+
if (datetimeArr[1]) {
|
|
355
|
+
element.setAttribute('data-hours', 1);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
element.setAttribute('data-days', 1);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
let getRoundedDate = (minutes, d = new Date()) => {
|
|
362
|
+
let ms = 1000 * 60 * minutes; // convert minutes to ms
|
|
363
|
+
let roundedDate = new Date(Math.round(d.getTime() / ms) * ms);
|
|
364
|
+
const newMonth = roundedDate.getMonth();
|
|
365
|
+
const newYear = roundedDate.getFullYear();
|
|
366
|
+
const newDay = roundedDate.getDate();
|
|
367
|
+
const newMinutes = roundedDate.getMinutes();
|
|
368
|
+
const newHour = roundedDate.getHours();
|
|
369
|
+
const strRoundedDate = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-${String(newDay).padStart(2, "0")}T${String(newHour).padStart(2, "0")}:${String(newMinutes).padStart(2, "0")}`;
|
|
370
|
+
return strRoundedDate;
|
|
371
|
+
};
|
|
372
|
+
if (datetimeArr[1]) {
|
|
373
|
+
element.setAttribute('data-start', datetimeArr[1]);
|
|
374
|
+
element.querySelector(':scope > span').setAttribute('data-start', datetimeArr[1]);
|
|
375
|
+
const roundedDatetime = getRoundedDate(15, new Date(datetime));
|
|
376
|
+
element.setAttribute('datetime', roundedDatetime);
|
|
377
|
+
console.log(roundedDatetime);
|
|
378
|
+
}
|
|
379
|
+
if (element.querySelector('.tooltip__content')) {
|
|
380
|
+
const tooltip = element.querySelector('.tooltip__content');
|
|
381
|
+
tooltip.style.positionAnchor = `--${id}`;
|
|
382
|
+
element.style.anchorName = `--${id}`;
|
|
383
|
+
}
|
|
384
|
+
element.classList.add('defaults-added');
|
|
385
|
+
}
|
|
386
|
+
function adjustEvent(component, element, continued) {
|
|
387
|
+
var _a;
|
|
388
|
+
const datetime = element.getAttribute('datetime');
|
|
389
|
+
const date = new Date(datetime);
|
|
390
|
+
const dayOfWeek = date.getDay() ? date.getDay() : 7;
|
|
391
|
+
// Locate where we need to add slots for the buttons to go - We need duplicate slots for the split view and fixed header
|
|
392
|
+
const timeTd = component.shadowRoot.querySelector(`.month-wrapper .table--day td:has(span[datetime="${datetime}"])${element.hasAttribute('data-calendar') ? `[data-calendar="${element.getAttribute('data-calendar').replace('_', '')}"]` : ''}`);
|
|
393
|
+
const timeTdHeader = component.shadowRoot.querySelector(`#week-view-header .table--day td:has(span[datetime="${datetime}"])${element.hasAttribute('data-calendar') ? `[data-calendar="${element.getAttribute('data-calendar').replace('_', '')}"]` : ''}`);
|
|
394
|
+
if (timeTdHeader && timeTdHeader.closest('tr').classList.contains("allday")) {
|
|
395
|
+
// Add the alldays slot for the fixed header
|
|
396
|
+
if (!timeTdHeader.querySelector(`slot[name="${datetime}${element.hasAttribute('data-calendar') ? `-${element.getAttribute('data-calendar').replace('_', '')}` : ''}-header]"`)) {
|
|
397
|
+
timeTdHeader.querySelector(`span[datetime="${datetime}"]`).insertAdjacentHTML('beforeEnd', `<slot name="${datetime}${element.hasAttribute('data-calendar') ? `-${element.getAttribute('data-calendar').replace('_', '')}` : ''}-header" class="${continued ? 'continued' : ''}"></slot>`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const dateTd = (_a = timeTd === null || timeTd === void 0 ? void 0 : timeTd.parentElement) === null || _a === void 0 ? void 0 : _a.closest('td');
|
|
401
|
+
// original event needs a slot name adding
|
|
402
|
+
element.setAttribute('slot', `${datetime}${element.hasAttribute('data-calendar') ? `-${element.getAttribute('data-calendar').replace('_', '')}` : ''}`);
|
|
403
|
+
// Add matching slot to the event element to have it show in the correct place on the calendar
|
|
404
|
+
if (timeTd) {
|
|
405
|
+
// Add the default slot
|
|
406
|
+
if (!timeTd.querySelector(`slot[name="${datetime}${element.hasAttribute('data-calendar') ? `-${element.getAttribute('data-calendar').replace('_', '')}` : ''}"]`)) {
|
|
407
|
+
timeTd.querySelector(`span[datetime="${datetime}"]`).insertAdjacentHTML('beforeEnd', `<slot name="${datetime}${element.hasAttribute('data-calendar') ? `-${element.getAttribute('data-calendar').replace('_', '')}` : ''}" class="${continued ? 'continued' : ''}"></slot>`);
|
|
408
|
+
}
|
|
409
|
+
// Set the classes need to create the grey bars in the mobile month view
|
|
410
|
+
const events = dateTd.hasAttribute('data-events') ? parseInt(dateTd.getAttribute('data-events')) : 0;
|
|
411
|
+
let hours = dateTd.hasAttribute('data-hours') ? parseFloat(dateTd.getAttribute('data-hours')) : 0;
|
|
412
|
+
hours += element.hasAttribute('data-hours') ? parseFloat(element.getAttribute('data-hours')) : 0;
|
|
413
|
+
dateTd.setAttribute('data-events', parseInt(events) + 1);
|
|
414
|
+
if ((events + 1) > 2)
|
|
415
|
+
dateTd.setAttribute('data-more', (parseInt(events) + 1) - 2);
|
|
416
|
+
dateTd.setAttribute('data-hours', hours);
|
|
417
|
+
dateTd.classList.add('has-event');
|
|
418
|
+
if (timeTd.closest('tr').classList.contains('has-event'))
|
|
419
|
+
timeTd.closest('tr').classList.add('multiple-event');
|
|
420
|
+
else
|
|
421
|
+
timeTd.closest('tr').classList.add('has-event');
|
|
422
|
+
if (hours > 2)
|
|
423
|
+
dateTd.classList.add('multi-events');
|
|
424
|
+
if (hours > 4)
|
|
425
|
+
dateTd.classList.add('busy-day');
|
|
426
|
+
if (element.hasAttribute('data-days'))
|
|
427
|
+
dateTd.classList.add('all-day');
|
|
428
|
+
if (element.classList.contains('continued'))
|
|
429
|
+
dateTd.classList.add('continued-day');
|
|
430
|
+
}
|
|
431
|
+
// Add CSS properties so we can control the size of the event elements for day and week view
|
|
432
|
+
if (element.hasAttribute('data-hours'))
|
|
433
|
+
element.style.setProperty('--event-height', `${parseInt(element.getAttribute('data-hours')) * (1.09375 * 4)}rem`);
|
|
434
|
+
if (element.hasAttribute('data-days') && !element.classList.contains('processed')) {
|
|
435
|
+
const eventDayTotal = element.getAttribute('data-days');
|
|
436
|
+
element.style.setProperty('--event-width', `${eventDayTotal * 100}%`);
|
|
437
|
+
element.style.setProperty('--event-max-width', `${(8 - dayOfWeek) * 100}%`);
|
|
438
|
+
element.classList.add('allday-event');
|
|
439
|
+
// Create a duplicate event for each day the orginal
|
|
440
|
+
for (let i = 1; i < eventDayTotal; i++) {
|
|
441
|
+
const cloneElement = element.cloneNode(true);
|
|
442
|
+
cloneElement.removeAttribute('data-days');
|
|
443
|
+
cloneElement.removeAttribute('style');
|
|
444
|
+
cloneElement.classList.add('continued');
|
|
445
|
+
cloneElement.classList.add('allday-event');
|
|
446
|
+
const id = `event${uniqueID(i)}`;
|
|
447
|
+
cloneElement.setAttribute('id', id);
|
|
448
|
+
if (cloneElement.querySelector('.tooltip__content')) {
|
|
449
|
+
const tooltip = cloneElement.querySelector('.tooltip__content');
|
|
450
|
+
tooltip.style.positionAnchor = `--${id}`;
|
|
451
|
+
cloneElement.style.anchorName = `--${id}`;
|
|
452
|
+
}
|
|
453
|
+
const newDate = new Date(datetime);
|
|
454
|
+
newDate.setDate(newDate.getDate() + i);
|
|
455
|
+
const newMonth = newDate.getMonth();
|
|
456
|
+
const newYear = newDate.getFullYear();
|
|
457
|
+
const newDay = newDate.getDate();
|
|
458
|
+
const newDayOfWeek = newDate.getDay() ? newDate.getDay() : 7;
|
|
459
|
+
const strCloneEvent = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-${String(newDay).padStart(2, "0")}`;
|
|
460
|
+
cloneElement.setAttribute('data-original-datetime', element.getAttribute('datetime'));
|
|
461
|
+
cloneElement.setAttribute('datetime', strCloneEvent);
|
|
462
|
+
element.after(cloneElement); // Add after original
|
|
463
|
+
adjustEvent(component, cloneElement, true);
|
|
464
|
+
if (newDayOfWeek == 1) { // Monday
|
|
465
|
+
cloneElement.style.setProperty('--event-width', `${(eventDayTotal - i) * 100}%`);
|
|
466
|
+
cloneElement.style.setProperty('--event-max-width', `${(8 - newDayOfWeek) * 100}%`);
|
|
467
|
+
cloneElement.classList.remove('continued');
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
// Add flag so we dont have to re-do the above
|
|
472
|
+
element.classList.add('processed');
|
|
473
|
+
}
|
|
474
|
+
this.pauseObserver = true;
|
|
475
|
+
Array.from(this.querySelectorAll('button[datetime]')).forEach((element, index) => {
|
|
476
|
+
setDefaultEventValues(this, element, index);
|
|
477
|
+
adjustEvent(this, element);
|
|
478
|
+
});
|
|
479
|
+
setTimeout(() => {
|
|
480
|
+
this.pauseObserver = false;
|
|
481
|
+
}, "500");
|
|
482
|
+
}
|
|
483
|
+
addJSEvents(component) {
|
|
484
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
485
|
+
// Add events to the newly created calendar
|
|
486
|
+
const title = (_a = component.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.calendar__title');
|
|
487
|
+
const datePicker = (_b = component.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector(`#date`);
|
|
488
|
+
const viewPicker = (_c = component.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector(`#view`);
|
|
489
|
+
const yearView = (_d = this.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('#year-view');
|
|
490
|
+
const today = new Date();
|
|
491
|
+
const date = today.getDate();
|
|
492
|
+
const month = today.getMonth();
|
|
493
|
+
const year = today.getFullYear();
|
|
494
|
+
const strToday = `${year}-${String(month + 1).padStart(2, "0")}-${String(date).padStart(2, "0")}`;
|
|
495
|
+
const tbody = (_e = component.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('#calendar > table > tbody');
|
|
496
|
+
// clicking on the day istelf
|
|
497
|
+
Array.from(component.shadowRoot.querySelectorAll('.month-wrapper > table > tbody > tr > td:has(slot)')).forEach((element) => {
|
|
498
|
+
element.addEventListener('click', (event) => {
|
|
499
|
+
if (!event.target.matches('button')) {
|
|
500
|
+
const elementDate = element.querySelector('time').getAttribute('datetime');
|
|
501
|
+
datePicker.value = elementDate;
|
|
502
|
+
Array.from(tbody.querySelectorAll(':scope > tr > td')).forEach((innerelement) => {
|
|
503
|
+
innerelement.classList.remove('selected');
|
|
504
|
+
});
|
|
505
|
+
element.classList.add('selected');
|
|
506
|
+
// Go to day if the in month view with out split view enabled
|
|
507
|
+
if (component.shadowRoot.querySelector('[name="split"]:checked') && viewPicker.value == "month") {
|
|
508
|
+
Array.from(component.querySelectorAll(`[data-slot]`)).forEach((button) => {
|
|
509
|
+
button.setAttribute('slot', button.getAttribute('data-slot'));
|
|
510
|
+
});
|
|
511
|
+
Array.from(component.querySelectorAll(`[slot^="${datePicker.value}"]`)).forEach((button) => {
|
|
512
|
+
button.setAttribute('data-slot', button.getAttribute('slot'));
|
|
513
|
+
button.removeAttribute('slot');
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
else if (!component.shadowRoot.querySelector('[name="split"]:checked') && viewPicker.value == "month") {
|
|
517
|
+
viewPicker.value = "day";
|
|
518
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(datePicker.value, viewPicker.value);
|
|
519
|
+
component.scrollIntoPlace();
|
|
520
|
+
}
|
|
521
|
+
if (viewPicker.value == "year") {
|
|
522
|
+
viewPicker.value = "month";
|
|
523
|
+
yearView === null || yearView === void 0 ? void 0 : yearView.innerHTML = '';
|
|
524
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = component.createCalendar(datePicker.value, strToday);
|
|
525
|
+
component.addEvents();
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
// Drag and drop
|
|
531
|
+
(_f = component.shadowRoot) === null || _f === void 0 ? void 0 : _f.querySelectorAll(`#calendar .table--day td span`).forEach((element) => {
|
|
532
|
+
element.addEventListener("dragover", (ev) => {
|
|
533
|
+
ev.preventDefault();
|
|
534
|
+
return false;
|
|
535
|
+
});
|
|
536
|
+
element.addEventListener("dragenter", (ev) => {
|
|
537
|
+
ev.preventDefault();
|
|
538
|
+
element.classList.add('dragover');
|
|
539
|
+
});
|
|
540
|
+
element.addEventListener("dragleave", (ev) => {
|
|
541
|
+
ev.preventDefault();
|
|
542
|
+
element.classList.remove('dragover');
|
|
543
|
+
});
|
|
544
|
+
element.addEventListener("drop", (ev) => {
|
|
545
|
+
ev.preventDefault();
|
|
546
|
+
const droppedElement = component.querySelector(`#${ev.dataTransfer.getData("text")}`);
|
|
547
|
+
const td = element.closest('td');
|
|
548
|
+
const datetime = element.getAttribute('datetime');
|
|
549
|
+
element.classList.remove('dragover');
|
|
550
|
+
// Add a new slot to te span if needed
|
|
551
|
+
if (!element.querySelector(`slot[name="${datetime}${td.hasAttribute('data-calendar') ? `-${td.getAttribute('data-calendar').replace('_', '')}]` : ''}]"`)) {
|
|
552
|
+
element.insertAdjacentHTML('beforeEnd', `<slot name="${datetime}${td.hasAttribute('data-calendar') ? `-${td.getAttribute('data-calendar').replace('_', '')}` : ''}" class=""></slot>`);
|
|
553
|
+
}
|
|
554
|
+
// Update the slot attribute to match the slot the event has been dropped on
|
|
555
|
+
droppedElement === null || droppedElement === void 0 ? void 0 : droppedElement.setAttribute('slot', `${datetime}${td.hasAttribute('data-calendar') ? `-${td.getAttribute('data-calendar').replace('_', '')}` : ''}`);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
// Watch for the event being resized
|
|
559
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
560
|
+
for (const entry of entries) {
|
|
561
|
+
if (entry.target.classList.contains('mousedown'))
|
|
562
|
+
entry.target.classList.add('resizing');
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
if (component.hasAttribute('data-drag')) {
|
|
566
|
+
component.querySelectorAll(`button:not([draggable])`).forEach((element) => {
|
|
567
|
+
element.setAttribute('draggable', 'true');
|
|
568
|
+
element.addEventListener("dragstart", (ev) => {
|
|
569
|
+
ev.dataTransfer.setData("text", ev.target.id); // save the id for when dropped
|
|
570
|
+
});
|
|
571
|
+
// set onbserver
|
|
572
|
+
resizeObserver.observe(element);
|
|
573
|
+
element.addEventListener("mousedown", (ev) => {
|
|
574
|
+
element.classList.add('mousedown');
|
|
575
|
+
});
|
|
576
|
+
element.addEventListener("click", (ev) => {
|
|
577
|
+
if (element.classList.contains('resizing')) {
|
|
578
|
+
ev.stopPropagation();
|
|
579
|
+
ev.stopImmediatePropagation();
|
|
580
|
+
element.classList.remove('mousedown');
|
|
581
|
+
element.classList.remove('resizing');
|
|
582
|
+
// Work out the evnt length in hours and set the height
|
|
583
|
+
const span = this.shadowRoot.querySelector(`span[datetime="${element.getAttribute('datetime')}"]`);
|
|
584
|
+
const spanStyles = window.getComputedStyle(span);
|
|
585
|
+
const hours = Math.round(parseInt(element.style.height) / parseInt(spanStyles.getPropertyValue("height"))) / 4;
|
|
586
|
+
element.setAttribute('data-hours', hours);
|
|
587
|
+
element.style.setProperty('--event-height', `${hours * (1.09375 * 4)}rem`);
|
|
588
|
+
element.style.height = "";
|
|
589
|
+
// to do dispatch event
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
component.querySelectorAll(`button`).forEach((element) => {
|
|
595
|
+
element.addEventListener("contextmenu", (event) => {
|
|
596
|
+
event.preventDefault();
|
|
597
|
+
event.stopPropagation();
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
(_g = component.shadowRoot) === null || _g === void 0 ? void 0 : _g.querySelectorAll(`.month-wrapper > table > tbody > tr > td`).forEach((element) => {
|
|
601
|
+
element.addEventListener("contextmenu", (event) => {
|
|
602
|
+
event.preventDefault();
|
|
603
|
+
const customEvent = new CustomEvent('right-click', {
|
|
604
|
+
detail: {
|
|
605
|
+
'clientX': event.clientX,
|
|
606
|
+
'clientY': event.clientY,
|
|
607
|
+
'element': element,
|
|
608
|
+
'datetime': element.querySelector('time').getAttribute('datetime')
|
|
609
|
+
},
|
|
610
|
+
});
|
|
611
|
+
console.log(element);
|
|
612
|
+
this.dispatchEvent(customEvent);
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
paginateDate(direction, view, currentDate) {
|
|
617
|
+
if (view == "month" || view == "list") {
|
|
618
|
+
const selectedDate = new Date(currentDate);
|
|
619
|
+
if (direction == "next")
|
|
620
|
+
selectedDate.setMonth(selectedDate.getMonth() + 1);
|
|
621
|
+
else
|
|
622
|
+
selectedDate.setMonth(selectedDate.getMonth() - 1);
|
|
623
|
+
const month = selectedDate.getMonth() + 1;
|
|
624
|
+
const year = selectedDate.getFullYear();
|
|
625
|
+
const strNextMonth = `${year}-${String(month).padStart(2, "0")}-01`;
|
|
626
|
+
return strNextMonth;
|
|
627
|
+
}
|
|
628
|
+
else if (view == "week") {
|
|
629
|
+
//const selectedDate = new Date(currentDate);
|
|
630
|
+
const monday = this.setToMonday(new Date(currentDate));
|
|
631
|
+
if (direction == "next")
|
|
632
|
+
monday.setDate(monday.getDate() + 7);
|
|
633
|
+
else
|
|
634
|
+
monday.setDate(monday.getDate() - 7);
|
|
635
|
+
const date = monday.getDate();
|
|
636
|
+
const month = monday.getMonth() + 1;
|
|
637
|
+
const year = monday.getFullYear();
|
|
638
|
+
const strNextWeek = `${year}-${String(month).padStart(2, "0")}-${String(date).padStart(2, "0")}`;
|
|
639
|
+
return strNextWeek;
|
|
640
|
+
}
|
|
641
|
+
else if (view == "year") {
|
|
642
|
+
const selectedDate = new Date(currentDate);
|
|
643
|
+
if (direction == "next")
|
|
644
|
+
selectedDate.setYear(selectedDate.getFullYear() + 1);
|
|
645
|
+
else
|
|
646
|
+
selectedDate.setYear(selectedDate.getFullYear() - 1);
|
|
647
|
+
const year = selectedDate.getFullYear();
|
|
648
|
+
const month = selectedDate.getMonth() + 1;
|
|
649
|
+
const strNextMonth = `${year}-${String(month).padStart(2, "0")}-01`;
|
|
650
|
+
return strNextMonth;
|
|
651
|
+
}
|
|
652
|
+
const nextDay = new Date(currentDate);
|
|
653
|
+
if (direction == "next")
|
|
654
|
+
nextDay.setDate(nextDay.getDate() + 1);
|
|
655
|
+
else
|
|
656
|
+
nextDay.setDate(nextDay.getDate() - 1);
|
|
657
|
+
const date = nextDay.getDate();
|
|
658
|
+
const month = nextDay.getMonth() + 1;
|
|
659
|
+
const year = nextDay.getFullYear();
|
|
660
|
+
const strNextDay = `${year}-${String(month).padStart(2, "0")}-${String(date).padStart(2, "0")}`;
|
|
661
|
+
return strNextDay;
|
|
662
|
+
}
|
|
663
|
+
setWeekDay() {
|
|
664
|
+
var _a, _b, _c, _d;
|
|
665
|
+
(_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.out-of-hours').forEach(element => {
|
|
666
|
+
element.classList.remove('out-of-hours');
|
|
667
|
+
});
|
|
668
|
+
const startTime = parseInt((_b = this.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('#start-time').value.split(':')[0]);
|
|
669
|
+
const endTime = parseInt((_c = this.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('#end-time').value.split(':')[0]);
|
|
670
|
+
(_d = this.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelectorAll('[data-hour]').forEach(element => {
|
|
671
|
+
const hour = parseInt(element.getAttribute('data-hour'));
|
|
672
|
+
if (hour < startTime)
|
|
673
|
+
element.classList.add('out-of-hours');
|
|
674
|
+
if (hour >= endTime)
|
|
675
|
+
element.classList.add('out-of-hours');
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
scrollIntoPlace() {
|
|
679
|
+
var _a, _b;
|
|
680
|
+
const fs = parseInt(window.getComputedStyle(document.body).getPropertyValue('font-size'));
|
|
681
|
+
const startTime = parseInt((_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#start-time').value.split(':')[0]);
|
|
682
|
+
const scrollPos = startTime * (4.5 * fs);
|
|
683
|
+
const viewPicker = (_b = this.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector(`#view`);
|
|
684
|
+
const wrapper = this.shadowRoot.querySelector('.calendar__wrapper');
|
|
685
|
+
// scroll
|
|
686
|
+
if (viewPicker.value == "week")
|
|
687
|
+
wrapper.scrollTo(0, scrollPos); // TO DO work out how much to scroll by
|
|
688
|
+
else if (viewPicker.value == "day") {
|
|
689
|
+
wrapper.scrollTo(0, scrollPos); // TO DO work out how much to scroll by
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
setupSettings() {
|
|
693
|
+
var _a, _b;
|
|
694
|
+
const settingsButton = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#settings-button');
|
|
695
|
+
const settingsDialog = (_b = this.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('#settings');
|
|
696
|
+
// Setup the pre-defined attributes and display the form elements to match
|
|
697
|
+
if (this.hasAttribute('data-hide-weekends'))
|
|
698
|
+
settingsDialog.querySelector('#weekends-no').checked = true;
|
|
699
|
+
else
|
|
700
|
+
settingsDialog.querySelector('#weekends-yes').checked = true;
|
|
701
|
+
if (this.hasAttribute('data-start-time'))
|
|
702
|
+
settingsDialog.querySelector('#start-time').value = this.getAttribute('data-start-time');
|
|
703
|
+
else
|
|
704
|
+
this.setAttribute('data-start-time', settingsDialog.querySelector('#start-time').value);
|
|
705
|
+
if (this.hasAttribute('data-end-time'))
|
|
706
|
+
settingsDialog.querySelector('#end-time').value = this.getAttribute('data-end-time');
|
|
707
|
+
else
|
|
708
|
+
this.setAttribute('data-end-time', settingsDialog.querySelector('#end-time').value);
|
|
709
|
+
// open dialog
|
|
710
|
+
settingsButton === null || settingsButton === void 0 ? void 0 : settingsButton.addEventListener('click', () => {
|
|
711
|
+
settingsDialog.showModal();
|
|
712
|
+
settingsDialog.focus();
|
|
713
|
+
const customEvent = new CustomEvent('open-settings');
|
|
714
|
+
this.dispatchEvent(customEvent);
|
|
715
|
+
});
|
|
716
|
+
// On clicking the save button, adjust the data attributes
|
|
717
|
+
settingsDialog === null || settingsDialog === void 0 ? void 0 : settingsDialog.addEventListener('click', (event) => {
|
|
718
|
+
if (event && event.target.matches('button')) {
|
|
719
|
+
if (event.target.matches('.btn-primary')) {
|
|
720
|
+
if (settingsDialog.querySelector('#weekends-no:checked'))
|
|
721
|
+
this.setAttribute('data-hide-weekends', 'true');
|
|
722
|
+
else
|
|
723
|
+
this.removeAttribute('data-hide-weekends');
|
|
724
|
+
this.setAttribute('data-start-time', settingsDialog.querySelector('#start-time').value);
|
|
725
|
+
this.setAttribute('data-end-time', settingsDialog.querySelector('#end-time').value);
|
|
726
|
+
this.setWeekDay();
|
|
727
|
+
const customEvent = new CustomEvent('save-settings');
|
|
728
|
+
this.dispatchEvent(customEvent);
|
|
729
|
+
}
|
|
730
|
+
const customEvent = new CustomEvent('close-settings');
|
|
731
|
+
this.dispatchEvent(customEvent);
|
|
732
|
+
settingsDialog.close();
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
setTime() {
|
|
737
|
+
var _a;
|
|
738
|
+
if (!this.hasAttribute('data-time')) {
|
|
739
|
+
const today = new Date();
|
|
740
|
+
const hour = today.getHours();
|
|
741
|
+
const minute = today.getMinutes();
|
|
742
|
+
const time = `${hour}:${minute}`;
|
|
743
|
+
this.setAttribute('data-time', time);
|
|
744
|
+
}
|
|
745
|
+
if (this.hasAttribute('data-time')) {
|
|
746
|
+
const time = this.getAttribute('data-time');
|
|
747
|
+
const hour = parseInt(time.split(':')[0]);
|
|
748
|
+
const minute = parseInt(time.split(':')[1]);
|
|
749
|
+
(_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-hour="${hour}"]`).forEach((element) => {
|
|
750
|
+
var _a;
|
|
751
|
+
element.setAttribute('data-time', time);
|
|
752
|
+
element.classList.add('column-header');
|
|
753
|
+
(_a = element.closest('tr')) === null || _a === void 0 ? void 0 : _a.style.setProperty('--minute-pos', ((minute / 60) * 100) + '%');
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
getYearView(selectedDate, today, sundayFirst) {
|
|
758
|
+
let yearViewStr = "";
|
|
759
|
+
for (let i = 0; i < 12; i++) {
|
|
760
|
+
console.log(selectedDate);
|
|
761
|
+
const selectedDateObj = new Date(selectedDate);
|
|
762
|
+
const selectedYear = selectedDateObj.getFullYear();
|
|
763
|
+
const selectedFormattedDate = `${selectedYear}-${String(i + 1).padStart(2, "0")}-01`;
|
|
764
|
+
yearViewStr += `<div class='month-wrapper'>
|
|
765
|
+
<time class="column-header">${this.monthArray[i]}</time>
|
|
766
|
+
<table>
|
|
767
|
+
<thead>
|
|
768
|
+
${this.createThead(sundayFirst)}
|
|
769
|
+
</thead>
|
|
770
|
+
<tbody>
|
|
771
|
+
${this.createCalendar(selectedFormattedDate, today, sundayFirst)}
|
|
772
|
+
</tbody>
|
|
773
|
+
</table>
|
|
774
|
+
</div>`;
|
|
775
|
+
}
|
|
776
|
+
return yearViewStr;
|
|
777
|
+
}
|
|
778
|
+
connectedCallback() {
|
|
779
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
780
|
+
// To to transform the below into variables of component to make more re-usable
|
|
781
|
+
const title = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.calendar__title');
|
|
782
|
+
const tbody = (_b = this.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('#calendar > table > tbody');
|
|
783
|
+
const thead = (_c = this.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('#calendar > table > thead');
|
|
784
|
+
//const tbodySplit = this.shadowRoot?.querySelector('#split > table > tbody');
|
|
785
|
+
//const theadSplit = this.shadowRoot?.querySelector('#split > table > thead');
|
|
786
|
+
const weekViewHeader = (_d = this.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('#week-view-header > table > tbody');
|
|
787
|
+
const yearView = (_e = this.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('#year-view');
|
|
788
|
+
const datePicker = (_f = this.shadowRoot) === null || _f === void 0 ? void 0 : _f.querySelector(`#date`);
|
|
789
|
+
const viewPicker = (_g = this.shadowRoot) === null || _g === void 0 ? void 0 : _g.querySelector(`#view`);
|
|
790
|
+
const todayButton = (_h = this.shadowRoot) === null || _h === void 0 ? void 0 : _h.querySelector('#today-button');
|
|
791
|
+
const filtersButton = (_j = this.shadowRoot) === null || _j === void 0 ? void 0 : _j.querySelector('#filters-button');
|
|
792
|
+
const prevButton = (_k = this.shadowRoot) === null || _k === void 0 ? void 0 : _k.querySelector('#prev-button');
|
|
793
|
+
const nextButton = (_l = this.shadowRoot) === null || _l === void 0 ? void 0 : _l.querySelector('#next-button');
|
|
794
|
+
const sundayFirst = this.hasAttribute('data-sunday-first');
|
|
795
|
+
const splitButton = (_m = this.shadowRoot) === null || _m === void 0 ? void 0 : _m.querySelector(`[name="split"]`);
|
|
796
|
+
// set the table head - starting by monday by default but can be changed to sunday
|
|
797
|
+
thead === null || thead === void 0 ? void 0 : thead.innerHTML = this.createThead(sundayFirst);
|
|
798
|
+
//theadSplit?.innerHTML = this.createThead(sundayFirst);
|
|
799
|
+
// Get a formatted version of todays date
|
|
800
|
+
const today = new Date();
|
|
801
|
+
const date = today.getDate();
|
|
802
|
+
const month = today.getMonth();
|
|
803
|
+
const year = today.getFullYear();
|
|
804
|
+
const strToday = `${year}-${String(month + 1).padStart(2, "0")}-${String(date).padStart(2, "0")}`;
|
|
805
|
+
datePicker.value = strToday;
|
|
806
|
+
// Setup the view, month being default
|
|
807
|
+
if (this.hasAttribute('data-view'))
|
|
808
|
+
viewPicker.value = this.getAttribute('data-view');
|
|
809
|
+
else {
|
|
810
|
+
this.setAttribute('data-view', "month");
|
|
811
|
+
viewPicker.value = "month";
|
|
812
|
+
}
|
|
813
|
+
if (this.hasAttribute('data-views'))
|
|
814
|
+
viewPicker === null || viewPicker === void 0 ? void 0 : viewPicker.setAttribute('data-views', this.getAttribute('data-views'));
|
|
815
|
+
// Create the calendars
|
|
816
|
+
if (this.hasAttribute('data-calendars')) {
|
|
817
|
+
this.calendars = this.getAttribute('data-calendars').split(',');
|
|
818
|
+
this.calendars.forEach((item, index) => {
|
|
819
|
+
this.calendars[index] = item.trim();
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
// Setup the settings dialog
|
|
823
|
+
this.setupSettings();
|
|
824
|
+
// Setup the calendar then adjust and add events
|
|
825
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(strToday, viewPicker.value);
|
|
826
|
+
const calendarHtml = this.createCalendar(strToday, strToday, sundayFirst);
|
|
827
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = calendarHtml;
|
|
828
|
+
//tbodySplit?.innerHTML = calendarHtml;
|
|
829
|
+
weekViewHeader === null || weekViewHeader === void 0 ? void 0 : weekViewHeader.innerHTML = calendarHtml;
|
|
830
|
+
if (viewPicker.value == "year") {
|
|
831
|
+
yearView === null || yearView === void 0 ? void 0 : yearView.innerHTML = this.getYearView(datePicker.value, strToday, sundayFirst);
|
|
832
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = '';
|
|
833
|
+
}
|
|
834
|
+
this.addEvents();
|
|
835
|
+
this.addJSEvents(this);
|
|
836
|
+
this.setWeekDay(); // Working hours
|
|
837
|
+
this.setTime(); // Month and day view has a current time indicator
|
|
838
|
+
this.scrollIntoPlace(); // Scroll into place - month and day view needs have the weekday hours in place
|
|
839
|
+
// #region Add events for the basic top controls
|
|
840
|
+
// Remove the slot attribute on selected days when in split mode
|
|
841
|
+
splitButton === null || splitButton === void 0 ? void 0 : splitButton.addEventListener('change', () => {
|
|
842
|
+
if (splitButton.checked) {
|
|
843
|
+
Array.from(this.querySelectorAll(`[slot^="${datePicker.value}"]`)).forEach((button) => {
|
|
844
|
+
button.setAttribute('data-slot', button.getAttribute('slot'));
|
|
845
|
+
button.removeAttribute('slot');
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
Array.from(this.querySelectorAll(`[data-slot]`)).forEach((button) => {
|
|
850
|
+
button.setAttribute('slot', button.getAttribute('data-slot'));
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
855
|
+
const splitButtonDisplayed = window.getComputedStyle(splitButton === null || splitButton === void 0 ? void 0 : splitButton.parentElement, null).display;
|
|
856
|
+
if (splitButtonDisplayed == "none") {
|
|
857
|
+
Array.from(this.querySelectorAll(`[data-slot]`)).forEach((button) => {
|
|
858
|
+
button.setAttribute('slot', button.getAttribute('data-slot'));
|
|
859
|
+
});
|
|
860
|
+
splitButton.checked = false;
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
resizeObserver.observe(this);
|
|
864
|
+
viewPicker === null || viewPicker === void 0 ? void 0 : viewPicker.addEventListener('change', () => {
|
|
865
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(datePicker.value, viewPicker.value);
|
|
866
|
+
this.setAttribute('data-view', viewPicker.value);
|
|
867
|
+
if (viewPicker.value == "week") {
|
|
868
|
+
Array.from(this.querySelectorAll(`.allday-event`)).forEach((button) => {
|
|
869
|
+
button.setAttribute('slot', button.getAttribute('slot') + '-header');
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
Array.from(this.querySelectorAll(`.allday-event`)).forEach((button) => {
|
|
874
|
+
var _a;
|
|
875
|
+
button.setAttribute('slot', (_a = button.getAttribute('slot')) === null || _a === void 0 ? void 0 : _a.replace('-header', ''));
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
if (viewPicker.value == "week" || viewPicker.value == "day")
|
|
879
|
+
this.scrollIntoPlace();
|
|
880
|
+
if (viewPicker.value != "month") {
|
|
881
|
+
Array.from(this.querySelectorAll(`[data-slot^="${datePicker.value}"]`)).forEach((button) => {
|
|
882
|
+
button.setAttribute('slot', button.getAttribute('data-slot'));
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
if (viewPicker.value == "year") {
|
|
886
|
+
yearView === null || yearView === void 0 ? void 0 : yearView.innerHTML = this.getYearView(datePicker.value, strToday, sundayFirst);
|
|
887
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = '';
|
|
888
|
+
this.addEvents();
|
|
889
|
+
this.addJSEvents(this);
|
|
890
|
+
this.setWeekDay(); // Working hours
|
|
891
|
+
this.setTime(); // Month and day view has a current time indicator
|
|
892
|
+
this.scrollIntoPlace();
|
|
893
|
+
}
|
|
894
|
+
else if ((tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML) == "") {
|
|
895
|
+
yearView === null || yearView === void 0 ? void 0 : yearView.innerHTML = '';
|
|
896
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = this.createCalendar(datePicker.value, strToday);
|
|
897
|
+
this.addEvents();
|
|
898
|
+
this.addJSEvents(this);
|
|
899
|
+
this.setWeekDay(); // Working hours
|
|
900
|
+
this.setTime(); // Month and day view has a current time indicator
|
|
901
|
+
this.scrollIntoPlace();
|
|
902
|
+
}
|
|
903
|
+
const customEvent = new CustomEvent('change-view', {
|
|
904
|
+
detail: {
|
|
905
|
+
'view': viewPicker.value,
|
|
906
|
+
'date': datePicker.value
|
|
907
|
+
},
|
|
908
|
+
});
|
|
909
|
+
this.dispatchEvent(customEvent);
|
|
910
|
+
});
|
|
911
|
+
function resetCalendar(component) {
|
|
912
|
+
if (viewPicker.value == "year") {
|
|
913
|
+
yearView === null || yearView === void 0 ? void 0 : yearView.innerHTML = component.getYearView(datePicker.value, strToday, sundayFirst);
|
|
914
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = '';
|
|
915
|
+
component.addEvents();
|
|
916
|
+
component.addJSEvents(component);
|
|
917
|
+
component.setWeekDay(); // Working hours
|
|
918
|
+
component.setTime(); // Month and day view has a current time indicator
|
|
919
|
+
}
|
|
920
|
+
else {
|
|
921
|
+
const calendarHtml = component.createCalendar(datePicker.value, strToday);
|
|
922
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = calendarHtml;
|
|
923
|
+
//tbodySplit?.innerHTML = calendarHtml;
|
|
924
|
+
weekViewHeader === null || weekViewHeader === void 0 ? void 0 : weekViewHeader.innerHTML = calendarHtml;
|
|
925
|
+
component.addEvents();
|
|
926
|
+
component.addJSEvents(component);
|
|
927
|
+
component.setWeekDay();
|
|
928
|
+
component.setTime();
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
function updateCalendar(component) {
|
|
932
|
+
Array.from(component.shadowRoot.querySelectorAll('.selected')).forEach((element) => {
|
|
933
|
+
element.classList.remove('selected');
|
|
934
|
+
});
|
|
935
|
+
Array.from(component.shadowRoot.querySelectorAll(`td:has(time[datetime="${datePicker.value}"]):not(.prev-month, .next-month)`)).forEach((element) => {
|
|
936
|
+
element.classList.add('selected');
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
datePicker === null || datePicker === void 0 ? void 0 : datePicker.addEventListener('change', () => {
|
|
940
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(datePicker.value, viewPicker.value);
|
|
941
|
+
if (this.shadowRoot.querySelector(`td:has(time[datetime="${datePicker.value}"]):not(.prev-month, .next-month)`))
|
|
942
|
+
updateCalendar(this);
|
|
943
|
+
else
|
|
944
|
+
resetCalendar(this);
|
|
945
|
+
const customEvent = new CustomEvent('change-date', {
|
|
946
|
+
detail: {
|
|
947
|
+
'view': viewPicker.value,
|
|
948
|
+
'date': datePicker.value
|
|
949
|
+
},
|
|
950
|
+
});
|
|
951
|
+
this.dispatchEvent(customEvent);
|
|
952
|
+
});
|
|
953
|
+
filtersButton === null || filtersButton === void 0 ? void 0 : filtersButton.addEventListener('click', () => {
|
|
954
|
+
const customEvent = new CustomEvent('open-filters');
|
|
955
|
+
this.dispatchEvent(customEvent);
|
|
956
|
+
});
|
|
957
|
+
// HTML Observer
|
|
958
|
+
const htmlUpdated = (mutationList, observer) => {
|
|
959
|
+
observer.disconnect();
|
|
960
|
+
console.log(this.pauseObserver);
|
|
961
|
+
if (this.pauseObserver == false) {
|
|
962
|
+
for (const mutation of mutationList) {
|
|
963
|
+
if (mutation.type == 'characterData' || (mutation.type == 'childList' && mutation.addedNodes.length) || mutation.type === 'attributes') {
|
|
964
|
+
//resetCalendar(this);
|
|
965
|
+
this.addEvents();
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
observer.observe(this, { childList: true, characterData: true, subtree: true, attributes: true });
|
|
970
|
+
};
|
|
971
|
+
const observer = new MutationObserver(htmlUpdated);
|
|
972
|
+
observer.observe(this, { childList: true, characterData: true, subtree: true, attributes: true });
|
|
973
|
+
todayButton === null || todayButton === void 0 ? void 0 : todayButton.addEventListener('click', () => {
|
|
974
|
+
datePicker.value = strToday;
|
|
975
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(datePicker.value, viewPicker.value);
|
|
976
|
+
if (this.shadowRoot.querySelector(`td:has(time[datetime="${datePicker.value}"]):not(.prev-month, .next-month)`))
|
|
977
|
+
updateCalendar(this);
|
|
978
|
+
else
|
|
979
|
+
resetCalendar(this);
|
|
980
|
+
const customEvent = new CustomEvent('change-date-today', {
|
|
981
|
+
detail: {
|
|
982
|
+
'view': viewPicker.value,
|
|
983
|
+
'date': datePicker.value
|
|
984
|
+
},
|
|
985
|
+
});
|
|
986
|
+
this.dispatchEvent(customEvent);
|
|
987
|
+
});
|
|
988
|
+
prevButton === null || prevButton === void 0 ? void 0 : prevButton.addEventListener('click', () => {
|
|
989
|
+
datePicker.value = this.paginateDate("prev", viewPicker.value, datePicker.value);
|
|
990
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(datePicker.value, viewPicker.value);
|
|
991
|
+
if (this.shadowRoot.querySelector(`td:has(time[datetime="${datePicker.value}"]):not(.prev-month, .next-month)`))
|
|
992
|
+
updateCalendar(this);
|
|
993
|
+
else
|
|
994
|
+
resetCalendar(this);
|
|
995
|
+
const customEvent = new CustomEvent('change-date-previous', {
|
|
996
|
+
detail: {
|
|
997
|
+
'view': viewPicker.value,
|
|
998
|
+
'date': datePicker.value
|
|
999
|
+
},
|
|
1000
|
+
});
|
|
1001
|
+
this.dispatchEvent(customEvent);
|
|
1002
|
+
});
|
|
1003
|
+
nextButton === null || nextButton === void 0 ? void 0 : nextButton.addEventListener('click', () => {
|
|
1004
|
+
datePicker.value = this.paginateDate("next", viewPicker.value, datePicker.value);
|
|
1005
|
+
title === null || title === void 0 ? void 0 : title.innerHTML = this.getTitle(datePicker.value, viewPicker.value);
|
|
1006
|
+
console.log(datePicker.value);
|
|
1007
|
+
if (this.shadowRoot.querySelector(`td:has(time[datetime="${datePicker.value}"]):not(.prev-month, .next-month)`))
|
|
1008
|
+
updateCalendar(this);
|
|
1009
|
+
else
|
|
1010
|
+
resetCalendar(this);
|
|
1011
|
+
const customEvent = new CustomEvent('change-date-next', {
|
|
1012
|
+
detail: {
|
|
1013
|
+
'view': viewPicker.value,
|
|
1014
|
+
'date': datePicker.value
|
|
1015
|
+
},
|
|
1016
|
+
});
|
|
1017
|
+
this.dispatchEvent(customEvent);
|
|
1018
|
+
});
|
|
1019
|
+
// #endregion
|
|
1020
|
+
// TODO
|
|
1021
|
+
trackComponent(this, 'iam-calendar', [
|
|
1022
|
+
'open-filters',
|
|
1023
|
+
'change-view',
|
|
1024
|
+
'change-date',
|
|
1025
|
+
'change-date-today',
|
|
1026
|
+
'change-date-previous',
|
|
1027
|
+
'change-date-next',
|
|
1028
|
+
'open-settings',
|
|
1029
|
+
'close-settings',
|
|
1030
|
+
'save-settings'
|
|
1031
|
+
]);
|
|
1032
|
+
}
|
|
1033
|
+
static get observedAttributes() {
|
|
1034
|
+
return ['data-calendars', 'data-view'];
|
|
1035
|
+
}
|
|
1036
|
+
attributeChangedCallback(attrName, oldVal, newVal) {
|
|
1037
|
+
var _a, _b, _c, _d;
|
|
1038
|
+
this.pauseObserver = true;
|
|
1039
|
+
switch (attrName) {
|
|
1040
|
+
case 'data-calendars':
|
|
1041
|
+
{
|
|
1042
|
+
if (oldVal != newVal) {
|
|
1043
|
+
const tbody = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#calendar > table > tbody');
|
|
1044
|
+
const weekViewHeader = (_b = this.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('#week-view-header > table > tbody');
|
|
1045
|
+
const datePicker = (_c = this.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector(`#date`);
|
|
1046
|
+
// Get a formatted version of todays date
|
|
1047
|
+
const today = new Date();
|
|
1048
|
+
const date = today.getDate();
|
|
1049
|
+
const month = today.getMonth();
|
|
1050
|
+
const year = today.getFullYear();
|
|
1051
|
+
const strToday = `${year}-${String(month + 1).padStart(2, "0")}-${String(date).padStart(2, "0")}`;
|
|
1052
|
+
if (this.hasAttribute('data-calendars')) {
|
|
1053
|
+
this.calendars = this.getAttribute('data-calendars').split(',');
|
|
1054
|
+
this.calendars.forEach((item, index) => {
|
|
1055
|
+
this.calendars[index] = item.trim();
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
const calendarHtml = this.createCalendar(datePicker.value, strToday);
|
|
1059
|
+
tbody === null || tbody === void 0 ? void 0 : tbody.innerHTML = calendarHtml;
|
|
1060
|
+
weekViewHeader === null || weekViewHeader === void 0 ? void 0 : weekViewHeader.innerHTML = calendarHtml;
|
|
1061
|
+
this.addEvents();
|
|
1062
|
+
this.addJSEvents(this);
|
|
1063
|
+
this.setWeekDay();
|
|
1064
|
+
this.setTime();
|
|
1065
|
+
}
|
|
1066
|
+
break;
|
|
1067
|
+
}
|
|
1068
|
+
;
|
|
1069
|
+
case 'data-view': {
|
|
1070
|
+
if (oldVal != newVal) {
|
|
1071
|
+
const viewPicker = (_d = this.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector(`#view`);
|
|
1072
|
+
viewPicker.value = newVal;
|
|
1073
|
+
viewPicker.dispatchEvent(new Event('change'));
|
|
1074
|
+
}
|
|
1075
|
+
break;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
setTimeout(() => {
|
|
1079
|
+
this.pauseObserver = false;
|
|
1080
|
+
}, "500");
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
export default iamCalendar;
|