@acorex/modules 20.6.2 → 20.6.4

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 (94) hide show
  1. package/fesm2022/{acorex-modules-auth-acorex-modules-auth-CAGlVzjD.mjs → acorex-modules-auth-acorex-modules-auth-D2RpP22p.mjs} +10 -10
  2. package/fesm2022/{acorex-modules-auth-acorex-modules-auth-CAGlVzjD.mjs.map → acorex-modules-auth-acorex-modules-auth-D2RpP22p.mjs.map} +1 -1
  3. package/fesm2022/{acorex-modules-auth-app-chooser.component-BAoN8dn6.mjs → acorex-modules-auth-app-chooser.component-BI3wED24.mjs} +2 -2
  4. package/fesm2022/{acorex-modules-auth-app-chooser.component-BAoN8dn6.mjs.map → acorex-modules-auth-app-chooser.component-BI3wED24.mjs.map} +1 -1
  5. package/fesm2022/{acorex-modules-auth-login.module-CToi7k63.mjs → acorex-modules-auth-login.module-CceKXOOB.mjs} +4 -4
  6. package/fesm2022/{acorex-modules-auth-login.module-CToi7k63.mjs.map → acorex-modules-auth-login.module-CceKXOOB.mjs.map} +1 -1
  7. package/fesm2022/{acorex-modules-auth-master.layout-YZfKfaoC.mjs → acorex-modules-auth-master.layout-knGLhLSY.mjs} +2 -2
  8. package/fesm2022/{acorex-modules-auth-master.layout-YZfKfaoC.mjs.map → acorex-modules-auth-master.layout-knGLhLSY.mjs.map} +1 -1
  9. package/fesm2022/{acorex-modules-auth-oauth-callback.component-CKQh5Mpa.mjs → acorex-modules-auth-oauth-callback.component-BmxjkoNA.mjs} +2 -2
  10. package/fesm2022/{acorex-modules-auth-oauth-callback.component-CKQh5Mpa.mjs.map → acorex-modules-auth-oauth-callback.component-BmxjkoNA.mjs.map} +1 -1
  11. package/fesm2022/acorex-modules-auth-password.component-BMLK4drm.mjs +563 -0
  12. package/fesm2022/acorex-modules-auth-password.component-BMLK4drm.mjs.map +1 -0
  13. package/fesm2022/{acorex-modules-auth-password.component-Jskc80kr.mjs → acorex-modules-auth-password.component-BhPfqSA_.mjs} +6 -6
  14. package/fesm2022/{acorex-modules-auth-password.component-Jskc80kr.mjs.map → acorex-modules-auth-password.component-BhPfqSA_.mjs.map} +1 -1
  15. package/fesm2022/{acorex-modules-auth-routes-BOofdLjr.mjs → acorex-modules-auth-routes-BtenIM-p.mjs} +2 -2
  16. package/fesm2022/{acorex-modules-auth-routes-BOofdLjr.mjs.map → acorex-modules-auth-routes-BtenIM-p.mjs.map} +1 -1
  17. package/fesm2022/{acorex-modules-auth-two-factor-code.component-BmlUjtYC.mjs → acorex-modules-auth-two-factor-code.component-Bk0jHCv_.mjs} +3 -3
  18. package/fesm2022/{acorex-modules-auth-two-factor-code.component-BmlUjtYC.mjs.map → acorex-modules-auth-two-factor-code.component-Bk0jHCv_.mjs.map} +1 -1
  19. package/fesm2022/{acorex-modules-auth-two-factor.module-Bc39IBha.mjs → acorex-modules-auth-two-factor.module-BUSxDCwt.mjs} +3 -3
  20. package/fesm2022/{acorex-modules-auth-two-factor.module-Bc39IBha.mjs.map → acorex-modules-auth-two-factor.module-BUSxDCwt.mjs.map} +1 -1
  21. package/fesm2022/{acorex-modules-auth-user-sessions.component-BBX97AST.mjs → acorex-modules-auth-user-sessions.component-CbMB_YWS.mjs} +2 -2
  22. package/fesm2022/{acorex-modules-auth-user-sessions.component-BBX97AST.mjs.map → acorex-modules-auth-user-sessions.component-CbMB_YWS.mjs.map} +1 -1
  23. package/fesm2022/acorex-modules-auth.mjs +1 -1
  24. package/fesm2022/{acorex-modules-document-management-acorex-modules-document-management-Cd7_tQ9I.mjs → acorex-modules-document-management-acorex-modules-document-management-Ch5hpPL2.mjs} +17 -17
  25. package/fesm2022/{acorex-modules-document-management-acorex-modules-document-management-Cd7_tQ9I.mjs.map → acorex-modules-document-management-acorex-modules-document-management-Ch5hpPL2.mjs.map} +1 -1
  26. package/fesm2022/{acorex-modules-document-management-attachment-widget.component-OOvQKX6g.mjs → acorex-modules-document-management-attachment-widget.component-DVSY3f9D.mjs} +2 -2
  27. package/fesm2022/{acorex-modules-document-management-attachment-widget.component-OOvQKX6g.mjs.map → acorex-modules-document-management-attachment-widget.component-DVSY3f9D.mjs.map} +1 -1
  28. package/fesm2022/{acorex-modules-document-management-details-view.component-BhqjkUbV.mjs → acorex-modules-document-management-details-view.component-B3qmcEdP.mjs} +2 -2
  29. package/fesm2022/{acorex-modules-document-management-details-view.component-BhqjkUbV.mjs.map → acorex-modules-document-management-details-view.component-B3qmcEdP.mjs.map} +1 -1
  30. package/fesm2022/{acorex-modules-document-management-document-signature-popup.component-DGWY6fSe.mjs → acorex-modules-document-management-document-signature-popup.component-DPQjvgPk.mjs} +2 -2
  31. package/fesm2022/{acorex-modules-document-management-document-signature-popup.component-DGWY6fSe.mjs.map → acorex-modules-document-management-document-signature-popup.component-DPQjvgPk.mjs.map} +1 -1
  32. package/fesm2022/{acorex-modules-document-management-drive-choose.component-WxmS0fOY.mjs → acorex-modules-document-management-drive-choose.component-D7P_HBZp.mjs} +2 -2
  33. package/fesm2022/{acorex-modules-document-management-drive-choose.component-WxmS0fOY.mjs.map → acorex-modules-document-management-drive-choose.component-D7P_HBZp.mjs.map} +1 -1
  34. package/fesm2022/{acorex-modules-document-management-drive.component-D8VzFK-5.mjs → acorex-modules-document-management-drive.component-SbeKAOPx.mjs} +2 -2
  35. package/fesm2022/{acorex-modules-document-management-drive.component-D8VzFK-5.mjs.map → acorex-modules-document-management-drive.component-SbeKAOPx.mjs.map} +1 -1
  36. package/fesm2022/{acorex-modules-document-management-large-icons-view.component-cYzLaOAQ.mjs → acorex-modules-document-management-large-icons-view.component-DAa8gWsg.mjs} +2 -2
  37. package/fesm2022/{acorex-modules-document-management-large-icons-view.component-cYzLaOAQ.mjs.map → acorex-modules-document-management-large-icons-view.component-DAa8gWsg.mjs.map} +1 -1
  38. package/fesm2022/{acorex-modules-document-management-large-tiles-view.component-BkcKvoe6.mjs → acorex-modules-document-management-large-tiles-view.component-CkA-fVcG.mjs} +2 -2
  39. package/fesm2022/{acorex-modules-document-management-large-tiles-view.component-BkcKvoe6.mjs.map → acorex-modules-document-management-large-tiles-view.component-CkA-fVcG.mjs.map} +1 -1
  40. package/fesm2022/{acorex-modules-document-management-list-view.component-CvPkInJy.mjs → acorex-modules-document-management-list-view.component-C4M3rY1_.mjs} +2 -2
  41. package/fesm2022/{acorex-modules-document-management-list-view.component-CvPkInJy.mjs.map → acorex-modules-document-management-list-view.component-C4M3rY1_.mjs.map} +1 -1
  42. package/fesm2022/{acorex-modules-document-management-permission-definition.provider-CODjZ6lP.mjs → acorex-modules-document-management-permission-definition.provider-C2IsTOYZ.mjs} +2 -2
  43. package/fesm2022/{acorex-modules-document-management-permission-definition.provider-CODjZ6lP.mjs.map → acorex-modules-document-management-permission-definition.provider-C2IsTOYZ.mjs.map} +1 -1
  44. package/fesm2022/{acorex-modules-document-management-small-icons-view.component-C30ghzKp.mjs → acorex-modules-document-management-small-icons-view.component-YgCRykmN.mjs} +2 -2
  45. package/fesm2022/{acorex-modules-document-management-small-icons-view.component-C30ghzKp.mjs.map → acorex-modules-document-management-small-icons-view.component-YgCRykmN.mjs.map} +1 -1
  46. package/fesm2022/{acorex-modules-document-management-small-tiles-view.component-DyLRmcJH.mjs → acorex-modules-document-management-small-tiles-view.component-0EDyw6SN.mjs} +2 -2
  47. package/fesm2022/{acorex-modules-document-management-small-tiles-view.component-DyLRmcJH.mjs.map → acorex-modules-document-management-small-tiles-view.component-0EDyw6SN.mjs.map} +1 -1
  48. package/fesm2022/acorex-modules-document-management.mjs +1 -1
  49. package/fesm2022/{acorex-modules-human-capital-management-acorex-modules-human-capital-management-crtjPRx2.mjs → acorex-modules-human-capital-management-acorex-modules-human-capital-management-oM_wM_T4.mjs} +17 -13
  50. package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-oM_wM_T4.mjs.map +1 -0
  51. package/fesm2022/{acorex-modules-human-capital-management-employee-skill.entity-B_gM9TMj.mjs → acorex-modules-human-capital-management-employee-skill.entity-BQzOwp3F.mjs} +2 -2
  52. package/fesm2022/{acorex-modules-human-capital-management-employee-skill.entity-B_gM9TMj.mjs.map → acorex-modules-human-capital-management-employee-skill.entity-BQzOwp3F.mjs.map} +1 -1
  53. package/fesm2022/{acorex-modules-human-capital-management-employee.entity-B6ndmf52.mjs → acorex-modules-human-capital-management-employee.entity-jBLPkWAr.mjs} +2 -2
  54. package/fesm2022/{acorex-modules-human-capital-management-employee.entity-B6ndmf52.mjs.map → acorex-modules-human-capital-management-employee.entity-jBLPkWAr.mjs.map} +1 -1
  55. package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-BJVwmQEY.mjs → acorex-modules-human-capital-management-employment-type.entity-D0R779WE.mjs} +2 -2
  56. package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-BJVwmQEY.mjs.map → acorex-modules-human-capital-management-employment-type.entity-D0R779WE.mjs.map} +1 -1
  57. package/fesm2022/acorex-modules-human-capital-management-leave-request-task-popover.component-c8fOqg4h.mjs +381 -0
  58. package/fesm2022/acorex-modules-human-capital-management-leave-request-task-popover.component-c8fOqg4h.mjs.map +1 -0
  59. package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-BA95ET48.mjs → acorex-modules-human-capital-management-leave-request.entity-DleoTbfj.mjs} +2 -2
  60. package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-BA95ET48.mjs.map → acorex-modules-human-capital-management-leave-request.entity-DleoTbfj.mjs.map} +1 -1
  61. package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-CJOejYZs.mjs → acorex-modules-human-capital-management-leave-type.entity-A8z8ra48.mjs} +2 -2
  62. package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-CJOejYZs.mjs.map → acorex-modules-human-capital-management-leave-type.entity-A8z8ra48.mjs.map} +1 -1
  63. package/fesm2022/{acorex-modules-human-capital-management-permission-definition.provider-CwVtMZMg.mjs → acorex-modules-human-capital-management-permission-definition.provider-S2AqzNxa.mjs} +2 -2
  64. package/fesm2022/{acorex-modules-human-capital-management-permission-definition.provider-CwVtMZMg.mjs.map → acorex-modules-human-capital-management-permission-definition.provider-S2AqzNxa.mjs.map} +1 -1
  65. package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-Yk21sgeU.mjs → acorex-modules-human-capital-management-position-assignment.entity-1U5PtuXv.mjs} +2 -2
  66. package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-Yk21sgeU.mjs.map → acorex-modules-human-capital-management-position-assignment.entity-1U5PtuXv.mjs.map} +1 -1
  67. package/fesm2022/{acorex-modules-human-capital-management-skill-level.entity-BX_Vc6L1.mjs → acorex-modules-human-capital-management-skill-level.entity-gnimpGin.mjs} +2 -2
  68. package/fesm2022/{acorex-modules-human-capital-management-skill-level.entity-BX_Vc6L1.mjs.map → acorex-modules-human-capital-management-skill-level.entity-gnimpGin.mjs.map} +1 -1
  69. package/fesm2022/{acorex-modules-human-capital-management-skill.entity-BIo0x54G.mjs → acorex-modules-human-capital-management-skill.entity-DImoZtMI.mjs} +2 -2
  70. package/fesm2022/{acorex-modules-human-capital-management-skill.entity-BIo0x54G.mjs.map → acorex-modules-human-capital-management-skill.entity-DImoZtMI.mjs.map} +1 -1
  71. package/fesm2022/acorex-modules-human-capital-management.mjs +1 -1
  72. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-BBHPVHzg.mjs → acorex-modules-platform-management-acorex-modules-platform-management-C9jPTG5T.mjs} +5 -5
  73. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-BBHPVHzg.mjs.map → acorex-modules-platform-management-acorex-modules-platform-management-C9jPTG5T.mjs.map} +1 -1
  74. package/fesm2022/{acorex-modules-platform-management-list-version.component-n5JOzU2Y.mjs → acorex-modules-platform-management-list-version.component-B8pyACIN.mjs} +2 -2
  75. package/fesm2022/{acorex-modules-platform-management-list-version.component-n5JOzU2Y.mjs.map → acorex-modules-platform-management-list-version.component-B8pyACIN.mjs.map} +1 -1
  76. package/fesm2022/{acorex-modules-platform-management-menu-list.component-CDLDkiW8.mjs → acorex-modules-platform-management-menu-list.component-jIE8GBmg.mjs} +3 -3
  77. package/fesm2022/acorex-modules-platform-management-menu-list.component-jIE8GBmg.mjs.map +1 -0
  78. package/fesm2022/{acorex-modules-platform-management-permission-definition.provider-Cc8ZV1K1.mjs → acorex-modules-platform-management-permission-definition.provider-9chqQLDF.mjs} +2 -2
  79. package/fesm2022/{acorex-modules-platform-management-permission-definition.provider-Cc8ZV1K1.mjs.map → acorex-modules-platform-management-permission-definition.provider-9chqQLDF.mjs.map} +1 -1
  80. package/fesm2022/acorex-modules-platform-management.mjs +1 -1
  81. package/fesm2022/acorex-modules-project-management.mjs +2 -0
  82. package/fesm2022/acorex-modules-project-management.mjs.map +1 -1
  83. package/fesm2022/{acorex-modules-task-management-task-board.page-BVf2enGZ.mjs → acorex-modules-task-management-task-board.page-CtXx8vc6.mjs} +524 -64
  84. package/fesm2022/acorex-modules-task-management-task-board.page-CtXx8vc6.mjs.map +1 -0
  85. package/fesm2022/acorex-modules-task-management.mjs +35 -4
  86. package/fesm2022/acorex-modules-task-management.mjs.map +1 -1
  87. package/human-capital-management/index.d.ts +3 -1
  88. package/package.json +2 -2
  89. package/task-management/index.d.ts +28 -4
  90. package/fesm2022/acorex-modules-auth-password.component-Dqb6GBes.mjs +0 -226
  91. package/fesm2022/acorex-modules-auth-password.component-Dqb6GBes.mjs.map +0 -1
  92. package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-crtjPRx2.mjs.map +0 -1
  93. package/fesm2022/acorex-modules-platform-management-menu-list.component-CDLDkiW8.mjs.map +0 -1
  94. package/fesm2022/acorex-modules-task-management-task-board.page-BVf2enGZ.mjs.map +0 -1
@@ -1,25 +1,35 @@
1
+ import * as i9 from '@acorex/cdk/accordion';
2
+ import { AXAccordionCdkModule } from '@acorex/cdk/accordion';
3
+ import { AXAccordionModule } from '@acorex/components/accordion';
4
+ import * as i8 from '@acorex/components/badge';
1
5
  import { AXBadgeModule } from '@acorex/components/badge';
2
6
  import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
3
7
  import * as i3 from '@acorex/components/button';
4
8
  import { AXButtonComponent, AXButtonModule } from '@acorex/components/button';
5
9
  import { AXCalendarComponent } from '@acorex/components/calendar';
10
+ import { AXCheckBoxModule } from '@acorex/components/check-box';
6
11
  import * as i5 from '@acorex/components/decorators';
