@sneat/extensions-schedulus-shared 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/esm2022/index.js +2 -0
  2. package/esm2022/index.js.map +1 -0
  3. package/esm2022/lib/components/calendar/calendar-base.component.js +83 -0
  4. package/esm2022/lib/components/calendar/calendar-base.component.js.map +1 -0
  5. package/esm2022/lib/components/calendar/calendar-brief.component.js +57 -0
  6. package/esm2022/lib/components/calendar/calendar-brief.component.js.map +1 -0
  7. package/esm2022/lib/components/calendar/calendar-component-types.js +2 -0
  8. package/esm2022/lib/components/calendar/calendar-component-types.js.map +1 -0
  9. package/esm2022/lib/components/calendar/calendar-state.service.js +90 -0
  10. package/esm2022/lib/components/calendar/calendar-state.service.js.map +1 -0
  11. package/esm2022/lib/components/calendar/calendar.component.js +284 -0
  12. package/esm2022/lib/components/calendar/calendar.component.js.map +1 -0
  13. package/esm2022/lib/components/calendar/components/calendar-add-buttons/calendar-add-buttons.component.js +45 -0
  14. package/esm2022/lib/components/calendar/components/calendar-add-buttons/calendar-add-buttons.component.js.map +1 -0
  15. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-base.component.js +26 -0
  16. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-base.component.js.map +1 -0
  17. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-card.component.js +67 -0
  18. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-card.component.js.map +1 -0
  19. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-tab.component.js +74 -0
  20. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-tab.component.js.map +1 -0
  21. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-title.component.js +27 -0
  22. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day-title.component.js.map +1 -0
  23. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day.component.js +129 -0
  24. package/esm2022/lib/components/calendar/components/calendar-day/calendar-day.component.js.map +1 -0
  25. package/esm2022/lib/components/calendar/components/calendar-filter/calendar-filter.component.js +162 -0
  26. package/esm2022/lib/components/calendar/components/calendar-filter/calendar-filter.component.js.map +1 -0
  27. package/esm2022/lib/components/calendar/components/calendar-filter/calendar-filter.js +17 -0
  28. package/esm2022/lib/components/calendar/components/calendar-filter/calendar-filter.js.map +1 -0
  29. package/esm2022/lib/components/calendar/components/calendar-filter/contacts-filter.component.js +95 -0
  30. package/esm2022/lib/components/calendar/components/calendar-filter/contacts-filter.component.js.map +1 -0
  31. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week-card.component.js +50 -0
  32. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week-card.component.js.map +1 -0
  33. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week-tab.component.js +18 -0
  34. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week-tab.component.js.map +1 -0
  35. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week-title.component.js +15 -0
  36. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week-title.component.js.map +1 -0
  37. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week.component.js +78 -0
  38. package/esm2022/lib/components/calendar/components/calendar-week/calendar-week.component.js.map +1 -0
  39. package/esm2022/lib/components/calendar/components/calendar-weekday/calendar-weekday.component.js +66 -0
  40. package/esm2022/lib/components/calendar/components/calendar-weekday/calendar-weekday.component.js.map +1 -0
  41. package/esm2022/lib/components/calendar/components/day-slot-item/day-slot-item.component.js +93 -0
  42. package/esm2022/lib/components/calendar/components/day-slot-item/day-slot-item.component.js.map +1 -0
  43. package/esm2022/lib/components/calendar/components/day-slot-item/slot-context-menu.component.js +324 -0
  44. package/esm2022/lib/components/calendar/components/day-slot-item/slot-context-menu.component.js.map +1 -0
  45. package/esm2022/lib/components/calendar/components/recurrings-tab/recurrings-tab.component.js +36 -0
  46. package/esm2022/lib/components/calendar/components/recurrings-tab/recurrings-tab.component.js.map +1 -0
  47. package/esm2022/lib/components/calendar/components/singles-tab/single-happenings-list.component.js +65 -0
  48. package/esm2022/lib/components/calendar/components/singles-tab/single-happenings-list.component.js.map +1 -0
  49. package/esm2022/lib/components/calendar/components/singles-tab/singles-tab.component.js +106 -0
  50. package/esm2022/lib/components/calendar/components/singles-tab/singles-tab.component.js.map +1 -0
  51. package/esm2022/lib/components/calendar/components/timing-badge/timing-badge.component.js +25 -0
  52. package/esm2022/lib/components/calendar/components/timing-badge/timing-badge.component.js.map +1 -0
  53. package/esm2022/lib/components/calendar/weekday.js +2 -0
  54. package/esm2022/lib/components/calendar/weekday.js.map +1 -0
  55. package/esm2022/lib/components/calendar-core.js +64 -0
  56. package/esm2022/lib/components/calendar-core.js.map +1 -0
  57. package/esm2022/lib/components/calendar-filter.service.js +28 -0
  58. package/esm2022/lib/components/calendar-filter.service.js.map +1 -0
  59. package/esm2022/lib/components/calendar-slots.js +30 -0
  60. package/esm2022/lib/components/calendar-slots.js.map +1 -0
  61. package/esm2022/lib/components/happening-base.component.js +188 -0
  62. package/esm2022/lib/components/happening-base.component.js.map +1 -0
  63. package/esm2022/lib/components/happening-card/happening-card.component.js +69 -0
  64. package/esm2022/lib/components/happening-card/happening-card.component.js.map +1 -0
  65. package/esm2022/lib/components/happening-component-base-params.js +37 -0
  66. package/esm2022/lib/components/happening-component-base-params.js.map +1 -0
  67. package/esm2022/lib/components/happening-form/happening-form.component.js +348 -0
  68. package/esm2022/lib/components/happening-form/happening-form.component.js.map +1 -0
  69. package/esm2022/lib/components/happening-form/happening-price-form/happening-price-modal.component.js +161 -0
  70. package/esm2022/lib/components/happening-form/happening-price-form/happening-price-modal.component.js.map +1 -0
  71. package/esm2022/lib/components/happening-form/happening-prices/happening-prices.component.js +142 -0
  72. package/esm2022/lib/components/happening-form/happening-prices/happening-prices.component.js.map +1 -0
  73. package/esm2022/lib/components/happening-participants/happening-participants.component.js +195 -0
  74. package/esm2022/lib/components/happening-participants/happening-participants.component.js.map +1 -0
  75. package/esm2022/lib/components/happening-slot-form/happening-slot-form.component.js +505 -0
  76. package/esm2022/lib/components/happening-slot-form/happening-slot-form.component.js.map +1 -0
  77. package/esm2022/lib/components/happening-slot-form/happening-slot-modal.component.js +140 -0
  78. package/esm2022/lib/components/happening-slot-form/happening-slot-modal.component.js.map +1 -0
  79. package/esm2022/lib/components/happening-slot-form/happening-slot-modal.service.js +47 -0
  80. package/esm2022/lib/components/happening-slot-form/happening-slot-modal.service.js.map +1 -0
  81. package/esm2022/lib/components/happening-slot-participants/happening-slot-participants.component.js +74 -0
  82. package/esm2022/lib/components/happening-slot-participants/happening-slot-participants.component.js.map +1 -0
  83. package/esm2022/lib/components/happening-slots/happening-slots.component.js +130 -0
  84. package/esm2022/lib/components/happening-slots/happening-slots.component.js.map +1 -0
  85. package/esm2022/lib/components/index.js +20 -0
  86. package/esm2022/lib/components/index.js.map +1 -0
  87. package/esm2022/lib/components/start-end-dates-range-form/start-end-dates-range-form.component.js +68 -0
  88. package/esm2022/lib/components/start-end-dates-range-form/start-end-dates-range-form.component.js.map +1 -0
  89. package/esm2022/lib/components/start-end-datetime-form/start-end-datetime-form.component.js +377 -0
  90. package/esm2022/lib/components/start-end-datetime-form/start-end-datetime-form.component.js.map +1 -0
  91. package/esm2022/lib/components/start-end-datetime-form/time-selector.component.js +92 -0
  92. package/esm2022/lib/components/start-end-datetime-form/time-selector.component.js.map +1 -0
  93. package/esm2022/lib/components/swipeable-base.component.js +112 -0
  94. package/esm2022/lib/components/swipeable-base.component.js.map +1 -0
  95. package/esm2022/lib/components/swipeable-ui.js +64 -0
  96. package/esm2022/lib/components/swipeable-ui.js.map +1 -0
  97. package/esm2022/lib/components/week.js +2 -0
  98. package/esm2022/lib/components/week.js.map +1 -0
  99. package/esm2022/lib/components/weekday-functions.js +13 -0
  100. package/esm2022/lib/components/weekday-functions.js.map +1 -0
  101. package/esm2022/lib/components/weekdays/weekdays-form-base.js +72 -0
  102. package/esm2022/lib/components/weekdays/weekdays-form-base.js.map +1 -0
  103. package/esm2022/lib/index.js +3 -0
  104. package/esm2022/lib/index.js.map +1 -0
  105. package/esm2022/lib/modals/happening-title-modal/happening-title-modal.component.js +87 -0
  106. package/esm2022/lib/modals/happening-title-modal/happening-title-modal.component.js.map +1 -0
  107. package/esm2022/lib/services/calendar-data-provider.js +271 -0
  108. package/esm2022/lib/services/calendar-data-provider.js.map +1 -0
  109. package/esm2022/lib/services/calendar-day.js +179 -0
  110. package/esm2022/lib/services/calendar-day.js.map +1 -0
  111. package/esm2022/lib/services/calendar-day.service.js +37 -0
  112. package/esm2022/lib/services/calendar-day.service.js.map +1 -0
  113. package/esm2022/lib/services/calendar-nav.service.js +36 -0
  114. package/esm2022/lib/services/calendar-nav.service.js.map +1 -0
  115. package/esm2022/lib/services/calendar-space.js +152 -0
  116. package/esm2022/lib/services/calendar-space.js.map +1 -0
  117. package/esm2022/lib/services/calendar-types.js +52 -0
  118. package/esm2022/lib/services/calendar-types.js.map +1 -0
  119. package/esm2022/lib/services/calendarium-services.module.js +16 -0
  120. package/esm2022/lib/services/calendarium-services.module.js.map +1 -0
  121. package/esm2022/lib/services/calendarium-space.service.js +16 -0
  122. package/esm2022/lib/services/calendarium-space.service.js.map +1 -0
  123. package/esm2022/lib/services/happening.service.js +225 -0
  124. package/esm2022/lib/services/happening.service.js.map +1 -0
  125. package/esm2022/lib/services/index.js +6 -0
  126. package/esm2022/lib/services/index.js.map +1 -0
  127. package/esm2022/sneat-extensions-schedulus-shared.js +5 -0
  128. package/esm2022/sneat-extensions-schedulus-shared.js.map +1 -0
  129. package/index.d.ts +1 -0
  130. package/lib/components/calendar/calendar-base.component.d.ts +23 -0
  131. package/lib/components/calendar/calendar-brief.component.d.ts +11 -0
  132. package/lib/components/calendar/calendar-component-types.d.ts +1 -0
  133. package/lib/components/calendar/calendar-state.service.d.ts +15 -0
  134. package/lib/components/calendar/calendar.component.d.ts +32 -0
  135. package/lib/components/calendar/components/calendar-add-buttons/calendar-add-buttons.component.d.ts +13 -0
  136. package/lib/components/calendar/components/calendar-day/calendar-day-base.component.d.ts +10 -0
  137. package/lib/components/calendar/components/calendar-day/calendar-day-card.component.d.ts +17 -0
  138. package/lib/components/calendar/components/calendar-day/calendar-day-tab.component.d.ts +19 -0
  139. package/lib/components/calendar/components/calendar-day/calendar-day-title.component.d.ts +10 -0
  140. package/lib/components/calendar/components/calendar-day/calendar-day.component.d.ts +30 -0
  141. package/lib/components/calendar/components/calendar-filter/calendar-filter.component.d.ts +39 -0
  142. package/lib/components/calendar/components/calendar-filter/calendar-filter.d.ts +10 -0
  143. package/lib/components/calendar/components/calendar-filter/contacts-filter.component.d.ts +20 -0
  144. package/lib/components/calendar/components/calendar-week/calendar-week-card.component.d.ts +15 -0
  145. package/lib/components/calendar/components/calendar-week/calendar-week-tab.component.d.ts +9 -0
  146. package/lib/components/calendar/components/calendar-week/calendar-week-title.component.d.ts +7 -0
  147. package/lib/components/calendar/components/calendar-week/calendar-week.component.d.ts +20 -0
  148. package/lib/components/calendar/components/calendar-weekday/calendar-weekday.component.d.ts +23 -0
  149. package/lib/components/calendar/components/day-slot-item/day-slot-item.component.d.ts +19 -0
  150. package/lib/components/calendar/components/day-slot-item/slot-context-menu.component.d.ts +40 -0
  151. package/lib/components/calendar/components/recurrings-tab/recurrings-tab.component.d.ts +15 -0
  152. package/lib/components/calendar/components/singles-tab/single-happenings-list.component.d.ts +22 -0
  153. package/lib/components/calendar/components/singles-tab/singles-tab.component.d.ts +29 -0
  154. package/lib/components/calendar/components/timing-badge/timing-badge.component.d.ts +17 -0
  155. package/lib/components/calendar/weekday.d.ts +7 -0
  156. package/lib/components/calendar-core.d.ts +10 -0
  157. package/lib/components/calendar-filter.service.d.ts +8 -0
  158. package/lib/components/calendar-slots.d.ts +5 -0
  159. package/lib/components/happening-base.component.d.ts +46 -0
  160. package/lib/components/happening-card/happening-card.component.d.ts +11 -0
  161. package/lib/components/happening-component-base-params.d.ts +16 -0
  162. package/lib/components/happening-form/happening-form.component.d.ts +52 -0
  163. package/lib/components/happening-form/happening-price-form/happening-price-modal.component.d.ts +29 -0
  164. package/lib/components/happening-form/happening-prices/happening-prices.component.d.ts +16 -0
  165. package/lib/components/happening-participants/happening-participants.component.d.ts +24 -0
  166. package/lib/components/happening-slot-form/happening-slot-form.component.d.ts +76 -0
  167. package/lib/components/happening-slot-form/happening-slot-modal.component.d.ts +26 -0
  168. package/lib/components/happening-slot-form/happening-slot-modal.service.d.ts +18 -0
  169. package/lib/components/happening-slot-participants/happening-slot-participants.component.d.ts +19 -0
  170. package/lib/components/happening-slots/happening-slots.component.d.ts +28 -0
  171. package/lib/components/index.d.ts +5 -0
  172. package/lib/components/start-end-dates-range-form/start-end-dates-range-form.component.d.ts +16 -0
  173. package/lib/components/start-end-datetime-form/start-end-datetime-form.component.d.ts +53 -0
  174. package/lib/components/start-end-datetime-form/time-selector.component.d.ts +15 -0
  175. package/lib/components/swipeable-base.component.d.ts +25 -0
  176. package/lib/components/swipeable-ui.d.ts +24 -0
  177. package/lib/components/week.d.ts +4 -0
  178. package/lib/components/weekday-functions.d.ts +3 -0
  179. package/lib/components/weekdays/weekdays-form-base.d.ts +31 -0
  180. package/lib/index.d.ts +2 -0
  181. package/lib/modals/happening-title-modal/happening-title-modal.component.d.ts +24 -0
  182. package/lib/services/calendar-data-provider.d.ts +33 -0
  183. package/lib/services/calendar-day.d.ts +45 -0
  184. package/lib/services/calendar-day.service.d.ts +18 -0
  185. package/lib/services/calendar-nav.service.d.ts +14 -0
  186. package/lib/services/calendar-space.d.ts +23 -0
  187. package/lib/services/calendar-types.d.ts +10 -0
  188. package/lib/services/calendarium-services.module.d.ts +6 -0
  189. package/lib/services/calendarium-space.service.d.ts +8 -0
  190. package/lib/services/happening.service.d.ts +99 -0
  191. package/lib/services/index.d.ts +5 -0
  192. package/package.json +26 -0
  193. package/sneat-extensions-schedulus-shared.d.ts +5 -0
  194. package/tsconfig.lib.prod.tsbuildinfo +1 -0
