decidim-calendar 0.13.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +9 -0
  4. data/Rakefile +43 -0
  5. data/app/assets/config/decidim_calendar_manifest.css +2 -0
  6. data/app/assets/config/decidim_calendar_manifest.js +2 -0
  7. data/app/assets/images/decidim/calendar/icon.svg +51 -0
  8. data/app/assets/javascripts/decidim/calendar/calendar.js.es6 +6 -0
  9. data/app/assets/javascripts/decidim/calendar/gantt.js.es6 +1 -0
  10. data/app/assets/stylesheets/decidim/calendar/calendar.scss +102 -0
  11. data/app/assets/stylesheets/decidim/calendar/gantt.scss +1 -0
  12. data/app/commands/decidim/calendar/admin/create_external_event.rb +38 -0
  13. data/app/commands/decidim/calendar/admin/destroy_external_event.rb +27 -0
  14. data/app/commands/decidim/calendar/admin/update_external_event.rb +43 -0
  15. data/app/controllers/decidim/calendar/admin/application_controller.rb +23 -0
  16. data/app/controllers/decidim/calendar/admin/external_events_controller.rb +84 -0
  17. data/app/controllers/decidim/calendar/application_controller.rb +21 -0
  18. data/app/controllers/decidim/calendar/calendar_controller.rb +33 -0
  19. data/app/forms/decidim/calendar/admin/external_event_form.rb +21 -0
  20. data/app/helpers/decidim/calendar/calendar_helper.rb +57 -0
  21. data/app/models/decidim/calendar/application_record.rb +9 -0
  22. data/app/models/decidim/calendar/event.rb +25 -0
  23. data/app/models/decidim/calendar/external_event.rb +18 -0
  24. data/app/permissions/decidim/calendar/admin/permissions.rb +22 -0
  25. data/app/presenters/decidim/calendar/event_presenter.rb +104 -0
  26. data/app/queries/decidim/calendar/organization_calendar.rb +15 -0
  27. data/app/services/decidim/calendar/event_to_ical.rb +27 -0
  28. data/app/services/decidim/calendar/general_calendar.rb +13 -0
  29. data/app/services/decidim/calendar/meeting_to_event.rb +8 -0
  30. data/app/services/decidim/meetings/calendar/base_calendar.rb +61 -0
  31. data/app/views/decidim/calendar/admin/external_events/_form.html.erb +22 -0
  32. data/app/views/decidim/calendar/admin/external_events/edit.html.erb +6 -0
  33. data/app/views/decidim/calendar/admin/external_events/index.html.erb +66 -0
  34. data/app/views/decidim/calendar/admin/external_events/new.html.erb +6 -0
  35. data/app/views/decidim/calendar/calendar/gantt.html.erb +22 -0
  36. data/app/views/decidim/calendar/calendar/index.html.erb +63 -0
  37. data/app/views/decidim/shared/_extended_navigation_bar.html.erb +51 -0
  38. data/app/views/layouts/_calendar_navigation.html.erb +18 -0
  39. data/app/views/layouts/calendar.html.erb +4 -0
  40. data/config/locales/ca.yml +38 -0
  41. data/config/locales/de.yml +38 -0
  42. data/config/locales/en.yml +48 -0
  43. data/config/locales/es.yml +38 -0
  44. data/config/locales/fi.yml +38 -0
  45. data/config/locales/fr.yml +38 -0
  46. data/config/locales/it.yml +38 -0
  47. data/config/locales/pl.yml +38 -0
  48. data/config/locales/pt.yml +38 -0
  49. data/config/locales/ro.yml +38 -0
  50. data/config/locales/ru.yml +38 -0
  51. data/config/locales/sv.yml +38 -0
  52. data/config/locales/tr.yml +38 -0
  53. data/config/locales/uk.yml +38 -0
  54. data/db/migrate/20190312132654_create_decidim_calendar_external_events.rb +18 -0
  55. data/lib/decidim/calendar.rb +11 -0
  56. data/lib/decidim/calendar/admin.rb +9 -0
  57. data/lib/decidim/calendar/admin_engine.rb +30 -0
  58. data/lib/decidim/calendar/engine.rb +34 -0
  59. data/lib/decidim/calendar/participatory_space.rb +20 -0
  60. data/lib/decidim/calendar/test/factories.rb +12 -0
  61. data/lib/decidim/calendar/version.rb +10 -0
  62. data/vendor/assets/javascripts/frappe-gantt/frappe-gantt.css +119 -0
  63. data/vendor/assets/javascripts/frappe-gantt/frappe-gantt.js +1883 -0
  64. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.css +33 -0
  65. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.js +90 -0
  66. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.min.css +5 -0
  67. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.min.js +20 -0
  68. data/vendor/assets/javascripts/fullcalendar/core/locales-all.js +1353 -0
  69. data/vendor/assets/javascripts/fullcalendar/core/locales-all.min.js +6 -0
  70. data/vendor/assets/javascripts/fullcalendar/core/locales/af.js +30 -0
  71. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-dz.js +31 -0
  72. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-kw.js +31 -0
  73. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ly.js +31 -0
  74. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ma.js +31 -0
  75. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-sa.js +31 -0
  76. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-tn.js +31 -0
  77. data/vendor/assets/javascripts/fullcalendar/core/locales/ar.js +31 -0
  78. data/vendor/assets/javascripts/fullcalendar/core/locales/bg.js +31 -0
  79. data/vendor/assets/javascripts/fullcalendar/core/locales/bs.js +32 -0
  80. data/vendor/assets/javascripts/fullcalendar/core/locales/ca.js +30 -0
  81. data/vendor/assets/javascripts/fullcalendar/core/locales/cs.js +32 -0
  82. data/vendor/assets/javascripts/fullcalendar/core/locales/da.js +30 -0
  83. data/vendor/assets/javascripts/fullcalendar/core/locales/de.js +33 -0
  84. data/vendor/assets/javascripts/fullcalendar/core/locales/el.js +30 -0
  85. data/vendor/assets/javascripts/fullcalendar/core/locales/en-au.js +17 -0
  86. data/vendor/assets/javascripts/fullcalendar/core/locales/en-gb.js +17 -0
  87. data/vendor/assets/javascripts/fullcalendar/core/locales/en-nz.js +17 -0
  88. data/vendor/assets/javascripts/fullcalendar/core/locales/es-us.js +30 -0
  89. data/vendor/assets/javascripts/fullcalendar/core/locales/es.js +30 -0
  90. data/vendor/assets/javascripts/fullcalendar/core/locales/et.js +32 -0
  91. data/vendor/assets/javascripts/fullcalendar/core/locales/eu.js +30 -0
  92. data/vendor/assets/javascripts/fullcalendar/core/locales/fa.js +33 -0
  93. data/vendor/assets/javascripts/fullcalendar/core/locales/fi.js +30 -0
  94. data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ca.js +27 -0
  95. data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ch.js +31 -0
  96. data/vendor/assets/javascripts/fullcalendar/core/locales/fr.js +31 -0
  97. data/vendor/assets/javascripts/fullcalendar/core/locales/gl.js +30 -0
  98. data/vendor/assets/javascripts/fullcalendar/core/locales/he.js +27 -0
  99. data/vendor/assets/javascripts/fullcalendar/core/locales/hi.js +32 -0
  100. data/vendor/assets/javascripts/fullcalendar/core/locales/hr.js +32 -0
  101. data/vendor/assets/javascripts/fullcalendar/core/locales/hu.js +30 -0
  102. data/vendor/assets/javascripts/fullcalendar/core/locales/id.js +30 -0
  103. data/vendor/assets/javascripts/fullcalendar/core/locales/is.js +30 -0
  104. data/vendor/assets/javascripts/fullcalendar/core/locales/it.js +32 -0
  105. data/vendor/assets/javascripts/fullcalendar/core/locales/ja.js +28 -0
  106. data/vendor/assets/javascripts/fullcalendar/core/locales/ka.js +32 -0
  107. data/vendor/assets/javascripts/fullcalendar/core/locales/kk.js +32 -0
  108. data/vendor/assets/javascripts/fullcalendar/core/locales/ko.js +26 -0
  109. data/vendor/assets/javascripts/fullcalendar/core/locales/lb.js +30 -0
  110. data/vendor/assets/javascripts/fullcalendar/core/locales/lt.js +30 -0
  111. data/vendor/assets/javascripts/fullcalendar/core/locales/lv.js +32 -0
  112. data/vendor/assets/javascripts/fullcalendar/core/locales/mk.js +28 -0
  113. data/vendor/assets/javascripts/fullcalendar/core/locales/ms.js +32 -0
  114. data/vendor/assets/javascripts/fullcalendar/core/locales/nb.js +30 -0
  115. data/vendor/assets/javascripts/fullcalendar/core/locales/nl.js +30 -0
  116. data/vendor/assets/javascripts/fullcalendar/core/locales/nn.js +30 -0
  117. data/vendor/assets/javascripts/fullcalendar/core/locales/pl.js +30 -0
  118. data/vendor/assets/javascripts/fullcalendar/core/locales/pt-br.js +28 -0
  119. data/vendor/assets/javascripts/fullcalendar/core/locales/pt.js +30 -0
  120. data/vendor/assets/javascripts/fullcalendar/core/locales/ro.js +32 -0
  121. data/vendor/assets/javascripts/fullcalendar/core/locales/ru.js +32 -0
  122. data/vendor/assets/javascripts/fullcalendar/core/locales/sk.js +32 -0
  123. data/vendor/assets/javascripts/fullcalendar/core/locales/sl.js +30 -0
  124. data/vendor/assets/javascripts/fullcalendar/core/locales/sq.js +32 -0
  125. data/vendor/assets/javascripts/fullcalendar/core/locales/sr-cyrl.js +32 -0
  126. data/vendor/assets/javascripts/fullcalendar/core/locales/sr.js +32 -0
  127. data/vendor/assets/javascripts/fullcalendar/core/locales/sv.js +30 -0
  128. data/vendor/assets/javascripts/fullcalendar/core/locales/th.js +25 -0
  129. data/vendor/assets/javascripts/fullcalendar/core/locales/tr.js +30 -0
  130. data/vendor/assets/javascripts/fullcalendar/core/locales/uk.js +32 -0
  131. data/vendor/assets/javascripts/fullcalendar/core/locales/vi.js +32 -0
  132. data/vendor/assets/javascripts/fullcalendar/core/locales/zh-cn.js +33 -0
  133. data/vendor/assets/javascripts/fullcalendar/core/locales/zh-tw.js +26 -0
  134. data/vendor/assets/javascripts/fullcalendar/core/main.css +900 -0
  135. data/vendor/assets/javascripts/fullcalendar/core/main.js +8791 -0
  136. data/vendor/assets/javascripts/fullcalendar/core/main.min.css +5 -0
  137. data/vendor/assets/javascripts/fullcalendar/core/main.min.js +9 -0
  138. data/vendor/assets/javascripts/fullcalendar/daygrid/main.css +69 -0
  139. data/vendor/assets/javascripts/fullcalendar/daygrid/main.js +1630 -0
  140. data/vendor/assets/javascripts/fullcalendar/daygrid/main.min.css +5 -0
  141. data/vendor/assets/javascripts/fullcalendar/daygrid/main.min.js +20 -0
  142. data/vendor/assets/javascripts/fullcalendar/google-calendar/main.js +169 -0
  143. data/vendor/assets/javascripts/fullcalendar/google-calendar/main.min.js +20 -0
  144. data/vendor/assets/javascripts/fullcalendar/interaction/main.js +2155 -0
  145. data/vendor/assets/javascripts/fullcalendar/interaction/main.min.js +21 -0
  146. data/vendor/assets/javascripts/fullcalendar/list/main.css +101 -0
  147. data/vendor/assets/javascripts/fullcalendar/list/main.js +341 -0
  148. data/vendor/assets/javascripts/fullcalendar/list/main.min.css +5 -0
  149. data/vendor/assets/javascripts/fullcalendar/list/main.min.js +20 -0
  150. data/vendor/assets/javascripts/fullcalendar/luxon/main.js +162 -0
  151. data/vendor/assets/javascripts/fullcalendar/luxon/main.min.js +20 -0
  152. data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.js +64 -0
  153. data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.min.js +20 -0
  154. data/vendor/assets/javascripts/fullcalendar/moment/main.js +103 -0
  155. data/vendor/assets/javascripts/fullcalendar/moment/main.min.js +6 -0
  156. data/vendor/assets/javascripts/fullcalendar/rrule/main.js +127 -0
  157. data/vendor/assets/javascripts/fullcalendar/rrule/main.min.js +20 -0
  158. data/vendor/assets/javascripts/fullcalendar/timegrid/main.css +266 -0
  159. data/vendor/assets/javascripts/fullcalendar/timegrid/main.js +1339 -0
  160. data/vendor/assets/javascripts/fullcalendar/timegrid/main.min.css +5 -0
  161. data/vendor/assets/javascripts/fullcalendar/timegrid/main.min.js +20 -0
  162. metadata +247 -0
