cronofy-elements 1.48.1 → 1.49.1

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.
Files changed (349) hide show
  1. package/dist/.gitkeep +0 -0
  2. package/dist/CronofyElements.js +2 -0
  3. package/{build/CronofyElements.v1.48.1.js.LICENSE.txt → dist/CronofyElements.js.LICENSE.txt} +0 -0
  4. package/package.json +10 -7
  5. package/.babelrc +0 -20
  6. package/.eslintrc.yaml +0 -43
  7. package/.prettierignore +0 -4
  8. package/.prettierrc +0 -7
  9. package/Makefile +0 -92
  10. package/brainstorm.md +0 -76
  11. package/build/CronofyElements.v1.48.1.js +0 -2
  12. package/build/npm/CronofyElements.js +0 -2
  13. package/compat.config.js +0 -25
  14. package/demo/agenda.ejs +0 -71
  15. package/demo/availability-viewer.ejs +0 -322
  16. package/demo/calendar-sync.ejs +0 -149
  17. package/demo/crossbrowser.ejs +0 -228
  18. package/demo/date-time-picker.ejs +0 -213
  19. package/demo/demo-styles.css +0 -134
  20. package/demo/index.ejs +0 -249
  21. package/demo/integration.ejs +0 -482
  22. package/demo/load-elements.ejs +0 -12
  23. package/demo/nav.ejs +0 -14
  24. package/demo/rules.ejs +0 -121
  25. package/demo/server.js +0 -425
  26. package/demo/slot-picker.ejs +0 -197
  27. package/git.README.md +0 -71
  28. package/notes.style.md +0 -197
  29. package/postcss.config.js +0 -3
  30. package/script/i18n-export +0 -11
  31. package/script/i18n-helpers/split_write.rb +0 -25
  32. package/script/i18n-import +0 -22
  33. package/script/i18n-reference-update +0 -241
  34. package/src/js/components/Agenda/Agenda.js +0 -243
  35. package/src/js/components/Agenda/AllDayEventsList.js +0 -37
  36. package/src/js/components/Agenda/Calendar.js +0 -100
  37. package/src/js/components/Agenda/CalendarHeader.js +0 -187
  38. package/src/js/components/Agenda/Event.js +0 -34
  39. package/src/js/components/Agenda/EventAllDay.js +0 -76
  40. package/src/js/components/Agenda/EventAttendees.js +0 -30
  41. package/src/js/components/Agenda/EventDetail.js +0 -111
  42. package/src/js/components/Agenda/EventMessages.js +0 -24
  43. package/src/js/components/Agenda/EventMeta.js +0 -48
  44. package/src/js/components/Agenda/EventTime.js +0 -34
  45. package/src/js/components/Agenda/EventWrapper.js +0 -271
  46. package/src/js/components/Agenda/Location.js +0 -29
  47. package/src/js/components/Agenda/Message.js +0 -22
  48. package/src/js/components/Agenda/TimedEventsList.js +0 -29
  49. package/src/js/components/AvailabilityRules/AddButton.js +0 -60
  50. package/src/js/components/AvailabilityRules/AvailabilityRules.js +0 -45
  51. package/src/js/components/AvailabilityRules/Calendar.js +0 -31
  52. package/src/js/components/AvailabilityRules/CalendarListItem.js +0 -53
  53. package/src/js/components/AvailabilityRules/CalendarProfiles.js +0 -67
  54. package/src/js/components/AvailabilityRules/CalendarSelector.js +0 -104
  55. package/src/js/components/AvailabilityRules/Calendars.js +0 -145
  56. package/src/js/components/AvailabilityRules/Checkmark.js +0 -51
  57. package/src/js/components/AvailabilityRules/DayLabels.js +0 -91
  58. package/src/js/components/AvailabilityRules/Footer.js +0 -109
  59. package/src/js/components/AvailabilityRules/Legend.js +0 -57
  60. package/src/js/components/AvailabilityRules/Loading.js +0 -53
  61. package/src/js/components/AvailabilityRules/RemoveButton.js +0 -57
  62. package/src/js/components/AvailabilityRules/Slot.js +0 -195
  63. package/src/js/components/AvailabilityRules/SlotDisplay.js +0 -27
  64. package/src/js/components/AvailabilityRules/Slots.js +0 -81
  65. package/src/js/components/AvailabilityRules/SlotsDisplay.js +0 -68
  66. package/src/js/components/AvailabilityRules/TimeExpander.js +0 -119
  67. package/src/js/components/AvailabilityRules/TimeLabels.js +0 -89
  68. package/src/js/components/AvailabilityRules/TimeZoneDisplay.js +0 -41
  69. package/src/js/components/AvailabilityRules/ToggleIcon.js +0 -41
  70. package/src/js/components/AvailabilityRules/Tooltip.js +0 -63
  71. package/src/js/components/AvailabilityRules/UnknownCalendar.js +0 -33
  72. package/src/js/components/AvailabilityRules/Week.js +0 -115
  73. package/src/js/components/AvailabilityRules/WeekGrid.js +0 -80
  74. package/src/js/components/AvailabilityRules/Wrapper.js +0 -414
  75. package/src/js/components/AvailabilityRules/contexts/drag-context.js +0 -15
  76. package/src/js/components/AvailabilityRules/scss/_base.buttons.scss +0 -58
  77. package/src/js/components/AvailabilityRules/scss/_base.theme.scss +0 -4
  78. package/src/js/components/AvailabilityRules/scss/_components.timezoneselector.scss +0 -74
  79. package/src/js/components/AvailabilityRules/scss/_generic.reset.scss +0 -13
  80. package/src/js/components/AvailabilityRules/scss/_settings.colours.scss +0 -12
  81. package/src/js/components/AvailabilityRules/scss/availabilityrules.scss +0 -5
  82. package/src/js/components/AvailabilityRules/utils/tz-utils.js +0 -44
  83. package/src/js/components/AvailabilityViewer/AvailabilityViewer.js +0 -524
  84. package/src/js/components/AvailabilityViewer/ColumnHeader.js +0 -35
  85. package/src/js/components/AvailabilityViewer/DayColumn.js +0 -36
  86. package/src/js/components/AvailabilityViewer/DayColumnDisplay.js +0 -33
  87. package/src/js/components/AvailabilityViewer/DayColumnWrapper.js +0 -29
  88. package/src/js/components/AvailabilityViewer/DayLabels.js +0 -41
  89. package/src/js/components/AvailabilityViewer/EmptyColumn.js +0 -29
  90. package/src/js/components/AvailabilityViewer/Footer.js +0 -36
  91. package/src/js/components/AvailabilityViewer/GridFreeSelect.js +0 -33
  92. package/src/js/components/AvailabilityViewer/HoverSlot.js +0 -35
  93. package/src/js/components/AvailabilityViewer/HoverTooltip.js +0 -34
  94. package/src/js/components/AvailabilityViewer/LabelColumn.js +0 -53
  95. package/src/js/components/AvailabilityViewer/LabelItem.js +0 -73
  96. package/src/js/components/AvailabilityViewer/Legend.js +0 -79
  97. package/src/js/components/AvailabilityViewer/Loading.js +0 -57
  98. package/src/js/components/AvailabilityViewer/MonthLabels.js +0 -43
  99. package/src/js/components/AvailabilityViewer/Navigation.js +0 -138
  100. package/src/js/components/AvailabilityViewer/Overlay.js +0 -60
  101. package/src/js/components/AvailabilityViewer/Preloading.js +0 -66
  102. package/src/js/components/AvailabilityViewer/SelectedSlot.js +0 -106
  103. package/src/js/components/AvailabilityViewer/SelectedSlots.js +0 -72
  104. package/src/js/components/AvailabilityViewer/SelectionMask.js +0 -44
  105. package/src/js/components/AvailabilityViewer/Slot.js +0 -237
  106. package/src/js/components/AvailabilityViewer/SlotFreeSelect.js +0 -115
  107. package/src/js/components/AvailabilityViewer/Slots.js +0 -57
  108. package/src/js/components/AvailabilityViewer/TimeExpander.js +0 -93
  109. package/src/js/components/AvailabilityViewer/TimeLines.js +0 -74
  110. package/src/js/components/AvailabilityViewer/TimeSelector.js +0 -243
  111. package/src/js/components/AvailabilityViewer/TimeSelectorTrigger.js +0 -42
  112. package/src/js/components/AvailabilityViewer/TimeZoneDisplay.js +0 -28
  113. package/src/js/components/AvailabilityViewer/ToggleIcon.js +0 -41
  114. package/src/js/components/AvailabilityViewer/Tooltip.js +0 -65
  115. package/src/js/components/AvailabilityViewer/Week.js +0 -255
  116. package/src/js/components/AvailabilityViewer/WeekWrapper.js +0 -132
  117. package/src/js/components/AvailabilityViewer/contexts/page-context.js +0 -17
  118. package/src/js/components/AvailabilityViewer/contexts/page-reducer.js +0 -28
  119. package/src/js/components/AvailabilityViewer/contexts/selection-context.js +0 -25
  120. package/src/js/components/AvailabilityViewer/contexts/selection-reducer.js +0 -18
  121. package/src/js/components/CalendarSync/Active.js +0 -57
  122. package/src/js/components/CalendarSync/AddToggle.js +0 -72
  123. package/src/js/components/CalendarSync/CalendarSync.js +0 -215
  124. package/src/js/components/CalendarSync/EditToggle.js +0 -71
  125. package/src/js/components/CalendarSync/Footer.js +0 -31
  126. package/src/js/components/CalendarSync/Inactive.js +0 -66
  127. package/src/js/components/CalendarSync/Loading.js +0 -52
  128. package/src/js/components/CalendarSync/Pending.js +0 -74
  129. package/src/js/components/CalendarSync/ProfileStatus.js +0 -33
  130. package/src/js/components/CalendarSync/Profiles.js +0 -109
  131. package/src/js/components/CalendarSync/ProviderLogo.js +0 -28
  132. package/src/js/components/CalendarSync/Providers.js +0 -80
  133. package/src/js/components/CalendarSync/RemoveLink.js +0 -96
  134. package/src/js/components/CalendarSync/SelectProvider.js +0 -25
  135. package/src/js/components/CalendarSync/contexts/status-reducer.js +0 -74
  136. package/src/js/components/DateTimePicker/Calendar.js +0 -127
  137. package/src/js/components/DateTimePicker/CalendarHeader.js +0 -80
  138. package/src/js/components/DateTimePicker/Confirm.js +0 -106
  139. package/src/js/components/DateTimePicker/DateTimePicker.js +0 -131
  140. package/src/js/components/DateTimePicker/DayButton.js +0 -38
  141. package/src/js/components/DateTimePicker/DayHeadings.js +0 -33
  142. package/src/js/components/DateTimePicker/Details.js +0 -33
  143. package/src/js/components/DateTimePicker/Error.js +0 -39
  144. package/src/js/components/DateTimePicker/Loading.js +0 -20
  145. package/src/js/components/DateTimePicker/LoadingCalendar.js +0 -21
  146. package/src/js/components/DateTimePicker/NoSlotsFound.js +0 -16
  147. package/src/js/components/DateTimePicker/SequencedSlotButton.js +0 -97
  148. package/src/js/components/DateTimePicker/SlotButton.js +0 -55
  149. package/src/js/components/DateTimePicker/SlotsList.js +0 -45
  150. package/src/js/components/DateTimePicker/Wrapper.js +0 -281
  151. package/src/js/components/DateTimePicker/contexts/status-context.js +0 -19
  152. package/src/js/components/DateTimePicker/contexts/status-reducer.js +0 -276
  153. package/src/js/components/DateTimePicker/contexts/theme-context.js +0 -33
  154. package/src/js/components/DateTimePicker/helpers/theming.js +0 -49
  155. package/src/js/components/DateTimePicker/scss/_base.buttons.scss +0 -58
  156. package/src/js/components/DateTimePicker/scss/_base.layout.scss +0 -28
  157. package/src/js/components/DateTimePicker/scss/_base.theme.scss +0 -17
  158. package/src/js/components/DateTimePicker/scss/_components.calendargrid.scss +0 -78
  159. package/src/js/components/DateTimePicker/scss/_components.calendarheader.scss +0 -71
  160. package/src/js/components/DateTimePicker/scss/_components.confirm.scss +0 -40
  161. package/src/js/components/DateTimePicker/scss/_components.details.scss +0 -20
  162. package/src/js/components/DateTimePicker/scss/_components.error.scss +0 -34
  163. package/src/js/components/DateTimePicker/scss/_components.loading.scss +0 -36
  164. package/src/js/components/DateTimePicker/scss/_components.slotslist.scss +0 -43
  165. package/src/js/components/DateTimePicker/scss/_components.timezoneselector.scss +0 -73
  166. package/src/js/components/DateTimePicker/scss/_generic.reset.scss +0 -18
  167. package/src/js/components/DateTimePicker/scss/_settings.colours.scss +0 -17
  168. package/src/js/components/DateTimePicker/scss/datetimepicker.scss +0 -5
  169. package/src/js/components/DateTimePicker/utils/calendar-keyboard.js +0 -109
  170. package/src/js/components/DateTimePicker/utils/calendar.js +0 -125
  171. package/src/js/components/DateTimePicker/utils/slots.js +0 -288
  172. package/src/js/components/SlotPicker/Confirm.js +0 -160
  173. package/src/js/components/SlotPicker/Days.js +0 -58
  174. package/src/js/components/SlotPicker/Slot.js +0 -72
  175. package/src/js/components/SlotPicker/SlotPicker.js +0 -292
  176. package/src/js/components/SlotPicker/Slots.js +0 -66
  177. package/src/js/components/SlotPicker/TimeSlots.js +0 -91
  178. package/src/js/components/generic/Button.js +0 -26
  179. package/src/js/components/generic/Container.js +0 -33
  180. package/src/js/components/generic/Error.js +0 -77
  181. package/src/js/components/generic/Loading.js +0 -51
  182. package/src/js/components/generic/LoadingSpinner.js +0 -30
  183. package/src/js/components/generic/ShadowScrollbars.js +0 -70
  184. package/src/js/components/generic/TimeZoneSelector.js +0 -158
  185. package/src/js/components/generic/TransitionSlide.js +0 -72
  186. package/src/js/contexts/i18n-context.js +0 -25
  187. package/src/js/contexts/log-context.js +0 -18
  188. package/src/js/contexts/tz-context.js +0 -18
  189. package/src/js/env.example.js +0 -8
  190. package/src/js/helpers/colors.js +0 -33
  191. package/src/js/helpers/comparators.AvailabilityViewer.js +0 -27
  192. package/src/js/helpers/connections.js +0 -370
  193. package/src/js/helpers/events.js +0 -166
  194. package/src/js/helpers/functional.js +0 -4
  195. package/src/js/helpers/generator.js +0 -107
  196. package/src/js/helpers/i18n.js +0 -153
  197. package/src/js/helpers/init.Agenda.js +0 -55
  198. package/src/js/helpers/init.AvailabilityRules.js +0 -195
  199. package/src/js/helpers/init.AvailabilityViewer.js +0 -215
  200. package/src/js/helpers/init.CalendarSync.js +0 -83
  201. package/src/js/helpers/init.DateTimePicker.js +0 -219
  202. package/src/js/helpers/init.SlotPicker.js +0 -89
  203. package/src/js/helpers/init.js +0 -308
  204. package/src/js/helpers/logging.js +0 -78
  205. package/src/js/helpers/mocks.js +0 -871
  206. package/src/js/helpers/slots.js +0 -340
  207. package/src/js/helpers/slots.rules.js +0 -220
  208. package/src/js/helpers/theming.js +0 -93
  209. package/src/js/helpers/translations.js +0 -42
  210. package/src/js/helpers/tz-list.js +0 -136
  211. package/src/js/helpers/utils.AvailabilityRules.js +0 -110
  212. package/src/js/helpers/utils.AvailabilityViewer.js +0 -789
  213. package/src/js/helpers/utils.CalendarSync.js +0 -199
  214. package/src/js/helpers/utils.js +0 -76
  215. package/src/js/hooks/useWindowSize.js +0 -20
  216. package/src/js/main.js +0 -133
  217. package/src/js/next.js +0 -37
  218. package/src/js/styles/_settings.utils.scss +0 -82
  219. package/src/js/styles/colors.js +0 -13
  220. package/src/js/styles/global.js +0 -49
  221. package/src/js/styles/utils.js +0 -81
  222. package/src/js/translations/de/agenda.json +0 -12
  223. package/src/js/translations/de/availability_rules.json +0 -18
  224. package/src/js/translations/de/availability_viewer.json +0 -14
  225. package/src/js/translations/de/calendar_sync.json +0 -14
  226. package/src/js/translations/de/core.json +0 -15
  227. package/src/js/translations/de/date_time_picker.json +0 -14
  228. package/src/js/translations/de/slot_picker.json +0 -9
  229. package/src/js/translations/de/time_zones.json +0 -135
  230. package/src/js/translations/en/agenda.json +0 -12
  231. package/src/js/translations/en/availability_rules.json +0 -18
  232. package/src/js/translations/en/availability_viewer.json +0 -14
  233. package/src/js/translations/en/calendar_sync.json +0 -14
  234. package/src/js/translations/en/core.json +0 -23
  235. package/src/js/translations/en/date_time_picker.json +0 -15
  236. package/src/js/translations/en/slot_picker.json +0 -9
  237. package/src/js/translations/en/time_zones.json +0 -17
  238. package/src/js/translations/es/agenda.json +0 -12
  239. package/src/js/translations/es/availability_rules.json +0 -18
  240. package/src/js/translations/es/availability_viewer.json +0 -14
  241. package/src/js/translations/es/calendar_sync.json +0 -14
  242. package/src/js/translations/es/core.json +0 -15
  243. package/src/js/translations/es/date_time_picker.json +0 -14
  244. package/src/js/translations/es/slot_picker.json +0 -9
  245. package/src/js/translations/es/time_zones.json +0 -203
  246. package/src/js/translations/fr/agenda.json +0 -12
  247. package/src/js/translations/fr/availability_rules.json +0 -18
  248. package/src/js/translations/fr/availability_viewer.json +0 -14
  249. package/src/js/translations/fr/calendar_sync.json +0 -14
  250. package/src/js/translations/fr/core.json +0 -15
  251. package/src/js/translations/fr/date_time_picker.json +0 -14
  252. package/src/js/translations/fr/slot_picker.json +0 -9
  253. package/src/js/translations/fr/time_zones.json +0 -161
  254. package/src/js/translations/fr-CA/agenda.json +0 -12
  255. package/src/js/translations/fr-CA/availability_rules.json +0 -18
  256. package/src/js/translations/fr-CA/availability_viewer.json +0 -14
  257. package/src/js/translations/fr-CA/calendar_sync.json +0 -14
  258. package/src/js/translations/fr-CA/core.json +0 -23
  259. package/src/js/translations/fr-CA/date_time_picker.json +0 -14
  260. package/src/js/translations/fr-CA/slot_picker.json +0 -9
  261. package/src/js/translations/fr-CA/time_zones.json +0 -163
  262. package/src/js/translations/it/agenda.json +0 -12
  263. package/src/js/translations/it/availability_rules.json +0 -18
  264. package/src/js/translations/it/availability_viewer.json +0 -14
  265. package/src/js/translations/it/calendar_sync.json +0 -14
  266. package/src/js/translations/it/core.json +0 -15
  267. package/src/js/translations/it/date_time_picker.json +0 -14
  268. package/src/js/translations/it/slot_picker.json +0 -9
  269. package/src/js/translations/it/time_zones.json +0 -126
  270. package/src/js/translations/ja/agenda.json +0 -12
  271. package/src/js/translations/ja/availability_rules.json +0 -18
  272. package/src/js/translations/ja/availability_viewer.json +0 -14
  273. package/src/js/translations/ja/calendar_sync.json +0 -14
  274. package/src/js/translations/ja/core.json +0 -15
  275. package/src/js/translations/ja/date_formats.json +0 -5
  276. package/src/js/translations/ja/date_time_picker.json +0 -14
  277. package/src/js/translations/ja/slot_picker.json +0 -9
  278. package/src/js/translations/ja/time_zones.json +0 -435
  279. package/src/js/translations/nl/agenda.json +0 -12
  280. package/src/js/translations/nl/availability_rules.json +0 -18
  281. package/src/js/translations/nl/availability_viewer.json +0 -14
  282. package/src/js/translations/nl/calendar_sync.json +0 -14
  283. package/src/js/translations/nl/core.json +0 -15
  284. package/src/js/translations/nl/date_time_picker.json +0 -14
  285. package/src/js/translations/nl/slot_picker.json +0 -9
  286. package/src/js/translations/nl/time_zones.json +0 -118
  287. package/src/js/translations/ru/agenda.json +0 -12
  288. package/src/js/translations/ru/availability_rules.json +0 -18
  289. package/src/js/translations/ru/availability_viewer.json +0 -14
  290. package/src/js/translations/ru/calendar_sync.json +0 -14
  291. package/src/js/translations/ru/core.json +0 -15
  292. package/src/js/translations/ru/date_time_picker.json +0 -14
  293. package/src/js/translations/ru/slot_picker.json +0 -9
  294. package/src/js/translations/ru/time_zones.json +0 -435
  295. package/src/js/translations/sv/agenda.json +0 -12
  296. package/src/js/translations/sv/availability_rules.json +0 -18
  297. package/src/js/translations/sv/availability_viewer.json +0 -14
  298. package/src/js/translations/sv/calendar_sync.json +0 -14
  299. package/src/js/translations/sv/core.json +0 -15
  300. package/src/js/translations/sv/date_time_picker.json +0 -14
  301. package/src/js/translations/sv/slot_picker.json +0 -9
  302. package/src/js/translations/sv/time_zones.json +0 -136
  303. package/tests/AvailabilityRules/AvailabilityRules.test.js +0 -39
  304. package/tests/AvailabilityRules/__snapshots__/AvailabilityRules.test.js.snap +0 -1045
  305. package/tests/AvailabilityViewer/Navigation.test.js +0 -130
  306. package/tests/AvailabilityViewer/contexts/page-reducer.test.js +0 -87
  307. package/tests/AvailabilityViewer/reducer.test.js +0 -73
  308. package/tests/CalendarSync/Active.test.js +0 -25
  309. package/tests/CalendarSync/AddToggle.test.js +0 -57
  310. package/tests/CalendarSync/EditToggle.test.js +0 -57
  311. package/tests/CalendarSync/Inactive.test.js +0 -26
  312. package/tests/CalendarSync/Pending.test.js +0 -25
  313. package/tests/CalendarSync/ProviderLogo.test.js +0 -95
  314. package/tests/CalendarSync/__snapshots__/Active.test.js.snap +0 -61
  315. package/tests/CalendarSync/__snapshots__/Inactive.test.js.snap +0 -78
  316. package/tests/CalendarSync/__snapshots__/Pending.test.js.snap +0 -90
  317. package/tests/CalendarSync/__snapshots__/ProviderLogo.test.js.snap +0 -267
  318. package/tests/CalendarSync/init.CalendarSync.test.js +0 -302
  319. package/tests/CalendarSync/mocks/theme.js +0 -14
  320. package/tests/CalendarSync/status-reducer.test.js +0 -435
  321. package/tests/DateTimePicker/SequencedSlotButton.test.js +0 -157
  322. package/tests/DateTimePicker/SlotButton.test.js +0 -118
  323. package/tests/DateTimePicker/contexts/status-reducer.test.js +0 -1036
  324. package/tests/DateTimePicker/dummy-data.js +0 -883
  325. package/tests/DateTimePicker/utils.test.js +0 -515
  326. package/tests/colors.test.js +0 -70
  327. package/tests/components/TimezoneSelector.test.js +0 -124
  328. package/tests/components/main.test.js +0 -203
  329. package/tests/components/rtl-utils.js +0 -32
  330. package/tests/connections.test.js +0 -684
  331. package/tests/events.test.js +0 -472
  332. package/tests/generator.test.js +0 -74
  333. package/tests/i18n.test.js +0 -255
  334. package/tests/init.Agenda.test.js +0 -122
  335. package/tests/init.AvailabilityRules.test.js +0 -279
  336. package/tests/init.AvailabilityViewer.test.js +0 -740
  337. package/tests/init.SlotPicker.test.js +0 -166
  338. package/tests/init.test.js +0 -231
  339. package/tests/logging.test.js +0 -235
  340. package/tests/mocks/i18n.js +0 -3
  341. package/tests/mocks/theme.js +0 -3
  342. package/tests/setupJest.js +0 -8
  343. package/tests/slots.rules.test.js +0 -195
  344. package/tests/slots.test.js +0 -278
  345. package/tests/utils.AvailabilityRules.test.js +0 -221
  346. package/tests/utils.AvailabilityViewer.test.js +0 -1800
  347. package/tests/utils.CalendarSync.test.js +0 -277
  348. package/tests/utils.test.js +0 -119
  349. package/webpack.config.js +0 -114