7
12
  import { AXDecoratorIconComponent, AXDecoratorModule } from '@acorex/components/decorators';
8
- import { AXDropdownPanelComponent } from '@acorex/components/dropdown';
13
+ import * as i4 from '@acorex/components/dropdown';
14
+ import { AXDropdownModule, AXDropdownPanelComponent } from '@acorex/components/dropdown';
9
15
  import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
10
- import * as i6 from '@acorex/components/loading';
16
+ import { AXFormFieldComponent, AXFormComponent, AXFormModule } from '@acorex/components/form';
17
+ import { AXLabelComponent, AXLabelModule } from '@acorex/components/label';
18
+ import * as i7 from '@acorex/components/loading';
11
19
  import { AXLoadingModule } from '@acorex/components/loading';
12
- import * as i2 from '@acorex/components/menu';
20
+ import * as i3$1 from '@acorex/components/menu';
13
21
  import { AXMenuModule } from '@acorex/components/menu';
14
- import * as i7 from '@acorex/components/popover';
22
+ import * as i2 from '@acorex/components/popover';
15
23
  import { AXPopoverModule } from '@acorex/components/popover';
24
+ import * as i10 from '@acorex/components/selection-list';
25
+ import { AXSelectionListModule } from '@acorex/components/selection-list';
16
26
  import { AXCalendarService } from '@acorex/core/date-time';
17
27
  import { AXLocaleService } from '@acorex/core/locale';
18
- import * as i2$1 from '@acorex/core/translation';
28
+ import * as i5$1 from '@acorex/core/translation';
19
29
  import { AXTranslatorPipe, AXTranslationModule } from '@acorex/core/translation';
20
30
  import { AXUnsubscriber } from '@acorex/core/utils';
21
31
  import { AXPPlatformScope, AXPDeviceService } from '@acorex/platform/core';
22
- import { AXPStateMessageComponent, AXPThemeLayoutBlockComponent } from '@acorex/platform/layout/components';
32
+ import { AXPStateMessageComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutHeaderComponent } from '@acorex/platform/layout/components';
23
33
  import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
24
34
  import * as i1$1 from '@angular/common';
25
35
  import { AsyncPipe, CommonModule } from '@angular/common';
@@ -35,10 +45,9 @@ import * as i1 from '@acorex/platform/layout/widget-core';
35
45
  import { AXPWidgetCoreModule, AXPWidgetsCatalog } from '@acorex/platform/layout/widget-core';
36
46
  import { AXPSettingService } from '@acorex/platform/common';
37
47
  import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
38
- import { AXFormFieldComponent, AXFormComponent } from '@acorex/components/form';
39
- import { AXLabelComponent } from '@acorex/components/label';
40
48
  import { isEqual, sortBy } from 'lodash-es';
41
49
  import { AXSchedulerComponent } from '@acorex/components/scheduler';
50
+ import { AXPCommandService } from '@acorex/platform/runtime';
42
51
  import { AXDataSource } from '@acorex/cdk/common';
43
52
  import * as i1$2 from '@acorex/components/data-table';
44
53
  import { AXDataTableModule } from '@acorex/components/data-table';
@@ -54,6 +63,7 @@ var AXMTaskBoardSettings;
54
63
  AXMTaskBoardSettings["SelectedAssigneeIds"] = "taskboard.filter.selectedAssigneeIds";
55
64
  AXMTaskBoardSettings["SelectedReporterIds"] = "taskboard.filter.selectedReporterIds";
56
65
  AXMTaskBoardSettings["SelectedTaskTypeNames"] = "taskboard.filter.selectedTaskTypeNames";
66
+ AXMTaskBoardSettings["SelectedCalendarEventTypeIds"] = "taskboard.filter.selectedCalendarEventTypeIds";
57
67
  })(AXMTaskBoardSettings || (AXMTaskBoardSettings = {}));
58
68
 