@@ -0,0 +1,87 @@
1
+ import { Component, inject, Input, ViewChild, signal, ChangeDetectionStrategy, } from '@angular/core';
2
+ import { FormControl, FormGroup, ReactiveFormsModule, Validators, } from '@angular/forms';
3
+ import { IonButton, IonButtons, IonContent, IonFooter, IonHeader, IonIcon, IonInput, IonItem, IonLabel, IonSpinner, IonTextarea, IonTitle, IonToolbar, } from '@ionic/angular/standalone';
4
+ import { HappeningService, HappeningServiceModule, } from '../../services/happening.service';
5
+ import { ClassName, SneatBaseModalComponent } from '@sneat/ui';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/forms";
8
+ export class HappeningTitleModalComponent extends SneatBaseModalComponent {
9
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
10
+ onEnter(_event) { }
11
+ constructor() {
12
+ super();
13
+ this.title = new FormControl('', Validators.required);
14
+ this.summary = new FormControl('');
15
+ this.description = new FormControl('');
16
+ this.form = new FormGroup({
17
+ title: this.title,
18
+ });
19
+ this.happeningService = inject(HappeningService);
20
+ this.$isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "$isSubmitting" }] : []));
21
+ }
22
+ ngOnInit() {
23
+ const h = this.happening || { id: '', space: { id: '' } };
24
+ this.title.setValue(h?.dbo?.title || h?.brief?.title || h.id);
25
+ }
26
+ submit() {
27
+ const spaceID = this.happening?.space?.id;
28
+ const happeningID = this.happening?.id;
29
+ if (!spaceID) {
30
+ throw new Error('space ID is not defined');
31
+ }
32
+ if (!happeningID) {
33
+ throw new Error('happening ID is not defined');
34
+ }
35
+ const title = this.title.value;
36
+ if (!title) {
37
+ return;
38
+ }
39
+ const request = {
40
+ spaceID,
41
+ happeningID,
42
+ title,
43
+ summary: this.summary.value || undefined,
44
+ description: this.description.value || undefined,
45
+ };
46
+ this.$isSubmitting.set(true);
47
+ this.happeningService.updateHappeningTexts(request).subscribe({
48
+ next: () => {
49
+ this.$isSubmitting.set(false);
50
+ this.dismissModal();
51
+ },
52
+ error: (error) => {
53
+ this.$isSubmitting.set(false);
54
+ this.errorLogger.logError(error, 'Failed to update happening texts');
55
+ },
56
+ });
57
+ }
58
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: HappeningTitleModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
59
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: HappeningTitleModalComponent, isStandalone: true, selector: "sneat-happening-title-modal", inputs: { happening: "happening" }, providers: [{ provide: ClassName, useValue: 'HappeningTitleModalComponent' }], viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-title>Edit happening</ion-title>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n label=\"Title\"\n maxlength=\"100\"\n placeholder=\"required field - 100 characters max\"\n #titleInput\n [formControl]=\"title\"\n [disabled]=\"$isSubmitting()\"\n (keyup.enter)=\"onEnter($event)\"\n type=\"text\"\n />\n </ion-item>\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n label=\"Summary\"\n type=\"text\"\n maxlength=\"200\"\n [formControl]=\"summary\"\n [disabled]=\"$isSubmitting()\"\n placeholder=\"optional - 200 characters max\"\n />\n </ion-item>\n\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-textarea\n label=\"Description\"\n placeholder=\"optional\"\n autoGrow=\"true\"\n [formControl]=\"description\"\n [disabled]=\"$isSubmitting()\"\n />\n </ion-item>\n</ion-content>\n<ion-footer>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"solid\" color=\"primary\" (click)=\"submit()\">\n @if ($isSubmitting()) {\n <ion-spinner name=\"lines-small\" slot=\"start\" />\n <ion-label>Saving changes...</ion-label>\n } @else {\n <ion-icon name=\"save-outline\" slot=\"start\" />\n <ion-label>Save changes</ion-label>\n }\n </ion-button>\n <ion-button (click)=\"close()\">\n <ion-icon name=\"close-outline\" slot=\"start\" />\n <ion-label>Cancel</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-footer>\n", dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "ngmodule", type: HappeningServiceModule }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
60
+ }
61
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: HappeningTitleModalComponent, decorators: [{
62
+ type: Component,
63
+ args: [{ imports: [
64
+ IonButton,
65
+ IonButtons,
66
+ IonIcon,
67
+ IonInput,
68
+ IonItem,
69
+ IonLabel,
70
+ ReactiveFormsModule,
71
+ IonHeader,
72
+ IonToolbar,
73
+ IonTitle,
74
+ IonContent,
75
+ IonFooter,
76
+ IonTextarea,
77
+ HappeningServiceModule,
78
+ IonSpinner,
79
+ ], providers: [{ provide: ClassName, useValue: 'HappeningTitleModalComponent' }], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'sneat-happening-title-modal', template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-title>Edit happening</ion-title>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n label=\"Title\"\n maxlength=\"100\"\n placeholder=\"required field - 100 characters max\"\n #titleInput\n [formControl]=\"title\"\n [disabled]=\"$isSubmitting()\"\n (keyup.enter)=\"onEnter($event)\"\n type=\"text\"\n />\n </ion-item>\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n label=\"Summary\"\n type=\"text\"\n maxlength=\"200\"\n [formControl]=\"summary\"\n [disabled]=\"$isSubmitting()\"\n placeholder=\"optional - 200 characters max\"\n />\n </ion-item>\n\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-textarea\n label=\"Description\"\n placeholder=\"optional\"\n autoGrow=\"true\"\n [formControl]=\"description\"\n [disabled]=\"$isSubmitting()\"\n />\n </ion-item>\n</ion-content>\n<ion-footer>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"solid\" color=\"primary\" (click)=\"submit()\">\n @if ($isSubmitting()) {\n <ion-spinner name=\"lines-small\" slot=\"start\" />\n <ion-label>Saving changes...</ion-label>\n } @else {\n <ion-icon name=\"save-outline\" slot=\"start\" />\n <ion-label>Save changes</ion-label>\n }\n </ion-button>\n <ion-button (click)=\"close()\">\n <ion-icon name=\"close-outline\" slot=\"start\" />\n <ion-label>Cancel</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-footer>\n" }]
80
+ }], ctorParameters: () => [], propDecorators: { happening: [{
81
+ type: Input,
82
+ args: [{ required: true }]
83
+ }], titleInput: [{
84
+ type: ViewChild,
85
+ args: ['titleInput', { static: true }]
86
+ }] } });
87
+ //# sourceMappingURL=happening-title-modal.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"happening-title-modal.component.js","sourceRoot":"","sources":["../../../../../../../../../libs/extensions/schedulus/shared/src/lib/modals/happening-title-modal/happening-title-modal.component.ts","../../../../../../../../../libs/extensions/schedulus/shared/src/lib/modals/happening-title-modal/happening-title-modal.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n inject,\n Input,\n OnInit,\n ViewChild,\n signal,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport {\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport {\n IonButton,\n IonButtons,\n IonContent,\n IonFooter,\n IonHeader,\n IonIcon,\n IonInput,\n IonItem,\n IonLabel,\n IonSpinner,\n IonTextarea,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport {\n HappeningService,\n HappeningServiceModule,\n IUpdateHappeningTextsRequest,\n} from '../../services/happening.service';\nimport { IHappeningContext } from '@sneat/mod-schedulus-core';\nimport { ClassName, SneatBaseModalComponent } from '@sneat/ui';\n\n@Component({\n imports: [\n IonButton,\n IonButtons,\n IonIcon,\n IonInput,\n IonItem,\n IonLabel,\n ReactiveFormsModule,\n IonHeader,\n IonToolbar,\n IonTitle,\n IonContent,\n IonFooter,\n IonTextarea,\n HappeningServiceModule,\n IonSpinner,\n ],\n providers: [{ provide: ClassName, useValue: 'HappeningTitleModalComponent' }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './happening-title-modal.component.html',\n selector: 'sneat-happening-title-modal',\n})\nexport class HappeningTitleModalComponent\n extends SneatBaseModalComponent\n implements OnInit\n{\n @Input({ required: true }) happening?: IHappeningContext;\n\n @ViewChild('titleInput', { static: true }) titleInput?: IonInput;\n\n protected readonly title = new FormControl<string>('', Validators.required);\n protected readonly summary = new FormControl<string>('');\n protected readonly description = new FormControl<string>('');\n\n protected readonly form = new FormGroup({\n title: this.title,\n });\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n protected onEnter(_event?: Event): void {}\n\n private happeningService = inject(HappeningService);\n\n public constructor() {\n super();\n }\n\n ngOnInit(): void {\n const h = this.happening || { id: '', space: { id: '' } };\n this.title.setValue(h?.dbo?.title || h?.brief?.title || h.id);\n }\n\n protected readonly $isSubmitting = signal(false);\n\n protected submit(): void {\n const spaceID = this.happening?.space?.id;\n const happeningID = this.happening?.id;\n if (!spaceID) {\n throw new Error('space ID is not defined');\n }\n if (!happeningID) {\n throw new Error('happening ID is not defined');\n }\n const title = this.title.value;\n if (!title) {\n return;\n }\n const request: IUpdateHappeningTextsRequest = {\n spaceID,\n happeningID,\n title,\n summary: this.summary.value || undefined,\n description: this.description.value || undefined,\n };\n this.$isSubmitting.set(true);\n this.happeningService.updateHappeningTexts(request).subscribe({\n next: () => {\n this.$isSubmitting.set(false);\n this.dismissModal();\n },\n error: (error) => {\n this.$isSubmitting.set(false);\n this.errorLogger.logError(error, 'Failed to update happening texts');\n },\n });\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-title>Edit happening</ion-title>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n label=\"Title\"\n maxlength=\"100\"\n placeholder=\"required field - 100 characters max\"\n #titleInput\n [formControl]=\"title\"\n [disabled]=\"$isSubmitting()\"\n (keyup.enter)=\"onEnter($event)\"\n type=\"text\"\n />\n </ion-item>\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n label=\"Summary\"\n type=\"text\"\n maxlength=\"200\"\n [formControl]=\"summary\"\n [disabled]=\"$isSubmitting()\"\n placeholder=\"optional - 200 characters max\"\n />\n </ion-item>\n\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-textarea\n label=\"Description\"\n placeholder=\"optional\"\n autoGrow=\"true\"\n [formControl]=\"description\"\n [disabled]=\"$isSubmitting()\"\n />\n </ion-item>\n</ion-content>\n<ion-footer>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"solid\" color=\"primary\" (click)=\"submit()\">\n @if ($isSubmitting()) {\n <ion-spinner name=\"lines-small\" slot=\"start\" />\n <ion-label>Saving changes...</ion-label>\n } @else {\n <ion-icon name=\"save-outline\" slot=\"start\" />\n <ion-label>Save changes</ion-label>\n }\n </ion-button>\n <ion-button (click)=\"close()\">\n <ion-icon name=\"close-outline\" slot=\"start\" />\n <ion-label>Cancel</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-footer>\n"]}
@@ -0,0 +1,271 @@
1
+ import { computed, signal } from '@angular/core';
2
+ import { dateToIso } from '@sneat/core';
3
+ import { EMPTY, Subject } from 'rxjs';
4
+ import { CalendarDay } from './calendar-day';
5
+ import { CalendarSpace } from './calendar-space';
6
+ import { emptyRecurringsByWeekday, } from './calendar-types';
7
+ // export function happeningDtoToSlot(id: string, dto: ISingleHappeningDto): ISlotItem {
8
+ // if (!dto.title) {
9
+ // throw new Error('!singleHappening.title');
10
+ // }
11
+ // if (!dto.dtStarts) {
12
+ // throw new Error('!singleHappening.dtStarts');
13
+ // }
14
+ // const brief = happeningBriefFromDto(id, dto);
15
+ // const happening: IHappeningContext = { id, brief, dto };
16
+ // // const wd = jsDayToWeekday(date.getDay());
17
+ // // noinspection UnnecessaryLocalVariableJS
18
+ // const slot: ISlotItem = {
19
+ // happening,
20
+ // title: dto.title,
21
+ // repeats: 'once',
22
+ // timing: {
23
+ // start: {
24
+ // time: timeToStr(dto.dtStarts) || '',
25
+ // },
26
+ // end: dto.dtEnds ? {
27
+ // time: timeToStr(dto.dtEnds),
28
+ // } : undefined,
29
+ // },
30
+ // // weekdays: singleHappening.weekdays,
31
+ // participants: dto.participants,
32
+ // // location: singleActivity.location ? singleActivity.location : undefined,
33
+ // levels: dto.levels ? dto.levels : undefined,
34
+ // };
35
+ // return slot;
36
+ // }
37
+ // export abstract class ISlotsProvider {
38
+ // // public abstract setTeamId(communeId: string): Observable<DtoRegularActivity[]>;
39
+ //
40
+ // public abstract setMemberId(memberId: string): void;
41
+ //
42
+ // public abstract preloadEvents(...dates: Date[]): Observable<SlotsGroup>;
43
+ //
44
+ // public abstract getDays(...weekdays: SlotsGroup[]): Observable<SlotsGroup>;
45
+ //
46
+ // // public abstract loadTodayAndFutureEvents(): Observable<DtoSingleActivity[]>;
47
+ // }
48
+ export class CalendarDataProvider {
49
+ // private contactID?: string; // TODO: should be {readonly spaceID: string; readonly contactID: string}
50
+ // public setContactId(contactID: string): void {
51
+ // this.contactID = contactID;
52
+ // }
53
+ constructor(injector, $primarySpaceID, errorLogger, happeningService, calendarDayService, calendariumSpaceService) {
54
+ this.injector = injector;
55
+ this.$primarySpaceID = $primarySpaceID;
56
+ this.errorLogger = errorLogger;
57
+ this.happeningService = happeningService;
58
+ this.calendarDayService = calendarDayService;
59
+ this.calendariumSpaceService = calendariumSpaceService;
60
+ /*implements OnDestroy - this is not a component, do not implement ngOnDestroy(), instead call destroy() */
61
+ /*extends ISlotsProvider*/
62
+ // At the moment tracks schedule of a single team
63
+ // but probably will track multiple teams at once.
64
+ this.destroyed = new Subject();
65
+ // private readonly recurringsSpaceItemService?: ModuleSpaceItemService<
66
+ // IHappeningBrief,
67
+ // IHappeningDbo
68
+ // >;
69
+ // private readonly singlesByDate: Record<string, ISlotUIContext[]> = {};
70
+ this.$space = signal(undefined, ...(ngDevMode ? [{ debugName: "$space" }] : []));
71
+ this.days = {};
72
+ this.$primarySpace = computed(() => {
73
+ const newSpaceID = this.$primarySpaceID();
74
+ if (this.primarySpace?.spaceID === newSpaceID) {
75
+ return this.primarySpace;
76
+ }
77
+ this.primarySpace?.destroy();
78
+ if (this.primarySpace?.spaceID == newSpaceID) {
79
+ return this.primarySpace;
80
+ }
81
+ this.primarySpace = newSpaceID
82
+ ? new CalendarSpace(newSpaceID, this.calendariumSpaceService)
83
+ : undefined;
84
+ return this.primarySpace;
85
+ }, ...(ngDevMode ? [{ debugName: "$primarySpace" }] : []));
86
+ this.$spaces = computed(() => {
87
+ const primarySpace = this.$primarySpace();
88
+ return primarySpace ? [primarySpace] : [];
89
+ }, ...(ngDevMode ? [{ debugName: "$spaces" }] : []));
90
+ this.$recurringByWd = computed(() => {
91
+ const recurringsByWd = emptyRecurringsByWeekday();
92
+ const spaces = this.$spaces();
93
+ spaces.forEach((space) => {
94
+ const spaceRecurringsByWd = space.$recurringByWd();
95
+ Object.entries(spaceRecurringsByWd).forEach(([wd, slots]) => {
96
+ recurringsByWd[wd] = [
97
+ ...recurringsByWd[wd].filter((slot) => slot.happening.space.id !== space.spaceID),
98
+ ...slots,
99
+ ];
100
+ });
101
+ });
102
+ return recurringsByWd;
103
+ }, ...(ngDevMode ? [{ debugName: "$recurringByWd" }] : []));
104
+ this.$recurringsBySpaceID = computed(() => {
105
+ const spaces = this.$spaces();
106
+ const result = {};
107
+ spaces.forEach((space) => {
108
+ result[space.spaceID] = space.$recurrings()?.recurringHappenings || {};
109
+ });
110
+ // console.log('$recurringsBySpaceID():', result);
111
+ return result;
112
+ }, ...(ngDevMode ? [{ debugName: "$recurringsBySpaceID" }] : []));
113
+ this.$inputs = computed(() => this.$spaces().map((space) => ({
114
+ spaceID: space.spaceID,
115
+ $recurringSlots: space.$recurringSlots.asReadonly(),
116
+ recurringSlots$: space.recurringSlots$,
117
+ })), ...(ngDevMode ? [{ debugName: "$inputs" }] : []));
118
+ // console.log('SpaceDaysProvider.constructor()');
119
+ // this.recurringsSpaceItemService = new ModuleSpaceItemService(
120
+ // 'calendarium',
121
+ // 'recurring_happenings', // TODO: Is this obsolete? Should we use 'happenings' instead?
122
+ // calendarDayService.afs,
123
+ // undefined as SneatApiService,
124
+ // );
125
+ }
126
+ destroy() {
127
+ this.destroyed.next();
128
+ Object.values(this.days).forEach((day) => {
129
+ day.destroy();
130
+ });
131
+ this.$spaces().forEach((space) => space.destroy());
132
+ }
133
+ getCalendarDay(date) {
134
+ const id = dateToIso(date);
135
+ let day = this.days[id];
136
+ if (!day) {
137
+ day = new CalendarDay(date, this.injector, this.$inputs, this.errorLogger, this.happeningService, this.calendarDayService);
138
+ this.days[id] = day;
139
+ }
140
+ return day;
141
+ }
142
+ preloadEvents(...dates) {
143
+ console.warn('not implemented: Preload events for:', dates);
144
+ return EMPTY;
145
+ // const dateKeys = dates.filter(d => !!d)
146
+ // .map(localDateToIso)
147
+ // .filter(dateKey => !this.singlesByDate[dateKey]);
148
+ // if (!dateKeys.length) {
149
+ // return EMPTY;
150
+ // }
151
+ // return this.loadEvents(...dates)
152
+ // .pipe(ignoreElements());
153
+ }
154
+ getDays() {
155
+ // console.log('SpaceDaysProvider.getDays()', weekdays);
156
+ return EMPTY;
157
+ // if (!weekdays?.length) {
158
+ // return EMPTY;
159
+ // }
160
+ // if (!this.team) {
161
+ // return from(weekdays);
162
+ // }
163
+ // const weekdaysByDateKey: { [date: string]: Day } = {};
164
+ //
165
+ // const weekdaysToLoad: Day[] = [];
166
+ // const weekdaysLoaded: Day[] = [];
167
+ //
168
+ // weekdays.forEach(weekday => {
169
+ // if (!weekday.date) {
170
+ // throw new Error('!weekday.date');
171
+ // }
172
+ // const dateKey = localDateToIso(weekday.date);
173
+ // weekdaysByDateKey[dateKey] = weekday;
174
+ // this.addRecurringsToSlotsGroup(weekday);
175
+ // const dateSingleSlots = this.singlesByDate[dateKey];
176
+ // if (dateSingleSlots) {
177
+ // if (weekday.slots) {
178
+ // weekday = { ...weekday, slots: weekday.slots.filter(slot => !slot.single) };
179
+ // }
180
+ // if (!weekday.slots) {
181
+ // weekday = { ...weekday, slots: [] };
182
+ // }
183
+ // dateSingleSlots.forEach(slot => weekday.slots && weekday.slots.push(slot));
184
+ // weekdaysLoaded.push(weekday);
185
+ // } else {
186
+ // weekdaysToLoad.push(weekday);
187
+ // }
188
+ // });
189
+ //
190
+ // if (weekdaysToLoad.length === 0) {
191
+ // return from(weekdaysLoaded);
192
+ // }
193
+ //
194
+ // const dates: Date[] = weekdaysToLoad
195
+ // .map(weekday => weekday.date)
196
+ // .filter(date => !!date) as Date[];
197
+ //
198
+ // const loadWeekdays$ = this.loadEvents(...dates)
199
+ // .pipe(
200
+ // map(eventSlotsByDate => {
201
+ // let weekday = weekdaysByDateKey[eventSlotsByDate.dateKey];
202
+ // if (weekday.slots) {
203
+ // weekday = { ...weekday, slots: weekday.slots.filter(slot => !slot.single) };
204
+ // }
205
+ // eventSlotsByDate.events.forEach(slot => {
206
+ // weekday.slots && weekday.slots.push(slot);
207
+ // });
208
+ // return weekday;
209
+ // }),
210
+ // );
211
+ //
212
+ // return weekdaysLoaded ? merge(weekdaysLoaded, loadWeekdays$) : loadWeekdays$;
213
+ }
214
+ loadForWeek() {
215
+ // console.log('SpaceDaysProvider.loadForWeek()', d);
216
+ }
217
+ // private addEventsToSlotsGroup(weekday: SlotsGroup, date:)
218
+ // public loadTodayAndFutureEvents(): Observable<DtoSingleActivity[]> {
219
+ //
220
+ // return this.singleService.selectFutureEvents(this.teamId)
221
+ // .pipe(
222
+ // map(selectResult => {
223
+ // const processedEventIds: string[] = [];
224
+ //
225
+ // selectResult.values.forEach(singleHappening => {
226
+ // const { id } = singleHappening;
227
+ // if (!id) {
228
+ // throw new Error('!id');
229
+ // }
230
+ // if (processedEventIds.includes(id)) {
231
+ // return;
232
+ // }
233
+ // processedEventIds.push(id);
234
+ // let date = new Date(singleHappening.dtStarts);
235
+ // while (date.getTime() < singleHappening.dtEnds) {
236
+ // const dateKey = localDateToIso(date);
237
+ // let dateEvents = this.singlesByDate[dateKey];
238
+ // if (!dateEvents) {
239
+ // this.singlesByDate[dateKey] = dateEvents = [];
240
+ // }
241
+ // dateEvents.push(eventToSlot(singleHappening));
242
+ // date = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
243
+ // }
244
+ // });
245
+ // return selectResult.values;
246
+ // }),
247
+ // );
248
+ // }
249
+ loadEvents() {
250
+ // console.log('loadEvents()', dates);
251
+ return EMPTY;
252
+ // const dateISOs = dates.map(localDateToIso);
253
+ //
254
+ // const mapSelectResult = (selectResult: SelectResult<DtoSingleActivity>) => {
255
+ // const dateKey = selectResult.key;
256
+ // if (!dateKey) {
257
+ // throw new Error('!dateKey');
258
+ // }
259
+ // this.singlesByDate[dateKey] = selectResult.values.length ? selectResult.values.map(eventToSlot) : [];
260
+ // return { dateKey, events: this.singlesByDate[dateKey] };
261
+ // };
262
+ // return this.singleService.selectByDate(tx, this.communeId, ...dateISOs)
263
+ // .pipe(
264
+ // map(selectResult => {
265
+ // console.log(`Loaded events ${selectResult.key}: ${selectResult.values.length}`);
266
+ // return mapSelectResult(selectResult);
267
+ // }),
268
+ // );
269
+ }
270
+ }
271
+ //# sourceMappingURL=calendar-data-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-data-provider.js","sourceRoot":"","sources":["../../../../../../../../libs/extensions/schedulus/shared/src/lib/services/calendar-data-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAU,MAAM,EAAY,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AASxC,OAAO,EAAE,KAAK,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;AAClD,OAAO,EAAE,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,wBAAwB,GAEzB,MAAM,kBAAkB,CAAC;AAI1B,wFAAwF;AACxF,qBAAqB;AACrB,+CAA+C;AAC/C,KAAK;AACL,wBAAwB;AACxB,kDAAkD;AAClD,KAAK;AACL,iDAAiD;AACjD,4DAA4D;AAC5D,gDAAgD;AAChD,8CAA8C;AAC9C,6BAA6B;AAC7B,eAAe;AACf,sBAAsB;AACtB,qBAAqB;AACrB,cAAc;AACd,cAAc;AACd,2CAA2C;AAC3C,QAAQ;AACR,yBAAyB;AACzB,mCAAmC;AACnC,oBAAoB;AACpB,OAAO;AACP,2CAA2C;AAC3C,oCAAoC;AACpC,gFAAgF;AAChF,iDAAiD;AACjD,MAAM;AACN,gBAAgB;AAChB,IAAI;AAEJ,yCAAyC;AACzC,sFAAsF;AACtF,EAAE;AACF,wDAAwD;AACxD,EAAE;AACF,4EAA4E;AAC5E,EAAE;AACF,+EAA+E;AAC/E,EAAE;AACF,mFAAmF;AACnF,IAAI;AAEJ,MAAM,OAAO,oBAAoB;IAkB/B,wGAAwG;IACxG,iDAAiD;IACjD,+BAA+B;IAC/B,IAAI;IAEJ,YACmB,QAAkB,EAClB,eAA2C,EAC3C,WAAyB,EACzB,gBAAkC,EAClC,kBAAsC,EACtC,uBAAgD;QALhD,aAAQ,GAAR,QAAQ,CAAU;QAClB,oBAAe,GAAf,eAAe,CAA4B;QAC3C,gBAAW,GAAX,WAAW,CAAc;QACzB,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,4BAAuB,GAAvB,uBAAuB,CAAyB;QA5BnE,2GAA2G;QAC3G,0BAA0B;QAC1B,iDAAiD;QACjD,kDAAkD;QAEjC,cAAS,GAAG,IAAI,OAAO,EAAQ,CAAC;QAEjD,wEAAwE;QACxE,oBAAoB;QACpB,iBAAiB;QACjB,KAAK;QACL,yEAAyE;QAExD,WAAM,GAAG,MAAM,CAA4B,SAAS,kDAAC,CAAC;QAEtD,SAAI,GAAgC,EAAE,CAAC;QA6BhD,kBAAa,GAAG,QAAQ,CAA4B,GAAG,EAAE;YAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,YAAY,EAAE,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC9C,OAAO,IAAI,CAAC,YAAY,CAAC;YAC3B,CAAC;YACD,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,YAAY,EAAE,OAAO,IAAI,UAAU,EAAE,CAAC;gBAC7C,OAAO,IAAI,CAAC,YAAY,CAAC;YAC3B,CAAC;YACD,IAAI,CAAC,YAAY,GAAG,UAAU;gBAC5B,CAAC,CAAC,IAAI,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,uBAAuB,CAAC;gBAC7D,CAAC,CAAC,SAAS,CAAC;YACd,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC,yDAAC,CAAC;QAEK,YAAO,GAAG,QAAQ,CAA2B,GAAG,EAAE;YACxD,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,CAAC,mDAAC,CAAC;QAEa,mBAAc,GAAG,QAAQ,CACvC,GAAG,EAAE;YACH,MAAM,cAAc,GAAwB,wBAAwB,EAAE,CAAC;YACvE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACvB,MAAM,mBAAmB,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;gBACnD,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;oBAC1D,cAAc,CAAC,EAAkB,CAAC,GAAG;wBACnC,GAAG,cAAc,CAAC,EAAkB,CAAC,CAAC,MAAM,CAC1C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,OAAO,CACpD;wBACD,GAAG,KAAK;qBACT,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,OAAO,cAAc,CAAC;QACxB,CAAC,0DACF,CAAC;QAEc,yBAAoB,GAAG,QAAQ,CAE7C,GAAG,EAAE;YACL,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAqC,EAAE,CAAC;YACpD,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACvB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,EAAE,mBAAmB,IAAI,EAAE,CAAC;YACzE,CAAC,CAAC,CAAC;YACH,kDAAkD;YAClD,OAAO,MAAM,CAAC;QAChB,CAAC,gEAAC,CAAC;QAUc,YAAO,GAAG,QAAQ,CAA+B,GAAG,EAAE,CACrE,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAChB,CAAC,KAAK,EAAqB,EAAE,CAAC,CAAC;YAC7B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,eAAe,EAAE,KAAK,CAAC,eAAe,CAAC,UAAU,EAAE;YACnD,eAAe,EAAE,KAAK,CAAC,eAAe;SACvC,CAAC,CACH,mDACF,CAAC;QA9EA,kDAAkD;QAClD,gEAAgE;QAChE,kBAAkB;QAClB,0FAA0F;QAC1F,2BAA2B;QAC3B,iCAAiC;QACjC,KAAK;IACP,CAAC;IAuDM,OAAO;QACZ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACvC,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IAYM,cAAc,CAAC,IAAU;QAC9B,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,WAAW,CACnB,IAAI,EACJ,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,kBAAkB,CACxB,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEM,aAAa,CAAC,GAAG,KAAa;QACnC,OAAO,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC;QACb,0CAA0C;QAC1C,wBAAwB;QACxB,qDAAqD;QACrD,0BAA0B;QAC1B,iBAAiB;QACjB,IAAI;QACJ,mCAAmC;QACnC,4BAA4B;IAC9B,CAAC;IAEM,OAAO;QACZ,wDAAwD;QACxD,OAAO,KAAK,CAAC;QACb,2BAA2B;QAC3B,iBAAiB;QACjB,IAAI;QACJ,oBAAoB;QACpB,0BAA0B;QAC1B,IAAI;QACJ,yDAAyD;QACzD,EAAE;QACF,oCAAoC;QACpC,oCAAoC;QACpC,EAAE;QACF,gCAAgC;QAChC,wBAAwB;QACxB,sCAAsC;QACtC,KAAK;QACL,iDAAiD;QACjD,yCAAyC;QACzC,4CAA4C;QAC5C,wDAAwD;QACxD,0BAA0B;QAC1B,yBAAyB;QACzB,kFAAkF;QAClF,MAAM;QACN,0BAA0B;QAC1B,0CAA0C;QAC1C,MAAM;QACN,gFAAgF;QAChF,kCAAkC;QAClC,YAAY;QACZ,kCAAkC;QAClC,KAAK;QACL,MAAM;QACN,EAAE;QACF,qCAAqC;QACrC,gCAAgC;QAChC,IAAI;QACJ,EAAE;QACF,uCAAuC;QACvC,iCAAiC;QACjC,sCAAsC;QACtC,EAAE;QACF,kDAAkD;QAClD,UAAU;QACV,8BAA8B;QAC9B,gEAAgE;QAChE,0BAA0B;QAC1B,mFAAmF;QACnF,OAAO;QACP,+CAA+C;QAC/C,iDAAiD;QACjD,SAAS;QACT,qBAAqB;QACrB,QAAQ;QACR,MAAM;QACN,EAAE;QACF,gFAAgF;IAClF,CAAC;IAEM,WAAW;QAChB,qDAAqD;IACvD,CAAC;IAED,4DAA4D;IAE5D,uEAAuE;IACvE,EAAE;IACF,6DAA6D;IAC7D,WAAW;IACX,2BAA2B;IAC3B,8CAA8C;IAC9C,EAAE;IACF,uDAAuD;IACvD,uCAAuC;IACvC,kBAAkB;IAClB,gCAAgC;IAChC,SAAS;IACT,6CAA6C;IAC7C,gBAAgB;IAChB,SAAS;IACT,mCAAmC;IACnC,sDAAsD;IACtD,yDAAyD;IACzD,8CAA8C;IAC9C,sDAAsD;IACtD,2BAA2B;IAC3B,wDAAwD;IACxD,UAAU;IACV,uDAAuD;IACvD,kFAAkF;IAClF,SAAS;IACT,UAAU;IACV,kCAAkC;IAClC,SAAS;IACT,OAAO;IACP,IAAI;IAEI,UAAU;QAChB,sCAAsC;QACtC,OAAO,KAAK,CAAC;QACb,8CAA8C;QAC9C,EAAE;QACF,+EAA+E;QAC/E,qCAAqC;QACrC,mBAAmB;QACnB,iCAAiC;QACjC,KAAK;QACL,yGAAyG;QACzG,4DAA4D;QAC5D,KAAK;QAEL,0EAA0E;QAC1E,UAAU;QACV,0BAA0B;QAC1B,sFAAsF;QACtF,2CAA2C;QAC3C,QAAQ;QACR,MAAM;IACR,CAAC;CACF","sourcesContent":["import { computed, Signal, signal, Injector } from '@angular/core';\nimport { dateToIso } from '@sneat/core';\nimport { CalendariumSpaceService } from '../services/calendarium-space.service';\nimport {\n CalendarHappeningBriefsBySpaceID,\n ISlotUIContext,\n WeekdayCode2,\n} from '@sneat/mod-schedulus-core';\nimport { IErrorLogger } from '@sneat/core';\nimport { ISpaceContext } from '@sneat/space-models';\nimport { EMPTY, Observable, Subject } from 'rxjs';\nimport { CalendarDay, ICalendarDayInput } from './calendar-day';\nimport { CalendarSpace } from './calendar-space';\nimport {\n emptyRecurringsByWeekday,\n RecurringsByWeekday,\n} from './calendar-types';\nimport { HappeningService } from './happening.service';\nimport { CalendarDayService } from './calendar-day.service';\n\n// export function happeningDtoToSlot(id: string, dto: ISingleHappeningDto): ISlotItem {\n// \tif (!dto.title) {\n// \t\tthrow new Error('!singleHappening.title');\n// \t}\n// \tif (!dto.dtStarts) {\n// \t\tthrow new Error('!singleHappening.dtStarts');\n// \t}\n// \tconst brief = happeningBriefFromDto(id, dto);\n// \tconst happening: IHappeningContext = { id, brief, dto };\n// \t// const wd = jsDayToWeekday(date.getDay());\n// \t// noinspection UnnecessaryLocalVariableJS\n// \tconst slot: ISlotItem = {\n// \t\thappening,\n// \t\ttitle: dto.title,\n// \t\trepeats: 'once',\n// \t\ttiming: {\n// \t\t\tstart: {\n// \t\t\t\ttime: timeToStr(dto.dtStarts) || '',\n// \t\t\t},\n// \t\t\tend: dto.dtEnds ? {\n// \t\t\t\ttime: timeToStr(dto.dtEnds),\n// \t\t\t} : undefined,\n// \t\t},\n// \t\t// weekdays: singleHappening.weekdays,\n// \t\tparticipants: dto.participants,\n// \t\t// location: singleActivity.location ? singleActivity.location : undefined,\n// \t\tlevels: dto.levels ? dto.levels : undefined,\n// \t};\n// \treturn slot;\n// }\n\n// export abstract class ISlotsProvider {\n// \t// public abstract setTeamId(communeId: string): Observable<DtoRegularActivity[]>;\n//\n// \tpublic abstract setMemberId(memberId: string): void;\n//\n// \tpublic abstract preloadEvents(...dates: Date[]): Observable<SlotsGroup>;\n//\n// \tpublic abstract getDays(...weekdays: SlotsGroup[]): Observable<SlotsGroup>;\n//\n// \t// public abstract loadTodayAndFutureEvents(): Observable<DtoSingleActivity[]>;\n// }\n\nexport class CalendarDataProvider {\n /*implements OnDestroy - this is not a component, do not implement ngOnDestroy(), instead call destroy() */\n /*extends ISlotsProvider*/\n // At the moment tracks schedule of a single team\n // but probably will track multiple teams at once.\n\n private readonly destroyed = new Subject<void>();\n\n // private readonly recurringsSpaceItemService?: ModuleSpaceItemService<\n // \tIHappeningBrief,\n // \tIHappeningDbo\n // >;\n // private readonly singlesByDate: Record<string, ISlotUIContext[]> = {};\n\n private readonly $space = signal<ISpaceContext | undefined>(undefined);\n\n private readonly days: Record<string, CalendarDay> = {};\n\n // private contactID?: string; // TODO: should be {readonly spaceID: string; readonly contactID: string}\n // public setContactId(contactID: string): void {\n // \tthis.contactID = contactID;\n // }\n\n constructor(\n private readonly injector: Injector,\n private readonly $primarySpaceID: Signal<string | undefined>,\n private readonly errorLogger: IErrorLogger,\n private readonly happeningService: HappeningService,\n private readonly calendarDayService: CalendarDayService,\n private readonly calendariumSpaceService: CalendariumSpaceService,\n // sneatApiService: SneatApiService,\n // private readonly regularService: IRegularHappeningService,\n // private readonly singleService: ISingleHappeningService,\n ) {\n // console.log('SpaceDaysProvider.constructor()');\n // this.recurringsSpaceItemService = new ModuleSpaceItemService(\n // \t'calendarium',\n // \t'recurring_happenings', // TODO: Is this obsolete? Should we use 'happenings' instead?\n // \tcalendarDayService.afs,\n // \tundefined as SneatApiService,\n // );\n }\n\n private primarySpace?: CalendarSpace;\n\n private $primarySpace = computed<CalendarSpace | undefined>(() => {\n const newSpaceID = this.$primarySpaceID();\n if (this.primarySpace?.spaceID === newSpaceID) {\n return this.primarySpace;\n }\n this.primarySpace?.destroy();\n if (this.primarySpace?.spaceID == newSpaceID) {\n return this.primarySpace;\n }\n this.primarySpace = newSpaceID\n ? new CalendarSpace(newSpaceID, this.calendariumSpaceService)\n : undefined;\n return this.primarySpace;\n });\n\n private $spaces = computed<readonly CalendarSpace[]>(() => {\n const primarySpace = this.$primarySpace();\n return primarySpace ? [primarySpace] : [];\n });\n\n public readonly $recurringByWd = computed<Readonly<RecurringsByWeekday>>(\n () => {\n const recurringsByWd: RecurringsByWeekday = emptyRecurringsByWeekday();\n const spaces = this.$spaces();\n spaces.forEach((space) => {\n const spaceRecurringsByWd = space.$recurringByWd();\n Object.entries(spaceRecurringsByWd).forEach(([wd, slots]) => {\n recurringsByWd[wd as WeekdayCode2] = [\n ...recurringsByWd[wd as WeekdayCode2].filter(\n (slot) => slot.happening.space.id !== space.spaceID,\n ),\n ...slots,\n ];\n });\n });\n return recurringsByWd;\n },\n );\n\n public readonly $recurringsBySpaceID = computed<\n Readonly<CalendarHappeningBriefsBySpaceID>\n >(() => {\n const spaces = this.$spaces();\n const result: CalendarHappeningBriefsBySpaceID = {};\n spaces.forEach((space) => {\n result[space.spaceID] = space.$recurrings()?.recurringHappenings || {};\n });\n // console.log('$recurringsBySpaceID():', result);\n return result;\n });\n\n public destroy(): void {\n this.destroyed.next();\n Object.values(this.days).forEach((day) => {\n day.destroy();\n });\n this.$spaces().forEach((space) => space.destroy());\n }\n\n private readonly $inputs = computed<readonly ICalendarDayInput[]>(() =>\n this.$spaces().map(\n (space): ICalendarDayInput => ({\n spaceID: space.spaceID,\n $recurringSlots: space.$recurringSlots.asReadonly(),\n recurringSlots$: space.recurringSlots$,\n }),\n ),\n );\n\n public getCalendarDay(date: Date): CalendarDay {\n const id = dateToIso(date);\n let day = this.days[id];\n if (!day) {\n day = new CalendarDay(\n date,\n this.injector,\n this.$inputs,\n this.errorLogger,\n this.happeningService,\n this.calendarDayService,\n );\n this.days[id] = day;\n }\n return day;\n }\n\n public preloadEvents(...dates: Date[]): Observable<CalendarDay> {\n console.warn('not implemented: Preload events for:', dates);\n return EMPTY;\n // const dateKeys = dates.filter(d => !!d)\n // \t.map(localDateToIso)\n // \t.filter(dateKey => !this.singlesByDate[dateKey]);\n // if (!dateKeys.length) {\n // \treturn EMPTY;\n // }\n // return this.loadEvents(...dates)\n // \t.pipe(ignoreElements());\n }\n\n public getDays(): Observable<CalendarDay> {\n // console.log('SpaceDaysProvider.getDays()', weekdays);\n return EMPTY;\n // if (!weekdays?.length) {\n // \treturn EMPTY;\n // }\n // if (!this.team) {\n // \treturn from(weekdays);\n // }\n // const weekdaysByDateKey: { [date: string]: Day } = {};\n //\n // const weekdaysToLoad: Day[] = [];\n // const weekdaysLoaded: Day[] = [];\n //\n // weekdays.forEach(weekday => {\n // \tif (!weekday.date) {\n // \t\tthrow new Error('!weekday.date');\n // \t}\n // \tconst dateKey = localDateToIso(weekday.date);\n // \tweekdaysByDateKey[dateKey] = weekday;\n // \tthis.addRecurringsToSlotsGroup(weekday);\n // \tconst dateSingleSlots = this.singlesByDate[dateKey];\n // \tif (dateSingleSlots) {\n // \t\tif (weekday.slots) {\n // \t\t\tweekday = { ...weekday, slots: weekday.slots.filter(slot => !slot.single) };\n // \t\t}\n // \t\tif (!weekday.slots) {\n // \t\t\tweekday = { ...weekday, slots: [] };\n // \t\t}\n // \t\tdateSingleSlots.forEach(slot => weekday.slots && weekday.slots.push(slot));\n // \t\tweekdaysLoaded.push(weekday);\n // \t} else {\n // \t\tweekdaysToLoad.push(weekday);\n // \t}\n // });\n //\n // if (weekdaysToLoad.length === 0) {\n // \treturn from(weekdaysLoaded);\n // }\n //\n // const dates: Date[] = weekdaysToLoad\n // \t.map(weekday => weekday.date)\n // \t.filter(date => !!date) as Date[];\n //\n // const loadWeekdays$ = this.loadEvents(...dates)\n // \t.pipe(\n // \t\tmap(eventSlotsByDate => {\n // \t\t\tlet weekday = weekdaysByDateKey[eventSlotsByDate.dateKey];\n // \t\t\tif (weekday.slots) {\n // \t\t\t\tweekday = { ...weekday, slots: weekday.slots.filter(slot => !slot.single) };\n // \t\t\t}\n // \t\t\teventSlotsByDate.events.forEach(slot => {\n // \t\t\t\tweekday.slots && weekday.slots.push(slot);\n // \t\t\t});\n // \t\t\treturn weekday;\n // \t\t}),\n // \t);\n //\n // return weekdaysLoaded ? merge(weekdaysLoaded, loadWeekdays$) : loadWeekdays$;\n }\n\n public loadForWeek(): void {\n // console.log('SpaceDaysProvider.loadForWeek()', d);\n }\n\n // private addEventsToSlotsGroup(weekday: SlotsGroup, date:)\n\n // public loadTodayAndFutureEvents(): Observable<DtoSingleActivity[]> {\n //\n // \treturn this.singleService.selectFutureEvents(this.teamId)\n // \t\t.pipe(\n // \t\t\tmap(selectResult => {\n // \t\t\t\tconst processedEventIds: string[] = [];\n //\n // \t\t\t\tselectResult.values.forEach(singleHappening => {\n // \t\t\t\t\tconst { id } = singleHappening;\n // \t\t\t\t\tif (!id) {\n // \t\t\t\t\t\tthrow new Error('!id');\n // \t\t\t\t\t}\n // \t\t\t\t\tif (processedEventIds.includes(id)) {\n // \t\t\t\t\t\treturn;\n // \t\t\t\t\t}\n // \t\t\t\t\tprocessedEventIds.push(id);\n // \t\t\t\t\tlet date = new Date(singleHappening.dtStarts);\n // \t\t\t\t\twhile (date.getTime() < singleHappening.dtEnds) {\n // \t\t\t\t\t\tconst dateKey = localDateToIso(date);\n // \t\t\t\t\t\tlet dateEvents = this.singlesByDate[dateKey];\n // \t\t\t\t\t\tif (!dateEvents) {\n // \t\t\t\t\t\t\tthis.singlesByDate[dateKey] = dateEvents = [];\n // \t\t\t\t\t\t}\n // \t\t\t\t\t\tdateEvents.push(eventToSlot(singleHappening));\n // \t\t\t\t\t\tdate = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);\n // \t\t\t\t\t}\n // \t\t\t\t});\n // \t\t\t\treturn selectResult.values;\n // \t\t\t}),\n // \t\t);\n // }\n\n private loadEvents(): Observable<{ dateKey: string; events: ISlotUIContext[] }> {\n // console.log('loadEvents()', dates);\n return EMPTY;\n // const dateISOs = dates.map(localDateToIso);\n //\n // const mapSelectResult = (selectResult: SelectResult<DtoSingleActivity>) => {\n // \tconst dateKey = selectResult.key;\n // \tif (!dateKey) {\n // \t\tthrow new Error('!dateKey');\n // \t}\n // \tthis.singlesByDate[dateKey] = selectResult.values.length ? selectResult.values.map(eventToSlot) : [];\n // \treturn { dateKey, events: this.singlesByDate[dateKey] };\n // };\n\n // return this.singleService.selectByDate(tx, this.communeId, ...dateISOs)\n // \t.pipe(\n // \t\tmap(selectResult => {\n // \t\t\tconsole.log(`Loaded events ${selectResult.key}: ${selectResult.values.length}`);\n // \t\t\treturn mapSelectResult(selectResult);\n // \t\t}),\n // \t);\n }\n}\n"]}
@@ -0,0 +1,179 @@
1
+ import { computed, effect, signal } from '@angular/core';
2
+ import { dateToIso } from '@sneat/core';
3
+ import { BehaviorSubject, shareReplay, Subject, takeUntil, } from 'rxjs';
4
+ import { getWd2, sortSlotItems, wdCodeToWeekdayLongName, } from '@sneat/mod-schedulus-core';
5
+ import { runInInjectionContext } from '@angular/core';
6
+ export class CalendarDay {
7
+ get spaces() {
8
+ return this._spaces;
9
+ }
10
+ get slots() {
11
+ return this._slots.value;
12
+ }
13
+ constructor(date, injector, $inputs, errorLogger,
14
+ // TODO: document why we need both HappeningService & CalendarDayService
15
+ happeningService, calendarDayService) {
16
+ this.date = date;
17
+ this.$inputs = $inputs;
18
+ this.errorLogger = errorLogger;
19
+ this.happeningService = happeningService;
20
+ this.calendarDayService = calendarDayService;
21
+ this.destroyed$ = new Subject();
22
+ // private recurringSlots?: RecurringSlots;
23
+ this.$recurringSlots = computed(() => {
24
+ const inputs = this.$inputs();
25
+ const recurringSlots = inputs
26
+ .map((input) => input.$recurringSlots())
27
+ .filter((v) => !!v);
28
+ const result = recurringSlots.length ? recurringSlots[0] : undefined; // TODO: add support for multiple inputs
29
+ return result;
30
+ }, ...(ngDevMode ? [{ debugName: "$recurringSlots" }] : []));
31
+ this._spaces = [];
32
+ this._isLoading = signal(true, ...(ngDevMode ? [{ debugName: "_isLoading" }] : []));
33
+ this.$isLoading = this._isLoading.asReadonly();
34
+ // private readonly $slots = signal<ISlotUIContext[] | undefined>(undefined);
35
+ this._slots = new BehaviorSubject(undefined);
36
+ this.slots$ = this._slots.asObservable().pipe(shareReplay(1), takeUntil(this.destroyed$));
37
+ this.subscriptions = [];
38
+ this.processSpaceID = (spaceID) => {
39
+ this.singles = undefined;
40
+ if (spaceID) {
41
+ this.subscribeForSingles(spaceID);
42
+ this.subscribeForCalendarDay(spaceID);
43
+ }
44
+ };
45
+ this.subscribeForCalendarDay = (spaceID) => {
46
+ this.subscriptions.push(this.calendarDayService
47
+ .watchSpaceDay({ id: spaceID }, this.dateID)
48
+ .pipe(takeUntil(this.destroyed$))
49
+ .subscribe({
50
+ next: (calendarDay) => {
51
+ const changed = this.calendarDayDbo != calendarDay.dbo;
52
+ if (changed) {
53
+ this.calendarDayDbo = calendarDay.dbo;
54
+ this.joinRecurringsWithSinglesAndEmit();
55
+ }
56
+ },
57
+ error: this.errorLogger.logErrorHandler('Failed to load calendarDay record', { show: false, feedback: false }),
58
+ }));
59
+ };
60
+ this.subscribeForSingles = (spaceID) => {
61
+ if (!this.dateID) {
62
+ console.error('Tried to subscribe for single happenings without dateID');
63
+ return;
64
+ }
65
+ try {
66
+ this.subscriptions.push(this.happeningService
67
+ .watchSinglesOnSpecificDay({ id: spaceID }, this.dateID)
68
+ .pipe(takeUntil(this.destroyed$))
69
+ .subscribe({
70
+ next: this.processSingles,
71
+ error: this.errorLogger.logErrorHandler(`Failed to get single happenings for a given day: spaceID=${spaceID}, date=${this.dateID}`),
72
+ }));
73
+ }
74
+ catch (e) {
75
+ this.errorLogger.logError(e, 'Failed to subscribe for team day single happenings');
76
+ }
77
+ };
78
+ this.processSingles = (singleHappenings) => {
79
+ try {
80
+ this.singles = [];
81
+ singleHappenings.forEach((happening) => {
82
+ const slotIDs = Object.keys(happening.dbo?.slots || {});
83
+ const slot = slotIDs?.length && happening.dbo?.slots?.[slotIDs[0]];
84
+ if (!slot) {
85
+ return;
86
+ }
87
+ const timing = {
88
+ start: slot.start,
89
+ end: slot.end,
90
+ durationMinutes: slot.durationMinutes,
91
+ };
92
+ const slotItem = {
93
+ slot: { ...slot, id: slotIDs[0] },
94
+ title: happening.brief?.title || happening?.dbo?.title || 'NO TITLE',
95
+ timing,
96
+ repeats: 'once',
97
+ happening,
98
+ };
99
+ this.singles?.push(slotItem);
100
+ });
101
+ // console.log('SpaceDay[${this.isoID}].processSingles()`, changes, this.singles);
102
+ this.joinRecurringsWithSinglesAndEmit();
103
+ }
104
+ catch (e) {
105
+ this.errorLogger.logError(e, 'failed to process single happenings');
106
+ }
107
+ };
108
+ this.processRecurrings = () => {
109
+ // this.recurringSlots = slots;
110
+ this.joinRecurringsWithSinglesAndEmit();
111
+ };
112
+ if (!date) {
113
+ throw new Error('missing required parameter: date');
114
+ }
115
+ this.dateID = dateToIso(date);
116
+ if (this.dateID === '1970-01-01') {
117
+ throw new Error('an attempt to set an empty date 1970-01-01');
118
+ }
119
+ this.wd = getWd2(date);
120
+ this.wdLongTitle = wdCodeToWeekdayLongName(this.wd);
121
+ runInInjectionContext(injector, () => {
122
+ this.effectRef = effect(() => {
123
+ const inputs = $inputs();
124
+ inputs.forEach((input) => {
125
+ this.subscriptions.forEach((s) => s.unsubscribe());
126
+ this.subscriptions.length = 0;
127
+ this.processSpaceID(input.spaceID);
128
+ this.subscribeForRecurrings(input.recurringSlots$);
129
+ });
130
+ }, ...(ngDevMode ? [{ debugName: "effectRef" }] : []));
131
+ });
132
+ }
133
+ destroy() {
134
+ this.effectRef?.destroy();
135
+ this.destroyed$.next();
136
+ this.destroyed$.complete();
137
+ }
138
+ subscribeForRecurrings(recurrings$) {
139
+ this.subscriptions.push(recurrings$.pipe(takeUntil(this.destroyed$)).subscribe({
140
+ next: this.processRecurrings,
141
+ }));
142
+ }
143
+ joinRecurringsWithSinglesAndEmit() {
144
+ let slots = [];
145
+ const recurringSlots = this.$recurringSlots();
146
+ const weekdaySlots = recurringSlots?.byWeekday[this.wd]?.map((wdSlot) => {
147
+ // console.log(
148
+ // 'joinRecurringsWithSinglesAndEmit, wdSlot',
149
+ // this.wd,
150
+ // wdSlot,
151
+ // this.scheduleDayDto,
152
+ // );
153
+ if (this.calendarDayDbo) {
154
+ const adjustment = this.calendarDayDbo?.happeningAdjustments?.[wdSlot.happening.id]
155
+ ?.slots?.[wdSlot.slot.id];
156
+ if (adjustment) {
157
+ return Object.assign(wdSlot, { adjustment });
158
+ }
159
+ }
160
+ return wdSlot;
161
+ });
162
+ if (weekdaySlots?.length) {
163
+ slots.push(...weekdaySlots);
164
+ }
165
+ if (this.singles) {
166
+ slots.push(...this.singles);
167
+ }
168
+ // console.log(
169
+ // 'SpaceDay[id=${this.isoID}, wd=${this.wd}].joinRecurringsWithSinglesAndEmit()`,
170
+ // `${weekdaySlots?.length || 0} recurrings:`, weekdaySlots,
171
+ // `${this.singles?.length || 0} singles:`, weekdaySlots,
172
+ // `=> ${slots.length} slots:`, slots);
173
+ slots = slots.toSorted(sortSlotItems);
174
+ this._slots.next(slots);
175
+ // this.$slots.set(slots);
176
+ this._isLoading.set(false);
177
+ }
178
+ }
179
+ //# sourceMappingURL=calendar-day.js.map