@@ -0,0 +1,20 @@
1
+ /*!
2
+ FullCalendar RRule Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("rrule"),require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","rrule","@fullcalendar/core"],r):(e=e||self,r(e.FullCalendarRrule={},e.rrule,e.FullCalendar))}(this,function(e,r,t){"use strict";function n(e,t){var n,i=null;if("string"==typeof e)n=r.rrulestr(e);else if("object"==typeof e&&e){var f=a({},e);if("string"==typeof f.dtstart){var o=t.createMarkerMeta(f.dtstart);o?(f.dtstart=o.marker,i=o.isTimeUnspecified):delete f.dtstart}"string"==typeof f.until&&(f.until=t.createMarker(f.until)),null!=f.freq&&(f.freq=l(f.freq)),null!=f.wkst?f.wkst=l(f.wkst):f.wkst=(t.weekDow-1+7)%7,null!=f.byweekday&&(f.byweekday=u(f.byweekday)),n=new r.RRule(f)}return n?{rrule:n,allDayGuess:i}:null}function u(e){return Array.isArray(e)?e.map(l):l(e)}function l(e){return"string"==typeof e?r.RRule[e.toUpperCase()]:e}/*! *****************************************************************************
7
+ Copyright (c) Microsoft Corporation. All rights reserved.
8
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
9
+ this file except in compliance with the License. You may obtain a copy of the
10
+ License at http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
14
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
15
+ MERCHANTABLITY OR NON-INFRINGEMENT.
16
+
17
+ See the Apache Version 2.0 License for specific language governing permissions
18
+ and limitations under the License.
19
+ ***************************************************************************** */
20
+ var a=function(){return a=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++){r=arguments[t];for(var u in r)Object.prototype.hasOwnProperty.call(r,u)&&(e[u]=r[u])}return e},a.apply(this,arguments)},i={rrule:null,duration:t.createDuration},f={parse:function(e,r,u){if(null!=e.rrule){var l=t.refineProps(e,i,{},r),a=n(l.rrule,u);if(a)return{typeData:a.rrule,allDayGuess:a.allDayGuess,duration:l.duration}}return null},expand:function(e,r){return e.between(r.start,r.end,!0).filter(function(e){return e.valueOf()<r.end.valueOf()})}},o=t.createPlugin({recurringTypes:[f]});e.default=o,Object.defineProperty(e,"__esModule",{value:!0})});
@@ -0,0 +1,266 @@
1
+ /*!
2
+ FullCalendar Time Grid Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ /* TimeGridView all-day area
7
+ --------------------------------------------------------------------------------------------------*/
8
+ .fc-timeGrid-view .fc-day-grid {
9
+ position: relative;
10
+ z-index: 2;
11
+ /* so the "more.." popover will be over the time grid */ }
12
+
13
+ .fc-timeGrid-view .fc-day-grid .fc-row {
14
+ min-height: 3em;
15
+ /* all-day section will never get shorter than this */ }
16
+
17
+ .fc-timeGrid-view .fc-day-grid .fc-row .fc-content-skeleton {
18
+ padding-bottom: 1em;
19
+ /* give space underneath events for clicking/selecting days */ }
20
+
21
+ /* TimeGrid axis running down the side (for both the all-day area and the slot area)
22
+ --------------------------------------------------------------------------------------------------*/
23
+ .fc .fc-axis {
24
+ /* .fc to overcome default cell styles */
25
+ vertical-align: middle;
26
+ padding: 0 4px;
27
+ white-space: nowrap; }
28
+
29
+ .fc-ltr .fc-axis {
30
+ text-align: right; }
31
+
32
+ .fc-rtl .fc-axis {
33
+ text-align: left; }
34
+
35
+ /* TimeGrid Structure
36
+ --------------------------------------------------------------------------------------------------*/
37
+ .fc-time-grid-container,
38
+ .fc-time-grid {
39
+ /* so slats/bg/content/etc positions get scoped within here */
40
+ position: relative;
41
+ z-index: 1; }
42
+
43
+ .fc-time-grid {
44
+ min-height: 100%;
45
+ /* so if height setting is 'auto', .fc-bg stretches to fill height */ }
46
+
47
+ .fc-time-grid table {
48
+ /* don't put outer borders on slats/bg/content/etc */
49
+ border: 0 hidden transparent; }
50
+
51
+ .fc-time-grid > .fc-bg {
52
+ z-index: 1; }
53
+
54
+ .fc-time-grid .fc-slats,
55
+ .fc-time-grid > hr {
56
+ /* the <hr> TimeGridView injects when grid is shorter than scroller */
57
+ position: relative;
58
+ z-index: 2; }
59
+
60
+ .fc-time-grid .fc-content-col {
61
+ position: relative;
62
+ /* because now-indicator lives directly inside */ }
63
+
64
+ .fc-time-grid .fc-content-skeleton {
65
+ position: absolute;
66
+ z-index: 3;
67
+ top: 0;
68
+ left: 0;
69
+ right: 0; }
70
+
71
+ /* divs within a cell within the fc-content-skeleton */
72
+ .fc-time-grid .fc-business-container {
73
+ position: relative;
74
+ z-index: 1; }
75
+
76
+ .fc-time-grid .fc-bgevent-container {
77
+ position: relative;
78
+ z-index: 2; }
79
+
80
+ .fc-time-grid .fc-highlight-container {
81
+ position: relative;
82
+ z-index: 3; }
83
+
84
+ .fc-time-grid .fc-event-container {
85
+ position: relative;
86
+ z-index: 4; }
87
+
88
+ .fc-time-grid .fc-now-indicator-line {
89
+ z-index: 5; }
90
+
91
+ .fc-time-grid .fc-mirror-container {
92
+ /* also is fc-event-container */
93
+ position: relative;
94
+ z-index: 6; }
95
+
96
+ /* TimeGrid Slats (lines that run horizontally)
97
+ --------------------------------------------------------------------------------------------------*/
98
+ .fc-time-grid .fc-slats td {
99
+ height: 1.5em;
100
+ border-bottom: 0;
101
+ /* each cell is responsible for its top border */ }
102
+
103
+ .fc-time-grid .fc-slats .fc-minor td {
104
+ border-top-style: dotted; }
105
+
106
+ /* TimeGrid Highlighting Slots
107
+ --------------------------------------------------------------------------------------------------*/
108
+ .fc-time-grid .fc-highlight-container {
109
+ /* a div within a cell within the fc-highlight-skeleton */
110
+ position: relative;
111
+ /* scopes the left/right of the fc-highlight to be in the column */ }
112
+
113
+ .fc-time-grid .fc-highlight {
114
+ position: absolute;
115
+ left: 0;
116
+ right: 0;
117
+ /* top and bottom will be in by JS */ }
118
+
119
+ /* TimeGrid Event Containment
120
+ --------------------------------------------------------------------------------------------------*/
121
+ .fc-ltr .fc-time-grid .fc-event-container {
122
+ /* space on the sides of events for LTR (default) */
123
+ margin: 0 2.5% 0 2px; }
124
+
125
+ .fc-rtl .fc-time-grid .fc-event-container {
126
+ /* space on the sides of events for RTL */
127
+ margin: 0 2px 0 2.5%; }
128
+
129
+ .fc-time-grid .fc-event,
130
+ .fc-time-grid .fc-bgevent {
131
+ position: absolute;
132
+ z-index: 1;
133
+ /* scope inner z-index's */ }
134
+
135
+ .fc-time-grid .fc-bgevent {
136
+ /* background events always span full width */
137
+ left: 0;
138
+ right: 0; }
139
+
140
+ /* TimeGrid Event Styling
141
+ ----------------------------------------------------------------------------------------------------
142
+ We use the full "fc-time-grid-event" class instead of using descendants because the event won't
143
+ be a descendant of the grid when it is being dragged.
144
+ */
145
+ .fc-time-grid-event {
146
+ margin-bottom: 1px; }
147
+
148
+ .fc-time-grid-event-inset {
149
+ -webkit-box-shadow: 0px 0px 0px 1px #fff;
150
+ box-shadow: 0px 0px 0px 1px #fff; }
151
+
152
+ .fc-time-grid-event.fc-not-start {
153
+ /* events that are continuing from another day */
154
+ /* replace space made by the top border with padding */
155
+ border-top-width: 0;
156
+ padding-top: 1px;
157
+ /* remove top rounded corners */
158
+ border-top-left-radius: 0;
159
+ border-top-right-radius: 0; }
160
+
161
+ .fc-time-grid-event.fc-not-end {
162
+ /* replace space made by the top border with padding */
163
+ border-bottom-width: 0;
164
+ padding-bottom: 1px;
165
+ /* remove bottom rounded corners */
166
+ border-bottom-left-radius: 0;
167
+ border-bottom-right-radius: 0; }
168
+
169
+ .fc-time-grid-event .fc-content {
170
+ overflow: hidden;
171
+ max-height: 100%; }
172
+
173
+ .fc-time-grid-event .fc-time,
174
+ .fc-time-grid-event .fc-title {
175
+ padding: 0 1px; }
176
+
177
+ .fc-time-grid-event .fc-time {
178
+ font-size: .85em;
179
+ white-space: nowrap; }
180
+
181
+ /* short mode, where time and title are on the same line */
182
+ .fc-time-grid-event.fc-short .fc-content {
183
+ /* don't wrap to second line (now that contents will be inline) */
184
+ white-space: nowrap; }
185
+
186
+ .fc-time-grid-event.fc-short .fc-time,
187
+ .fc-time-grid-event.fc-short .fc-title {
188
+ /* put the time and title on the same line */
189
+ display: inline-block;
190
+ vertical-align: top; }
191
+
192
+ .fc-time-grid-event.fc-short .fc-time span {
193
+ display: none;
194
+ /* don't display the full time text... */ }
195
+
196
+ .fc-time-grid-event.fc-short .fc-time:before {
197
+ content: attr(data-start);
198
+ /* ...instead, display only the start time */ }
199
+
200
+ .fc-time-grid-event.fc-short .fc-time:after {
201
+ content: "\000A0-\000A0";
202
+ /* seperate with a dash, wrapped in nbsp's */ }
203
+
204
+ .fc-time-grid-event.fc-short .fc-title {
205
+ font-size: .85em;
206
+ /* make the title text the same size as the time */
207
+ padding: 0;
208
+ /* undo padding from above */ }
209
+
210
+ /* resizer (cursor device) */
211
+ .fc-time-grid-event.fc-allow-mouse-resize .fc-resizer {
212
+ left: 0;
213
+ right: 0;
214
+ bottom: 0;
215
+ height: 8px;
216
+ overflow: hidden;
217
+ line-height: 8px;
218
+ font-size: 11px;
219
+ font-family: monospace;
220
+ text-align: center;
221
+ cursor: s-resize; }
222
+
223
+ .fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after {
224
+ content: "="; }
225
+
226
+ /* resizer (touch device) */
227
+ .fc-time-grid-event.fc-selected .fc-resizer {
228
+ /* 10x10 dot */
229
+ border-radius: 5px;
230
+ border-width: 1px;
231
+ width: 8px;
232
+ height: 8px;
233
+ border-style: solid;
234
+ border-color: inherit;
235
+ background: #fff;
236
+ /* horizontally center */
237
+ left: 50%;
238
+ margin-left: -5px;
239
+ /* center on the bottom edge */
240
+ bottom: -5px; }
241
+
242
+ /* Now Indicator
243
+ --------------------------------------------------------------------------------------------------*/
244
+ .fc-time-grid .fc-now-indicator-line {
245
+ border-top-width: 1px;
246
+ left: 0;
247
+ right: 0; }
248
+
249
+ /* arrow on axis */
250
+ .fc-time-grid .fc-now-indicator-arrow {
251
+ margin-top: -5px;
252
+ /* vertically center on top coordinate */ }
253
+
254
+ .fc-ltr .fc-time-grid .fc-now-indicator-arrow {
255
+ left: 0;
256
+ /* triangle pointing right... */
257
+ border-width: 5px 0 5px 6px;
258
+ border-top-color: transparent;
259
+ border-bottom-color: transparent; }
260
+
261
+ .fc-rtl .fc-time-grid .fc-now-indicator-arrow {
262
+ right: 0;
263
+ /* triangle pointing left... */
264
+ border-width: 5px 6px 5px 0;
265
+ border-top-color: transparent;
266
+ border-bottom-color: transparent; }
@@ -0,0 +1,1339 @@
1
+ /*!
2
+ FullCalendar Time Grid Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ (function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) :
8
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygrid'], factory) :
9
+ (global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid));
10
+ }(this, function (exports, core, daygrid) { 'use strict';
11
+
12
+ /*! *****************************************************************************
13
+ Copyright (c) Microsoft Corporation. All rights reserved.
14
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
15
+ this file except in compliance with the License. You may obtain a copy of the
16
+ License at http://www.apache.org/licenses/LICENSE-2.0
17
+
18
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
20
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
21
+ MERCHANTABLITY OR NON-INFRINGEMENT.
22
+
23
+ See the Apache Version 2.0 License for specific language governing permissions
24
+ and limitations under the License.
25
+ ***************************************************************************** */
26
+ /* global Reflect, Promise */
27
+
28
+ var extendStatics = function(d, b) {
29
+ extendStatics = Object.setPrototypeOf ||
30
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
32
+ return extendStatics(d, b);
33
+ };
34
+
35
+ function __extends(d, b) {
36
+ extendStatics(d, b);
37
+ function __() { this.constructor = d; }
38
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
39
+ }
40
+
41
+ var __assign = function() {
42
+ __assign = Object.assign || function __assign(t) {
43
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
44
+ s = arguments[i];
45
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
46
+ }
47
+ return t;
48
+ };
49
+ return __assign.apply(this, arguments);
50
+ };
51
+
52
+ /*
53
+ Only handles foreground segs.
54
+ Does not own rendering. Use for low-level util methods by TimeGrid.
55
+ */
56
+ var TimeGridEventRenderer = /** @class */ (function (_super) {
57
+ __extends(TimeGridEventRenderer, _super);
58
+ function TimeGridEventRenderer(timeGrid) {
59
+ var _this = _super.call(this, timeGrid.context) || this;
60
+ _this.timeGrid = timeGrid;
61
+ _this.fullTimeFormat = core.createFormatter({
62
+ hour: 'numeric',
63
+ minute: '2-digit',
64
+ separator: _this.context.options.defaultRangeSeparator
65
+ });
66
+ return _this;
67
+ }
68
+ // Given an array of foreground segments, render a DOM element for each, computes position,
69
+ // and attaches to the column inner-container elements.
70
+ TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
71
+ var segsByCol = this.timeGrid.groupSegsByCol(segs);
72
+ // order the segs within each column
73
+ // TODO: have groupSegsByCol do this?
74
+ for (var col = 0; col < segsByCol.length; col++) {
75
+ segsByCol[col] = this.sortEventSegs(segsByCol[col]);
76
+ }
77
+ this.segsByCol = segsByCol;
78
+ this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls);
79
+ };
80
+ TimeGridEventRenderer.prototype.detachSegs = function (segs) {
81
+ segs.forEach(function (seg) {
82
+ core.removeElement(seg.el);
83
+ });
84
+ this.segsByCol = null;
85
+ };
86
+ TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) {
87
+ var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
88
+ var colCnt = timeGrid.colCnt;
89
+ timeGrid.computeSegVerticals(allSegs); // horizontals relies on this
90
+ if (segsByCol) {
91
+ for (var col = 0; col < colCnt; col++) {
92
+ this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array
93
+ }
94
+ }
95
+ };
96
+ TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) {
97
+ var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
98
+ var colCnt = timeGrid.colCnt;
99
+ timeGrid.assignSegVerticals(allSegs); // horizontals relies on this
100
+ if (segsByCol) {
101
+ for (var col = 0; col < colCnt; col++) {
102
+ this.assignSegCss(segsByCol[col]);
103
+ }
104
+ }
105
+ };
106
+ // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
107
+ TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
108
+ return {
109
+ hour: 'numeric',
110
+ minute: '2-digit',
111
+ meridiem: false
112
+ };
113
+ };
114
+ // Computes a default `displayEventEnd` value if one is not expliclty defined
115
+ TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
116
+ return true;
117
+ };
118
+ // Renders the HTML for a single event segment's default rendering
119
+ TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
120
+ var eventRange = seg.eventRange;
121
+ var eventDef = eventRange.def;
122
+ var eventUi = eventRange.ui;
123
+ var allDay = eventDef.allDay;
124
+ var isDraggable = eventUi.startEditable;
125
+ var isResizableFromStart = seg.isStart && eventUi.durationEditable && this.context.options.eventResizableFromStart;
126
+ var isResizableFromEnd = seg.isEnd && eventUi.durationEditable;
127
+ var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
128
+ var skinCss = core.cssToStr(this.getSkinCss(eventUi));
129
+ var timeText;
130
+ var fullTimeText; // more verbose time text. for the print stylesheet
131
+ var startTimeText; // just the start time text
132
+ classes.unshift('fc-time-grid-event');
133
+ // if the event appears to span more than one day...
134
+ if (core.isMultiDayRange(eventRange.range)) {
135
+ // Don't display time text on segments that run entirely through a day.
136
+ // That would appear as midnight-midnight and would look dumb.
137
+ // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
138
+ if (seg.isStart || seg.isEnd) {
139
+ var unzonedStart = seg.start;
140
+ var unzonedEnd = seg.end;
141
+ timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones
142
+ fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat);
143
+ startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false
144
+ }
145
+ }
146
+ else {
147
+ // Display the normal time text for the *event's* times
148
+ timeText = this.getTimeText(eventRange);
149
+ fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat);
150
+ startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false
151
+ }
152
+ return '<a class="' + classes.join(' ') + '"' +
153
+ (eventDef.url ?
154
+ ' href="' + core.htmlEscape(eventDef.url) + '"' :
155
+ '') +
156
+ (skinCss ?
157
+ ' style="' + skinCss + '"' :
158
+ '') +
159
+ '>' +
160
+ '<div class="fc-content">' +
161
+ (timeText ?
162
+ '<div class="fc-time"' +
163
+ ' data-start="' + core.htmlEscape(startTimeText) + '"' +
164
+ ' data-full="' + core.htmlEscape(fullTimeText) + '"' +
165
+ '>' +
166
+ '<span>' + core.htmlEscape(timeText) + '</span>' +
167
+ '</div>' :
168
+ '') +
169
+ (eventDef.title ?
170
+ '<div class="fc-title">' +
171
+ core.htmlEscape(eventDef.title) +
172
+ '</div>' :
173
+ '') +
174
+ '</div>' +
175
+ /* TODO: write CSS for this
176
+ (isResizableFromStart ?
177
+ '<div class="fc-resizer fc-start-resizer"></div>' :
178
+ ''
179
+ ) +
180
+ */
181
+ (isResizableFromEnd ?
182
+ '<div class="fc-resizer fc-end-resizer"></div>' :
183
+ '') +
184
+ '</a>';
185
+ };
186
+ // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
187
+ // Assumed the segs are already ordered.
188
+ // NOTE: Also reorders the given array by date!
189
+ TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) {
190
+ var levels;
191
+ var level0;
192
+ var i;
193
+ levels = buildSlotSegLevels(segs);
194
+ computeForwardSlotSegs(levels);
195
+ if ((level0 = levels[0])) {
196
+ for (i = 0; i < level0.length; i++) {
197
+ computeSlotSegPressures(level0[i]);
198
+ }
199
+ for (i = 0; i < level0.length; i++) {
200
+ this.computeSegForwardBack(level0[i], 0, 0);
201
+ }
202
+ }
203
+ };
204
+ // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
205
+ // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
206
+ // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
207
+ //
208
+ // The segment might be part of a "series", which means consecutive segments with the same pressure
209
+ // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
210
+ // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
211
+ // coordinate of the first segment in the series.
212
+ TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
213
+ var forwardSegs = seg.forwardSegs;
214
+ var i;
215
+ if (seg.forwardCoord === undefined) { // not already computed
216
+ if (!forwardSegs.length) {
217
+ // if there are no forward segments, this segment should butt up against the edge
218
+ seg.forwardCoord = 1;
219
+ }
220
+ else {
221
+ // sort highest pressure first
222
+ this.sortForwardSegs(forwardSegs);
223
+ // this segment's forwardCoord will be calculated from the backwardCoord of the
224
+ // highest-pressure forward segment.
225
+ this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
226
+ seg.forwardCoord = forwardSegs[0].backwardCoord;
227
+ }
228
+ // calculate the backwardCoord from the forwardCoord. consider the series
229
+ seg.backwardCoord = seg.forwardCoord -
230
+ (seg.forwardCoord - seriesBackwardCoord) / // available width for series
231
+ (seriesBackwardPressure + 1); // # of segments in the series
232
+ // use this segment's coordinates to computed the coordinates of the less-pressurized
233
+ // forward segments
234
+ for (i = 0; i < forwardSegs.length; i++) {
235
+ this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
236
+ }
237
+ }
238
+ };
239
+ TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
240
+ var objs = forwardSegs.map(buildTimeGridSegCompareObj);
241
+ var specs = [
242
+ // put higher-pressure first
243
+ { field: 'forwardPressure', order: -1 },
244
+ // put segments that are closer to initial edge first (and favor ones with no coords yet)
245
+ { field: 'backwardCoord', order: 1 }
246
+ ].concat(this.context.view.eventOrderSpecs);
247
+ objs.sort(function (obj0, obj1) {
248
+ return core.compareByFieldSpecs(obj0, obj1, specs);
249
+ });
250
+ return objs.map(function (c) {
251
+ return c._seg;
252
+ });
253
+ };
254
+ // Given foreground event segments that have already had their position coordinates computed,
255
+ // assigns position-related CSS values to their elements.
256
+ TimeGridEventRenderer.prototype.assignSegCss = function (segs) {
257
+ for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
258
+ var seg = segs_1[_i];
259
+ core.applyStyle(seg.el, this.generateSegCss(seg));
260
+ if (seg.level > 0) {
261
+ seg.el.classList.add('fc-time-grid-event-inset');
262
+ }
263
+ // if the event is short that the title will be cut off,
264
+ // attach a className that condenses the title into the time area.
265
+ if (seg.eventRange.def.title && seg.bottom - seg.top < 30) {
266
+ seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name
267
+ }
268
+ }
269
+ };
270
+ // Generates an object with CSS properties/values that should be applied to an event segment element.
271
+ // Contains important positioning-related properties that should be applied to any event element, customized or not.
272
+ TimeGridEventRenderer.prototype.generateSegCss = function (seg) {
273
+ var shouldOverlap = this.context.options.slotEventOverlap;
274
+ var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
275
+ var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
276
+ var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
277
+ var isRtl = this.timeGrid.isRtl;
278
+ var left; // amount of space from left edge, a fraction of the total width
279
+ var right; // amount of space from right edge, a fraction of the total width
280
+ if (shouldOverlap) {
281
+ // double the width, but don't go beyond the maximum forward coordinate (1.0)
282
+ forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
283
+ }
284
+ if (isRtl) {
285
+ left = 1 - forwardCoord;
286
+ right = backwardCoord;
287
+ }
288
+ else {
289
+ left = backwardCoord;
290
+ right = 1 - forwardCoord;
291
+ }
292
+ props.zIndex = seg.level + 1; // convert from 0-base to 1-based
293
+ props.left = left * 100 + '%';
294
+ props.right = right * 100 + '%';
295
+ if (shouldOverlap && seg.forwardPressure) {
296
+ // add padding to the edge so that forward stacked events don't cover the resizer's icon
297
+ props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
298
+ }
299
+ return props;
300
+ };
301
+ return TimeGridEventRenderer;
302
+ }(core.FgEventRenderer));
303
+ // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
304
+ // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
305
+ function buildSlotSegLevels(segs) {
306
+ var levels = [];
307
+ var i;
308
+ var seg;
309
+ var j;
310
+ for (i = 0; i < segs.length; i++) {
311
+ seg = segs[i];
312
+ // go through all the levels and stop on the first level where there are no collisions
313
+ for (j = 0; j < levels.length; j++) {
314
+ if (!computeSlotSegCollisions(seg, levels[j]).length) {
315
+ break;
316
+ }
317
+ }
318
+ seg.level = j;
319
+ (levels[j] || (levels[j] = [])).push(seg);
320
+ }
321
+ return levels;
322
+ }
323
+ // For every segment, figure out the other segments that are in subsequent
324
+ // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
325
+ function computeForwardSlotSegs(levels) {
326
+ var i;
327
+ var level;
328
+ var j;
329
+ var seg;
330
+ var k;
331
+ for (i = 0; i < levels.length; i++) {
332
+ level = levels[i];
333
+ for (j = 0; j < level.length; j++) {
334
+ seg = level[j];
335
+ seg.forwardSegs = [];
336
+ for (k = i + 1; k < levels.length; k++) {
337
+ computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
338
+ }
339
+ }
340
+ }
341
+ }
342
+ // Figure out which path forward (via seg.forwardSegs) results in the longest path until
343
+ // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
344
+ function computeSlotSegPressures(seg) {
345
+ var forwardSegs = seg.forwardSegs;
346
+ var forwardPressure = 0;
347
+ var i;
348
+ var forwardSeg;
349
+ if (seg.forwardPressure === undefined) { // not already computed
350
+ for (i = 0; i < forwardSegs.length; i++) {
351
+ forwardSeg = forwardSegs[i];
352
+ // figure out the child's maximum forward path
353
+ computeSlotSegPressures(forwardSeg);
354
+ // either use the existing maximum, or use the child's forward pressure
355
+ // plus one (for the forwardSeg itself)
356
+ forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
357
+ }
358
+ seg.forwardPressure = forwardPressure;
359
+ }
360
+ }
361
+ // Find all the segments in `otherSegs` that vertically collide with `seg`.
362
+ // Append into an optionally-supplied `results` array and return.
363
+ function computeSlotSegCollisions(seg, otherSegs, results) {
364
+ if (results === void 0) { results = []; }
365
+ for (var i = 0; i < otherSegs.length; i++) {
366
+ if (isSlotSegCollision(seg, otherSegs[i])) {
367
+ results.push(otherSegs[i]);
368
+ }
369
+ }
370
+ return results;
371
+ }
372
+ // Do these segments occupy the same vertical space?
373
+ function isSlotSegCollision(seg1, seg2) {
374
+ return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
375
+ }
376
+ function buildTimeGridSegCompareObj(seg) {
377
+ var obj = core.buildSegCompareObj(seg);
378
+ obj.forwardPressure = seg.forwardPressure;
379
+ obj.backwardCoord = seg.backwardCoord;
380
+ return obj;
381
+ }
382
+
383
+ var TimeGridMirrorRenderer = /** @class */ (function (_super) {
384
+ __extends(TimeGridMirrorRenderer, _super);
385
+ function TimeGridMirrorRenderer() {
386
+ return _super !== null && _super.apply(this, arguments) || this;
387
+ }
388
+ TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
389
+ this.segsByCol = this.timeGrid.groupSegsByCol(segs);
390
+ this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls);
391
+ this.sourceSeg = mirrorInfo.sourceSeg;
392
+ };
393
+ TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) {
394
+ var props = _super.prototype.generateSegCss.call(this, seg);
395
+ var sourceSeg = this.sourceSeg;
396
+ if (sourceSeg && sourceSeg.col === seg.col) {
397
+ var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg);
398
+ props.left = sourceSegProps.left;
399
+ props.right = sourceSegProps.right;
400
+ props.marginLeft = sourceSegProps.marginLeft;
401
+ props.marginRight = sourceSegProps.marginRight;
402
+ }
403
+ return props;
404
+ };
405
+ return TimeGridMirrorRenderer;
406
+ }(TimeGridEventRenderer));
407
+
408
+ var TimeGridFillRenderer = /** @class */ (function (_super) {
409
+ __extends(TimeGridFillRenderer, _super);
410
+ function TimeGridFillRenderer(timeGrid) {
411
+ var _this = _super.call(this, timeGrid.context) || this;
412
+ _this.timeGrid = timeGrid;
413
+ return _this;
414
+ }
415
+ TimeGridFillRenderer.prototype.attachSegs = function (type, segs) {
416
+ var timeGrid = this.timeGrid;
417
+ var containerEls;
418
+ // TODO: more efficient lookup
419
+ if (type === 'bgEvent') {
420
+ containerEls = timeGrid.bgContainerEls;
421
+ }
422
+ else if (type === 'businessHours') {
423
+ containerEls = timeGrid.businessContainerEls;
424
+ }
425
+ else if (type === 'highlight') {
426
+ containerEls = timeGrid.highlightContainerEls;
427
+ }
428
+ timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
429
+ return segs.map(function (seg) {
430
+ return seg.el;
431
+ });
432
+ };
433
+ TimeGridFillRenderer.prototype.computeSegSizes = function (segs) {
434
+ this.timeGrid.computeSegVerticals(segs);
435
+ };
436
+ TimeGridFillRenderer.prototype.assignSegSizes = function (segs) {
437
+ this.timeGrid.assignSegVerticals(segs);
438
+ };
439
+ return TimeGridFillRenderer;
440
+ }(core.FillRenderer));
441
+
442
+ /* A component that renders one or more columns of vertical time slots
443
+ ----------------------------------------------------------------------------------------------------------------------*/
444
+ // potential nice values for the slot-duration and interval-duration
445
+ // from largest to smallest
446
+ var AGENDA_STOCK_SUB_DURATIONS = [
447
+ { hours: 1 },
448
+ { minutes: 30 },
449
+ { minutes: 15 },
450
+ { seconds: 30 },
451
+ { seconds: 15 }
452
+ ];
453
+ var TimeGrid = /** @class */ (function (_super) {
454
+ __extends(TimeGrid, _super);
455
+ function TimeGrid(context, el, renderProps) {
456
+ var _this = _super.call(this, context, el) || this;
457
+ _this.isSlatSizesDirty = false;
458
+ _this.isColSizesDirty = false;
459
+ _this.renderSlats = core.memoizeRendering(_this._renderSlats);
460
+ var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this);
461
+ var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this);
462
+ _this.mirrorRenderer = new TimeGridMirrorRenderer(_this);
463
+ var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns);
464
+ _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]);
465
+ _this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]);
466
+ _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]);
467
+ _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]);
468
+ _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
469
+ _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]);
470
+ _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]);
471
+ _this.processOptions();
472
+ el.innerHTML =
473
+ '<div class="fc-bg"></div>' +
474
+ '<div class="fc-slats"></div>' +
475
+ '<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />';
476
+ _this.rootBgContainerEl = el.querySelector('.fc-bg');
477
+ _this.slatContainerEl = el.querySelector('.fc-slats');
478
+ _this.bottomRuleEl = el.querySelector('.fc-divider');
479
+ _this.renderProps = renderProps;
480
+ return _this;
481
+ }
482
+ /* Options
483
+ ------------------------------------------------------------------------------------------------------------------*/
484
+ // Parses various options into properties of this object
485
+ TimeGrid.prototype.processOptions = function () {
486
+ var slotDuration = this.opt('slotDuration');
487
+ var snapDuration = this.opt('snapDuration');
488
+ var snapsPerSlot;
489
+ var input;
490
+ slotDuration = core.createDuration(slotDuration);
491
+ snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration;
492
+ snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration);
493
+ if (snapsPerSlot === null) {
494
+ snapDuration = slotDuration;
495
+ snapsPerSlot = 1;
496
+ // TODO: say warning?
497
+ }
498
+ this.slotDuration = slotDuration;
499
+ this.snapDuration = snapDuration;
500
+ this.snapsPerSlot = snapsPerSlot;
501
+ // might be an array value (for TimelineView).
502
+ // if so, getting the most granular entry (the last one probably).
503
+ input = this.opt('slotLabelFormat');
504
+ if (Array.isArray(input)) {
505
+ input = input[input.length - 1];
506
+ }
507
+ this.labelFormat = core.createFormatter(input || {
508
+ hour: 'numeric',
509
+ minute: '2-digit',
510
+ omitZeroMinute: true,
511
+ meridiem: 'short'
512
+ });
513
+ input = this.opt('slotLabelInterval');
514
+ this.labelInterval = input ?
515
+ core.createDuration(input) :
516
+ this.computeLabelInterval(slotDuration);
517
+ };
518
+ // Computes an automatic value for slotLabelInterval
519
+ TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
520
+ var i;
521
+ var labelInterval;
522
+ var slotsPerLabel;
523
+ // find the smallest stock label interval that results in more than one slots-per-label
524
+ for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
525
+ labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]);
526
+ slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration);
527
+ if (slotsPerLabel !== null && slotsPerLabel > 1) {
528
+ return labelInterval;
529
+ }
530
+ }
531
+ return slotDuration; // fall back
532
+ };
533
+ /* Rendering
534
+ ------------------------------------------------------------------------------------------------------------------*/
535
+ TimeGrid.prototype.render = function (props) {
536
+ var cells = props.cells;
537
+ this.colCnt = cells.length;
538
+ this.renderSlats(props.dateProfile);
539
+ this.renderColumns(props.cells, props.dateProfile);
540
+ this.renderBusinessHours(props.businessHourSegs);
541
+ this.renderDateSelection(props.dateSelectionSegs);
542
+ this.renderFgEvents(props.fgEventSegs);
543
+ this.renderBgEvents(props.bgEventSegs);
544
+ this.renderEventSelection(props.eventSelection);
545
+ this.renderEventDrag(props.eventDrag);
546
+ this.renderEventResize(props.eventResize);
547
+ };
548
+ TimeGrid.prototype.destroy = function () {
549
+ _super.prototype.destroy.call(this);
550
+ // should unrender everything else too
551
+ this.renderSlats.unrender();
552
+ this.renderColumns.unrender();
553
+ };
554
+ TimeGrid.prototype.updateSize = function (isResize) {
555
+ var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
556
+ if (isResize || this.isSlatSizesDirty) {
557
+ this.buildSlatPositions();
558
+ this.isSlatSizesDirty = false;
559
+ }
560
+ if (isResize || this.isColSizesDirty) {
561
+ this.buildColPositions();
562
+ this.isColSizesDirty = false;
563
+ }
564
+ fillRenderer.computeSizes(isResize);
565
+ eventRenderer.computeSizes(isResize);
566
+ mirrorRenderer.computeSizes(isResize);
567
+ fillRenderer.assignSizes(isResize);
568
+ eventRenderer.assignSizes(isResize);
569
+ mirrorRenderer.assignSizes(isResize);
570
+ };
571
+ TimeGrid.prototype._renderSlats = function (dateProfile) {
572
+ var theme = this.theme;
573
+ this.slatContainerEl.innerHTML =
574
+ '<table class="' + theme.getClass('tableGrid') + '">' +
575
+ this.renderSlatRowHtml(dateProfile) +
576
+ '</table>';
577
+ this.slatEls = core.findElements(this.slatContainerEl, 'tr');
578
+ this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical
579
+ );
580
+ this.isSlatSizesDirty = true;
581
+ };
582
+ // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
583
+ TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) {
584
+ var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl;
585
+ var html = '';
586
+ var dayStart = core.startOfDay(dateProfile.renderRange.start);
587
+ var slotTime = dateProfile.minTime;
588
+ var slotIterator = core.createDuration(0);
589
+ var slotDate; // will be on the view's first day, but we only care about its time
590
+ var isLabeled;
591
+ var axisHtml;
592
+ // Calculate the time for each slot
593
+ while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) {
594
+ slotDate = dateEnv.add(dayStart, slotTime);
595
+ isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null;
596
+ axisHtml =
597
+ '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' +
598
+ (isLabeled ?
599
+ '<span>' + // for matchCellWidths
600
+ core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) +
601
+ '</span>' :
602
+ '') +
603
+ '</td>';
604
+ html +=
605
+ '<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' +
606
+ (isLabeled ? '' : ' class="fc-minor"') +
607
+ '>' +
608
+ (!isRtl ? axisHtml : '') +
609
+ '<td class="' + theme.getClass('widgetContent') + '"></td>' +
610
+ (isRtl ? axisHtml : '') +
611
+ '</tr>';
612
+ slotTime = core.addDurations(slotTime, this.slotDuration);
613
+ slotIterator = core.addDurations(slotIterator, this.slotDuration);
614
+ }
615
+ return html;
616
+ };
617
+ TimeGrid.prototype._renderColumns = function (cells, dateProfile) {
618
+ var theme = this.theme;
619
+ var bgRow = new daygrid.DayBgRow(this.context);
620
+ this.rootBgContainerEl.innerHTML =
621
+ '<table class="' + theme.getClass('tableGrid') + '">' +
622
+ bgRow.renderHtml({
623
+ cells: cells,
624
+ dateProfile: dateProfile,
625
+ renderIntroHtml: this.renderProps.renderBgIntroHtml
626
+ }) +
627
+ '</table>';
628
+ this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
629
+ if (this.isRtl) {
630
+ this.colEls.reverse();
631
+ }
632
+ this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal
633
+ false);
634
+ this.renderContentSkeleton();
635
+ this.isColSizesDirty = true;
636
+ };
637
+ TimeGrid.prototype._unrenderColumns = function () {
638
+ this.unrenderContentSkeleton();
639
+ };
640
+ /* Content Skeleton
641
+ ------------------------------------------------------------------------------------------------------------------*/
642
+ // Renders the DOM that the view's content will live in
643
+ TimeGrid.prototype.renderContentSkeleton = function () {
644
+ var parts = [];
645
+ var skeletonEl;
646
+ parts.push(this.renderProps.renderIntroHtml());
647
+ for (var i = 0; i < this.colCnt; i++) {
648
+ parts.push('<td>' +
649
+ '<div class="fc-content-col">' +
650
+ '<div class="fc-event-container fc-mirror-container"></div>' +
651
+ '<div class="fc-event-container"></div>' +
652
+ '<div class="fc-highlight-container"></div>' +
653
+ '<div class="fc-bgevent-container"></div>' +
654
+ '<div class="fc-business-container"></div>' +
655
+ '</div>' +
656
+ '</td>');
657
+ }
658
+ if (this.isRtl) {
659
+ parts.reverse();
660
+ }
661
+ skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' +
662
+ '<table>' +
663
+ '<tr>' + parts.join('') + '</tr>' +
664
+ '</table>' +
665
+ '</div>');
666
+ this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col');
667
+ this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container');
668
+ this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)');
669
+ this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container');
670
+ this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container');
671
+ this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container');
672
+ if (this.isRtl) {
673
+ this.colContainerEls.reverse();
674
+ this.mirrorContainerEls.reverse();
675
+ this.fgContainerEls.reverse();
676
+ this.bgContainerEls.reverse();
677
+ this.highlightContainerEls.reverse();
678
+ this.businessContainerEls.reverse();
679
+ }
680
+ this.el.appendChild(skeletonEl);
681
+ };
682
+ TimeGrid.prototype.unrenderContentSkeleton = function () {
683
+ core.removeElement(this.contentSkeletonEl);
684
+ };
685
+ // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
686
+ TimeGrid.prototype.groupSegsByCol = function (segs) {
687
+ var segsByCol = [];
688
+ var i;
689
+ for (i = 0; i < this.colCnt; i++) {
690
+ segsByCol.push([]);
691
+ }
692
+ for (i = 0; i < segs.length; i++) {
693
+ segsByCol[segs[i].col].push(segs[i]);
694
+ }
695
+ return segsByCol;
696
+ };
697
+ // Given segments grouped by column, insert the segments' elements into a parallel array of container
698
+ // elements, each living within a column.
699
+ TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
700
+ var col;
701
+ var segs;
702
+ var i;
703
+ for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
704
+ segs = segsByCol[col];
705
+ for (i = 0; i < segs.length; i++) {
706
+ containerEls[col].appendChild(segs[i].el);
707
+ }
708
+ }
709
+ };
710
+ /* Now Indicator
711
+ ------------------------------------------------------------------------------------------------------------------*/
712
+ TimeGrid.prototype.getNowIndicatorUnit = function () {
713
+ return 'minute'; // will refresh on the minute
714
+ };
715
+ TimeGrid.prototype.renderNowIndicator = function (segs, date) {
716
+ // HACK: if date columns not ready for some reason (scheduler)
717
+ if (!this.colContainerEls) {
718
+ return;
719
+ }
720
+ var top = this.computeDateTop(date);
721
+ var nodes = [];
722
+ var i;
723
+ // render lines within the columns
724
+ for (i = 0; i < segs.length; i++) {
725
+ var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' });
726
+ lineEl.style.top = top + 'px';
727
+ this.colContainerEls[segs[i].col].appendChild(lineEl);
728
+ nodes.push(lineEl);
729
+ }
730
+ // render an arrow over the axis
731
+ if (segs.length > 0) { // is the current time in view?
732
+ var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' });
733
+ arrowEl.style.top = top + 'px';
734
+ this.contentSkeletonEl.appendChild(arrowEl);
735
+ nodes.push(arrowEl);
736
+ }
737
+ this.nowIndicatorEls = nodes;
738
+ };
739
+ TimeGrid.prototype.unrenderNowIndicator = function () {
740
+ if (this.nowIndicatorEls) {
741
+ this.nowIndicatorEls.forEach(core.removeElement);
742
+ this.nowIndicatorEls = null;
743
+ }
744
+ };
745
+ /* Coordinates
746
+ ------------------------------------------------------------------------------------------------------------------*/
747
+ TimeGrid.prototype.getTotalSlatHeight = function () {
748
+ return this.slatContainerEl.offsetHeight;
749
+ };
750
+ // Computes the top coordinate, relative to the bounds of the grid, of the given date.
751
+ // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
752
+ TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) {
753
+ if (!startOfDayDate) {
754
+ startOfDayDate = core.startOfDay(when);
755
+ }
756
+ return this.computeTimeTop(when.valueOf() - startOfDayDate.valueOf());
757
+ };
758
+ // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
759
+ TimeGrid.prototype.computeTimeTop = function (timeMs) {
760
+ var len = this.slatEls.length;
761
+ var dateProfile = this.props.dateProfile;
762
+ var slatCoverage = (timeMs - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered
763
+ var slatIndex;
764
+ var slatRemainder;
765
+ // compute a floating-point number for how many slats should be progressed through.
766
+ // from 0 to number of slats (inclusive)
767
+ // constrained because minTime/maxTime might be customized.
768
+ slatCoverage = Math.max(0, slatCoverage);
769
+ slatCoverage = Math.min(len, slatCoverage);
770
+ // an integer index of the furthest whole slat
771
+ // from 0 to number slats (*exclusive*, so len-1)
772
+ slatIndex = Math.floor(slatCoverage);
773
+ slatIndex = Math.min(slatIndex, len - 1);
774
+ // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
775
+ // could be 1.0 if slatCoverage is covering *all* the slots
776
+ slatRemainder = slatCoverage - slatIndex;
777
+ return this.slatPositions.tops[slatIndex] +
778
+ this.slatPositions.getHeight(slatIndex) * slatRemainder;
779
+ };
780
+ // For each segment in an array, computes and assigns its top and bottom properties
781
+ TimeGrid.prototype.computeSegVerticals = function (segs) {
782
+ var eventMinHeight = this.opt('timeGridEventMinHeight');
783
+ var i;
784
+ var seg;
785
+ var dayDate;
786
+ for (i = 0; i < segs.length; i++) {
787
+ seg = segs[i];
788
+ dayDate = this.props.cells[seg.col].date;
789
+ seg.top = this.computeDateTop(seg.start, dayDate);
790
+ seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate));
791
+ }
792
+ };
793
+ // Given segments that already have their top/bottom properties computed, applies those values to
794
+ // the segments' elements.
795
+ TimeGrid.prototype.assignSegVerticals = function (segs) {
796
+ var i;
797
+ var seg;
798
+ for (i = 0; i < segs.length; i++) {
799
+ seg = segs[i];
800
+ core.applyStyle(seg.el, this.generateSegVerticalCss(seg));
801
+ }
802
+ };
803
+ // Generates an object with CSS properties for the top/bottom coordinates of a segment element
804
+ TimeGrid.prototype.generateSegVerticalCss = function (seg) {
805
+ return {
806
+ top: seg.top,
807
+ bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
808
+ };
809
+ };
810
+ /* Sizing
811
+ ------------------------------------------------------------------------------------------------------------------*/
812
+ TimeGrid.prototype.buildColPositions = function () {
813
+ this.colPositions.build();
814
+ };
815
+ TimeGrid.prototype.buildSlatPositions = function () {
816
+ this.slatPositions.build();
817
+ };
818
+ /* Hit System
819
+ ------------------------------------------------------------------------------------------------------------------*/
820
+ TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) {
821
+ var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions;
822
+ var colIndex = colPositions.leftToIndex(positionLeft);
823
+ var slatIndex = slatPositions.topToIndex(positionTop);
824
+ if (colIndex != null && slatIndex != null) {
825
+ var slatTop = slatPositions.tops[slatIndex];
826
+ var slatHeight = slatPositions.getHeight(slatIndex);
827
+ var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
828
+ var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
829
+ var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
830
+ var dayDate = this.props.cells[colIndex].date;
831
+ var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex));
832
+ var start = dateEnv.add(dayDate, time);
833
+ var end = dateEnv.add(start, this.snapDuration);
834
+ return {
835
+ col: colIndex,
836
+ dateSpan: {
837
+ range: { start: start, end: end },
838
+ allDay: false
839
+ },
840
+ dayEl: this.colEls[colIndex],
841
+ relativeRect: {
842
+ left: colPositions.lefts[colIndex],
843
+ right: colPositions.rights[colIndex],
844
+ top: slatTop,
845
+ bottom: slatTop + slatHeight
846
+ }
847
+ };
848
+ }
849
+ };
850
+ /* Event Drag Visualization
851
+ ------------------------------------------------------------------------------------------------------------------*/
852
+ TimeGrid.prototype._renderEventDrag = function (state) {
853
+ if (state) {
854
+ this.eventRenderer.hideByHash(state.affectedInstances);
855
+ if (state.isEvent) {
856
+ this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
857
+ }
858
+ else {
859
+ this.fillRenderer.renderSegs('highlight', state.segs);
860
+ }
861
+ }
862
+ };
863
+ TimeGrid.prototype._unrenderEventDrag = function (state) {
864
+ if (state) {
865
+ this.eventRenderer.showByHash(state.affectedInstances);
866
+ this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
867
+ this.fillRenderer.unrender('highlight');
868
+ }
869
+ };
870
+ /* Event Resize Visualization
871
+ ------------------------------------------------------------------------------------------------------------------*/
872
+ TimeGrid.prototype._renderEventResize = function (state) {
873
+ if (state) {
874
+ this.eventRenderer.hideByHash(state.affectedInstances);
875
+ this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
876
+ }
877
+ };
878
+ TimeGrid.prototype._unrenderEventResize = function (state) {
879
+ if (state) {
880
+ this.eventRenderer.showByHash(state.affectedInstances);
881
+ this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
882
+ }
883
+ };
884
+ /* Selection
885
+ ------------------------------------------------------------------------------------------------------------------*/
886
+ // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
887
+ TimeGrid.prototype._renderDateSelection = function (segs) {
888
+ if (segs) {
889
+ if (this.opt('selectMirror')) {
890
+ this.mirrorRenderer.renderSegs(segs, { isSelecting: true });
891
+ }
892
+ else {
893
+ this.fillRenderer.renderSegs('highlight', segs);
894
+ }
895
+ }
896
+ };
897
+ TimeGrid.prototype._unrenderDateSelection = function (segs) {
898
+ this.mirrorRenderer.unrender(segs, { isSelecting: true });
899
+ this.fillRenderer.unrender('highlight');
900
+ };
901
+ return TimeGrid;
902
+ }(core.DateComponent));
903
+
904
+ var AllDaySplitter = /** @class */ (function (_super) {
905
+ __extends(AllDaySplitter, _super);
906
+ function AllDaySplitter() {
907
+ return _super !== null && _super.apply(this, arguments) || this;
908
+ }
909
+ AllDaySplitter.prototype.getKeyInfo = function () {
910
+ return {
911
+ allDay: {},
912
+ timed: {}
913
+ };
914
+ };
915
+ AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
916
+ if (dateSpan.allDay) {
917
+ return ['allDay'];
918
+ }
919
+ else {
920
+ return ['timed'];
921
+ }
922
+ };
923
+ AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
924
+ if (!eventDef.allDay) {
925
+ return ['timed'];
926
+ }
927
+ else if (core.hasBgRendering(eventDef)) {
928
+ return ['timed', 'allDay'];
929
+ }
930
+ else {
931
+ return ['allDay'];
932
+ }
933
+ };
934
+ return AllDaySplitter;
935
+ }(core.Splitter));
936
+
937
+ var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5;
938
+ var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' });
939
+ /* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically.
940
+ ----------------------------------------------------------------------------------------------------------------------*/
941
+ // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
942
+ // Responsible for managing width/height.
943
+ var TimeGridView = /** @class */ (function (_super) {
944
+ __extends(TimeGridView, _super);
945
+ function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) {
946
+ var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
947
+ _this.splitter = new AllDaySplitter();
948
+ /* Header Render Methods
949
+ ------------------------------------------------------------------------------------------------------------------*/
950
+ // Generates the HTML that will go before the day-of week header cells
951
+ _this.renderHeadIntroHtml = function () {
952
+ var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv;
953
+ var range = _this.props.dateProfile.renderRange;
954
+ var dayCnt = core.diffDays(range.start, range.end);
955
+ var weekText;
956
+ if (_this.opt('weekNumbers')) {
957
+ weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT);
958
+ return '' +
959
+ '<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' +
960
+ core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
961
+ _this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML
962
+ ) +
963
+ '</th>';
964
+ }
965
+ else {
966
+ return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>';
967
+ }
968
+ };
969
+ /* Time Grid Render Methods
970
+ ------------------------------------------------------------------------------------------------------------------*/
971
+ // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
972
+ _this.renderTimeGridBgIntroHtml = function () {
973
+ var theme = _this.theme;
974
+ return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>';
975
+ };
976
+ // Generates the HTML that goes before all other types of cells.
977
+ // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
978
+ _this.renderTimeGridIntroHtml = function () {
979
+ return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
980
+ };
981
+ /* Day Grid Render Methods
982
+ ------------------------------------------------------------------------------------------------------------------*/
983
+ // Generates the HTML that goes before the all-day cells
984
+ _this.renderDayGridBgIntroHtml = function () {
985
+ var theme = _this.theme;
986
+ return '' +
987
+ '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' +
988
+ '<span>' + // needed for matchCellWidths
989
+ core.getAllDayHtml(_this) +
990
+ '</span>' +
991
+ '</td>';
992
+ };
993
+ // Generates the HTML that goes before all other types of cells.
994
+ // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
995
+ _this.renderDayGridIntroHtml = function () {
996
+ return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
997
+ };
998
+ _this.el.classList.add('fc-timeGrid-view');
999
+ _this.el.innerHTML = _this.renderSkeletonHtml();
1000
+ _this.scroller = new core.ScrollComponent('hidden', // overflow x
1001
+ 'auto' // overflow y
1002
+ );
1003
+ var timeGridWrapEl = _this.scroller.el;
1004
+ _this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl);
1005
+ timeGridWrapEl.classList.add('fc-time-grid-container');
1006
+ var timeGridEl = core.createElement('div', { className: 'fc-time-grid' });
1007
+ timeGridWrapEl.appendChild(timeGridEl);
1008
+ _this.timeGrid = new TimeGrid(_this.context, timeGridEl, {
1009
+ renderBgIntroHtml: _this.renderTimeGridBgIntroHtml,
1010
+ renderIntroHtml: _this.renderTimeGridIntroHtml
1011
+ });
1012
+ if (_this.opt('allDaySlot')) { // should we display the "all-day" area?
1013
+ _this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view
1014
+ _this.context, _this.el.querySelector('.fc-day-grid'), {
1015
+ renderNumberIntroHtml: _this.renderDayGridIntroHtml,
1016
+ renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
1017
+ renderIntroHtml: _this.renderDayGridIntroHtml,
1018
+ colWeekNumbersVisible: false,
1019
+ cellWeekNumbersVisible: false
1020
+ });
1021
+ // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
1022
+ _this.dayGrid.bottomCoordPadding = _this.el.querySelector('.fc-divider').offsetHeight;
1023
+ }
1024
+ return _this;
1025
+ }
1026
+ TimeGridView.prototype.destroy = function () {
1027
+ _super.prototype.destroy.call(this);
1028
+ this.timeGrid.destroy();
1029
+ if (this.dayGrid) {
1030
+ this.dayGrid.destroy();
1031
+ }
1032
+ this.scroller.destroy();
1033
+ };
1034
+ /* Rendering
1035
+ ------------------------------------------------------------------------------------------------------------------*/
1036
+ // Builds the HTML skeleton for the view.
1037
+ // The day-grid and time-grid components will render inside containers defined by this HTML.
1038
+ TimeGridView.prototype.renderSkeletonHtml = function () {
1039
+ var theme = this.theme;
1040
+ return '' +
1041
+ '<table class="' + theme.getClass('tableGrid') + '">' +
1042
+ (this.opt('columnHeader') ?
1043
+ '<thead class="fc-head">' +
1044
+ '<tr>' +
1045
+ '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
1046
+ '</tr>' +
1047
+ '</thead>' :
1048
+ '') +
1049
+ '<tbody class="fc-body">' +
1050
+ '<tr>' +
1051
+ '<td class="' + theme.getClass('widgetContent') + '">' +
1052
+ (this.opt('allDaySlot') ?
1053
+ '<div class="fc-day-grid"></div>' +
1054
+ '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' :
1055
+ '') +
1056
+ '</td>' +
1057
+ '</tr>' +
1058
+ '</tbody>' +
1059
+ '</table>';
1060
+ };
1061
+ /* Now Indicator
1062
+ ------------------------------------------------------------------------------------------------------------------*/
1063
+ TimeGridView.prototype.getNowIndicatorUnit = function () {
1064
+ return this.timeGrid.getNowIndicatorUnit();
1065
+ };
1066
+ // subclasses should implement
1067
+ // renderNowIndicator(date: DateMarker) {
1068
+ // }
1069
+ TimeGridView.prototype.unrenderNowIndicator = function () {
1070
+ this.timeGrid.unrenderNowIndicator();
1071
+ };
1072
+ /* Dimensions
1073
+ ------------------------------------------------------------------------------------------------------------------*/
1074
+ TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
1075
+ _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
1076
+ this.timeGrid.updateSize(isResize);
1077
+ if (this.dayGrid) {
1078
+ this.dayGrid.updateSize(isResize);
1079
+ }
1080
+ };
1081
+ // Adjusts the vertical dimensions of the view to the specified values
1082
+ TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
1083
+ var _this = this;
1084
+ var eventLimit;
1085
+ var scrollerHeight;
1086
+ var scrollbarWidths;
1087
+ // make all axis cells line up
1088
+ this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis'));
1089
+ // hack to give the view some height prior to timeGrid's columns being rendered
1090
+ // TODO: separate setting height from scroller VS timeGrid.
1091
+ if (!this.timeGrid.colEls) {
1092
+ if (!isAuto) {
1093
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
1094
+ this.scroller.setHeight(scrollerHeight);
1095
+ }
1096
+ return;
1097
+ }
1098
+ // set of fake row elements that must compensate when scroller has scrollbars
1099
+ var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) {
1100
+ return !_this.scroller.el.contains(node);
1101
+ });
1102
+ // reset all dimensions back to the original state
1103
+ this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary
1104
+ this.scroller.clear(); // sets height to 'auto' and clears overflow
1105
+ noScrollRowEls.forEach(core.uncompensateScroll);
1106
+ // limit number of events in the all-day area
1107
+ if (this.dayGrid) {
1108
+ this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
1109
+ eventLimit = this.opt('eventLimit');
1110
+ if (eventLimit && typeof eventLimit !== 'number') {
1111
+ eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
1112
+ }
1113
+ if (eventLimit) {
1114
+ this.dayGrid.limitRows(eventLimit);
1115
+ }
1116
+ }
1117
+ if (!isAuto) { // should we force dimensions of the scroll container?
1118
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
1119
+ this.scroller.setHeight(scrollerHeight);
1120
+ scrollbarWidths = this.scroller.getScrollbarWidths();
1121
+ if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
1122
+ // make the all-day and header rows lines up
1123
+ noScrollRowEls.forEach(function (rowEl) {
1124
+ core.compensateScroll(rowEl, scrollbarWidths);
1125
+ });
1126
+ // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
1127
+ // and reapply the desired height to the scroller.
1128
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
1129
+ this.scroller.setHeight(scrollerHeight);
1130
+ }
1131
+ // guarantees the same scrollbar widths
1132
+ this.scroller.lockOverflow(scrollbarWidths);
1133
+ // if there's any space below the slats, show the horizontal rule.
1134
+ // this won't cause any new overflow, because lockOverflow already called.
1135
+ if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
1136
+ this.timeGrid.bottomRuleEl.style.display = '';
1137
+ }
1138
+ }
1139
+ };
1140
+ // given a desired total height of the view, returns what the height of the scroller should be
1141
+ TimeGridView.prototype.computeScrollerHeight = function (viewHeight) {
1142
+ return viewHeight -
1143
+ core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
1144
+ };
1145
+ /* Scroll
1146
+ ------------------------------------------------------------------------------------------------------------------*/
1147
+ // Computes the initial pre-configured scroll state prior to allowing the user to change it
1148
+ TimeGridView.prototype.computeInitialDateScroll = function () {
1149
+ var scrollTime = core.createDuration(this.opt('scrollTime'));
1150
+ var top = this.timeGrid.computeTimeTop(scrollTime.milliseconds);
1151
+ // zoom can give weird floating-point values. rather scroll a little bit further
1152
+ top = Math.ceil(top);
1153
+ if (top) {
1154
+ top++; // to overcome top border that slots beyond the first have. looks better
1155
+ }
1156
+ return { top: top };
1157
+ };
1158
+ TimeGridView.prototype.queryDateScroll = function () {
1159
+ return { top: this.scroller.getScrollTop() };
1160
+ };
1161
+ TimeGridView.prototype.applyDateScroll = function (scroll) {
1162
+ if (scroll.top !== undefined) {
1163
+ this.scroller.setScrollTop(scroll.top);
1164
+ }
1165
+ };
1166
+ // Generates an HTML attribute string for setting the width of the axis, if it is known
1167
+ TimeGridView.prototype.axisStyleAttr = function () {
1168
+ if (this.axisWidth != null) {
1169
+ return 'style="width:' + this.axisWidth + 'px"';
1170
+ }
1171
+ return '';
1172
+ };
1173
+ return TimeGridView;
1174
+ }(core.View));
1175
+ TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
1176
+
1177
+ var SimpleTimeGrid = /** @class */ (function (_super) {
1178
+ __extends(SimpleTimeGrid, _super);
1179
+ function SimpleTimeGrid(context, timeGrid) {
1180
+ var _this = _super.call(this, context, timeGrid.el) || this;
1181
+ _this.buildDayRanges = core.memoize(buildDayRanges);
1182
+ _this.slicer = new TimeGridSlicer();
1183
+ _this.timeGrid = timeGrid;
1184
+ context.calendar.registerInteractiveComponent(_this, {
1185
+ el: _this.timeGrid.el
1186
+ });
1187
+ return _this;
1188
+ }
1189
+ SimpleTimeGrid.prototype.destroy = function () {
1190
+ _super.prototype.destroy.call(this);
1191
+ this.calendar.unregisterInteractiveComponent(this);
1192
+ };
1193
+ SimpleTimeGrid.prototype.render = function (props) {
1194
+ var dateProfile = props.dateProfile, dayTable = props.dayTable;
1195
+ var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv);
1196
+ this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] }));
1197
+ };
1198
+ SimpleTimeGrid.prototype.renderNowIndicator = function (date) {
1199
+ this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date);
1200
+ };
1201
+ SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) {
1202
+ var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop);
1203
+ if (rawHit) {
1204
+ return {
1205
+ component: this.timeGrid,
1206
+ dateSpan: rawHit.dateSpan,
1207
+ dayEl: rawHit.dayEl,
1208
+ rect: {
1209
+ left: rawHit.relativeRect.left,
1210
+ right: rawHit.relativeRect.right,
1211
+ top: rawHit.relativeRect.top,
1212
+ bottom: rawHit.relativeRect.bottom
1213
+ },
1214
+ layer: 0
1215
+ };
1216
+ }
1217
+ };
1218
+ return SimpleTimeGrid;
1219
+ }(core.DateComponent));
1220
+ function buildDayRanges(dayTable, dateProfile, dateEnv) {
1221
+ var ranges = [];
1222
+ for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) {
1223
+ var date = _a[_i];
1224
+ ranges.push({
1225
+ start: dateEnv.add(date, dateProfile.minTime),
1226
+ end: dateEnv.add(date, dateProfile.maxTime)
1227
+ });
1228
+ }
1229
+ return ranges;
1230
+ }
1231
+ var TimeGridSlicer = /** @class */ (function (_super) {
1232
+ __extends(TimeGridSlicer, _super);
1233
+ function TimeGridSlicer() {
1234
+ return _super !== null && _super.apply(this, arguments) || this;
1235
+ }
1236
+ TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) {
1237
+ var segs = [];
1238
+ for (var col = 0; col < dayRanges.length; col++) {
1239
+ var segRange = core.intersectRanges(range, dayRanges[col]);
1240
+ if (segRange) {
1241
+ segs.push({
1242
+ start: segRange.start,
1243
+ end: segRange.end,
1244
+ isStart: segRange.start.valueOf() === range.start.valueOf(),
1245
+ isEnd: segRange.end.valueOf() === range.end.valueOf(),
1246
+ col: col
1247
+ });
1248
+ }
1249
+ }
1250
+ return segs;
1251
+ };
1252
+ return TimeGridSlicer;
1253
+ }(core.Slicer));
1254
+
1255
+ var TimeGridView$1 = /** @class */ (function (_super) {
1256
+ __extends(TimeGridView, _super);
1257
+ function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
1258
+ var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
1259
+ _this.buildDayTable = core.memoize(buildDayTable);
1260
+ if (_this.opt('columnHeader')) {
1261
+ _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
1262
+ }
1263
+ _this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid);
1264
+ if (_this.dayGrid) {
1265
+ _this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid);
1266
+ }
1267
+ return _this;
1268
+ }
1269
+ TimeGridView.prototype.destroy = function () {
1270
+ _super.prototype.destroy.call(this);
1271
+ if (this.header) {
1272
+ this.header.destroy();
1273
+ }
1274
+ this.simpleTimeGrid.destroy();
1275
+ if (this.simpleDayGrid) {
1276
+ this.simpleDayGrid.destroy();
1277
+ }
1278
+ };
1279
+ TimeGridView.prototype.render = function (props) {
1280
+ _super.prototype.render.call(this, props); // for flags for updateSize
1281
+ var dateProfile = this.props.dateProfile;
1282
+ var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator);
1283
+ var splitProps = this.splitter.splitProps(props);
1284
+ if (this.header) {
1285
+ this.header.receiveProps({
1286
+ dateProfile: dateProfile,
1287
+ dates: dayTable.headerDates,
1288
+ datesRepDistinctDays: true,
1289
+ renderIntroHtml: this.renderHeadIntroHtml
1290
+ });
1291
+ }
1292
+ this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile,
1293
+ dayTable: dayTable }));
1294
+ if (this.simpleDayGrid) {
1295
+ this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile,
1296
+ dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false }));
1297
+ }
1298
+ };
1299
+ TimeGridView.prototype.renderNowIndicator = function (date) {
1300
+ this.simpleTimeGrid.renderNowIndicator(date);
1301
+ };
1302
+ return TimeGridView;
1303
+ }(TimeGridView));
1304
+ function buildDayTable(dateProfile, dateProfileGenerator) {
1305
+ var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
1306
+ return new core.DayTable(daySeries, false);
1307
+ }
1308
+
1309
+ var main = core.createPlugin({
1310
+ defaultView: 'timeGridWeek',
1311
+ views: {
1312
+ timeGrid: {
1313
+ class: TimeGridView$1,
1314
+ allDaySlot: true,
1315
+ slotDuration: '00:30:00',
1316
+ slotEventOverlap: true // a bad name. confused with overlap/constraint system
1317
+ },
1318
+ timeGridDay: {
1319
+ type: 'timeGrid',
1320
+ duration: { days: 1 }
1321
+ },
1322
+ timeGridWeek: {
1323
+ type: 'timeGrid',
1324
+ duration: { weeks: 1 }
1325
+ }
1326
+ }
1327
+ });
1328
+
1329
+ exports.AbstractTimeGridView = TimeGridView;
1330
+ exports.TimeGrid = TimeGrid;
1331
+ exports.TimeGridSlicer = TimeGridSlicer;
1332
+ exports.TimeGridView = TimeGridView$1;
1333
+ exports.buildDayRanges = buildDayRanges;
1334
+ exports.buildDayTable = buildDayTable;
1335
+ exports.default = main;
1336
+
1337
+ Object.defineProperty(exports, '__esModule', { value: true });
1338
+
1339
+ }));