59
69
  const AXMTaskBoardViewModel = signalStore({ providedIn: 'root' }, withState(() => ({
@@ -69,6 +79,7 @@ const AXMTaskBoardViewModel = signalStore({ providedIn: 'root' }, withState(() =
69
79
  selectedAssigneeIds: [],
70
80
  selectedPriorities: [],
71
81
  selectedReporterIds: [],
82
+ selectedCalendarEventTypeIds: [],
72
83
  })), withComputed((store) => ({
73
84
  selectedTaskTypes: computed(() => {
74
85
  const names = store.selectedTaskTypeNames();
@@ -110,7 +121,7 @@ const AXMTaskBoardViewModel = signalStore({ providedIn: 'root' }, withState(() =
110
121
  try {
111
122
  const taskTypes = await taskBoardService.getTaskTypes();
112
123
  patchState(store, { taskTypes });
113
- const [savedDaysCount, savedDateString, savedDetailPanel, savedViewMode, savedTaskTypeNames, savedAssigneeIds, savedReporterIds, savedPriorities,] = await Promise.all([
124
+ const [savedDaysCount, savedDateString, savedDetailPanel, savedViewMode, savedTaskTypeNames, savedAssigneeIds, savedReporterIds, savedPriorities, savedCalendarEventTypeIds,] = await Promise.all([
114
125
  userScopedSettings().get(AXMTaskBoardSettings.DaysCount),
115
126
  userScopedSettings().get(AXMTaskBoardSettings.CurrentDate),
116
127
  userScopedSettings().get(AXMTaskBoardSettings.DetailPanel),
@@ -119,16 +130,27 @@ const AXMTaskBoardViewModel = signalStore({ providedIn: 'root' }, withState(() =
119
130
  userScopedSettings().get(AXMTaskBoardSettings.SelectedAssigneeIds),
120
131
  userScopedSettings().get(AXMTaskBoardSettings.SelectedReporterIds),
121
132
  userScopedSettings().get(AXMTaskBoardSettings.SelectedPriorities),
133
+ userScopedSettings().get(AXMTaskBoardSettings.SelectedCalendarEventTypeIds),
122
134
  ]);
135
+ // Ensure currentDate is always a valid Date
136
+ let currentDate;
137
+ if (savedDateString) {
138
+ const parsedDate = new Date(savedDateString);
139
+ currentDate = isNaN(parsedDate.getTime()) ? new Date() : parsedDate;
140
+ }
141
+ else {
142
+ currentDate = new Date();
143
+ }
123
144
  patchState(store, {
124
145
  daysCount: savedDaysCount || 7,
125
146
  detailPanel: savedDetailPanel || false,
126
147
  currentViewMode: savedViewMode || 'month',
127
- currentDate: savedDateString ? new Date(savedDateString) : new Date(),
148
+ currentDate,
128
149
  selectedTaskTypeNames: savedTaskTypeNames || [],
129
150
  selectedAssigneeIds: savedAssigneeIds || [],
130
151
  selectedReporterIds: savedReporterIds || [],
131
152
  selectedPriorities: savedPriorities || [],
153
+ selectedCalendarEventTypeIds: savedCalendarEventTypeIds || [],
132
154
  isLoading: false,
133
155
  });
134
156
  }
@@ -142,6 +164,7 @@ const AXMTaskBoardViewModel = signalStore({ providedIn: 'root' }, withState(() =
142
164
  selectedAssigneeIds: [],
143
165
  selectedPriorities: [],
144
166
  selectedReporterIds: [],
167
+ selectedCalendarEventTypeIds: [],
145
168
  taskTypes: store.taskTypes(),
146
169
  isLoading: false,
147
170
  });
@@ -200,6 +223,14 @@ const AXMTaskBoardViewModel = signalStore({ providedIn: 'root' }, withState(() =
200
223
  .set(AXMTaskBoardSettings.SelectedPriorities, priorities)
201
224
  .catch((error) => console.error('Error saving selected priority filter:', error));
202
225
  },
226
+ setSelectedCalendarEventTypeIds(eventTypeIds, isQueryParam = false) {
227
+ patchState(store, { selectedCalendarEventTypeIds: eventTypeIds });
228
+ if (isQueryParam)
229
+ return;
230
+ userScopedSettings()
231
+ .set(AXMTaskBoardSettings.SelectedCalendarEventTypeIds, eventTypeIds)
232
+ .catch((error) => console.error('Error saving selected calendar event type filter:', error));
233
+ },
203
234
  /**
204
235
  * Sets the currently selected task. Pass `null` to clear the selection.
205
236
  * @param task The task to select, or null.
@@ -308,6 +339,7 @@ class AXMTaskBoardFiltersComponent {
308
339
  this.rootConfig = RootConfig;
309
340
  this.vm = inject(AXMTaskBoardViewModel);
310
341
  this.isQueryParam = input(false, ...(ngDevMode ? [{ debugName: "isQueryParam" }] : []));
342
+ this.excludeTaskType = input(false, ...(ngDevMode ? [{ debugName: "excludeTaskType" }] : []));
311
343
  this.applyClicked = output();
312
344
  this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
313
345
  this.isInitialized = false;
@@ -330,24 +362,27 @@ class AXMTaskBoardFiltersComponent {
330
362
  const viewMode = this.vm.currentViewMode();
331
363
  return viewMode !== 'kanban' && viewMode !== 'status-grouped-grid';
332
364
  }, ...(ngDevMode ? [{ debugName: "isMultiSelectEnabled" }] : []));
333
- this.nodes = computed(() => [
334
- {
335
- name: 'taskType',
336
- path: 'options.taskType',
337
- type: AXPWidgetsCatalog.select,
338
- options: {
339
- valueField: 'name',
340
- textField: 'title',
341
- dataSource: 'task-types',
342
- placeholder: 'Select Task Type',
343
- multiple: this.isMultiSelectEnabled(),
344
- allowClear: this.isMultiSelectEnabled(),
345
- },
346
- meta: {
347
- title: 'task-board.filter.task-type',
348
- },
349
- },
350
- {
365
+ this.nodes = computed(() => {
366
+ const allNodes = [];
367
+ if (!this.excludeTaskType()) {
368
+ allNodes.push({
369
+ name: 'taskType',
370
+ path: 'options.taskType',
371
+ type: AXPWidgetsCatalog.select,
372
+ options: {
373
+ valueField: 'name',
374
+ textField: 'title',
375
+ dataSource: 'task-types',
376
+ placeholder: 'Select Task Type',
377
+ multiple: this.isMultiSelectEnabled(),
378
+ allowClear: this.isMultiSelectEnabled(),
379
+ },
380
+ meta: {
381
+ title: 'task-board.filter.task-type',
382
+ },
383
+ });
384
+ }
385
+ allNodes.push({
351
386
  name: 'assignee',
352
387
  path: 'options.assignee',
353
388
  type: AXPWidgetsCatalog.select,
@@ -362,8 +397,7 @@ class AXMTaskBoardFiltersComponent {
362
397
  meta: {
363
398
  title: 'task-board.filter.assignee',
364
399
  },
365
- },
366
- {
400
+ }, {
367
401
  name: 'reporter',
368
402
  path: 'options.reporter',
369
403
  type: AXPWidgetsCatalog.select,
@@ -378,8 +412,7 @@ class AXMTaskBoardFiltersComponent {
378
412
  meta: {
379
413
  title: 'task-board.filter.reporter',
380
414
  },
381
- },
382
- {
415
+ }, {
383
416
  name: 'priority',
384
417
  path: 'options.priority',
385
418
  type: AXPWidgetsCatalog.select,
@@ -394,8 +427,9 @@ class AXMTaskBoardFiltersComponent {
394
427
  meta: {
395
428
  title: 'task-board.filter.priority',
396
429
  },
397
- },
398
- ], ...(ngDevMode ? [{ debugName: "nodes" }] : []));
430
+ });
431
+ return allNodes;
432
+ }, ...(ngDevMode ? [{ debugName: "nodes" }] : []));
399
433
  }
400
434
  #init;
401
435
  resetContextToViewModel() {
@@ -409,20 +443,25 @@ class AXMTaskBoardFiltersComponent {
409
443
  : vmTaskTypeNames.length > 0
410
444
  ? vmTaskTypeNames[0]
411
445
  : null;
446
+ const contextOptions = {
447
+ priority: vmPriorities,
448
+ assignee: vmAssigneeIds,
449
+ reporter: vmReporterIds,
450
+ };
451
+ if (!this.excludeTaskType()) {
452
+ contextOptions.taskType = taskTypeContextValue;
453
+ }
412
454
  this.context.set({
413
- options: {
414
- priority: vmPriorities,
415
- assignee: vmAssigneeIds,
416
- reporter: vmReporterIds,
417
- taskType: taskTypeContextValue,
418
- },
455
+ options: contextOptions,
419
456
  });
420
457
  }
421
458
  handleContextChanged(e) {
422
459
  this.context.set(e.data);
423
460
  }
424
461
  handleApply() {
425
- this.syncTaskTypesToViewModel(this.context()?.options?.taskType);
462
+ if (!this.excludeTaskType()) {
463
+ this.syncTaskTypesToViewModel(this.context()?.options?.taskType);
464
+ }
426
465
  this.syncAssigneesToViewModel(this.context()?.options?.assignee);
427
466
  this.syncReportersToViewModel(this.context()?.options?.reporter);
428
467
  this.syncPrioritiesToViewModel(this.context()?.options?.priority);
@@ -480,17 +519,19 @@ class AXMTaskBoardFiltersComponent {
480
519
  handleReset() {
481
520
  if (this.vm.currentViewMode() === 'kanban' || this.vm.currentViewMode() === 'status-grouped-grid') {
482
521
  const currentOptions = this.context();
522
+ const contextOptions = {};
523
+ if (!this.excludeTaskType()) {
524
+ contextOptions.taskType = currentOptions?.options?.taskType;
525
+ }
483
526
  this.context.set({
484
- options: {
485
- taskType: currentOptions?.options?.taskType,
486
- },
527
+ options: contextOptions,
487
528
  });
488
529
  return;
489
530
  }
490
531
  this.context.set({});
491
532
  }
492
533
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMTaskBoardFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
493
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXMTaskBoardFiltersComponent, isStandalone: true, selector: "axm-task-board-filters", inputs: { isQueryParam: { classPropertyName: "isQueryParam", publicName: "isQueryParam", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { applyClicked: "applyClicked" }, ngImport: i0, template: "<div class=\"ax-px-4 ax-py-3 ax-flex ax-flex-col ax-gap-2 ax-sm ax-w-[20rem]\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChanged($event)\">\n <ax-form>\n <div class=\"ax-flex ax-flex-col ax-gap-4\">\n @for (node of nodes(); track $index) {\n <ax-form-field>\n @if (node.meta?.['title']) {\n <ax-label>\n {{ node.meta?.['title'] | translate: { scope: rootConfig.config.i18n } | async }}\n </ax-label>\n }\n <ng-container axp-widget-renderer [node]=\"node\" [mode]=\"'edit'\"></ng-container>\n </ax-form-field>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-mt-6 ax-mb-1\">\n <ax-button\n (onClick)=\"handleReset()\"\n class=\"ax-w-full\"\n [text]=\"'@general:actions.clear.title' | translate | async\"\n ></ax-button>\n <ax-button\n color=\"primary\"\n [type]=\"'submit'\"\n (onClick)=\"handleApply()\"\n class=\"ax-w-full\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n ></ax-button>\n </div>\n </ax-form>\n </axp-widgets-container>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "component", type: AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
534
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXMTaskBoardFiltersComponent, isStandalone: true, selector: "axm-task-board-filters", inputs: { isQueryParam: { classPropertyName: "isQueryParam", publicName: "isQueryParam", isSignal: true, isRequired: false, transformFunction: null }, excludeTaskType: { classPropertyName: "excludeTaskType", publicName: "excludeTaskType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { applyClicked: "applyClicked" }, ngImport: i0, template: "<div class=\"ax-px-4 ax-py-3 ax-flex ax-flex-col ax-gap-2 ax-sm ax-w-[20rem]\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChanged($event)\">\n <ax-form>\n <div class=\"ax-flex ax-flex-col ax-gap-4\">\n @for (node of nodes(); track $index) {\n <ax-form-field>\n @if (node.meta?.['title']) {\n <ax-label>\n {{ node.meta?.['title'] | translate: { scope: rootConfig.config.i18n } | async }}\n </ax-label>\n }\n <ng-container axp-widget-renderer [node]=\"node\" [mode]=\"'edit'\"></ng-container>\n </ax-form-field>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-mt-6 ax-mb-1\">\n <ax-button\n (onClick)=\"handleReset()\"\n class=\"ax-w-full\"\n [text]=\"'@general:actions.clear.title' | translate | async\"\n ></ax-button>\n <ax-button\n color=\"primary\"\n [type]=\"'submit'\"\n (onClick)=\"handleApply()\"\n class=\"ax-w-full\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n ></ax-button>\n </div>\n </ax-form>\n </axp-widgets-container>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "component", type: AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
494
535
  }
495
536
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMTaskBoardFiltersComponent, decorators: [{
496
537
  type: Component,
@@ -504,7 +545,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
504
545
  AXTranslatorPipe,
505
546
  AsyncPipe,
506
547
  ], template: "<div class=\"ax-px-4 ax-py-3 ax-flex ax-flex-col ax-gap-2 ax-sm ax-w-[20rem]\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChanged($event)\">\n <ax-form>\n <div class=\"ax-flex ax-flex-col ax-gap-4\">\n @for (node of nodes(); track $index) {\n <ax-form-field>\n @if (node.meta?.['title']) {\n <ax-label>\n {{ node.meta?.['title'] | translate: { scope: rootConfig.config.i18n } | async }}\n </ax-label>\n }\n <ng-container axp-widget-renderer [node]=\"node\" [mode]=\"'edit'\"></ng-container>\n </ax-form-field>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-mt-6 ax-mb-1\">\n <ax-button\n (onClick)=\"handleReset()\"\n class=\"ax-w-full\"\n [text]=\"'@general:actions.clear.title' | translate | async\"\n ></ax-button>\n <ax-button\n color=\"primary\"\n [type]=\"'submit'\"\n (onClick)=\"handleApply()\"\n class=\"ax-w-full\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n ></ax-button>\n </div>\n </ax-form>\n </axp-widgets-container>\n</div>\n" }]
507
- }], propDecorators: { isQueryParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "isQueryParam", required: false }] }], applyClicked: [{ type: i0.Output, args: ["applyClicked"] }] } });
548
+ }], propDecorators: { isQueryParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "isQueryParam", required: false }] }], excludeTaskType: [{ type: i0.Input, args: [{ isSignal: true, alias: "excludeTaskType", required: false }] }], applyClicked: [{ type: i0.Output, args: ["applyClicked"] }] } });
508
549
 
509
550
  class AXMTaskBoardCalendarViewComponent {
510
551
  constructor() {
@@ -512,7 +553,26 @@ class AXMTaskBoardCalendarViewComponent {
512
553
  this.calendarService = inject(AXCalendarService);
513
554
  this.taskBoardService = inject(AXPTaskBoardService);
514
555
  this.settingService = inject(AXPSettingService);
556
+ this.commandService = inject(AXPCommandService);
515
557
  this.schedulerComponent = viewChild(AXSchedulerComponent, ...(ngDevMode ? [{ debugName: "schedulerComponent" }] : []));
558
+ this.taskPopover = viewChild('taskPopover', ...(ngDevMode ? [{ debugName: "taskPopover" }] : []));
559
+ this.selectedTask = signal(null, ...(ngDevMode ? [{ debugName: "selectedTask" }] : []));
560
+ this.popoverTarget = signal(null, ...(ngDevMode ? [{ debugName: "popoverTarget" }] : []));
561
+ this.taskActions = signal([], ...(ngDevMode ? [{ debugName: "taskActions" }] : []));
562
+ this.customComponentType = signal(null, ...(ngDevMode ? [{ debugName: "customComponentType" }] : []));
563
+ // Separate primary and secondary actions
564
+ this.primaryActions = computed(() => {
565
+ return this.taskActions().filter((action) => (action.priority ?? 'secondary') === 'primary');
566
+ }, ...(ngDevMode ? [{ debugName: "primaryActions" }] : []));
567
+ this.secondaryActions = computed(() => {
568
+ return this.taskActions().filter((action) => (action.priority ?? 'secondary') === 'secondary');
569
+ }, ...(ngDevMode ? [{ debugName: "secondaryActions" }] : []));
570
+ this.customComponentInputs = computed(() => {
571
+ const task = this.selectedTask();
572
+ if (!task)
573
+ return null;
574
+ return { task };
575
+ }, ...(ngDevMode ? [{ debugName: "customComponentInputs" }] : []));
516
576
  this.resources = input([], ...(ngDevMode ? [{ debugName: "resources" }] : []));
517
577
  this.startingDate = input(new Date(), ...(ngDevMode ? [{ debugName: "startingDate" }] : []));
518
578
  this.selectedView = input('month', ...(ngDevMode ? [{ debugName: "selectedView" }] : []));
@@ -520,7 +580,10 @@ class AXMTaskBoardCalendarViewComponent {
520
580
  this.firstDayOfWeek = signal('monday', ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
521
581
  this.weekendDays = signal([0, 6], ...(ngDevMode ? [{ debugName: "weekendDays" }] : []));
522
582
  this.holidays = (range) => {
523
- return this.taskBoardService.getEvents(range);
583
+ const selectedEventTypeIds = this.vm.selectedCalendarEventTypeIds();
584
+ // When nothing is selected, pass non-existent ID to show no events
585
+ const eventTypeIdsForQuery = selectedEventTypeIds.length > 0 ? selectedEventTypeIds : ['__NONE__'];
586
+ return this.taskBoardService.getEvents(range, eventTypeIdsForQuery);
524
587
  };
525
588
  this.currentSchedulerView = computed(() => this.selectedView() === 'kanban' || this.selectedView() === 'grid'
526
589
  ? 'month'
@@ -591,16 +654,256 @@ class AXMTaskBoardCalendarViewComponent {
591
654
  handleActionClick(event) {
592
655
  this.onActionClick.emit({ nativeEvent: event.nativeEvent, task: event.appointment });
593
656
  }
594
- onTaskClickHandler(event) {
595
- this.onTaskClick.emit(event.appointment);
657
+ async onTaskClickHandler(event) {
658
+ const task = event.appointment;
659
+ // Find the appointment container element
660
+ let targetElement = event.nativeEvent.currentTarget || event.nativeEvent.target;
661
+ // Traverse up to find the appointment container
662
+ let element = targetElement;
663
+ const maxDepth = 10;
664
+ let depth = 0;
665
+ while (element && element !== document.body && depth < maxDepth) {
666
+ depth++;
667
+ const isAppointment = element.classList?.contains('dx-scheduler-appointment') ||
668
+ element.classList?.contains('ax-scheduler-appointment') ||
669
+ element.hasAttribute('data-appointment-id');
670
+ if (isAppointment) {
671
+ targetElement = element;
672
+ break;
673
+ }
674
+ const parent = element.parentElement;
675
+ if (parent) {
676
+ const isParentAppointment = parent.classList?.contains('dx-scheduler-appointment') ||
677
+ parent.classList?.contains('ax-scheduler-appointment');
678
+ if (isParentAppointment) {
679
+ targetElement = parent;
680
+ break;
681
+ }
682
+ }
683
+ element = element.parentElement;
684
+ }
685
+ // Set the selected task and target element
686
+ this.selectedTask.set(task);
687
+ this.popoverTarget.set(targetElement);
688
+ // Check if provider has a custom component
689
+ await this.loadCustomComponent(task);
690
+ // Load actions for the task
691
+ await this.loadTaskActions(task);
692
+ // Open the popover
693
+ setTimeout(() => {
694
+ if (this.taskPopover() && targetElement) {
695
+ this.taskPopover().target = targetElement;
696
+ this.taskPopover().open();
697
+ }
698
+ }, 0);
699
+ // Still emit the event for backward compatibility
700
+ this.onTaskClick.emit(task);
701
+ }
702
+ async loadTaskActions(task) {
703
+ try {
704
+ const providerName = task.provider;
705
+ if (!providerName) {
706
+ this.taskActions.set([]);
707
+ return;
708
+ }
709
+ const provider = this.taskBoardService.getProvider(providerName);
710
+ if (!provider) {
711
+ this.taskActions.set([]);
712
+ return;
713
+ }
714
+ const actions = await provider.getActions(task);
715
+ // Ensure all actions have a priority (default to 'secondary' if not specified)
716
+ const actionsWithPriority = (actions || []).map((action) => ({
717
+ ...action,
718
+ priority: action.priority ?? 'secondary',
719
+ }));
720
+ this.taskActions.set(actionsWithPriority);
721
+ }
722
+ catch (error) {
723
+ console.error('Failed to load task actions:', error);
724
+ this.taskActions.set([]);
725
+ }
726
+ }
727
+ getActionColor(action) {
728
+ return action.color;
729
+ }
730
+ async executeAction(action) {
731
+ const task = this.selectedTask();
732
+ if (!task || !action.command)
733
+ return;
734
+ try {
735
+ const providerName = task.provider;
736
+ if (!providerName)
737
+ return;
738
+ await this.taskBoardService.executeCommand(action.command, providerName);
739
+ this.closePopover();
740
+ }
741
+ catch (error) {
742
+ console.error('Failed to execute action:', error);
743
+ }
744
+ }
745
+ async openTaskDetails() {
746
+ const task = this.selectedTask();
747
+ if (!task)
748
+ return;
749
+ try {
750
+ await this.commandService.execute('Entity:OpenDetails', {
751
+ entity: `${RootConfig.module.name}.${RootConfig.entities.task.name}`,
752
+ data: { id: task.id },
753
+ });
754
+ this.closePopover();
755
+ }
756
+ catch (error) {
757
+ console.error('Failed to open task details:', error);
758
+ }
759
+ }
760
+ async loadCustomComponent(task) {
761
+ if (!task.provider) {
762
+ console.log('[TaskPopover] No provider on task:', task);
763
+ this.customComponentType.set(null);
764
+ return;
765
+ }
766
+ const provider = this.taskBoardService.getProvider(task.provider);
767
+ if (!provider) {
768
+ console.log('[TaskPopover] Provider not found:', task.provider);
769
+ this.customComponentType.set(null);
770
+ return;
771
+ }
772
+ const componentGetter = provider.getComponent?.();
773
+ if (!componentGetter) {
774
+ console.log('[TaskPopover] No component getter on provider:', task.provider);
775
+ this.customComponentType.set(null);
776
+ return;
777
+ }
778
+ console.log('[TaskPopover] Component getter found:', componentGetter, 'Type:', typeof componentGetter);
779
+ try {
780
+ let componentType;
781
+ // Check if it's a lazy loading function or direct component type
782
+ // A lazy loader is a function that returns a Promise
783
+ // A component type is a class constructor (also a function, but used differently)
784
+ if (typeof componentGetter === 'function') {
785
+ // Try calling it to see if it returns a Promise (lazy loader)
786
+ const testCall = componentGetter;
787
+ let result;
788
+ try {
789
+ result = testCall();
790
+ }
791
+ catch (e) {
792
+ // If calling throws (e.g., class constructor without 'new'), use it directly
793
+ console.log('[TaskPopover] Component getter is a class constructor, using directly');
794
+ componentType = componentGetter;
795
+ this.customComponentType.set(componentType);
796
+ return;
797
+ }
798
+ if (result instanceof Promise) {
799
+ // It's a lazy loading function
800
+ console.log('[TaskPopover] Component getter is a lazy loader');
801
+ componentType = await result;
802
+ }
803
+ else if (result) {
804
+ // It returned a component type directly
805
+ console.log('[TaskPopover] Component getter returned component type directly');
806
+ componentType = result;
807
+ }
808
+ else {
809
+ // Result is undefined, use the original as component type
810
+ console.log('[TaskPopover] Component getter returned undefined, using original as component type');
811
+ componentType = componentGetter;
812
+ }
813
+ }
814
+ else {
815
+ console.log('[TaskPopover] Component getter is not a function');
816
+ this.customComponentType.set(null);
817
+ return;
818
+ }
819
+ console.log('[TaskPopover] Component type loaded successfully:', componentType?.name);
820
+ this.customComponentType.set(componentType);
821
+ }
822
+ catch (error) {
823
+ console.error('[TaskPopover] Failed to load custom task popover component:', error);
824
+ this.customComponentType.set(null);
825
+ }
826
+ }
827
+ closePopover() {
828
+ this.taskPopover()?.close();
829
+ this.customComponentType.set(null);
830
+ this.selectedTask.set(null);
831
+ this.popoverTarget.set(null);
832
+ this.taskActions.set([]);
833
+ }
834
+ formatTime(date) {
835
+ return this.calendarService.create(date).format('HH:mm');
836
+ }
837
+ formatDate(date) {
838
+ return this.calendarService.create(date).format('MMM DD, YYYY');
839
+ }
840
+ formatDateTime(date) {
841
+ return this.calendarService.create(date).format('MMM DD, YYYY HH:mm');
842
+ }
843
+ isMultiDay(task) {
844
+ if (task.allDay) {
845
+ const start = this.calendarService.create(task.startDate);
846
+ const end = this.calendarService.create(task.endDate);
847
+ return start.date.getTime() !== end.date.getTime();
848
+ }
849
+ // Check if start and end are on different days
850
+ const start = this.calendarService.create(task.startDate);
851
+ const end = this.calendarService.create(task.endDate);
852
+ const startDay = start.date.getDate();
853
+ const endDay = end.date.getDate();
854
+ const startMonth = start.date.getMonth();
855
+ const endMonth = end.date.getMonth();
856
+ const startYear = start.date.getFullYear();
857
+ const endYear = end.date.getFullYear();
858
+ return startDay !== endDay || startMonth !== endMonth || startYear !== endYear;
859
+ }
860
+ formatDateRange(task) {
861
+ if (task.allDay) {
862
+ const start = this.calendarService.create(task.startDate);
863
+ const end = this.calendarService.create(task.endDate);
864
+ // Same day
865
+ if (start.date.getTime() === end.date.getTime()) {
866
+ return this.formatDate(task.startDate);
867
+ }
868
+ // Different days - show range
869
+ const startFormatted = this.formatDate(task.startDate);
870
+ const endFormatted = this.formatDate(task.endDate);
871
+ // Same month and year
872
+ if (start.date.getMonth() === end.date.getMonth() && start.date.getFullYear() === end.date.getFullYear()) {
873
+ const startDay = start.date.getDate();
874
+ const endDay = end.date.getDate();
875
+ const monthYear = start.format('MMM YYYY');
876
+ return `${startDay} - ${endDay}, ${monthYear}`;
877
+ }
878
+ // Different months or years
879
+ return `${startFormatted} - ${endFormatted}`;
880
+ }
881
+ // Not all-day
882
+ if (this.isMultiDay(task)) {
883
+ const startFormatted = this.formatDateTime(task.startDate);
884
+ const endFormatted = this.formatDateTime(task.endDate);
885
+ return `${startFormatted} - ${endFormatted}`;
886
+ }
887
+ // Same day, show date with time range
888
+ const dateFormatted = this.formatDate(task.startDate);
889
+ const timeRange = `${this.formatTime(task.startDate)} - ${this.formatTime(task.endDate)}`;
890
+ return `${dateFormatted} ${timeRange}`;
596
891
  }
597
892
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMTaskBoardCalendarViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
598
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.12", type: AXMTaskBoardCalendarViewComponent, isStandalone: true, selector: "axm-task-board-calendar-view", inputs: { resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: false, transformFunction: null }, startingDate: { classPropertyName: "startingDate", publicName: "startingDate", isSignal: true, isRequired: false, transformFunction: null }, selectedView: { classPropertyName: "selectedView", publicName: "selectedView", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onTaskClick: "onTaskClick", onTaskChanged: "onTaskChanged", onMonthSlotDblClicked: "onMonthSlotDblClicked", onActionClick: "onActionClick", component: "component", onTaskRightClick: "onTaskRightClick", onRangeChanged: "onRangeChanged" }, viewQueries: [{ propertyName: "schedulerComponent", first: true, predicate: AXSchedulerComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-scheduler\n [hasHeader]=\"false\"\n [hasActions]=\"true\"\n [holidays]=\"holidays\"\n [resources]=\"resources()\"\n [dataSource]=\"dataSource()\"\n [startingDate]=\"startingDate()\"\n [selectedView]=\"currentSchedulerView()\"\n [multiDayViewDaysCount]=\"vm.daysCount()\"\n (onAppointmentDrop)=\"onTaskDrop($event)\"\n (onActionClick)=\"handleActionClick($event)\"\n (onRangeChanged)=\"handleRangeChanged($event)\"\n (onSlotDblClicked)=\"onSlotDblClicked($event)\"\n (onAppointmentClicked)=\"onTaskClickHandler($event)\"\n (onAppointmentRightClick)=\"onTaskRightClickHandler($event)\"\n [weekend]=\"weekendDays()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n></ax-scheduler>\n", styles: ["ax-scheduler{line-height:1.5;background-color:rgba(var(--ax-sys-color-lightest-surface))!important}\n"], dependencies: [{ kind: "component", type: AXSchedulerComponent, selector: "ax-scheduler", inputs: ["calendar", "startingDate", "endDayHour", "startDayHour", "hasHeader", "readonly", "draggable", "hasActions", "dragStartDelay", "weekend", "allowFullScreen", "multiDayViewDaysCount", "showResourceHeaders", "showCurrentTimeIndicator", "showUnassignedAppointments", "resources", "resourceTemplate", "firstDayOfWeek", "tooltipTemplate", "dataSource", "holidays", "views", "selectedView"], outputs: ["selectedViewChange", "onDataLoaded", "onRangeChanged", "onSlotClicked", "onSlotDblClicked", "onSlotRightClick", "onAppointmentDrop", "onActionClick", "onAppointmentClicked", "onAppointmentDblClicked", "onAppointmentRightClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
893
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXMTaskBoardCalendarViewComponent, isStandalone: true, selector: "axm-task-board-calendar-view", inputs: { resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: false, transformFunction: null }, startingDate: { classPropertyName: "startingDate", publicName: "startingDate", isSignal: true, isRequired: false, transformFunction: null }, selectedView: { classPropertyName: "selectedView", publicName: "selectedView", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onTaskClick: "onTaskClick", onTaskChanged: "onTaskChanged", onMonthSlotDblClicked: "onMonthSlotDblClicked", onActionClick: "onActionClick", component: "component", onTaskRightClick: "onTaskRightClick", onRangeChanged: "onRangeChanged" }, viewQueries: [{ propertyName: "schedulerComponent", first: true, predicate: AXSchedulerComponent, descendants: true, isSignal: true }, { propertyName: "taskPopover", first: true, predicate: ["taskPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-scheduler\n [hasHeader]=\"false\"\n [holidays]=\"holidays\"\n [resources]=\"resources()\"\n [dataSource]=\"dataSource()\"\n [startingDate]=\"startingDate()\"\n [selectedView]=\"currentSchedulerView()\"\n [multiDayViewDaysCount]=\"vm.daysCount()\"\n (onAppointmentDrop)=\"onTaskDrop($event)\"\n (onActionClick)=\"handleActionClick($event)\"\n (onRangeChanged)=\"handleRangeChanged($event)\"\n (onSlotDblClicked)=\"onSlotDblClicked($event)\"\n (onAppointmentClicked)=\"onTaskClickHandler($event)\"\n [weekend]=\"weekendDays()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n></ax-scheduler>\n\n<!-- Task Detail Popover (Modern Google Calendar Style) -->\n<ax-popover\n #taskPopover\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [offsetY]=\"12\"\n [offsetX]=\"12\"\n [adaptivityEnabled]=\"true\"\n>\n @if (selectedTask()) {\n <div class=\"task-popover ax-shadow-md ax-border\">\n <!-- Header Section -->\n <div class=\"task-popover__header\">\n <div class=\"task-popover__title-section\">\n <div class=\"task-popover__title-row\">\n <h3 class=\"task-popover__title\" [title]=\"selectedTask()!.title\">{{ selectedTask()!.title }}</h3>\n <button type=\"button\" class=\"task-popover__close-btn\" (click)=\"closePopover()\" aria-label=\"Close\">\n <ax-icon class=\"ax-icon ax-icon-close\"></ax-icon>\n </button>\n </div>\n @if (selectedTask()!.description && !customComponentType()) {\n <p class=\"task-popover__description\">{{ selectedTask()!.description }}</p>\n }\n </div>\n </div>\n\n <!-- Custom Component or Default Content -->\n @if (customComponentType()) {\n <!-- Custom Component from Provider -->\n <div class=\"task-popover__custom-content\">\n <ng-container *ngComponentOutlet=\"customComponentType()!; inputs: customComponentInputs()!\"></ng-container>\n </div>\n } @else {\n <!-- Default Content Section -->\n <div class=\"task-popover__content\">\n <!-- Time -->\n <div class=\"task-popover__info-item\">\n <div class=\"task-popover__icon\">\n <i class=\"fa-light fa-clock\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span class=\"task-popover__info-text\">{{ formatDateRange(selectedTask()!) }}</span>\n </div>\n </div>\n\n <!-- Status -->\n @if (selectedTask()!.status) {\n <div class=\"task-popover__info-item\">\n <div class=\"task-popover__icon\">\n <i class=\"fa-light fa-flag\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span class=\"task-popover__info-text\">{{ selectedTask()!.status.title }}</span>\n </div>\n </div>\n }\n\n <!-- Assignee -->\n @if (selectedTask()!.assignee) {\n <div class=\"task-popover__info-item\">\n <div class=\"task-popover__icon\">\n <i class=\"fa-light fa-user\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span class=\"task-popover__info-text\">{{\n selectedTask()!.assignee?.fullName || selectedTask()!.assignee?.username || 'Unassigned'\n }}</span>\n </div>\n </div>\n }\n\n <!-- Priority -->\n @if (selectedTask()!.priority) {\n <div class=\"task-popover__info-item\">\n <div\n class=\"task-popover__icon task-popover__icon--priority\"\n [attr.data-priority]=\"selectedTask()!.priority\"\n >\n <i class=\"fa-light fa-exclamation-circle\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span\n class=\"task-popover__info-text task-popover__priority\"\n [attr.data-priority]=\"selectedTask()!.priority\"\n >\n {{ selectedTask()!.priority }}\n </span>\n </div>\n </div>\n }\n </div>\n\n <!-- Actions Section -->\n <div class=\"task-popover__actions\">\n <!-- Task Actions from Provider -->\n @if (taskActions().length > 0) {\n <div class=\"task-popover__actions-group\">\n <!-- Primary Actions: Icon-only buttons -->\n @if (primaryActions().length > 0) {\n @for (action of primaryActions(); track action.name || action.title) {\n <ax-button\n [look]=\"'solid'\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"executeAction(action)\"\n [disabled]=\"action.disabled === true\"\n [text]=\"action.title\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n }\n\n <!-- Secondary Actions: Dropdown with \"...\" button -->\n @if (secondaryActions().length > 0) {\n <ax-button [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (action of secondaryActions(); track action.name || action.title) {\n <ax-button-item\n [text]=\"action.title\"\n [disabled]=\"action.disabled === true\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n</ax-popover>\n", styles: ["ax-scheduler{line-height:1.5;background-color:rgba(var(--ax-sys-color-lightest-surface))!important}.task-popover{background:rgba(var(--ax-sys-color-lightest-surface));border-radius:12px;overflow:hidden;display:flex;flex-direction:column}.task-popover__header{padding:20px 20px 16px;border-bottom:1px solid var(--ax-sys-color-border);background:linear-gradient(to bottom,var(--ax-sys-color-lightest-surface),var(--ax-sys-color-lighter-surface))}.task-popover__title-section{display:flex;flex-direction:column;gap:8px}.task-popover__title-row{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.task-popover__title{font-size:18px;font-weight:600;line-height:1.4;color:var(--ax-sys-color-text-primary);margin:0;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.task-popover__close-btn{flex-shrink:0;background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--ax-sys-color-text-neutral-600);transition:color .2s ease;border-radius:4px}.task-popover__close-btn:hover{color:var(--ax-sys-color-text-primary);background:var(--ax-sys-color-lighter-surface)}.task-popover__close-btn:active{background:var(--ax-sys-color-light-surface)}.task-popover__close-btn ax-icon{display:block;width:16px;height:16px}.task-popover__description{font-size:14px;line-height:1.5;color:var(--ax-sys-color-text-secondary);margin:0;display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.task-popover__content{padding:16px 20px;display:flex;flex-direction:column;gap:12px;flex:1}.task-popover__info-item{display:flex;align-items:flex-start;gap:12px;min-height:24px}.task-popover__icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px;color:var(--ax-sys-color-text-neutral-600);font-size:14px}.task-popover__icon i{display:block}.task-popover__icon--priority[data-priority=highest]{color:var(--ax-sys-color-danger)}.task-popover__icon--priority[data-priority=high]{color:var(--ax-sys-color-warning)}.task-popover__icon--priority[data-priority=medium]{color:var(--ax-sys-color-info)}.task-popover__icon--priority[data-priority=low],.task-popover__icon--priority[data-priority=lowest]{color:var(--ax-sys-color-text-neutral-500)}.task-popover__info-content{flex:1;min-width:0;display:flex;align-items:center}.task-popover__info-text{font-size:14px;line-height:1.5;color:var(--ax-sys-color-text-primary);word-wrap:break-word}.task-popover__time{font-weight:500;color:var(--ax-sys-color-text-primary);margin-left:4px}.task-popover__priority{text-transform:capitalize;font-weight:500}.task-popover__priority[data-priority=highest]{color:var(--ax-sys-color-danger)}.task-popover__priority[data-priority=high]{color:var(--ax-sys-color-warning)}.task-popover__priority[data-priority=medium]{color:var(--ax-sys-color-info)}.task-popover__priority[data-priority=low],.task-popover__priority[data-priority=lowest]{color:var(--ax-sys-color-text-neutral-600)}.task-popover__actions{padding:12px 20px 16px;border-top:1px solid var(--ax-sys-color-border);display:flex;flex-direction:column;gap:8px;background:var(--ax-sys-color-lighter-surface)}.task-popover__actions-group{display:flex;justify-content:flex-end;gap:8px;flex-wrap:wrap}.task-popover__actions-group--default{margin-top:4px;padding-top:8px;border-top:1px solid var(--ax-sys-color-border)}.task-popover__action-divider{width:100%;height:1px;background:var(--ax-sys-color-border);margin:4px 0}.task-popover__action-btn{min-width:100px;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: AXSchedulerComponent, selector: "ax-scheduler", inputs: ["calendar", "startingDate", "endDayHour", "startDayHour", "hasHeader", "readonly", "draggable", "hasActions", "dragStartDelay", "weekend", "allowFullScreen", "multiDayViewDaysCount", "showResourceHeaders", "showCurrentTimeIndicator", "showUnassignedAppointments", "resources", "resourceTemplate", "firstDayOfWeek", "tooltipTemplate", "dataSource", "holidays", "views", "selectedView"], outputs: ["selectedViewChange", "onDataLoaded", "onRangeChanged", "onSlotClicked", "onSlotDblClicked", "onSlotRightClick", "onAppointmentDrop", "onActionClick", "onAppointmentClicked", "onAppointmentDblClicked", "onAppointmentRightClick"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
599
894
  }
600
895
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMTaskBoardCalendarViewComponent, decorators: [{
601
896
  type: Component,
602
- args: [{ selector: 'axm-task-board-calendar-view', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXSchedulerComponent], template: "<ax-scheduler\n [hasHeader]=\"false\"\n [hasActions]=\"true\"\n [holidays]=\"holidays\"\n [resources]=\"resources()\"\n [dataSource]=\"dataSource()\"\n [startingDate]=\"startingDate()\"\n [selectedView]=\"currentSchedulerView()\"\n [multiDayViewDaysCount]=\"vm.daysCount()\"\n (onAppointmentDrop)=\"onTaskDrop($event)\"\n (onActionClick)=\"handleActionClick($event)\"\n (onRangeChanged)=\"handleRangeChanged($event)\"\n (onSlotDblClicked)=\"onSlotDblClicked($event)\"\n (onAppointmentClicked)=\"onTaskClickHandler($event)\"\n (onAppointmentRightClick)=\"onTaskRightClickHandler($event)\"\n [weekend]=\"weekendDays()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n></ax-scheduler>\n", styles: ["ax-scheduler{line-height:1.5;background-color:rgba(var(--ax-sys-color-lightest-surface))!important}\n"] }]
603
- }], propDecorators: { schedulerComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXSchedulerComponent), { isSignal: true }] }], resources: [{ type: i0.Input, args: [{ isSignal: true, alias: "resources", required: false }] }], startingDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "startingDate", required: false }] }], selectedView: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedView", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: true }] }], onTaskClick: [{ type: i0.Output, args: ["onTaskClick"] }], onTaskChanged: [{ type: i0.Output, args: ["onTaskChanged"] }], onMonthSlotDblClicked: [{ type: i0.Output, args: ["onMonthSlotDblClicked"] }], onActionClick: [{ type: i0.Output, args: ["onActionClick"] }], component: [{ type: i0.Output, args: ["component"] }], onTaskRightClick: [{ type: i0.Output, args: ["onTaskRightClick"] }], onRangeChanged: [{ type: i0.Output, args: ["onRangeChanged"] }] } });
897
+ args: [{ selector: 'axm-task-board-calendar-view', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
898
+ CommonModule,
899
+ AXSchedulerComponent,
900
+ AXPopoverModule,
901
+ AXButtonModule,
902
+ AXDropdownModule,
903
+ AXDecoratorModule,
904
+ AXTranslationModule,
905
+ ], template: "<ax-scheduler\n [hasHeader]=\"false\"\n [holidays]=\"holidays\"\n [resources]=\"resources()\"\n [dataSource]=\"dataSource()\"\n [startingDate]=\"startingDate()\"\n [selectedView]=\"currentSchedulerView()\"\n [multiDayViewDaysCount]=\"vm.daysCount()\"\n (onAppointmentDrop)=\"onTaskDrop($event)\"\n (onActionClick)=\"handleActionClick($event)\"\n (onRangeChanged)=\"handleRangeChanged($event)\"\n (onSlotDblClicked)=\"onSlotDblClicked($event)\"\n (onAppointmentClicked)=\"onTaskClickHandler($event)\"\n [weekend]=\"weekendDays()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n></ax-scheduler>\n\n<!-- Task Detail Popover (Modern Google Calendar Style) -->\n<ax-popover\n #taskPopover\n [openOn]=\"'manual'\"\n [closeOn]=\"'clickOut'\"\n [offsetY]=\"12\"\n [offsetX]=\"12\"\n [adaptivityEnabled]=\"true\"\n>\n @if (selectedTask()) {\n <div class=\"task-popover ax-shadow-md ax-border\">\n <!-- Header Section -->\n <div class=\"task-popover__header\">\n <div class=\"task-popover__title-section\">\n <div class=\"task-popover__title-row\">\n <h3 class=\"task-popover__title\" [title]=\"selectedTask()!.title\">{{ selectedTask()!.title }}</h3>\n <button type=\"button\" class=\"task-popover__close-btn\" (click)=\"closePopover()\" aria-label=\"Close\">\n <ax-icon class=\"ax-icon ax-icon-close\"></ax-icon>\n </button>\n </div>\n @if (selectedTask()!.description && !customComponentType()) {\n <p class=\"task-popover__description\">{{ selectedTask()!.description }}</p>\n }\n </div>\n </div>\n\n <!-- Custom Component or Default Content -->\n @if (customComponentType()) {\n <!-- Custom Component from Provider -->\n <div class=\"task-popover__custom-content\">\n <ng-container *ngComponentOutlet=\"customComponentType()!; inputs: customComponentInputs()!\"></ng-container>\n </div>\n } @else {\n <!-- Default Content Section -->\n <div class=\"task-popover__content\">\n <!-- Time -->\n <div class=\"task-popover__info-item\">\n <div class=\"task-popover__icon\">\n <i class=\"fa-light fa-clock\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span class=\"task-popover__info-text\">{{ formatDateRange(selectedTask()!) }}</span>\n </div>\n </div>\n\n <!-- Status -->\n @if (selectedTask()!.status) {\n <div class=\"task-popover__info-item\">\n <div class=\"task-popover__icon\">\n <i class=\"fa-light fa-flag\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span class=\"task-popover__info-text\">{{ selectedTask()!.status.title }}</span>\n </div>\n </div>\n }\n\n <!-- Assignee -->\n @if (selectedTask()!.assignee) {\n <div class=\"task-popover__info-item\">\n <div class=\"task-popover__icon\">\n <i class=\"fa-light fa-user\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span class=\"task-popover__info-text\">{{\n selectedTask()!.assignee?.fullName || selectedTask()!.assignee?.username || 'Unassigned'\n }}</span>\n </div>\n </div>\n }\n\n <!-- Priority -->\n @if (selectedTask()!.priority) {\n <div class=\"task-popover__info-item\">\n <div\n class=\"task-popover__icon task-popover__icon--priority\"\n [attr.data-priority]=\"selectedTask()!.priority\"\n >\n <i class=\"fa-light fa-exclamation-circle\"></i>\n </div>\n <div class=\"task-popover__info-content\">\n <span\n class=\"task-popover__info-text task-popover__priority\"\n [attr.data-priority]=\"selectedTask()!.priority\"\n >\n {{ selectedTask()!.priority }}\n </span>\n </div>\n </div>\n }\n </div>\n\n <!-- Actions Section -->\n <div class=\"task-popover__actions\">\n <!-- Task Actions from Provider -->\n @if (taskActions().length > 0) {\n <div class=\"task-popover__actions-group\">\n <!-- Primary Actions: Icon-only buttons -->\n @if (primaryActions().length > 0) {\n @for (action of primaryActions(); track action.name || action.title) {\n <ax-button\n [look]=\"'solid'\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"executeAction(action)\"\n [disabled]=\"action.disabled === true\"\n [text]=\"action.title\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n }\n\n <!-- Secondary Actions: Dropdown with \"...\" button -->\n @if (secondaryActions().length > 0) {\n <ax-button [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (action of secondaryActions(); track action.name || action.title) {\n <ax-button-item\n [text]=\"action.title\"\n [disabled]=\"action.disabled === true\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"action.icon\"></i>\n </ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n</ax-popover>\n", styles: ["ax-scheduler{line-height:1.5;background-color:rgba(var(--ax-sys-color-lightest-surface))!important}.task-popover{background:rgba(var(--ax-sys-color-lightest-surface));border-radius:12px;overflow:hidden;display:flex;flex-direction:column}.task-popover__header{padding:20px 20px 16px;border-bottom:1px solid var(--ax-sys-color-border);background:linear-gradient(to bottom,var(--ax-sys-color-lightest-surface),var(--ax-sys-color-lighter-surface))}.task-popover__title-section{display:flex;flex-direction:column;gap:8px}.task-popover__title-row{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.task-popover__title{font-size:18px;font-weight:600;line-height:1.4;color:var(--ax-sys-color-text-primary);margin:0;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.task-popover__close-btn{flex-shrink:0;background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--ax-sys-color-text-neutral-600);transition:color .2s ease;border-radius:4px}.task-popover__close-btn:hover{color:var(--ax-sys-color-text-primary);background:var(--ax-sys-color-lighter-surface)}.task-popover__close-btn:active{background:var(--ax-sys-color-light-surface)}.task-popover__close-btn ax-icon{display:block;width:16px;height:16px}.task-popover__description{font-size:14px;line-height:1.5;color:var(--ax-sys-color-text-secondary);margin:0;display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.task-popover__content{padding:16px 20px;display:flex;flex-direction:column;gap:12px;flex:1}.task-popover__info-item{display:flex;align-items:flex-start;gap:12px;min-height:24px}.task-popover__icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px;color:var(--ax-sys-color-text-neutral-600);font-size:14px}.task-popover__icon i{display:block}.task-popover__icon--priority[data-priority=highest]{color:var(--ax-sys-color-danger)}.task-popover__icon--priority[data-priority=high]{color:var(--ax-sys-color-warning)}.task-popover__icon--priority[data-priority=medium]{color:var(--ax-sys-color-info)}.task-popover__icon--priority[data-priority=low],.task-popover__icon--priority[data-priority=lowest]{color:var(--ax-sys-color-text-neutral-500)}.task-popover__info-content{flex:1;min-width:0;display:flex;align-items:center}.task-popover__info-text{font-size:14px;line-height:1.5;color:var(--ax-sys-color-text-primary);word-wrap:break-word}.task-popover__time{font-weight:500;color:var(--ax-sys-color-text-primary);margin-left:4px}.task-popover__priority{text-transform:capitalize;font-weight:500}.task-popover__priority[data-priority=highest]{color:var(--ax-sys-color-danger)}.task-popover__priority[data-priority=high]{color:var(--ax-sys-color-warning)}.task-popover__priority[data-priority=medium]{color:var(--ax-sys-color-info)}.task-popover__priority[data-priority=low],.task-popover__priority[data-priority=lowest]{color:var(--ax-sys-color-text-neutral-600)}.task-popover__actions{padding:12px 20px 16px;border-top:1px solid var(--ax-sys-color-border);display:flex;flex-direction:column;gap:8px;background:var(--ax-sys-color-lighter-surface)}.task-popover__actions-group{display:flex;justify-content:flex-end;gap:8px;flex-wrap:wrap}.task-popover__actions-group--default{margin-top:4px;padding-top:8px;border-top:1px solid var(--ax-sys-color-border)}.task-popover__action-divider{width:100%;height:1px;background:var(--ax-sys-color-border);margin:4px 0}.task-popover__action-btn{min-width:100px;white-space:nowrap}\n"] }]
906
+ }], propDecorators: { schedulerComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXSchedulerComponent), { isSignal: true }] }], taskPopover: [{ type: i0.ViewChild, args: ['taskPopover', { isSignal: true }] }], resources: [{ type: i0.Input, args: [{ isSignal: true, alias: "resources", required: false }] }], startingDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "startingDate", required: false }] }], selectedView: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedView", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: true }] }], onTaskClick: [{ type: i0.Output, args: ["onTaskClick"] }], onTaskChanged: [{ type: i0.Output, args: ["onTaskChanged"] }], onMonthSlotDblClicked: [{ type: i0.Output, args: ["onMonthSlotDblClicked"] }], onActionClick: [{ type: i0.Output, args: ["onActionClick"] }], component: [{ type: i0.Output, args: ["component"] }], onTaskRightClick: [{ type: i0.Output, args: ["onTaskRightClick"] }], onRangeChanged: [{ type: i0.Output, args: ["onRangeChanged"] }] } });
604
907
 
605
908
  class AXMTaskBoardGridViewComponent {
606
909
  constructor() {
@@ -870,12 +1173,20 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
870
1173
  this.taskBoardService = inject(AXPTaskBoardService);
871
1174
  this.popover = viewChild('popover', ...(ngDevMode ? [{ debugName: "popover" }] : []));
872
1175
  this.calendar = viewChild('calendar', ...(ngDevMode ? [{ debugName: "calendar" }] : []));
1176
+ this.sidebarCalendar = viewChild('sidebarCalendar', ...(ngDevMode ? [{ debugName: "sidebarCalendar" }] : []));
873
1177
  this.isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : []));
1178
+ this.taskTypes = signal([], ...(ngDevMode ? [{ debugName: "taskTypes" }] : []));
1179
+ this.calendarEventTypes = signal([], ...(ngDevMode ? [{ debugName: "calendarEventTypes" }] : []));
874
1180
  this.resources = signal([], ...(ngDevMode ? [{ debugName: "resources" }] : []));
875
1181
  this.isQueryParam = signal(false, ...(ngDevMode ? [{ debugName: "isQueryParam" }] : []));
1182
+ this.taskTypeAccordionCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "taskTypeAccordionCollapsed" }] : []));
1183
+ this.calendarEventTypeAccordionCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "calendarEventTypeAccordionCollapsed" }] : []));
876
1184
  this.currentTask = signal(null, ...(ngDevMode ? [{ debugName: "currentTask" }] : []));
877
1185
  this.currentViewMode = signal('calendar', ...(ngDevMode ? [{ debugName: "currentViewMode" }] : []));
878
1186
  this.schedulerComponent = signal(null, ...(ngDevMode ? [{ debugName: "schedulerComponent" }] : []));
1187
+ this.dayCellTemplateRef = viewChild('dayCellTemplate', ...(ngDevMode ? [{ debugName: "dayCellTemplateRef" }] : []));
1188
+ this.dayCellTemplate = computed(() => this.dayCellTemplateRef(), ...(ngDevMode ? [{ debugName: "dayCellTemplate" }] : []));
1189
+ this.dayDataCache = signal(new Map(), ...(ngDevMode ? [{ debugName: "dayDataCache" }] : []));
879
1190
  this.menuItems = signal([
880
1191
  {
881
1192
  key: 'calendar',
@@ -934,13 +1245,17 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
934
1245
  if (this.vm.currentViewMode() === 'grid' ||
935
1246
  this.vm.currentViewMode() === 'kanban' ||
936
1247
  this.vm.currentViewMode() === 'status-grouped-grid') {
937
- const start = this.calendarService.create(this.vm.currentDate(), this.localeService.activeProfile().calendar.system);
1248
+ const currentDate = this.vm.currentDate();
1249
+ if (!currentDate) {
1250
+ return '';
1251
+ }
1252
+ const start = this.calendarService.create(currentDate, this.localeService.activeProfile().calendar.system);
938
1253
  const end = start.add('day', this.vm.daysCount() - 1);
939
1254
  const startText = start.format('DD MMMM yyyy', { locale: this.localeService.activeProfile().calendar.system });
940
1255
  const endText = end.format('DD MMMM yyyy', { locale: this.localeService.activeProfile().calendar.system });
941
1256
  return `${startText} - ${endText}`;
942
1257
  }
943
- return this.schedulerComponent()?.currentDateText();
1258
+ return this.schedulerComponent()?.currentDateText() || '';
944
1259
  }, ...(ngDevMode ? [{ debugName: "timeText" }] : []));
945
1260
  this.calendarDepth = computed(() => {
946
1261
  if (this.vm.currentViewMode() === 'grid' ||
@@ -948,8 +1263,12 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
948
1263
  this.vm.currentViewMode() === 'status-grouped-grid') {
949
1264
  return 'day';
950
1265
  }
951
- return this.schedulerComponent()?.calendarDepth();
1266
+ return this.schedulerComponent()?.calendarDepth() || 'day';
952
1267
  }, ...(ngDevMode ? [{ debugName: "calendarDepth" }] : []));
1268
+ this.currentDateForCalendar = computed(() => {
1269
+ const date = this.vm.currentDate();
1270
+ return date || new Date();
1271
+ }, ...(ngDevMode ? [{ debugName: "currentDateForCalendar" }] : []));
953
1272
  this.selectedViewMode = computed(() => {
954
1273
  const currentMode = this.vm.currentViewMode();
955
1274
  for (const category of this.menuItems()) {
@@ -970,11 +1289,16 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
970
1289
  }, ...(ngDevMode ? [{ debugName: "selectedViewMode" }] : []));
971
1290
  this.filter = computed(() => {
972
1291
  const taskTypeNames = this.vm.selectedTaskTypeNames();
973
- const types = taskTypeNames.length > 0 ? taskTypeNames : undefined;
1292
+ // When nothing is selected (empty array), we want to show NO types
1293
+ // The service treats empty/undefined types as "show all providers"
1294
+ // To show none when nothing is selected, we pass a non-existent type name
1295
+ // This ensures filteredProviders.length === 0, resulting in empty results
1296
+ const types = taskTypeNames.length > 0 ? taskTypeNames : ['__NONE__'];
974
1297
  const assigneeIds = this.vm.selectedAssigneeIds();
975
1298
  const reporterIds = this.vm.selectedReporterIds();
976
1299
  const priorities = this.vm.selectedPriorities();
977
- let from = this.calendarService.create(this.vm.currentDate(), this.localeService.activeProfile().calendar.system);
1300
+ const currentDate = this.vm.currentDate() || new Date();
1301
+ let from = this.calendarService.create(currentDate, this.localeService.activeProfile().calendar.system);
978
1302
  let end;
979
1303
  const currentView = this.vm.currentViewMode();
980
1304
  if (currentView === 'grid' ||
@@ -992,7 +1316,8 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
992
1316
  end = from.endOf('day');
993
1317
  }
994
1318
  return {
995
- ...(types && { types }),
1319
+ // Always include types - empty array means show no types, non-empty means show only selected types
1320
+ types,
996
1321
  ...(assigneeIds.length > 0 && { assigneeIds }),
997
1322
  ...(reporterIds.length > 0 && { reporterIds }),
998
1323
  ...(priorities.length > 0 && { priorities }),
@@ -1027,6 +1352,18 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1027
1352
  this.getResources();
1028
1353
  this.schedulerComponent()?.refresh();
1029
1354
  }, ...(ngDevMode ? [{ debugName: "refreshEffect" }] : []));
1355
+ this.calendarEventTypeRefreshEffect = effect(() => {
1356
+ this.vm.selectedCalendarEventTypeIds();
1357
+ // Refresh calendar view to update holidays when event types change
1358
+ this.schedulerComponent()?.refresh();
1359
+ }, ...(ngDevMode ? [{ debugName: "calendarEventTypeRefreshEffect" }] : []));
1360
+ this.dayDataCacheEffect = effect(async () => {
1361
+ // Update cache when filters or date change
1362
+ this.vm.currentDate();
1363
+ this.vm.selectedTaskTypeNames();
1364
+ this.vm.selectedCalendarEventTypeIds();
1365
+ await this.updateDayDataCache();
1366
+ }, ...(ngDevMode ? [{ debugName: "dayDataCacheEffect" }] : []));
1030
1367
  this.rangeBasedViews = [
1031
1368
  'grid',
1032
1369
  'kanban',
@@ -1073,10 +1410,44 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1073
1410
  }
1074
1411
  return null;
1075
1412
  };
1413
+ this.taskTypeItems = computed(() => {
1414
+ return this.taskTypes().map((taskType) => ({
1415
+ id: taskType.name,
1416
+ text: taskType.title,
1417
+ icon: taskType.icon,
1418
+ }));
1419
+ }, ...(ngDevMode ? [{ debugName: "taskTypeItems" }] : []));
1420
+ this.selectedTaskTypeValues = computed(() => {
1421
+ return this.vm.selectedTaskTypeNames();
1422
+ }, ...(ngDevMode ? [{ debugName: "selectedTaskTypeValues" }] : []));
1423
+ this.calendarEventTypeItems = computed(() => {
1424
+ return this.calendarEventTypes().map((eventType) => ({
1425
+ id: eventType.id,
1426
+ text: eventType.title,
1427
+ icon: eventType.icon,
1428
+ color: eventType.color,
1429
+ }));
1430
+ }, ...(ngDevMode ? [{ debugName: "calendarEventTypeItems" }] : []));
1431
+ this.selectedCalendarEventTypeValues = computed(() => {
1432
+ return this.vm.selectedCalendarEventTypeIds();
1433
+ }, ...(ngDevMode ? [{ debugName: "selectedCalendarEventTypeValues" }] : []));
1076
1434
  }
1077
1435
  async ngOnInit() {
1078
1436
  await super.ngOnInit();
1079
1437
  await this.vm.initialize();
1438
+ // Load task types for checkbox filter
1439
+ const types = await this.taskBoardService.getTaskTypes();
1440
+ this.taskTypes.set(types);
1441
+ // Load calendar event types for checkbox filter
1442
+ const eventTypes = await this.taskBoardService.getCalendarEventTypes();
1443
+ this.calendarEventTypes.set(eventTypes.map((et) => ({
1444
+ id: et.id,
1445
+ title: et.title,
1446
+ color: et.color,
1447
+ icon: et.icon,
1448
+ })));
1449
+ // Initialize day data cache
1450
+ await this.updateDayDataCache();
1080
1451
  this.router.events
1081
1452
  .pipe(this.unsubscribe.takeUntilDestroy, filter((event) => event instanceof NavigationEnd), startWith(null))
1082
1453
  .subscribe(async () => {
@@ -1148,6 +1519,65 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1148
1519
  this.popover()?.close();
1149
1520
  dropdownPanel.close();
1150
1521
  }
1522
+ async updateDayDataCache() {
1523
+ const currentDate = this.vm.currentDate();
1524
+ const monthStart = this.calendarService.create(currentDate).startOf('month').date;
1525
+ const monthEnd = this.calendarService.create(currentDate).endOf('month').date;
1526
+ // Get tasks for the month
1527
+ const tasks = await this.taskBoardService.getTasks({
1528
+ ...this.filter(),
1529
+ range: { from: monthStart, end: monthEnd },
1530
+ });
1531
+ // Get events for the month
1532
+ const selectedEventTypeIds = this.vm.selectedCalendarEventTypeIds();
1533
+ // When nothing is selected, pass non-existent ID to show no events
1534
+ const eventTypeIdsForQuery = selectedEventTypeIds.length > 0 ? selectedEventTypeIds : ['__NONE__'];
1535
+ const events = await this.taskBoardService.getEvents({ from: monthStart, end: monthEnd }, eventTypeIdsForQuery);
1536
+ // Create a map of day -> count
1537
+ const dayCountMap = new Map();
1538
+ // Count tasks per day
1539
+ tasks.items.forEach((task) => {
1540
+ const taskStart = new Date(task.startDate);
1541
+ const taskEnd = new Date(task.endDate);
1542
+ const startDay = this.calendarService.create(taskStart).startOf('day');
1543
+ const endDay = this.calendarService.create(taskEnd).startOf('day');
1544
+ let currentDay = startDay;
1545
+ while (currentDay.compare(endDay, 'day') <= 0) {
1546
+ const dayKey = currentDay.format('YYYY-MM-DD');
1547
+ dayCountMap.set(dayKey, (dayCountMap.get(dayKey) || 0) + 1);
1548
+ currentDay = currentDay.add('day', 1);
1549
+ }
1550
+ });
1551
+ // Count events per day
1552
+ events.forEach((event) => {
1553
+ const eventDate = new Date(event.date);
1554
+ const dayKey = this.calendarService.create(eventDate).format('YYYY-MM-DD');
1555
+ dayCountMap.set(dayKey, (dayCountMap.get(dayKey) || 0) + 1);
1556
+ });
1557
+ this.dayDataCache.set(dayCountMap);
1558
+ this.sidebarCalendar()?.render();
1559
+ }
1560
+ getDayDataCount(date) {
1561
+ if (!date) {
1562
+ return 0;
1563
+ }
1564
+ try {
1565
+ // Get the native Date object from AXDateTime
1566
+ const dateObj = date.date || date._date;
1567
+ if (!dateObj) {
1568
+ return 0;
1569
+ }
1570
+ // Create a new AXDateTime from the date object for consistent formatting
1571
+ const nativeDate = dateObj instanceof Date ? dateObj : new Date(dateObj);
1572
+ const axDate = this.calendarService.create(nativeDate);
1573
+ const dayKey = axDate.format('YYYY-MM-DD');
1574
+ return this.dayDataCache().get(dayKey) || 0;
1575
+ }
1576
+ catch (error) {
1577
+ console.warn('Error getting day data count:', error);
1578
+ return 0;
1579
+ }
1580
+ }
1151
1581
  handleContextMenuItemClick(event) {
1152
1582
  this.taskBoardService.executeCommand(event.item.data?.command, this.currentTask()?.provider ?? '');
1153
1583
  }
@@ -1178,6 +1608,7 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1178
1608
  }
1179
1609
  this.popover()?.close();
1180
1610
  this.calendar()?.render();
1611
+ this.sidebarCalendar()?.render();
1181
1612
  }
1182
1613
  handleCalendarSlotClick(event) {
1183
1614
  if (event.component.activeView !== event.component.depth)
@@ -1189,6 +1620,7 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1189
1620
  if (!selectionStartDate) {
1190
1621
  this.vm.setRangeStartDate(clickedDate);
1191
1622
  this.calendar()?.render();
1623
+ this.sidebarCalendar()?.render();
1192
1624
  return;
1193
1625
  }
1194
1626
  const date1 = selectionStartDate.getTime();
@@ -1200,6 +1632,7 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1200
1632
  this.vm.setDaysCount(differenceInDays);
1201
1633
  this.vm.setRangeStartDate(null);
1202
1634
  this.calendar()?.render();
1635
+ this.sidebarCalendar()?.render();
1203
1636
  this.popover()?.close();
1204
1637
  return;
1205
1638
  }
@@ -1216,6 +1649,7 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1216
1649
  this.vm.setCurrentDate(dateToSet);
1217
1650
  this.popover()?.close();
1218
1651
  this.calendar()?.render();
1652
+ this.sidebarCalendar()?.render();
1219
1653
  }
1220
1654
  /**
1221
1655
  * Helper function to calculate the difference in whole days between two dates.
@@ -1245,6 +1679,17 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1245
1679
  this.vm.setCurrentDate(currentDate);
1246
1680
  this.popover()?.close();
1247
1681
  this.calendar()?.render();
1682
+ this.sidebarCalendar()?.render();
1683
+ }
1684
+ handleTaskTypeSelectionChange(selectedValues) {
1685
+ // If nothing is selected, pass empty array to show no types
1686
+ this.vm.setSelectedTaskTypeNames(selectedValues || [], this.isQueryParam());
1687
+ }
1688
+ handleCalendarEventTypeSelectionChange(selectedValues) {
1689
+ // If nothing is selected, pass empty array to show no types
1690
+ this.vm.setSelectedCalendarEventTypeIds(selectedValues || [], this.isQueryParam());
1691
+ // Refresh calendar view to update holidays
1692
+ this.schedulerComponent()?.refresh();
1248
1693
  }
1249
1694
  async loadFromRoute() {
1250
1695
  const snapshot = this.activatedRoute.snapshot.queryParamMap;
@@ -1313,17 +1758,24 @@ class AXMTaskBoardPage extends AXPPageLayoutBaseComponent {
1313
1758
  const resources = await this.taskBoardService.getResources(this.vm.selectedTaskTypeNames()[0] ?? '');
1314
1759
  this.resources.set(resources);
1315
1760
  }
1761
+ log(message) {
1762
+ console.log(message);
1763
+ }
1764
+ // protected layout = viewChild(AXPPageLayoutComponent);
1765
+ toggleStartSide() {
1766
+ this.layout()?.toggleStartSide();
1767
+ }
1316
1768
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMTaskBoardPage, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1317
1769
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXMTaskBoardPage, isStandalone: true, selector: "ng-component", providers: [
1318
1770
  {
1319
1771
  provide: AXPPageLayoutBase,
1320
1772
  useExisting: AXMTaskBoardPage,
1321
1773
  },
1322
- ], viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }, { propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true, isSignal: true }, { propertyName: "contextMenu", first: true, predicate: ["rootContextMenu"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n <axp-page-toolbar>\n <axp-layout-prefix class=\"sm:ax-flex-row ax-flex-col ax-items-start\">\n <ax-button [text]=\"(t('task-board.view.' + selectedViewMode().text, { scope: rootConfig.config.i18n}) | async)!\">\n <ax-prefix><ax-icon [icon]=\"selectedViewMode().icon\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #dropdownPanel>\n <ax-menu [orientation]=\"'vertical'\" class=\"ax-menu-container\">\n @for (category of menuItems(); track category.key) {\n <ng-container>\n @if (category.children && category.children.length > 0) {\n <ax-menu-item>\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ (t('task-board.' + category.text, { scope: rootConfig.config.i18n}) | async)! }}</ax-text>\n @for (child of category.children; track child.key) {\n <ax-menu-item (onClick)=\"handleViewChange(child.key,dropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"child.icon\"></ax-icon>\n </ax-prefix>\n <ax-text\n >{{ (t('task-board.view.' + child.text, { scope: rootConfig.config.i18n}) | async)! }}</ax-text\n >\n </ax-menu-item>\n }\n </ax-menu-item>\n } @else {\n <ax-menu-item (onClick)=\"handleViewChange(category.key,dropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ (t('task-board.' + category.text, { scope: rootConfig.config.i18n}) | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ng-container>\n }\n </ax-menu>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n\n <div class=\"ax-scheduler-header ax-w-max ax-sm sm:ax-md\">\n <ax-button look=\"blank\" (onClick)=\"changeDate(false)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-left arrow-icon\"></ax-icon>\n </ax-button>\n <ax-button look=\"blank\" [text]=\"timeText()\" #date></ax-button>\n <ax-button look=\"blank\" (onClick)=\"changeDate(true)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-right arrow-icon\"></ax-icon>\n </ax-button>\n <ax-popover [target]=\"date\" [placement]=\"'bottom'\" #popover [adaptivityEnabled]=\"true\">\n <div class=\"ax-overlay-pane\">\n <ax-calendar\n #calendar\n [type]=\"calendarType()\"\n [depth]=\"calendarDepth()\"\n [cellClass]=\"getCellClass\"\n [ngModel]=\"vm.currentDate()\"\n class=\"ax-single-range-calendar\"\n (onSlotClick)=\"handleCalendarSlotClick($event)\"\n >\n <ax-footer>\n <ax-button\n look=\"link\"\n color=\"primary\"\n [text]=\"todayButtonText()\"\n (onClick)=\"handleTodayClick()\"\n ></ax-button>\n </ax-footer>\n </ax-calendar>\n </div>\n </ax-popover>\n </div>\n </axp-layout-prefix>\n\n <axp-layout-suffix>\n <ax-button [text]=\"t('task-board.filter.title', { scope: rootConfig.config.i18n }) | async\">\n <ax-prefix><ax-icon icon=\"fa-{{vm.activeFilterCount()?'solid':'light'}} fa-filter\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #filterDropdownPanel (onOpened)=\"filtersComponent.resetContextToViewModel()\">\n <axm-task-board-filters\n #filtersComponent\n [isQueryParam]=\"isQueryParam()\"\n (applyClicked)=\"filterDropdownPanel.close()\"\n ></axm-task-board-filters>\n </ax-dropdown-panel>\n </ax-button>\n\n @if(deviceService.isLarge()) {\n <ax-button (onClick)=\"vm.toggleDetailPanel()\">\n <ax-icon icon=\"{{ vm.isDetailPanelOpen() ? 'fa-solid fa-square-info' : 'fa-light fa-square-info' }}\"></ax-icon>\n </ax-button>\n }\n </axp-layout-suffix>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-flex ax-flex-row ax-gap-2\">\n @if (isReady()) { @switch(vm.currentViewMode()) { @case('kanban') {\n <axm-task-board-kanban-view\n class=\"axp-kanban-container ax-h-full ax-w-full ax-min-w-0\"\n [tasks]=\"resolvedTasks()\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-kanban-view>\n } @case('grid') {\n <axm-task-board-grid-view\n class=\"ax-h-full ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-grid-view>\n } @case('status-grouped-grid') {\n <axm-task-board-status-grouped-grid-view\n class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-status-grouped-grid-view>\n } @default {\n <axm-task-board-calendar-view\n class=\"axp-scheduler-container ax-h-full ax-w-full ax-min-w-0\"\n [resources]=\"resources()\"\n [startingDate]=\"vm.currentDate()\"\n [dataSource]=\"schedulerDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n [selectedView]=\"vm.currentViewMode()\"\n (onActionClick)=\"handleContextMenu($event)\"\n (onTaskRightClick)=\"handleContextMenu($event)\"\n (component)=\"schedulerComponentChanged($event)\"\n (onMonthSlotDblClicked)=\"handleMonthSlotDblClicked($event)\"\n ></axm-task-board-calendar-view>\n } }\n <ax-context-menu\n #rootContextMenu\n [closeOn]=\"'leave'\"\n [orientation]=\"'vertical'\"\n (onOpening)=\"handleContextMenuOnOpening($event)\"\n (onItemClick)=\"handleContextMenuItemClick($event)\"\n >\n </ax-context-menu>\n @if (vm.isDetailPanelOpen() && deviceService.isLarge()) {\n <axm-task-board-detail-panel></axm-task-board-detail-panel>\n } } @else {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-w-full ax-h-full\">\n <ax-loading></ax-loading>\n </div>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["html[dir=rtl] axp-page-layout axp-page-toolbar axp-layout-prefix .ax-scheduler-header .arrow-icon:before{-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scaleX(-1)}.ax-single-range-calendar .ax-range-start,.ax-single-range-calendar .ax-range-end{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.85)!important}.ax-single-range-calendar .ax-range-start:hover,.ax-single-range-calendar .ax-range-end:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}.ax-single-range-calendar .ax-range-start.ax-state-holiday,.ax-single-range-calendar .ax-range-end.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.85)!important}.ax-single-range-calendar .ax-range-between{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.65)}.ax-single-range-calendar .ax-range-between.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.65)}.ax-single-range-calendar ax-footer{display:flex;justify-content:center;border-color:rgba(var(--ax-comp-calendar-view-header-border-color));border-top-width:var(--ax-comp-calendar-view-header-border-width, 1px)}axp-page-content:not(:has(axm-task-board-status-grouped-grid-view,axm-task-board-time-grouped-grid-view)){overflow-y:hidden}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1774
+ ], viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }, { propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true, isSignal: true }, { propertyName: "sidebarCalendar", first: true, predicate: ["sidebarCalendar"], descendants: true, isSignal: true }, { propertyName: "dayCellTemplateRef", first: true, predicate: ["dayCellTemplate"], descendants: true, isSignal: true }, { propertyName: "contextMenu", first: true, predicate: ["rootContextMenu"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n <axp-layout-start-side class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header class=\"ax-p-4 ax-border-b\">\n <ng-container *ngTemplateOutlet=\"viewSelectorTemplate; context: { location: 'sidebar' }\"></ng-container>\n </axp-layout-header>\n\n <axp-layout-content class=\"ax-flex ax-flex-col ax-min-h-0 ax-overflow-y-auto\">\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-6\">\n <div class=\"ax-flex ax-flex-col ax-gap-3\">\n <!-- <h3 class=\"ax-text-sm ax-font-semibold ax-text-neutral-800 ax-uppercase ax-tracking-wide\">\n {{ (t('task-board.terms.calendar', { scope: rootConfig.config.i18n}) | async) }}\n </h3> -->\n <ax-calendar\n #sidebarCalendar\n [type]=\"calendarType()\"\n [depth]=\"calendarDepth()\"\n [cellClass]=\"getCellClass\"\n [ngModel]=\"currentDateForCalendar()\"\n [dayCellTemplate]=\"dayCellTemplate\"\n class=\"ax-single-range-calendar ax-border ax-rounded-lg\"\n (onSlotClick)=\"handleCalendarSlotClick($event)\"\n >\n </ax-calendar>\n </div>\n\n <div axAccordionGroup>\n <div\n class=\"ax-mb-2 ax-w-full ax-border ax-p-2 ax-rounded-lg\"\n axAccordionItem\n #taskTypeAccordion=\"axAccordionItem\"\n >\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-2 ax-select-none ax-cursor-pointer\"\n axAccordionItemHeader\n >\n <h3 class=\"ax-text-sm ax-font-semibold\">\n {{ (t('task-board.filter.task-type', { scope: rootConfig.config.i18n}) | async)! }}\n </h3>\n <ax-icon\n [icon]=\"taskTypeAccordion?.isCollapsed() ? 'fa-light fa-chevron-down' : 'fa-light fa-chevron-up'\"\n class=\"ax-transition-transform\"\n ></ax-icon>\n </div>\n <div axAccordionItemContent>\n <div class=\"ax-pt-2\">\n <ax-selection-list\n [items]=\"taskTypeItems()\"\n [ngModel]=\"selectedTaskTypeValues()\"\n (onValueChanged)=\"handleTaskTypeSelectionChange($event.value)\"\n direction=\"vertical\"\n [multiple]=\"true\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n >\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n <span [class]=\"item.icon ? 'ax-ml-2' : ''\">{{ item.text }}</span>\n </div>\n </ng-template>\n </ax-selection-list>\n </div>\n </div>\n </div>\n\n <div\n class=\"ax-mb-2 ax-w-full ax-border ax-p-2 ax-rounded-lg\"\n axAccordionItem\n #calendarEventTypeAccordion=\"axAccordionItem\"\n >\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-2 ax-select-none ax-cursor-pointer\"\n axAccordionItemHeader\n >\n <h3 class=\"ax-text-sm ax-font-semibold\">\n {{ (t('task-board.filter.calendar-event-type', { scope: rootConfig.config.i18n}) | async)! }}\n </h3>\n <ax-icon\n [icon]=\"calendarEventTypeAccordion?.isCollapsed() ? 'fa-light fa-chevron-down' : 'fa-light fa-chevron-up'\"\n class=\"ax-transition-transform\"\n ></ax-icon>\n </div>\n <div axAccordionItemContent>\n <div class=\"ax-pt-2\">\n <ax-selection-list\n [items]=\"calendarEventTypeItems()\"\n [ngModel]=\"selectedCalendarEventTypeValues()\"\n (onValueChanged)=\"handleCalendarEventTypeSelectionChange($event.value)\"\n direction=\"vertical\"\n [multiple]=\"true\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n >\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n <span [class]=\"item.icon ? 'ax-ml-2' : ''\">{{ item.text }}</span>\n </div>\n </ng-template>\n </ax-selection-list>\n </div>\n </div>\n </div>\n </div>\n </div>\n </axp-layout-content>\n </axp-layout-start-side>\n <axp-page-toolbar>\n <axp-layout-prefix class=\"sm:ax-flex-row ax-flex-col ax-items-start\">\n <div class=\"ax-scheduler-header ax-w-max ax-sm sm:ax-md\">\n <ax-button look=\"blank\" (onClick)=\"changeDate(false)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-left arrow-icon\"></ax-icon>\n </ax-button>\n <ax-button look=\"blank\" [text]=\"timeText()\" #date></ax-button>\n <ax-button look=\"blank\" (onClick)=\"changeDate(true)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-right arrow-icon\"></ax-icon>\n </ax-button>\n <!-- <ax-popover [target]=\"date\" [placement]=\"'bottom'\" #popover [adaptivityEnabled]=\"true\">\n <div class=\"ax-overlay-pane\">\n <ax-calendar\n #calendar\n [type]=\"calendarType()\"\n [depth]=\"calendarDepth()\"\n [cellClass]=\"getCellClass\"\n [ngModel]=\"vm.currentDate()\"\n class=\"ax-single-range-calendar\"\n (onSlotClick)=\"handleCalendarSlotClick($event)\"\n >\n <ax-footer>\n <ax-button\n look=\"link\"\n color=\"primary\"\n [text]=\"todayButtonText()\"\n (onClick)=\"handleTodayClick()\"\n ></ax-button>\n </ax-footer>\n </ax-calendar>\n </div>\n </ax-popover> -->\n </div>\n </axp-layout-prefix>\n\n <axp-layout-suffix>\n @if (deviceService.isSmall()) {\n <ax-button id=\"axp-toolbar-btn-filters\" (onClick)=\"toggleStartSide()\" [iconOnly]=\"true\" [color]=\"'default'\">\n <i class=\"fa-light fa-bars\"></i>\n </ax-button>\n }\n <!-- @if (!deviceService.isSmall()) {\n <ng-container *ngTemplateOutlet=\"viewSelectorTemplate; context: { location: 'toolbar' }\"></ng-container>\n } -->\n <ax-button [text]=\"t('task-board.filter.title', { scope: rootConfig.config.i18n }) | async\">\n <ax-prefix><ax-icon icon=\"fa-{{vm.activeFilterCount()?'solid':'light'}} fa-filter\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #filterDropdownPanel (onOpened)=\"filtersComponent.resetContextToViewModel()\">\n <axm-task-board-filters\n #filtersComponent\n [isQueryParam]=\"isQueryParam()\"\n [excludeTaskType]=\"true\"\n (applyClicked)=\"filterDropdownPanel.close()\"\n ></axm-task-board-filters>\n </ax-dropdown-panel>\n </ax-button>\n\n <!-- @if(deviceService.isLarge()) {\n <ax-button (onClick)=\"vm.toggleDetailPanel()\">\n <ax-icon icon=\"{{ vm.isDetailPanelOpen() ? 'fa-solid fa-square-info' : 'fa-light fa-square-info' }}\"></ax-icon>\n </ax-button>\n } -->\n </axp-layout-suffix>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-flex ax-flex-row ax-gap-2\">\n @if (isReady()) { @switch(vm.currentViewMode()) { @case('kanban') {\n <axm-task-board-kanban-view\n class=\"axp-kanban-container ax-h-full ax-w-full ax-min-w-0\"\n [tasks]=\"resolvedTasks()\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-kanban-view>\n } @case('grid') {\n <axm-task-board-grid-view\n class=\"ax-h-full ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-grid-view>\n } @case('status-grouped-grid') {\n <axm-task-board-status-grouped-grid-view\n class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-status-grouped-grid-view>\n } @default {\n <axm-task-board-calendar-view\n class=\"axp-scheduler-container ax-h-full ax-w-full ax-min-w-0\"\n [resources]=\"resources()\"\n [startingDate]=\"vm.currentDate()\"\n [dataSource]=\"schedulerDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n [selectedView]=\"vm.currentViewMode()\"\n (onActionClick)=\"handleContextMenu($event)\"\n (onTaskRightClick)=\"handleContextMenu($event)\"\n (component)=\"schedulerComponentChanged($event)\"\n (onMonthSlotDblClicked)=\"handleMonthSlotDblClicked($event)\"\n ></axm-task-board-calendar-view>\n } }\n <ax-context-menu\n #rootContextMenu\n [closeOn]=\"'leave'\"\n [orientation]=\"'vertical'\"\n (onOpening)=\"handleContextMenuOnOpening($event)\"\n (onItemClick)=\"handleContextMenuItemClick($event)\"\n >\n </ax-context-menu>\n @if (vm.isDetailPanelOpen() && deviceService.isLarge()) {\n <axm-task-board-detail-panel></axm-task-board-detail-panel>\n } } @else {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-w-full ax-h-full\">\n <ax-loading></ax-loading>\n </div>\n }\n </axp-page-content>\n</axp-page-layout>\n\n<ng-template #viewSelectorTemplate let-location=\"location\">\n @if (location === 'sidebar') {\n <ax-button\n [text]=\"('@task-management:task-board.view.' + selectedViewMode().text | translate | async)!\"\n class=\"ax-w-full\"\n >\n <ax-prefix><ax-icon [icon]=\"selectedViewMode().icon\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #sidebarDropdownPanel>\n <ax-menu [orientation]=\"'vertical'\" class=\"ax-menu-container\">\n @for (category of menuItems(); track category.key) {\n <ng-container>\n @if (category.children && category.children.length > 0) {\n <ax-menu-item>\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n @for (child of category.children; track child.key) {\n <ax-menu-item (onClick)=\"handleViewChange(child.key, sidebarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"child.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.view.' + child.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ax-menu-item>\n } @else {\n <ax-menu-item (onClick)=\"handleViewChange(category.key, sidebarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ng-container>\n }\n </ax-menu>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n } @else {\n <ax-button [text]=\"('@task-management:task-board.view.' + selectedViewMode().text | translate | async)!\">\n <ax-prefix><ax-icon [icon]=\"selectedViewMode().icon\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #toolbarDropdownPanel>\n <ax-menu [orientation]=\"'vertical'\" class=\"ax-menu-container\">\n @for (category of menuItems(); track category.key) {\n <ng-container>\n @if (category.children && category.children.length > 0) {\n <ax-menu-item>\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n @for (child of category.children; track child.key) {\n <ax-menu-item (onClick)=\"handleViewChange(child.key, toolbarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"child.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.view.' + child.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ax-menu-item>\n } @else {\n <ax-menu-item (onClick)=\"handleViewChange(category.key, toolbarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ng-container>\n }\n </ax-menu>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n }\n</ng-template>\n\n<ng-template #dayCellTemplate let-slot>\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-between ax-w-full ax-gap-1\"\n [style.padding-bottom]=\"'0.25rem'\"\n >\n <span class=\"ax-flex-1 ax-text-center\">{{ slot.slot.text ?? slot.slot.date?.day ?? '' }}</span>\n @if (slot.slot.date && getDayDataCount(slot.slot.date) > 0) {\n <ax-badge color=\"warning\"></ax-badge>\n }\n </div>\n</ng-template>\n", styles: ["html[dir=rtl] axp-page-layout axp-page-toolbar axp-layout-prefix .ax-scheduler-header .arrow-icon:before{-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scaleX(-1)}.ax-single-range-calendar .ax-range-start,.ax-single-range-calendar .ax-range-end{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.85)!important}.ax-single-range-calendar .ax-range-start:hover,.ax-single-range-calendar .ax-range-end:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}.ax-single-range-calendar .ax-range-start.ax-state-holiday,.ax-single-range-calendar .ax-range-end.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.85)!important}.ax-single-range-calendar .ax-range-between{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.65)}.ax-single-range-calendar .ax-range-between.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.65)}.ax-single-range-calendar ax-footer{display:flex;justify-content:center;border-color:rgba(var(--ax-comp-calendar-view-header-border-color));border-top-width:var(--ax-comp-calendar-view-header-border-width, 1px)}axp-page-content:not(:has(axm-task-board-status-grouped-grid-view,axm-task-board-time-grouped-grid-view)){overflow-y:hidden}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1323
1775
  //
1324
- AXMenuModule }, { kind: "component", type: i2.AXMenuItemComponent, selector: "ax-menu-item", inputs: ["name", "data", "disabled", "color"], outputs: ["onClick"] }, { kind: "component", type: i2.AXMenuComponent, selector: "ax-menu", inputs: ["orientation", "openOn", "closeOn", "items", "hasArrow"], outputs: ["onItemClick"] }, { kind: "component", type: i2.AXContextMenuComponent, selector: "ax-context-menu", inputs: ["orientation", "openOn", "closeOn", "items", "target"], outputs: ["onItemClick", "onOpening"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i2$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i6.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type:
1776
+ AXMenuModule }, { kind: "component", type: i3$1.AXMenuItemComponent, selector: "ax-menu-item", inputs: ["name", "data", "disabled", "color"], outputs: ["onClick"] }, { kind: "component", type: i3$1.AXMenuComponent, selector: "ax-menu", inputs: ["orientation", "openOn", "closeOn", "items", "hasArrow"], outputs: ["onItemClick"] }, { kind: "component", type: i3$1.AXContextMenuComponent, selector: "ax-context-menu", inputs: ["orientation", "openOn", "closeOn", "items", "target"], outputs: ["onItemClick", "onOpening"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i7.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i8.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXAccordionModule }, { kind: "ngmodule", type: AXAccordionCdkModule }, { kind: "directive", type: i9.AXAccordionGroupDirective, selector: "[axAccordionGroup]", inputs: ["accordion", "activeIndex", "collapsedOnItemClick"], exportAs: ["axAccordionGroup"] }, { kind: "directive", type: i9.AXAccordionItemContentDirective, selector: "[axAccordionItemContent]", inputs: ["transition"], exportAs: ["axAccordionItemContent"] }, { kind: "directive", type: i9.AXAccordionItemHeaderDirective, selector: "[axAccordionItemHeader]", exportAs: ["axAccordionItemHeader"] }, { kind: "directive", type: i9.AXAccordionItemDirective, selector: "[axAccordionItem]", inputs: ["isCollapsed"], outputs: ["isCollapsedChange", "onClick"], exportAs: ["axAccordionItem"] }, { kind: "component", type:
1325
1777
  //
1326
- AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXMTaskBoardCalendarViewComponent, selector: "axm-task-board-calendar-view", inputs: ["resources", "startingDate", "selectedView", "dataSource"], outputs: ["onTaskClick", "onTaskChanged", "onMonthSlotDblClicked", "onActionClick", "component", "onTaskRightClick", "onRangeChanged"] }, { kind: "component", type: AXMTaskBoardKanbanViewComponent, selector: "axm-task-board-kanban-view", inputs: ["tasks"], outputs: ["tasksChange", "onTaskClick", "onTaskChanged", "component", "onActionClick"] }, { kind: "component", type: AXMTaskBoardGridViewComponent, selector: "axm-task-board-grid-view", inputs: ["dataSource"], outputs: ["onTaskClick", "onActionClick"] }, { kind: "component", type: AXMTaskBoardStatusGroupedGridViewComponent, selector: "axm-task-board-status-grouped-grid-view", inputs: ["provider", "dataSource"], outputs: ["onActionClick"] }, { kind: "component", type: AXMTaskBoardDetailPanel, selector: "axm-task-board-detail-panel" }, { kind: "component", type: AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i7.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXCalendarComponent, selector: "ax-calendar", inputs: ["rtl", "readonly", "value", "name", "disabled", "depth", "activeView", "minValue", "maxValue", "disabledDates", "holidayDates", "type", "dayCellTemplate", "monthCellTemplate", "yearCellTemplate", "cellClass", "showNavigation", "count", "id", "weekend", "weekdays"], outputs: ["onOptionChanged", "valueChange", "onValueChanged", "minValueChange", "maxValueChange", "onBlur", "onFocus", "depthChange", "typeChange", "activeViewChange", "disabledDatesChange", "holidayDatesChange", "onNavigate", "onSlotClick", "countChange"] }, { kind: "component", type: AXMTaskBoardFiltersComponent, selector: "axm-task-board-filters", inputs: ["isQueryParam"], outputs: ["applyClicked"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1778
+ AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXMTaskBoardCalendarViewComponent, selector: "axm-task-board-calendar-view", inputs: ["resources", "startingDate", "selectedView", "dataSource"], outputs: ["onTaskClick", "onTaskChanged", "onMonthSlotDblClicked", "onActionClick", "component", "onTaskRightClick", "onRangeChanged"] }, { kind: "component", type: AXMTaskBoardKanbanViewComponent, selector: "axm-task-board-kanban-view", inputs: ["tasks"], outputs: ["tasksChange", "onTaskClick", "onTaskChanged", "component", "onActionClick"] }, { kind: "component", type: AXMTaskBoardGridViewComponent, selector: "axm-task-board-grid-view", inputs: ["dataSource"], outputs: ["onTaskClick", "onActionClick"] }, { kind: "component", type: AXMTaskBoardStatusGroupedGridViewComponent, selector: "axm-task-board-status-grouped-grid-view", inputs: ["provider", "dataSource"], outputs: ["onActionClick"] }, { kind: "component", type: AXMTaskBoardDetailPanel, selector: "axm-task-board-detail-panel" }, { kind: "component", type: AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: AXCalendarComponent, selector: "ax-calendar", inputs: ["rtl", "readonly", "value", "name", "disabled", "depth", "activeView", "minValue", "maxValue", "disabledDates", "holidayDates", "type", "dayCellTemplate", "monthCellTemplate", "yearCellTemplate", "cellClass", "showNavigation", "count", "id", "weekend", "weekdays"], outputs: ["onOptionChanged", "valueChange", "onValueChanged", "minValueChange", "maxValueChange", "onBlur", "onFocus", "depthChange", "typeChange", "activeViewChange", "disabledDatesChange", "holidayDatesChange", "onNavigate", "onSlotClick", "countChange"] }, { kind: "component", type: AXMTaskBoardFiltersComponent, selector: "axm-task-board-filters", inputs: ["isQueryParam", "excludeTaskType"], outputs: ["applyClicked"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "component", type: i10.AXSelectionListComponent, selector: "ax-selection-list", inputs: ["id", "name", "disabled", "readonly", "tabIndex", "size", "value", "valueField", "textField", "disabledField", "readonlyField", "multiple", "direction", "customTemplate", "showControl", "items", "look"], outputs: ["onValueChanged", "onBlur", "onFocus"] }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1327
1779
  }
1328
1780
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMTaskBoardPage, decorators: [{
1329
1781
  type: Component,
@@ -1340,6 +1792,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1340
1792
  AXLoadingModule,
1341
1793
  AXBreadcrumbsModule,
1342
1794
  AXBadgeModule,
1795
+ AXAccordionModule,
1796
+ AXAccordionCdkModule,
1343
1797
  //
1344
1798
  AXPThemeLayoutBlockComponent,
1345
1799
  AXPPageLayoutComponent,
@@ -1352,13 +1806,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1352
1806
  AXPopoverModule,
1353
1807
  AXCalendarComponent,
1354
1808
  AXMTaskBoardFiltersComponent,
1809
+ AXCheckBoxModule,
1810
+ AXFormModule,
1811
+ AXLabelModule,
1812
+ AXSelectionListModule,
1813
+ AXPThemeLayoutStartSideComponent,
1814
+ AXPThemeLayoutHeaderComponent,
1355
1815
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
1356
1816
  {
1357
1817
  provide: AXPPageLayoutBase,
1358
1818
  useExisting: AXMTaskBoardPage,
1359
1819
  },
1360
- ], template: "<axp-page-layout *translate=\"let t\">\n <axp-page-toolbar>\n <axp-layout-prefix class=\"sm:ax-flex-row ax-flex-col ax-items-start\">\n <ax-button [text]=\"(t('task-board.view.' + selectedViewMode().text, { scope: rootConfig.config.i18n}) | async)!\">\n <ax-prefix><ax-icon [icon]=\"selectedViewMode().icon\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #dropdownPanel>\n <ax-menu [orientation]=\"'vertical'\" class=\"ax-menu-container\">\n @for (category of menuItems(); track category.key) {\n <ng-container>\n @if (category.children && category.children.length > 0) {\n <ax-menu-item>\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ (t('task-board.' + category.text, { scope: rootConfig.config.i18n}) | async)! }}</ax-text>\n @for (child of category.children; track child.key) {\n <ax-menu-item (onClick)=\"handleViewChange(child.key,dropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"child.icon\"></ax-icon>\n </ax-prefix>\n <ax-text\n >{{ (t('task-board.view.' + child.text, { scope: rootConfig.config.i18n}) | async)! }}</ax-text\n >\n </ax-menu-item>\n }\n </ax-menu-item>\n } @else {\n <ax-menu-item (onClick)=\"handleViewChange(category.key,dropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ (t('task-board.' + category.text, { scope: rootConfig.config.i18n}) | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ng-container>\n }\n </ax-menu>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n\n <div class=\"ax-scheduler-header ax-w-max ax-sm sm:ax-md\">\n <ax-button look=\"blank\" (onClick)=\"changeDate(false)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-left arrow-icon\"></ax-icon>\n </ax-button>\n <ax-button look=\"blank\" [text]=\"timeText()\" #date></ax-button>\n <ax-button look=\"blank\" (onClick)=\"changeDate(true)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-right arrow-icon\"></ax-icon>\n </ax-button>\n <ax-popover [target]=\"date\" [placement]=\"'bottom'\" #popover [adaptivityEnabled]=\"true\">\n <div class=\"ax-overlay-pane\">\n <ax-calendar\n #calendar\n [type]=\"calendarType()\"\n [depth]=\"calendarDepth()\"\n [cellClass]=\"getCellClass\"\n [ngModel]=\"vm.currentDate()\"\n class=\"ax-single-range-calendar\"\n (onSlotClick)=\"handleCalendarSlotClick($event)\"\n >\n <ax-footer>\n <ax-button\n look=\"link\"\n color=\"primary\"\n [text]=\"todayButtonText()\"\n (onClick)=\"handleTodayClick()\"\n ></ax-button>\n </ax-footer>\n </ax-calendar>\n </div>\n </ax-popover>\n </div>\n </axp-layout-prefix>\n\n <axp-layout-suffix>\n <ax-button [text]=\"t('task-board.filter.title', { scope: rootConfig.config.i18n }) | async\">\n <ax-prefix><ax-icon icon=\"fa-{{vm.activeFilterCount()?'solid':'light'}} fa-filter\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #filterDropdownPanel (onOpened)=\"filtersComponent.resetContextToViewModel()\">\n <axm-task-board-filters\n #filtersComponent\n [isQueryParam]=\"isQueryParam()\"\n (applyClicked)=\"filterDropdownPanel.close()\"\n ></axm-task-board-filters>\n </ax-dropdown-panel>\n </ax-button>\n\n @if(deviceService.isLarge()) {\n <ax-button (onClick)=\"vm.toggleDetailPanel()\">\n <ax-icon icon=\"{{ vm.isDetailPanelOpen() ? 'fa-solid fa-square-info' : 'fa-light fa-square-info' }}\"></ax-icon>\n </ax-button>\n }\n </axp-layout-suffix>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-flex ax-flex-row ax-gap-2\">\n @if (isReady()) { @switch(vm.currentViewMode()) { @case('kanban') {\n <axm-task-board-kanban-view\n class=\"axp-kanban-container ax-h-full ax-w-full ax-min-w-0\"\n [tasks]=\"resolvedTasks()\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-kanban-view>\n } @case('grid') {\n <axm-task-board-grid-view\n class=\"ax-h-full ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-grid-view>\n } @case('status-grouped-grid') {\n <axm-task-board-status-grouped-grid-view\n class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-status-grouped-grid-view>\n } @default {\n <axm-task-board-calendar-view\n class=\"axp-scheduler-container ax-h-full ax-w-full ax-min-w-0\"\n [resources]=\"resources()\"\n [startingDate]=\"vm.currentDate()\"\n [dataSource]=\"schedulerDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n [selectedView]=\"vm.currentViewMode()\"\n (onActionClick)=\"handleContextMenu($event)\"\n (onTaskRightClick)=\"handleContextMenu($event)\"\n (component)=\"schedulerComponentChanged($event)\"\n (onMonthSlotDblClicked)=\"handleMonthSlotDblClicked($event)\"\n ></axm-task-board-calendar-view>\n } }\n <ax-context-menu\n #rootContextMenu\n [closeOn]=\"'leave'\"\n [orientation]=\"'vertical'\"\n (onOpening)=\"handleContextMenuOnOpening($event)\"\n (onItemClick)=\"handleContextMenuItemClick($event)\"\n >\n </ax-context-menu>\n @if (vm.isDetailPanelOpen() && deviceService.isLarge()) {\n <axm-task-board-detail-panel></axm-task-board-detail-panel>\n } } @else {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-w-full ax-h-full\">\n <ax-loading></ax-loading>\n </div>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["html[dir=rtl] axp-page-layout axp-page-toolbar axp-layout-prefix .ax-scheduler-header .arrow-icon:before{-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scaleX(-1)}.ax-single-range-calendar .ax-range-start,.ax-single-range-calendar .ax-range-end{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.85)!important}.ax-single-range-calendar .ax-range-start:hover,.ax-single-range-calendar .ax-range-end:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}.ax-single-range-calendar .ax-range-start.ax-state-holiday,.ax-single-range-calendar .ax-range-end.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.85)!important}.ax-single-range-calendar .ax-range-between{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.65)}.ax-single-range-calendar .ax-range-between.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.65)}.ax-single-range-calendar ax-footer{display:flex;justify-content:center;border-color:rgba(var(--ax-comp-calendar-view-header-border-color));border-top-width:var(--ax-comp-calendar-view-header-border-width, 1px)}axp-page-content:not(:has(axm-task-board-status-grouped-grid-view,axm-task-board-time-grouped-grid-view)){overflow-y:hidden}\n"] }]
1361
- }], propDecorators: { popover: [{ type: i0.ViewChild, args: ['popover', { isSignal: true }] }], calendar: [{ type: i0.ViewChild, args: ['calendar', { isSignal: true }] }], contextMenu: [{ type: i0.ViewChild, args: ['rootContextMenu', { isSignal: true }] }] } });
1820
+ ], template: "<axp-page-layout *translate=\"let t\">\n <axp-layout-start-side class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header class=\"ax-p-4 ax-border-b\">\n <ng-container *ngTemplateOutlet=\"viewSelectorTemplate; context: { location: 'sidebar' }\"></ng-container>\n </axp-layout-header>\n\n <axp-layout-content class=\"ax-flex ax-flex-col ax-min-h-0 ax-overflow-y-auto\">\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-6\">\n <div class=\"ax-flex ax-flex-col ax-gap-3\">\n <!-- <h3 class=\"ax-text-sm ax-font-semibold ax-text-neutral-800 ax-uppercase ax-tracking-wide\">\n {{ (t('task-board.terms.calendar', { scope: rootConfig.config.i18n}) | async) }}\n </h3> -->\n <ax-calendar\n #sidebarCalendar\n [type]=\"calendarType()\"\n [depth]=\"calendarDepth()\"\n [cellClass]=\"getCellClass\"\n [ngModel]=\"currentDateForCalendar()\"\n [dayCellTemplate]=\"dayCellTemplate\"\n class=\"ax-single-range-calendar ax-border ax-rounded-lg\"\n (onSlotClick)=\"handleCalendarSlotClick($event)\"\n >\n </ax-calendar>\n </div>\n\n <div axAccordionGroup>\n <div\n class=\"ax-mb-2 ax-w-full ax-border ax-p-2 ax-rounded-lg\"\n axAccordionItem\n #taskTypeAccordion=\"axAccordionItem\"\n >\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-2 ax-select-none ax-cursor-pointer\"\n axAccordionItemHeader\n >\n <h3 class=\"ax-text-sm ax-font-semibold\">\n {{ (t('task-board.filter.task-type', { scope: rootConfig.config.i18n}) | async)! }}\n </h3>\n <ax-icon\n [icon]=\"taskTypeAccordion?.isCollapsed() ? 'fa-light fa-chevron-down' : 'fa-light fa-chevron-up'\"\n class=\"ax-transition-transform\"\n ></ax-icon>\n </div>\n <div axAccordionItemContent>\n <div class=\"ax-pt-2\">\n <ax-selection-list\n [items]=\"taskTypeItems()\"\n [ngModel]=\"selectedTaskTypeValues()\"\n (onValueChanged)=\"handleTaskTypeSelectionChange($event.value)\"\n direction=\"vertical\"\n [multiple]=\"true\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n >\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n <span [class]=\"item.icon ? 'ax-ml-2' : ''\">{{ item.text }}</span>\n </div>\n </ng-template>\n </ax-selection-list>\n </div>\n </div>\n </div>\n\n <div\n class=\"ax-mb-2 ax-w-full ax-border ax-p-2 ax-rounded-lg\"\n axAccordionItem\n #calendarEventTypeAccordion=\"axAccordionItem\"\n >\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-2 ax-select-none ax-cursor-pointer\"\n axAccordionItemHeader\n >\n <h3 class=\"ax-text-sm ax-font-semibold\">\n {{ (t('task-board.filter.calendar-event-type', { scope: rootConfig.config.i18n}) | async)! }}\n </h3>\n <ax-icon\n [icon]=\"calendarEventTypeAccordion?.isCollapsed() ? 'fa-light fa-chevron-down' : 'fa-light fa-chevron-up'\"\n class=\"ax-transition-transform\"\n ></ax-icon>\n </div>\n <div axAccordionItemContent>\n <div class=\"ax-pt-2\">\n <ax-selection-list\n [items]=\"calendarEventTypeItems()\"\n [ngModel]=\"selectedCalendarEventTypeValues()\"\n (onValueChanged)=\"handleCalendarEventTypeSelectionChange($event.value)\"\n direction=\"vertical\"\n [multiple]=\"true\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n >\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n <span [class]=\"item.icon ? 'ax-ml-2' : ''\">{{ item.text }}</span>\n </div>\n </ng-template>\n </ax-selection-list>\n </div>\n </div>\n </div>\n </div>\n </div>\n </axp-layout-content>\n </axp-layout-start-side>\n <axp-page-toolbar>\n <axp-layout-prefix class=\"sm:ax-flex-row ax-flex-col ax-items-start\">\n <div class=\"ax-scheduler-header ax-w-max ax-sm sm:ax-md\">\n <ax-button look=\"blank\" (onClick)=\"changeDate(false)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-left arrow-icon\"></ax-icon>\n </ax-button>\n <ax-button look=\"blank\" [text]=\"timeText()\" #date></ax-button>\n <ax-button look=\"blank\" (onClick)=\"changeDate(true)\">\n <ax-icon class=\"ax-icon ax-text-xl ax-icon-chevron-right arrow-icon\"></ax-icon>\n </ax-button>\n <!-- <ax-popover [target]=\"date\" [placement]=\"'bottom'\" #popover [adaptivityEnabled]=\"true\">\n <div class=\"ax-overlay-pane\">\n <ax-calendar\n #calendar\n [type]=\"calendarType()\"\n [depth]=\"calendarDepth()\"\n [cellClass]=\"getCellClass\"\n [ngModel]=\"vm.currentDate()\"\n class=\"ax-single-range-calendar\"\n (onSlotClick)=\"handleCalendarSlotClick($event)\"\n >\n <ax-footer>\n <ax-button\n look=\"link\"\n color=\"primary\"\n [text]=\"todayButtonText()\"\n (onClick)=\"handleTodayClick()\"\n ></ax-button>\n </ax-footer>\n </ax-calendar>\n </div>\n </ax-popover> -->\n </div>\n </axp-layout-prefix>\n\n <axp-layout-suffix>\n @if (deviceService.isSmall()) {\n <ax-button id=\"axp-toolbar-btn-filters\" (onClick)=\"toggleStartSide()\" [iconOnly]=\"true\" [color]=\"'default'\">\n <i class=\"fa-light fa-bars\"></i>\n </ax-button>\n }\n <!-- @if (!deviceService.isSmall()) {\n <ng-container *ngTemplateOutlet=\"viewSelectorTemplate; context: { location: 'toolbar' }\"></ng-container>\n } -->\n <ax-button [text]=\"t('task-board.filter.title', { scope: rootConfig.config.i18n }) | async\">\n <ax-prefix><ax-icon icon=\"fa-{{vm.activeFilterCount()?'solid':'light'}} fa-filter\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #filterDropdownPanel (onOpened)=\"filtersComponent.resetContextToViewModel()\">\n <axm-task-board-filters\n #filtersComponent\n [isQueryParam]=\"isQueryParam()\"\n [excludeTaskType]=\"true\"\n (applyClicked)=\"filterDropdownPanel.close()\"\n ></axm-task-board-filters>\n </ax-dropdown-panel>\n </ax-button>\n\n <!-- @if(deviceService.isLarge()) {\n <ax-button (onClick)=\"vm.toggleDetailPanel()\">\n <ax-icon icon=\"{{ vm.isDetailPanelOpen() ? 'fa-solid fa-square-info' : 'fa-light fa-square-info' }}\"></ax-icon>\n </ax-button>\n } -->\n </axp-layout-suffix>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-flex ax-flex-row ax-gap-2\">\n @if (isReady()) { @switch(vm.currentViewMode()) { @case('kanban') {\n <axm-task-board-kanban-view\n class=\"axp-kanban-container ax-h-full ax-w-full ax-min-w-0\"\n [tasks]=\"resolvedTasks()\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-kanban-view>\n } @case('grid') {\n <axm-task-board-grid-view\n class=\"ax-h-full ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-grid-view>\n } @case('status-grouped-grid') {\n <axm-task-board-status-grouped-grid-view\n class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full ax-min-w-0\"\n [dataSource]=\"gridDataSource\"\n (onActionClick)=\"handleContextMenu($event)\"\n ></axm-task-board-status-grouped-grid-view>\n } @default {\n <axm-task-board-calendar-view\n class=\"axp-scheduler-container ax-h-full ax-w-full ax-min-w-0\"\n [resources]=\"resources()\"\n [startingDate]=\"vm.currentDate()\"\n [dataSource]=\"schedulerDataSource\"\n (onTaskClick)=\"vm.selectTask($event)\"\n [selectedView]=\"vm.currentViewMode()\"\n (onActionClick)=\"handleContextMenu($event)\"\n (onTaskRightClick)=\"handleContextMenu($event)\"\n (component)=\"schedulerComponentChanged($event)\"\n (onMonthSlotDblClicked)=\"handleMonthSlotDblClicked($event)\"\n ></axm-task-board-calendar-view>\n } }\n <ax-context-menu\n #rootContextMenu\n [closeOn]=\"'leave'\"\n [orientation]=\"'vertical'\"\n (onOpening)=\"handleContextMenuOnOpening($event)\"\n (onItemClick)=\"handleContextMenuItemClick($event)\"\n >\n </ax-context-menu>\n @if (vm.isDetailPanelOpen() && deviceService.isLarge()) {\n <axm-task-board-detail-panel></axm-task-board-detail-panel>\n } } @else {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-w-full ax-h-full\">\n <ax-loading></ax-loading>\n </div>\n }\n </axp-page-content>\n</axp-page-layout>\n\n<ng-template #viewSelectorTemplate let-location=\"location\">\n @if (location === 'sidebar') {\n <ax-button\n [text]=\"('@task-management:task-board.view.' + selectedViewMode().text | translate | async)!\"\n class=\"ax-w-full\"\n >\n <ax-prefix><ax-icon [icon]=\"selectedViewMode().icon\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #sidebarDropdownPanel>\n <ax-menu [orientation]=\"'vertical'\" class=\"ax-menu-container\">\n @for (category of menuItems(); track category.key) {\n <ng-container>\n @if (category.children && category.children.length > 0) {\n <ax-menu-item>\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n @for (child of category.children; track child.key) {\n <ax-menu-item (onClick)=\"handleViewChange(child.key, sidebarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"child.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.view.' + child.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ax-menu-item>\n } @else {\n <ax-menu-item (onClick)=\"handleViewChange(category.key, sidebarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ng-container>\n }\n </ax-menu>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n } @else {\n <ax-button [text]=\"('@task-management:task-board.view.' + selectedViewMode().text | translate | async)!\">\n <ax-prefix><ax-icon [icon]=\"selectedViewMode().icon\"></ax-icon></ax-prefix>\n <ax-dropdown-panel #toolbarDropdownPanel>\n <ax-menu [orientation]=\"'vertical'\" class=\"ax-menu-container\">\n @for (category of menuItems(); track category.key) {\n <ng-container>\n @if (category.children && category.children.length > 0) {\n <ax-menu-item>\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n @for (child of category.children; track child.key) {\n <ax-menu-item (onClick)=\"handleViewChange(child.key, toolbarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"child.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.view.' + child.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ax-menu-item>\n } @else {\n <ax-menu-item (onClick)=\"handleViewChange(category.key, toolbarDropdownPanel)\">\n <ax-prefix>\n <ax-icon [icon]=\"category.icon\"></ax-icon>\n </ax-prefix>\n <ax-text>{{ ('@task-management:task-board.' + category.text | translate | async)! }}</ax-text>\n </ax-menu-item>\n }\n </ng-container>\n }\n </ax-menu>\n </ax-dropdown-panel>\n <ax-suffix>\n <ax-icon icon=\"fa-light fa-caret-down\"></ax-icon>\n </ax-suffix>\n </ax-button>\n }\n</ng-template>\n\n<ng-template #dayCellTemplate let-slot>\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-between ax-w-full ax-gap-1\"\n [style.padding-bottom]=\"'0.25rem'\"\n >\n <span class=\"ax-flex-1 ax-text-center\">{{ slot.slot.text ?? slot.slot.date?.day ?? '' }}</span>\n @if (slot.slot.date && getDayDataCount(slot.slot.date) > 0) {\n <ax-badge color=\"warning\"></ax-badge>\n }\n </div>\n</ng-template>\n", styles: ["html[dir=rtl] axp-page-layout axp-page-toolbar axp-layout-prefix .ax-scheduler-header .arrow-icon:before{-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scaleX(-1)}.ax-single-range-calendar .ax-range-start,.ax-single-range-calendar .ax-range-end{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.85)!important}.ax-single-range-calendar .ax-range-start:hover,.ax-single-range-calendar .ax-range-end:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}.ax-single-range-calendar .ax-range-start.ax-state-holiday,.ax-single-range-calendar .ax-range-end.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.85)!important}.ax-single-range-calendar .ax-range-between{color:rgba(var(--ax-sys-color-on-primary-surface))!important;background-color:rgba(var(--ax-sys-color-primary-surface),.65)}.ax-single-range-calendar .ax-range-between.ax-state-holiday{background-color:rgba(var(--ax-sys-color-danger-surface),.65)}.ax-single-range-calendar ax-footer{display:flex;justify-content:center;border-color:rgba(var(--ax-comp-calendar-view-header-border-color));border-top-width:var(--ax-comp-calendar-view-header-border-width, 1px)}axp-page-content:not(:has(axm-task-board-status-grouped-grid-view,axm-task-board-time-grouped-grid-view)){overflow-y:hidden}\n"] }]
1821
+ }], propDecorators: { popover: [{ type: i0.ViewChild, args: ['popover', { isSignal: true }] }], calendar: [{ type: i0.ViewChild, args: ['calendar', { isSignal: true }] }], sidebarCalendar: [{ type: i0.ViewChild, args: ['sidebarCalendar', { isSignal: true }] }], dayCellTemplateRef: [{ type: i0.ViewChild, args: ['dayCellTemplate', { isSignal: true }] }], contextMenu: [{ type: i0.ViewChild, args: ['rootContextMenu', { isSignal: true }] }] } });
1362
1822
 
1363
1823
  export { AXMTaskBoardPage };
1364
- //# sourceMappingURL=acorex-modules-task-management-task-board.page-BVf2enGZ.mjs.map
1824
+ //# sourceMappingURL=acorex-modules-task-management-task-board.page-CtXx8vc6.mjs.map