@@ -1,789 +0,0 @@
1
- import moment from "moment-timezone";
2
- import {
3
- createEmptySlotsForPeriod,
4
- getMonthsDescription,
5
- roundPeriod,
6
- keyFormat,
7
- shortKeyFormat,
8
- } from "./slots";
9
- import { objectToArray } from "./utils";
10
- import { timeLabels } from "./slots";
11
-
12
- // Use the slot's "start" time-string as the
13
- // key (for quicker/simpler look-up later)
14
- export const addKeysToSlots = rawSlots => {
15
- if (rawSlots) {
16
- return rawSlots.reduce((acc, curr) => {
17
- acc[curr.start] = curr;
18
- return acc;
19
- }, {});
20
- } else {
21
- return {};
22
- }
23
- };
24
-
25
- export const sortKeys = keys =>
26
- keys.sort((a, b) => {
27
- if (moment.utc(a) < moment.utc(b)) {
28
- return -1;
29
- }
30
- if (moment.utc(a) > moment.utc(b)) {
31
- return 1;
32
- }
33
- return 0;
34
- });
35
-
36
- export const getMinMaxDates = (queryPeriods = false) => {
37
- if (!queryPeriods || Object.keys(queryPeriods).length < 1) {
38
- return {
39
- min: moment.utc().format("YYYY-MM-DD"),
40
- max: moment.utc().add(1, "days").format("YYYY-MM-DD"),
41
- };
42
- }
43
-
44
- const startDates = sortKeys(Object.keys(queryPeriods));
45
-
46
- return {
47
- min: moment
48
- .utc(queryPeriods[startDates[0]].start, "YYYY-MM-DDTHH:mm:00Z")
49
- .local()
50
- .format("YYYY-MM-DD"),
51
- max: moment
52
- .utc(queryPeriods[startDates[startDates.length - 1]].end, "YYYY-MM-DDTHH:mm:00Z")
53
- .local()
54
- .format("YYYY-MM-DD"),
55
- };
56
- };
57
-
58
- export const buildDayPeriod = (startTime, endTime, day, tzid) => {
59
- const localStart = `${day}T${startTime}`;
60
- const localEnd = `${day}T${endTime}`;
61
- const UTCStart = moment.tz(localStart, "YYYY-MM-DDTHH:mm", tzid).utc();
62
- const UTCEnd = moment.tz(localEnd, "YYYY-MM-DDTHH:mm", tzid).utc();
63
-
64
- const is24Hours = startTime === endTime;
65
- if (is24Hours) {
66
- UTCEnd.add(1, "days");
67
- }
68
-
69
- // An end-time of midnight will always be at the *end* of our
70
- // target day (a.k.a. the very start of the following day)
71
- const localMidnight = moment(`${day}T00:00`, "YYYY-MM-DDTHH:mm");
72
- if (UTCEnd.diff(localMidnight, "minutes") === 0) {
73
- UTCEnd.add(1, "days");
74
- }
75
-
76
- const start = UTCStart.format("YYYY-MM-DDTHH:mm[:00Z]");
77
- const end = UTCEnd.format("YYYY-MM-DDTHH:mm[:00Z]");
78
-
79
- return {
80
- start,
81
- end,
82
- };
83
- };
84
-
85
- export const getDaysForWeek = startDate => {
86
- const start = startDate.clone();
87
- return [
88
- start.format("YYYY-MM-DD"),
89
- start.add(1, "days").format("YYYY-MM-DD"),
90
- start.add(1, "days").format("YYYY-MM-DD"),
91
- start.add(1, "days").format("YYYY-MM-DD"),
92
- start.add(1, "days").format("YYYY-MM-DD"),
93
- start.add(1, "days").format("YYYY-MM-DD"),
94
- start.add(1, "days").format("YYYY-MM-DD"),
95
- ];
96
- };
97
-
98
- export const getDayOffset = (day, target = "sunday") => {
99
- const dayNumbers = {
100
- sunday: 0,
101
- monday: 1,
102
- tuesday: 2,
103
- wednesday: 3,
104
- thursday: 4,
105
- friday: 5,
106
- saturday: 6,
107
- };
108
- const diff = dayNumbers[day] - dayNumbers[target];
109
- const adjustedDiff = diff < 0 ? diff + 7 : diff;
110
- return adjustedDiff;
111
- };
112
-
113
- export const getStartDate = (dateObject, targetDayName) => {
114
- // Belt and braces: we *need* this value to be a lowercase day-name in English
115
- // regardless of whatever locale or format moment might try to give us if left
116
- // to its own devices.
117
- const dateDayName = dateObject.clone().locale("en").format("dddd").toLowerCase();
118
-
119
- const offset = getDayOffset(dateDayName, targetDayName);
120
- return dateObject.subtract(offset, "days");
121
- };
122
-
123
- export const getPageCount = (weekStartDate, end, count = 1) => {
124
- const weekEndDate = weekStartDate.clone().add(7, "days");
125
- const endDiff = end.diff(weekEndDate, "days");
126
- if (endDiff < 0) {
127
- return count;
128
- }
129
- return getPageCount(weekEndDate, end, count + 1);
130
- };
131
-
132
- export const getAllWeekDays = ({ startDate, endDate, startDay = "sunday", tzid }) => {
133
- const start = moment.tz(startDate, "YYYY-MM-DD", tzid);
134
- const end = moment.tz(endDate, "YYYY-MM-DD", tzid);
135
-
136
- const weekStartDate = getStartDate(start, startDay);
137
-
138
- const weekCount = getPageCount(weekStartDate, end);
139
-
140
- let weeks = [];
141
- for (let i = 0; i < weekCount; i++) {
142
- weeks.push(...getDaysForWeek(weekStartDate.clone().add(i * 7, "days")));
143
- }
144
- return weeks;
145
- };
146
-
147
- export const getWeeksInfo = weekdays => {
148
- const current = 1;
149
- const total = Math.ceil(weekdays.length / 7);
150
-
151
- return {
152
- set: true,
153
- days: weekdays,
154
- total,
155
- current,
156
- hasNext: current < total,
157
- hasPrev: false,
158
- };
159
- };
160
-
161
- export const checkWeekdaysSlotAvailability = (
162
- weekdaysEmpties,
163
- availablePeriods,
164
- selectedSlots,
165
- duration,
166
- interval,
167
- unrestricted
168
- ) => {
169
- const slotsPerSelection = duration / interval;
170
-
171
- const relativeSlot = (slot, offset) => slot.clone().add(offset * interval, "minutes");
172
-
173
- const slotKey = slot => slot.format(shortKeyFormat);
174
-
175
- const allAvailableSlots = {};
176
- Object.values(availablePeriods).forEach(ap => {
177
- let slotStart = moment.utc(ap.start);
178
- const apEnd = moment.utc(ap.end);
179
-
180
- while (slotStart < apEnd) {
181
- allAvailableSlots[slotKey(slotStart)] = ap;
182
- slotStart = relativeSlot(slotStart, 1);
183
- }
184
- });
185
-
186
- const allSlotsInSelections = {};
187
- Object.keys(selectedSlots).forEach(selected => {
188
- const selectedSlot = moment.utc(selected, keyFormat);
189
- for (let i = 0; i < slotsPerSelection; i++) {
190
- const slot = relativeSlot(selectedSlot, i);
191
- allSlotsInSelections[slotKey(slot)] = slot;
192
- }
193
- });
194
-
195
- const slotSelectable = slot => {
196
- if (allSlotsInSelections[slot.start]) {
197
- return false;
198
- } else if (unrestricted) {
199
- return true;
200
- } else {
201
- return !!allAvailableSlots[slot.start];
202
- }
203
- };
204
-
205
- const newParsedSlot = (start, lastSelectableMoment) => {
206
- const startKey = slotKey(start);
207
- const slotEnd = start.clone().add(duration, "minutes");
208
- const endKey = slotKey(slotEnd);
209
- const availableSlot = allAvailableSlots[startKey];
210
- const visiblyAvailable = !!availableSlot && startKey <= lastSelectableMoment;
211
- const participants = !!availableSlot ? availableSlot.participants : [];
212
-
213
- return {
214
- startMoment: start,
215
- start: startKey,
216
- end: endKey,
217
- available: false, // Can it actually be selected?
218
- visiblyAvailable: visiblyAvailable, // is it availble in the calendar
219
- blocked: false,
220
- selected: false,
221
- target: false,
222
- targetOffset: 0,
223
- participants: participants,
224
- };
225
- };
226
-
227
- // If a slot is `available` then it can be selected by a user.
228
- //
229
- // If a slot is `visiblyAvailable`, it cannot be directly selected, but
230
- // should be displayed as "available" (because it falls in the duration
231
- // overflow)
232
- //
233
- // If a slot is `blocked` it would normally be available, but is currently
234
- // unselectable becasue of an existing user selection (this is a dynamic
235
- // effect, and not set here).
236
-
237
- return weekdaysEmpties.map(day => {
238
- const parsedSlots = {};
239
- const lastSlotOfTheDay = day.slots[day.slots.length - 1];
240
- const lastSelectableMoment = lastSlotOfTheDay.end;
241
-
242
- // Pre-generate all the slot objects for the day
243
- day.slots.forEach(slot => {
244
- const slotStart = moment.utc(slot.start, keyFormat);
245
- const newSlot = newParsedSlot(slotStart, lastSelectableMoment);
246
- parsedSlots[slot.start] = newSlot;
247
- });
248
-
249
- // March foward through each slot, seeing if the window of slots ahead of it can be selected
250
- day.slots.forEach(slot => {
251
- const parsedSlot = parsedSlots[slot.start];
252
-
253
- // Even if this one is available, the slot would overun the end of the element
254
- if (parsedSlot.end > lastSelectableMoment) return;
255
-
256
- // If we click this Slot, which other slots will need to be selected?
257
- const additionalSlotsForSelection = [];
258
- for (let i = 0; i < slotsPerSelection; i++) {
259
- const windowSlot = relativeSlot(parsedSlot.startMoment, i);
260
- const windowParsedSlot = parsedSlots[slotKey(windowSlot)];
261
- if (windowParsedSlot) additionalSlotsForSelection.push(windowParsedSlot);
262
- }
263
-
264
- // Are all of the slots we need selectable?
265
- if (additionalSlotsForSelection.every(slotSelectable)) {
266
- // Yes, set all of the slots in the window to use the current slot as their parent
267
- additionalSlotsForSelection.forEach((windowParsedSlot, offset) => {
268
- if (offset === 0) {
269
- // Slot is the start of a selectable group
270
- windowParsedSlot.available = true;
271
- windowParsedSlot.target = false;
272
- windowParsedSlot.targetOffset = false;
273
- } else {
274
- // Slot is the part of a selectable group
275
- windowParsedSlot.target = slot.start;
276
- windowParsedSlot.targetOffset = slotsPerSelection - offset;
277
- }
278
- parsedSlots[windowParsedSlot.start] = windowParsedSlot;
279
- });
280
- }
281
- });
282
-
283
- const daySlots = Object.values(parsedSlots);
284
- return {
285
- day: day.day,
286
- slots: daySlots,
287
- };
288
- });
289
- };
290
-
291
- export const checkWeekdaysSlotAvailabilityFreeSelect = (weekdaysEmpties, availablePeriods) => {
292
- return weekdaysEmpties.map(day => ({
293
- ...day,
294
- slots: day.slots.map(slot => {
295
- const withinPeriod = Object.keys(availablePeriods).map(periodKey => {
296
- const period = availablePeriods[periodKey];
297
- return slot.start >= period.start && slot.end <= period.end;
298
- });
299
- const result = withinPeriod.reduce((bool, acc) => {
300
- if (bool) {
301
- return true;
302
- } else {
303
- return acc;
304
- }
305
- }, false);
306
- return { ...slot, visiblyAvailable: result };
307
- }),
308
- }));
309
- };
310
-
311
- export const generatePageSlots = (
312
- { availablePeriods, selectedSlots, limits, pages, tzid, unrestricted, freeSelect = false },
313
- getEmpties = createEmptySlotsForPeriod,
314
- buildPeriod = buildDayPeriod
315
- ) => {
316
- const weekdaysEmpties = pages.days.reduce((acc, day) => {
317
- const dayPeriod = buildPeriod(limits.start, limits.end, day, tzid);
318
-
319
- // Make sure the period starts on a round value (according to the duration)
320
- const roundedPeriod = roundPeriod(dayPeriod, limits.duration);
321
-
322
- acc.push({
323
- day: day,
324
- slots: getEmpties(roundedPeriod, limits.interval, tzid),
325
- });
326
- return acc;
327
- }, []);
328
-
329
- let allSlots = [];
330
- if (freeSelect) {
331
- allSlots = checkWeekdaysSlotAvailabilityFreeSelect(weekdaysEmpties, availablePeriods);
332
- } else {
333
- const currentPage = pages.current || 1;
334
- const day0 = (currentPage - 1) * 7;
335
- const day7 = currentPage * 7;
336
- const daysToProcess = weekdaysEmpties.slice(day0, day7);
337
- allSlots = checkWeekdaysSlotAvailability(
338
- daysToProcess,
339
- availablePeriods,
340
- selectedSlots,
341
- limits.duration,
342
- limits.interval,
343
- unrestricted
344
- );
345
- }
346
-
347
- return {
348
- pages,
349
- slots: allSlots,
350
- };
351
- };
352
-
353
- export const createExportableSelection = slots => objectToArray(slots).map(item => item.value.slot);
354
-
355
- export const checkBlockedSlots = ({ slots, selected, duration = 60, interval = 60 }) => {
356
- const intervalsPerSlot = duration / interval;
357
-
358
- let precedingBlocks = [];
359
- let selectedBlocks = [];
360
-
361
- // We just need the `start` string values (used as the keys for the selected
362
- // slots object).
363
- const selectedKeys = Object.keys(selected);
364
-
365
- selectedKeys.map(key => {
366
- const blockSource = moment(key, "YYYY-MM-DDTHH:mm:00Z");
367
- for (let i = 1; i < intervalsPerSlot; i++) {
368
- // Get the `start` string for any slots directly covered
369
- // by the current selection.
370
- const selectedKey = blockSource
371
- .clone()
372
- .utc()
373
- .add(i * interval, "minutes")
374
- .format("YYYY-MM-DDTHH:mm[:00Z]");
375
- selectedBlocks.push(selectedKey);
376
-
377
- // Get the `start` string for any preceding slots that would
378
- // overlap the selected slot.
379
- const precedingOverlapKey = blockSource
380
- .clone()
381
- .utc()
382
- .subtract(i * interval, "minutes")
383
- .format("YYYY-MM-DDTHH:mm[:00Z]");
384
- precedingBlocks.push(precedingOverlapKey);
385
- }
386
- });
387
-
388
- const blockedSlots = slots.map(day => ({
389
- ...day,
390
- slots: day.slots.map(slot => {
391
- // Is this slot a `preceding` slot? (if so, it should be blocked).
392
- const precedingBlockStatus = precedingBlocks.includes(slot.start);
393
-
394
- // Is this slot at the end of an available period *and* with the overlap
395
- // region of a selected slot? (if so, it should be blocked).
396
- const followingBlockStatus = slot.target && selectedBlocks.includes(slot.target);
397
-
398
- const blockStatus = precedingBlockStatus || followingBlockStatus || false;
399
- return {
400
- ...slot,
401
- blocked: blockStatus,
402
- };
403
- }),
404
- }));
405
- return blockedSlots;
406
- };
407
-
408
- export const generateStaticPages = (queryPeriods, startDay, tzid) => {
409
- const periodsWithKeys = addKeysToSlots(queryPeriods);
410
- const minMax = getMinMaxDates(periodsWithKeys);
411
- const weekdays = getAllWeekDays({
412
- startDate: minMax.min,
413
- endDate: minMax.max,
414
- startDay: startDay,
415
- tzid: tzid,
416
- });
417
-
418
- const weeks = getWeeksInfo(weekdays);
419
- return weeks;
420
- };
421
-
422
- export const divideDaysIntoWeeks = (days, currentPage) =>
423
- [...days].slice((currentPage - 1) * 7, currentPage * 7);
424
-
425
- // compare 2 periods (objects with start/end as moment instances).
426
- // If they overlap, return that overlapping period as an object
427
- // with start/end as "YYYY-MM-DDTHH:mm:00Z" strings.
428
- // If they don't, return false.
429
- export const periodOverlap = (testPeriod, wrapper) => {
430
- // If `testPeriod` ends before `wrapper` starts, then there's no overlap
431
- const endsBefore = testPeriod.end.diff(wrapper.start, "hours");
432
- if (endsBefore <= 0) return false;
433
-
434
- // If `wrapper` starts after `testPeriod` ends, then there's no overlap
435
- const startsAfter = testPeriod.start.diff(wrapper.end, "hours");
436
- if (startsAfter >= 0) return false;
437
-
438
- const startDiff = wrapper.start.diff(testPeriod.start, "minutes");
439
- const endDiff = testPeriod.end.diff(wrapper.end, "minutes");
440
-
441
- const newStart =
442
- startDiff < 0
443
- ? testPeriod.start.format("YYYY-MM-DDTHH:mm[:00Z]")
444
- : wrapper.start.format("YYYY-MM-DDTHH:mm[:00Z]");
445
- const newEnd =
446
- endDiff < 0
447
- ? testPeriod.end.format("YYYY-MM-DDTHH:mm[:00Z]")
448
- : wrapper.end.format("YYYY-MM-DDTHH:mm[:00Z]");
449
- const newPeriod = { start: newStart, end: newEnd };
450
- return newPeriod;
451
- };
452
-
453
- export const cropQuery = (query, extent, ignoreWeeks = false) => {
454
- let days;
455
- if (ignoreWeeks) {
456
- days = extent.days;
457
- } else {
458
- days = divideDaysIntoWeeks(extent.days, extent.currentPage);
459
- }
460
-
461
- // These are the bounds within which our query should live:
462
- const bounds = days.map(day => {
463
- const localStart = extent.startTime;
464
- const localEnd = extent.endTime;
465
-
466
- const startTime = moment.tz(`${day}T${localStart}`, "YYYY-MM-DDTHH:mm", extent.tzid).utc();
467
-
468
- const endTimeRaw = moment.tz(`${day}T${localEnd}`, "YYYY-MM-DDTHH:mm", extent.tzid).utc();
469
-
470
- // If the endTime is an earlier hour than the startTime, that means
471
- // the period overflows a day boundary.
472
- const isEndBeforeStart = startTime.diff(endTimeRaw, "minutes") > 0;
473
-
474
- const endTime =
475
- isEndBeforeStart || extent.startTime === extent.endTime
476
- ? endTimeRaw.add(1, "days")
477
- : endTimeRaw;
478
-
479
- return {
480
- start: startTime,
481
- end: endTime,
482
- };
483
- });
484
-
485
- const croppedPeriods = bounds.reduce((periodsAccumulator, day) => {
486
- const newPeriods = query.query_periods
487
- .map(period => {
488
- const periodStart = moment.utc(period.start, "YYYY-MM-DDTHH:mm:00Z");
489
- const periodEnd = moment.utc(period.end, "YYYY-MM-DDTHH:mm:00Z");
490
- const overlap = periodOverlap({ start: periodStart, end: periodEnd }, day);
491
-
492
- return overlap;
493
- })
494
- .filter(period => period);
495
-
496
- return [...periodsAccumulator, ...newPeriods];
497
- }, []);
498
-
499
- return { ...query, query_periods: croppedPeriods };
500
- };
501
-
502
- export const calculateDisplayText = (i18n, slot, status) => {
503
- const startObject = moment.tz(slot.start, "YYYY-MM-DDTHH:mm:00Z", status.tzid);
504
- const endObject = moment.tz(slot.end, "YYYY-MM-DDTHH:mm:00Z", status.tzid);
505
- const startTime = i18n.f(startObject, "LT").replace(" ", "");
506
- const endTime = i18n.f(endObject, "LT").replace(" ", "");
507
-
508
- let text;
509
- switch (status.mode) {
510
- case "multi_select":
511
- case "no_confirm":
512
- text = `${startTime} - ${endTime}`;
513
- break;
514
- case "free_select":
515
- text = "";
516
- break;
517
- default:
518
- text = i18n.t("confirm");
519
- }
520
- return {
521
- time: `${startTime} - ${endTime}`,
522
- text,
523
- };
524
- };
525
-
526
- export const buildPeriodsFromSlots = slots => {
527
- const sortedSlots = slots.sort((a, b) => {
528
- if (a.start < b.start) {
529
- return -1;
530
- }
531
- if (a.start > b.start) {
532
- return 1;
533
- }
534
- return 0;
535
- });
536
-
537
- const periods = sortedSlots.reduce((acc, curr, i) => {
538
- const prev = slots[i - 1];
539
-
540
- if (!prev) {
541
- // This is the last slot, so just add it to the array
542
- return [
543
- ...acc,
544
- {
545
- start: curr.start,
546
- end: curr.end,
547
- },
548
- ];
549
- }
550
-
551
- if (curr.start === prev.end) {
552
- // This slot abuts the one that came before, so
553
- // let's remove the previous one and combine it with
554
- // the current one.
555
- const lastItem = acc.pop(); // Note: we're relying on pop() mutating acc here
556
- const combo = {
557
- start: lastItem.start,
558
- end: curr.end,
559
- };
560
- return [...acc, combo];
561
- }
562
- // The slots don't abut, so just add this one
563
- return [
564
- ...acc,
565
- {
566
- start: curr.start,
567
- end: curr.end,
568
- },
569
- ];
570
- }, []);
571
-
572
- return periods;
573
- };
574
-
575
- export const addSlotStarts = (start, interval, count) => {
576
- const times = [];
577
- for (let i = 0; i <= count; i++) {
578
- const time = start.clone().add(i * interval, "minutes");
579
- times.push(time.format("YYYY-MM-DDTHH:mm[:00Z]"));
580
- }
581
- return times;
582
- };
583
-
584
- // Given a start and end slot-time, caluculate the start-times
585
- // of all slots that fall between those times
586
- export const tweenSlots = ({ start, end, tzid, interval }) => {
587
- const first = start < end ? start : end;
588
- const last = start > end ? start : end;
589
-
590
- const startTime = moment.utc(first, "YYYY-MM-DDTHH:mm:00Z");
591
- const endTime = moment.utc(last, "YYYY-MM-DDTHH:mm:00Z");
592
- const diff = endTime.diff(startTime, "minutes");
593
-
594
- const firstDate = startTime.clone().tz(tzid);
595
- const lastDate = endTime.clone().tz(tzid);
596
- if (firstDate.format("YYYY-MM-DD") !== lastDate.format("YYYY-MM-DD")) {
597
- // The selection spans mulitple days
598
- const localFirstTime = startTime.clone().tz(tzid).format("HH:mm");
599
- const localLastTime = endTime.clone().tz(tzid).format("HH:mm");
600
- const sortedLocalFirstTime =
601
- localFirstTime < localLastTime ? localFirstTime : localLastTime;
602
- const sortedLocalLastTime = localFirstTime > localLastTime ? localFirstTime : localLastTime;
603
-
604
- const timeDiff = moment(sortedLocalLastTime, "HH:mm").diff(
605
- moment(sortedLocalFirstTime, "HH:mm"),
606
- "minutes"
607
- );
608
- const dayTweenCount = timeDiff / interval;
609
-
610
- const dayDiff = lastDate
611
- .clone()
612
- .endOf("day")
613
- .diff(firstDate.clone().startOf("day"), "hours");
614
- const dayCount = Math.floor(dayDiff / 24);
615
- const dates = [firstDate.format("YYYY-MM-DD")];
616
- for (let i = 1; i < dayCount; i++) {
617
- const tweenDay = firstDate.clone().add(i, "days");
618
- dates.push(tweenDay.format("YYYY-MM-DD"));
619
- }
620
- dates.push(lastDate.format("YYYY-MM-DD"));
621
-
622
- const daysTweens = dates.map(day => {
623
- const dayStart = moment
624
- .tz(`${day} ${sortedLocalFirstTime}`, "YYYY-MM-DD HH:mm", tzid)
625
- .utc();
626
-
627
- const dayTweens = addSlotStarts(dayStart, interval, dayTweenCount);
628
-
629
- return dayTweens;
630
- });
631
-
632
- const flattenedTweens = [].concat.apply([], daysTweens);
633
-
634
- return flattenedTweens;
635
- }
636
-
637
- const tweenCount = diff / interval;
638
- const tweens = addSlotStarts(startTime, interval, tweenCount);
639
- return tweens;
640
- };
641
-
642
- export const calculateTimeString = (slot, i18n, tzid) => {
643
- const startTimeString = i18n
644
- .f(moment(slot.start, "YYYY-MM-DDTHH:mm:00Z").tz(tzid), "LT")
645
- .replace(" ", "");
646
- const endTimeString = i18n
647
- .f(moment(slot.end, "YYYY-MM-DDTHH:mm:00Z").tz(tzid), "LT")
648
- .replace(" ", "");
649
- const timeString = `${startTimeString} - ${endTimeString}`;
650
- return timeString;
651
- };
652
-
653
- export const getSelectedSlots = slots => {
654
- const flattenedSlots = [].concat.apply(
655
- [],
656
- slots.map(day => day.slots)
657
- );
658
- const selectedSlotsByDay = flattenedSlots.filter(slot => slot.selected);
659
- return selectedSlotsByDay;
660
- };
661
-
662
- export const checkSelectedState = (newSlots, oldSlots) => {
663
- let selectedTimes = [];
664
- oldSlots.map(day =>
665
- day.slots.map(slot => {
666
- if (slot.selected) {
667
- selectedTimes.push(slot.start);
668
- }
669
- })
670
- );
671
- const mergedSlots = newSlots.map(day => ({
672
- ...day,
673
- slots: day.slots.map(slot => {
674
- if (selectedTimes.includes(slot.start)) {
675
- return {
676
- ...slot,
677
- selected: true,
678
- };
679
- }
680
- return slot;
681
- }),
682
- }));
683
- return mergedSlots;
684
- };
685
-
686
- export const condenseTimeLabel = label =>
687
- label
688
- .replace(/[^0-9][0-9]{2} ?/g, "")
689
- .replace(/m/i, "")
690
- .replace(" ", "");
691
-
692
- export const cropDaysToWindow = (rawDays, windowSize = 34) => {
693
- const days = rawDays.slice(0, windowSize);
694
- const overflow = rawDays.slice(windowSize - 1, rawDays.length);
695
-
696
- return { days, overflow };
697
- };
698
-
699
- export const getAllLabels = ({ days, limits, tzid, i18n, locale }) => {
700
- // For each week that the AV could potentially show we
701
- // want to calculate:
702
- // 1. An array of days in that week
703
- // 2. An array of time label info (start-time | end-time | is-hour?)
704
- // 3. The appropriate month label for the week
705
-
706
- // Generate an array with one empty item for each week.
707
- const emptyWeeks = Array.from(new Array(Math.ceil(days.length / 7)));
708
-
709
- // Add the days to each week.
710
- const weeksWithDays = emptyWeeks.map((_, i) => {
711
- const start = i * 7;
712
- const end = start + 7;
713
- const weeklyDays = days.slice(start, end);
714
- const dayObjects = weeklyDays.map(day => {
715
- const dayObject = moment.tz(day, "YYYY-MM-DD", tzid);
716
- return {
717
- date: day,
718
- number: i18n.f(dayObject, "D"),
719
- name: i18n.f(dayObject, "ddd"),
720
- };
721
- });
722
- return { days: dayObjects };
723
- });
724
-
725
- // Add the time labels to each week.
726
- const weeksWithTimes = weeksWithDays.map(week => {
727
- // `days[1]` is the second day in the week (Monday) so that even on
728
- // weeks where there is a DST transition on a Sunday, the labels are
729
- // accurate for the main bulk of the days shown.
730
- return {
731
- ...week,
732
- times: timeLabels(limits, week.days[1].date, tzid),
733
- };
734
- });
735
-
736
- // Add a month label to each week [TODO]
737
- const weeksWithMonths = weeksWithTimes.map(week => {
738
- const simpleDaysArray = week.days.map(day => day.date);
739
- return {
740
- ...week,
741
- month: getMonthsDescription(simpleDaysArray, locale),
742
- };
743
- });
744
-
745
- return weeksWithMonths;
746
- };
747
-
748
- // Do the days stored in our `allLabels` state match the days
749
- // in our `pages` context?
750
- export const checkIfDaysMatch = (days, allLabels) => {
751
- if (typeof allLabels !== "object" || allLabels.length <= 0) {
752
- // We have no saved days, so they definitely do not match
753
- return false;
754
- }
755
-
756
- // First and last days from `pages`
757
- const firstDay = days[0];
758
- const lastDay = days[days.length - 1];
759
-
760
- // First and last days from `allLabels`
761
- const firstSavedDay = allLabels[0].days[0].date;
762
- const lastSavedWeek = allLabels[allLabels.length - 1].days;
763
- const lastSavedDay = lastSavedWeek[lastSavedWeek.length - 1].date;
764
-
765
- return firstDay === firstSavedDay && lastDay === lastSavedDay;
766
- };
767
-
768
- export const checkIfLimitsMatch = ({ start, end }, times, tzid = "Etc/UTC") => {
769
- // Get the first start time in `HH:mm` format
770
- const startTime = moment
771
- .tz(times[0].start, "YYYY-MM-DDTHH:mm:00Z", tzid)
772
- .local()
773
- .format("HH:mm");
774
-
775
- // Get the last end time in `HH:mm` format
776
- const rawEndTime = moment
777
- .tz(times[times.length - 1].end, "YYYY-MM-DDTHH:mm:00Z", tzid)
778
- .local()
779
- .format("HH:mm");
780
-
781
- // Account for limits.end being "24:00"
782
- const endTime = rawEndTime === "00:00" ? "24:00" : rawEndTime;
783
-
784
- const startMatches = startTime === start;
785
- const endMatches = endTime === end;
786
-
787
- // The limits match the time-labels if *both* start and end match.
788
- return startMatches && endMatches;
789
- };